mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-28 12:32:17 +02:00
avcodec/avcodec: Store whether AVCodec->close needs to be called
Right now all AVCodecContexts except those using frame-threaded decoding call the codec's init function and expect its close function to be called. In order to make sure that the close function is not called for frame-threaded decoding ff_frame_thread_free() resets AVCodecContext.codec (and because of this it has to free the private AVOptions of the main AVCodecContext itself). This is not obvious and potentially fragile. Instead add a field to AVCodecInternal that indicates whether close should be called for this AVCodecContext. It is always zero when using frame-threaded decoding, so that resetting the codec is no longer necessary and has been removed. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
d07534b5f5
commit
29f5c1e51b
@ -135,7 +135,6 @@ static int64_t get_bit_rate(AVCodecContext *ctx)
|
|||||||
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
|
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int codec_init_ok = 0;
|
|
||||||
AVDictionary *tmp = NULL;
|
AVDictionary *tmp = NULL;
|
||||||
AVCodecInternal *avci;
|
AVCodecInternal *avci;
|
||||||
|
|
||||||
@ -320,14 +319,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
|
|||||||
if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS))
|
if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS))
|
||||||
avctx->thread_count = 1;
|
avctx->thread_count = 1;
|
||||||
|
|
||||||
if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME)
|
if (!(avctx->active_thread_type & FF_THREAD_FRAME) ||
|
||||||
|| avci->frame_thread_encoder)) {
|
avci->frame_thread_encoder) {
|
||||||
ret = avctx->codec->init(avctx);
|
if (avctx->codec->init) {
|
||||||
if (ret < 0) {
|
ret = avctx->codec->init(avctx);
|
||||||
codec_init_ok = -1;
|
if (ret < 0) {
|
||||||
goto free_and_end;
|
avci->needs_close = avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP;
|
||||||
|
goto free_and_end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
codec_init_ok = 1;
|
avci->needs_close = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret=0;
|
ret=0;
|
||||||
@ -378,9 +379,7 @@ end:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
free_and_end:
|
free_and_end:
|
||||||
if (avctx->codec && avctx->codec->close &&
|
if (avci->needs_close && avctx->codec->close)
|
||||||
(codec_init_ok > 0 || (codec_init_ok < 0 &&
|
|
||||||
avctx->codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP)))
|
|
||||||
avctx->codec->close(avctx);
|
avctx->codec->close(avctx);
|
||||||
|
|
||||||
if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder)
|
if (CONFIG_FRAME_THREAD_ENCODER && avci->frame_thread_encoder)
|
||||||
@ -502,7 +501,7 @@ av_cold int avcodec_close(AVCodecContext *avctx)
|
|||||||
}
|
}
|
||||||
if (HAVE_THREADS && avci->thread_ctx)
|
if (HAVE_THREADS && avci->thread_ctx)
|
||||||
ff_thread_free(avctx);
|
ff_thread_free(avctx);
|
||||||
if (avctx->codec && avctx->codec->close)
|
if (avci->needs_close && avctx->codec->close)
|
||||||
avctx->codec->close(avctx);
|
avctx->codec->close(avctx);
|
||||||
avci->byte_buffer_size = 0;
|
avci->byte_buffer_size = 0;
|
||||||
av_freep(&avci->byte_buffer);
|
av_freep(&avci->byte_buffer);
|
||||||
|
@ -160,6 +160,12 @@ typedef struct AVCodecInternal {
|
|||||||
|
|
||||||
EncodeSimpleContext es;
|
EncodeSimpleContext es;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is set, then AVCodec->close (if existing) needs to be called
|
||||||
|
* for the parent AVCodecContext.
|
||||||
|
*/
|
||||||
|
int needs_close;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of audio samples to skip at the start of the next decoded frame
|
* Number of audio samples to skip at the start of the next decoded frame
|
||||||
*/
|
*/
|
||||||
|
@ -801,10 +801,6 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
|||||||
free_pthread(fctx, thread_ctx_offsets);
|
free_pthread(fctx, thread_ctx_offsets);
|
||||||
|
|
||||||
av_freep(&avctx->internal->thread_ctx);
|
av_freep(&avctx->internal->thread_ctx);
|
||||||
|
|
||||||
if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
|
|
||||||
av_opt_free(avctx->priv_data);
|
|
||||||
avctx->codec = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
|
static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user