Reputation: 11
I want to compress a depth map that has 16 bits of information per pixel. In general, such depth maps can be stored in different ways, e.g. p016le, gray16le, yuv420p16le, yuv444p16le, ... but for simplicity, let's assume the depth map is a yuv420p16le (where the y-channel contains the depth).
For some reason when encoding with hevc_nvenc
(I use an NVIDIA GTX 1660 Ti GPU), ffmpeg (the command line tool) changes the pixel format to a 10 or 12 bit variant (p010le, gray12le, yuv420p10le, yuv444p12le, ...), but I would like to keep the full 16 bits, since this affects the quality of the depth stored.
For example:
ffmpeg.exe -s:v 1920x1080 -r 30 -pix_fmt yuv420p16le -i depth_yuv420p16le.yuv -c:v hevc_nvenc -pix_fmt yuv444p16le output.mp4
If I use ffprobe on the output.mp4, it tells me that the underlying pixel format is actually yuv444p10le. (Decoding and looking at the raw pixel data, I can confirm that the precision has decreased from 16 bits to 10 bits).
I hope 16 bit compression is possible, since according to
ffmpeg -h encoder=hevc_nvenc
the supported pixel formats are:
hevc_nvenc: yuv420p nv12 p010le yuv444p p016le yuv444p16le bgr0 rgb0 cuda d3d11
But p016le results in a p010le output, and yuv444p16le in yuv444p10le.
Does anyone know where the problem could lie? Should I re-install ffmpeg (version 4.3.2-2021-02-27-essentials_build-www.gyan.dev)? Is it because of Windows 10 having limited encoding/decoding capabilities? Will buying the HEVC Video Extensions help solve this problem?
Additional info: using libx256
does not look like it will work for this purpose, since the supported pixel formats are:
libx256 : yuv420p yuvj420p yuv422p yuvj422p yuv444p yuvj444p gbrp yuv420p10le yuv422p10le yuv444p10le gbrp10le yuv420p12le yuv422p12le yuv444p12le gbrp12le gray gray10le gray12le
Any help would be greatly appreciated.
Upvotes: 1
Views: 3424
Reputation: 61
I was attempting to encode 16-bit per channel RGB (48 bits per pixel) .exr frames into whatever video format supported it, and through trial & error I came to the conclusion that only the ffv1 codec supports this, using the gbrp16le or the yuv420p16le pixel formats and the .mkv container. Here are the commands I used:
ffmpeg -i {INPUT} -pix_fmt gbrp16le -c:v ffv1 -level 3 -coder 1 -context 1 -g 1 {OUTPUT.mkv}
ffmpeg -i {INPUT} -pix_fmt yuv420p16le -c:v ffv1 -level 3 -coder 1 -context 1 -g 1 {OUTPUT.mkv}
I can confirm that these formats indeed preserved the 16-bit info, as I decoded them back to .exr and examined the raw bytes.
I hope this helps!
Upvotes: 0