mediaplayerservice 作爲android 提供多媒體服務的service, 其服務主要涉及playback, Recorder , metadataRetriever; 下面就來對mediaplayerservice一探究竟
- mediaplayerservice 接口分析
constructor 完成一件非常重要的事情,MediaPlayerFactory::registerBuiltinFactories();完成 MediaPlayerFactory的register, 之後才能使用 MediaPlayerFactory進行getPlayerType.
2, void MediaPlayerService::instantiate()
defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService()); 通過ServiceManager add service, 之後就可以通過getService拿到BpMediaPlayerService.
3, sp<IMediaRecorder> createMediaRecorder(pid_t pid)
在其中進行sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid); MediaRecorderClient will new StagefrightRecorder;
4, sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid)
在其中進行sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid); MetadataRetrieverClient 將進行具體的setDataSource, 進行getPlayerType, 進而extractMetadata.
5, sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId);
在其中進行sp<Client> c = new Client(this, pid, connId, client, audioSessionId,IPCThreadState::self()->getCallingUid()); playback 就以來於此client, 此client 負責管理具體的player.
6, sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat);
此接口藉助player, decoder 解一段data, 看一下流程, MediaPlayerFactory::getPlayerType ---> MediaPlayerFactory::createPlayer--->player.get())->setAudioSink ---->
player->setDataSource----> player->prepareAsync() ----> player->start()-----> mem = new MemoryBase(cache->getHeap(), 0, cache->size())
儼然一個player的簡易工作流程已經出來.
7, sp<IOMX> getOMX();
mOMX = new OMX; 非常重要,之後player進行OMXCodec::Create 將會用到它,用於管理OMXComponent.
- class Client : public BnMediaPlayer 在mediaplayerservice中處於非常重要的位置,media playback 就靠它了,下面來分析一下它的interface.
1, MediaPlayerService::Client::setDataSource
此接口有三種不同的模式,分別是URL, FD, STREAM, 具體使用哪個要看對於mediaplayer中c++ API的使用,或者說看APK如何使用了,不過在mediaplay.jave中對URL進行了一些處理,will try to open url, 如果成功,那麼將使用FD.
首先會有player_type playerType = MediaPlayerFactory::getPlayerType的調用,在此就不得不說 MediaPlayerFactory , 之前有提到在 MediaPlayerService的constructor中會register MediaPlayerFactory , 在其中就會add 所以的player, 對於任何新加的player, 也將在此進行add, 如此在後續的處理中,纔會命中相應的player;
getPlayerType實際將由一個宏定義GET_PLAYER_TYPE_IMPL來完成對於player的select, GET_PLAYER_TYPE_IMPL 將會遍歷所有的register player, 按照約定的規則,使用scoreFactory進行打分,得分最高的player,也就是目標player, OK, get Player over.
然後將call sp<MediaPlayerBase> p = setDataSource_pre(playerType), 在setDataSource_pre中完成createPlayer(playerType), 同時對於非hardwareOutput的audio , new AudioOutput(mAudioSessionId), 實爲AudioTrack, 經AudinFlinger, HAL 輸出audio.
最後setDataSource_post(p, p->setDataSource(...)); 首先會有一個p->setDataSource(...) 的調用,此處交給選定的player進行具體的setDataSource的操作, 之後記錄mStatus, 然後是set the re-transmission endpoint if one was chosen.
至此, setDataSource 完成.
2, MediaPlayerService::Client::prepareAsync
MediaPlayerService::Client::start()
MediaPlayerService::Client::pause() 等
均是call 選擇的player進行具體的工作.
3, MediaPlayerService::Client::setVideoSurfaceTexture
對於video, 需要 setVideoSurfaceTexture, 同樣call player p->setVideoSurfaceTexture(surfaceTexture) .
- mediaplayerservice內部有幾個嵌套類,作一下分析
1, class AudioOutput : public MediaPlayerBase::AudioSink
包含成員變量AudioTrack* mTrack;
2,class AudioCache : public MediaPlayerBase::AudioSink
在MediaPlayerService::decode 時候會用到new AudioCache,抓decoder之後的data.
3, class Client : public BnMediaPlayer
用於media playback, 前面已經分析.
簡略分析了一下mediaplayerservice一些主要的接口, 欲給player增加一些新的功能,加深對mediaplayerservice 的理解就顯得至關重要. 待進一步挖掘分析.