[pitivi: 11/13] discoverer: link pads on the first notify::caps ev



commit 4cb4e62ba2c429bb103d7f5b96ec28bed4dc380a
Author: Alessandro Decina <alessandro decina collabora co uk>
Date:   Thu Mar 12 16:40:29 2009 +0100

    discoverer: link pads on the first notify::caps even if caps are still not fixed.
---
 pitivi/discoverer.py     |   43 +++++++++++++++++++++++++++++++++++--------
 tests/test_discoverer.py |   39 ++++++++++++++++++++-------------------
 2 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/pitivi/discoverer.py b/pitivi/discoverer.py
index 7f032d2..edde766 100644
--- a/pitivi/discoverer.py
+++ b/pitivi/discoverer.py
@@ -91,6 +91,8 @@ class Discoverer(object, Signallable, Loggable):
         self.error_debug = None
         self.unfixed_pads = 0
         self.missing_plugin_messages = []
+        self.dynamic_elements = []
+        self.thumbnails = {}
 
     def _resetPipeline(self):
         # finish current, cleanup
@@ -103,6 +105,9 @@ class Discoverer(object, Signallable, Loggable):
             res = self.pipeline.set_state(gst.STATE_NULL)
             self.info("after setting to NULL : %s", res)
 
+        for element in self.dynamic_elements:
+            self.pipeline.remove(element)
+
     def addFile(self, filename):
         """ queue a filename to be discovered """
         self.info("filename: %s", filename)
@@ -390,7 +395,7 @@ class Discoverer(object, Signallable, Loggable):
 
         return filename
 
-    def _newVideoPadCb(self, pad, stream):
+    def _newVideoPadCb(self, pad):
         """ a new video pad was found """
         self.debug("pad %s", pad)
 
@@ -400,8 +405,10 @@ class Discoverer(object, Signallable, Loggable):
         csp = gst.element_factory_make("ffmpegcolorspace")
         pngenc = gst.element_factory_make("pngenc")
         pngsink = gst.element_factory_make("filesink")
-        stream.thumbnail = self._getThumbnailFilenameFromPad(pad)
-        pngsink.props.location = stream.thumbnail
+        self.thumbnails[pad] = thumbnail = self._getThumbnailFilenameFromPad(pad)
+        pngsink.props.location = thumbnail
+
+        self.dynamic_elements.extend([queue, csp, pngenc, pngsink])
 
         self.pipeline.add(queue, csp, pngenc, pngsink)
         gst.element_link_many(queue, csp, pngenc, pngsink)
@@ -410,10 +417,31 @@ class Discoverer(object, Signallable, Loggable):
         for element in [queue, csp, pngenc, pngsink]:
             element.sync_state_with_parent()
 
+    def _newPadCb(self, pad):
+        queue = gst.element_factory_make('queue')
+        fakesink = gst.element_factory_make('fakesink')
+        self.dynamic_elements.append(queue)
+        self.dynamic_elements.append(fakesink)
+
+        self.pipeline.add(queue, fakesink)
+        pad.link(queue.get_pad('sink'))
+        queue.link(fakesink)
+
+        queue.sync_state_with_parent()
+        fakesink.sync_state_with_parent()
+
     def _capsNotifyCb(self, pad, unused_property, ghost=None):
+        import pdb
         if ghost is None:
             ghost = pad
 
+        if not ghost.is_linked():
+            caps_str = str(pad.get_caps())
+            if caps_str.startswith("video/x-raw"):
+                self._newVideoPadCb(ghost)
+            else:
+                self._newPadCb(ghost)
+
         caps = pad.props.caps
         if caps is None or not caps.is_fixed():
             return
@@ -422,12 +450,11 @@ class Discoverer(object, Signallable, Loggable):
 
         self.unfixed_pads -= 1
         stream = self._addStreamFromPad(ghost)
-        if caps[0].get_name().startswith("video/x-raw"):
-            self._newVideoPadCb(ghost, stream)
+        if isinstance(stream, VideoStream):
+            stream.thumbnail = self.thumbnails[ghost]
 
     def _newDecodedPadCb(self, unused_element, pad, is_last):
         self.info("pad:%s caps:%s is_last:%s", pad, pad.get_caps(), is_last)
-
         # try to get the duration
         # NOTE: this gets the duration only once, usually for the first stream.
         # Demuxers don't seem to implement per stream duration queries anyway.
@@ -440,7 +467,8 @@ class Discoverer(object, Signallable, Loggable):
 
             caps_str = str(pad.get_caps())
             if caps_str.startswith("video/x-raw"):
-                self._newVideoPadCb(pad, stream)
+                self._newVideoPadCb(pad)
+                stream.thumbnail = self.thumbnails[pad]
         else:
             # add the stream once the caps are fixed
             if gst.version() < (0, 10, 21, 1) and \
@@ -454,7 +482,6 @@ class Discoverer(object, Signallable, Loggable):
                 pad.connect("notify::caps", self._capsNotifyCb)
             self.unfixed_pads += 1
 
-
     def _addStreamFromPad(self, pad):
         stream  = get_stream_for_pad(pad)
         self.current_streams.append(stream)
diff --git a/tests/test_discoverer.py b/tests/test_discoverer.py
index 361a900..68b311f 100644
--- a/tests/test_discoverer.py
+++ b/tests/test_discoverer.py
@@ -77,6 +77,8 @@ class Discoverer1(Discoverer):
     timeout_scheduled = False
     timeout_expired = True
     timeout_cancelled = False
