通过检查本机代码,Android的MediaPlayer如何工作?

时间:2013-10-21 09:46:13

标签: java android android-ndk java-native-interface android-mediaplayer

检查MediaPlayerlink)的源代码,start()方法如下所示:

public  void start() throws IllegalStateException {
        stayAwake(true);
        _start();
}

_start()方法如下所示:

private native void _start() throws IllegalStateException;

检查原生_start()方法(link)(名为start(),但由于原生呼叫被命名为_start(),是否应该将其称为_start()? ):

status_t MediaPlayer::start()
{
    ALOGV("start");
    Mutex::Autolock _l(mLock);
    if (mCurrentState & MEDIA_PLAYER_STARTED)
        return NO_ERROR;
    if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_PREPARED |
                    MEDIA_PLAYER_PLAYBACK_COMPLETE | MEDIA_PLAYER_PAUSED ) ) ) {
        mPlayer->setLooping(mLoop);
        mPlayer->setVolume(mLeftVolume, mRightVolume);
        mPlayer->setAuxEffectSendLevel(mSendLevel);
        mCurrentState = MEDIA_PLAYER_STARTED;
        status_t ret = mPlayer->start();
        if (ret != NO_ERROR) {
            mCurrentState = MEDIA_PLAYER_STATE_ERROR;
        } else {
            if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
                ALOGV("playback completed immediately following start()");
            }
        }
        return ret;
    }
    ALOGE("start called in state %d", mCurrentState);
    return INVALID_OPERATION;
}

数据在哪里读取?我想检查Android如何使用RTSP,但我无法找到它加载数据的位置。我想知道它是否使用了像FFMpeg或其他一些实现的库。

编辑:

为什么使用JNI需要此代码?

3 个答案:

答案 0 :(得分:3)

以下所有路径都引用src / frameworks / base /.

在media / jni / android_media_MediaPlayer.cpp中,您将找到将Java方法调用转发到底层本机框架的JNI代码。您可以在gMethods[]数组中看到名称映射,并在文件底部附近看到AndroidRuntime::registerNativeMethods调用。您可以阅读有关使用JNI here注册本机方法的更多信息,但这不是真正有趣的部分。

在这个阶段,我们是Java MediaPlayer的原生对应物。在大多数情况下,它也没有做任何有趣的事情。它绑定到MediaPlayerServiceIBinder个交易。 MediaPlayerService根据媒体类型创建实际原生播放器,并维护客户端(MediaPlayerService::Client)以促进与原生MediaPlayer的通信,其中包含把气泡转回Java。您可以在以下文件中看到所有这些(如果您有兴趣):

  

媒体/ libmedia / mediaplayer.cpp,   媒体/ libmedia / IMediaPlayer.cpp,   媒体/ libmedia / IMediaPlayerClient.cpp,   媒体/ libmedia / IMediaPlayerService.cpp,   媒体/ libmediaplayerservice / MediaPlayerService.cpp

libmedia的头文件位于include / media / libmedia /.

现在到了真正有趣的部分,它们是组件玩家。在MediaServicePlayer.cpp中,有几个getPlayerType方法决定要实例化的播放器。还有用于MIDI的Stagefright框架(AwesomePlayer和NuPlayer)和Sonivox播放器。对于RTSP,NuPlayer是您将获得的。你可以在media / libmediaplayerservice / nuplayer /中找到一个胶水层,以及media / libstagefright /和media / libstagefright / rtsp /中的所有真实源代码。

答案 1 :(得分:1)

你错过了一步。 Java代码中的private native void _start()引用MediaPlayer JNI层中的this entry(引用this function)。

对于RTSP实现,您可能会在the Stagefright sources中找到它。

答案 2 :(得分:0)

_start方法在此媒体播放器文件link

中的jni中定义

从这里开始调用libmedia start方法。