Browse Source

Preserve capture clock across call delivery and validate media peer

stream-multiview
evgeny 1 week ago
parent
commit
2e1908a52b
  1. 29
      src/call/call.c
  2. 2
      src/call/call_headless.c

29
src/call/call.c

@ -668,13 +668,24 @@ static void call_handle_hangup(struct call_ctx* ctx, uint64_t from, const uint8_
}
static void call_handle_media(struct call_ctx* ctx, uint64_t from, const uint8_t* b, size_t n) {
if (n < CALL_MEDIA_HDR_SIZE) return;
if (n <= CALL_MEDIA_HDR_SIZE) { DEBUG_WARN(DEBUG_CATEGORY_CALL, "call media truncated bytes=%zu", n); return; }
uint64_t call_id; memcpy(&call_id, b + 1, 8);
struct call_session* s = call_session_find(ctx, call_id);
if (!s || s->state != CALL_ST_ACTIVE) {
/* медиа вне ACTIVE — игнорируем (гонка с завершением) */
return;
}
struct call_pkt_media packet;
memcpy(&packet, b, sizeof(packet));
if (from != s->peer_node_id || packet.track_id != CALL_TRACK_AUDIO || packet.codec_delay_samples > CALL_OPUS_SAMPLE_RATE
|| (packet.capture_pts_us != INT64_MIN && (packet.capture_pts_us < 0 || packet.capture_pts_us > INT64_MAX / 2
|| !packet.capture_epoch))) {
DEBUG_WARN(DEBUG_CATEGORY_CALL, "call media invalid peer=%016llx expected=%016llx track=%u pts=%lld epoch=%llu delay=%u",
(unsigned long long)from, (unsigned long long)s->peer_node_id, packet.track_id,
(long long)packet.capture_pts_us, (unsigned long long)packet.capture_epoch, packet.codec_delay_samples);
return;
}
struct call_capture_time timing = {packet.capture_pts_us, packet.capture_epoch, packet.codec_delay_samples};
s->c_rx_frames++;
s->last_media_tb = get_time_tb();
@ -686,7 +697,7 @@ static void call_handle_media(struct call_ctx* ctx, uint64_t from, const uint8_t
/* аудио-движок (декод + джиттер-буфер) — если зарегистрирован */
if (ctx->audio_ops && ctx->audio_ops->on_media)
ctx->audio_ops->on_media(ctx->inst, call_id, seq, ts_ms,
b + CALL_MEDIA_HDR_SIZE, (int)(n - CALL_MEDIA_HDR_SIZE));
b + CALL_MEDIA_HDR_SIZE, (int)(n - CALL_MEDIA_HDR_SIZE), &timing);
/* релей Opus-кадра потребителю (headless-аудио-сокет) */
if (ctx->media_recv_fn)
@ -843,12 +854,19 @@ static void call_tx_flush(struct call_session* s) {
}
}
int call_send_media(struct UTUN_INSTANCE* inst, uint64_t call_id, const uint8_t* opus, int len) {
int call_send_media(struct UTUN_INSTANCE* inst, uint64_t call_id, const uint8_t* opus, int len,
const struct call_capture_time* timing) {
struct call_ctx* ctx = call_of(inst);
if (!ctx || !ctx->initialized || !opus || len <= 0) return -1;
struct call_session* s = call_session_find(ctx, call_id);
if (!s || s->state != CALL_ST_ACTIVE) return -1;
if (CALL_MEDIA_HDR_SIZE + (size_t)len > 1024) return -1;
if (timing && (timing->delay_samples > CALL_OPUS_SAMPLE_RATE || (timing->pts_us != INT64_MIN
&& (timing->pts_us < 0 || timing->pts_us > INT64_MAX / 2 || !timing->epoch)))) {
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call media invalid capture metadata pts=%lld epoch=%llu delay=%u",
(long long)timing->pts_us, (unsigned long long)timing->epoch, timing->delay_samples);
return -1;
}
uint8_t buf[1024];
struct call_pkt_media* m = (struct call_pkt_media*)buf;
@ -857,6 +875,9 @@ int call_send_media(struct UTUN_INSTANCE* inst, uint64_t call_id, const uint8_t*
m->track_id = CALL_TRACK_AUDIO;
m->seq = s->tx_media_seq++;
m->ts_ms = (uint32_t)(get_time_tb() / 10);
m->capture_pts_us = timing ? timing->pts_us : INT64_MIN;
m->capture_epoch = timing ? timing->epoch : 0;
m->codec_delay_samples = timing ? timing->delay_samples : 0;
memcpy(buf + CALL_MEDIA_HDR_SIZE, opus, (size_t)len);
size_t mlen = CALL_MEDIA_HDR_SIZE + (size_t)len;
@ -1025,6 +1046,6 @@ void call_hangup_trampoline(void* arg) {
void call_send_media_trampoline(void* arg) {
struct call_media_arg* a = (struct call_media_arg*)arg;
call_send_media(a->inst, a->call_id, a->opus, a->len);
call_send_media(a->inst, a->call_id, a->opus, a->len, &a->timing);
u_free(a);
}

2
src/call/call_headless.c

@ -206,7 +206,7 @@ static void ca_parse_frames(struct call_audio_client* cli) {
CH_ID, olen, (unsigned long long)call_id);
} else {
ca->c_enc_frames++;
if (call_send_media(ca->inst, call_id, opus, olen) != 0)
if (call_send_media(ca->inst, call_id, opus, olen, NULL) != 0)
DEBUG_WARN(DEBUG_CATEGORY_CALL, "%s: send_media failed call_id=%016llx len=%d",
CH_ID, (unsigned long long)call_id, olen);
}

Loading…
Cancel
Save