两个局部变量i_mb_x,i_mb_y,全局的控制一个slice中的每个宏块的位置
没有帧场自适应,所以初始化两个都为0
在一个大的循环中
While (1)
{
/********************对于当前宏块编码完成*******************/
//对于两个变量进行更新 然后进行写一个宏块的编码
if( SLICE_MBAFF )
{
i_mb_x += i_mb_y & 1;
i_mb_y ^= i_mb_x < h->mb.i_mb_width;
}
else
i_mb_x++;
if( i_mb_x == h->mb.i_mb_width )
{
i_mb_y++;
i_mb_x = 0;
}
}
在while(1)循环中首先对于宏块级做操作的是给宏块做定位操作,就是对于当前宏块,定位它的左右上下几个号宏块的坐标和存在情况是通过函数
if( SLICE_MBAFF )
x264_macroblock_cache_load_interlaced( h, i_mb_x, i_mb_y );
else
x264_macroblock_cache_load_progressive( h, i_mb_x, i_mb_y );
实现的。我们使用的是progressive模式,所以进入第二个函数。直接的调用了另外一个函数
void x264_macroblock_cache_load_progressive( x264_t *h, int mb_x, int mb_y )
{
x264_macroblock_cache_load( h, mb_x, mb_y, 0 );
}
最后一个参数为0或者为1就是为了区别interlaced和progressive两种模式。进入这个函数
首先第一个调用的函数x264_macroblock_cache_load_neighbours( h, mb_x, mb_y, b_mbaff );
这个函数就是为了给周围宏块坐标赋值比如h->mb.i_mb_x,h->mb.i_mb_top_xy等等。
这里总结下,进行赋值的变量总结
h->mb.i_mb_x = mb_x; //当前宏块x坐标
h->mb.i_mb_y = mb_y; //当前宏块的y坐标
h->mb.i_mb_xy = mb_y * h->mb.i_mb_stride + mb_x; //当前宏块的xy坐标也就是第几个
上面几个坐标都是当宏块大小为16x16的时候,下面几个变量赋值是当宏块是8x8的时候
h->mb.i_b8_xy = 2*(mb_y * h->mb.i_b8_stride + mb_x); //8x8时候宏块的xy位置
h->mb.i_b4_xy = 4*(mb_y * h->mb.i_b4_stride + mb_x); //4x4时候xy位置
//三种情况的左边的坐标值,但是8x8情况和4x4情况都是以16x16为大小的话的第一个宏块就是比如一个行是16但是当行是4的时候不是h->mb.left_b4不是4相邻的左边一个块,而是相邻的以16为大小的第一个宏块
http://hi.baidu.com/ilovejoy/blog/item/0a361fd364dc8038970a169d.html 里面图像很直观
left[0] = left[1] = h->mb.i_mb_xy - 1;
h->mb.left_b8[0] = h->mb.left_b8[1] = h->mb.i_b8_xy - 2;
h->mb.left_b4[0] = h->mb.left_b4[1] = h->mb.i_b4_xy - 4;
下面这几个有一些不太理解他们的赋值
/*首先将它的i_neighbour_frame值或操作这里有点不是很明白,也就是偶数帧的话相邻帧加1,奇数帧的话相邻帧不变??
h->mb.i_neighbour_frame |= MB_LEFT;
h->mb.i_mb_left_xy[0] = left[0]; //应该就是它做相邻x坐标
h->mb.i_mb_left_xy[1] = left[1];
//类型存储进行没有找到 应该在别的函数里面已经赋值,宏块的类型在前面函数已经决定了貌似。
h->mb.i_mb_type_left[0] = h->mb.type[h->mb.i_mb_left_xy[0]];
h->mb.i_mb_type_left[1] = h->mb.type[h->mb.i_mb_left_xy[1]];
以上都是在 if(mb_x > 0)情况下进行。应该不包含每个宏块的第一个最左边宏块
然后后面有个多线程判断条件如果
if( (h->i_threadslice_start >> mb_interlaced) != (mb_y >> mb_interlaced) ) 里面的判定条件意思有点不是很明确
然后继续开始对另外一些东西进行赋值
h->mb.i_neighbour_frame |= MB_TOP; //这里赋值始终有点疑惑,这里加了2对有些情况
h->mb.i_mb_top_xy = top;
h->mb.i_mb_top_y = top_y;
h->mb.i_mb_type_top = h->mb.type[h->mb.i_mb_top_xy];
加菲的博客
另外一个人的博客
http://blog.csdn.net/szu030606/article/details/5936391
Ffmpeg那个完整网页
http://bbs.chinavideo.org/viewthread.php?tid=1284
然后开始就是scan8中的一些赋值,但是这里更新的完全不一样了 首先scan8的大小改变了
static const uint8_t x264_scan8[16*3 + 3] =
{
4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8, 这里是原本有的定位4x4的问题的内容
4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
4+11*8, 5+11*8, 4+12*8, 5+12*8,
6+11*8, 7+11*8, 6+12*8, 7+12*8,
4+13*8, 5+13*8, 4+14*8, 5+14*8,
6+13*8, 7+13*8, 6+14*8, 7+14*8,
0+ 0*8, 0+ 5*8, 0+10*8
};
这个是对照注释,scan8作用仍然是原来那样,但是数组的排列进行了改变
/* Scan8 organization:
* 0 1 2 3 4 5 6 7
* 0 DY y y y y y
* 1 y Y Y Y Y
* 2 y Y Y Y Y
* 3 y Y Y Y Y
* 4 y Y Y Y Y
* 5 DU u u u u u
* 6 u U U U U
* 7 u U U U U
* 8 u U U U U
* 9 u U U U U
* 10 DV v v v v v
* 11 v V V V V
* 12 v V V V V
* 13 v V V V V
* 14 v V V V V
* DY/DU/DV are for luma/chroma DC.