Browse Source

Deliver decoder results through the thread-safe call video port

master
evgeny 5 days ago
parent
commit
afe9437c49
  1. 26
      src/call/call_video_port.c
  2. 3
      src/call/call_video_port.h

26
src/call/call_video_port.c

@ -24,6 +24,8 @@ static struct {
uint32_t minimum, maximum; uint32_t minimum, maximum;
struct call_video_frame tx, rx[8]; struct call_video_frame tx, rx[8];
unsigned count, bytes; unsigned count, bytes;
uint64_t decoded_generation;
int decoded_pending, decoded_accepted;
} port; } port;
static void process(void *arg); static void process(void *arg);
@ -71,7 +73,14 @@ static void bitrate(void *arg, uint64_t generation, uint64_t request, uint32_t b
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
} }
static const struct call_video_ops ops = {peer, ready, frame, need_key, bitrate}; static void decoded(void *arg, uint64_t generation, int accepted) {
pthread_mutex_lock(&lock);
if (port.id == (uint64_t)(uintptr_t)arg) {
port.status.decoded_generation = generation; port.status.decoded_accepted = accepted;
}
pthread_mutex_unlock(&lock);
}
static const struct call_video_ops ops = {peer, ready, frame, need_key, bitrate, decoded};
/* Снимок команды под mutex; API транспорта вызывается без mutex, callbacks могут войти обратно. */ /* Снимок команды под mutex; API транспорта вызывается без mutex, callbacks могут войти обратно. */
static void process(void *arg) { static void process(void *arg) {
@ -82,6 +91,8 @@ static void process(void *arg) {
uint64_t id = port.id, old = port.bound; 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 opening = port.opening, configure = port.configure, completed = port.completed, resume = port.resume, key = port.key;
int range = port.range; int range = port.range;
int decoded_pending = port.decoded_pending, decoded_accepted = port.decoded_accepted;
uint64_t decoded_generation = port.decoded_generation;
uint32_t minimum = port.minimum, maximum = port.maximum; uint32_t minimum = port.minimum, maximum = port.maximum;
struct call_video_caps caps = port.local; struct call_video_caps caps = port.local;
struct call_video_format format = port.format; struct call_video_format format = port.format;
@ -90,6 +101,7 @@ static void process(void *arg) {
struct call_video_frame tx = port.tx; port.tx = (struct call_video_frame){0}; 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.opening = port.configure = port.completed = port.resume = port.key = 0;
port.range = 0; port.range = 0;
port.decoded_pending = 0;
if (opening) port.bound = id; if (opening) port.bound = id;
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
int result = 0, sent = 1; int result = 0, sent = 1;
@ -108,6 +120,7 @@ static void process(void *arg) {
if (id && completed) call_video_rate_applied(inst, id, generation, request, applied_bps); if (id && completed) call_video_rate_applied(inst, id, generation, request, applied_bps);
if (id && resume) call_video_resume_receive(inst, id); if (id && resume) call_video_resume_receive(inst, id);
if (id && key) call_video_request_key(inst, id); if (id && key) call_video_request_key(inst, id);
if (id && decoded_pending) call_video_decode_result(inst, id, decoded_generation, decoded_accepted);
if (id && tx.data) sent = call_video_send_frame(inst, &tx); if (id && tx.data) sent = call_video_send_frame(inst, &tx);
} }
u_free((void *)tx.data); u_free((void *)tx.data);
@ -143,7 +156,7 @@ int call_video_port_open(uint64_t id, const struct call_video_caps *caps) {
if (!result) { if (!result) {
if (port.id != id) { if (port.id != id) {
clear_frames(); port.status = (struct call_video_port_status){0}; clear_frames(); port.status = (struct call_video_port_status){0};
port.configure = port.completed = port.resume = port.key = port.range = 0; port.configure = port.completed = port.resume = port.key = port.range = port.decoded_pending = 0;
} }
port.id = id; port.local = *caps; port.opening = 1; port.id = id; port.local = *caps; port.opening = 1;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video port open requested call=%llu", (unsigned long long)id); DEBUG_INFO(DEBUG_CATEGORY_CALL, "video port open requested call=%llu", (unsigned long long)id);
@ -154,7 +167,7 @@ void call_video_port_close(uint64_t id) {
pthread_mutex_lock(&lock); pthread_mutex_lock(&lock);
if (port.id == id) { if (port.id == id) {
clear_frames(); port.id = 0; port.opening = 1; clear_frames(); port.id = 0; port.opening = 1;
port.configure = port.completed = port.resume = port.key = port.range = 0; port.configure = port.completed = port.resume = port.key = port.range = port.decoded_pending = 0;
if (port.inst) schedule(); if (port.inst) schedule();
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video port close requested call=%llu", (unsigned long long)id); DEBUG_INFO(DEBUG_CATEGORY_CALL, "video port close requested call=%llu", (unsigned long long)id);
} }
@ -215,3 +228,10 @@ int call_video_port_range(uint64_t id, uint32_t minimum, uint32_t maximum) {
if (!result) { port.minimum = minimum; port.maximum = maximum; port.range = 1; } if (!result) { port.minimum = minimum; port.maximum = maximum; port.range = 1; }
pthread_mutex_unlock(&lock); return result; pthread_mutex_unlock(&lock); return result;
} }
int call_video_port_decoded(uint64_t id, uint64_t generation, int accepted) {
if (!generation || (accepted != 0 && accepted != 1)) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port invalid decoder result"); return -1; }
pthread_mutex_lock(&lock);
int result = id && id == port.id ? schedule() : -1;
if (!result) { port.decoded_generation = generation; port.decoded_accepted = accepted; port.decoded_pending = 1; }
pthread_mutex_unlock(&lock); return result;
}

3
src/call/call_video_port.h

@ -15,6 +15,8 @@ struct call_video_port_status {
uint32_t rate_bps; uint32_t rate_bps;
uint32_t minimum_bps, maximum_bps; uint32_t minimum_bps, maximum_bps;
int have_peer, error; int have_peer, error;
uint64_t decoded_generation;
int decoded_accepted;
}; };
int call_video_port_attach(struct UTUN_INSTANCE *inst); int call_video_port_attach(struct UTUN_INSTANCE *inst);
void call_video_port_detach(struct UTUN_INSTANCE *inst); void call_video_port_detach(struct UTUN_INSTANCE *inst);
@ -27,6 +29,7 @@ int call_video_port_send(const struct call_video_frame *frame);
int call_video_port_pull(uint64_t id, struct call_video_frame *out); int call_video_port_pull(uint64_t id, struct call_video_frame *out);
void call_video_port_request_key(uint64_t id); void call_video_port_request_key(uint64_t id);
int call_video_port_range(uint64_t id, uint32_t minimum_bps, uint32_t maximum_bps); int call_video_port_range(uint64_t id, uint32_t minimum_bps, uint32_t maximum_bps);
int call_video_port_decoded(uint64_t id, uint64_t generation, int accepted);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

Loading…
Cancel
Save