From e3dfef8e3c85a64dbe6388117303f5819fa3c6a2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 20 Mar 2016 08:53:10 +0100 Subject: [PATCH] qsvdec_h2645: switch to the new BSF API --- libavcodec/qsvdec_h2645.c | 84 ++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c index 99a71e46f8..a65be995c4 100644 --- a/libavcodec/qsvdec_h2645.c +++ b/libavcodec/qsvdec_h2645.c @@ -49,13 +49,11 @@ typedef struct QSVH2645Context { int load_plugin; // the filter for converting to Annex B - AVBitStreamFilterContext *bsf; + AVBSFContext *bsf; AVFifoBuffer *packet_fifo; - AVPacket input_ref; AVPacket pkt_filtered; - uint8_t *filtered_data; } QSVH2645Context; static void qsv_clear_buffers(QSVH2645Context *s) @@ -66,10 +64,9 @@ static void qsv_clear_buffers(QSVH2645Context *s) av_packet_unref(&pkt); } - if (s->filtered_data != s->input_ref.data) - av_freep(&s->filtered_data); - s->filtered_data = NULL; - av_packet_unref(&s->input_ref); + av_bsf_free(&s->bsf); + + av_packet_unref(&s->pkt_filtered); } static av_cold int qsv_decode_close(AVCodecContext *avctx) @@ -82,8 +79,6 @@ static av_cold int qsv_decode_close(AVCodecContext *avctx) av_fifo_free(s->packet_fifo); - av_bitstream_filter_close(s->bsf); - return 0; } @@ -113,15 +108,6 @@ static av_cold int qsv_decode_init(AVCodecContext *avctx) goto fail; } - if (avctx->codec_id == AV_CODEC_ID_H264) - s->bsf = av_bitstream_filter_init("h264_mp4toannexb"); - else - s->bsf = av_bitstream_filter_init("hevc_mp4toannexb"); - if (!s->bsf) { - ret = AVERROR(ENOMEM); - goto fail; - } - s->qsv.iopattern = MFX_IOPATTERN_OUT_SYSTEM_MEMORY; return 0; @@ -130,6 +116,37 @@ fail: return ret; } +static int qsv_init_bsf(AVCodecContext *avctx, QSVH2645Context *s) +{ + const char *filter_name = avctx->codec_id == AV_CODEC_ID_HEVC ? + "hevc_mp4toannexb" : "h264_mp4toannexb"; + const AVBitStreamFilter *filter; + int ret; + + if (s->bsf) + return 0; + + filter = av_bsf_get_by_name(filter_name); + if (!filter) + return AVERROR_BUG; + + ret = av_bsf_alloc(filter, &s->bsf); + if (ret < 0) + return ret; + + ret = avcodec_parameters_from_context(s->bsf->par_in, avctx); + if (ret < 0) + return ret; + + s->bsf->time_base_in = avctx->time_base; + + ret = av_bsf_init(s->bsf); + if (ret < 0) + return ret; + + return ret; +} + static int qsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -137,6 +154,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, AVFrame *frame = data; int ret; + /* make sure the bitstream filter is initialized */ + ret = qsv_init_bsf(avctx, s); + if (ret < 0) + return ret; + /* buffer the input packet */ if (avpkt->size) { AVPacket input_ref = { 0 }; @@ -158,28 +180,26 @@ static int qsv_decode_frame(AVCodecContext *avctx, void *data, while (!*got_frame) { /* prepare the input data -- convert to Annex B if needed */ if (s->pkt_filtered.size <= 0) { - int size; + AVPacket input_ref; /* no more data */ if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket)) return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, avpkt); - if (s->filtered_data != s->input_ref.data) - av_freep(&s->filtered_data); - s->filtered_data = NULL; - av_packet_unref(&s->input_ref); + av_packet_unref(&s->pkt_filtered); - av_fifo_generic_read(s->packet_fifo, &s->input_ref, sizeof(s->input_ref), NULL); - ret = av_bitstream_filter_filter(s->bsf, avctx, NULL, - &s->filtered_data, &size, - s->input_ref.data, s->input_ref.size, 0); + av_fifo_generic_read(s->packet_fifo, &input_ref, sizeof(input_ref), NULL); + ret = av_bsf_send_packet(s->bsf, &input_ref); if (ret < 0) { - s->filtered_data = s->input_ref.data; - size = s->input_ref.size; + av_packet_unref(&input_ref); + return ret; } - s->pkt_filtered = s->input_ref; - s->pkt_filtered.data = s->filtered_data; - s->pkt_filtered.size = size; + + ret = av_bsf_receive_packet(s->bsf, &s->pkt_filtered); + if (ret < 0) + av_packet_move_ref(&s->pkt_filtered, &input_ref); + else + av_packet_unref(&input_ref); } ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, &s->pkt_filtered);