diff mbox

[FFmpeg-devel] avcodec/utvideodec: decode to GBR(A)P

Message ID 20170626093331.13799-1-onemda@gmail.com
State New
Headers show

Commit Message

Paul B Mahol June 26, 2017, 9:33 a.m. UTC
This is actually internal utvideo format.
Allows to make use of SIMD for median prediction for rgb(a) formats,
thus speeding up decoding.
Simplifies code, eases further developement and maintenance.

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavcodec/utvideodec.c                   | 283 +++---------------------------
 tests/ref/fate/utvideo_rgb_left           |   8 +-
 tests/ref/fate/utvideo_rgb_median         |  10 +-
 tests/ref/fate/utvideo_rgba_left          |  10 +-
 tests/ref/fate/utvideo_rgba_median        |  10 +-
 tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
 6 files changed, 49 insertions(+), 274 deletions(-)

Comments

wm4 June 26, 2017, 10:07 a.m. UTC | #1
On Mon, 26 Jun 2017 11:33:31 +0200
Paul B Mahol <onemda@gmail.com> wrote:

> This is actually internal utvideo format.
> Allows to make use of SIMD for median prediction for rgb(a) formats,
> thus speeding up decoding.
> Simplifies code, eases further developement and maintenance.
> 
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  libavcodec/utvideodec.c                   | 283 +++---------------------------
>  tests/ref/fate/utvideo_rgb_left           |   8 +-
>  tests/ref/fate/utvideo_rgb_median         |  10 +-
>  tests/ref/fate/utvideo_rgba_left          |  10 +-
>  tests/ref/fate/utvideo_rgba_median        |  10 +-
>  tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
>  6 files changed, 49 insertions(+), 274 deletions(-)

Holy shit, that's a nice find.
Clément Bœsch June 26, 2017, 10:37 a.m. UTC | #2
On Mon, Jun 26, 2017 at 11:33:31AM +0200, Paul B Mahol wrote:
> This is actually internal utvideo format.
> Allows to make use of SIMD for median prediction for rgb(a) formats,
> thus speeding up decoding.
> Simplifies code, eases further developement and maintenance.
> 
> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> ---
>  libavcodec/utvideodec.c                   | 283 +++---------------------------
>  tests/ref/fate/utvideo_rgb_left           |   8 +-
>  tests/ref/fate/utvideo_rgb_median         |  10 +-
>  tests/ref/fate/utvideo_rgba_left          |  10 +-
>  tests/ref/fate/utvideo_rgba_median        |  10 +-
>  tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
>  6 files changed, 49 insertions(+), 274 deletions(-)
> 

I think you can drop ff_ut_rgb_order

Can you also add an explanation about the FATE changes?
Paul B Mahol June 26, 2017, 10:46 a.m. UTC | #3
On 6/26/17, Clement Boesch <u@pkh.me> wrote:
> On Mon, Jun 26, 2017 at 11:33:31AM +0200, Paul B Mahol wrote:
>> This is actually internal utvideo format.
>> Allows to make use of SIMD for median prediction for rgb(a) formats,
>> thus speeding up decoding.
>> Simplifies code, eases further developement and maintenance.
>>
>> Signed-off-by: Paul B Mahol <onemda@gmail.com>
>> ---
>>  libavcodec/utvideodec.c                   | 283
>> +++---------------------------
>>  tests/ref/fate/utvideo_rgb_left           |   8 +-
>>  tests/ref/fate/utvideo_rgb_median         |  10 +-
>>  tests/ref/fate/utvideo_rgba_left          |  10 +-
>>  tests/ref/fate/utvideo_rgba_median        |  10 +-
>>  tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
>>  6 files changed, 49 insertions(+), 274 deletions(-)
>>
>
> I think you can drop ff_ut_rgb_order

Will do.

>
> Can you also add an explanation about the FATE changes?

FATE changes because it now decodes to GBR(A)P instead of packed formats.
wm4 June 26, 2017, 10:58 a.m. UTC | #4
On Mon, 26 Jun 2017 12:46:29 +0200
Paul B Mahol <onemda@gmail.com> wrote:

