[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