1. MediaPlayer::prepare()
Frameworks/base/media/java/android/media/MediaPlayer.java
public native void prepare() throws IOException,IllegalStateException;
2. android_media_MediaPlayer_prepare ()
Frameworks/base/media/jni/Android_media_MediaPlayer.cpp
static void
static void
android_media_MediaPlayer_prepare(JNIEnv *env, jobject thiz)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env,"java/lang/IllegalStateException", NULL);
return;
}
// Handle the case where the displaysurface was set before the mp was
// initialized. We try again to make itstick.
sp<IGraphicBufferProducer> st = getVideoSurfaceTexture(env, thiz);
mp->setVideoSurfaceTexture(st);
process_media_player_call( env, thiz, mp->prepare(),"java/io/IOException", "Prepare failed." );
}
3. MediaPlayer:: prepare ()
Frameworks/av/media/libmedia/MediaPlayer.cpp
status_tMediaPlayer::prepare()
{
ALOGV("prepare");
Mutex::Autolock _l(mLock);
mLockThreadId = getThreadId();
if (mPrepareSync) {
mLockThreadId = 0;
return -EALREADY;
}
mPrepareSync = true;
status_t ret = prepareAsync_l();
if (ret != NO_ERROR) {
mLockThreadId = 0;
return ret;
}
if (mPrepareSync) {
mSignal.wait(mLock); // wait for prepare done
mPrepareSync = false;
}
ALOGV("prepare complete -status=%d", mPrepareStatus);
mLockThreadId = 0;
return mPrepareStatus;
}
status_tMediaPlayer::prepareAsync_l()
{
if ( (mPlayer != 0) && (mCurrentState & ( MEDIA_PLAYER_INITIALIZED | MEDIA_PLAYER_STOPPED) ) ) {
mPlayer->setAudioStreamType(mStreamType);
mCurrentState = MEDIA_PLAYER_PREPARING;
// mPlayer是一个BpMediaPlayer(BpBinder)对象
returnmPlayer->prepareAsync();
}
ALOGE("prepareAsync called in state%d", mCurrentState);
return INVALID_OPERATION;
}
4. BpMediaPlayer:: prepareAsync()
Frameworks/av/media/libmedia/IMediaPlayer.cpp
class BpMediaPlayer: public BpInterface<IMediaPlayer>
{
status_t prepareAsync()
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
// remote() 得到的是BpMediaPlayer(BpBinder)中的BpBinder
remote()->transact(PREPARE_ASYNC, data, &reply);
return reply.readInt32();
}
}
5. BnMediaPlayer:: onTransact()
Frameworks/av/media/libmedia/IMediaPlayer.cpp
通过Binder机制调用BnMediaPlayer的onTransact()
status_tBnMediaPlayer::onTransact(
uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags)
{
switch (code) {
case DISCONNECT: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
disconnect();
return NO_ERROR;
} break;
case SET_DATA_SOURCE_URL: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
const char* url =data.readCString();
KeyedVector<String8, String8>headers;
int32_t numHeaders =data.readInt32();
for (int i = 0; i < numHeaders;++i) {
String8 key =data.readString8();
String8 value =data.readString8();
headers.add(key, value);
}
reply->writeInt32(setDataSource(url, numHeaders > 0 ? &headers: NULL));
return NO_ERROR;
} break;
case SET_DATA_SOURCE_FD: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
int fd = data.readFileDescriptor();
int64_t offset = data.readInt64();
int64_t length = data.readInt64();
reply->writeInt32(setDataSource(fd, offset, length));
return NO_ERROR;
}
case SET_DATA_SOURCE_STREAM: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<IStreamSource> source =
interface_cast<IStreamSource>(data.readStrongBinder());
reply->writeInt32(setDataSource(source));
return NO_ERROR;
}
case SET_VIDEO_SURFACETEXTURE: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
sp<IGraphicBufferProducer>bufferProducer =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
reply->writeInt32(setVideoSurfaceTexture(bufferProducer));
return NO_ERROR;
} break;
casePREPARE_ASYNC: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
reply->writeInt32(prepareAsync());
returnNO_ERROR;
} break;
case START: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
reply->writeInt32(start());
return NO_ERROR;
} break;
case STOP: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
reply->writeInt32(stop());
return NO_ERROR;
} break;
case IS_PLAYING: {
CHECK_INTERFACE(IMediaPlayer, data,reply);
bool state;
status_t ret =isPlaying(&state);
reply->writeInt32(state);
reply->writeInt32(ret);
return NO_ERROR;
} break;
.........................................................
default:
return BBinder::onTransact(code,data, reply, flags);
}
}
6. MediaPlayerService::Client::prepareAsync()
Frameworks/av/media/libmediaplayerservice/MediaPlayerService.h
Frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
classMediaPlayerService : public BnMediaPlayerService
{
class Client;
classClient : public BnMediaPlayer {
// IMediaPlayer interface
virtual void disconnect();
virtual status_t setVideoSurfaceTexture(
constsp<IGraphicBufferProducer>& bufferProducer);
virtual status_t prepareAsync();
virtual status_t start();
virtual status_t stop();
virtual status_t pause();
virtual status_t isPlaying(bool* state);
virtual status_t seekTo(int msec);
virtual status_t getCurrentPosition(int* msec);
virtual status_t setDataSource(constsp<IStreamSource> &source);
…………………………………………
}
status_tMediaPlayerService::Client::prepareAsync()
{
ALOGV("[%d] prepareAsync", mConnId);
// 这个p 是一个StageFrightPlayer对象
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
// 调用StageFrightPlayer对象的prepareAsync()
status_t ret =p->prepareAsync();
#ifCALLBACK_ANTAGONIZER
ALOGD("start Antagonizer");
if (ret == NO_ERROR)mAntagonizer->start();
#endif
return ret;
}
7. StageFrightPlayer::prepareAsync()
Frameworks/av/media/libmediaplayerservice/StageFrightPlayer.cpp
status_tStagefrightPlayer::prepareAsync() {
//StageFrightPlayer对象的mPlayer成员变量是一个AwesomePlayer对象
// 因此调用AwesomePlayer的prepareAsync方法
return mPlayer->prepareAsync();
}
8. AwesomePlayer::prepareAsync()
Frameworks/av/media/libstagefright/AwesomePlayer.cpp
status_tAwesomePlayer::prepareAsync() {
ATRACE_CALL();
Mutex::Autolock autoLock(mLock);
if (mFlags & PREPARING) {
return UNKNOWN_ERROR; // async prepare already pending
}
mIsAsyncPrepare = true;
return prepareAsync_l();
}
status_tAwesomePlayer::prepareAsync_l() {
if (mFlags & PREPARING) {
return UNKNOWN_ERROR; // async prepare already pending
}
if (!mQueueStarted) {
mQueue.start();
mQueueStarted = true;
}
modifyFlags(PREPARING, SET);
mAsyncPrepareEvent= new AwesomeEvent(
this,&AwesomePlayer::onPrepareAsyncEvent);
mQueue.postEvent(mAsyncPrepareEvent);
return OK;
}
voidAwesomePlayer::onPrepareAsyncEvent() {
Mutex::Autolock autoLock(mLock);
if (mFlags & PREPARE_CANCELLED) {
ALOGI("prepare was cancelledbefore doing anything");
abortPrepare(UNKNOWN_ERROR);
return;
}
if (mUri.size() > 0) {
status_t err =finishSetDataSource_l();
if (err != OK) {
abortPrepare(err);
return;
}
}
if (mVideoTrack != NULL &&mVideoSource == NULL) {
status_t err =initVideoDecoder();
if (err != OK) {
abortPrepare(err);
return;
}
}
if (mAudioTrack != NULL &&mAudioSource == NULL) {
status_t err =initAudioDecoder();
if (err != OK) {
abortPrepare(err);
return;
}
}
modifyFlags(PREPARING_CONNECTED, SET);
if (isStreamingHTTP()) {
postBufferingEvent_l();
} else {
finishAsyncPrepare_l();
}
}