ffmpeg中guess_mv的分析

本文详细分析了FFmpeg中guess_mv函数的实现,该函数用于处理H.264编码视频中错误宏块的运动矢量。通过错误隐藏策略,guess_mv尝试修复损坏的MV,以提高播放质量。函数主要通过比较相邻宏块的MV并选择最佳匹配,以减少视觉失真。
摘要由CSDN通过智能技术生成
static void guess_mv(MpegEncContext *s){
    uint8_t fixed[s->mb_stride * s->mb_height];
#define MV_FROZEN    3
#define MV_CHANGED   2
#define MV_UNCHANGED 1
    const int mb_stride = s->mb_stride;
    const int mb_width = s->mb_width;
    const int mb_height= s->mb_height;
    int i, depth, num_avail;
    int mb_x, mb_y, mot_step, mot_stride;

    set_mv_strides(s, &mot_step, &mot_stride); //!< mot_step = 4, mot_stride = s->b4_stride

    num_avail=0;
    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[ i ];
        int f=0;
        int error= s->error_status_table[mb_xy];

        if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
        if(!(error&MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV

        fixed[mb_xy]= f;
        if(f==MV_FROZEN)
            num_avail++;
    }

    if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){ //!< 不使用错误隐藏或者宏块可用数少
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
                const int mb_xy= mb_x + mb_y*s->mb_stride;

                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue; 
                if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; //!< mv ok

                s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
                s->mb_intra=0;
                s->mv_type = MV_TYPE_16X16;
                s->mb_skipped=0;

                s->dsp.clear_blocks(s->block[0]);

                s->mb_x= mb_x;
                s->mb_y= mb_y;
                s->mv[0][0][0]= 0;
                s->mv[0][0][1]= 0;
                decode_mb(s, 0);
            }
        }
        return;
    }

    for(depth=0;; depth++){
        int changed, pass, none_left;

        none_left=1;
        changed=1;
        for(pass=0; (changed || pass<2) && pass<10; pass++){ //!< pass和changed用于控制迭代次数:changed || pass < 2,如果经历了pass=0
            int mb_x, mb_y;									 //!< 和pass=1两次迭代后(刚好做完一整帧的错误隐藏),changed仍为0,即实际没有宏块的mv被修正,
			int score_sum=0;								 //!< 则没有继续下一轮迭代的必要;pass < 10,控制总迭代次数不超过10次

            changed=0;
            for(mb_y=0; mb_y<s->mb_height; mb_y++){
                for(mb_x=0; mb_x<s->mb_width; mb_x++){
                    const int mb_xy= mb_x + mb_y*s->mb_stride;
                    int mv_predictor[8][2]={
  {0}};
                    int re
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值