在FFMEPG的代码中判断Skip宏块的代码如下:
/* compute cbp */
cbp = 0;
for(i=0;i<6;i++) {
if (s->block_last_index[i] >= 0)
cbp |= 1 << (5 - i);
}
if ( cbp == 0 && !first_mb &&
s->mv_type == MV_TYPE_16X16 &&
(mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||
( s->pict_type == B_TYPE
&& s->mv_dir == s->last_mv_dir &&
(((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0)
)
) {
s->mb_skip_run++;
s->qscale -= s->dquant;
s->skip_count++;
s->misc_bits++;
s->last_bits++;
if(s->pict_type == P_TYPE){
s->last_mv[0][1][0]= s->last_mv[0][0][0]=
s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
}
} else {
......
以P帧为例(相对来讲简单一些),满足的条件是:
cbp=0:cbp为0
!first_mb:不是第一个宏块
(mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)):不是右和下边界上的宏块,并且编码类型为MPEG
((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||:P帧,并且两个运行矢量均为0
后面几个条件比较好理解,这里看一下第一个条件。
cbp是coded block pattern的缩写。
cbp一共6bit,高2bit表示cbpc(2:cb、cr中至少一个4x4块的AC系数不全为0;1:cb、cr中至少一个2x2的DC系数不全为0;0:所有色度系数全0)
低4bit分别表示4个8x8亮度块,其中从最低一位开始的4位分别对应00,10,01,11位置的8*8亮度块。如果某位为1,表示该对应8*8块的4个4*4块中至少有一个的系数不全为0。
ICBPTAB[0] = 0 (00 0000)表示既没有亮度系数,也没有色差系数
ICBPTAB[1] = 16 (01 0000)表示没有亮度系数,有色差直流系数(没有交流系数)
ICBPTAB[2] = 32 (10 0000)表示没有亮度系数,有色差交流系数(可能含有直流系数)
ICBPTAB[3] = 15 (00 1111)表示有亮度系数,没有色差系数
ICBPTAB[4] = 31 (01 1111)表示有亮度系数,有色差直流系数(没有交流系数)
ICBPTAB[5] = 47 (10 1111)表示有亮度系数,有色差交流系数(可能含有直流系数)
在上面的CODE中,/* compute cbp */下面的几行就是计算这个cbp了。
/* compute cbp */
cbp = 0;
for(i=0;i<6;i++) {
if (s->block_last_index[i] >= 0)
cbp |= 1 << (5 - i);
}
if ( cbp == 0 && !first_mb &&
s->mv_type == MV_TYPE_16X16 &&
(mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&
((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||
( s->pict_type == B_TYPE
&& s->mv_dir == s->last_mv_dir &&
(((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0)
)
) {
s->mb_skip_run++;
s->qscale -= s->dquant;
s->skip_count++;
s->misc_bits++;
s->last_bits++;
if(s->pict_type == P_TYPE){
s->last_mv[0][1][0]= s->last_mv[0][0][0]=
s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
}
} else {
......
以P帧为例(相对来讲简单一些),满足的条件是:
cbp=0:cbp为0
!first_mb:不是第一个宏块
(mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)):不是右和下边界上的宏块,并且编码类型为MPEG
((s->pict_type == P_TYPE && (motion_x | motion_y) == 0) ||:P帧,并且两个运行矢量均为0
后面几个条件比较好理解,这里看一下第一个条件。
cbp是coded block pattern的缩写。
cbp一共6bit,高2bit表示cbpc(2:cb、cr中至少一个4x4块的AC系数不全为0;1:cb、cr中至少一个2x2的DC系数不全为0;0:所有色度系数全0)
低4bit分别表示4个8x8亮度块,其中从最低一位开始的4位分别对应00,10,01,11位置的8*8亮度块。如果某位为1,表示该对应8*8块的4个4*4块中至少有一个的系数不全为0。
ICBPTAB[0] = 0 (00 0000)表示既没有亮度系数,也没有色差系数
ICBPTAB[1] = 16 (01 0000)表示没有亮度系数,有色差直流系数(没有交流系数)
ICBPTAB[2] = 32 (10 0000)表示没有亮度系数,有色差交流系数(可能含有直流系数)
ICBPTAB[3] = 15 (00 1111)表示有亮度系数,没有色差系数
ICBPTAB[4] = 31 (01 1111)表示有亮度系数,有色差直流系数(没有交流系数)
ICBPTAB[5] = 47 (10 1111)表示有亮度系数,有色差交流系数(可能含有直流系数)
在上面的CODE中,/* compute cbp */下面的几行就是计算这个cbp了。