|
|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|