[opus] How to wrap Opus data in an Ogg stream?

Mark Harris mark.hsj at gmail.com
Wed Oct 14 05:39:41 PDT 2015

On Wed, Oct 14, 2015 at 4:18 AM, Daniel Armyr <daniel at armyr.se> wrote:
> Hi.
> I am trying to understand how to package opus-encoded data in an ogg stream to make a standards-compilant ogg/opus file. Most things are clear, but there is one thing I simply do not understand.
> What I do understand is that Ogg is based on pages, that each come with a fairly sizeable header (>=27 bytes). Now, I encode with a fairly low bitrate, so my opus packages are <100 bytes long. Therefore, it does not make sense to place one Opus packet in each Ogg page because of the overhead.

If latency is not important, you will probably want one second of
audio or more per Ogg page.

> Now, the following document (It has expired? Is it still valid?) https://tools.ietf.org/html/draft-terriberry-oggopus-01

It is now an IETF document.  The current version is:

> contains the following text regarding how to place Opus audio data in an Ogg page ( =? Ogg packet ): "The first N-1 Opus packets, if any, are packed one after another into the Ogg packet, using the self-delimiting framing from Appendix B of  [RFCOpus]."

This is discussing how to combine multiple Opus packets (one for each
Opus stream) into a multi-stream Ogg Opus packet, for example if you
are encoding 5.1 channel surround sound.  For mono or stereo you would
only have one Opus packet in each Ogg Opus packet and would have no
need for self-delimited framing.

To put multiple Ogg Opus packets in an Ogg page, all you need to do is
start a new segment for each Ogg Opus packet.  There can be up to 255
segments per page.  For details, see the Ogg specification:

> Reading said appendix, it seems that this self-delimiting format is not just taking on a header to a regular packet, but somehow placing the packet length inside the packet. Is this something I have to do manually, or is there a way to tell libOpus to create these self-delimiting packets?

The libopus multi-stream API does this automatically when you are
using multiple streams.  It is not applicable with just one stream.

 - Mark

More information about the opus mailing list