1. AwesomePlayer的构造
以前我也不怎么注意看构造函数,造成很多困扰,因为很多很重要的函数调用,是藏在构造里面的。AwesomePlayer就是一例
AwesomePlayer::AwesomePlayer(){
CHECK_EQ(mClient.connect(), (status_t)OK);
}
[OMXClinet.cpp]
status_t OMXClient::connect() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.player"));
sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
mOMX = service->getOMX();
}
[OMX.cpp]
OMX::OMX()
: mMaster(new OMXMaster){
}
[OMXMaster.cpp]
OMXMaster::OMXMaster()
: mVendorLibHandle(NULL) {
addVendorPlugin();
addPlugin(new SoftOMXPlugin);
}
void OMXMaster::addPlugin(const char *libname) {
mVendorLibHandle = dlopen(libname, RTLD_NOW);
createOMXPlugin = (CreateOMXPluginFunc)dlsym()
}
AwesomePlayer的构造会藏着一个OMXClient.connect.这个connect是OMX的一个入口。。。。。其实OMX是Mediaservice创建的,我们通过binder机制取得了这个入口,后面就要构造OMX。OMX构造了OMXMaster。OMXMaster构造里,addPlugin和AddVendorPlugin是用来加上解码器的。解码器在OMX里面都是通过OMXMaster来控制,有一个控制一个,所以我们如果要加入自己的软解CODEC,也需要让master来注册并控制。CODEC都是当成一个个的plugin在master里面监控。vendorPlugin是HW解码,是一个直接的动态文件。软解的根据名字不一样,大概如此。
2. AwesomePlayer是如何使用OMX并找到decoder去解码、渲染??
按照代码顺序,我们分步来看。
[AwesomePlayer.cpp]
status_t AwesomePlayer::initAudioDecoder() {
mAudioSource = OMXCodec::Create(
mClient.interface(), mAudioTrack->getFormat(),
false, // createEncoder
mAudioTrack);
mAudioSource->start();
}
[OMXCodec.cpp]
sp<MediaSource> OMXCodec::Create(
const sp<IOMX> &omx,
const sp<MetaData> &meta, bool createEncoder,
const sp<MediaSource> &source,
const char *matchComponentName,
uint32_t flags,
const sp<ANativeWindow> &nativeWindow) {
findMatchingCodecs
sp<OMXCodecObserver> observer = new OMXCodecObserver;
status_t err = omx->allocateNode(componentName, observer, &node);
if (err == OK) {
sp<OMXCodec> codec = new OMXCodec(
omx, node, quirks, flags,
createEncoder, mime, componentName,
source, nativeWindow);
observer->setCodec(codec);
err = codec->configureCodec(meta);
}
}
[OMX.cpp]
status_t OMX::allocateNode(
const char *name, const sp<IOMXObserver> &observer, node_id *node) {
OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
OMX_COMPONENTTYPE *handle;
OMX_ERRORTYPE err = mMaster->makeComponentInstance(
name, &OMXNodeInstance::kCallbacks,
instance, &handle);
}
[OMXMaster.cpp]
OMX_ERRORTYPE OMXMaster::makeComponentInstance(
const char *name,
const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData,
OMX_COMPONENTTYPE **component) {
OMXPluginBase *plugin = mPluginByComponentName.valueAt(index);
OMX_ERRORTYPE err =
plugin->makeComponentInstance(name, callbacks, appData, component);
mPluginByInstance.add(*component, plugin);
}
AwesomePlayer首先是initAudioDecoder,initVideoDecoder流程相同,不赘述。
在这里里面,OMXCodec::Create调用,创建OMX。在Create里面,首先findMatchingCodecs, new 一个observer,然后连着一起传递给allocateNode.....AllocateNode是个主角,他会根据相应的解码器分配node值。node值后面会有用处。。。。然后就是CodecMaster会调用makeComponentInstance。在前期,我们在AwesomePlayer的构造里面初始化了plugin,现在根据name找到那个plugin,我们的plugin(有软解、硬解)就要发挥自己的作用,在动态库中调用他们的具体实现方法。