Specify jitter reserve at startup and expose delay diagnostics

This commit is contained in:
evgeny committed 2026-10-15 13:19:39 +02:00
1 parent aaff1a5494
commit c1cc3c459b
2 files changed
+10 -3

No files matched your search

+5 -1
View File
@@ -9,7 +9,8 @@ extern "C" {
#endif #endif
/* Звонок: FIFO Opus, запас 20мс..max_reserve_ms по изменению задержки доставки за 10 секунд и догон после паузы устройства. /* Звонок: FIFO Opus, запас 20мс..max_reserve_ms по изменению задержки доставки за 10 секунд и догон после паузы устройства.
* push — сетевой поток, pull/decode/SoundTouch — единственный аудиопоток. * push — сетевой поток, pull/decode/CallDelay — единственный аудиопоток.
* Старт/восстановление ждут запас плюс запрошенный блок; при выдаче PCM запас не резервируется повторно.
* destroy — после остановки обоих потребителей. get_stats — любой поток. */ * destroy — после остановки обоих потребителей. get_stats — любой поток. */
#define CALL_JITTER_FRAME_MS 20 #define CALL_JITTER_FRAME_MS 20
#define CALL_JITTER_MIN_RESERVE_MS 20 #define CALL_JITTER_MIN_RESERVE_MS 20
@@ -24,6 +25,9 @@ struct call_jitter_diagnostics {
int encoded_ms, processing_ms, pcm_samples; int encoded_ms, processing_ms, pcm_samples;
int64_t arrival_spread_ms; int64_t arrival_spread_ms;
uint32_t underruns; uint32_t underruns;
int delay_mode, tempo_ppm;
unsigned phase_samples;
uint64_t cut_samples, stretch_entries, stretch_exits;
}; };
/* Снимок и сброс событий под mutex; логировать после выхода из mutex голосового стека. */ /* Снимок и сброс событий под mutex; логировать после выхода из mutex голосового стека. */
void call_jitter_get_diagnostics(struct call_jitter*, struct call_jitter_diagnostics*, int reset_events); void call_jitter_get_diagnostics(struct call_jitter*, struct call_jitter_diagnostics*, int reset_events);
+5 -2
View File
@@ -123,7 +123,7 @@ int main() {
decoder d; decoder d;
auto* j = call_jitter_create(decode, &d, 1000); auto* j = call_jitter_create(decode, &d, 1000);
CHECK(j); CHECK(j);
push(j, 0); // 20мс достаточно для допуска в decoder, но SoundTouch ещё накапливает PCM. push(j, 0); // Сохраняем запас 20мс после первого блока, а не расходуем его при старте.
CHECK(call_jitter_pull(j, pcm, 480) == 0); CHECK(call_jitter_pull(j, pcm, 480) == 0);
push(j, 1); push(j, 1);
CHECK(call_jitter_pull(j, pcm, 480) > 0); CHECK(call_jitter_pull(j, pcm, 480) > 0);
@@ -159,7 +159,10 @@ int main() {
for (size_t i = 0; i < d.seen.size(); i++) CHECK(d.seen[i] == (int)i); for (size_t i = 0; i < d.seen.size(); i++) CHECK(d.seen[i] == (int)i);
for (int i = 0; i < 100; i++) call_jitter_pull(j, pcm, 480); for (int i = 0; i < 100; i++) call_jitter_pull(j, pcm, 480);
size_t before = d.seen.size(); size_t before = d.seen.size();
// После опустошения один кадр дополняет остаток SoundTouch и возобновляет PCM при запасе 20мс. // После опустошения ждём полный блок сверх сетевого запаса; скрытого накопления DSP больше нет.
push(j, next++);
CHECK(call_jitter_pull(j, pcm, 480) == 0);
CHECK(d.seen.size() == before);
push(j, next++); push(j, next++);
int refill = call_jitter_pull(j, pcm, 480); int refill = call_jitter_pull(j, pcm, 480);
if (refill != 480) { if (refill != 480) {