Skip to content

Commit 0f4e71e

Browse files
committed
video_em: fills in contant tx style to help emulate skype; does not well match skype packet captures, but getting there
1 parent 62e0b7e commit 0f4e71e

File tree

1 file changed

+105
-29
lines changed

1 file changed

+105
-29
lines changed

l3_video_em.pl

Lines changed: 105 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,37 @@
157157
# 1080p60 1920x1080 373MBps, 6.2Mbps frame size
158158
"raw1080p" => [ 1920, 1080, 0, 128000, 2975872000, 2976000000, 60],
159159

160+
# Skype requirements below as listed on https://support.skype.com/en/faq/FA1417/how-much-bandwidth-does-skype-need
161+
# ^--- indicates there is a minimum TX requirement for stations
162+
# group calls range from 128k up to 512k up, roughly HQ-recommended, maybe 1280x720x15
163+
# https://www.quora.com/Does-Skype-support-1080p-HD-video-calls
164+
# https://tomtalks.blog/2018/04/set-skype-for-business-to-record-meetings-at-1080p-and-30-fps/
165+
# Transmission quality is fundamentally different than YouTube -- it is constant TX that varies by
166+
# the amount of compression available. Variation between minimum required bandwidth and recommended
167+
# bandwidth is visible in packet captures.
168+
# Actual capture resolutions depend on your camera and can be manipulated via settings, esp frame rate:
169+
# https://superuser.com/questions/180690/how-to-reduce-the-skype-video-settings-to-work-with-an-older-computer
170+
# https://lifehacker.com/how-to-get-better-quality-out-of-your-video-chats-5836186
171+
# https://docs.microsoft.com/en-us/skypeforbusiness/plan-your-deployment/clients-and-devices/video-resolutions
172+
# ^--- This outlines a requirements for 4 core processors as requirement for Skype at 720p!
173+
# Jed is roughly interpolating many of these values for this table
174+
# nicname w, h, interlaced, audio, vid bps, tt bps framerate
175+
"skype-vox-min" => [ 0, 0, 0, 30000, 0, 30000, 0 ],
176+
"skype-vox-rcmd" => [ 0, 0, 0, 100000, 0, 100000, 0 ],
177+
# screen sharing falls into min requirement
178+
"skype-vid-min" => [ 424, 240, 0, 30000, 98000, 128000, 15 ],
179+
"skype-vid-rcmd" => [ 640, 360, 0, 100000, 200000, 300000, 30 ],
180+
"skype-vid-hq-min" => [ 960, 540, 0, 100000, 300000, 400000, 15 ],
181+
"skype-vid-hq-rcmd" => [ 1280, 720, 0, 100000, 400000, 500000, 30 ],
182+
"skype-vid-hd-min" => [ 1920, 1080, 0, 100000, 1100000, 1200000, 15 ],
183+
"skype-vid-hd-rcmd" => [ 1920, 1080, 0, 100000, 1400000, 1500000, 30 ],
184+
"skype-vid-grp3-min" => [ 640, 480, 0, 30000, 482000, 512000, 15 ],
185+
"skype-vid-grp3-rcmd" => [ 1280, 720, 0, 100000, 900000, 2000000, 15 ],
186+
"skype-vid-grp5-min" => [ 640, 360, 0, 30000, 1700000, 2000000, 15 ],
187+
"skype-vid-grp5-rcmd" => [ 1280, 720, 0, 100000, 3700000, 4000000, 15 ],
188+
"skype-vid-grp7-min" => [ 640, 360, 0, 30000, 3700000, 4000000, 15 ],
189+
"skype-vid-grp7-rcmd" => [ 1280, 720, 0, 100000, 7700000, 8000000, 15 ],
190+
160191
);
161192

