⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroblock.c

📁 H.264 source codes
💻 C
📖 第 1 页 / 共 2 页
字号:
            x264_mb_partition_get( mb, 0, i, 0, &i_ref, NULL, NULL );            for( i_sub = 0; i_sub < x264_mb_partition_count_table[mb->i_sub_partition[i]]; i_sub++ )            {                int mv[2];                x264_mb_predict_mv( mb, 0, i, i_sub, mv );                mv[0] += bs_read_se( s );                mv[1] += bs_read_se( s );                x264_mb_partition_mv_set( mb, 0, i, i_sub, mv );            }        }    }    else if( mb->i_type != B_DIRECT )    {        /* FIXME will work only for P block */        /* FIXME using x264_mb_partition_set/x264_mb_partition_get here are too unoptimised         * I should introduce ref and mv get/set */        /* Motion Vector */        int i_part = x264_mb_partition_count_table[mb->i_partition];        for( i = 0; i < i_part; i++ )        {            int i_ref;            i_ref = bs_read_te( s, h->sh.i_num_ref_idx_l0_active - 1 );            x264_mb_partition_ref_set( mb, 0, i, i_ref );        }        for( i = 0; i < i_part; i++ )        {            int mv[2];            x264_mb_predict_mv( mb, 0, i, 0, mv );            mv[0] += bs_read_se( s );            mv[1] += bs_read_se( s );            x264_mb_partition_mv_set( mb, 0, i, 0, mv );        }    }    if( mb->i_type != I_16x16 )    {        int i_cbp;        i_cbp = bs_read_ue( s );        if( i_cbp >= 48 )        {            fprintf( stderr, "invalid cbp\n" );            return -1;        }        if( mb->i_type == I_4x4 )        {            i_cbp = golomb_to_intra4x4_cbp[i_cbp];        }        else        {            i_cbp = golomb_to_inter_cbp[i_cbp];        }        mb->i_cbp_luma   = i_cbp&0x0f;        mb->i_cbp_chroma = i_cbp >> 4;    }    if( mb->i_cbp_luma > 0 || mb->i_cbp_chroma > 0 || mb->i_type == I_16x16 )    {        mb->i_qp = bs_read_se( s ) + h->pps->i_pic_init_qp + h->sh.i_qp_delta;        /* write residual */        if( mb->i_type == I_16x16 )        {            /* DC Luma */            if( block_residual_read_cavlc( h, s, mb, BLOCK_INDEX_LUMA_DC , mb->luma16x16_dc, 16 ) < 0 )            {                return -1;            }            if( mb->i_cbp_luma != 0 )            {                /* AC Luma */                for( i = 0; i < 16; i++ )                {                    if( block_residual_read_cavlc( h, s, mb, i, mb->block[i].residual_ac, 15 ) < 0 )                    {                        return -1;                    }                }            }            else            {                for( i = 0; i < 16; i++ )                {                    mb->block[i].i_non_zero_count = 0;                    array_zero_set( mb->block[i].residual_ac, 15 );                }            }        }        else        {            for( i = 0; i < 16; i++ )            {                if( mb->i_cbp_luma & ( 1 << ( i / 4 ) ) )                {                    if( block_residual_read_cavlc( h, s, mb, i, mb->block[i].luma4x4, 16 ) < 0 )                    {                        return -1;                    }                }                else                {                    mb->block[i].i_non_zero_count = 0;                    array_zero_set( mb->block[i].luma4x4, 16 );                }            }        }        if( mb->i_cbp_chroma &0x03 )    /* Chroma DC residual present */        {            if( block_residual_read_cavlc( h, s, mb, BLOCK_INDEX_CHROMA_DC, mb->chroma_dc[0], 4 ) < 0 ||                block_residual_read_cavlc( h, s, mb, BLOCK_INDEX_CHROMA_DC, mb->chroma_dc[1], 4 ) < 0 )            {                return -1;            }        }        else        {            array_zero_set( mb->chroma_dc[0], 4 );            array_zero_set( mb->chroma_dc[1], 4 );        }        if( mb->i_cbp_chroma&0x02 ) /* Chroma AC residual present */        {            for( i = 0; i < 8; i++ )            {                if( block_residual_read_cavlc( h, s, mb, 16 + i, mb->block[16+i].residual_ac, 15 ) < 0 )                {                    return -1;                }            }        }        else        {            for( i = 0; i < 8; i++ )            {                mb->block[16+i].i_non_zero_count = 0;                array_zero_set( mb->block[16+i].residual_ac, 15 );            }        }    }    else    {        mb->i_qp = h->pps->i_pic_init_qp + h->sh.i_qp_delta;        for( i = 0; i < 16; i++ )        {            mb->block[i].i_non_zero_count = 0;            array_zero_set( mb->block[i].luma4x4, 16 );        }        array_zero_set( mb->chroma_dc[0], 4 );        array_zero_set( mb->chroma_dc[1], 4 );        for( i = 0; i < 8; i++ )        {            array_zero_set( mb->block[16+i].residual_ac, 15 );            mb->block[16+i].i_non_zero_count = 0;        }    }    //fprintf( stderr, "mb read type=%d\n", mb->i_type );    return 0;}static int x264_mb_pred_mode16x16_valid( x264_macroblock_t *mb, int i_mode ){    if( ( mb->i_neighbour & (MB_LEFT|MB_TOP) ) == (MB_LEFT|MB_TOP) )    {        return i_mode;    }    else if( ( mb->i_neighbour & MB_LEFT ) )    {        if( i_mode == I_PRED_16x16_DC )        {            return I_PRED_16x16_DC_LEFT;        }        else if( i_mode == I_PRED_16x16_H )        {            return I_PRED_16x16_H;        }        fprintf( stderr, "invalid 16x16 prediction\n" );        return I_PRED_16x16_DC_LEFT;    }    else if( ( mb->i_neighbour & MB_TOP ) )    {        if( i_mode == I_PRED_16x16_DC )        {            return I_PRED_16x16_DC_TOP;        }        else if( i_mode == I_PRED_16x16_V )        {            return I_PRED_16x16_V;        }        fprintf( stderr, "invalid 16x16 prediction\n" );        return I_PRED_16x16_DC_TOP;    }    else    {        return I_PRED_16x16_DC_128;    }}static int x264_mb_pred_mode8x8_valid( x264_macroblock_t *mb, int i_mode ){    if( ( mb->i_neighbour & (MB_LEFT|MB_TOP) ) == (MB_LEFT|MB_TOP) )    {        return i_mode;    }    else if( ( mb->i_neighbour & MB_LEFT ) )    {        if( i_mode == I_PRED_CHROMA_DC )        {            return I_PRED_CHROMA_DC_LEFT;        }        else if( i_mode == I_PRED_CHROMA_H )        {            return I_PRED_CHROMA_H;        }        fprintf( stderr, "invalid 8x8 prediction\n" );        return I_PRED_CHROMA_DC_LEFT;    }    else if( ( mb->i_neighbour & MB_TOP ) )    {        if( i_mode == I_PRED_CHROMA_DC )        {            return I_PRED_CHROMA_DC_TOP;        }        else if( i_mode == I_PRED_CHROMA_V )        {            return I_PRED_CHROMA_V;        }        fprintf( stderr, "invalid 8x8 prediction\n" );        return I_PRED_CHROMA_DC_TOP;    }    else    {        return I_PRED_CHROMA_DC_128;    }}static int x264_mb_pred_mode4x4_valid( x264_macroblock_t *mb, int idx, int i_mode, int *pb_emu ){    int b_a, b_b, b_c;    static const int needmb[16] =    {        MB_LEFT|MB_TOP, MB_TOP,        MB_LEFT,        MB_PRIVATE,        MB_TOP,         MB_TOP|MB_TOPRIGHT,        0,              MB_PRIVATE,        MB_LEFT,        0,        MB_LEFT,        MB_PRIVATE,        0,              MB_PRIVATE,        0,              MB_PRIVATE    };    int b_emu = 0;    *pb_emu = 0;    b_a = (needmb[idx]&mb->i_neighbour&MB_LEFT) == (needmb[idx]&MB_LEFT);    b_b = (needmb[idx]&mb->i_neighbour&MB_TOP) == (needmb[idx]&MB_TOP);    b_c = (needmb[idx]&mb->i_neighbour&(MB_TOPRIGHT|MB_PRIVATE)) == (needmb[idx]&(MB_TOPRIGHT|MB_PRIVATE));    if( b_c == 0 && b_b )    {        b_emu = 1;        b_c = 1;    }    /* handle I_PRED_4x4_DC */    if( i_mode == I_PRED_4x4_DC )    {        if( b_a && b_b )        {            return I_PRED_4x4_DC;        }        else if( b_a )        {            return I_PRED_4x4_DC_LEFT;        }        else if( b_b )        {            return I_PRED_4x4_DC_TOP;        }        return I_PRED_4x4_DC_128;    }    /* handle 1 dir needed only */    if( ( b_a && i_mode == I_PRED_4x4_H ) ||        ( b_b && i_mode == I_PRED_4x4_V ) )    {        return i_mode;    }    /* handle b_c case (b_b always true) */    if( b_c && ( i_mode == I_PRED_4x4_DDL || i_mode == I_PRED_4x4_VL ) )    {        *pb_emu = b_emu;        return i_mode;    }    if( b_a && b_b )    {        /* I_PRED_4x4_DDR, I_PRED_4x4_VR, I_PRED_4x4_HD, I_PRED_4x4_HU */        return i_mode;    }    fprintf( stderr, "invalid 4x4 predict mode(%d, mb:%x-%x idx:%d\n", i_mode, mb->i_mb_x, mb->i_mb_y, idx );    return I_PRED_CHROMA_DC_128;    /* unefficient */}/**************************************************************************** * UnScan functions ****************************************************************************/static const int scan_zigzag_x[16]={0, 1, 0, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 3, 2, 3};static const int scan_zigzag_y[16]={0, 0, 1, 2, 1, 0, 0, 1, 2, 3, 3, 2, 1, 2, 3, 3};static inline void unscan_zigzag_4x4full( int16_t dct[4][4], int level[16] ){    int i;    for( i = 0; i < 16; i++ )    {        dct[scan_zigzag_y[i]][scan_zigzag_x[i]] = level[i];    }}static inline void unscan_zigzag_4x4( int16_t dct[4][4], int level[15] ){    int i;    for( i = 1; i < 16; i++ )    {        dct[scan_zigzag_y[i]][scan_zigzag_x[i]] = level[i - 1];    }}static inline void unscan_zigzag_2x2_dc( int16_t dct[2][2], int level[4] ){    dct[0][0] = level[0];    dct[0][1] = level[1];    dct[1][0] = level[2];    dct[1][1] = level[3];}int x264_macroblock_decode( x264_t *h, x264_macroblock_t *mb ){    x264_mb_context_t *ctx = mb->context;    int i_qscale;    int ch;    int i;    if( !IS_INTRA(mb->i_type ) )    {        /* Motion compensation */        x264_mb_mc( h, mb );    }    /* luma */    i_qscale = mb->i_qp;    if( mb->i_type == I_16x16 )    {        int     i_mode = x264_mb_pred_mode16x16_valid( mb, mb->i_intra16x16_pred_mode );        int16_t luma[16][4][4];        int16_t dct4x4[16+1][4][4];        /* do the right prediction */        h->predict_16x16[i_mode]( ctx->p_fdec[0], ctx->i_fdec[0] );        /* get dc coeffs */        unscan_zigzag_4x4full( dct4x4[0], mb->luma16x16_dc );        h->dctf.idct4x4dc( dct4x4[0], dct4x4[0] );        x264_mb_dequant_4x4_dc( dct4x4[0], i_qscale );        /* decode the 16x16 macroblock */        for( i = 0; i < 16; i++ )        {            unscan_zigzag_4x4( dct4x4[1+i], mb->block[i].residual_ac );            x264_mb_dequant_4x4( dct4x4[1+i], i_qscale );            /* copy dc coeff */            dct4x4[1+i][0][0] = dct4x4[0][block_idx_y[i]][block_idx_x[i]];            h->dctf.idct4x4( luma[i], dct4x4[i+1] );        }        /* put pixels to fdec */        h->pixf.add16x16( ctx->p_fdec[0], ctx->i_fdec[0], luma );    }    else if( mb->i_type == I_4x4 )    {        for( i = 0; i < 16; i++ )        {            int16_t luma[4][4];            int16_t dct4x4[4][4];            uint8_t *p_dst_by;            int     i_mode;            int     b_emu;            /* Do the right prediction */            p_dst_by = ctx->p_fdec[0] + 4 * block_idx_x[i] + 4 * block_idx_y[i] * ctx->i_fdec[0];            i_mode   = x264_mb_pred_mode4x4_valid( mb, i, mb->block[i].i_intra4x4_pred_mode, &b_emu );            if( b_emu )            {                fprintf( stderr, "mmmh b_emu\n" );                memset( &p_dst_by[4], p_dst_by[3], 4 );            }            h->predict_4x4[i_mode]( p_dst_by, ctx->i_fdec[0] );            if( mb->block[i].i_non_zero_count > 0 )            {                /* decode one 4x4 block */                unscan_zigzag_4x4full( dct4x4, mb->block[i].luma4x4 );                x264_mb_dequant_4x4( dct4x4, i_qscale );                h->dctf.idct4x4( luma, dct4x4 );                h->pixf.add4x4( p_dst_by, ctx->i_fdec[0], luma );            }        }    }    else /* Inter mb */    {        for( i = 0; i < 16; i++ )        {            uint8_t *p_dst_by;            int16_t luma[4][4];            int16_t dct4x4[4][4];            if( mb->block[i].i_non_zero_count > 0 )            {                unscan_zigzag_4x4full( dct4x4, mb->block[i].luma4x4 );                x264_mb_dequant_4x4( dct4x4, i_qscale );                h->dctf.idct4x4( luma, dct4x4 );                p_dst_by = ctx->p_fdec[0] + 4 * block_idx_x[i] + 4 * block_idx_y[i] * ctx->i_fdec[0];                h->pixf.add4x4( p_dst_by, ctx->i_fdec[0], luma );            }        }    }    /* chroma */    i_qscale = i_chroma_qp_table[x264_clip3( i_qscale + h->pps->i_chroma_qp_index_offset, 0, 51 )];    if( IS_INTRA( mb->i_type ) )    {        int i_mode = x264_mb_pred_mode8x8_valid( mb, mb->i_chroma_pred_mode );        /* do the right prediction */        h->predict_8x8[i_mode]( ctx->p_fdec[1], ctx->i_fdec[1] );        h->predict_8x8[i_mode]( ctx->p_fdec[2], ctx->i_fdec[2] );    }    if( mb->i_cbp_chroma != 0 )    {        for( ch = 0; ch < 2; ch++ )        {            int16_t chroma[4][4][4];            int16_t dct2x2[2][2];            int16_t dct4x4[4][4][4];            /* get dc chroma */            unscan_zigzag_2x2_dc( dct2x2, mb->chroma_dc[ch] );            h->dctf.idct2x2dc( dct2x2, dct2x2 );            x264_mb_dequant_2x2_dc( dct2x2, i_qscale );            for( i = 0; i < 4; i++ )            {                unscan_zigzag_4x4( dct4x4[i], mb->block[16+i+ch*4].residual_ac );                x264_mb_dequant_4x4( dct4x4[i], i_qscale );                /* copy dc coeff */                dct4x4[i][0][0] = dct2x2[block_idx_y[i]][block_idx_x[i]];                h->dctf.idct4x4( chroma[i], dct4x4[i] );            }            h->pixf.add8x8( ctx->p_fdec[1+ch], ctx->i_fdec[1+ch], chroma );        }    }    return 0;}void x264_macroblock_decode_skip( x264_t *h, x264_macroblock_t *mb ){    int i;    int x, y;    int mv[2];    /* decode it as a 16x16 with no luma/chroma */    mb->i_type = P_L0;    mb->i_partition = D_16x16;    mb->i_cbp_luma = 0;    mb->i_cbp_chroma = 0;    for( i = 0; i < 16 + 8; i++ )    {        mb->block[i].i_non_zero_count = 0;    }    for( i = 0; i < 16; i++ )    {        array_zero_set( mb->block[i].luma4x4, 16 );    }    array_zero_set( mb->chroma_dc[0], 4 );    array_zero_set( mb->chroma_dc[1], 4 );    for( i = 0; i < 8; i++ )    {        array_zero_set( mb->block[16+i].residual_ac, 15 );    }    /* set ref0 */    for( x = 0; x < 4; x++ )    {        for( y = 0; y < 4; y++ )        {            mb->partition[x][y].i_ref[0] = 0;        }    }    /* get mv */    x264_mb_predict_mv_pskip( mb, mv );    x264_mb_partition_mv_set( mb, 0, 0, 0, mv );    /* Motion compensation */    x264_mb_mc( h, mb );    mb->i_type = P_SKIP;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -