From e691cf1eed454e715557b864b227230888d38e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 14 Dec 2023 20:53:58 +0100 Subject: [PATCH] ffmpeg: avcodec_free_context seems to also free extradata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * context->extradata seems to be set to fExtraData or fInputFormat.MetaData(). Both are managed by us, so set context->extradata to NULL before freeing. * avcodec_close() shouldn't use according to the documentation: "Use avcodec_free_context() to destroy a codec context (either open or closed). Opening and closing a codec context multiple times is not supported anymore – use multiple codec contexts instead." * fix #18713 Change-Id: I820deefcffea52a39fcb7587153d40dc03c85024 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7208 Reviewed-by: waddlesplash Tested-by: Commit checker robot --- .../media/plugins/ffmpeg/AVCodecDecoder.cpp | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp index e1beccc645..20b88cf3f2 100644 --- a/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp +++ b/src/add-ons/media/plugins/ffmpeg/AVCodecDecoder.cpp @@ -147,9 +147,6 @@ AVCodecDecoder::~AVCodecDecoder() } #endif - if (fCodecInitDone) - avcodec_close(fCodecContext); - swr_free(&fResampleContext); free(fChunkBuffer); free(fDecodedData); @@ -158,6 +155,7 @@ AVCodecDecoder::~AVCodecDecoder() av_frame_free(&fRawDecodedPicture); av_free(fRawDecodedAudio->opaque); av_frame_free(&fRawDecodedAudio); + fCodecContext->extradata = NULL; avcodec_free_context(&fCodecContext); av_frame_free(&fDecodedDataBuffer); @@ -301,6 +299,12 @@ AVCodecDecoder::NegotiateOutputFormat(media_format* inOutFormat) TRACE(" [%c] requested format = %s\n", fIsAudio?('a'):('v'), buffer); #endif + // close any previous instance + fCodecContext->extradata = NULL; + avcodec_free_context(&fCodecContext); + fCodecContext = avcodec_alloc_context3(fCodec); + fCodecInitDone = false; + if (fIsAudio) return _NegotiateAudioOutputFormat(inOutFormat); else @@ -350,18 +354,11 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat) // to _DecodeNextAudioFrameChunk() will update the essential audio // format properties accordingly regardless of the settings here. - // close any previous instance - if (fCodecInitDone) { - fCodecInitDone = false; - avcodec_close(fCodecContext); - } - - if (avcodec_open2(fCodecContext, fCodec, NULL) >= 0) - fCodecInitDone = true; - else { + if (avcodec_open2(fCodecContext, fCodec, NULL) < 0) { TRACE("avcodec_open() failed to init codec!\n"); return B_ERROR; } + fCodecInitDone = true; free(fChunkBuffer); fChunkBuffer = NULL; @@ -464,18 +461,11 @@ AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat) fCodecContext->flags |= AV_CODEC_FLAG_TRUNCATED; } - // close any previous instance - if (fCodecInitDone) { - fCodecInitDone = false; - avcodec_close(fCodecContext); - } - - if (avcodec_open2(fCodecContext, fCodec, NULL) >= 0) - fCodecInitDone = true; - else { + if (avcodec_open2(fCodecContext, fCodec, NULL) < 0) { TRACE("avcodec_open() failed to init codec!\n"); return B_ERROR; } + fCodecInitDone = true; #if USE_SWS_FOR_COLOR_SPACE_CONVERSION fOutputColorSpace = B_RGB32;