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

Open Mash Cross Reference
mash/tcl/psvp/temporal-selector.tcl

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

  1 # temporal-selector.tcl --
  2 #
  3 #       This file contains the TemporalSelector base class
  4 #
  5 # Copyright (c) 1998-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 # The TemporalSelector object responds to graph interface communication
 32 # received through its recv_graph_comm method and sends graph
 33 # interface communication through the send_graph_comm method.
 34 #
 35 
 36 # Object fields
 37 #
 38 # input_id_list_ : list of input ids. The same ids are expected to be used
 39 #                  by individual execution subgraphs
 40 # input_info_ : array of info on input_ids. For each input id $i,
 41 #       ($i,spec) : multicast spec for input data
 42 #       ($i,trigger) : 0/1 indicating if input is execution trigger
 43 #       ($i,selector) : selector object for this input
 44 # vagent_array_ : array associated by "addr,port" indexes that holds
 45 #                 the name of video agents used by this object.
 46 # subgraph_list_ : list of subgraph identifiers. These identifiers are
 47 #                  local only.
 48 # subgraph_info_ : array of info on subgraphs. For each subgraph $s and
 49 #                  each input id $i,
 50 #       ($s,comm_obj) : graph comm object for talking to this subgraph
 51 #       ($s,spec) : cntrl spec for this subgraph
 52 # id_ : id of this object to be used in graph communication
 53 # comm_obj_ : object for graph comm (from above, NOT to subgraphs)
 54 # callback_array_ : holds comm callbacks with index <sid>,<mid>
 55 
 56 import GraphComm
 57 import PsvpVideoAgent
 58 import TemporalSelectorInput
 59 
 60 Class TemporalSelector
 61 
 62 TemporalSelector instproc init {id control_spec} {
 63     $self next;
 64 
 65     $self instvar input_id_list_;
 66     $self instvar input_info_;
 67     $self instvar vagent_array_;
 68     $self instvar subgraph_list_;
 69     $self instvar subgraph_info_;
 70     $self instvar id_;
 71     $self instvar comm_obj_;
 72     $self instvar callback_array_;
 73     $self instvar next_subgraph_;
 74     $self instvar ctoken_subgraph_q_;
 75     $self instvar sid_;
 76     $self instvar ctoken_count_;
 77     $self instvar token_rate_period_;
 78     $self instvar rate_pressure_ rate_constant_;
 79 
 80 #    set rate_pressure_ 1.1;
 81      set rate_pressure_ 1.0
 82 #    set rate_constant_ [expr 1.0/1000.0];
 83     set rate_constant_ 0.0;
 84 
 85     set input_id_list_ "";
 86     set id_ $id;
 87 
 88     set comm_obj_ [new GraphComm/TemporalSelector $self $id_ $control_spec];
 89 
 90     set sid_ -1;
 91     set subgraph_list_ "";
 92     set next_subgraph_ "";
 93     set ctoken_subgraph_q_ "";
 94     set ctoken_count_ 0;
 95     set token_rate_period_ 1000;
 96 
 97     $self instvar trigger_count_;
 98     $self instvar fire_count_;
 99 
100     set trigger_count_ 0;
101     set fire_count_ 0;
102 }
103 
104 TemporalSelector instproc decr_ctoken_count {} {
105     $self instvar ctoken_count_;
106 
107     incr ctoken_count_ -1;
108 
109 }
110 
111 TemporalSelector instproc decr_trigger_count {} {
112     $self instvar trigger_count_;
113 
114     incr trigger_count_ -1;
115 }
116 
117 TemporalSelector instproc handle_trigger_count {} {
118     $self instvar trigger_count_;
119     $self instvar token_rate_period_;
120 
121     incr trigger_count_ 1;
122     after $token_rate_period_ "$self decr_trigger_count";
123 }
124 
125 TemporalSelector instproc decr_fire_count {} {
126     $self instvar fire_count_
127 
128     incr fire_count_ -1;
129 }
130 
131 TemporalSelector instproc handle_fire_count {} {
132     $self instvar fire_count_;
133     $self instvar token_rate_period_;
134 
135     incr fire_count_ 1;
136 
137     after $token_rate_period_ "$self decr_fire_count";
138 }
139 
140 TemporalSelector instproc SetupInput {new_input} {
141     $self instvar subgraph_list_;
142     $self instvar subgraph_info_;
143     $self instvar vagent_array_;
144 
145     $self instvar input_id_list_;
146     $self instvar input_info_;
147 
148     if {[lsearch $input_id_list_ $new_input] == -1} {
149         $self instvar comm_obj_;
150 
151         lappend input_id_list_ $new_input;
152         set input_info_($new_input,spec) "";
153         set input_info_($new_input,trigger) 0;
154         set input_info_($new_input,selector) "";
155 
156         $comm_obj_ create_input $new_input
157     }
158 }
159 
160 TemporalSelector instproc ReflectInputAttr {iname aname} {
161     $self instvar comm_obj_
162 
163     $comm_obj_ create_input_attr $iname $aname
164 }
165 
166 TemporalSelector instproc trigger {} {
167     $self instvar next_subgraph_;
168     $self instvar ctoken_subgraph_q_;
169     $self instvar subgraph_list_;
170     $self instvar subgraph_info_;
171     $self instvar input_id_list_;
172     $self instvar input_info_;
173     $self instvar fire_count_;
174 
175     $self handle_trigger_count;
176 
177     # This is a total hack to prevent overflowing the processors.
178 
179     $self instvar last_time_click_;
180     $self instvar update_status;
181     $self instvar ctoken_count_ token_rate_period_;
182     $self instvar rate_pressure_ rate_constant_;
183 
184     if {![info exists last_time_click_]} {
185         set last_time_click_ [clock clicks];
186     }
187 
188     set now [clock clicks];
189 
190     set target_rate [expr ($rate_pressure_ * \
191             (($ctoken_count_*1.0) / ($token_rate_period_*1.0)) + \
192             $rate_constant_)];
193 
194     if {$target_rate <= 0.0} {
195         set target_rate .001;
196     }
197 
198     set target_interval [expr  (0.5 / $target_rate) + (rand() * (0.5 / $target_rate))];
199 
200     set tdiff [expr ($now - $last_time_click_) / 1000.0];
201 
202     if {$tdiff < $target_interval} {
203         set update_status 0;
204     } elseif {$fire_count_ == $ctoken_count_} {
205         set update_status 1;
206         set last_time_click_ $now
207     } else {
208         set update_status 1;
209 #       set last_time_click_ [expr $last_time_click_ + int(($target_interval * 1000.0))];
210         set last_time_click_ $now
211     }
212 
213     set s "";
214     if {$update_status} {
215         if {[llength $ctoken_subgraph_q_] > 0} {
216             set s [lindex $ctoken_subgraph_q_ 0];
217             set ctoken_subgraph_q_ [lreplace $ctoken_subgraph_q_ 0 0];
218         } else {
219             set s [lindex $next_subgraph_ 0];
220             set next_subgraph_ [lreplace $next_subgraph_ 0 0];
221             lappend next_subgraph_ $s;
222         }
223 
224         # Build and send trigger vector
225         $self instvar tvector_;
226         set tvector_ "";
227         foreach i $input_id_list_ {
228             set selector $input_info_($i,selector);
229             if {$selector != ""} {
230                 set ts [$selector get_current_ts];
231                 lappend tvector_ [list $i $ts];
232             }
233         }
234 #puts "Trigger: $tvector_"
235         $subgraph_info_($s,comm_obj) send_trigger_vector $tvector_;
236         $self handle_fire_count;
237     }
238     foreach i $input_id_list_ {
239         set selector $input_info_($i,selector);
240         if {$selector != ""} {
241             $selector update_subgraph $s
242         }
243     }
244 }
245 
246 TemporalSelector instproc set_input_spec {in_id spec} {
247     $self instvar input_info_;
248     $self instvar vagent_array_;
249     $self instvar subgraph_list_;
250     $self instvar subgraph_info_;
251 
252     if {$input_info_($in_id,spec) == $spec} {
253         return;
254     }
255 
256     # If input already associated with a spec, delete selector no longer
257     # needed.
258 
259     if {$input_info_($in_id,spec) != ""} {
260         set selector $input_info_($in_id,selector);
261         if {$selector != ""} {
262             set vagent [$selector set vagent_];
263 
264             set src [[$selector get_decoder] set src_];
265             $src proc trigger_sr {args} {};
266 
267             $vagent delete_decoder [$selector get_decoder];
268             delete $selector;
269             set input_info_($id,selector) "";
270         }
271         set input_info_($in_id,spec) "";
272     }
273 
274     set spec_split [split $spec "/"];
275 
276     set addr [lindex $spec_split 0];
277     set port [lindex $spec_split 1];
278     set srcid [lindex $spec_split 2];
279 
280     if {![info exists vagent_array_($addr,$port)]} {
281         set vagent_array_($addr,$port) [new PsvpVideoAgent $addr/$port];
282     }
283     set vagent $vagent_array_($addr,$port);
284 
285     set src [$vagent get_source_by_id $srcid];
286 
287     if {$src == ""} {
288         $vagent set_create_decoder_callback $srcid "$self set_input_spec_cb $in_id $spec"
289     } else {
290         set fmt_name [$vagent classmap [$src format_name]];
291 
292         set selector [new TemporalSelectorInput/${fmt_name} $self $in_id]
293 
294         if {$selector == ""} {
295             set selector [new TemporalSelectorInput/Null $self $in_id];
296         }
297         if {$input_info_($in_id,trigger) != 0} {
298             $selector set_callback "$self trigger; # ";
299         }
300         foreach s $subgraph_list_ {
301             $selector add_subgraph $s;
302         }
303         $vagent set_src_decoder $src [$selector get_decoder];
304 
305         $selector set vagent_ $vagent;
306 
307         set input_info_($in_id,selector) $selector;
308 
309         # Major hack to get sender report triggers to work
310         $src proc trigger_sr {args} "catch {$selector trigger_sr $src}";
311 
312     }
313     set input_info_($in_id,spec) $spec;
314 }
315 
316 TemporalSelector instproc set_input_spec_cb {id spec src} {
317     $self instvar input_info_
318     $self instvar vagent_array_
319     $self instvar subgraph_info_
320     $self instvar subgraph_list_
321 
322     if {$input_info_($id,spec) != $spec} {
323         puts "$input_info_($id,spec) != $spec !!!";
324         return;
325     }
326 
327     if {$input_info_($id,selector) != ""} {
328         puts "$input_info_($id,selector) != {} !!!";
329         return;
330     }
331 
332     # Find videoagent and source
333 
334     set spec_split [split $spec "/"];
335 
336     set addr [lindex $spec_split 0];
337     set port [lindex $spec_split 1];
338     set srcid [lindex $spec_split 2];
339 
340     set vagent $vagent_array_($addr,$port);
341 
342     # Setup decoder.
343 
344     set fmt_name [$vagent classmap [$src format_name]];
345 
346     set selector [new TemporalSelectorInput/${fmt_name} $self $id];
347 
348     if {$selector == ""} {
349         # No such selector. Create a NULL decoder and associate that.
350         set selector [new TemporalSelectorInput/Null $self $id];
351     } else {
352         if {$input_info_($id,trigger) != 0} {
353             $selector set_callback "$self trigger; #";
354         }
355         foreach s $subgraph_list_ {
356             $selector add_subgraph $s;
357         }
358     }
359     # Update input info array
360 
361     $selector set vagent_ $vagent;
362 
363     set input_info_($id,selector) $selector;
364 
365     # Major hack to get sender report triggers to work
366     $src proc trigger_sr {args} "catch {$selector trigger_sr $src}";
367 
368     return [$selector get_decoder];
369 }
370 
371 TemporalSelector instproc set_subgraph_input_spec {sid in_id spec} {
372     $self instvar subgraph_info_;
373 
374     $subgraph_info_($sid,comm_obj) set_input_spec $in_id $spec;
375 }
376 
377 TemporalSelector instproc GenerateSpec {} {
378     # OK, this is a REAL hack
379 
380     global spec_generator;
381 
382     if {![info exists spec_generator(init)]} {
383         set gen_spec [split [$self get_option gen_spec] "."];
384 
385         set spec_generator(init) 1;
386         set spec_generator(b1) [lindex $gen_spec 0];
387         set spec_generator(b2) [lindex $gen_spec 1];
388         set spec_generator(b3) [lindex $gen_spec 2];
389         set spec_generator(b4) [lindex $gen_spec 3];
390         set spec_generator(port) [expr (int(rand() * 5000)*2) + 10000]
391     }
392 
393     incr spec_generator(b4);
394 
395     return "$spec_generator(b1).$spec_generator(b2).$spec_generator(b3).$spec_generator(b4)/$spec_generator(port)/16";
396 }
397 
398 Class GraphComm/TemporalSelector -superclass GraphComm
399 
400 GraphComm/TemporalSelector instproc init {tselect id spec} {
401     $self instvar tselect_;
402 
403     set tselect_ $tselect;
404 
405     set spec [split $spec "/"];
406 
407     set addr [lindex $spec 0];
408     set port [lindex $spec 1];
409     set ttl [lindex $spec 2];
410 
411     $self next $id $addr $port $ttl;
412 
413     $self instvar sess_map_ primary_sess_;
414 
415     set sess_map_($primary_sess_,inputs) 1;
416     set sess_map_($primary_sess_,outputs) 0;
417     set sess_map_($primary_sess_,parameters) 0;
418     set sess_map_($primary_sess_,misc) 1;
419     set sess_map_($primary_sess_,trigger_cmds) 1;
420     set sess_map_($primary_sess_,map_cmds) 1;
421 }
422 
423 GraphComm/TemporalSelector instproc recv_misc {data} {
424     $self next $data;
425 
426     $self instvar tselect_;
427 
428     set cmd [lindex $data 0];
429 
430     switch -exact -- $cmd {
431         add_subgraph {
432             puts "In add_subgraph"; #debug
433 
434             $tselect_ instvar subgraph_list_ subgraph_info_ id_ sid_;
435             $tselect_ instvar next_subgraph_;
436 
437             set new_subgraph [lindex $data 1];
438 
439             foreach sid $subgraph_list_ {
440                 if {$subgraph_info_($sid,spec) == $new_subgraph} {
441                     return;
442                 }
443             }
444 
445             incr sid_;
446             lappend subgraph_list_ $sid_;
447             lappend next_subgraph_ $sid_;
448 
449             puts "Creating subgraph comm"; # debug
450             $self instvar primary_sess_;
451 
452             set subgraph_info_($sid_,comm_obj) [new GraphComm/TSToSubgraph $tselect_ $id_ $new_subgraph];
453             $subgraph_info_($sid_,comm_obj) send_map_command [list map_parameters [$primary_sess_ set addr_] [$primary_sess_ set rport_] [$primary_sess_ set ttl_]];
454             $self send_map_command [list map_parameters [[$subgraph_info_($sid_,comm_obj) set primary_sess_] set addr_] [[$subgraph_info_($sid_,comm_obj) set primary_sess_] set rport_] [[$subgraph_info_($sid_,comm_obj) set primary_sess_] set ttl_]];
455 
456             $subgraph_info_($sid_,comm_obj) set sid_ $sid_;
457 
458             set subgraph_info_($sid_,spec) $new_subgraph;
459 
460             $tselect_ instvar input_id_list_ input_info_;
461 
462             foreach i $input_id_list_ {
463                 if {$input_info_($i,selector) != ""} {
464                     $input_info_($i,selector) add_subgraph $sid_;
465                 }
466             }
467         }
468         del_subgraph {
469             $tselect_ instvar subgraph_info_ subgraph_list_ next_subgraph_;
470 
471             set spec_to_del [lindex $data 1];
472             set sid_to_del "";
473             foreach s $subgraph_list_ {
474                 if {$subgraph_info_($s,spec) == $spec_to_del} {
475                     set sid_to_del $s;
476                     break;
477                 }
478             }
479             if {$sid_to_del == ""} {
480                 return;
481             }
482             set idx [lindex $subgraph_list_ $sid_to_del];
483             set subgraph_list_ [lreplace $subgraph_list_ $idx $idx];
484 
485             set idx [lindex $next_subgraph_ $sid_to_del];
486             if {$idx != -1} {
487                 set next_subgraph_ [lreplace $next_subgraph_ $idx $idx];
488             }
489 
490             $tselect_ instvar input_id_list_ input_info_;
491 
492             foreach i $input_id_list_ {
493                 set selector $input_info_($i,selector);
494                 if {$selector != ""} {
495                     $selector del_subgraph $sid_to_del;
496                 }
497             }
498             delete $subgraph_info_($sid_to_del,comm_obj);
499             unset subgraph_info_($sid_to_del,comm_obj);
500             unset subgraph_info_($sid_to_del,spec);
501 
502             if {$subgraph_list_ == ""} {
503                 # All the subgraphs are gone.
504                 # FIXME Need to handle this case.
505             }
506         }
507     }
508     return;
509 }
510 
511 GraphComm/TemporalSelector instproc recv_trigger_command {data} {
512     $self next $data;
513 
514     $self instvar tselect_;
515 
516     $tselect_ instvar subgraph_list_;
517 
518     if {$subgraph_list_ == ""} {
519         return;
520     }
521 
522     set cmd [lindex $data 0];
523 
524     switch -exact -- $cmd {
525         trigger {
526             $tselect_ trigger;
527         }
528     }
529     return;
530 }
531 
532 GraphComm/TemporalSelector instproc update_input_attr_value {input_name attr value} {
533     $self next $input_name $attr $value;
534 
535     $self instvar tselect_
536     $tselect_ instvar input_id_list_;
537 
538     if {[lsearch $input_id_list_ $input_name] == -1} {
539         return;
540     }
541 
542     switch -exact -- $attr {
543         spec {
544             $tselect_ set_input_spec $input_name $value;
545         }
546         trigger {
547             $tselect_ instvar input_info_;
548 
549             set type [lindex $value 0];
550             if {$type == "auto"} {
551                 set trigger_flag [lindex $value 1];
552                 if {$input_info_($input_name,trigger) != $trigger_flag} {
553                     set input_info_($input_name,trigger) $trigger_flag;
554 
555                     if {$input_info_($input_name,selector) != ""} {
556                         if {$input_info_($input_name,trigger) != 0} {
557                             $input_info_($input_name,selector) set_callback "$tselect_ trigger; # ";
558                         } else {
559                             $input_info_($input_name,selector) set_callback "";
560                         }
561                     }
562                 }
563             }
564 
565             set some_trigger 0;
566             foreach in_id $input_id_list_ {
567                 if {$input_info_($in_id,trigger) != 0} {
568                     set some_trigger 1;
569                     break;
570                 }
571             }
572             if {$some_trigger == 0} {
573                 $tselect_ instvar last_time_click_;
574                 if {[info exists last_time_click_]} {
575                     unset last_time_click_;
576                 }
577             }
578         }
579     }
580 }
581 
582 Class GraphComm/TSToSubgraph -superclass GraphComm;
583 
584 GraphComm/TSToSubgraph instproc init {tselect id spec} {
585     $self instvar tselect_;
586 
587     set tselect_ $tselect;
588 
589     set spec [split $spec "/"];
590 
591     set addr [lindex $spec 0];
592     set port [lindex $spec 1];
593     set ttl [lindex $spec 2];
594 
595     $self next $id $addr $port $ttl;
596 
597     $self instvar primary_sess_ sess_map_;
598 
599     set sess_map_($primary_sess_,outputs) 0;
600     set sess_map_($primary_sess_,parameters) 0;
601 }
602 
603 GraphComm/TSToSubgraph instproc new_input {new_input} {
604     $self next $new_input;
605 
606     $self instvar tselect_;
607 
608     $tselect_ SetupInput $new_input;
609 }
610 
611 GraphComm/TSToSubgraph instproc new_input_attribute {iname aname} {
612     $self next $iname $aname;
613 
614     $self instvar tselect_;
615 
616     $tselect_ ReflectInputAttr $iname $aname
617 }
618 
619 
620 GraphComm/TSToSubgraph instproc set_input_spec {id value} {
621     $self create_input $id;
622     $self create_input_attr $id spec;
623     $self set_input_attr $id spec $value;
624 }
625 
626 GraphComm/TSToSubgraph instproc send_trigger_vector {vec} {
627     $self send_trigger_command [list trigger_vector $vec];
628 }
629 
630 GraphComm/TSToSubgraph instproc recv_trigger_command {data} {
631     $self instvar sid_;
632 
633     set cmd [lindex $data 0];
634 
635     switch -exact -- $cmd {
636         trigger_completion_token {
637             $self instvar tselect_;
638             $tselect_ instvar next_subgraph_;
639             $tselect_ instvar ctoken_subgraph_q_;
640             $tselect_ instvar subgraph_list_;
641 
642             $tselect_ instvar ctoken_count_ token_rate_period_;
643 
644             incr ctoken_count_ 1;
645 #######
646 #puts "CTokenCount = $ctoken_count_";
647 #######
648             after $token_rate_period_ "$tselect_ decr_ctoken_count";
649 
650             if {[lsearch $subgraph_list_ $sid_] != -1} {
651                 lappend ctoken_subgraph_q_ $sid_;
652             }
653         }
654     }
655 }
656 
657 GraphComm/TSToSubgraph instproc recv_map_command {cmd} {
658     set type [lindex $cmd 0];
659     set addr [lindex $cmd 1];
660     set port [lindex $cmd 2];
661     set ttl [lindex $cmd 3];
662 
663     switch -exact -- $type {
664         map_parameter -
665         map_parameters {
666             $self instvar tselect_;
667             $tselect_ instvar comm_obj_;
668 
669             $comm_obj_ send_map_command $cmd;
670         }
671         default {
672             $self next $cmd;
673         }
674     }
675 }
676 

~ [ 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.