[vlc-devel] [PATCH 1/3] Android utils, OpenGL: load ASurfaceTexture NDK API

Zhao Zhili quinkblack at foxmail.com
Wed Apr 8 16:52:57 CEST 2020



> On Apr 6, 2020, at 5:51 PM, Louis Regnier <louis.videolabs at gmail.com> wrote:
> 
> Implement a new Android NDK API library to manage surfacetexture natively.
> If device is not recent enough to support this API it will fallback to the
> previous JNI API.
> 
> To avoid JNI, we need an access to the SurfaceTexture which is
> initialized in the AWindow.java class in the Android bindings.
> 
> Currently only a Surface (weak reference to the producer side)
> is returned by the AWindow JNI API preventing using the NDK API
> directly.
> 
> First, add those new method bindings from the AWindow object.
> 
> Then, if method exist, dynamically bind the NDK SurfaceTexture API
> to a pointer structure to determine whether it is available.
> Fallback to JNI behaviour if they are not available.
> 
> refs videolan/vlc#20344
> ---
> modules/video_output/android/utils.c | 99 ++++++++++++++++++++++++----
> modules/video_output/android/utils.h |  1 +
> 2 files changed, 86 insertions(+), 14 deletions(-)
> 
> diff --git a/modules/video_output/android/utils.c b/modules/video_output/android/utils.c
> index 2010f13976..7158ec6658 100644
> --- a/modules/video_output/android/utils.c
> +++ b/modules/video_output/android/utils.c
> @@ -25,11 +25,39 @@
> #include <jni.h>
> #include <pthread.h>
> #include <assert.h>
> +#include <android/surface_texture.h>
> +#include <android/surface_texture_jni.h>

Is it necessary to include these header files?

