Subject: [codec] Fwd: New Version Notification for draft-terriberry-oggopus-00.txt

From: "Timothy B. Terriberry" <[email-masked]>
Date: Thu, 05 Jul 2012 08:12:45 -0700

Now that the main codec draft has been approved by the IESG, I thought 
we should move on to standardizing a long-term storage file format. 
After some discussion with the ADs, we decided that the codec WG itself 
was the best place to do this, so we've written a draft for it (see 
forwarded message).

The text here isn't perfect (there are some outstanding issues even the 
authors want to resolve), but I thought I'd post it now to get some 
discussion rolling. For the actual format itself, we currently have 
deployed implementations in our own opus-tools package, Firefox, and 
gstreamer. I expect libav/FFmpeg and additional application support will 
be coming soon.

Subject: New Version Notification for draft-terriberry-oggopus-00.txt
From: [email-masked]
To: [email-masked]
Cc: [email-masked]
Date: Thu, 05 Jul 2012 08:07:04 -0700

A new version of I-D, draft-terriberry-oggopus-00.txt
has been successfully submitted by Timothy B. Terriberry and posted to the
IETF repository.

Filename:	 draft-terriberry-oggopus
Revision:	 00
Title:		 Ogg Encapsulation for the Opus Audio Codec
Creation date:	 2012-07-03
WG ID:		 Individual Submission
Number of pages: 27
URL:             http://www.ietf.org/internet-drafts/draft-terriberry-oggopus-00.txt
Status:          http://datatracker.ietf.org/doc/draft-terriberry-oggopus
Htmlized:        http://tools.ietf.org/html/draft-terriberry-oggopus-00

Abstract:
   This document defines the Ogg encapsulation for the Opus interactive
   speech and audio codec.  This allows data encoded in the Opus format
   to be stored in an Ogg logical bitstream.  This provides Opus with a
   long-term storage format supporting all of the essential features,
   including metadata, fast and accurate seeking, corruption detection,
   recapture after errors, low overhead, and the ability to multiplex
   Opus with other codecs (including video) with minimal buffering.  It
   also provides a live streamable format, capable of delivery over a
   reliable stream-oriented transport, without requiring all the data,
   or even the total length of the data, up-front, in a form that is
   identical to the on-disk storage format.

The IETF Secretariat

---

From: "Kevin P. Fleming" <[email-masked]>
Date: Thu, 05 Jul 2012 10:37:18 -0500

> was the best place to do this, so we've written a draft for it (see

Will this require a charter update, to add this as a WG deliverable?

-- 
Kevin P. Fleming
Digium, Inc. | Director of Software Technologies
Jabber: [email-masked] | SIP: [email-masked] | Skype: kpfleming
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
Check us out at www.digium.com & www.asterisk.org

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Thu, 05 Jul 2012 08:54:04 -0700

> Will this require a charter update, to add this as a WG deliverable?

I believe Robert said he would coordinate with the chairs to get a 
milestone in place. I don't know if we need to do anything more than that.

---

From: Ralph Giles <[email-masked]>
Date: Thu, 05 Jul 2012 15:38:13 -0700

> we should move on to standardizing a long-term storage file format.

Thanks for writing this up! As Tim says, this draft is already
implemented in Firefox, with support in the HTML <audio> element, hidden
behind a preference switch. You can try it with Aurora (alpha) and
Nightly builds. See http://people.xiph.org/~giles/2012/opus/ for details.

You can create test files with an experimental suite of command-line
utilities in the opus-tools package. See
http://opus-codec.org/downloads/ for how to obtain a copy.

Some comments on the draft:

I think it would be better to swap sections 4 and 5. In particular, the
header layout figures are of general interest to writing file
identification and metadata extraction tools, as well as full
implementations, so having them near the beginnning of the draft makes
for easier reference. The granulepos section is quite long, and fits
better with the seeking and other considerations in section 6.

Section 4 says the granulepos values MUST increment by the number of
decodeable samples in the intervening packets, so that decoders can
calculate identical timestamps moving either forward or backward. I
think the draft should offer some guidance as to what a decoder MAY or
SHOULD do if there *is* a hole in the data, for example if part of the
file is corrupt.

Of course such a file is technically invalid, and the paragraph about
granuleposition offsets being smaller than decoded data still stand, but
in the case of corrupt Ogg pages, a decoder MAY wish to scan for the
next valid page and trust its timestamp or the average bitrate to
reconstruct what durations of packets were invalid.

