wingo - in flumotion/trunk: . conf/managers/default/flows
flumotion/component/combiners/switch
flumotion-commit at lists.fluendo.com
flumotion-commit at lists.fluendo.com
Mon Dec 17 16:33:50 CET 2007
Author: wingo
Date: Mon Dec 17 16:33:39 2007
New Revision: 6008
Modified:
flumotion/trunk/ChangeLog
flumotion/trunk/conf/managers/default/flows/switch-av.xml
flumotion/trunk/flumotion/component/combiners/switch/switch.py
Log:
2007-12-17 Andy Wingo <wingo at pobox.com>
* flumotion/component/combiners/switch/switch.py
(Switch.try_switch): Drastically simplify, requiring the new
switch from gst-plugins-bad.
* conf/managers/default/flows/switch-av.xml: Change to have two
flows that will actually have the same caps. Different caps will
bork most all encoders.
Modified: flumotion/trunk/ChangeLog
==============================================================================
--- flumotion/trunk/ChangeLog (original)
+++ flumotion/trunk/ChangeLog Mon Dec 17 16:33:39 2007
@@ -1,3 +1,13 @@
+2007-12-17 Andy Wingo <wingo at pobox.com>
+
+ * flumotion/component/combiners/switch/switch.py
+ (Switch.try_switch): Drastically simplify, requiring the new
+ switch from gst-plugins-bad.
+
+ * conf/managers/default/flows/switch-av.xml: Change to have two
+ flows that will actually have the same caps. Different caps will
+ bork most all encoders.
+
2007-12-17 Sebastien Merle <sebastien at fluendo.com>
* flumotion.spec.in:
@@ -8,7 +18,8 @@
* flumotion/ui/simplewizard.py (SimpleWizard.on_finished):
Workaround gtk+ bug #56070
- * flumotion/component/consumers/httpstreamer/resources.py (HTTPStreamingResource.getMaxAllowedClients):
+ * flumotion/component/consumers/httpstreamer/resources.py
+ (HTTPStreamingResource.getMaxAllowedClients):
Fix indentation.
2007-12-10 Thomas Vander Stichele <thomas at apestaart dot org>
Modified: flumotion/trunk/conf/managers/default/flows/switch-av.xml
==============================================================================
--- flumotion/trunk/conf/managers/default/flows/switch-av.xml (original)
+++ flumotion/trunk/conf/managers/default/flows/switch-av.xml Mon Dec 17 16:33:39 2007
@@ -1,46 +1,28 @@
<?xml version="1.0" ?>
<planet>
<flow name="default">
- <component name="video-source-1" type="videotest-producer" worker="localhost">
+ <component name="looper1" type="loop-producer" worker="localhost">
<!-- properties -->
- <property name="format">video/x-raw-yuv</property>
- <property name="framerate">50/10</property>
- <property name="height">240</property>
- <property name="pattern">0</property>
- <property name="width">320</property>
- </component>
- <component name="audio-source-1" project="flumotion" type="audiotest-producer" worker="localhost">
- <property name="frequency">220</property>
- <property name="rate">8000</property>
- <property name="volume">1.0</property>
+ <property name="location">/home/wingo/media/vilanova_presentation.ogg</property>
</component>
- <component name="video-source-2" type="videotest-producer" worker="localhost">
+ <component name="looper2" type="loop-producer" worker="localhost">
<!-- properties -->
- <property name="format">video/x-raw-yuv</property>
- <property name="framerate">50/10</property>
- <property name="height">240</property>
- <property name="pattern">1</property>
- <property name="width">320</property>
- </component>
- <component name="audio-source-2" project="flumotion" type="audiotest-producer" worker="localhost">
- <property name="frequency">280</property>
- <property name="rate">8000</property>
- <property name="volume">1.0</property>
+ <property name="location">/home/wingo/media/vilanova_presentation.ogg</property>
</component>
<component name="switch" type="av-switch-combiner" worker="localhost">
<eater name="video-master">
- <feed>video-source-1</feed>
+ <feed>looper1:video</feed>
</eater>
<eater name="audio-master">
- <feed>audio-source-1</feed>
+ <feed>looper1:audio</feed>
</eater>
<eater name="video-backup">
- <feed>video-source-2</feed>
+ <feed>looper2:video</feed>
</eater>
<eater name="audio-backup">
- <feed>audio-source-2</feed>
+ <feed>looper2:audio</feed>
</eater>
</component>
<component name="video-encoder" type="theora-encoder" worker="localhost">
@@ -60,7 +42,7 @@
<feed>audio-encoder</feed>
</eater>
</component>
- <component name="http-video" type="http-streamer" worker="localhost">
+ <component name="http" type="http-streamer" worker="localhost">
<eater name="default">
<feed>muxer</feed>
</eater>
Modified: flumotion/trunk/flumotion/component/combiners/switch/switch.py
==============================================================================
--- flumotion/trunk/flumotion/component/combiners/switch/switch.py (original)
+++ flumotion/trunk/flumotion/component/combiners/switch/switch.py Mon Dec 17 16:33:39 2007
@@ -275,85 +275,19 @@
#
# We have to make sure the current segment on both the switch
# elements has the same stop value, and the next segment on both to
- # have the same start value to maintain sync. This case is different
- # from the one in playbin/streamselector where all the streams are
- # in the same segment.
+ # have the same start value to maintain sync.
#
# In order to do this:
- # 1) we need to block all src pads of elements connected
- # to the switches' sink pads
- # 2) we need to set the property "stop-value" on both the
- # switches to the highest value of "last-timestamp" on the two
- # switches.
- # 3) the pads should be switched (ie active-pad set) on the two switched
- # 4) the switch elements should be told to queue buffers coming on their
- # active sinkpads by setting the queue-buffers property to TRUE
- # 5) pad buffer probes should be added to the now active sink pads of the
- # switch elements, so that the start value of the enxt new segment can
- # be determined
- # 6) the src pads we blocked in 1) should be unblocked
- # 7) when both pad probes have fired once, use the lowest timestamp
- # received as the start value for the switch elements
- # 8) set the queue-buffers property on the switch elements to FALSE
+ # 1) we need to block the switch from processing more data
+ # 2) we need to query the last_stop on all stream segments of the
+ # previously active stream, and take the maximum to set as the
+ # stop_time of the old segments
+ # 3) we need to query the last_stop on all stream segments of the
+ # new stream, and take the minimum to set as the start_time of
+ # the new segments
+ # 4) tell the switches to switch, with the stop_time and start_time
def try_switch(self, checkActive=True):
- def set_switching(switching):
- if switching:
- if self._switching:
- self.warning("Switch already in progress")
- return False
- else:
- self.debug('starting switch to %s', self.idealFeed)
- self._switching = True
- return True
- else:
- if self._switching:
- self.debug('switch to %s complete', self.activeFeed)
- self._switching = False
- return True
- else:
- self.warning('something went terribly wrong')
- return False
-
- def set_blocked(blocked):
- # block/unblock all pads, not just of new feed
- for pad, e in self.switchPads.values():
- pad.set_blocked_async(blocked, lambda x, y: None)
-
- def set_stop_time():
- times = [e.get_property('last-timestamp')
- for pad, e in switchPads]
- stop_time = max(times)
-
- if stop_time != gst.CLOCK_TIME_NONE:
- self.debug('stop time = %u', stop_time)
- for pad, e in switchPads:
- e.set_property('stop-value', stop_time)
-
- diff = max(times) - min(times)
- if diff > gst.SECOND * 10:
- fmt = N_("When switching to %s, feed timestamps out"
- " of sync by %u")
- self.addWarning('large-timestamp-difference', fmt,
- feed, diff, priority=40)
-
- def set_queueing(queueing, start_time=None):
- for pad, e in switchPads:
- if start_time:
- e.set_property("start-value", start_time)
- e.set_property("queue-buffers", queueing)
-
- def switch():
- for pad, e in switchPads:
- e.set_property('active-pad', pad.get_name())
- self.activeFeed = feed
- self.uiState.set("active-eater", feed)
-
- def get_new_start_times():
- return collect_single_shot_buffer_probe(
- [pad for pad, e in switchPads],
- lambda pad, buffer: buffer.timestamp)
-
feed = self.idealFeed
if feed == self.activeFeed:
@@ -364,22 +298,44 @@
if checkActive and not self.is_active(feed):
return False
- if not set_switching(True):
- return False
+ # (pad, switch)
+ pairs = [self.switchPads[alias]
+ for alias in self.logicalFeeds[feed]]
+
+ stop_times = [e.emit('block') for p, e in pairs]
+ start_times = [p.get_property('last-stop-time') for p, e in pairs]
+
+ # FIXME: I don't know what to do if we get a GST_CLOCK_TIME_NONE
+ # for one of the stop_times. E.g. if we get audio data but no
+ # video data. The two options would be (1) to open and close
+ # e.g. a video segment of equal extent to the audio segment, or
+ # to (2) not open and close a video segment, relying on the
+ # future segment setting things right. (1) would certainly be
+ # correct, but (2) might be fine also.
+
+ stop_time = max(stop_times)
+ self.debug('stop time = %s', gst.TIME_ARGS(stop_time))
+
+ if stop_time != gst.CLOCK_TIME_NONE:
+ diff = float(max(stop_times) - min(stop_times))
+ if diff > gst.SECOND * 10:
+ fmt = N_("When switching to %s, feed timestamps out"
+ " of sync by %us")
+ self.addWarning('large-timestamp-difference', fmt,
+ feed, diff / gst.SECOND, priority=40)
+
+ # FIXME: I don't know what to do if we get a GST_CLOCK_TIME_NONE
+ # in the start_times. For now I am punting on this one. Yick.
+
+ start_time = min(start_times)
+ self.debug('start time = %s', gst.TIME_ARGS(start_time))
+
+ self.debug('switching from %r to %r', self.activeFeed, feed)
+ for p, e in pairs:
+ e.emit('switch', p.get_name(), stop_time, start_time)
- switchPads = [self.switchPads[alias]
- for alias in self.logicalFeeds[feed]]
- set_blocked(True) # (1)
- set_stop_time() # (2)
- switch() # (3)
- set_queueing(True) # (4)
- d = get_new_start_times() # (5)
- set_blocked(False) # (6)
- d.addCallback(lambda times: set_queueing(False, min(times))) # (7, 8)
- d.addCallback(lambda _: set_switching(False))
- # in self.idealEater was changed in the meantime, also to clear
- # the warning message if everything is ok
- d.addCallback(lambda _: self.try_switch())
+ self.activeFeed = feed
+ self.uiState.set("active-eater", feed)
return True
class SingleSwitch(Switch):
More information about the flumotion-commit
mailing list