From 743687177fc769f6b66e2e34273ac00b7b83ca3a Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 15 Jun 2013 18:25:02 +0800 Subject: [PATCH] ijksdl: introduce SDL_Vout --- ijkmediaplayer/jni/ijksdl/Android.mk | 2 + ijkmediaplayer/jni/ijksdl/ijksdl.h | 1 + ijkmediaplayer/jni/ijksdl/ijksdl_vout.c | 64 +++++ ijkmediaplayer/jni/ijksdl/ijksdl_vout.h | 61 +++++ .../jni/ijksdl/ijksdl_vout_android.c | 220 ++++++++++++++++++ .../jni/ijksdl/ijksdl_vout_android.h | 38 +++ .../jni/ijksdl/ijksdl_vout_internal.h | 77 ++++++ 7 files changed, 463 insertions(+) create mode 100644 ijkmediaplayer/jni/ijksdl/ijksdl_vout.c create mode 100644 ijkmediaplayer/jni/ijksdl/ijksdl_vout.h create mode 100644 ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.c create mode 100644 ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.h create mode 100644 ijkmediaplayer/jni/ijksdl/ijksdl_vout_internal.h diff --git a/ijkmediaplayer/jni/ijksdl/Android.mk b/ijkmediaplayer/jni/ijksdl/Android.mk index a67fa87a..a3080b5a 100644 --- a/ijkmediaplayer/jni/ijksdl/Android.mk +++ b/ijkmediaplayer/jni/ijksdl/Android.mk @@ -20,6 +20,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_C_CFLAGS += -std=c99 +LOCAL_LDLIBS += -llog LOCAL_SRC_FILES += ijksdl_audio.c LOCAL_SRC_FILES += ijksdl_error.c @@ -29,6 +30,7 @@ LOCAL_SRC_FILES += ijksdl_stdinc.c LOCAL_SRC_FILES += ijksdl_thread.c LOCAL_SRC_FILES += ijksdl_timer.c LOCAL_SRC_FILES += ijksdl_video.c +LOCAL_SRC_FILES += ijksdl_vout.c LOCAL_MODULE := ijksdl include $(BUILD_STATIC_LIBRARY) diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl.h b/ijkmediaplayer/jni/ijksdl/ijksdl.h index 4bb1f634..0c9e3c28 100644 --- a/ijkmediaplayer/jni/ijksdl/ijksdl.h +++ b/ijkmediaplayer/jni/ijksdl/ijksdl.h @@ -31,5 +31,6 @@ #include "ijksdl_thread.h" #include "ijksdl_timer.h" #include "ijksdl_video.h" +#include "ijksdl_vout.h" #endif diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl_vout.c b/ijkmediaplayer/jni/ijksdl/ijksdl_vout.c new file mode 100644 index 00000000..1b7749b3 --- /dev/null +++ b/ijkmediaplayer/jni/ijksdl/ijksdl_vout.c @@ -0,0 +1,64 @@ +/***************************************************************************** + * ijksdl_vout.c + ***************************************************************************** + * + * copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ijksdl_vout.h" + +#include +#include + +void SDL_VoutFree(SDL_Vout *vout) +{ + if (!vout) + return; + + if (vout->free_l) { + vout->free_l(vout); + } else { + free(vout); + } +} + +int SDL_VoutGetSurface(SDL_Vout *vout, SDL_VoutSurface** ppsurface, int w, int h, int format) +{ + assert(ppsurface); + if (!ppsurface || !vout || !vout->get_surface) + return -1; + + SDL_LockMutex(vout->mutex); + int retval = vout->get_surface(vout, ppsurface, w, h, format); + SDL_UnlockMutex(vout->mutex); + + return retval; +} + +void SDL_VoutSurface_Free(SDL_VoutSurface *surface) +{ + if (!surface) + return; + + if (surface->free_l) + surface->free_l(surface); + else + free(surface); +} + diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl_vout.h b/ijkmediaplayer/jni/ijksdl/ijksdl_vout.h new file mode 100644 index 00000000..6c0b18ff --- /dev/null +++ b/ijkmediaplayer/jni/ijksdl/ijksdl_vout.h @@ -0,0 +1,61 @@ +/***************************************************************************** + * ijksdl_vout.h + ***************************************************************************** + * + * copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IJKSDL__IJKSDL_VOUT_H +#define IJKSDL__IJKSDL_VOUT_H + +#include "ijksdl_stdinc.h" +#include "ijksdl_mutex.h" + +typedef struct SDL_VoutOverlay { + void *opaque; + + int w; + int h; +} SDL_VoutOverlay; + +typedef struct SDL_VoutSurface SDL_VoutSurface; +typedef struct SDL_VoutSurface { + int w; + int h; + int format; + + void *opaque; + void (*free_l)(SDL_VoutSurface *surface); +} SDL_VoutSurface; + +typedef struct SDL_Vout SDL_Vout; +typedef struct SDL_Vout { + SDL_mutex *mutex; + + void *opaque; + void (*free_l)(SDL_Vout *vout); + int (*get_surface)(SDL_Vout *vout, SDL_VoutSurface** ppsurface, int w, int h, int format); +} SDL_Vout; + +void SDL_Vout_Free(SDL_Vout *vout); +int SDL_Vout_GetSurface(SDL_Vout *vout, SDL_VoutSurface** ppsurface, int w, int h, int format); + +void SDL_VoutSurface_Free(SDL_VoutSurface *surface); + +#endif diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.c b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.c new file mode 100644 index 00000000..e6374467 --- /dev/null +++ b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.c @@ -0,0 +1,220 @@ +/***************************************************************************** + * ijksdl_vout_android.c + ***************************************************************************** + * + * copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ijksdl_vout_android.h" + +#include +#include "ijksdl_vout.h" +#include "ijksdl_vout_internal.h" + +typedef struct SDL_Vout_Opaque { + ANativeWindow *native_window; +} SDL_Vout_Opaque; + +typedef struct SDL_VoutSurface_Opaque { + ANativeWindow *native_window; +} SDL_VoutSurface_Opaque; + +static void surface_opaque_free(SDL_VoutSurface *surface) +{ + if (!surface) + return; + + SDL_VoutSurface_Opaque *opaque = surface->opaque; + if (opaque) { + if (opaque->native_window) { + ANativeWindow_release(opaque->native_window); + } + free(opaque); + surface->opaque = NULL; + } + + SDL_VoutSurface_FreeInternal(surface); +} + +static SDL_VoutSurface *surface_create_l(ANativeWindow *native_window) +{ + SDL_VoutSurface *surface = SDL_VoutSurface_CreateInternal(); + if (!surface) + return -1; + + SDL_VoutSurface_Opaque *opaque = (SDL_VoutSurface_Opaque*) malloc(sizeof(SDL_VoutSurface_Opaque)); + if (!opaque) { + free(surface); + return -1; + } + memset(opaque, 0, sizeof(opaque)); + + ANativeWindow_acquire(native_window); + opaque->native_window = native_window; + + surface->opaque = opaque; + surface->free_l = surface_opaque_free; + return surface; +} + +static void vout_opaque_free(SDL_Vout *vout) +{ + if (!vout) + return; + + SDL_Vout_Opaque *opaque = vout->opaque; + if (opaque) { + if (opaque->native_window) { + ANativeWindow_release(opaque->native_window); + } + free(vout->opaque); + vout->opaque = NULL; + } + + SDL_Vout_FreeInternal(vout); +} + +static int vout_get_surface(SDL_Vout *vout, SDL_VoutSurface** ppsurface, int w, int h, int format) +{ + SDL_Vout_Opaque *vout_opaque = vout->opaque; + SDL_VoutSurface *surface = *ppsurface; + SDL_VoutSurface_Opaque *surface_opaque = NULL; + ANativeWindow *new_native_window = NULL; + + SDL_LockMutex(vout->mutex); + if (surface != NULL) { + surface_opaque = surface->opaque; + + if (surface_opaque->native_window == vout_opaque->native_window && + w == surface->w && h == surface->h && format == surface->format) { + } else { + SDL_VoutSurfaceFree(surface); + *ppsurface = NULL; + surface = NULL; + } + } + + // aquire new native_window from vout */ + if (surface == NULL) { + new_native_window = vout_opaque->native_window; + ANativeWindow_aquire(new_native_window); + } + + SDL_UnlockMutex(vout->mutex); + + // setup surface without lock + if (surface == NULL) { + if (ANativeWindow_setBuffersGeometry(new_native_window, w, h, format) < 0) { + ANativeWindow_release(new_native_window); + new_native_window = NULL; + } + + if (new_native_window) { + assert(surface); + surface = surface_create_l(new_native_window); + if (surface) + new_native_window = NULL; + + ANativeWindow_release(vout_opaque->native_window); + } + + if (new_native_window) { + ANativeWindow_release(new_native_window); + new_native_window = NULL; + } + } + + return surface ? 0 : -1; +} + +SDL_Vout *SDL_VoutAndroid_CreateFromANativeWindow(ANativeWindow *native_window) +{ + SDL_Vout *vout = SDL_Vout_CreateInternal(); + if (!vout) + return NULL; + + SDL_Vout_Opaque *opaque = malloc(sizeof(SDL_Vout_Opaque)); + if (!opaque) + { + SDL_Vout_Free(opaque); + return NULL; + } + memset(opaque, 0, sizeof(SDL_Vout_Opaque)); + + if (native_window) { + ANativeWindow_acquire(native_window); + } + + opaque->native_window = native_window; + + vout->opaque = opaque; + vout->free_l = vout_opaque_free; + vout->get_surface = vout_get_surface; + + return vout; +} + +SDL_Vout *SDL_VoutAndroid_CreateFromAndroidSurface(jobject android_surface) +{ + if (!android_surface) + return NULL; + + ANativeWindow *native_window = ANativeWindow_fromSurface(android_surface); + if (!native_window) + return NULL; + + SDL_Vout *vout = SDL_Vout_Create_FromANativeWindow(native_window); + ANativeWindow_release(native_window); + + return vout; +} + +static void SDL_VoutAndroid_SetNativeWindow_l(SDL_Vout vout, ANativeWindow *native_window) +{ + SDL_Vout_Opaque *opaque = vout->opaque; + + if (opaque->native_window == native_window) + return; + + if (opaque->native_window) + ANativeWindow_release(opaque->native_window); + + ANativeWindow_acquire(native_window); + opaque->native_window = native_window; +} + +void SDL_VoutAndroid_SetNativeWindow(SDL_Vout vout, ANativeWindow *native_window) +{ + SDL_LockMutex(vout->mutex); + SDL_VoutAndroid_SetNativeWindow_l(vout, native_window); + SDL_UnlockMutex(vout->mutex); +} + +void SDL_VoutAndroid_SetAndroidSurface(SDL_Vout vout, jobject android_surface) +{ + if (!android_surface) + return; + + ANativeWindow *native_window = ANativeWindow_fromSurface(android_surface); + if (!native_window) + return; + + SDL_VoutNativeWindow_SetNativeWindow(native_window); + ANativeWindow_release(native_window); +} diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.h b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.h new file mode 100644 index 00000000..679a8f31 --- /dev/null +++ b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_android.h @@ -0,0 +1,38 @@ +/***************************************************************************** + * ijksdl_vout_android.h + ***************************************************************************** + * + * copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IJKSDL__IJKSDL_VOUT_ANDROID_H +#define IJKSDL__IJKSDL_VOUT_ANDROID_H + +#include +#include +#include "ijksdl_stdinc.h" +#include "ijksdl_mutex.h" + +typedef struct ANativeWindow ANativeWindow; + +SDL_Vout *SDL_VoutAndroid_Create_FromANativeWindow(ANativeWindow *native_window); +SDL_Vout *SDL_VoutAndroid_Create_FromAndroidSurface(jobject android_surface); + +void SDL_VoutAndroid_SetNativeWindow(SDL_Vout vout, ANativeWindow *native_window); +void SDL_VoutAndroid_SetAndroidSurface(SDL_Vout vout, jobject android_surface); diff --git a/ijkmediaplayer/jni/ijksdl/ijksdl_vout_internal.h b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_internal.h new file mode 100644 index 00000000..b961b3c3 --- /dev/null +++ b/ijkmediaplayer/jni/ijksdl/ijksdl_vout_internal.h @@ -0,0 +1,77 @@ +/***************************************************************************** + * ijksdl_vout_internal.h + ***************************************************************************** + * + * copyright (c) 2013 Zhang Rui + * + * This file is part of ijkPlayer. + * + * ijkPlayer 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. + * + * ijkPlayer 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 ijkPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IJKSDL__IJKSDL_VOUT_INTERNAL_H +#define IJKSDL__IJKSDL_VOUT_INTERNAL_H + +#include "ijksdl_vout.h" + +inline static SDL_Vout *SDL_Vout_CreateInternal() +{ + SDL_Vout *vout = (SDL_Vout*) malloc(sizeof(SDL_Vout)); + if (!vout) + return NULL; + + memset(vout, 0, sizeof(SDL_Vout)); + vout->mutex = SDL_CreateMutex(); + if (vout->mutex == NULL) { + free(vout); + return NULL; + } + + return vout; +} + +inline static void SDL_Vout_FreeInternal(SDL_Vout *vout) +{ + if (!vout) + return; + + if (vout->mutex) { + SDL_DestroyMutex(vout->mutex); + } + + memset(vout, 0, sizeof(SDL_VoutSurface)); + free(vout); +} + +inline static SDL_VoutSurface *SDL_VoutSurface_CreateInternal() +{ + SDL_VoutSurface *surface = (SDL_VoutSurface*) malloc(sizeof(SDL_VoutSurface)); + if (!surface) + return NULL; + + memset(surface, 0, sizeof(SDL_VoutSurface)); + return surface; +} + +inline static void SDL_VoutSurface_FreeInternal(SDL_Vout *vout) +{ + if (!vout) + return; + + memset(vout, 0, sizeof(SDL_VoutSurface)); + free(vout); +} + +#endif -- GitLab