[FFmpeg-cvslog] r26337 - in trunk/libavcodec: h264.c h264.h h264_cabac.c h264_cavlc.c
darkshikari
subversion
Fri Jan 14 22:36:17 CET 2011
Author: darkshikari
Date: Fri Jan 14 22:36:16 2011
New Revision: 26337
Log:
H.264: switch to x264-style tracking of luma/chroma DC NNZ
Useful so that we don't have to run the hierarchical DC iDCT if there aren't
any coefficients. Opens up some future opportunities for optimization as well.
Modified:
trunk/libavcodec/h264.c
trunk/libavcodec/h264.h
trunk/libavcodec/h264_cabac.c
trunk/libavcodec/h264_cavlc.c
Modified: trunk/libavcodec/h264.c
==============================================================================
--- trunk/libavcodec/h264.c Fri Jan 14 22:34:25 2011 (r26336)
+++ trunk/libavcodec/h264.c Fri Jan 14 22:36:16 2011 (r26337)
@@ -1203,6 +1203,7 @@ static av_always_inline void hl_decode_m
}
}else{
h->hpc.pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);
+ if(h->non_zero_count_cache[ scan8[LUMA_DC_BLOCK_INDEX] ]){
if(is_h264){
if(!transform_bypass)
h->h264dsp.h264_luma_dc_dequant_idct(h->mb, h->mb_luma_dc, h->dequant4_coeff[0][s->qscale][0]);
@@ -1214,6 +1215,7 @@ static av_always_inline void hl_decode_m
}
}else
ff_svq3_luma_dc_dequant_idct_c(h->mb, h->mb_luma_dc, s->qscale);
+ }
}
if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple);
@@ -1281,8 +1283,10 @@ static av_always_inline void hl_decode_m
}
}
}else{
- chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);
- chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);
+ if(h->non_zero_count_cache[ scan8[CHROMA_DC_BLOCK_INDEX+0] ])
+ chroma_dc_dequant_idct_c(h->mb + 16*16 , h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);
+ if(h->non_zero_count_cache[ scan8[CHROMA_DC_BLOCK_INDEX+1] ])
+ chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);
if(is_h264){
h->h264dsp.h264_idct_add8(dest, block_offset,
h->mb, uvlinesize,
Modified: trunk/libavcodec/h264.h
==============================================================================
--- trunk/libavcodec/h264.h Fri Jan 14 22:34:25 2011 (r26336)
+++ trunk/libavcodec/h264.h Fri Jan 14 22:36:16 2011 (r26337)
@@ -39,8 +39,8 @@
#define interlaced_dct interlaced_dct_is_a_bad_name
#define mb_intra mb_intra_is_not_initialized_see_mb_type
-#define LUMA_DC_BLOCK_INDEX 25
-#define CHROMA_DC_BLOCK_INDEX 26
+#define LUMA_DC_BLOCK_INDEX 24
+#define CHROMA_DC_BLOCK_INDEX 25
#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
#define COEFF_TOKEN_VLC_BITS 8
@@ -722,8 +722,20 @@ o-o o-o
/ / /
o-o o-o
*/
+
+/* Scan8 organization:
+ * 0 1 2 3 4 5 6 7
+ * 0 u u y y y y y
+ * 1 u U U y Y Y Y Y
+ * 2 u U U y Y Y Y Y
+ * 3 v v y Y Y Y Y
+ * 4 v V V y Y Y Y Y
+ * 5 v V V DYDUDV
+ * DY/DU/DV are for luma/chroma DC.
+ */
+
//This table must be here because scan8[constant] must be known at compiletime
-static const uint8_t scan8[16 + 2*4]={
+static const uint8_t scan8[16 + 2*4 + 3]={
4+1*8, 5+1*8, 4+2*8, 5+2*8,
6+1*8, 7+1*8, 6+2*8, 7+2*8,
4+3*8, 5+3*8, 4+4*8, 5+4*8,
@@ -732,6 +744,7 @@ static const uint8_t scan8[16 + 2*4]={
1+2*8, 2+2*8,
1+4*8, 2+4*8,
1+5*8, 2+5*8,
+ 4+5*8, 5+5*8, 6+5*8
};
static av_always_inline uint32_t pack16to32(int a, int b){
Modified: trunk/libavcodec/h264_cabac.c
==============================================================================
--- trunk/libavcodec/h264_cabac.c Fri Jan 14 22:34:25 2011 (r26336)
+++ trunk/libavcodec/h264_cabac.c Fri Jan 14 22:36:16 2011 (r26337)
@@ -965,6 +965,7 @@ static av_always_inline int get_cabac_cb
nza = h->left_cbp&0x100;
nzb = h-> top_cbp&0x100;
} else {
+ idx -= CHROMA_DC_BLOCK_INDEX;
nza = (h->left_cbp>>(6+idx))&0x01;
nzb = (h-> top_cbp>>(6+idx))&0x01;
}
@@ -1060,8 +1061,7 @@ static av_always_inline void decode_caba
/* read coded block flag */
if( is_dc || cat != 5 ) {
if( get_cabac( CC, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n, is_dc ) ] ) == 0 ) {
- if( !is_dc )
- h->non_zero_count_cache[scan8[n]] = 0;
+ h->non_zero_count_cache[scan8[n]] = 0;
#ifdef CABAC_ON_STACK
h->cabac.range = cc.range ;
@@ -1112,7 +1112,8 @@ static av_always_inline void decode_caba
if( cat == 0 )
h->cbp_table[h->mb_xy] |= 0x100;
else
- h->cbp_table[h->mb_xy] |= 0x40 << n;
+ h->cbp_table[h->mb_xy] |= 0x40 << (n - CHROMA_DC_BLOCK_INDEX);
+ h->non_zero_count_cache[scan8[n]] = coeff_count;
} else {
if( cat == 5 )
fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
@@ -1642,7 +1643,7 @@ 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);
- decode_cabac_residual_dc( h, h->mb_luma_dc, 0, 0, scan, 16);
+ 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];
@@ -1681,7 +1682,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, c, chroma_dc_scan, 4);
+ decode_cabac_residual_dc(h, h->mb + 256 + 16*4*c, 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4);
}
}
Modified: trunk/libavcodec/h264_cavlc.c
==============================================================================
--- trunk/libavcodec/h264_cavlc.c Fri Jan 14 22:34:25 2011 (r26336)
+++ trunk/libavcodec/h264_cavlc.c Fri Jan 14 22:36:16 2011 (r26337)
@@ -371,7 +371,7 @@ static int decode_residual(H264Context *
//FIXME put trailing_onex into the context
- if(n == CHROMA_DC_BLOCK_INDEX){
+ if(n >= CHROMA_DC_BLOCK_INDEX){
coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
total_coeff= coeff_token>>2;
}else{
@@ -383,9 +383,9 @@ static int decode_residual(H264Context *
total_coeff= pred_non_zero_count(h, n);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2;
- h->non_zero_count_cache[ scan8[n] ]= total_coeff;
}
}
+ h->non_zero_count_cache[ scan8[n] ]= total_coeff;
//FIXME set last_non_zero?
@@ -482,14 +482,14 @@ static int decode_residual(H264Context *
if(total_coeff == max_coeff)
zeros_left=0;
else{
- if(n == CHROMA_DC_BLOCK_INDEX)
+ if(n >= CHROMA_DC_BLOCK_INDEX)
zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
else
zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
}
scantable += zeros_left + total_coeff - 1;
- if(n > 24){
+ if(n >= LUMA_DC_BLOCK_INDEX){
block[*scantable] = level[0];
for(i=1;i<total_coeff && zeros_left > 0;i++) {
if(zeros_left < 7)
@@ -988,7 +988,7 @@ decode_intra_mb:
if(cbp&0x30){
for(chroma_idx=0; chroma_idx<2; chroma_idx++)
- if( decode_residual(h, gb, h->mb + 256 + 16*4*chroma_idx, CHROMA_DC_BLOCK_INDEX, chroma_dc_scan, NULL, 4) < 0){
+ if( decode_residual(h, gb, h->mb + 256 + 16*4*chroma_idx, CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
return -1;
}
}
More information about the ffmpeg-cvslog
mailing list