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,
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
};
static ALWAYS_INLINE int x264_mb_predict_intra4x4_mode( x264_t *h, int idx )
{
const int ma = h->mb.cache.intra4x4_pred_mode[x264_scan8[idx] - 1];
const int mb = h->mb.cache.intra4x4_pred_mode[x264_scan8[idx] - 8];
const int m = X264_MIN( x264_mb_pred_mode4x4_fix(ma),
x264_mb_pred_mode4x4_fix(mb) );
if( m < 0 )
return I_PRED_4x4_DC;
return m;
}
/* 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.
*/
int i_pred_mode = x264_mb_predict_intra4x4_mode( h, 4*idx );
// 对于8x8的宏块, idx = 0, 1, 2, 3
// 对于idx = 1, 传入参数为idx = idx * 4 = 4,(如上)
// x264_scan8[4] = 6 + 1 * 8,
// 上述的Y便表示为一个4x4块
// idx = 1表示第二个8x8块,其刚好对应
// 着第三个4x4块, 即scan8 layout中的
// 第一行第六列
// 对于idx = 2, 传入参数为idx = idx * 4 = 8,
// x264_scan8[8] = 4 + 3 * 8,
// 上述的Y便表示为一个4x4块
// idx = 2表示第三个8x8块,其刚好对应
// 着第9个4x4块, 即scan8 layout中的
// 第三行第四列
// 对于idx = 3, 传入参数为idx = idx * 4 = 12,
// x264_scan8[12] = 6 + 3 * 8,
// 上述的Y便表示为一个4x4块
// idx = 3表示第四个8x8块,其刚好对应
// 着第11个4x4块, 即scan8 layout中的
// 第三行第六列
所以x264_scan8[idx] - 1表示其左边的宏块
x264_scan8[idx] - 8便是其顶部的宏块,
两者都是以4x4宏块为计量单位的。