Browse Source

Drain receiver backlog before admitting new production and avoid double waiting

stream-multiview
evgeny 5 days ago
parent
commit
943f9f2646
  1. 3
      src/call/call_video_playout.c
  2. 17
      src/call/call_video_port.c

3
src/call/call_video_playout.c

@ -58,7 +58,8 @@ enum call_video_playout_action call_video_playout_poll(struct call_video_playout
p->audio_valid = !!audio_valid;
}
if (!audio_valid) { p->anchored = 0; p->clock_wait++; return CALL_VIDEO_PLAYOUT_WAIT; }
if (!f) return CALL_VIDEO_PLAYOUT_WAIT;
// Ожидание новых данных уже прошло в реальном времени: повторно добавлять этот интервал нельзя.
if (!f) { p->anchored = 0; return CALL_VIDEO_PLAYOUT_WAIT; }
if (f->pts_us <= p->last_pts || f->received_us < 0 || f->received_us > now) {
DEBUG_WARN(DEBUG_CATEGORY_CALL, "video playout invalid/order call=%llu pts=%lld last=%lld received=%lld now=%lld",
(unsigned long long)p->call_id, (long long)f->pts_us, (long long)p->last_pts,

17
src/call/call_video_port.c

@ -30,6 +30,7 @@ static struct {
int64_t tx_wait_started;
unsigned tx_retries;
unsigned count, bytes;
int64_t rx_wait_started; // Полный FIFO возобновляет приём после drain, а не по одному освободившемуся месту.
uint64_t decoded_generation;
int decoded_pending, decoded_accepted;
} port;
@ -48,6 +49,7 @@ static void clear_frames(void) {
port.tx_wait_started = 0; port.tx_retries = 0;
for (unsigned i = 0; i < port.count; ++i) u_free((void *)port.rx[i].data);
port.count = port.bytes = 0;
port.rx_wait_started = 0;
}
static void peer(void *arg, const struct call_video_caps *caps) {
pthread_mutex_lock(&lock);
@ -56,7 +58,20 @@ static void peer(void *arg, const struct call_video_caps *caps) {
}
static int ready(void *arg, uint32_t bytes) {
pthread_mutex_lock(&lock);
int result = port.id == (uint64_t)(uintptr_t)arg && port.count < 8 && bytes <= 4u * 1024u * 1024u - port.bytes;
int result = 0;
if (port.id == (uint64_t)(uintptr_t)arg) {
if (port.rx_wait_started && !port.count) {
DEBUG_DEBUG(DEBUG_CATEGORY_CALL, "video port RX drained call=%llu wait_us=%lld; admission resumed",
(unsigned long long)port.id, (long long)(call_video_playout_now_us() - port.rx_wait_started));
port.rx_wait_started = 0;
}
result = !port.rx_wait_started && port.count < 8 && bytes <= 4u * 1024u * 1024u - port.bytes;
if (!result && !port.rx_wait_started) {
port.rx_wait_started = call_video_playout_now_us();
DEBUG_WARN(DEBUG_CATEGORY_CALL, "video port RX full call=%llu frames=%u bytes=%u next_bytes=%u; drain before resume",
(unsigned long long)port.id, port.count, port.bytes, bytes);
}
}
pthread_mutex_unlock(&lock); return result;
}
static void frame(void *arg, const struct call_video_frame *f) {

Loading…
Cancel
Save