[libav-bugs] [Bug 772] New: yuv420 -> rgb conversion sometimes fails to convert all pixels

bugzilla at aruru.libav.org bugzilla at aruru.libav.org
Sat Nov 1 22:37:43 CET 2014


https://bugzilla.libav.org/show_bug.cgi?id=772

            Bug ID: 772
           Summary: yuv420 -> rgb conversion sometimes fails to convert
                    all pixels
           Product: Libav
           Version: git HEAD
          Hardware: X86
                OS: All
            Status: NEW
          Severity: normal
          Priority: ---
         Component: libswscale
          Assignee: bugzilla at libav.org
          Reporter: dpb at corrigendum.ru

To reproduce:

$ convert -size 500x300 pattern:checkerboard test.jpg # create a 500x300 JPEG
$ avconv -i test.jpg test.bmp

Inspect test.bmp - it has a thin vertical strip of black pixels on the right
side.

I believe this happens because of a bug in the MMX-optimized conversion
routine. Namely, in libswscale/x86/yuv2rgb_template.c there's this code:

#define YUV2RGB_LOOP(depth)                                          \
    h_size = (c->dstW + 7) & ~7;                                     \
    if (h_size * depth > FFABS(dstStride[0]))                        \
        h_size -= 8;                                                 \
...

The code processes pixels in chunks of 8, and the check effectively cancels the
last chunk if writing it to the destination image would go past the end of the
line. Which is all well and good, but then that last chunk never gets processed
at all.

If the destination image uses the least stride possible (i.e. width times
depth), then the destination image will end up with a vertical strip of garbage
on the right whenever the width is not divisible by 8. With the way libav
calculates strides for its own images, it happens rarer, but it's still
possible. I believe it's when width % 16 is 1, 2, 3, 4, 5, 9, or 10, but I
could be wrong.

Here's the source image info in case you want it:

$ avconv -v 9 -loglevel 99 -i test.jpg
avconv version aae6b3b, Copyright (c) 2000-2014 the Libav developers
  built on Oct 31 2014 18:22:59 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --enable-debug --disable-optimizations --prefix=/opt/libav
--disable-pthreads
  libavutil     54.  5. 0 / 54.  5. 0
  libavcodec    56.  5. 2 / 56.  5. 2
  libavformat   56.  6. 2 / 56.  6. 2
  libavdevice   55.  1. 0 / 55.  1. 0
  libavfilter    5.  0. 0 /  5.  0. 0
  libavresample  2.  1. 0 /  2.  1. 0
  libswscale     3.  0. 0 /  3.  0. 0
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set libav* logging level) with
argument '9'.
Reading option '-loglevel' ... matched as option 'loglevel' (set libav* logging
level) with argument '99'.
Reading option '-i' ... matched as input file with argument 'test.jpg'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set libav* logging level) with argument 9.
Successfully parsed a group of options.
Parsing a group of options: input file test.jpg.
Successfully parsed a group of options.
Opening an input file: test.jpg.
[mjpeg @ 0x3672c80] marker=d8 avail_size_in_buf=28179
[mjpeg @ 0x3672c80] marker parser used 0 bytes (0 bits)
[mjpeg @ 0x3672c80] marker=e0 avail_size_in_buf=28177
[mjpeg @ 0x3672c80] marker parser used 16 bytes (128 bits)
[mjpeg @ 0x3672c80] marker=db avail_size_in_buf=28159
[mjpeg @ 0x3672c80] index=0
[mjpeg @ 0x3672c80] qscale[0]: 1
[mjpeg @ 0x3672c80] marker parser used 67 bytes (536 bits)
[mjpeg @ 0x3672c80] marker=db avail_size_in_buf=28090
[mjpeg @ 0x3672c80] index=1
[mjpeg @ 0x3672c80] qscale[1]: 2
[mjpeg @ 0x3672c80] marker parser used 67 bytes (536 bits)
[mjpeg @ 0x3672c80] marker=c0 avail_size_in_buf=28021
[mjpeg @ 0x3672c80] sof0: picture: 500x300
[mjpeg @ 0x3672c80] component 0 2:2 id: 0 quant:0
[mjpeg @ 0x3672c80] component 1 1:1 id: 1 quant:1
[mjpeg @ 0x3672c80] component 2 1:1 id: 2 quant:1
[mjpeg @ 0x3672c80] pix fmt id 22111100
[mjpeg @ 0x3672c80] marker parser used 17 bytes (136 bits)
[mjpeg @ 0x3672c80] marker=c4 avail_size_in_buf=28002
[mjpeg @ 0x3672c80] class=0 index=0 nb_codes=9
[mjpeg @ 0x3672c80] marker parser used 26 bytes (208 bits)
[mjpeg @ 0x3672c80] marker=c4 avail_size_in_buf=27974
[mjpeg @ 0x3672c80] class=1 index=0 nb_codes=227
[mjpeg @ 0x3672c80] marker parser used 68 bytes (544 bits)
[mjpeg @ 0x3672c80] marker=c4 avail_size_in_buf=27904
[mjpeg @ 0x3672c80] class=0 index=1 nb_codes=1
[mjpeg @ 0x3672c80] marker parser used 20 bytes (160 bits)
[mjpeg @ 0x3672c80] marker=c4 avail_size_in_buf=27882
[mjpeg @ 0x3672c80] class=1 index=1 nb_codes=1
[mjpeg @ 0x3672c80] marker parser used 20 bytes (160 bits)
[mjpeg @ 0x3672c80] escaping removed 123 bytes
[mjpeg @ 0x3672c80] marker=da avail_size_in_buf=27860
[mjpeg @ 0x3672c80] component: 0
[mjpeg @ 0x3672c80] component: 1
[mjpeg @ 0x3672c80] component: 2
[mjpeg @ 0x3672c80] marker parser used 27736 bytes (221886 bits)
[mjpeg @ 0x3672c80] marker=d9 avail_size_in_buf=0
[mjpeg @ 0x3672c80] mjpeg decode frame unused 0 bytes
Input #0, image2, from 'test.jpg':
  Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
    Stream #0:0, 1, 1/25: Video: mjpeg
      yuvj420p, pc, bt470bg/unknown/unknown, center
      500x300 [PAR 72:72 DAR 5:3], 0/1
      25 tbn
Successfully opened the file.
At least one output file must be specified

-- 
You are receiving this mail because:
You are watching all bug changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libav.org/pipermail/libav-bugs/attachments/20141101/09d12e6f/attachment-0001.html>


More information about the libav-bugs mailing list