From 94fe138de0ba5892a7051f5b47c191a41b78805a Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 26 Jul 2018 20:42:27 -0300 Subject: [PATCH] avcodec/decode: flush the internal bsfs instead of constantly reinitalizing them Initialize the bsfs once when opening the codec and uninitialize them once when closing it, instead of at every codec flush/seek. Signed-off-by: James Almer --- libavcodec/decode.c | 20 ++++++++++---------- libavcodec/decode.h | 2 ++ libavcodec/utils.c | 7 +++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index db364ca700..2e82f6b506 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -182,7 +182,7 @@ static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) return 0; } -static int bsfs_init(AVCodecContext *avctx) +int ff_decode_bsfs_init(AVCodecContext *avctx) { AVCodecInternal *avci = avctx->internal; DecodeFilterContext *s = &avci->filter; @@ -688,10 +688,6 @@ int attribute_align_arg avcodec_send_packet(AVCodecContext *avctx, const AVPacke if (avpkt && !avpkt->size && avpkt->data) return AVERROR(EINVAL); - ret = bsfs_init(avctx); - if (ret < 0) - return ret; - av_packet_unref(avci->buffer_pkt); if (avpkt && (avpkt->data || avpkt->side_data_elems)) { ret = av_packet_ref(avci->buffer_pkt, avpkt); @@ -751,10 +747,6 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec)) return AVERROR(EINVAL); - ret = bsfs_init(avctx); - if (ret < 0) - return ret; - if (avci->buffer_frame->buf[0]) { av_frame_move_ref(frame, avci->buffer_frame); } else { @@ -1978,6 +1970,14 @@ int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame) return ret; } +static void bsfs_flush(AVCodecContext *avctx) +{ + DecodeFilterContext *s = &avctx->internal->filter; + + for (int i = 0; i < s->nb_bsfs; i++) + av_bsf_flush(s->bsfs[i]); +} + void avcodec_flush_buffers(AVCodecContext *avctx) { avctx->internal->draining = 0; @@ -1998,7 +1998,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->pts_correction_last_pts = avctx->pts_correction_last_dts = INT64_MIN; - ff_decode_bsfs_uninit(avctx); + bsfs_flush(avctx); if (!avctx->refcounted_frames) av_frame_unref(avctx->internal->to_free); diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 15271c529a..c3e0e82f4c 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -64,6 +64,8 @@ typedef struct FrameDecodeData { */ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); +int ff_decode_bsfs_init(AVCodecContext *avctx); + void ff_decode_bsfs_uninit(AVCodecContext *avctx); /** diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 4f9a2b76ef..285bfdbc63 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -727,6 +727,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + if (av_codec_is_decoder(avctx->codec)) { + ret = ff_decode_bsfs_init(avctx); + if (ret < 0) + goto free_and_end; + } + if (HAVE_THREADS && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) { ret = ff_thread_init(avctx); @@ -1032,6 +1038,7 @@ FF_ENABLE_DEPRECATION_WARNINGS av_packet_free(&avctx->internal->last_pkt_props); av_packet_free(&avctx->internal->ds.in_pkt); + ff_decode_bsfs_uninit(avctx); av_freep(&avctx->internal->pool); }