www.pudn.com > T264-src-0.02.zip > cavlc.c


/***************************************************************************** 
 * 
 *  T264 AVC CODEC 
 * 
 *  Copyright(C) 2004-2005 llcc  
 *               2004-2005 visionany  
 * 
 *  This program is free software ; you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation ; either version 2 of the License, or 
 *  (at your option) any later version. 
 * 
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY ; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details. 
 * 
 *  You should have received a copy of the GNU General Public License 
 *  along with this program ; if not, write to the Free Software 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
 * 
 ****************************************************************************/ 
 
 /***************************************************************************** 
 * cavlc.c: from x 264 
 *****************************************************************************/ 
 
 
//#include  
//#include  
//#include  
 
#include  
 
#include "t264.h" 
#include "vlc.h" 
#include "bitstream.h" 
#include "inter.h" 
 
static const uint8_t intra4x4_cbp_to_golomb[48]= 
{ 
  3, 29, 30, 17, 31, 18, 37,  8, 32, 38, 19,  9, 20, 10, 11,  2, 
 16, 33, 34, 21, 35, 22, 39,  4, 36, 40, 23,  5, 24,  6,  7,  1, 
 41, 42, 43, 25, 44, 26, 46, 12, 45, 47, 27, 13, 28, 14, 15,  0 
}; 
static const uint8_t inter_cbp_to_golomb[48]= 
{ 
  0,  2,  3,  7,  4,  8, 17, 13,  5, 18,  9, 14, 10, 15, 16, 11, 
  1, 32, 33, 36, 34, 37, 44, 40, 35, 45, 38, 41, 39, 42, 43, 19, 
  6, 24, 25, 20, 26, 21, 46, 28, 27, 47, 22, 29, 23, 30, 31, 12 
}; 
 
/* 
static const uint8_t block_idx_x[16] = 
{ 
    0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3 
}; 
static const uint8_t block_idx_y[16] = 
{ 
    0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 
}; 
static const uint8_t block_idx_xy[4][4] = 
{ 
    { 0, 2, 8,  10}, 
    { 1, 3, 9,  11}, 
    { 4, 6, 12, 14}, 
    { 5, 7, 13, 15} 
}; 
*/ 
 
 
#define BLOCK_INDEX_CHROMA_DC   (-1) 
#define BLOCK_INDEX_LUMA_DC     (-2) 
 
static __inline void eg_write_vlc(bs_t* bs, vlc_t v) 
{ 
	eg_write_direct(bs, v.i_bits & ((uint32_t)~0 >> (uint32_t)(32 - v.i_size)), v.i_size); 
} 
 
int8_t 
T264_mb_predict_intra4x4_mode(T264_t *t, int32_t idx) 
{ 
	int32_t x, y; 
	int8_t nA, nB, pred_blk; 
 
    x = luma_inverse_x[idx]; 
    y = luma_inverse_y[idx]; 
 
    nA = t->mb.i4x4_pred_mode_ref[IPM_LUMA + x + y * 8 - 1]; 
    nB = t->mb.i4x4_pred_mode_ref[IPM_LUMA + x + y * 8 - 8]; 
	 
    pred_blk  = T264_MIN(nA, nB); 
 
    if( pred_blk < 0 ) 
        return Intra_4x4_DC; 
 
    return pred_blk;	 
} 
 
uint8_t  
T264_mb_predict_non_zero_code(T264_t* t, int idx) 
{	 
    int32_t x, y; 
    int32_t nA, nB; 
	int16_t pred_blk; 
 
	if(idx >= 0 && idx < 16) 
	{ 
        x = luma_inverse_x[idx]; 
        y = luma_inverse_y[idx]; 
        nA = t->mb.nnz_ref[NNZ_LUMA + x + y * 8 - 1]; 
        nB = t->mb.nnz_ref[NNZ_LUMA + x + y * 8 - 8]; 
	} 
	else if(idx < 20) 
	{ 
		y = (idx - 16) / 2; 
		x = (idx - 16) % 2; 
        nA = t->mb.nnz_ref[NNZ_CHROMA0 + x + y * 8 - 1]; 
        nB = t->mb.nnz_ref[NNZ_CHROMA0 + x + y * 8 - 8]; 
	} 
	else if(idx < 24) 
	{ 
        y = (idx - 20) / 2; 
        x = (idx - 20) % 2; 
        nA = t->mb.nnz_ref[NNZ_CHROMA1 + x + y * 8 - 1]; 
        nB = t->mb.nnz_ref[NNZ_CHROMA1 + x + y * 8 - 8]; 
	} 
	 
    pred_blk = nA + nB; 
 
    if( pred_blk < 0x80 ) 
    { 
        pred_blk = ( pred_blk + 1 ) >> 1; 
    } 
    return pred_blk & 0x7f; 
} 
 
