===========第一步:确定相邻块===========
MV 预测以宏块分割(或亚宏块分割,如果宏块存在亚分割)为单位,同一个宏块分割(或亚宏块分割)内所有 4*4 块 MV 预测值相同。以每个宏块分割(或亚宏块分割)的左上角像素 pixel1 和右上角像素 pixel2 为参考点来确定相邻块则:
pixel1 左侧相邻像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 A
pixel1 上方相邻像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 B
pixel2 右上对角线像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 C
pixel1 左上对角线像素所在 4*4 块为当前宏块分割(或亚宏块分割)的相邻块 D
以最复杂的 8*8 宏块分割类型为例(此时只存在亚宏块分割),分析如下:
假设图中黑色框表示宏块、每个绿色框表示一个 4*4 块、每个红色框表示一个 8*8 块。当前宏块的宏块分割模式为 8*8(如图中红色线),其亚宏块分割模式分别为:第一个 8*8 块为 8*8,第二个 8*8 块为 4*4(如图中蓝色线),第三个 8*8 块为 4*8(如图中蓝色线),第四个 8*8 块为 8*4(如图中蓝色线)。则按照上述方法来确定相邻块的方法如下:
第一个预测对象为第一个 8*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 7 号 4*4 块,B 为 2 号 4*4 块,C 为 4 号 4*4 块,D 为 1 号 4*4 块。9、14、15 与 8 具有相同 MV 预测值
第二个预测对象为第二个 8*8 块的第一个 4*4 块,即 10 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 9 号4*4块,B 为 4 号4*4块,C 为 5 号 4*4 块, D 为 3 号 4*4 块
第三个预测对象为第二个 8*8 块的第二个 4*4 块,即 11 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 10 号4*4块,B 为 5 号4*4块,C 为 6 号 4*4 块,D 为 4 号 4*4 块
第四个预测对象为第二个 8*8 块的第三个 4*4 块,即 16 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 15 号4*4块,B 为 10 号4*4块,C 为 11 号 4*4 块,D 为 9 号 4*4 块
第五个预测对象为第二个 8*8 块的第四个 4*4 块,即 17 号块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 16 号4*4块,B 为 11 号4*4块,C 为 12 号 4*4 块,D 为 10 号 4*4 块
第六个预测对象为第三个 8*8 块的第一个 4*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 19 号 4*4 块,B 为 14 号 4*4 块,C 为 15 号 4*4 块,D 为 13 号 4*4 块。26 与 20 具有相同 MV 预测值
第七个预测对象为第三个 8*8 块的第二个 4*8 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 20 号 4*4 块,B 为 15 号 4*4 块,C 为 16 号 4*4 块,D 为 14 号 4*4 块。27 与 21 具有相同 MV 预测值
第八个预测对象为第四个 8*8 块的第一个 8*4 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 21 号 4*4 块,B 为 16 号 4*4 块,C 为 18 号 4*4 块,D 为 15 号 4*4 块。23 与 22 具有相同 MV 预测值
第九个预测对象为第四个 8*8 块的第二个 8*4 块,以其左上角像素 pixel1 和右上角像素 pixel2 为参考点,则:A 为 27 号 4*4 块,B 为 22 号 4*4 块,C 为 24 号 4*4 块,D 为 21 号 4*4 块。29 与 28 具有相同 MV 预测值
===========第二步:确定 A、B、C 的可用性===========
根据 A、B、C 所在宏块是否存在或者是否允许参与预测来判断。如果 C 不可用,采用 D 代替 C
===========第三步:预测 MV ===========
1、如果 A、B、C 三个参考块中只有一个与当前预测对象为同一参考帧,则选取该参考块的 MV 作为最终 MV 预测值
2、当前宏块是否为 8*16 或者 16*8 分割:
(1)、如果当前宏块为 8*16 分割类型:
对于左边 8*16 分割,如果 A 与当前分割为同一参考帧,则采用 A 的 MV 为该分割的最终 MV 预测值
对于右边 8*16 分割,如果 C 与当前分割为同一参考帧,则采用 C 的 MV 为该分割的最终 MV 预测值
(2)、如果当前宏块为 16*8 分割类型:
对于上边 16*8 分割,如果 B 与当前分割为同一参考帧,则采用 B 的 MV 为该分割的最终 MV 预测值
对于下边 16*8 分割,如果 A 与当前分割为同一参考帧,则采用 A 的 MV 为该分割的最终 MV 预测值
3、其余情况并且 B、C 中有一个可用或者两者都可用,则采用中值预测(取 A、B、C 三者中MV的中值为最终 MV 预测值)
4、其余情况并且 B、C 皆不可用,则采用 A 的 MV 为最终 MV 预测值
【注】:1、宏块分割时的相邻块确定方法与第一步所述过程雷同:16*16 相当于 8*8,8*16、16*8 分别相当于 4*8、8*4
2、对于不可用的相邻块,其 MV 仍然可能参与 MV 预测,但其值为 0。例如:A 不可用,B、C 可用,则最终可能仍然是在 A、B、C 中取中值,但此时 A 的 MV 为 0;
3、对于不可用的相邻块,其参考帧索引被设置为 -1,即必然与当前预测对象非同一参考帧;
4、可以验证:同时满足第三步的第一、第二两种情况时,按第一种情况计算 MV 预测值与按第二种情况计算 MV 预测值等效;
5、该预测过程即为标准 8.4.1.3 小节的内容,在 JM86 中对应的代码为 SetMotionVectorPredictor 函数;
6、MBAFF 情况下的相邻块均指对应位置(co-locate)块。
我有一点想问,为什么SetMotionVectorPredictor 函数只在 img->type==B_SLICE && img->direct_type && (IS_DIRECT (currMB) || (IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))) 这个条件下进行,其他条件下为什么不用呢? 另外,我最近在看decode_one_macroblock这个函数,感觉跟标准上定义的有出入,比如上面这个问题,还有一些参数看不明白,字面上的意思与实际用途不符合,好郁闷。 |
还是上面的问题,在条件里面IS_P8x8(currMB)在这里做何意?定义IS_P8x8(MB)=((MB)->mb_type==P8x8) P8x8=8。这里我就是想不通,标准里面mb_type=8(B Slice情况下)表示B_L0_L1_16x8。而P条带里面P8x8的mb_type值为3,任何一个都不为8,真的是不明白啊。
还有后面的currMB->b8mode又是指什么呢,按照条件,任何一个currMB->b8mode[x]=0条件就满足,这又是什么意思呢?
我在decode_one_macroblock这个函数里琢磨了好几天了,一直为一些细节烦恼,又找不到人讨论,快崩溃啦,帮帮我~~
本帖最后由 firstime 于 2009-3-23 09:49 PM 编辑 1、为什么SetMotionVectorPredictor 函数只在 img->type==B_SLICE && img->direct_type && (IS_DIRECT (currMB) || (IS_P8x8(currMB) && !(currMB->b8mode[0] && currMB->b8mode[1] && currMB->b8mode[2] && currMB->b8mode[3]))) 这个条件下进行,其他条件下为什么不用呢? ——你看错了哈。JM86 代码中一共有 7 处调用该函数。 2、IS_P8x8(currMB)在这里做何意? ——说明你没有看我的这篇帖子“JM 代码中宏块类型宏定义的说明 ” 3、currMB->b8mode又是指什么 ——说明你不但没看城里汉子的那篇帖子“对几个重要问题的详细阐述”,也没有查看以前的聊天记录,更没有看我加了注释的代码。 |
根据B,C的位置决定方法,本来的情况是B不可用的时候C也肯定不可用,但是由于有第二步中的D代替C这一条,B和C的可用不可用配对方式就似乎变得复杂了,但仔细按照MB可能的位置一一分析其实并不复杂,因为可以通过第三步前三种情况到达第4种情况(默认partitionType不是16X8和8X16)的,只能是当前MB是frame内第一行MB的情况。(在最后一列位置(除去同属于第一行的右上角位置)的时候,虽然C不可用,但是第2步中D代替了C,所以变成B和C同时可用,这样就满足第三步中第三个条件了)
再来看第一行,对于所有位于第一行的MB,BC都是不存在的。 而除了位于最左上角的情况A都是存在,只有A存在的时候用A是理所当然。 而最左上角A也不存在,即可以理解为A,B,C都为(0,0),这样,A = (0,0) = Median((0,0),(0,0),(0,0)) = Median(A,B,C), 两者等效。
呵呵,不知道这么想正确不,还请指正。
还有,非常感谢这段分析,受益匪浅~