6. MediaPlayer如何与MediaPlayerService交互
6.1 MeidaPlayerService根据MediaPlayer的请求,创建对应的MeidaPlayer
//MediaPlayerService.cpp static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, notify_callback_f notifyFunc) { sp<MediaPlayerBase> p; switch (playerType) { case XX_PLAYER: LOGV("Create XXPlayer"); p = new XXPlayerService(); break; #ifndef NO_OPENCORE case PV_PLAYER: LOGV(" create PVPlayer"); p = new PVPlayer(); break; #endif case SONIVOX_PLAYER: LOGV(" create MidiFile"); p = new MidiFile(); break; case VORBIS_PLAYER: LOGV(" create VorbisPlayer"); p = new VorbisPlayer(); break; #if BUILD_WITH_FULL_STAGEFRIGHT case STAGEFRIGHT_PLAYER: LOGV(" create StagefrightPlayer"); p = new StagefrightPlayer; break; #endif case TEST_PLAYER: LOGV("Create Test Player stub"); p = new TestPlayerStub(); break; } if (p != NULL) { if (p->initCheck() == NO_ERROR) { p->setNotifyCallback(cookie, notifyFunc); } else { p.clear(); } } if (p == NULL) { LOGE("Failed to create player object"); } return p; }
class MediaPlayer : public BnMediaPlayerClient, public virtual IMediaDeathNotifier ============================================================= class IMediaPlayerClient: public IInterface { public: DECLARE_META_INTERFACE(MediaPlayerClient); virtual void notify(int msg, int ext1, int ext2) = 0; }; class BnMediaPlayerClient: public BnInterface<IMediaPlayerClient> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; ============================================================= class IMediaDeathNotifier: virtual public RefBase { public: IMediaDeathNotifier() { addObitRecipient(this); } virtual ~IMediaDeathNotifier() { removeObitRecipient(this); } virtual void died() = 0; //establish binder interface to MediaPlayerService static const sp<IMediaPlayerService>& getMediaPlayerService(); private: IMediaDeathNotifier &operator=(const IMediaDeathNotifier &); IMediaDeathNotifier(const IMediaDeathNotifier &); static void addObitRecipient(const wp<IMediaDeathNotifier>& recipient); static void removeObitRecipient(const wp<IMediaDeathNotifier>& recipient); class DeathNotifier: public IBinder::DeathRecipient { public: DeathNotifier() {} virtual ~DeathNotifier(); virtual void binderDied(const wp<IBinder>& who); }; friend class DeathNotifier; static Mutex sServiceLock; static sp<IMediaPlayerService> sMediaPlayerService; static sp<DeathNotifier> sDeathNotifier; static SortedVector< wp<IMediaDeathNotifier> > sObitRecipients; }
6.2 通过ServiceManager获取BpMediaPlayerService
const sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService() { LOGV("getMediaPlayerService"); Mutex::Autolock _l(sServiceLock); if (sMediaPlayerService.get() == 0) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; do { binder = sm->getService(String16("media.player")); if (binder != 0) { break; } LOGW("Media player service not published, waiting..."); usleep(500000); // 0.5 s } while(true); if (sDeathNotifier == NULL) { sDeathNotifier = new DeathNotifier(); } binder->linkToDeath(sDeathNotifier); // sMediaPlayerService中保存的为BpMediaPlayerService sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); } LOGE_IF(sMediaPlayerService == 0, "no media player service!?"); return sMediaPlayerService; }
6.3 获取mPlayer(IMediaPlayer,实质为BpMediaPlayer)
status_t MediaPlayer::setDataSource( const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource(%s)", url); status_t err = BAD_VALUE; if (url != NULL) { //service实质上是BpMediaPlayerService const sp<IMediaPlayerService>& service(getMediaPlayerService()); if (service != 0) { // Player实质上是BpMediaPlayer sp<IMediaPlayer> player(service->create(getpid(), this, url, headers)); //把BpMediaPlayer赋值给成员变量mPlayer,如果以前的mPlayer有效,则Disconnect以前的Player err = setDataSource(player); } } return err; }
BpMediaPlayerService::create (Client端)
class BpMediaPlayerService: public BpInterface<IMediaPlayerService> { public: BpMediaPlayerService(const sp<IBinder>& impl) : BpInterface<IMediaPlayerService>(impl) { } virtual sp<IMediaPlayer> create( pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers) { Parcel data, reply; data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor()); data.writeInt32(pid); data.writeStrongBinder(client->asBinder()); data.writeCString(url); if (headers == NULL) { data.writeInt32(0); } else { // serialize the headers data.writeInt32(headers->size()); for (size_t i = 0; i < headers->size(); ++i) { data.writeString8(headers->keyAt(i)); data.writeString8(headers->valueAt(i)); } } remote()->transact(CREATE_URL, data, &reply); //传递到BnMediaPlayerSerivce执行 return interface_cast<IMediaPlayer>(reply.readStrongBinder()); //返回BpMediaPlayer } }
在BnMediaPlayerService处理CREATE_URL(Server端)
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case CREATE_URL: { //收到上面的CREATE_URL并进行处理 CHECK_INTERFACE(IMediaPlayerService, data, reply); pid_t pid = data.readInt32(); sp<IMediaPlayerClient> client = //实质保存的为BpMediaPlayerClient,用于向MediaPlayer发通知消息,它为Client,MediaPlayer为Sever interface_cast<IMediaPlayerClient>(data.readStrongBinder()); 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); } //在BnMediaPlayerService的派生类MediaPlayerService中实现,创建一个Client对象(Client:public BnMediaPlayer) sp<IMediaPlayer> player = create( pid, client, url, numHeaders > 0 ? &headers : NULL); reply->writeStrongBinder(player->asBinder()); return NO_ERROR; } break; }
MediaPlayerService::create才是真正的实现创建IMediaPlayer
sp<IMediaPlayer> MediaPlayerService::create( pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers) { int32_t connId = android_atomic_inc(&mNextConnId);
//创建一个Clinet,class Client : public BnMediaPlayer,真正实现start, stop, pause, resume... sp<Client> c = new Client(this, pid, connId, client); LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
//分析url,并创建真正的player(demuxer,decoder) if (NO_ERROR != c->setDataSource(url, headers)) { c.clear(); return c; } wp<Client> w = c; Mutex::Autolock lock(mLock); mClients.add(w); return c;//返回此BnMediaPlayer派生类的对象 }
MediaPlayerService::Client::setDataSource分析URL类型,然后创建对应的Player
status_t MediaPlayerService::Client::setDataSource( const char *url, const KeyedVector<String8, String8> *headers) { LOGV("setDataSource(%s)", url); if (url == NULL) return UNKNOWN_ERROR; if (strncmp(url, "content://", 10) == 0) { // get a filedescriptor for the content Uri and // pass it to the setDataSource(fd) method String16 url16(url); int fd = android::openContentProviderFile(url16); if (fd < 0) { LOGE("Couldn't open fd for %s", url); return UNKNOWN_ERROR; } setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus close(fd); return mStatus; } else { //根据url返回对应的player_type,如: PV_PLAYER,STAGEFRIGHT_PLAYER, XX_PLAYER player_type playerType = getPlayerType(url); LOGV("player type = %d", playerType); // create the right type of player,建立真正的AVPlayer sp<MediaPlayerBase> p = createPlayer(playerType); if (p == NULL) return NO_INIT; if (!p->hardwareOutput()) { mAudioOutput = new AudioOutput(); static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); } // now set data source,把URL传递给真正的AVPlayer LOGV(" setDataSource"); mStatus = p->setDataSource(url, headers); p->setOutRange( mService->getLeft(), mService->getTop(), mService->getWidth(), mService->getHeight()); if (mStatus == NO_ERROR) { mPlayer = p; } else { LOGE(" error: %d", mStatus); } return mStatus; } }
创建真正的AVPlayer
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) { // determine if we have the right player type sp<MediaPlayerBase> p = mPlayer; LOGV("Enter MediaPlayerService::Client::createPlayer: playerType is %d", playerType); if ((p != NULL) && (p->playerType() != playerType)) { LOGV("p->playerType() is: %d, , delete player", p->playerType()); p.clear(); } if (p == NULL) { LOGV("Create new player"); p = android::createPlayer(playerType, this, notify); } return p; } static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie, notify_callback_f notifyFunc) { sp<MediaPlayerBase> p; switch (playerType) { case XX_PLAYER: LOGV("Create XXPlayer"); p = new XXPlayerService(); break; #ifndef NO_OPENCORE case PV_PLAYER: LOGV(" create PVPlayer"); p = new PVPlayer(); break; #endif case SONIVOX_PLAYER: LOGV(" create MidiFile"); p = new MidiFile(); break; case VORBIS_PLAYER: LOGV(" create VorbisPlayer"); p = new VorbisPlayer(); break; #if BUILD_WITH_FULL_STAGEFRIGHT case STAGEFRIGHT_PLAYER: LOGV(" create StagefrightPlayer"); p = new StagefrightPlayer; break; #endif case TEST_PLAYER: LOGV("Create Test Player stub"); p = new TestPlayerStub(); break; } if (p != NULL) { if (p->initCheck() == NO_ERROR) { p->setNotifyCallback(cookie, notifyFunc); } else { p.clear(); } } if (p == NULL) { LOGE("Failed to create player object"); } return p; }
6.4 开始播放MediaPlayer::start
MediaPlayer::mPlayer实质为BpMediaPlayer
MediaPlayerService::Client::mPlayer实质为真正的AVPlayer,如:PVPlayer, XXPlayer
class PVPlayer: public MediaPlayerInterface
class MediaPlayerInterface : public MediaPlayerBase
MediaPlayer::start() --> mPlayer->start(BpMediaPlayer::start) --> remote()->transact(START, data, &reply)--> BpBinder::transact--> IPCThreadState::self()->transact--> ioctl(写) --> ioctl(读,在IPCThreadState::joinThreadPool中调用) --> BBinder::transact --> BnMediaPlayer::onTransact
--> MediaPlayerService::Client::start -->MediaPlayerService::Client::mPlayer->start(PVPlayer->start)