日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android多媒体开发-- android中OpenMax的实现整体框架

發(fā)布時間:2023/12/15 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android多媒体开发-- android中OpenMax的实现整体框架 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.android中用openmax來干啥?

android中的?AwesomePlayer就 是用openmax來做(code)編解碼,其實在openmax接口設(shè)計中,他不光能用來當(dāng)編解碼。通過他的組件可以組成一個完整的播放器,包括 sourc、demux、decode、output。但是為什么android只用他來做code呢?我認(rèn)為有以下幾方面:

1.在整個播放器中,解碼器不得不說是最重要的一部分,而且也是最耗資源的一塊。 如果全靠軟解,直接通過cpu來運算,特別是高清視頻。別的事你就可以啥都不干了。所以解碼器是最需要硬件提供加速的部分。現(xiàn)在的高清解碼芯片都是主芯 片+DSP結(jié)構(gòu),解碼的工作都是通過DSP來做,不會在過多的占用主芯片。所有將芯片中DSP硬件編解碼的能力通過openmax標(biāo)準(zhǔn)接口呈現(xiàn)出來,提供 上層播放器來用。我認(rèn)為這塊是openmax最重要的意義。
2.source 主要是和協(xié)議打交道,demux 分解容器部分,大多數(shù)的容器格式的分解是不需要通過硬件來支持。只是ts流這種格式最可能用到硬件的支持。因為ts格式比較特殊,單包的大小太小了,只有 188字節(jié)。所以也是為什么現(xiàn)在常見的解碼芯片都會提供硬件ts demux 的支持。
3.音視頻輸出部分video\audio output 這塊和操作系統(tǒng)關(guān)系十分緊密。可以看看著名開源播放器vlc。vlc 在mac、linux、Windows都有,功能上差別也不大。所以說他是跨平臺的,他跨平臺跨在哪?主要的工作量還是在音視頻解碼完之后的輸出模塊。因 為各個系統(tǒng)的圖像渲染和音頻輸出實現(xiàn)方法不同,所以vlc需要針對每個平臺實現(xiàn)不同的output。這部分內(nèi)容放在openmax來顯然不合適。
所以openmax 中硬件抽象的編解碼是最為常用的,也是為什么android中只用它來抽象code。

2.android中openmax實現(xiàn)框架



1.上面已經(jīng)說過了,android系統(tǒng)中只用openmax來做code,所以android向上抽象了一層OMXCodec,提供給上層播放器用。 播放器中音視頻解碼器mVideosource、mAudiosource都是OMXCodec的實例。
2.OMXCodec通過IOMX 依賴binder機制 獲得 OMX服務(wù),OMX服務(wù) 才是openmax 在android中 實現(xiàn)。
3. OMX把軟編解碼和硬件編解碼統(tǒng)一看作插件的形式管理起來。

AwesomePlayer 中有個變量?

