Browse code

avcodec/huffyuv: fix median prediction for >8bps

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

Michael Niedermayer authored on 2014/01/17 02:33:17
Showing 2 changed files
... ...
@@ -725,6 +725,32 @@ static void add_bytes(HYuvContext *s, uint8_t *dst, uint8_t *src, int w)
725 725
     }
726 726
 }
727 727
 
728
+static void add_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src, const uint8_t *diff, int w, int *left, int *left_top)
729
+{
730
+    if (s->bps <= 8) {
731
+        s->dsp.add_hfyu_median_prediction(dst, src, diff, w, left, left_top);
732
+    } else {
733
+        //FIXME optimize
734
+        unsigned mask = s->n-1;
735
+        int i;
736
+        uint16_t l, lt;
737
+        const uint16_t *src16  = (const uint16_t *)src;
738
+        const uint16_t *diff16 = (const uint16_t *)diff;
739
+        uint16_t       *dst16  = (      uint16_t *)dst;
740
+
741
+        l  = *left;
742
+        lt = *left_top;
743
+
744
+        for(i=0; i<w; i++){
745
+            l  = (mid_pred(l, src16[i], (l + src16[i] - lt) & mask) + diff16[i]) & mask;
746
+            lt = src16[i];
747
+            dst16[i] = l;
748
+        }
749
+
750
+        *left     = l;
751
+        *left_top = lt;
752
+    }
753
+}
728 754
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
729 755
                         AVPacket *avpkt)
730 756
 {
... ...
@@ -817,7 +843,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
817 817
 
818 818
                 lefttop = p->data[plane][0];
819 819
                 decode_plane_bitstream(s, w, plane);
820
-                s->dsp.add_hfyu_median_prediction(p->data[plane] + fake_stride, p->data[plane], s->temp[0], w, &left, &lefttop);
820
+                add_median_prediction(s, p->data[plane] + fake_stride, p->data[plane], s->temp[0], w, &left, &lefttop);
821 821
                 y++;
822 822
 
823 823
                 for (; y<h; y++) {
... ...
@@ -827,7 +853,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
827 827
 
828 828
                     dst = p->data[plane] + p->linesize[plane] * y;
829 829
 
830
-                    s->dsp.add_hfyu_median_prediction(dst, dst - fake_stride, s->temp[0], w, &left, &lefttop);
830
+                    add_median_prediction(s, dst, dst - fake_stride, s->temp[0], w, &left, &lefttop);
831 831
                 }
832 832
 
833 833
                 break;
... ...
@@ -153,6 +153,33 @@ static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst,
153 153
     *blue  = src[(w - 1) * 3 + 2];
154 154
 }
155 155
 
156
+static void sub_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top)
157
+{
158
+    if (s->bps <= 8) {
159
+        s->dsp.sub_hfyu_median_prediction(dst, src1, src2, w , left, left_top);
160
+    } else {
161
+        int i;
162
+        uint16_t l, lt;
163
+        const uint16_t *src116 = (const uint16_t *)src1;
164
+        const uint16_t *src216 = (const uint16_t *)src2;
165
+        uint16_t       *dst16  = (      uint16_t *)dst;
166
+        unsigned mask = s->n - 1;
167
+
168
+        l  = *left;
169
+        lt = *left_top;
170
+
171
+        for(i=0; i<w; i++){
172
+            const int pred = mid_pred(l, src116[i], (l + src116[i] - lt) & mask);
173
+            lt = src116[i];
174
+            l  = src216[i];
175
+            dst16[i] = (l - pred) & mask;
176
+        }
177
+
178
+        *left     = l;
179
+        *left_top = lt;
180
+    }
181
+}
182
+
156 183
 static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
157 184
 {
158 185
     int i;
... ...
@@ -857,7 +884,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
857 857
                 for (; y < h; y++) {
858 858
                     uint8_t *dst = p->data[plane] + p->linesize[plane] * y;
859 859
 
860
-                    s->dsp.sub_hfyu_median_prediction(s->temp[0], dst - fake_stride, dst, w , &left, &lefttop);
860
+                    sub_median_prediction(s, s->temp[0], dst - fake_stride, dst, w , &left, &lefttop);
861 861
 
862 862
                     encode_plane_bitstream(s, w, plane);
863 863
                 }