Revision 46b4feec

View differences:

libavcodec/avcodec.h
909 909
#define FF_DEBUG_SKIP      0x00000080
910 910
#define FF_DEBUG_STARTCODE 0x00000100
911 911
#define FF_DEBUG_PTS       0x00000200
912
#define FF_DEBUG_ER        0x00000400
912 913
    
913 914
    /**
914 915
     * error.
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 */
libavcodec/h263.c
2760 2760
                    if(dc_pred_dir) dir|=1;
2761 2761
                }
2762 2762
                s->pred_dir_table[xy]= dir;
2763
                
2764
                s->error_status_table[xy]= AC_ERROR;
2765 2763
            }else{ /* P/S_TYPE */
2766 2764
                int mx, my, pred_x, pred_y, bits;
2767 2765
                int16_t * const mot_val= s->motion_val[s->block_index[0]];
......
2790 2788

  
2791 2789
                    if(s->mbintra_table[xy])
2792 2790
                        ff_clean_intra_table_entries(s);
2793

  
2794
                    s->error_status_table[xy]= AC_ERROR;
2795 2791
                    continue;
2796 2792
                }
2797 2793
                cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
......
2815 2811
                    mot_val[0+stride]= mot_val[2+stride]= 0;
2816 2812
                    mot_val[1       ]= mot_val[3       ]=
2817 2813
                    mot_val[1+stride]= mot_val[3+stride]= 0;
2818
                    s->error_status_table[xy]= DC_ERROR|AC_ERROR;
2819 2814
                }else{
2820 2815
                    if(s->mbintra_table[xy])
2821 2816
                        ff_clean_intra_table_entries(s);
......
2864 2859
                            mot_val[1] = my;
2865 2860
                        }
2866 2861
                    }
2867
                    s->error_status_table[xy]= AC_ERROR;
2868 2862
                }
2869 2863
            }
2870 2864
        }
......
2933 2927
                    s->cbp_table[xy]&= 3; //remove dquant
2934 2928
                    s->cbp_table[xy]|= cbpy<<2;
2935 2929
                    s->pred_dir_table[xy]= dir | (ac_pred<<7);
2936
                    s->error_status_table[xy]&= ~DC_ERROR;
2937 2930
                }else if(s->mb_type[xy]&MB_TYPE_SKIPED){
2938 2931
                    s->current_picture.qscale_table[xy]= s->qscale;
2939 2932
                    s->cbp_table[xy]= 0;
......
2968 2961
int ff_mpeg4_decode_partitions(MpegEncContext *s)
2969 2962
{
2970 2963
    int mb_num;
2964
    const int part_a_error= s->pict_type==I_TYPE ? (DC_ERROR|MV_ERROR) : MV_ERROR;
2965
    const int part_a_end  = s->pict_type==I_TYPE ? (DC_END  |MV_END)   : MV_END;
2971 2966
    
2972 2967
    mb_num= mpeg4_decode_partition_a(s);    
2973
    if(mb_num<0)
2968
    if(mb_num<0){
2969
        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
2974 2970
        return -1;
2971
    }
2975 2972
    
2976 2973
    if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){
2977 2974
        fprintf(stderr, "slice below monitor ...\n");
2975
        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
2978 2976
        return -1;
2979 2977
    }
2980 2978

  
......
2984 2982
        if(get_bits(&s->gb, 19)!=DC_MARKER){
2985 2983
            fprintf(stderr, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y);
2986 2984
            return -1;
2987
        }else
2988
            s->error_status_table[s->mb_x + s->mb_y*s->mb_width-1]|= MV_END|DC_END;
2985
        }
2989 2986
    }else{
2990 2987
        if(get_bits(&s->gb, 17)!=MOTION_MARKER){
2991 2988
            fprintf(stderr, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y);
2992 2989
            return -1;
2993
        }else
2994
            s->error_status_table[s->mb_x + s->mb_y*s->mb_width-1]|= MV_END;
2990
        }
2995 2991
    }
2992
    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end);
2996 2993
    
