qsvdec_h2645: switch to the new BSF API
authorAnton Khirnov <anton@khirnov.net>
Sun, 20 Mar 2016 07:53:10 +0000 (08:53 +0100)
committerAnton Khirnov <anton@khirnov.net>
Fri, 25 Mar 2016 13:53:37 +0000 (14:53 +0100)
libavcodec/qsvdec_h2645.c

index 99a71e4..a65be99 100644 (file)
@@ -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);