Hi, it seems Ogg keeps track of a packet's size at the byte level, rather than at the bit level (eg, if I encode a packet with just one bit, decode will think there are 8 bits available). Am I right ? Not that it's a particularly important issue, since remaining bits will probably be initialized, but I noticed this while adding some calls to oggpack_look1 at the end of my decode routines to check that negative was being returned (eg, the data stream ended where it should), and it didn't. Also, oggpack_bits, when called with a read buffer, returns the number of bits read so far, rather than the number of bits still unread, which does seem counterintuitive (to me): the docs say the routine returns: "[...] the total number of bits within the current buffer" which I would read as either the full size of the read buffer, regardless of what was already read, or the number of bits still in the buffer after any have been read, rather than the number of bits that have been read so far from the current buffer. It does make total sense for write buffers though, so I kinda suspect it wasn't really intended for read buffers ?
On 06/02/2008, ogg.k.ogg.k@googlemail.com <ogg.k.ogg.k@googlemail.com> wrote:> Hi, > > it seems Ogg keeps track of a packet's size at the byte level, rather than > at the bit level (eg, if I encode a packet with just one bit, decode will > think there are 8 bits available). Am I right ?Yes, you are right that Ogg packets are always a whole number of bytes in length. The bitpacking routines in libogg are completely separate from the framing (the part which handles page and packet headers, and thus packet lengths etc.) That bitpacker is only used by the Vorbis codec, it's not really a part of Ogg encapsulation. cheers, Conrad.
On 2/7/08, Conrad Parker <conrad@metadecks.org> wrote:> That bitpacker is only used by the Vorbis codec, > it's not really a part of Ogg encapsulation.I have been wondering when will the bitpacker be taken to libvorbis. I suspect that not only there would be a performance gain in doing this, but it would make it easier to encapsulate Vorbis in other containers. -Ivo
On 2/7/08, Ivo Emanuel Gon?alves <justivo@gmail.com> wrote:> "This gives more than an 18% decoding speed-up for an > 82-byte net increase in code size."And IF that kind of performance can be gained in libvorbis too, the question is, what are we waiting for?
On 2/7/08, Ralph Giles <ralph.giles@artifex.com> wrote:> And theora, remember.Actually, I thought I remember derf doing that. And there it was on Trac's timeline. Look at changeset 14369: "Copy the libogg bitpacker directly into libtheoradec. Due to the vagaries of -fPIC and dynamic linking, we wasting a _huge_ amount of time on function call overhead. We also take the opportunity to get rid of our wrapper around the old libogg API and implement the API we want directly. This gives more than an 18% decoding speed-up for an 82-byte net increase in code size." -Ivo
It's very small, maybe it could be made a separate statically linked lib ? Or some of it inlined. That said, libogg is small too, and some of the routines in there are quite small as well.
Ivo Emanuel Gon?alves wrote:> And IF that kind of performance can be gained in libvorbis too, the > question is, what are we waiting for?I doubt the performance gain would be that large. Theora had the fun little situation where it was thunking into the big endian version of some bitpacker functions which were one-line calls to the little endian version. Because gcc seemed to be concerned that some dynamic library could override one and not the other, it went through the routine of saving old registers and setting up the PIC register two times, and then restoring everything on the way out two times. Hence almost half the time spent in the hundreds of thousands of calls to that function per frame was for mucking around with the stack in a one-line call that should've been inlined away anyway. And on top of that Theora had an additional wrapper to handle various problems with the libogg1 API when reading past the end of a packet, which added even more overhead. Vorbis, on the other hand, calls the little endian versions of the functions directly and decodes far fewer bits per second, typically. Also, Ralph reported that x86-64 showed only a 7% speed-up in Theora with the above patch (presumably because of the much saner ABI), so architecture makes a big difference as well. None of that means there aren't other very good reasons we should pull the bitpacker out of libogg that have nothing to do with speed. People seem to have a philosophical problem with linking to libogg when they want to mux Vorbis in non-Ogg containers, even though the only Ogg-specific parts of libogg are a single C file which compiles to a single object file smaller than 30K. The only people who actually care about something so small are embedded developers, who would use Tremor (with its own built-in bitpacker) anyway.