diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-12-22 00:24:39 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-12-22 00:25:48 +0100 |
commit | a40f43db647bfacafbd1e27a4cd5f6134c6e6c53 (patch) | |
tree | 3ec929f7ff920bcfb803709cd869de881e012d5f | |
parent | 8d960fbc70d5d7b6cd62db22712a8d5c2c5e26bf (diff) | |
download | ffmpeg-a40f43db647bfacafbd1e27a4cd5f6134c6e6c53.tar.gz |
error_concealment: optimize guess_dc()
Fixes Ticket811
Bug found by: Oana Stratulat
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/error_resilience.c | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index d4507cb033..ee0e6fcfe2 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -154,11 +154,68 @@ static void filter181(int16_t *data, int width, int height, int stride){ */ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){ int b_x, b_y; + int16_t (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4); + uint16_t (*dist)[4] = av_malloc(stride*h*sizeof(uint16_t)*4); + + for(b_y=0; b_y<h; b_y++){ + int color= 1024; + int distance= -1; + for(b_x=0; b_x<w; b_x++){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][1]= color; + dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999; + } + color= 1024; + distance= -1; + for(b_x=w-1; b_x>=0; b_x--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_x; + } + col [b_x + b_y*stride][0]= color; + dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999; + } + } + for(b_x=0; b_x<w; b_x++){ + int color= 1024; + int distance= -1; + for(b_y=0; b_y<h; b_y++){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][3]= color; + dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999; + } + color= 1024; + distance= -1; + for(b_y=h-1; b_y>=0; b_y--){ + int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&ER_DC_ERROR)){ + color= dc[b_x + b_y*stride]; + distance= b_y; + } + col [b_x + b_y*stride][2]= color; + dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999; + } + } for(b_y=0; b_y<h; b_y++){ for(b_x=0; b_x<w; b_x++){ - int color[4]={1024,1024,1024,1024}; - int distance[4]={9999,9999,9999,9999}; int mb_index, error, j; int64_t guess, weight_sum; @@ -169,59 +226,12 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i if(IS_INTER(s->current_picture.f.mb_type[mb_index])) continue; //inter if(!(error&ER_DC_ERROR)) continue; //dc-ok - /* right block */ - for(j=b_x+1; j<w; j++){ - int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; - int error_j= s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if(intra_j==0 || !(error_j&ER_DC_ERROR)){ - color[0]= dc[j + b_y*stride]; - distance[0]= j-b_x; - break; - } - } - - /* left block */ - for(j=b_x-1; j>=0; j--){ - int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; - int error_j= s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if(intra_j==0 || !(error_j&ER_DC_ERROR)){ - color[1]= dc[j + b_y*stride]; - distance[1]= b_x-j; - break; - } - } - - /* bottom block */ - for(j=b_y+1; j<h; j++){ - int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride; - int error_j= s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if(intra_j==0 || !(error_j&ER_DC_ERROR)){ - color[2]= dc[b_x + j*stride]; - distance[2]= j-b_y; - break; - } - } - - /* top block */ - for(j=b_y-1; j>=0; j--){ - int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride; - int error_j= s->error_status_table[mb_index_j]; - int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]); - if(intra_j==0 || !(error_j&ER_DC_ERROR)){ - color[3]= dc[b_x + j*stride]; - distance[3]= b_y-j; - break; - } - } weight_sum=0; guess=0; for(j=0; j<4; j++){ - int64_t weight= 256*256*256*16/distance[j]; - guess+= weight*(int64_t)color[j]; + int64_t weight= 256*256*256*16/dist[b_x + b_y*stride][j]; + guess+= weight*(int64_t)col[b_x + b_y*stride][j]; weight_sum+= weight; } guess= (guess + weight_sum/2) / weight_sum; @@ -229,6 +239,8 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, i dc[b_x + b_y*stride]= guess; } } + av_freep(&col); + av_freep(&dist); } /** |