1 # sc-spatial-combiner.tcl --
2 #
3 # FIXME: This file needs a description here.
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 import GraphComm
32
33 Class ScSpatialCombiner
34
35 ScSpatialCombiner instproc init {id cntrl_spec} {
36 $self next;
37
38 $self instvar output_id_list_;
39 $self instvar output_info_;
40
41 $self instvar subgraph_list_;
42 $self instvar subgraph_info_;
43
44 $self instvar sid_;
45
46 $self instvar id_;
47 $self instvar comm_obj_;
48
49 $self instvar callback_array_;
50
51 set output_id_list_ "";
52
53 set id_ $id;
54
55 set cntrl_spec [split $cntrl_spec "/"];
56 set addr [lindex $cntrl_spec 0];
57 set port [lindex $cntrl_spec 1];
58 set ttl [lindex $cntrl_spec 2];
59
60 set comm_obj_ [new GraphComm/ScSpatialCombiner $self $id_ $addr $port $ttl];
61
62 set sid_ -1;
63 set subgraph_list_ "";
64
65 #### Testing only stuff below
66 $self instvar test_mode_;
67
68 set test_mode_ [$self get_option spatial_test_mode];
69 puts "Test mode is: $test_mode_"
70 #####
71
72 #### Testing counters for frame drops and hits
73 $self instvar hit_cntr_ miss_cntr_ cntr_reset_
74 set hit_cntr_ 0
75 set miss_cntr_ 0
76 set cntr_reset_ 1
77 ####
78
79 }
80
81 ScSpatialCombiner instproc add_subgraph {new_subgraph} {
82 $self instvar subgraph_info_ subgraph_list_ sid_;
83 $self instvar comm_obj_ id_
84
85 foreach sid $subgraph_list_ {
86 if {$subgraph_info_($sid,spec) == $new_subgraph} {
87 return;
88 }
89 }
90
91 incr sid_;
92
93 lappend subgraph_list_ $sid_;
94
95 set subgraph_info_($sid_,spec) $new_subgraph;
96 set subgraph_info_($sid_,comm_obj) [new GraphComm/ScCombToSubgraph $self $id_ $new_subgraph];
97
98
99 # Map trigger commands from above.
100
101 $subgraph_info_($sid_,comm_obj) send_map_command [list map_trigger_cmds [$comm_obj_ primary_addr] [$comm_obj_ primary_port] [$comm_obj_ primary_ttl]];
102
103 # Map inputs up. Send input info down.
104
105 $comm_obj_ send_map_command [list map_inputs [$subgraph_info_($sid_,comm_obj) primary_addr] [$subgraph_info_($sid_,comm_obj) primary_port] [$subgraph_info_($sid_,comm_obj) primary_ttl]];
106
107 $comm_obj_ update_new_subgraph $subgraph_info_($sid_,comm_obj);
108
109 # Map parameters up and down
110
111 $subgraph_info_($sid_,comm_obj) send_map_command [list map_parameters [$comm_obj_ primary_addr] [$comm_obj_ primary_port] [$comm_obj_ primary_ttl]];
112
113 $comm_obj_ send_map_command [list map_parameters [$subgraph_info_($sid_,comm_obj) primary_addr] [$subgraph_info_($sid_,comm_obj) primary_port] [$subgraph_info_($sid_,comm_obj) primary_ttl]];
114
115
116 # Recalculate any existing divisions
117 $self recalculate_division
118
119 }
120
121 ScSpatialCombiner instproc update_rate_trigger {oid period} {
122 $self instvar comm_obj_;
123 $self instvar rate_triggers_ rate_trigger_periods_;
124
125 $comm_obj_ instvar input_names_ input_info_;
126
127 if {[info exists rate_trigger_periods_($oid)]} {
128 if {$period < $rate_trigger_periods_($oid)} {
129 return;
130 }
131 }
132
133 foreach i $input_names_ {
134 if {[info exists input_info_($i,trigger,cur_value)]} {
135 if {[lindex $input_info_($i,trigger,cur_value) 0] == "auto"} {
136 if {[lindex $input_info_($i,trigger,cur_value) 1] == 1} {
137 if {$period > 0} {
138 puts "Limiting trigger on $i to [expr 90000.0/$period] fps"
139
140 if {[info exists rate_triggers_($oid)]} {
141 after cancel $rate_triggers_($oid);
142 }
143
144 $self instvar subgraph_list_ subgraph_info_;
145
146 foreach s $subgraph_list_ {
147 set cobj $subgraph_info_($s,comm_obj);
148 $cobj set_input_attr $i trigger [list rate_limited 1 0 $period];
149 }
150
151 # set rate_triggers_($oid) [after 1000 "$self incr_rate_trigger $oid"]
152 # set rate_trigger_periods_($oid) $period;
153 } else {
154 puts "Turning trigger limits off"
155 $self instvar subgraph_list_ subgraph_info_;
156
157 foreach s $subgraph_list_ {
158 set cobj $subgraph_info_($s,comm_obj);
159 $cobj set_input_attr $i trigger [list auto 1];
160 }
161
162 if {[info exists rate_trigger_periods_($oid)]} {
163 unset rate_trigger_periods_($oid);
164 }
165 }
166 }
167 }
168 }
169 }
170 }
171
172 ScSpatialCombiner instproc incr_rate_trigger {oid} {
173 $self instvar rate_triggers_ rate_trigger_periods_
174
175 if {![info exists rate_triggers_($oid)]} {
176 return;
177 }
178 unset rate_triggers_($oid);
179
180 set period [expr int($rate_trigger_periods_($oid) * 0.9)];
181
182 unset rate_trigger_periods_($oid);
183
184 $self update_rate_trigger $oid $period;
185 }
186
187 ScSpatialCombiner instproc send_completion_token {} {
188 $self instvar comm_obj_;
189
190 $comm_obj_ send_trigger_command "trigger_completion_token";
191 }
192
193 ScSpatialCombiner instproc incr_hit_cntr {} {
194 $self instvar hit_cntr_;
195 incr hit_cntr_;
196 }
197
198 ScSpatialCombiner instproc incr_miss_cntr {} {
199 $self instvar miss_cntr_;
200 incr miss_cntr_;
201
202 $self instvar subgraph_list_;
203
204 if {[expr $miss_cntr_ % [llength $subgraph_list_]] == 0} {
205 $self send_completion_token;
206 }
207 }
208
209 ScSpatialCombiner instproc update_hitbased_rate_trigger {} {
210 $self instvar hit_cntr_ miss_cntr_ cntr_reset_;
211 $self instvar last_cntr_update_
212 $self instvar subgraph_list_
213
214 if {$cntr_reset_} {
215 set last_cntr_update_ [clock clicks];
216 set hit_cntr_ 0;
217 set miss_cntr_ 0;
218 set cntr_reset_ 0;
219 } else {
220 set now [clock clicks];
221 set delta [expr $now - $last_cntr_update_];
222 set hit_rate [expr ($hit_cntr_ * 1000000.0) / $delta];
223 if {[llength $subgraph_list_] > 0} {
224 set miss_rate [expr ($miss_cntr_ * 1000000.0) / ([llength $subgraph_list_] * $delta)];
225 } else {
226 set miss_rate [expr ($miss_cntr_ * 1000000.0) / ($delta)];
227 }
228
229 puts "Hit rate = $hit_rate ($hit_cntr_ / $delta); Miss rate = $miss_rate ($miss_cntr_ / ([llength $subgraph_list_] * $delta)); Combined rate = [expr $hit_rate + $miss_rate]";
230
231 set hit_cntr_ 0;
232 set miss_cntr_ 0;
233 set last_cntr_update_ $now;
234
235 if {[expr $hit_rate + $miss_rate] > 0.0} {
236 set new_rate [expr int(90000.0 / (1.1 * ($hit_rate + $miss_rate)))];
237 } else {
238 set new_rate 0
239 }
240
241 $self instvar output_id_list_;
242 foreach o $output_id_list_ {
243 $self update_rate_trigger $o $new_rate;
244 }
245
246 }
247 after 1500 $self update_hitbased_rate_trigger
248 }
249
250 ScSpatialCombiner instproc del_subgraph {subgraph_to_del} {
251 $self instvar subgraph_list_ subgraph_info_;
252
253 set sid_to_del "";
254 foreach s $subgraph_list_ {
255 if {$subgraph_info_($s,spec) == $subgraph_to_del} {
256 set sid_to_del $s;
257 break;
258 }
259 }
260 if {$sid_to_del == ""} return;
261
262 delete $subgraph_info_($sid_to_del,comm_obj);
263 unset subgraph_info_($sid_to_del,comm_obj);
264 unset subgraph_info_($sid_to_del,spec);
265
266 set idx [lsearch $subgraph_list_ $sid_to_del];
267 set subgraph_list_ [lreplace $subgraph_list_ $idx $idx];
268
269 $self recalculate_division;
270 }
271
272 ScSpatialCombiner instproc recalculate_division {} {
273 $self instvar subgraph_list_;
274 $self instvar subgraph_info_;
275 $self instvar output_id_list_;
276
277 set num_subgraph [llength $subgraph_list_];
278
279 set x0 0.0
280 set x1 1.0
281
282 foreach s $subgraph_list_ {
283 set idx [lsearch $subgraph_list_ $s];
284 set comm_obj $subgraph_info_($s,comm_obj);
285
286 set y0 [expr ($idx * 1.0) / ($num_subgraph * 1.0)];
287 set y1 [expr ($idx * 1.0 + 1.0) / ($num_subgraph * 1.0)];
288
289 foreach o $output_id_list_ {
290 $comm_obj set_output_attr $o geometry [list $x0 $y0 $x1 $y1];
291 }
292 }
293 }
294
295 ScSpatialCombiner instproc new_output {subgraph_comm o} {
296
297 $self instvar output_id_list_ subgraph_list_
298 $self instvar subgraph_info_ output_info_
299
300 if {[lsearch $output_id_list_ $o] == -1} {
301 lappend output_id_list_ $o;
302
303 # Brand new output discovered.
304
305 set spec [$self GenerateSpec];
306 set spec_split [split $spec "/"];
307 set addr [lindex $spec_split 0];
308 set port [lindex $spec_split 1];
309
310 set output_info_($o,combiner_obj) [new Module/Combine/Spatial/SC];
311 set vagent_array_($addr,$port) [new ScSpatialCombinerVideoAgent $addr/$port $output_info_($o,combiner_obj)];
312 set output_info_($o,vagent) $vagent_array_($addr,$port);
313 set output_info_($o,in_spec) $addr/$port;
314 set output_info_($o,out_vagent) "";
315
316 set output_info_($o,sc_decoder) [new Module/VideoDecoder/SCToSemicompressed];
317 set output_info_($o,sc_buffer) [new VidRep/Semicompressed];
318 $output_info_($o,sc_decoder) set_frame_buffer $output_info_($o,sc_buffer);
319
320 set output_info_($o,encoder) [new Module/VideoEncoder/SemicompressedToJPEG];
321 set output_info_($o,bufferpool) [new BufferPool/RTP];
322 $output_info_($o,encoder) buffer-pool $output_info_($o,bufferpool);
323 $output_info_($o,encoder) mtu [$self get_option mtu];
324 $output_info_($o,sc_decoder) set_callback "$self incr_hit_cntr; $output_info_($o,encoder) recv $output_info_($o,sc_buffer); $self send_completion_token"
325
326 $output_info_($o,combiner_obj) target $output_info_($o,sc_decoder);
327
328 # Reflect new output in our control session
329
330 $self instvar comm_obj_;
331
332 $comm_obj_ create_output $o;
333
334 ##### Testing only
335 $output_info_($o,combiner_obj) off_synch_cmd "$self incr_miss_cntr";
336 $self instvar test_mode_
337 if {[lindex $test_mode_ 0] == "rate"} {
338 # Set up rate limiting trigger
339 $self update_hitbased_rate_trigger;
340 }
341 }
342
343 $subgraph_comm create_output $o;
344 $subgraph_comm create_output_attr $o spec;
345 $subgraph_comm create_output_attr $o geometry;
346 $subgraph_comm set_output_attr $o spec $output_info_($o,in_spec);
347
348 foreach s $subgraph_list_ {
349 if {$subgraph_info_($s,comm_obj) == $subgraph_comm} {
350 break;
351 }
352 }
353 set idx [lindex $subgraph_list_ $s];
354 set num_subgraph [llength $subgraph_list_];
355
356 set x0 0.0;
357 set x1 1.0;
358 set y0 [expr ($idx * 1.0) / ($num_subgraph * 1.0)];
359 set y1 [expr ($idx * 1.0 + 1.0) / ($num_subgraph * 1.0)];
360
361 $subgraph_comm set_output_attr $o geometry [list $x0 $y0 $x1 $y1];
362 }
363
364 ScSpatialCombiner instproc set_output_spec {out_id spec} {
365 $self instvar output_id_list_ output_info_
366
367 if {[lsearch $output_id_list_ $out_id] == -1} {
368 return;
369 }
370
371 set combiner_obj $output_info_($out_id,combiner_obj);
372
373 set spec_split [split $spec "/"];
374
375 set addr [lindex $spec_split 0];
376 set port [lindex $spec_split 1];
377
378 set output_info_($out_id,out_vagent) [new VideoAgent $self $addr/$port];
379 $output_info_($out_id,out_vagent) local_bandwidth 30000000;
380
381 $combiner_obj ssrc [$output_info_($out_id,out_vagent) get_local_srcid];
382 $output_info_($out_id,bufferpool) srcid [$output_info_($out_id,out_vagent) get_local_srcid];
383 [$output_info_($out_id,out_vagent) get_transmitter] set loopback_ 0
384 $output_info_($out_id,encoder) target [$output_info_($out_id,out_vagent) get_transmitter];
385
386 ##### Testing only
387 $self instvar test_mode_
388 if {[lindex $test_mode_ 1] != "xcode"} {
389 $combiner_obj target [$output_info_($out_id,out_vagent) get_transmitter];
390 }
391 }
392
393 ScSpatialCombiner instproc GenerateSpec {} {
394 # OK, this is a REAL hack
395
396 global spec_generator;
397
398 if {![info exists spec_generator(init)]} {
399 set spec_generator(init) 1;
400 set spec_generator(b1) 224;
401 set spec_generator(b2) 5;
402 set spec_generator(b3) 9;
403 set spec_generator(b4) 1;
404 set spec_generator(port) 22334;
405 }
406
407 incr spec_generator(b4);
408
409 return "$spec_generator(b1).$spec_generator(b2).$spec_generator(b3).$spec_generator(b4)/$spec_generator(port)/16";
410 }
411
412
413 Class GraphComm/ScSpatialCombiner -superclass GraphComm
414
415 GraphComm/ScSpatialCombiner instproc init {sc_combiner id addr port ttl} {
416 $self next $id $addr $port $ttl;
417
418 $self instvar sc_combiner_;
419
420 set sc_combiner_ $sc_combiner;
421 }
422
423
424 GraphComm/ScSpatialCombiner instproc recv_misc {data} {
425 $self next $data;
426
427 $self instvar sc_combiner_;
428
429 set cmd [lindex $data 0];
430
431 switch -exact -- $cmd {
432 add_subgraph {
433 $sc_combiner_ add_subgraph [lindex $data 1];
434 }
435 del_subgraph {
436 $sc_combiner_ del_subgraph [lindex $data 1];
437 }
438 }
439 }
440
441 GraphComm/ScSpatialCombiner instproc update_output_attr_value {output_name attr_name value} {
442 $self next $output_name $attr_name $value;
443
444 if {$attr_name == "spec"} {
445 $self instvar sc_combiner_;
446
447 $sc_combiner_ set_output_spec $output_name $value;
448 }
449 }
450
451 GraphComm/ScSpatialCombiner instproc update_new_subgraph {subgraph_comm} {
452 $self instvar input_info_ input_names_
453
454 foreach i $input_names_ {
455 $subgraph_comm create_input $i;
456 foreach a $input_info_($i,attr_list) {
457 $subgraph_comm create_input_attr $i $a
458 if {[info exists input_info_($i,$a,cur_value)]} {
459 $subgraph_comm set_input_attr $i $a $input_info_($i,$a,cur_value);
460 }
461 }
462 }
463 $self instvar map_cmd_list_;
464 if {[info exists map_cmd_list_]} {
465 foreach cmd $map_cmd_list_ {
466 $subgraph_comm send_map_command $cmd;
467 }
468 }
469 }
470
471
472 GraphComm/ScSpatialCombiner instproc new_input {new_name} {
473 $self instvar sc_combiner_
474
475 $self next $new_name;
476
477 $sc_combiner_ instvar subgraph_list_ subgraph_info_
478
479 foreach s $subgraph_list_ {
480 set comm_obj $subgraph_info_($s,comm_obj)
481 $comm_obj create_input $new_name;
482 }
483 }
484
485 GraphComm/ScSpatialCombiner instproc new_input_attribute {input_name attr_name} {
486 $self instvar sc_combiner_
487
488 $self next $input_name $attr_name
489
490 $sc_combiner_ instvar subgraph_list_ subgraph_info_
491
492 foreach s $subgraph_list_ {
493 set comm_obj $subgraph_info_($s,comm_obj)
494 $comm_obj create_input_attr $input_name $attr_name;
495 }
496 }
497
498 GraphComm/ScSpatialCombiner instproc update_input_attr_value {input_name attr_name value} {
499 $self instvar sc_combiner_
500
501 $self next $input_name $attr_name $value
502
503 $sc_combiner_ instvar subgraph_list_ subgraph_info_
504
505 foreach s $subgraph_list_ {
506 set comm_obj $subgraph_info_($s,comm_obj)
507 $comm_obj set_input_attr $input_name $attr_name $value
508 }
509 }
510
511 GraphComm/ScSpatialCombiner instproc recv_map_command {cmd} {
512 $self instvar sc_combiner_ map_cmd_list_
513
514 set type [lindex $cmd 0];
515 set addr [lindex $cmd 1];
516 set port [lindex $cmd 2];
517 set ttl [lindex $cmd 3];
518
519 switch -exact -- $type {
520 map_trigger -
521 map_triggers -
522 map_parameter -
523 map_parameters {
524 if {[info exists sc_combiner_]} {
525 $sc_combiner_ instvar subgraph_list_ subgraph_info_
526
527 foreach s $subgraph_list_ {
528 set comm_obj $subgraph_info_($s,comm_obj)
529 $comm_obj send_map_command $cmd;
530 }
531 }
532 lappend map_cmd_list_ $cmd;
533 }
534 default {
535 $self next $cmd;
536 }
537 }
538 }
539
540
541
542 Class GraphComm/ScCombToSubgraph -superclass GraphComm
543
544 GraphComm/ScCombToSubgraph instproc init {sc_combiner id spec} {
545 set spec [split $spec "/"];
546 set addr [lindex $spec 0];
547 set port [lindex $spec 1];
548 set ttl [lindex $spec 2];
549
550 $self next $id $addr $port $ttl;
551
552 $self instvar sc_combiner_;
553
554 set sc_combiner_ $sc_combiner;
555 }
556
557 GraphComm/ScCombToSubgraph instproc new_output {new_name} {
558 $self next $new_name;
559
560 $self instvar sc_combiner_;
561
562 $sc_combiner_ new_output $self $new_name;
563 }
564
565
566 import VideoAgent
567
568 Class ScSpatialCombinerVideoAgent -superclass VideoAgent
569
570 ScSpatialCombinerVideoAgent instproc init {spec combiner} {
571 eval $self next $self $spec;
572
573 $self instvar combiner_;
574
575 set combiner_ $combiner;
576 }
577
578 ScSpatialCombinerVideoAgent instproc create_decoder src {
579 $self instvar combiner_;
580
581 set d [$src handler];
582 if {$d != ""} {
583 delete $d;
584 }
585
586 return $combiner_;
587 }
588
589 ScSpatialCombinerVideoAgent instproc deactivate src {
590 puts "$src has been deactivated!!!!";
591 }
592
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.