From 8ea1dc025d46ae74fe622e60ebefe4a7fb249654 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Mon, 5 Apr 2010 23:20:40 +0000 Subject: [PATCH] * morituri/image/image.py: Fix AudioLengthTask for the case where we don't have the decoder, by instead of doing get_state, waiting for an ASYNC_DONE or ERROR message. Properly raise a gst.GError in that case. * morituri/common/task.py: Add some debug. * morituri/test/test_image_image.py: After this fix, we now catch the TYPE_NOT_FOUND because of an empty stream instead of the later gst.QueryError. * morituri/test/test_common_encode.py: Let us know what it is if not a gst.QueryError. --- ChangeLog | 14 ++++++++++++++ morituri/common/task.py | 2 ++ morituri/image/image.py | 25 +++++++++++++++++++++++-- morituri/test/test_common_encode.py | 3 ++- morituri/test/test_image_image.py | 7 +++++-- 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6f578ae..e7a6883 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-04-06 Thomas Vander Stichele + + * morituri/image/image.py: + Fix AudioLengthTask for the case where we don't have the decoder, + by instead of doing get_state, waiting for an ASYNC_DONE or ERROR + message. Properly raise a gst.GError in that case. + * morituri/common/task.py: + Add some debug. + * morituri/test/test_image_image.py: + After this fix, we now catch the TYPE_NOT_FOUND because of an + empty stream instead of the later gst.QueryError. + * morituri/test/test_common_encode.py: + Let us know what it is if not a gst.QueryError. + 2010-04-05 Thomas Vander Stichele * doc/Makefile.am: diff --git a/morituri/common/task.py b/morituri/common/task.py index 0dbef2f..e9e3d4c 100644 --- a/morituri/common/task.py +++ b/morituri/common/task.py @@ -359,6 +359,7 @@ class SyncRunner(TaskRunner, ITaskListener): # only start the task after going into the mainloop, # otherwise the task might complete before we are in it gobject.timeout_add(0L, self._startWrap, self._task) + self.debug('run loop') self._loop.run() self.debug('done running task %r', task) @@ -372,6 +373,7 @@ class SyncRunner(TaskRunner, ITaskListener): # wrap task start such that we can report any exceptions and # never hang try: + self.debug('start task %r' % task) task.start(self) except Exception, e: # getExceptionMessage uses global exception state that doesn't diff --git a/morituri/image/image.py b/morituri/image/image.py index 22b86cf..e5237b8 100644 --- a/morituri/image/image.py +++ b/morituri/image/image.py @@ -160,10 +160,19 @@ class AudioLengthTask(task.Task): decodebin ! audio/x-raw-int ! fakesink name=sink''' % common.quoteParse(self._path).encode('utf-8')) + self._bus = self._pipeline.get_bus() + self._bus.add_signal_watch() + self._bus.connect('message::error', self._error_cb) + self.debug('pausing') self._pipeline.set_state(gst.STATE_PAUSED) - self._pipeline.get_state() - self.debug('paused') + self.debug('waiting for ASYNC_DONE or ERROR') + message = self._bus.timed_pop_filtered(gst.CLOCK_TIME_NONE, + gst.MESSAGE_ASYNC_DONE | gst.MESSAGE_ERROR) + if message.type == gst.MESSAGE_ERROR: + self._error_cb(self._bus, message) + self._pipeline.set_state(gst.STATE_NULL) + return self.debug('query duration') sink = self._pipeline.get_by_name('sink') @@ -185,6 +194,18 @@ class AudioLengthTask(task.Task): self.stop() + def _error_cb(self, bus, msg): + error, debug = msg.parse_error() + self.debug('Got GStreamer error: %r, debug: %r' % ( + error.message, debug)) + # give us an exception stack for debugging + try: + raise error + except: + pass + self.setException(error) + self.stop() + class ImageVerifyTask(task.MultiSeparateTask): """ I verify a disk image and get the necessary track lengths. diff --git a/morituri/test/test_common_encode.py b/morituri/test/test_common_encode.py index 1b21295..f0a76fa 100644 --- a/morituri/test/test_common_encode.py +++ b/morituri/test/test_common_encode.py @@ -24,7 +24,8 @@ class PathTestCase(common.TestCase): encode.WavProfile()) e = self.assertRaises(task.TaskException, self.runner.run, encodetask, verbose=False) - self.failUnless(isinstance(e.exception, gst.QueryError)) + self.failUnless(isinstance(e.exception, gst.QueryError), + "%r is not a gst.QueryError" % e.exception) os.unlink(path) def testUnicodePath(self): diff --git a/morituri/test/test_image_image.py b/morituri/test/test_image_image.py index f2ec688..f52ace0 100644 --- a/morituri/test/test_image_image.py +++ b/morituri/test/test_image_image.py @@ -94,8 +94,11 @@ class AudioLengthPathTestCase(tcommon.TestCase): t = image.AudioLengthTask(path) e = self.assertRaises(task.TaskException, self.runner.run, t, verbose=False) - self.failUnless(isinstance(e.exception, gst.QueryError), - "%r is not a gst.QueryError" % e.exceptionMessage) + self.failUnless(isinstance(e.exception, gst.GError), + "%r is not a gst.GError" % e.exceptionMessage) + self.assertEquals(e.exception.domain, gst.STREAM_ERROR) + # our empty file triggers TYPE_NOT_FOUND + self.assertEquals(e.exception.code, gst.STREAM_ERROR_TYPE_NOT_FOUND) os.unlink(path) def testUnicodePath(self):