Verify RX drain and explicit decoder rejection semantics
This commit is contained in:
1 parent
943f9f2646
commit
5f1985f9ab
2 files changed
+15
-8
No files matched your search
+1
-1
@@ -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 (call_video_port_status(t->call_id, &status) || status.decoded_generation != 1 || status.decoded_accepted) break;
|
||||||
if (++t->phase_ticks < 10) break; // Регулятор не должен отменять запрет decoder на следующем tick.
|
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;
|
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.
|
// Все команды попадут в uasync после синхронного ENDED; TX ещё принадлежит mailbox.
|
||||||
struct call_video_frame closing[2] = {f, f}; ++closing[1].frame_id; closing[1].pts_us += 33333;
|
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)
|
if (call_video_port_format(t->call_id, &f.format, 500000)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ int main(void) {
|
|||||||
session = (struct call_session){.ctx = &ctx, .call_id = 7, .state = CALL_ST_ACTIVE};
|
session = (struct call_session){.ctx = &ctx, .call_id = 7, .state = CALL_ST_ACTIVE};
|
||||||
assert(!call_video_port_attach(&inst));
|
assert(!call_video_port_attach(&inst));
|
||||||
struct call_video_caps caps = {0};
|
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);
|
assert(callbacks && callbacks->writable); callbacks->writable(callback_arg, 1);
|
||||||
uint8_t data[8][16]; struct call_video_frame frames[8];
|
uint8_t data[8][16]; struct call_video_frame frames[8];
|
||||||
for (unsigned i = 0; i < 8; ++i) {
|
for (unsigned i = 0; i < 8; ++i) {
|
||||||
@@ -56,20 +56,27 @@ int main(void) {
|
|||||||
extra = frames[7]; concurrent = 1; allowance = 2;
|
extra = frames[7]; concurrent = 1; allowance = 2;
|
||||||
assert(call_video_port_send(frames, 8) == 1);
|
assert(call_video_port_send(frames, 8) == 1);
|
||||||
memset(data, 0, sizeof(data)); // Порт обязан владеть собственной копией.
|
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);
|
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;
|
struct call_video_port_status status;
|
||||||
assert(!call_video_port_status(7, &status) && !status.can_encode && !status.key_serial);
|
assert(!call_video_port_status(7, &status) && !status.can_encode && !status.key_serial);
|
||||||
for (unsigned i = 0; i < 3; ++i) {
|
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);
|
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(accepted == 8 && !port.tx_count);
|
||||||
assert(!call_video_port_status(7, &status) && status.can_encode && !status.key_serial);
|
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");
|
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);
|
for (unsigned i = 0; i < 8; ++i) { assert(callbacks->receive_ready(callback_arg, 16)); callbacks->frame(callback_arg, &frames[i]); }
|
||||||
call_video_port_detach(&inst); uasync_drain_immediate(ua);
|
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;
|
uasync_destroy(ua, 0); return 0;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user