In the description of the 'pre-skip' field in the granulepos discussion,
the draft says this may be used to exactly trim the start-time of stream
to perform lossless cropping. Then in the description of the field in
the ID header section, "When constructing cropped Ogg Opus streams, a
pre-skip of at least 3,840 samples (80 ms) is RECOMMENDED." Do I
understand correctly that, since pre-skip is subtracted from granulepos
to obtain timestamps, cropping this way requires rewriting the
granulepos field for every page in the logical stream, if
synchronization with other logical streams is to be maintained? I
suppose this is true of vorbis cropping too, but the need to preroll the
encoder makes the issue much more noticeable.

I don't understand the motivation for the R128_TRACK_GAIN header.
Applying this gain is optional, while there is already a manditory
output_gain in the ID header. It seems like there are two ways to
specify the same thing here.

>From informal discussions, I'm aware of the following arguments for
specifying this field. Perhaps someone more familiar with audio
normalization can respond if I've left someting out.

(a) It is important to describe the interaction between normalization
metadata, user-controlled volume settings, and the output_gain header
field to ensure that the later is correctly implemented as a manditory
element.

(b) While the manditory output_gain field can be used to fix recording
level problems in situations where re-encoding is not feasible, for
example files produced by a separate workflow, or a recording of a live
event, some producers and distributors want an *optional* way to mark
files to support the subset of applications which apply playback
normalization. This is effectively metadata for machine consumption, not
a change in the intended mix level, so a separate field is justified.

(c) It is useful to define a new tag based on the EBU R128 reference
level, rather than reusing the older 'replaygain' specification. The EBU
standard is technically superiour and gaining broader support in audio
production tools and safety regulations.

All of which seems noble enough, but only (a) is specific to Opus, and
addressing that issue doesn't require defining a new tag. Would it be
better to document this in another draft, or a revision of the
referenced vorbis-comment document?

Contrariwise, why does the draft tackle this one metadata issue without
addressing other infelicities with vorbis-comment tag schemes, such as
non-dublincore keys, machine-parsible date formats, proper attribution
of Creative Commons licensed work, and so on?

I was surprised that the R128_TRACK_GAIN field specifies its value is
the ascii representation of an integer, which is then interpreted as
a fixed point number. Surely including the radix would be more natural
for a human-readable field. The draft could still specify the same valid
range.

I also think it would be better to clamp the allowed range rather than
specifying that it MUST be valid. As a decoder author I wouldn't reject
a file because an optional metadata value is incorrect.

It might be useful to define a metadata scheme for naming the output
channels from Channel mapping 255. One use case for this mode is
multitrack recording for later offline mixing. Being able to propagate
channel labels between the input and output applications would be a nice
feature. For example:

CHANNEL_000=lead mic
CHANNEL_001=backing mic
CHANNEL_002=guitar
CHANNEL_003=bass
CHANNEL_010=piano left
CHANNEL_011=piano right

Cheers,
 -r

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Thu, 05 Jul 2012 16:55:28 -0700

> Thanks for writing this up! As Tim says, this draft is already

Well, I had a bunch of help. This has been percolating for a while at 
http://wiki.xiph.org/OggOpus

> I think it would be better to swap sections 4 and 5. In particular, the

Of course, this means the reader has none of the concepts needed to 
understand the pre-skip field when it is introduced (in particular, the 
48 kHz decoding rate assumption, the difference between granule position 
and PCM sample position, etc.). We could forward-reference it, but it 
will remain completely mysterious until they get to the granule position 
section.

Anyone else have opinions on this?

> SHOULD do if there *is* a hole in the data, for example if part of the

