Opened 11 years ago

Closed 11 years ago

Last modified 10 years ago

#2684 closed defect (fixed)

Black becomes dark gray when converting rgb24 to gray

Reported by: Zsbán Ambrus Owned by:
Priority: important Component: swscale
Version: git-master Keywords: regression
Cc: Blocked By:
Blocking: Reproduced by developer: yes
Analyzed by developer: no

Description

When converting from rgb24 color space to gray colorspace, black input (represented as 0 0 0) becomes dary gray (represented as 16) in the output.
I believe the correct output would be black (represented as 0) in the output.

I have originally found this problem when reading from a png file, but it will be reproduced with raw input and output here.

How to reproduce:

I have tried the following on windows 7 with the zeranoe build ffmpeg version N-53307-g5a65fea built on May 20 2013 22:46:15 with gcc 4.7.3.

First, I have created a raw rgb24 input file with all zero contents, with the following command.

perl -we "binmode STDOUT; print pack (x).(3*16*16);" > zero-in-rgb.raw

I have then invoked ffmpeg with the following command.

ffmpeg -report -v 99 -f rawvideo -pix_fmt rgb24 -s 16x16 -i zero-in-rgb.raw -f rawvideo -pix_fmt gray zero-out-gray.raw

Finally, I have examined the output with the following command.

perl -we "open F, q/</, shift or die; binmode F or die; local $/ = \16; while (<F>) { print join(q/ /, unpack q/C*/, $_), qq/\n/; }" zero-out-gray.raw

which showed in its output that the output file does not contain zero bytes:

16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16
16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16

Following is the log the ffmpeg command has saved (80 lines long).

ffmpeg started on 2013-06-18 at 13:09:19
Report written to "ffmpeg-20130618-130919.log"
Command line:
"E:\\ambrus\\local\\ffmpeg-20130520-git-5a65fea-win64-shared\\bin\\ffmpeg.exe" -report -v 99 -f rawvideo -pix_fmt rgb24 -s 16x16 -i zero-in-rgb.raw -f rawvideo -pix_fmt gray zero-out-gray.raw
ffmpeg version N-53307-g5a65fea Copyright (c) 2000-2013 the FFmpeg developers
  built on May 20 2013 22:46:15 with gcc 4.7.3 (GCC)
  configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      52. 33.100 / 52. 33.100
  libavcodec     55. 10.101 / 55. 10.101
  libavformat    55.  7.100 / 55.  7.100
  libavdevice    55.  1.100 / 55.  1.100
  libavfilter     3. 68.101 /  3. 68.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Splitting the commandline.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Reading option '-v' ... matched as option 'v' (set logging level) with argument '99'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'rawvideo'.
Reading option '-pix_fmt' ... matched as option 'pix_fmt' (set pixel format) with argument 'rgb24'.
Reading option '-s' ... matched as option 's' (set frame size (WxH or abbreviation)) with argument '16x16'.
Reading option '-i' ... matched as input file with argument 'zero-in-rgb.raw'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'rawvideo'.
Reading option '-pix_fmt' ... matched as option 'pix_fmt' (set pixel format) with argument 'gray'.
Reading option 'zero-out-gray.raw' ... matched as output file.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option report (generate a report) with argument 1.
Applying option v (set logging level) with argument 99.
Successfully parsed a group of options.
Parsing a group of options: input file zero-in-rgb.raw.
Applying option f (force format) with argument rawvideo.
Applying option pix_fmt (set pixel format) with argument rgb24.
Applying option s (set frame size (WxH or abbreviation)) with argument 16x16.
Successfully parsed a group of options.
Opening an input file: zero-in-rgb.raw.
[rawvideo @ 000000000028f980] File position before avformat_find_stream_info() is 0
[rawvideo @ 000000000028f980] All info found
[rawvideo @ 000000000028f980] Estimating duration from bitrate, this may be inaccurate
[rawvideo @ 000000000028f980] File position after avformat_find_stream_info() is 768
Input #0, rawvideo, from 'zero-in-rgb.raw':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 153 kb/s
    Stream #0:0, 1, 1/25: Video: rawvideo (RGB[24] / 0x18424752), rgb24, 16x16, 1/25, 153 kb/s, 25 tbr, 25 tbn, 25 tbc
