mirror of
https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
synced 2025-10-28 17:32:35 +00:00
video_em: fills in contant tx style to help emulate skype; does not well match skype packet captures, but getting there
This commit is contained in:
134
l3_video_em.pl
134
l3_video_em.pl
@@ -157,6 +157,37 @@ our %avail_stream_res = (
|
||||
# 1080p60 1920x1080 373MBps, 6.2Mbps frame size
|
||||
"raw1080p" => [ 1920, 1080, 0, 128000, 2975872000, 2976000000, 60],
|
||||
|
||||
# Skype requirements below as listed on https://support.skype.com/en/faq/FA1417/how-much-bandwidth-does-skype-need
|
||||
# ^--- indicates there is a minimum TX requirement for stations
|
||||
# group calls range from 128k up to 512k up, roughly HQ-recommended, maybe 1280x720x15
|
||||
# https://www.quora.com/Does-Skype-support-1080p-HD-video-calls
|
||||
# https://tomtalks.blog/2018/04/set-skype-for-business-to-record-meetings-at-1080p-and-30-fps/
|
||||
# Transmission quality is fundamentally different than YouTube -- it is constant TX that varies by
|
||||
# the amount of compression available. Variation between minimum required bandwidth and recommended
|
||||
# bandwidth is visible in packet captures.
|
||||
# Actual capture resolutions depend on your camera and can be manipulated via settings, esp frame rate:
|
||||
# https://superuser.com/questions/180690/how-to-reduce-the-skype-video-settings-to-work-with-an-older-computer
|
||||
# https://lifehacker.com/how-to-get-better-quality-out-of-your-video-chats-5836186
|
||||
# https://docs.microsoft.com/en-us/skypeforbusiness/plan-your-deployment/clients-and-devices/video-resolutions
|
||||
# ^--- This outlines a requirements for 4 core processors as requirement for Skype at 720p!
|
||||
# Jed is roughly interpolating many of these values for this table
|
||||
# nicname w, h, interlaced, audio, vid bps, tt bps framerate
|
||||
"skype-vox-min" => [ 0, 0, 0, 30000, 0, 30000, 0 ],
|
||||
"skype-vox-rcmd" => [ 0, 0, 0, 100000, 0, 100000, 0 ],
|
||||
# screen sharing falls into min requirement
|
||||
"skype-vid-min" => [ 424, 240, 0, 30000, 98000, 128000, 15 ],
|
||||
"skype-vid-rcmd" => [ 640, 360, 0, 100000, 200000, 300000, 30 ],
|
||||
"skype-vid-hq-min" => [ 960, 540, 0, 100000, 300000, 400000, 15 ],
|
||||
"skype-vid-hq-rcmd" => [ 1280, 720, 0, 100000, 400000, 500000, 30 ],
|
||||
"skype-vid-hd-min" => [ 1920, 1080, 0, 100000, 1100000, 1200000, 15 ],
|
||||
"skype-vid-hd-rcmd" => [ 1920, 1080, 0, 100000, 1400000, 1500000, 30 ],
|
||||
"skype-vid-grp3-min" => [ 640, 480, 0, 30000, 482000, 512000, 15 ],
|
||||
"skype-vid-grp3-rcmd" => [ 1280, 720, 0, 100000, 900000, 2000000, 15 ],
|
||||
"skype-vid-grp5-min" => [ 640, 360, 0, 30000, 1700000, 2000000, 15 ],
|
||||
"skype-vid-grp5-rcmd" => [ 1280, 720, 0, 100000, 3700000, 4000000, 15 ],
|
||||
"skype-vid-grp7-min" => [ 640, 360, 0, 30000, 3700000, 4000000, 15 ],
|
||||
"skype-vid-grp7-rcmd" => [ 1280, 720, 0, 100000, 7700000, 8000000, 15 ],
|
||||
|
||||
);
|
||||
|
||||
our $avail_stream_desc = join(", ", keys(%avail_stream_res));
|
||||
@@ -244,19 +275,19 @@ if ($list_streams) {
|
||||
my %sortedkeys = ();
|
||||
foreach my $oldkey (keys(%::avail_stream_res)) {
|
||||
my $ra_row = $::avail_stream_res{$oldkey};
|
||||
my $x = 10000000 + int(@$ra_row[$stream_keys{x}]);
|
||||
my $y = 10000000 + int(@$ra_row[$stream_keys{y}]);
|
||||
my $b = 10000000000 + int(@$ra_row[$stream_keys{video_bps}]);
|
||||
my $x = 10000000 + int(@$ra_row[$::stream_keys{x}]);
|
||||
my $y = 10000000 + int(@$ra_row[$::stream_keys{y}]);
|
||||
my $b = 10000000000 + int(@$ra_row[$::stream_keys{video_bps}]);
|
||||
my $newkey = "${b}_${x}_${y}_${oldkey}";
|
||||
$sortedkeys{$newkey} = $oldkey;
|
||||
}
|
||||
foreach my $sorted_key (sort(keys(%sortedkeys))) {
|
||||
my $key = $sortedkeys{$sorted_key};
|
||||
my $ra_row1 = $::avail_stream_res{$key};
|
||||
my $x = @$ra_row1[$stream_keys{x}];
|
||||
my $y = @$ra_row1[$stream_keys{y}];
|
||||
my $bps = int(@$ra_row1[$stream_keys{stream_bps}]);
|
||||
my $bps_sum = int(@$ra_row1[$stream_keys{video_bps}]) + int(@$ra_row1[$stream_keys{audio_bps}]);
|
||||
my $x = @$ra_row1[$::stream_keys{x}];
|
||||
my $y = @$ra_row1[$::stream_keys{y}];
|
||||
my $bps = int(@$ra_row1[$::stream_keys{stream_bps}]);
|
||||
my $bps_sum = int(@$ra_row1[$::stream_keys{video_bps}]) + int(@$ra_row1[$::stream_keys{audio_bps}]);
|
||||
#my $warning = "";
|
||||
printf("[ %15s ] %4s x %4s using %8s kbps", $key, $x, $y, ($bps/1000));
|
||||
if ($bps != $bps_sum) {
|
||||
@@ -574,41 +605,92 @@ else {
|
||||
$::begin_running = 0;
|
||||
}
|
||||
|
||||
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
# Layer-3 constant setup
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
|
||||
if ($::tx_style =~ /constant/) {
|
||||
if ($::stream_key !~ /^skype-/) {
|
||||
print "Using 'constant' tx-style only makes sense when emulating Skype calls. Please choose different stream.\n";
|
||||
exit 1;
|
||||
}
|
||||
if ($::stream_key =~ /grp\d+/) {
|
||||
print "group calls not implemented presently\n";
|
||||
exit 1;
|
||||
}
|
||||
else {
|
||||
print "Call upload requirements still under development.\n";
|
||||
}
|
||||
|
||||
# if someone sets stream resolution to "-min$", that's not a cap that Skype respects, skype will
|
||||
# search for more bandwidth...stream max will be /-rcmd$/, min will be /-min$/
|
||||
if ($::stream_key =~ /-min$/) {
|
||||
$::stream_key =~ s/-min/-rcmd/;
|
||||
}
|
||||
}
|
||||
die ("Please provide cx_name")
|
||||
unless((defined $::cx_name) && ("" ne $::cx_name));
|
||||
|
||||
my $stream_bps = 0;
|
||||
die("Unknown stream key $::stream_key")
|
||||
unless(exists $::avail_stream_res{$::stream_key});
|
||||
|
||||
$stream_bps = @{$::avail_stream_res{$stream_key}}[$stream_keys{stream_bps}];
|
||||
$stream_bps = @{$::avail_stream_res{$::stream_key}}[$::stream_keys{stream_bps}];
|
||||
|
||||
# estimated fill time is probably not going to be accurate because
|
||||
# there's no way to know the txrate between the AP and station.
|
||||
$::est_fill_time_sec = (8 * $::buf_size) / ($::max_tx * 0.5);
|
||||
my $drain_time_sec = (8 * $::buf_size) / $stream_bps;
|
||||
my $drain_wait_sec = $drain_time_sec - $est_fill_time_sec;
|
||||
my $drain_time_sec = 0;
|
||||
my $drain_wait_sec = 0;
|
||||
my $stream_kbps = 0;
|
||||
|
||||
if ($drain_wait_sec <= 0) {
|
||||
my $stream_kbps = $stream_bps / 1000;
|
||||
print "Warning: constant transmit! Raise max_tx to at least $stream_kbps Kbps\n";
|
||||
$drain_wait_sec = 0;
|
||||
if ($::tx_style =~ /constant/) {
|
||||
my $stream_min = $::stream_key;
|
||||
$stream_min =~ s/-rcmd/-min/;
|
||||
|
||||
$::min_tx = @{$::avail_stream_res{$stream_min}}[$::stream_keys{stream_bps}];
|
||||
$::max_tx = @{$::avail_stream_res{$::stream_key}}[$::stream_keys{stream_bps}];
|
||||
$stream_bps = $::max_tx;
|
||||
$stream_kbps = $stream_bps / 1000;
|
||||
}
|
||||
else {
|
||||
# estimated fill time is probably not going to be accurate because
|
||||
# there's no way to know the txrate between the AP and station.
|
||||
$::est_fill_time_sec = (8 * $::buf_size) / ($::max_tx * 0.5);
|
||||
my $drain_time_sec = (8 * $::buf_size) / $stream_bps;
|
||||
my $drain_wait_sec = $drain_time_sec - $est_fill_time_sec;
|
||||
|
||||
my $buf_kB = $::buf_size / 1024;
|
||||
print "Filling $::stream_key $buf_kB KB buffer est ${est_fill_time_sec}sec, empties in ${drain_time_sec} sec\n"
|
||||
unless($::silent);
|
||||
if ($drain_wait_sec <= 0) {
|
||||
my $stream_kbps = $stream_bps / 1000;
|
||||
print "Warning: constant transmit! Raise max_tx to at least $stream_kbps Kbps\n";
|
||||
$drain_wait_sec = 0;
|
||||
}
|
||||
|
||||
my $buf_kB = $::buf_size / 1024;
|
||||
print "Filling $::stream_key $buf_kB KB buffer est ${est_fill_time_sec}sec, empties in ${drain_time_sec} sec\n"
|
||||
unless($::silent);
|
||||
}
|
||||
$stream_kbps = $stream_bps / 1000;
|
||||
|
||||
die ("Please provide cx_name")
|
||||
unless((defined $::cx_name) && ("" ne $::cx_name));
|
||||
# check for cx if we're bufferfill
|
||||
my $cx_exists = 0;
|
||||
@lines = split("\r?\n", $::utils->doAsyncCmd($::utils->fmt_cmd("show_cx", "all", $::cx_name)));
|
||||
@matches = grep {/Could not find/} @lines;
|
||||
$cx_exists = 1 if (@matches == 0);
|
||||
|
||||
if ($::tx_style eq "bufferfill") {
|
||||
if (($::tx_style eq "bufferfill") && !$cx_exists) {
|
||||
print "Tx_style bufferfill requires your connection already exists, bye.\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (($::tx_style =~ /constant/) && !$cx_exists) {
|
||||
my $cmd = "./lf_firemod.pl --mgr $::lfmgr_host --mgr_port $::lfmgr_port --action create_cx "
|
||||
."--cx_name $::cx_name --use_ports $::sta,$::upstream --use_speeds 128000,$::max_tx "
|
||||
."--speed $::min_tx --max_speed $::max_tx --endp_type udp --report_timer 3000";
|
||||
my $result = `$cmd`;
|
||||
print "x"x72, "\n";
|
||||
print $result, "\n";
|
||||
print "x"x72, "\n";
|
||||
}
|
||||
|
||||
print "Stopping and configuring $::cx_name\n" unless($silent);
|
||||
if (($::tx_style eq "L4") && ($::cx_name !~ /^CX_/)) {
|
||||
$::cx_name = "CX_$::cx_name";
|
||||
@@ -684,12 +766,6 @@ if ($::tx_style eq "L4") {
|
||||
$::utils->doAsyncCmd($cmd);
|
||||
}
|
||||
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
# Layer-3 constant setup
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
|
||||
|
||||
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
# Layer-3 constant bufferfill
|
||||
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
|
||||
|
||||
Reference in New Issue
Block a user