|
|
|
|
@ -65,6 +65,7 @@ enum call_phase {
|
|
|
|
|
P_WAIT_MEDIA, /* B: media_recv_cb получил кадр */ |
|
|
|
|
P_VIDEO_CONFIG, P_VIDEO_SEND, P_VIDEO_HOLD, P_VIDEO_BUSY, P_VIDEO_RESUME, P_VIDEO_RANGE_WAIT, P_VIDEO_SWITCH, P_VIDEO_SWITCH_WAIT, |
|
|
|
|
P_VIDEO_SHRINK_WAIT, P_VIDEO_PORT_OPEN, P_VIDEO_PORT_RECEIVE, P_VIDEO_PORT_SEND, P_VIDEO_PORT_ACK, |
|
|
|
|
P_VIDEO_DECODE_OK, P_VIDEO_DECODE_REJECT, |
|
|
|
|
P_HANGUP, /* A: call_hangup */ |
|
|
|
|
P_WAIT_ENDED1, /* обе ENDED */ |
|
|
|
|
P_CALL2_START, /* A: call_start (2-й звонок) */ |
|
|
|
|
@ -650,10 +651,25 @@ 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 (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; |
|
|
|
|
} |
|
|
|
|
case P_VIDEO_DECODE_OK: { |
|
|
|
|
struct call_video_port_status status; |
|
|
|
|
if (call_video_port_status(t->call_id, &status) || status.decoded_generation != 1) break; |
|
|
|
|
if (!status.decoded_accepted || call_video_decode_result(A, t->call_id, 1, 0)) { t->result = 2; break; } |
|
|
|
|
t->phase_ticks = 0; t->phase = P_VIDEO_DECODE_REJECT; break; |
|
|
|
|
} |
|
|
|
|
case P_VIDEO_DECODE_REJECT: { |
|
|
|
|
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; |
|
|
|
|
if (call_video_send_frame(B, &f) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video ignored decoder rejection"); t->result = 2; break; } |
|
|
|
|
call_video_port_request_key(t->call_id); |
|
|
|
|
call_video_port_close(t->call_id); |
|
|
|
|
call_video_port_detach(B); // Отменяет уже поставленный post до destroy ядра.
|
|
|
|
|
struct call_video_port_status status; |
|
|
|
|
if (call_video_port_status(t->call_id, &status) != -1) { t->result = 2; break; } |
|
|
|
|
t->phase = P_HANGUP; break; |
|
|
|
|
} |
|
|
|
|
|