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 帧中的参考帧设置,暂且不分析,帧内完全分析完成后在