Oggless: Difference between revisions

From XiphWiki
Jump to navigation Jump to search
(theora support)
m (→‎FLAC: Added Native FLAC. (Is there a better link?))
 
(17 intermediate revisions by 7 users not shown)
Line 1: Line 1:
The text below is supposed to be a startpoint for disscussions and is ATM identical to [http://svn.mplayerhq.hu/nut/docs/oggless-xiph-codecs.txt?view=log]
{{draft}}
 
==Explicit mappings==
The preferred method to map Xiph formats into other containers is to write an explicit mapping. Some mappings are documented below.
 
===FLAC===
* MP4: https://bug1286097.bmoattachments.org/attachment.cgi?id=8805161
* [https://xiph.org/flac/format.html#stream Native FLAC]
 
===Opus===
* MP4: [[Mp4Opus]]
* TS: [[OpusTS]]
 
The rest of the page describes a generic mapping. It is strongly preferred to instead write an explicit mapping. The generic mapping is not compatible with the explicit mappings above.


==Abstract==
==Abstract==
Embedding xiph codecs like vorbis in containers other than ogg
This page documents how to embed the different Xiph codecs like Vorbis or Theora in containers other than Ogg.  It's still in the drafting stage, and most of it was taken from a [http://svn.mplayerhq.hu/nut/docs/oggless-xiph-codecs.txt?revision=486&pathrev=577 version] that was previously a part of the NUT Subversion repository.
Said document was originally authored by Michael Niedermayer.


==Current Version==
==Current Version==
* 2007-05-23
* 2007-07-21


==Status==
==Status==
This is a proposal being discussedIt's currently not ready to be used on real-life situations.
Information on how to convert losslessly from one format to another is missing, as is Ogg timestampingRegardless, it is mostly finished and likely won't be updated further.


<!-- ==License==
==Minimum container requirements==
GPL + GFDL + anything neeeded to turn this into a open standard like a RFC~
This appendix only explains how to store Xiph codecs in containers which
(License should not be stated yet, or it will be a mess to change later) -->
support at least one global header per stream, can separate individual codec packets and in principle support the codec. So for example in the case of Vorbis, that would be variable bitrate and variable number of samples/packet.  Storage in other containers is outside the scope of this appendix.


==Minimum container requirments==
===Global header:===
This appendix only explains how to store xiph codecs in containers which
If the container can store 3 headers per stream in an unambiguous and ordered way then they shall be stored in that way. If OTOH the container is only capable of storing a single global header, then the 3 codec headers shall be concatenated without any additional header, footer or separator between them. To recover the 3 headers from such a global header the following procedure shall be used:
support at least one global header per stream, can separate individual codec
packets and in principle support the codec, so for example in the case of
vorbis that would be variable bitrate and variable number of samples/packet
Storage in other containers is outside the scope of this appendix


 
: 1) Search for the 1st occurrence of ID1. The found match and the following ID1_LEN bytes are the 1st header packet.
FIXME non vorbis/theora
: 2) search for the 1st occurrence of ID2 after here
===Global header:===
If the container can store 3 headers per stream in an unambiguos and ordered
way then they shall be stored in that way, if OTOH the container is only
capable to store a single global header then the 3 codec headers shall be
concatenated without any additional header, footer or separator between them
to recover the 3 headers from such a global header the following procedure
shall be used:
: 1) search for the 1st occurance of ID1 the found match and the following ID1_LEN bytes are the 1st header packet
: 2) search for the 1st occurance of ID2 after here
:: 3) read an unsigned integer of 32 bits and skip that many bytes
:: 3) read an unsigned integer of 32 bits and skip that many bytes
:: 4) [user_comment_list_length] = read an unsigned integer of 32 bits
:: 4) [user_comment_list_length] = read an unsigned integer of 32 bits
Line 39: Line 40:
:: 7) skip 1 byte
:: 7) skip 1 byte
: 8) the match in 2) and what follows until here is the 2nd header packet
: 8) the match in 2) and what follows until here is the 2nd header packet
: 9) search for the 1st occurance of ID3 after here the matching part and what follows is the 3rd header packet
: 9) Search for the 1st occurrence of ID3 after here. The matching part and what follows is the 3rd header packet.


====Constants:====
====Constants:====
{|
{| border="1" cellpadding="4"
! Codec
! Codec
! ID1
! ID1
Line 62: Line 63:
|}
|}


if the container needs an identifer for the global header, for example a 4cc
If the container needs an identifier for the global header, for example a fourcc for a global header chunk then glbl shall be used.
for a global header chunk then glbl shall be used




===Storing packets:===
===Storing packets:===
Each codec packet shall be stored in exactly one "container packet"
Each codec packet shall be stored in exactly one "container packet" and one "container packet" must not contain more then one codec packet. "container packet" here means the smallest separable data unit in the container.
and one "container packet" must not contain more then one codec packet
"container packet" here means the smallest separatable unit of data in the
container




