~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/tcl/dc/replay/application-replayproxy.tcl

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 # application-replayproxy.tcl --
  2 #
  3 #       Created to talk to MARS to provide replay.  Also provides replay UI to
  4 #       DC video window
  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 Application
 33 import SSAC_Client
 34 import CServiceManager
 35 import CService
 36 
 37 
 38 Class CReplayProxyApplication -superclass { Application Observer }
 39 
 40 ##############################################################################
 41 #
 42 # CReplayProxyApplication instproc InitArgs { options } {
 43 #
 44 # Input:
 45 # options - the options object
 46 #
 47 # Output:
 48 # none
 49 #
 50 # Description:
 51 # Registers all options before the command line argument is parsed
 52 #
 53 ##############################################################################
 54 CReplayProxyApplication instproc InitArgs { options } {
 55 
 56     # for the active services
 57     $options register_option -sas optSpecAS
 58     $options register_option -ComPort optComPort
 59 }
 60 
 61 ##############################################################################
 62 #
 63 # CReplayProxyApplication instproc InitResources { options } {
 64 #
 65 # Input:
 66 # options - the options object
 67 #
 68 # Output:
 69 # none
 70 #
 71 # Description:
 72 # Gives defaults for options
 73 #
 74 ##############################################################################
 75 CReplayProxyApplication instproc InitResources { options } {
 76     # for the active services
 77     $options add_default optSpecAS 224.4.5.24/50000/31
 78     $options add_default optComPort 0
 79 }
 80 
 81 
 82 ##############################################################################
 83 #
 84 # CReplayProxyApplication instproc init { argv } {
 85 #
 86 # Input:
 87 # argv - command line input
 88 #
 89 # Output:
 90 # none
 91 #
 92 # Description:
 93 # Constructor for the object.
 94 #
 95 ##############################################################################
 96 CReplayProxyApplication instproc init { argv } {
 97     $self next ReplayProxy
 98 
 99     # initialize some variables
100     $self instvar m_inetClientAddress
101     $self instvar m_iClientPort
102     $self instvar m_liSourceId
103     $self instvar m_szPlayPauseState
104     $self instvar m_iOffset
105     $self instvar m_iPreviousOffset
106     $self instvar m_timer
107     $self instvar m_tmStart
108     $self instvar m_tmEnd
109 
110     set m_inetClientAddress ""
111     set m_iClientPort ""
112     set m_liSourceId ""
113     set m_szPlayPauseState "PLAY"
114     set m_iOffset 0
115     set m_iPreviousOffset 600000
116     set m_timer ""
117     set m_tmStart 0
118     set m_tmEnd 0
119 
120 
121     # Initiailization of options
122     set options [$self options]
123     $self InitArgs $options
124     $self InitResources $options
125     $options load_preferences "archival ReplayProxy"
126     set argv [$options parse_args $argv]
127 
128 
129     # setup the service manager stuff
130     $self instvar m_serviceManager
131     $self instvar m_lService
132 
133     set iPort [$options get_option optComPort]
134     set m_serviceManager [new CServiceManager "ServiceApp" "Replay" $iPort]
135     $m_serviceManager Attach $self
136 
137     set m_lService ""
138 
139     # setup the ssac client
140     $self instvar m_ssacClient
141     $self instvar m_specSsacAS
142 
143     set m_specSsacAS [$options get_option optSpecAS]
144     set m_ssacClient [new SSAC_Client $m_specSsacAS -]
145     $m_ssacClient attach_observer $self
146 
147     $self StartReplay $argv
148 }
149 
150 
151 ##############################################################################
152 #
153 # CReplayProxyApplication instproc destroy { }
154 #
155 # Input:
156 # none
157 #
158 # Output:
159 # none
160 #
161 # Description:
162 # destructor
163 #
164 ##############################################################################
165 CReplayProxyApplication instproc destroy { } {
166     $self instvar m_timer
167 
168     if { m_timer != "" } {
169         after cancel $m_timer
170     }
171 }
172 
173 
174 
175 ##############################################################################
176 #
177 # CReplayProxyApplication instproc NewConnection { service }
178 #
179 # Input:
180 # service - the new service that got connected
181 #
182 # Output:
183 # 1 - if handling this service
184 # 0 - otherwise
185 #
186 # Description:
187 # A call back function for the service manager.  This function will be called
188 # when a new connection has just been noticed by the service manager
189 #
190 ##############################################################################
191 CReplayProxyApplication instproc NewConnection { service } {
192     # this member should never be called.
193     puts "Replay Proxy got a new connection: exiting"
194     exit
195 
196     return 0
197 }
198 
199 
200 ##############################################################################
201 #
202 # CReplayProxyApplication public StartReplay { arguments } {
203 #
204 # Input:
205 # arguments - the arguments that are sent by the client.  It should hold
206 #   the address and port of the remote client as well as all the information
207 #   to start a new replay
208 #
209 # Output:
210 # none
211 #
212 # Description:
213 #
214 ##############################################################################
215 CReplayProxyApplication public StartReplay { arguments } {
216     $self instvar m_ssacClient
217     $self instvar m_specSsacAS
218     $self instvar m_inetClientAddr
219     $self instvar m_iClientPort
220 
221     # parse out the arguments
222     set inetMStudioAddr [lindex $arguments 0]
223     set iMStudioPort [lindex $arguments 1]
224     set specVideo "$inetMStudioAddr/$iMStudioPort"
225     set m_inetClientAddr [lindex $arguments 2]
226     set m_iClientPort [lindex $arguments 3]
227     set szCatalogName [lindex $arguments 4]
228     set specAudio [lindex $arguments 5]
229 
230     # Start filling out the description fields
231     set description ""
232     append description "START_DESCR\n"
233     append description "file: $szCatalogName\n"
234     append description "server: $m_specSsacAS\n"
235     append description "inetBroadcastAddr: video:$specVideo\n"
236     append description "inetBroadcastAddr: audio:$specAudio\n"
237     append description "END_DESCR\n"
238 
239     # now get the information from the catalog file and append it to the end
240     if [catch "open $szCatalogName r" fileId] {
241         puts stderr " Can't open $szCatalogName: $fileId"
242         exit
243     }
244 
245     append description [read $fileId]
246 
247     # tell the server to start the video
248     $m_ssacClient open $description 0
249 }
250 
251 
252 ##############################################################################
253 #
254 # CReplayProxyApplication public activate { tmStart tmEnd }
255 #
256 # Input:
257 # tmStart - the start time of the replay
258 # tmEnd - the end time of the replay
259 #
260 # Output:
261 # none
262 #
263 # Description:
264 # This is a callback from the client-ssac object which tells you the start
265 # and end time for the replay archive.  The main function is to change the
266 # slider to have the correct start and end times
267 #
268 ##############################################################################
269 CReplayProxyApplication public activate { tmStart tmEnd } {
270     $self instvar m_tmStart
271     $self instvar m_tmEnd
272 
273     set m_tmStart $tmStart
274     set m_tmEnd $tmEnd
275 }
276 
277 
278 ##############################################################################
279 #
280 # CReplayProxyApplication public play_update { state }
281 #
282 # Input:
283 # state - the state of the replay either play or pause
284 #
285 # Output:
286 # none
287 #
288 # Description:
289 # if the state is pause, then it's actually playing and vice-versa.
290 #
291 ##############################################################################
292 CReplayProxyApplication public play_update { state } {
293     $self instvar m_lService
294     $self instvar m_szPlayPauseState
295 
296     if { $m_szPlayPauseState != $state } {
297         set m_szPlayPauseState $state
298 
299         $self UpdateAllClients
300     }
301 }
302 
303 ##############################################################################
304 #
305 # CReplayProxyApplication public update_title { szSessionInfo1 \
306 #       szSessionInfo2 iDuration }
307 #
308 # Input:
309 # szSessionInfo1 - session info
310 # szSessionInfo2 - session info
311 # iDuration - the duration of the video
312 #
313 # Output:
314 # none
315 #
316 # Description:
317 # if the state is pause, then it's actually playing and vice-versa.
318 #
319 ##############################################################################
320 CReplayProxyApplication public update_title { szSessionInfo1 \
321         szSessionInfo2 iDuration } {
322 }
323 
324 
325 ##############################################################################
326 #
327 # CReplayProxyApplication public set_offset { iOffset }
328 #
329 # Input:
330 # iOffset - the new offset that the replay is on
331 #
332 # Output:
333 # none
334 #
335 # Description:
336 # if the state is pause, then it's actually playing and vice-versa.
337 #
338 ##############################################################################
339 CReplayProxyApplication public set_offset { iOffset } {
340     $self instvar m_iPreviousOffset
341     $self instvar m_iOffset
342     $self instvar m_tmStart
343     $self instvar m_tmEnd
344 
345     set m_iOffset $iOffset
346 
347     set duration [expr $m_tmEnd - $m_tmStart]
348     if { [expr abs($iOffset - $m_iPreviousOffset) > int($duration/20)] } {
349         set m_iPreviousOffset $iOffset
350         $self UpdateAllClients
351     }
352 }
353 
354 ##############################################################################
355 #
356 # CReplayProxyApplication public ssac_reset { szMedia szAddress }
357 #
358 # Input:
359 # szMedia - the type of media that the this address is broadcasting
360 # szAddress - the address of the broadcast
361 #
362 # Output:
363 # none
364 #
365 # Description:
366 # This function will use the inputted information to start the video service
367 # connection back to the client.  However, the source id's area also needed.
368 # The source id's are all in the ssac client object but we don't have a good
369 # interface to get them.  Changing this callback function would adversely
370 # affect other programs using this object.  So a hack will be made.
371 #
372 ##############################################################################
373 CReplayProxyApplication public ssac_reset { szMedia szAddress } {
374     $self instvar m_ssacClient
375     $self instvar m_liSourceId
376     $self instvar m_lService
377     $self instvar m_inetClientAddr
378     $self instvar m_iClientPort
379     $self instvar m_serviceManager
380     $self instvar m_lService
381 
382     # I'm only interested in video streams right now
383     if { $szMedia != "video" } {
384         return
385     }
386 
387     # I'm breaking the abstraction layer for the ssac.  I'm going to dig deep
388     # into it's data structure to get to the source id's for the archive
389     # stream being sent.
390     set lSessionList [$m_ssacClient set sesslist_]
391 
392     foreach sess $lSessionList {
393         if { [$m_ssacClient set session_($sess,Address)] == $szAddress && \
394                 [$m_ssacClient set session_($sess,Media)] == $szMedia } {
395             set liSourceId [$m_ssacClient set session_($sess,SourceId)]
396             break
397         }
398     }
399 
400     foreach iSourceId $liSourceId {
401         # see if we've already dealt with this source id
402         if { [lsearch -exact $m_liSourceId $iSourceId] == -1 } {
403             lappend m_liSourceId $iSourceId
404 
405             set service [$m_serviceManager NewService $m_inetClientAddr \
406                     $m_iClientPort "VideoService" $iSourceId]
407 
408             $service MapMessage "GET_UI_CONTROL" $self "GetUIControl"
409             $service MapMessage "UPDATE_CONTROL_UI" $self "UpdateControlUI"
410             $service MapMessage "PLAY_PAUSE" $self "PlayPauseCmd"
411             $service MapMessage "MOVE_SLIDER" $self "MoveSliderCmd"
412             $service MapMessage "CLOSE_LINK" $self "CloseService"
413             $service MapMessage "GET_INFO" $self GetInfo
414 
415             lappend m_lService $service
416 
417         }
418     }
419 }
420 
421 ##############################################################################
422 #
423 # CReplayProxyApplication private GetUIControl { service arguments }
424 #
425 # Input:
426 # service - the service that called this function
427 # arguments - the ui commands that will be evaluated to update the ui
428 #
429 # Output:
430 # none
431 #
432 # Description:
433 # send the control ui commands back to the client
434 #
435 ##############################################################################
436 CReplayProxyApplication private GetUIControl { service arguments } {
437     $self instvar m_szPlayPauseState
438     $self instvar m_iOffset
439     $self instvar m_tmStart
440     $self instvar m_tmEnd
441 
442     set cmd ""
443 
444     # for unique variable names
445     append cmd "regsub -all -- {\\\.} \$winFrame {_} __name \n"
446 
447     # the play/pause button
448     append cmd "global playPause\$__name \n"
449     append cmd "set playPause\$__name $m_szPlayPauseState \n"
450     append cmd "button \$winFrame.playPauseButton \
451             -textvariable playPause\$__name  \
452             -command \"\$service Send PLAY_PAUSE \\\"\\\" \" \n"
453 
454     append cmd "pack \$winFrame.playPauseButton -fill y -side right \n"
455 
456     # the progress slider
457     append cmd "global slider\$__name \n"
458     append cmd "set slider\$__name [expr int($m_iOffset)] \n"
459     append cmd "scale \$winFrame.slider -orient horizontal \
460             -from 0 -to [expr int($m_tmEnd - $m_tmStart)] \
461             -tickinterval [expr int(0.49 * ($m_tmEnd - $m_tmStart))] \
462             -showvalue true \
463             -variable slider\$__name \
464             -length 200 \
465             -command \"\$service Send MOVE_SLIDER\" \n"
466     append cmd "pack \$winFrame.slider -side left -fill x -expand 1 \n"
467 
468 
469     $service Send CONTROL_UI $cmd
470 }
471 
472 ##############################################################################
473 #
474 # CReplayProxyApplication private UpdateControlUI { service arguments }
475 #
476 # Input:
477 # service - the service that called this function
478 # arguments - the ui commands that will be evaluated to update the ui
479 #
480 # Output:
481 # none
482 #
483 # Description:
484 #
485 ##############################################################################
486 CReplayProxyApplication private UpdateControlUI { service arguments } {
487     $self instvar m_szPlayPauseState
488     $self instvar m_iOffset
489 
490     set cmd ""
491 
492     # for unique variable names
493     append cmd "regsub -all -- {\\\.} \$winFrame {_} __name \n"
494 
495     append cmd "global playPause\$__name \n"
496     append cmd "set playPause\$__name $m_szPlayPauseState \n"
497 
498     append cmd "global slider\$__name \n"
499     append cmd "set slider\$__name [expr int($m_iOffset)] \n"
500 
501     $service Send UPDATE_CONTROL_UI $cmd
502 }
503 
504 
505 ##############################################################################
506 #
507 # CReplayProxyApplication private UpdateAllClients { }
508 #
509 # Input:
510 # none
511 #
512 # Output:
513 # none
514 #
515 # Description:
516 # this will update all the clients' ui.
517 #
518 ##############################################################################
519 CReplayProxyApplication private UpdateAllClients { } {
520     $self instvar m_lService
521 
522     foreach service $m_lService {
523         $self UpdateControlUI $service ""
524     }
525 }
526 
527 
528 ##############################################################################
529 #
530 # CReplayProxyApplication private UpdateOffset { }
531 #
532 # Input:
533 # none
534 #
535 # Output:
536 # none
537 #
538 # Description:
539 # update the offset
540 #
541 ##############################################################################
542 CReplayProxyApplication private UpdateOffset { } {
543     $self instvar m_timer
544     $self instvar m_iOffset
545     $self instvar m_szPlayPauseState
546 
547     if { $m_szPlayPauseState == "PAUSE" } {
548         incr m_iOffset 2
549         $self UpdateAllClients
550     }
551 
552     set m_timer [after 2000 "$self UpdateOffset"]
553 }
554 
555 
556 ##############################################################################
557 #
558 # CReplayProxyApplication private PlayPauseCmd { service arguments }
559 #
560 # Input:
561 # service - the service that called this function
562 # arguments - the ui commands that will be evaluated to update the ui
563 #
564 # Output:
565 # none
566 #
567 # Description:
568 # called by the client when the user presses the play/pause button
569 #
570 ##############################################################################
571 CReplayProxyApplication private PlayPauseCmd { service arguments } {
572     $self instvar m_ssacClient
573     $self instvar m_szPlayPauseState
574     $self instvar m_iOffset
575 
576     if { $m_szPlayPauseState == "PLAY" } {
577         $m_ssacClient play $m_iOffset
578     } else {
579         $m_ssacClient pause
580     }
581 
582 
583 }
584 
585 
586 ##############################################################################
587 #
588 # CReplayProxyApplication private MoveSliderCmd { service arguments } {
589 #
590 # Input:
591 # service - the service that called this function
592 # arguments - the new offset to move to
593 #
594 # Output:
595 # none
596 #
597 # Description:
598 # called by the client when the user moves the slider
599 #
600 ##############################################################################
601 CReplayProxyApplication private MoveSliderCmd { service arguments } {
602     $self instvar m_ssacClient
603     $self instvar m_szPlayPauseState
604     $self instvar m_iOffset
605 
606     # set the new offset
607     set m_iOffset [expr int($arguments)]
608 
609     # move position in the archive only if we're playing - ie. with pause
610     # showing.  This is cause once we move, we'll be in the play mode.
611     if { $m_szPlayPauseState == "PAUSE" } {
612         $m_ssacClient send PLAY [expr int($arguments)] 1
613     }
614 }
615 
616 
617 ##############################################################################
618 #
619 # CReplayProxyApplication public CloseService { service arguments } {
620 #
621 # Input:
622 # service - the service that called this function
623 # arguments - the arguments associated with this call
624 #
625 # Output:
626 # none
627 #
628 # Description:
629 # This is called by the remote service client closes the service link.
630 #
631 ##############################################################################
632 CReplayProxyApplication public CloseService { service arguments } {
633     exit
634 }
635 
636 # the string argument to UPDATE_INFO is put in the DC display
637 CReplayProxyApplication public GetInfo { service } {
638     $service Send UPDATE_INFO ""
639 }
640 
641 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.