|
|
|
|
@ -26,9 +26,9 @@ struct android_stream_opus {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamOpen( |
|
|
|
|
JNIEnv *env, jobject obj, jlong id, jlong group, jlong source, jint width, jint height, jint rotation, jboolean audio, jlong epoch) { |
|
|
|
|
JNIEnv *env, jobject obj, jlong id, jlong group, jlong source, jint width, jint height, jint rotation, jboolean audio, jlong epoch, jint codec) { |
|
|
|
|
(void)env; (void)obj; |
|
|
|
|
return android_stream_open((uint64_t)id, (uint64_t)group, (uint64_t)source, width, height, rotation, audio, (uint64_t)epoch) == 0; |
|
|
|
|
return android_stream_open((uint64_t)id, (uint64_t)group, (uint64_t)source, width, height, rotation, audio, (uint64_t)epoch, codec) == 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamWatch(JNIEnv *env, jobject obj, jlong group) { |
|
|
|
|
@ -38,7 +38,7 @@ JNIEXPORT jboolean JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamWatch(J
|
|
|
|
|
|
|
|
|
|
JNIEXPORT jint JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamFeed( |
|
|
|
|
JNIEnv *env, jobject obj, jlong id, jboolean video, jlong pts, jboolean key, jbyteArray data, |
|
|
|
|
jlong revision, jint width, jint height, jint rotation, jboolean audio) { |
|
|
|
|
jlong revision, jint width, jint height, jint rotation, jboolean audio, jint video_codec) { |
|
|
|
|
(void)obj; |
|
|
|
|
if (!data || pts < 0 || (video && (revision <= 0 || revision > UINT32_MAX || width <= 0 || width > 4096 |
|
|
|
|
|| height <= 0 || height > 4096 || rotation < 0 || rotation > 270 || rotation % 90))) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "JNI stream feed missing data/invalid PTS"); return -1; } |
|
|
|
|
@ -46,7 +46,11 @@ JNIEXPORT jint JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamFeed(
|
|
|
|
|
jbyte *bytes = (*env)->GetByteArrayElements(env, data, NULL); |
|
|
|
|
if (!bytes) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "JNI stream feed array access failed"); return -1; } |
|
|
|
|
struct stream_media_format format = {(uint16_t)width, (uint16_t)height, (uint16_t)rotation, |
|
|
|
|
STREAM_MEDIA_H264, audio ? STREAM_MEDIA_OPUS_STEREO : 0, (uint32_t)revision}; |
|
|
|
|
(uint8_t)video_codec, audio ? STREAM_MEDIA_OPUS_STEREO : 0, (uint32_t)revision}; |
|
|
|
|
if (video && (video_codec < STREAM_MEDIA_H264 || video_codec > STREAM_MEDIA_H266)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "JNI video codec invalid id=%d", video_codec); |
|
|
|
|
(*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT); return -1; |
|
|
|
|
} |
|
|
|
|
int result = android_stream_feed((uint64_t)id, video, (uint64_t)pts, key, (const uint8_t *)bytes, (size_t)length, video ? &format : NULL); |
|
|
|
|
(*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT); |
|
|
|
|
return result; |
|
|
|
|
@ -56,6 +60,17 @@ JNIEXPORT void JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamStop(JNIEnv
|
|
|
|
|
(void)env; (void)obj; android_stream_stop((uint64_t)id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JNIEXPORT jlongArray JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamTxStats(JNIEnv *env, jobject obj, jlong id) { |
|
|
|
|
(void)obj; struct android_stream_tx_stats s; |
|
|
|
|
if (android_stream_tx_snapshot((uint64_t)id, &s) < 0) return NULL; |
|
|
|
|
jlong values[] = {s.sample_us, s.video_bytes, s.audio_bytes, s.stream_bytes, s.transport_bytes, |
|
|
|
|
s.inflight_bytes, s.acked_1s, s.total_bytes, s.connections}; |
|
|
|
|
jlongArray result = (*env)->NewLongArray(env, 9); |
|
|
|
|
if (result) (*env)->SetLongArrayRegion(env, result, 0, 9, values); |
|
|
|
|
else DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "JNI TX stats allocation failed"); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_com_utun_chat_data_NativeLib_nativeStreamPull( |
|
|
|
|
JNIEnv *env, jobject obj, jlong id, jlong position, jlong video_ahead, jlong audio_ahead) { |
|
|
|
|
(void)obj; |
|
|
|
|
|