Java端发起调用,MediaPlayer会转至MediaPlayerService,在mediaserver进程中创建一个client,然后通过client调用相应的解码工具解码后创建AudioTrack,所有待输出的AudioTrack在AudioFlinger::AudioMixer里合成,然后通过AudioHAL(AudioHardwareInterface的实际实现者)传至实际的硬件来实现播放
1.Java调用
MediaPlayer mp =
new
MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();
2.MediaPlayer调用通过binder方式在MediaPlayerService进程中创建Client;
MediaPlayer:: prepare MediaPlayer:: start 通过binder调用Client的具体实现。
status_t MediaPlayer::setDataSource(
const char *url, const KeyedVector<String8, String8> *headers)
{
LOGI("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
const sp< IMediaPlayerService >& service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(
service->create(getpid(), this, url, headers));
err = setDataSource(player);
}
}
return err;
}
const char *url, const KeyedVector<String8, String8> *headers)
{
LOGI("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
const sp< IMediaPlayerService >& service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(
service->create(getpid(), this, url, headers));
err = setDataSource(player);
}
}
return err;
}
3.MediaPlayerService实现
/*实例化Client*/
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);
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);
if (NO_ERROR != c->setDataSource(url, headers))
{
c.clear();
return c;
}
wp<Client> w = c;
Mutex::Autolock lock(mLock);
mClients.add(w);//SortedVector< wp<Client> > mClients;
return c;
}
pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
const KeyedVector<String8, String8> *headers)
{
int32_t connId = android_atomic_inc(&mNextConnId);
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);
if (NO_ERROR != c->setDataSource(url, headers))
{
c.clear();
return c;
}
wp<Client> w = c;
Mutex::Autolock lock(mLock);
mClients.add(w);//SortedVector< wp<Client> > mClients;
return c;
}
void MediaPlayerService::removeClient(wp<Client> client)
{
Mutex::Autolock lock(mLock);
mClients.remove(client);
}
{
Mutex::Autolock lock(mLock);
mClients.remove(client);
}
MediaPlayerService::Client::~Client()
{
LOGV("Client(%d) destructor pid = %d", mConnId, mPid);
mAudioOutput.clear();
wp<Client> client(this);
disconnect();
mService->removeClient(client);
}
{
LOGV("Client(%d) destructor pid = %d", mConnId, mPid);
mAudioOutput.clear();
wp<Client> client(this);
disconnect();
mService->removeClient(client);
}
MediaPlayerService::Client::setDataSource(...) {
....
sp<MediaPlayerBase> p = createPlayer(playerType);// call android::createPlayer(playerType, this, notify); set notify to MediaPlayer
....
}
MediaPlayerService::Client::prepareAsync;
MediaPlayerService::Client::start;
4. Awesomeplayer
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
if (mListener != NULL) {
sp<MediaPlayerBase> listener = mListener.promote();
if (listener != NULL) {
listener->sendEvent(msg, ext1, ext2);
}
}
}
virtual void sendEvent(int msg, int ext1=0, int ext2=0) { if (mNotify)mNotify(mCookie, msg, ext1, ext2); }
mNotify----> void MediaPlayer::notify(int msg, int ext1, int ext2)
http://forest606.blog.163.com/blog/static/134450089201002835641104/