On Fri, Oct 21, 2011 at 12:13:13AM -0700, Ronald S. Bultje wrote:
> From: Baptiste Coudurier <[email protected]>
> 
> Signed-off-by: Diego Biurrun <[email protected]>
> Signed-off-by: Ronald S. Bultje <[email protected]>
> ---
>  Changelog                            |    1 +
>  libavcodec/arm/h264dsp_init_arm.c    |    9 +-
>  libavcodec/arm/h264pred_init_arm.c   |    6 +-
>  libavcodec/dsputil.h                 |    2 +
>  libavcodec/h264.c                    |   95 +++++++++++++++++------
>  libavcodec/h264.h                    |   12 +--
>  libavcodec/h264_cabac.c              |   84 ++++++++++++++++++--
>  libavcodec/h264_cavlc.c              |  127 +++++++++++++++++++++++++++++--
>  libavcodec/h264_loopfilter.c         |   61 ++++++++++++---
>  libavcodec/h264_mvpred.h             |    7 ++-
>  libavcodec/h264_ps.c                 |    5 +-
>  libavcodec/h264data.h                |    9 ++-
>  libavcodec/h264dsp.c                 |   38 +++++++---
>  libavcodec/h264dsp.h                 |    8 +-
>  libavcodec/h264dsp_template.c        |   16 ++++
>  libavcodec/h264idct_template.c       |   50 ++++++++++++
>  libavcodec/h264pred.c                |   51 +++++++++----
>  libavcodec/h264pred.h                |    6 +-
>  libavcodec/h264pred_template.c       |  138 
> ++++++++++++++++++++++++++++++++++
>  libavcodec/ppc/h264_altivec.c        |    5 +-
>  libavcodec/rv34.c                    |    2 +-
>  libavcodec/vp8.c                     |    2 +-
>  libavcodec/x86/h264_intrapred_init.c |   47 +++++++----
>  libavcodec/x86/h264dsp_mmx.c         |   23 ++++--
>  24 files changed, 671 insertions(+), 133 deletions(-)
> 
> diff --git a/Changelog b/Changelog
> index f61d3e2..ecfc34f 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -53,6 +53,7 @@ easier to use. The changes are:
>  - lut, lutrgb, and lutyuv filters
>  - boxblur filter
>  - Ut Video decoder
> +- 4:2:2 H.264 decoding support
>  
>  
>  version 0.7:
> diff --git a/libavcodec/arm/h264dsp_init_arm.c 
> b/libavcodec/arm/h264dsp_init_arm.c
> index c2399e5..c1ca217 100644
> --- a/libavcodec/arm/h264dsp_init_arm.c
> +++ b/libavcodec/arm/h264dsp_init_arm.c
> @@ -92,7 +92,7 @@ void ff_h264_idct8_add4_neon(uint8_t *dst, const int 
> *block_offset,
>                               DCTELEM *block, int stride,
>                               const uint8_t nnzc[6*8]);
>  
> -static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth)
> +static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, 
> const int chroma_format_idc)
>  {
>      if (bit_depth == 8) {
>      c->h264_v_loop_filter_luma   = ff_h264_v_loop_filter_luma_neon;
> @@ -122,14 +122,15 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, 
> const int bit_depth)
>      c->h264_idct_dc_add     = ff_h264_idct_dc_add_neon;
>      c->h264_idct_add16      = ff_h264_idct_add16_neon;
>      c->h264_idct_add16intra = ff_h264_idct_add16intra_neon;
> -    c->h264_idct_add8       = ff_h264_idct_add8_neon;
> +    if (chroma_format_idc == 1)
> +        c->h264_idct_add8   = ff_h264_idct_add8_neon;
>      c->h264_idct8_add       = ff_h264_idct8_add_neon;
>      c->h264_idct8_dc_add    = ff_h264_idct8_dc_add_neon;
>      c->h264_idct8_add4      = ff_h264_idct8_add4_neon;
>      }
>  }
>  
> -void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth)
> +void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int 
> chroma_format_idc)
>  {
> -    if (HAVE_NEON) ff_h264dsp_init_neon(c, bit_depth);
> +    if (HAVE_NEON) ff_h264dsp_init_neon(c, bit_depth, chroma_format_idc);
>  }
> diff --git a/libavcodec/arm/h264pred_init_arm.c 
> b/libavcodec/arm/h264pred_init_arm.c
> index e96f339..5fc07bc 100644
> --- a/libavcodec/arm/h264pred_init_arm.c
> +++ b/libavcodec/arm/h264pred_init_arm.c
> @@ -42,7 +42,7 @@ void ff_pred8x8_0lt_dc_neon(uint8_t *src, int stride);
>  void ff_pred8x8_l00_dc_neon(uint8_t *src, int stride);
>  void ff_pred8x8_0l0_dc_neon(uint8_t *src, int stride);
>  
> -static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const 
> int bit_depth)
> +static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const 
> int bit_depth, const int chroma_format_idc)
>  {
>      const int high_depth = bit_depth > 8;
>  
> @@ -74,7 +74,7 @@ static void ff_h264_pred_init_neon(H264PredContext *h, int 
> codec_id, const int b
>          h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_neon;
>  }
>  
> -void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth)
> +void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth, 
> const int chroma_format_idc)
>  {
> -    if (HAVE_NEON)    ff_h264_pred_init_neon(h, codec_id, bit_depth);
> +    if (HAVE_NEON)    ff_h264_pred_init_neon(h, codec_id, bit_depth, 
> chroma_format_idc);
>  }
> diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
> index bef2cdd..acb2041 100644
> --- a/libavcodec/dsputil.h
> +++ b/libavcodec/dsputil.h
> @@ -63,8 +63,10 @@ void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, 
> DCTELEM *block, int strid
>  void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int 
> *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
>  void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int 
> *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
>  void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int 
> *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
> +void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int 
> *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
>  void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int 
> *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
>  void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(DCTELEM *output, DCTELEM 
> *input, int qmul);\
> +void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int 
> qmul);\
>  void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int 
> qmul);
>  
>  H264_IDCT( 8)
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index 1faaaa6..d78ec7d 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -942,7 +942,7 @@ static void clone_tables(H264Context *dst, H264Context 
> *src, int i){
>      dst->list_counts              = src->list_counts;
>  
>      dst->s.obmc_scratchpad = NULL;
> -    ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma);
> +    ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma, 
> src->sps.chroma_format_idc);
>  }
>  
>  /**
> @@ -970,8 +970,8 @@ static av_cold void common_init(H264Context *h){
>      s->height = s->avctx->height;
>      s->codec_id= s->avctx->codec->id;
>  
> -    ff_h264dsp_init(&h->h264dsp, 8);
> -    ff_h264_pred_init(&h->hpc, s->codec_id, 8);
> +    ff_h264dsp_init(&h->h264dsp, 8, 1);
> +    ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
>  
>      h->dequant_coeff_pps= -1;
>      s->unrestricted_mv=1;
> @@ -1432,11 +1432,16 @@ static void decode_postinit(H264Context *h, int 
> setup_finished){
>          ff_thread_finish_setup(s->avctx);
>  }
>  
> -static av_always_inline void backup_mb_border(H264Context *h, uint8_t 
> *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int 
> chroma444, int simple){
> +static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
> +                                              uint8_t *src_cb, uint8_t 
> *src_cr,
> +                                              int linesize, int uvlinesize, 
> int simple)
> +{
>      MpegEncContext * const s = &h->s;
>      uint8_t *top_border;
>      int top_idx = 1;
>      const int pixel_shift = h->pixel_shift;
> +    int chroma444 = CHROMA444;
> +    int chroma422 = CHROMA422;
>  
>      src_y  -=   linesize;
>      src_cb -= uvlinesize;
> @@ -1460,6 +1465,14 @@ static av_always_inline void 
> backup_mb_border(H264Context *h, uint8_t *src_y, ui
>                              AV_COPY128(top_border+16, src_cb + 
> 15*uvlinesize);
>                              AV_COPY128(top_border+32, src_cr + 
> 15*uvlinesize);
>                          }
> +                    } else if(chroma422) {
> +                        if (pixel_shift) {
> +                            AV_COPY128(top_border+32, src_cb + 
> 15*uvlinesize);
> +                            AV_COPY128(top_border+48, src_cr + 
> 15*uvlinesize);
> +                        } else {
> +                            AV_COPY64(top_border+16, src_cb +  
> 15*uvlinesize);
> +                            AV_COPY64(top_border+24, src_cr +  
> 15*uvlinesize);
> +                        }
>                      } else {
>                          if (pixel_shift) {
>                              AV_COPY128(top_border+32, src_cb+7*uvlinesize);
> @@ -1495,6 +1508,14 @@ static av_always_inline void 
> backup_mb_border(H264Context *h, uint8_t *src_y, ui
>                  AV_COPY128(top_border+16, src_cb + 16*linesize);
>                  AV_COPY128(top_border+32, src_cr + 16*linesize);
>              }
> +        } else if(chroma422) {
> +            if (pixel_shift) {
> +                AV_COPY128(top_border+32, src_cb+16*uvlinesize);
> +                AV_COPY128(top_border+48, src_cr+16*uvlinesize);
> +            } else {
> +                AV_COPY64(top_border+16, src_cb+16*uvlinesize);
> +                AV_COPY64(top_border+24, src_cr+16*uvlinesize);
> +            }
>          } else {
>              if (pixel_shift) {
>                  AV_COPY128(top_border+32, src_cb+8*uvlinesize);
> @@ -1773,10 +1794,11 @@ static av_always_inline void 
> hl_decode_mb_internal(H264Context *h, int simple, i
>      /* is_h264 should always be true if SVQ3 is disabled. */
>      const int is_h264 = !CONFIG_SVQ3_DECODER || simple || s->codec_id == 
> CODEC_ID_H264;
>      void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
> +    const int block_h = 16 >> s->chroma_y_shift;
>  
>      dest_y  = s->current_picture.f.data[0] + ((mb_x << pixel_shift) + mb_y * 
> s->linesize  ) * 16;
> -    dest_cb = s->current_picture.f.data[1] + ((mb_x << pixel_shift) + mb_y * 
> s->uvlinesize) *  8;
> -    dest_cr = s->current_picture.f.data[2] + ((mb_x << pixel_shift) + mb_y * 
> s->uvlinesize) *  8;
> +    dest_cb = s->current_picture.f.data[1] + (mb_x << pixel_shift)*8 + mb_y 
> * s->uvlinesize * block_h;
> +    dest_cr = s->current_picture.f.data[2] + (mb_x << pixel_shift)*8 + mb_y 
> * s->uvlinesize * block_h;
>  
>      s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + (64 << 
> pixel_shift), s->linesize, 4);
>      s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + (64 << 
> pixel_shift), dest_cr - dest_cb, 2);
> @@ -1789,8 +1811,8 @@ static av_always_inline void 
> hl_decode_mb_internal(H264Context *h, int simple, i
>          block_offset = &h->block_offset[48];
>          if(mb_y&1){ //FIXME move out of this function?
>              dest_y -= s->linesize*15;
> -            dest_cb-= s->uvlinesize*7;
> -            dest_cr-= s->uvlinesize*7;
> +            dest_cb-= s->uvlinesize * (block_h - 1);
> +            dest_cr-= s->uvlinesize * (block_h - 1);
>          }
>          if(FRAME_MBAFF) {
>              int list;
> @@ -1842,12 +1864,12 @@ static av_always_inline void 
> hl_decode_mb_internal(H264Context *h, int simple, i
>                          }
>                      }
>                  } else {
> -                    for (i = 0; i < 8; i++) {
> +                    for (i = 0; i < block_h; i++) {
>                          uint16_t *tmp_cb = (uint16_t*)(dest_cb + 
> i*uvlinesize);
>                          for (j = 0; j < 8; j++)
>                              tmp_cb[j] = get_bits(&gb, bit_depth);
>                      }
> -                    for (i = 0; i < 8; i++) {
> +                    for (i = 0; i < block_h; i++) {
>                          uint16_t *tmp_cr = (uint16_t*)(dest_cr + 
> i*uvlinesize);
>                          for (j = 0; j < 8; j++)
>                              tmp_cr[j] = get_bits(&gb, bit_depth);
> @@ -1865,7 +1887,7 @@ static av_always_inline void 
> hl_decode_mb_internal(H264Context *h, int simple, i
>                          memset(dest_cr + i*uvlinesize, 128, 8);
>                      }
>                  } else {
> -                    for (i = 0; i < 8; i++) {
> +                    for (i = 0; i < block_h; i++) {
>                          memcpy(dest_cb + i*uvlinesize, h->mb + 128 + i*4,  
> 8);
>                          memcpy(dest_cr + i*uvlinesize, h->mb + 160 + i*4,  
> 8);
>                      }
> @@ -1913,10 +1935,18 @@ static av_always_inline void 
> hl_decode_mb_internal(H264Context *h, int simple, i
>                  }
>              }else{
>                  if(is_h264){
> +                    int qp[2];
> +                    if (CHROMA422) {
> +                        qp[0] = h->chroma_qp[0] + 3;
> +                        qp[1] = h->chroma_qp[1] + 3;
> +                    } else {
> +                        qp[0] = h->chroma_qp[0];
> +                        qp[1] = h->chroma_qp[1];
> +                    }
>                      if(h->non_zero_count_cache[ 
> scan8[CHROMA_DC_BLOCK_INDEX+0] ])
> -                        h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 
> (16*16*1 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 
> 1:4][h->chroma_qp[0]][0]);
> +                        h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 
> (16*16*1 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 
> 1:4][qp[0]][0]);
>                      if(h->non_zero_count_cache[ 
> scan8[CHROMA_DC_BLOCK_INDEX+1] ])
> -                        h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 
> (16*16*2 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 
> 2:5][h->chroma_qp[1]][0]);
> +                        h->h264dsp.h264_chroma_dc_dequant_idct(h->mb + 
> (16*16*2 << pixel_shift), h->dequant4_coeff[IS_INTRA(mb_type) ? 
> 2:5][qp[1]][0]);
>                      h->h264dsp.h264_idct_add8(dest, block_offset,
>                                                h->mb, uvlinesize,
>                                                h->non_zero_count_cache);
> @@ -2555,11 +2585,13 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0){
>  
>      h->b_stride=  s->mb_width*4;
>  
> +    s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
> +
>      s->width = 16*s->mb_width - (2>>CHROMA444)*FFMIN(h->sps.crop_right, 
> (8<<CHROMA444)-1);
>      if(h->sps.frame_mbs_only_flag)
> -        s->height= 16*s->mb_height - 
> (2>>CHROMA444)*FFMIN(h->sps.crop_bottom, (8<<CHROMA444)-1);
> +        s->height= 16*s->mb_height - 
> (1<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
>      else
> -        s->height= 16*s->mb_height - 
> (4>>CHROMA444)*FFMIN(h->sps.crop_bottom, (8<<CHROMA444)-1);
> +        s->height= 16*s->mb_height - 
> (2<<s->chroma_y_shift)*FFMIN(h->sps.crop_bottom, (16>>s->chroma_y_shift)-1);
>  
>      if (s->context_initialized
>          && (   s->width != s->avctx->width || s->height != s->avctx->height
> @@ -2601,14 +2633,24 @@ static int decode_slice_header(H264Context *h, 
> H264Context *h0){
>  
>          switch (h->sps.bit_depth_luma) {
>              case 9 :
> -                s->avctx->pix_fmt = CHROMA444 ? PIX_FMT_YUV444P9 : 
> PIX_FMT_YUV420P9;
> +                if (CHROMA444)
> +                    s->avctx->pix_fmt = PIX_FMT_YUV444P9;
> +                else
> +                    s->avctx->pix_fmt = PIX_FMT_YUV420P9;

Is there no 422 possible here?
Also why some SIMD funcs (like IDCT and pred) are enabled only for
chroma_idc=1 ?
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to