comparison error_resilience.c @ 11510:927b985f73f4 libavcodec

Error concealment of h264 with multiple references.
author michael
date Sat, 20 Mar 2010 00:52:08 +0000
parents eb86fea1146b
children 6bf21de8e6eb
comparison
equal deleted inserted replaced
11509:9adad5749f23 11510:927b985f73f4
36 * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264) 36 * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
37 * but error concealment must support both h264 and h263 thus we must undo this 37 * but error concealment must support both h264 and h263 thus we must undo this
38 */ 38 */
39 #undef mb_intra 39 #undef mb_intra
40 40
41 static void decode_mb(MpegEncContext *s){ 41 static void decode_mb(MpegEncContext *s, int ref){
42 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; 42 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
43 s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift); 43 s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
44 s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift); 44 s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
45 45
46 if(s->codec_id == CODEC_ID_H264){ 46 if(s->codec_id == CODEC_ID_H264){
47 H264Context *h= (void*)s; 47 H264Context *h= (void*)s;
48 h->mb_xy= s->mb_x + s->mb_y*s->mb_stride; 48 h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
49 memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache)); 49 memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
50 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); 50 assert(ref>=0);
51 if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added
52 ref=0;
53 fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
54 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
51 fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4); 55 fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
52 assert(h->list_count==1);
53 assert(!FRAME_MBAFF); 56 assert(!FRAME_MBAFF);
54 ff_h264_hl_decode_mb(h); 57 ff_h264_hl_decode_mb(h);
55 }else{ 58 }else{
59 assert(ref==0);
56 MPV_decode_mb(s, s->block); 60 MPV_decode_mb(s, s->block);
57 } 61 }
58 } 62 }
59 63
60 /** 64 /**
395 399
396 s->mb_x= mb_x; 400 s->mb_x= mb_x;
397 s->mb_y= mb_y; 401 s->mb_y= mb_y;
398 s->mv[0][0][0]= 0; 402 s->mv[0][0][0]= 0;
399 s->mv[0][0][1]= 0; 403 s->mv[0][0][1]= 0;
400 decode_mb(s); 404 decode_mb(s, 0);
401 } 405 }
402 } 406 }
403 return; 407 return;
404 } 408 }
405 409
415 changed=0; 419 changed=0;
416 for(mb_y=0; mb_y<s->mb_height; mb_y++){ 420 for(mb_y=0; mb_y<s->mb_height; mb_y++){
417 for(mb_x=0; mb_x<s->mb_width; mb_x++){ 421 for(mb_x=0; mb_x<s->mb_width; mb_x++){
418 const int mb_xy= mb_x + mb_y*s->mb_stride; 422 const int mb_xy= mb_x + mb_y*s->mb_stride;
419 int mv_predictor[8][2]={{0}}; 423 int mv_predictor[8][2]={{0}};
424 int ref[8]={0};
420 int pred_count=0; 425 int pred_count=0;
421 int j; 426 int j;
422 int best_score=256*256*256*64; 427 int best_score=256*256*256*64;
423 int best_pred=0; 428 int best_pred=0;
424 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step; 429 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
448 none_left=0; 453 none_left=0;
449 454
450 if(mb_x>0 && fixed[mb_xy-1]){ 455 if(mb_x>0 && fixed[mb_xy-1]){
451 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0]; 456 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
452 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1]; 457 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
458 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)];
453 pred_count++; 459 pred_count++;
454 } 460 }
455 if(mb_x+1<mb_width && fixed[mb_xy+1]){ 461 if(mb_x+1<mb_width && fixed[mb_xy+1]){
456 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0]; 462 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
457 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1]; 463 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
464 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+1)];
458 pred_count++; 465 pred_count++;
459 } 466 }
460 if(mb_y>0 && fixed[mb_xy-mb_stride]){ 467 if(mb_y>0 && fixed[mb_xy-mb_stride]){
461 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0]; 468 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
462 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1]; 469 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
470 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
463 pred_count++; 471 pred_count++;
464 } 472 }
465 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){ 473 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
466 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0]; 474 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
467 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1]; 475 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
476 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
468 pred_count++; 477 pred_count++;
469 } 478 }
470 if(pred_count==0) continue; 479 if(pred_count==0) continue;
471 480
472 if(pred_count>1){ 481 if(pred_count>1){
473 int sum_x=0, sum_y=0; 482 int sum_x=0, sum_y=0, sum_r=0;
474 int max_x, max_y, min_x, min_y; 483 int max_x, max_y, min_x, min_y, max_r, min_r;
475 484
476 for(j=0; j<pred_count; j++){ 485 for(j=0; j<pred_count; j++){
477 sum_x+= mv_predictor[j][0]; 486 sum_x+= mv_predictor[j][0];
478 sum_y+= mv_predictor[j][1]; 487 sum_y+= mv_predictor[j][1];
488 sum_r+= ref[j];
489 if(j && ref[j] != ref[j-1])
490 goto skip_mean_and_median;
479 } 491 }
480 492
481 /* mean */ 493 /* mean */
482 mv_predictor[pred_count][0] = sum_x/j; 494 mv_predictor[pred_count][0] = sum_x/j;
483 mv_predictor[pred_count][1] = sum_y/j; 495 mv_predictor[pred_count][1] = sum_y/j;
496 ref [pred_count] = sum_r/j;
484 497
485 /* median */ 498 /* median */
486 if(pred_count>=3){ 499 if(pred_count>=3){
487 min_y= min_x= 99999; 500 min_y= min_x= min_r= 99999;
488 max_y= max_x=-99999; 501 max_y= max_x= max_r=-99999;
489 }else{ 502 }else{
490 min_x=min_y=max_x=max_y=0; 503 min_x=min_y=max_x=max_y=min_r=max_r=0;
491 } 504 }
492 for(j=0; j<pred_count; j++){ 505 for(j=0; j<pred_count; j++){
493 max_x= FFMAX(max_x, mv_predictor[j][0]); 506 max_x= FFMAX(max_x, mv_predictor[j][0]);
494 max_y= FFMAX(max_y, mv_predictor[j][1]); 507 max_y= FFMAX(max_y, mv_predictor[j][1]);
508 max_r= FFMAX(max_r, ref[j]);
495 min_x= FFMIN(min_x, mv_predictor[j][0]); 509 min_x= FFMIN(min_x, mv_predictor[j][0]);
496 min_y= FFMIN(min_y, mv_predictor[j][1]); 510 min_y= FFMIN(min_y, mv_predictor[j][1]);
511 min_r= FFMIN(min_r, ref[j]);
497 } 512 }
498 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x; 513 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
499 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y; 514 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
515 ref [pred_count+1] = sum_r - max_r - min_r;
500 516
501 if(pred_count==4){ 517 if(pred_count==4){
502 mv_predictor[pred_count+1][0] /= 2; 518 mv_predictor[pred_count+1][0] /= 2;
503 mv_predictor[pred_count+1][1] /= 2; 519 mv_predictor[pred_count+1][1] /= 2;
520 ref [pred_count+1] /= 2;
504 } 521 }
505 pred_count+=2; 522 pred_count+=2;
506 } 523 }
524 skip_mean_and_median:
507 525
508 /* zero MV */ 526 /* zero MV */
509 pred_count++; 527 pred_count++;
510 528
511 /* last MV */ 529 /* last MV */
512 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0]; 530 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
513 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1]; 531 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
532 ref [pred_count] = s->current_picture.ref_index[0][4*mb_xy];
514 pred_count++; 533 pred_count++;
515 534
516 s->mv_dir = MV_DIR_FORWARD; 535 s->mv_dir = MV_DIR_FORWARD;
517 s->mb_intra=0; 536 s->mb_intra=0;
518 s->mv_type = MV_TYPE_16X16; 537 s->mv_type = MV_TYPE_16X16;
528 uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; 547 uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
529 548
530 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; 549 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
531 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; 550 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
532 551
533 decode_mb(s); 552 if(ref[j]<0) //predictor intra or otherwise not available
553 continue;
554
555 decode_mb(s, ref[j]);
534 556
535 if(mb_x>0 && fixed[mb_xy-1]){ 557 if(mb_x>0 && fixed[mb_xy-1]){
536 int k; 558 int k;
537 for(k=0; k<16; k++) 559 for(k=0; k<16; k++)
538 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]); 560 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
566 for(j=0; j<mot_step; j++){ 588 for(j=0; j<mot_step; j++){
567 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0]; 589 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
568 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1]; 590 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
569 } 591 }
570 592
571 decode_mb(s); 593 decode_mb(s, ref[best_pred]);
572 594
573 595
574 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){ 596 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
575 fixed[mb_xy]=MV_CHANGED; 597 fixed[mb_xy]=MV_CHANGED;
576 changed++; 598 changed++;
744 } 766 }
745 pic->motion_subsample_log2= 3; 767 pic->motion_subsample_log2= 3;
746 s->current_picture= *s->current_picture_ptr; 768 s->current_picture= *s->current_picture_ptr;
747 } 769 }
748 770
749 for(i=0; i<2; i++){
750 if(pic->ref_index[i])
751 memset(pic->ref_index[i], 0, size * sizeof(uint8_t));
752 }
753
754 if(s->avctx->debug&FF_DEBUG_ER){ 771 if(s->avctx->debug&FF_DEBUG_ER){
755 for(mb_y=0; mb_y<s->mb_height; mb_y++){ 772 for(mb_y=0; mb_y<s->mb_height; mb_y++){
756 for(mb_x=0; mb_x<s->mb_width; mb_x++){ 773 for(mb_x=0; mb_x<s->mb_width; mb_x++){
757 int status= s->error_status_table[mb_x + mb_y*s->mb_stride]; 774 int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
758 775
946 963
947 s->dsp.clear_blocks(s->block[0]); 964 s->dsp.clear_blocks(s->block[0]);
948 965
949 s->mb_x= mb_x; 966 s->mb_x= mb_x;
950 s->mb_y= mb_y; 967 s->mb_y= mb_y;
951 decode_mb(s); 968 decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
952 } 969 }
953 } 970 }
954 971
955 /* guess MVs */ 972 /* guess MVs */
956 if(s->pict_type==FF_B_TYPE){ 973 if(s->pict_type==FF_B_TYPE){
988 } 1005 }
989 1006
990 s->dsp.clear_blocks(s->block[0]); 1007 s->dsp.clear_blocks(s->block[0]);
991 s->mb_x= mb_x; 1008 s->mb_x= mb_x;
992 s->mb_y= mb_y; 1009 s->mb_y= mb_y;
993 decode_mb(s); 1010 decode_mb(s, 0);
994 } 1011 }
995 } 1012 }
996 }else 1013 }else
997 guess_mv(s); 1014 guess_mv(s);
998 1015