Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#4986 closed defect (invalid)

video artifacts when encoding a 10 bit image sequence, using 10 bit build of x264

Reported by: spacediver Owned by:
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no


Summary of the bug: When I encode a 16 bit png file using the 10 bit x264 build, there are artifacts present in the video that are not present when the original png files are viewed. I brought this to Zeranoe's attention, who suggested it may be a bug in swscale, and that I report it.

How to reproduce:

If you have a 10 bit video pipeline (including display), then you won't need to enable dithering in madVR to see this. If you have an 8 bit system, then dithering will need to be enabled (rendering/dithering/pick your favourite dithering mode).

Make sure enable fullscreen exclusive mode is checked (rendering/general settings).

First, load up "1.png" in madVR, and switch to fullscreen. Turn lights off, and let your eyes dark adapt. You should see 8 distinct vertical bars that fill the screen.

Now load up "test.mp4". This is a movie file that was created from an image sequence of 10 images similar to 1.png. Once file is loaded, scroll the slider to the beginning (it should be paused). Now switch to full screen, and inspect the image. On my end, the third and fourth bars are identical, so there are only seven distinct bars. Now using CTRL+rightarrow, step through the 10 frames, and notice how the same sort of artifact appears across many of these gradients. Also notice that on some frames, there are gradient divisions where they shouldn't be. For example, see frame 6 (and compare with 6.png).

The images are grayscale gradients. Each image contains eight 10bit codes: the first image has codes 0-7 (out of a possible 1023), the second has codes 8-15, etc. They were created in Matlab, by first encoding in the range of 1-1024, then multiplying by 64, and then subtracting 1, so that they were appropriately scaled to fit the 16 png format.

I'm attaching two images (corresponding to the 1st and 6th frames of the mp4), and the encoded mp4.

I'm using the following build of ffmeg (static, win32): x264 10-bit Builds (20151027-git-e6f9952), found here:

This is the code I'm using to encode the video:

% ffmpeg -start_number 1 -i %d.png test.mp4

here is the console output:

>ffmpeg -start_number 1 -i %d.png test.mp4
ffmpeg version N-76277-ge6f9952 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib
--enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray
--enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-lib
gsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libop
encore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-
libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aa
cenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp -
-enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --e
  libavutil      55.  4.100 / 55.  4.100
  libavcodec     57. 10.100 / 57. 10.100
  libavformat    57. 11.100 / 57. 11.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 14.100 /  6. 14.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.100 /  2.  0.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, image2, from '%d.png':
  Duration: 00:00:00.40, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb48be(pc), 1920x1200, 25 fps, 25 tbr, 25 tbn, 25 tbc
No pixel format specified, yuv444p10le for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264 @ 009a8c20] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
[libx264 @ 009a8c20] profile High 4:4:4 Predictive, level 5.0, 4:4:4 10-bit
[libx264 @ 009a8c20] 264 - core 148 r2638 7599210 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http
:// - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7
psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fas
t_pskip=1 chroma_qp_offset=4 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlace
d=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 op
en_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=
1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=81 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'test.mp4':
    encoder         : Lavf57.11.100
    Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv444p10le, 1920x1200, q=-1--1, 25 f
ps, 12800 tbn, 25 tbc
      encoder         : Lavc57.10.100 libx264
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=   10 fps=9.3 q=-1.0 Lsize=       5kB time=00:00:00.32 bitrate= 123.2kbits/s
video:4kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 22.623196%
[libx264 @ 009a8c20] frame I:1     Avg QP:20.00  size:   551
[libx264 @ 009a8c20] frame P:8     Avg QP:20.62  size:   291
[libx264 @ 009a8c20] frame B:1     Avg QP:21.00  size:   451
[libx264 @ 009a8c20] consecutive B-frames: 80.0% 20.0%  0.0%  0.0%
[libx264 @ 009a8c20] mb I  I16..4:  0.0% 100.0%  0.0%
[libx264 @ 009a8c20] mb P  I16..4: 15.8%  4.8%  0.0%  P16..4:  0.1%  0.0%  0.0%  0.0%  0.0%    skip:79
[libx264 @ 009a8c20] mb B  I16..4:  0.0%  5.8%  0.0%  B16..8:  0.0%  0.0%  0.0%  direct: 0.0%  skip:94
.2%  L0: 0.0% L1: 0.0% BI:100.0%
[libx264 @ 009a8c20] 8x8 transform intra:53.4% inter:100.0%
[libx264 @ 009a8c20] coded y,u,v intra: 0.0% 0.0% 0.0% inter: 0.0% 0.0% 0.0%
[libx264 @ 009a8c20] i16 v,h,dc,p: 98%  0%  2%  0%
[libx264 @ 009a8c20] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 17%  0% 83%  0%  0%  0%  0%  0%  0%
[libx264 @ 009a8c20] Weighted P-Frames: Y:100.0% UV:0.0%
[libx264 @ 009a8c20] kb/s:66.58

Attachments (3)

1.png (16.1 KB) - added by spacediver 5 years ago.
6.png (16.1 KB) - added by spacediver 5 years ago.
test.mp4 (4.8 KB) - added by spacediver 5 years ago.

Download all attachments as: .zip

Change History (7)

Changed 5 years ago by spacediver

Changed 5 years ago by spacediver

Changed 5 years ago by spacediver

comment:1 Changed 5 years ago by cehoyos

When you say "codes" do you mean "values"?
Are you reporting that the dynamics of RGB are different than the dynamics of YUV? This is how YUV is defined, both for 8 bit and >8 bit...

comment:2 Changed 5 years ago by spacediver

Yes, I think I meant values (so, in a PC RGB 8 bit context, encoding a pixel value of "0" would result in the minimum luminance, and 255 would result in the peak luminance).

Your comment inspired me to do another test in 8 bit.

The same problem occurs with values in an 8 bit gradient, which makes me think it might have something to do with the RGB to YUV conversion. Perhaps a 16-235 vs 0-255 range issue? Is there a way to preserve the "full swing" in the YUV conversion?

comment:3 Changed 5 years ago by cehoyos

  • Resolution set to invalid
  • Status changed from new to closed

Yes but I would expect all playback software to assume MPEG-scale:
Use the input option -color_range mpeg to force 0->0. It appears that this fails for rgb48 but please also try the output option -dst_range 1. And please use the user mailing list for all usage questions.

comment:4 Changed 5 years ago by spacediver

thanks, and noted.

Note: See TracTickets for help on using tickets.