Trying to specify what to do in the case of a corrupt file always looked 
like a pretty deep rathole to me (years ago I started writing a tool to 
make a best-effort attempt at repairing all kinds of corruption and 
invalid constructs in Ogg files, and with all the restrictions on 
beginning and end of stream, headers, ordering, etc., it becomes 
exceedingly complicated extremely quickly. And then you add chaining.

> reconstruct what durations of packets were invalid.

Most of these restrictions are in place to make things easier to 
implement, but "what's easy" depends a good deal on your application. 
Just to illustrate: scanning forward for the next valid page is fine and 
good, but what do you do with the data once you get there? If you're not 
synchronizing with other streams and playing out to a soundcard, maybe 
you just keep playing (after skipping a suitable amount of samples for 
preroll and maybe cross-fading to avoid clicks... though sounding 
obviously broken in this case might be an advantage). If you are 
synchronizing with other streams or writing to a file, maybe you run a 
PLC algorithm or inject silence (in the file writing case, because you 
don't know what use it will be put to afterwards, so maintaining sync 
might be important there, too). Try not to think too hard about what 
happens if you're using a frame-based PLC like the one in libopus, and 
the gap is not a multiple of a valid frame size in the most recent mode. 
The more important question is, what happens when the next timestamp is 
2**63 samples in the future?

And of course, most importantly, I don't want to give people the 
impression that, however weakly we suggest it in the spec, what's 
written there is what all implementations will do, and that therefore 
encoders will _rely_ on that behavior. Then it becomes impossible to use 
the decoder flexibility gained by declaring such constructs invalid.

> encoder makes the issue much more noticeable.

Yes, I believe this is correct. This is still an improvement, in that 
you can get sample-accurate cutting without rewriting the granulepos 
field in every page so long as you _aren't_ trying to synchronize with 
another stream. That's impossible in Vorbis.

> specify the same thing here.

I don't think these are the same thing. As the draft says, the field in 
the header should normally correspond to what REPLAYGAIN_ALBUM_GAIN used 
to represent. R128_TRACK_GAIN corresponds to REPLAYGAIN_TRACK_GAIN. The 
former is a single normalization calculated across an entire collection 
of files (for some definition of collection), while the latter is 
calculated from the apparent loudness of just that individual file.

> [Snip]

I think it might be reasonable to document R128 versions of the 
ReplayGain tags elsewhere, but I think point (a) is the reason that this 
tag was discussed explicitly in this draft, and not any of the other issues.

There is also the whole proscriptive (output gain) vs. descriptive 
(R128_TRACK_GAIN) argument, but I'll let Greg Maxwell argue that one.

> for a human-readable field. The draft could still specify the same valid

Care to offer some text to make this more clear?

> a file because an optional metadata value is incorrect.

As a decoder author, you of course could do whatever you wanted if an 
encoder fails to follow a MUST restriction. For example, you might want 
to just not apply the tag at all, because it's likely the result of a 
bogus calculation in the encoder (and the extremes of the representable 
range are _very_ extreme).

> channels from Channel mapping 255. One use case for this mode is

I don't have a strong opinion on this one, so I'll defer to others here.

Thanks for the feedback!

---

From: Jean-Marc Valin <[email-masked]>
Date: Mon, 09 Jul 2012 21:27:58 -0400

One thing we should explicitly mention in the draft is that a decoder
MUST NOT reject a file because the header is longer than expected.
This makes it possible to have a minor revision to the format that
adds a field to the header. As an exception, if the decoder knows the
exact length of header for the minor revision that the file uses, then
it MAY reject it. Any thoughts?

	Jean-Marc

On 07/05/2012 11:12 AM, Timothy B. Terriberry wrote:
> Now that the main codec draft has been approved by the IESG, I
> thought we should move on to standardizing a long-term storage file
> format. After some discussion with the ADs, we decided that the
> codec WG itself was the best place to do this, so we've written a
> draft for it (see forwarded message).
> 
> The text here isn't perfect (there are some outstanding issues even
> the authors want to resolve), but I thought I'd post it now to get
> some discussion rolling. For the actual format itself, we currently
> have deployed implementations in our own opus-tools package,
> Firefox, and gstreamer. I expect libav/FFmpeg and additional
> application support will be coming soon.
> 
> 
> _______________________________________________ codec mailing list 
> [email-masked] https://www.ietf.org/mailman/listinfo/codec
>

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Tue, 10 Jul 2012 18:32:44 -0700

> MUST NOT reject a file because the header is longer than expected.

Yeah, I hadn't touched on this because I wasn't sure what I thought yet.

> it MAY reject it. Any thoughts?

The test would actually have to be: exact version is known (0 or 1) AND 
(mapping family is 0 AND length is not 19, OR mapping family is > 0 and 
length is not 21+c). I don't see a reason to disallow rejection this 
case beyond the complexity required to explain how to allow rejection. 
What's the upside to allowing rejection?

---

