[FFmpeg-devel] [PATCH] Fix alignment for calls to dsp diff_bytes()

Jeff Downs heydowns
Fri May 22 20:29:33 CEST 2009


diff_bytes() in dsputil has 16 byte alignment restriction on its first 
source pointer.  At a minimum, the C implementation, diff_bytes_c(), 
does depend on this.

huffyuv passes unaligned pointers to diff_bytes during encode 
(encode_frame, first set of calls to sub_left_prediction, which in turn 
uses diff_bytes).

This was revealed by "make test" (make regtest-huffyuv is the specific 
test) failing with Bus Error on Sparc/Solaris 
(http://fate.multimedia.cx/index.php?test_result=15846002).


Potential fix attached in two parts:

1. huff-offsets.patch:  Adds offset to encode_422_bitstream to enable 
skip of initial elements in s->temp when coding. Needed for second patch, 
split for clarity.

2. huff-align.patch: Changes calls to sub_left_prediction such that 
the source frame data pointers are no longer offset to skip the initial 
elements, thus keeping them properly aligned.  Changes encoding offset to 
compensate.

With patches, no change to regression tests on x86_64/Linux and regression 
tests now complete (but do not pass due to other issues ... I think) on 
Sparc/Solaris.

	-Jeff
-------------- next part --------------
Index: libavcodec/huffyuv.c
===================================================================
--- libavcodec/huffyuv.c	(revision 18893)
+++ libavcodec/huffyuv.c	(working copy)
@@ -746,8 +746,11 @@
 }
 
 #if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER
-static int encode_422_bitstream(HYuvContext *s, int count){
+static int encode_422_bitstream(HYuvContext *s, int offset, int count){
     int i;
+    const uint8_t *y = s->temp[0] + offset;
+    const uint8_t *u = s->temp[1] + offset/2;
+    const uint8_t *v = s->temp[2] + offset/2;
 
     if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){
         av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
@@ -755,10 +758,10 @@
     }
 
 #define LOAD4\
-            int y0 = s->temp[0][2*i];\
-            int y1 = s->temp[0][2*i+1];\
-            int u0 = s->temp[1][i];\
-            int v0 = s->temp[2][i];
+            int y0 = y[2*i];\
+            int y1 = y[2*i+1];\
+            int u0 = u[i];\
+            int v0 = v[i];
 
     count/=2;
     if(s->flags&CODEC_FLAG_PASS1){
@@ -1258,7 +1261,7 @@
         leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
         leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
 
-        encode_422_bitstream(s, width-2);
+        encode_422_bitstream(s, 0, width-2);
 
         if(s->predictor==MEDIAN){
             int lefttopy, lefttopu, lefttopv;
@@ -1268,7 +1271,7 @@
                 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
                 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
 
-                encode_422_bitstream(s, width);
+                encode_422_bitstream(s, 0, width);
                 y++; cy++;
             }
 
@@ -1276,7 +1279,7 @@
             leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu);
             leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv);
 
-            encode_422_bitstream(s, 4);
+            encode_422_bitstream(s, 0, 4);
 
             lefttopy= p->data[0][3];
             lefttopu= p->data[1][1];
@@ -1284,7 +1287,7 @@
             s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
             s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
             s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
-            encode_422_bitstream(s, width-4);
+            encode_422_bitstream(s, 0, width-4);
             y++; cy++;
 
             for(; y<height; y++,cy++){
@@ -1307,7 +1310,7 @@
                 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
                 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
 
-                encode_422_bitstream(s, width);
+                encode_422_bitstream(s, 0, width);
             }
         }else{
             for(cy=y=1; y<height; y++,cy++){
@@ -1347,7 +1350,7 @@
                     leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
                 }
 
-                encode_422_bitstream(s, width);
+                encode_422_bitstream(s, 0, width);
             }
         }
     }else if(avctx->pix_fmt == PIX_FMT_RGB32){
-------------- next part --------------
--- libavcodec/huffyuv-offsetadded.c	2009-05-22 13:59:15.000000000 -0400
+++ libavcodec/huffyuv.c	2009-05-22 13:59:27.000000000 -0400
@@ -1257,11 +1257,11 @@
         put_bits(&s->pb, 8, leftu= p->data[1][0]);
         put_bits(&s->pb, 8,        p->data[0][0]);
 
-        lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
-        leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
-        leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
+        lefty= sub_left_prediction(s, s->temp[0], p->data[0], width , 0);
+        leftu= sub_left_prediction(s, s->temp[1], p->data[1], width2, 0);
+        leftv= sub_left_prediction(s, s->temp[2], p->data[2], width2, 0);
 
-        encode_422_bitstream(s, 0, width-2);
+        encode_422_bitstream(s, 2, width-2);
 
         if(s->predictor==MEDIAN){
             int lefttopy, lefttopu, lefttopv;



More information about the ffmpeg-devel mailing list