|
|
|
|
@ -1,11 +1,13 @@
|
|
|
|
|
#include "call_video_port.h" |
|
|
|
|
#include "call_video_transport.h" |
|
|
|
|
#include "../chat/chat_setting.h" |
|
|
|
|
#include "../utun_instance.h" |
|
|
|
|
#include "../../lib/u_async.h" |
|
|
|
|
#include "../../lib/mem.h" |
|
|
|
|
#include "../../lib/debug_config.h" |
|
|
|
|
#include <pthread.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
|
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; |
|
|
|
|
static struct { |
|
|
|
|
@ -18,6 +20,8 @@ static struct {
|
|
|
|
|
uint32_t bps, applied_bps; |
|
|
|
|
uint64_t applied_generation, applied_request; |
|
|
|
|
int opening, configure, completed, resume, key; |
|
|
|
|
int range; |
|
|
|
|
uint32_t minimum, maximum; |
|
|
|
|
struct call_video_frame tx, rx[8]; |
|
|
|
|
unsigned count, bytes; |
|
|
|
|
} port; |
|
|
|
|
@ -77,16 +81,25 @@ static void process(void *arg) {
|
|
|
|
|
struct UTUN_INSTANCE *inst = port.inst; |
|
|
|
|
uint64_t id = port.id, old = port.bound; |
|
|
|
|
int opening = port.opening, configure = port.configure, completed = port.completed, resume = port.resume, key = port.key; |
|
|
|
|
int range = port.range; |
|
|
|
|
uint32_t minimum = port.minimum, maximum = port.maximum; |
|
|
|
|
struct call_video_caps caps = port.local; |
|
|
|
|
struct call_video_format format = port.format; |
|
|
|
|
uint32_t bps = port.bps, applied_bps = port.applied_bps; |
|
|
|
|
uint64_t generation = port.applied_generation, request = port.applied_request; |
|
|
|
|
struct call_video_frame tx = port.tx; port.tx = (struct call_video_frame){0}; |
|
|
|
|
port.opening = port.configure = port.completed = port.resume = port.key = 0; |
|
|
|
|
port.range = 0; |
|
|
|
|
if (opening) port.bound = id; |
|
|
|
|
pthread_mutex_unlock(&lock); |
|
|
|
|
int result = 0, sent = 1; |
|
|
|
|
if (inst) { |
|
|
|
|
if (range) { |
|
|
|
|
char value[32]; snprintf(value, sizeof(value), "%u:%u", minimum / 1000, maximum / 1000); |
|
|
|
|
if (chat_setting_set(inst, "call_video_bitrate_range_kbps", value) < 0) |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port bitrate range rejected value=%s", value); |
|
|
|
|
} |
|
|
|
|
call_video_rate_parse_range(chat_setting_get(inst, "call_video_bitrate_range_kbps"), &minimum, &maximum); |
|
|
|
|
if (opening && old && old != id) { |
|
|
|
|
struct call_video_caps empty = {0}; call_video_configure(inst, old, &empty, NULL, NULL); |
|
|
|
|
} |
|
|
|
|
@ -100,6 +113,7 @@ static void process(void *arg) {
|
|
|
|
|
u_free((void *)tx.data); |
|
|
|
|
pthread_mutex_lock(&lock); |
|
|
|
|
if (port.id == id) { |
|
|
|
|
port.status.minimum_bps = minimum; port.status.maximum_bps = maximum; |
|
|
|
|
if (result < 0) { port.status.error = 1; DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port configuration failed call=%llu", (unsigned long long)id); } |
|
|
|
|
else if (configure) { port.status.configured_generation = format.generation; port.status.error = 0; } |
|
|
|
|
if (sent != 1) ++port.status.key_serial; |
|
|
|
|
@ -188,3 +202,12 @@ void call_video_port_request_key(uint64_t id) {
|
|
|
|
|
if (id && id == port.id) { port.key = 1; schedule(); } |
|
|
|
|
pthread_mutex_unlock(&lock); |
|
|
|
|
} |
|
|
|
|
int call_video_port_range(uint64_t id, uint32_t minimum, uint32_t maximum) { |
|
|
|
|
if (minimum < 300000 || maximum > 4000000 || minimum > maximum || minimum % 1000 || maximum % 1000) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port invalid range min=%u max=%u", minimum, maximum); return -1; |
|
|
|
|
} |
|
|
|
|
pthread_mutex_lock(&lock); |
|
|
|
|
int result = id && id == port.id ? schedule() : -1; |
|
|
|
|
if (!result) { port.minimum = minimum; port.maximum = maximum; port.range = 1; } |
|
|
|
|
pthread_mutex_unlock(&lock); return result; |
|
|
|
|
} |
|
|
|
|
|