### 3?mediaplayer的核心庫libmedia.so
libs/media/mediaplayer.cpp文件用于實現mediaplayer.h提供的接口,其中一個重要的片段如下所示:
~~~
const sp<IMediaPlayerService>& MediaPlayer::getMediaPlayerService()
{
Mutex::Autolock _l(mServiceLock);
if (mMediaPlayerService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.player"));
if (binder != 0)
break;
LOGW("MediaPlayerService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
LOGE_IF(mMediaPlayerService==0, "no MediaPlayerService!?");
return mMediaPlayerService;
}
~~~
其中最重要的一點是binder?=?sm->getService(String16("media.player"));這個調用用來得到一個名稱為"media.player"的服務,這個調用返回值的類型為IBinder,根據實現將其轉換成類型IMediaPlayerService使用。
~~~
status_t MediaPlayer::setDataSource(const char *url)
{
LOGV("setDataSource(%s)", url);
status_t err = UNKNOWN_ERROR;
if (url != NULL) {
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(getpid(), this, url));
err = setDataSource(player);
}
}
return err;
}
~~~
在函數setDataSource函數中,調用getMediaPlayerService得到了一個IMediaPlayerService,又從IMediaPlayerService中得到了IMediaPlayer類型的指針,通過這個指針進行著具體的操作。
其他一些函數的實現也與setDataSource類似。
為了實現Binder的具體功能,在這些類中還需要實現一個BpXXX的類,例如IMediaPlayerClient.cpp的實現如下所示:l
~~~
class BpMediaPlayerClient: public BpInterface<IMediaPlayerClient>
{
public:
BpMediaPlayerClient(const sp<IBinder>& impl)
: BpInterface<IMediaPlayerClient>(impl){}
virtual void notify(int msg, int ext1, int ext2)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerClient::getInterfaceDescriptor());
data.writeInt32(msg);
data.writeInt32(ext1);
data.writeInt32(ext2);
remote()->transact(NOTIFY, data, &reply, IBinder::FLAG_ONEWAY);
}
};
~~~
以上的實現都是基于Binder框架的實現方式,只需要按照模版實現即可。其中BpXXX的類為代理類(proxy),BnXXX的類為本地類(native)。代理類的transact函數和本地類的onTransact函數實現對應的通訊。
### 4?media服務libmediaservice.so
多媒體服務的守護進程的代碼:frameworks/base/media/mediaserver/其中只有一個源文件main_mediaserver.cpp,將被編譯成為一個可執行程序mediaserver。它負責啟
動了多媒體服務、照相機服務,音頻服務這三個服務
~~~
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::instantiate();
CameraService::instantiate();
AudioPolicyService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
~~~
frameworks/base/media\libmediaplayerservice目錄中的MediaPlayerService.h和MediaPlayerService.cpp用于實現一個
servers/media/的服務,MediaPlayerService是繼承BnMediaPlayerService的實現,在這個類的內部又定義了類Client,MediaPlayerService::Client繼承了BnMediaPlayer。
~~~
class MediaPlayerService : public BnMediaPlayerService
{
class Client : public BnMediaPlayer
}
~~~
?? 在MediaPlayerService中具有如下一個靜態函數instantiate:
~~~
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
~~~
在instantiate函數中,調用IServiceManager的一個函數addService,向其中增加了一個名為"media.player"的服務。
這個名為"media.player"的服務和mediaplayer.cpp中調用getService中得到的使用一樣名稱。因此,在這里調用addService增加服務在mediaplayer.cpp中可以按照名稱"media.player"來使用。這就是使用Binder實現進程間通訊的(IPC)的作用,事實上這個MediaPlayerService類是在服務中運行的,而mediaplayer.cpp調用的功能在應用中運行,二者并不是一個進程。但是在mediaplayer.cpp卻像一個進程的調用一樣調用MediaPlayerService的功能。
?在MediaPlayerService.cpp中的createPlayer函數如下所示:
~~~
static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
notify_callback_f notifyFunc)
{
sp<MediaPlayerBase> p;
switch (playerType) {
#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;
}
~~~
在這里根據playerType的類型建立不同的播放器:對于大多數情況,類型將是PV_PLAYER,這時會調用了new?PVPlayer()建立一個PVPlayer,然后將其指針轉換成MediaPlayerBase來使用;對于Mini文件的情況,類型為SONIVOX_PLAYER,將會建立一個MidiFile;對于Ogg?Vorbis格式的情況,將會建立一個VorbisPlayer。
(OGG?Vobis是一種音頻壓縮格式,與[MP3](http://digital.it168.com/files/music.asp)等的音樂格式類似,它具有完全免費、開放和沒有專利限制的特點。)
值得注意的是PVPlayer、MidiFile和VorbisPlayer三個類都是繼承MediaPlayerInterface得到的,而MediaPlayerInterface又是繼承MediaPlayerBase得到的,因此三者具有相同接口類型。只有建立的時候會調用各自的構造函數,在建立之后,將只通過MediaPlayerBase接口來MediaPlayerBase控制它們。
???在frameworks/base/media/libmediaplayerservice目錄中,MidiFile.h和MidiFile.cpp的實現MidiFile,VorbisPlayer.h和VorbisPlayer.cpp實現一個VorbisPlayer。
- 前言
- Camera源碼分析(android2.2)
- Android開機啟動流程說明
- android應用程序管理機制
- MediaPlayer框架概述(一)
- MediaPlayer框架概述(二)
- Android MediaPlayer+Stagefright框架(音頻)圖解
- Stagefright框架解讀(—)音視頻Playback流程
- Android mediaRecorder框架簡述(一)
- Android mediaRecorder框架簡述(二)
- Android IntentService淺談以及源碼分析
- Android多線程(二)AsyncTask源碼分析
- Android View體系(五)從源碼解析View的事件分發機制
- Android View體系(六)從源碼解析Activity的構成