Mapping of WebM codec inside Ogg container has been specified since the introduction of the WebM archived that refer to a document describing "Ogg container format mapping for WebM", and implementations of VP8 inside Ogg is already implemented by ffmpeg, development version of liboogz and some other softwares.
Some time later google release VP9, but no software that support VP9 inside Ogg yet. Firefox documentation claim that archived they can play VP8 and VP9 inside Ogg. Contrary to their documentation though, Firefox in fact can not play Ogg with VP8 codec (tested on Firefox version 104.0.1). On related note, Google Chrome and MS Edge do support VP8 inside Ogg. I can not test whether they can play VP9 inside Ogg because I can not even able to find any software that can put VP9 inside Ogg.
Because lack of OggVP9 implementation, for learning purpose, I am interested to implement it.
Here is what I found while searching for the elusive document describing "Ogg container format mapping for WebM"
- The mapping document on the aftermentioned article archived is now inaccessible
- The Xiph Wiki also have no mention of it, which is understandable since they are not Xiph codecs
- A bit searching I found this PDF document which I believe is the same document linked on the article
From there I am implementing OggVP9 mostly using the same mapping as OggVP8 with VP9 specific changes
- The
ID
field is (obviously) set toVP90
- VP9 pts always increasing regardless visible or invisible frame, this also true for VP9 inside IVF format
More detail is written in this document.
However it should be noted that it is not offical OggVP9 mapping or anything. What I am doing is just taking existing OggVP8 specification, experimenting what is work for VP9 and documenting it.
My implementation is just a small patch for FFmpeg. All patches licensed under LGPL v2.1 or later, or the same license as FFmpeg this patch applied to. However the code is experimental and might contains serious bugs. Use it at your own risk.
To build from source you should install at least gcc, yasm, and development version of these libraries
- libvpx
- libopus
- libvorbis
- libtheora
- sdl2
This patch should work on FFmpeg 5.1, and may also work with more recent version of FFmpeg.
$ git clone https://github.com/aranugra/ogg-vp9.git
$ wget http://ffmpeg.org/releases/ffmpeg-5.1.tar.xz
$ tar -xf ffmpeg-5.1.tar.xz
$ patch -p1 -d ffmpeg-5.1 < ogg-vp9/ffmpeg/vp9-inside-ogg.patch
Configure and build FFmpeg
$ OGGVP9_PREFIX=/opt/ffmpeg-5.1-ogg-vp9
$ cd ffmpeg-5.1
$ ./configure --prefix=$OGGVP9_PREFIX --enable-libvpx --enable-libopus --enable-libtheora --enable-libvorbis --enable-shared
$ make -j3
$ make install
Then add $OGGVP9_PREFIX/bin
to path if necessary.
Compiled packages for Win64 are available on the release page.
Encoding with constant rate factor
$ ffmpeg -i input.mp4 -f ogg -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 160k output.ogv
Generally you can refer to VP9 encoding guide and just replace
-f webm
to -f ogg
and replace output extension to .ogv
.
Here is some OggVP9 video samples.
To play OggVP9 video, you can use ffplay
$ ffplay output.ogv
For a real video player, you can build mpv linked against this version of FFmpeg. In turn you can use SMPlayer as mpv front-end.
Known limitation on current implementation
- Does not support any features of VP9 that only supported by matroska container (alpha, WebTTV, etc, etc)
- No VP9 codec private information