ijksdl_vout_android.c 4.8 KB
Newer Older
Z
Zhang Rui 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*****************************************************************************
 * ijksdl_vout_android.c
 *****************************************************************************
 *
 * copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
 *
 * 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"

Z
Zhang Rui 已提交
26 27
#include <assert.h>
#include <android/native_window.h>
Z
Zhang Rui 已提交
28 29 30 31 32
#include <android/native_window_jni.h>
#include "ijksdl_vout.h"
#include "ijksdl_vout_internal.h"

typedef struct SDL_VoutSurface_Opaque {
33
    SDL_Vout *vout;
Z
Zhang Rui 已提交
34 35
} SDL_VoutSurface_Opaque;

36 37 38 39 40
typedef struct SDL_Vout_Opaque {
    ANativeWindow *native_window;
    SDL_VoutSurface dummy_surface;
    SDL_VoutSurface_Opaque dummy_surface_opaque;
} SDL_Vout_Opaque;
Z
Zhang Rui 已提交
41

42
static void vout_free(SDL_Vout *vout)
Z
Zhang Rui 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
{
    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);
}

59
static SDL_VoutSurface *vout_set_video_mode_l(SDL_Vout *vout, int w, int h, int bpp, int flags)
Z
Zhang Rui 已提交
60
{
61 62 63 64 65 66
    SDL_Vout_Opaque *opaque = vout->opaque;
    SDL_VoutSurface *surface = &opaque->dummy_surface;
    ANativeWindow *native_window = opaque->native_window;
    int curr_w = 0;
    int curr_h = 0;
    int curr_format = 0;
Z
Zhang Rui 已提交
67

68 69
    if (!native_window)
        return NULL;
Z
Zhang Rui 已提交
70

71 72 73 74 75 76
    curr_w = ANativeWindow_getWidth(native_window);
    curr_h = ANativeWindow_getHeight(native_window);
    curr_format = ANativeWindow_getFormat(native_window);
    if (curr_w == w && curr_h == h) {
        surface->format = curr_format;
        return surface;
Z
Zhang Rui 已提交
77 78
    }

79 80 81 82 83 84 85
    ANativeWindow_setBuffersGeometry(native_window, w, h, curr_format);
    curr_w = ANativeWindow_getWidth(native_window);
    curr_h = ANativeWindow_getHeight(native_window);
    curr_format = ANativeWindow_getFormat(native_window);
    if (curr_w == w && curr_h == h) {
        surface->format = curr_format;
        return surface;
Z
Zhang Rui 已提交
86 87
    }

88 89 90
    return NULL;
}

91
static SDL_VoutSurface *vout_set_video_mode(SDL_Vout *vout, int w, int h, int bpp, Uint32 flags)
92 93
{
    SDL_LockMutex(vout->mutex);
94
    SDL_VoutSurface *surface = vout_set_video_mode_l(vout, w, h, bpp, flags);
95 96
    SDL_UnlockMutex(vout->mutex);
    return surface;
Z
Zhang Rui 已提交
97 98
}

99 100 101 102 103 104
static int voud_display_overlay(SDL_Vout *vout, SDL_VoutOverlay *overlay)
{
    // FIXME: implement
    return -1;
}

Z
Zhang Rui 已提交
105
SDL_Vout *SDL_VoutAndroid_CreateForANativeWindow()
Z
Zhang Rui 已提交
106 107 108 109 110 111 112 113
{
    SDL_Vout *vout = SDL_Vout_CreateInternal();
    if (!vout)
        return NULL;

    SDL_Vout_Opaque *opaque = malloc(sizeof(SDL_Vout_Opaque));
    if (!opaque)
    {
114
        SDL_VoutFree(vout);
Z
Zhang Rui 已提交
115 116 117 118
        return NULL;
    }
    memset(opaque, 0, sizeof(SDL_Vout_Opaque));

119 120 121 122
    opaque->dummy_surface_opaque.vout = vout;

    opaque->dummy_surface.opaque = &opaque->dummy_surface_opaque;

Z
Zhang Rui 已提交
123
    vout->opaque = opaque;
124 125
    vout->free_l = vout_free;
    vout->set_video_mode = vout_set_video_mode;
126
    vout->display_overlay = voud_display_overlay;
Z
Zhang Rui 已提交
127 128 129 130

    return vout;
}

Z
Zhang Rui 已提交
131
static void SDL_VoutAndroid_SetNativeWindow_l(SDL_Vout *vout, ANativeWindow *native_window)
Z
Zhang Rui 已提交
132 133 134 135 136 137 138 139 140
{
    SDL_Vout_Opaque *opaque = vout->opaque;

    if (opaque->native_window == native_window)
        return;

    if (opaque->native_window)
        ANativeWindow_release(opaque->native_window);

141 142 143
    if (native_window)
        ANativeWindow_acquire(native_window);

Z
Zhang Rui 已提交
144 145 146
    opaque->native_window = native_window;
}

Z
Zhang Rui 已提交
147
void SDL_VoutAndroid_SetNativeWindow(SDL_Vout *vout, ANativeWindow *native_window)
Z
Zhang Rui 已提交
148 149 150 151 152 153
{
    SDL_LockMutex(vout->mutex);
    SDL_VoutAndroid_SetNativeWindow_l(vout, native_window);
    SDL_UnlockMutex(vout->mutex);
}

Z
Zhang Rui 已提交
154 155 156 157 158 159
SDL_Vout *SDL_VoutAndroid_CreateForAndroidSurface()
{
    return SDL_VoutAndroid_CreateForANativeWindow();
}

void SDL_VoutAndroid_SetAndroidSurface(SDL_Vout *vout, JNIEnv *env, jobject android_surface)
Z
Zhang Rui 已提交
160 161 162 163
{
    if (!android_surface)
        return;

Z
Zhang Rui 已提交
164
    ANativeWindow *native_window = ANativeWindow_fromSurface(env, android_surface);
Z
Zhang Rui 已提交
165 166 167
    if (!native_window)
        return;

Z
Zhang Rui 已提交
168
    SDL_VoutAndroid_SetNativeWindow(vout, native_window);
Z
Zhang Rui 已提交
169 170
    ANativeWindow_release(native_window);
}