Mercurial > libavcodec.hg
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 |