MediaPlayer Analyze - MediaPlayerService
Android-Nuplayer播放视频怎么获取对应的extractor
一 初始化
frameworks\av\media\libmedia\mediaplayer.cpp
// 通过MediaPlayerService调用create
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client, audio_session_t audioSessionId)
{
pid_t pid = IPCThreadState::self()->getCallingPid();
int32_t connId = android_atomic_inc(&mNextConnId);
sp<Client> c = new Client(
this, pid, connId, client, audioSessionId,
IPCThreadState::self()->getCallingUid());
ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid, IPCThreadState::self()->getCallingUid());
wp<Client> w = c;
{
Mutex::Autolock lock(mLock);
mClients.add(w);
}
return c;
}
MediaPlayerService::Client::Client(
const sp<MediaPlayerService>& service, pid_t pid,
int32_t connId, const sp<IMediaPlayerClient>& client,
audio_session_t audioSessionId, uid_t uid)
{
ALOGV("Client(%d) constructor", connId);
mPid = pid;
mConnId = connId;
mService = service;
mClient = client;
mLoop = false;
mStatus = NO_INIT;
mAudioSessionId = audioSessionId;
mUid = uid;
mRetransmitEndpointValid = false;
mAudioAttributes = NULL;
mListener = new Listener(this);
#if CALLBACK_ANTAGONIZER
ALOGD("create Antagonizer");
mAntagonizer = new Antagonizer(mListener);
#endif
}
二 设置Source setDataSource
frameworks\av\media\libmedia\mediaplayer.cpp
sp<IMediaPlayer> player(service->create(this, mAudioSessionId));
if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
(NO_ERROR != player->setDataSource(httpService, url, headers))) {
player.clear();
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource(
const sp<IMediaHTTPService> &httpService,
const char *url,
const KeyedVector<String8, String8> *headers)
{
// 本地流
if (strncmp(url, "content://", 10) == 0) {
......
} else { // 网路流
player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
// 创建NuPlayerDriver
sp<MediaPlayerBase> p = setDataSource_pre(playerType);
if (p == NULL) {
return NO_INIT;
}
return mStatus = setDataSource_post(p, p->setDataSource(httpService, url, headers));
}
}
2.1 setDataSource_pre(playerType)
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(player_type playerType)
{
// create the right type of player
// 根据后文可知,这里是NuPlayerDriver实例
sp<MediaPlayerBase> p = createPlayer(playerType);
// Listen to death of media.extractor service
......
{
using ::android::hidl::base::V1_0::IBase;
// Listen to death of OMX service
......
// Listen to death of Codec2 services
......
}
Mutex::Autolock lock(mLock);
......
if (!p->hardwareOutput()) {
mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
mPid, mAudioAttributes, mAudioDeviceUpdatedListener);
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
// NuPlayerDriver
return p;
}
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) {
// NuPlayerDriver
p = MediaPlayerFactory::createPlayer(playerType, mListener, mPid);
}
if (p != NULL) {
p->setUID(mUid);
}
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);
// NuPlayerDriver
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;
}
class NuPlayerFactory : public MediaPlayerFactory::IFactory {
public:
virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
ALOGV(" create NuPlayer");
return new NuPlayerDriver(pid);
}
};
2.2 setDataSource_post(p, p->setDataSource(httpService, url, headers))
frameworks\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是指NuPlayer实例
mPlayer->setDataSourceAsync(httpService, url, headers);
while (mState == STATE_SET_DATASOURCE_PENDING) {
mCondition.wait(mLock);
}
return mAsyncResult;
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::setDataSource_post(
const sp<MediaPlayerBase>& p,
status_t status)
{
// Set the re-transmission endpoint if one was chosen.
// resume时重新设置播放位置的地方?
if (mRetransmitEndpointValid) {
status = p->setRetransmitEndpoint(&mRetransmitEndpoint);
if (status != NO_ERROR) {
ALOGE("setRetransmitEndpoint error: %d", status);
}
}
if (status == OK) {
Mutex::Autolock lock(mLock);
mPlayer = p; // 保存player到mPlayer变量
}
return status;
}
三 准备 prepare
frameworks\av\media\libmedia\mediaplayer.cpp
return mPlayer->prepareAsync();
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::prepareAsync()
{
ALOGV("[%d] prepareAsync", mConnId);
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
status_t ret = p->prepareAsync();
return ret;
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::prepareAsync() {
ALOGV("prepareAsync(%p)", this);
Mutex::Autolock autoLock(mLock);
switch (mState) {
case STATE_UNPREPARED:
mState = STATE_PREPARING;
mIsAsyncPrepare = true;
mPlayer->prepareAsync(); // NuPlayer调用另外分析
return OK;
case STATE_STOPPED:
// this is really just paused. handle as seek to start
mAtEOS = false;
mState = STATE_STOPPED_AND_PREPARING;
mIsAsyncPrepare = true;
mPlayer->seekToAsync(0, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */, true /* needNotify */);
return OK;
default:
return INVALID_OPERATION;
};
}
四 开始/恢复播放 start/resume
frameworks\av\media\libmedia\mediaplayer.cpp
ret = mPlayer->start();
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::start()
{
ALOGV("[%d] start", mConnId);
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
p->setLooping(mLoop);
return p->start();
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::start() {
ALOGV("start(%p), state is %d, eos is %d", this, mState, mAtEOS);
Mutex::Autolock autoLock(mLock);
return start_l();
}
status_t NuPlayerDriver::start_l() {
switch (mState) {
......
case STATE_PAUSED:
case STATE_STOPPED_AND_PREPARED:
case STATE_PREPARED:
{
mPlayer->start(); // NuPlayer另外分析
FALLTHROUGH_INTENDED;
}
......
}
mState = STATE_RUNNING;
return OK;
}
五 暂停 pause
frameworks\av\media\libmedia\mediaplayer.cpp
status_t MediaPlayer::pause()
{
......
if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER_STARTED)) {
status_t ret = mPlayer->pause();
......
return ret;
}
ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::pause()
{
ALOGV("[%d] pause", mConnId);
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
return p->pause();
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::pause() {
......
switch (mState) {
......
case STATE_RUNNING:
mState = STATE_PAUSED;
notifyListener_l(MEDIA_PAUSED);
mPlayer->pause(); // NuPlayer另外分析
break;
default:
return INVALID_OPERATION;
}
return OK;
}
六 停止 stop
frameworks\av\media\libmedia\mediaplayer.cpp
status_t MediaPlayer::stop()
{
.....
if ( (mPlayer != 0) && ( mCurrentState & ( MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED |
MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE ) ) ) {
status_t ret = mPlayer->stop();
.....
}
ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::stop()
{
ALOGV("[%d] stop", mConnId);
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
return p->stop();
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::stop() {
......
switch (mState) {
case STATE_RUNNING:
mPlayer->pause(); // NuPlayer另外分析
FALLTHROUGH_INTENDED;
......
}
return OK;
}
七 重置 reset
frameworks\av\media\libmedia\mediaplayer.cpp
status_t MediaPlayer::reset()
{
ALOGV("reset");
mLockThreadId = getThreadId();
Mutex::Autolock _l(mLock);
status_t result = reset_l();
mLockThreadId = 0;
return result;
}
status_t MediaPlayer::reset_l()
{
mLoop = false;
if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
mPrepareSync = false;
if (mPlayer != 0) {
status_t ret = mPlayer->reset();
......
}
clear_l();
return NO_ERROR;
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
status_t MediaPlayerService::Client::reset()
{
ALOGV("[%d] reset", mConnId);
mRetransmitEndpointValid = false;
sp<MediaPlayerBase> p = getPlayer();
if (p == 0) return UNKNOWN_ERROR;
return p->reset();
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::reset() {
......
mState = STATE_RESET_IN_PROGRESS;
mPlayer->resetAsync(); // NuPlayer另外分析
......
}
八 释放 release
frameworks\av\media\libmedia\mediaplayer.cpp
void MediaPlayer::disconnect()
{
ALOGV("disconnect");
sp<IMediaPlayer> p;
{
Mutex::Autolock _l(mLock);
p = mPlayer;
mPlayer.clear(); // TODO: clear()函数在哪里? 作用好像是强弱引用的清除?
}
if (p != 0) {
p->disconnect();
}
}
frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp
void MediaPlayerService::Client::disconnect()
{
ALOGV("disconnect(%d) from pid %d", mConnId, mPid);
// grab local reference and clear main reference to prevent future
// access to object
sp<MediaPlayerBase> p;
{
Mutex::Autolock l(mLock);
p = mPlayer;
mClient.clear();
mPlayer.clear();
}
// clear the notification to prevent callbacks to dead client
// and reset the player. We assume the player will serialize
// access to itself if necessary.
if (p != 0) {
p->setNotifyCallback(0);
p->reset(); // 调用NuPlayerDriver的reset()
}
{
Mutex::Autolock l(mLock);
disconnectNativeWindow_l();
}
IPCThreadState::self()->flushCommands();
}
frameworks\av\media\libmediaplayerservice\nuplayer\NuPlayerDriver.cpp
status_t NuPlayerDriver::reset() {
......
mState = STATE_RESET_IN_PROGRESS;
mPlayer->resetAsync(); // NuPlayer另外分析
......
}