===Codec Identifer:===
===Codec Identifier:===
{|
{| border="1" cellpadding="4"
! xiph-codec
! Xiph codec
! 4-cc id
! fourcc ID
! long id
! long ID
|-
|-
| Vorbis       
| Vorbis       
Line 91: Line 88:
| tarkin
| tarkin
|-
|-
| Flac
| FLAC
| flac
| flac
| flac
| flac
Line 101: Line 98:
|}
|}


if the container uses 4-character codes 4-cc identifer from the table above
If the container uses 4-character codes, the fourcc identifier from the table above shall be used. If the container uses arbitrary length strings as identifiers, then the long ID from the table above shall be used.
shall be used
if the container uses arbitrary length strings as identifers then the long
id from the table above shall be used
 
 
===Examples and Disscussions about specific containers===
What follows are some notes about specific containers, these notes are just
informative as they just repeat what is written above or in the
specification of the specific container
 
 
====Example and Disscussion of the avi container====
avi supports everything needed to store vorbis, this does not mean that all
application will support vorbis in avi as vorbis is rather different from
other audio codecs commonly stored in avi ...
avi supports a single global header like wav does, the 3 vorbis headers
shall be stored in it and only in it as described above
dwSampleSize must be set to zero as vorbis is vbr, many applications do
this incorrectly for other vbr codecs and consequently vbr audio in avi
becomes problematic
avi does not have timestamps but each chunk has a constant duration, while
vorbis packets can have one of 2 durations, if now the avi header is setup
so that each avi chunk has the same duration as the smaller duration of
the 2 possibilities in vorbis then simply inserting empty avi chunks will
allow every avi chunk to have the correct duration, this is of course
not the most beautifull solution but it is the only way to keep things
exact, additionally note, that empty chunks have been used since ages
in avi to lengthen the duration of video chunks


===Examples and Discussions about specific containers===
What follows are some notes about specific containers, these notes are just informative as they just repeat what is written above or in the
specification of the specific container.


====Example and Disscussion of the asf container====
====Example and Discussion of the AVI container====
asf supports a single global header per stream and has timestamps so
AVI supports everything needed to store Vorbis, this does not mean that all applications will support Vorbis in AVI, as Vorbis is rather different from other audio codecs commonly stored in AVI.
storing xiph codecs in it should be possible but asf is patented and
microsoft has already threatened individuals so we strongly urge you to
avoid this container


AVI supports a single global header like WAV does, the 3 Vorbis headers
shall be stored in it and only in it as described above.  dwSampleSize must be set to zero as vorbis is VBR, many applications do this incorrectly for other VBR codecs and consequently VBR audio in AVI
becomes problematic.


====Example and Disscussion of the matroska container====
AVI does not have timestamps, but each chunk has a constant duration,
matroska supports storing 3 headers using a codec specific
while Vorbis packets can have one of 2 durations.
format, which should be used for storing the 3 headers
If now the AVI header is set up in a way that each AVI chunk has the
Note, the above procedure to split one header into 3 works with the
same duration as the smaller duration of the 2 possibilities in Vorbis,
vorbis-matroska specific format too
then simply inserting empty AVI chunks will allow every AVI chunk to
have the correct duration.
This is of course not the most beautiful solution but it is the only way
to keep things exact.
Additionally, note that empty chunks have been used since ages in AVI to
lengthen the duration of video chunks.


Some Links:
* [http://svn.xiph.org/tags/vorbisacm_20020708/ Vorbisacm]
* [http://www.alexander-noe.com/video/documentation/avi.pdf AVI File Format] (PDF), 5.7 (p.21) VFR Audio - Storing Vorbis in AVI


====Example and Disscussion of the nut container====
====Example and Discussion of the ASF container====
nut supports a single global header per stream so the 1<->3 merge/split
ASF supports a single global header per stream and has timestamps, so
procedure above must be used, except that theres nothing special with
storing Xiph codecs in it should be possible, but ASF is patented and
storing xiph codecs in nut
Microsoft has already threatened individuals, so we strongly urge you to
avoid this container.


====Example and Discussion of the Matroska container====
Matroska supports storing 3 headers using a codec-specific format.
This should be used for storing the 3 headers.


====Example and Disscussion of mpeg-ps / mpeg-ts container====
Note that the above procedure to split one header into 3 works with the
These containers neither support a global header nor provide the neccessary
Vorbis-Matroska-specific format, too.
packet separation / framing, so storing xiph codecs in them is outside the
scope of this appendix


====Example and Discussion of the NUT container====
NUT supports a single global header per stream so the 1<->3 merge/split
procedure above must be used. Except that there is nothing special with
storing Xiph codecs in NUT.


====Example and Disscussion of wav container====
====Example and Discussion of MPEG-PS / MPEG-TS container====
wav does not provide the neccessary packet separation / framing, so storing
These containers neither support a global header nor do they provide
xiph codecs in it is outside the scope of this appendix
the necessary packet separation / framing.
Storing Xiph codecs in them is thus outside the scope of this appendix.


====Example and Discussion of WAV container====
WAV does not provide the necessary packet separation / framing, so storing Xiph codecs in it is outside the scope of this appendix.


====Example and Disscussion of the mov container====
====Example and Discussion of the MOV container====
a single glbl atom shall be placed in the stsd atom in which the the global
A single glbl atom shall be placed in the stsd atom in which the the global header shall be stored.
header shall be stored

Latest revision as of 10:10, 29 July 2017


Explicit mappings

The preferred method to map Xiph formats into other containers is to write an explicit mapping. Some mappings are documented below.

FLAC

Opus

The rest of the page describes a generic mapping. It is strongly preferred to instead write an explicit mapping. The generic mapping is not compatible with the explicit mappings above.

Abstract

This page documents how to embed the different Xiph codecs like Vorbis or Theora in containers other than Ogg. It's still in the drafting stage, and most of it was taken from a version that was previously a part of the NUT Subversion repository. Said document was originally authored by Michael Niedermayer.

Current Version

  • 2007-07-21

Status

Information on how to convert losslessly from one format to another is missing, as is Ogg timestamping. Regardless, it is mostly finished and likely won't be updated further.

Minimum container requirements

This appendix only explains how to store Xiph codecs in containers which support at least one global header per stream, can separate individual codec packets and in principle support the codec. So for example in the case of Vorbis, that would be variable bitrate and variable number of samples/packet. Storage in other containers is outside the scope of this appendix.

Global header:

If the container can store 3 headers per stream in an unambiguous and ordered way then they shall be stored in that way. If OTOH the container is only capable of storing a single global header, then the 3 codec headers shall be concatenated without any additional header, footer or separator between them. To recover the 3 headers from such a global header the following procedure shall be used:

1) Search for the 1st occurrence of ID1. The found match and the following ID1_LEN bytes are the 1st header packet.
2) search for the 1st occurrence of ID2 after here
3) read an unsigned integer of 32 bits and skip that many bytes
4) [user_comment_list_length] = read an unsigned integer of 32 bits
5) iterate [user_comment_list_length] times {
6) read an unsigned integer of 32 bits and skip that many bytes
}
7) skip 1 byte
8) the match in 2) and what follows until here is the 2nd header packet
9) Search for the 1st occurrence of ID3 after here. The matching part and what follows is the 3rd header packet.

