Browse Source

Проверить готовую пачку GPU через транспорт и обновить JNI видеопорта

stream-multiview
evgeny 6 days ago
parent
commit
66526ad4a5
  1. 23
      tests/test_call.c
  2. 2
      tools/chatgui-android/jni_bridge/android_call_video_jni.c
  3. 5
      tools/chatgui/src/call_video_engine.cpp

23
tests/test_call.c

@ -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); // Повторное закрытие после отмены команд.

2
tools/chatgui-android/jni_bridge/android_call_video_jni.c

@ -79,7 +79,7 @@ JNIEXPORT jint JNICALL Java_com_utun_chat_data_CallVideoNative_send(
jbyte *data = (*e)->GetByteArrayElements(e, bytes, NULL); if (!data) return -1;
f.call_id = id; f.frame_id = values[9]; f.pts_us = values[10]; f.flags = values[11];
f.size = f.length = size; f.data = (uint8_t *)data;
int result = call_video_port_send(&f); (*e)->ReleaseByteArrayElements(e, bytes, data, JNI_ABORT); return result;
int result = call_video_port_send(&f, 1); (*e)->ReleaseByteArrayElements(e, bytes, data, JNI_ABORT); return result;
}
JNIEXPORT jbyteArray JNICALL Java_com_utun_chat_data_CallVideoNative_pull(JNIEnv *e, jobject o, jlong id, jlongArray meta) {
(void)o;

5
tools/chatgui/src/call_video_engine.cpp

@ -271,12 +271,13 @@ void CallVideoEngine::transmit() {
expired += count; forceKey = true; continue;
}
forceKey = call_video_port_send(packets, count) != 1; }
for (const auto& output : outputs) {
for (unsigned i = 0; i < count; ++i) {
const auto& output = outputs[i];
// Одинаковое окно исходного PTS на всех этапах: примерно один кадр в секунду, без трассы каждого кадра.
if (output.pts % 1000000 < 34000)
DEBUG_DEBUG(DEBUG_CATEGORY_CALL,
"video timing stage=encode call=%llu frame=%llu pts=%lld mono_us=%lld encode_us=%lld accepted=%d",
(unsigned long long)m->id, (unsigned long long)(frameId - count + 1 + &output - outputs.constData()),
(unsigned long long)m->id, (unsigned long long)(frameId - count + i + 1),
(long long)output.pts, (long long)nowUs(),
(long long)(nowUs() - encodeStarted), !forceKey);
}

Loading…
Cancel
Save