summaryrefslogtreecommitdiff
path: root/libavcodec/h264_cabac.c
diff options
context:
space:
mode:
authorOskar Arvidsson <oskar@irock.se>2011-03-29 17:48:57 +0200
committerRonald S. Bultje <rsbultje@gmail.com>2011-05-10 07:24:33 -0400
commit6e3ef511d787ff632547059f8730396ff4498e70 (patch)
treebda396b13aaa01e8dccbd60d697a543eff7643db /libavcodec/h264_cabac.c
parent44ca80df3445a59bc065924d8c6110fa10367d01 (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.c105
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 {