1 /*****************************************************************************
2 * utils.h: shared code between Android vout modules.
3 *****************************************************************************
4 * Copyright (C) 2014-2015 VLC authors and VideoLAN
5 *
6 * Authors: Felix Abecassis <felix.abecassis@gmail.com>
7 * Thomas Guillem <thomas@gllm.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <jni.h>
29 #include <android/native_window.h>
30 #include <android/native_window_jni.h>
31 #include <android/input.h>
32
33 #include <vlc_vout_display.h>
34 #include <vlc_common.h>
35
36 typedef struct AWindowHandler AWindowHandler;
37
38 enum AWindow_ID {
39 AWindow_Video,
40 AWindow_Subtitles,
41 AWindow_SurfaceTexture,
42 AWindow_Max,
43 };
44
45 /**
46 * native_window_api_t. See android/native_window.h in NDK
47 */
48 typedef struct
49 {
50 int32_t (*winLock)(ANativeWindow*, ANativeWindow_Buffer*, ARect*);
51 void (*unlockAndPost)(ANativeWindow*);
52 int32_t (*setBuffersGeometry)(ANativeWindow*, int32_t, int32_t, int32_t); /* can be NULL */
53 } native_window_api_t;
54
55 /**
56 * native_window_priv_api_t. See system/core/include/system/window.h in AOSP.
57 */
58 typedef struct native_window_priv native_window_priv;
59 typedef struct
60 {
61 native_window_priv *(*connect)(ANativeWindow *);
62 int (*disconnect) (native_window_priv *);
63 int (*setUsage) (native_window_priv *, bool, int );
64 int (*setBuffersGeometry) (native_window_priv *, int, int, int );
65 int (*getMinUndequeued) (native_window_priv *, unsigned int *);
66 int (*getMaxBufferCount) (native_window_priv *, unsigned int *);
67 int (*setBufferCount) (native_window_priv *, unsigned int );
68 int (*setCrop) (native_window_priv *, int, int, int, int);
69 int (*dequeue) (native_window_priv *, void **);
70 int (*lock) (native_window_priv *, void *);
71 int (*queue) (native_window_priv *, void *);
72 int (*cancel) (native_window_priv *, void *);
73 int (*lockData) (native_window_priv *, void **, ANativeWindow_Buffer *);
74 int (*unlockData) (native_window_priv *, void *, bool b_render);
75 int (*setOrientation) (native_window_priv *, int);
76 } native_window_priv_api_t;
77
78 struct awh_mouse_coords
79 {
80 int i_action;
81 int i_button;
82 int i_x;
83 int i_y;
84 };
85
86 typedef struct
87 {
88 void (*on_new_window_size)(vout_window_t *wnd, unsigned i_width,
89 unsigned i_height);
90 void (*on_new_mouse_coords)(vout_window_t *wnd,
91 const struct awh_mouse_coords *coords);
92 } awh_events_t;
93
94 /**
95 * Load a private native window API
96 *
97 * This can be used to access the private ANativeWindow API.
98 * \param api doesn't need to be released
99 * \return 0 on success, -1 on error.
100 */
101 int android_loadNativeWindowPrivApi(native_window_priv_api_t *api);
102
103 /**
104 * Attach or get a JNIEnv*
105 *
106 * The returned JNIEnv* is created from the android JavaVM attached to the VLC
107 * object var.
108 * \return a valid JNIEnv * or NULL. It doesn't need to be released.
109 */
110 JNIEnv *android_getEnv(vlc_object_t *p_obj, const char *psz_thread_name);
111
112 /**
113 * Create new AWindowHandler
114 *
115 * This handle allow to access IAWindowNativeHandler jobject attached to the
116 * VLC object var.
117 * \return a valid AWindowHandler * or NULL. It must be released with
118 * AWindowHandler_destroy.
119 */
120 AWindowHandler *AWindowHandler_new(vout_window_t *wnd, awh_events_t *p_events);
121 void AWindowHandler_destroy(AWindowHandler *p_awh);
122
123 /**
124 * Get the public native window API
125 *
126 * Used to access the public ANativeWindow API.
127 * \return a valid native_window_api_t. It doesn't need to be released.
128 */
129 native_window_api_t *AWindowHandler_getANativeWindowAPI(AWindowHandler *p_awh);
130
131 /**
132 * Get the Video or the Subtitles Android Surface
133 *
134 * \return the surface in a jobject, or NULL. It should be released with
135 * AWindowHandler_releaseANativeWindow() or AWindowHandler_destroy().
136 */
137 jobject AWindowHandler_getSurface(AWindowHandler *p_awh, enum AWindow_ID id);
138
139 /**
140 * Get the Video or the Subtitles ANativeWindow
141 *
142 * \return a valid ANativeWindow or NULL.It should be released with
143 * AWindowHandler_releaseANativeWindow() or AWindowHandler_destroy.()
144 */
145 ANativeWindow *AWindowHandler_getANativeWindow(AWindowHandler *p_awh,
146 enum AWindow_ID id);
147
148 /**
149 * Release the Video/Subtitles Surface/ANativeWindow
150 */
151 void AWindowHandler_releaseANativeWindow(AWindowHandler *p_awh,
152 enum AWindow_ID id);
153 /**
154 * Pre-ICS hack of ANativeWindow_setBuffersGeometry
155 *
156 * This function is a fix up of ANativeWindow_setBuffersGeometry that doesn't
157 * work before Android ICS. It configures the Surface from the Android
158 * MainThread via a SurfaceHolder. It returns VLC_SUCCESS if the Surface was
159 * configured (it returns VLC_EGENERIC after Android ICS).
160 */
161 int AWindowHandler_setBuffersGeometry(AWindowHandler *p_awh, enum AWindow_ID id,
162 int i_width, int i_height, int i_format);
163
164 /**
165 * Returns true if the video layout can be changed
166 */
167 bool AWindowHandler_canSetVideoLayout(AWindowHandler *p_awh);
168
169 /**
170 * Set the video layout
171 *
172 * Should be called only if AWindowHandler_canSetVideoLayout() returned true
173 */
174 int AWindowHandler_setVideoLayout(AWindowHandler *p_awh,
175 int i_width, int i_height,
176 int i_visible_width, int i_visible_height,
177 int i_sar_num, int i_sar_den);
178
179 /**
180 * Attach a SurfaceTexture to the OpenGL ES context that is current on the
181 * calling thread.
182 *
183 * See SurfaceTexture Android documentation.
184 * \return 0 on success, -1 on error.
185 */
186 int
187 SurfaceTexture_attachToGLContext(AWindowHandler *p_awh, int tex_name);
188
189 /**
190 * Detach a SurfaceTexture from the OpenGL ES context that owns the OpenGL ES
191 * texture object.
192 */
193 void
194 SurfaceTexture_detachFromGLContext(AWindowHandler *p_awh);
195
196 /**
197 * Get a Java Surface from the attached SurfaceTexture
198 *
199 * This object can be used with mediacodec_jni.
200 */
201 static inline jobject
SurfaceTexture_getSurface(AWindowHandler * p_awh)202 SurfaceTexture_getSurface(AWindowHandler *p_awh)
203 {
204 return AWindowHandler_getSurface(p_awh, AWindow_SurfaceTexture);
205 }
206
207 /**
208 * Get a ANativeWindow from the attached SurfaceTexture
209 *
210 * This pointer can be used with mediacodec_ndk.
211 */
212 static inline ANativeWindow *
SurfaceTexture_getANativeWindow(AWindowHandler * p_awh)213 SurfaceTexture_getANativeWindow(AWindowHandler *p_awh)
214 {
215 return AWindowHandler_getANativeWindow(p_awh, AWindow_SurfaceTexture);
216 }
217
218 /**
219 * Wait for a new frame and update it
220 *
221 * This function must be called from the OpenGL thread. This is an helper that
222 * waits for a new frame via the Java SurfaceTexture.OnFrameAvailableListener
223 * listener and update the frame via the SurfaceTexture.updateTexImage()
224 * method.
225 *
226 * \param pp_transform_mtx the transform matrix fetched from
227 * SurfaceTexture.getTransformMatrix() after the
228 * SurfaceTexture.updateTexImage() call
229 * \return VLC_SUCCESS or a VLC error
230 */
231 int
232 SurfaceTexture_waitAndUpdateTexImage(AWindowHandler *p_awh,
233 const float **pp_transform_mtx);
234