Revision 7bc9090a libavcodec/error_resilience.c

View differences:

libavcodec/error_resilience.c
23 23
 * Error resilience / concealment.
24 24
 */
25 25

  
26
#include <limits.h>
27
 
26 28
#include "avcodec.h"
27 29
#include "dsputil.h"
28 30
#include "mpegvideo.h"
......
111 113
            int mb_index, error, j;
112 114
            int64_t guess, weight_sum;
113 115
            
114
            mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_width;
116
            mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
115 117
            
116 118
            error= s->error_status_table[mb_index];
117 119
            
118
            if(!(s->mb_type[mb_index]&MB_TYPE_INTRA)) continue; //inter
120
            if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
119 121
            if(!(error&DC_ERROR)) continue;           //dc-ok
120 122
            
121 123
            /* right block */
122 124
            for(j=b_x+1; j<w; j++){
123
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
125
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
124 126
                int error_j= s->error_status_table[mb_index_j];
125
                int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
127
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
126 128
                if(intra_j==0 || !(error_j&DC_ERROR)){
127 129
                    color[0]= dc[j + b_y*stride];
128 130
                    distance[0]= j-b_x;
......
132 134
            
133 135
            /* left block */
134 136
            for(j=b_x-1; j>=0; j--){
135
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_width;
137
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
136 138
                int error_j= s->error_status_table[mb_index_j];
137
                int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
139
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
138 140
                if(intra_j==0 || !(error_j&DC_ERROR)){
139 141
                    color[1]= dc[j + b_y*stride];
140 142
                    distance[1]= b_x-j;
......
144 146

  
145 147
            /* bottom block */
146 148
            for(j=b_y+1; j<h; j++){
147
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
149
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
148 150
                int error_j= s->error_status_table[mb_index_j];
149
                int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
151
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
150 152
                if(intra_j==0 || !(error_j&DC_ERROR)){
151 153
                    color[2]= dc[b_x + j*stride];
152 154
                    distance[2]= j-b_y;
......
156 158

  
157 159
            /* top block */
158 160
            for(j=b_y-1; j>=0; j--){
159
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_width;
161
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
160 162
                int error_j= s->error_status_table[mb_index_j];
161
                int intra_j= s->mb_type[mb_index_j]&MB_TYPE_INTRA;
163
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
162 164
                if(intra_j==0 || !(error_j&DC_ERROR)){
163 165
                    color[3]= dc[b_x + j*stride];
164 166
                    distance[3]= b_y-j;
......
192 194
    for(b_y=0; b_y<h; b_y++){
193 195
        for(b_x=0; b_x<w-1; b_x++){
194 196
            int y;
195
            int left_status = s->error_status_table[( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_width];
196
            int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width];
197
            int left_intra=   s->mb_type      [( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
198
            int right_intra=  s->mb_type      [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
197
            int left_status = s->error_status_table[( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_stride];
198
            int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
199
            int left_intra=   IS_INTRA(s->current_picture.mb_type      [( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
200
            int right_intra=  IS_INTRA(s->current_picture.mb_type      [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
199 201
            int left_damage =  left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
200 202
            int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
201 203
            int offset= b_x*8 + b_y*stride*8;
......
252 254
    for(b_y=0; b_y<h-1; b_y++){
253 255
        for(b_x=0; b_x<w; b_x++){
254 256
            int x;
255
            int top_status   = s->error_status_table[(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_width];
256
            int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width];
257
            int top_intra=     s->mb_type      [(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_width]&MB_TYPE_INTRA;
258
            int bottom_intra=  s->mb_type      [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_width]&MB_TYPE_INTRA;
257
            int top_status   = s->error_status_table[(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_stride];
258
            int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
259
            int top_intra=     IS_INTRA(s->current_picture.mb_type      [(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_stride]);
260
            int bottom_intra=  IS_INTRA(s->current_picture.mb_type      [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
259 261
            int top_damage =      top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
260 262
            int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
261 263
            int offset= b_x*8 + b_y*stride*8;
......
301 303
}
302 304

  
303 305
static void guess_mv(MpegEncContext *s){
304
    uint8_t fixed[s->mb_num];
306
    uint8_t fixed[s->mb_stride * s->mb_height];
305 307
#define MV_FROZEN    3
306 308
#define MV_CHANGED   2
307 309
#define MV_UNCHANGED 1
310
    const int mb_stride = s->mb_stride;
308 311
    const int mb_width = s->mb_width;
309 312
    const int mb_height= s->mb_height;
310 313
    int i, depth, num_avail;
314
    int mb_x, mb_y;
311 315
   
312 316
    num_avail=0;
313 317
    for(i=0; i<s->mb_num; i++){
318
        const int mb_xy= s->mb_index2xy[ i ];
314 319
        int f=0;
315
        int error= s->error_status_table[i];
320
        int error= s->error_status_table[mb_xy];
316 321

  
317
        if(s->mb_type[i]&MB_TYPE_INTRA) f=MV_FROZEN; //intra //FIXME check
322
        if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
318 323
        if(!(error&MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV
319 324
        
320
        fixed[i]= f;
325
        fixed[mb_xy]= f;
321 326
        if(f==MV_FROZEN)
322 327
            num_avail++;
323 328
    }
324 329
    
325 330
    if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
326
        int mb_x, mb_y;
327
        i= -1;
328 331
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
329 332
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
330
                i++;
333
                const int mb_xy= mb_x + mb_y*s->mb_stride;
331 334
                
332
                if(s->mb_type[i]&MB_TYPE_INTRA) continue;
333
                if(!(s->error_status_table[i]&MV_ERROR)) continue;
335
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
336
                if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
334 337

  
335 338
                s->mv_dir = MV_DIR_FORWARD;
336 339
                s->mb_intra=0;
......
355 358
        none_left=1;
356 359
        changed=1;
357 360
        for(pass=0; (changed || pass<2) && pass<10; pass++){
358
            int i,mb_x, mb_y;
361
            int mb_x, mb_y;
359 362
int score_sum=0;
360 363
 
361 364
            changed=0;
362
            i= -1;
363 365
            for(mb_y=0; mb_y<s->mb_height; mb_y++){
364 366
                for(mb_x=0; mb_x<s->mb_width; mb_x++){
367
                    const int mb_xy= mb_x + mb_y*s->mb_stride;
365 368
                    int mv_predictor[8][2]={{0}};
366 369
                    int pred_count=0;
367 370
                    int j;
......
372 375
                    int prev_x= s->motion_val[mot_index][0];
373 376
                    int prev_y= s->motion_val[mot_index][1];
374 377

  
375
                    i++;
376 378
                    if((mb_x^mb_y^pass)&1) continue;
377 379
                    
378
                    if(fixed[i]==MV_FROZEN) continue;
380
                    if(fixed[mb_xy]==MV_FROZEN) continue;
381
                    assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
382
                    assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
379 383
                    
380 384
                    j=0;
381
                    if(mb_x>0           && fixed[i-1       ]==MV_FROZEN) j=1;
382
                    if(mb_x+1<mb_width  && fixed[i+1       ]==MV_FROZEN) j=1;
383
                    if(mb_y>0           && fixed[i-mb_width]==MV_FROZEN) j=1;
384
                    if(mb_y+1<mb_height && fixed[i+mb_width]==MV_FROZEN) j=1;
385
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_FROZEN) j=1;
386
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_FROZEN) j=1;
387
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
388
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
385 389
                    if(j==0) continue;
386 390

  
387 391
                    j=0;
388
                    if(mb_x>0           && fixed[i-1       ]==MV_CHANGED) j=1;
389
                    if(mb_x+1<mb_width  && fixed[i+1       ]==MV_CHANGED) j=1;
390
                    if(mb_y>0           && fixed[i-mb_width]==MV_CHANGED) j=1;
391
                    if(mb_y+1<mb_height && fixed[i+mb_width]==MV_CHANGED) j=1;
392
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_CHANGED) j=1;
393
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_CHANGED) j=1;
394
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
395
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
392 396
                    if(j==0 && pass>1) continue;
393 397
                    
394 398
                    none_left=0;
395 399
                    
396
                    if(mb_x>0 && fixed[i-1]){
400
                    if(mb_x>0 && fixed[mb_xy-1]){
397 401
                        mv_predictor[pred_count][0]= s->motion_val[mot_index - 2][0];
398 402
                        mv_predictor[pred_count][1]= s->motion_val[mot_index - 2][1];
399 403
                        pred_count++;
400 404
                    }
401
                    if(mb_x+1<mb_width && fixed[i+1]){
405
                    if(mb_x+1<mb_width && fixed[mb_xy+1]){
402 406
                        mv_predictor[pred_count][0]= s->motion_val[mot_index + 2][0];
403 407
                        mv_predictor[pred_count][1]= s->motion_val[mot_index + 2][1];
404 408
                        pred_count++;
405 409
                    }
406
                    if(mb_y>0 && fixed[i-mb_width]){
410
                    if(mb_y>0 && fixed[mb_xy-mb_stride]){
407 411
                        mv_predictor[pred_count][0]= s->motion_val[mot_index - mot_stride*2][0];
408 412
                        mv_predictor[pred_count][1]= s->motion_val[mot_index - mot_stride*2][1];
409 413
                        pred_count++;
410 414
                    }
411
                    if(mb_y+1<mb_height && fixed[i+mb_width]){
415
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
412 416
                        mv_predictor[pred_count][0]= s->motion_val[mot_index + mot_stride*2][0];
413 417
                        mv_predictor[pred_count][1]= s->motion_val[mot_index + mot_stride*2][1];
414 418
                        pred_count++;
......
468 472

  
469 473
                    s->mb_x= mb_x;
470 474
                    s->mb_y= mb_y;
475

  
471 476
                    for(j=0; j<pred_count; j++){
472 477
                        int score=0;
473 478
                        uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
474 479

  
475 480
                        s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
476 481
                        s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
482

  
477 483
                        MPV_decode_mb(s, s->block);
478 484
                        
479
                        if(mb_x>0 && fixed[i-1]){
485
                        if(mb_x>0 && fixed[mb_xy-1]){
480 486
                            int k;
481 487
                            for(k=0; k<16; k++)
482 488
                                score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);
483 489
                        }
484
                        if(mb_x+1<mb_width && fixed[i+1]){
490
                        if(mb_x+1<mb_width && fixed[mb_xy+1]){
485 491
                            int k;
486 492
                            for(k=0; k<16; k++)
487 493
                                score += ABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
488 494
                        }
489
                        if(mb_y>0 && fixed[i-mb_width]){
495
                        if(mb_y>0 && fixed[mb_xy-mb_stride]){
490 496
                            int k;
491 497
                            for(k=0; k<16; k++)
492 498
                                score += ABS(src[k-s->linesize   ]-src[k               ]);
493 499
                        }
494
                        if(mb_y+1<mb_height && fixed[i+mb_width]){
500
                        if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
495 501
                            int k;
496 502
                            for(k=0; k<16; k++)
497 503
                                score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
......
511 517

  
512 518
                    
513 519
                    if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
514
                        fixed[i]=MV_CHANGED;
520
                        fixed[mb_xy]=MV_CHANGED;
515 521
                        changed++;
516 522
                    }else
517
                        fixed[i]=MV_UNCHANGED;
523
                        fixed[mb_xy]=MV_UNCHANGED;
518 524
                }
519 525
            }
520 526

  
......
525 531
            return;
526 532
            
527 533
        for(i=0; i<s->mb_num; i++){
528
            if(fixed[i])
529
                fixed[i]=MV_FROZEN;
534
            int mb_xy= s->mb_index2xy[i];
535
            if(fixed[mb_xy])
536
                fixed[mb_xy]=MV_FROZEN;
530 537
        }
531 538
//        printf(":"); fflush(stdout);
532 539
    }
......
539 546

  
540 547
    undamaged_count=0;
541 548
    for(i=0; i<s->mb_num; i++){
542
        int error= s->error_status_table[i];
549
        const int mb_xy= s->mb_index2xy[i];
550
        const int error= s->error_status_table[mb_xy];
543 551
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
544 552
            undamaged_count++;
545 553
    }
......
550 558
    is_intra_likely=0;
551 559

  
552 560
    j=0;
553
    i=-1;
554 561
    for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
555 562
        for(mb_x= 0; mb_x<s->mb_width; mb_x++){
556 563
            int error;
564
            const int mb_xy= mb_x + mb_y*s->mb_stride;
557 565

  
558
            i++;
559
            error= s->error_status_table[i];
566
            error= s->error_status_table[mb_xy];
560 567
            if((error&DC_ERROR) && (error&MV_ERROR))
561 568
                continue; //skip damaged
562 569
        
......
570 577
		is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr                    , s->linesize);
571 578
                is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize);
572 579
            }else{
573
                if(s->mbintra_table[i]) //HACK (this is allways inited but we should use mb_type[])
580
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
574 581
                   is_intra_likely++;
575 582
                else
576 583
                   is_intra_likely--;
......
584 591
void ff_er_frame_start(MpegEncContext *s){
585 592
    if(!s->error_resilience) return;
586 593

  
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));
594
    memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
595
    s->error_count= 3*s->mb_num;
588 596
}
589 597

  
590 598
/**
......
594 602
 *               error of the same type occured
595 603
 */
596 604
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;
605
    const int start_i= clip(startx + starty * s->mb_width    , 0, s->mb_num-1);
606
    const int end_i  = clip(endx   + endy   * s->mb_width    , 0, s->mb_num);
607
    const int start_xy= s->mb_index2xy[start_i];
608
    const int end_xy  = s->mb_index2xy[end_i];
600 609
    int mask= -1;
601 610
    
602 611
    if(!s->error_resilience) return;
603 612

  
604 613
    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);    
614
    if(status & (AC_ERROR|AC_END)){
615
        mask &= ~(AC_ERROR|AC_END);
616
        s->error_count -= end_i - start_i + 1;
617
    }
618
    if(status & (DC_ERROR|DC_END)){
619
        mask &= ~(DC_ERROR|DC_END);
620
        s->error_count -= end_i - start_i + 1;
621
    }
622
    if(status & (MV_ERROR|MV_END)){
623
        mask &= ~(MV_ERROR|MV_END);
624
        s->error_count -= end_i - start_i + 1;
625
    }
626

  
627
    if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
608 628

  
609 629
    if(mask == ~0x7F){
610
        memset(&s->error_status_table[start_xy], 0, mb_count * sizeof(uint8_t));
630
        memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
611 631
    }else{
612 632
        int i;
613 633
        for(i=start_xy; i<end_xy; i++){
614
            s->error_status_table[i] &= mask;
634
            s->error_status_table[ i ] &= mask;
615 635
        }
616 636
    }
617
   
618
    if(end_xy < s->mb_num){
637

  
638
    if(end_i == s->mb_num) 
639
        s->error_count= INT_MAX;
640
    else{
619 641
        s->error_status_table[end_xy] &= mask;
620 642
        s->error_status_table[end_xy] |= status;
621 643
    }
622 644
 
623 645
    s->error_status_table[start_xy] |= VP_START;
646

  
647
    if(start_xy > 0){
648
        int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
649
        
650
        prev_status &= ~ VP_START;
651
        if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
652
    }
624 653
}
625 654

  
626 655
void ff_er_frame_end(MpegEncContext *s){
......
629 658
    int threshold_part[4]= {100,100,100};
630 659
    int threshold= 50;
631 660
    int is_intra_likely;
632
    int num_end_markers=0;
633 661
    
634
    if(!s->error_resilience) return;
662
    if(!s->error_resilience || s->error_count==0) return;
635 663

  
636
    error=0;
637
    for(i=0; i<s->mb_num; i++){
638
        int status= s->error_status_table[i];
664
    fprintf(stderr, "concealing errors\n");
665
    
666
    if(s->motion_val == NULL){
667
        int size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
639 668
        
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--;
669
        fprintf(stderr, "Warning MVs not available\n");
670
        
671
        s->motion_val= av_mallocz(size * 2 * sizeof(int16_t));
655 672
    }
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];
673
    
674
    if(s->avctx->debug&FF_DEBUG_ER){
675
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
676
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
677
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
664 678
            
665
            if(i%s->mb_width == 0) printf("\n");
666
            printf("%2X ", status); 
679
                printf("%2X ", status); 
680
            }
681
            printf("\n");
667 682
        }
668 683
    }
669 684
    
......
673 688
        int end_ok=0;
674 689

  
675 690
        for(i=s->mb_num-1; i>=0; i--){
676
            int error= s->error_status_table[i];
691
            const int mb_xy= s->mb_index2xy[i];
692
            int error= s->error_status_table[mb_xy];
677 693
        
678 694
            if(error&(1<<error_type))
679 695
                end_ok=1;
......
681 697
                end_ok=1;
682 698

  
683 699
            if(!end_ok)
684
                s->error_status_table[i]|= 1<<error_type;
700
                s->error_status_table[mb_xy]|= 1<<error_type;
685 701

  
686 702
            if(error&VP_START)
687 703
                end_ok=0;
......
694 710
        int end_ok=0;
695 711

  
696 712
        for(i=s->mb_num-1; i>=0; i--){
697
            int error= s->error_status_table[i];
713
            const int mb_xy= s->mb_index2xy[i];
714
            int error= s->error_status_table[mb_xy];
698 715
        
699 716
            if(error&AC_END)
700 717
                end_ok=0;
......
702 719
                end_ok=1;
703 720

  
704 721
            if(!end_ok)
705
                s->error_status_table[i]|= AC_ERROR;
722
                s->error_status_table[mb_xy]|= AC_ERROR;
706 723

  
707 724
            if(error&VP_START)
708 725
                end_ok=0;
......
714 731
        int end_ok=1;
715 732
                
716 733
        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
717
            int error1= s->error_status_table[i  ];
718
            int error2= s->error_status_table[i+1];
734
            const int mb_xy= s->mb_index2xy[i];
735
            int error1= s->error_status_table[mb_xy  ];
736
            int error2= s->error_status_table[mb_xy+1];
719 737
        
720 738
            if(error1&VP_START)
721 739
                end_ok=1;
......
727 745
            }
728 746
        
729 747
            if(!end_ok)
730
                s->error_status_table[i]|= DC_ERROR|AC_ERROR|MV_ERROR;
748
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
731 749
        }
732 750
    }
733 751
    
......
736 754
    distance=9999999;
737 755
    for(error_type=1; error_type<=3; error_type++){
738 756
        for(i=s->mb_num-1; i>=0; i--){
739
            int error= s->error_status_table[i];
757
            const int mb_xy= s->mb_index2xy[i];
758
            int error= s->error_status_table[mb_xy];
740 759
            
741
            if(!s->mbskip_table[i]) //FIXME partition specific
760
            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
742 761
                distance++;            
743 762
            if(error&(1<<error_type))
744 763
                distance= 0;
745 764

  
746 765
            if(s->partitioned_frame){
747 766
                if(distance < threshold_part[error_type-1])
748
                    s->error_status_table[i]|= 1<<error_type;
767
                    s->error_status_table[mb_xy]|= 1<<error_type;
749 768
            }else{
750 769
                if(distance < threshold)
751
                    s->error_status_table[i]|= 1<<error_type;
770
                    s->error_status_table[mb_xy]|= 1<<error_type;
752 771
            }
753 772

  
754 773
            if(error&VP_START)
......
760 779
    /* forward mark errors */
761 780
    error=0;
762 781
    for(i=0; i<s->mb_num; i++){
763
        int old_error= s->error_status_table[i];
782
        const int mb_xy= s->mb_index2xy[i];
783
        int old_error= s->error_status_table[mb_xy];
764 784
        
765 785
        if(old_error&VP_START)
766 786
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
767 787
        else{
768 788
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
769
            s->error_status_table[i]|= error;
789
            s->error_status_table[mb_xy]|= error;
770 790
        }
771 791
    }
772 792
#if 1
773 793
    /* handle not partitioned case */
774 794
    if(!s->partitioned_frame){
775 795
        for(i=0; i<s->mb_num; i++){
776
            error= s->error_status_table[i];
796
            const int mb_xy= s->mb_index2xy[i];
797
            error= s->error_status_table[mb_xy];
777 798
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
778 799
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
779
            s->error_status_table[i]= error;
800
            s->error_status_table[mb_xy]= error;
780 801
        }
781 802
    }
782 803
#endif
......
784 805

  
785 806
    /* set unknown mb-type to most likely */
786 807
    for(i=0; i<s->mb_num; i++){
787
        int intra;
788
        error= s->error_status_table[i];
789
        if((error&DC_ERROR) && (error&MV_ERROR))
790
            intra= is_intra_likely;
791
        else
792
            intra= s->mbintra_table[i];
808
        const int mb_xy= s->mb_index2xy[i];
809
        error= s->error_status_table[mb_xy];
810
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
811
            continue;
793 812

  
794
        if(intra)
795
            s->mb_type[i]|= MB_TYPE_INTRA;
813
        if(is_intra_likely)
814
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
796 815
        else
797
            s->mb_type[i]&= ~MB_TYPE_INTRA;
816
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
798 817
    }
799 818
    
800 819
    /* handle inter blocks with damaged AC */
801
    i= -1;
802 820
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
803 821
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
804
            i++;
805
            error= s->error_status_table[i];
822
            const int mb_xy= mb_x + mb_y * s->mb_stride;
823
            const int mb_type= s->current_picture.mb_type[mb_xy];
824
            error= s->error_status_table[mb_xy];
806 825

  
807
            if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
826
            if(IS_INTRA(mb_type)) continue; //intra
808 827
            if(error&MV_ERROR) continue;              //inter with damaged MV
809 828
            if(!(error&AC_ERROR)) continue;           //undamaged inter
810 829
            
811 830
            s->mv_dir = MV_DIR_FORWARD;
812 831
            s->mb_intra=0;
813 832
            s->mb_skiped=0;
814
            if(s->mb_type[i]&MB_TYPE_INTER4V){
833
            if(IS_8X8(mb_type)){
815 834
                int mb_index= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
816 835
                int j;
817 836
                s->mv_type = MV_TYPE_8X8;
......
835 854

  
836 855
    /* guess MVs */
837 856
    if(s->pict_type==B_TYPE){
838
        i= -1;
839 857
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
840 858
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
841 859
                int xy= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
842
                i++;
843
                error= s->error_status_table[i];
860
                const int mb_xy= mb_x + mb_y * s->mb_stride;
861
                const int mb_type= s->current_picture.mb_type[mb_xy];
862
                error= s->error_status_table[mb_xy];
844 863

  
845
                if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
864
                if(IS_INTRA(mb_type)) continue;
846 865
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
847 866
                if(!(error&AC_ERROR)) continue;           //undamaged inter
848 867
            
......
876 895
        guess_mv(s);
877 896

  
878 897
    /* fill DC for inter blocks */
879
    i= -1;
880 898
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
881 899
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
882 900
            int dc, dcu, dcv, y, n;
883 901
            int16_t *dc_ptr;
884 902
            uint8_t *dest_y, *dest_cb, *dest_cr;
903
            const int mb_xy= mb_x + mb_y * s->mb_stride;
904
            const int mb_type= s->current_picture.mb_type[mb_xy];
885 905
           
886
            i++;
887
            error= s->error_status_table[i];
906
            error= s->error_status_table[mb_xy];
888 907

  
889
            if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra
908
            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
890 909
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
891 910
            
892 911
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
......
928 947
    
929 948
#if 1
930 949
    /* render DC only intra */
931
    i= -1;
932 950
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
933 951
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
934 952
            uint8_t *dest_y, *dest_cb, *dest_cr;
935
           
936
            i++;
937
            error= s->error_status_table[i];
953
            const int mb_xy= mb_x + mb_y * s->mb_stride;
954
            const int mb_type= s->current_picture.mb_type[mb_xy];
955

  
956
            error= s->error_status_table[mb_xy];
938 957

  
939
            if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter
958
            if(IS_INTER(mb_type)) continue;
940 959
            if(!(error&AC_ERROR)) continue;              //undamaged
941 960
            
942 961
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
......
962 981

  
963 982
    /* clean a few tables */
964 983
    for(i=0; i<s->mb_num; i++){
965
        int error= s->error_status_table[i];
984
        const int mb_xy= s->mb_index2xy[i];
985
        int error= s->error_status_table[mb_xy];
966 986
        
967 987
        if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
968
            s->mbskip_table[i]=0;
988
            s->mbskip_table[mb_xy]=0;
969 989
        }
970
        s->mbintra_table[i]=1;
990
        s->mbintra_table[mb_xy]=1;
971 991
    }    
972 992
}

Also available in: Unified diff