> On 6/26/17, Clement Boesch <u@pkh.me> wrote:
> > On Mon, Jun 26, 2017 at 11:33:31AM +0200, Paul B Mahol wrote:  
> >> This is actually internal utvideo format.
> >> Allows to make use of SIMD for median prediction for rgb(a) formats,
> >> thus speeding up decoding.
> >> Simplifies code, eases further developement and maintenance.
> >>
> >> Signed-off-by: Paul B Mahol <onemda@gmail.com>
> >> ---
> >>  libavcodec/utvideodec.c                   | 283
> >> +++---------------------------
> >>  tests/ref/fate/utvideo_rgb_left           |   8 +-
> >>  tests/ref/fate/utvideo_rgb_median         |  10 +-
> >>  tests/ref/fate/utvideo_rgba_left          |  10 +-
> >>  tests/ref/fate/utvideo_rgba_median        |  10 +-
> >>  tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
> >>  6 files changed, 49 insertions(+), 274 deletions(-)
> >>  
> >
> > I think you can drop ff_ut_rgb_order  
> 
> Will do.
> 
> >
> > Can you also add an explanation about the FATE changes?  
> 
> FATE changes because it now decodes to GBR(A)P instead of packed formats.

(I assume that you verified that the output is exactly the same when
the output is reordered to the same pixfmt by swscale.)
Paul B Mahol June 26, 2017, 11:12 a.m. UTC | #5
On 6/26/17, wm4 <nfxjfg@googlemail.com> wrote:
> On Mon, 26 Jun 2017 12:46:29 +0200
> Paul B Mahol <onemda@gmail.com> wrote:
>
>> On 6/26/17, Clement Boesch <u@pkh.me> wrote:
>> > On Mon, Jun 26, 2017 at 11:33:31AM +0200, Paul B Mahol wrote:
>> >> This is actually internal utvideo format.
>> >> Allows to make use of SIMD for median prediction for rgb(a) formats,
>> >> thus speeding up decoding.
>> >> Simplifies code, eases further developement and maintenance.
>> >>
>> >> Signed-off-by: Paul B Mahol <onemda@gmail.com>
>> >> ---
>> >>  libavcodec/utvideodec.c                   | 283
>> >> +++---------------------------
>> >>  tests/ref/fate/utvideo_rgb_left           |   8 +-
>> >>  tests/ref/fate/utvideo_rgb_median         |  10 +-
>> >>  tests/ref/fate/utvideo_rgba_left          |  10 +-
>> >>  tests/ref/fate/utvideo_rgba_median        |  10 +-
>> >>  tests/ref/fate/utvideo_rgba_single_symbol |   2 +-
>> >>  6 files changed, 49 insertions(+), 274 deletions(-)
>> >>
>> >
>> > I think you can drop ff_ut_rgb_order
>>
>> Will do.
>>
>> >
>> > Can you also add an explanation about the FATE changes?
>>
>> FATE changes because it now decodes to GBR(A)P instead of packed formats.
>
> (I assume that you verified that the output is exactly the same when
> the output is reordered to the same pixfmt by swscale.)

Yes it is.
Jan Ekström June 26, 2017, 5:51 p.m. UTC | #6
Hi,

On Mon, Jun 26, 2017 at 2:12 PM, Paul B Mahol <onemda@gmail.com> wrote:
>
> Yes it is.

As the output is verified to be bit-exact, this is LGTM for me (as
someone who has poked this format's dec/enc in the past).

Jan
diff mbox

Patch

diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 7979618..0c6f89e 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -333,21 +333,25 @@  fail:
     return AVERROR_INVALIDDATA;
 }
 
