[Vorbis-dev] copying an ogg stream

Christoph Rupp crupp at umc-web.de
Wed Sep 22 08:41:56 PDT 2004


dear list,

i am trying to write a small program which reads an ogg file and writes 
it to another ogg file (and changes serial number, granulepos etc on the 
fly).

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.

here's what i am doing. (python-like pseudo-code). First i create copies 
of all packets in a page, store them in 'list'; i also save the 
granule-position of this page:

foreach page in oggfile:
   g=get_granulepos(page)
   list=[]
   foreach packet in page:
     list.append(dup_packet(packet))  # creates a deep copy of packet

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).

   foreach packet in list[:-1]:   # does NOT include the last packet!
     packet.granulepos=-1
     packet.packetno=global_packetno++
     write_packet(packet)

now i write the last packet (this is also the place where i would set 
e_o_f...):

   packet=list[len(list)-1]
   packet.granulepos=g
   packet.packetno=global_packetno++
   write_packet(packet)


the write_packet function looks like this:

def write_packet(packet):
   ogg_stream_packetin(os, packet)

   ogg_page page;

   while (ogg_stream_pageout(os, page)):
     fwrite(page.header, page.header_len, f)
     fwrite(page.body, page.body_len, f)

(if the e_o_s flag is set, then i use ogg_stream_flush() instead of 
ogg_stream_pageout())

my problem is: when i look at the original file, it differs from the 
copied file. this is the output of the first few lines with oggzdump:

original file:

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:
...
00002030: serialno 1295053610, granulepos 23296, packetno 38:

the new file:

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:
...
00007527: serialno 0000012345, granulepos 175744, packetno 168:


first of all the granule positions have changed, and also in the 
original file packet no 38 is the last packet of the first page. in the 
new file, it's packet 168! but when stepping through the debugger, i'm 
pretty sure i have submitted the correct packets...

also, ogginfo complains a lot about "Negative granulepos on vorbis 
stream outside of headers. This file was created by a buggy encoder". 
Playback with ogg123 is ok, though.

i hope i have made my case clear and the pseudo code is not too 
overwhelming :) i can also send the "real" C/C++ code, if somebody wants 
to see it.

thanks for every idea!
Chris


More information about the Vorbis-dev mailing list