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

📄 macroblock.c

📁 H.264改进解码软件
💻 C
📖 第 1 页 / 共 4 页
字号:
                case D_BI_4x8:                    x264_mb_mc_01xywh( h, x+0, y, 1, 2 );                    x264_mb_mc_01xywh( h, x+1, y, 1, 2 );                    break;                case D_BI_4x4:                    x264_mb_mc_01xywh( h, x+0, y+0, 1, 1 );                    x264_mb_mc_01xywh( h, x+1, y+0, 1, 1 );                    x264_mb_mc_01xywh( h, x+0, y+1, 1, 1 );                    x264_mb_mc_01xywh( h, x+1, y+1, 1, 1 );                    break;                case D_DIRECT_8x8:                    x264_mb_mc_direct8x8( h, x, y );                    break;            }        }    }    else if( h->mb.i_type == B_SKIP || h->mb.i_type == B_DIRECT )    {        x264_mb_mc_direct8x8( h, 0, 0 );        x264_mb_mc_direct8x8( h, 2, 0 );        x264_mb_mc_direct8x8( h, 0, 2 );        x264_mb_mc_direct8x8( h, 2, 2 );    }    else    /* B_*x* */    {        int b_list0[2];        int b_list1[2];        int i;        /* init ref list utilisations */        for( i = 0; i < 2; i++ )        {            b_list0[i] = x264_mb_type_list0_table[h->mb.i_type][i];            b_list1[i] = x264_mb_type_list1_table[h->mb.i_type][i];        }        if( h->mb.i_partition == D_16x16 )        {            if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 4, 4 );            else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 4, 4 );            else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 4, 4 );        }        else if( h->mb.i_partition == D_16x8 )        {            if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 4, 2 );            else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 4, 2 );            else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 4, 2 );            if( b_list0[1] && b_list1[1] ) x264_mb_mc_01xywh( h, 0, 2, 4, 2 );            else if( b_list0[1] )          x264_mb_mc_0xywh ( h, 0, 2, 4, 2 );            else if( b_list1[1] )          x264_mb_mc_1xywh ( h, 0, 2, 4, 2 );        }        else if( h->mb.i_partition == D_8x16 )        {            if( b_list0[0] && b_list1[0] ) x264_mb_mc_01xywh( h, 0, 0, 2, 4 );            else if( b_list0[0] )          x264_mb_mc_0xywh ( h, 0, 0, 2, 4 );            else if( b_list1[0] )          x264_mb_mc_1xywh ( h, 0, 0, 2, 4 );            if( b_list0[1] && b_list1[1] ) x264_mb_mc_01xywh( h, 2, 0, 2, 4 );            else if( b_list0[1] )          x264_mb_mc_0xywh ( h, 2, 0, 2, 4 );            else if( b_list1[1] )          x264_mb_mc_1xywh ( h, 2, 0, 2, 4 );        }    }}void x264_macroblock_cache_init( x264_t *h ){    int i, j;    int i_mb_count = h->mb.i_mb_count;    h->mb.i_mb_stride = h->sps->i_mb_width;    h->mb.i_b8_stride = h->sps->i_mb_width * 2;    h->mb.i_b4_stride = h->sps->i_mb_width * 4;    h->mb.qp  = x264_malloc( i_mb_count * sizeof(int8_t) );    h->mb.cbp = x264_malloc( i_mb_count * sizeof(int16_t) );    h->mb.skipbp = x264_malloc( i_mb_count * sizeof(int8_t) );    h->mb.mb_transform_size = x264_malloc( i_mb_count * sizeof(int8_t) );    /* 0 -> 3 top(4), 4 -> 6 : left(3) */    h->mb.intra4x4_pred_mode = x264_malloc( i_mb_count * 7 * sizeof( int8_t ) );    /* all coeffs */    h->mb.non_zero_count = x264_malloc( i_mb_count * 24 * sizeof( uint8_t ) );    /*if( h->param.b_cabac )    {        h->mb.chroma_pred_mode = x264_malloc( i_mb_count * sizeof( int8_t) );        h->mb.mvd[0] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );        h->mb.mvd[1] = x264_malloc( 2*16 * i_mb_count * sizeof( int16_t ) );    }*/    for( i=0; i<2; i++ )//为前\后向预测参考帧序列分配缓存空间    {        int i_refs = (i ? 1 : h->param.i_frame_reference) + h->param.b_bframe_pyramid;        for( j=0; j < i_refs && j < 16; j++ )//最多16个参考帧            h->mb.mvr[i][j] = x264_malloc( 2 * i_mb_count * sizeof( int16_t ) );    }    /* init with not avaiable (for top right idx=7,15) */    memset( h->mb.cache.ref[0], -2, X264_SCAN8_SIZE * sizeof( int8_t ) );    //memset( h->mb.cache.ref[1], -2, X264_SCAN8_SIZE * sizeof( int8_t ) );}void x264_macroblock_cache_end( x264_t *h ){    int i, j;    for( i=0; i<2; i++ )    {        int i_refs = i ? 1 + h->param.b_bframe_pyramid : h->param.i_frame_reference;        for( j=0; j < i_refs; j++ )            x264_free( h->mb.mvr[i][j] );    }    if( h->param.b_cabac )    {        x264_free( h->mb.chroma_pred_mode );        x264_free( h->mb.mvd[0] );        x264_free( h->mb.mvd[1] );    }    x264_free( h->mb.intra4x4_pred_mode );    x264_free( h->mb.non_zero_count );    x264_free( h->mb.mb_transform_size );    x264_free( h->mb.skipbp );    x264_free( h->mb.cbp );    x264_free( h->mb.qp );}void x264_macroblock_slice_init( x264_t *h ){    int i, j;    h->mb.mv[0] = h->fdec->mv[0];    h->mb.mv[1] = h->fdec->mv[1];    h->mb.ref[0] = h->fdec->ref[0];    h->mb.ref[1] = h->fdec->ref[1];    h->mb.type = h->fdec->mb_type;    h->fdec->i_ref[0] = h->i_ref0;   // h->fdec->i_ref[1] = h->i_ref1;    for( i = 0; i < h->i_ref0; i++ )        h->fdec->ref_poc[0][i] = h->fref0[i]->i_poc;   /* if( h->sh.i_type == SLICE_TYPE_B )    {        for( i = 0; i < h->i_ref1; i++ )            h->fdec->ref_poc[1][i] = h->fref1[i]->i_poc;        h->mb.map_col_to_list0[-1] = -1;        h->mb.map_col_to_list0[-2] = -2;        for( i = 0; i < h->fref1[0]->i_ref[0]; i++ )        {            int poc = h->fref1[0]->ref_poc[0][i];            h->mb.map_col_to_list0[i] = -2;            for( j = 0; j < h->i_ref0; j++ )                if( h->fref0[j]->i_poc == poc )                {                    h->mb.map_col_to_list0[i] = j;                    break;                }        }    }*/    if( h->sh.i_type == SLICE_TYPE_P )        memset( h->mb.cache.skip, 0, X264_SCAN8_SIZE * sizeof( int8_t ) );}void x264_macroblock_cache_load( x264_t *h, int i_mb_x, int i_mb_y ){    const int i_mb_4x4 = 4*(i_mb_y * h->mb.i_b4_stride + i_mb_x);//当前宏块首个4*4块在当前幅图像中的4*4块扫描序号    const int i_mb_8x8 = 2*(i_mb_y * h->mb.i_b8_stride + i_mb_x);//当前宏块首个8*8块在当前幅图像中的8*8块扫描序号    int i_mb_xy = i_mb_y * h->mb.i_mb_stride + i_mb_x;//在当前幅图像中的宏块号    int i_top_xy = i_mb_xy - h->mb.i_mb_stride;//上邻宏块号    int i_left_xy = -1;    int i_top_type = -1;    /* gcc warn */    int i_left_type= -1;    int i;    /* init index */    h->mb.i_mb_x = i_mb_x;    h->mb.i_mb_y = i_mb_y;    h->mb.i_mb_xy = i_mb_xy;    h->mb.i_b8_xy = i_mb_8x8;    h->mb.i_b4_xy = i_mb_4x4;    h->mb.i_neighbour = 0;    /* fdec:      fenc://???     * yyyyyyy     * yYYYY      YYYY     * yYYYY      YYYY     * yYYYY      YYYY     * yYYYY      YYYY     * uuu vvv    UUVV     * uUU vVV    UUVV     * uUU vVV     *///解码帧缓存是按扫描顺序存放一帧图像的像素值    h->mb.pic.p_fenc[0] = h->mb.pic.fenc_buf;//指针赋值,指向待编码宏块缓存首地址,即亮度数据y    h->mb.pic.p_fenc[1] = h->mb.pic.fenc_buf + 16*FENC_STRIDE;//指向色度数据u    h->mb.pic.p_fenc[2] = h->mb.pic.fenc_buf + 16*FENC_STRIDE + 8;//指向v??    h->mb.pic.p_fdec[0] = h->mb.pic.fdec_buf + 2*FDEC_STRIDE;//解码重构造宏块缓存中,当前宏块首个4*4块数据(Y)位置    h->mb.pic.p_fdec[1] = h->mb.pic.fdec_buf + 19*FDEC_STRIDE;    h->mb.pic.p_fdec[2] = h->mb.pic.fdec_buf + 19*FDEC_STRIDE + 16;    /* load picture pointers */    for( i = 0; i < 3; i++ )//y,u,v    {        const int w = (i == 0 ? 16 : 8);//宏块宽\高        const int i_stride = h->fdec->i_stride[i];//y时为416=352+64??,无限制矢量下扩充边界了??哪里赋初值        const uint8_t *plane_fdec = &h->fdec->plane[i][ w * (i_mb_x + i_mb_y * i_stride) ];//h->fdec初始值为h->frames.reference[0]        int   j;                                                                           //指向解码帧缓中当前宏块首像素位置        h->mb.pic.i_stride[i] = i_stride;
        //从h->fenc->plane帧缓存拷贝待编码宏块原始数据到宏块缓存h->mb.pic.p_fenc[i],都是一维存放        h->mc.copy[i?PIXEL_8x8:PIXEL_16x16]( h->mb.pic.p_fenc[i], FENC_STRIDE,            &h->fenc->plane[i][ w * (i_mb_x + i_mb_y * i_stride) ], i_stride, w );
        
		//亮度时,从帧缓存中读取左上角1个,上邻行16个,右上邻行8个像素数据,写入当前宏块解码总缓存的31~56位置,即fdec[0]的-33~-8        memcpy( &h->mb.pic.p_fdec[i][-1-FDEC_STRIDE], &plane_fdec[-1-i_stride], w*3/2+1 );
        
		//亮度时,从解码重建帧缓存中读取左邻列16个像素数据,写入当前宏块解码总缓存的64+j*32-1(j=0~15)位置,即fdec[0]的j*32-1
        for( j = 0; j < w; j++ )            h->mb.pic.p_fdec[i][-1+j*FDEC_STRIDE] = plane_fdec[-1+j*i_stride];        for( j = 0; j < h->i_ref0; j++ )//指针赋值,前向预测参考帧队列中相同坐标位置的宏块数据首像素存放地址        {            h->mb.pic.p_fref[0][j][i==0 ? 0:i+3] = &h->fref0[j]->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];            h->mb.pic.p_fref[0][j][i+1] = &h->fref0[j]->filtered[i+1][ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];        }       /* for( j = 0; j < h->i_ref1; j++ )        {            h->mb.pic.p_fref[1][j][i==0 ? 0:i+3] = &h->fref1[j]->plane[i][ w * ( i_mb_x + i_mb_y * i_stride )];            h->mb.pic.p_fref[1][j][i+1] = &h->fref1[j]->filtered[i+1][ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];        }*/    }    if( h->fdec->integral )    {        for( i = 0; i < h->i_ref0; i++ )            h->mb.pic.p_integral[0][i] = &h->fref0[i]->integral[ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];        for( i = 0; i < h->i_ref1; i++ )            h->mb.pic.p_integral[1][i] = &h->fref1[i]->integral[ 16 * ( i_mb_x + i_mb_y * h->fdec->i_stride[0] )];    }    /* load cache */    if( i_mb_xy >= h->sh.i_first_mb + h->mb.i_mb_stride )//不是第一行宏块    {        h->mb.i_mb_type_top =        i_top_type= h->mb.type[i_top_xy];        h->mb.i_neighbour |= MB_TOP;
		//下一段,等号左边[]中的值是8*6二维表格中的扫描序号,与某二维位置对应.这里-8表示二维表格中当前宏块亮度第一4*4块行的上邻块行
        /* load intra4x4 *///存放当前宏块亮度数据的上邻4*4块行信息        h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][0];//h->mb.intra4x4_pred_mode[i_mb_count][7], 0 -> 3 top(4), 4 -> 6 : left(3) 
        h->mb.cache.intra4x4_pred_mode[x264_scan8[1] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][1];        h->mb.cache.intra4x4_pred_mode[x264_scan8[4] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][2];        h->mb.cache.intra4x4_pred_mode[x264_scan8[5] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][3];//上邻宏块的下边缘4个4*4块        /* load non_zero_count */        h->mb.cache.non_zero_count[x264_scan8[0] - 8] = h->mb.non_zero_count[i_top_xy][10];        h->mb.cache.non_zero_count[x264_scan8[1] - 8] = h->mb.non_zero_count[i_top_xy][11];        h->mb.cache.non_zero_count[x264_scan8[4] - 8] = h->mb.non_zero_count[i_top_xy][14];        h->mb.cache.non_zero_count[x264_scan8[5] - 8] = h->mb.non_zero_count[i_top_xy][15];        h->mb.cache.non_zero_count[x264_scan8[16+0] - 8] = h->mb.non_zero_count[i_top_xy][16+2];        h->mb.cache.non_zero_count[x264_scan8[16+1] - 8] = h->mb.non_zero_count[i_top_xy][16+3];        h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 8] = h->mb.non_zero_count[i_top_xy][16+4+2];        h->mb.cache.non_zero_count[x264_scan8[16+4+1] - 8] = h->mb.non_zero_count[i_top_xy][16+4+3];    }    else//是第一行宏块    {        h->mb.i_mb_type_top = -1;                /* load intra4x4 *///h->mb.cache.intra4x4_pred_mode[]该数组大小为48        h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[1] - 8] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[4] - 8] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[5] - 8] = -1;// 在二维表格中描述亮度宏块的上邻4*4块行不可得(即上邻宏块的下边缘4个4*4块)        /* load non_zero_count */        h->mb.cache.non_zero_count[x264_scan8[0] - 8] =        h->mb.cache.non_zero_count[x264_scan8[1] - 8] =        h->mb.cache.non_zero_count[x264_scan8[4] - 8] =        h->mb.cache.non_zero_count[x264_scan8[5] - 8] =        h->mb.cache.non_zero_count[x264_scan8[16+0] - 8] =        h->mb.cache.non_zero_count[x264_scan8[16+1] - 8] =        h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 8] =//在二维表格中描述上邻行亮度和色度信息均无效(不可得)        h->mb.cache.non_zero_count[x264_scan8[16+4+1] - 8] = 0x80;// h->mb.cache.non_zero_count[1,2,4,5,6,7,25,26]=128    }    if( i_mb_x > 0 && i_mb_xy > h->sh.i_first_mb )//不是第一列宏块也不是帧内第一个宏块    {        i_left_xy = i_mb_xy - 1;//左邻宏块号        h->mb.i_mb_type_left =        i_left_type = h->mb.type[i_left_xy];        h->mb.i_neighbour |= MB_LEFT;        /* load intra4x4 *///等号左边是8*6二维表格的[]中扫描序号对应的位置,用来存放当前宏块亮度数据的左邻4*4块列信息        h->mb.cache.intra4x4_pred_mode[x264_scan8[0 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][4];        h->mb.cache.intra4x4_pred_mode[x264_scan8[2 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][5];        h->mb.cache.intra4x4_pred_mode[x264_scan8[8 ] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][6];        h->mb.cache.intra4x4_pred_mode[x264_scan8[10] - 1] = h->mb.intra4x4_pred_mode[i_left_xy][3];        /* load non_zero_count */        h->mb.cache.non_zero_count[x264_scan8[0 ] - 1] = h->mb.non_zero_count[i_left_xy][5];        h->mb.cache.non_zero_count[x264_scan8[2 ] - 1] = h->mb.non_zero_count[i_left_xy][7];        h->mb.cache.non_zero_count[x264_scan8[8 ] - 1] = h->mb.non_zero_count[i_left_xy][13];        h->mb.cache.non_zero_count[x264_scan8[10] - 1] = h->mb.non_zero_count[i_left_xy][15];        h->mb.cache.non_zero_count[x264_scan8[16+0] - 1] = h->mb.non_zero_count[i_left_xy][16+1];        h->mb.cache.non_zero_count[x264_scan8[16+2] - 1] = h->mb.non_zero_count[i_left_xy][16+3];        h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 1] = h->mb.non_zero_count[i_left_xy][16+4+1];        h->mb.cache.non_zero_count[x264_scan8[16+4+2] - 1] = h->mb.non_zero_count[i_left_xy][16+4+3];    }    else//是第一列宏块    {        h->mb.i_mb_type_left = -1;        h->mb.cache.intra4x4_pred_mode[x264_scan8[0 ] - 1] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[2 ] - 1] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[8 ] - 1] =        h->mb.cache.intra4x4_pred_mode[x264_scan8[10] - 1] = -1;//无左邻行        /* load non_zero_count */        h->mb.cache.non_zero_count[x264_scan8[0 ] - 1] =// h->mb.cache.non_zero_count[11,19,27,35,8,16,32,40]=128        h->mb.cache.non_zero_count[x264_scan8[2 ] - 1] =        h->mb.cache.non_zero_count[x264_scan8[8 ] - 1] =        h->mb.cache.non_zero_count[x264_scan8[10] - 1] =        h->mb.cache.non_zero_count[x264_scan8[16+0] - 1] =        h->mb.cache.non_zero_count[x264_scan8[16+2] - 1] =        h->mb.cache.non_zero_count[x264_scan8[16+4+0] - 1] =        h->mb.cache.non_zero_count[x264_scan8[16+4+2] - 1] = 0x80;    }    if( i_mb_x < h->sps->i_mb_width - 1 && i_top_xy + 1 >= h->sh.i_first_mb )//不是最后一列,同时上邻宏块存在时(即不是第一行也不是最后一列的宏块)    {        h->mb.i_neighbour |= MB_TOPRIGHT;//右上宏块存在        h->mb.i_mb_type_topright = h->mb.type[ i_top_xy + 1 ];    }    else//或者是第一行,或者是最后一列宏块        h->mb.i_mb_type_topright = -1;    if( i_mb_x > 0 && i_top_xy - 1 >= h->sh.i_first_mb )//不是第一列也不是第一行的宏块时    {        h->mb.i_neighbour |= MB_TOPLEFT;//左上宏块存在        h->mb.i_mb_type_topleft = h->mb.type[ i_top_xy - 1 ];    }    else        h->mb.i_mb_type_topleft = -1;//左上宏块不存在    if( h->param.analyse.b_transform_8x8 )    {        h->mb.cache.i_neighbour_transform_size =            ( i_left_type >= 0 && h->mb.mb_transform_size[i_left_xy] )          + ( i_top_type  >= 0 && h->mb.mb_transform_size[i_top_xy]  );    }    /* load ref/mv/mvd *///相邻4*4的矢量信息    if( h->sh.i_type != SLICE_TYPE_I )    {        const int s8x8 = h->mb.i_b8_stride;//一行包含8*8块数量        const int s4x4 = h->mb.i_b4_stride;        int i_list;        for( i_list = 0; i_list < (h->sh.i_type == SLICE_TYPE_B ? 2  : 1 ); i_list++ )        {            /*            h->mb.cache.ref[i_list][x264_scan8[5 ]+1] =            h->mb.cache.ref[i_list][x264_scan8[7 ]+1] =            h->mb.cache.ref[i_list][x264_scan8[13]+1] = -2;            */            if( h->mb.i_neighbour & MB_TOPLEFT )//左上角宏块存在            {                const int i8 = x264_scan8[0] - 1 - 1*8;//3,左上角相邻4*4在二维表格中的扫描序号                const int ir = i_mb_8x8 - s8x8 - 1;//左上角8*8块在帧中的序号                const int iv = i_mb_4x4 - s4x4 - 1;//左上角4*4块在帧中的序号                h->mb.cache.ref[i_list][i8]  = h->mb.ref[i_list][ir];//这么看,参考值数据以8*8为单位存放

⌨️ 快捷键说明

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