|
|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
#include "call_video_transport.h" |
|
|
|
|
#include "call_priv.h" |
|
|
|
|
#include "../chat/chat_setting.h" |
|
|
|
|
#include "../utun_instance.h" |
|
|
|
|
#include "../routing_layer/etcp_router.h" |
|
|
|
|
#include "../routing_layer/route_crypto.h" |
|
|
|
|
@ -25,7 +26,7 @@ struct call_video_transport {
|
|
|
|
|
struct call_video_rate rate; |
|
|
|
|
struct route_tx_meter production; |
|
|
|
|
uint64_t rate_generation, rate_request, produced_id, route_local_epoch, route_peer_epoch, rate_requested_us; |
|
|
|
|
uint32_t applied_bps, maximum_bps; |
|
|
|
|
uint32_t applied_bps, maximum_bps, range_minimum_bps, range_maximum_bps; |
|
|
|
|
int rate_pending, admit; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
@ -86,6 +87,20 @@ static void update_rate(struct call_video_transport *v) {
|
|
|
|
|
(unsigned long long)s->call_id, (unsigned long long)v->rate_generation, (unsigned long long)v->rate_request); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
uint32_t minimum, maximum; |
|
|
|
|
if (call_video_rate_parse_range(chat_setting_get(s->ctx->inst, "call_video_bitrate_range_kbps"), &minimum, &maximum)) { |
|
|
|
|
v->admit = 0; return; |
|
|
|
|
} |
|
|
|
|
if (maximum > v->maximum_bps) maximum = v->maximum_bps; |
|
|
|
|
if (minimum != v->range_minimum_bps || maximum != v->range_maximum_bps) { |
|
|
|
|
v->range_minimum_bps = minimum; v->range_maximum_bps = maximum; |
|
|
|
|
if (minimum > maximum) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_CALL, "video range unavailable call=%llu min=%u codec_cap=%u; admission paused", |
|
|
|
|
(unsigned long long)s->call_id, minimum, v->maximum_bps); |
|
|
|
|
else DEBUG_INFO(DEBUG_CATEGORY_CALL, "video range applied call=%llu min=%u max=%u codec_cap=%u", |
|
|
|
|
(unsigned long long)s->call_id, minimum, maximum, v->maximum_bps); |
|
|
|
|
} |
|
|
|
|
if (minimum > maximum) { v->admit = 0; return; } |
|
|
|
|
struct ETCP_ROUTER_TX_STATS net = {0}; |
|
|
|
|
int found = etcp_router_tx_stats(s->ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL_VIDEO, now, &net) == 0; |
|
|
|
|
if (found && (net.local_epoch != v->route_local_epoch || net.peer_epoch != v->route_peer_epoch)) { |
|
|
|
|
@ -101,7 +116,7 @@ static void update_rate(struct call_video_transport *v) {
|
|
|
|
|
sample.delivered_bytes = media_bytes(net.window.bytes, net.window.packets); sample.produced_bytes = produced.bytes; |
|
|
|
|
sample.debt_bytes = media_bytes(net.queued_bytes + net.inflight_bytes, (uint64_t)net.queued_packets + net.inflight_packets); |
|
|
|
|
if (v->data && !held) sample.debt_bytes += v->tx.size - v->tx.offset; |
|
|
|
|
sample.applied_bps = v->applied_bps; sample.minimum_bps = 64000; sample.maximum_bps = v->maximum_bps; |
|
|
|
|
sample.applied_bps = v->applied_bps; sample.minimum_bps = minimum; sample.maximum_bps = maximum; |
|
|
|
|
sample.baseline_rtt_us = net.baseline_rtt_us; sample.rtt_us = net.rtt_us; |
|
|
|
|
sample.frame_interval_us = v->tx.format.fps ? 1000000 / v->tx.format.fps : 33333; |
|
|
|
|
sample.debt_limit_bytes = CALL_VIDEO_MAX_FRAME; |
|
|
|
|
@ -236,6 +251,12 @@ int call_video_configure_rate(struct UTUN_INSTANCE *inst, uint64_t id, uint64_t
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video rate configure invalid call=%llu generation=%llu bitrate=%u cap=%u", |
|
|
|
|
(unsigned long long)id, (unsigned long long)generation, applied, maximum); return -1; |
|
|
|
|
} |
|
|
|
|
uint32_t range_minimum, range_maximum; |
|
|
|
|
if (call_video_rate_parse_range(chat_setting_get(inst, "call_video_bitrate_range_kbps"), &range_minimum, &range_maximum)) return -1; |
|
|
|
|
if (maximum < range_minimum) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video rate codec cap below requested minimum call=%llu min=%u cap=%u", |
|
|
|
|
(unsigned long long)id, range_minimum, maximum); return -1; |
|
|
|
|
} |
|
|
|
|
if (v->rate_generation != generation) { |
|
|
|
|
v->rate_generation = generation; v->rate_pending = 0; v->admit = 1; |
|
|
|
|
call_video_rate_init(&v->rate, get_time_us()); route_tx_meter_reset(&v->production, get_time_us()); |
|
|
|
|
|