1 # temporal-interleaver.tcl --
2 #
3 # This file contains the TemporalInterleavor 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 TemporalInterleavor object responds to graph interface communication
32 # recieved through its recv_graph_comm method and sends graph
33 # interface communication throught the send_graph_comm method.
34
35 # Object fields
36 #
37 # output_id_list_ : list of output ids. The same ids are expected to be
38 # used by individual execution subgraphs
39 # output_info_ : array of info on output_ids. For each output id $o,
40 # ($o,spec) : multicast spec for where interleaved output data should
41 # go.
42 # ($o,inter_obj) : interleaver object for incoming streams for this
43 # output id
44 # ($o,vagent) : video agent for incoming streams for this output id
45 # ($o,in_spec) : spec for incoming streams for this output id
46 # ($o,out_vagent) : video agent for outgoing stream for this output id
47 # vagent_array_ : array associated by "addr,port" indexes that holds the
48 # name of video agents used by this object.
49 # subgraph_list_ : list of subgraph identifiers. These identifiers are local
50 # only
51 # subgraph_info_ : array of info on subgraphs. For each subgraph $s,
52 # ($s,comm_obj) : graph comm object for talking to this subgraph
53 # ($s,spec) : spec of subgraph
54 # id_ : id of this object to be used in graph communication
55 # comm_obj_ : object for graph comm (from above, NOT to subgraphs)
56 # callback_array_ : holds comm callbacks with index <comm_obj>,<mid>
57
58 import PsvpVideoAgent
59 import GraphComm
60
61 Class TemporalInterleaver
62
63 TemporalInterleaver instproc init {id control_spec} {
64 $self next;
65
66 $self instvar output_id_list_;
67 $self instvar output_info_;
68 $self instvar vagent_array_;
69 $self instvar subgraph_list_;
70 $self instvar subgraph_info_;
71 $self instvar id_;
72 $self instvar comm_obj_;
73 $self instvar callback_array_;
74 $self instvar sid_;
75
76 set output_id_list_ "";
77
78 set id_ $id;
79
80 set control_spec [split $control_spec "/"];
81 set addr [lindex $control_spec 0];
82 set port [lindex $control_spec 1];
83 set ttl [lindex $control_spec 2];
84
85 set comm_obj_ [new GraphComm/TemporalInterleaver $self $id_ $addr $port $ttl];
86 $comm_obj_ create_parameter "latency";
87 $comm_obj_ create_parameter_attr "latency" type
88 $comm_obj_ create_parameter_attr "latency" domain
89 $comm_obj_ create_parameter_attr "latency" value
90
91 $comm_obj_ set_parameter_attr "latency" type real
92 $comm_obj_ set_parameter_attr "latency" domain "(0.0,1.0)"
93 $comm_obj_ set_parameter_attr "latency" value 1.0
94
95 set sid_ -1;
96 set subgraph_list_ "";
97
98 $self instvar latency_control_;
99
100 set latency_control_ 1.0;
101 }
102
103 TemporalInterleaver instproc del_subgraph sid {
104 $self instvar subgraph_info_ subgraph_list_;
105
106 delete $subgraph_info_($sid,comm_obj);
107
108 unset subgraph_info_($sid,comm_obj);
109 unset subgraph_info_($sid,spec);
110
111 set idx [lsearch $subgraph_list_ $sid];
112 set subgraph_list_ [lreplace $subgraph_list_ $idx $idx];
113
114 if {$subgraph_list_ == ""} {
115 # All the subgraphs are gone.
116 # FIXME Need to handle this case.
117 }
118 }
119
120 TemporalInterleaver instproc add_subgraph spec {
121 $self instvar sid_ subgraph_list_ subgraph_info_;
122 $self instvar output_info_ output_id_list_ id_;
123
124 foreach s $subgraph_list_ {
125 if {$subgraph_info_($s,spec) == $spec} {
126 return;
127 }
128 }
129
130 incr sid_
131
132 lappend subgraph_list_ $sid_;
133
134 set subgraph_info_($sid_,comm_obj) [new GraphComm/TIToSubgraph $self $id_ $spec];
135
136 set subgraph_info_($sid_,spec) $spec;
137
138 foreach o $output_id_list_ {
139 $subgraph_info_($sid_,comm_obj) set_output_spec $o $output_info_($o,in_spec);
140 }
141 }
142
143 TemporalInterleaver instproc setup_output {oid} {
144 $self instvar subgraph_list_;
145 $self instvar subgraph_info_;
146 $self instvar vagent_array_;
147
148 $self instvar output_id_list_;
149 $self instvar output_info_ comm_obj_
150
151 if {[lsearch $output_id_list_ $oid] != -1} {
152 return;
153 }
154
155 lappend output_id_list_ $oid;
156
157 $comm_obj_ create_output $oid;
158
159 set output_info_($oid,spec) "";
160
161 set spec [$self GenerateSpec];
162 set spec_split [split $spec "/"];
163 set addr [lindex $spec_split 0];
164 set port [lindex $spec_split 1];
165
166 set output_info_($oid,inter_obj) [new Module/Combine/Temporal];
167
168 $self instvar latency_control_;
169 $output_info_($oid,inter_obj) large_factor $latency_control_;
170 $output_info_($oid,inter_obj) small_factor [expr 1.0 - $latency_control_];
171
172 set vagent_array_($addr,$port) [new TemporalInterleaverVideoAgent $addr/$port $output_info_($oid,inter_obj)];
173
174 # Major hack to handle trigger_sr
175
176 $vagent_array_($addr,$port) proc trigger_sr {src} "$self trigger_sr \$src $oid; \$self next \$src";
177
178 set output_info_($oid,vagent) $vagent_array_($addr,$port);
179 set output_info_($oid,in_spec) $addr/$port
180 set output_info_($oid,out_vagent) "";
181
182 foreach s $subgraph_list_ {
183 # Create transmitting video agents in each subgraph and
184 # set spec accordingly
185
186 $subgraph_info_($s,comm_obj) set_output_spec $oid $output_info_($oid,in_spec);
187 }
188 }
189
190 TemporalInterleaver instproc trigger_sr {src oid} {
191 $self instvar output_info_;
192
193 if {[info exists output_info_($oid,out_vagent)]} {
194 set in_layer [lindex [$src set layers_] 0];
195 set out_layer [lindex [[$output_info_($oid,out_vagent) set local_] set layers_] 0];
196
197 $out_layer set ref_mts_ [$in_layer set mts_];
198 $out_layer set ref_ntp_sec_ [$in_layer set ntp_ts_sec_];
199 $out_layer set ref_ntp_fsec_ [$in_layer set ntp_ts_fsec_];
200 }
201 }
202
203
204 TemporalInterleaver instproc set_output_spec {out_id spec} {
205 $self instvar output_info_;
206
207 if {$output_info_($out_id,spec) == $spec} {
208 return;
209 }
210
211 set inter_obj $output_info_($out_id,inter_obj);
212
213 set spec_split [split $spec "/"];
214
215 set addr [lindex $spec_split 0];
216 set port [lindex $spec_split 1];
217
218 set output_info_($out_id,out_vagent) [new PsvpVideoAgent $addr/$port];
219 [$output_info_($out_id,out_vagent) get_transmitter] set loopback_ 0;
220
221 $inter_obj ssrc [$output_info_($out_id,out_vagent) get_local_srcid];
222
223 global kpatel_debug;
224
225 if {[info exists kpatel_debug]} {
226 set logger [new Module/RTPPktLogger];
227 $logger target [$output_info_($out_id,out_vagent) get_transmitter];
228 $inter_obj target $logger;
229 } else {
230 $inter_obj target [$output_info_($out_id,out_vagent) get_transmitter];
231 }
232
233 # Total hack FIXMEXX
234 $output_info_($out_id,out_vagent) local_bandwidth 30000000
235
236 set output_info_($out_id,spec) $spec;
237 }
238
239
240 Class GraphComm/TemporalInterleaver -superclass GraphComm
241
242 GraphComm/TemporalInterleaver instproc init {inter id addr port ttl} {
243 $self next $id $addr $port $ttl;
244
245 $self instvar inter_;
246
247 set inter_ $inter;
248 }
249
250 GraphComm/TemporalInterleaver instproc update_parameter_attr_value {pname attr value} {
251 $self next $pname $attr $value;
252
253 if {$pname == "latency"} {
254 if {$attr == "value"} {
255 $self instvar inter_;
256 $inter_ instvar latency_control_;
257
258 if {$value > 1.0} {
259 $self set_parameter_attr $pname $attr 1.0;
260 set latency_control_ 1.0;
261 } elseif {$value < 0.0} {
262 $self set_parameter_attr $pname $attr 0.0;
263 set latency_control_ 0.0;
264 } else {
265 set latency_control_ $value;
266 }
267
268 $inter_ large_factor $latency_control_;
269 $inter_ small_factor [expr 1.0 - $latency_control_];
270 }
271 }
272 }
273
274
275 GraphComm/TemporalInterleaver instproc update_output_attr_value {output_name attr_name value} {
276 $self next $output_name $attr_name $value;
277
278 $self instvar inter_;
279 $inter_ instvar output_info_ output_id_list_ subgraph_list_;
280
281 if {[lsearch $output_id_list_ $output_name] == -1} {
282 return;
283 }
284
285 if {$subgraph_list_ == ""} {
286 return;
287 }
288
289 switch -exact -- $attr_name {
290 spec {
291 $inter_ set_output_spec $output_name $value
292 }
293 format {
294 foreach s $subgraph_list_ {
295 $subgraph_info_($s,comm_obj) set_output_format $output_name $value;
296 }
297 }
298 geometry {
299 foreach s $subgraph_list_ {
300 $subgraph_info_($s,comm_obj) set_output_geometry $output_name $value
301 }
302 }
303 }
304 }
305
306 GraphComm/TemporalInterleaver instproc recv_misc {data} {
307 $self next $data;
308
309 $self instvar inter_;
310
311 set cmd [lindex $data 0];
312
313 switch -exact -- $cmd {
314 add_subgraph {
315 $inter_ instvar subgraph_info_;
316 $inter_ instvar callback_array_;
317 $inter_ instvar subgraph_list_;
318
319 set new_subgraph [lindex $data 1];
320
321 foreach sid $subgraph_list_ {
322 if {$subgraph_info_($sid,spec) == $new_subgraph} {
323 return;
324 }
325 }
326
327 $inter_ add_subgraph $new_subgraph;
328 }
329 del_subgraph {
330 $inter_ instvar subgraph_list_ subgraph_info_;
331
332 set subgraph_to_del [lindex $data 1];
333
334 set sid_to_del "";
335 foreach s $subgraph_list_ {
336 if {$subgraph_info_($s,spec) == $subgraph_to_del} {
337 set sid_to_del $s;
338 break;
339 }
340 }
341
342 if {$sid_to_del == ""} {
343 return;
344 }
345 $inter_ del_subgraph $sid_to_del;
346 }
347 }
348 }
349
350
351 Class TemporalInterleaverVideoAgent -superclass VideoAgent
352
353 TemporalInterleaverVideoAgent instproc init {spec combiner} {
354 eval $self next $self $spec;
355
356 $self instvar combiner_;
357
358 set combiner_ $combiner;
359 }
360
361 TemporalInterleaverVideoAgent instproc create_decoder src {
362 $self instvar combiner_;
363
364 set d [$src handler];
365 if {$d != ""} {
366 delete $d;
367 }
368
369 return $combiner_;
370 }
371
372 TemporalInterleaverVideoAgent instproc deactivate src {
373 puts "$src has been deactivated!!!!";
374 }
375
376
377 TemporalInterleaver 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
399 # Some routines to help with ui in tinter.tcl
400
401 TemporalInterleaver instproc large_factor {value} {
402
403 eval $self instvar [$self info vars];
404
405 foreach o $output_id_list_ {
406 set inter_obj $output_info_($o,inter_obj);
407 if {$inter_obj != ""} {
408 $inter_obj large_factor $value;
409 }
410 }
411 }
412
413 TemporalInterleaver instproc small_factor {value} {
414
415 eval $self instvar [$self info vars];
416
417 foreach o $output_id_list_ {
418 set inter_obj $output_info_($o,inter_obj);
419 if {$inter_obj != ""} {
420 $inter_obj small_factor $value;
421 }
422 }
423 }
424
425 TemporalInterleaver instproc expected_tolerance_factor {value} {
426
427 eval $self instvar [$self info vars];
428
429 foreach o $output_id_list_ {
430 set inter_obj $output_info_($o,inter_obj);
431 if {$inter_obj != ""} {
432 $inter_obj expected_tolerance_factor $value;
433 }
434 }
435 }
436
437 TemporalInterleaver instproc catch_up_factor {value} {
438
439 eval $self instvar [$self info vars];
440
441 foreach o $output_id_list_ {
442 set inter_obj $output_info_($o,inter_obj);
443 if {$inter_obj != ""} {
444 $inter_obj catch_up_factor $value;
445 }
446 }
447 }
448
449 TemporalInterleaver instproc get_marked {} {
450 eval $self instvar [$self info vars];
451 set res "";
452
453 foreach o $output_id_list_ {
454 set inter_obj $output_info_($o,inter_obj);
455 if {$inter_obj != ""} {
456 lappend res [$inter_obj set marked_];
457 }
458 }
459 return $res;
460 }
461
462 TemporalInterleaver instproc get_unmarked {} {
463 eval $self instvar [$self info vars];
464 set res "";
465
466 foreach o $output_id_list_ {
467 set inter_obj $output_info_($o,inter_obj);
468 if {$inter_obj != ""} {
469 lappend res [$inter_obj set unmarked_];
470 }
471 }
472 return $res;
473 }
474
475 TemporalInterleaver instproc get_late {} {
476 eval $self instvar [$self info vars];
477 set res "";
478
479 foreach o $output_id_list_ {
480 set inter_obj $output_info_($o,inter_obj);
481 if {$inter_obj != ""} {
482 lappend res [$inter_obj set late_];
483 }
484 }
485 return $res;
486 }
487
488 TemporalInterleaver instproc get_early_expected {} {
489 eval $self instvar [$self info vars];
490 set res "";
491
492 foreach o $output_id_list_ {
493 set inter_obj $output_info_($o,inter_obj);
494 if {$inter_obj != ""} {
495 lappend res [$inter_obj set early_expected_];
496 }
497 }
498 return $res;
499 }
500
501 TemporalInterleaver instproc get_early_queued {} {
502 eval $self instvar [$self info vars];
503 set res "";
504
505 foreach o $output_id_list_ {
506 set inter_obj $output_info_($o,inter_obj);
507 if {$inter_obj != ""} {
508 lappend res [$inter_obj set early_queued_];
509 }
510 }
511 return $res;
512 }
513
514 TemporalInterleaver instproc get_late_valid {} {
515 eval $self instvar [$self info vars];
516 set res "";
517
518 foreach o $output_id_list_ {
519 set inter_obj $output_info_($o,inter_obj);
520 if {$inter_obj != ""} {
521 lappend res [$inter_obj set late_valid_];
522 }
523 }
524 return $res;
525 }
526
527 TemporalInterleaver instproc get_q_length {} {
528 eval $self instvar [$self info vars];
529 set res "";
530
531 foreach o $output_id_list_ {
532 set inter_obj $output_info_($o,inter_obj);
533 if {$inter_obj != ""} {
534 lappend res [$inter_obj set q_length_];
535 }
536 }
537 return $res;
538 }
539
540
541 TemporalInterleaver instproc reset_stats {} {
542 $self instvar output_id_list_ output_info_
543
544 foreach o $output_id_list_ {
545 set inter_obj $output_info_($o,inter_obj);
546 if {$inter_obj != ""} {
547 $inter_obj reset_stats
548 }
549 }
550 }
551
552 Class GraphComm/TIToSubgraph -superclass GraphComm;
553
554 GraphComm/TIToSubgraph instproc init {tinter id spec} {
555 set spec [split $spec "/"];
556
557 set addr [lindex $spec 0];
558 set port [lindex $spec 1];
559 set ttl [lindex $spec 2];
560
561 $self next $id $addr $port $ttl;
562
563 $self instvar tinter_;
564
565 set tinter_ $tinter;
566 }
567
568 GraphComm/TIToSubgraph instproc set_output_spec {id spec} {
569 $self create_output $id
570 $self create_output_attr $id spec
571 $self set_output_attr $id spec $spec;
572 }
573
574 GraphComm/TIToSubgraph instproc set_output_geometry {out_id geometry} {
575 $self create_output $out_id;
576 $self create_output_attr $out_id geometry;
577 $self set_output_attr $out_id geometry $geometry;
578 }
579
580 GraphComm/TIToSubgraph instproc set_output_format {id format} {
581 $self create_output $out_id;
582 $self create_output_attr $out_id format;
583 $self set_output_attr $out_id format $format;
584 }
585
586 GraphComm/TIToSubgraph instproc new_output {output_name} {
587 $self next $output_name;
588
589 $self instvar tinter_;
590 $tinter_ setup_output $output_name;
591 }
592
593
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.