Revision 46b4feec libavcodec/error_resilience.c

View differences:

libavcodec/error_resilience.c
26 26
#include "avcodec.h"
27 27
#include "dsputil.h"
28 28
#include "mpegvideo.h"
29
#include "common.h"
29 30

  
30 31
/**
31 32
 * replaces the current MB with a flat dc only version.
......
580 581
    return is_intra_likely > 0;    
581 582
}
582 583

  
583
void ff_error_resilience(MpegEncContext *s){
584
void ff_er_frame_start(MpegEncContext *s){
585
    if(!s->error_resilience) return;
586

  
587
    memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_num*sizeof(uint8_t));
588
}
589

  
590
/**
591
 * adds a slice.
592
 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
593
 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
594
 *               error of the same type occured
595
 */
596
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
597
    const int start_xy= clip(startx + starty * s->mb_width, 0, s->mb_num-1);
598
    const int end_xy  = clip(endx   + endy   * s->mb_width, 0, s->mb_num);
599
    const int mb_count= end_xy - start_xy;
600
    int mask= -1;
601
    
602
    if(!s->error_resilience) return;
603

  
604
    mask &= ~VP_START;
605
    if(status & (AC_ERROR|AC_END)) mask &= ~(AC_ERROR|AC_END);
606
    if(status & (DC_ERROR|DC_END)) mask &= ~(DC_ERROR|DC_END);
607
    if(status & (MV_ERROR|MV_END)) mask &= ~(MV_ERROR|MV_END);    
608

  
609
    if(mask == ~0x7F){
610
        memset(&s->error_status_table[start_xy], 0, mb_count * sizeof(uint8_t));
611
    }else{
612
        int i;
613
        for(i=start_xy; i<end_xy; i++){
614
            s->error_status_table[i] &= mask;
615
        }
616
    }
617

  
618
    s->error_status_table[start_xy] |= VP_START;
619
    
620
    if(end_xy < s->mb_num){
621
        s->error_status_table[end_xy] &= mask;
622
        s->error_status_table[end_xy] |= status;
623
    }
624
}
625

  
626
void ff_er_frame_end(MpegEncContext *s){
584 627
    int i, mb_x, mb_y, error, error_type;
585 628
    int distance;
586 629
    int threshold_part[4]= {100,100,100};
587 630
    int threshold= 50;
588 631
    int is_intra_likely;
632
    int num_end_markers=0;
633
    
634
    if(!s->error_resilience) return;
635

  
636
    error=0;
637
    for(i=0; i<s->mb_num; i++){
638
        int status= s->error_status_table[i];
639
        
640
        if(status==0) continue;
641

  
642
        if(status&(DC_ERROR|AC_ERROR|MV_ERROR))
643
            error=1;
644
        if(status&VP_START){
645
            if(num_end_markers) 
646
                error=1;
647
            num_end_markers=3;
648
        }
649
        if(status&AC_END)
650
            num_end_markers--;
651
        if(status&DC_END)
652
            num_end_markers--;
653
        if(status&MV_END)
654
            num_end_markers--;
655
    }
656
    if(num_end_markers==0 && error==0)
657
        return;
658

  
659
    fprintf(stderr, "concealing errors\n");
660

  
661
    if(s->avctx->debug&FF_DEBUG_ER){    
662
        for(i=0; i<s->mb_num; i++){
663
            int status= s->error_status_table[i];
664
            
665
            if(i%s->mb_width == 0) printf("\n");
666
            printf("%2X ", status); 
667
        }
668
    }
589 669
    
590 670
#if 1
591 671
    /* handle overlapping slices */

Also available in: Unified diff