[02/17] h264: Add a copy of draw_horiz_band

Message ID 1362578206-2806-2-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö March 6, 2013, 1:56 p.m.
From: "Ronald S. Bultje" <rsbultje@gmail.com>

This makes the decoder independent of mpegvideo.

This copy is simplified compared to the "generic" mpegvideo one
which still has a number of special cases for different codecs.
---
 configure         |    4 ++--
 libavcodec/h264.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 49 insertions(+), 6 deletions(-)

Comments

Luca Barbato March 6, 2013, 2:35 p.m. | #1
On 06/03/13 14:56, Martin Storsjö wrote:
> From: "Ronald S. Bultje" <rsbultje@gmail.com>
> 
> This makes the decoder independent of mpegvideo.
> 
> This copy is simplified compared to the "generic" mpegvideo one
> which still has a number of special cases for different codecs.
> ---
>  configure         |    4 ++--
>  libavcodec/h264.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 49 insertions(+), 6 deletions(-)
> 

Looks fine.
Anton Khirnov March 6, 2013, 3:32 p.m. | #2
On Wed,  6 Mar 2013 15:56:31 +0200, Martin Storsjö <martin@martin.st> wrote:
> From: "Ronald S. Bultje" <rsbultje@gmail.com>
> 
> This makes the decoder independent of mpegvideo.
> 
> This copy is simplified compared to the "generic" mpegvideo one
> which still has a number of special cases for different codecs.
> ---
>  configure         |    4 ++--
>  libavcodec/h264.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++----
>  2 files changed, 49 insertions(+), 6 deletions(-)
> 
> diff --git a/configure b/configure
> index 7525e22..0aed51d 100755
> --- a/configure
> +++ b/configure
> @@ -1542,7 +1542,7 @@ h263_decoder_select="error_resilience h263_parser mpegvideo"
>  h263_encoder_select="aandcttables error_resilience mpegvideoenc"
>  h263i_decoder_select="h263_decoder"
>  h263p_encoder_select="h263_encoder"
> -h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
> +h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel videodsp"
>  huffyuv_encoder_select="huffman"
>  iac_decoder_select="fft mdct sinewin"
>  imc_decoder_select="fft mdct sinewin"
> @@ -1689,7 +1689,7 @@ wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
>  wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
>  
>  # parsers
> -h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
> +h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel videodsp"
>  mpeg4video_parser_select="error_resilience mpegvideo"
>  mpegvideo_parser_select="error_resilience mpegvideo"
>  vc1_parser_select="error_resilience mpegvideo"
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index 7ec5583..0b43248 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -121,12 +121,55 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
>      ff_h264_hl_decode_mb(h);
>  }
>  
> +static void draw_horiz_band(AVCodecContext *avctx, Picture *cur,
> +                            Picture *last, int y, int h, int picture_structure,
> +                            int first_field, int low_delay)
> +{
> +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
> +    int vshift = desc->log2_chroma_h;
> +    const int field_pic = picture_structure != PICT_FRAME;
> +    if (field_pic) {
> +        h <<= 1;
> +        y <<= 1;
> +    }
> +
> +    h = FFMIN(h, avctx->height - y);
> +
> +    if (field_pic && first_field && !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD))
> +        return;
> +
> +    if (avctx->draw_horiz_band) {
> +        AVFrame *src;
> +        int offset[AV_NUM_DATA_POINTERS];
> +        int i;
> +
> +        if (cur->f.pict_type == AV_PICTURE_TYPE_B || low_delay ||
> +           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
> +            src = &cur->f;
> +        else if (last)
> +            src = &last->f;
> +        else
> +            return;
> +
> +        offset[0] = y * src->linesize[0];
> +        offset[1] =
> +        offset[2] = (y >> vshift) * src->linesize[1];
> +        for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
> +            offset[i] = 0;
> +
> +        emms_c();
> +
> +        avctx->draw_horiz_band(avctx, src, offset,
> +                               y, picture_structure, h);
> +    }
> +}
> +
>  void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
>  {
> -    ff_draw_horiz_band(h->avctx, NULL, &h->cur_pic,
> -                       h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
> -                       y, height, h->picture_structure, h->first_field, 0,
> -                       h->low_delay, h->mb_height * 16, h->mb_width * 16);
> +    draw_horiz_band(h->avctx, &h->cur_pic,
> +                    h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
> +                    y, height, h->picture_structure, h->first_field,
> +                    h->low_delay);
>  }

Why not merge it into ff_h264_draw_horiz_band()?

Patch

diff --git a/configure b/configure
index 7525e22..0aed51d 100755
--- a/configure
+++ b/configure
@@ -1542,7 +1542,7 @@  h263_decoder_select="error_resilience h263_parser mpegvideo"
 h263_encoder_select="aandcttables error_resilience mpegvideoenc"
 h263i_decoder_select="h263_decoder"
 h263p_encoder_select="h263_encoder"
-h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
+h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel videodsp"
 huffyuv_encoder_select="huffman"
 iac_decoder_select="fft mdct sinewin"
 imc_decoder_select="fft mdct sinewin"
@@ -1689,7 +1689,7 @@  wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
 wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
 
 # parsers
-h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
+h264_parser_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel videodsp"
 mpeg4video_parser_select="error_resilience mpegvideo"
 mpegvideo_parser_select="error_resilience mpegvideo"
 vc1_parser_select="error_resilience mpegvideo"
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 7ec5583..0b43248 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -121,12 +121,55 @@  static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
     ff_h264_hl_decode_mb(h);
 }
 
+static void draw_horiz_band(AVCodecContext *avctx, Picture *cur,
+                            Picture *last, int y, int h, int picture_structure,
+                            int first_field, int low_delay)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    int vshift = desc->log2_chroma_h;
+    const int field_pic = picture_structure != PICT_FRAME;
+    if (field_pic) {
+        h <<= 1;
+        y <<= 1;
+    }
+
+    h = FFMIN(h, avctx->height - y);
+
+    if (field_pic && first_field && !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD))
+        return;
+
+    if (avctx->draw_horiz_band) {
+        AVFrame *src;
+        int offset[AV_NUM_DATA_POINTERS];
+        int i;
+
+        if (cur->f.pict_type == AV_PICTURE_TYPE_B || low_delay ||
+           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+            src = &cur->f;
+        else if (last)
+            src = &last->f;
+        else
+            return;
+
+        offset[0] = y * src->linesize[0];
+        offset[1] =
+        offset[2] = (y >> vshift) * src->linesize[1];
+        for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+            offset[i] = 0;
+
+        emms_c();
+
+        avctx->draw_horiz_band(avctx, src, offset,
+                               y, picture_structure, h);
+    }
+}
+
 void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
 {
-    ff_draw_horiz_band(h->avctx, NULL, &h->cur_pic,
-                       h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
-                       y, height, h->picture_structure, h->first_field, 0,
-                       h->low_delay, h->mb_height * 16, h->mb_width * 16);
+    draw_horiz_band(h->avctx, &h->cur_pic,
+                    h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL,
+                    y, height, h->picture_structure, h->first_field,
+                    h->low_delay);
 }
 
 static void free_frame_buffer(H264Context *h, Picture *pic)