关于MPEG-2中的Skip宏块

在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了。

你可能感兴趣的:(video,Codec)