[vlc-devel] [PATCH 3/5] android: util: init ASurfaceTexture from Java
Thomas Guillem
thomas at gllm.fr
Tue Apr 28 16:30:54 CEST 2020
On Tue, Apr 28, 2020, at 12:57, Thomas Guillem wrote:
>
>
> On Mon, Apr 27, 2020, at 23:28, Louis Regnier wrote:
> > When the native SurfaceTexture API is available, construct a SurfaceTexture
> > object from Java through JNI calls and store the producer side
> > (Surface/ANativeWindow) for the AWindowHandler clients.
> >
> > The SurfaceTexture constructor is only available since API 26 but the NDK
> > API for ASurfaceTexture already require API 28
> > ---
> > modules/video_output/android/utils.c | 97 ++++++++++++++++++++++++++--
> > 1 file changed, 92 insertions(+), 5 deletions(-)
> >
> > diff --git a/modules/video_output/android/utils.c
> > b/modules/video_output/android/utils.c
> > index 8a300b05bb..62d5ba16b0 100644
> > --- a/modules/video_output/android/utils.c
> > +++ b/modules/video_output/android/utils.c
> > @@ -77,6 +77,7 @@ struct AWindowHandler
> > native_window_api_t anw_api;
> >
> > struct ASurfaceTextureAPI ast_api;
> > + bool b_has_ast_api;
>
> This variable name is confusing. It seem to be used to identify if the
> NDK API is present. Why not adding ndk in the var name ?
> Also, when is this variable set to true ?
>
> >
> > struct {
> > awh_events_t cb;
> > @@ -100,6 +101,8 @@ static struct
> > jmethodID setVideoLayout;
> > } AndroidNativeWindow;
> > struct {
> > + jclass clazz;
> > + jmethodID constructor;
> > jmethodID attachToGLContext;
> > jmethodID detachFromGLContext;
> > jmethodID waitAndUpdateTexImage;
>
> This is misleading but it is my fault.
> The methods from the SurfaceTexture struct are methods of the AWindow
> class.
> The methods from the AndroidNativeWindow struct are methods of the
> AWindow class.
> Therefore, both struct should be first merged and name AWindow.
>
> Then you could add clazz and constructor on the SurfaceTexture struct
> that will be methods/class of the SurfaceTexture class.
>
> > @@ -284,6 +287,30 @@ LoadNativeSurfaceAPI(AWindowHandler *p_awh)
> > * Android ASurfaceTexture Android NDK
> > */
> >
> > +#define GET_CLASS(clazz, str, b_globlal) do { \
> > + (clazz) = (*env)->FindClass(env, (str)); \
> > + if (!(clazz)) { \
> > + return -1; \
> > + } \
> > + if (b_globlal) { \
> > + (clazz) = (jclass) (*env)->NewGlobalRef(env, (clazz)); \
>
> You leak a local ref, you should call (*env)->DeleteLocalRef(env,
> clazz); after getting the global ref (and use an other class var).
>
>
> > + if (!(clazz)) { \
> > + return -1; \
> > + } \
> > + } \
> > +} while (0)
>
> THis macro is used only one time, and could be removed.
>
> > +
> > +static int JNI_getSurfaceTexture(JNIEnv *env)
> > +{
> > + GET_CLASS(jfields.SurfaceTexture.clazz,
> > "android/graphics/SurfaceTexture", true);
> > +
> > + jfields.SurfaceTexture.constructor =
> > + (*env)->GetMethodID(env, jfields.SurfaceTexture.clazz,
> > "<init>", "(Z)V");
> > + if (jfields.SurfaceTexture.constructor == NULL)
> > + return -1;
> > + return 0;
>
> I think you could put direcly the content of this function in
> LoadSurfaceTextureAPI().
>
> > +}
> > +
> > static int
> > LoadSurfaceTextureAPI(AWindowHandler *p_awh, void *p_library)
> > {
> > @@ -327,7 +354,7 @@ LoadSurfaceTextureAPI(AWindowHandler *p_awh, void
> > *p_library)
> > */
> >
> > static void
> > -LoadNativeWindowAPI(AWindowHandler *p_awh)
> > +LoadNativeWindowAPI(AWindowHandler *p_awh, JNIEnv *p_env)
> > {
> > void *p_library = dlopen("libandroid.so", RTLD_NOW);
> > if (!p_library)
> > @@ -346,7 +373,9 @@ LoadNativeWindowAPI(AWindowHandler *p_awh)
> > && p_awh->anw_api.winLock && p_awh->anw_api.unlockAndPost
> > && p_awh->anw_api.setBuffersGeometry)
> > {
> > - LoadSurfaceTextureAPI(p_awh, p_library);
> > + if (LoadSurfaceTextureAPI(p_awh, p_library) == VLC_SUCCESS)
> > + JNI_getSurfaceTexture(p_env);
> > + p_awh->b_has_ast_api = false;
> > p_awh->p_anw_dl = p_library;
> > }
> > else
> > @@ -593,7 +622,7 @@ AWindowHandler_new(vout_window_t *wnd, awh_events_t
> > *p_events)
> > free(p_awh);
> > return NULL;
> > }
> > - LoadNativeWindowAPI(p_awh);
> > + LoadNativeWindowAPI(p_awh, p_env);
> >
> > p_awh->b_has_video_layout_listener =
> > flags & AWINDOW_REGISTER_FLAGS_HAS_VIDEO_LAYOUT_LISTENER;
> > @@ -642,6 +671,18 @@ AWindowHandler_destroy(AWindowHandler *p_awh)
> >
> > if (p_env)
> > {
> > + if (p_awh->b_has_ast_api)
> > + {
> > + AWindowHandler_releaseANativeWindowEnv(p_awh, p_env,
> > AWindow_SurfaceTexture);
> > + (*p_env)->DeleteGlobalRef(p_env,
> > p_awh->ast_api.surfacetexture);
> > + if (p_awh->ast_api.p_ast != NULL)
> > + {
> > + p_awh->ast_api.pf_releaseAst(p_awh->ast_api.p_ast);
> > + p_awh->ast_api.p_ast = NULL;
> > + }
> > + (*p_env)->DeleteGlobalRef(p_env,
> > jfields.SurfaceTexture.clazz);
> > + }
> > +
> > JNI_ANWCALL(CallVoidMethod, unregisterNative);
> > AWindowHandler_releaseANativeWindowEnv(p_awh, p_env,
> > AWindow_Video);
> > AWindowHandler_releaseANativeWindowEnv(p_awh, p_env,
> > AWindow_Subtitles);
> > @@ -661,6 +702,46 @@ AWindowHandler_getANativeWindowAPI(AWindowHandler
> > *p_awh)
> > return &p_awh->anw_api;
> > }
> >
> > +static jobject InitSurfaceTextureNDK(AWindowHandler *p_awh, JNIEnv
> > *p_env,
> > + enum AWindow_ID id)
> > +{
> > + jobject surfacetexture = (*p_env)->NewObject(p_env,
> > + jfields.SurfaceTexture.clazz,
> > jfields.SurfaceTexture.constructor, false);
> > +
> > + if (surfacetexture == NULL)
> > + goto error;
> > +
> > + p_awh->ast_api.surfacetexture = (*p_env)->NewGlobalRef(p_env,
> > surfacetexture);
>
> You leak a local ref, you should call (*env)->DeleteLocalRef(env,
> surfacetexture); after getting the global ref.
Ah no, you release it at the end of this function.
>
> > +
> > + p_awh->ast_api.p_ast = p_awh->ast_api.pf_astFromst(p_env,
> > + p_awh->ast_api.surfacetexture);
> > + if (p_awh->ast_api.p_ast == NULL)
> > + goto error;
> > +
> > + p_awh->views[id].p_anw =
> > p_awh->ast_api.pf_acquireAnw(p_awh->ast_api.p_ast);
> > + if (p_awh->views[id].p_anw == NULL)
> > + goto error;
> > +
> > + jobject jsurface = p_awh->ast_api.pf_anwToSurface(p_env,
> > p_awh->views[id].p_anw);
> > + if (jsurface == NULL)
> > + goto error;
> > + (*p_env)->DeleteLocalRef(p_env, surfacetexture);
> > + return jsurface;
> > +
> > +error:
> > + if (surfacetexture == NULL)
> > + return NULL;
> > + (*p_env)->DeleteLocalRef(p_env, surfacetexture);
> > + p_awh->ast_api.surfacetexture = (*p_env)->NewGlobalRef(p_env,
> > surfacetexture);
> > + if (p_awh->ast_api.p_ast == NULL)
> > + return NULL;
> > + p_awh->ast_api.pf_releaseAst(p_awh->ast_api.p_ast);
> > + if (p_awh->views[id].p_anw == NULL)
> > + return NULL;
> > + AWindowHandler_releaseANativeWindow(p_awh, id);
> > + return NULL;
> > +}
> > +
> > static int
> > WindowHandler_NewSurfaceEnv(AWindowHandler *p_awh, JNIEnv *p_env,
> > enum AWindow_ID id)
> > @@ -676,8 +757,13 @@ WindowHandler_NewSurfaceEnv(AWindowHandler *p_awh,
> > JNIEnv *p_env,
> > jsurface = JNI_ANWCALL(CallObjectMethod,
> > getSubtitlesSurface);
> > break;
> > case AWindow_SurfaceTexture:
> > - jsurface = JNI_STEXCALL(CallObjectMethod, getSurface);
> > + {
> > + if (p_awh->b_has_ast_api)
> > + jsurface = InitSurfaceTextureNDK(p_awh, p_env, id);
> > + else
> > + jsurface = JNI_STEXCALL(CallObjectMethod, getSurface);
> > break;
> > + }
> > default:
> > vlc_assert_unreachable();
> > }
> > @@ -707,7 +793,8 @@ AWindowHandler_getANativeWindow(AWindowHandler
> > *p_awh, enum AWindow_ID id)
> > return NULL;
> > assert(p_awh->views[id].jsurface != NULL);
> >
> > - p_awh->views[id].p_anw = p_awh->pf_winFromSurface(p_env,
> > + if (!p_awh->b_has_ast_api || id != AWindow_SurfaceTexture)
> > + p_awh->views[id].p_anw = p_awh->pf_winFromSurface(p_env,
> >
> > p_awh->views[id].jsurface);
> > return p_awh->views[id].p_anw;
> > }
> > --
> > 2.26.2
> >
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list