|
|
|
|
@ -151,8 +151,9 @@ static unsigned g_video_keys[2];
|
|
|
|
|
static int g_port_frame; |
|
|
|
|
static void port_received(void *arg, const struct call_video_frame *f) { |
|
|
|
|
(void)arg; |
|
|
|
|
g_port_frame = f->frame_id == 1 && f->format.generation == 1 && f->size == sizeof(g_video_data) |
|
|
|
|
&& !memcmp(f->data, g_video_data, sizeof(g_video_data)) ? 1 : -1; |
|
|
|
|
if (g_port_frame >= 0 && f->frame_id == (uint64_t)g_port_frame + 1 && f->format.generation == 1 |
|
|
|
|
&& f->size == sizeof(g_video_data) && !memcmp(f->data, g_video_data, sizeof(g_video_data))) ++g_port_frame; |
|
|
|
|
else g_port_frame = -1; |
|
|
|
|
} |
|
|
|
|
static void video_caps(void *arg, const struct call_video_caps *caps) { g_video_peer[(size_t)arg] = *caps; } |
|
|
|
|
static void video_need_key(void *arg) { g_video_keys[(size_t)arg]++; } |
|
|
|
|
@ -684,8 +685,15 @@ static void call_tick(void* arg) {
|
|
|
|
|
struct call_video_port_status status; |
|
|
|
|
if (call_video_port_status(t->call_id, &status) || status.configured_generation != 1) break; |
|
|
|
|
struct call_video_frame f = video_test_frame(t->call_id, 1); |
|
|
|
|
struct call_video_frame batch[3] = {f, f, f}; |
|
|
|
|
for (unsigned i = 1; i < 3; ++i) { batch[i].frame_id += i; batch[i].pts_us += i * 33333; batch[i].flags = 0; } |
|
|
|
|
++batch[1].call_id; |
|
|
|
|
if (call_video_port_send(batch, 3) != -1) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port accepted mixed-call batch"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
--batch[1].call_id; |
|
|
|
|
if (status.minimum_bps != 300000 || status.maximum_bps != 500000 |
|
|
|
|
|| call_video_port_send(&f) != 1 || call_video_port_send(&f) != 0) { |
|
|
|
|
|| call_video_port_send(batch, 3) != 1 || call_video_port_send(batch, 3) != 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port TX mailbox/range mismatch"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
struct call_capture_time timing = sent_timing; timing.pts_us += 200000; |
|
|
|
|
@ -695,7 +703,8 @@ static void call_tick(void* arg) {
|
|
|
|
|
} |
|
|
|
|
case P_VIDEO_PORT_ACK: { |
|
|
|
|
if (!g_port_frame) break; |
|
|
|
|
if (g_port_frame != 1) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port TX payload mismatch"); t->result = 2; break; } |
|
|
|
|
if (g_port_frame < 0) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video port TX payload mismatch"); t->result = 2; break; } |
|
|
|
|
if (g_port_frame != 3) break; |
|
|
|
|
if (call_video_decode_result(A, t->call_id, 1, 1) |
|
|
|
|
|| call_video_decode_result(A, t->call_id, 2, 0) != -1) { t->result = 2; break; } |
|
|
|
|
t->phase = P_VIDEO_DECODE_OK; break; |
|
|
|
|
@ -710,12 +719,12 @@ static void call_tick(void* arg) {
|
|
|
|
|
struct call_video_port_status status; |
|
|
|
|
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 = 2; f.pts_us += 33333; |
|
|
|
|
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; } |
|
|
|
|
// Все команды попадут в uasync после синхронного ENDED; TX ещё принадлежит mailbox.
|
|
|
|
|
if (call_video_port_format(t->call_id, &f.format, 500000) |
|
|
|
|
|| call_video_port_applied(t->call_id, 1, 1, 500000) |
|
|
|
|
|| call_video_port_decoded(t->call_id, 1, 1) || call_video_port_send(&f) != 1) { |
|
|
|
|
|| call_video_port_decoded(t->call_id, 1, 1) || call_video_port_send(&f, 1) != 1) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video teardown commands were not queued"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
call_video_port_request_key(t->call_id); |
|
|
|
|
@ -731,7 +740,7 @@ static void call_tick(void* arg) {
|
|
|
|
|
case P_VIDEO_PORT_CANCELLED: { |
|
|
|
|
struct call_video_port_status status; |
|
|
|
|
struct call_video_frame f = video_test_frame(t->call_id, 1); |
|
|
|
|
if (call_video_port_status(t->call_id, &status) != -1 || call_video_port_send(&f) != -1 || g_port_frame != 1) { |
|
|
|
|
if (call_video_port_status(t->call_id, &status) != -1 || call_video_port_send(&f, 1) != -1 || g_port_frame != 3) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "ended video port retained commands or accepted a late frame"); t->result = 2; break; |
|
|
|
|
} |
|
|
|
|
call_video_port_close(t->call_id); // Повторное закрытие после отмены команд.
|
|
|
|
|
|