aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-12-22 00:24:39 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-22 00:25:48 +0100
commita40f43db647bfacafbd1e27a4cd5f6134c6e6c53 (patch)
tree3ec929f7ff920bcfb803709cd869de881e012d5f
parent8d960fbc70d5d7b6cd62db22712a8d5c2c5e26bf (diff)
downloadffmpeg-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.c114
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);
}
/**