/**************************************************************************** 
 * block_residual_write_cavlc 
 ****************************************************************************/ 
static void block_residual_write_cavlc( T264_t *h, int32_t i_idx, int16_t *l, int32_t i_count ) 
{ 
    int level[16], run[16]; 
    int i_total, i_trailing; 
    int i_total_zero; 
    int i_last; 
    unsigned int i_sign; 
 
    int i; 
    int i_zero_left; 
    int i_suffix_length; 
 
    /* first find i_last */ 
    i_last = i_count - 1; 
    while( i_last >= 0 && l[i_last] == 0 ) 
    { 
        i_last--; 
    } 
 
    i_sign = 0; 
    i_total = 0; 
    i_trailing = 0; 
    i_total_zero = 0; 
 
    if( i_last >= 0 ) 
    { 
        int b_trailing = 1; 
        int idx = 0; 
 
        /* level and run and total */ 
        while( i_last >= 0 ) 
        { 
            level[idx] = l[i_last--]; 
 
            run[idx] = 0; 
            while( i_last >= 0 && l[i_last] == 0 ) 
            { 
                run[idx]++; 
                i_last--; 
            } 
 
            i_total++; 
            i_total_zero += run[idx]; 
 
            if( b_trailing && ABS( level[idx] ) == 1 && i_trailing < 3 ) 
            { 
                i_sign <<= 1; 
                if( level[idx] < 0 ) 
                { 
                    i_sign |= 0x01; 
                } 
 
                i_trailing++; 
            } 
            else 
            { 
                b_trailing = 0; 
            } 
 
            idx++; 
        } 
    } 
 
    /* total/trailing represented by Coeff_token (5 tables)*/ 
    if( i_idx == BLOCK_INDEX_CHROMA_DC ) 
    { 
		eg_write_vlc(&h->bs, x264_coeff_token[4][i_total*4+i_trailing]); 
    } 
    else 
    { 
        /* T264_mb_predict_non_zero_code return 0 <-> (16+16+1)>>1 = 16 */ 
        static const int ct_index[17] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3 }; 
        int nC = 0; 
 
        if( i_idx == BLOCK_INDEX_LUMA_DC ) 
        { 
			// predict nC = (nA + nB) / 2; 
            nC = T264_mb_predict_non_zero_code(h, 0); 
        } 
        else 
        { 
			// predict nC = (nA + nB) / 2; 
            nC = T264_mb_predict_non_zero_code(h, i_idx); 
        } 
 
		eg_write_vlc(&h->bs, x264_coeff_token[ct_index[nC]][i_total*4+i_trailing]); 
    } 
 
    if( i_total <= 0 ) 
    { 
        return; 
    } 
 
	//encoding trailing '1's (max = 3) 
    i_suffix_length = i_total > 10 && i_trailing < 3 ? 1 : 0; 
    if( i_trailing > 0 ) 
    { 
		eg_write_direct(&h->bs, i_sign & ((uint32_t)~0 >> (uint32_t)(32 - i_trailing)), i_trailing); 
    } 
 
	//encoding remain levels of non-zero coefficients (prefix + suffix) 
    for( i = i_trailing; i < i_total; i++ ) 
    { 
        int i_level_code; 
 
        /* calculate level code */ 
        if( level[i] < 0 ) 
        { 
            i_level_code = -2*level[i] - 1; 
        } 
        else /* if( level[i] > 0 ) */ 
        { 
            i_level_code = 2 * level[i] - 2; 
        } 
        if( i == i_trailing && i_trailing < 3 ) 
        { 
            i_level_code -=2; /* as level[i] can't be 1 for the first one if i_trailing < 3 */ 
        } 
 
        if( ( i_level_code >> i_suffix_length ) < 14 ) 
        { 
            eg_write_vlc(&h->bs, x264_level_prefix[i_level_code >> i_suffix_length]); 
            if( i_suffix_length > 0 ) 
            { 
				eg_write_direct(&h->bs, (uint32_t)i_level_code & ((uint32_t)~0 >> (uint32_t)(32 - i_suffix_length)), i_suffix_length); 
            } 
        } 
        else if( i_suffix_length == 0 && i_level_code < 30 ) 
        { 
            eg_write_vlc(&h->bs, x264_level_prefix[14]); 
            eg_write_direct(&h->bs, (i_level_code - 14) & ((uint32_t)~0 >> (uint32_t)(32 - 4)), 4); 
        } 
        else if( i_suffix_length > 0 && ( i_level_code >> i_suffix_length ) == 14 ) 
        { 
            eg_write_vlc(&h->bs, x264_level_prefix[14]); 
            eg_write_direct(&h->bs, i_level_code & ((uint32_t)~0 >> (uint32_t)(32 - i_suffix_length)), i_suffix_length); 
        } 
        else 
        { 
            eg_write_vlc(&h->bs, x264_level_prefix[15]); 
            i_level_code -= 15 << i_suffix_length; 
            if( i_suffix_length == 0 ) 
            { 
                i_level_code -= 15; 
            } 
 
            if( i_level_code >= ( 1 << 12 ) || i_level_code < 0 ) 
            { 
                fprintf( stderr, "OVERFLOW levelcode=%d\n", i_level_code ); 
            } 
 
			eg_write_direct(&h->bs, i_level_code & ((uint32_t)~0 >> (uint32_t)(32 - 12)), 12); 
        } 
 
        if( i_suffix_length == 0 ) 
        { 
            i_suffix_length++; 
        } 
        if( ABS( level[i] ) > ( 3 << ( i_suffix_length - 1 ) ) && i_suffix_length < 6 ) 
        { 
            i_suffix_length++; 
        } 
    } 
 
	//encode total zeros [i_total-1][i_total_zero] 
    if( i_total < i_count ) 
    { 
        if( i_idx == BLOCK_INDEX_CHROMA_DC ) 
        { 
            eg_write_vlc(&h->bs, x264_total_zeros_dc[i_total-1][i_total_zero]); 
        } 
        else 
        { 
            eg_write_vlc(&h->bs, x264_total_zeros[i_total-1][i_total_zero]); 
        } 
    } 
 
	//encode each run of zeros 
    for( i = 0, i_zero_left = i_total_zero; i < i_total - 1; i++ ) 
    { 
        int i_zl; 
 
        if( i_zero_left <= 0 ) 
        { 
            break; 
        } 
 
        i_zl = T264_MIN( i_zero_left - 1, 6 ); 
 
		eg_write_vlc(&h->bs, x264_run_before[i_zl][run[i]]); 
 
        i_zero_left -= run[i]; 
    } 
} 
 
