H264源码分析(四)

时间:2022-05-08 23:45:18

(十二)子宏块预测句法

sub_mb_pred( mb_type ) {  
    for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ )         
        // sub_mb_type[ mbPartIdx ]    指明子宏块的预测类型,在不同的宏块类型中这个句法元素的语义不一样。     
        sub_mb_type[ mbPartIdx ]  
    for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ )             
        if( ( num_ref_idx_l0_active_minus1    >    0    | |  
mb_field_decoding_flag ) &&
            mb_type    !=    P_8x8ref0    &&
            sub_mb_type[ mbPartIdx ]    !=    B_Direct_8x8    &&
            SubMbPredMode( sub_mb_type[ mbPartIdx ] )    !=    Pred_L1 )
            ref_idx_l0[ mbPartIdx ]   
    for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ )             
        if( (num_ref_idx_l1_active_minus1    >    0    | |    mb_field_decoding_flag )
&&
                sub_mb_type[ mbPartIdx ]    !=    B_Direct_8x8    &&
                SubMbPredMode( sub_mb_type[ mbPartIdx ] )    !=    Pred_L0 )
            ref_idx_l1[ mbPartIdx ]  
    for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ )             
        if( sub_mb_type[ mbPartIdx ]    !=    B_Direct_8x8    &&
            SubMbPredMode( sub_mb_type[ mbPartIdx ] )    !=    Pred_L1 )
            for( subMbPartIdx = 0;  
                      subMbPartIdx < NumSubMbPart( sub_mb_type[ mbPartIdx ] );
                      subMbPartIdx++)
                for( compIdx = 0; compIdx < 2; compIdx++ )         
                    mvd_l0[ mbPartIdx ][ subMbPartIdx ][ compIdx ]  
    for( mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++ )         
        if( sub_mb_type[ mbPartIdx ]    !=    B_Direct_8x8    &&
            SubMbPredMode( sub_mb_type[ mbPartIdx ] )    !=    Pred_L0 )
            for( subMbPartIdx = 0;  
                      subMbPartIdx < NumSubMbPart( sub_mb_type[ mbPartIdx ] );
                      subMbPartIdx++)
                for( compIdx = 0; compIdx < 2; compIdx++ )         
                    mvd_l1[ mbPartIdx ][ subMbPartIdx ][ compIdx ]  
}

 

(十三)残差句法

residual( ) { 
    if( !entropy_coding_mode_flag )          
        residual_block = residual_block_cavlc          
    else          
        residual_block = residual_block_cabac          
    if( MbPartPredMode( mb_type, 0 )    = =    Intra_16x16 )          
        residual_block( Intra16x16DCLevel, 16 )    
    for( i8x8 = 0; i8x8 < 4; i8x8++ )    /* each luma 8x8 block */          
        for( i4x4 = 0; i4x4 < 4; i4x4++ )    /* each 4x4 sub-block of block */          
            if( CodedBlockPatternLuma & ( 1 << i8x8 ) ) {            
                if( MbPartPredMode( mb_type, 0 )    = =    Intra_16x16 )          
                    residual_block( Intra16x16ACLevel[ i8x8 * 4 + i4x4 ], 15 )   
                else          
                    residual_block( LumaLevel[ i8x8 * 4 + i4x4 ], 16 )          
            } else {          
                if( MbPartPredMode( mb_type, 0 )    = =    Intra_16x16 )          
                    for( i = 0; i < 15; i++ )            
                        Intra16x16ACLevel[ i8x8 * 4 + i4x4 ][ i ] = 0          
                else          
                    for( i = 0; i < 16; i++ )          
                        LumaLevel[ i8x8 * 4 + i4x4 ][ i ] = 0          
            }          
    for( iCbCr = 0; iCbCr < 2; iCbCr++ )          
        if( CodedBlockPatternChroma & 3 )    /* chroma DC residual present */                   
            residual_block( ChromaDCLevel[ iCbCr ], 4 )       
        else          
            for( i = 0; i < 4; i++ )          
                ChromaDCLevel[ iCbCr ][ i ] = 0          
    for( iCbCr = 0; iCbCr < 2; iCbCr++ )          
        for( i4x4 = 0; i4x4 < 4; i4x4++ )          
            if( CodedBlockPatternChroma & 2 )    
                /* chroma AC residual present */  
                residual_block( ChromaACLevel[ iCbCr ][ i4x4 ], 15 )      
            else          
                for( i = 0; i < 15; i++ )          
                    ChromaACLevel[ iCbCr ][ i4x4 ][ i ] = 0          
}

 

 

(十四)CAVLC 残差句法

 

residual_block_cavlc( coeffLevel, maxNumCoeff ) {  C      Descriptor
    for( i = 0; i < maxNumCoeff; i++ )          
        coeffLevel[ i ] = 0     
    // coeff_token      指明了非零系数的个数,拖尾系数的个数。      
    coeff_token 
    if( TotalCoeff( coeff_token ) > 0 ) {          
        if( TotalCoeff( coeff_token ) > 10    &&    TrailingOnes( coeff_token ) <
3 )
            suffixLength = 1          
        else          
            suffixLength = 0          
        for( i = 0; i < TotalCoeff( coeff_token ); i++ )          
            if( i < TrailingOnes( coeff_token ) ) {           
                // trailing_ones_sign_flag  拖尾系数的符号
                    -     如果trailing_ones_sign_flag = 0,  相应的拖尾系数是+1。
                    -     否则,trailing_ones_sign_flag =1,相应的拖尾系数是-1。
 
                trailing_ones_sign_flag  
                level[ i ] = 1 – 2 * trailing_ones_sign_flag          
            } else {          
                // level_prefix and level_suffix  非零系数值的前缀和后缀。 
                level_prefix 
                levelCode = ( level_prefix << suffixLength )          
                if( suffixLength > 0    | |    level_prefix >= 14 ) {          
                    level_suffix  
                    levelCode += level_suffix          
                }          
                if( level_prefix    = =    15    &&    suffixLength    = =    0 )          
                    levelCode += 15          
                if( i    = =    TrailingOnes( coeff_token )    &&    
                      TrailingOnes( coeff_token ) < 3 )
                    levelCode += 2          
                if( levelCode % 2    = =    0 )          
                    level[ i ] = ( levelCode + 2 ) >> 1          
                else          
                    level[ i ] = ( –levelCode – 1 ) >> 1          
                if( suffixLength    = =    0 )          
                    suffixLength = 1          
                if( Abs( level[ i ] )    >    ( 3 << ( suffixLength – 1 ) )    &&    
                      suffixLength < 6 )
                    suffixLength++          
            }          
        if( TotalCoeff( coeff_token ) < maxNumCoeff ) {          
            // total_zeros    系数中 0 的总个数。
            total_zeros   
            zerosLeft = total_zeros          
        } else          
            zerosLeft = 0          
        for( i = 0; i < TotalCoeff( coeff_token ) – 1; i++ ) {          
            if( zerosLeft > 0 ) {          
               
                run_before   
                run[ i ] = run_before          
            } else          
                run[ i ] = 0          
            zerosLeft = zerosLeft – run[ i ]          
        }          
        run[ TotalCoeff( coeff_token ) – 1 ] = zerosLeft          
        coeffNum = -1          
        for( i = TotalCoeff( coeff_token ) – 1; i >= 0; i-- ) {          
            coeffNum += run[ i ] + 1          
            coeffLevel[ coeffNum ] = level[ i ]            
        }          
    }          
}