diff mbox

[FFmpeg-devel] crystalhd: Use up-to-date bsf API

Message ID 1474227805-19235-1-git-send-email-philipl@overt.org
State Accepted
Commit 7447ec91b5a692121b81a04c6501a5811d867775
Headers show

Commit Message

Philip Langdale Sept. 18, 2016, 7:43 p.m. UTC
Although the old API is supposed to functional, the crystalhd
decoder is currently not working for non-annex.b h.264 content.

So, let's update to the modern API and make it work again.

Signed-off-by: Philip Langdale <philipl@overt.org>
---
 libavcodec/crystalhd.c | 87 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 65 insertions(+), 22 deletions(-)

Comments

Philip Langdale Sept. 21, 2016, 5:19 p.m. UTC | #1
On Sun, 18 Sep 2016 12:43:25 -0700
Philip Langdale <philipl@overt.org> wrote:

> Although the old API is supposed to functional, the crystalhd
> decoder is currently not working for non-annex.b h.264 content.
> 
> So, let's update to the modern API and make it work again.
> 
> Signed-off-by: Philip Langdale <philipl@overt.org>
> ---
>  libavcodec/crystalhd.c | 87
> +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 65
> insertions(+), 22 deletions(-)
> 
> diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
> index d6ebcee..59b14b9 100644
> --- a/libavcodec/crystalhd.c
> +++ b/libavcodec/crystalhd.c
> @@ -131,7 +131,7 @@ typedef struct {
>      uint8_t *orig_extradata;
>      uint32_t orig_extradata_size;
>  
> -    AVBitStreamFilterContext *bsfc;
> +    AVBSFContext *bsfc;
>      AVCodecParserContext *parser;
>  
>      uint8_t is_70012;
> @@ -359,7 +359,7 @@ static av_cold int uninit(AVCodecContext *avctx)
>  
>      av_parser_close(priv->parser);
>      if (priv->bsfc) {
> -        av_bitstream_filter_close(priv->bsfc);
> +        av_bsf_free(&priv->bsfc);
>      }
>  
>      av_freep(&priv->sps_pps_buf);
> @@ -418,30 +418,46 @@ static av_cold int init(AVCodecContext *avctx)
>      switch (subtype) {
>      case BC_MSUBTYPE_AVC1:
>          {
> -            uint8_t *dummy_p;
> -            int dummy_int;
> +            const AVBitStreamFilter *bsf;
> +            int avret;
>  
> -            /* Back up the extradata so it can be restored at close
> time. */
> -            priv->orig_extradata = av_malloc(avctx->extradata_size +
> AV_INPUT_BUFFER_PADDING_SIZE);
> -            if (!priv->orig_extradata) {
> +            bsf = av_bsf_get_by_name("h264_mp4toannexb");
> +            if (!bsf) {
>                  av_log(avctx, AV_LOG_ERROR,
> -                       "Failed to allocate copy of extradata\n");
> +                       "Cannot open the h264_mp4toannexb BSF!\n");
> +                return AVERROR_BSF_NOT_FOUND;
> +            }
> +            avret = av_bsf_alloc(bsf, &priv->bsfc);
> +            if (avret != 0) {
> +                return AVERROR(ENOMEM);
> +            }
> +            avret =
> avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
> +            if (avret != 0) {
> +                return AVERROR(ENOMEM);
> +            }
> +            avret = av_bsf_init(priv->bsfc);
> +            if (avret != 0) {
>                  return AVERROR(ENOMEM);
>              }
> -            priv->orig_extradata_size = avctx->extradata_size;
> -            memcpy(priv->orig_extradata, avctx->extradata,
> avctx->extradata_size); 
> -            priv->bsfc =
> av_bitstream_filter_init("h264_mp4toannexb");
> -            if (!priv->bsfc) {
> +            format.metaDataSz = priv->bsfc->par_out->extradata_size;
> +            format.pMetaData = av_malloc(format.metaDataSz +
> AV_INPUT_BUFFER_PADDING_SIZE);
> +            if (!format.pMetaData) {
>                  av_log(avctx, AV_LOG_ERROR,
> -                       "Cannot open the h264_mp4toannexb BSF!\n");
> -                return AVERROR_BSF_NOT_FOUND;
> +                       "Failed to allocate copy of extradata\n");
> +                return AVERROR(ENOMEM);
>              }
> -            av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
> &dummy_p,
> -                                       &dummy_int, NULL, 0, 0);
> +            memcpy(format.pMetaData, priv->bsfc->par_out->extradata,
> format.metaDataSz); +
> +            /* Back up the extradata so it can be restored at close
> time. */
> +            priv->orig_extradata = avctx->extradata;
> +            priv->orig_extradata_size = avctx->extradata_size;
> +            avctx->extradata = format.pMetaData;
> +            avctx->extradata_size = format.metaDataSz;
>          }
>          subtype = BC_MSUBTYPE_H264;
> -        // Fall-through
> +        format.startCodeSz = 4;
> +        break;
>      case BC_MSUBTYPE_H264:
>          format.startCodeSz = 4;
>          // Fall-through
> @@ -901,14 +917,41 @@ static int decode(AVCodecContext *avctx, void
> *data, int *got_frame, AVPacket *a if (len) {
>          int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
>  
> -        if (priv->parser) {
> +        if (priv->bsfc) {
>              int ret = 0;
> +            AVPacket filter_packet = { 0 };
> +            AVPacket filtered_packet = { 0 };
> +
> +            ret = av_packet_ref(&filter_packet, avpkt);
> +            if (ret < 0) {
> +                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb
> filter "
> +                       "failed to ref input packet\n");
> +                return ret;
> +            }
> +
> +              ret = av_bsf_send_packet(priv->bsfc, &filter_packet);
> +              if (ret < 0) {
> +                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb
> filter "
> +                       "failed to send input packet\n");
> +                return ret;
> +            }
>  
> -            if (priv->bsfc) {
> -                ret = av_bitstream_filter_filter(priv->bsfc, avctx,
> NULL,
> -                                                 &in_data, &len,
> -                                                 avpkt->data, len,
> 0);
> +            ret = av_bsf_receive_packet(priv->bsfc,
> &filtered_packet);
> +            if (ret < 0) {
> +                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb
> filter "
> +                       "failed to receive output packet\n");
> +                return ret;
>              }
> +
> +            in_data = filtered_packet.data;
> +            len = filtered_packet.size;
> +
> +            av_packet_unref(&filter_packet);
> +        }
> +
> +        if (priv->parser) {
> +            int ret = 0;
> +
>              free_data = ret > 0;
>  
>              if (ret >= 0) {

Pushed.

--phil
diff mbox

Patch

diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index d6ebcee..59b14b9 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -131,7 +131,7 @@  typedef struct {
     uint8_t *orig_extradata;
     uint32_t orig_extradata_size;
 
-    AVBitStreamFilterContext *bsfc;
+    AVBSFContext *bsfc;
     AVCodecParserContext *parser;
 
     uint8_t is_70012;
@@ -359,7 +359,7 @@  static av_cold int uninit(AVCodecContext *avctx)
 
     av_parser_close(priv->parser);
     if (priv->bsfc) {
-        av_bitstream_filter_close(priv->bsfc);
+        av_bsf_free(&priv->bsfc);
     }
 
     av_freep(&priv->sps_pps_buf);
@@ -418,30 +418,46 @@  static av_cold int init(AVCodecContext *avctx)
     switch (subtype) {
     case BC_MSUBTYPE_AVC1:
         {
-            uint8_t *dummy_p;
-            int dummy_int;
+            const AVBitStreamFilter *bsf;
+            int avret;
 
-            /* Back up the extradata so it can be restored at close time. */
-            priv->orig_extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!priv->orig_extradata) {
+            bsf = av_bsf_get_by_name("h264_mp4toannexb");
+            if (!bsf) {
                 av_log(avctx, AV_LOG_ERROR,
-                       "Failed to allocate copy of extradata\n");
+                       "Cannot open the h264_mp4toannexb BSF!\n");
+                return AVERROR_BSF_NOT_FOUND;
+            }
+            avret = av_bsf_alloc(bsf, &priv->bsfc);
+            if (avret != 0) {
+                return AVERROR(ENOMEM);
+            }
+            avret = avcodec_parameters_from_context(priv->bsfc->par_in, avctx);
+            if (avret != 0) {
+                return AVERROR(ENOMEM);
+            }
+            avret = av_bsf_init(priv->bsfc);
+            if (avret != 0) {
                 return AVERROR(ENOMEM);
             }
-            priv->orig_extradata_size = avctx->extradata_size;
-            memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size);
 
-            priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
-            if (!priv->bsfc) {
+            format.metaDataSz = priv->bsfc->par_out->extradata_size;
+            format.pMetaData = av_malloc(format.metaDataSz + AV_INPUT_BUFFER_PADDING_SIZE);
+            if (!format.pMetaData) {
                 av_log(avctx, AV_LOG_ERROR,
-                       "Cannot open the h264_mp4toannexb BSF!\n");
-                return AVERROR_BSF_NOT_FOUND;
+                       "Failed to allocate copy of extradata\n");
+                return AVERROR(ENOMEM);
             }
-            av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p,
-                                       &dummy_int, NULL, 0, 0);
+            memcpy(format.pMetaData, priv->bsfc->par_out->extradata, format.metaDataSz);
+
+            /* Back up the extradata so it can be restored at close time. */
+            priv->orig_extradata = avctx->extradata;
+            priv->orig_extradata_size = avctx->extradata_size;
+            avctx->extradata = format.pMetaData;
+            avctx->extradata_size = format.metaDataSz;
         }
         subtype = BC_MSUBTYPE_H264;
-        // Fall-through
+        format.startCodeSz = 4;
+        break;
     case BC_MSUBTYPE_H264:
         format.startCodeSz = 4;
         // Fall-through
@@ -901,14 +917,41 @@  static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *a
     if (len) {
         int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
 
-        if (priv->parser) {
+        if (priv->bsfc) {
             int ret = 0;
+            AVPacket filter_packet = { 0 };
+            AVPacket filtered_packet = { 0 };
+
+            ret = av_packet_ref(&filter_packet, avpkt);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
+                       "failed to ref input packet\n");
+                return ret;
+            }
+
+              ret = av_bsf_send_packet(priv->bsfc, &filter_packet);
+              if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
+                       "failed to send input packet\n");
+                return ret;
+            }
 
-            if (priv->bsfc) {
-                ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
-                                                 &in_data, &len,
-                                                 avpkt->data, len, 0);
+            ret = av_bsf_receive_packet(priv->bsfc, &filtered_packet);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR, "CrystalHD: mpv4toannexb filter "
+                       "failed to receive output packet\n");
+                return ret;
             }
+
+            in_data = filtered_packet.data;
+            len = filtered_packet.size;
+
+            av_packet_unref(&filter_packet);
+        }
+
+        if (priv->parser) {
+            int ret = 0;
+
             free_data = ret > 0;
 
             if (ret >= 0) {