frameworks/base/media/java/android/media/MediaPlayer.java
frameworks/base/media/jni/android_media_MediaPlayer.cpp
frameworks/av/media/libmedia/Mediaplayer.cpp
frameworks/av/include/media/Mediaplayer.h
frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
frameworks/av/media/libmediaplayerservice/libmediaplayerservice/MediaPlayerService.h
frameworks/av/media/libmediaplayerservice/libmediaplayerservice/MediaPlayerFactory.cpp
MediaPlayerFactory.cpp以 下就是具体的播放器的实现了。
媒体播放的抽象层:
frameworks/av/include/media/MediaPlayerInterface.h以上文件是播放器的abstract base class,类似于硬件抽象层(HAL),是每个具体的播放器都需要根据这个基类来实现对应的MediaPlayerInterface。
一个是命令+命令的响应(cmd+respond)
一个是事件(unsolicited)
void MediaPlayerService::instantiate() { defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); }
// establish binder interface to MediaPlayerService /*static*/const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService() { ALOGV("getMediaPlayerService"); Mutex::Autolock _l(sServiceLock); if (sMediaPlayerService == 0) { sp<IServiceManager> sm = defaultServiceManager();//实名服务的管理者 sp<IBinder> binder; do { binder = sm->getService(String16("media.player"));//提供实名服务对应的名字,返回的是binder实例在客服端进程中的引用句柄号。 if (binder != 0) { break; } ALOGW("Media player service not published, waiting..."); usleep(500000); // 0.5 s } while (true); if (sDeathNotifier == NULL) { sDeathNotifier = new DeathNotifier(); } binder->linkToDeath(sDeathNotifier); sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);//将Bpbinder cast to BpMediaPlayerService } ALOGE_IF(sMediaPlayerService == 0, "no media player service!?"); return sMediaPlayerService; }而匿名binder是怎么获取的呢?
virtual sp<IMediaPlayer> create(//frameworks/av/media/libmedia/IMediaPlayerService.cpp const sp<IMediaPlayerClient>& client, int audioSessionId) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); data.writeStrongBinder(client->asBinder());//将IMediaPlayerClient binder实体传递到binder驱动中 data.writeInt32(audioSessionId); remote()->transact(CREATE, data, &reply); return interface_cast<IMediaPlayer>(reply.readStrongBinder());//获取ImediaPlayer binder实体在当前进程中的引用句柄,并将它封装在BpMediaPlayer实例中。 }
status_t BnMediaPlayerService::onTransact(//frameworks/av/media/libmedia/IMediaPlayerService.cpp uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case CREATE: { CHECK_INTERFACE(IMediaPlayerService, data, reply); sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());//获取BpMediaPlayerClient int audioSessionId = data.readInt32(); sp<IMediaPlayer> player = create(client, audioSessionId);//创建BnMediaPlayer实体 reply->writeStrongBinder(player->asBinder());//将BnMediaPlayer binder实体写到驱动中。 return NO_ERROR; } break; case DECODE_URL: {
MediaPlayer::setDataSource //MediaPlayer.cpp |-->const sp<IMediaPlayerService>& service(getMediaPlayerService());//获取BpMeidaPlayerService |-->sp<IMediaPlayer> player(service->create(this, mAudioSessionId));//返回BpMediaPlayer |-->player->setDataSource(url, headers)//调用BpMediaPlayer.setDataSource(ImediaPlayer.cpp) 以上调用会通过binder调用到binder实体对应的函数: MediaPlayerService::Client::setDataSource |-->MediaPlayerFactory::getPlayerType()//获取播放器的类型 |-->setDataSource_pre(playerType)//根据playerType创建具体的播放器实例,例如ffplayer(见ffplayer.cpp) |-->p->setDataSource//调用具体播放器的setDataSource函数
MediaPlayerService::Client::notify //MediaPlayerService.cpp |-->sp<IMediaPlayerClient> c; |-->c = client->mClient;//获取BpMediaPlayerClient,即binder的客服端 |-->c->notify();以上调用会通过binder调用到BnMediaPlayer,即binder实体端:
MediaPlayerService::Client::createPlayer |--->MediaPlayerFactory::createPlayer(playerType, this, notify) |--->p->setNotifyCallback //MediaPlayerInterface.h |->mNotify = notifyFunc |->sendEvent //上面初始化的mNotify函数,被sendEvent函数调用 |->mNotify(mCookie, msg, ext1, ext2, obj);
android_media_MediaPlayer_native_setup//android_media_MediaPlayer.cpp |-->sp<MediaPlayer> mp = new MediaPlayer(); |-->sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this); |-->mp->setListener(listener);//即为<span style="font-size:18px;">MediaPlayer::setListener函数</span> 以上过程,将<span style="font-size:18px;">侦听者设置为JNIMediaPlayerListener,所以当事件产生时,会调用 </span> void JNIMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj) |-->env->CallStaticVoidMethod(mClass, fields.post_event...);//从jni调到MediaPlayer.java |--->postEventFromNative //MediaPlayer.java |-->Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj); |-->mp.mEventHandler.sendMessage(m); //MediaPlayer.mEventHandler = new EventHandler(this, looper);