工具: foreman_qcif.yuv, JM8.6, H.264visa. 下面仅讨论第一帧第一个宏块MB(16 * 16)的亮度Y分量.
步骤1:用JM8.6编码foreman_qcif.yuv的第一帧, 得到test.264,用H.264visa打开test.264, 然后用H.264visa打开foreman_qcif.yuv. 从H.264visa中的结果可以看出,第一帧的大部分宏块都是4*4预测的,只有5个宏块采用的是16*16预测的., 这5个宏块的特点也都很明显:非常平滑.
步骤2:给出几个重要的矩阵,然后分析这样一个关系:
orgMB - predictMB = encoderResMB ------> max(0, min(255, decoderResMB + predictMB) )= preFilterMB
( 编 码 端) ( 解 码 端)
原始的foreman_qcif.yuv在H.264visa中的结果是:(orgMB)
====================== Y Data ======================
+----------------+----------------+----------------+----------------+
| 43,216,254,249,|251,254,254,253,|251,252,254,254,|254,254,254,253,|
| 49,198,193,211,|228,205,213,185,|211,207,186,248,|198,203,208,183,|
| 48,194,177,171,|197,173,185,136,|191,195,138,179,|142,176,177,135,|
| 46,214,225,169,|177,189,198,160,|203,208,177,165,|173,196,191,156,|
+----------------+----------------+----------------+----------------+
| 41,185,208,180,|203,228,226,200,|214,226,225,227,|228,225,224,210,|
| 31,130,173,178,|215,230,221,212,|220,229,227,228,|229,227,226,226,|
| 29,119,194,216,|211,213,219,222,|225,223,220,219,|218,218,218,218,|
| 25,126,219,224,|217,224,227,227,|227,226,225,224,|220,220,221,222,|
+----------------+----------------+----------------+----------------+
| 26,131,215,223,|226,225,225,225,|225,226,223,219,|221,221,219,220,|
| 30,136,216,226,|223,224,225,225,|224,221,217,221,|222,219,220,226,|
| 30,136,216,227,|224,224,225,223,|221,218,221,216,|211,224,224,211,|
| 29,135,217,225,|222,221,222,222,|221,209,181,155,|186,210,186,164,|
+----------------+----------------+----------------+----------------+
| 29,134,216,224,|226,230,230,227,|206,177,146,113,|149,162,147,150,|
| 29,135,219,231,|225,201,190,185,|163,144,153,140,|127,143,165,184,|
| 30,139,210,192,|165,142,134,133,|143,141,129,138,|150,178,201,207,|
| 30,125,166,145,|144,154,132,111,|118,161,175,180,|204,214,213,209,|
+----------------+----------------+----------------+----------------+
预测值在H.264visa中的结果为:(predictMB)
====================== Y Data ======================
+----------------+----------------+----------------+----------------+
|128,128,128,128,|238,238,238,238,|255,255,255,255,|245,228,210,192,|
|128,128,128,128,|205,205,205,205,|180,180,180,180,|210,192,174,170,|
|128,128,128,128,|167,167,167,167,|137,137,137,137,|174,170,166,166,|
|128,128,128,128,|160,160,160,160,|169,169,169,169,|166,166,166,166,|
+----------------+----------------+----------------+----------------+
|161,161,161,161,|179,189,182,169,|201,201,201,201,|219,219,219,219,|
|161,161,161,161,|184,185,175,169,|214,214,214,214,|227,227,227,227,|
|161,161,161,161,|189,182,169,169,|216,216,216,216,|219,219,219,219,|
|161,161,161,161,|185,175,169,169,|229,229,229,229,|227,227,227,227,|
+----------------+----------------+----------------+----------------+
| 28,127,218,229,|224,224,224,224,|227,227,228,227,|224,224,224,224,|
| 28,127,218,229,|224,224,224,224,|224,225,227,227,|214,214,214,214,|
| 28,127,218,229,|224,224,224,224,|224,224,224,225,|212,212,212,212,|
| 28,127,218,229,|224,224,224,224,|224,224,224,224,|165,165,165,165,|
+----------------+----------------+----------------+----------------+
| 33,130,216,224,|231,223,215,194,|204,182,160,142,|127,133,139,147,|
| 33,130,216,224,|215,194,173,162,|160,142,125,120,|139,147,154,165,|
| 33,130,216,224,|173,162,150,150,|125,120,116,116,|154,165,176,176,|
| 33,130,216,224,|150,150,150,150,|116,116,116,116,|176,176,176,176,|
+----------------+----------------+----------------+----------------+
编码端的残差值即为上述两个矩阵相减(orgMB - predictMB),解码端的残差值在H.264visa中为:(decoderResMB)
====================== Y Data ======================
+------------------------+------------------------+------------------------+------------------------+
| -78, 88, 132, 110,| 24, 14, 24, 19,| -8, 7, -3, -4,| 16, 31, 48, 51,|
| -81, 63, 67, 77,| 30, 1, 11, -25,| 19, 24, 6, 59,| -12, 20, 32, 10,|
| -83, 62, 48, 39,| 25, 6, 16, -30,| 54, 46, 4, 44,| -30, 7, 5, -32,|
| -80, 87, 93, 32,| 14, 24, 34, 9,| 31, 37, 7, -3,| 6, 28, 21, -9,|
+------------------------+------------------------+------------------------+------------------------+
| -117, 22, 51, 22,| 25, 35, 38, 32,| 18, 18, 18, 18,| 5, 5, 5, 5,|
| -135, -22, 22, 19,| 32, 43, 50, 45,| 13, 13, 13, 13,| 3, 3, 3, 3,|
| -131, -38, 38, 55,| 20, 35, 48, 47,| 3, 3, 3, 3,| -2, -2, -2, -2,|
| -133, -34, 57, 68,| 27, 43, 60, 60,| -2, -2, -2, -2,| -5, -5, -5, -5,|
+------------------------+------------------------+------------------------+------------------------+
| 5, 3, -2, -5,| 0, 0, 0, 0,| -4, -4, -3, -3,| -5, -6, -5, -2,|
| 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| -2, 5, 14, 15,|
| 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| 0, 14, 15, 3,|
| 5, 3, -2, -5,| 0, 0, 0, 0,| 2, -13, -44, -59,| 23, 35, 24, 0,|
+------------------------+------------------------+------------------------+------------------------+
| -4, -4, 0, 4,| 1, 5, 18, 26,| 0, 0, -2, -34,| 25, 20, 8, 3,|
| 2, 7, 11, 10,| 13, 3, 9, 25,| 6, 7, 25, 26,| -9, -3, 9, 15,|
| 0, 6, -8, -28,| -5, -11, -17, -17,| 16, 20, 12, 16,| -5, 4, 22, 31,|
| -6, -5, -39, -74,| -9, 3, -10, -34,| 6, 43, 55, 60,| 33, 33, 35, 35,|
+------------------------+------------------------+------------------------+------------------------+
解码端的滤波前的值在H.264visa中为:(preFilterMB)
====================== Y Data ======================
+----------------+----------------+----------------+----------------+
| 50,216,255,238,|255,252,255,255,|247,255,252,251,|255,255,255,243,|
| 47,191,195,205,|235,206,216,180,|199,204,186,239,|198,212,206,180,|
| 45,190,176,167,|192,173,183,137,|191,183,141,181,|144,177,171,134,|
| 48,215,221,160,|174,184,194,169,|200,206,176,166,|172,194,187,157,|
+----------------+----------------+----------------+----------------+
| 44,183,212,183,|204,224,220,201,|219,219,219,219,|224,224,224,224,|
| 26,139,183,180,|216,228,225,214,|227,227,227,227,|230,230,230,230,|
| 30,123,199,216,|209,217,217,216,|219,219,219,219,|217,217,217,217,|
| 28,127,218,229,|212,218,229,229,|227,227,227,227,|222,222,222,222,|
+----------------+----------------+----------------+----------------+
| 33,130,216,224,|224,224,224,224,|223,223,225,224,|219,218,219,222,|
| 33,130,216,224,|224,224,224,224,|221,220,217,214,|212,219,228,229,|
| 33,130,216,224,|224,224,224,224,|221,219,214,212,|212,226,227,215,|
| 33,130,216,224,|224,224,224,224,|226,211,180,165,|188,200,189,165,|
+----------------+----------------+----------------+----------------+
| 29,126,216,228,|232,228,233,220,|204,182,158,108,|152,153,147,150,|
| 35,137,227,234,|228,197,182,187,|166,149,150,146,|130,144,163,180,|
| 33,136,208,196,|168,151,133,133,|141,140,128,132,|149,169,198,207,|
| 27,125,177,150,|141,153,140,116,|122,159,171,176,|209,209,211,211,|
+----------------+----------------+----------------+----------------+
先来看看第一宏块信息:
(1)分析第一个4*4块. 最初(第一个MB的第一个4*4)块的预测值是什么呢?从H.264visa中可以看出,predictMB[i][j] = 128(0<= i, j <= 3), 而从JM8.6的源码中也可以看出,事实的确如此。源码如下:
if (block_available_up && block_available_left)//上有左有 { // no edge //P_...为重建帧的值,直流预测是 sum(P_...)/n //加上4是为了实现四舍五入 s0 = (P_A + P_B + P_C + P_D + P_I + P_J + P_K + P_L + 4)/(2*BLOCK_SIZE); } else if (!block_available_up && block_available_left)//上空左有 { // upper edge s0 = (P_I + P_J + P_K + P_L + 2)/BLOCK_SIZE; } else if (block_available_up && !block_available_left)//上有左空 { // left edge s0 = (P_A + P_B + P_C + P_D + 2)/BLOCK_SIZE; } else //if (!block_available_up && !block_available_left) { // top left corner, nothing to predict from //上空左空,也就是没有像素可供预测,此时设置预测值为128(很好) //这个相当于是编解码器的一个约定,如果把128改为1280,那么编码效果特差 s0 = 128; }
通过H.264visa发现,orgMB[0][0] = 43(foreman的第一个像素的亮度是43). 那么在编码端得到的残差便是:encoderResMB[0][0] = 43 - 128 = -85, 用H.264visa可以看出,解码端得到的残差是decoderResMB[0][0]为-78(有损是必然的),在解码端得到的滤波前的值为preFilterMB[0][0] = -78 + 128 = 50, 这就是解码端的滤波前的值(50和原始的43有一定出入是必然的).以上分析的是i = j =0时候的情况,其实0<= i, j <= 3时的分析方法完全一致.
(2) 分析第二个4*4块,从H.264visa看出,这个4*4块的预测方式是Horizontal的. 第一个4*4块的滤波前的值为preFilterMB[0][3] = 238, preFilterMB[1][3] = 205, preFilterMB[2][3] = 167, preFilterMB[3][3] = 160. 既然第二个4*4采用的是水平预测方式,那么看下该4*4块的预测值到底是不是这四个数字呢?观察发现 predictMB[0][j] = 238, predictMB[1][j] = 205, predictMB[2][j] = 167, predictMB[3][j] = 160(其中4<=j<=7). 嗯,数据高度一致. 剩下的分析方法与(1)中完全一致.
(3) 帧内预测的参考值是参考块的滤波前的值,而不是重建值,这一点与帧间预测不同,因为帧类预测的参考块还没有来得及滤波呢. 这一点也可以用H.264visa进行验证.