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

2016-09-21 Thread Philip Langdale
On Sun, 18 Sep 2016 12:43:25 -0700
Philip Langdale  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 
> ---
>  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_fi

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

2016-09-18 Thread Philip Langdale
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 
---
 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