162193
our $avail_stream_desc = join(", ", keys(%avail_stream_res));
@@ -244,19 +275,19 @@
244275
my %sortedkeys = ();
245276
foreach my $oldkey (keys(%::avail_stream_res)) {
246277
my $ra_row = $::avail_stream_res{$oldkey};
247-
my $x = 10000000 + int(@$ra_row[$stream_keys{x}]);
248-
my $y = 10000000 + int(@$ra_row[$stream_keys{y}]);
249-
my $b = 10000000000 + int(@$ra_row[$stream_keys{video_bps}]);
278+
my $x = 10000000 + int(@$ra_row[$::stream_keys{x}]);
279+
my $y = 10000000 + int(@$ra_row[$::stream_keys{y}]);
280+
my $b = 10000000000 + int(@$ra_row[$::stream_keys{video_bps}]);
250281
my $newkey = "${b}_${x}_${y}_${oldkey}";
251282
$sortedkeys{$newkey} = $oldkey;
252283
}
253284
foreach my $sorted_key (sort(keys(%sortedkeys))) {
254285
my $key = $sortedkeys{$sorted_key};
255286
my $ra_row1 = $::avail_stream_res{$key};
256-
my $x = @$ra_row1[$stream_keys{x}];
257-
my $y = @$ra_row1[$stream_keys{y}];
258-
my $bps = int(@$ra_row1[$stream_keys{stream_bps}]);
259-
my $bps_sum = int(@$ra_row1[$stream_keys{video_bps}]) + int(@$ra_row1[$stream_keys{audio_bps}]);
287+
my $x = @$ra_row1[$::stream_keys{x}];
288+
my $y = @$ra_row1[$::stream_keys{y}];
289+
my $bps = int(@$ra_row1[$::stream_keys{stream_bps}]);
290+
my $bps_sum = int(@$ra_row1[$::stream_keys{video_bps}]) + int(@$ra_row1[$::stream_keys{audio_bps}]);
260291
#my $warning = "";
261292
printf("[ %15s ] %4s x %4s using %8s kbps", $key, $x, $y, ($bps/1000));
262293
if ($bps != $bps_sum) {
@@ -574,41 +605,92 @@ sub txbytes {
574605
$::begin_running = 0;
575606
}
576607

608+
609+
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
610+
# Layer-3 constant setup
611+
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
612+
613+
if ($::tx_style =~ /constant/) {
614+
if ($::stream_key !~ /^skype-/) {
615+
print "Using 'constant' tx-style only makes sense when emulating Skype calls. Please choose different stream.\n";
616+
exit 1;
617+
}
618+
if ($::stream_key =~ /grp\d+/) {
619+
print "group calls not implemented presently\n";
620+
exit 1;
621+
}
622+
else {
623+
print "Call upload requirements still under development.\n";
624+
}
625+
626+
# if someone sets stream resolution to "-min$", that's not a cap that Skype respects, skype will
627+
# search for more bandwidth...stream max will be /-rcmd$/, min will be /-min$/
628+
if ($::stream_key =~ /-min$/) {
629+
$::stream_key =~ s/-min/-rcmd/;
630+
}
631+
}
632+
die ("Please provide cx_name")
633+
unless((defined $::cx_name) && ("" ne $::cx_name));
634+
577635
my $stream_bps = 0;
578636
die("Unknown stream key $::stream_key")
579637
unless(exists $::avail_stream_res{$::stream_key});
580638

581-
$stream_bps = @{$::avail_stream_res{$stream_key}}[$stream_keys{stream_bps}];
639+
$stream_bps = @{$::avail_stream_res{$::stream_key}}[$::stream_keys{stream_bps}];
582640

583-
# estimated fill time is probably not going to be accurate because
584-
# there's no way to know the txrate between the AP and station.
585-
$::est_fill_time_sec = (8 * $::buf_size) / ($::max_tx * 0.5);
586-
my $drain_time_sec = (8 * $::buf_size) / $stream_bps;
587-
my $drain_wait_sec = $drain_time_sec - $est_fill_time_sec;
641+
my $drain_time_sec = 0;
642+
my $drain_wait_sec = 0;
643+
my $stream_kbps = 0;
588644

589-
if ($drain_wait_sec <= 0) {
590-
my $stream_kbps = $stream_bps / 1000;
591-
print "Warning: constant transmit! Raise max_tx to at least $stream_kbps Kbps\n";
592-
$drain_wait_sec = 0;
645+
if ($::tx_style =~ /constant/) {
646+
my $stream_min = $::stream_key;
647+
$stream_min =~ s/-rcmd/-min/;
648+
649+
$::min_tx = @{$::avail_stream_res{$stream_min}}[$::stream_keys{stream_bps}];
650+
$::max_tx = @{$::avail_stream_res{$::stream_key}}[$::stream_keys{stream_bps}];
651+
$stream_bps = $::max_tx;
652+
$stream_kbps = $stream_bps / 1000;
593653
}
654+
else {
655+
# estimated fill time is probably not going to be accurate because
656+
# there's no way to know the txrate between the AP and station.
657+
$::est_fill_time_sec = (8 * $::buf_size) / ($::max_tx * 0.5);
658+
my $drain_time_sec = (8 * $::buf_size) / $stream_bps;
659+
my $drain_wait_sec = $drain_time_sec - $est_fill_time_sec;
660+
661+
if ($drain_wait_sec <= 0) {
662+
my $stream_kbps = $stream_bps / 1000;
663+
print "Warning: constant transmit! Raise max_tx to at least $stream_kbps Kbps\n";
664+
$drain_wait_sec = 0;
665+
}
594666

595-
my $buf_kB = $::buf_size / 1024;
596-
print "Filling $::stream_key $buf_kB KB buffer est ${est_fill_time_sec}sec, empties in ${drain_time_sec} sec\n"
597-
unless($::silent);
667+
my $buf_kB = $::buf_size / 1024;
668+
print "Filling $::stream_key $buf_kB KB buffer est ${est_fill_time_sec}sec, empties in ${drain_time_sec} sec\n"
669+
unless($::silent);
670+
}
671+
$stream_kbps = $stream_bps / 1000;
598672

599-
die ("Please provide cx_name")
600-
unless((defined $::cx_name) && ("" ne $::cx_name));
601673
# check for cx if we're bufferfill
602674
my $cx_exists = 0;
603675
@lines = split("\r?\n", $::utils->doAsyncCmd($::utils->fmt_cmd("show_cx", "all", $::cx_name)));
604676
@matches = grep {/Could not find/} @lines;
605677
$cx_exists = 1 if (@matches == 0);
606678

607-
if ($::tx_style eq "bufferfill") {
679+
if (($::tx_style eq "bufferfill") && !$cx_exists) {
608680
print "Tx_style bufferfill requires your connection already exists, bye.\n";
609681
exit 1;
610682
}
611683

684+
if (($::tx_style =~ /constant/) && !$cx_exists) {
685+
my $cmd = "./lf_firemod.pl --mgr $::lfmgr_host --mgr_port $::lfmgr_port --action create_cx "
686+
."--cx_name $::cx_name --use_ports $::sta,$::upstream --use_speeds 128000,$::max_tx "
687+
."--speed $::min_tx --max_speed $::max_tx --endp_type udp --report_timer 3000";
688+
my $result = `$cmd`;
689+
print "x"x72, "\n";
690+
print $result, "\n";
691+
print "x"x72, "\n";
692+
}
693+
612694
print "Stopping and configuring $::cx_name\n" unless($silent);
613695
if (($::tx_style eq "L4") && ($::cx_name !~ /^CX_/)) {
614696
$::cx_name = "CX_$::cx_name";
@@ -684,12 +766,6 @@ sub txbytes {
684766
$::utils->doAsyncCmd($cmd);
685767
}
686768

687-
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
688-
# Layer-3 constant setup
689-
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
690-
691-
692-
693769
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
694770
# Layer-3 constant bufferfill
695771
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----

0 commit comments

Comments
 (0)