-static void restore_rgb_planes(uint8_t *src, int step, ptrdiff_t stride,
-                               int width, int height)
+static void restore_rgb_planes(AVFrame *frame, int width, int height)
 {
-    int i, j;
+    uint8_t *src_r = (uint8_t *)frame->data[2];
+    uint8_t *src_g = (uint8_t *)frame->data[0];
+    uint8_t *src_b = (uint8_t *)frame->data[1];
     uint8_t r, g, b;
+    int i, j;
 
     for (j = 0; j < height; j++) {
-        for (i = 0; i < width * step; i += step) {
-            r = src[i];
-            g = src[i + 1];
-            b = src[i + 2];
-            src[i]     = r + g - 0x80;
-            src[i + 2] = b + g - 0x80;
+        for (i = 0; i < width; i++) {
+            r = src_r[i];
+            g = src_g[i];
+            b = src_b[i];
+            src_r[i] = r + g - 0x80;
+            src_b[i] = b + g - 0x80;
         }
-        src += stride;
+        src_r += frame->linesize[2];
+        src_g += frame->linesize[0];
+        src_b += frame->linesize[1];
     }
 }
 
@@ -476,132 +480,6 @@  static void restore_median_planar_il(UtvideoContext *c, uint8_t *src, ptrdiff_t
     }
 }
 
-static void restore_median_packed(uint8_t *src, int step, ptrdiff_t stride,
-                                  int width, int height, int slices, int rmode)
-{
-    int i, j, slice;
-    int A, B, C;
-    uint8_t *bsrc;
-    int slice_start, slice_height;
-    const int cmask = ~rmode;
-
-    for (slice = 0; slice < slices; slice++) {
-        slice_start  = ((slice * height) / slices) & cmask;
-        slice_height = ((((slice + 1) * height) / slices) & cmask) -
-                       slice_start;
-
-        if (!slice_height)
-            continue;
-        bsrc = src + slice_start * stride;
-
-        // first line - left neighbour prediction
-        bsrc[0] += 0x80;
-        A = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            bsrc[i] += A;
-            A        = bsrc[i];
-        }
-        bsrc += stride;
-        if (slice_height <= 1)
-            continue;
-        // second line - first element has top prediction, the rest uses median
-        C        = bsrc[-stride];
-        bsrc[0] += C;
-        A        = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            B        = bsrc[i - stride];
-            bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
-            C        = B;
-            A        = bsrc[i];
-        }
-        bsrc += stride;
-        // the rest of lines use continuous median prediction
-        for (j = 2; j < slice_height; j++) {
-            for (i = 0; i < width * step; i += step) {
-                B        = bsrc[i - stride];
-                bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
-                C        = B;
-                A        = bsrc[i];
-            }
-            bsrc += stride;
-        }
-    }
-}
-
-/* UtVideo interlaced mode treats every two lines as a single one,
- * so restoring function should take care of possible padding between
- * two parts of the same "line".
- */
-static void restore_median_packed_il(uint8_t *src, int step, ptrdiff_t stride,
-                                     int width, int height, int slices, int rmode)
-{
-    int i, j, slice;
-    int A, B, C;
-    uint8_t *bsrc;
-    int slice_start, slice_height;
-    const int cmask   = ~(rmode ? 3 : 1);
-    const ptrdiff_t stride2 = stride << 1;
-
-    for (slice = 0; slice < slices; slice++) {
-        slice_start    = ((slice * height) / slices) & cmask;
-        slice_height   = ((((slice + 1) * height) / slices) & cmask) -
-                         slice_start;
-        slice_height >>= 1;
-        if (!slice_height)
-            continue;
-
-        bsrc = src + slice_start * stride;
-
-        // first line - left neighbour prediction
-        bsrc[0] += 0x80;
-        A        = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            bsrc[i] += A;
-            A        = bsrc[i];
-        }
-        for (i = 0; i < width * step; i += step) {
-            bsrc[stride + i] += A;
-            A                 = bsrc[stride + i];
-        }
-        bsrc += stride2;
-        if (slice_height <= 1)
-            continue;
-        // second line - first element has top prediction, the rest uses median
-        C        = bsrc[-stride2];
-        bsrc[0] += C;
-        A        = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            B        = bsrc[i - stride2];
-            bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
-            C        = B;
-            A        = bsrc[i];
-        }
-        for (i = 0; i < width * step; i += step) {
-            B                 = bsrc[i - stride];
-            bsrc[stride + i] += mid_pred(A, B, (uint8_t)(A + B - C));
-            C                 = B;
-            A                 = bsrc[stride + i];
-        }
-        bsrc += stride2;
-        // the rest of lines use continuous median prediction
-        for (j = 2; j < slice_height; j++) {
-            for (i = 0; i < width * step; i += step) {
-                B        = bsrc[i - stride2];
-                bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
-                C        = B;
-                A        = bsrc[i];
-            }
-            for (i = 0; i < width * step; i += step) {
-                B                 = bsrc[i - stride];
-                bsrc[i + stride] += mid_pred(A, B, (uint8_t)(A + B - C));
-                C                 = B;
-                A                 = bsrc[i + stride];
-            }
-            bsrc += stride2;
-        }
-    }
-}
-
 static void restore_gradient_planar(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
                                     int width, int height, int slices, int rmode)
 {
@@ -691,108 +569,6 @@  static void restore_gradient_planar_il(UtvideoContext *c, uint8_t *src, ptrdiff_
     }
 }
 
