[vlc-devel] [PATCH 07/14] android: utils: refactor creation of SurfaceTexture
Romain Vimont
rom1v at videolabs.io
Fri Jun 12 17:04:02 CEST 2020
On Fri, Jun 12, 2020 at 11:40:50AM +0200, Alexandre Janniaux wrote:
> The new function use a `struct vlc_asurfacetexture` object and is
s/use/uses/
> written to be extended to the case in which we don't have the NDK
> ASurfaceTexture API.
> ---
> modules/video_output/android/utils.c | 147 ++++++++++++++++++---------
> 1 file changed, 101 insertions(+), 46 deletions(-)
>
> diff --git a/modules/video_output/android/utils.c b/modules/video_output/android/utils.c
> index 85ae69423e0..3204bc20057 100644
> --- a/modules/video_output/android/utils.c
> +++ b/modules/video_output/android/utils.c
> @@ -927,48 +927,95 @@ AWindowHandler_getANativeWindowAPI(AWindowHandler *p_awh)
> return &p_awh->anw_api;
> }
>
> -static jobject InitNDKSurfaceTexture(AWindowHandler *p_awh, JNIEnv *p_env,
> - enum AWindow_ID id)
> +static struct SurfaceTextureHandle* SurfaceTextureHandle_Create(
> + AWindowHandler *p_awh, JNIEnv *p_env)
> {
> - /* This API should be available if using NDK SurfaceTexture API */
> - if (!jfields.SurfaceTexture.init_z)
> + jobject surfacetexture;
> +
> + struct SurfaceTextureHandle *handle = malloc(sizeof *handle);
> + if (handle == NULL)
> return NULL;
>
> - jobject surfacetexture = (*p_env)->NewObject(p_env,
> + handle->awh = p_awh;
> + handle->texture = NULL;
> + handle->jtexture = NULL;
> + handle->surface.jsurface = NULL;
> + handle->surface.window = NULL;
> + handle->surface.ops = NULL;
> +
> + /* API 26 */
> + if (jfields.SurfaceTexture.init_z == NULL)
> + goto error;
> +
> + msg_Info(p_awh->wnd, "Using SurfaceTexture constructor init_z");
> +
> + /* We can create a SurfaceTexture in detached mode directly */
> + surfacetexture = (*p_env)->NewObject(p_env,
> jfields.SurfaceTexture.clazz, jfields.SurfaceTexture.init_z, false);
>
> if (surfacetexture == NULL)
> goto error;
>
> - p_awh->ndk_ast_api.surfacetexture = (*p_env)->NewGlobalRef(p_env,
> - surfacetexture);
> -
> - p_awh->ndk_ast_api.p_ast = p_awh->ndk_ast_api.pf_astFromst(p_env,
> - p_awh->ndk_ast_api.surfacetexture);
> - if (p_awh->ndk_ast_api.p_ast == NULL)
> - goto error;
> -
> - p_awh->views[id].p_anw = p_awh->ndk_ast_api.pf_acquireAnw(p_awh->ndk_ast_api.p_ast);
> - if (p_awh->views[id].p_anw == NULL)
> - goto error;
> -
> - jobject jsurface = p_awh->ndk_ast_api.pf_anwToSurface(p_env, p_awh->views[id].p_anw);
> - if (jsurface == NULL)
> - goto error;
> + msg_Info(p_awh->wnd, "Adding reference to surfacetexture");
> + handle->jtexture = (*p_env)->NewGlobalRef(p_env, surfacetexture);
> (*p_env)->DeleteLocalRef(p_env, surfacetexture);
> - return jsurface;
> +
> + if (handle->jtexture == NULL)
> + goto error;
> +
> + if (p_awh->b_has_ndk_ast_api)
> + {
> + msg_Info(p_awh->wnd, "Using NDK API to init SurfaceTextureHandle");
> + handle->texture = p_awh->ndk_ast_api.pf_astFromst(p_env, handle->jtexture);
> + handle->surface.ops = &NDKSurfaceAPI;
> + handle->surface.window = p_awh->ndk_ast_api.pf_acquireAnw(handle->texture);
> + jobject jsurface = p_awh->ndk_ast_api.pf_anwToSurface(p_env, handle->surface.window);
> + if (jsurface == NULL) // TODO IsSame NULL
About the TODO: for local and global references, == NULL is correct.
IsSameObject() is necessary only for weak references.
> + goto error;
> +
> + handle->surface.jsurface = (*p_env)->NewGlobalRef(p_env, jsurface);
> + (*p_env)->DeleteLocalRef(p_env, jsurface);
> +
> + if (handle->surface.jsurface == NULL)
> + goto error;
> + }
> + else
> + {
> + msg_Info(p_awh->wnd, "Using JNI API to init SurfaceTextureHandle");
> + handle->texture = NULL;
> + /* Create Surface(SurfaceTexture), ie. producer side of the buffer
> + * queue in Android. */
> + jobject jsurface = (*p_env)->NewObject(p_env,
> + jfields.Surface.clazz, jfields.Surface.init_st, handle->jtexture);
> + if (!jsurface)
> + goto error;
> + handle->surface.jsurface = (*p_env)->NewGlobalRef(p_env, jsurface);
A NULL-check is missing.
> + (*p_env)->DeleteLocalRef(p_env, jsurface);
> +
> + handle->surface.window =
> + p_awh->pf_winFromSurface(p_env, handle->surface.jsurface);
> + handle->surface.ops = &JNISurfaceAPI;
> + }
> +
> + msg_Info(p_awh->wnd, "Successfully initialized SurfaceTexture");
> +
> + return handle;
>
> error:
> - if (surfacetexture == NULL)
> - return NULL;
> - (*p_env)->DeleteLocalRef(p_env, surfacetexture);
> - (*p_env)->DeleteGlobalRef(p_env, p_awh->ndk_ast_api.surfacetexture);
> - if (p_awh->ndk_ast_api.p_ast == NULL)
> - return NULL;
> - p_awh->ndk_ast_api.pf_releaseAst(p_awh->ndk_ast_api.p_ast);
> - if (p_awh->views[id].p_anw == NULL)
> - return NULL;
> - AWindowHandler_releaseANativeWindow(p_awh, id);
> +
> + if (handle->surface.window != NULL)
> + p_awh->pf_winRelease(handle->surface.window);
> +
> + if (handle->surface.jsurface != NULL)
> + (*p_env)->DeleteGlobalRef(p_env, handle->surface.jsurface);
> +
> + if (handle->texture != NULL)
> + p_awh->ndk_ast_api.pf_releaseAst(p_awh->ndk_ast_api.p_ast);
> +
> + if (handle->jtexture != NULL)
> + (*p_env)->DeleteGlobalRef(p_env, handle->jtexture);
> +
> + free(handle);
> return NULL;
> }
>
> @@ -988,33 +1035,41 @@ WindowHandler_NewSurfaceEnv(AWindowHandler *p_awh, JNIEnv *p_env,
> break;
> case AWindow_SurfaceTexture:
> {
> - struct SurfaceTextureHandle *surfacetexture =
> - malloc(sizeof *surfacetexture);
> - if (surfacetexture == NULL)
> - return VLC_EGENERIC;
> + struct SurfaceTextureHandle *surfacetexture = NULL;
>
> if (p_awh->b_has_ndk_ast_api)
> {
> - jsurface = InitNDKSurfaceTexture(p_awh, p_env, id);
> + surfacetexture = SurfaceTextureHandle_Create(p_awh, p_env);
> +
> + if (surfacetexture == NULL)
> + return VLC_EGENERIC;
> +
> surfacetexture->surface.ops = &NDKSurfaceAPI;
> - surfacetexture->surface.window = p_awh->views[id].p_anw;
> + p_awh->views[id].p_anw = surfacetexture->surface.window;
> + p_awh->views[id].jsurface = surfacetexture->surface.jsurface;
> + p_awh->ndk_ast_api.p_ast = surfacetexture->texture;
> + p_awh->ndk_ast_api.surfacetexture = surfacetexture->jtexture;
> }
> else
> {
> + surfacetexture = malloc(sizeof *surfacetexture);
> + /* We use AWindow wrapper functions for SurfaceTexture. */
> jsurface = JNI_STEXCALL(CallObjectMethod, getSurface);
> + surfacetexture->surface.jsurface = (*p_env)->NewGlobalRef(p_env, jsurface);
> + (*p_env)->DeleteLocalRef(p_env, jsurface);
> surfacetexture->surface.ops = &JNISurfaceAPI;
> surfacetexture->surface.window
> = p_awh->views[id].p_anw
> - = p_awh->pf_winFromSurface(p_env, jsurface);
> - }
> + = p_awh->pf_winFromSurface(p_env, surfacetexture->surface.jsurface);
> + surfacetexture->awh = p_awh;
> + surfacetexture->jtexture = NULL;
> + surfacetexture->texture = NULL;
>
> - surfacetexture->awh = p_awh;
> - surfacetexture->jtexture = p_awh->ndk_ast_api.surfacetexture;
> - surfacetexture->texture = p_awh->ndk_ast_api.p_ast;
> - surfacetexture->surface.jsurface
> - = p_awh->views[id].jsurface
> - = (*p_env)->NewGlobalRef(p_env, jsurface);
> - (*p_env)->DeleteLocalRef(p_env, jsurface);
> + p_awh->views[id].p_anw = surfacetexture->surface.window;
> + p_awh->views[id].jsurface = surfacetexture->surface.jsurface;
> + p_awh->ndk_ast_api.p_ast = NULL;
> + p_awh->ndk_ast_api.surfacetexture = NULL;
> + }
>
> assert(surfacetexture->surface.window);
> assert(surfacetexture->surface.jsurface);
> --
> 2.27.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