How can I create an uncompressed AVI from a series of 1000's of PNG images using FFMPEG?

I used this command to convert an input.avi file to a series of PNG frames:

ffmpeg -y -i input.avi  -an -vcodec png  -s 1024x768 pic%d.png`

Now I need to know how to make an uncompressed AVI video from all those PNG frames. I tried this:

ffmpeg -i pic%d.png -y -f avi -b 1150 -s 1024x768 -r 29.97 -g 12 -qmin 3 -qmax 13 -ab 224 -ar 44100 -ac 2 test.avi

But the resulting video loses a lot of quality relative to the original AVI.

3 Answers 3


There are several ways to get an "uncompressed" AVI out of ffmpeg, but I suspect you actually mean "lossless." Both terms have a fair bit of wiggle room in their definitions, as you will see.

I'm going to anchor this discussion with the 720p HD version of Big Buck Bunny, since it's a freely-available video we can all test with and get results we can compare. The raw data rate of 1280×720p video at 24 fps is very nearly equal to that of your stated 1024×768 at 29.97 fps goal, so my results should be a pretty good guide to the data rates you can expect on your footage.

Automatic Listing of Available Options

The following POSIX command¹ gives you a list that mostly² matches what we discuss below:

$ ffmpeg -codecs 2> /dev/null | grep '^..EV..S ' | grep -vE 'bitmap|image'

You might want to run that command on your own machine to see what your build of FFmpeg will support. FFmpeg is rarely built with every possible encoder enabled.

Now let's discuss those options.

Fully Uncompressed

If your definition of "uncompressed" is the form the video is in right before it's turned to photons by a digital display, the closest I see in the ffmpeg -codecs list are -c:v r210, r10k, v410, v308, ayuv and v408. These are all substantially the same thing, differing only in color depth, color space, and alpha channel support.

  • R210 and R10K are 4:4:4 RGB at 10 bits per component (bpc), so they both require about 708 Mbit/s for 720p in my testing. (That's about ⅓ TB per hour, friends!)

    These codecs both pack the 3×10 bit color components per pixel into a 32-bit value for ease of manipulation by computers, which like power-of-2 sizes. The only difference between these codecs is which end of the 32-bit word the two unused bits are on. This trivial difference is doubtless because they come from competing companies, Blackmagic Design and AJA Video Systems, respectively.

    Although these are trivial codecs, you will probably have to download the Blackmagic and/or AJA codecs to play files using them on your computer. Both companies will let you download their codecs without having bought their hardware first, since they know you may be dealing with files produced by customers who do have some of their hardware.

  • V410 is essentially just the YUV version of R210/R10K; their data rates are identical. This codec may nevertheless encode faster, because ffmpeg is more likely to have an accelerated color space conversion path between your input frames' color space and this color space.

    I cannot recommend this codec, however, since I was unable to get the resulting file to play in any software I tried, even with the AJA and Blackmagic codecs installed.

  • V308 is the 8 bpc variant of V410, so it comes to 518 Mbit/s in my testing. As with V410, I was unable to get these files to play back in normal video player software.

  • AYUV and V408 are essentially the same thing as V308, except that they include an alpha channel, whether it is needed or not! If your video doesn't use transparency, this means you pay the size penalty of the 10 bpc R210/R10K codecs above without getting the benefit of the deeper color space.

    AYUV does have one virtue: it is a "native" codec in Windows Media, so it doesn't require special software to play.

    V408 is supposed to be native to QuickTime in the same way, but the V408 file wouldn't play in either QuickTime 7 or 10 on my Mac.

So, putting all this together, if your PNGs are named frame0001.png and so forth:

$ ffmpeg -i frame%04d.png -c:v r10k output.mov
  ...or...                -c:v r210 output.mov
  ...or...                -c:v v410 output.mov
  ...or...                -c:v v408 output.mov
  ...or...                -c:v v308 output.mov
  ...or...                -c:v ayuv output.avi

Notice that I have specified AVI in the case of AYUV, since it's pretty much a Windows-only codec. The others may work in either QuickTime or AVI, depending on which codecs are on your machine. If one container format doesn't work, try the other.

The above commands — and those below, too — assume your input frames are already the same size as you want for your output video. If not, add something like -s 1280x720 to the command, before the output file name.

Compressed RGB, But Also Lossless

If, as I suspect, you actually mean "lossless" instead of "uncompressed," a much better choice than any of the above is Apple QuickTime Animation, via -c:v qtrle

I know you said you wanted an AVI, but the fact is that you're probably going to have to install a codec on a Windows machine to read any of the AVI-based file formats mentioned here, whereas with QuickTime there's a chance the video app of your choice already knows how to open a QuickTime Animation file. (The AYUV codec above is the lone exception I'm aware of, but its data rate is awfully high, just to get the benefit of AVI.)

ffmpeg will stuff qtrle into an AVI container for you, but the result may not be very widely compatible. In my testing, QuickTime Player will gripe a bit about such a file, but it does then play it. Oddly, though, VLC won't play it, even though it's based in part on ffmpeg. I'd stick to QT containers for this codec.

The QuickTime Animation codec uses a trivial RLE scheme, so for simple animations, it should do about as well as Huffyuv below. The more colors in each frame, the more it will approach the bit rate of the fully uncompressed options above. In my testing with Big Buck Bunny, I was able to get ffmpeg to give me a 165 Mbit/s file in RGB 4:4:4 mode, via -pix_fmt rgb24.

Although this format is compressed, it will give identical output pixel values to your PNG input files, for the same reason that PNG's lossless compression doesn't affect pixel values.

The ffmpeg QuickTime Animation implementation also supports -pix_fmt argb, which gets you 4:4:4:4 RGB, meaning it has an alpha channel. In a very rough sort of way, it is the QuickTime equivalent to -c:v ayuv, mentioned above. Because of the lossless compression, though, it comes to only 214 Mbit/s, less than ⅓ the data rate of AYUV with zero loss in quality or features.

There are variants of QuickTime Animation with fewer than 24 bits per pixel, but they're best used for progressively simpler animation styles. ffmpeg appears to support only one of the other formats defined by the spec, -pix_fmt rgb555be, meaning 15 bpp big-endian RGB. It's tolerable for some video, and is fine for most screencast captures and simple animations. If you can accept the color space decimation, you may find its 122 Mbit/s data rate appealing.

Putting all this together:

$ ffmpeg -i frame%04d.png -c:v qtrle -pix_fmt rgb24    output.mov
  ...or...                           -pix_fmt argb     output.mov
  ...or...                           -pix_fmt rgb555be output.mov

Effectively Lossless: The YUV Trick

Now, the thing about RGB and 4:4:4 YUV is that these encodings are very easy for computers to process, but they ignore a fact about human vision, which is that our eyes are more sensitive to black and white differences than color differences.

Video storage and delivery systems therefore almost always use fewer bits per pixel for color information than for luminance information. This is called chroma subsampling. The most common schemes are 4:2:0 and 4:2:2.

The data rate of 4:2:0 YUV is just 50% higher than for black and white (Y only) uncompressed video and ½ the data rate of 4:4:4 RGB or YUV.

4:2:2 is a kind of halfway point between 4:2:0 and 4:4:4. It is twice the data rate of Y-only video and ⅔ the data rate of 4:4:4.

You also sometimes see 4:1:1, as in the old DV camera standard. 4:1:1 has the same uncompressed data rate as 4:2:0, but the color information is arranged differently.

The point of all this is that if you're starting with a 4:2:0 H.264 file, re-encoding it to 4:4:4 uncompressed RGB buys you absolutely nothing over 4:2:0 losslessly compressed YUV. This is true even if you know your workflow is otherwise 4:4:4 RGB, since it's a trivial conversion; video hardware and software do such conversions on the fly routinely.

You really only need 4:4:4 when you're pixel peeping or you're doing pixel-level color changes on the video, and you need to preserve exact pixel values. Visual effects (VFX) work is easier to do with a 4:4:4 pixel format, for example, so high-end VFX houses are often willing to tolerate the higher data rates it requires.

Effectively Lossless: Codec Choices

Once you open yourself up to YUV codecs with color decimation, your options open up, too. ffmpeg has many effectively lossless codecs.


The most widely compatible option is Huffyuv. You get this via -c:v huffyuv.

The original Windows Huffyuv codec only supports two pixel formats: RGB24 and YUV 4:2:2. (Actually, it supports two flavors of YUV 4:2:2, differing only in the order of the bytes on disk.)

Older versions of the FFmpeg Huffyuv codec did not include RGB24 support, so if you try it and FFmpeg tells you it is going to use the yuv422p pixel format, you need to upgrade.

FFmpeg also has a Huffyuv variant codec called FFVHuff, which supports YUV 4:2:0. This variant isn't compatible with the Windows DirectShow Huffyuv codec, but it should open in any software based on libavcodec, such as VLC.

  • RGB24 — RGB 4:4:4 is essentially the same thing as QuickTime Animation's RGB24 color space option. The two codecs will differ somewhat in compression for a given file, but they will usually be close.

    It is also essentially the same thing as the YUV 4:4:4 mode used by the V308 option above. The color space difference makes no practical difference, since the color space conversion is easy to do in real time.

    Due to Huffyuv's lossless compression, I was able to get a test video to compress to about 251 Mbit/s in RGB24 mode, with identical visual quality to what you'd get from V308 or AYUV. If AVI is an absolute must for you, installing the Huffyuv codec is probably less painful than paying the 3× data rate cost of AYUV.

  • YUV 4:2:2 — This mode is far more practical for video than RGB24, which is doubtless why the ffmpeg developers chose to implement it first. As you'd expect from the theoretical ⅔ reduction discussed above, my test file encoded to 173 Mbit/s. That's pretty much exactly ⅔, if you take into account the fact that the audio track was unchanged between these two tests.

  • YUV 4:2:0 — This option decimates the color information more than 4:2:2 does, dropping the data rate to 133 Mbit/s in my testing.

Putting all this together:

$ ffmpeg -i frame%04d.png -c:v huffyuv -pix_fmt rgb24   output.avi
  ...or...                             -pix_fmt yuv422p output.avi
  ...or...                -c:v ffvhuff -pix_fmt yuv420p output.avi

Although the ffvhuff codec defaults to 4:2:0 as I write this, and indeed only supports that pixel format in the release version I'm using, this is changing, so you should include the flag in case this default changes.

Ut Video

A more recent option in the same spirit as Huffyuv and FFVHuff is Ut Video. Like Huffyuv, there is a Windows video codec which means any Windows program that can play a movie can play videos using this codec with the codec installed. Unlike Huffyuv, there is also a Mac video codec as well, so you aren't restricted to software based on FFmpeg or libavcodec to read these files on Macs.

This codec is very flexible in terms of color spaces, so I will just give a few examples of common color spaces:

  • 4:4:4 RGB via -f avi -c:v utvideo -pix_fmt rgb24 gives 178 Mbit/sec output

  • 4:4:4 YUV via -f avi -c:v utvideo -pix_fmt yuv444p gives 153 Mbit/sec output

  • 4:2:2 YUV via -f avi -c:v utvideo -pix_fmt yuv422p gives 123 Mbit/sec output

  • 4:2:0 YUV via -f avi -c:v utvideo -pix_fmt yuv420p gives 100 Mbit/sec output

I suspect 4:4:4 YUV does better than 4:4:4 RGB in this test despite these two being technically equivalent because the source video is 4:2:0 YUV, so arranging the data in YUV format allows for better lossless compression by grouping the partially-redundant U and V channels together in the file.


Another interesting option in this space is FFmpeg's own FFV1 codec. This is mostly used as an archival codec rather than a playback or editing codec, but since so much software is either based on the libavcodec library underpinning FFmpeg or can be lashed to libavcodec via tools like ffdshow, it may be useful to you anyway.

By default, ffmpeg will preserve your input files' color space when using a flexible codec like FFV1, so that if you feed it one of the official Big Buck Bunny MP4 files, which use 4:2:0 YUV, that's what you'll get out unless you give a -pix_fmt flag to ffmpeg. This results in a 63 Mbit/s output file.

If you force FFV1 to use a 4:4:4 YUV color space with -pix_fmt yuv444p, the file size only goes up to 86 Mbit/sec, but it's buying us nothing in this case since we're encoding from a 4:2:0 original. However, if you feed in a set of PNGs instead, as in the original question, the output file is likely to use the bgra or bgr0 color space, which are just rearrangements of the argb and rgb24 color spaces brought up above.

Lossless H.264

Another interesting alternative is Lossless H.264. This is pretty much an x264-only thing as of this writing, but those using FFmpeg on the encoding side are likely to be using other software that includes libx264 on the decoding side, too, such as VLC.

The simplest way to get such a file is:

$ ffmpeg -i frame%04d.png -c:v libx264 -qp 0 -f mp4 output.mp4

The -qp 0 flag is the key: higher values give lossy compression. (You can also give -crf 0 to get the same effect.)

As with FFV1, ffmpeg will try to guess the best output color space given the input color space, so for comparison to the results above, I ran multiple encode passes on the Big Buck Bunny source file with different color spaces:

  • yuv444p: This is what ffmpeg chooses when you give it an RGB PNG stream, as in the original question, and results in a 44 Mbit/sec file with our test file

  • yuv422p: This is similar to the default color space for Huffyuv, but we get a 34 Mbit/sec file in this case, quite a savings!

  • yuv420p: This is the default for the Big Buck Bunny official MP4s I'm testing with, and results in a 29 Mbit/sec file.

Beware that you're trading a lot of compatibility to get such small file sizes. That's why I didn't even bother trying to stuff this into an AVI or MOV container. It's so closely tied to x264 that you might as well use its standard container type (MP4) instead. You could also use something like Matroska for this.

You can trade off some of that bit rate for a faster encoding time by adding -preset ultrafast. That increased my test file's bit rate to 44 Mbit/s in YUV 4:2:2 mode, but encoded much faster, as promised. The docs claim that -preset veryslow is also worthwhile, but it resulted in a much longer encode time while only saving a tiny bit of space; I can't recommend it.


ffmpeg also supports decode-only mode for Lagarith and encode-only mode for Lossless JPEG. These two codecs are actually somewhat similar, and should give files a bit smaller than Huffyuv with the same quality. If the ffmpeg developers ever add Lagarith encoding, it would be a strong alternative to Huffyuv. I cannot recommend Lossless JPEG, though, since it doesn't enjoy wide decoding support.

Perceptually Lossless: Or, You Can Probably Get Away With Some Loss

Then there are the codecs that are perceptually lossless. Unless you're pixel peeping, you almost certainly cannot tell that these give different visual results than the previous two groups. By giving up on the idea of absolutely zero change between the video capture sensor and the display device, you buy considerable savings:

  • Apple ProRes: -c:v prores or -c:v prores_ks — ProRes is a profile-based codec, meaning that there are several variants, each with a different quality vs. space tradeoff:

    • ProRes 4444 encodes our test video using only 114 Mbit/s, yet is VFX quality. There are currently three different prores* codecs in FFmpeg, but only prores_ks supports ProRes 4444, as I write this, via the -profile:v 4444 option.

      If you're wondering why you'd bother going with ProRes 4444 over Lossless H.264, it comes down to compatibility, decoding speed, predictability, and the alpha channel.

    • ProRes 422 saves even more space, needing only 84 Mbit/s to give a result you can tell from ProRes 4444 only by pixel-peeping. Unless you need the alpha channel offered by ProRes 4444, there's probably no reason to insist on ProRes 4444.

      ProRes 422 is a closer competitor to the Lossless H.264 option above, since neither supports an alpha channel. You'll want to tolerate the higher bit rate of ProRes if you need compatibility with Apple pro video apps, a lower CPU overhead for encoding and decoding, or predictable bit rates. The latter is important with hardware encoders, for example. On the other hand, if you can cope with the compatibility problems of Lossless H.264, you get the option of using the 4:2:0 color space, which isn't an option from any ProRes profile.

      All three of the ProRes encoders in FFmpeg support the ProRes 422 profile, so the simplest option is to use -c:v prores, rather than -c:v prores_ks -profile hq, or depend on the auto-profile feature of prores_ks to do the right thing.

    There are even more parsimonious ProRes profiles, but they're meant for either SD video or as proxies for full-res files.

    The main problem with ProRes is that it doesn't yet have wide support outside the Apple and pro video worlds.

  • Avid's DNxHD is a similar codec to ProRes, but isn't tied to the Apple pro video world. Avid offers freely-downloadable codecs for both Windows and Macintosh, and FFmpeg now supports it via -c:v dnxhd.

    Because DNxHD is a profile-based codec like ProRes, you choose the profile from the predefined set, and that tells the codec which frame size, frame rate, and bit rate to use. For the Big Buck Bunny test file, the -b:v 60M profile is most appropriate. Unsurprisingly, the resulting file is about 59 Mbit/s.

  • Low-loss MJPEG: -vcodec mjpeg -qscale:v 1 — This is far more common than lossless JPEG. In fact, this was once a quite common video editing codec, and it's still frequently used by things like networked streaming video cameras. All that history means it is easy to find software that supports it.

    Expect pretty wide variability in data rates from this codec. A test I just made here gave me 25 Mbit/s for 720p video. That's high enough compression to make me nervous about lossiness, but it looked pretty good to me. Based on data rate alone, I'd say it's probably on par quality-wise to 12 Mbit/s MPEG-2 or 6 Mbit/s H.264.

Putting all this together:

$ ffmpeg -i frame%04d.png -c:v prores_ks -profile:v 4444 output.mov
  ...or...                -c:v prores_ks -profile:v hq   output.mov
  ...or...                -c:v prores                    output.mov
  ...or...                -c:v dnxhd -b:v 60M            output.mov
  ...or...                -c:v mjpeg -qscale:v 1         output.avi

Bottom line on these methods is that unless you're doing something very demanding, "good enough" really is good enough.

Footnotes and Digressions

  1. The command should work as-given on Linux, macOS, the BSDs, and Unix. If you're on Windows, you can get a POSIX command line via Cygwin or WSL.

  2. There are several reasons why the list produced by that command doesn't perfectly match the set of codecs I've chosen to discuss above:

    • The second grep is meant to filter out inappropriate encoders like bmp which are not "video" codecs, despite being tagged V in this list. While technically you could probably stuff many of these into a container like AVI, MP4, or MKV to get a single-file video, that file won't likely be readable by anything but a program based on ffmpeg or libavcodec.

      There are a few exceptions to this, such as that -f avi -c:v ljpeg gives something you could call "Lossless MJPEG," but as a rule, we're not interested in stuffing many still-image files into an A/V container here to make a movie. We want widely-recognized video codecs here, not semantic trickery.

    • The command currently fails to filter out some inappropriate encoders such as GIF because they are not currently described in the ffmpeg -codecs output as bitmap or image file formats.

      GIF is an interesting case: it supports multiple image frames in a single GIF file with timing information for motion playback, but for several reasons, it is entirely inappropriate to our discussion here.

    • A few of the options that are shown are obsolete or never really got much traction, such as flashsv, dirac, and snow, so it's not worth discussing them above.

    • Some of the options in that list are meant only for use in pipelines between ffmpeg instances or between ffmpeg and another program, such as rawvideo and wrapped_avframe, and so are inappropriate for our purposes here.

    • Near the end of the discussion above, I judiciously expand the scope of the question a bit to include a few carefully chosen lossy options, so they don't pass the first grep filter in the above command.

  • 1
    After trying many, many uncompressed/lossless formats to find one that After Effects would import, your Quicktime one finally did it. For reference it was ffmpeg -i input.avi -c:v qtrle -pix_fmt rgb24 output.mov.
    – felwithe
    Feb 22, 2016 at 22:26
  • I test many of codec you mentioned, the slowest one so fare were Apple ProRes it was ~6 times slower than ``ffvhuff
    – Salem F
    Aug 20, 2022 at 6:07
  • 1
    @SalemF: FFmpeg's open-source implementation of ProRes was quite slow last time I tested it, too. It must not be well-optimized, since Apple's own implementation (in their closed-source software) is supposed to be very fast. Nov 28, 2022 at 5:09

So I ended up making my own answer too long.
TL;DR summary: For losslessly storing a sequence of images, use libx264 or libx264rgb with -preset ultrafast -qp 0. It's nearly as fast as ffvhuff, with much lower bitrate, and decodes faster. huffyuv is much more widely supported outside of ffmpeg, but doesn't support as many pixel formats as ffvhuff. So that's another reason to use h.264, assuming your other tools can handle the h.264 High 4:4:4 Predictive profile that x264 uses in lossless mode. x264 can do intra-only if fast random access to arbitrary frames is needed.

Beware of a ffmpeg bug affecting libx264rgb when reading from a directory of images. (and who knows what other cases.) Test for losslessness in your setup before using. (easy with ffmpeg -i in -pix_fmt rgb24 -f framemd5 on source and lossless-compressed))

edit: utvideo encodes and decodes fairly fast, and is a much simpler codec than h.264. It's basically a modern huffyuv, with support for more useful colorspaces. If you ever have a problem with h.264, try utvideo next for temporary files.

edit2: PNG as a RGB codec appears to do well, at least on the Sintel trailer.

See also my similar answer to a similar question: https://superuser.com/a/860335/20798

There's a lot of info in the Warren Young's answer about various raw formats and codecs. I think the answer would be more useful if it was shorter, so I'm making a new answer. If you're working with software that doesn't support lossless x264 or ffvhuff, then some of that info is probably still useful.

The most useful definition of "lossless" in this context is that you can recover the input bit-for-bit. Zero worry about quality degradation from video encoding, regardless of what you do.


Ideally, avoid multiple colorspace conversions. The rounding errors can potentially build up. If you're going to operate on your video with filters that work in the RGB colorspace, then keeping it RGB makes sense, as long as the higher bitrates aren't an issue. You're probably going to ultimately produce a yuv 4:2:0 video, but keeping the extra chroma resolution is potentially useful, depending on what filters you're going to apply.

Either way, lossless x264 and ffvhuff both support RGB and yuv 4:4:4, 4:2:2, and 4:2:0. I'd suggest x264, as it's fast to decode. If you're trying to play back RGB HD video in realtime, try opengl instead of xv, since xv on my system only accepts yuv input. mplayer was taking extra CPU time to do a color-space conversion.

Source for the following encoder tests: https://media.xiph.org/. https://media.xiph.org/sintel/sintel_trailer-1080-png.tar.gz They forgot to gzip the y4m files for the sintel trailer, so the png tarball is actually a lot smaller.

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac \
-c:a copy -c:v libx264rgb -preset ultrafast -qp 0 \


peter@tesla:/mnt/GP1TB/p/encoder-sample/sintel$ time ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac -c:a copy -c:v libx264rgb -preset ultrafast -qp 0 frompng.sintel.264rgb.mkv
ffmpeg version N-67983-g2b358b4 Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 10 2015 05:32:37 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --enable-gpl --enable-version3 --enable-nonfree --disable-doc --disable-ffserver --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libopus --enable-libwebp --enable-libvpx --disable-outdev=oss --disable-indev=oss --disable-encoder=vorbis --enable-libvorbis --enable-libfdk-aac --disable-encoder=aac --disable-decoder=jpeg2000
  libavutil      54. 16.100 / 54. 16.100
  libavcodec     56. 20.100 / 56. 20.100
  libavformat    56. 18.100 / 56. 18.100
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  7.100 /  5.  7.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, image2, from '1080/sintel_trailer_2k_%4d.png':
  Duration: 00:00:50.12, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24, 1920x1080 [SAR 72:72 DAR 16:9], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, flac, from 'sintel_trailer-audio.flac':
  Duration: 00:00:52.00, start: 0.000000, bitrate: 721 kb/s
    Stream #1:0: Audio: flac, 48000 Hz, stereo, s16
File 'frompng.sintel.264rgb.mkv' already exists. Overwrite ? [y/N] y
No pixel format specified, rgb24 for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264rgb @ 0x2770760] using SAR=1/1
[libx264rgb @ 0x2770760] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 SlowShuffle
[libx264rgb @ 0x2770760] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264rgb @ 0x2770760] 264 - core 144 r2525+2 6a4fca8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'frompng.sintel.264rgb.mkv':
    encoder         : Lavf56.18.100
    Stream #0:0: Video: h264 (libx264rgb) (H264 / 0x34363248), rgb24, 1920x1080 [SAR 72:72 DAR 16:9], q=-1--1, 25 fps, 1k tbn, 25 tbc
      encoder         : Lavc56.20.100 libx264rgb
    Stream #0:1: Audio: flac ([172][241][0][0] / 0xF1AC), 48000 Hz, stereo (16 bit)
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264rgb))
  Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1253 fps= 18 q=-1.0 Lsize=  834790kB time=00:00:51.96 bitrate=131592.5kbits/s
video:830198kB audio:4575kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.002025%
[libx264rgb @ 0x2770760] frame I:6     Avg QP: 0.00  size:612470
[libx264rgb @ 0x2770760] frame P:1247  Avg QP: 0.00  size:678787
[libx264rgb @ 0x2770760] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264rgb @ 0x2770760] mb P  I16..4: 50.3%  0.0%  0.0%  P16..4: 12.0%  0.0%  0.0%  0.0%  0.0%    skip:37.6%
[libx264rgb @ 0x2770760] coded y,u,v intra: 71.1% 68.2% 70.0% inter: 22.8% 22.8% 23.2%
[libx264rgb @ 0x2770760] i16 v,h,dc,p: 50% 48%  1%  1%
[libx264rgb @ 0x2770760] kb/s:135693.94

Note that I forgot to specify -r 24 fps, so it won't keep av sync with the audio. (and the bitrate (but not file size) numbers will be off, too. ffmpeg defaults to 25fps). CPU in this machine is a 1st-gen (conroe) core2duo 2.4GHz (E6600).


4.5M    sintel_trailer-audio.flac  # this is muxed in to every mkv
948M    1080  # the directory of PNGs
940M    /var/tmp/dl/sintel_trailer-1080-png.tar.gz
7434M   sintel.y4m  # yuv444, uncompressed.  mplayer gets the colors wrong?
2342M   qtrle.mkv   # encode went at 16fps, so qtrle is slower and worse filesize
2105M   sintel.huff.mkv  # ffvhuff with default options, rgb pix fmt
1228M    sintel.utvideo.mkv  # muxed without audio, I should update the others this way
946M    png-copy.mkv  # -codec copy makes a MPNG stream.  Use -codec png for non-png sources, but it won't make PNGs as small.  Decodes very fast
824M    lossy.prores_ks.mov # yuv444p10le extremely slow to encode (2.3fps), and worse bitrate.
816M    frompng.sintel.264rgb.mkv
735M    sintel.x264rgb.medium.nocabac.mkv  # encode went at 3.3 fps instead of 18.  Better gain than for live-action, though
626M    sintel_trailer.rgb.lossless.veryslow.mkv # 1.1fps.  With CABAC, 16 ref frames, etc. etc.
512M    lossy.prores.mov # yuv422p10le, 12fps
341M    sintel.yuv420.x264.lossless.mkv
21M     lossy.rgb.crf26.preset=medium.mkv
13M     lossy.yuv420.crf26.preset=medium.mkv  # remember this is WITH 4.5MB audio

Note that mediainfo doesn't know about RGB h.264, it still says that the files are YUV.

Check that it really was lossless:

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -f framemd5 png.framemd5
ffmpeg -i fromhuff.sintel.264rgb.mkv -an -sn -pix_fmt rgb24  -f framemd5 x264rgb.framemd5
diff -s *.framemd5
Files png.framemd5 and x264rgb.framemd5 are identical

So you can recover the original PNG input that way, i.e. you could make PNGs with identical image data in them.

Note the -pix_fmt rgb24 for the x264 test. ffmpeg's h.264 decoder outputs gbrp (planar, not packed) output, so the bits are the same, but in a different order. The framemd5 "container" doesn't impose any sort of format restrictions, but you'll only get the same md5 if the bits are arranged the same way. I just looked at what ffmpeg said it was using for a pix fmt when I fed it PNGs, then used that as the arg to -pix_fmt for decode. Incidentally, this is the reason vlc won't play RGB h.264 files (until next release, or current nightly builds): It doesn't support the gbrp pixel format.

For yuv use libx264, not libx264rgb. You don't need to install an RGB version of x264, the actual library supports both. It's just ffmpeg that implemented it as two differently named encoders. I think if they hadn't done that, the default behaviour would be to leave rgb input as rgb, and run really slowly while producing much higher bitrate output for the same quality. (you still sometimes have to use -pix_fmt yuv420p if you want 420 instead of 444 h.264 output.

Unless you are making files for long-term storage, always use -preset ultrafast for lossless x264. More reference frames and motion search barely makes any difference for lossless, for non-animated material with any noise. CABAC takes a huge amount of CPU at lossless bitrates, even to decode. Only use for archival purposes, not scratch files. (ultrafast disables CABAC). CABAC gives 10 to 15% bitrate savings.

If you need every frame to be a keyframe, set -keyint 1. Then video editing software that only wants to cut on keyframes or w/e will not limit you.

To answer the original question: This is what you should do for throwing around temporary files while trying things in stages (e.g. a slow deinterlace, saving lossless output before trying other things):

ffmpeg -i dv-video-source.ts -vf yadif=2:1,mcdeint=3:1:10 -c:a copy -c:v libx264 -preset ultrafast -qp 0 deinterlaced.mkv

If you really need your output in image files that you can modify with still-image tools, then sure, decode to png. You're not going to lose anything more than maybe the least significant of the 8 bits of for each of the Y, Cb, and Cr values for each pixel.

x264 comes out REALLY well in this because there are a lot of black frames with a bit of text, a fade-in and fade-out, and perfect similarity between big areas of many frames, which it manages to take advantage of even with -preset ultrafast. On live-action, I still see x264 at half the filesize of ffvhuff (yuv420).

For anyone curious: The high-cpu-time lossless rgb encode had (x264 core 144 r2525):

[libx264rgb @ 0x35b97a0] frame I:27    Avg QP: 0.00  size:604367
[libx264rgb @ 0x35b97a0] frame P:1226  Avg QP: 0.00  size:517512
[libx264rgb @ 0x35b97a0] mb I  I16..4..PCM: 46.3% 38.1% 15.7%  0.0%
[libx264rgb @ 0x35b97a0] mb P  I16..4..PCM: 24.3%  5.4%  4.5%  0.0%  P16..4: 10.5%  3.3%  5.7%  0.0%  0.0%    skip:46.3%
[libx264rgb @ 0x35b97a0] 8x8 transform intra:17.3% inter:46.1%
[libx264rgb @ 0x35b97a0] coded y,u,v intra: 81.6% 77.5% 80.0% inter: 28.0% 27.7% 28.1%
[libx264rgb @ 0x35b97a0] i16 v,h,dc,p: 35% 64%  1%  0%
[libx264rgb @ 0x35b97a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 49% 13%  2%  1%  1%  1%  1%  1%
[libx264rgb @ 0x35b97a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 37%  5%  5%  6%  5%  5%  4%  3%
[libx264rgb @ 0x35b97a0] Weighted P-Frames: Y:41.1% UV:40.7%
[libx264rgb @ 0x35b97a0] ref P L0: 74.5%  4.2%  9.1%  4.1%  2.1%  1.7%  1.2%  0.8%  0.6%  0.5%  0.3%  0.2%  0.2%  0.2%  0.2%  0.1%
[libx264rgb @ 0x35b97a0] kb/s:99721.66

Note the really high fraction of weighted p frames, and also the really high fraction of skip macroblocks. Every scene transition is a fade, not a cut, and x264 takes advantage if you give it the CPU time to figure out how.

further notes (lossy codecs for editting):

For scrubbing forwards/backwards through clips, intra-only codecs are usually favoured (utvideo, ffvhuff, mjpeg, jpeg2000, pro-res, AVC-Intra). I'd imagine regular AVC with short GOPs (1/2 to 1 sec) would scrub pretty well, too, as long as the software knew what it was doing (decode nearest I frame when scrubbing fast, decode within the GOP to get to an inter frame if you're zoomed in enough on a timeline for that to be needed).

I've posted some negative things on this and https://video.stackexchange.com/ about pro-res, like "what's the point if it's slower and worse compression than a lossless codec", but it does have some interesting features. Apple says that it can decode at half-resolution using as little as 1/3 the CPU time of decoding full rez.

ffmpeg's prores implementation is probably not as optimized for speed as Apple's either, which is why my testing with ffmpeg has made it look slow. It's probably not worth using if you have a Free software workflow with tools based on ffmpeg, but it might be worth trying if you're using commercial software.

I don't do a lot of video editting, mostly just encoding, so I don't have a good sense of what tests would be appropriate for codecs like prores. I'd guess that maybe mjpeg would be a good fast alternative, if short-GOP x264 doesn't work well. There are asm-accelerated implementations of jpeg in Linux distros, and it's a pretty simple codec. You can turn the quality up or down as needed to trade off quality vs. filesize + encode/decode speed. It's ancient, but if you want an intra-only codec that's really fast, it might beat x264.

For x264, I'd try something like x264 --crf 10 --keyint=1 --preset superfast --tune fastdecode (Intra-only, without any of the other stuff that --avcintra-class sets.) Note superfast (without CABAC), or faster, not ultrafast is probably best for lossy operation. I think ultrafast loses a lot of quality without being that much faster. The lower quality (higher crf) you use, the more it's worth spending a bit more CPU time finding a better encode. A lot of this probably isn't relevant with GOP size = 1, though.

With GOP size > 1, if you're throwing so many bits at the encode that better inter-prediction won't save many bits when encoding the residuals (because noise / grain / subtle changes between frames are getting preserved very accurately), then just superfast is probably fine. Otherwise, with --keyint=30 or something, probably --preset veryfast --crf 12 would be interesting.

In theory, quality at a given CRF setting should be constant across presets. If you're looking for smaller files (faster decodes), trading off some quality and some encode time makes sense.

  • Just wanted to say thanks for that list with the file sizes; great stuff for quick reference.. Cheers!
    – sdaau
    Jan 30, 2015 at 7:09
  • @sdaau Note that the source video is VERY different from typical videos made with cameras. It's a 3D render, with letterboxing, and with many fades between short scenes. And a decent fraction of totally still frames with text. The totally-still frames are all quite intra-compressible, but it still favours codecs with inter frames (like x264) more than I imagine lossless compression of camera footage (with any noise at all) would. Feb 1, 2015 at 3:34
  • +1: I had no idea Lossless H.264 was even a thing. I have added info about it to my answer. Feel free to take some ideas from my briefer presentation to solve your tl;dr problem. As for my own answer, it is meant to be comprehensive, rather than try to present the One True Solution to the problem. We have so many different codecs because no single codec meets everyone's needs. May 7, 2015 at 6:38

I think ffmpeg actually does support converting to uncompressed video.
I used ffmpeg -i input.mp4 -vcodec rawvideo out.avi and the resulting .avi was roughly the right filesize. Windows media player didn't seem to be able to play it correctly but it could be read by VirtualDub and I did not see any loss in picture quality.

You must log in to answer this question.