-static void restore_gradient_packed(uint8_t *src, int step, ptrdiff_t stride,
-                                    int width, int height, int slices, int rmode)
-{
-    int i, j, slice;
-    int A, B, C;
-    uint8_t *bsrc;
-    int slice_start, slice_height;
-    const int cmask = ~rmode;
-
-    for (slice = 0; slice < slices; slice++) {
-        slice_start  = ((slice * height) / slices) & cmask;
-        slice_height = ((((slice + 1) * height) / slices) & cmask) -
-                       slice_start;
-
-        if (!slice_height)
-            continue;
-        bsrc = src + slice_start * stride;
-
-        // first line - left neighbour prediction
-        bsrc[0] += 0x80;
-        A = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            bsrc[i] += A;
-            A        = bsrc[i];
-        }
-        bsrc += stride;
-        if (slice_height <= 1)
-            continue;
-        for (j = 1; j < slice_height; j++) {
-            // second line - first element has top prediction, the rest uses gradient
-            C        = bsrc[-stride];
-            bsrc[0] += C;
-            for (i = step; i < width * step; i += step) {
-                A = bsrc[i - stride];
-                B = bsrc[i - (stride + step)];
-                C = bsrc[i - step];
-                bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
-            }
-            bsrc += stride;
-        }
-    }
-}
-
-static void restore_gradient_packed_il(uint8_t *src, int step, ptrdiff_t stride,
-                                       int width, int height, int slices, int rmode)
-{
-    int i, j, slice;
-    int A, B, C;
-    uint8_t *bsrc;
-    int slice_start, slice_height;
-    const int cmask   = ~(rmode ? 3 : 1);
-    const ptrdiff_t stride2 = stride << 1;
-
-    for (slice = 0; slice < slices; slice++) {
-        slice_start    = ((slice * height) / slices) & cmask;
-        slice_height   = ((((slice + 1) * height) / slices) & cmask) -
-                         slice_start;
-        slice_height >>= 1;
-        if (!slice_height)
-            continue;
-
-        bsrc = src + slice_start * stride;
-
-        // first line - left neighbour prediction
-        bsrc[0] += 0x80;
-        A        = bsrc[0];
-        for (i = step; i < width * step; i += step) {
-            bsrc[i] += A;
-            A        = bsrc[i];
-        }
-        for (i = 0; i < width * step; i += step) {
-            bsrc[stride + i] += A;
-            A                 = bsrc[stride + i];
-        }
-        bsrc += stride2;
-        if (slice_height <= 1)
-            continue;
-        for (j = 1; j < slice_height; j++) {
-            // second line - first element has top prediction, the rest uses gradient
-            C        = bsrc[-stride2];
-            bsrc[0] += C;
-            for (i = step; i < width * step; i += step) {
-                A = bsrc[i - stride2];
-                B = bsrc[i - (stride2 + step)];
-                C = bsrc[i - step];
-                bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
-            }
-            A = bsrc[-stride];
-            B = bsrc[-(step + stride + stride - width * step)];
-            C = bsrc[width * step - step];
-            bsrc[stride] = (A - B + C + bsrc[stride]) & 0xFF;
-            for (i = step; i < width * step; i += step) {
-                A = bsrc[i - stride];
-                B = bsrc[i - (step + stride)];
-                C = bsrc[i - step + stride];
-                bsrc[i + stride] = (A - B + C + bsrc[i + stride]) & 0xFF;
-            }
-            bsrc += stride2;
-        }
-    }
-}
-
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
@@ -887,41 +663,40 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     switch (c->avctx->pix_fmt) {
-    case AV_PIX_FMT_RGB24:
-    case AV_PIX_FMT_RGBA:
+    case AV_PIX_FMT_GBRP:
+    case AV_PIX_FMT_GBRAP:
         for (i = 0; i < c->planes; i++) {
-            ret = decode_plane(c, i, frame.f->data[0] + ff_ut_rgb_order[i],
-                               c->planes, frame.f->linesize[0], avctx->width,
+            ret = decode_plane(c, i, frame.f->data[i], 1,
+                               frame.f->linesize[i], avctx->width,
                                avctx->height, plane_start[i],
                                c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median_packed(frame.f->data[0] + ff_ut_rgb_order[i],
-                                          c->planes, frame.f->linesize[0], avctx->width,
+                    restore_median_planar(c, frame.f->data[i],
+                                          frame.f->linesize[i], avctx->width,
                                           avctx->height, c->slices, 0);
                 } else {
-                    restore_median_packed_il(frame.f->data[0] + ff_ut_rgb_order[i],
-                                             c->planes, frame.f->linesize[0],
+                    restore_median_planar_il(c, frame.f->data[i],
+                                             frame.f->linesize[i],
                                              avctx->width, avctx->height, c->slices,
                                              0);
                 }
             } else if (c->frame_pred == PRED_GRADIENT) {
                 if (!c->interlaced) {
-                    restore_gradient_packed(frame.f->data[0] + ff_ut_rgb_order[i],
-                                            c->planes, frame.f->linesize[0], avctx->width,
+                    restore_gradient_planar(c, frame.f->data[i],
+                                            frame.f->linesize[i], avctx->width,
                                             avctx->height, c->slices, 0);
                 } else {
-                    restore_gradient_packed_il(frame.f->data[0] + ff_ut_rgb_order[i],
-                                               c->planes, frame.f->linesize[0],
+                    restore_gradient_planar_il(c, frame.f->data[i],
+                                               frame.f->linesize[i],
                                                avctx->width, avctx->height, c->slices,
                                                0);
                 }
             }
         }
-        restore_rgb_planes(frame.f->data[0], c->planes, frame.f->linesize[0],
-                           avctx->width, avctx->height);
+        restore_rgb_planes(frame.f, avctx->width, avctx->height);
         break;
     case AV_PIX_FMT_GBRAP10:
     case AV_PIX_FMT_GBRP10:
@@ -1094,11 +869,11 @@  static av_cold int decode_init(AVCodecContext *avctx)
     switch (avctx->codec_tag) {
     case MKTAG('U', 'L', 'R', 'G'):
         c->planes      = 3;
-        avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        avctx->pix_fmt = AV_PIX_FMT_GBRP;
         break;
     case MKTAG('U', 'L', 'R', 'A'):
         c->planes      = 4;
-        avctx->pix_fmt = AV_PIX_FMT_RGBA;
+        avctx->pix_fmt = AV_PIX_FMT_GBRAP;
         break;
     case MKTAG('U', 'L', 'Y', '0'):
         c->planes      = 3;
diff --git a/tests/ref/fate/utvideo_rgb_left b/tests/ref/fate/utvideo_rgb_left
index d2ccbce..23e48c4 100644
--- a/tests/ref/fate/utvideo_rgb_left
+++ b/tests/ref/fate/utvideo_rgb_left
@@ -3,7 +3,7 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 640x480
 #sar 0: 0/1
-0,          0,          0,        1,   921600, 0x27e6001e
-0,          1,          1,        1,   921600, 0x7c0a92bc
-0,          2,          2,        1,   921600, 0x4d2be42c
-0,          3,          3,        1,   921600, 0x58ddd0be
+0,          0,          0,        1,   921600, 0xb457001e
+0,          1,          1,        1,   921600, 0xceff92bc
+0,          2,          2,        1,   921600, 0x762de42c
+0,          3,          3,        1,   921600, 0xef14d0be
diff --git a/tests/ref/fate/utvideo_rgb_median b/tests/ref/fate/utvideo_rgb_median
index 913b697..e7c623a 100644
--- a/tests/ref/fate/utvideo_rgb_median
+++ b/tests/ref/fate/utvideo_rgb_median
@@ -3,8 +3,8 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 640x480
 #sar 0: 0/1
-0,          0,          0,        1,   921600, 0x9776611f
-0,          1,          1,        1,   921600, 0xdbfa64f4
-0,          2,          2,        1,   921600, 0xed2a0580
-0,          3,          3,        1,   921600, 0x6ecc80bc
-0,          4,          4,        1,   921600, 0x58ddd0be
+0,          0,          0,        1,   921600, 0x85af611f
+0,          1,          1,        1,   921600, 0xc97a64f4
+0,          2,          2,        1,   921600, 0xb1db0580
+0,          3,          3,        1,   921600, 0xa18d80bc
+0,          4,          4,        1,   921600, 0xef14d0be
diff --git a/tests/ref/fate/utvideo_rgba_left b/tests/ref/fate/utvideo_rgba_left
index cb7876f..b24b7f4 100644
--- a/tests/ref/fate/utvideo_rgba_left
+++ b/tests/ref/fate/utvideo_rgba_left
@@ -3,8 +3,8 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 640x480
 #sar 0: 0/1
-0,          0,          0,        1,  1228800, 0xf1bc9432
-0,          1,          1,        1,  1228800, 0x8480d1e5
-0,          2,          2,        1,  1228800, 0xb01d5fb2
-0,          3,          3,        1,  1228800, 0x53cb42c4
-0,          4,          4,        1,  1228800, 0x2b2ea176
+0,          0,          0,        1,  1228800, 0xf9f49432
+0,          1,          1,        1,  1228800, 0xf089d1e5
+0,          2,          2,        1,  1228800, 0xbd025fb2
+0,          3,          3,        1,  1228800, 0x17bf42c4
+0,          4,          4,        1,  1228800, 0xe31ea176
diff --git a/tests/ref/fate/utvideo_rgba_median b/tests/ref/fate/utvideo_rgba_median
index cb7876f..b24b7f4 100644
--- a/tests/ref/fate/utvideo_rgba_median
+++ b/tests/ref/fate/utvideo_rgba_median
@@ -3,8 +3,8 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 640x480
 #sar 0: 0/1
-0,          0,          0,        1,  1228800, 0xf1bc9432
-0,          1,          1,        1,  1228800, 0x8480d1e5
-0,          2,          2,        1,  1228800, 0xb01d5fb2
-0,          3,          3,        1,  1228800, 0x53cb42c4
-0,          4,          4,        1,  1228800, 0x2b2ea176
+0,          0,          0,        1,  1228800, 0xf9f49432
+0,          1,          1,        1,  1228800, 0xf089d1e5
+0,          2,          2,        1,  1228800, 0xbd025fb2
+0,          3,          3,        1,  1228800, 0x17bf42c4
+0,          4,          4,        1,  1228800, 0xe31ea176
diff --git a/tests/ref/fate/utvideo_rgba_single_symbol b/tests/ref/fate/utvideo_rgba_single_symbol
index 553c835..a20dc3d 100644
--- a/tests/ref/fate/utvideo_rgba_single_symbol
+++ b/tests/ref/fate/utvideo_rgba_single_symbol
@@ -3,4 +3,4 @@ 
 #codec_id 0: rawvideo
 #dimensions 0: 1024x768
 #sar 0: 0/1
-0,          0,          0,        1,  3145728, 0xac95c593
+0,          0,          0,        1,  3145728, 0xa07dc593