ffmpeg: av_init_packet is deprecated

https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=3189

Change-Id: I5ac25141ce76b2f7737e2f1b7ce5c8eac4a90082
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7249
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2023-12-29 11:14:01 +01:00 committed by waddlesplash
parent 3d6dc09d83
commit 9bf436a214
4 changed files with 56 additions and 50 deletions

View File

@ -119,6 +119,7 @@ AVCodecDecoder::AVCodecDecoder()
fDecodedDataBuffer(av_frame_alloc()), fDecodedDataBuffer(av_frame_alloc()),
fDecodedDataBufferOffset(0), fDecodedDataBufferOffset(0),
fDecodedDataBufferSize(0), fDecodedDataBufferSize(0),
fTempPacket(NULL),
fBufferSinkContext(NULL), fBufferSinkContext(NULL),
fBufferSourceContext(NULL), fBufferSourceContext(NULL),
fFilterGraph(NULL), fFilterGraph(NULL),
@ -168,6 +169,8 @@ AVCodecDecoder::~AVCodecDecoder()
#endif #endif
delete[] fExtraData; delete[] fExtraData;
av_packet_free(&fTempPacket);
} }
@ -335,9 +338,10 @@ AVCodecDecoder::Decode(void* outBuffer, int64* outFrameCount,
void void
AVCodecDecoder::_ResetTempPacket() AVCodecDecoder::_ResetTempPacket()
{ {
av_init_packet(&fTempPacket); if (fTempPacket == NULL)
fTempPacket.size = 0; fTempPacket = av_packet_alloc();
fTempPacket.data = NULL; fTempPacket->size = 0;
fTempPacket->data = NULL;
} }
@ -700,7 +704,7 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
status_t status_t
AVCodecDecoder::_DecodeNextAudioFrame() AVCodecDecoder::_DecodeNextAudioFrame()
{ {
assert(fTempPacket.size >= 0); assert(fTempPacket->size >= 0);
assert(fDecodedDataSizeInBytes == 0); assert(fDecodedDataSizeInBytes == 0);
// _DecodeNextAudioFrame needs to be called on empty fDecodedData only! // _DecodeNextAudioFrame needs to be called on empty fDecodedData only!
// If this assert holds wrong we have a bug somewhere. // If this assert holds wrong we have a bug somewhere.
@ -862,10 +866,10 @@ AVCodecDecoder::_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow()
"buffer! %" B_PRId32 "\n", fDecodedDataBufferSize); "buffer! %" B_PRId32 "\n", fDecodedDataBufferSize);
fDecodedDataBufferSize = 0; fDecodedDataBufferSize = 0;
} }
if (fTempPacket.size < 0) { if (fTempPacket->size < 0) {
fprintf(stderr, "Decoding read past the end of the temp packet! %d\n", fprintf(stderr, "Decoding read past the end of the temp packet! %d\n",
fTempPacket.size); fTempPacket->size);
fTempPacket.size = 0; fTempPacket->size = 0;
} }
} }
@ -1003,7 +1007,7 @@ AVCodecDecoder::_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes()
fDecodedDataBuffer->pkt_dts += framesTimeInterval; fDecodedDataBuffer->pkt_dts += framesTimeInterval;
// Start time of buffer is updated in case that it contains // Start time of buffer is updated in case that it contains
// more audio frames to move. // more audio frames to move.
fTempPacket.dts += framesTimeInterval; fTempPacket->dts += framesTimeInterval;
// Start time of fTempPacket is updated in case the fTempPacket // Start time of fTempPacket is updated in case the fTempPacket
// contains more audio frames to decode. // contains more audio frames to decode.
} }
@ -1056,10 +1060,10 @@ AVCodecDecoder::_DecodeNextAudioFrameChunk()
if (!fAudioDecodeError) { if (!fAudioDecodeError) {
// Report failure if not done already // Report failure if not done already
int32 chunkBufferOffset = fTempPacket.data - fChunkBuffer; int32 chunkBufferOffset = fTempPacket->data - fChunkBuffer;
printf("########### audio decode error, " printf("########### audio decode error, "
"fTempPacket.size %d, fChunkBuffer data offset %" B_PRId32 "fTempPacket->size %d, fChunkBuffer data offset %" B_PRId32
"\n", fTempPacket.size, chunkBufferOffset); "\n", fTempPacket->size, chunkBufferOffset);
fAudioDecodeError = true; fAudioDecodeError = true;
} }
@ -1080,7 +1084,7 @@ AVCodecDecoder::_DecodeNextAudioFrameChunk()
This function assumes to be called only when the following assumptions This function assumes to be called only when the following assumptions
hold true: hold true:
1. fDecodedDataBufferSize equals zero. 1. fDecodedDataBufferSize equals zero.
2. fTempPacket.size is greater than zero. 2. fTempPacket->size is greater than zero.
After this function returns successfully the caller can safely make the After this function returns successfully the caller can safely make the
following assumptions: following assumptions:
@ -1093,7 +1097,7 @@ AVCodecDecoder::_DecodeNextAudioFrameChunk()
When this function failed to decode at least one audio frame due to a When this function failed to decode at least one audio frame due to a
decoding error the caller can safely make the following assumptions: decoding error the caller can safely make the following assumptions:
1. fDecodedDataBufferSize equals zero. 1. fDecodedDataBufferSize equals zero.
2. fTempPacket.size equals zero. 2. fTempPacket->size equals zero.
Note: It is possible that there wasn't any audio frame decoded into Note: It is possible that there wasn't any audio frame decoded into
fDecodedDataBuffer after calling this function. This is normal and can fDecodedDataBuffer after calling this function. This is normal and can
@ -1122,10 +1126,10 @@ AVCodecDecoder::_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer()
if (error == AVERROR(EAGAIN)) { if (error == AVERROR(EAGAIN)) {
// We need to feed more data into the decoder // We need to feed more data into the decoder
avcodec_send_packet(fCodecContext, &fTempPacket); avcodec_send_packet(fCodecContext, fTempPacket);
// All the data is always consumed by avcodec_send_packet // All the data is always consumed by avcodec_send_packet
fTempPacket.size = 0; fTempPacket->size = 0;
// Try again to see if we can get some decoded audio out now // Try again to see if we can get some decoded audio out now
error = avcodec_receive_frame(fCodecContext, fDecodedDataBuffer); error = avcodec_receive_frame(fCodecContext, fDecodedDataBuffer);
@ -1258,19 +1262,19 @@ AVCodecDecoder::_DecodeNextVideoFrame()
char timestamp[AV_TS_MAX_STRING_SIZE]; char timestamp[AV_TS_MAX_STRING_SIZE];
av_ts_make_time_string(timestamp, av_ts_make_time_string(timestamp,
fTempPacket.dts, &fCodecContext->time_base); fTempPacket->dts, &fCodecContext->time_base);
TRACE("[v] Feed %d more bytes (dts %s)\n", fTempPacket.size, TRACE("[v] Feed %d more bytes (dts %s)\n", fTempPacket->size,
timestamp); timestamp);
send_error = avcodec_send_packet(fCodecContext, &fTempPacket); send_error = avcodec_send_packet(fCodecContext, fTempPacket);
if (send_error < 0 && send_error != AVERROR(EAGAIN)) { if (send_error < 0 && send_error != AVERROR(EAGAIN)) {
TRACE("[v] AVCodecDecoder: ignoring error in decoding frame " TRACE("[v] AVCodecDecoder: ignoring error in decoding frame "
"%lld: %d\n", fFrame, error); "%lld: %d\n", fFrame, error);
} }
// Packet is consumed, clear it // Packet is consumed, clear it
fTempPacket.data = NULL; fTempPacket->data = NULL;
fTempPacket.size = 0; fTempPacket->size = 0;
error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture); error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture);
if (error != 0 && error != AVERROR(EAGAIN)) { if (error != 0 && error != AVERROR(EAGAIN)) {
@ -1367,7 +1371,7 @@ AVCodecDecoder::_ApplyEssentialVideoContainerPropertiesToContext()
status_t status_t
AVCodecDecoder::_LoadNextChunkIfNeededAndAssignStartTime() AVCodecDecoder::_LoadNextChunkIfNeededAndAssignStartTime()
{ {
if (fTempPacket.size > 0) if (fTempPacket->size > 0)
return B_OK; return B_OK;
const void* chunkBuffer = NULL; const void* chunkBuffer = NULL;
@ -1386,9 +1390,9 @@ AVCodecDecoder::_LoadNextChunkIfNeededAndAssignStartTime()
if (chunkBufferPaddingStatus != B_OK) if (chunkBufferPaddingStatus != B_OK)
return chunkBufferPaddingStatus; return chunkBufferPaddingStatus;
fTempPacket.data = fChunkBuffer; fTempPacket->data = fChunkBuffer;
fTempPacket.size = fChunkBufferSize; fTempPacket->size = fChunkBufferSize;
fTempPacket.dts = chunkMediaHeader.start_time; fTempPacket->dts = chunkMediaHeader.start_time;
// Let FFMPEG handle the correct relationship between start_time and // Let FFMPEG handle the correct relationship between start_time and
// decoded a/v frame. By doing so we are simply copying the way how it // decoded a/v frame. By doing so we are simply copying the way how it
// is implemented in ffplay.c for video frames (for audio frames it // is implemented in ffplay.c for video frames (for audio frames it

View File

@ -154,7 +154,7 @@ private:
int32 fDecodedDataBufferOffset; int32 fDecodedDataBufferOffset;
int32 fDecodedDataBufferSize; int32 fDecodedDataBufferSize;
AVPacket fTempPacket; AVPacket* fTempPacket;
// video deinterlace feature // video deinterlace feature
AVFilterContext* fBufferSinkContext; AVFilterContext* fBufferSinkContext;

View File

@ -534,12 +534,11 @@ AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
status_t ret; status_t ret;
// Encode one audio chunk/frame. // Encode one audio chunk/frame.
AVPacket packet; AVPacket* packet = av_packet_alloc();
av_init_packet(&packet);
// By leaving these NULL, we let the encoder allocate memory as it needs. // By leaving these NULL, we let the encoder allocate memory as it needs.
// This way we don't risk iving a too small buffer. // This way we don't risk iving a too small buffer.
packet.data = NULL; packet->data = NULL;
packet.size = 0; packet->size = 0;
int gotPacket = 0; int gotPacket = 0;
@ -552,6 +551,7 @@ AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
if (count < 0) { if (count < 0) {
TRACE(" avcodec_encode_audio() failed filling data: %d\n", count); TRACE(" avcodec_encode_audio() failed filling data: %d\n", count);
av_packet_free(&packet);
return B_ERROR; return B_ERROR;
} }
@ -561,11 +561,11 @@ AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
fFramesWritten += fFrame->nb_samples; fFramesWritten += fFrame->nb_samples;
ret = avcodec_send_frame(fCodecContext, fFrame); ret = avcodec_send_frame(fCodecContext, fFrame);
gotPacket = avcodec_receive_packet(fCodecContext, &packet) == 0; gotPacket = avcodec_receive_packet(fCodecContext, packet) == 0;
} else { } else {
// If called with NULL, ask the encoder to flush any buffers it may // If called with NULL, ask the encoder to flush any buffers it may
// have pending. // have pending.
ret = avcodec_receive_packet(fCodecContext, &packet); ret = avcodec_receive_packet(fCodecContext, packet);
gotPacket = (ret == 0); gotPacket = (ret == 0);
} }
@ -574,6 +574,7 @@ AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
if (ret != 0) { if (ret != 0) {
TRACE(" avcodec_encode_audio() failed: %s\n", strerror(ret)); TRACE(" avcodec_encode_audio() failed: %s\n", strerror(ret));
av_packet_free(&packet);
return B_ERROR; return B_ERROR;
} }
@ -581,23 +582,23 @@ AVCodecEncoder::_EncodeAudio(const uint8* buffer, size_t bufferSize,
if (gotPacket) { if (gotPacket) {
// Setup media_encode_info, most important is the time stamp. // Setup media_encode_info, most important is the time stamp.
info->start_time = packet.pts; info->start_time = packet->pts;
if (packet.flags & AV_PKT_FLAG_KEY) if (packet->flags & AV_PKT_FLAG_KEY)
info->flags = B_MEDIA_KEY_FRAME; info->flags = B_MEDIA_KEY_FRAME;
else else
info->flags = 0; info->flags = 0;
// We got a packet out of the encoder, write it to the output stream // We got a packet out of the encoder, write it to the output stream
ret = WriteChunk(packet.data, packet.size, info); ret = WriteChunk(packet->data, packet->size, info);
if (ret != B_OK) { if (ret != B_OK) {
TRACE(" error writing chunk: %s\n", strerror(ret)); TRACE(" error writing chunk: %s\n", strerror(ret));
av_packet_unref(&packet); av_packet_free(&packet);
return ret; return ret;
} }
} }
av_packet_unref(&packet); av_packet_free(&packet);
return B_OK; return B_OK;
} }

View File

@ -72,7 +72,7 @@ public:
private: private:
AVFormatContext* fFormatContext; AVFormatContext* fFormatContext;
AVStream* fStream; AVStream* fStream;
AVPacket fPacket; AVPacket* fPacket;
// Since different threads may write to the target, // Since different threads may write to the target,
// we need to protect the file position and I/O by a lock. // we need to protect the file position and I/O by a lock.
BLocker* fStreamLock; BLocker* fStreamLock;
@ -87,13 +87,14 @@ AVFormatWriter::StreamCookie::StreamCookie(AVFormatContext* context,
fStream(NULL), fStream(NULL),
fStreamLock(streamLock) fStreamLock(streamLock)
{ {
av_init_packet(&fPacket); fPacket = av_packet_alloc();
} }
AVFormatWriter::StreamCookie::~StreamCookie() AVFormatWriter::StreamCookie::~StreamCookie()
{ {
// fStream is freed automatically when the codec context is closed // fStream is freed automatically when the codec context is closed
av_packet_free(&fPacket);
} }
@ -105,7 +106,7 @@ AVFormatWriter::StreamCookie::Init(media_format* format,
BAutolock _(fStreamLock); BAutolock _(fStreamLock);
fPacket.stream_index = fFormatContext->nb_streams; fPacket->stream_index = fFormatContext->nb_streams;
fStream = avformat_new_stream(fFormatContext, NULL); fStream = avformat_new_stream(fFormatContext, NULL);
if (fStream == NULL) { if (fStream == NULL) {
@ -113,7 +114,7 @@ AVFormatWriter::StreamCookie::Init(media_format* format,
return B_ERROR; return B_ERROR;
} }
fStream->id = fPacket.stream_index; fStream->id = fPacket->stream_index;
// TRACE(" fStream->codecpar: %p\n", fStream->codecpar); // TRACE(" fStream->codecpar: %p\n", fStream->codecpar);
// TODO: This is a hack for now! Use avcodec_find_encoder_by_name() // TODO: This is a hack for now! Use avcodec_find_encoder_by_name()
@ -302,21 +303,21 @@ AVFormatWriter::StreamCookie::WriteChunk(const void* chunkBuffer,
BAutolock _(fStreamLock); BAutolock _(fStreamLock);
fPacket.data = const_cast<uint8_t*>((const uint8_t*)chunkBuffer); fPacket->data = const_cast<uint8_t*>((const uint8_t*)chunkBuffer);
fPacket.size = chunkSize; fPacket->size = chunkSize;
fPacket.stream_index = fStream->index; fPacket->stream_index = fStream->index;
fPacket.pts = int64_t((double)encodeInfo->start_time fPacket->pts = int64_t((double)encodeInfo->start_time
* fStream->time_base.den / (1000000.0 * fStream->time_base.num) * fStream->time_base.den / (1000000.0 * fStream->time_base.num)
+ 0.5); + 0.5);
fPacket.dts = fPacket.pts; fPacket->dts = fPacket->pts;
fPacket.flags = 0; fPacket->flags = 0;
if ((encodeInfo->flags & B_MEDIA_KEY_FRAME) != 0) if ((encodeInfo->flags & B_MEDIA_KEY_FRAME) != 0)
fPacket.flags |= AV_PKT_FLAG_KEY; fPacket->flags |= AV_PKT_FLAG_KEY;
TRACE_PACKET(" PTS: %" PRId64 " (stream->time_base: (%d/%d)\n", fPacket.pts, TRACE_PACKET(" PTS: %" PRId64 " (stream->time_base: (%d/%d)\n", fPacket->pts,
fStream->time_base.num, fStream->time_base.den); fStream->time_base.num, fStream->time_base.den);
#if 0 #if 0
@ -325,11 +326,11 @@ AVFormatWriter::StreamCookie::WriteChunk(const void* chunkBuffer,
// more than one stream. For the moment, this crashes in AVPacket // more than one stream. For the moment, this crashes in AVPacket
// shuffling inside libavformat. Maybe if we want to use this, we // shuffling inside libavformat. Maybe if we want to use this, we
// need to allocate a separate AVPacket and copy the chunk buffer. // need to allocate a separate AVPacket and copy the chunk buffer.
int result = av_interleaved_write_frame(fFormatContext, &fPacket); int result = av_interleaved_write_frame(fFormatContext, fPacket);
if (result < 0) if (result < 0)
TRACE(" av_interleaved_write_frame(): %d\n", result); TRACE(" av_interleaved_write_frame(): %d\n", result);
#else #else
int result = av_write_frame(fFormatContext, &fPacket); int result = av_write_frame(fFormatContext, fPacket);
if (result < 0) if (result < 0)
TRACE(" av_write_frame(): %d\n", result); TRACE(" av_write_frame(): %d\n", result);
#endif #endif