1 # agent-transcoder.tcl --
2 #
3 # Allows you to transcode different video sources and output at
4 # different bit rates and formats
5 #
6 # Copyright (c) 2000-2002 The Regents of the University of California.
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are met:
11 #
12 # A. Redistributions of source code must retain the above copyright notice,
13 # this list of conditions and the following disclaimer.
14 # B. Redistributions in binary form must reproduce the above copyright notice,
15 # this list of conditions and the following disclaimer in the documentation
16 # and/or other materials provided with the distribution.
17 # C. Neither the names of the copyright holders nor the names of its
18 # contributors may be used to endorse or promote products derived from this
19 # software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
22 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
25 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 import AnnounceListenManager/AS/Service/Transcoder/Video
33 import Session/RTP/RTPGW
34 import AddressBlock
35 import MediaAgent/RTPGW
36
37 ##############################################################################
38 #
39 # Code for CTranscoderAgent
40 #
41 ##############################################################################
42 Class CTranscoderAgent
43
44 CTranscoderAgent instproc init { specAS iBW specService } {
45 $self instvar m_almVideo
46 $self instvar m_llTranscoderState
47
48 $self instvar m_aSession
49 $self instvar m_aTrancoder
50
51 # create a new announce listen object and start it
52 set m_almVideo [new AnnounceListenManager/AS/Service/Transcoder/Video \
53 $self $specAS $iBW $specService]
54
55 $m_almVideo start
56 }
57
58 ##############################################################################
59 #
60 # CTranscoderAgent instproc ReceiveMessage { msg } {
61 #
62 # Input:
63 # msg - the state message given by client
64 #
65 # Output:
66 # none
67 #
68 # Description:
69 # a new state is has just arrived and we need to update the state of the
70 # transcoder to reflect this new state. This is done by first marking
71 # all sessions and transcoders with a clear bit which is later set when
72 # the session or transcoder is updated. If any session or transcoder is
73 # in the new state but not in our current state, then they must be made.
74 # When all the state information has been process, go through the list
75 # of sessions and transcoders and make sure that their marked bit is
76 # set, if not then delete this session or transcoder
77 #
78 ##############################################################################
79 CTranscoderAgent instproc ReceiveMessage { msg } {
80 $self instvar m_aSession
81 $self instvar m_aTranscoder
82 $self instvar m_llTranscoderState
83
84 # store away the list
85 set m_llTranscoderState $msg
86
87 # mark each session and transcoder with a clear bit
88 foreach {sessionName sessionObject} [array get m_aSession] {
89 set aMarkBit($sessionName) 0
90 }
91 foreach {transcoderName transcoderObject} [array get m_aTranscoder] {
92 set aMarkBit($transcoderName) 0
93 }
94
95
96
97 # go through the state list and update or create
98 foreach lTranscoderState $m_llTranscoderState {
99 array set aTranscoderState $lTranscoderState
100
101 set specInputSession $aTranscoderState(InputSession)
102 set specOutputSession $aTranscoderState(OutputSession)
103
104 # the creation will chec if it's there and return immediately if there
105 $self CreateSession $specInputSession
106 $self CreateSession $specOutputSession
107
108 # set this session's mark bit
109 set aMarkBit($specInputSession) 1
110 set aMarkBit($specOutputSession) 1
111
112 # ok now let's deal with the transcoders and sources
113 set inputSession $m_aSession($specInputSession)
114 set sourceManager [$inputSession sm]
115 set lSource [$sourceManager set sources_]
116
117 foreach source $lSource {
118 set iSourceId [$source srcid]
119
120 # get the bw and format information
121 if { [info exist aTranscoderState($iSourceId)] } {
122 set transcoderInfo aTranscoderState($iSourceId)
123 } else {
124 set transcoderInfo aTranscoderState(Default)
125 }
126
127 set outputSession $m_aSession($specOutputSession)
128 if {![info exists m_aTranscoder($specOutputSession,$iSourceId)]} {
129 $self CreateTranscoder $outputSession $source $transcoderInfo
130 } else {
131 $self UpdateTranscoder $outputSession $source $transcoderInfo
132 }
133
134 # set the mark bit
135 set aMarkbit($specOutputSession,$iSourceId) 1
136 }
137 }
138
139
140 # finally delete all the unused transcoders and sessions
141 # FIXME need to do this part
142
143
144 }
145
146
147 ##############################################################################
148 #
149 # CTranscoderAgent instproc CreateSession { specSession } {
150 #
151 # Input:
152 # specSession - the spec (addr/port) of the session to be created
153 #
154 # Output:
155 # session - the created session or existing session with the same spec
156 #
157 # Description:
158 # Creates a session with the spec inputted. If the session already exists
159 # this function will return with no effect. If the session does not exist
160 # then one will be created and inserted info the list of sessions.
161 #
162 ##############################################################################
163 CTranscoderAgent instproc CreateSession { specSession } {
164 $self instvar m_aSession
165
166 # check it already exists
167 if { [info exist m_aSession($specSession)] } {
168 return $m_aSession($specSession)
169 }
170
171 # otherwise we have to create it
172 set session [new Session/RTP/RTPGW/Video $self]
173
174 # this is copied from agent-rtpgw.tcl
175 # FIXME delete this in destructor!
176 $session buffer-pool [new BufferPool]
177 # no local loopback
178 $session loopback-layer -1
179 $session set rate_control_ 1
180 $session set txonly_ 0
181 set sm [new MediaAgent/RTPGW $self]
182 $sm site-drop-time [$self get_option siteDropTime]
183 $session sm $sm
184
185 if { $specSession != "none" } {
186 set ab [new AddressBlock $specSession]
187 $session reset $ab
188 delete $ab
189 }
190
191 # Add this session to the array
192 set m_aSession($specSession) $session
193
194 # no local source
195 $session set loopbackLayer_ 0
196 }
197
198
199 ##############################################################################
200 #
201 # CTranscoderAgent instproc CreateTranscoder { outputSession source \
202 # transcoderInfo } {
203 #
204 # Input:
205 # outputSession - the session to output to
206 # source - the source object that serves as input
207 # transcoderInfo - the list of attributes for the transcoder (bw, format, etc.)
208 #
209 # Output:
210 # transcoder that it created
211 #
212 # Description:
213 # Creates a transcoder with the information inputed. Will return immediately
214 # if the transcoder already exists.
215 #
216 ##############################################################################
217 CTranscoderAgent instproc CreateTranscoder { outputSession source \
218 transcoderInfo } {
219 $self instvar m_aTranscoder
220
221
222 # get the source id and session spec
223 set specOutputSession [$outputSession GetSpec]
224 set iSourceId [$source srcid]
225
226 set transcoder [new Transcoder/Null $source $outputSession]
227 $transcoder set tname_ pass-thru
228
229
230 # Control path is set up in base constructor since it is
231 # identical for all transcoders.
232 set i [$outputSession data-handler]
233 set o [$transcoder data-handler]
234 $o target $i
235
236 # Add the transcoder to the array
237 set m_aTranscoder($specOutputSession,$iSourceId) $transcoder
238
239 return $transcoder
240 }
241
242
243 ##############################################################################
244 #
245 # CTranscoderAgent instproc UpdateTranscoder { outputSession source \
246 # transcoderInfo } {
247 #
248 # Input:
249 # outputSession - the session to output to
250 # source - the source object that serves as input
251 # transcoderInfo - the list of attributes for the transcoder (bw, format, etc.)
252 #
253 # Output:
254 # transcoder that it created
255 #
256 # Description:
257 # Creates a transcoder with the information inputed. Will return immediately
258 # if the transcoder already exists.
259 #
260 ##############################################################################
261 CTranscoderAgent instproc UpdateTranscoder { outputSession source \
262 transcoderInfo } {
263 # FIXME need to do this
264 }
265
266
267
268 ##############################################################################
269 #
270 # CTranscoderAgent instproc register { src } {
271 #
272 # Input:
273 # src - the source object that's registered
274 #
275 # Output:
276 # none
277 #
278 # Description:
279 # Call back function that is dynamically created in agent-rtp.tcl. The
280 # call originates from the source object. We'll set up the control pass
281 # through for this source.
282 #
283 ##############################################################################
284 CTranscoderAgent instproc register { src } {
285 $self instvar m_llTranscoderState
286 $self instvar m_aTranscoder
287 $self instvar m_aSession
288
289 #
290 # set up pass through control path
291 #
292 set replicator [new Replicator/Packet/Copy]
293 set inputSession [$src set session_]
294 set specInputSession [$inputSession GetSpec]
295
296 # with this session, attach all other sessions to the replicator
297 foreach lTranscoderState $m_llTranscoderState {
298 array set aTranscoderState $lTranscoderState
299
300 # we only care if the inputsession is equal to this source's session
301 if { $aTranscoderState(InputSession) != $specInputSession } {
302 continue
303 }
304
305 # get the output session and add it's ctrl-handler to the target
306 set specOutputSession $aTranscoderState(OutputSession)
307 set outputSession $m_aSession($specOutputSession)
308 $replicator add-target [$outputSession ctrl-handler]
309 }
310
311
312 # finally set this replicator to this source
313 $src ctrl-handler $replicator
314 }
315
316 ##############################################################################
317 #
318 # CTranscoderAgent instproc unregister { src } {
319 #
320 # Input:
321 # src - the source object that's being unregistered
322 #
323 # Output:
324 # none
325 #
326 # Description:
327 # Call back function that is dynamically created in agent-rtp.tcl. The
328 # call originates from the source object. We'll tear down the control pass
329 # through for this source.
330 #
331 ##############################################################################
332 CTranscoderAgent instproc unregister { src } {
333
334 # just delete the ctrl-handler created during register
335 delete [$src ctrl-handler]
336 }
337
338 ##############################################################################
339 #
340 # CTranscoderAgent instproc activate { source } {
341 #
342 # Input:
343 # source - the source object that's being activated
344 #
345 # Output:
346 # none
347 #
348 # Description:
349 # Call back function that is dynamically created in agent-rtp.tcl. The
350 # call originates from the source object. This is where all the action
351 # happens. The data and control replicators are created. Transcoders are
352 # made.
353 #
354 ##############################################################################
355 CTranscoderAgent instproc activate { source } {
356
357 puts ""
358 puts "CTranscoderAgent: activate called"
359 puts ""
360
361 $self instvar m_llTranscoderState
362 $self instvar m_aTranscoder
363 $self instvar m_aSession
364
365 set sourceSession [$source set session_]
366 set specSourceSession [$sourceSession GetSpec]
367 set iSourceId [$source srcid]
368
369 #
370 # Set up data path and redirect control path
371 #
372 set rep [new Replicator/Packet/Copy]
373 $source data-handler $rep
374
375 delete [$source ctrl-handler]
376 set rep [new Replicator/Packet/Copy]
377 $source ctrl-handler $rep
378
379 # with this session, attach all other sessions to the replicator
380 foreach lTranscoderState $m_llTranscoderState {
381 array set aTranscoderState $lTranscoderState
382
383 # we only care if the inputsession is equal to this source's session
384 if { $aTranscoderState(InputSession) != $specSourceSession } {
385 continue
386 }
387
388 # just in case check if there's a transcoder already
389 if { [info exists m_aTranscoder($specSourceSession,$iSourceId)] } {
390 return
391 }
392
393 # get the output session
394 set specOutputSession $aTranscoderState(OutputSession)
395 set outputSession $m_aSession($specOutputSession)
396
397 # get the bw and format information
398 if { [info exist aTranscoderState($iSourceId)] } {
399 set transcoderInfo aTranscoderState($iSourceId)
400 } else {
401 set transcoderInfo aTranscoderState(Default)
402 }
403
404 # create the transcoder
405 $self CreateTranscoder $outputSession $source $transcoderInfo
406 }
407 }
408
409
410
411 ##############################################################################
412 #
413 # CTranscoderAgent instproc set_maxchannel { n } {
414 #
415 # Input:
416 # n - the number of channels
417 #
418 # Output:
419 # none
420 #
421 # Description:
422 # Call back for the network manager object. It's inform you of the max
423 # channels, currently we don't make use of this information
424 #
425 ##############################################################################
426 CTranscoderAgent instproc set_maxchannel { n } {
427 # If and when we have a layered transcoder - we'll have to
428 # do something here.
429 }
430
431 ##############################################################################
432 #
433 # Session/RTP/RTPGW instproc GetSpec { } {
434 #
435 # Input:
436 # none
437 #
438 # Output:
439 # spec (addr/port) of this session
440 #
441 # Description:
442 # returns the spec of this session
443 #
444 ##############################################################################
445 Session/RTP/RTPGW instproc GetSpec { } {
446 $self instvar agent_ netmgr_
447
448 set net [$netmgr_ set net_(0)]
449 set inetAddr "[$net set addr_]/[$net set port_]"
450
451 return $inetAddr
452 }
453
454
455 # src is the source that we need as input
456 # sess is the session which we want this source to be transcoded into
457
458 Transcoder instproc init { src sess } {
459 puts "transcoder: init called src-$src sess-$sess"
460
461 $self next
462
463 $self source $src
464
465 set datarep [$src data-handler]
466 set ctrlrep [$src ctrl-handler]
467
468 # creates a new data handler and add it to the set of replicate targets
469 set h [new Module/DataHandler]
470 $self data-handler $h
471 $datarep add-target $h
472
473 set h [new Module/ControlHandler]
474 $h target [$sess ctrl-handler]
475 $self ctrl-handler $h
476 $ctrlrep add-target $h
477 }
478
479 Transcoder/Null instproc rtcp-thumbnail n {}
480
481 Transcoder set bps_ 64000
482 Transcoder set opkts_ 0
483 Transcoder set obytes_ 0
484 Transcoder set ofrms_ 0
485 Transcoder set forward_ 0
486 Transcoder set txonly_ 0
487
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.