Browse Source

Verify RX drain and explicit decoder rejection semantics

stream-multiview
evgeny 6 days ago
parent
commit
5f1985f9ab
  1. 2
      tests/test_call.c
  2. 21
      tests/test_call_video_port.c

2
tests/test_call.c

@ -725,7 +725,7 @@ static void call_tick(void* arg) {
if (call_video_port_status(t->call_id, &status) || status.decoded_generation != 1 || status.decoded_accepted) break;
if (++t->phase_ticks < 10) break; // Регулятор не должен отменять запрет decoder на следующем tick.
struct call_video_frame f = video_test_frame(t->call_id, 1); f.frame_id = 4; f.pts_us += 99999;
if (call_video_send_frame(B, &f) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video ignored decoder rejection"); t->result = 2; break; }
if (call_video_send_frame(B, &f) != -1) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video ignored decoder rejection"); t->result = 2; break; }
// Все команды попадут в uasync после синхронного ENDED; TX ещё принадлежит mailbox.
struct call_video_frame closing[2] = {f, f}; ++closing[1].frame_id; closing[1].pts_us += 33333;
if (call_video_port_format(t->call_id, &f.format, 500000)

21
tests/test_call_video_port.c

@ -44,7 +44,7 @@ int main(void) {
session = (struct call_session){.ctx = &ctx, .call_id = 7, .state = CALL_ST_ACTIVE};
assert(!call_video_port_attach(&inst));
struct call_video_caps caps = {0};
assert(!call_video_port_open(7, &caps)); uasync_drain_immediate(ua);
assert(!call_video_port_open(7, &caps)); uasync_poll(ua, 0);
assert(callbacks && callbacks->writable); callbacks->writable(callback_arg, 1);
uint8_t data[8][16]; struct call_video_frame frames[8];
for (unsigned i = 0; i < 8; ++i) {
@ -56,20 +56,27 @@ int main(void) {
extra = frames[7]; concurrent = 1; allowance = 2;
assert(call_video_port_send(frames, 8) == 1);
memset(data, 0, sizeof(data)); // Порт обязан владеть собственной копией.
uasync_drain_immediate(ua);
uasync_poll(ua, 0);
assert(accepted == 2 && port.tx_count == 6 && !port.tx_processing && !port.pending);
unsigned before = offered; uasync_drain_immediate(ua); assert(offered == before); // Нет busy loop.
unsigned before = offered; uasync_poll(ua, 0); assert(offered == before); // Нет busy loop.
struct call_video_port_status status;
assert(!call_video_port_status(7, &status) && !status.can_encode && !status.key_serial);
for (unsigned i = 0; i < 3; ++i) {
callbacks->writable(callback_arg, 0); uasync_drain_immediate(ua);
callbacks->writable(callback_arg, 0); uasync_poll(ua, 0);
assert(accepted == 2 && port.tx_count == 6 && !port.pending);
}
allowance = 8; callbacks->writable(callback_arg, 1); uasync_drain_immediate(ua);
allowance = 8; callbacks->writable(callback_arg, 1); uasync_poll(ua, 0);
assert(accepted == 8 && !port.tx_count);
assert(!call_video_port_status(7, &status) && status.can_encode && !status.key_serial);
DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS video port: all 8 frames preserved across partial send and repeated busy; no KEY or spin");
call_video_port_close(7); uasync_drain_immediate(ua);
call_video_port_detach(&inst); uasync_drain_immediate(ua);
for (unsigned i = 0; i < 8; ++i) { assert(callbacks->receive_ready(callback_arg, 16)); callbacks->frame(callback_arg, &frames[i]); }
assert(!callbacks->receive_ready(callback_arg, 16));
for (unsigned i = 0; i < 8; ++i) {
struct call_video_frame f; assert(call_video_port_pull(7, &f) == 1 && f.frame_id == i + 1); u_free((void *)f.data);
assert(callbacks->receive_ready(callback_arg, 16) == (i == 7));
}
DEBUG_INFO(DEBUG_CATEGORY_CALL, "PASS video port: full RX drains completely before resuming producer admission");
call_video_port_close(7); uasync_poll(ua, 0);
call_video_port_detach(&inst); uasync_poll(ua, 0);
uasync_destroy(ua, 0); return 0;
}

Loading…
Cancel
Save