[FFmpeg-devel] scan8[] and 8x8 or 4x4 neighbour information

Habib Nusrat-R80026 R80026
Wed Aug 22 19:37:49 CEST 2007


Hi  Michael Niedermayer
 
Thanks for supporting ffmpeg activities. You guys are doing an excellent
job!! I am trying to under the the code for the CABAC portion. I read
the specs (still reading its so convoluted). Do you have the H.264 code
in visual C++ project.
 
I am having difficulties to understand how the code is computing the 8x8
or 4x4 neighbors information..I would appreciate very much if could
explain how the scan8 is used in get_cabac_cbf_ctx code
static int inline get_cabac_cbf_ctx( H264Context *h, int cat, int idx )
{
    int nza, nzb;
    int ctx = 0;
 
    if( cat == 0 ) {
        nza = h->left_cbp&0x100;
        nzb = h-> top_cbp&0x100;
    } else if( cat == 1 || cat == 2 ) {
        nza = h->non_zero_count_cache[scan8[idx] - 1];
        nzb = h->non_zero_count_cache[scan8[idx] - 8];
    } else if( cat == 3 ) {
        nza = (h->left_cbp>>(6+idx))&0x01;
        nzb = (h-> top_cbp>>(6+idx))&0x01;
    } else {
        assert(cat == 4);
        nza = h->non_zero_count_cache[scan8[16+idx] - 1];
        nzb = h->non_zero_count_cache[scan8[16+idx] - 8];
    }
 
    if( nza > 0 )
        ctx++;
 
    if( nzb > 0 )
        ctx += 2;
 
    return ctx + 4 * cat;
}
 
Also how LumaBlxIdxN is computed in 
 
static int decode_cabac_mb_cbp_luma( H264Context *h) {
    int cbp = 0;
    int cbp_b = -1;
    int i8x8;
 
    if( h->slice_table[h->top_mb_xy] == h->slice_num ) {
        cbp_b = h->top_cbp;
        tprintf("cbp_b = top_cbp = %x\n", cbp_b);
    }
 
    for( i8x8 = 0; i8x8 < 4; i8x8++ ) {
        int cbp_a = -1;
        int x, y;
        int ctx = 0;
 
        x = block_idx_x[4*i8x8];
        y = block_idx_y[4*i8x8];
 
        if( x > 0 )
            cbp_a = cbp;
        else if( h->slice_table[h->left_mb_xy[0]] == h->slice_num ) {
            cbp_a = h->left_cbp;
            tprintf("cbp_a = left_cbp = %x\n", cbp_a);
        }
 
        if( y > 0 )
            cbp_b = cbp;
 
        /* No need to test for skip as we put 0 for skip block */
        /* No need to test for IPCM as we put 1 for IPCM block */
        if( cbp_a >= 0 ) {
            int i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
            if( ((cbp_a >> i8x8a)&0x01) == 0 )
                ctx++;
        }
 
        if( cbp_b >= 0 ) {
            int i8x8b = block_idx_xy[x][(y-1)&0x03]/4;
            if( ((cbp_b >> i8x8b)&0x01) == 0 )
                ctx += 2;
        }
Best regards
Nusart
 
        if( get_cabac( &h->cabac, &h->cabac_state[73 + ctx] ) ) {
            cbp |= 1 << i8x8;
        }
    }
    return cbp;
}




More information about the ffmpeg-devel mailing list