Package flumotion :: Package component :: Package effects :: Package kuscheduler :: Module kuscheduler
[hide private]

Source Code for Module flumotion.component.effects.kuscheduler.kuscheduler

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18   
 19  import gobject 
 20  import gst 
 21   
 22  from flumotion.common import gstreamer 
 23  from flumotion.common.i18n import gettexter 
 24  from flumotion.component import feedcomponent 
 25   
 26  __version__ = "$Rev$" 
 27  T_ = gettexter() 
 28   
 29   
 30  DEFAULT_INTERVAL = 10 * gst.SECOND 
 31   
 32   
33 -class GstKeyUnitsScheduler(gst.Element):
34 35 __gproperties__ = { 36 'interval': (gobject.TYPE_UINT64, 37 'Key Unit Interval', 38 'Key Unit interval in ns', 39 0, gst.CLOCK_TIME_NONE, DEFAULT_INTERVAL, 40 gobject.PARAM_READWRITE)} 41 42 __gstdetails__ = ('FluKeyUnitsScheduler', 'Converter', 43 'Key Units scheduler for flumotion', 44 'Flumotion Dev Team') 45 46 _sinkpadtemplate = gst.PadTemplate("sink", 47 gst.PAD_SINK, 48 gst.PAD_ALWAYS, 49 gst.caps_new_any()) 50 51 _srcpadtemplate = gst.PadTemplate("src", 52 gst.PAD_SRC, 53 gst.PAD_ALWAYS, 54 gst.caps_new_any()) 55
56 - def __init__(self):
57 gst.Element.__init__(self) 58 self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") 59 self.sinkpad.set_chain_function(self.chainfunc) 60 self.add_pad(self.sinkpad) 61 62 self.srcpad = gst.Pad(self._srcpadtemplate, "src") 63 self.add_pad(self.srcpad) 64 65 self._last_ts = 0L 66 self._count = 0 67 self.interval = DEFAULT_INTERVAL
68
69 - def _send_event(self, timestamp):
70 clock = self.get_clock() 71 if clock is not None: 72 running_time = clock.get_time() - self.get_base_time() 73 else: 74 running_time = 0 75 s = gst.Structure("GstForceKeyUnit") 76 s.set_value('timestamp', timestamp, 'uint64') 77 s.set_value('stream-time', timestamp, 'uint64') 78 s.set_value('running-time', running_time, 'uint64') 79 s.set_value('all-headers', True) 80 s.set_value('count', self._count) 81 return self.srcpad.push_event( 82 gst.event_new_custom(gst.EVENT_CUSTOM_DOWNSTREAM, s))
83
84 - def chainfunc(self, pad, buf):
85 if self.interval == 0 or buf.timestamp == gst.CLOCK_TIME_NONE: 86 pass 87 elif self._last_ts == 0 or \ 88 buf.timestamp >= self._last_ts + self.interval: 89 self._count += 1 90 self._last_ts = buf.timestamp 91 if not self._send_event(buf.timestamp): 92 self.warning("Error sending GstForceKeyUnit event") 93 return self.srcpad.push(buf)
94
95 - def do_change_state(self, transition):
96 if transition == gst.STATE_CHANGE_PAUSED_TO_READY: 97 self._last_ts = 0L 98 self._count = 0 99 return gst.Element.do_change_state(self, transition)
100
101 - def do_set_property(self, property, value):
102 if property.name == 'interval': 103 self.interval = value 104 else: 105 raise AttributeError('unknown property %s' % property.name)
106
107 - def do_get_property(self, property):
108 if property.name == 'interval': 109 return self.interval 110 raise AttributeError('unknown property %s' % property.name)
111 112
113 -class KeyUnitsScheduler(feedcomponent.PostProcEffect):
114 """ 115 I can be added after a raw video source to schedule GstForceKeyUnit 116 event, used to synchronize downstream elements, like encoders or 117 fragmenters. 118 """ 119 logCategory = "kuscheduler-effect" 120
121 - def __init__(self, name, sourcePad, pipeline, interval):
122 """ 123 @param element: the video source element on which the post 124 processing effect will be added 125 @param sourcePad: source pad used for linking the effect 126 @param pipeline: the pipeline of the element 127 @param interval: interval between GstForceKeyUnit events in ns 128 """ 129 feedcomponent.PostProcEffect.__init__(self, name, sourcePad, 130 self.get_kuscheduler(interval), pipeline)
131
132 - def get_kuscheduler(self, interval):
133 if not gstreamer.element_factory_exists('keyunitsscheduler'): 134 register() 135 136 kubin = gst.parse_bin_from_description('keyunitsscheduler interval=%s ' 137 'name=scheduler' % interval, True) 138 self._kuscheduler = kubin.get_by_name('scheduler') 139 return kubin
140
141 - def effect_setInterval(self, interval):
142 self._kuscheduler.set_property('interval', interval) 143 return interval
144
145 - def effect_getInterval(self):
146 return self._kuscheduler.get_property('interval')
147 148
149 -def register():
150 gobject.type_register(GstKeyUnitsScheduler) 151 gst.element_register(GstKeyUnitsScheduler, 'keyunitsscheduler', 152 gst.RANK_MARGINAL)
153