work around GStreamer bug in flacdec for really short files

This commit is contained in:
Thomas Vander Stichele
2013-02-26 23:11:42 +01:00
parent f052896505
commit 4e03a6e966
2 changed files with 48 additions and 29 deletions

View File

@@ -101,49 +101,65 @@ class ChecksumTask(log.Loggable, gstreamer.GstPipelineTask):
appsink name=sink sync=False emit-signals=True
''' % gstreamer.quoteParse(self._path).encode('utf-8')
def _getSampleLength(self):
# get length in samples of file
sink = self.pipeline.get_by_name('sink')
self.debug('query duration')
try:
length, qformat = sink.query_duration(gst.FORMAT_DEFAULT)
except gst.QueryError, e:
self.setException(e)
return None
# wavparse 0.10.14 returns in bytes
if qformat == gst.FORMAT_BYTES:
self.debug('query returned in BYTES format')
length /= 4
self.debug('total sample length of file: %r', length)
return length
def paused(self):
sink = self.pipeline.get_by_name('sink')
if self._sampleLength < 0:
self.debug('query duration')
try:
length, qformat = sink.query_duration(gst.FORMAT_DEFAULT)
except gst.QueryError, e:
self.setException(e)
return
length = self._getSampleLength()
if length is None:
return
# wavparse 0.10.14 returns in bytes
if qformat == gst.FORMAT_BYTES:
self.debug('query returned in BYTES format')
length /= 4
self.debug('total sample length of file: %r', length)
if self._sampleLength < 0:
self._sampleLength = length - self._sampleStart
self.debug('sampleLength is queried as %d samples',
self._sampleLength)
else:
self.debug('sampleLength is known, and is %d samples' %
self._sampleLength)
self._sampleEnd = self._sampleStart + self._sampleLength - 1
self.debug('sampleEnd is sample %d' % self._sampleEnd)
self.debug('event')
# the segment end only is respected since -good 0.10.14.1
event = gst.event_new_seek(1.0, gst.FORMAT_DEFAULT,
gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, self._sampleStart,
gst.SEEK_TYPE_SET, self._sampleEnd + 1) # half-inclusive interval
self.debug('CRCing %r from sector %d to sector %d' % (
self._path,
self._sampleStart / common.SAMPLES_PER_FRAME,
(self._sampleEnd + 1) / common.SAMPLES_PER_FRAME))
# FIXME: sending it with sampleEnd set screws up the seek, we don't get
# everything for flac; fixed in recent -good
result = sink.send_event(event)
self.debug('event sent, result %r', result)
if not result:
self.error('Failed to select samples with GStreamer seek event')
if self._sampleStart == 0 and self._sampleEnd + 1 == length:
self.debug('No need to seek, crcing full file')
else:
# the segment end only is respected since -good 0.10.14.1
event = gst.event_new_seek(1.0, gst.FORMAT_DEFAULT,
gst.SEEK_FLAG_FLUSH,
gst.SEEK_TYPE_SET, self._sampleStart,
gst.SEEK_TYPE_SET, self._sampleEnd + 1) # half-inclusive
self.debug('CRCing %r from frame %d to frame %d (excluded)' % (
self._path,
self._sampleStart / common.SAMPLES_PER_FRAME,
(self._sampleEnd + 1) / common.SAMPLES_PER_FRAME))
# FIXME: sending it with sampleEnd set screws up the seek, we
# don't get # everything for flac; fixed in recent -good
result = sink.send_event(event)
self.debug('event sent, result %r', result)
if not result:
self.error('Failed to select samples with GStreamer seek event')
sink.connect('new-buffer', self._new_buffer_cb)
sink.connect('eos', self._eos_cb)

View File

@@ -167,6 +167,7 @@ class EncodeTask(ctask.GstPipelineTask):
self._inpath = inpath
self._outpath = outpath
self._taglist = taglist
self._length = 0 # in samples
self._level = None
self._peakdB = None
@@ -299,8 +300,10 @@ class EncodeTask(ctask.GstPipelineTask):
if self._duration:
self.warning('GStreamer level element did not send messages.')
# workaround for when the file is too short to have volume ?
# self.peak = 0.0
# workaround for when the file is too short to have volume ?
if self._length == common.SAMPLES_PER_FRAME:
self.warning('only one frame of audio, setting peak to 0.0')
self.peak = 0.0
class TagReadTask(ctask.GstPipelineTask):