[Vorbis-dev] copying an ogg stream
Christoph Rupp
crupp at umc-web.de
Thu Sep 23 01:02:20 PDT 2004
Hi Ralph,
Ralph Giles wrote:
> On Wed, Sep 22, 2004 at 05:41:56PM +0200, Christoph Rupp wrote:
>>reading the ogg file is ok (ogg_sync_pageout, ogg_stream_pagein,
>>ogg_stream_packetout). but writing the file doesn't work - the
>>granulepos and page structures don't match with the original file.
>
>
> That's because you're changing them. :)
good point :)
>>then i write all pages but the last one to the output file (because, as
>>i understand it, only the last packet has the correct granulepos; all
>>other packets have a granulepos of -1).
>
>
> This is incorrect. Only the header packets have a granulepos of -1, and
> pages that no packet ends on. That's at least part of the problem. I'm
> not sure what's up with the ordering issues.
hmmm... looking at a correctly encoded file (with oggzdump, file encoded
with oggenc) it seems that the vorbis headers (the first 2 pages with
codebook and comments) have a granulepos of 0. Every packet, which is
not the last packet of a page, has -1. Only the last packet of each page
has a granulepos != -1.
>> foreach packet in list[:-1]: # does NOT include the last packet!
>> packet.granulepos=-1
>> packet.packetno=global_packetno++
>> write_packet(packet)
>
>
> Note that do to this correctly, you need to infer the granulepos of each
> packet and set that, so repagination is still accurate. The Ogg stream
> only stores the granulepos once per page, but you can always count up
> from the previous page by parsing enough of the packets to get their
> decoded length. This is the only way to accurately adjust the
> granulepos.
actually i don't want to change the granulepos. the only thing i want to
do is setting the e_o_s flag. in my code, i just copy the original
granulepos. i don't calculate it.
i've changed my code: just copy each packet to the output stream.
foreach packet in page:
write_packet(packet)
result: oggzdump output looks still very different:
new file (the copy):
0000003a: serialno 0000012345, granulepos 0, packetno 0 *** bos:
00001142: serialno 0000012345, granulepos -1, packetno 1:
00001142: serialno 0000012345, granulepos -1, packetno 2:
00001142: serialno 0000012345, granulepos -1, packetno 3:
00001142: serialno 0000012345, granulepos -1, packetno 4:
00002231: serialno 0000012345, granulepos -1, packetno 5:
old file (the original):
0000003a: serialno 1295053610, granulepos 0, packetno 0 *** bos:
00000fc7: serialno 1295053610, granulepos -1, packetno 1:
00000fc7: serialno 1295053610, granulepos 0, packetno 2:
00002030: serialno 1295053610, granulepos -1, packetno 3:
00002030: serialno 1295053610, granulepos -1, packetno 4:
00002030: serialno 1295053610, granulepos -1, packetno 5:
i don't touch the granulepos at all! i don't know why it got changed...
> Note that Arc wrote a serial number changer in python. I expect it's in
> svn somewhere; check google for references. That only does half of want
> you want though, but it's much simpler since you can just copy pages.
i had a look. i'll try to change my test program to copy pages instead
of packets, just to see if it would work. but it's not what i want, i
can't set e_o_s that way...
thanks,
Chris
More information about the Vorbis-dev
mailing list