Successfully opened the file.
Parsing a group of options: output file zero-out-gray.raw.
Applying option f (force format) with argument rawvideo.
Applying option pix_fmt (set pixel format) with argument gray.
Successfully parsed a group of options.
Opening an output file: zero-out-gray.raw.
Successfully opened the file.
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'video_size' to value '16x16'
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'pix_fmt' to value '2'
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'time_base' to value '1/25'
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'pixel_aspect' to value '0/1'
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 000000000028ec80] Setting 'frame_rate' to value '25/1'
[graph 0 input from stream 0:0 @ 000000000028ec80] w:16 h:16 pixfmt:rgb24 tb:1/25 fr:25/1 sar:0/1 sws_param:flags=2
[format @ 000000000028bea0] compat: called with args=[gray]
[format @ 000000000028bea0] Setting 'pix_fmts' to value 'gray'
[auto-inserted scaler 0 @ 000000000028c6c0] Setting 'flags' to value '0x4'
[auto-inserted scaler 0 @ 000000000028c6c0] w:iw h:ih flags:'0x4' interl:0
[format @ 000000000028bea0] auto-inserting filter 'auto-inserted scaler 0' between the filter 'Parsed_null_0' and the filter 'format'
[AVFilterGraph @ 000000000028cf80] query_formats: 4 queried, 3 merged, 1 already done, 0 delayed
[auto-inserted scaler 0 @ 000000000028c6c0] w:16 h:16 fmt:rgb24 sar:0/1 -> w:16 h:16 fmt:gray sar:0/1 flags:0x4
Output #0, rawvideo, to 'zero-out-gray.raw':
  Metadata:
    encoder         : Lavf55.7.100
    Stream #0:0, 0, 1/90000: Video: rawvideo (Y800 / 0x30303859), gray, 16x16, 1/25, q=2-31, 200 kb/s, 90k tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo -> rawvideo)
Press [q] to stop, [?] for help
[output stream 0:0 @ 000000000028bd40] EOF on sink link output stream 0:0:default.
No more output streams to write to, finishing.
frame=    1 fps=0.0 q=0.0 Lsize=       0kB time=00:00:00.04 bitrate=  51.2kbits/s    

video:0kB audio:0kB subtitle:0 global headers:0kB muxing overhead 0.000000%
1 frames successfully decoded, 0 decoding errors
[AVIOContext @ 000000000028eba0] Statistics: 0 seeks, 1 writeouts
[AVIOContext @ 000000000028ff00] Statistics: 768 bytes read, 0 seeks

Change History (8)

comment:1 by Carl Eugen Hoyos, 11 years ago

Reproducible with:

$ ffmpeg -f lavfi -i color=black -vframes 1 black.bmp
$ ffmpeg -i black.bmp -pix_fmt gray -f rawvideo black.raw

Works better with FFmpeg 0.5.

comment:2 by Carl Eugen Hoyos, 11 years ago

Component: undeterminedswscale
Version: unspecifiedgit-master

comment:3 by Zsbán Ambrus, 11 years ago

Further experiments reveal that the output of the rgb24 to gray conversion seems similar to the Y plane of the yuv444p pixel format (as opposed to the yuvj444p pixel format). This makes repeated roundtrip conversions from gray to rgb24 to gray very inconsistent: doing the roundtrip four times reduces the contrast of the grayscale image by over 40%.

comment:4 by Carl Eugen Hoyos, 11 years ago

Keywords: regression added
Priority: normalimportant

If this is not expected behaviour, it is a regression since 6d4f53c

comment:5 by Michael Niedermayer, 11 years ago

Patch on ml

comment:6 by Michael Niedermayer, 11 years ago

Reproduced by developer: set
Resolution: fixed
Status: newclosed

comment:7 by Carl Eugen Hoyos, 11 years ago

[17:28] <b_jonas> I have verified, and it seems that https://trac.ffmpeg.org/ticket/2684 is indeed fixed, fix works for me. Thanks for all the developers.

Regarding your comment on irc: The problem is that some developers claim that the original behaviour (before the patch fixing this ticket) was intended and therefore block the patch for the 1.2.2 release (etc.), maybe you want to comment on the mailing list:
http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/165656/focus=165755
Just for completeness another user recently confirmed that the relevant commit fixed a bug he observed:
http://thread.gmane.org/gmane.comp.video.ffmpeg.user/46511

comment:8 by Zsbán Ambrus, 10 years ago

Although this bug is fixed, a very similar bug #3422 still exists.

Note: See TracTickets for help on using tickets.