Test lossless mailbox retry after partial video transmission
This commit is contained in:
1 parent
322947777c
commit
b11a1beb44
2 files changed
+79
No files matched your search
@@ -12,6 +12,7 @@ check_PROGRAMS = \
|
||||
test_route_tx_stats \
|
||||
test_call_video_rate \
|
||||
test_call_video_playout \
|
||||
test_call_video_port \
|
||||
test_call_video \
|
||||
test_call_video_flush \
|
||||
test_memory_pool_and_config \
|
||||
@@ -718,6 +719,9 @@ test_call_video_rate_LDADD = $(LIBUTUN) $(COMMON_LIBS)
|
||||
test_call_video_playout_SOURCES = test_call_video_playout.c
|
||||
test_call_video_playout_LDADD = $(LIBUTUN) $(COMMON_LIBS)
|
||||
|
||||
test_call_video_port_SOURCES = test_call_video_port.c
|
||||
test_call_video_port_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
|
||||
|
||||
test_call_video_SOURCES = test_call_video.c
|
||||
test_call_video_LDADD = $(LIBUTUN) $(COMMON_LIBS)
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/* Реальные mailbox/mutex/post: частичная передача, повторная занятость, конкурентный producer и отмена. */
|
||||
#define call_video_send_frame test_video_send
|
||||
#define call_video_configure test_video_configure
|
||||
#define call_session_find test_session_find
|
||||
#define chat_setting_get test_setting_get
|
||||
#include "../src/call/call_video_port.c"
|
||||
#undef call_video_send_frame
|
||||
#undef call_video_configure
|
||||
#undef call_session_find
|
||||
#undef chat_setting_get
|
||||
#include <assert.h>
|
||||
|
||||
static struct call_session session;
|
||||
static const struct call_video_ops *callbacks;
|
||||
static void *callback_arg;
|
||||
static unsigned accepted, allowance, offered;
|
||||
static int concurrent;
|
||||
static struct call_video_frame extra;
|
||||
|
||||
struct call_session *test_session_find(struct call_ctx *ctx, uint64_t id) {
|
||||
return ctx == session.ctx && id == session.call_id ? &session : NULL;
|
||||
}
|
||||
const char *test_setting_get(struct UTUN_INSTANCE *inst, const char *name) {
|
||||
(void)inst; (void)name; return "300:4000";
|
||||
}
|
||||
int test_video_configure(struct UTUN_INSTANCE *inst, uint64_t id, const struct call_video_caps *caps,
|
||||
const struct call_video_ops *ops, void *arg) {
|
||||
(void)inst; (void)id; (void)caps; callbacks = ops; callback_arg = arg; return 0;
|
||||
}
|
||||
int test_video_send(struct UTUN_INSTANCE *inst, const struct call_video_frame *f) {
|
||||
(void)inst; offered++;
|
||||
if (concurrent) { assert(call_video_port_send(&extra, 1) == 0); concurrent = 0; }
|
||||
if (accepted == allowance) return 0;
|
||||
assert(f->frame_id == accepted + 1 && f->pts_us == (int64_t)f->frame_id * 33333);
|
||||
assert(f->size == 16);
|
||||
for (unsigned i = 0; i < f->size; ++i) assert(f->data[i] == f->frame_id);
|
||||
accepted++; return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO);
|
||||
struct UASYNC *ua = uasync_create(); assert(ua);
|
||||
struct UTUN_INSTANCE inst = {.ua = ua}; struct call_ctx ctx = {.inst = &inst}; inst.call = &ctx;
|
||||
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(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) {
|
||||
memset(data[i], i + 1, sizeof(data[i]));
|
||||
frames[i] = (struct call_video_frame){.call_id = 7, .frame_id = i + 1, .pts_us = (i + 1) * 33333,
|
||||
.format = {1, 640, 480, 30, 0, CALL_VIDEO_H264, 31, 4000000, CALL_VIDEO_BASELINE},
|
||||
.size = 16, .length = 16, .data = data[i]};
|
||||
}
|
||||
extra = frames[7]; concurrent = 1; allowance = 2;
|
||||
assert(call_video_port_send(frames, 8) == 1);
|
||||
memset(data, 0, sizeof(data)); // Порт обязан владеть собственной копией.
|
||||
uasync_drain_immediate(ua);
|
||||
assert(accepted == 2 && port.tx_count == 6 && !port.tx_processing && !port.pending);
|
||||
unsigned before = offered; uasync_drain_immediate(ua); 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);
|
||||
assert(accepted == 2 && port.tx_count == 6 && !port.pending);
|
||||
}
|
||||
allowance = 8; callbacks->writable(callback_arg, 1); uasync_drain_immediate(ua);
|
||||
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);
|
||||
uasync_destroy(ua, 0); return 0;
|
||||
}
|
||||
Reference in new issue
Block a user