Constants:

Codec ID1 ID2 ID3 ID1_LEN
Vorbis 0x01,'v','o','r','b','i','s' 0x03,'v','o','r','b','i','s' 0x05,'v','o','r','b','i','s' 23
Theora 0x80,'t','h','e','o','r','a' 0x81,'t','h','e','o','r','a' 0x82,'t','h','e','o','r','a' 35

If the container needs an identifier for the global header, for example a fourcc for a global header chunk then glbl shall be used.


Storing packets:

Each codec packet shall be stored in exactly one "container packet" and one "container packet" must not contain more then one codec packet. "container packet" here means the smallest separable data unit in the container.


Codec Identifier:

Xiph codec fourcc ID long ID
Vorbis vrbs vorbis
Theora ther theora
Tarkin trkn tarkin
FLAC flac flac
Speex spex speex

If the container uses 4-character codes, the fourcc identifier from the table above shall be used. If the container uses arbitrary length strings as identifiers, then the long ID from the table above shall be used.

Examples and Discussions about specific containers

What follows are some notes about specific containers, these notes are just informative as they just repeat what is written above or in the specification of the specific container.

Example and Discussion of the AVI container

AVI supports everything needed to store Vorbis, this does not mean that all applications will support Vorbis in AVI, as Vorbis is rather different from other audio codecs commonly stored in AVI.

AVI supports a single global header like WAV does, the 3 Vorbis headers shall be stored in it and only in it as described above. dwSampleSize must be set to zero as vorbis is VBR, many applications do this incorrectly for other VBR codecs and consequently VBR audio in AVI becomes problematic.

AVI does not have timestamps, but each chunk has a constant duration, while Vorbis packets can have one of 2 durations. If now the AVI header is set up in a way that each AVI chunk has the same duration as the smaller duration of the 2 possibilities in Vorbis, then simply inserting empty AVI chunks will allow every AVI chunk to have the correct duration. This is of course not the most beautiful solution but it is the only way to keep things exact. Additionally, note that empty chunks have been used since ages in AVI to lengthen the duration of video chunks.

Some Links:

Example and Discussion of the ASF container

ASF supports a single global header per stream and has timestamps, so storing Xiph codecs in it should be possible, but ASF is patented and Microsoft has already threatened individuals, so we strongly urge you to avoid this container.

Example and Discussion of the Matroska container

Matroska supports storing 3 headers using a codec-specific format. This should be used for storing the 3 headers.

Note that the above procedure to split one header into 3 works with the Vorbis-Matroska-specific format, too.

Example and Discussion of the NUT container

NUT supports a single global header per stream so the 1<->3 merge/split procedure above must be used. Except that there is nothing special with storing Xiph codecs in NUT.

Example and Discussion of MPEG-PS / MPEG-TS container

These containers neither support a global header nor do they provide the necessary packet separation / framing. Storing Xiph codecs in them is thus outside the scope of this appendix.

Example and Discussion of WAV container

WAV does not provide the necessary packet separation / framing, so storing Xiph codecs in it is outside the scope of this appendix.

Example and Discussion of the MOV container

A single glbl atom shall be placed in the stsd atom in which the the global header shall be stored.