⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 error_resilience.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 3 页
字号:
        s->current_picture= *s->current_picture_ptr;
    }

    for(i=0; i<2; i++){
        if(pic->ref_index[i])
            memset(pic->ref_index[i], 0, size * sizeof(uint8_t));
    }

    if(s->avctx->debug&FF_DEBUG_ER){
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];

                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
            }
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
        }
    }

#if 1
    /* handle overlapping slices */
    for(error_type=1; error_type<=3; error_type++){
        int end_ok=0;

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

            if(error&(1<<error_type))
                end_ok=1;
            if(error&(8<<error_type))
                end_ok=1;

            if(!end_ok)
                s->error_status_table[mb_xy]|= 1<<error_type;

            if(error&VP_START)
                end_ok=0;
        }
    }
#endif
#if 1
    /* handle slices with partitions of different length */
    if(s->partitioned_frame){
        int end_ok=0;

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

            if(error&AC_END)
                end_ok=0;
            if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
                end_ok=1;

            if(!end_ok)
                s->error_status_table[mb_xy]|= AC_ERROR;

            if(error&VP_START)
                end_ok=0;
        }
    }
#endif
    /* handle missing slices */
    if(s->error_resilience>=4){
        int end_ok=1;

        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
            const int mb_xy= s->mb_index2xy[i];
            int error1= s->error_status_table[mb_xy  ];
            int error2= s->error_status_table[s->mb_index2xy[i+1]];

            if(error1&VP_START)
                end_ok=1;

            if(   error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
               && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
               && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited
                end_ok=0;
            }

            if(!end_ok)
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
        }
    }

#if 1
    /* backward mark errors */
    distance=9999999;
    for(error_type=1; error_type<=3; error_type++){
        for(i=s->mb_num-1; i>=0; i--){
            const int mb_xy= s->mb_index2xy[i];
            int error= s->error_status_table[mb_xy];

            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
                distance++;
            if(error&(1<<error_type))
                distance= 0;

            if(s->partitioned_frame){
                if(distance < threshold_part[error_type-1])
                    s->error_status_table[mb_xy]|= 1<<error_type;
            }else{
                if(distance < threshold)
                    s->error_status_table[mb_xy]|= 1<<error_type;
            }

            if(error&VP_START)
                distance= 9999999;
        }
    }
#endif

    /* forward mark errors */
    error=0;
    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        int old_error= s->error_status_table[mb_xy];

        if(old_error&VP_START)
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
        else{
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
            s->error_status_table[mb_xy]|= error;
        }
    }
#if 1
    /* handle not partitioned case */
    if(!s->partitioned_frame){
        for(i=0; i<s->mb_num; i++){
            const int mb_xy= s->mb_index2xy[i];
            error= s->error_status_table[mb_xy];
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
            s->error_status_table[mb_xy]= error;
        }
    }
#endif

    dc_error= ac_error= mv_error=0;
    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        error= s->error_status_table[mb_xy];
        if(error&DC_ERROR) dc_error ++;
        if(error&AC_ERROR) ac_error ++;
        if(error&MV_ERROR) mv_error ++;
    }
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);

    is_intra_likely= is_intra_more_likely(s);

    /* set unknown mb-type to most likely */
    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        error= s->error_status_table[mb_xy];
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
            continue;

        if(is_intra_likely)
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
        else
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
    }

    /* handle inter blocks with damaged AC */
    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;
            const int mb_type= s->current_picture.mb_type[mb_xy];
            error= s->error_status_table[mb_xy];

            if(IS_INTRA(mb_type)) continue; //intra
            if(error&MV_ERROR) continue;              //inter with damaged MV
            if(!(error&AC_ERROR)) continue;           //undamaged inter

            s->mv_dir = MV_DIR_FORWARD;
            s->mb_intra=0;
            s->mb_skipped=0;
            if(IS_8X8(mb_type)){
                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
                int j;
                s->mv_type = MV_TYPE_8X8;
                for(j=0; j<4; j++){
                    s->mv[0][j][0] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
                    s->mv[0][j][1] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
                }
            }else{
                s->mv_type = MV_TYPE_16X16;
                s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0];
                s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1];
            }

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

            s->mb_x= mb_x;
            s->mb_y= mb_y;
            decode_mb(s);
        }
    }

    /* guess MVs */
    if(s->pict_type==B_TYPE){
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
                int xy= mb_x*2 + mb_y*2*s->b8_stride;
                const int mb_xy= mb_x + mb_y * s->mb_stride;
                const int mb_type= s->current_picture.mb_type[mb_xy];
                error= s->error_status_table[mb_xy];

                if(IS_INTRA(mb_type)) continue;
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
                if(!(error&AC_ERROR)) continue;           //undamaged inter

                s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
                s->mb_intra=0;
                s->mv_type = MV_TYPE_16X16;
                s->mb_skipped=0;

                if(s->pp_time){
                    int time_pp= s->pp_time;
                    int time_pb= s->pb_time;

                    s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
                    s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
                    s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
                    s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
                }else{
                    s->mv[0][0][0]= 0;
                    s->mv[0][0][1]= 0;
                    s->mv[1][0][0]= 0;
                    s->mv[1][0][1]= 0;
                }

                s->dsp.clear_blocks(s->block[0]);
                s->mb_x= mb_x;
                s->mb_y= mb_y;
                decode_mb(s);
            }
        }
    }else
        guess_mv(s);

#ifdef HAVE_XVMC
    /* the filters below are not XvMC compatible, skip them */
    if(s->avctx->xvmc_acceleration) goto ec_clean;
#endif
    /* fill DC for inter blocks */
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
            int dc, dcu, dcv, y, n;
            int16_t *dc_ptr;
            uint8_t *dest_y, *dest_cb, *dest_cr;
            const int mb_xy= mb_x + mb_y * s->mb_stride;
            const int mb_type= s->current_picture.mb_type[mb_xy];

            error= s->error_status_table[mb_xy];

            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?

            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;

            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
            for(n=0; n<4; n++){
                dc=0;
                for(y=0; y<8; y++){
                    int x;
                    for(x=0; x<8; x++){
                       dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
                    }
                }
                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
            }

            dcu=dcv=0;
            for(y=0; y<8; y++){
                int x;
                for(x=0; x<8; x++){
                    dcu+=dest_cb[x + y*(s->uvlinesize)];
                    dcv+=dest_cr[x + y*(s->uvlinesize)];
                }
            }
            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
        }
    }
#if 1
    /* guess DC for damaged blocks */
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
#endif
    /* filter luma DC */
    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);

#if 1
    /* render DC only intra */
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
            uint8_t *dest_y, *dest_cb, *dest_cr;
            const int mb_xy= mb_x + mb_y * s->mb_stride;
            const int mb_type= s->current_picture.mb_type[mb_xy];

            error= s->error_status_table[mb_xy];

            if(IS_INTER(mb_type)) continue;
            if(!(error&AC_ERROR)) continue;              //undamaged

            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;

            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
        }
    }
#endif

    if(s->avctx->error_concealment&FF_EC_DEBLOCK){
        /* filter horizontal block boundaries */
        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);

        /* filter vertical block boundaries */
        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
    }

#ifdef HAVE_XVMC
ec_clean:
#endif
    /* clean a few tables */
    for(i=0; i<s->mb_num; i++){
        const int mb_xy= s->mb_index2xy[i];
        int error= s->error_status_table[mb_xy];

        if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
            s->mbskip_table[mb_xy]=0;
        }
        s->mbintra_table[mb_xy]=1;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -