Package flumotion :: Package component :: Module eater
[hide private]

Source Code for Module flumotion.component.eater

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_feedcomponent010 -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  import time 
 23   
 24  from twisted.internet import reactor 
 25   
 26  from flumotion.common import componentui 
 27   
 28   
29 -class Eater:
30 """ 31 This class groups eater-related information as used by a Feed Component. 32 33 @ivar eaterAlias: the alias of this eater (e.g. "default", "video", 34 ...) 35 @ivar feedId: id of the feed this is eating from 36 @ivar uiState: the serializable UI State for this eater 37 """
38 - def __init__(self, eaterAlias, eaterName):
39 self.eaterAlias = eaterAlias 40 self.eaterName = eaterName 41 self.feedId = None 42 self.fd = None 43 self.elementName = 'eater:' + eaterAlias 44 self.depayName = self.elementName + '-depay' 45 self.setPadMonitor(None) 46 self.uiState = componentui.WorkerComponentUIState() 47 self.uiState.addKey('eaterAlias') 48 self.uiState.set('eaterAlias', eaterAlias) 49 self.uiState.addKey('eaterName') 50 self.uiState.set('eaterName', eaterName) 51 # dict for the current connection 52 connectionDict = { 53 "feedId": None, 54 "timeTimestampDiscont": None, 55 "timestampTimestampDiscont": 0.0, # ts of buffer after discont, 56 # in float seconds 57 "lastTimestampDiscont": 0.0, 58 "totalTimestampDiscont": 0.0, 59 "countTimestampDiscont": 0, 60 "timeOffsetDiscont": None, 61 "offsetOffsetDiscont": 0, # offset of buffer after discont 62 "lastOffsetDiscont": 0, 63 "totalOffsetDiscont": 0, 64 "countOffsetDiscont": 0, 65 66 } 67 self.uiState.addDictKey('connection', connectionDict) 68 69 for key in ( 70 'lastConnect', # last client connection, in epoch seconds 71 'lastDisconnect', # last client disconnect, in epoch seconds 72 'totalConnections', # number of connections made by this client 73 'countTimestampDiscont', # number of timestamp disconts seen 74 'countOffsetDiscont', # number of timestamp disconts seen 75 ): 76 self.uiState.addKey(key, 0) 77 for key in ( 78 'totalTimestampDiscont', # total timestamp discontinuity 79 'totalOffsetDiscont', # total offset discontinuity 80 ): 81 self.uiState.addKey(key, 0.0) 82 self.uiState.addKey('fd', None)
83
84 - def __repr__(self):
85 return '<Eater %s %s>' % (self.eaterAlias, 86 (self.feedId and '(disconnected)' 87 or ('eating from %s' % self.feedId)))
88
89 - def connected(self, fd, feedId, when=None):
90 """ 91 The eater has been connected. 92 Update related stats. 93 """ 94 if not when: 95 when = time.time() 96 97 self.feedId = feedId 98 self.fd = fd 99 100 self.uiState.set('lastConnect', when) 101 self.uiState.set('fd', fd) 102 self.uiState.set('totalConnections', 103 self.uiState.get('totalConnections', 0) + 1) 104 105 self.uiState.setitem("connection", 'feedId', feedId) 106 self.uiState.setitem("connection", "countTimestampDiscont", 0) 107 self.uiState.setitem("connection", "timeTimestampDiscont", None) 108 self.uiState.setitem("connection", "lastTimestampDiscont", 0.0) 109 self.uiState.setitem("connection", "totalTimestampDiscont", 0.0) 110 self.uiState.setitem("connection", "countOffsetDiscont", 0) 111 self.uiState.setitem("connection", "timeOffsetDiscont", None) 112 self.uiState.setitem("connection", "lastOffsetDiscont", 0) 113 self.uiState.setitem("connection", "totalOffsetDiscont", 0)
114
115 - def disconnected(self, when=None):
116 """ 117 The eater has been disconnected. 118 Update related stats. 119 """ 120 if not when: 121 when = time.time() 122 123 def updateUIState(): 124 self.uiState.set('lastDisconnect', when) 125 self.fd = None 126 self.uiState.set('fd', None)
127 128 reactor.callFromThread(updateUIState)
129
130 - def setPadMonitor(self, monitor):
131 self._padMonitor = monitor
132
133 - def isActive(self):
134 return self._padMonitor and self._padMonitor.isActive()
135
136 - def timestampDiscont(self, seconds, timestamp):
137 """ 138 @param seconds: discont duration in seconds 139 @param timestamp: GStreamer timestamp of new buffer, in seconds. 140 141 Inform the eater of a timestamp discontinuity. 142 This is called from a bus message handler, so in the main thread. 143 """ 144 uiState = self.uiState 145 146 c = uiState.get('connection') # dict 147 uiState.setitem('connection', 'countTimestampDiscont', 148 c.get('countTimestampDiscont', 0) + 1) 149 uiState.set('countTimestampDiscont', 150 uiState.get('countTimestampDiscont', 0) + 1) 151 152 uiState.setitem('connection', 'timeTimestampDiscont', time.time()) 153 uiState.setitem('connection', 'timestampTimestampDiscont', timestamp) 154 uiState.setitem('connection', 'lastTimestampDiscont', seconds) 155 uiState.setitem('connection', 'totalTimestampDiscont', 156 c.get('totalTimestampDiscont', 0) + seconds) 157 uiState.set('totalTimestampDiscont', 158 uiState.get('totalTimestampDiscont', 0) + seconds)
159
160 - def offsetDiscont(self, units, offset):
161 """ 162 Inform the eater of an offset discontinuity. 163 This is called from a bus message handler, so in the main thread. 164 """ 165 uiState = self.uiState 166 167 c = uiState.get('connection') # dict 168 uiState.setitem('connection', 'countOffsetDiscont', 169 c.get('countOffsetDiscont', 0) + 1) 170 uiState.set('countOffsetDiscont', 171 uiState.get('countOffsetDiscont', 0) + 1) 172 173 uiState.setitem('connection', 'timeOffsetDiscont', time.time()) 174 uiState.setitem('connection', 'offsetOffsetDiscont', offset) 175 uiState.setitem('connection', 'lastOffsetDiscont', units) 176 uiState.setitem('connection', 'totalOffsetDiscont', 177 c.get('totalOffsetDiscont', 0) + units) 178 uiState.set('totalOffsetDiscont', 179 uiState.get('totalOffsetDiscont', 0) + units)
180