diff --git a/morituri/extern/task/ChangeLog b/morituri/extern/task/ChangeLog index 0f72e8a..9845dc1 100644 --- a/morituri/extern/task/ChangeLog +++ b/morituri/extern/task/ChangeLog @@ -1,3 +1,11 @@ +2011-08-15 Thomas Vander Stichele + + * task.py: + Better logging when scheduling. + * gstreamer.py: + If paused() returns True, don't go to playing. + add a method for querying duration in the common case. + 2011-08-08 Thomas Vander Stichele * task.py: diff --git a/morituri/extern/task/gstreamer.py b/morituri/extern/task/gstreamer.py index e5e735c..bf86393 100644 --- a/morituri/extern/task/gstreamer.py +++ b/morituri/extern/task/gstreamer.py @@ -96,12 +96,18 @@ class GstPipelineTask(task.Task): ret = self.pipeline.get_state() self.debug('got pipeline to PAUSED: %r', ret) + # GStreamer tasks could already be done in paused, and not + # need playing. if not self.exception: - self.paused() + done = self.paused() else: raise self.exception - self.play() + if done: + self.debug('paused() is done') + else: + self.debug('paused() wants more') + self.play() def play(self): # since set_state returns non-False, adding it as timeout_add @@ -121,12 +127,13 @@ class GstPipelineTask(task.Task): return False if self.playing: - self.debug('scheduling setting pipeline to PLAYING') + self.debug('schedule playLater()') self.schedule(0, playLater) def stop(self): self.debug('stopping') + # FIXME: in theory this should help clean up properly, # but in practice we can still get # python: /builddir/build/BUILD/Python-2.7/Python/pystate.c:595: PyGILState_Ensure: Assertion `autoInterpreterState' failed. @@ -167,7 +174,10 @@ class GstPipelineTask(task.Task): def paused(self): """ - Called after pipeline is paused + Called after pipeline is paused. + + If this returns True, the task is done and + should not continue going to PLAYING. """ pass @@ -202,3 +212,29 @@ class GstPipelineTask(task.Task): self.setAndRaiseException(exc) self.debug('error, scheduling stop') self.schedule(0, self.stop) + + def query_length(self, element): + """ + Query the length of the pipeline in samples, for progress updates. + To be called from paused() + """ + # get duration + self.debug('query duration') + try: + duration, qformat = element.query_duration(self.gst.FORMAT_DEFAULT) + except self.gst.QueryError, e: + self.setException(e) + # schedule it, otherwise runner can get set to None before + # we're done starting + self.schedule(0, self.stop) + return + + # wavparse 0.10.14 returns in bytes + if qformat == self.gst.FORMAT_BYTES: + self.debug('query returned in BYTES format') + duration /= 4 + self.debug('total duration: %r', duration) + + return duration + + diff --git a/morituri/extern/task/task.py b/morituri/extern/task/task.py index 4edca9e..112e544 100644 --- a/morituri/extern/task/task.py +++ b/morituri/extern/task/task.py @@ -148,6 +148,7 @@ class Task(object): print 'ERROR: stopping task which is already stopped' import traceback; traceback.print_stack() self.runner = None + self.debug('reset runner to None') self._notifyListeners('stopped') ### base class methods @@ -205,6 +206,10 @@ class Task(object): exception, self.exceptionMessage)) def schedule(self, delta, callable, *args, **kwargs): + if not self.runner: + print "ERROR: scheduling on a task that's altready stopped" + import traceback; traceback.print_stack() + return self.runner.schedule(self, delta, callable, *args, **kwargs) @@ -511,6 +516,8 @@ class SyncRunner(TaskRunner, ITaskListener): def schedule(self, task, delta, callable, *args, **kwargs): def c(): try: + self.log('schedule: calling %r(*args=%r, **kwargs=%r)', + callable, args, kwargs) callable(*args, **kwargs) return False except Exception, e: @@ -519,6 +526,9 @@ class SyncRunner(TaskRunner, ITaskListener): task.setException(e) self.stopped(task) raise + self.log('schedule: scheduling %r(*args=%r, **kwargs=%r)', + callable, args, kwargs) + gobject.timeout_add(int(delta * 1000L), c) ### ITaskListener methods