[cpp] view plaincopy
  • OMXClient?mClient;??
  • 讓我們看看?? OMXClient? [cpp] view plaincopy
  • class?OMXClient?{??
  • public:??
  • ????OMXClient();??
  • ??
  • ????status_t?connect();??
  • ????void?disconnect();??
  • ??
  • ????sp<IOMX>?interface()?{??
  • ????????return?mOMX;??
  • ????}??
  • ??
  • private:??
  • ????sp<IOMX>?mOMX;??
  • ??
  • ????OMXClient(const?OMXClient?&);??
  • ????OMXClient?&operator=(const?OMXClient?&);??
  • };??
  • OMXClient 有個IOMX 的變量 mOMX ,這個就是和OMX服務(wù)進(jìn)行binder通訊的。 在?AwesomePlayer 的構(gòu)造函數(shù)中會調(diào)用? [cpp] view plaincopy
  • CHECK_EQ(mClient.connect(),?(status_t)OK);??
  • [cpp] view plaincopy
  • status_t?OMXClient::connect()?{??
  • ????sp<IServiceManager>?sm?=?defaultServiceManager();??
  • ????sp<IBinder>?binder?=?sm->getService(String16("media.player"));??
  • ????sp<IMediaPlayerService>?service?=?interface_cast<IMediaPlayerService>(binder);??
  • ??
  • ????CHECK(service.get()?!=?NULL);??
  • ??
  • ????mOMX?=?service->getOMX();??
  • ????CHECK(mOMX.get()?!=?NULL);??
  • ??
  • ????if?(!mOMX->livesLocally(NULL?/*?node?*/,?getpid()))?{??
  • ????????ALOGI("Using?client-side?OMX?mux.");??
  • ????????mOMX?=?new?MuxOMX(mOMX);??
  • ????}??
  • ??
  • ????return?OK;??
  • }??
  • [cpp] view plaincopy
  • sp<IOMX>?MediaPlayerService::getOMX()?{??
  • ????Mutex::Autolock?autoLock(mLock);??
  • ??
  • ????if?(mOMX.get()?==?NULL)?{??
  • ????????mOMX?=?new?OMX;??
  • ????}??
  • ??
  • ????return?mOMX;??
  • }??

  • OMXClient::connect函數(shù)是通過binder機制 獲得到MediaPlayerService,然后通過MediaPlayerService來創(chuàng)建OMX的實例。這樣OMXClient就獲得到了OMX的入口,接下來就可以通過binder機制來獲得OMX提供的服務(wù)。 也就是說OMXClient 是android中 openmax 的入口。
    在創(chuàng)建音視頻解碼mVideoSource、mAudioSource的時候會把OMXClient中的sp<IOMX> mOMX的實例 傳給mVideoSource、mAudioSource來共享使用這個OMX的入口。 也就是說一個AwesomePlayer對應(yīng)著 一個IOMX 變量,AwesomePlayer中的音視頻解碼器共用這個IOMX變量來獲得OMX服務(wù)。 [cpp] view plaincopy
  • sp<IOMX>?interface()?{??
  • ??????return?mOMX;??
  • ??}??
  • [cpp] view plaincopy
  • mAudioSource?=?OMXCodec::Create(??
  • ????????????????mClient.interface(),?mAudioTrack->getFormat(),??
  • ????????????????false,?//?createEncoder??
  • ????????????????mAudioTrack);??
  • [cpp] view plaincopy
  • mVideoSource?=?OMXCodec::Create(??
  • ????????????mClient.interface(),?mVideoTrack->getFormat(),??
  • ????????????false,?//?createEncoder??
  • ????????????mVideoTrack,??
  • ????????????NULL,?flags,?USE_SURFACE_ALLOC???mNativeWindow?:?NULL);??
  • [cpp] view plaincopy
  • ?
  • 通過上文知道了,每個AwesomePlayer 只有一個OMX服務(wù)的入口,但是AwesomePlayer不一定就只需要1種解碼器。有可能音視頻都有,或者有很多種。這個時候這些解碼器都需要OMX的服務(wù),也就是OMX那頭需要建立不同的解碼器的組件來對應(yīng)著AwesomePlayer中不同的code。OMX中非常重要的2個成員就是?OMXMaster 和?OMXNodeInstance。OMX通過這倆個成員來創(chuàng)建和維護(hù)不同的openmax 解碼器組件,為AwesomePlayer中不同解碼提供服務(wù)。讓我們看看他們是怎么實現(xiàn)這些工作的。



    1. OMX中?OMXNodeInstance 負(fù)責(zé)創(chuàng)建并維護(hù)不同的實例,這些實例是根據(jù)上面需求創(chuàng)建的,以node作為唯一標(biāo)識。這樣播放器中每個OMXCodec在OMX服務(wù)端都對應(yīng)有了自己的OMXNodeInstance實例。

    2.OMXMaster 維護(hù)底層軟硬件解碼庫,根據(jù)OMXNodeInstance中想要的解碼器來創(chuàng)建解碼實體組件。

    接下來我們假設(shè)視頻解碼器需要的是AVC,來看看解碼器創(chuàng)建的流程。

    (默認(rèn)走軟解碼)

    1.準(zhǔn)備工作初始化OMXMaster

    OMX構(gòu)造函數(shù)中會進(jìn)行初始化。

    [cpp] view plaincopy
  • OMXMaster?*mMaster;??
  • [cpp] view plaincopy
  • OMX::OMX()??
  • ????:?mMaster(new?OMXMaster),??
  • ??????mNodeCounter(0)?{??
  • }??
  • [cpp] view plaincopy
  • OMXMaster::OMXMaster()??
  • ????:?mVendorLibHandle(NULL)?{??
  • ????addVendorPlugin();??
  • ????addPlugin(new?SoftOMXPlugin);??
  • }??
  • OMXMaster 負(fù)責(zé)OMX中編解碼器插件管理,軟件解碼和硬件解碼都是使用OMX標(biāo)準(zhǔn),掛載plugins的方式來進(jìn)行管理。 軟解通過 addPlugin(new SoftOMXPlugin);會把這些編解碼器的名字都放在mPluginByComponentName中。 android 默認(rèn)會提供一系列的軟件解碼器。目前支持這些格式的軟編解碼。 [cpp] view plaincopy
  • kComponents[]?=?{??
  • ????{?"OMX.google.aac.decoder",?"aacdec",?"audio_decoder.aac"?},??
  • ????{?"OMX.google.aac.encoder",?"aacenc",?"audio_encoder.aac"?},??
  • ????{?"OMX.google.amrnb.decoder",?"amrdec",?"audio_decoder.amrnb"?},??
  • ????{?"OMX.google.amrnb.encoder",?"amrnbenc",?"audio_encoder.amrnb"?},??
  • ????{?"OMX.google.amrwb.decoder",?"amrdec",?"audio_decoder.amrwb"?},??
  • ????{?"OMX.google.amrwb.encoder",?"amrwbenc",?"audio_encoder.amrwb"?},??
  • ????{?"OMX.google.h264.decoder",?"h264dec",?"video_decoder.avc"?},??
  • ????{?"OMX.google.h264.encoder",?"h264enc",?"video_encoder.avc"?},??
  • ????{?"OMX.google.g711.alaw.decoder",?"g711dec",?"audio_decoder.g711alaw"?},??
  • ????{?"OMX.google.g711.mlaw.decoder",?"g711dec",?"audio_decoder.g711mlaw"?},??
  • ????{?"OMX.google.h263.decoder",?"mpeg4dec",?"video_decoder.h263"?},??
  • ????{?"OMX.google.h263.encoder",?"mpeg4enc",?"video_encoder.h263"?},??
  • ????{?"OMX.google.mpeg4.decoder",?"mpeg4dec",?"video_decoder.mpeg4"?},??
  • ????{?"OMX.google.mpeg4.encoder",?"mpeg4enc",?"video_encoder.mpeg4"?},??
  • ????{?"OMX.google.mp3.decoder",?"mp3dec",?"audio_decoder.mp3"?},??
  • ????{?"OMX.google.vorbis.decoder",?"vorbisdec",?"audio_decoder.vorbis"?},??
  • ????{?"OMX.google.vpx.decoder",?"vpxdec",?"video_decoder.vpx"?},??
  • ????{?"OMX.google.raw.decoder",?"rawdec",?"audio_decoder.raw"?},??
  • ????{?"OMX.google.flac.encoder",?"flacenc",?"audio_encoder.flac"?},??
  • };??
  • 硬件編解碼是通過 addVendorPlugin();加載libstagefrighthw.so.各個芯片平臺可以遵循openmax 標(biāo)準(zhǔn),生成libstagefrighthw.so的庫來提供android應(yīng)用。 [cpp] view plaincopy
  • void?OMXMaster::addVendorPlugin()?{??
  • ????addPlugin("libstagefrighthw.so");??
  • }??
  • 然后通過dlopen、dlsym來調(diào)用庫中的函數(shù)。

    這部分準(zhǔn)備工作是在AwesomePlayer的構(gòu)造函數(shù)中 CHECK_EQ(mClient.connect(), (status_t)OK); 已經(jīng)完成了。

    2.創(chuàng)建mVideoSource

    有了上面的OMX,接下來會在AwesomePlayer::initVideoDecoder中創(chuàng)建mVideoSource 實例,下面代碼只保留的主要部分: [cpp] view plaincopy
  • status_t?AwesomePlayer::initVideoDecoder(uint32_t?flags)?{??
  • ????ATRACE_CALL();??
  • ????mVideoSource?=?OMXCodec::Create(??
  • ????????????mClient.interface(),?mVideoTrack->getFormat(),??
  • ????????????false,?//?createEncoder??
  • ????????????mVideoTrack,??
  • ????????????NULL,?flags,?USE_SURFACE_ALLOC???mNativeWindow?:?NULL);??
  • ????status_t?err?=?mVideoSource->start();??
  • ????return?mVideoSource?!=?NULL???OK?:?UNKNOWN_ERROR;??
  • }??
  • 保留主要部分,去除編碼相關(guān) [cpp] view plaincopy
  • 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)?{??
  • ????int32_t?requiresSecureBuffers;??
  • ??????
  • ????const?char?*mime;??
  • ????bool?success?=?meta->findCString(kKeyMIMEType,?&mime);??
  • ????CHECK(success);??
  • ??
  • ????Vector<String8>?matchingCodecs;??
  • ????Vector<uint32_t>?matchingCodecQuirks;??
  • ????findMatchingCodecs(??
  • ????????????mime,?createEncoder,?matchComponentName,?flags,??
  • ????????????&matchingCodecs,?&matchingCodecQuirks);??
  • ??
  • ????sp<OMXCodecObserver>?observer?=?new?OMXCodecObserver;??
  • ????IOMX::node_id?node?=?0;??
  • ??
  • ????for?(size_t?i?=?0;?i?<?matchingCodecs.size();?++i)?{??
  • ????????const?char?*componentNameBase?=?matchingCodecs[i].string();??
  • ????????uint32_t?quirks?=?matchingCodecQuirks[i];??
  • ????????const?char?*componentName?=?componentNameBase;??
  • ??
  • ????????AString?tmp;??
  • ?????
  • ????????status_t?err?=?omx->allocateNode(componentName,?observer,?&node);??
  • ????????if?(err?==?OK)?{??
  • ????????????ALOGV("Successfully?allocated?OMX?node?'%s'",?componentName);??
  • ??
  • ????????????sp<OMXCodec>?codec?=?new?OMXCodec(??
  • ????????????????????omx,?node,?quirks,?flags,??
  • ????????????????????createEncoder,?mime,?componentName,??
  • ????????????????????source,?nativeWindow);??
  • ??
  • ????????????observer->setCodec(codec);??
  • ??
  • ????????????err?=?codec->configureCodec(meta);??
  • ??
  • ????????????if?(err?==?OK)?{??
  • ????????????????if?(!strcmp("OMX.Nvidia.mpeg2v.decode",?componentName))?{??
  • ????????????????????codec->mFlags?|=?kOnlySubmitOneInputBufferAtOneTime;??
  • ????????????????}??
  • ??
  • ????????????????return?codec;??
  • ????????????}??
  • ??
  • ????????????ALOGV("Failed?to?configure?codec?'%s'",?componentName);??
  • ????????}??
  • ????}??
  • ??
  • ????return?NULL;??
  • }??
  • 1.根據(jù)mVideoTrack傳進(jìn)來的視頻信息,查找相匹配的解碼器。

    [cpp] view plaincopy
  • bool?success?=?meta->findCString(kKeyMIMEType,?&mime);??
  • findMatchingCodecs(??
  • ???????????mime,?createEncoder,?matchComponentName,?flags,??
  • ???????????&matchingCodecs,?&matchingCodecQuirks);??

  • 2. 創(chuàng)建OMXCodecObserver 實例,OMXCodecObserver功能后續(xù)會詳細(xì)介紹。創(chuàng)建一個node 并初始化為0. [cpp] view plaincopy
  • sp<OMXCodecObserver>?observer?=?new?OMXCodecObserver;??
  • ????IOMX::node_id?node?=?0;??

  • 3. 通過omx入口 依靠binder 機制調(diào)用OMX服務(wù)中的allocateNode(),這一步把匹配得到的解碼器組件名、OMXCodecObserver實例和初始化為0的node一并傳入。 [cpp] view plaincopy
  • status_t?err?=?omx->allocateNode(componentName,?observer,?&node);??
  • 這個allocateNode 就是文章最開始講的,在OMX那頭創(chuàng)建一個和mVideoSource相匹配的解碼實例。用node值作為唯一標(biāo)識。
    讓我們來看看真正的omx中allocateNode做了啥? [cpp] view plaincopy
  • status_t?OMX::allocateNode(??
  • ????????const?char?*name,?const?sp<IOMXObserver>?&observer,?node_id?*node)?{??
  • ????Mutex::Autolock?autoLock(mLock);??
  • ??
  • ????*node?=?0;??
  • ??
  • ????OMXNodeInstance?*instance?=?new?OMXNodeInstance(this,?observer);??
  • ??
  • ????OMX_COMPONENTTYPE?*handle;??
  • ????OMX_ERRORTYPE?err?=?mMaster->makeComponentInstance(??
  • ????????????name,?&OMXNodeInstance::kCallbacks,??
  • ????????????instance,?&handle);??
  • ??
  • ????if?(err?!=?OMX_ErrorNone)?{??
  • ????????ALOGV("FAILED?to?allocate?omx?component?'%s'",?name);??
  • ??
  • ????????instance->onGetHandleFailed();??
  • ??
  • ????????return?UNKNOWN_ERROR;??
  • ????}??
  • ??
  • ????*node?=?makeNodeID(instance);??
  • ????mDispatchers.add(*node,?new?CallbackDispatcher(instance));??
  • ??
  • ????instance->setHandle(*node,?handle);??
  • ??
  • ????mLiveNodes.add(observer->asBinder(),?instance);??
  • ????observer->asBinder()->linkToDeath(this);??
  • ??
  • ????return?OK;??
  • }??

  • 創(chuàng)建一個OMXNodeInstance實例。 通過mMaster->makeComponentInstance創(chuàng)建真正解碼器的組件,并通過handle與OMXNodeInstance關(guān)聯(lián)。 所以說mMaster->makeComponentInstance這里是建立解碼器組件的核心。會把mVideoSource需要的解碼器name一直傳遞下去。 [cpp] view plaincopy
  • OMX_ERRORTYPE?OMXMaster::makeComponentInstance(??
  • ????????const?char?*name,??
  • ????????const?OMX_CALLBACKTYPE?*callbacks,??
  • ????????OMX_PTR?appData,??
  • ????????OMX_COMPONENTTYPE?**component)?{??
  • ????Mutex::Autolock?autoLock(mLock);??
  • ??
  • ????*component?=?NULL;??
  • ??
  • ????ssize_t?index?=?mPluginByComponentName.indexOfKey(String8(name));??
  • ??
  • ????if?(index?<?0)?{??
  • ????????return?OMX_ErrorInvalidComponentName;??
  • ????}??
  • ??
  • ????OMXPluginBase?*plugin?=?mPluginByComponentName.valueAt(index);??
  • ????OMX_ERRORTYPE?err?=??
  • ????????plugin->makeComponentInstance(name,?callbacks,?appData,?component);??
  • ??
  • ????if?(err?!=?OMX_ErrorNone)?{??
  • ????????return?err;??
  • ????}??
  • ??
  • ????mPluginByInstance.add(*component,?plugin);??
  • ??
  • ????return?err;??
  • }??

  • 最開始OMXMaster通過?addPlugin(new SoftOMXPlugin);把支持的軟解碼放在mPluginByComponentName中,在makeComponentInstance中通過上面?zhèn)飨聛淼慕獯a器的name值從mPluginByComponentName找到相對應(yīng)的plugin,然后調(diào)用? plugin->makeComponentInstance(name, callbacks, appData, component);
    這里的plugin 值得就是軟解SoftOMXPlugin 也就是調(diào)用了 [cpp] view plaincopy
  • OMX_ERRORTYPE?SoftOMXPlugin::makeComponentInstance(??
  • ????????const?char?*name,??
  • ????????const?OMX_CALLBACKTYPE?*callbacks,??
  • ????????OMX_PTR?appData,??
  • ????????OMX_COMPONENTTYPE?**component)?{??
  • ????ALOGV("makeComponentInstance?'%s'",?name);??
  • ??
  • ????for?(size_t?i?=?0;?i?<?kNumComponents;?++i)?{??
  • ????????if?(strcmp(name,?kComponents[i].mName))?{??
  • ????????????continue;??
  • ????????}??
  • ??
  • ????????AString?libName?=?"libstagefright_soft_";??
  • ????????libName.append(kComponents[i].mLibNameSuffix);??
  • ????????libName.append(".so");??
  • ??
  • ????????void?*libHandle?=?dlopen(libName.c_str(),?RTLD_NOW);??
  • ??
  • ????????if?(libHandle?==?NULL)?{??
  • ????????????ALOGE("unable?to?dlopen?%s",?libName.c_str());??
  • ??
  • ????????????return?OMX_ErrorComponentNotFound;??
  • ????????}??
  • ??
  • ????????typedef?SoftOMXComponent?*(*CreateSoftOMXComponentFunc)(??
  • ????????????????const?char?*,?const?OMX_CALLBACKTYPE?*,??
  • ????????????????OMX_PTR,?OMX_COMPONENTTYPE?**);??
  • ??
  • ????????CreateSoftOMXComponentFunc?createSoftOMXComponent?=??
  • ????????????(CreateSoftOMXComponentFunc)dlsym(??
  • ????????????????????libHandle,??
  • ????????????????????"_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPE"??
  • ????????????????????"PvPP17OMX_COMPONENTTYPE");??
  • ??
  • ????????if?(createSoftOMXComponent?==?NULL)?{??
  • ????????????dlclose(libHandle);??
  • ????????????libHandle?=?NULL;??
  • ??
  • ????????????return?OMX_ErrorComponentNotFound;??
  • ????????}??
  • ??
  • ????????sp<SoftOMXComponent>?codec?=??
  • ????????????(*createSoftOMXComponent)(name,?callbacks,?appData,?component);??
  • ??
  • ????????if?(codec?==?NULL)?{??
  • ????????????dlclose(libHandle);??
  • ????????????libHandle?=?NULL;??
  • ??
  • ????????????return?OMX_ErrorInsufficientResources;??
  • ????????}??
  • ??
  • ????????OMX_ERRORTYPE?err?=?codec->initCheck();??
  • ????????if?(err?!=?OMX_ErrorNone)?{??
  • ????????????dlclose(libHandle);??
  • ????????????libHandle?=?NULL;??
  • ??
  • ????????????return?err;??
  • ????????}??
  • ??
  • ????????codec->incStrong(this);??
  • ????????codec->setLibHandle(libHandle);??
  • ??
  • ????????return?OMX_ErrorNone;??
  • ????}??
  • ??
  • ????return?OMX_ErrorInvalidComponentName;??
  • }??
  • 通過上面?zhèn)飨聛淼慕獯a器的name,找到對應(yīng)庫的名字。假如是264的話,要加載的庫就是 libstagefright_soft_h264dec.so,也就是對應(yīng)上層264解碼的話,omx解碼組件會加載對應(yīng)的 libstagefright_soft_h264dec.so庫。相對應(yīng)的軟解代碼在 Android4.1.1\frameworks\av\media\libstagefright\codecs\on2\h264dec 中。 加載完264解碼庫后 通過dlopen、dlsym來調(diào)用庫中函數(shù)。 通過調(diào)用 SoftAVC 中的 createSoftOMXComponent 來創(chuàng)建真正264解碼器實例SoftOMXComponent。以后真正視頻解碼的工作都是通過avc 這個SoftAVC實例完成的 [cpp] view plaincopy
  • android::SoftOMXComponent?*createSoftOMXComponent(??
  • ????????const?char?*name,?const?OMX_CALLBACKTYPE?*callbacks,??
  • ????????OMX_PTR?appData,?OMX_COMPONENTTYPE?**component)?{??
  • ????return?new?android::SoftAVC(name,?callbacks,?appData,?component);??
  • }??

  • 經(jīng)過這一路下來,終于完成了解碼器的創(chuàng)建工作。簡單總結(jié)一下。
    1.AwesomePlayer中通過initVideoDecoder 來創(chuàng)建video解碼器mVideoSource 2.mVideoSource 中通過上部分demux后的視頻流 mVideoTrack來獲得解碼器的類型,通過類型調(diào)用omx->allocateNode 創(chuàng)建omx node實例與自己對應(yīng)。以后都是通過node實例來操作解碼器。 3.在 omx->allocateNode中 通過mMaster->makeComponentInstance 來創(chuàng)建真正對應(yīng)的解碼器組件。這個解碼器組件是完成之后解碼實際工作的。 4.在創(chuàng)建mMaster->makeComponentInstance過程中,也是通過上面mVideoTrack 過來的解碼器類型名,找到相對應(yīng)的解碼器的庫,然后實例化。

    轉(zhuǎn)載于:https://www.cnblogs.com/shakin/p/4096536.html

    總結(jié)

    以上是生活随笔為你收集整理的Android多媒体开发-- android中OpenMax的实现整体框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。