[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