From 49f71f4e1efec71322e723a235042d7d5f0b5ab1 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 26 May 2021 22:53:54 +0400 Subject: [PATCH] Use av_packet_alloc instead of av_init_packet. --- Telegram/SourceFiles/ffmpeg/ffmpeg_utility.h | 46 +++++++------------ .../media/audio/media_audio_capture.cpp | 15 +++--- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.h b/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.h index 4be81913c5..dd4675b25a 100644 --- a/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.h +++ b/Telegram/SourceFiles/ffmpeg/ffmpeg_utility.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "base/bytes.h" +#include "base/algorithm.h" #include @@ -61,55 +62,42 @@ private: class Packet { public: - Packet() { - setEmpty(); - } - Packet(const AVPacket &data) { - bytes::copy(_data, bytes::object_as_span(&data)); - } - Packet(Packet &&other) { - bytes::copy(_data, other._data); - if (!other.empty()) { - other.release(); - } + Packet() = default; + Packet(Packet &&other) : _data(base::take(other._data)) { } Packet &operator=(Packet &&other) { if (this != &other) { - av_packet_unref(&fields()); - bytes::copy(_data, other._data); - if (!other.empty()) { - other.release(); - } + release(); + _data = base::take(other._data); } return *this; } ~Packet() { - av_packet_unref(&fields()); + release(); } [[nodiscard]] AVPacket &fields() { - return *reinterpret_cast(_data); + if (!_data) { + _data = av_packet_alloc(); + } + return *_data; } [[nodiscard]] const AVPacket &fields() const { - return *reinterpret_cast(_data); + if (!_data) { + _data = av_packet_alloc(); + } + return *_data; } [[nodiscard]] bool empty() const { - return !fields().data; + return !_data || !fields().data; } void release() { - setEmpty(); + av_packet_free(&_data); } private: - void setEmpty() { - auto &native = fields(); - av_init_packet(&native); - native.data = nullptr; - native.size = 0; - } - - alignas(alignof(AVPacket)) bytes::type _data[sizeof(AVPacket)]; + mutable AVPacket *_data = nullptr; }; diff --git a/Telegram/SourceFiles/media/audio/media_audio_capture.cpp b/Telegram/SourceFiles/media/audio/media_audio_capture.cpp index 43dd26da15..5e3d8a58d2 100644 --- a/Telegram/SourceFiles/media/audio/media_audio_capture.cpp +++ b/Telegram/SourceFiles/media/audio/media_audio_capture.cpp @@ -736,16 +736,15 @@ bool Instance::Inner::writeFrame(AVFrame *frame) { } int Instance::Inner::writePackets() { - AVPacket pkt; - memset(&pkt, 0, sizeof(pkt)); // data and size must be 0; + AVPacket *pkt = av_packet_alloc(); + const auto guard = gsl::finally([&] { av_packet_free(&pkt); }); int res = 0; char err[AV_ERROR_MAX_STRING_SIZE] = { 0 }; int written = 0; do { - av_init_packet(&pkt); - if ((res = avcodec_receive_packet(d->codecContext, &pkt)) < 0) { + if ((res = avcodec_receive_packet(d->codecContext, pkt)) < 0) { if (res == AVERROR(EAGAIN)) { return written; } else if (res == AVERROR_EOF) { @@ -756,16 +755,16 @@ int Instance::Inner::writePackets() { return res; } - av_packet_rescale_ts(&pkt, d->codecContext->time_base, d->stream->time_base); - pkt.stream_index = d->stream->index; - if ((res = av_interleaved_write_frame(d->fmtContext, &pkt)) < 0) { + av_packet_rescale_ts(pkt, d->codecContext->time_base, d->stream->time_base); + pkt->stream_index = d->stream->index; + if ((res = av_interleaved_write_frame(d->fmtContext, pkt)) < 0) { LOG(("Audio Error: Unable to av_interleaved_write_frame for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res))); fail(); return -1; } ++written; - av_packet_unref(&pkt); + av_packet_unref(pkt); } while (true); return written; }