2997 2994
    if( mpeg4_decode_partition_b(s, mb_num) < 0){
2995
        if(s->pict_type==P_TYPE)
2996
            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, DC_ERROR);
2998 2997
        return -1;
2998
    }else{
2999
        if(s->pict_type==P_TYPE)
3000
            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, DC_END);
2999 3001
    }
3000
    
3001
    s->error_status_table[s->mb_x + s->mb_y*s->mb_width-1]|= DC_END;
3002 3002

  
3003 3003
    return 0;        
3004 3004
}
......
3071 3071
        }
3072 3072
    }
3073 3073

  
3074
    s->error_status_table[xy]&= ~AC_ERROR;
3075

  
3076 3074
    /* per-MB end of slice check */
3077 3075

  
3078 3076
    if(--s->mb_num_left <= 0){
......
3096 3094
    int16_t *mot_val;
3097 3095
    static int8_t quant_tab[4] = { -1, -2, 1, 2 };
3098 3096

  
3099
    s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
3100

  
3101 3097
    if(s->mb_x==0) PRINT_MB_TYPE("\n");
3102 3098

  
3103 3099
    if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) {
libavcodec/h263dec.c
144 144
}
145 145

  
146 146
static int decode_slice(MpegEncContext *s){
147
    const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
147 148
    s->last_resync_gb= s->gb;
148 149
    s->first_slice_line= 1;
149 150
        
......
174 175
        /* per-row end of slice checks */
175 176
        if(s->msmpeg4_version){
176 177
            if(s->resync_mb_y + s->slice_height == s->mb_y){
177
                const int xy= s->mb_x + s->mb_y*s->mb_width;
178
                s->error_status_table[xy-1]|= AC_END|DC_END|MV_END;
178
                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
179

  
179 180
                return 0;
180 181
            }
181 182
        }
......
211 212
                const int xy= s->mb_x + s->mb_y*s->mb_width;
212 213
                if(ret==SLICE_END){
213 214
//printf("%d %d %d %06X\n", s->mb_x, s->mb_y, s->gb.size*8 - get_bits_count(&s->gb), show_bits(&s->gb, 24));
214
                    s->error_status_table[xy]|= AC_END;
215
                    if(!s->partitioned_frame)
216
                        s->error_status_table[xy]|= MV_END|DC_END;
215
                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
217 216

  
218 217
                    s->padding_bug_score--;
219 218
                        
......
225 224
                    return 0; 
226 225
                }else if(ret==SLICE_NOEND){
227 226
                    fprintf(stderr,"Slice mismatch at MB: %d\n", xy);
227
                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
228 228
                    return -1;
229 229
                }
230 230
                fprintf(stderr,"Error at MB: %d\n", xy);
231
                s->error_status_table[xy]|= AC_ERROR;
232
                if(!s->partitioned_frame)
233
                    s->error_status_table[xy]|= DC_ERROR|MV_ERROR;
231
                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
234 232
    
235 233
                return -1;
236 234
            }
......
290 288
        else if(left<0){
291 289
            fprintf(stderr, "overreading %d bits\n", -left);
292 290
        }else
293
            s->error_status_table[s->mb_num-1]|= AC_END|MV_END|DC_END;
291
            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
294 292
        
295 293
        return 0;
296 294
    }
......
298 296
    fprintf(stderr, "slice end not reached but screenspace end (%d left %06X)\n", 
299 297
            s->gb.size_in_bits - get_bits_count(&s->gb),
300 298
            show_bits(&s->gb, 24));
299
            
300
    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
301

  
301 302
    return -1;
302 303
}
303 304

  
......
596 597
        || ABS(new_aspect - avctx->aspect_ratio) > 0.001) {
597 598
        /* H.263 could change picture size any time */
598 599
        MPV_common_end(s);
599
        s->context_initialized=0;
600 600
    }
601 601
    if (!s->context_initialized) {
602 602
        avctx->width = s->width;
......
641 641
    printf("qscale=%d\n", s->qscale);
642 642
#endif
643 643

  
644
    if(s->error_resilience)
645
        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));
644
    ff_er_frame_start(s);
646 645
    
647 646
    /* decode each macroblock */
