# HG changeset patch # User michael # Date 1269046328 0 # Node ID 927b985f73f41d7fba5c33b1c18c22a39565ef7b # Parent 9adad5749f23be30323be9196063c8498162dfb5 Error concealment of h264 with multiple references. diff -r 9adad5749f23 -r 927b985f73f4 error_resilience.c --- a/error_resilience.c Thu Mar 18 23:36:54 2010 +0000 +++ b/error_resilience.c Sat Mar 20 00:52:08 2010 +0000 @@ -38,7 +38,7 @@ */ #undef mb_intra -static void decode_mb(MpegEncContext *s){ +static void decode_mb(MpegEncContext *s, int ref){ s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; 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); 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); @@ -47,12 +47,16 @@ H264Context *h= (void*)s; h->mb_xy= s->mb_x + s->mb_y*s->mb_stride; memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache)); - fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); + assert(ref>=0); + 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 + ref=0; + fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1); + fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1); fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4); - assert(h->list_count==1); assert(!FRAME_MBAFF); ff_h264_hl_decode_mb(h); }else{ + assert(ref==0); MPV_decode_mb(s, s->block); } } @@ -397,7 +401,7 @@ s->mb_y= mb_y; s->mv[0][0][0]= 0; s->mv[0][0][1]= 0; - decode_mb(s); + decode_mb(s, 0); } } return; @@ -417,6 +421,7 @@ for(mb_x=0; mb_xmb_width; mb_x++){ const int mb_xy= mb_x + mb_y*s->mb_stride; int mv_predictor[8][2]={{0}}; + int ref[8]={0}; int pred_count=0; int j; int best_score=256*256*256*64; @@ -450,60 +455,73 @@ if(mb_x>0 && fixed[mb_xy-1]){ mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0]; mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1]; + ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)]; pred_count++; } if(mb_x+1current_picture.motion_val[0][mot_index + mot_step][0]; mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1]; + ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+1)]; pred_count++; } if(mb_y>0 && fixed[mb_xy-mb_stride]){ mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0]; mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1]; + ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)]; pred_count++; } if(mb_y+1current_picture.motion_val[0][mot_index + mot_stride*mot_step][0]; mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1]; + ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)]; pred_count++; } if(pred_count==0) continue; if(pred_count>1){ - int sum_x=0, sum_y=0; - int max_x, max_y, min_x, min_y; + int sum_x=0, sum_y=0, sum_r=0; + int max_x, max_y, min_x, min_y, max_r, min_r; for(j=0; j=3){ - min_y= min_x= 99999; - max_y= max_x=-99999; + min_y= min_x= min_r= 99999; + max_y= max_x= max_r=-99999; }else{ - min_x=min_y=max_x=max_y=0; + min_x=min_y=max_x=max_y=min_r=max_r=0; } for(j=0; jcurrent_picture.motion_val[0][mot_index][0]; mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1]; + ref [pred_count] = s->current_picture.ref_index[0][4*mb_xy]; pred_count++; s->mv_dir = MV_DIR_FORWARD; @@ -530,7 +549,10 @@ s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; - decode_mb(s); + if(ref[j]<0) //predictor intra or otherwise not available + continue; + + decode_mb(s, ref[j]); if(mb_x>0 && fixed[mb_xy-1]){ int k; @@ -568,7 +590,7 @@ s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1]; } - decode_mb(s); + decode_mb(s, ref[best_pred]); if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){ @@ -746,11 +768,6 @@ s->current_picture= *s->current_picture_ptr; } - for(i=0; i<2; i++){ - if(pic->ref_index[i]) - memset(pic->ref_index[i], 0, size * sizeof(uint8_t)); - } - if(s->avctx->debug&FF_DEBUG_ER){ for(mb_y=0; mb_ymb_height; mb_y++){ for(mb_x=0; mb_xmb_width; mb_x++){ @@ -948,7 +965,7 @@ s->mb_x= mb_x; s->mb_y= mb_y; - decode_mb(s); + decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/); } } @@ -990,7 +1007,7 @@ s->dsp.clear_blocks(s->block[0]); s->mb_x= mb_x; s->mb_y= mb_y; - decode_mb(s); + decode_mb(s, 0); } } }else