[vlc-devel] [PATCH 2/3] Vout: add a new window provider to create android native windows.

Rémi Denis-Courmont remi at remlab.net
Thu Nov 7 08:52:31 CET 2013


On Wed,  6 Nov 2013 22:54:08 +0100, Adrien Maglo <magsoft at videolan.org>
wrote:
> ---
>  modules/video_output/Modules.am            |  10 ++
>  modules/video_output/androidnativewindow.c | 188
>  +++++++++++++++++++++++++++++
>  2 files changed, 198 insertions(+)
>  create mode 100644 modules/video_output/androidnativewindow.c
> 
> diff --git a/modules/video_output/Modules.am
> b/modules/video_output/Modules.am
> index 041dc29..3393a11 100644
> --- a/modules/video_output/Modules.am
> +++ b/modules/video_output/Modules.am
> @@ -180,6 +180,16 @@ if HAVE_KVA
>  vout_LTLIBRARIES += libkva_plugin.la
>  endif
>  
> +### Android ###
> +
> +libandroid_native_window_plugin_la_SOURCES = androidnativewindow.c
> +libandroid_native_window_plugin_la_CFLAGS = $(AM_CFLAGS)
> +libandroid_native_window_plugin_la_LIBADD = -ldl
> +
> +if HAVE_ANDROID
> +vout_LTLIBRARIES += libandroid_native_window_plugin.la
> +endif

IMHO, Android source stuff should be in a subdirectory rather than have
the same prefix over and over.

> +
>  ### Coloured ASCII art ###
>  libcaca_plugin_la_SOURCES = caca.c
>  libcaca_plugin_la_CFLAGS = $(AM_CFLAGS) $(CACA_CFLAGS)
> diff --git a/modules/video_output/androidnativewindow.c
> b/modules/video_output/androidnativewindow.c
> new file mode 100644
> index 0000000..8482fba
> --- /dev/null
> +++ b/modules/video_output/androidnativewindow.c
> @@ -0,0 +1,188 @@
> +/**
> + * @file androidnativewindow.c
> + * @brief Android native window provider module for VLC media player
> + */
>
+/*****************************************************************************
> + * Copyright © 2013 VLC authors and VideoLAN
> + *
> + * Author: Adrien Maglo <magsoft at videolan.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
it
> + * under the terms of the GNU Lesser General Public License as
published
> by
> + * the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> License
> + * along with this program; if not, write to the Free Software
Foundation,
> + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> +
>
*****************************************************************************/
> +
> +#ifdef HAVE_CONFIG_H
> +# include <config.h>
> +#endif
> +
> +#include <stdarg.h>
> +#include <assert.h>

Not used?