void  
T264_macroblock_write_cavlc(T264_t *t) 
{ 
    int32_t mb_mode = t->mb.mb_mode; 
    int32_t i; 
    int32_t offset; 
 
    if (t->slice_type == SLICE_I) 
    { 
        offset = 0; 
    } 
    else if (t->slice_type == SLICE_P) 
    { 
        offset = 5; 
    } 
    else if (t->slice_type == SLICE_B) 
    { 
        offset = 23; 
    } 
 
    if(t->slice_type != SLICE_I) 
    { 
        eg_write_ue(&t->bs, t->skip);  /* skip run */ 
        t->skip = 0; 
    } 
 
    if (mb_mode == I_4x4) 
    { 
        // mb_type 
        eg_write_ue(&t->bs, offset + 0); 
        /* Prediction: Luma */ 
        for (i = 0 ; i < 16; i ++) /* i : Inverse raster scan */ 
        { 
            int8_t pred = T264_mb_predict_intra4x4_mode(t, i); 
            int8_t mode = t->mb.mode_i4x4[i]; 
 
            if( pred == mode) 
            { 
                eg_write_direct1(&t->bs, 1);	/* b_prev_intra4x4_pred_mode */ 
            } 
            else 
            { 
                eg_write_direct1(&t->bs, 0);	/* b_prev_intra4x4_pred_mode */ 
                if( mode < pred ) 
                { 
                    eg_write_direct(&t->bs, mode, 3);  /* rem_intra4x4_pred_mode */ 
                } 
                else 
                { 
                    eg_write_direct(&t->bs, mode - 1, 3);  /* rem_intra4x4_pred_mode */ 
                } 
            } 
        } 
        //intra_chroma_pred_mode 
        eg_write_ue(&t->bs, t->mb.mb_mode_uv); 
 
        // coded_block_pattern 
        eg_write_ue(&t->bs, intra4x4_cbp_to_golomb[( t->mb.cbp_c << 4 ) | t->mb.cbp_y]); 
 
        //delta_qp 
        if (t->mb.cbp_y > 0 || t->mb.cbp_c > 0) 
        { 
            eg_write_se(&t->bs, t->mb.mb_qp_delta);	/* 0 = no change on qp */ 
 
            for (i = 0; i < 16 ; i ++) 
            { 
                if(t->mb.cbp_y & (1 << ( i / 4 ))) 
                { 
                    block_residual_write_cavlc(t, i, t->mb.dct_y_z[i], 16); 
                } 
            } 
        } 
    } 
    else if (mb_mode == I_16x16) 
    { 
        // mb_type 
        eg_write_ue(&t->bs, offset + 1 + t->mb.mode_i16x16 +  
            t->mb.cbp_c * 4 + (t->mb.cbp_y == 0 ? 0 : 12)); 
        // intra chroma pred mode 
        eg_write_ue(&t->bs, t->mb.mb_mode_uv); 
 
        // delta qp 
        eg_write_se(&t->bs, t->mb.mb_qp_delta); 
 
        // dc luma 
        block_residual_write_cavlc(t, BLOCK_INDEX_LUMA_DC, t->mb.dc4x4_z, 16); 
 
        if (t->mb.cbp_y != 0) 
        { 
            for(i = 0 ; i < 16 ; i ++) 
            { 
                if (t->mb.cbp_y & (1 << (i / 4))) 
                { 
                    block_residual_write_cavlc(t, i, &(t->mb.dct_y_z[i][1]), 15); 
                } 
            } 
        } 
    } 
    else if (mb_mode == P_L0) 
    { 
        T264_vector_t vec; 
        switch (t->mb.mb_part)  
        { 
        case MB_16x16: 
            eg_write_ue(&t->bs, MB_16x16); 
            if (t->ps.num_ref_idx_l0_active_minus1 > 0) 
            { 
                eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][0].refno); 
            } 
            vec = t->mb.vec[0][0]; 
            T264_predict_mv(t, 0, 0, 4, &vec); 
            eg_write_se(&t->bs, t->mb.vec[0][0].x - vec.x); 
            eg_write_se(&t->bs, t->mb.vec[0][0].y - vec.y); 
        	break; 
        case MB_16x8: 
            eg_write_ue(&t->bs, MB_16x8); 
            if (t->ps.num_ref_idx_l0_active_minus1 > 0) 
            { 
                eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][0].refno); 
                eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][8].refno); 
            } 
            vec = t->mb.vec[0][0]; 
            T264_predict_mv(t, 0, 0, 4, &vec); 
            eg_write_se(&t->bs, t->mb.vec[0][0].x - vec.x); 
            eg_write_se(&t->bs, t->mb.vec[0][0].y - vec.y); 
 
            vec = t->mb.vec[0][8]; 
            T264_predict_mv(t, 0, 8, 4, &vec); 
            eg_write_se(&t->bs, t->mb.vec[0][8].x - vec.x); 
            eg_write_se(&t->bs, t->mb.vec[0][8].y - vec.y); 
        	break; 
        case MB_8x16: 
            eg_write_ue(&t->bs, MB_8x16); 
            if (t->ps.num_ref_idx_l0_active_minus1 > 0) 
            { 
                eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][0].refno); 
                eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][luma_index[4]].refno); 
            } 
            vec = t->mb.vec[0][0]; 
            T264_predict_mv(t, 0, 0, 2, &vec); 
            eg_write_se(&t->bs, t->mb.vec[0][0].x - vec.x); 
            eg_write_se(&t->bs, t->mb.vec[0][0].y - vec.y); 
 
            vec = t->mb.vec[0][luma_index[4]]; 
            T264_predict_mv(t, 0, luma_index[4], 2, &vec); 
            eg_write_se(&t->bs, t->mb.vec[0][luma_index[4]].x - vec.x); 
            eg_write_se(&t->bs, t->mb.vec[0][luma_index[4]].y - vec.y); 
            break; 
        case MB_8x8: 
        case MB_8x8ref0: 
            if (t->mb.vec[0][luma_index[0]].refno == 0 && 
                t->mb.vec[0][luma_index[4]].refno == 0 && 
                t->mb.vec[0][luma_index[8]].refno == 0 && 
                t->mb.vec[0][luma_index[12]].refno == 0) 
            { 
                eg_write_ue(&t->bs, MB_8x8ref0); 
                for (i = 0 ; i < 4 ; i ++) 
                { 
                    switch (t->mb.submb_part[luma_index[4 * i]])  
                    { 
                    case MB_8x8: 
                        eg_write_ue(&t->bs, 0); 
                    	break; 
                    case MB_8x4: 
                        eg_write_ue(&t->bs, 1); 
                        break; 
                    case MB_4x8: 
                        eg_write_ue(&t->bs, 2); 
                        break; 
                    case MB_4x4: 
                        eg_write_ue(&t->bs, 3); 
                        break; 
                    default: 
                        break; 
                    } 
                } 
            } 
            else 
            { 
                eg_write_ue(&t->bs, MB_8x8); 
                for (i = 0 ; i < 4 ; i ++) 
                { 
                    switch (t->mb.submb_part[luma_index[4 * i]])  
                    { 
                    case MB_8x8: 
                        eg_write_ue(&t->bs, 0); 
                        break; 
                    case MB_8x4: 
                        eg_write_ue(&t->bs, 1); 
                        break; 
                    case MB_4x8: 
                        eg_write_ue(&t->bs, 2); 
                        break; 
                    case MB_4x4: 
                        eg_write_ue(&t->bs, 3); 
                        break; 
                    default: 
                        break; 
                    } 
                } 
                 
                if (t->ps.num_ref_idx_l0_active_minus1 > 0) 
                { 
                    eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][0].refno); 
                    eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][luma_index[4]].refno); 
                    eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][luma_index[8]].refno); 
                    eg_write_te(&t->bs, t->ps.num_ref_idx_l0_active_minus1, t->mb.vec[0][luma_index[12]].refno); 
                } 
            } 
            for(i = 0 ; i < 4 ; i ++) 
            { 
                switch(t->mb.submb_part[luma_index[4 * i]])  
                { 
                case MB_8x8: 
                    vec = t->mb.vec[0][luma_index[4 * i]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i], 2, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].y - vec.y); 
                	break; 
                case MB_8x4: 
                    vec = t->mb.vec[0][luma_index[4 * i]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i], 2, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].y - vec.y); 
 
                    vec = t->mb.vec[0][luma_index[4 * i + 2]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i + 2], 2, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 2]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 2]].y - vec.y); 
                	break; 
                case MB_4x8: 
                    vec = t->mb.vec[0][luma_index[4 * i]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].y - vec.y); 
 
                    vec = t->mb.vec[0][luma_index[4 * i + 1]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i + 1], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 1]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 1]].y - vec.y); 
                    break; 
                case MB_4x4: 
                    vec = t->mb.vec[0][luma_index[4 * i]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i]].y - vec.y); 
 
                    vec = t->mb.vec[0][luma_index[4 * i + 1]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i + 1], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 1]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 1]].y - vec.y); 
 
                    vec = t->mb.vec[0][luma_index[4 * i + 2]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i + 2], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 2]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 2]].y - vec.y); 
 
                    vec = t->mb.vec[0][luma_index[4 * i + 3]]; 
                    T264_predict_mv(t, 0, luma_index[4 * i + 3], 1, &vec); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 3]].x - vec.x); 
                    eg_write_se(&t->bs, t->mb.vec[0][luma_index[4 * i + 3]].y - vec.y); 
                    break; 
                } 
            } 
            break; 
        default: 
            break; 
        } 
        eg_write_ue(&t->bs, inter_cbp_to_golomb[(t->mb.cbp_c << 4)| t->mb.cbp_y]); 
        //delta_qp 
        if (t->mb.cbp_y > 0 || t->mb.cbp_c > 0) 
        { 
            eg_write_se(&t->bs, t->mb.mb_qp_delta);	/* 0 = no change on qp */ 
 
            for (i = 0; i < 16 ; i ++) 
            { 
                if(t->mb.cbp_y & (1 << ( i / 4 ))) 
                { 
                    block_residual_write_cavlc(t, i, t->mb.dct_y_z[i], 16); 
                } 
            } 
        } 
    } 
 
    if (t->mb.cbp_c != 0) 
    { 
        block_residual_write_cavlc(t, BLOCK_INDEX_CHROMA_DC, t->mb.dc2x2_z[0], 4); 
        block_residual_write_cavlc(t, BLOCK_INDEX_CHROMA_DC, t->mb.dc2x2_z[1], 4); 
        if (t->mb.cbp_c & 0x2) 
        { 
            for(i = 0 ; i < 8 ; i ++) 
            { 
                block_residual_write_cavlc(t, 16 + i, &(t->mb.dct_uv_z[i / 4][i % 4][1]), 15); 
            } 
        } 
    } 
}