调用MediaPlayer的setDataSource方法后,经过一系列处理,最终后调用MediaPlayerService的setDataSource方法,MediaPlayerService的setDataSource有多个重载方法,具体如下:
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers)
{
ALOGV("setDataSource(%s)", url);
if (url == NULL)
return UNKNOWN_ERROR;
if ((strncmp(url, "http://", 7) == 0) ||
(strncmp(url, "https://", 8) == 0) ||
(strncmp(url, "rtsp://", 7) == 0)) {
if (!checkPermission("android.permission.INTERNET")) {
return PERMISSION_DENIED;
}
}
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)
{
ALOGE("Couldn't open fd for %s", url);
return UNKNOWN_ERROR;
}
status_t status = setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus 调用setDataSource重载方法
close(fd);
return mStatus = status;
} else {
player_type playerType = MediaPlayerFactory::getPlayerType(this, url); //调用MediaPlayerFactory的getPlayerType,获取playerType
sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
if (p == NULL) {
return NO_INIT;
}
return mStatus =
setDataSource_post(
p, p->setDataSource(httpService, url, headers)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
}
//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 (ret != 0) {
ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
return UNKNOWN_ERROR;
}
ALOGV("st_dev = %llu", static_cast<unsigned long long>(sb.st_dev));
ALOGV("st_mode = %u", sb.st_mode);
ALOGV("st_uid = %lu", static_cast<unsigned long>(sb.st_uid));
ALOGV("st_gid = %lu", static_cast<unsigned long>(sb.st_gid));
ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));
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); //调用MediaPlayerFactory的getPlayerType,获取playerType
sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
if (p == NULL) {
return NO_INIT;
}
// now set data source
return mStatus = setDataSource_post(p, p->setDataSource(fd, offset, length)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
const sp<IStreamSource> &source) {
// create the right type of player
player_type playerType = MediaPlayerFactory::getPlayerType(this, source); //调用MediaPlayerFactory的getPlayerType,获取playerType
sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
if (p == NULL) {
return NO_INIT;
}
// now set data source
return mStatus = setDataSource_post(p, p->setDataSource(source)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
const sp<IDataSource> &source) {
sp<DataSource> dataSource = CreateDataSourceFromIDataSource(source);
player_type playerType = MediaPlayerFactory::getPlayerType(this, dataSource); //调用MediaPlayerFactory的getPlayerType,获取playerType
sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
if (p == NULL) {
return NO_INIT;
}
// now set data source
return mStatus = setDataSource_post(p, p->setDataSource(dataSource)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
//frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
const String8& rtpParams) {
player_type playerType = NU_PLAYER;
sp<MediaPlayerBase> p = setDataSource_pre(playerType); //调用setDataSource_pre方法
if (p == NULL) {
return NO_INIT;
}
// now set data source
return mStatus = setDataSource_post(p, p->setDataSource(rtpParams)); //调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法
}
上面方法主要处理如下:
调用MediaPlayerFactory的getPlayerType,获取playerType。
调用setDataSource_pre方法。
调用MediaPlayerBase的setDataSource方法,然后将结果作为参数调用setDataSource_post方法。
下面我们分别进行分析:
MediaPlayerFactory::getPlayerType
MediaPlayerFactory的getPlayerType有许多重载方法:
//frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
const char* url) {
GET_PLAYER_TYPE_IMPL(client, url);
}
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
int fd,
int64_t offset,
int64_t length) {
GET_PLAYER_TYPE_IMPL(client, fd, offset, length);
}
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
const sp<IStreamSource> &source) {
GET_PLAYER_TYPE_IMPL(client, source);
}
player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
const sp<DataSource> &source) {
GET_PLAYER_TYPE_IMPL(client, source);
}
GET_PLAYER_TYPE_IMPL是一个宏,定义如下:
#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;
MediaPlayerService::Client::setDataSource_pre
我们继续分析MediaPlayerService的setDataSource_pre方法:
std::vector<DeathNotifier> mDeathNotifiers;
//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); //调用createPlayer方法
if (p == NULL) {
return p;
}
std::vector<DeathNotifier> deathNotifiers;
// Listen to death of media.extractor service
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.extractor"));
if (binder == NULL) {
ALOGE("extractor service not available");
return NULL;
}
deathNotifiers.emplace_back(
binder, [l = wp<MediaPlayerBase>(p)]() {
sp<MediaPlayerBase> listener = l.promote();
if (listener) {
ALOGI("media.extractor died. Sending death notification.");
listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
MEDIAEXTRACTOR_PROCESS_DEATH);
} else {
ALOGW("media.extractor died without a death handler.");
}
});
{
using ::android::hidl::base::V1_0::IBase;
// Listen to death of OMX service
{
sp<IBase> base = ::android::hardware::media::omx::V1_0::
IOmx::getService(); //获取IOmx
if (base == nullptr) {
ALOGD("OMX service is not available");
} else {
deathNotifiers.emplace_back(
base, [l = wp<MediaPlayerBase>(p)]() {
sp<MediaPlayerBase> listener = l.promote();
if (listener) {
ALOGI("OMX service died. "
"Sending death notification.");
listener->sendEvent(
MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
MEDIACODEC_PROCESS_DEATH);
} else {
ALOGW("OMX service died without a death handler.");
}
});
}
}
// Listen to death of Codec2 services
{
for (std::shared_ptr<Codec2Client> const& client :
Codec2Client::CreateFromAllServices()) {
sp<IBase> base = client->getBase();
deathNotifiers.emplace_back(
base, [l = wp<MediaPlayerBase>(p),
name = std::string(client->getServiceName())]() {
sp<MediaPlayerBase> listener = l.promote();
if (listener) {
ALOGI("Codec2 service \"%s\" died. "
"Sending death notification.",
name.c_str());
listener->sendEvent(
MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
MEDIACODEC_PROCESS_DEATH);
} else {
ALOGW("Codec2 service \"%s\" died "
"without a death handler.",
name.c_str());
}
});
}
}
}
Mutex::Autolock lock(mLock);
mDeathNotifiers.clear();
mDeathNotifiers.swap(deathNotifiers);
mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p); //创建AudioDeviceUpdatedNotifier对象
if (!p->hardwareOutput()) {
mAudioOutput = new AudioOutput(mAudioSessionId, mAttributionSource,
mAudioAttributes, mAudioDeviceUpdatedListener); //创建AudioOutput对象
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput); //调用MediaPlayerInterface的setAudioSink方法
}
return p;
}
NuPlayerDriver::setDataSource
MediaPlayerBase是一个抽象类,MediaPlayerBase和MediaPlayerHWInterface接口继承于MediaPlayerBase,而NuPlayerDriver又继承于MediaPlayerInterface:
class MediaPlayerInterface : public MediaPlayerBase {}
class MediaPlayerHWInterface : public MediaPlayerBase {}
struct NuPlayerDriver : public MediaPlayerInterface {}
因此调用MediaPlayerBase的setDataSource方法,就会调用到NuPlayerDriver的setDataSource方法,NuPlayerDriver的setDataSource有多个重载方法,具体如下:
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers) {
ALOGV("setDataSource(%p) url(%s)", this, uriDebugString(url, false).c_str());
Mutex::Autolock autoLock(mLock);
if (mState != STATE_IDLE) {
return INVALID_OPERATION;
}
mState = STATE_SET_DATASOURCE_PENDING;
mPlayer->setDataSourceAsync(httpService, url, headers);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
ALOGV("setDataSource(%p) file(%d)", this, fd);
Mutex::Autolock autoLock(mLock);
if (mState != STATE_IDLE) {
return INVALID_OPERATION;
}
mState = STATE_SET_DATASOURCE_PENDING;
mPlayer->setDataSourceAsync(fd, offset, length);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
ALOGV("setDataSource(%p) stream source", this);
Mutex::Autolock autoLock(mLock);
if (mState != STATE_IDLE) {
return INVALID_OPERATION;
}
mState = STATE_SET_DATASOURCE_PENDING;
mPlayer->setDataSourceAsync(source);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const sp<DataSource> &source) {
ALOGV("setDataSource(%p) callback source", this);
Mutex::Autolock autoLock(mLock);
if (mState != STATE_IDLE) {
return INVALID_OPERATION;
}
mState = STATE_SET_DATASOURCE_PENDING;
mPlayer->setDataSourceAsync(source);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
const sp<NuPlayer> mPlayer;
//rameworks/av/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
status_t NuPlayerDriver::setDataSource(const String8& rtpParams) {
ALOGV("setDataSource(%p) rtp source", this);
Mutex::Autolock autoLock(mLock);
if (mState != STATE_IDLE) {
return INVALID_OPERATION;
}
mState = STATE_SET_DATASOURCE_PENDING;
mPlayer->setDataSourceAsync(rtpParams);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
调用NuPlayer的setDataSourceAsync方法,NuPlayer相关内容我们在NuPlayer中继续分析: