[vlc-devel] [PATCH 13/17] android: make AWindowHandler work without AWindow
Alexandre Janniaux
ajanni at videolabs.io
Wed Jan 13 11:07:26 UTC 2021
From: Romain Vimont <rom1v at videolabs.io>
AWindowHandler_new() failed if no instance were registered in the VLC
variable "drawable-androidwindow".
The official Android app registers an instance here, but other libvlc
clients may not need it (e.g. for offscreen encoding).
Co-authored-by: Alexandre Janniaux <ajanni at videolabs.io>
---
modules/video_output/android/utils.c | 64 ++++++++++++++++------------
1 file changed, 37 insertions(+), 27 deletions(-)
diff --git a/modules/video_output/android/utils.c b/modules/video_output/android/utils.c
index 89c702a06b..1172b6c16b 100644
--- a/modules/video_output/android/utils.c
+++ b/modules/video_output/android/utils.c
@@ -703,28 +703,31 @@ InitJNIFields(JNIEnv *env, vlc_object_t *p_obj, jobject *jobj, AWindowHandler *a
CHECK_EXCEPTION("GetMethodID("str")", critical); \
} while( 0 )
- clazz = (*env)->GetObjectClass(env, jobj);
- CHECK_EXCEPTION("AndroidNativeWindow clazz", true);
-
- awh->jfields.AWindow.clazz = (*env)->NewGlobalRef(env, clazz);
- (*env)->DeleteLocalRef(env, clazz);
-
- GET_METHOD(AWindow, getVideoSurface,
- "getVideoSurface", "()Landroid/view/Surface;", true);
- GET_METHOD(AWindow, getSubtitlesSurface,
- "getSubtitlesSurface", "()Landroid/view/Surface;", true);
- GET_METHOD(AWindow, registerNative,
- "registerNative", "(J)I", true);
- GET_METHOD(AWindow, unregisterNative,
- "unregisterNative", "()V", true);
- GET_METHOD(AWindow, setVideoLayout,
- "setVideoLayout", "(IIIIII)V", true);
-
- if ((*env)->RegisterNatives(env, awh->jfields.AWindow.clazz, jni_callbacks, 2) < 0)
+ if (jobj)
{
- msg_Err(p_obj, "RegisterNatives failed");
- i_init_state = 0;
- goto end;
+ clazz = (*env)->GetObjectClass(env, jobj);
+ CHECK_EXCEPTION("AndroidNativeWindow clazz", true);
+
+ awh->jfields.AWindow.clazz = (*env)->NewGlobalRef(env, clazz);
+ (*env)->DeleteLocalRef(env, clazz);
+
+ GET_METHOD(AWindow, getVideoSurface,
+ "getVideoSurface", "()Landroid/view/Surface;", true);
+ GET_METHOD(AWindow, getSubtitlesSurface,
+ "getSubtitlesSurface", "()Landroid/view/Surface;", true);
+ GET_METHOD(AWindow, registerNative,
+ "registerNative", "(J)I", true);
+ GET_METHOD(AWindow, unregisterNative,
+ "unregisterNative", "()V", true);
+ GET_METHOD(AWindow, setVideoLayout,
+ "setVideoLayout", "(IIIIII)V", true);
+
+ if ((*env)->RegisterNatives(env, awh->jfields.AWindow.clazz, jni_callbacks, 2) < 0)
+ {
+ msg_Err(p_obj, "RegisterNatives failed");
+ i_init_state = 0;
+ goto end;
+ }
}
awh->jfields.SurfaceTexture.clazz = NULL;
@@ -820,7 +823,7 @@ AWindowHandler_new(vlc_object_t *obj, vout_window_t *wnd, awh_events_t *p_events
JavaVM *p_jvm = var_InheritAddress(obj, "android-jvm");
jobject jobj = var_InheritAddress(obj, "drawable-androidwindow");
- if (!p_jvm || !jobj)
+ if (!p_jvm)
{
msg_Err(obj, "libvlc_media_player options not set");
return NULL;
@@ -838,7 +841,7 @@ AWindowHandler_new(vlc_object_t *obj, vout_window_t *wnd, awh_events_t *p_events
return NULL;
p_awh->p_jvm = p_jvm;
- p_awh->jobj = (*p_env)->NewGlobalRef(p_env, jobj);
+ p_awh->jobj = jobj ? (*p_env)->NewGlobalRef(p_env, jobj) : NULL;
/* Zero the jfields structure before usage. */
p_awh->jfields = (struct vlc_android_jfields) { .AWindow.clazz = NULL };
@@ -873,7 +876,8 @@ AWindowHandler_new(vlc_object_t *obj, vout_window_t *wnd, awh_events_t *p_events
if ((flags & AWINDOW_REGISTER_FLAGS_SUCCESS) == 0)
{
msg_Err(obj, "AWindow already registered");
- (*p_env)->DeleteGlobalRef(p_env, p_awh->jobj);
+ if (p_awh->jobj)
+ (*p_env)->DeleteGlobalRef(p_env, p_awh->jobj);
(*p_env)->DeleteGlobalRef(p_env, p_awh->stex.jtransform_mtx_array);
free(p_awh);
return NULL;
@@ -933,10 +937,12 @@ AWindowHandler_destroy(AWindowHandler *p_awh)
if (p_awh->jfields.Surface.clazz)
(*p_env)->DeleteGlobalRef(p_env, p_awh->jfields.Surface.clazz);
- JNI_ANWCALL(CallVoidMethod, unregisterNative);
+ if (p_awh->jobj)
+ JNI_ANWCALL(CallVoidMethod, unregisterNative);
AWindowHandler_releaseANativeWindowEnv(p_awh, p_env, AWindow_Video);
AWindowHandler_releaseANativeWindowEnv(p_awh, p_env, AWindow_Subtitles);
- (*p_env)->DeleteGlobalRef(p_env, p_awh->jobj);
+ if (p_awh->jobj)
+ (*p_env)->DeleteGlobalRef(p_env, p_awh->jobj);
}
if (p_awh->p_anw_dl)
@@ -1181,9 +1187,13 @@ WindowHandler_NewSurfaceEnv(AWindowHandler *p_awh, JNIEnv *p_env,
switch (id)
{
case AWindow_Video:
+ if (p_awh->wnd == NULL) return VLC_EGENERIC;
+ assert(p_awh->jfields.AWindow.getVideoSurface != NULL);
jsurface = JNI_ANWCALL(CallObjectMethod, getVideoSurface);
break;
case AWindow_Subtitles:
+ if (p_awh->wnd == NULL) return VLC_EGENERIC;
+ assert(p_awh->jfields.AWindow.getSubtitlesSurface!= NULL);
jsurface = JNI_ANWCALL(CallObjectMethod, getSubtitlesSurface);
break;
default:
@@ -1273,7 +1283,7 @@ AndroidNativeWindow_onWindowSize(JNIEnv* env, jobject clazz, jlong handle,
bool
AWindowHandler_canSetVideoLayout(AWindowHandler *p_awh)
{
- return p_awh->b_has_video_layout_listener;
+ return p_awh->b_has_video_layout_listener && p_awh->wnd != NULL;
}
int
--
2.30.0
More information about the vlc-devel
mailing list