Use av_packet_alloc instead of av_init_packet.

This commit is contained in:
John Preston 2021-05-26 22:53:54 +04:00
parent 0c5258b43a
commit 49f71f4e1e
2 changed files with 24 additions and 37 deletions

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "base/bytes.h" #include "base/bytes.h"
#include "base/algorithm.h"
#include <crl/crl_time.h> #include <crl/crl_time.h>
@ -61,55 +62,42 @@ private:
class Packet { class Packet {
public: public:
Packet() { Packet() = default;
setEmpty(); Packet(Packet &&other) : _data(base::take(other._data)) {
}
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 &operator=(Packet &&other) { Packet &operator=(Packet &&other) {
if (this != &other) { if (this != &other) {
av_packet_unref(&fields()); release();
bytes::copy(_data, other._data); _data = base::take(other._data);
if (!other.empty()) {
other.release();
}
} }
return *this; return *this;
} }
~Packet() { ~Packet() {
av_packet_unref(&fields()); release();
} }
[[nodiscard]] AVPacket &fields() { [[nodiscard]] AVPacket &fields() {
return *reinterpret_cast<AVPacket*>(_data); if (!_data) {
_data = av_packet_alloc();
}
return *_data;
} }
[[nodiscard]] const AVPacket &fields() const { [[nodiscard]] const AVPacket &fields() const {
return *reinterpret_cast<const AVPacket*>(_data); if (!_data) {
_data = av_packet_alloc();
}
return *_data;
} }
[[nodiscard]] bool empty() const { [[nodiscard]] bool empty() const {
return !fields().data; return !_data || !fields().data;
} }
void release() { void release() {
setEmpty(); av_packet_free(&_data);
} }
private: private:
void setEmpty() { mutable AVPacket *_data = nullptr;
auto &native = fields();
av_init_packet(&native);
native.data = nullptr;
native.size = 0;
}
alignas(alignof(AVPacket)) bytes::type _data[sizeof(AVPacket)];
}; };

View file

@ -736,16 +736,15 @@ bool Instance::Inner::writeFrame(AVFrame *frame) {
} }
int Instance::Inner::writePackets() { int Instance::Inner::writePackets() {
AVPacket pkt; AVPacket *pkt = av_packet_alloc();
memset(&pkt, 0, sizeof(pkt)); // data and size must be 0; const auto guard = gsl::finally([&] { av_packet_free(&pkt); });
int res = 0; int res = 0;
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 }; char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
int written = 0; int written = 0;
do { 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)) { if (res == AVERROR(EAGAIN)) {
return written; return written;
} else if (res == AVERROR_EOF) { } else if (res == AVERROR_EOF) {
@ -756,16 +755,16 @@ int Instance::Inner::writePackets() {
return res; return res;
} }
av_packet_rescale_ts(&pkt, d->codecContext->time_base, d->stream->time_base); av_packet_rescale_ts(pkt, d->codecContext->time_base, d->stream->time_base);
pkt.stream_index = d->stream->index; pkt->stream_index = d->stream->index;
if ((res = av_interleaved_write_frame(d->fmtContext, &pkt)) < 0) { 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))); 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(); fail();
return -1; return -1;
} }
++written; ++written;
av_packet_unref(&pkt); av_packet_unref(pkt);
} while (true); } while (true);
return written; return written;
} }