|
|
|
|
@ -20,7 +20,9 @@ static int decode(void* arg, const uint8_t* enc, int len, int16_t* pcm, int cap)
|
|
|
|
|
for (int i = 0; i < cap; i++) pcm[i] = (int16_t)(8000 * std::sin(2 * 3.141592653589793 * 440 * i / 48000)); |
|
|
|
|
return cap; |
|
|
|
|
} |
|
|
|
|
static void push(call_jitter* j, int id) { call_jitter_push(j, (const uint8_t*)&id, sizeof(id)); } |
|
|
|
|
static void push(call_jitter* j, int id, int64_t received_ms = -1) { |
|
|
|
|
call_jitter_push(j, (const uint8_t*)&id, sizeof(id), (uint32_t)(id * 20), received_ms < 0 ? id * 20 : received_ms); |
|
|
|
|
} |
|
|
|
|
int main() { |
|
|
|
|
{ |
|
|
|
|
call_jitter_window w; |
|
|
|
|
@ -36,6 +38,19 @@ int main() {
|
|
|
|
|
CHECK(limited.reserve == cap); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
call_jitter_window arrival; |
|
|
|
|
// Разные часы и переполнение uint32 не создают джиттер при ровной доставке.
|
|
|
|
|
uint32_t sent = UINT32_MAX - 39; |
|
|
|
|
for (int i = 0; i < 100; i++) arrival.observe_arrival(900000 + i * 20, sent + (uint32_t)(i * 20)); |
|
|
|
|
CHECK(arrival.high == 0 && arrival.low == 0 && arrival.reserve == 60); |
|
|
|
|
arrival.observe_arrival(902200, sent + 2000); // задержка доставки +200мс
|
|
|
|
|
CHECK(arrival.reserve == 200); |
|
|
|
|
arrival.observe_arrival(902220, sent + 2220); // очередь пришла пачкой
|
|
|
|
|
CHECK(arrival.reserve == 200); |
|
|
|
|
arrival.observe_arrival(920000, sent + 20000); // старый burst ушёл из окна
|
|
|
|
|
CHECK(arrival.reserve == 60); |
|
|
|
|
} |
|
|
|
|
debug_set_level(DEBUG_LEVEL_WARN); |
|
|
|
|
int16_t pcm[480]; |
|
|
|
|
int depth, tempo; |
|
|
|
|
@ -48,20 +63,20 @@ int main() {
|
|
|
|
|
CHECK(call_jitter_pull(j, pcm, 480) == 0); |
|
|
|
|
push(j, 2); |
|
|
|
|
CHECK(call_jitter_pull(j, pcm, 480) > 0); |
|
|
|
|
for (int i = 3; i < 503; i++) push(j, i); // 10с накопления, без удаления существовавшего хвоста
|
|
|
|
|
for (int i = 3; i < 503; i++) push(j, i, 10060); // 10с сетевой задержки, затем пачка
|
|
|
|
|
int next = 503, highest = 100; |
|
|
|
|
for (int tick = 0; tick < 6000; tick++) { |
|
|
|
|
if (tick % 2 == 0) push(j, next++); // непрерывный live: кадр каждые 20мс
|
|
|
|
|
if (tick % 2 == 0) push(j, next++, 10060 + tick * 10); // непрерывный live
|
|
|
|
|
call_jitter_pull(j, pcm, 480); |
|
|
|
|
call_jitter_get_stats(j, &depth, &tempo, &dropped, &under, nullptr); |
|
|
|
|
if (tempo > highest) highest = tempo; |
|
|
|
|
} |
|
|
|
|
call_jitter_range range; |
|
|
|
|
call_jitter_get_stats(j, nullptr, nullptr, nullptr, nullptr, &range); |
|
|
|
|
CHECK(range.reserve_ms == 1000 && range.max_ms >= 10000); |
|
|
|
|
CHECK(range.reserve_ms == 60 && range.max_ms >= 10000); |
|
|
|
|
CHECK(range.min_ms <= range.max_ms); |
|
|
|
|
CHECK(highest >= 150); |
|
|
|
|
CHECK(depth < 1200); |
|
|
|
|
CHECK(depth < 200); |
|
|
|
|
CHECK(tempo <= 110); |
|
|
|
|
CHECK(dropped == 0); |
|
|
|
|
for (size_t i = 0; i < d.seen.size(); i++) CHECK(d.seen[i] == (int)i); |
|
|
|
|
@ -74,6 +89,26 @@ int main() {
|
|
|
|
|
CHECK(call_jitter_pull(j, pcm, 480) > 0); |
|
|
|
|
call_jitter_destroy(j); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
decoder d; |
|
|
|
|
auto* j = call_jitter_create(decode, &d, 1000); |
|
|
|
|
// Устройство готовилось 1.2с, но сеть всё время доставляла кадры равномерно.
|
|
|
|
|
for (int i = 0; i < 60; i++) push(j, i); |
|
|
|
|
call_jitter_range range; |
|
|
|
|
call_jitter_get_stats(j, &depth, nullptr, nullptr, nullptr, &range); |
|
|
|
|
CHECK(depth == 1200 && range.reserve_ms == 60); |
|
|
|
|
CHECK(call_jitter_pull(j, pcm, 480) == 480); // первый pull сразу воспроизводит речь
|
|
|
|
|
int next = 60; |
|
|
|
|
for (int tick = 0; tick < 6000; tick++) { |
|
|
|
|
if (tick % 2 == 0) push(j, next++); |
|
|
|
|
CHECK(call_jitter_pull(j, pcm, 480) == 480); |
|
|
|
|
call_jitter_get_stats(j, &depth, &tempo, &dropped, &under, &range); |
|
|
|
|
CHECK(range.reserve_ms == 60); // догон не увеличивает сетевой резерв
|
|
|
|
|
} |
|
|
|
|
CHECK(depth < 150 && tempo <= 110 && dropped == 0 && under == 0); |
|
|
|
|
for (size_t i = 0; i < d.seen.size(); i++) CHECK(d.seen[i] == (int)i); |
|
|
|
|
call_jitter_destroy(j); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
decoder d; |
|
|
|
|
auto* j = call_jitter_create(decode, &d, 1000); |
|
|
|
|
|