diff options
author | Oskar Arvidsson <oskar@irock.se> | 2011-03-29 19:48:57 +0400 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2011-05-10 15:24:33 +0400 |
commit | 6e3ef511d787ff632547059f8730396ff4498e70 (patch) | |
tree | bda396b13aaa01e8dccbd60d697a543eff7643db /libavcodec/h264_cabac.c | |
parent | 44ca80df3445a59bc065924d8c6110fa10367d01 (diff) |
Add the notion of pixel size in h264 related functions.
In high bit depth the pixels will not be stored in uint8_t like in the
normal case, but in uint16_t. The pixel size is thus 1 in normal bit
depth and 2 in high bit depth.
Preparatory patch for high bit depth h264 decoding support.
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavcodec/h264_cabac.c')
-rw-r--r-- | libavcodec/h264_cabac.c | 105 |
1 files changed, 58 insertions, 47 deletions
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 25215fabe8..61ad4493f9 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1100,47 +1100,54 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT } } - do { - uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; - - int j= scantable[index[--coeff_count]]; - - if( get_cabac( CC, ctx ) == 0 ) { - node_ctx = coeff_abs_level_transition[0][node_ctx]; - if( is_dc ) { - block[j] = get_cabac_bypass_sign( CC, -1); - }else{ - block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; - } - } else { - int coeff_abs = 2; - ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base; - node_ctx = coeff_abs_level_transition[1][node_ctx]; - - while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { - coeff_abs++; - } - - if( coeff_abs >= 15 ) { - int j = 0; - while( get_cabac_bypass( CC ) ) { - j++; - } - - coeff_abs=1; - while( j-- ) { - coeff_abs += coeff_abs + get_cabac_bypass( CC ); - } - coeff_abs+= 14; - } +#define STORE_BLOCK(type) \ + do { \ + uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \ + \ + int j= scantable[index[--coeff_count]]; \ + \ + if( get_cabac( CC, ctx ) == 0 ) { \ + node_ctx = coeff_abs_level_transition[0][node_ctx]; \ + if( is_dc ) { \ + ((type*)block)[j] = get_cabac_bypass_sign( CC, -1); \ + }else{ \ + ((type*)block)[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; \ + } \ + } else { \ + int coeff_abs = 2; \ + ctx = coeff_abs_levelgt1_ctx[node_ctx] + abs_level_m1_ctx_base; \ + node_ctx = coeff_abs_level_transition[1][node_ctx]; \ +\ + while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { \ + coeff_abs++; \ + } \ +\ + if( coeff_abs >= 15 ) { \ + int j = 0; \ + while( get_cabac_bypass( CC ) ) { \ + j++; \ + } \ +\ + coeff_abs=1; \ + while( j-- ) { \ + coeff_abs += coeff_abs + get_cabac_bypass( CC ); \ + } \ + coeff_abs+= 14; \ + } \ +\ + if( is_dc ) { \ + ((type*)block)[j] = get_cabac_bypass_sign( CC, -coeff_abs ); \ + }else{ \ + ((type*)block)[j] = ((int)(get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32)) >> 6; \ + } \ + } \ + } while ( coeff_count ); - if( is_dc ) { - block[j] = get_cabac_bypass_sign( CC, -coeff_abs ); - }else{ - block[j] = (get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32) >> 6; - } - } - } while( coeff_count ); + if (h->pixel_shift) { + STORE_BLOCK(int32_t) + } else { + STORE_BLOCK(int16_t) + } #ifdef CABAC_ON_STACK h->cabac.range = cc.range ; h->cabac.low = cc.low ; @@ -1196,6 +1203,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) { int mb_xy; int mb_type, partition_count, cbp = 0; int dct8x8_allowed= h->pps.transform_8x8_mode; + const int pixel_shift = h->pixel_shift; mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; @@ -1304,6 +1312,7 @@ decode_intra_mb: h->slice_table[ mb_xy ]= h->slice_num; if(IS_INTRA_PCM(mb_type)) { + const int mb_size = (384*h->sps.bit_depth_luma) >> 3; const uint8_t *ptr; // We assume these blocks are very rare so we do not optimize it. @@ -1316,9 +1325,9 @@ decode_intra_mb: } // The pixels are stored in the same order as levels in h->mb array. - memcpy(h->mb, ptr, 256); ptr+=256; + memcpy(h->mb, ptr, 2*mb_size/3); ptr+=2*mb_size/3; if(CHROMA){ - memcpy(h->mb+128, ptr, 128); ptr+=128; + memcpy(h->mb+mb_size/3, ptr, mb_size/3); ptr+=mb_size/3; } ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); @@ -1652,13 +1661,15 @@ decode_intra_mb: //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" ); AV_ZERO128(h->mb_luma_dc+0); AV_ZERO128(h->mb_luma_dc+8); + AV_ZERO128(h->mb_luma_dc+16); + AV_ZERO128(h->mb_luma_dc+24); decode_cabac_residual_dc( h, h->mb_luma_dc, 0, LUMA_DC_BLOCK_INDEX, scan, 16); if( cbp&15 ) { qmul = h->dequant4_coeff[0][s->qscale]; for( i = 0; i < 16; i++ ) { //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i ); - decode_cabac_residual_nondc(h, h->mb + 16*i, 1, i, scan + 1, qmul, 15); + decode_cabac_residual_nondc(h, h->mb + (16*i << pixel_shift), 1, i, scan + 1, qmul, 15); } } else { fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1); @@ -1668,7 +1679,7 @@ decode_intra_mb: for( i8x8 = 0; i8x8 < 4; i8x8++ ) { if( cbp & (1<<i8x8) ) { if( IS_8x8DCT(mb_type) ) { - decode_cabac_residual_nondc(h, h->mb + 64*i8x8, 5, 4*i8x8, + decode_cabac_residual_nondc(h, h->mb + (64*i8x8 << pixel_shift), 5, 4*i8x8, scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64); } else { qmul = h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale]; @@ -1676,7 +1687,7 @@ decode_intra_mb: const int index = 4*i8x8 + i4x4; //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index ); //START_TIMER - decode_cabac_residual_nondc(h, h->mb + 16*index, 2, index, scan, qmul, 16); + decode_cabac_residual_nondc(h, h->mb + (16*index << pixel_shift), 2, index, scan, qmul, 16); //STOP_TIMER("decode_residual") } } @@ -1691,7 +1702,7 @@ decode_intra_mb: int c; for( c = 0; c < 2; c++ ) { //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c ); - decode_cabac_residual_dc(h, h->mb + 256 + 16*4*c, 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4); + decode_cabac_residual_dc(h, h->mb + ((256 + 16*4*c) << pixel_shift), 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4); } } @@ -1702,7 +1713,7 @@ decode_intra_mb: for( i = 0; i < 4; i++ ) { const int index = 16 + 4 * c + i; //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 ); - decode_cabac_residual_nondc(h, h->mb + 16*index, 4, index, scan + 1, qmul, 15); + decode_cabac_residual_nondc(h, h->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15); } } } else { |