[vlc-devel] [PATCH 07/14] android: utils: refactor creation of SurfaceTexture

Alexandre Janniaux ajanni at videolabs.io
Mon Jun 15 10:06:53 CEST 2020


On Fri, Jun 12, 2020 at 05:04:02PM +0200, Romain Vimont wrote:
Hi,

Thanks for the typo, and woops for the TODO, I was pretty sure
had removed it but it seems I miss some of them. :)

Regards,
--
Alexandre Janniaux
Videolabs

> 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
> _______________________________________________
> 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