From 9858be4f63c2148aa18bd65e139586e3e837f8c2 Mon Sep 17 00:00:00 2001 From: PulkoMandy Date: Wed, 9 Aug 2023 21:39:01 +0200 Subject: [PATCH] ffmpeg: remove usage of deprecated method avcodec_decode_audio4 Use avcodec_send_packet and avcodec_receive_frame as recommended in ffmpeg documentation. Change-Id: Ib9dc343a9f5cfbc50192158934e5e80c09a37fab Reviewed-on: https://review.haiku-os.org/c/haiku/+/6803 Reviewed-by: Adrien Destugues --- .../media/plugins/ffmpeg/AVCodecDecoder.cpp | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp index 9609c28c869..6bfb68d4edd 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp @@ -757,7 +757,7 @@ AVCodecDecoder::_DecodeNextAudioFrame() Note: This function must be called before the AVCodec is opened via avcodec_open2(). Otherwise the behaviour of FFMPEG's audio decoding - function avcodec_decode_audio4() is undefined. + function avcodec_receive_frame() is undefined. Essential properties applied from fInputFormat.u.encoded_audio: - bit_rate copied to fCodecContext->bit_rate @@ -1097,7 +1097,7 @@ AVCodecDecoder::_DecodeNextAudioFrameChunk() 1. fDecodedDataBufferSize is greater than zero in the common case. Also see "Note" below. 2. fTempPacket was updated to exclude the data chunk that was consumed - by avcodec_decode_audio4(). + by avcodec_send_packet(). 3. fDecodedDataBufferOffset is set to zero. When this function failed to decode at least one audio frame due to a @@ -1113,7 +1113,7 @@ AVCodecDecoder::_DecodeNextAudioFrameChunk() \returns B_OK Decoding successful. fDecodedDataBuffer contains decoded audio frames only when fDecodedDataBufferSize is greater than zero. - fDecodedDataBuffer is empty, when avcodec_decode_audio4() didn't return + fDecodedDataBuffer is empty, when avcodec_receive_frame() didn't return audio frames due to delayed decoding or incomplete audio frames. \returns B_ERROR Decoding failed thus fDecodedDataBuffer contains no audio frames. @@ -1126,29 +1126,30 @@ AVCodecDecoder::_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer() memset(fDecodedDataBuffer, 0, sizeof(AVFrame)); av_frame_unref(fDecodedDataBuffer); fDecodedDataBufferOffset = 0; - int gotAudioFrame = 0; - int encodedDataSizeInBytes = avcodec_decode_audio4(fCodecContext, - fDecodedDataBuffer, &gotAudioFrame, &fTempPacket); - if (encodedDataSizeInBytes <= 0) { - // Error or failure to produce decompressed output. - // Skip the temp packet data entirely. - fTempPacket.size = 0; - return B_ERROR; - } + int error = avcodec_receive_frame(fCodecContext, fDecodedDataBuffer); + if (error == AVERROR_EOF) + return B_LAST_BUFFER_ERROR; - fTempPacket.data += encodedDataSizeInBytes; - fTempPacket.size -= encodedDataSizeInBytes; + if (error == AVERROR(EAGAIN)) { + // We need to feed more data into the decoder + avcodec_send_packet(fCodecContext, &fTempPacket); - bool gotNoAudioFrame = gotAudioFrame == 0; - if (gotNoAudioFrame) - return B_OK; + // All the data is always consumed by avcodec_send_packet + fTempPacket.size = 0; + + // Try again to see if we can get some decoded audio out now + error = avcodec_receive_frame(fCodecContext, fDecodedDataBuffer); + } fDecodedDataBufferSize = fDecodedDataBuffer->nb_samples; if (fDecodedDataBufferSize < 0) fDecodedDataBufferSize = 0; - return B_OK; + if (error == 0) + return B_OK; + else + return B_ERROR; }