> 
> typedef ANativeWindow* (*ptr_ANativeWindow_fromSurface)(JNIEnv*, jobject);
> typedef ANativeWindow* (*ptr_ANativeWindow_fromSurfaceTexture)(JNIEnv*, jobject);
> typedef void (*ptr_ANativeWindow_release)(ANativeWindow*);
> 
> +typedef void (*ptr_ASurfaceTexture_getTransformMatrix)
> +                                        (ASurfaceTexture *st, float mtx[16]);
> +typedef ASurfaceTexture* (*ptr_ASurfaceTexture_fromSurfaceTexture)
> +                                        (JNIEnv* env, jobject surfacetexture);
> +typedef int (*ptr_ASurfaceTexture_updateTexImage)(ASurfaceTexture* st);
> +typedef int (*ptr_ASurfaceTexture_detachFromGLContext)
> +                                        (ASurfaceTexture *st);
> +typedef int (*ptr_ASurfaceTexture_attachToGLContext)
> +                                        (ASurfaceTexture *st, uint32_t texName);
> +typedef void (*ptr_ASurfaceTexture_release)(ASurfaceTexture *st);
> +
> +struct ASurfaceTextureAPI
> +{
> +    float   transMat[16];
> +
> +    jobject surfacetexture;
> +    ASurfaceTexture *p_ast;
> +
> +    ptr_ASurfaceTexture_updateTexImage pf_updateTexImage;
> +    ptr_ASurfaceTexture_fromSurfaceTexture pf_astFromst;
> +    ptr_ASurfaceTexture_attachToGLContext pf_attachToGL;
> +    ptr_ASurfaceTexture_detachFromGLContext pf_detachFromGL;
> +    ptr_ASurfaceTexture_getTransformMatrix pf_getTransMatrix;
> +    ptr_ASurfaceTexture_release pf_releaseAst;
> +};
> +
> struct AWindowHandler
> {
>     JavaVM *p_jvm;
> @@ -46,6 +74,9 @@ struct AWindowHandler
>     ptr_ANativeWindow_release pf_winRelease;
>     native_window_api_t anw_api;
> 
> +    struct SurfaceTextureHandler st;
> +    struct ASurfaceTextureAPI ast_api;
> +
>     struct {
>         awh_events_t cb;
>     } event;
> @@ -57,20 +88,6 @@ struct AWindowHandler
>     } stex;
> };
> 
> -struct SurfaceTexture
> -{
> -    JavaVM *p_jvm;
> -
> -    void *p_anw_dl;
> -    ptr_ANativeWindow_fromSurface pf_winFromSurface;
> -    ptr_ANativeWindow_release pf_winRelease;
> -
> -    jobject thiz;
> -    jobject jsurface;
> -    ANativeWindow *p_anw;
> -
> -};
> -
> static struct
> {
>     struct {
> @@ -86,6 +103,8 @@ static struct
>         jmethodID detachFromGLContext;
>         jmethodID waitAndUpdateTexImage;
>         jmethodID getSurface;
> +        jmethodID getSurfaceTexture;
> +        jmethodID removeFrameAvailableListener;
>     } SurfaceTexture;
> } jfields;
> 
> @@ -262,6 +281,53 @@ LoadNativeSurfaceAPI(AWindowHandler *p_awh)
>     p_awh->anw_api.setBuffersGeometry = NULL;
> }
> 
> +/*
> + * Android ASurfaceTexture Android NDK
> + */
> +
> +static int
> +ASurfaceTexture_attachToGLContext(AWindowHandler *p_awh, uint32_t texName);
> +static int
> +ASurfaceTexture_updateTexImage(AWindowHandler *p_awh, const float **pp_transform_mtx);
> +static void
> +ASurfaceTexture_detachFromGLContext(AWindowHandler *p_awh);
> +static int
> +JNISurfaceTexture_waitAndUpdateTexImage(AWindowHandler *p_awh,
> +                                            const float **pp_transform_mtx);
> +static void
> +JNISurfaceTexture_detachFromGLContext(AWindowHandler *p_awh);
> +static int
> +JNISurfaceTexture_attachToGLContext(AWindowHandler *p_awh, uint32_t tex_name);
> +
> +static int
> +LoadSurfaceTextureAPI(AWindowHandler *p_awh, void *p_library)
> +{
> +    if (jfields.SurfaceTexture.removeFrameAvailableListener
> +            && jfields.SurfaceTexture.getSurfaceTexture)
> +    {
> +        p_awh->ast_api.pf_astFromst = (ptr_ASurfaceTexture_fromSurfaceTexture)
> +            dlsym(p_library, "ASurfaceTexture_fromSurfaceTexture");
> +        p_awh->ast_api.pf_updateTexImage = (ptr_ASurfaceTexture_updateTexImage)
> +            dlsym(p_library, "ASurfaceTexture_updateTexImage");
> +        p_awh->ast_api.pf_attachToGL = (ptr_ASurfaceTexture_attachToGLContext)
> +            dlsym(p_library, "ASurfaceTexture_attachToGLContext");
> +        p_awh->ast_api.pf_detachFromGL = (ptr_ASurfaceTexture_detachFromGLContext)
> +            dlsym(p_library, "ASurfaceTexture_detachFromGLContext");
> +        p_awh->ast_api.pf_getTransMatrix = (ptr_ASurfaceTexture_getTransformMatrix)
> +            dlsym(p_library, "ASurfaceTexture_getTransformMatrix");
> +        p_awh->ast_api.pf_releaseAst = (ptr_ASurfaceTexture_release)
> +            dlsym(p_library, "ASurfaceTexture_release");
> +
> +        if (p_awh->ast_api.pf_astFromst && p_awh->ast_api.pf_updateTexImage
> +                && p_awh->ast_api.pf_attachToGL && p_awh->ast_api.pf_detachFromGL
> +                && p_awh->ast_api.pf_getTransMatrix && p_awh->ast_api.pf_releaseAst)
> +        {
> +            return VLC_SUCCESS;
> +        }
> +    }
> +    return VLC_EGENERIC;
> +}
> +
> /*
>  * Android NativeWindow (post android 2.3)
>  */
> @@ -286,6 +352,7 @@ LoadNativeWindowAPI(AWindowHandler *p_awh)
>      && p_awh->anw_api.winLock && p_awh->anw_api.unlockAndPost
>      && p_awh->anw_api.setBuffersGeometry)
>     {
> +        LoadSurfaceTextureAPI(p_awh, p_library);
>         p_awh->p_anw_dl = p_library;
>     }
>     else
> @@ -435,6 +502,10 @@ InitJNIFields(JNIEnv *env, vlc_object_t *p_obj, jobject *jobj)
>                true);
>     GET_METHOD(SurfaceTexture.getSurface,
>                "SurfaceTexture_getSurface", "()Landroid/view/Surface;", true);
> +    GET_METHOD(SurfaceTexture.getSurfaceTexture,
> +               "SurfaceTexture_getSurfaceTexture", "()Landroid/graphics/SurfaceTexture;", true);
> +    GET_METHOD(SurfaceTexture.removeFrameAvailableListener,
> +               "SurfaceTexture_removeFrameAvailableListener", "()V", true);
> 
>     if ((*env)->RegisterNatives(env, clazz, jni_callbacks, 2) < 0)
>     {
> diff --git a/modules/video_output/android/utils.h b/modules/video_output/android/utils.h
> index 35ccc41906..28aed6c6a1 100644
> --- a/modules/video_output/android/utils.h
> +++ b/modules/video_output/android/utils.h
> @@ -34,6 +34,7 @@
> #include <vlc_common.h>
> 
> typedef struct AWindowHandler AWindowHandler;
> +typedef struct ASurfaceTexture ASurfaceTexture;
> 
> enum AWindow_ID {
>     AWindow_Video,
> -- 
> 2.26.0
> 
> _______________________________________________
> 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