From: Jean-Marc Valin <[email-masked]>
Date: Tue, 10 Jul 2012 22:00:05 -0400

> What's the upside to allowing rejection?

Well, the alternative would be to say that implementations MUST NOT
reject (some) files that are known to be invalid. That seems a bit wrong
to me.

	Jean-Marc

---

From: Ron <[email-masked]>
Date: Wed, 11 Jul 2012 14:19:03 +0930

On Mon, Jul 09, 2012 at 09:27:58PM -0400, Jean-Marc Valin wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 

I'm a bit uncomfortable with the idea of this header being "arbitrarily"
extensible without any clearly defined mechanism for encapsulating further
'backward compatible' extensions that allows at least some measure of
basic validation to be performed.

If my code recognises version 1 headers, and I get a version 2 header
that is several MB in size, should I really just blindly accept that
Nothing Is Wrong?

It also doesn't really seem ideal to be appending extra fields after
the variable length mapping table data anyway.

Since any extra fields added with a minor version change must necessarily
be optional, with correct decoder behaviour still occurring if they are
ignored, I see two possible angles we could look at this from.  One is
that such things be added to the comment header - which already defines
a mechanism for arbitrary additional fields.  The other would be to
define some more formal extension mechanism, and perhaps put the channel
mapping table into it as well.

I'm not really sure what things you envisage may be added in a minor
version bump though, which are important enough to add a field to the
header, but incidental enough that decoders might ignore them with no
ill effects.  So it's not quite clear to me yet what the best way to
go for this would be either.

We already have one mechanism for extra data that is optional, do we
actually need to have a second one?

 Cheers,
 Ron

---

From: Ron <[email-masked]>
Date: Wed, 11 Jul 2012 15:09:51 +0930

On Thu, Jul 05, 2012 at 04:55:28PM -0700, Timothy B. Terriberry wrote:
> Well, I had a bunch of help. This has been percolating for a while
> at http://wiki.xiph.org/OggOpus
> 
> understand the pre-skip field when it is introduced (in particular,
> the 48 kHz decoding rate assumption, the difference between granule
> position and PCM sample position, etc.). We could forward-reference
> it, but it will remain completely mysterious until they get to the
> granule position section.

The order this is currently presented in seems fairly correct and
logical to me, in the sense that we have:

 1. - Introduction (refers the reader to the Ogg RFC as the basic
      first thing they need to know something about).

 3. & 4. - Expands on Ogg concepts that Ogg leaves to the codec
           mapping to define.

 5. - Defines the detail of things that are 'completely new' for
      this mapping.

I agree that section 4 is kind of long, and talks about more than
just granule position, but the order the information is presented
there seems roughly correct too for understanding as much as you
might from a first linear reading of the document.  It probably
could usefully be split into some subsections - with the pre-skip
definition in section 5 then providing a back reference to 4.1
about how it fits together with granule position etc.

Section 6 I suspect should be folded back into appropriate places
in the rest of the document and that section dropped entirely.
That was kind of a placeholder for various issues that came up in
discussion, but didn't otherwise already have a place in the wiki
where it obviously fit at the time.

The defined values for Channel Mapping Family might benefit from
being moved to that field's description in 5.1 rather than being
left until the latter part of 5.1.1 - or at least moved to the
top of 5.1.1 where it flows directly on from that, since we refer
to the special cases for family 0 in the descriptions of the
mapping table fields, without having introduced family 0 except
by way of saying "it's special".

I'm likewise interested in how this reads to other people too
though, since being clear to people who haven't read it before
is obviously the goal :)

 Cheers,
 Ron

---

From: Gregory Maxwell <[email-masked]>
Date: Wed, 11 Jul 2012 09:45:17 -0700