> +
> +#include <vlc_common.h>
> +#include <vlc_plugin.h>
> +#include <vlc_vout_window.h>
> +
> +#include <dlfcn.h>
> +#include <android/native_window.h>
> +#include <jni.h>
> +#include <android/native_window_jni.h>
> +
> +#include <android/log.h>
> +# define LOGV(...) 
> __android_log_print(ANDROID_LOG_VERBOSE,"VLC_OPENGL",__VA_ARGS__)
> +
> +
> +typedef ANativeWindow* (*ptr_ANativeWindow_fromSurface)(JNIEnv*,
jobject);
> +typedef void (*ptr_ANativeWindow_release)(ANativeWindow*);
> +
> +extern JavaVM *myVm;
> +extern jobject jni_LockAndGetAndroidJavaSurface();
> +extern void jni_UnlockAndroidSurface();
> +extern void  jni_SetAndroidSurfaceSize(int width, int height, int
> visible_width, int visible_height, int sar_num, int sar_den);
> +
> +static int Open(vout_window_t *, const vout_window_cfg_t *);
> +static void Close(vout_window_t *);
> +static int Control(vout_window_t *, int, va_list ap);
> +
> +/*
> + * Module descriptor
> + */
> +vlc_module_begin()
> +    set_shortname(N_("ANativeWindow"))
> +    set_description(N_("Android native window"))
> +    set_category(CAT_VIDEO)
> +    set_subcategory(SUBCAT_VIDEO_VOUT)
> +    set_capability("vout window anativewindow", 10)
> +    set_callbacks(Open, Close)
> +vlc_module_end()
> +
> +
> +struct vout_window_sys_t
> +{
> +    void *p_library;
> +
> +    ptr_ANativeWindow_fromSurface s_winFromSurface;
> +    ptr_ANativeWindow_release s_winRelease;
> +
> +    ANativeWindow *window;
> +};
> +
> +
> +/**
> + * Dynamically load the libandroid library and the needed symbols.
> + */
> +static void *InitLibrary(vout_window_sys_t *p_sys)
> +{
> +    void *p_library = dlopen("libandroid.so", RTLD_NOW);
> +    if (!p_library)
> +        return NULL;
> +
> +    p_sys->s_winFromSurface =
> +        (ptr_ANativeWindow_fromSurface)(dlsym(p_library,
> "ANativeWindow_fromSurface"));
> +    p_sys->s_winRelease =
> +        (ptr_ANativeWindow_release)(dlsym(p_library,
> "ANativeWindow_release"));
> +
> +    if (p_sys->s_winFromSurface == NULL || p_sys->s_winRelease == NULL)
> +    {
> +        dlclose(p_sys->p_library);
> +        return NULL;
> +    }
> +
> +    return p_library;
> +}
> +
> +
> +/**
> + * Create an Android native window.
> + */
> +static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
> +{
> +    vout_window_sys_t *p_sys = malloc(sizeof (*p_sys));
> +    if (p_sys == NULL)
> +        return VLC_ENOMEM;
> +
> +    p_sys->p_library = InitLibrary(p_sys);
> +    if (p_sys->p_library == NULL)
> +    {
> +        free(p_sys);
> +        return VLC_EGENERIC;
> +    }
> +
> +    // Create the native window by first getting the Java surface.
> +    jobject javaSurface = jni_LockAndGetAndroidJavaSurface();
> +    if (javaSurface == NULL)
> +        goto error;
> +
> +    JNIEnv *p_env;
> +    (*myVm)->AttachCurrentThread(myVm, &p_env, NULL);
> +    p_sys->window = p_sys->s_winFromSurface(p_env, javaSurface); //
> ANativeWindow_fromSurface call.
> +    (*myVm)->DetachCurrentThread(myVm);
> +
> +    jni_UnlockAndroidSurface();
> +
> +    if (p_sys->window == NULL)
> +        goto error;
> +
> +    wnd->handle.anativewindow = p_sys->window;
> +    wnd->control = Control;
> +    wnd->sys = p_sys;
> +
> +    /* Set the Java surface size.
> +     * TODO: get the visible size and sar from vout_window_cfg_t
> +     * by adding new members to this structure? */

No, the caller should adjust the configuration as it sees fit. I have yet
to see a display with physically variable pixel aspect ratio, so I don't
see why the window provider should care.

> +    jni_SetAndroidSurfaceSize(cfg->width, cfg->height, cfg->width,
> cfg->height, 1, 1);
> +
> +    return VLC_SUCCESS;
> +
> +error:
> +    dlclose(p_sys->p_library);
> +    free(p_sys);
> +    return VLC_EGENERIC;
> +}
> +
> +
> +/**
> + * Destroys the Android native window.
> + */
> +static void Close(vout_window_t *wnd)
> +{
> +    vout_window_sys_t *p_sys = wnd->sys;
> +    p_sys->s_winRelease(p_sys->window); // Release the native window.
> +    dlclose(p_sys->p_library); // Close the library.
> +    free (p_sys);
> +}
> +
> +
> +/**
> + * Window control.
> + */
> +static int Control(vout_window_t *wnd, int cmd, va_list ap)
> +{
> +    switch (cmd)
> +    {
> +        case VOUT_WINDOW_SET_SIZE:
> +        {
> +            unsigned width = va_arg(ap, unsigned);
> +            unsigned height = va_arg(ap, unsigned);
> +            jni_SetAndroidSurfaceSize(width, height, width, height, 1,
1);
> +            break;
> +        }
> +        case VOUT_WINDOW_SET_STATE:
> +        case VOUT_WINDOW_SET_FULLSCREEN:
> +            return VLC_EGENERIC;
> +        default:
> +            msg_Err (wnd, "request %d not implemented", cmd);
> +            return VLC_EGENERIC;
> +    }
> +    return VLC_SUCCESS;
> +}

-- 
Rémi Denis-Courmont
Sent from my collocated server



More information about the vlc-devel mailing list