diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2013-03-02 11:22:02 -0800 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2013-03-07 09:31:44 +0200 |
commit | 64e4386974b976070fc22ec3153e163de4a3e14e (patch) | |
tree | 32c4d67a4d996d4c9de7582539895f3c55e13c35 | |
parent | 70762508ec5919474edb92a5b1f266fd06640f9c (diff) | |
download | ffmpeg-64e4386974b976070fc22ec3153e163de4a3e14e.tar.gz |
h264: Integrate draw_horiz_band into ff_h264_draw_horiz_band
This makes the decoder independent of mpegvideo.
This copy of the draw_horiz_band code is simplified compared to
the "generic" mpegvideo one which still has a number of special
cases for different codecs.
Signed-off-by: Martin Storsjö <martin@martin.st>
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | libavcodec/h264.c | 44 |
2 files changed, 42 insertions, 6 deletions
@@ -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 610c815732..24d9c96276 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -123,10 +123,46 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, 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); + AVCodecContext *avctx = h->avctx; + Picture *cur = &h->cur_pic; + Picture *last = h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); + int vshift = desc->log2_chroma_h; + const int field_pic = h->picture_structure != PICT_FRAME; + if (field_pic) { + height <<= 1; + y <<= 1; + } + + height = FFMIN(height, avctx->height - y); + + if (field_pic && h->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 || h->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, h->picture_structure, height); + } } static void free_frame_buffer(H264Context *h, Picture *pic) |