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
- <p>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);</p><p> //创建一个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);</p><p> //分析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派生类的对象
- }</p>
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)