Separate call audio and video from signaling queues
This commit is contained in:
1 parent
14a56d9b33
commit
609221e384
2 files changed
+36
-8
No files matched your search
+31
-7
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "call.h"
|
||||
#include "call_priv.h"
|
||||
#include "call_video_transport.h"
|
||||
#include "call_proto.h"
|
||||
#include "../dm/dm_core.h"
|
||||
#include "../utun_instance.h"
|
||||
@@ -147,7 +148,8 @@ static void call_session_free_cb(void* arg) {
|
||||
/* Освободить медиа-объекты сессии: отменить waiter на send_q роутера и
|
||||
* дренировать tx_q (без отправки). Безопасно вызывать из uasync-потока. */
|
||||
static void call_session_cleanup(struct call_ctx* ctx, struct call_session* s) {
|
||||
etcp_router_cancel_send_ready(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL, &s->send_waiter);
|
||||
call_video_transport_stop(s);
|
||||
etcp_router_cancel_send_ready(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL_AUDIO, &s->send_waiter);
|
||||
if (s->tx_q) {
|
||||
struct ll_entry* e;
|
||||
while ((e = queue_data_get(s->tx_q)) != NULL) {
|
||||
@@ -282,6 +284,7 @@ static void call_end(struct call_ctx* ctx, struct call_session* s, uint8_t reaso
|
||||
if (!ctx || !s || s->state == CALL_ST_ENDED) return;
|
||||
|
||||
s->state = CALL_ST_ENDED;
|
||||
call_video_transport_stop(s);
|
||||
s->reason = reason;
|
||||
ctx->c_calls_ended++;
|
||||
|
||||
@@ -679,6 +682,19 @@ static void call_etcp_recv(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
const uint8_t* body = d + ROUTER_SVC_PAYLOAD_OFF;
|
||||
size_t blen = entry->len - ROUTER_SVC_PAYLOAD_OFF;
|
||||
|
||||
if ((subcmd == CALL_SUBCMD_MEDIA) != (d[0] == ETCP_RT_ID_CALL_AUDIO)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call packet in wrong channel svc=%u subcmd=%u", d[0], subcmd);
|
||||
queue_dgram_free(entry); queue_entry_free(entry); return;
|
||||
}
|
||||
if (subcmd != CALL_SUBCMD_INVITE && blen >= 9) {
|
||||
uint64_t id; memcpy(&id, body + 1, 8);
|
||||
struct call_session *s = call_session_find(ctx, id);
|
||||
if (s && (s->peer_node_id != from || s->group_id != group)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call packet peer/group mismatch id=%llu", (unsigned long long)id);
|
||||
queue_dgram_free(entry); queue_entry_free(entry); return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (subcmd) {
|
||||
case CALL_SUBCMD_INVITE: call_handle_invite(ctx, from, group, body, blen); break;
|
||||
case CALL_SUBCMD_RINGING: call_handle_ringing(ctx, from, body, blen); break;
|
||||
@@ -722,6 +738,10 @@ int call_init(struct UTUN_INSTANCE* inst) {
|
||||
}
|
||||
|
||||
ctx->initialized = 1;
|
||||
if (etcp_router_bind(inst, ETCP_RT_ID_CALL_AUDIO, call_etcp_recv) || call_video_transport_bind(inst)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call media channel bind failed");
|
||||
call_destroy(inst); return -1;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CALL, "%s: initialized (svc=0x%02x)", CALL_ID, ETCP_RT_ID_CALL);
|
||||
return 0;
|
||||
}
|
||||
@@ -746,6 +766,8 @@ void call_destroy(struct UTUN_INSTANCE* inst) {
|
||||
queue_entry_free(e);
|
||||
}
|
||||
queue_free(ctx->sessions);
|
||||
call_video_transport_unbind(inst);
|
||||
etcp_router_unbind(inst, ETCP_RT_ID_CALL_AUDIO);
|
||||
etcp_router_unbind(inst, ETCP_RT_ID_CALL);
|
||||
inst->call = NULL;
|
||||
uint32_t started = ctx->c_calls_started, ended = ctx->c_calls_ended;
|
||||
@@ -792,17 +814,19 @@ static void call_tx_flush(struct call_session* s) {
|
||||
struct call_ctx* ctx = s->ctx;
|
||||
if (s->state == CALL_ST_ENDED) return;
|
||||
/* гарантируем router conn — иначе has_room/on_send_ready не видят его */
|
||||
etcp_router_conn_get(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL);
|
||||
etcp_router_conn_get(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL_AUDIO);
|
||||
while (s->tx_q && s->tx_q->head) {
|
||||
if (!etcp_router_send_q_has_room(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL)) {
|
||||
etcp_router_on_send_ready(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL,
|
||||
if (!etcp_router_send_q_has_room(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL_AUDIO)) {
|
||||
etcp_router_on_send_ready(ctx->inst, s->group_id, s->peer_node_id, ETCP_RT_ID_CALL_AUDIO,
|
||||
&s->send_waiter, call_tx_drain_cb, s);
|
||||
return;
|
||||
}
|
||||
struct ll_entry* e = queue_data_get(s->tx_q);
|
||||
if (etcp_route_send(ctx->inst, s->group_id, s->peer_node_id, e, 1, 0) == 0)
|
||||
struct call_pkt_media packet; memcpy(&packet, e->dgram + 1, sizeof(packet));
|
||||
if (etcp_route_send(ctx->inst, s->group_id, s->peer_node_id, e, 1, 0) == 0) {
|
||||
s->c_tx_frames++;
|
||||
else DEBUG_WARN(DEBUG_CATEGORY_CALL, "%s: media enqueue failed id=%016llx", CALL_ID, (unsigned long long)s->call_id);
|
||||
if (packet.capture_pts_us != INT64_MIN) call_video_audio_sent(s, packet.capture_pts_us + 20000);
|
||||
} else DEBUG_WARN(DEBUG_CATEGORY_CALL, "%s: media enqueue failed id=%016llx", CALL_ID, (unsigned long long)s->call_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,7 +862,7 @@ int call_send_media(struct UTUN_INSTANCE* inst, uint64_t call_id, const uint8_t*
|
||||
if (!e) return -1;
|
||||
e->dgram = u_malloc(1 + mlen);
|
||||
if (!e->dgram) { queue_entry_free(e); return -1; }
|
||||
e->dgram[0] = ETCP_RT_ID_CALL;
|
||||
e->dgram[0] = ETCP_RT_ID_CALL_AUDIO;
|
||||
memcpy(e->dgram + 1, buf, mlen);
|
||||
e->len = (uint16_t)(1 + mlen);
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ extern "C" {
|
||||
// 0x06 ICMP_PROXY, 0x07 MEDIA_DELIVERY, 0x08 TCP_PROXY_CLIENT,
|
||||
// 0x11 CONN_MGR, 0x32 ADMIN_KEY, 0x33 JOIN, 0x34 DM,
|
||||
// 0x35 DM_MAILBOX, 0x36 CALL, 0x37 FILE_TRANSFER, 0x38 DM_MEDIA, 0x39 MEMBER_FILES,
|
||||
// 0x3A GROUP_AVATAR, 0x3B NAT_DETECTION, 0x3C STREAM
|
||||
// 0x3A GROUP_AVATAR, 0x3B NAT_DETECTION, 0x3C STREAM,
|
||||
// 0x3D CALL_VIDEO_CONTROL, 0x3E CALL_VIDEO, 0x3F CALL_AUDIO
|
||||
//
|
||||
// !!! Новый ID: впиши его в нужный реестр выше и убедись, что значение
|
||||
// не занято в том же пространстве.
|
||||
@@ -81,6 +82,9 @@ extern "C" {
|
||||
#define ETCP_RT_ID_DM 0x34 // dm_core — прямой p2p чат
|
||||
#define ETCP_RT_ID_DM_MAILBOX 0x35 // dm_mailbox — offline-хранение
|
||||
#define ETCP_RT_ID_CALL 0x36 // call — P2P аудио-звонок
|
||||
#define ETCP_RT_ID_CALL_VIDEO_CONTROL 0x3D // возможности и восстановление видеотрека
|
||||
#define ETCP_RT_ID_CALL_VIDEO 0x3E // видео, отдельный ACK/debt/backpressure
|
||||
#define ETCP_RT_ID_CALL_AUDIO 0x3F // аудио, независимо от сигналинга/видео
|
||||
#define ETCP_RT_ID_FILE_TRANSFER 0x37 // file_transfer — передача неизменяемых файлов
|
||||
#define ETCP_RT_ID_DM_MEDIA 0x38 // dm_media — custody, location и подтверждения медиа
|
||||
#define ETCP_RT_ID_MEMBER_FILES 0x39 // member_files — каталоги и файлы участников группы
|
||||
|
||||
Reference in new issue
Block a user