Drain receiver backlog before admitting new production and avoid double waiting
This commit is contained in:
1 parent
02e7bbd9af
commit
943f9f2646
2 files changed
+18
-2
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in new issue
Block a user