Package: libvorbis0a Version: 1.2.3-3 Severity: normal Hello,
I'm using oggscissors.py to recalculate the granulepos of files recorded with streamripper: oggscissors.py infile.ogg outfile.ogg Using version 1.2.0.dfsg-3.1 of the libvorbis* packages this works fine. However updating to 1.2.3-3 breaks the above and I get the following Python error message: oggscissors.py infile.ogg outfile.ogg [...] Dumping pages 3 Counting packets Traceback (most recent call last): File "./oggscissors.py", line 377, in <module> n, pages, packets, os, grskip = copy_packets(fin, fout, os, startpacket, count, pages, packets, grskip, 1) File "./oggscissors.py", line 108, in copy_packets total_packets = count_packets(fin) - skip_packets File "./oggscissors.py", line 85, in count_packets p = instream.packetout() ogg.OggError: lost sync I don't know if this is due to a deficiency in the python bindings. I tried the available versions of the python-ogg and python-pyvorbis packages without success. So I guess it's a problem in the C library itself. I attached the oggscissors.py script. The ogg file can be found under http://eeh06.physik.hu-berlin.de/~vseggern/libvorbisbug/infile.ogg Thank you and best regards eike -- System Information: Debian Release: squeeze/sid APT prefers testing APT policy: (600, 'testing'), (202, 'unstable'), (101, 'stable') Architecture: i386 (i686) Kernel: Linux 2.6.30-2-686 (SMP w/2 CPU cores) Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages libvorbis0a depends on: ii libc6 2.9-25 GNU C Library: Shared libraries ii libogg0 1.1.4~dfsg-1 Ogg bitstream library libvorbis0a recommends no packages. libvorbis0a suggests no packages. -- no debconf information
#!/usr/bin/env python -u # Oggscissors - cut and rejoin Ogg Vorbis streams without reencoding # Revision 3 - 2007-01-27 # Copyright 2005 - 2007 Jan Hornyak <p...@oook.cz> # http://www.oook.cz/bsd/ import getopt import ogg.vorbis import sys def usage(): print 'usage:' print ' oggscissors.py --analyze file.ogg' print " oggscissors.py --from=startpos --upto=endpos in.ogg out.ogg" sys.exit(" oggscissors.py --join in1.ogg in2.ogg out.ogg") def analyze_packets(fin, filenamein): count = None copied = 0 written = 0 pageno = 0 instream = None insync = ogg.OggSyncState() while count == None or copied < count: b = fin.read(65536) if not b: break insync.bytesin(b) skipped = 1 while skipped != 0: skipped, page = insync.pageseek() print 'read', skipped, 'bytes:', page if skipped > 0: if instream and page.serialno() != serialno: print 'we hit a chain boundary, leaving' break if not instream: serialno = page.serialno() instream = ogg.OggStreamState(serialno) page.pageno = pageno pageno = pageno + 1 instream.pagein(page) while 1: p = instream.packetout() if not p: break print ' read', p copied = copied + 1 elif skipped < 0: print 'skipped', -skipped, 'bytes' def count_packets(fin): print 'Counting packets', fin.seek(0) count = 0 instream = None insync = ogg.OggSyncState() while 1: b = fin.read(65536) if not b: break insync.bytesin(b) skipped = 1 while skipped != 0: skipped, page = insync.pageseek() if skipped > 0: if instream and page.serialno() != serialno: print 'we hit a chain boundary, leaving' break if not instream: serialno = page.serialno() instream = ogg.OggStreamState(serialno) instream.pagein(page) while 1: p = instream.packetout() if not p: break #print ' read', p count = count + 1 elif skipped < 0: print 'skipped', -skipped, 'bytes' fin.seek(0) print count return count def copy_packets(fin, fout, outstream=None, skip_packets=0, count=0, written_pages=0, written_packets=0, granule_delta=0, last_chunk=0): fin.seek(0) copied = 0 written = 0 orig_packetno = 0 granule_skip = 0 if last_chunk and count == 0: total_packets = count_packets(fin) - skip_packets instream = None insync = ogg.OggSyncState() if skip_packets: print 'Skipping packets', skip_packets, while count == 0 or copied < count: b = fin.read(65536) if not b: break insync.bytesin(b) skipped = 1 while skipped != 0: skipped, page = insync.pageseek() if skipped > 0: if instream and page.serialno() != serialno: print 'we hit a chain boundary' # we hit a chain boundary break if not instream: serialno = page.serialno() instream = ogg.OggStreamState(serialno) if not outstream: outstream = ogg.OggStreamState(serialno) #print 'reading', page instream.pagein(page) while count == 0 or copied < count: p = instream.packetout() if not p: break if (skip_packets > 0): #print ' skipping', p, 'yet to skip:', skip_packets skip_packets = skip_packets - 1 orig_packetno = orig_packetno + 1 if p.granulepos != -1: granule_skip = p.granulepos if skip_packets % 1000 == 0: print skip_packets, if skip_packets == 1: print continue #print ' reading', p if p.eos: p.eos = 0 if last_chunk: if count > 0: if copied + 1 == count: p.eos = 512 else: if copied + 1 == total_packets: p.eos = 512 if written_packets >= 3: if samples.has_key(orig_packetno): granule_delta = granule_delta + samples[orig_packetno] else: granule_delta = granule_delta + 1024 print 'Unknown size of packet', orig_packetno p.granulepos = granule_delta #print ' writing', p outstream.packetin(p) copied = copied + 1 written_packets = written_packets + 1 orig_packetno = orig_packetno + 1 if copied % 1000 == 0: print copied, if copied % 25000 == 0: print written_pages, written, outstream = dump_pages(outstream, written_pages, written) elif skipped < 0: print 'skipped', -skipped, 'bytes' print copied written_pages, written, outstream = dump_pages(outstream, written_pages, written) return (written, written_pages, written_packets, outstream, granule_delta) def dump_pages(outstream, written_pages, written): print 'Dumping pages', while 1: pg = outstream.flush() if not pg: break pg.pageno = written_pages #print 'writing', pg written = written + pg.writeout(fout) #print 'written', written, 'bytes so far' written_pages = written_pages + 1 if written_pages % 100 == 0: print written_pages, print written_pages return written_pages, written, outstream def get_packetno(seconds, rate): needed_samples = seconds * rate for z in samples: needed_samples = needed_samples - samples[z] if needed_samples <= 0: break return z def get_samples(filenamein): print 'Scanning packets', vf = ogg.vorbis.VorbisFile(filenamein) pcm_prev = 0 packetno = 3 samples = {} while 1: (buff, bytes, bit) = vf.read(4096) if bytes == 0: break pcm_now = vf.pcm_tell() samples[packetno] = pcm_now - pcm_prev if samples[packetno] > 1024: print print "Clipping bogus packet", packetno, "sample size", samples[packetno], "to 1024" samples[packetno] = 1024 pcm_prev = pcm_now packetno = packetno + 1 if packetno % 1000 == 0: print packetno, (buff, bytes,bit) = vf.read(4096) vinfo = vf.info() return samples, vinfo.rate def renumber_pages(filenamein): filenameout = filenamein+".fixed.ogg" print print "Hole detected! Fixing ogg file and writing it to", filenameout fin = open(filenamein, 'rb') fout = open(filenameout, 'wb') insync = ogg.OggSyncState() instream = None outstream = None pageno = 0 while 1: b = fin.read(65536) if not b: break insync.bytesin(b) skipped = 1 while skipped != 0: skipped, page = insync.pageseek() if skipped > 0: if instream and page.serialno() != serialno: print "we hit a chain boundary, leaving" break if not instream: serialno = page.serialno() instream = ogg.OggStreamState(serialno) if not outstream: outstream = ogg.OggStreamState(serialno) instream.pagein(page) #print "in -- ", page while 1: try: p = instream.packetout() except ogg.OggError: instream.reset() instream.pagein(page) p = instream.packetout() if not p: break outstream.packetin(p) while 1: pg = outstream.flush() if not pg: break pg.writeout(fout) #print "out - ", pg fin.close() fout.close() return filenameout opts, pargs = getopt.getopt(sys.argv[1:], '', ['analyze', 'join', 'from=', 'upto=']) opt_analyze = opt_join = 0 startpos = -1 endpos = -1 for option, argument in opts: if option == '--from': try: startpos = float(argument) except ValueError: usage() elif option == '--upto': try: endpos = float(argument) except ValueError: usage() elif option == '--analyze': opt_analyze = 1 elif option == '--join': opt_join = 1 else: usage() if opt_analyze: if len(pargs) != 1: usage() filenamein = pargs[0] fin = open(filenamein, 'rb') analyze_packets(fin, filenamein) elif opt_join: if len(pargs) != 3: usage() filenamein = pargs[0] try: samples, rate = get_samples(filenamein) except ogg.vorbis.VorbisError, errorString: filenamein = renumber_pages(filenamein) samples, rate = get_samples(filenamein) fin = open(filenamein, 'rb') filenameout = pargs[2] fout = open(filenameout, 'wb') n, pages, packets, os, grskip = copy_packets(fin, fout, None, 0, 3) n, pages, packets, os, grskip = copy_packets(fin, fout, os, 3, 0, pages, packets, grskip) filenamein = pargs[1] try: samples, rate = get_samples(filenamein) except ogg.vorbis.VorbisError, errorString: filenamein = renumber_pages(filenamein) samples, rate = get_samples(filenamein) fin = open(filenamein, 'rb') n, pages, packets, os, grskip = copy_packets(fin, fout, os, 3, 0, pages, packets, grskip, 1) else: if len(pargs) != 2: usage() filenamein = pargs[0] try: samples, rate = get_samples(filenamein) except ogg.vorbis.VorbisError, errorString: filenamein = renumber_pages(filenamein) samples, rate = get_samples(filenamein) fin = open(filenamein, 'rb') filenameout = pargs[1] fout = open(filenameout, 'wb') n, pages, packets, os, grskip = copy_packets(fin, fout, None, 0, 3) if startpos > -1: startpacket = get_packetno(startpos, rate) else: startpacket = 3 if startpacket > 5: startpacket = startpacket - 2 if endpos > -1: endpacket = get_packetno(endpos, rate) count = endpacket - startpacket else: count = 0 n, pages, packets, os, grskip = copy_packets(fin, fout, os, startpacket, count, pages, packets, grskip, 1)