您的位置:首页 > 其它

深入了解mediaserver-3

2011-12-07 19:36 253 查看
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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: