[opus] Encoder state management - 'chunked' Opus?

David Holroyd
Mon, 22 Jul 2013 15:43:21 -0000

On 22/07/13 15:55, Timothy B. Terriberry wrote:
> David Holroyd wrote:
>> My code does not recreate encoder state per-frame, but it does create
>> new state at the start of each 'chunk'
> This does sound like the source of your issue. If you don't
reinitialize
> the decoder at the start of each chunk, then you'll decode extra
padding
> samples at the start of each one (and lose the corresponding samples
> from the end of the previous chunk).

Right.  I will try resetting both encoder and decoder.

>> If you're putting these frames in, e.g., Ogg, then you can start a
new
>> chain for each chunk, which will indicate to the decoder that it needs
>> to reset between them. Make sure you're properly setting the
preskip
>> value in the header to get it to skip the padding samples at the start,
>> and encoding at least that many samples extra to flush the buffered
>> samples at the end.

I didn't bother with a proper container, thinking I could get an
implementation up and running faster by just shipping opus frames with
length headers.  This is not how to do things in a 'real' implementation
of course :-D

Would padding need to be handled 'by hand' in my case, or is resetting
the decoder enough?  Clearly I would take a proper look at the opus_demo
code.

If I've missed out a lot of considerations that ogg already handles,
then I might need to just hurry up and start generating lots of 1 second
.ogg files!


>> [..link to ideas..]. Unfortunately,
>> these are not yet implemented, and require tracking state between
chunks
>> (which, if you could do that easily, presumably you wouldn't be
>> resetting the encoder state for each one).

Your assumption is correct.  No encoder state (outside of a given
'chunk' of work) is one of my design goals.

>> N.B., not all players handle chained streams very well (e.g., Firefox
>> treats them as unseekable).

I had assumed that Firefox would not provide me with a way of retrieving
a chunked Opus stream anyway.  Maybe this becomes a possibility once
Media Source extension support lands?  In the meantime, I stream using
XMLHttpRequest, decode using a javascript libopus port[1] and use the
Web Audio API in Chrome for playback.

Of course, if something out there already does chunked opus so that I
don't need to hand craft it, I would appreciate pointers!


Many thanks for all your help,
dave


[1] https://github.com/kazuki/opus.js-sample/

--