接著上一篇历等,MediaPlayerService已經(jīng)被注冊(cè)到ServiceManager中了尺碰,本篇將接著分析MediaPlayerService服務(wù)的獲取,以及通過MediaPlayerService服務(wù)創(chuàng)建播放器2個(gè)流程洒宝。
從<Binder(一)>一篇知道颠黎,MediaPlayer.java調(diào)用setDataSource方法,最終會(huì)調(diào)用MediaPlayer.cpp的setDataSource函數(shù)总处。
status_t MediaPlayer::setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url, const KeyedVector<String8, String8> *headers)
{
ALOGV("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
//1狈惫,獲取IMediaPlayerService服務(wù)
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
//2,讓遠(yuǎn)程服務(wù)創(chuàng)建播放器
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
//通過IMediaPlayer操作播放器
(NO_ERROR != player->setDataSource(httpService, url, headers))) {
player.clear();
}
err = attachNewPlayer(player);
}
}
return err;
}
我們先看getMediaPlayerService()函數(shù)的執(zhí)行過程鹦马。
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
//獲取IServiceManager
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
do {
//使用String16("media.player")獲取服務(wù)
binder = sm->getService(String16("media.player"));
if (binder != 0) {
break;
}
//如果服務(wù)還未注冊(cè)胧谈,等待
usleep(500000); // 0.5 s
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
//將IBinder保存到BpMediaPlayerService的成員變量mRemote中
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
return sMediaPlayerService;
}
defaultServiceManager()返回BpServiceManager。
class BpServiceManager : public BpInterface<IServiceManager>
{
public:
BpServiceManager(const sp<IBinder>& impl)
: BpInterface<IServiceManager>(impl)
{
}
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
//最多查詢5次
for (n = 0; n < 5; n++){
sp<IBinder> svc = checkService(name);
if (svc != NULL) return svc;
ALOGI("Waiting for service %s...\n", String8(name).string());
sleep(1);
}
return NULL;
}
//發(fā)送查找指令
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
//發(fā)送CHECK_SERVICE_TRANSACTION指令
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
//讀取響應(yīng)數(shù)據(jù)
return reply.readStrongBinder();
}
transact會(huì)通過BpBinder(0)發(fā)送數(shù)據(jù)給ServiceManager查找名字為"media.player"的Service荸频,在上一篇分析過菱肖,ServiceManager會(huì)通過svcmgr_handler函數(shù)來處理請(qǐng)求。
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
......
switch(txn->code) {
//獲取某個(gè)Service旭从,通過msg來取
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
//s為對(duì)應(yīng)Service名字
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
//查找Service稳强,返回handle值
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
//不為0則找到
if (!handle)
break;
//寫入reply回傳給客戶端
bio_put_ref(reply, handle);
return 0;
do_find_service根據(jù)"media.player"進(jìn)行查找场仲,并返回它的句柄handle。
uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
struct svcinfo *si;
//檢查權(quán)限
if (!svc_can_find(s, len, spid)) {
ALOGE("find_service('%s') uid=%d - PERMISSION DENIED\n",
str8(s, len), uid);
return 0;
}
//查找服務(wù)
si = find_svc(s, len);
//si不為null退疫,handle大于0
if (si && si->handle) {
if (!si->allow_isolated) {
uid_t appid = uid % AID_USER;
if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
return 0;
}
}
//成功返回handle
return si->handle;
} else {
return 0;
}
}
繼續(xù)看查找的關(guān)鍵函數(shù)find_svc渠缕。
struct svcinfo *find_svc(const uint16_t *s16, size_t len)
{
struct svcinfo *si;
//遍歷
for (si = svclist; si; si = si->next) {
if ((len == si->len) &&
!memcmp(s16, si->name, len * sizeof(uint16_t))) {
return si;
}
}
return NULL;
}
Service整個(gè)查找過程薄疚,就是根據(jù)Service名去遍歷svcinfo鏈表趋距,找到svcinfo結(jié)構(gòu)體后,將svcinfo的handle值寫入緩存迅矛,回傳給客戶端棒坏。
我們回頭看reply.readStrongBinder()這個(gè)方法如何解析響應(yīng)數(shù)據(jù)燕差,和返回需要的服務(wù)對(duì)象。reply是一個(gè)Parcel類坝冕。
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, sp<IBinder>* out)
{
//讀取數(shù)據(jù)
const flat_binder_object* flat = in.readObject(false);
//此時(shí)為BINDER_TYPE_HANDLE類型
if (flat) {
switch (flat->type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
//傳入handle
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//構(gòu)建一個(gè)entry
handle_entry* e = lookupHandleLocked(handle);
if (e != NULL) {
IBinder* b = e->binder;
if (b == NULL || !e->refs->attemptIncWeak(this)) {
//此時(shí)handle不為0
if (handle == 0) {
Parcel data;
//ping下驅(qū)動(dòng)是否通
status_t status = IPCThreadState::self()->transact(
0, IBinder::PING_TRANSACTION, data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
//根據(jù)handle創(chuàng)建了一個(gè)BpBinder
b = new BpBinder(handle);
e->binder = b;
if (b) e->refs = b->getWeakRefs();
//將創(chuàng)建的BpBinder返回
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
這里的流程和獲取IServiceManger是相同的徒探,只是此時(shí)的handle大于0,它通過ProcessState創(chuàng)建了一個(gè)BpBinder(handle)喂窟。
回到IMediaDeathNotifier::getMediaPlayerService函數(shù)测暗,BpBinder(handle)同樣通過interface_cast進(jìn)行了強(qiáng)轉(zhuǎn),強(qiáng)轉(zhuǎn)流程可以看前面IServiceManger的獲取流程谎替。
也就是說偷溺,最終客戶端得到一個(gè)BpMediaPlayerService蹋辅,它的成員變量mRemote持有一個(gè)BpBinder(handle)钱贯,有了這個(gè)handle句柄,就能通過Binder驅(qū)動(dòng)和MediaPlayerService進(jìn)行通訊了侦另。
流程1到此分析完成秩命,即當(dāng)前已獲取到了IMediaPlayerService。繼續(xù)分析流程2褒傅,IMediaPlayerService調(diào)用了create函數(shù)弃锐,創(chuàng)建播放器。
virtual sp<IMediaPlayer> create(
const sp<IMediaPlayerClient>& client, int audioSessionId) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
data.writeStrongBinder(client->asBinder());
data.writeInt32(audioSessionId);
//獲取mRemote殿托,發(fā)送創(chuàng)建指令CREATE霹菊,
remote()->transact(CREATE, data, &reply);
//返回播放器引用
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
通過remote()獲取mRemote,即BpBinder(0)發(fā)送CREATE創(chuàng)建指令支竹。上一篇分析過旋廷,MediaPlayerService在MediaServer中創(chuàng)建,并開啟了兩個(gè)線程循環(huán)執(zhí)行talkWithDriver函數(shù)礼搁,循環(huán)讀寫消息饶碘,假設(shè)其中一個(gè)線程收到CREATE這個(gè)指令,最終將執(zhí)行executeCommand函數(shù)馒吴,
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch (cmd) {
......
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
if (result != NO_ERROR) break;
......
Parcel reply;
status_t error;
//轉(zhuǎn)為BBinder對(duì)象扎运,實(shí)際就是BnMediaPlayerService
if (tr.target.ptr) {
sp<BBinder> b((BBinder*)tr.cookie);
error = b->transact(tr.code, buffer, &reply, tr.flags);
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
BpXXX對(duì)應(yīng)著服務(wù)端在客戶端的業(yè)務(wù)代理瑟曲,而Bn則對(duì)應(yīng)服務(wù)端本地的業(yè)務(wù)處理類,因此每個(gè)服務(wù)端都包含一個(gè)BnXXX內(nèi)部類豪治,它繼承模板類BnInterface和BBinder對(duì)象洞拨。
class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
};
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
而transact函數(shù)定義在BBinder中,直接看transact函數(shù)负拟。
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
//處理消息數(shù)據(jù)
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
onTransact用于處理消息數(shù)據(jù)扣甲,它是一個(gè)虛函數(shù),由繼承關(guān)系知道齿椅,它實(shí)現(xiàn)在BnMediaPlayerService中琉挖。
status_t BnMediaPlayerService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code) {
......
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp<IMediaPlayerClient> client =
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
int audioSessionId = data.readInt32();
//創(chuàng)建播放器
sp<IMediaPlayer> player = create(client, audioSessionId);
//將播放器轉(zhuǎn)為Binder類型的數(shù)據(jù),寫入響應(yīng)緩沖區(qū)
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
......
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
如上涣脚,BnMediaPlayerService將會(huì)創(chuàng)建一個(gè)播放器示辈,返回給MediaPlayer.cpp客戶端,這個(gè)MediaPlayer.cpp的遠(yuǎn)程服務(wù)端是一個(gè)MediaPlayerService的內(nèi)部類遣蚀,為Client矾麻,它繼承自IMediaPlayer。
sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
int audioSessionId)
{
pid_t pid = IPCThreadState::self()->getCallingPid();
int32_t connId = android_atomic_inc(&mNextConnId);
//創(chuàng)建Client對(duì)象芭梯,它是BnMediaPlayer的子類
sp<Client> c = new Client(
this, pid, connId, client, audioSessionId,
IPCThreadState::self()->getCallingUid());
wp<Client> w = c;
{
Mutex::Autolock lock(mLock);
mClients.add(w);
}
return c;
}
Client是MediaPlayerService的內(nèi)部類险耀,它繼承自BnMediaPlayer,也就是IMediaPlayer的服務(wù)端玖喘,函數(shù)返回后甩牺,也就是客戶端得到Client的遠(yuǎn)程對(duì)象代理,那么緊接著會(huì)執(zhí)行Client的setDataSource函數(shù)累奈。
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
struct stat sb;
int ret = fstat(fd, &sb);
if (ret != 0) {
return UNKNOWN_ERROR;
}
if (offset >= sb.st_size) {
ALOGE("offset error");
::close(fd);
return UNKNOWN_ERROR;
}
if (offset + length > sb.st_size) {
length = sb.st_size - offset;
ALOGV("calculated length = %lld", length);
}
//獲取到當(dāng)前適合播放該視頻源的播放器類型
player_type playerType = MediaPlayerFactory::getPlayerType(this,
fd,
offset,
length);
// 根據(jù)得到的播放器類型去創(chuàng)建對(duì)應(yīng)的播放器實(shí)例:
sp<MediaPlayerBase> p = setDataSource_pre(playerType);
if (p == NULL) {
return NO_INIT;
}
setDataSource_post(p, p->setDataSource(fd, offset, length));
return mStatus;
}
這里分兩步執(zhí)行贬派,先獲取到適合播放該視頻源的播放器類型,再根據(jù)這個(gè)類型去創(chuàng)建播放器澎媒。MediaPlayerFactory保存的工廠類搞乏,在MediaPlayerService構(gòu)造時(shí)就注冊(cè)好了。
MediaPlayerService::MediaPlayerService()
{
ALOGV("MediaPlayerService created");
mNextConnId = 1;
mBatteryAudio.refCount = 0;
for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
mBatteryAudio.deviceOn[i] = 0;
mBatteryAudio.lastTime[i] = 0;
mBatteryAudio.totalTime[i] = 0;
}
mBatteryAudio.deviceOn[SPEAKER] = 1;
const sp<IServiceManager> sm(defaultServiceManager());
if (sm != NULL) {
const String16 name("batterystats");
sp<IBatteryStats> batteryStats =
interface_cast<IBatteryStats>(sm->getService(name));
if (batteryStats != NULL) {
batteryStats->noteResetVideo();
batteryStats->noteResetAudio();
}
}
//注冊(cè)播放器工廠類
MediaPlayerFactory::registerBuiltinFactories();
}
構(gòu)造函數(shù)最后一行注冊(cè)了所有類型播放器工廠戒努。
void MediaPlayerFactory::registerBuiltinFactories() {
Mutex::Autolock lock_(&sLock);
if (sInitComplete)
return;
registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);
registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER);
registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
sInitComplete = true;
}
我們回頭看根據(jù)類型獲取播放器的函數(shù)setDataSource_pre请敦。
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
player_type playerType)
{
//根據(jù)類型創(chuàng)建播放器
sp<MediaPlayerBase> p = createPlayer(playerType);
if (p == NULL) {
return p;
}
if (!p->hardwareOutput()) {
mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
mPid, mAudioAttributes);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
return p;
}
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
sp<MediaPlayerBase> p = mPlayer;
if ((p != NULL) && (p->playerType() != playerType)) {
ALOGV("delete player");
p.clear();
}
//通過工廠類創(chuàng)建播放器
if (p == NULL) {
p = MediaPlayerFactory::createPlayer(playerType, this, notify);
}
if (p != NULL) {
p->setUID(mUID);
}
return p;
}
關(guān)鍵代碼所示,MediaPlayerFactory工廠類獲取播放器储玫。
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
player_type playerType,
void* cookie,
notify_callback_f notifyFunc) {
sp<MediaPlayerBase> p;
IFactory* factory;
status_t init_result;
Mutex::Autolock lock_(&sLock);
if (sFactoryMap.indexOfKey(playerType) < 0) {
ALOGE("Failed to create player object of type %d, no registered"
" factory", playerType);
return p;
}
//從sFactoryMap獲取對(duì)應(yīng)的工廠類
factory = sFactoryMap.valueFor(playerType);
CHECK(NULL != factory);
//通過IFactory內(nèi)部類的不同實(shí)現(xiàn)類侍筛,創(chuàng)建不同的MediaPlayer
p = factory->createPlayer();
if (p == NULL) {
ALOGE("Failed to create player object of type %d, create failed",
playerType);
return p;
}
init_result = p->initCheck();
if (init_result == NO_ERROR) {
p->setNotifyCallback(cookie, notifyFunc);
} else {
p.clear();
}
return p;
}
在注冊(cè)工廠類時(shí)已經(jīng)將各類型工廠加入到成員sFactoryMap中,此時(shí)根據(jù)類型獲取到特定的工廠缘缚,并通過createPlayer創(chuàng)建播放器勾笆,安卓有2種類型的播放器,以NuPlayerFactory為例來看下創(chuàng)建的函數(shù)桥滨。
class NuPlayerFactory : public MediaPlayerFactory::IFactory {
public:
virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
const char* url,
float curScore) {
static const float kOurScore = 0.8;
if (kOurScore <= curScore)
return 0.0;
if (!strncasecmp("http://", url, 7)
|| !strncasecmp("https://", url, 8)
|| !strncasecmp("file://", url, 7)) {
size_t len = strlen(url);
if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
return kOurScore;
}
if (strstr(url,"m3u8")) {
return kOurScore;
}
if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
return kOurScore;
}
}
if (!strncasecmp("rtsp://", url, 7)) {
return kOurScore;
}
return 0.0;
}
virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
const sp<IStreamSource>& /*source*/,
float /*curScore*/) {
return 1.0;
}
//創(chuàng)建播放器
virtual sp<MediaPlayerBase> createPlayer() {
ALOGV(" create NuPlayer");
return new NuPlayerDriver;
}
};
到此播放器便創(chuàng)建完成窝爪,