[Libav-user] Writing 16bit greyscale videos

Peter Steinbach steinbach at scionics.de
Tue Aug 30 10:40:19 EEST 2016

>> -----Original Message-----
>> From: Libav-user [mailto:libav-user-bounces at ffmpeg.org] On Behalf Of Carl Eugen Hoyos
>> Sent: Montag, 29. August 2016 12:17
>> To: This list is about using libavcodec, libavformat, libavutil, libavdevice and libavfilter.
>> Subject: Re: [Libav-user] Writing 16bit greyscale videos
>>> 2016-08-29 10:59 GMT+02:00 Masneri, Stefano <stefano.masneri at brain.mpg.de>:
>>> I have a small class that creates an h264 video from a set of input images.
>>> I have some problems trying to write 16 bit input images: Conversion
>>> to yuv420p format loses 8 bit of precision, and apparently x264 does
>>> not support encoding 16 bit greyscale data.
>> H.264 does not support more than 14bit, x264 does not support more than 10bit input.
>>> Do you know of a codec that supports encoding a video using
>>> AV_PIX_FMT_GRAY16BE pixel format (or anything similar)?
>> jpegls, png, tiff, dpx, sgi, ffvhuff, ffv1 (all lossless) Jpeg2000, but FFmpeg needs the external library libopenjpeg for encoding
>> gray16 (lossy or lossless)
>> Carl Eugen
> Thanks Carl. I am able to create the video with 16 bit greyscale images, but when I try watching the video in VLC I only see a green image. Reading the frames one by one (with a simple class which uses FFmpeg) I see a strange behaviour: every second column of the video is zero, while the other are exactly as the input fed to the class that created the video. I guess there is somewhere a problem switching from uint16 to uint8, but I cannot figure it out. Any hints?
> Here's the output of ffprobe
> D:\Code\VisualStudio\FFmpegApps\Win\VideoWriterApp>ffprobe -i test16bit.avi
> ffprobe version 2.8.6 Copyright (c) 2007-2016 the FFmpeg developers
>   built with gcc 5.3.0 (GCC)
>   configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --ena
> ble-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-
> libgme --enable-libgsm --enable-libilbc --enable-libmodplug --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-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
>   libavutil      54. 31.100 / 54. 31.100
>   libavcodec     56. 60.100 / 56. 60.100
>   libavformat    56. 40.101 / 56. 40.101
>   libavdevice    56.  4.100 / 56.  4.100
>   libavfilter     5. 40.101 /  5. 40.101
>   libswscale      3.  1.101 /  3.  1.101
>   libswresample   1.  2.101 /  1.  2.101
>   libpostproc    53.  3.100 / 53.  3.100
> Input #0, avi, from 'test16bit.avi':
>   Metadata:
>     encoder         : Lavf56.40.101
>   Duration: 00:00:40.00, start: 0.000000, bitrate: 854 kb/s
>     Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), gray16le, 720x576, 849 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc

Stefano, did you check if your dataset really spans all 16 bits? if not, 
you might be lucky. otherwise 16-to-8-bit quantisation might do the 
trick, but is outside the scope of ffmpeg AFAIK. one thing I also 
haven't tried is copying gray16 into yuv444 and let h264 swallow it. the 
idea is to split the 16-bit in 2 compartments. and fill Y and U only 
(the empty V channel gives 8bit overhead).
x265 might one day support 16-bits maturely, but is not really 
competitive yet in terms of ingest bandwidth with x264 ... at least from 
my studies (compression ration is already well ahead of x264). HEVC 
yields native grey16 support as far as the standard goes.


More information about the Libav-user mailing list