+    new_video_pad_cb = 0
+    new_pad_cb = 0
 
     def _scheduleAnalysis(self):
         # we call _analyze manually so we don't have to do tricks to keep test
@@ -106,10 +108,19 @@ class Discoverer1(Discoverer):
 
         return source
 
+    def _newVideoPadCb(self, pad):
+        Discoverer._newVideoPadCb(self, pad)
+        self.new_video_pad_cb += 1
+
+    def _newPadCb(self, pad):
+        Discoverer._newPadCb(self, pad)
+        self.new_pad_cb += 1
+
 class TestAnalysis(TestCase):
     def setUp(self):
         TestCase.setUp(self)
         self.discoverer = Discoverer1()
+        self.discoverer.pipeline = gst.Bin()
 
     def tearDown(self):
         self.discoverer = None
@@ -281,11 +292,6 @@ class TestAnalysis(TestCase):
         self.failUnlessEqual(dic['debug'], 'debug2')
 
     def testNewDecodedPadFixed(self):
-        bag = {'called': 0}
-        def new_video_pad_cb(pad, stream):
-            bag['called'] += 1
-
-        self.discoverer._newVideoPadCb = new_video_pad_cb
         video = gst.Pad('video_00', gst.PAD_SRC)
         video.set_caps(gst.Caps('video/x-raw-rgb'))
         audio = gst.Pad('audio_00', gst.PAD_SRC)
@@ -294,18 +300,13 @@ class TestAnalysis(TestCase):
         self.failUnlessEqual(self.discoverer.current_streams, [])
         self.discoverer._newDecodedPadCb(None, video, False)
         self.failUnlessEqual(len(self.discoverer.current_streams), 1)
-        self.failUnlessEqual(bag['called'], 1)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 1)
 
         self.discoverer._newDecodedPadCb(None, audio, False)
         self.failUnlessEqual(len(self.discoverer.current_streams), 2)
-        self.failUnlessEqual(bag['called'], 1)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 1)
 
     def testNewDecodedPadNotFixed(self):
-        bag = {'called': 0}
-        def new_video_pad_cb(pad, stream):
-            bag['called'] += 1
-
-        self.discoverer._newVideoPadCb = new_video_pad_cb
         video_template = gst.PadTemplate('video_00', gst.PAD_SRC,
                 gst.PAD_ALWAYS, gst.Caps('video/x-raw-rgb, '
                         'framerate=[0/1, %d/1]' % ((2 ** 31) - 1)))
@@ -319,27 +320,26 @@ class TestAnalysis(TestCase):
         self.failUnlessEqual(self.discoverer.current_streams, [])
         self.discoverer._newDecodedPadCb(None, video, False)
         self.failUnlessEqual(len(self.discoverer.current_streams), 0)
-        self.failUnlessEqual(bag['called'], 0)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 0)
 
         self.discoverer._newDecodedPadCb(None, audio, False)
         self.failUnlessEqual(len(self.discoverer.current_streams), 0)
-        self.failUnlessEqual(bag['called'], 0)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 0)
 
         # fix the caps
         video.set_caps(gst.Caps('video/x-raw-rgb, framerate=25/1'))
         self.failUnlessEqual(len(self.discoverer.current_streams), 1)
-        self.failUnlessEqual(bag['called'], 1)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 1)
 
         audio.set_caps(gst.Caps('audio/x-raw-int, rate=44100'))
         self.failUnlessEqual(len(self.discoverer.current_streams), 2)
-        self.failUnlessEqual(bag['called'], 1)
+        self.failUnlessEqual(self.discoverer.new_video_pad_cb, 1)
 
 class TestStateChange(TestCase):
     def setUp(self):
         TestCase.setUp(self)
         self.discoverer = Discoverer1()
         # don't plug the thumbnailing branch
-        self.discoverer._newVideoPadCb = lambda pad, stream: None
         self.discoverer.current_uri = 'file:///foo/bar'
         self.src = gst.Bin()
         self.discoverer.pipeline = self.src
@@ -408,7 +408,7 @@ class TestStateChange(TestCase):
         self.failUnlessEqual(self.error, None)
         self.discoverer._busMessageStateChangedCb(None, message)
         # should go to PLAYING to do thumbnails
-        self.failUnlessEqual(self.src.get_state()[1], gst.STATE_PLAYING)
+        self.failUnlessEqual(self.src.get_state(0)[2], gst.STATE_PLAYING)
         self.discoverer._finishAnalysis()
         self.failUnlessEqual(len(self.factories), 1)
         factory = self.factories[0]
@@ -435,6 +435,7 @@ class TestStateChange(TestCase):
     def testBusStateChangedImageOnly(self):
         # only image
         pngdec = gst.element_factory_make('pngdec')
+        self.discoverer.pipeline.add(pngdec)
         pad = pngdec.get_pad('src')
         caps = gst.Caps(pad.get_caps()[0])
         caps[0]['width'] = 320
@@ -450,7 +451,7 @@ class TestStateChange(TestCase):
         self.failUnlessEqual(self.error, None)
         self.discoverer._busMessageStateChangedCb(None, message)
         # should go to PLAYING to do thumbnails
-        self.failUnlessEqual(self.src.get_state()[1], gst.STATE_PLAYING)
+        self.failUnlessEqual(self.src.get_state(0)[2], gst.STATE_PLAYING)
         self.discoverer._finishAnalysis()
         self.failUnlessEqual(len(self.factories), 1)
         factory = self.factories[0]



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]