IjkMediaPlayer的mNativeMediaPlayer的设置
作者:互联网
public final class IjkMediaPlayer extends AbstractMediaPlayer {
@AccessedByNative
private long mNativeMediaPlayer;
}
@AccessedByNative
意思是通过native代码进行赋值
在IjkMediaPlayer有下面一段代码
public static void loadLibrariesOnce(IjkLibLoader libLoader) {
Class var1 = IjkMediaPlayer.class;
synchronized(IjkMediaPlayer.class) {
if (!mIsLibLoaded) {
if (libLoader == null) {
libLoader = sLocalLibLoader;
}
libLoader.loadLibrary("ijkffmpeg");
libLoader.loadLibrary("ijksdl");
libLoader.loadLibrary("ijkplayer");
mIsLibLoaded = true;
}
}
}
libLoader.loadLibrary("ijksdl");加载sdl库
这句话会执行ijksdl_android_jni.c的JNI_OnLoad 使用了动态注册技术。动态注册可以看我前面写的文章https://blog.csdn.net/qq_15255121/article/details/115243826
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
int retval;
JNIEnv* env = NULL;
g_jvm = vm;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
retval = J4A_LoadAll__catchAll(env);
JNI_CHECK_RET(retval == 0, env, NULL, NULL, -1);
return JNI_VERSION_1_4;
}
重点我们看J4A_LoadAll__catchAll
int J4A_LoadAll__catchAll(JNIEnv *env)
{
int ret = 0;
// load android.os.Build at very beginning
J4A_LOAD_CLASS(android_os_Build);
#include "j4a/j4a_allclasses.loader.h"
fail:
return ret;
}
这段代码有意思#include "j4a/j4a_allclasses.loader.h"
用.h定义了一顿代码
J4A_LOAD_CLASS(java_nio_Buffer);
J4A_LOAD_CLASS(java_nio_ByteBuffer);
J4A_LOAD_CLASS(java_util_ArrayList);
J4A_LOAD_CLASS(android_media_AudioTrack);
J4A_LOAD_CLASS(android_media_MediaCodec);
J4A_LOAD_CLASS(android_media_MediaFormat);
J4A_LOAD_CLASS(android_media_PlaybackParams);
J4A_LOAD_CLASS(android_os_Build);
J4A_LOAD_CLASS(android_os_Bundle);
J4A_LOAD_CLASS(tv_danmaku_ijk_media_player_misc_IMediaDataSource);
J4A_LOAD_CLASS(tv_danmaku_ijk_media_player_misc_IAndroidIO);
J4A_LOAD_CLASS(tv_danmaku_ijk_media_player_IjkMediaPlayer);
我们重点看
J4A_LOAD_CLASS(tv_danmaku_ijk_media_player_IjkMediaPlayer);
#define J4A_LOAD_CLASS(class__) \
do { \
ret = J4A_loadClass__J4AC_##class__(env); \
if (ret) \
goto fail; \
} while (0)
可以知道最后调用的是J4A_loadClass__J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer
我们看下定义
int J4A_loadClass__J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer(JNIEnv *env)
{
int ret = -1;
const char *J4A_UNUSED(name) = NULL;
const char *J4A_UNUSED(sign) = NULL;
jclass J4A_UNUSED(class_id) = NULL;
int J4A_UNUSED(api_level) = 0;
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id != NULL)
return 0;
sign = "tv/danmaku/ijk/media/player/IjkMediaPlayer";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id = J4A_FindClass__asGlobalRef__catchAll(env, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "mNativeMediaPlayer";
sign = "J";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer = J4A_GetFieldID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "mNativeMediaDataSource";
sign = "J";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaDataSource = J4A_GetFieldID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaDataSource == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "mNativeAndroidIO";
sign = "J";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeAndroidIO = J4A_GetFieldID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeAndroidIO == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "postEventFromNative";
sign = "(Ljava/lang/Object;IIILjava/lang/Object;)V";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_postEventFromNative = J4A_GetStaticMethodID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_postEventFromNative == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "onSelectCodec";
sign = "(Ljava/lang/Object;Ljava/lang/String;II)Ljava/lang/String;";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onSelectCodec = J4A_GetStaticMethodID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onSelectCodec == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "onNativeInvoke";
sign = "(Ljava/lang/Object;ILandroid/os/Bundle;)Z";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onNativeInvoke = J4A_GetStaticMethodID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.method_onNativeInvoke == NULL)
goto fail;
J4A_ALOGD("J4ALoader: OK: '%s' loaded\n", "tv.danmaku.ijk.media.player.IjkMediaPlayer");
ret = 0;
fail:
return ret;
}
typedef struct J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer {
jclass id;
jfieldID field_mNativeMediaPlayer;
jfieldID field_mNativeMediaDataSource;
jfieldID field_mNativeAndroidIO;
jmethodID method_postEventFromNative;
jmethodID method_onSelectCodec;
jmethodID method_onNativeInvoke;
} J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer;
static J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer;
我们通过上面的函数
sign = "tv/danmaku/ijk/media/player/IjkMediaPlayer";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id = J4A_FindClass__asGlobalRef__catchAll(env, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id == NULL)
goto fail;
class_id = class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.id;
name = "mNativeMediaPlayer";
sign = "J";
class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer = J4A_GetFieldID__catchAll(env, class_id, name, sign);
if (class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer == NULL)
goto fail;
就能知道获取到mNativeMediaPlayer相应的fileId
我们看下mNativeMediaPlayer的值的获取与设置
jlong J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__get(JNIEnv *env, jobject thiz)
{
return (*env)->GetLongField(env, thiz, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer);
}
jlong J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__get__catchAll(JNIEnv *env, jobject thiz)
{
jlong ret_value = J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__get(env, thiz);
if (J4A_ExceptionCheck__catchAll(env)) {
return 0;
}
return ret_value;
}
void J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__set(JNIEnv *env, jobject thiz, jlong value)
{
(*env)->SetLongField(env, thiz, class_J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer.field_mNativeMediaPlayer, value);
}
void J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__set__catchAll(JNIEnv *env, jobject thiz, jlong value)
{
J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__set(env, thiz, value);
J4A_ExceptionCheck__catchAll(env);
}
我们看下mNativeMediaPlayer的设置
IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
我们使用ijikplayer的时候要
IjkMediaPlayer.java
public IjkMediaPlayer() {
this(sLocalLibLoader);
}
public IjkMediaPlayer(IjkLibLoader libLoader) {
this.mWakeLock = null;
this.initPlayer(libLoader);
}
private void initPlayer(IjkLibLoader libLoader) {
loadLibrariesOnce(libLoader);
initNativeOnce();
Looper looper;
if ((looper = Looper.myLooper()) != null) {
this.mEventHandler = new IjkMediaPlayer.EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
this.mEventHandler = new IjkMediaPlayer.EventHandler(this, looper);
} else {
this.mEventHandler = null;
}
this.native_setup(new WeakReference(this));
}
ijkplayer_jni.c
{ "native_setup", "(Ljava/lang/Object;)V", (void *) IjkMediaPlayer_native_setup },
static void
IjkMediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
MPTRACE("%s\n", __func__);
IjkMediaPlayer *mp = ijkmp_android_create(message_loop);
JNI_CHECK_GOTO(mp, env, "java/lang/OutOfMemoryError", "mpjni: native_setup: ijkmp_create() failed", LABEL_RETURN);
jni_set_media_player(env, thiz, mp);
ijkmp_set_weak_thiz(mp, (*env)->NewGlobalRef(env, weak_this));
ijkmp_set_inject_opaque(mp, ijkmp_get_weak_thiz(mp));
ijkmp_set_ijkio_inject_opaque(mp, ijkmp_get_weak_thiz(mp));
ijkmp_android_set_mediacodec_select_callback(mp, mediacodec_select_callback, ijkmp_get_weak_thiz(mp));
LABEL_RETURN:
ijkmp_dec_ref_p(&mp);
}
static IjkMediaPlayer *jni_set_media_player(JNIEnv* env, jobject thiz, IjkMediaPlayer *mp)
{
pthread_mutex_lock(&g_clazz.mutex);
IjkMediaPlayer *old = (IjkMediaPlayer*) (intptr_t) J4AC_IjkMediaPlayer__mNativeMediaPlayer__get__catchAll(env, thiz);
if (mp) {
ijkmp_inc_ref(mp);
}
J4AC_IjkMediaPlayer__mNativeMediaPlayer__set__catchAll(env, thiz, (intptr_t) mp);
pthread_mutex_unlock(&g_clazz.mutex);
// NOTE: ijkmp_dec_ref may block thread
if (old != NULL ) {
ijkmp_dec_ref_p(&old);
}
return old;
}
#define J4AC_IjkMediaPlayer__mNativeMediaPlayer__set__catchAll J4AC_tv_danmaku_ijk_media_player_IjkMediaPlayer__mNativeMediaPlayer__set__catchAll
这样就设置了mNativeMediaPlayer
标签:__,IjkMediaPlayer,media,class,player,设置,ijk,mNativeMediaPlayer 来源: https://blog.csdn.net/qq_15255121/article/details/118858483