Android 12(S) MultiMedia Learning(四)MediaPlayerService
getMediaPlayerService方法获取到的是media.player服务
IMediaDeathNotifier::getMediaPlayerService() { // ...... spsm = defaultServiceManager(); sp binder; binder = sm->getService(String16("media.player")); sMediaPlayerService = interface_cast (binder); // ...... return sMediaPlayerService; }
MediaPlayerService 和 MediaPlayerFactory的主要代码位置:
http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
http://aospxref.com/android-12.0.0_r3/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerFactory.cpp
1、服务注册
main_mediaserver 中会调用instantiate方法将media.player服务注册到servicemanager当中
void MediaPlayerService::instantiate() { defaultServiceManager()->addService( String16("media.player"), new MediaPlayerService()); }
注册时会实例化一个MediaPlayerService对象,构造函数中会调用 MediaPlayerFactory::registerBuiltinFactories 来初始化播放器工厂
// MediaPlayerService MediaPlayerService::MediaPlayerService() { ALOGV("MediaPlayerService created"); mNextConnId = 1; MediaPlayerFactory::registerBuiltinFactories(); } // MediaPlayerFactory void MediaPlayerFactory::registerBuiltinFactories() { Mutex::Autolock lock_(&sLock); if (sInitComplete) return; IFactory* factory = new NuPlayerFactory(); if (registerFactory_l(factory, NU_PLAYER) != OK) delete factory; factory = new TestPlayerFactory(); if (registerFactory_l(factory, TEST_PLAYER) != OK) delete factory; sInitComplete = true; }
2、服务使用
2.1、create
create方法中实例化了一个Client对象,并且把这个对象返回给了native mediaplayer,同时创建的Client对象会被记录到mClient这个列表当中
spMediaPlayerService::create(const sp & client, audio_session_t audioSessionId, const AttributionSourceState& attributionSource) { // ...... sp c = new Client( this, verifiedAttributionSource, connId, client, audioSessionId); // ...... wp w = c; { Mutex::Autolock lock(mLock); mClients.add(w); } return c; }
3、MediaPlayerService::Client
client是MediaPlayerService的一个内部类,继承于BnMediaPlayer,既然是个binder对象,所以可以使用binder service来传递给native mediaplayer。
/********************************************************** * Native mediaplayer -> MediaPlayerService::Client * setDataSource 构造函数 setDataSource * setVideoSurfaceTexture setVideoSurfaceTexture * prepareAsync setAudioStreamType prepareAsync * start setLooping setVolume start **********************************************************/
3.1、构造函数
构造函数主要初始化了成员变量,这里看到第四个参数传来的是native mediaPlayer对象,主要是要调用notify方法,回调上层postEventFromNative函数
MediaPlayerService::Client::Client( const sp& service, const AttributionSourceState& attributionSource, int32_t connId, const sp & client, audio_session_t audioSessionId) : mAttributionSource(attributionSource) { ALOGV("Client(%d) constructor", connId); mConnId = connId; mService = service; mClient = client; mLoop = false; mStatus = NO_INIT; mAudioSessionId = audioSessionId; mRetransmitEndpointValid = false; mAudioAttributes = NULL; mListener = new Listener(this); #if CALLBACK_ANTAGONIZER ALOGD("create Antagonizer"); mAntagonizer = new Antagonizer(mListener); #endif }
3.2、setDataSource
这里干了两件事:
a. MediaPlayerFactory::getPlayerType 从MediaPlayerFactory中获取播放器的类型
b. setDataSource_pre 根据类型来创建播放器
c. setDataSource 调用创建的MediaPlayerBase的setDataSource方法
status_t MediaPlayerService::Client::setDataSource( const sp&httpService, const char *url, const KeyedVector *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 close(fd); return mStatus = status; } else { player_type playerType = MediaPlayerFactory::getPlayerType(this, url); sp p = setDataSource_pre(playerType); if (p == NULL) { return NO_INIT; } return mStatus = setDataSource_post( p, p->setDataSource(httpService, url, headers)); } }
3.3、setVideoSurfaceTexture
这里做的事情目前还不太了解是做什么用的,但是调用了MediaPlayerBase的setVideoSurfaceTexture方法
status_t MediaPlayerService::Client::setVideoSurfaceTexture( const sp& bufferProducer) { ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, bufferProducer.get()); sp p = getPlayer(); if (p == 0) return UNKNOWN_ERROR; sp binder(IInterface::asBinder(bufferProducer)); if (mConnectedWindowBinder == binder) { return OK; } sp anw; if (bufferProducer != NULL) { anw = new Surface(bufferProducer, true /* controlledByApp */); status_t err = nativeWindowConnect(anw.get(), "setVideoSurfaceTexture"); if (err != OK) { ALOGE("setVideoSurfaceTexture failed: %d", err); // Note that we must do the reset before disconnecting from the ANW. // Otherwise queue/dequeue calls could be made on the disconnected // ANW, which may result in errors. reset(); Mutex::Autolock lock(mLock); disconnectNativeWindow_l(); return err; } } // Note that we must set the player's new GraphicBufferProducer before // disconnecting the old one. Otherwise queue/dequeue calls could be made // on the disconnected ANW, which may result in errors. status_t err = p->setVideoSurfaceTexture(bufferProducer); mLock.lock(); disconnectNativeWindow_l(); if (err == OK) { mConnectedWindow = anw; mConnectedWindowBinder = binder; mLock.unlock(); } else { mLock.unlock(); status_t err = nativeWindowDisconnect( anw.get(), "disconnectNativeWindow"); if (err != OK) { ALOGW("nativeWindowDisconnect returned an error: %s (%d)", strerror(-err), err); } } return err; }
3.4、setAudioStreamType
setAudioStreamType 操作的是AudioOutput对象,暂时不研究audio部分
status_t MediaPlayerService::Client::setAudioStreamType(audio_stream_type_t type) { ALOGV("[%d] setAudioStreamType(%d)", mConnId, type); // TODO: for hardware output, call player instead Mutex::Autolock l(mLock); if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type); return NO_ERROR; }
3.5、prepareAsync
调用了MediaPlayerBase的prepareAsync方法
status_t MediaPlayerService::Client::prepareAsync() { ALOGV("[%d] prepareAsync", mConnId); spp = getPlayer(); if (p == 0) return UNKNOWN_ERROR; status_t ret = p->prepareAsync(); #if CALLBACK_ANTAGONIZER ALOGD("start Antagonizer"); if (ret == NO_ERROR) mAntagonizer->start(); #endif return ret; }
3.6、start
调用了MediaPlayerBase的start方法
status_t MediaPlayerService::Client::start() { ALOGV("[%d] start", mConnId); spp = getPlayer(); if (p == 0) return UNKNOWN_ERROR; p->setLooping(mLoop); return p->start(); }
看到这里明白了mediaPlayer的调用顺序
mediaplayer java --> JNI --> mediaPlayer native --> mediaplayerservice (create player) --> NuplayerDriver
上层收到MEDIA_PREPARED事件的过程
接下来一节将会学习NuPlayer