MatroskaOpus

From XiphWiki
Revision as of 16:45, 21 December 2011 by Rillian (talk | contribs) (→‎Questions: Update on the pre-skip signalling question)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

DRAFT

This is an encapsulation spec for the Opus codec in [Matroska].

Opus has few signaling requirements, so a simple mapping:

- CodecID is A_OPUS
- SampleFrequency is always 48000
- Channels is 1 or 2 based on what the muxer knows about the input
- CodecPrivate is void.

However, this doesn't work for multistream. Supporting multistream requires signalling the number of Opus streams packed in each frame and the mapping from those to output channels through the container.

To support multistream, we place the complete 'OpusHead' header packet from OggOpus, as defined there, in the CodecPrivate element. This provides the number of streams and the channel mapping table, as well as related features like pre-skip and gain which improve the chances of lossless remuxing between the two encapsulations.

- CodecID is A_OPUS
- SampleFrequecy is 48000
- Channels is number of output PCM channels
- CodecPrivate is the 'OpusHead' packet, identical to the Ogg mapping

The second 'OpusTags' header packet from OggOpus is not used in the Matroska encapsulation. Matroska has its own system for tag metadata, and this avoids duplicating it and the need for sub-framing to index multiple packets within the CodecPrivate element.

If the CodecPrivate is empty, players should treat it as the simpler mapping, I guess.

Questions

Should we say muxers MAY or SHOULD NOT produce simple streams without filling in CodecPrivate?

How does the OpusHead pre-skip field interact with the timestamps? The SimpleBlock timestamp is signed 16 bits, so we can the format can signal about half of the pre-skip if playback timestamps are to start at zero.

How important that is in Matroska?

The SimpleBlock structure also has an 'invisible' bit, which tell the player to decode, but not display, the contained frames. This lets the muxer signal the pre-skip semantics with frame accuracy, but not sample accuracy. If players implement this it will at least help with sync.