tinymix-MediaPlayer流程分析

1、framework(frameworks/base/media/java/android/media/MediaPlayer.java)java

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

2、JNI(frameworks/base/media/jni/android_media_MediaPlayer.cpp)android

{"_start",    "()V",    (void *)android_media_MediaPlayer_start},
android_media_MediaPlayer_start(JNIEnv *env, jobject thiz)
{
    ALOGV("start");
    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
    if (mp == NULL ) {
        jniThrowException(env, "java/lang/IllegalStateException", NULL);
        return;
    }
    process_media_player_call( env, thiz, mp->start(), NULL, NULL );
}
static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStatus, 
    const char* exception, const char *message)
{
    if (exception == NULL) {  // Don't throw exception. Instead, send an event.
        if (opStatus != (status_t) OK) {
            sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
            if (mp != 0) mp->notify(MEDIA_ERROR, opStatus, 0); 
        }   
    } else {  // Throw exception!
        if ( opStatus == (status_t) INVALID_OPERATION ) { 
            jniThrowException(env, "java/lang/IllegalStateException", NULL);
        } else if ( opStatus == (status_t) PERMISSION_DENIED ) { 
            jniThrowException(env, "java/lang/SecurityException", NULL);
        } else if ( opStatus != (status_t) OK ) { 
            if (strlen(message) > 230) {
               // if the message is too long, don't bother displaying the status code
               jniThrowException( env, exception, message);
            } else {
               char msg[256];
                // append the status code to the message
               sprintf(msg, "%s: status=0x%X", message, opStatus);
               jniThrowException( env, exception, msg);
            }   
        }   
    }   
}
View Code

3、HAL(frameworks/av/media/libmedia/mediaplayer.cpp)app

兩種Audio Hardware HAL接口定義:ide

1/ legacy:hardware/libhardware_legacy/include/hardware_legacy/AudioHardwareInterface.hoop

2/ 非legacy:hardware/libhardware/include/hardware/audio.h (tinyalsa應該是這種)spa

 

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;
}

//frameworks/av/media/libmedia/IMediaPlayer.cppcode

    status_t start()
    {   
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
        remote()->transact(START, data, &reply);
        return reply.readInt32();
    }   
View Code
相關文章
相關標籤/搜索