Android OMX 01

本文详细解析了AwesomePlayer如何通过OMX组件初始化、寻找解码器,并完成音视频解码的过程。从AwesomePlayer构造函数入手,介绍了OMXClient连接及OMX组件实例化的步骤,最终实现解码器的选择与配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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(有软解、硬解)就要发挥自己的作用,在动态库中调用他们的具体实现方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值