Commit c4afc796 authored by Adrien Maglo's avatar Adrien Maglo

Native code part of the new video output module that displays frames using Java OpenGL ES API.

Still need some cleaning.
parent 09954fb5
......@@ -34,9 +34,9 @@ vlc-android/jni/Android.mk:
echo 'LOCAL_PATH := $$(call my-dir)' >> vlc-android/jni/Android.mk; \
echo "include \$$(CLEAR_VARS)\n" >> vlc-android/jni/Android.mk; \
echo "LOCAL_MODULE := libvlcjni" >> vlc-android/jni/Android.mk; \
echo "LOCAL_SRC_FILES := libvlcjni.c" >> vlc-android/jni/Android.mk; \
echo "LOCAL_SRC_FILES := libvlcjni.c vout.c" >> vlc-android/jni/Android.mk; \
echo "LOCAL_C_INCLUDES := \$$(LOCAL_PATH)/../../../../../include" >> vlc-android/jni/Android.mk; \
echo "LOCAL_LDLIBS := -L$$ANDROID_NDK/platforms/android-9/arch-arm/usr/lib -L$$VLC_CONTRIB/lib $$LDFLAGS $$prefix$$VLC_BUILD_DIR/src/.libs/libvlc.a $$prefix$$VLC_BUILD_DIR/src/.libs/libvlccore.a -ldl -lz -lm -logg -lvorbisenc -lvorbis -lFLAC -lspeex -ltheora -lavformat -lavcodec -lavcore -lavutil -lpostproc -lswscale -lmpeg2 -lgcc -lpng -logg -ldca -ldvbpsi -ltwolame -lkate -lOpenSLES -lGLESv1_CM -lEGL -llog -landroid -la52" >> vlc-android/jni/Android.mk; \
echo "LOCAL_LDLIBS := -L$$ANDROID_NDK/platforms/android-9/arch-arm/usr/lib -L$$VLC_CONTRIB/lib $$LDFLAGS $$prefix$$VLC_BUILD_DIR/src/.libs/libvlc.a $$prefix$$VLC_BUILD_DIR/src/.libs/libvlccore.a -ldl -lz -lm -logg -lvorbisenc -lvorbis -lFLAC -lspeex -ltheora -lavformat -lavcodec -lavcore -lavutil -lpostproc -lswscale -lmpeg2 -lgcc -lpng -logg -ldca -ldvbpsi -ltwolame -lkate -llog -la52" >> vlc-android/jni/Android.mk; \
echo "include \$$(BUILD_SHARED_LIBRARY)" >> vlc-android/jni/Android.mk
vlc-android/libs/armeabi/libvlcjni.so: vlc-android/jni/Android.mk
......
#include <stdio.h>
#include <string.h>
#include <android/native_window_jni.h>
#include <assert.h>
#include <jni.h>
#include <vlc/vlc.h>
#include "libvlcjni.h"
#include "vout.h"
#include "log.h"
// Native android window to display the video.
ANativeWindow *p_nativeWindow;
JavaVM *myVm; // Pointer on the Java virtul machine.
jobject myJavaLibVLC; // Pointer on the LibVLC Java object.
void Java_vlc_android_LibVLC_setSurface(JNIEnv *env, jobject thiz, jobject surface)
jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
p_nativeWindow = ANativeWindow_fromSurface(env, surface);
// Keep a reference on the Java VM.
myVm = vm;
LOGD("JNI interface loaded.\n");
return JNI_VERSION_1_2;
}
jint Java_vlc_android_LibVLC_init(JNIEnv *env, jobject thiz)
{
char psz_pWin[255];
snprintf(psz_pWin, 255, "%i", p_nativeWindow);
myJavaLibVLC = (*env)->NewGlobalRef(env, thiz);
const char *argv[] = {"-I", "dummy", "-vvv", "--no-plugins-cache",
"--no-drop-late-frames",
"--vout", "egl_android",
"--egl-android-window", psz_pWin};
return (jint)libvlc_new_with_builtins(9, argv, vlc_builtins_modules);
"--no-audio", "--no-drop-late-frames",
"--vout", "vmem"};
jint ret = (jint)libvlc_new_with_builtins(8, argv, vlc_builtins_modules);
LOGI("LibVLC loaded.\n");
return ret;
}
void Java_vlc_android_LibVLC_destroy(JNIEnv *env, jobject thiz, jint instance)
{
(*env)->DeleteGlobalRef(env, myJavaLibVLC);
libvlc_instance_t *p_instance = (libvlc_instance_t*)instance;
libvlc_release(p_instance);
}
void Java_vlc_android_LibVLC_readMedia(JNIEnv *env, jobject thiz, jint instance,
jstring mrl)
{
......@@ -47,7 +59,11 @@ void Java_vlc_android_LibVLC_readMedia(JNIEnv *env, jobject thiz, jint instance,
psz_mrl);
/* Create a media player playing environement */
libvlc_media_player_t *mp = libvlc_media_player_new_from_media(m);
libvlc_media_player_t *mp = libvlc_media_player_new((libvlc_instance_t*)instance);
libvlc_media_player_set_media(mp, m);
libvlc_video_set_format_callbacks(mp, vout_format, vout_cleanup);
libvlc_video_set_callbacks(mp, vout_lock, vout_unlock, vout_display, NULL);
/* No need to keep the media now */
libvlc_media_release(m);
......@@ -60,6 +76,7 @@ void Java_vlc_android_LibVLC_readMedia(JNIEnv *env, jobject thiz, jint instance,
(*env)->ReleaseStringUTFChars(env, mrl, psz_mrl);
}
jstring Java_vlc_android_LibVLC_version(JNIEnv* env, jobject thiz)
{
return (*env)->NewStringUTF(env, libvlc_get_version());
......
#ifndef LIBVLCJNI_LOG_H
#define LIBVLCJNI_LOG_H
#include <android/log.h>
#define LOG_TAG "libvlcjni"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#endif // LIBVLCJNI_LOG_H
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <jni.h>
#include <vlc/vlc.h>
#include "vout.h"
#include "log.h"
extern JavaVM *myVm;
extern jobject myJavaLibVLC;
unsigned vout_format(void **opaque, char *chroma,
unsigned *width, unsigned *height,
unsigned *pitches,
unsigned *lines)
{
vout_sys_t **pp_sys = (vout_sys_t **)opaque;
*pp_sys = malloc(sizeof(vout_sys_t));
if (*pp_sys == NULL)
return 0;
vout_sys_t *p_sys = *pp_sys;
p_sys->i_frameWidth = *width;
p_sys->i_frameHeight = *height;
p_sys->i_frameSize = p_sys->i_frameWidth * p_sys->i_frameHeight * 2;
p_sys->p_frameData = calloc(1, p_sys->i_frameSize);
if (p_sys->p_frameData == NULL)
return 0;
strcpy(chroma, "RV16");
*pitches = p_sys->i_frameWidth * 2;
*lines = p_sys->i_frameHeight;
return 1;
}
void vout_cleanup(void *opaque)
{
vout_sys_t *p_sys = opaque;
free(p_sys);
}
void *vout_lock(void *opaque, void **pixels)
{
vout_sys_t *p_sys = (vout_sys_t *)opaque;
*pixels = p_sys->p_frameData;
return NULL;
}
void vout_unlock(void *opaque, void *picture, void *const *p_pixels)
{
// Nothing to do here until now.
}
void vout_display(void *opaque, void *picture)
{
LOGI("Display\n");
vout_sys_t *p_sys = (vout_sys_t *)opaque;
static char b_attached = 0;
static jmethodID methodIdDisplay = 0;
static JNIEnv *env;
if (!b_attached)
{
if ((*myVm)->AttachCurrentThread(myVm, &env, NULL) != 0)
{
LOGE("Couldn't attach the display thread to the JVM !\n");
return;
}
jclass cls = (*env)->GetObjectClass(env, myJavaLibVLC);
jmethodID methodIdSetVoutSize =
(*env)->GetMethodID(env, cls, "setVoutSize", "(II)V");
if(methodIdSetVoutSize == 0)
{
LOGE("Method setVoutParams not found !\n");
return;
}
// Transmit to Java the vout size.
(*env)->CallVoidMethod(env, myJavaLibVLC, methodIdSetVoutSize,
p_sys->i_frameWidth, p_sys->i_frameHeight);
methodIdDisplay = (*env)->GetMethodID(env, cls, "displayCallback", "([B)V");
if (methodIdDisplay == 0)
{
LOGE("Method displayCallback not found !\n");
return;
}
b_attached = 1;
}
// Fill the image buffer for debug purpose.
//memset(p_sys->p_imageData, 255, p_sys->i_texSize / 2);
jbyteArray jb = (*env)->NewByteArray(env, p_sys->i_frameSize);
(*env)->SetByteArrayRegion(env, jb, 0, p_sys->i_frameSize,
(jbyte *)p_sys->p_frameData);
(*env)->CallVoidMethod(env, myJavaLibVLC, methodIdDisplay, jb);
(*env)->DeleteLocalRef(env, jb);
}
#ifndef LIBVLCJNI_VOUT_H
#define LIBVLCJNI_VOUT_H
typedef struct vout_sys_t
{
unsigned i_frameWidth;
unsigned i_frameHeight;
unsigned i_frameSize;
char *p_frameData;
char b_attached;
}vout_sys_t;
unsigned getAlignedSize(unsigned size);
unsigned vout_format(void **opaque, char *chroma,
unsigned *width, unsigned *height,
unsigned *pitches,
unsigned *lines);
void vout_cleanup(void *opaque);
void *vout_lock(void *opaque, void **pixels);
void vout_unlock(void *opaque, void *picture, void *const *p_pixels);
void vout_display(void *opaque, void *picture);
#endif // LIBVLCJNI_VOUT_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment