[FFmpeg-cvslog] error_concealment: optimize guess_dc()

Michael Niedermayer git at videolan.org
Thu Dec 22 00:34:18 CET 2011


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Thu Dec 22 00:24:39 2011 +0100| [a40f43db647bfacafbd1e27a4cd5f6134c6e6c53] | committer: Michael Niedermayer

error_concealment: optimize guess_dc()
Fixes Ticket811
Bug found by: Oana Stratulat

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a40f43db647bfacafbd1e27a4cd5f6134c6e6c53
---

 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 d4507cb..ee0e6fc 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);
 }
 
 /**



More information about the ffmpeg-cvslog mailing list