>(mapping family is 0 AND length is not 19, OR mapping family is > 0 and

I'd prefer to just say— generally— that they SHOULD rejected headers
which are completely defined by this specification which can not be
completely parsed.

And that they also MUST accept new minor numbers which have 
additional data.  It's not like there is any complexity in this. You just
stop when you're done reading what you understand.

If an addition is made which can't be safely handled this way
then it should simply use a new major number.

Ron [[email-masked]]:
> and I get a version 2 header that is several MB in size, should I
> really just blindly accept that Nothing Is Wrong

Well—You'll blindly accept that nothing is wrong with
several MB of junk in the comments or in Opus padding.

But, see RFC 3533. The initial header packet must be on a single
page, so its limited by the container spec to 64K.

And because there is no explicit length field implementers won't
run into contradictions with the decoder or memory exhaustion
attacks where you malloc the signaled size which can be much
greater than the bits on the wire.

> the variable length mapping table data anyway.

I'm not sure what you're thinking here. You just append them.

With this extensions must be monotonic— e.g. you couldn't
know about Y but not an extension added before it, but the
version numbers are also monotonic.  If there arose a need
for TLV style extensions in this header, that could be added
in some version.  But /currently/ I can only come up with
reasons why this would be a horrible idea.

A key point here is that there are not currently any anticipated
extensions.  But a byte there aligns the header, and having
it be explicit is superior to the header size sniffing I observed
implementers doing for version=0, before the pre-draft spec
defined how the version field should be used (when it was
just treated as a null terminator for "OpusHead")

I'm stridently opposed to implementing some deathstar
complexity binary-xml-extension-mechanism-whatever
when we don't have much of idea what it would be used for.

Experience in early implementations shows what we have in 
the document now is simple enough that people will implement
and validate the whole thing, even parts they don't really
care about.

No one who's contributed to the draft so far is new at this,
and, apparently, based on the collective experience with
vorbis, speex, flac, theora, (and the many non Ogg formats
we've all worked with), it doesn't appear that there will
ever need to be anything added to the header.

But, Opus is new and hits some new applications and it
would seem to be foolish to leave no graceful way out
in the case of currently unanticipated needs.

If it would be helpful, let me suggest a kind of thing
that would be done with this:

Say we find that through some astonishing
boneheaded flaw, the Opus bitstream spec results
in terrible quality for some important signal. Experts
mash their heads together and come up with a
bitstream modification which can be decoded by the
original decoder with no worse quality and fixes the 
decode when played with a new type decoder, but
only if it knows its playing a new-type bitstream. The
Opus RFC is updated.

But then an updated player needs to know that it
has a new-type file.  The header could just be
changed entirely but then the result wouldn't
play in old players.

So instead a v=2 header would just define some
field to signal this.  Because its a codec setup
header it would be available in the right layers
of applications to pass it on to the codec
implementation.

This is all terribly unlikely, not just because of all
the work that went into the opus spec but also
because no one would be eager to revise the bitstream,
but the availability of a simple compatible version
field prevents being cornered with ~zero complexity
in the likely case that it never happens.

> One is that such things be added to the comment header - which
> already defines a mechanism for arbitrary additional fields

Ugh.  The comment header is for stream metadata.
In theory it should all just be preserved if you transcode
the file between other formats.  It really shouldn't
contain anything codec specific.  

My experience in Vorbis indicates to me that using
the comment packets for less-metadata-ish use has 
had bad consequences:  It results in an application
layering violation (metadata doesn't get anywhere 
near the codec itself), it gets moved between
files where it doesn't belong, and editing tools invalidate
it without removing it (because they can 'parse' but
not understand it).  You'd have applications that
care nothing about metadata being forced to parse
it just to get whatever extension you need.  And then
you also get lovely results like your terminal getting
broken because something shoved a bunch of binary
data into the comments and a simplistic application
just splat it out to your terminal.

---

From: Ralph Giles <[email-masked]>
Date: Wed, 11 Jul 2012 10:30:21 -0700

> in the case of currently unanticipated needs.

Another versioning example, although it doesn't address the length
issue: The draft defines three channel mapping familes which give
semantic meaning to the various output channels, and specifies that any
unrecognized channel mapping should be treated like mapping 255, which
is discrete multichannel with no specific channel meanings.

If an a new surround audio encoding became popular, like an ambisonic
expansion or a 24 speaker configuration for immersive environments, a
revision of this specification could define a new channel mapping family
for that encoding. But, and this is something I think the draft could
describe more clearly, encoders producing files with that family number
could reasonably increment the minor version nibble to indicate a
compatible change. This would signal to updated decoders how to
interpret the new channel mapping family value, while older decoders
would produce discrete output without confusion.

> ever need to be anything added to the header.

This is my expectation as well. I think it's still valuable to specify
decoders MUST ignore extra data at the end of the header packets so
later drafts can take advange of the extension flag if it is needed.

 -r

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Wed, 11 Jul 2012 10:38:13 -0700

> stop when you're done reading what you understand.

This sounds pretty good to me.

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Wed, 11 Jul 2012 11:19:23 -0700

> about how it fits together with granule position etc.

Yes, this is a pretty good idea. Feel free to offer some suggestions for 
section titles, etc.

> where it obviously fit at the time.

The first paragraph probably belongs in Section 4 somewhere, but I 
worried that introducing it too early would confuse the issue with 
pre-skip, when the concepts are totally independent. I should probably 
also add a sentence about what to do if the seek point is before the 
first 80 ms.

The rest (discussing packet size limitations) arguably belongs in 
Section 3, but it really is a complete aside. Having it off the critical 
path for "things you need to understand to implement this specification" 
is an advantage, I think.

I may move the first paragraph out and re-title Section 6 to reflect the 
fact that it just discusses packet size limitations.

> by way of saying "it's special".

I think I originally pushed it back because I wanted a clear definition 
of "decoded channels" vs. "output channels" in place before I tried to 
describe the restrictions associated with each mapping family. Upon 
re-reading, I agree this order creates some other problems, though. 
However, I do think it's beneficial to keep it in its own subsection.

---

From: Ron <[email-masked]>
Date: Thu, 12 Jul 2012 10:04:38 +0930

> would produce discrete output without confusion.

This was the only concrete thing that really occurred to me which we
_might_ plausibly get value out of the "minor version" with -- however
the draft explicitly says "General-purpose players SHOULD NOT attempt
to play these (family 255) streams" -- which kind of conflicts with
the notion that minor version increments are backward compatible and
existing decoders SHOULD accept them and be able to play them.

If we add a new mapping family, then we sort of have created a stream
that is not really backward compatible with previously existing code.

The minor version in this case at best might act as a sort of crude
checksum, that says family 7 really is supposed to be defined, rather
than being an encoding error - but if we use it like that, we're going
to run out of minor versions long before we run out of new mapping
families that we might add ...  and what will we do then?

One alternative is we could just revise the spec to define new families
without bumping the minor version.  Since they'd basically act as you
suggest for things that don't recognise them anyway in that case.

> later drafts can take advange of the extension flag if it is needed.

I likewise don't actually expect we will ever find a reason to bump
the minor version (though defining new mapping families seems like a
real possibility), which is mostly why I wonder if this is really the
best mechanism for enabling extensions that we cannot yet imagine,
and mostly doubt we'll need ...

 Ron

---

From: "Timothy B. Terriberry" <[email-masked]>
Date: Wed, 11 Jul 2012 17:52:39 -0700

> suggest for things that don't recognise them anyway in that case.

I think this is basically what we'd want to, _provided_ that the new 
families did not need more information added to the header. I can easily 
see a family that required specifying speaker/capture positions (e.g., 
something CLUE-like).

But I'm not in a rush to go down that path. I just want to leave the 
door open should we need it. Let's keep things simple for now.

---

From: Gregory Maxwell <[email-masked]>
Date: Wed, 11 Jul 2012 18:16:41 -0700

> that is not really backward compatible with previously existing code.

Thats unavoidable.  Say I tell you now that mapping 3 is B-format.
None of your existing code would know that. It wouldn't be able to
play it.  Not playing it is the right thing to do. rather than sending
W out the left speaker and Z out the right and what have you.

Other than perhaps adding more channels in the mapping 1
sequence (e.g. for counts > 8) I would not generally expect
other new mappings to actually be usefully compatible without
actually knowing what they were.

>suggest for things that don't recognise them anyway in that case.
[snip]
> the minor version 

Nah, thats the reason they're reserved.  You can think of it is though
they are all _already_ defined, but the devilish fog of causality
prevents you from seeing the definitions as of yet, and thus
you can't implement support for them.

---

From: Ron <[email-masked]>
Date: Sun, 15 Jul 2012 22:17:18 +0930

On Wed, Jul 11, 2012 at 11:19:23AM -0700, Timothy B. Terriberry wrote:
> Yes, this is a pretty good idea. Feel free to offer some suggestions
> for section titles, etc.

As currently written, the logical sub-section breaks to me look
something like:

 4.1 - Pre-skip
   There is some amount of latency introduced ...

 4.2 - PCM sample position
   The PCM sample position is ...

The paragraph beginning "Vorbis streams use a granule position", should
perhaps become a footnote, or possibly move up into section 4.1.  That
seems like useful information for people who already understand the
Vorbis Ogg mapping, but may just add confusion to people who first look
at this in the context of Opus.  As part of the rationale for why we
have preskip there is useful information in it that should be included
somewhere here though.

 4.3 - EOS trimming
   The page with the 'end of stream' flag ...

 4.4 - Streams beginning after time 0
   The granule position of the first audio data page with a completed
   packet MAY be larger ...

   [Someone might have a better section title for this ...]

> pre-skip, when the concepts are totally independent. I should
> probably also add a sentence about what to do if the seek point is
> before the first 80 ms.

We could maybe add a: 4.5 - Seeking within a stream
and elaborate a little on general best practices for that there too.
Since this seems to be something people commonly do badly on their
first attempt, despite good methods having been detailed elsewhere.
Some references to those might be enough.

> Section 3, but it really is a complete aside. Having it off the
> critical path for "things you need to understand to implement this
> specification" is an advantage, I think.
> 
> I may move the first paragraph out and re-title Section 6 to reflect
> the fact that it just discusses packet size limitations.

Yes, that makes good sense to me.  I agree that once the first paragraph
is taken out of section 6, the rest does fairly coherently talk about
just packet size issues, and is distinct enough from everything else to
put in its own specific section as a final discussion point.

 Cheers,
 Ron

---

From: Ron <[email-masked]>
Date: Sun, 15 Jul 2012 23:32:40 +0930

> several MB of junk in the comments or in Opus padding.

There is a chance that _might_ not actually be wrong though, for instance
there could be base64 encoded cover art in comments etc.  while a MB of
junk in the OpusHead packet would 'clearly' always be wrong.

What wasn't clear is how much more accurately I could bound that given
the "MUST accept extra header data" condition that was proposed.

> page, so its limited by the container spec to 64K.

That RFC is actually a little handwavy on this detail, and mostly delegates
to the codec mapping to define what is a valid BOS packet.  It does say:

 So, a physical bitstream begins with the bos pages of all logical
 bitstreams containing one initial header packet per page, followed by
 the subsidiary header packets of all streams, followed by pages
 containing data packets.

But that's not a MUST, and hinges on 'containing' meaning the packet
completes on that page and is not continued to a subsequent page.

I agree that is the only sane interpretation for the current set of
mappings, where the BOS packet is quite small, and that it probably
was the original intention, but the stronger requirement is:

 The format of the bos page is dependent on the codec and therefore
 MUST be given in the encapsulation specification of that logical
 bitstream type.

So if we are going to add the condition:
"MUST accept new minor numbers which have additional data."

Then amending section 3 which says the BOS packet "MUST be placed alone"
to also explicitly explain that it "MUST complete on that page", at least
places a clear constraint on the amount of additional data that may ever
appear in some later version - and gives us a chance that application
authors won't just make up their own arbitrary 'sanity check' bounds
(or accept dozens of pages of carefully crafted rubbish) - which is the
main problem I worried we could be newly introducing here.

 Cheers,
 Ron

---

From: Ralph Giles <[email-masked]>
Date: Mon, 16 Jul 2012 14:39:25 -0400

On 12-07-05 4:55 PM, Timothy B. Terriberry wrote:

> like a pretty deep rathole to me 

Fair enough.

> implement, but "what's easy" depends a good deal on your application.

True, but you go on to list exactly the sort of options I was thinking
it would be helpful to document. What options and tradeoffs are
available isn't necessarily obvious to implementors without previous
experience with the Ogg container, or the details of the Opus codec.

> the decoder flexibility gained by declaring such constructs invalid.

Ok.

>> Do I
>> synchronization with other logical streams is to be maintained?
> 

I agree. Thanks for clarifying.

> Care to offer some text to make this more clear?

One new comment tag is introduced for Ogg Opus:

  R128_TRACK_GAIN=-2.238

representing the volume shift needed to normalize the track's volume.
The value of this tag is an ASCII signed decimal number representing
the gain in dB with the same scale as the ID header's 'output gain'
field.

An Ogg Opus logical stream MUST NOT have more than one such tag. Players
MAY clamp the the value to the same range and precision of the Q7.8
fixed-point value of the 'output-gain' field.

Decoders MUST ignore any additional characters after the last digit. So
'R128_TRACK_GAIN=-2.238dB' would be equivalent to the above example.

 -r