NuPlayerDriver的创建也是在setDataSource()中发生的,那么我们继续前文分析,这次我们换个本地播放的setDataSource()方法来看看,稍微简单点:
//frameworks/av/media/libmedia/mediaplayer.cpp
status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
status_t err = UNKNOWN_ERROR;
const sp<IMediaPlayerService> service(getMediaPlayerService());
if (service != 0) {
sp<IMediaPlayer> player(service->create(this, mAudioSessionId, mAttributionSource));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
(NO_ERROR != player->setDataSource(fd, offset, length))) {
player.clear();
}
err = attachNewPlayer(player);
}
return err;
}
create()前文已经看过了,接着看今天的正题:
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",
fd, nameForFd(fd).c_str(), (long long) offset, (long long) length);
struct stat sb;
int ret = fstat(fd, &sb);
//省略
if (offset >= sb.st_size) {
ALOGE("offset error");
return UNKNOWN_ERROR;
}
if (offset + length > sb.st_size) {
length = sb.st_size - offset;
ALOGV("calculated length = %lld", (long long)length);
}
player_type playerType = MediaPlayerFactory::getPlayerType(this,
fd,
offset,
length);
sp<MediaPlayerBase> p = setDataSource_pre(playerType);
if (p == NULL) {
return NO_INIT;
}
// now set data source
return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length));
}
先通过getPlayerType()方法来确定player的类型(其实在当前版本中,只有一种player:NU_PLAYER类型),我们来看看getPlayerType()的原理是啥:
//frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
int fd,
int64_t offset,
int64_t length) {
GET_PLAYER_TYPE_IMPL(client, fd, offset, length);
}
#define GET_PLAYER_TYPE_IMPL(a...) \
Mutex::Autolock lock_(&sLock); \
\
player_type ret = STAGEFRIGHT_PLAYER; \
float bestScore = 0.0; \
\
for (size_t i = 0; i < sFactoryMap.size(); ++i) { \
\
IFactory* v = sFactoryMap.valueAt(i); \
float thisScore; \
CHECK(v != NULL); \
thisScore = v->scoreFactory(a, bestScore); \
if (thisScore > bestScore) { \
ret = sFactoryMap.keyAt(i); \
bestScore = thisScore; \
} \
} \
\
if (0.0 == bestScore) { \
ret = getDefaultPlayerType(); \
} \
\
return ret;
这段代码定义了一个宏 GET_PLAYER_TYPE_IMPL,用于确定最佳播放器类型。这个宏的作用是在多个工厂对象中选择得分最高的播放器类型。设计这个宏的人估计喜欢打球。
在讲MediaPlayerService章节的时候,其实有一个player没讲,即:TEST_PLAYER。sFactoryMap里面存储了两个Factory类型:NuPlayerFactory和TestPlayerFactory,看名字就知道后者是测试用的。而这两个Factory都没有实现本地播放类型的scoreFactory()方法,所以它的返回值就是父类的初始实现的值:0.0。所以最终返回的还是getDefaultPlayerType()类型:NU_PLAYER。话说回来,当前Android12版本只保留了NU_PLAYER类型,根本不需要这一通分析,哈哈。
那么,继续看setDataSource_pre()方法在操办什么大事情:
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
player_type playerType)
{
ALOGV("player type = %d", playerType);
// create the right type of player
sp<MediaPlayerBase> p = createPlayer(playerType);
if (p == NULL) {
return p;
}
//监听三个服务的死亡情况:media.extractor服务、OMX服务、Codec2服务
//省略
mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p);
if (!p->hardwareOutput()) {
mAudioOutput = new AudioOutput(mAudioSessionId, mAttributionSource,
mAudioAttributes, mAudioDeviceUpdatedListener);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
return p;
}
这段代码里应题的内容都在createPlayer()内,死亡通知我直接省略了,AudioOutput不是本次的主题也不看了。我们来看看createPlayer()的实现吧:
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
// determine if we have the right player type
sp<MediaPlayerBase> p = getPlayer();
if ((p != NULL) && (p->playerType() != playerType)) {
ALOGV("delete player");
p.clear();
}
if (p == NULL) {
p = MediaPlayerFactory::createPlayer(playerType, mListener,
VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mAttributionSource.pid)));
}
if (p != NULL) {
p->setUID(VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mAttributionSource.uid)));
}
return p;
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
player_type playerType,
const sp<MediaPlayerBase::Listener> &listener,
pid_t pid) {
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;
}
factory = sFactoryMap.valueFor(playerType);
CHECK(NULL != factory);
p = factory->createPlayer(pid);
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(listener);
} else {
ALOGE("Failed to create player object of type %d, initCheck failed"
" (res = %d)", playerType, init_result);
p.clear();
}
return p;
}
第一次进createPlayer()必然会调用MediaPlayerFactory::createPlayer(),根据player_type从sFactoryMap中取出Factory,这里就进入了NuPlayerFactory的createPlayer()方法:
//frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
ALOGV(" create NuPlayer");
return new NuPlayerDriver(pid);
}
今天的主角来了,此处直接new了一个NuPlayerDriver:
//frameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
NuPlayerDriver::NuPlayerDriver(pid_t pid)
: mState(STATE_IDLE),
mIsAsyncPrepare(false),
mAsyncResult(UNKNOWN_ERROR),
mSetSurfaceInProgress(false),
mDurationUs(-1),
mPositionUs(-1),
mSeekInProgress(false),
mPlayingTimeUs(0),
mRebufferingTimeUs(0),
mRebufferingEvents(0),
mRebufferingAtExit(false),
mLooper(new ALooper),
mMediaClock(new MediaClock),
mPlayer(new NuPlayer(pid, mMediaClock)),
mPlayerFlags(0),
mMetricsItem(NULL),
mClientUid(-1),
mAtEOS(false),
mLooping(false),
mAutoLoop(false) {
ALOGD("NuPlayerDriver(%p) created, clientPid(%d)", this, pid);
mLooper->setName("NuPlayerDriver Looper");
mMediaClock->init();
// set up an analytics record
mMetricsItem = mediametrics::Item::create(kKeyPlayer);
mLooper->start(
false, /* runOnCallingThread */
true, /* canCallJava */
PRIORITY_AUDIO);
mLooper->registerHandler(mPlayer);
mPlayer->init(this);
}
看其构造函数还是一目了然的,分别创建了ALooper、MediaClock和Nuplayer并做一些初始化操作。这里就不挨个分析了,我直接把new NuPlayerDriver()生成的内容以图的方法展现出来:
本来想把所有的模块画在一起,但是因为连线的原因不好处理,连接的乱七八糟,怎么调整都不好看,所以干脆就分割成了几个小块,也就是图中的3个小方框。需要注意的是:颜色相同的模块是同一个实例,大家自行在脑海里去把他们连接成一个整体。
值得一提的是:NuPlayerDriver中已经把NuPlayer的消息通知机制(ALooper/AHandler/AMessage,AMessage是随用随创建的)给建立起来了。这个消息通知机制我将在下一章节来分析。
回过头来,创建完NuPlayerDriver以后,调用setNotifyCallback()将Client构造时(参见:Android12 MultiMedia框架之MediaPlayerService::Client)创建的Listener保存到它的父类MediaPlayerBase的mListener成员中。
至此,setDataSource_pre()分析结束。接下来进入setDataSource_post()了,它的第二个参数传入的是NuPlayerDriver的setDataSource()的执行结果,这个函数就是在创建source了,我们后面的章节再看,这里跳过。setDataSource_post()其实就是将创建的NuPlayerDriver保存到mPlayer。
最后,来整体看下执行完MediaPlayer的setDataSource()后,生成的大概的框图是什么样子的: