0

I'm currently creating webm videos using ffmpeg to encode an image sequence. My command is:
ffmpeg -framerate 30 -f image2 -i frames/%04d.png -i my_audio.flac -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -tile-columns 2 -crf 18 -c:a libopus -b:a 128k -r 30 -g 300 -y my_video.webm

The webm VP9 encoding guide only seems to list examples of 2-pass encoding with ffmpeg. And for image sequences, their example doesn't even seem to use ffmpeg.

So I wonder, is it possible to do 2-pass encoding of image sequences using ffmpeg and libvp9? If so, what would be the equivalent to my single-pass command? Is there any advantage in using the 2-pass approach instead of a single pass in this scenario?

References:

webm wiki > FFmpeg > VP9 Encoding Guide: http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide
webm wiki > HOWTOs‎ > ‎Convert PNG frames to WebM video: http://wiki.webmproject.org/howtos/convert-png-frames-to-webm-video

0

You would use

ffmpeg -framerate 30 -f image2 -i frames/%04d.png -pass 1 -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -tile-columns 2 -crf 18 -r 30 -g 300 -y -f null -

and then

ffmpeg -framerate 30 -f image2 -i frames/%04d.png -i my_audio.flac -pass 2 -c:v libvpx-vp9 -pix_fmt yuva420p -b:v 0 -tile-columns 2 -crf 18 -c:a libopus -b:a 128k -r 30 -g 300 -y my_video.webm

In FFmpeg the container format or encoding of the input is, in itself, irrelevant in terms of using encoder features like two-pass.

  • Thanks Gyan. What's the effect of the trailing dash in your first pass command? Is it required? I'm assuming the -y is not required in the first pass because of where you sent the output... – Framerate Jul 31 '18 at 2:03
  • The trailing - stands for stdout so the destination is a pipe which isn't redirected anywhere so NULL. -y can be dropped. – Gyan Jul 31 '18 at 4:44
  • Interestingly, the trac.ffmpeg.org 2-pass encoding guide for x264 retains the -y for the first pass, even though output goes to /dev/null. Not sure why, but I guess they have reasons. I accepted you're answer, as it's fairly direct and is a very close equivalent to the command in the original post... though I get better results with the command I posted. – Framerate Aug 2 '18 at 2:31
  • Will get that changed in the wiki. You only asked about syntax, not optimal commands for encoding :) – Gyan Aug 2 '18 at 5:34
0

is it possible to do 2-pass encoding of image sequences using ffmpeg and libvp9?

Yes, it is possible to do 2-pass encoding from a PNG image sequence using ffmpeg and VP9.

If so, what would be the equivalent to my single-pass command?

Gyan's answer provides a close equivalent to the single-pass command used in the original post. An alternative command is listed below, which is likely to yield better results in terms of compression, while maintaining at least as good visual quality and potentially improving on it.

Is there any advantage in using the 2-pass approach instead of a single pass in this scenario?

Here are three advantages of the 2-pass approach rather than a single pass for the VP9 codec specifically:

  1. Certain codec options only become possible with 2-pass encoding and these can impact quality. For example auto-alt-ref to enable the use of alternate reference frames, which can enhance visual quality. (See webm project's VP9 encoding guide for details)

  2. Potential for better compression, meaning smaller output video file. See tests results below, where I get about 10% improvement using 2-pass.

  3. The ability to control your target bitrate, which might impact you in a VoD/streaming scenario, since you'll likely have specific bandwidth constraints.

There may be other advantages/reasons to do 2-pass encoding with VP9, depending on your use case. So far, 2-pass with VP9 works well for me. In fact, as long as I have the time for a 2-pass encode, I wouldn't even consider using a single-pass encode now.

Note: I generally don't use 2-pass encoding for x264, but for VP9 it seems to be recommended over single-pass.

Alternative 2-pass command for the OP's single-pass

ffmpeg -framerate 30 -f image2 -i frames/%04d.png                  -c:v libvpx-vp9 -pass 1 -pix_fmt yuva420p -b:v 0 -tile-columns 6 -frame-parallel 1 -row-mt 1 -crf 18 -threads 8 -quality good -speed 4 -r 30 -g 300 -an -nostdin -y -f webm /dev/null
ffmpeg -framerate 30 -f image2 -i frames/%04d.png -i my_audio.flac -c:v libvpx-vp9 -pass 2 -pix_fmt yuva420p -b:v 0 -tile-columns 6 -frame-parallel 1 -row-mt 1 -crf 18 -threads 8 -quality good -speed 0 -auto-alt-ref 1 -lag-in-frames 25 -c:a libopus -b:a 128k -r 30 -g 300 -nostdin -y my_video.webm

The difference in flags compared to the original post and Gyan's solution are as follows:

  • -frame-parallel 1 : Per webm project VP9 encoding guide, can enable multi-threaded decoding
  • -row-mt 1 : Enable row-based multi-threaded encoding for VP9
  • -threads 8 : Per webm project VP9 encoding guide, bump encoding performance
  • -quality good -speed <integer> : This is the quality preset I want, and I'd use speed 4 on the first pass, and speed 0 on the second if you have the time to wait. Speed 1 or 2 for the second pass give reasonable results as well.
  • -an : Explicitly tells ffmpeg to ignore audio on the first pass. It may not actually matter whether this flag is present, especially given the PNG-only input on first pass
  • -nostdin : I run ffmpeg in a loop in a script. This is one way to stop ffmpeg from reading from stdin and choking itself in that scenario
  • -auto-alt-ref 1 -lag-in-frames 25 : Per webm project VP9 encoding guide, turns on VP9's alt-ref frames... can enhance quality

Test results using 2-pass instead of single pass

I performed a test on a video of about 2 minutes length, with the content being just a screen recording at 720p with a few very simple visual effects. I used the above command to do a 2-pass encode, but the second pass speed was set to 1. Then I did a single pass encode, using exactly the same settings where possible, such as CRF, quality, speed 1, tile columns, etc. I used the same low-spec machine for each encode.

The output video for the 2-pass encode was smaller by about 10% of the single pass result. But the 2-pass encode time was significantly longer... about 160% of the original, or roughly 10mins vs 6mins.

References

webm project VP9 encoding guide: http://wiki.webmproject.org/ffmpeg/vp9-encoding-guide webm project VP8 encoding options: https://sites.google.com/a/webmproject.org/wiki/ffmpeg ffmpeg VP9 codec options: https://ffmpeg.org/ffmpeg-codecs.html#libvpx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.