5_9 代码分析 load_pic_pointers

#define MB_INTERLACED 0

#define CHROMA_V_SHIFT 0

static void load_pic_pointers( int mb_x, int mb_y, int b_mbaff, int b_chroma )

{

//就是对于场或者帧的一个设置 标识符

int mb_interlaced = b_mbaff && MB_INTERLACED;

//height = 16 宏块是亮度还是色度的 亮度就是16

int height = b_chroma ? 16 >> CHROMA_V_SHIFT : 16;

 

//int i_stride = h->fdec->i_stride[i]; 经过boder之后的width值,因为原本的width值可能不是16的倍数,分宏块时候可能有问题

int i_stride  = 1984;

int i_stride2 = i_stride;

/*第一个选择没看还是interlaced里面的东西*/

这一个是一个比较重要的偏移变量。当第一行的时候mb_y = 0可见i_pix_offset是以16为基准递增,

考虑这标识的是一个个宏块的话,就很好理解,第一个是第一个像素点,第二个是第一个偏移16

 

但是高的话就不一样了,因为宏块有高度,所以不能直接的就下一行,要在当前值mb_y个宏块的情况下偏移

int i_pix_offset = mb_interlaced

                     ? 16 * mb_x + height * (mb_y&~1) * i_stride + (mb_y&1) * i_stride

                     : 16 * mb_x + height * mb_y * i_stride;

 

这也就是像素偏移了,通过刚才上面那个像素的偏移值,可以得到每一个宏块的第一个像素点位置

我们分析的是色度,i值是0

pixel *plane_fdec = &h->fdec->plane[i][offset];

还是需要帧场判断的一个东西,对于奇数行和偶数行的一个设置

int fdec_idx = b_mbaff ? (mb_interlaced ? (3 + (mb_y&1)) : (mb_y&1) ? 2 : 4) : !(mb_y&1);

 

/*****************h->intra_boder_backup 变量作用不明晰************************/

 

pixel *intra_fdec = &h->intra_border_backup[fdec_idx][i][mb_x*16];

    int ref_pix_offset[2] = { i_pix_offset, i_pix_offset };

    /* ref_pix_offset[0] references the current field and [1] the opposite field. */

    if( mb_interlaced )

        ref_pix_offset[1] += (1-2*(mb_y&1)) * i_stride;

/********************************8***************************************************/

设置宏块图像的stride 

设置当前宏块的标识  要编码亮度块的第一个像素指针

h->mb.pic.i_stride[i] = i_stride2;

h->mb.pic.p_fenc_plane[i] = &h->fenc->plane[i][i_pix_offset];

 

通过这个变量  亮度色度分开处理,先看亮度 else中

  if( b_chroma )

    {

        h->mc.load_deinterleave_chroma_fenc( h->mb.pic.p_fenc[1], h->mb.pic.p_fenc_plane[1], i_stride2, height );

        memcpy( h->mb.pic.p_fdec[1]-FDEC_STRIDE, intra_fdec, 8*sizeof(pixel) );

        memcpy( h->mb.pic.p_fdec[2]-FDEC_STRIDE, intra_fdec+8, 8*sizeof(pixel) );

        h->mb.pic.p_fdec[1][-FDEC_STRIDE-1] = intra_fdec[-1-8];

        h->mb.pic.p_fdec[2][-FDEC_STRIDE-1] = intra_fdec[-1];

    }

    else

{

宏定义中PIXEL_16X16 = 0 在下面详细分析这个函数 mc中的出事声明

通过这个改变了 h->mb.pic.p_fenc[0] 也就是帧内编码中要用到的那个指针

        h->mc.copy[PIXEL_16x16]( h->mb.pic.p_fenc[i], FENC_STRIDE, h->mb.pic.p_fenc_plane[i], i_stride2, 16 );

        memcpy( h->mb.pic.p_fdec[i]-FDEC_STRIDE, intra_fdec, 24*sizeof(pixel) );

        h->mb.pic.p_fdec[i][-FDEC_STRIDE-1] = intra_fdec[-1];

}

 

如果要进行多次编码的话,或者是场模式,则要fdenc重新设置一些东西 这里暂且不分析

if( b_mbaff || h->mb.b_reencode_mb )

{

    for( int j = 0; j < height; j++ )

        if( b_chroma )

        {

            h->mb.pic.p_fdec[1][-1+j*FDEC_STRIDE] = plane_fdec[-2+j*i_stride2];

            h->mb.pic.p_fdec[2][-1+j*FDEC_STRIDE] = plane_fdec[-1+j*i_stride2];

        }

        else

            h->mb.pic.p_fdec[i][-1+j*FDEC_STRIDE] = plane_fdec[-1+j*i_stride2];

}

 

剩下的就是对于B P 帧中的参考帧设置,暂且不分析,帧内完全分析完成后在

 

 

 

 

 

posted on 2012-05-09 12:48  hatreds  阅读(317)  评论(0编辑  收藏  举报