Commit e29f8ecf authored by Thomas Guillem's avatar Thomas Guillem

android: add AWindowHandler and android_getEnv

android_getEnv: get a JNIEnv* from the Java VM passed via the "android-jvm"
option.

AWindowHandler: utility class that provide a way to get the Video / Subtitles
Java Surface or ANativeWindow.
parent 63dbabfd
......@@ -4,7 +4,8 @@ aout_LTLIBRARIES =
libopensles_android_plugin_la_SOURCES = audio_output/opensles_android.c
libopensles_android_plugin_la_LIBADD = $(LIBDL) $(LIBM)
libandroid_audiotrack_plugin_la_SOURCES = audio_output/audiotrack.c
libandroid_audiotrack_plugin_la_SOURCES = audio_output/audiotrack.c \
video_output/android/utils.c video_output/android/utils.h
libandroid_audiotrack_plugin_la_CFLAGS = $(AM_CFLAGS)
if HAVE_ANDROID
......
......@@ -33,6 +33,7 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
#include "../video_output/android/utils.h"
#define MIN_AUDIOTRACK_BUFFER_US INT64_C(250000) // 250ms
#define MAX_AUDIOTRACK_BUFFER_US INT64_C(1000000) // 1000ms
......@@ -131,7 +132,7 @@ vlc_module_begin ()
vlc_module_end ()
#define THREAD_NAME "android_audiotrack"
extern JNIEnv *jni_get_env(const char *name);
#define GET_ENV() android_getEnv( VLC_OBJECT(p_aout), THREAD_NAME )
static struct
{
......@@ -200,26 +201,19 @@ static struct
/* init all jni fields.
* Done only one time during the first initialisation */
static bool
InitJNIFields( audio_output_t *p_aout )
InitJNIFields( audio_output_t *p_aout, JNIEnv* env )
{
static vlc_mutex_t lock = VLC_STATIC_MUTEX;
static int i_init_state = -1;
bool ret;
jclass clazz;
jfieldID field;
JNIEnv* env = NULL;
vlc_mutex_lock( &lock );
if( i_init_state != -1 )
goto end;
if (!(env = jni_get_env(THREAD_NAME)))
{
i_init_state = 0;
goto end;
}
#define CHECK_EXCEPTION( what, critical ) do { \
if( (*env)->ExceptionOccurred( env ) ) \
{ \
......@@ -650,7 +644,7 @@ TimeGet( audio_output_t *p_aout, mtime_t *restrict p_delay )
mtime_t i_audiotrack_us;
JNIEnv *env;
if( p_sys->b_error || !( env = jni_get_env( THREAD_NAME ) ) )
if( p_sys->b_error || !( env = GET_ENV() ) )
return -1;
if( p_sys->b_spdif )
......@@ -848,7 +842,7 @@ Start( audio_output_t *p_aout, audio_sample_format_t *restrict p_fmt )
b_spdif = var_InheritBool( p_aout, "spdif" );
i_max_channels = var_InheritInteger( p_aout, "audiotrack-audio-channels" );
if( !( env = jni_get_env( THREAD_NAME ) ) )
if( !( env = GET_ENV() ) )
return VLC_EGENERIC;
p_sys->fmt = *p_fmt;
......@@ -1043,7 +1037,7 @@ Stop( audio_output_t *p_aout )
aout_sys_t *p_sys = p_aout->sys;
JNIEnv *env;
if( !( env = jni_get_env( THREAD_NAME ) ) )
if( !( env = GET_ENV() ) )
return;
if( p_sys->p_audiotrack )
......@@ -1326,7 +1320,7 @@ Play( audio_output_t *p_aout, block_t *p_buffer )
mtime_t i_play_wait = 0;
aout_sys_t *p_sys = p_aout->sys;
if( p_sys->b_error || !( env = jni_get_env( THREAD_NAME ) ) )
if( p_sys->b_error || !( env = GET_ENV() ) )
goto bailout;
p_sys->b_error = AudioTrack_PreparePlay( env, p_aout, p_buffer )
......@@ -1368,7 +1362,7 @@ Pause( audio_output_t *p_aout, bool b_pause, mtime_t i_date )
JNIEnv *env;
VLC_UNUSED( i_date );
if( p_sys->b_error || !( env = jni_get_env( THREAD_NAME ) ) )
if( p_sys->b_error || !( env = GET_ENV() ) )
return;
if( b_pause )
......@@ -1389,7 +1383,7 @@ Flush( audio_output_t *p_aout, bool b_wait )
aout_sys_t *p_sys = p_aout->sys;
JNIEnv *env;
if( p_sys->b_error || !( env = jni_get_env( THREAD_NAME ) ) )
if( p_sys->b_error || !( env = GET_ENV() ) )
return;
/* Android doc:
......@@ -1434,8 +1428,9 @@ Open( vlc_object_t *obj )
{
audio_output_t *p_aout = (audio_output_t *) obj;
aout_sys_t *p_sys;
JNIEnv *env = GET_ENV();
if( !InitJNIFields( p_aout ) )
if( !env || !InitJNIFields( p_aout, env ) )
return VLC_EGENERIC;
p_sys = calloc( 1, sizeof (aout_sys_t) );
......@@ -1463,7 +1458,7 @@ Close( vlc_object_t *obj )
aout_sys_t *p_sys = p_aout->sys;
JNIEnv *env;
if( ( env = jni_get_env( THREAD_NAME ) ) )
if( ( env = GET_ENV() ) )
{
if( p_sys->p_bytearray )
(*env)->DeleteGlobalRef( env, p_sys->p_bytearray );
......
......@@ -391,6 +391,9 @@ libomxil_plugin_la_SOURCES = \
codec/omxil/qcom.c codec/omxil/qcom.h \
codec/omxil/omxil.c codec/omxil/omxil.h codec/omxil/omxil_core.c codec/omxil/omxil_core.h \
video_chroma/copy.c
if HAVE_ANDROID
libomxil_plugin_la_SOURCES += video_output/android/utils.c video_output/android/utils.h
endif
libomxil_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil $(CFLAGS_omxil)
libomxil_plugin_la_LIBADD = $(LIBDL)
libomxil_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
......@@ -408,6 +411,7 @@ libmediacodec_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/codec/omxil
libmediacodec_plugin_la_SOURCES = codec/omxil/mediacodec.c codec/omxil/mediacodec.h \
codec/omxil/mediacodec_jni.c codec/omxil/mediacodec_ndk.c codec/omxil/utils.c \
video_chroma/copy.c codec/omxil/android_opaque.c codec/omxil/android_opaque.h \
video_output/android/utils.c video_output/android/utils.h
packetizer/h264_nal.c packetizer/h264_nal.h
packetizer/hevc_nal.c packetizer/hevc_nal.h
......
......@@ -48,9 +48,7 @@
#include "../../video_output/android/android_window.h"
/* JNI functions to get/set an Android Surface object. */
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
extern void jni_EventHardwareAccelerationError();
extern void jni_EventHardwareAccelerationError(); // TODO REMOVE
/* Implementation of a circular buffer of timestamps with overwriting
* of older values. MediaCodec has only one type of timestamp, if a
......@@ -136,6 +134,7 @@ struct csd
struct decoder_sys_t
{
mc_api *api;
AWindowHandler *p_awh;
char *psz_name;
uint32_t nal_size;
......@@ -341,7 +340,6 @@ static int StartMediaCodec(decoder_t *p_dec)
int i_angle = 0, i_ret;
size_t h264_profile = 0;
char *psz_name = NULL;
jobject jsurface = NULL;
if (p_dec->fmt_in.i_extra && !p_sys->p_csd)
{
......@@ -424,12 +422,10 @@ static int StartMediaCodec(decoder_t *p_dec)
if (!psz_name)
return VLC_EGENERIC;
if (var_InheritBool(p_dec, CFG_PREFIX "dr"))
jsurface = jni_LockAndGetAndroidJavaSurface();
i_ret = p_sys->api->start(p_sys->api, jsurface, psz_name, p_sys->mime,
if (!p_sys->p_awh && var_InheritBool(p_dec, CFG_PREFIX "dr"))
p_sys->p_awh = AWindowHandler_new(VLC_OBJECT(p_dec));
i_ret = p_sys->api->start(p_sys->api, p_sys->p_awh, psz_name, p_sys->mime,
p_sys->i_width, p_sys->i_height, i_angle);
if (jsurface)
jni_UnlockAndroidSurface();
if (i_ret == VLC_SUCCESS)
{
......@@ -462,6 +458,11 @@ static void StopMediaCodec(decoder_t *p_dec)
p_sys->psz_name = NULL;
p_sys->api->stop(p_sys->api);
if (p_sys->p_awh)
{
AWindowHandler_releaseANativeWindow(p_sys->p_awh, AWindow_Video);
AWindowHandler_releaseSurface(p_sys->p_awh, AWindow_Video);
}
}
/*****************************************************************************
......@@ -592,6 +593,8 @@ static void CloseDecoder(vlc_object_t *p_this)
timestamp_FifoRelease(p_sys->timestamp_fifo);
p_sys->api->clean(p_sys->api);
free(p_sys->api);
if (p_sys->p_awh)
AWindowHandler_destroy(p_sys->p_awh);
free(p_sys);
}
......
......@@ -22,6 +22,7 @@
#define VLC_MEDIACODEC_H
#include <vlc_common.h>
#include "../../video_output/android/utils.h"
typedef struct mc_api mc_api;
typedef struct mc_api_sys mc_api_sys;
......@@ -74,7 +75,7 @@ struct mc_api
bool b_support_interlaced;
void (*clean)(mc_api *);
int (*start)(mc_api *, jobject jsurface, const char *psz_name,
int (*start)(mc_api *, AWindowHandler *p_awh, const char *psz_name,
const char *psz_mime, int i_width, int i_height, int i_angle);
int (*stop)(mc_api *);
int (*flush)(mc_api *);
......
......@@ -38,7 +38,6 @@
#include "mediacodec.h"
#define THREAD_NAME "mediacodec_jni"
extern JNIEnv *jni_get_env(const char *name);
#define BUFFER_FLAG_CODEC_CONFIG 2
#define INFO_OUTPUT_BUFFERS_CHANGED -3
......@@ -174,7 +173,7 @@ static inline bool check_exception(JNIEnv *env)
return false;
}
#define CHECK_EXCEPTION() check_exception( env )
#define GET_ENV() if (!(env = jni_get_env(THREAD_NAME))) return VLC_EGENERIC;
#define GET_ENV() if (!(env = android_getEnv(api->p_obj, THREAD_NAME))) return VLC_EGENERIC;
/* Initialize all jni fields.
* Done only one time during the first initialisation */
......@@ -283,7 +282,7 @@ char* MediaCodec_GetName(vlc_object_t *p_obj, const char *psz_mime,
jstring jmime;
char *psz_name = NULL;
if (!(env = jni_get_env(THREAD_NAME)))
if (!(env = android_getEnv(p_obj, THREAD_NAME)))
return NULL;
if (!InitJNIFields(p_obj, env))
......@@ -459,7 +458,7 @@ static int Stop(mc_api *api)
/*****************************************************************************
* Start
*****************************************************************************/
static int Start(mc_api *api, jobject jsurface, const char *psz_name,
static int Start(mc_api *api, AWindowHandler *p_awh, const char *psz_name,
const char *psz_mime, int i_width, int i_height, int i_angle)
{
mc_api_sys *p_sys = api->p_sys;
......@@ -474,6 +473,7 @@ static int Start(mc_api *api, jobject jsurface, const char *psz_name,
jobject jinput_buffers = NULL;
jobject joutput_buffers = NULL;
jobject jbuffer_info = NULL;
jobject jsurface = NULL;
GET_ENV();
......@@ -499,6 +499,8 @@ static int Start(mc_api *api, jobject jsurface, const char *psz_name,
jfields.create_video_format, jmime,
i_width, i_height);
if (p_awh)
jsurface = AWindowHandler_getSurface(p_awh, AWindow_Video);
b_direct_rendering = !!jsurface;
/* There is no way to rotate the video using direct rendering (and using a
......@@ -825,7 +827,7 @@ static void Clean(mc_api *api)
*****************************************************************************/
int MediaCodecJni_Init(mc_api *api)
{
JNIEnv* env = NULL;
JNIEnv *env;
GET_ENV();
......
......@@ -37,10 +37,8 @@
#include "omxil_utils.h"
#include "mediacodec.h"
#include "../../video_output/android/utils.h"
#define THREAD_NAME "mediacodec_ndk"
extern JNIEnv *jni_get_env(const char *name);
/* Not in NdkMedia API but we need it since we send config data via input
* buffers and not via "csd-*" buffers from AMediaFormat */
......@@ -180,7 +178,6 @@ struct syms
} AMediaFormat;
};
static struct syms syms;
static native_window_api_t anw_syms;
struct members
{
......@@ -246,12 +243,6 @@ InitSymbols(mc_api *api)
}
*(void **)((uint8_t*)&syms + members[i].offset) = sym;
}
void *anw_handle = LoadNativeWindowAPI(&anw_syms);
if (!anw_handle)
{
dlclose(ndk_handle);
goto end;
}
i_init_state = 1;
end:
......@@ -271,7 +262,6 @@ struct mc_api_sys
{
AMediaCodec* p_codec;
AMediaFormat* p_format;
ANativeWindow* p_anw;
};
/*****************************************************************************
......@@ -299,11 +289,6 @@ static int Stop(mc_api *api)
syms.AMediaFormat.delete(p_sys->p_format);
p_sys->p_format = NULL;
}
if (p_sys->p_anw)
{
anw_syms.winRelease(p_sys->p_anw);
p_sys->p_anw = NULL;
}
msg_Dbg(api->p_obj, "MediaCodec via NDK closed");
return VLC_SUCCESS;
......@@ -312,11 +297,12 @@ static int Stop(mc_api *api)
/*****************************************************************************
* Start
*****************************************************************************/
static int Start(mc_api *api, jobject jsurface, const char *psz_name,
static int Start(mc_api *api, AWindowHandler *p_awh, const char *psz_name,
const char *psz_mime, int i_width, int i_height, int i_angle)
{
mc_api_sys *p_sys = api->p_sys;
int i_ret = VLC_EGENERIC;
ANativeWindow *p_anw = NULL;
p_sys->p_codec = syms.AMediaCodec.createCodecByName(psz_name);
if (!p_sys->p_codec)
......@@ -338,17 +324,11 @@ static int Start(mc_api *api, jobject jsurface, const char *psz_name,
syms.AMediaFormat.setInt32(p_sys->p_format, "rotation-degrees", i_angle);
syms.AMediaFormat.setInt32(p_sys->p_format, "encoder", 0);
if (jsurface)
{
JNIEnv *env;
if (!(env = jni_get_env(THREAD_NAME)))
goto error;
p_sys->p_anw = anw_syms.winFromSurface(env, jsurface);
}
if (p_awh)
p_anw = AWindowHandler_getANativeWindow(p_awh, AWindow_Video);
if (syms.AMediaCodec.configure(p_sys->p_codec, p_sys->p_format,
p_sys->p_anw, NULL, 0) != AMEDIA_OK)
p_anw, NULL, 0) != AMEDIA_OK)
{
msg_Err(api->p_obj, "AMediaCodec.configure failed");
goto error;
......@@ -360,7 +340,7 @@ static int Start(mc_api *api, jobject jsurface, const char *psz_name,
}
api->b_started = true;
api->b_direct_rendering = !!p_sys->p_anw;
api->b_direct_rendering = !!p_anw;
api->b_support_interlaced = true;
i_ret = VLC_SUCCESS;
......
......@@ -68,9 +68,6 @@
#if defined(USE_IOMX)
/* JNI functions to get/set an Android Surface object. */
#define THREAD_NAME "omxil"
extern JNIEnv *jni_get_env(const char *name);
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
#endif
/*****************************************************************************
......@@ -2020,8 +2017,7 @@ static void HwBuffer_ChangeState( decoder_t *p_dec, OmxPort *p_port,
static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
{
VLC_UNUSED( p_dec );
void *surf;
JNIEnv *p_env;
ANativeWindow *p_anw;
OMX_ERRORTYPE omx_error;
if( !p_port->b_direct || p_port->definition.eDir != OMX_DirOutput ||
......@@ -2045,38 +2041,30 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
goto error;
}
vlc_cond_init (&p_port->p_hwbuf->wait);
p_port->p_hwbuf->p_library = LoadNativeWindowAPI( &p_port->p_hwbuf->native_window );
if( !p_port->p_hwbuf->p_library )
p_port->p_hwbuf->p_awh = AWindowHandler_new( VLC_OBJECT( p_dec ) );
if( !p_port->p_hwbuf->p_awh )
{
msg_Warn( p_dec, "LoadNativeWindowAPI failed" );
msg_Warn( p_dec, "AWindowHandler_new failed" );
goto error;
}
if( LoadNativeWindowPrivAPI( &p_port->p_hwbuf->anwpriv ) != 0 )
p_port->p_hwbuf->anwpriv = AWindowHandler_getANativeWindowPrivAPI( p_port->p_hwbuf->p_awh );
if( !p_port->p_hwbuf->anwpriv )
{
msg_Warn( p_dec, "LoadNativeWindowPrivAPI failed" );
msg_Warn( p_dec, "AWindowHandler_getANativeWindowPrivAPI failed" );
goto error;
}
surf = jni_LockAndGetAndroidJavaSurface();
if( !surf ) {
msg_Warn( p_dec, "jni_LockAndGetAndroidJavaSurface failed" );
p_anw = AWindowHandler_getANativeWindow( p_port->p_hwbuf->p_awh,
AWindow_Video );
if( !p_anw )
{
msg_Warn( p_dec, "AWindowHandler_getVideoANativeWindow failed" );
goto error;
}
if ((p_env = jni_get_env(THREAD_NAME)))
p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
jni_UnlockAndroidSurface();
if( !p_port->p_hwbuf->window ) {
msg_Warn( p_dec, "winFromSurface failed" );
goto error;
}
p_port->p_hwbuf->window_priv =
p_port->p_hwbuf->anwpriv.connect( p_port->p_hwbuf->window );
p_port->p_hwbuf->window_priv = p_port->p_hwbuf->anwpriv->connect( p_anw );
if( !p_port->p_hwbuf->window_priv ) {
msg_Warn( p_dec, "connect failed" );
p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
p_port->p_hwbuf->window = NULL;
goto error;
}
......@@ -2106,19 +2094,19 @@ static void HwBuffer_Destroy( decoder_t *p_dec, OmxPort *p_port )
{
if( p_port->p_hwbuf )
{
if( p_port->p_hwbuf->p_library )
if( p_port->p_hwbuf->window_priv )
{
if( p_port->p_hwbuf->window )
{
HwBuffer_Stop( p_dec, p_port );
HwBuffer_FreeBuffers( p_dec, p_port );
HwBuffer_Join( p_dec, p_port );
p_port->p_hwbuf->anwpriv.disconnect( p_port->p_hwbuf->window_priv );
pf_enable_graphic_buffers( p_port->omx_handle,
p_port->i_port_index, OMX_FALSE );
p_port->p_hwbuf->native_window.winRelease( p_port->p_hwbuf->window );
}
dlclose( p_port->p_hwbuf->p_library );
HwBuffer_Stop( p_dec, p_port );
HwBuffer_FreeBuffers( p_dec, p_port );
HwBuffer_Join( p_dec, p_port );
p_port->p_hwbuf->anwpriv->disconnect( p_port->p_hwbuf->window_priv );
pf_enable_graphic_buffers( p_port->omx_handle,
p_port->i_port_index, OMX_FALSE );
}
if( p_port->p_hwbuf->p_awh )
{
AWindowHandler_destroy( p_port->p_hwbuf->p_awh );
p_port->p_hwbuf->p_awh = NULL;
}
vlc_cond_destroy( &p_port->p_hwbuf->wait );
......@@ -2177,17 +2165,17 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
default:
i_angle = 0;
}
p_port->p_hwbuf->anwpriv.setOrientation( p_port->p_hwbuf->window_priv,
p_port->p_hwbuf->anwpriv->setOrientation( p_port->p_hwbuf->window_priv,
i_angle );
}
if( p_port->p_hwbuf->anwpriv.setUsage( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->setUsage( p_port->p_hwbuf->window_priv,
true, (int) i_hw_usage ) != 0 )
{
msg_Err( p_dec, "can't set usage" );
goto error;
}
if( p_port->p_hwbuf->anwpriv.setBuffersGeometry( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->setBuffersGeometry( p_port->p_hwbuf->window_priv,
def->format.video.nFrameWidth,
def->format.video.nFrameHeight,
colorFormat ) != 0 )
......@@ -2196,7 +2184,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
goto error;
}
if( p_port->p_hwbuf->anwpriv.getMinUndequeued( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->getMinUndequeued( p_port->p_hwbuf->window_priv,
&min_undequeued ) != 0 )
{
msg_Err( p_dec, "can't get min_undequeued" );
......@@ -2218,7 +2206,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
omx_error, ErrorToString(omx_error) );
}
if( p_port->p_hwbuf->anwpriv.setBufferCount( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->setBufferCount( p_port->p_hwbuf->window_priv,
def->nBufferCountActual ) != 0 )
{
msg_Err( p_dec, "can't set buffer_count" );
......@@ -2246,7 +2234,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
{
void *p_handle = NULL;
if( p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->dequeue( p_port->p_hwbuf->window_priv,
&p_handle ) != 0 )
{
msg_Err( p_dec, "OMXHWBuffer_dequeue Fail" );
......@@ -2259,7 +2247,7 @@ static int HwBuffer_AllocateBuffers( decoder_t *p_dec, OmxPort *p_port )
for(; i < p_port->p_hwbuf->i_buffers; i++)
{
OMX_DBG( "canceling buffer(%d)", i );
p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv,
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv,
p_port->p_hwbuf->pp_handles[i] );
}
......@@ -2290,7 +2278,7 @@ static int HwBuffer_FreeBuffers( decoder_t *p_dec, OmxPort *p_port )
if( p_handle && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
{
p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv, p_handle );
HwBuffer_ChangeState( p_dec, p_port, i, BUF_STATE_NOT_OWNED );
}
}
......@@ -2330,7 +2318,7 @@ static int HwBuffer_Start( decoder_t *p_dec, OmxPort *p_port )
if( p_header && p_port->p_hwbuf->i_states[i] == BUF_STATE_OWNED )
{
if( p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv,
if( p_port->p_hwbuf->anwpriv->lock( p_port->p_hwbuf->window_priv,
p_header->pBuffer ) != 0 )
{
msg_Err( p_dec, "lock failed" );
......@@ -2380,7 +2368,7 @@ static int HwBuffer_Stop( decoder_t *p_dec, OmxPort *p_port )
void *p_handle = p_port->pp_buffers[p_picsys->priv.hw.i_index]->pBuffer;
if( p_handle )
{
p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv, p_handle );
HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index,
BUF_STATE_NOT_OWNED );
}
......@@ -2475,7 +2463,7 @@ static void HwBuffer_SetCrop( decoder_t *p_dec, OmxPort *p_port,
{
VLC_UNUSED( p_dec );
p_port->p_hwbuf->anwpriv.setCrop( p_port->p_hwbuf->window_priv,
p_port->p_hwbuf->anwpriv->setCrop( p_port->p_hwbuf->window_priv,
p_rect->nLeft, p_rect->nTop,
p_rect->nWidth, p_rect->nHeight );
}
......@@ -2510,9 +2498,9 @@ static void *DequeueThread( void *data )
/* The thread can be stuck here. It shouldn't happen since we make sure
* we call the dequeue function if there is at least one buffer
* available. */
err = p_port->p_hwbuf->anwpriv.dequeue( p_port->p_hwbuf->window_priv, &p_handle );
err = p_port->p_hwbuf->anwpriv->dequeue( p_port->p_hwbuf->window_priv, &p_handle );
if( err == 0 )
err = p_port->p_hwbuf->anwpriv.lock( p_port->p_hwbuf->window_priv, p_handle );
err = p_port->p_hwbuf->anwpriv->lock( p_port->p_hwbuf->window_priv, p_handle );
HWBUFFER_LOCK();
......@@ -2524,7 +2512,7 @@ static void *DequeueThread( void *data )
if( !p_port->p_hwbuf->b_run )
{
p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv, p_handle );
continue;
}
......@@ -2539,7 +2527,7 @@ static void *DequeueThread( void *data )
}
if( i_index == -1 )
{
msg_Err( p_dec, "p_port->p_hwbuf->anwpriv.dequeue returned unknown handle" );
msg_Err( p_dec, "p_port->p_hwbuf->anwpriv->dequeue returned unknown handle" );
continue;
}
......@@ -2589,9 +2577,9 @@ static void UnlockPicture( picture_t* p_pic, bool b_render )
}
if( b_render )
p_port->p_hwbuf->anwpriv.queue( p_port->p_hwbuf->window_priv, p_handle );
p_port->p_hwbuf->anwpriv->queue( p_port->p_hwbuf->window_priv, p_handle );
else
p_port->p_hwbuf->anwpriv.cancel( p_port->p_hwbuf->window_priv, p_handle );
p_port->p_hwbuf->anwpriv->cancel( p_port->p_hwbuf->window_priv, p_handle );
HwBuffer_ChangeState( p_dec, p_port, p_picsys->priv.hw.i_index, BUF_STATE_NOT_OWNED );
HWBUFFER_BROADCAST( p_port );
......
......@@ -74,11 +74,9 @@ typedef struct HwBuffer
unsigned int i_max_owned;
unsigned int i_owned;
void *p_library;
void *window;
#if defined(USE_IOMX)
native_window_api_t native_window;
native_window_priv_api_t anwpriv;
AWindowHandler *p_awh;
native_window_priv_api_t *anwpriv;
native_window_priv *window_priv;
#endif
......
......@@ -266,7 +266,8 @@ libegl_android_plugin_la_SOURCES = video_output/egl.c
libegl_android_plugin_la_CFLAGS = $(AM_CFLAGS) $(EGL_CFLAGS) -DUSE_PLATFORM_ANDROID=1
libegl_android_plugin_la_LIBADD = $(EGL_LIBS)
libandroid_native_window_plugin_la_SOURCES = video_output/android/nativewindow.c video_output/android/utils.c
libandroid_native_window_plugin_la_SOURCES = video_output/android/nativewindow.c \
video_output/android/utils.c video_output/android/utils.h
libandroid_native_window_plugin_la_CFLAGS = $(AM_CFLAGS)
libandroid_native_window_plugin_la_LIBADD = $(LIBDL)
......
......@@ -67,16 +67,6 @@ vlc_module_end()
*****************************************************************************/
#define THREAD_NAME "android_window"
extern JNIEnv *jni_get_env(const char *name);
extern jobject jni_LockAndGetAndroidJavaSurface();
extern jobject jni_LockAndGetSubtitlesSurface();
extern void jni_UnlockAndroidSurface();
extern void jni_SetSurfaceLayout(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
extern int jni_ConfigureSurface(jobject jsurf, int width, int height, int hal, bool *configured);
extern int jni_GetWindowSize(int *width, int *height);
extern void jni_getMouseCoordinates(int *, int *, int *, int *);
static const vlc_fourcc_t subpicture_chromas[] =
{
......@@ -101,7 +91,7 @@ struct android_window
bool b_use_priv;
bool b_opaque;
jobject jsurf;
enum AWindow_ID id;
ANativeWindow *p_handle;
native_window_priv *p_handle_priv;
};
......@@ -120,10 +110,9 @@ struct vout_display_sys_t
int i_display_width;
int i_display_height;
void *p_library;
native_window_api_t anw;
native_window_priv_api_t anwp;
bool b_has_anwp;
AWindowHandler *p_awh;
native_window_api_t *anw;
native_window_priv_api_t *anwp;
android_window *p_window;
android_window *p_sub_window;
......@@ -159,7 +148,8 @@ static inline int ChromaToAndroidHal(vlc_fourcc_t i_chroma)
}
}
static int UpdateWindowSize(video_format_t *p_fmt, bool b_cropped)
static int UpdateWindowSize(vout_display_sys_t *sys, video_format_t *p_fmt,
bool b_cropped)
{
unsigned int i_width, i_height;
unsigned int i_sar_num = 1, i_sar_den = 1;
......@@ -179,11 +169,10 @@ static int UpdateWindowSize(video_format_t *p_fmt, bool b_cropped)
i_height = rot_fmt.i_height;
}
jni_SetSurfaceLayout(i_width, i_height,
rot_fmt.i_visible_width,
rot_fmt.i_visible_height,
i_sar_num,
i_sar_den);
AWindowHandler_setWindowLayout(sys->p_awh, i_width, i_height,
rot_fmt.i_visible_width,
rot_fmt.i_visible_height,
i_sar_num, i_sar_den);
return 0;
}
......@@ -310,30 +299,25 @@ static void SetupPictureYV12(picture_t *p_picture, uint32_t i_in_stride)
}
}
static int AndroidWindow_SetSurface(vout_display_sys_t *sys,
android_window *p_window,
jobject jsurf)
static void AndroidWindow_DisconnectSurface(vout_display_sys_t *sys,
android_window *p_window)
{
if (jsurf != p_window->jsurf) {
if (p_window->p_handle_priv) {
sys->anwp.disconnect(p_window->p_handle_priv);
p_window->p_handle_priv = NULL;
}
if (p_window->p_handle) {
sys->anw.winRelease(p_window->p_handle);
p_window->p_handle = NULL;
}
if (p_window->p_handle_priv) {
sys->anwp->disconnect(p_window->p_handle_priv);
p_window->p_handle_priv = NULL;
}
if (p_window->p_handle) {
AWindowHandler_releaseANativeWindow(sys->p_awh, p_window->id);