648 647
    s->block_wrap[0]=
......
655 654
    s->mb_y=0;
656 655
    
657 656
    decode_slice(s);
658
    s->error_status_table[0]|= VP_START;
659 657
    while(s->mb_y<s->mb_height && s->gb.size_in_bits - get_bits_count(&s->gb)>16){
660 658
        if(s->msmpeg4_version){
661 659
            if(s->mb_x!=0 || (s->mb_y%s->slice_height)!=0)
......
669 667
            ff_mpeg4_clean_buffers(s);
670 668

  
671 669
        decode_slice(s);
672

  
673
        s->error_status_table[s->resync_mb_x + s->resync_mb_y*s->mb_width]|= VP_START;
674 670
    }
675 671

  
676 672
    if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)
......
699 695
        }
700 696
    }
701 697

  
702
    if(s->error_resilience){
703
        int error=0, num_end_markers=0;
704
        for(i=0; i<s->mb_num; i++){
705
            int status= s->error_status_table[i];
706
#if 0
707
            if(i%s->mb_width == 0) printf("\n");
708
            printf("%2X ", status); 
709
#endif
710
            if(status==0) continue;
711

  
712
            if(status&(DC_ERROR|AC_ERROR|MV_ERROR))
713
                error=1;
714
            if(status&VP_START){
715
                if(num_end_markers) 
716
                    error=1;
717
                num_end_markers=3;
718
            }
719
            if(status&AC_END)
720
                num_end_markers--;
721
            if(status&DC_END)
722
                num_end_markers--;
723
            if(status&MV_END)
724
                num_end_markers--;
725
        }
726
        if(num_end_markers || error){
727
            fprintf(stderr, "concealing errors\n");
728
            ff_error_resilience(s);
729
        }
730
    }
698
    ff_er_frame_end(s);
731 699

  
732 700
    MPV_frame_end(s);
733 701

  
libavcodec/mpegvideo.h
629 629
void MPV_common_init_ppc(MpegEncContext *s);
630 630
#endif
631 631
extern void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w);
632
void ff_conceal_past_errors(MpegEncContext *s, int conceal_all);
633 632
void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length);
634 633
void ff_clean_intra_table_entries(MpegEncContext *s);
635 634
void ff_init_scantable(MpegEncContext *s, ScanTable *st, const uint8_t *src_scantable);
636
void ff_error_resilience(MpegEncContext *s);
637 635
void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
638 636
void ff_emulated_edge_mc(MpegEncContext *s, uint8_t *src, int linesize, int block_w, int block_h, 
639 637
                                    int src_x, int src_y, int w, int h);
640 638
char ff_get_pict_type_char(int pict_type);
641 639
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
642 640

  
641
void ff_er_frame_start(MpegEncContext *s);
642
void ff_er_frame_end(MpegEncContext *s);
643
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status);
644

  
645

  
643 646
extern enum PixelFormat ff_yuv420p_list[2];
644 647

  
645 648
static inline void ff_init_block_index(MpegEncContext *s){
libavcodec/msmpeg4.c
1486 1486
{
1487 1487
    int cbp, code, i;
1488 1488
    
1489
    s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
1490
    
1491 1489
    if (s->pict_type == P_TYPE) {
1492 1490
        if (s->use_skip_mb_code) {
1493 1491
            if (get_bits1(&s->gb)) {
......
1581 1579
}
1582 1580
#endif
1583 1581

  
1584
    s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
1585
    
1586 1582
    if (s->pict_type == P_TYPE) {
1587 1583
        set_stat(ST_INTER_MB);
1588 1584
        if (s->use_skip_mb_code) {
libavcodec/wmv2.c
710 710

  
711 711
    if(w->j_type) return 0;
712 712
    
713
    s->error_status_table[s->mb_x + s->mb_y*s->mb_width]= 0;
714
    
715 713
    if (s->pict_type == P_TYPE) {
716 714
        if(s->mb_type[s->mb_y * s->mb_width + s->mb_x]&MB_TYPE_SKIPED){
717 715
            /* skip mb */

Also available in: Unified diff