#8359 closed defect (invalid)
FFmpeg’s nv12 libx264: ffmpeg encodes in “yuv420p” instead of “nv12”
| Reported by: | Kdmeizk | Owned by: | |
|---|---|---|---|
| Priority: | normal | Component: | undetermined |
| Version: | git-master | Keywords: | |
| Cc: | Blocked By: | ||
| Blocking: | Reproduced by developer: | no | |
| Analyzed by developer: | no |
Description
Input file:
https://drive.google.com/file/d/0B40VEgqICZzWZ1UwQ2M5VldvNmM/view?usp=sharing
ffmpeg-20191101-53c21c2-win64-static\bin\ffmpeg.exe -i 00006.m2ts -to 00:00:05 -c:v libx264 -pix_fmt nv12 -an output.mkv
ffmpeg version git-2019-11-01-53c21c2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20191010
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 35.101 / 56. 35.101
libavcodec 58. 60.100 / 58. 60.100
libavformat 58. 33.100 / 58. 33.100
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 66.100 / 7. 66.100
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Input #0, mpegts, from '00006.m2ts':
Duration: 00:00:44.05, start: 1.992667, bitrate: 36799 kb/s
Program 1
Stream #0:0[0x1011]: Video: h264 (High) (HDMV / 0x564D4448), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 90k tbn, 47.95 tbc
Stream #0:1[0x1100]: Audio: dts (DTS-HD MA) ([134][0][0][0] / 0x0086), 48000 Hz, 5.1(side), s32p (24 bit)
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
Output #0, matroska, to 'output.mkv':
Metadata:
encoder : Lavf58.33.100
Stream #0:0: Video: h264 (libx264) (H264 / 0x34363248), nv12, 1920x1080 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 1k tbn, 23.98 tbc
Metadata:
encoder : Lavc58.60.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
video:1408kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.115162%
ffmpeg-20191101-53c21c2-win64-static\bin\ffprobe.exe output.mkv
ffprobe version git-2019-11-01-53c21c2 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20191010
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 35.101 / 56. 35.101
libavcodec 58. 60.100 / 58. 60.100
libavformat 58. 33.100 / 58. 33.100
libavdevice 58. 9.100 / 58. 9.100
libavfilter 7. 66.100 / 7. 66.100
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Input #0, matroska,webm, from 'output.mkv':
Metadata:
ENCODER : Lavf58.33.100
Duration: 00:00:05.01, start: 0.000000, bitrate: 2306 kb/s
Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
Metadata:
ENCODER : Lavc58.60.100 libx264
DURATION : 00:00:05.005000000
Change History (6)
follow-up: 2 comment:1 by , 7 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
comment:2 by , 7 years ago
Replying to heleppkes:
The h264 bitstream carries chroma always in the same way. How a decoder chooses to represent it is up to the implementation, and the ffmpeg h264 decoder choose yuv420p to do it.
The following output files are byte-to-byte identical:
ffmpeg-20191101-53c21c2-win64-static\bin\ffmpeg.exe -i 00006.m2ts -to 00:00:05 -c:v libx264 -pix_fmt yuv420p -crf 0 -an output_yuv420p.nut ffmpeg-20191101-53c21c2-win64-static\bin\ffmpeg.exe -i 00006.m2ts -to 00:00:05 -c:v libx264 -pix_fmt nv12 -crf 0 -an output_nv12.nut
But it is not normal.
From “https://wiki.videolan.org/YUV/”:
For a single I420 pixel: YYYYYYYY UU VV
[…]
For 1 NV12 pixel: YYYYYYYY UVUV
So ffmpeg encodes in “yuv420p” instead of “nv12”, otherwise the files should not be byte-to-byte identical.
follow-up: 4 comment:3 by , 7 years ago
h264 does not care what format you feed it, it simply encodes 4:2:0 chroma. It does not encode a specific pixel format, those are implementation details.
comment:4 by , 7 years ago
Replying to heleppkes:
h264 does not care what format you feed it, it simply encodes 4:2:0 chroma. It does not encode a specific pixel format, those are implementation details.
Example:
x264-r2969-d4099dd.exe --fullhelp
[…]
--input-csp <string> Specify input colorspace format for raw input
- valid csps for `raw' demuxer:
i400, i420, yv12, nv12, nv21, i422, yv16, nv16,
yuyv, uyvy, i444, yv24, bgr, bgra, rgb
- valid csps for `lavf' demuxer:
yuv420p, yuyv422, rgb24, bgr24, yuv422p,
yuv444p, yuv410p, yuv411p, gray, monow, monob,
pal8, yuvj420p, yuvj422p, yuvj444p, uyvy422,
uyyvyy411, bgr8, bgr4, bgr4_byte, rgb8, rgb4,
rgb4_byte, nv12, nv21, argb, rgba, abgr, bgra,
gray16be, gray16le, yuv440p, yuvj440p,
yuva420p, rgb48be, rgb48le, rgb565be, rgb565le,
rgb555be, rgb555le, bgr565be, bgr565le,
bgr555be, bgr555le, vaapi_moco, vaapi_idct,
vaapi_vld, yuv420p16le, yuv420p16be,
yuv422p16le, yuv422p16be, yuv444p16le,
yuv444p16be, dxva2_vld, rgb444le, rgb444be,
bgr444le, bgr444be, ya8, bgr48be, bgr48le,
yuv420p9be, yuv420p9le, yuv420p10be,
yuv420p10le, yuv422p10be, yuv422p10le,
yuv444p9be, yuv444p9le, yuv444p10be,
yuv444p10le, yuv422p9be, yuv422p9le, gbrp,
gbrp9be, gbrp9le, gbrp10be, gbrp10le, gbrp16be,
gbrp16le, yuva422p, yuva444p, yuva420p9be,
yuva420p9le, yuva422p9be, yuva422p9le,
yuva444p9be, yuva444p9le, yuva420p10be,
yuva420p10le, yuva422p10be, yuva422p10le,
yuva444p10be, yuva444p10le, yuva420p16be,
yuva420p16le, yuva422p16be, yuva422p16le,
yuva444p16be, yuva444p16le, vdpau, xyz12le,
xyz12be, nv16, nv20le, nv20be, rgba64be,
rgba64le, bgra64be, bgra64le, yvyu422, ya16be,
ya16le, gbrap, gbrap16be, gbrap16le, qsv, mmal,
d3d11va_vld, cuda, 0rgb, rgb0, 0bgr, bgr0,
yuv420p12be, yuv420p12le, yuv420p14be,
yuv420p14le, yuv422p12be, yuv422p12le,
yuv422p14be, yuv422p14le, yuv444p12be,
yuv444p12le, yuv444p14be, yuv444p14le,
gbrp12be, gbrp12le, gbrp14be, gbrp14le,
yuvj411p, bayer_bggr8, bayer_rggb8,
bayer_gbrg8, bayer_grbg8, bayer_bggr16le,
bayer_bggr16be, bayer_rggb16le, bayer_rggb16be,
bayer_gbrg16le, bayer_gbrg16be, bayer_grbg16le,
bayer_grbg16be, xvmc, yuv440p10le, yuv440p10be,
yuv440p12le, yuv440p12be, ayuv64le, ayuv64be,
videotoolbox_vld, p010le, p010be, gbrap12be,
gbrap12le, gbrap10be, gbrap10le, mediacodec,
gray12be, gray12le, gray10be, gray10le, p016le,
p016be, d3d11, gray9be, gray9le, gbrpf32be,
gbrpf32le, gbrapf32be, gbrapf32le, drm_prime,
opencl, gray14be, gray14le, grayf32be,
grayf32le, yuva422p12be, yuva422p12le,
yuva444p12be, yuva444p12le
--output-csp <string> Specify output colorspace ["i420"]
- i400, i420, i422, i444, rgb
“-pix_fmt yuv420p” means “--input-csp yuv420p” and “--output-csp i420”.
| “i420” | = colorspace format |
| “yuv420p” | = pixel format using the colorspace format “i420” |
comment:5 by , 5 years ago
There are some ways to affect the chroma sitting/location/lattice in libx264. Keywords for googling chromaloc=2 chromaloc-top and chroma_sample_location. But you do NOT really need this. This is very obscure at least for AVC, for HEVC two chroma lattices are actively used. There are more than that though.
Lattice is signalled in VUI.
Also see https://forum.doom9.org/showpost.php?p=1766645&postcount=123
-vf 'scale=out_color_matrix=bt709:out_h_chr_pos=0:out_v_chr_pos=128'
for center left that is used in SDR. In HDR out_h_chr_pos=0:out_v_chr_pos=0 is in use. That is top left.
There are 4 more types of it. In jpeg, for example.
comment:6 by , 4 years ago
Oh, BTW, you can decode to rawvideo in format nv12 (HW decoders do that by default) and then encode NV12 but tagging it as yuv420p. The result will be very funny, but you can do that.



The h264 bitstream carries chroma always in the same way. How a decoder chooses to represent it is up to the implementation, and the ffmpeg h264 decoder choose yuv420p to do it.