Question: I am working at a raw to timelapse program, and I am using ffmpeg to generate a video out of a sequence of JPGs that my program outputs.

The user can select from different codecs, such as libx264, mjpeg, vp8, vp9.

I am having good results with h264 and mjpeg, but vp8 gives me some *very* bad quality videos, even though I set the quality pretty high, and the file size is comparable to h264 videos.

I am using the following settings:

```
ffmpeg.exe -framerate 12 -i "./output/img_%05d.jpg" -dst_range 1 -color_range 2 -c:v libvpx -b:v 0 -threads 8 -speed 2 -crf 8 "./output/video.webm"

```

You can see a sample video here: <https://www.youtube.com/watch?v=eG2jxzR3Uxs> (the encoding problems are mostly visible after 9 seconds).

Someone at Stack Overflow said that VP8 needs two passes, but this is unpractical. Is it any way to get good results in a single pass? Something comparable to h264 in terms of size/quality?

Answer: 
The only way to get good quality results in a single pass is to use a constant rate factor ([CRF](http://slhck.info/video/2017/02/24/crf-guide.html)) mode. Please read the [VP8](http://trac.ffmpeg.org/wiki/Encode/VP8) and [VP9](http://trac.ffmpeg.org/wiki/Encode/VP9) guides for more info.

When setting `-crf X`, each frame is encoded with that target quality level `X`. However, an additional constraint is applied in the encoder, depending on the bitrate set by `-b:v`:

* If `-b:v 0` is used, the bitrate can vary freely depending on the source sequence and the set target quality. This is the option you want for a “normal CRF mode”, equivalent to `-crf X` with `x264`.
* If `-b:v` is set to a positive bitrate, that constraint will be used as a maximum bitrate.

For example, with VP8, using `-crf 10` and `-b:v 500K` for a 1080p video will most certainly always reduce the bitrate to 500 kBit/s rather than letting the quality vary freely, making the output look rather bad, since 1080p video requires much more than 500 kBit/s. Setting `-crf 10 -b:v 5M` would make more sense for VP8. For VP9, you generally want lower bitrate values, since it is more efficient.
* If `-b:v` is not set at all, ffmpeg will choose a default of 200 kBit/s, which will very likely lead to bad quality (unless you have a low resolution, easy to encode sequence). So, don't do this when using `-crf`.

You can verify the encoder settings by looking at the output produced by ffmpeg when run with the `-loglevel debug` setting.

In your specific case, I don't see anything wrong with the options, except maybe `-speed 2`. Setting this will disable some encoder features at the expense of rate control accuracy. Remove the option and see if that improves your quality.

Note that the `-quality` option is misleading; it's a legacy option now called `-deadline` (see `ffmpeg -h encoder=libvpx` for more info). The only viable settings for `-quality` are `good` or `best` (and `realtime`, but this is for live streaming). `good` is the default, so you don't have to explicitly specify it. `best` will result in very long encoding times.
Although the perceived quality is subjective you can adjust the overall quality using the `-quality` variable for example `-quality good`. The bitrate will impact the quality which you have set to 0, which I assume was just a mistake.