1。A:JM86里面,GetStrength这个函数中下面这个数组有什么作用呢??
byte BLK_NUM[2][4][4] = {{{0,4,8,12},{1,5,9,13},{2,6,10,14},{3,7,11,15}},{{0,1,2,3},{4,5,6,7},{8,9,10,11},{12,13,14,15}}} ;
blk_y = (mb_y<<2) + (blkQ >> 2) ;
blk_x = (mb_x<<2) + (blkQ & 3) ;
这是计算子块的坐标的么,mb_y为什么有乘以4呢?还有就是blkQ >> 2和blkQ & 3起什么作用??
答:把 BLK_NUM[2][4][4] 前面四个一维数组和后面四个一维数组分别写成矩阵形式:
0 4 8 12 0 1 2 3 1 5 9 13 4 5 6 7 2 6 10 14 8 9 10 11 3 7 11 15 12 13 14 15
观察一下特点。再联想一下滤波的顺序——首先是垂直边界从左到右,然后是水平边界从上到下。可以推断:第一矩阵就是用来标志边界滤波强度每个 4*4 块的垂直边界的计算顺序,第二个矩阵就是用来标志边界滤波强度每个 4*4 块的水平边界的计算顺序。
宏块坐标乘 4 表示什么呢?首先我们想一下,什么东西的坐标与宏块坐标存在 4 倍关系?是的,每个宏块的第一个 4*4 块的坐标与宏块坐标存在 4 倍关系,那么宏块坐标乘 4 当然就是表示得到每个宏块的第一个 4*4 块的坐标了。后面再进行一些 “+” 的操作得到的数值可能就应该是宏块内某个 4*4 块的坐标了(以整幅图像左上角为原点)。
至于 blkQ >> 2和 blkQ & 3起什么作用,这个当然首先要看 blkQ 是什么意思了。然后把 blkQ 可能出现的值全部进行 &3 操作,一个个列在纸上,看看有什么特点。然后再推断,验证。
A:void DeblockMb(ImageParameters *img, byte **imgY, byte ***imgUV, int mb_y, int mb_x) { int EdgeCondition; int dir, edge, QP ; 各个参数的定义? |
dir=0: vertical edges; dir=1: horicontal edges
EdgeCondition:考虑左宏块或上宏块是否可用
edge:就是
滤波的时候的横向的4条或纵向的4条
A:MbP = (edge)? MbQ : ((dir)? (MbQ -(img->width>>4)) : (MbQ-1) ) ; 这一句怎么理解
非MBAFF模式下:
对于第0条边,垂直情况取左相邻MB的QP,所以MbQ-1;水平情况取上相邻QP,所以是MbQ -(img->width>>4),当前MB地址减一行的MB数,就是上相邻MB地址。
对于其他边,QP就取当前MB的
A;请教达人,在x264编码实现的过程中,有没有实现环内去块滤波,看了很久的源码也没有发现有这部分功能的实现,另外其运动估计部分是1/4像素运动估计么?
多谢提示,刚刚在源码中找到了关于环形滤波的部分,原来在编码完成后,参考帧的更新中有deblocking filter /* ---------------------- Update encoder state ------------------------- */ /* update rc */ x264_cpu_restore( h->param.cpu ); x264_ratecontrol_end( h, i_frame_size * 8 ); /* handle references */ if( i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE ) x264_reference_update( h ); #ifdef DEBUG_DUMP_FRAME else x264_fdec_deblock( h ); #endif x264_frame_put( h->frames.unused, h->fenc ); 我想知道,一个frame图象结构里已经有plane保存数据了,为什么还要有filtered啊。搞的头大死了,尤其在看帧间预测的时候,希望大家帮下忙,谢谢。原来是放半像素插值的,呵呵,终于弄懂了。 为什么在x264的编码里面不对B帧进行滤波呢?就因为B帧不作为参考帧吗?可还是要输出的啊,不解,希望大家帮下忙,谢谢. 因为你在做开发的时候才需要输出编码端的重构图像作参考。实际应用中,谁会把编码的重构图像输出呢?输出又有什么用呢? if (p->MbaffFrameFlag && mb_y==16 && MbQ->mb_field) filterTopMbEdgeFlag = 0; 这个判断是针对域宏块对来说的么?为什么mb_y要等于16而不是0呢? 对照标准 8.7 小节中变量 filterTopMbEdgeFlag 的推倒过程去理解。标准规定了 filterTopMbEdgeFlag = 0 有 5 种情况,自己去对照一下看该段代码的功能与哪种情况比较吻合。 我在查阅了标准,他是这样解释的: If any of the following conditions is true, the variable filterTopMbEdgeFlag is set equal to 0. – MbaffFrameFlag is equal to 0 and CurrMbAddr is less than PicWidthInMbs. – MbaffFrameFlag is equal to 1, ( CurrMbAddr >> 1 ) is less than PicWidthInMbs, and the macroblock CurrMbAddr is a field macroblock. – MbaffFrameFlag is equal to 1, ( CurrMbAddr >> 1 ) is less than PicWidthInMbs, the macroblock CurrMbAddr is a frame macroblock, and CurrMbAddr % 2 is equal to 0. – disable_deblocking_filter_idc for the slice that contains the macroblock CurrMbAddr is equal to 1 – disable_deblocking_filter_idc for the slice that contains the macroblock CurrMbAddr is equal to 2 and the macroblock mbAddrB is not available 就是第二条 看了城里汉子的帖子,并且在编码端找到了 static const int b8_mode_table[6] = {0, 4, 5, 6, 7}; // DO NOT CHANGE ORDER !!! static const int mb_mode_table[7] = {0, 1, 2, 3, P8x8, I16MB, I4MB}; // DO NOT CHANGE ORDER !!!
疑问一:b8_mode_table只有5个元素,为什么这边数组长度定义了6?
疑问二:在解码端ercWriteMBMODEandMV()函数中,有这样的判断 pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA : currMB->b8mode==IBLOCK ? REGMODE_INTRA_8x8 : currMB->b8mode==0 ? REGMODE_INTER_COPY : currMB->b8mode==1 ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
显然这边的currMB->b8mode值应该是在mb_mode_table[7]中,但是城里汉子说b8Mode划分定在表格b8_mode_table中?
疑问三:能不能解释下mb_mode_table[7]各个值的意义,我不太明白?
疑问四:currMB->mb_type的取值是划分定在表格mb_mode_table[7]中的吗? 1、b8_mode_table只用了5个元素。第6个空间一直没用到,程序员的问题 2、保存宏块模式mb_type时,都是以8*8为单位。比如16*16编码,那么其4个8*8块的模式都记录为1。但不代表1就应该是b8_mode_table中的值。如果是p8*8模式,就要分别其4个8*8的具体模式(b8_mode_table中的一种), 3、分别是direct 8*8,8*8,8*4,4*8,4*4模式 4、见2
|