MediaPlayer Analyze - Framework JNI
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static const JNINativeMethod gMethods[] = {
{"_setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setDataSource", "(Landroid/media/MediaDataSource;)V",(void *)android_media_MediaPlayer_setDataSourceCallback },
{"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer_setVideoSurface},
{"_prepare", "()V", (void *)android_media_MediaPlayer_prepare},
{"prepareAsync", "()V", (void *)android_media_MediaPlayer_prepareAsync},
{"_start", "()V", (void *)android_media_MediaPlayer_start},
{"_stop", "()V", (void *)android_media_MediaPlayer_stop},
......
}
一 初始化
1.1 java层接口
native_setup(new WeakReference<MediaPlayer>(this));
1.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
ALOGV("native_setup");
sp<MediaPlayer> mp = new MediaPlayer(); // new C++ MediaPlayer()
if (mp == NULL) {
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
}
// create new listener and give it to MediaPlayer
sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
mp->setListener(listener);
// Stow our new C++ MediaPlayer in an opaque field in the Java object.
// 保存C++对象到Java对象中
setMediaPlayer(env, thiz, mp);
}
二 设置source
2.1 java层接口
// 网络流调用
nativeSetDataSource( // 非本地流调用
MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
path,
keys,
values);
// 本地流调用
_setDataSource(fd, offset, length);
2.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_setDataSourceAndHeaders(
JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path, jobjectArray keys, jobjectArray values) {
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
sp<IMediaHTTPService> httpService;
if (httpServiceBinderObj != NULL) {
sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
httpService = interface_cast<IMediaHTTPService>(binder);
}
// 调用native层接口
status_t opStatus =
mp->setDataSource(
httpService,
pathStr,
headersVector.size() > 0? &headersVector : NULL);
// 回调
process_media_player_call(
env, thiz, opStatus, "java/io/IOException",
"setDataSource failed." );
}
三 准备
3.1 java层接口
_prepare();
3.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
mp->setVideoSurfaceTexture(st);
process_media_player_call( env, thiz, mp->prepare(), "java/io/IOException", "Prepare failed." );
}
四 开始/恢复播放
4.1 java层接口
_start();
4.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
{
ALOGV("start");
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
process_media_player_call( env, thiz, mp->start(), NULL, NULL );
}
五 暂停播放
5.1 java层接口
_pause();
5.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_pause(JNIEnv *env, jobject thiz)
{
ALOGV("pause");
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
}
六 停止播放
6.1 java层接口
_stop();
6.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_stop(JNIEnv *env, jobject thiz)
{
ALOGV("stop");
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
process_media_player_call( env, thiz, mp->stop(), NULL, NULL );
}
七 重置
7.1 java层接口
_reset();
7.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_reset(JNIEnv *env, jobject thiz)
{
ALOGV("reset");
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
}
八 释放
8.1 java层接口
_release();
8.2 jni层接口
frameworks\base\media\jni\android_media_MediaPlayer.cpp
static void
android_media_MediaPlayer_release(JNIEnv *env, jobject thiz)
{
ALOGV("release");
decVideoSurfaceRef(env, thiz);
sp<MediaPlayer> mp = setMediaPlayer(env, thiz, 0);
if (mp != NULL) {
// this prevents native callbacks after the object is released
mp->setListener(0);
mp->disconnect();
}
}