1 # agent-video.tcl --
2 #
3 # VideoAgent object definition
4 #
5 # Copyright (c) 1996-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #
31 # @(#) $Header: /usr/mash/src/repository/mash/mash-1/tcl/net/agent-video.tcl,v 1.60 2003/06/18 23:36:47 aswan Exp $
32
33
34 import RTPAgent RTP/Video AnnounceListenManager/AS/Client/MeGa/Video
35
36 # pvh decoder may not be built in
37 catch {Module/VideoDecoder/PVH set maxChannel_ 0}
38
39 #------------------------------------------------------------------------
40 # Class:
41 # VideoAgent
42 #
43 # Description:
44 # The VideoAgent class provides a coarse-grained interface
45 # that abstracts away all the details of networked video decoding.
46 # This agent is responsible for creating the underlying RTP
47 # session for the video channel, for opening and initializing
48 # any video decoding hardware, and for creating and deleting software
49 # decoder objects to process the compressed bit streams from the network.
50 # <p>
51 # Since VideoAgent is derived from the RTPAgent base class,
52 # the standard RTP observer API is supported. Any ``interesting''
53 # events (e.g., the arrival of a new RTP flow) within the underlying
54 # RTP sessions are relayed to all the observers attached to this agent.
55 # (Note that the AudioAgent class catches and handles some of the
56 # events on its own.)
57 # <p>
58 # Typically, a mash script will create a separate user interface
59 # object and attach it to the VideoAgent as an Observer.
60 #------------------------------------------------------------------------
61
62 Class VideoAgent -superclass { RTPAgent RTP/Video } -configuration {
63 megaVideoFormat h261
64 # multicast is default
65 megaRecvVideoPort 0
66 megaVideoCtrl 224.4.5.24/50000/31
67 megaVideoCtrlBW 20000
68 videoServiceLocation urn:vgw
69 }
70
71 #
72 VideoAgent public init { app spec {callback {}}} {
73 $self set myhandler_ $app
74
75 set ab [SessionAddress parse $spec]
76 if { $ab != "" } {
77 set fmt [$ab fmt]
78 if { $fmt != {} } { $self add_option videoFormat $fmt }
79 }
80 $self next $ab $callback
81
82 if { $ab != "" } {
83 delete $ab
84 }
85
86 $self site-drop-time [$self get_option siteDropTime]
87 $self instvar decoders_
88 #FIXME
89 set decoders_ ""
90
91 set localbw [$app get_option videoSessionBW]
92 if { $localbw == "" } {
93 set localbw [$app get_option maxVideoSessionBW]
94 }
95 $self sessionbw $localbw
96
97 $self start_mega
98 }
99
100
101 #
102 # you should ensure nobody is using actively this agent (a VideoPipeline,
103 # for example) before destroying it
104 #
105 VideoAgent public destroy { } {
106 $self instvar al_
107 if [info exists al_] { delete $al_ }
108 $self next
109 }
110
111
112 VideoAgent public start_mega { } {
113 $self instvar al_ myhandler_
114
115 if [info exists al_] { delete $al_ }
116 if { [$myhandler_ get_option megaVideoSession] != "" } {
117 set sname [$myhandler_ get_option megaVideoSession]
118 set sspec [$self get_option videoSessionSpec]
119 set rportspec [$self get_option megaRecvVideoPort]
120 set ofmt [$self get_option megaVideoFormat]
121
122 set localbw [$myhandler_ get_option videoSessionBW]
123 if { $localbw == "" } {
124 set localbw [$myhandler_ get_option maxVideoSessionBW]
125 }
126 set bw [expr 0.02*$localbw]
127 set megaspec [$self get_option megaVideoCtrl]
128 set loc [$self get_option videoServiceLocation]
129
130 set ab [new AddressBlock $sspec]
131 set sspec [$ab addr]/[$ab sport]:[$ab rport]/[$ab ttl]
132 delete $ab
133 set al_ [new AnnounceListenManager/AS/Client/MeGa/Video \
134 $self $megaspec $bw [Application name] video \
135 $sname $sspec $rportspec $ofmt $loc]
136 $al_ start
137 }
138 }
139
140
141 VideoAgent public video_handler {} { return [$self set myhandler_] }
142
143
144 #
145 # Used when we need to point the mega audio gateway we're controlling
146 # to listen to a new source. This is kludgy, and needs a redesign.
147 #
148 VideoAgent public reset_mega {} {
149 $self instvar al_
150 if ![info exists al_] {
151 $self start_mega
152 } else {
153 $al_ reset_spec [$self get_option videoSessionSpec]
154 }
155 }
156
157 #
158 # Create a Session object that appropriate for this
159 # type of agent. Called by the RTPAgent class when
160 # initializing the network state.
161 #
162 VideoAgent public create_session {} {
163 return [new Session/RTP/Video]
164 }
165
166 #
167 # Handle an activate event on source <i>src</i>.
168 # Called from C++ (through Source/RTP) when we start
169 # actively receiving data pkts from the given source.
170 # Create the decoder and dispatch the method to the
171 # observers as normal.
172 # Extends method in RTPAgent.
173 #
174 VideoAgent public activate src {
175 $self instvar decoders_
176 set d [$self create_decoder $src]
177 lappend decoders_ $d
178 $src data-handler $d
179 $self next $src
180 }
181
182 #
183 # Handle a deactivate event on source <i>src</i>.
184 # Called from C++ (through Source/RTP) when a source
185 # has left the session (either via an RTCP BYE message
186 # or via an expiration timer). This method can also
187 # get called back if the Source object is explicitly
188 # deleted from the local program.
189 # Extends method in RTPAgent.
190 #
191 VideoAgent public deactivate src {
192 $self instvar decoders_
193 # Source/RTP handler is deprecated to differentiate control handler
194 # (ctrl-handler) and data handler (data-handler).
195 set d [$src data-handler]
196 set k [lsearch -exact $decoders_ $d]
197 set decoders_ [lreplace $decoders_ $k $k]
198 $self next $src
199 if {$d != ""} {
200 delete $d
201 }
202 }
203
204 #
205 #called when the format changes and we need to delete the old decoder
206 #and create a new one
207 #
208 VideoAgent public reactivate src {
209 $self instvar decoders_
210 set d [$src data-handler]
211 if {$d!=""} {
212 delete $d
213 }
214 set k [lsearch -exact $decoders_ $d]
215 set decoders_ [lreplace $decoders_ $k $k]
216 set decoder [$self create_decoder $src]
217 lappend decoders_ $decoder
218 $src data-handler $decoder
219 return $decoder
220 }
221
222 #
223 # Change the target bandwidth assumed to be in use by the aggregate
224 # underlying network session to <i>b</i> bits per second.
225 # Upon changing the bandwidth, each attached observer
226 # is notified.
227 #
228 VideoAgent public sessionbw b {
229 $self set sessionbw_ $b
230 $self notify_observers sessionbw $b
231 }
232
233 #
234 # Change the target bandwidth used by the local source
235 # with the underlying network session to <i>b</i> bits per second.
236 # Upon changing the bandwidth, each attached observer
237 # is notified.
238 #
239 VideoAgent public local_bandwidth b {
240 [$self set session_] data-bandwidth $b
241 }
242
243 #
244 # Dispatch a decoder_changed event to all observers of
245 # the VideoAgent object associated with this Decoder.
246 # This method is from C++ the video stream state changes in a way that
247 # would affect the choice of renderer. For example, when a jpeg stream
248 # changes from type-0 to type-1 we might have to revert from
249 # hardware to software decoding, or we might have to reallocate
250 # a 422 renderer as a 420 renderer. This never needs to happen
251 # for most stream types (i.e., because the decimation factor is fixed).
252 #
253 Module/VideoDecoder public parameters_changed {} {
254 $self instvar agent_ src_
255 $agent_ notify_observers decoder_changed $src_
256 }
257
258 #
259 # Called by the underlying network object when the number
260 # of media layers expected across all sources changes.
261 # For example, an underlying network protocol might adjust
262 # the number of multicast channels received to carry out
263 # congestion control. When the level of subscription changes,
264 # the codecs must be informed so that they do not wait
265 # unnecessarily for packets that will never arrive (because
266 # the corresponding layer is not present).
267 # <p>
268 # Extends method in RTPAgent.
269 #
270 VideoAgent public set_maxchannel n {
271 $self instvar decoders_ channels_
272 if [info exists decoders_] {
273 foreach d $decoders_ {
274 $d set maxChannel_ $n
275 }
276 }
277 set channels_ $n
278 }
279
280 #
281 # Create and return a video decoder object that is capabale of decoding
282 # the RTP video stream from source <i>src</i>. If the stream type
283 # is not supported, create and return a ``null'' decoder, which consumes
284 # packets and collects statistics but cannot decode the video.
285 # FIXME this method should be private, but currently the observer
286 # is currently responsible for creating new decoders on format changes.
287 #
288 VideoAgent public create_decoder src {
289 set c [$self classmap [$src format_name]]
290
291 #puts "VideoAgent::create_decoder... creating Module/VideoDecoder/$c"
292 set result [catch {new Module/VideoDecoder/$c} decoder]
293 if {($result != 0) || ($decoder == "")} {
294 # don't support this format
295 set decoder [new Module/VideoDecoder/Null]
296 }
297
298 #FIXME
299 $decoder set agent_ $self
300 $decoder set src_ $src
301
302 $self instvar channels_
303 $decoder set maxChannel_ $channels_
304
305 return $decoder
306 }
307
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.