[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