Skip to content
Snippets Groups Projects
Commit 53fbc0a6 authored by Adrien Béraud's avatar Adrien Béraud
Browse files

android video: use sinkclient custom buffer to avoid copy

Pixel 4 XL, 720p:
before: 6.69 ms (14,9 fps)
after: 5.92 ms (16,9 fps)

Change-Id: I8a2bdbed7388efbf95b066ace2f8032684a87a2e
parent aa144f38
No related branches found
No related tags found
No related merge requests found
...@@ -290,7 +290,6 @@ JNIEXPORT jlong JNICALL Java_net_jami_daemon_JamiServiceJNI_acquireNativeWindow( ...@@ -290,7 +290,6 @@ JNIEXPORT jlong JNICALL Java_net_jami_daemon_JamiServiceJNI_acquireNativeWindow(
JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_releaseNativeWindow(JNIEnv *jenv, jclass jcls, jlong window_) JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_releaseNativeWindow(JNIEnv *jenv, jclass jcls, jlong window_)
{ {
std::lock_guard<std::mutex> guard(windows_mutex);
ANativeWindow *window = (ANativeWindow*)((intptr_t) window_); ANativeWindow *window = (ANativeWindow*)((intptr_t) window_);
ANativeWindow_release(window); ANativeWindow_release(window);
} }
...@@ -298,37 +297,17 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_releaseNativeWindow(J ...@@ -298,37 +297,17 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_releaseNativeWindow(J
JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_setNativeWindowGeometry(JNIEnv *jenv, jclass jcls, jlong window_, int width, int height) JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_setNativeWindowGeometry(JNIEnv *jenv, jclass jcls, jlong window_, int width, int height)
{ {
ANativeWindow *window = (ANativeWindow*)((intptr_t) window_); ANativeWindow *window = (ANativeWindow*)((intptr_t) window_);
ANativeWindow_setBuffersGeometry(window, width, height, WINDOW_FORMAT_RGBA_8888); ANativeWindow_setBuffersGeometry(window, width, height, WINDOW_FORMAT_RGBX_8888);
} }
void AndroidDisplayCb(ANativeWindow *window, std::unique_ptr<DRing::FrameBuffer> frame) void AndroidDisplayCb(ANativeWindow *window, std::unique_ptr<DRing::FrameBuffer> frame)
{ {
std::unique_lock<std::mutex> guard(windows_mutex, std::defer_lock);
if (!guard.try_lock())
return;
try {
auto& i = windows.at(window);
ANativeWindow_Buffer buffer;
if (ANativeWindow_lock(window, &buffer, NULL) == 0) {
if (buffer.bits && frame && frame->ptr) {
if (buffer.stride == frame->width)
memcpy(buffer.bits, frame->ptr, frame->width * frame->height * 4);
else {
size_t line_size_in = frame->width * 4;
size_t line_size_out = buffer.stride * 4;
for (size_t i=0, n=frame->height; i<n; i++)
memcpy((uint8_t*)buffer.bits + line_size_out * i, frame->ptr + line_size_in * i, line_size_in);
}
}
else
__android_log_print(ANDROID_LOG_WARN, TAG, "Can't copy surface");
ANativeWindow_unlockAndPost(window); ANativeWindow_unlockAndPost(window);
} else { std::unique_lock<std::mutex> guard(windows_mutex);
__android_log_print(ANDROID_LOG_WARN, TAG, "Can't lock surface"); try {
} windows.at(window) = std::move(frame);
i = std::move(frame);
} catch (...) { } catch (...) {
__android_log_print(ANDROID_LOG_WARN, TAG, "Can't copy frame: no window"); __android_log_print(ANDROID_LOG_WARN, TAG, "Can't move frame: no window");
} }
} }
...@@ -340,17 +319,20 @@ std::unique_ptr<DRing::FrameBuffer> sinkTargetPullCallback(ANativeWindow *window ...@@ -340,17 +319,20 @@ std::unique_ptr<DRing::FrameBuffer> sinkTargetPullCallback(ANativeWindow *window
std::lock_guard<std::mutex> guard(windows_mutex); std::lock_guard<std::mutex> guard(windows_mutex);
ret = std::move(windows.at(window)); ret = std::move(windows.at(window));
} }
if (not ret) { if (ret) {
__android_log_print(ANDROID_LOG_WARN, TAG, "Creating new video buffer of %zu kib", bytes/1024); ANativeWindow_Buffer buffer;
ret.reset(new DRing::FrameBuffer()); if (ANativeWindow_lock(window, &buffer, nullptr) == 0) {
ret->avframe->format = AV_PIX_FMT_RGBA;
ret->avframe->width = buffer.width;
ret->avframe->height = buffer.height;
ret->avframe->data[0] = (uint8_t *) buffer.bits;
ret->avframe->linesize[0] = buffer.stride * 4;
} }
ret->storage.resize(bytes);
ret->ptr = ret->storage.data();
ret->ptrSize = bytes;
return ret; return ret;
}
} catch (...) { } catch (...) {
return {};
} }
return {};
} }
JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_registerVideoCallback(JNIEnv *jenv, jclass jcls, jstring sinkId, jlong window) JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_registerVideoCallback(JNIEnv *jenv, jclass jcls, jstring sinkId, jlong window)
...@@ -371,7 +353,9 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_registerVideoCallback ...@@ -371,7 +353,9 @@ JNIEXPORT void JNICALL Java_net_jami_daemon_JamiServiceJNI_registerVideoCallback
{ {
std::lock_guard<std::mutex> guard(windows_mutex); std::lock_guard<std::mutex> guard(windows_mutex);
windows.emplace(nativeWindow, nullptr); auto buf = std::make_unique<DRing::FrameBuffer>();
buf->avframe.reset(av_frame_alloc());
windows.emplace(nativeWindow, std::move(buf));
} }
DRing::registerSinkTarget(sink, DRing::SinkTarget {.pull=p_display_cb, .push=f_display_cb}); DRing::registerSinkTarget(sink, DRing::SinkTarget {.pull=p_display_cb, .push=f_display_cb});
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment