Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#2684 closed defect (fixed)

Black becomes dark gray when converting rgb24 to gray

Reported by: b_jonas 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 Changed 4 years ago by cehoyos

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 Changed 4 years ago by cehoyos

  • Component changed from undetermined to swscale
  • Version changed from unspecified to git-master

comment:3 Changed 4 years ago by b_jonas

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 Changed 4 years ago by cehoyos

  • Keywords regression added
  • Priority changed from normal to important

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

comment:5 Changed 4 years ago by michael

Patch on ml

comment:6 Changed 4 years ago by michael

  • Reproduced by developer set
  • Resolution set to fixed
  • Status changed from new to closed

comment:7 Changed 4 years ago by cehoyos

[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 Changed 4 years ago by b_jonas

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

Note: See TracTickets for help on using tickets.