当前位置: 首页 > news >正文

公司网站建设推广方案模板在线平台

公司网站建设推广方案模板,在线平台,网站的建设方法有哪些内容,秦皇岛开发区媒体编解码API使用示例 //获取相关格式文件的内容信息#xff0c;如轨道数量、获取MIME信息、视频的高度与宽度、语言格式、播放总时长等 MediaExtractor mediaExtractor new MediaExtractor(); try {mediaExtractor.setDataSource(path); // 设置数据源 } catch (IOExcept…媒体编解码API使用示例 //获取相关格式文件的内容信息如轨道数量、获取MIME信息、视频的高度与宽度、语言格式、播放总时长等 MediaExtractor mediaExtractor new MediaExtractor(); try {mediaExtractor.setDataSource(path); // 设置数据源 } catch (IOException e1) {e1.printStackTrace(); }String mimeType null; // video/mp4v-es - MPEG4 video audio/3gpp - AMR narrowband audio for (int i 0; i mediaExtractor.getTrackCount(); i) { // 信道总数MediaFormat format mediaExtractor.getTrackFormat(i); // 音频文件信息mimeType format.getString(MediaFormat.KEY_MIME);if (mimeType.startsWith(video/)) { // 视频信道mediaExtractor.selectTrack(i); // 切换到视频信道try {mediaCodec MediaCodec.createDecoderByType(mimeType); // 创建解码器,提供数据输出} catch (IOException e) {e.printStackTrace();}mediaCodec.configure(format, surface, null, 0);break;} } mediaCodec.start(); // 启动MediaCodec 等待传入数据 1.createDecoderByType根据MimeType信息创建相匹配的解码器。 public static MediaCodec createDecoderByType(NonNull String type)throws IOException {return new MediaCodec(type, true /* nameIsType */, false /* encoder */); }private MediaCodec(NonNull String name, boolean nameIsType, boolean encoder) {Looper looper;if ((looper Looper.myLooper()) ! null) {mEventHandler new EventHandler(this, looper);} else if ((looper Looper.getMainLooper()) ! null) {mEventHandler new EventHandler(this, looper);} else {mEventHandler null;}mCallbackHandler mEventHandler;mOnFrameRenderedHandler mEventHandler;mBufferLock new Object();native_setup(name, nameIsType, encoder); } 通过JNI调用到MediaCodec.cpp static void android_media_MediaCodec_native_setup(spJMediaCodec codec new JMediaCodec(env, thiz, tmp, nameIsType, encoder); }JMediaCodec::JMediaCodec(JNIEnv *env, jobject thiz,const char *name, bool nameIsType, bool encoder): mClass(NULL),mObject(NULL) { ...if (nameIsType) {mCodec MediaCodec::CreateByType(mLooper, name, encoder, mInitStatus);} else {mCodec MediaCodec::CreateByComponentName(mLooper, name, mInitStatus);}CHECK((mCodec ! NULL) ! (mInitStatus ! OK)); } 2.CreateByType创建对应的MediaCodec并初始化 // frameworks\av\media\libstagefright\MediaCodec.cpp spMediaCodec MediaCodec::CreateByType(const spALooper looper, const AString mime, bool encoder, status_t *err, pid_t pid,uid_t uid) {VectorAString matchingCodecs;// 1.根据mime获取对应的codecMediaCodecList::findMatchingCodecs(mime.c_str(),encoder,0,matchingCodecs);if (err ! NULL) {*err NAME_NOT_FOUND;}//2.创建对应的MediaCodec并初始化for (size_t i 0; i matchingCodecs.size(); i) {spMediaCodec codec new MediaCodec(looper, pid, uid);AString componentName matchingCodecs[i];status_t ret codec-init(componentName);if (err ! NULL) {*err ret;}if (ret OK) {return codec;}ALOGD(Allocating component %s failed (%d), try next one.,componentName.c_str(), ret);}return NULL; } 3.findMatchingCodecs获取对应的codec 先获取支持的编解码器列表再匹配最佳的编解码器 //frameworks\av\media\libstagefright\MediaCodecList.cpp void MediaCodecList::findMatchingCodecs(const char *mime, bool encoder, uint32_t flags,VectorAString *matches) {matches-clear();// 获取系统支持的编解码器列表const spIMediaCodecList list getInstance();if (list nullptr) {return;}//匹配最佳的编解码器size_t index 0;for (;;) {ssize_t matchIndex list-findCodecByType(mime, encoder, index);if (matchIndex 0) {break;}index matchIndex 1;const spMediaCodecInfo info list-getCodecInfo(matchIndex);CHECK(info ! nullptr);AString componentName info-getCodecName();if ((flags kHardwareCodecsOnly) isSoftwareCodec(componentName)) {ALOGV(skipping SW codec %s, componentName.c_str());} else {matches-push(componentName);ALOGV(matching %s, componentName.c_str());}}if (flags kPreferSoftwareCodecs ||property_get_bool(debug.stagefright.swcodec, false)) {matches-sort(compareSoftwareCodecsFirst);} } 4.获取系统支持的Codec列表 先通过binder调到MediaPlayerService的getCodecList函数 //frameworks\av\media\libstagefright\MediaCodecList.cpp spIMediaCodecList MediaCodecList::getInstance() {Mutex::Autolock _l(sRemoteInitMutex);if (sRemoteList nullptr) {spIBinder binder defaultServiceManager()-getService(String16(media.player));spIMediaPlayerService service interface_castIMediaPlayerService(binder);if (service.get() ! nullptr) {// 获取服务端的MediaCodecListsRemoteList service-getCodecList();if (sRemoteList ! nullptr) {sBinderDeathObserver new BinderDeathObserver();binder-linkToDeath(sBinderDeathObserver.get());}}if (sRemoteList nullptr) {// if failed to get remote list, create local listsRemoteList getLocalInstance();}}return sRemoteList; } 可以看到又回到了MediaCodecList没错就是media/stagefright下的MediaCodecList 说明MediaCodecList的创建是在mediaplayerservice进程 //frameworks\av\media\libmediaplayerservice\MediaPlayerService.cpp spIMediaCodecList MediaPlayerService::getCodecList() const {return MediaCodecList::getLocalInstance(); } GetBuilders()作为参数创建MediaCodecList单例并返回关键在于GetBuilders()函数 //frameworks\av\media\libstagefright\MediaCodecList.cpp spIMediaCodecList MediaCodecList::getLocalInstance() {Mutex::Autolock autoLock(sInitMutex);if (sCodecList nullptr) {MediaCodecList *codecList new MediaCodecList(GetBuilders());if (codecList-initCheck() OK) {sCodecList codecList;if (isProfilingNeeded()) {ALOGV(Codec profiling needed, will be run in separated thread.);pthread_t profiler;if (pthread_create(profiler, nullptr, profilerThreadWrapper, nullptr) ! 0) {ALOGW(Failed to create thread for codec profiling.);}}} else {// failure to initialize may be temporary. retry on next call.delete codecList;}}return sCodecList; }GetBuilders std::vectorMediaCodecListBuilderBase * GetBuilders() {std::vectorMediaCodecListBuilderBase * builders;// if plugin provides the input surface, we cannot use OMX video encoders.// In this case, rely on plugin to provide list of OMX codecs that are usable.spPersistentSurface surfaceTest StagefrightPluginLoader::GetCCodecInstance()-createInputSurface();if (surfaceTest nullptr) {builders.push_back(sOmxInfoBuilder);}builders.push_back(GetCodec2InfoBuilder());return builders; } 5.构造MediaCodecList frameworks\av\media\libstagefright\MediaCodecList.cpp MediaCodecList::MediaCodecList(std::vectorMediaCodecListBuilderBase* builders) {mGlobalSettings new AMessage();mCodecInfos.clear();MediaCodecListWriter writer;for (MediaCodecListBuilderBase *builder : builders) {if (builder nullptr) {ALOGD(ignored a null builder);continue;}// 进入build的buildMediaCodecList函数mInitCheck builder-buildMediaCodecList(writer);if (mInitCheck ! OK) {break;}}writer.writeGlobalSettings(mGlobalSettings);writer.writeCodecInfos(mCodecInfos);std::stable_sort(mCodecInfos.begin(),mCodecInfos.end(),[](const spMediaCodecInfo info1, const spMediaCodecInfo info2) {if (info2 nullptr) {return false;} else if (info1 nullptr) {return true;} else {return info1-rank() info2-rank();}}); } 通过OmxInfoBuilder创建MediaCodec列表途径一 1、通过HIDL调用到OmxStore.cpp, 通过OmxStore从xml解析支持的CodecList及Attributes 2、将支持的codec存储进swCodecName2Info, hwCodecName2Info //frameworks\av\media\libstagefright\OmxInfoBuilder.cpp status_t OmxInfoBuilder::buildMediaCodecList(MediaCodecListWriter* writer) {// Obtain IOmxStorespIOmxStore omxStore IOmxStore::getService();if (omxStore nullptr) {ALOGE(Cannot find an IOmxStore service.);return NO_INIT;}// List service attributes (global settings)Status status;hidl_vecIOmxStore::RoleInfo roles;// 通过HIDL获取inRoleListauto transStatus omxStore-listRoles([roles] (const hidl_vecIOmxStore::RoleInfo inRoleList) {roles inRoleList;});if (!transStatus.isOk()) {ALOGE(Fail to obtain codec roles from IOmxStore.);return NO_INIT;}hidl_vecIOmxStore::ServiceAttribute serviceAttributes;transStatus omxStore-listServiceAttributes([status, serviceAttributes] (Status inStatus,const hidl_vecIOmxStore::ServiceAttribute inAttributes) {status inStatus;serviceAttributes inAttributes;});if (!transStatus.isOk()) {ALOGE(Fail to obtain global settings from IOmxStore.);return NO_INIT;}if (status ! Status::OK) {ALOGE(IOmxStore reports parsing error.);return NO_INIT;}for (const auto p : serviceAttributes) {writer-addGlobalSetting(p.key.c_str(), p.value.c_str());}// Convert roles to lists of codecs// codec name - index into swCodecs/hwCodecsstd::maphidl_string, std::unique_ptrMediaCodecInfoWriterswCodecName2Info, hwCodecName2Info;char rank[PROPERTY_VALUE_MAX];uint32_t defaultRank 0x100;if (property_get(debug.stagefright.omx_default_rank, rank, nullptr)) {defaultRank std::strtoul(rank, nullptr, 10);}//将支持的codec存储进swCodecName2Info, hwCodecName2Infofor (const IOmxStore::RoleInfo role : roles) {const hidl_string typeName role.type;bool isEncoder role.isEncoder;bool preferPlatformNodes role.preferPlatformNodes;// If preferPlatformNodes is true, hardware nodes must be added after// platform (software) nodes. hwCodecs is used to hold hardware nodes// that need to be added after software nodes for the same role.std::vectorconst IOmxStore::NodeInfo* hwCodecs;for (const IOmxStore::NodeInfo node : role.nodes) {const hidl_string nodeName node.name;// OMX.google开头的都是软解码bool isSoftware hasPrefix(nodeName, OMX.google);MediaCodecInfoWriter* info;if (isSoftware) {auto c2i swCodecName2Info.find(nodeName);if (c2i swCodecName2Info.end()) {// Create a new MediaCodecInfo for a new node.c2i swCodecName2Info.insert(std::make_pair(nodeName, writer-addMediaCodecInfo())).first;info c2i-second.get();info-setName(nodeName.c_str());info-setOwner(node.owner.c_str());info-setEncoder(isEncoder);info-setRank(defaultRank);} else {// The node has been seen before. Simply retrieve the// existing MediaCodecInfoWriter.info c2i-second.get();}} else {auto c2i hwCodecName2Info.find(nodeName);if (c2i hwCodecName2Info.end()) {// Create a new MediaCodecInfo for a new node.if (!preferPlatformNodes) {c2i hwCodecName2Info.insert(std::make_pair(nodeName, writer-addMediaCodecInfo())).first;info c2i-second.get();info-setName(nodeName.c_str());info-setOwner(node.owner.c_str());info-setEncoder(isEncoder);info-setRank(defaultRank);} else {// If preferPlatformNodes is true, this node must be// added after all software nodes.hwCodecs.push_back(node);continue;}} else {// The node has been seen before. Simply retrieve the// existing MediaCodecInfoWriter.info c2i-second.get();}}std::unique_ptrMediaCodecInfo::CapabilitiesWriter caps info-addMime(typeName.c_str());if (queryCapabilities(node, typeName.c_str(), isEncoder, caps.get()) ! OK) {ALOGW(Fail to add mime %s to codec %s,typeName.c_str(), nodeName.c_str());info-removeMime(typeName.c_str());}}。。。}return OK; } 通过OmxStore.cpp解析xml中的编解码器及属性 OmxStore.cpp读取的配置文件有 实际项目在 /vendor/etc 中 //frameworks\av\media\libstagefright\xmlparser\include\media\stagefright\xmlparser\MediaCodecsXmlParser.h static constexpr char const* defaultSearchDirs[] {/odm/etc, /vendor/etc, /etc, nullptr}; static constexpr char const* defaultMainXmlName media_codecs.xml; static constexpr char const* defaultPerformanceXmlName media_codecs_performance.xml; static constexpr char const* defaultProfilingResultsXmlPath /data/misc/media/media_codecs_profiling_results.xml;获取对应解码器的查询能力实际为创建对应得解码器 //frameworks\av\media\libstagefright\OmxInfoBuilder.cpp status_t queryCapabilities(const IOmxStore::NodeInfo node, const char* mime, bool isEncoder,MediaCodecInfo::CapabilitiesWriter* caps) {spACodec codec new ACodec();status_t err codec-queryCapabilities(node.owner.c_str(), node.name.c_str(), mime, isEncoder, caps); // ... } 依靠binder机制调用OMX服务中的allocateNode() //frameworks\av\media\libstagefright\ACodec.cpp status_t ACodec::queryCapabilities(const char* owner, const char* name, const char* mime, bool isEncoder,MediaCodecInfo::CapabilitiesWriter* caps) {const char *role AVUtils::get()-getComponentRole(isEncoder, mime);if (role NULL) {return BAD_VALUE;}OMXClient client;// 获取名为“” Omx实现status_t err client.connect(owner);if (err ! OK) {return err;}// 获取omx bp代理对象spIOMX omx client.interface();spCodecObserver observer new CodecObserver;spIOMXNode omxNode;// hidl远程调用allocateNodeerr omx-allocateNode(name, observer, omxNoe);// ... } 获取服务名为XXXX的OMX并以LWOmx封装返回 frameworks\av\media\libstagefright\OMXClient.cpp status_t OMXClient::connect(const char* name) {using namespace ::android::hardware::media::omx::V1_0;if (name nullptr) {name default;}spIOmx tOmx IOmx::getService(name);if (tOmx.get() nullptr) {ALOGE(Cannot obtain IOmx service.);return NO_INIT;}if (!tOmx-isRemote()) {ALOGE(IOmx service running in passthrough mode.);return NO_INIT;}mOMX new utils::LWOmx(tOmx);ALOGI(IOmx service obtained);return OK; } 6.allocateNode创建对应的解码器 LWOmx是代理具体的实现在libstagefright_omx.so //frameworks\av\media\libmedia\omx\1.0\WOmx.cpp status_t LWOmx::allocateNode(char const* name,spIOMXObserver const observer,spIOMXNode* omxNode) {status_t fnStatus;// allocateNodestatus_t transStatus toStatusT(mBase-allocateNode(name, new TWOmxObserver(observer),[fnStatus, omxNode](Status status, spIOmxNode const node) {fnStatus toStatusT(status);*omxNode new LWOmxNode(node);}));return transStatus NO_ERROR ? fnStatus : transStatus; } 6.1 创建对应的OMXNodeInstance对象 OMXNodeInstance对象持有一些关键信息比如生成的节点id(mNodeID)、ACodec传递下来的observer、plugin里创建的解码组件handle和构造OMXNodeInstance时传入的omx对象等。还有关键的解码事件返回的kCallbacks。 //frameworks\av\media\libstagefright\omx\1.0\Omx.cpp //libstagefright_omx.so Returnvoid Omx::allocateNode(const hidl_string name,const spIOmxObserver observer,allocateNode_cb _hidl_cb) {using ::android::IOMXNode;using ::android::IOMXObserver;spOMXNodeInstance instance;{Mutex::Autolock autoLock(mLock);if (mLiveNodes.size() kMaxNodeInstances) {_hidl_cb(toStatus(NO_MEMORY), nullptr);return Void();}// 1. 实例化OMXNodeInstance对象存放node id、解码组件handle、ACodec传递下来的observer等instance new OMXNodeInstance(this, new LWOmxObserver(observer), name.c_str());OMX_COMPONENTTYPE *handle;// 2. master通知plugin创建对应的解码组件、并返回其操作句柄 OMX_ERRORTYPE err mMaster-makeComponentInstance(name.c_str(), OMXNodeInstance::kCallbacks,instance.get(), handle);if (err ! OMX_ErrorNone) {LOG(ERROR) Failed to allocate omx component name.c_str() err asString(err) (0x std::hex unsigned(err) );_hidl_cb(toStatus(StatusFromOMXError(err)), nullptr);return Void();}instance-setHandle(handle);// Find quirks from mParserconst auto codec mParser.getCodecMap().find(name.c_str());if (codec mParser.getCodecMap().cend()) {LOG(WARNING) Failed to obtain quirks for omx component name.c_str() from XML files;} else {uint32_t quirks 0;for (const auto quirk : codec-second.quirkSet) {if (quirk requires-allocate-on-input-ports) {quirks | OMXNodeInstance::kRequiresAllocateBufferOnInputPorts;}if (quirk requires-allocate-on-output-ports) {quirks | OMXNodeInstance::kRequiresAllocateBufferOnOutputPorts;}}instance-setQuirks(quirks);}mLiveNodes.add(observer.get(), instance);mNode2Observer.add(instance.get(), observer.get());}observer-linkToDeath(this, 0);_hidl_cb(toStatus(OK), new TWOmxNode(instance));return Void(); }// frameworks/av/media/libstagefright/omx/OMXNodeInstance.cpp // static OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks {OnEvent, OnEmptyBufferDone, OnFillBufferDone }; 6.2 makeComponentInstance OMXMaster是解码库加载的核心 先找到指定的plugin解码器组件有厂商定制的及AOSP的、再通知plugin去创建对应的解码组件。 frameworks\av\media\libstagefright\omx\OMXMaster.cpp OMX_ERRORTYPE OMXMaster::makeComponentInstance(const char *name,const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData,OMX_COMPONENTTYPE **component) {ALOGI(makeComponentInstance(%s) in %s process, name, mProcessName);Mutex::Autolock autoLock(mLock);*component NULL;// 找到对应的Pluginssize_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构造函数 加载软硬编解码管理器中的所有解码器并存在mPluginByComponentName。 1.加载厂商编解码管理器libstagefrighthw.so 2.加载软编解码管理器SoftOMXPlugin OMXMaster::OMXMaster(): mVendorLibHandle(NULL) {pid_t pid getpid();char filename[20];snprintf(filename, sizeof(filename), /proc/%d/comm, pid);int fd open(filename, O_RDONLY);if (fd 0) {ALOGW(couldnt determine process name);strlcpy(mProcessName, unknown, sizeof(mProcessName));} else {ssize_t len read(fd, mProcessName, sizeof(mProcessName));if (len 2) {ALOGW(couldnt determine process name);strlcpy(mProcessName, unknown, sizeof(mProcessName));} else {// the name is newline terminated, so erase the newlinemProcessName[len - 1] 0;}close(fd);}//加载厂商解码器SOaddVendorPlugin();//加载软解码器SOaddPlugin(new SoftOMXPlugin); }void OMXMaster::addVendorPlugin() {addPlugin(libstagefrighthw.so); } 7 实际创建对应解码器makeComponentInstance 如果是软件编解码器调用SoftOMXPlugin的makeComponentInstance 如果是硬件就调用QComOMXPlugin的makeComponentInstance Component可以理解为一个解码器实例。 7.1 软解码器 1.根据mime name匹配kComponents数据如 { OMX.google.aac.decoder, aacdec, audio_decoder.aac }, 2. 拿到的mLibNameSuffix值为aacdec最后拼接的libName是libstagefright_soft_aacdec.so 3. 从system/lib目录下加载libstagefright_soft_aacdec.so库 4. 调用其对应的createSoftOMXComponent函数创建SoftOMXComponent // frameworks\av\media\libstagefright\omx\SoftOMXComponent.cpp 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) {// 1.根据name匹配kComponents数据// 如 { OMX.google.aac.decoder, aacdec, audio_decoder.aac },if (strcmp(name, kComponents[i].mName)) {continue;}// 2. 拿到的mLibNameSuffix值为aacdec最后拼接的libName是libstagefright_soft_aacdec.soAString libName libstagefright_soft_;libName.append(kComponents[i].mLibNameSuffix);libName.append(.so);// RTLD_NODELETE means we keep the shared library around forever.// this eliminates thrashing during sequences like loading soundpools.// It also leaves the rest of the logic around the dlopen()/dlclose()// calls in this file unchanged.//// Implications of the change:// -- the codec process (where this happens) will have a slightly larger// long-term memory footprint as it accumulates the loaded shared libraries.// This is expected to be a small amount of memory.// -- plugin codecs can no longer (and never should have) depend on a// free reset of any static data as the library would have crossed// a dlclose/dlopen cycle.//// 3. 从system/lib目录下加载libstagefright_soft_aacdec.so库void *libHandle dlopen(libName.c_str(), RTLD_NOW|RTLD_NODELETE);if (libHandle NULL) {ALOGE(unable to dlopen %s: %s, libName.c_str(), dlerror());return OMX_ErrorComponentNotFound;}typedef SoftOMXComponent *(*CreateSoftOMXComponentFunc)(const char *, const OMX_CALLBACKTYPE *,OMX_PTR, OMX_COMPONENTTYPE **);CreateSoftOMXComponentFunc createSoftOMXComponent (CreateSoftOMXComponentFunc)dlsym(libHandle,_Z22createSoftOMXComponentPKcPK16OMX_CALLBACKTYPEPvPP17OMX_COMPONENTTYPE);if (createSoftOMXComponent NULL) {dlclose(libHandle);libHandle NULL;return OMX_ErrorComponentNotFound;}// 4. 创建对应的SoftOMXComponentspSoftOMXComponent 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; } SoftOmxPlugin是google提供的原生的一套编解码器插件 即通常说的软解硬解中的软解。它支持市面上常用的音视频格式软解码支持的格式 // frameworks\av\media\libstagefright\omx\SoftOMXPlugin.cpp static const struct {const char *mName;const char *mLibNameSuffix;const char *mRole;} kComponents[] {// two choices for aac decoding.// configurable in media/libstagefright/data/media_codecs_google_audio.xml// default implementation{ OMX.google.aac.decoder, aacdec, audio_decoder.aac },// alternate implementation{ OMX.google.xaac.decoder, xaacdec, 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, avcdec, video_decoder.avc },{ OMX.google.h264.encoder, avcenc, video_encoder.avc },{ OMX.google.hevc.decoder, hevcdec, video_decoder.hevc },{ OMX.google.g711.alaw.decoder, g711dec, audio_decoder.g711alaw },{ OMX.google.g711.mlaw.decoder, g711dec, audio_decoder.g711mlaw },{ OMX.google.mpeg2.decoder, mpeg2dec, video_decoder.mpeg2 },{ 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.opus.decoder, opusdec, audio_decoder.opus },{ OMX.google.vp8.decoder, vpxdec, video_decoder.vp8 },{ OMX.google.vp9.decoder, vpxdec, video_decoder.vp9 },{ OMX.google.vp8.encoder, vpxenc, video_encoder.vp8 },{ OMX.google.vp9.encoder, vpxenc, video_encoder.vp9 },{ OMX.google.raw.decoder, rawdec, audio_decoder.raw },{ OMX.google.flac.decoder, flacdec, audio_decoder.flac },{ OMX.google.flac.encoder, flacenc, audio_encoder.flac },{ OMX.google.gsm.decoder, gsmdec, audio_decoder.gsm }, #ifdef QTI_FLAC_DECODER{ OMX.qti.audio.decoder.flac, qtiflacdec, audio_decoder.flac }, #endif }; 软解码器代码目录 frameworks\av\media\libstagefright\codecs编译会生成对应的so库 车机内软解码so所在的目录 软解码器的实现 是基于“OpenMax IL的标准接口”进行实际硬解码器也是如此。 以libstagefright_soft_aacdec为例子 libstagefright_soft_aacdec.so主体是SoftAAC2.cpp和SoftAAC2.h所以dlsym返回的createSoftOMXComponent值如下 //frameworks\av\media\libstagefright\codecs\aacdec\SoftAAC2.cpp android::SoftOMXComponent *createSoftOMXComponent(const char *name, const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData, OMX_COMPONENTTYPE **component) {return new android::SoftAAC2(name, callbacks, appData, component); } SoftAAC2继承自SimpleSoftOMXComponent //frameworks\av\media\libstagefright\codecs\aacdec\SoftAAC2.cpp SoftAAC2::SoftAAC2(const char *name,const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData,OMX_COMPONENTTYPE **component): SimpleSoftOMXComponent(name, callbacks, appData, component),mAACDecoder(NULL),mStreamInfo(NULL),mIsADTS(false),mInputBufferCount(0),mOutputBufferCount(0),mSignalledError(false),mLastInHeader(NULL),mLastHeaderTimeUs(-1),mNextOutBufferTimeUs(0),mOutputPortSettingsChange(NONE) {initPorts();CHECK_EQ(initDecoder(), (status_t)OK); } SimpleSoftOMXComponent实现OpenMax IL的标准接口例如sendCommand、setParameter //frameworks\av\media\stagefright\omx\SimpleSoftOMXComponent.cpp SimpleSoftOMXComponent::SimpleSoftOMXComponent(const char *name,const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData,OMX_COMPONENTTYPE **component): SoftOMXComponent(name, callbacks, appData, component),mLooper(new ALooper),mHandler(new AHandlerReflectorSimpleSoftOMXComponent(this)),mState(OMX_StateLoaded),mTargetState(OMX_StateLoaded) {mLooper-setName(name);mLooper-registerHandler(mHandler);mLooper-start(false, // runOnCallingThreadfalse, // canCallJavaANDROID_PRIORITY_VIDEO); }SoftOMXComponent里有对OpenMax接口的 // frameworks\av\media\stagefright\omx\SoftOMXComponent.cpp // OMX_Component.h为 OpenMax IL version 1.1.2的接口头文件 #include OMX_Component.h SoftOMXComponent::SoftOMXComponent(const char *name,const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData,OMX_COMPONENTTYPE **component): mName(name),mCallbacks(callbacks),mComponent(new OMX_COMPONENTTYPE),mLibHandle(NULL) {mComponent-nSize sizeof(*mComponent);mComponent-nVersion.s.nVersionMajor 1;mComponent-nVersion.s.nVersionMinor 0;mComponent-nVersion.s.nRevision 0;mComponent-nVersion.s.nStep 0;mComponent-pComponentPrivate this;mComponent-pApplicationPrivate appData; 。。。*component mComponent; }7.2 硬解码器 调用mGetHandle函数指针而该函数指针是在该类构造时初始化。 //hardware\qcom\media\libstagefrighthw\QComOMXPlugin.cpp OMX_ERRORTYPE QComOMXPlugin::makeComponentInstance(const char *name,const OMX_CALLBACKTYPE *callbacks,OMX_PTR appData,OMX_COMPONENTTYPE **component) {if (mLibHandle NULL) {return OMX_ErrorUndefined;}return (*mGetHandle)(reinterpret_castOMX_HANDLETYPE *(component),const_castchar *(name),appData, const_castOMX_CALLBACKTYPE *(callbacks)); } 可以看到原来mGetHandle就是libOmxCore.so库中的OMX_GetHandle函数 //hardware\qcom\media\libstagefrighthw\QComOMXPlugin.cpp QComOMXPlugin::QComOMXPlugin(): mLibHandle(dlopen(libOmxCore.so, RTLD_NOW)),mInit(NULL),mDeinit(NULL),mComponentNameEnum(NULL),mGetHandle(NULL),mFreeHandle(NULL),mGetRolesOfComponentHandle(NULL) {if (mLibHandle ! NULL) {mInit (InitFunc)dlsym(mLibHandle, OMX_Init);mDeinit (DeinitFunc)dlsym(mLibHandle, OMX_Deinit);mComponentNameEnum (ComponentNameEnumFunc)dlsym(mLibHandle, OMX_ComponentNameEnum);mGetHandle (GetHandleFunc)dlsym(mLibHandle, OMX_GetHandle);mFreeHandle (FreeHandleFunc)dlsym(mLibHandle, OMX_FreeHandle);mGetRolesOfComponentHandle (GetRolesOfComponentFunc)dlsym(mLibHandle, OMX_GetRolesOfComponent);if (!mInit || !mDeinit || !mComponentNameEnum || !mGetHandle ||!mFreeHandle || !mGetRolesOfComponentHandle) {dlclose(mLibHandle);mLibHandle NULL;} else(*mInit)();} }OMX_GetHandle函数 1、如果是avc解码器加载libOmxVideoDSMode.so库,判断是否有dsmode 2、视频预处理开启情况需要加载vpp库 3、动态加载对应的编解码so //hardware\qcom\media\mm-core\src\common\qc_omx_core.c // libOmxCore.so OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(OMX_OUT OMX_HANDLETYPE* handle,OMX_IN OMX_STRING componentName,OMX_IN OMX_PTR appData,OMX_IN OMX_CALLBACKTYPE* callBacks) {OMX_ERRORTYPE eRet OMX_ErrorNone;int cmp_index -1;int hnd_index -1;int vpp_cmp_index -1;DEBUG_PRINT(OMXCORE API : GetHandle %p %s %p\n, handle,componentName,appData);pthread_mutex_lock(lock_core);if(handle){*handle NULL;char optComponentName[OMX_MAX_STRINGNAME_SIZE];strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);// 如果是avc解码器加载libOmxVideoDSMode.so库,判断是否有dsmodeif(strstr(componentName, avc) strstr(componentName, decoder)){void *libhandle dlopen(libOmxVideoDSMode.so, RTLD_NOW);if(libhandle){int (*fn_ptr)() dlsym(libhandle, isDSModeActive);dlclose(libhandle);}else{DEBUG_PRINT_ERROR(Failed to load dsmode library);}}if(cmp_index 0){cmp_index get_cmp_index(componentName);strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);}if(cmp_index 0){char value[PROPERTY_VALUE_MAX];DEBUG_PRINT(getting fn pointer\n);// Load VPP omx component for decoder if vpp// property is enabled// 视频预处理开启情况需要加载vppif ((property_get(vendor.media.vpp.enable, value, NULL)) (!strcmp(1, value) || !strcmp(true, value))) {DEBUG_PRINT(VPP property is enabled);if (!strcmp(core[cmp_index].so_lib_name, libOmxVdec.so)|| !strcmp(core[cmp_index].so_lib_name, libOmxSwVdec.so)) {vpp_cmp_index get_cmp_index(OMX.qti.vdec.vpp);if (vpp_cmp_index 0) {DEBUG_PRINT_ERROR(Unable to find VPP OMX lib in registry );} else {DEBUG_PRINT(Loading vpp for vdec);cmp_index vpp_cmp_index;}}}// dynamically load the socore[cmp_index].fn_ptr omx_core_load_cmp_library(core[cmp_index].so_lib_name,core[cmp_index].so_lib_handle);。。。。 }加载对应的SO库 // /hardware\qcom\media\mm-core\src\common\qc_omx_core.c static create_qc_omx_component omx_core_load_cmp_library(char *libname, void **handle_ptr) {create_qc_omx_component fn_ptr NULL;if(handle_ptr){DEBUG_PRINT(Dynamically Loading the library : %s\n,libname);if (!strcmp(libname, libOmxVpp.so))*handle_ptr dlopen(libname, RTLD_NOW|RTLD_GLOBAL);else*handle_ptr dlopen(libname, RTLD_NOW);if(*handle_ptr){fn_ptr dlsym(*handle_ptr, get_omx_component_factory_fn);if(fn_ptr NULL){DEBUG_PRINT(Error: Library %s incompatible as QCOM OMX component loader - %s\n,libname, dlerror());*handle_ptr NULL;}}else{DEBUG_PRINT(Error: Couldnt load %s: %s\n,libname,dlerror());}}return fn_ptr; }高通平台支持的硬解码器 注意里边有一些是软解码包含Sw字符的 omx_core_cb_type core[] {//Common entriesOMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.avc, libOmxVdec.so, video_decoder.avc),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.avc.secure, libOmxVdec.so, video_decoder.avc),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.mpeg2, libOmxVdec.so, video_decoder.mpeg2),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.mpeg2.secure, libOmxVdec.so, video_decoder.mpeg2),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.hevc, libOmxVdec.so, video_decoder.hevc),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.hevc.secure, libOmxVdec.so, video_decoder.hevc),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.vp8, libOmxVdec.so, video_decoder.vp8),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.vp9, libOmxVdec.so, video_decoder.vp9),OMX_REGISTRY_ENTRY(OMX.qcom.video.decoder.vp9.secure, libOmxVdec.so, video_decoder.vp9),OMX_REGISTRY_ENTRY(OMX.qti.video.decoder.mpeg4sw, libOmxSwVdec.so, video_decoder.mpeg4),OMX_REGISTRY_ENTRY(OMX.qti.video.decoder.divxsw, libOmxSwVdec.so, video_decoder.divx),OMX_REGISTRY_ENTRY(OMX.qti.video.decoder.divx4sw, libOmxSwVdec.so, DIVX4_MIME),OMX_REGISTRY_ENTRY(OMX.qti.video.decoder.h263sw, libOmxSwVdec.so, video_decoder.h263),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.mpeg4sw, libOmxSwVencMpeg4.so, video_encoder.mpeg4),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.h263sw, libOmxSwVencMpeg4.so, video_encoder.h263),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.avc, libOmxVenc.so, video_encoder.avc),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.avc.secure, libOmxVenc.so, video_encoder.avc),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.vp8, libOmxVenc.so, video_encoder.vp8),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.hevc, libOmxVenc.so, video_encoder.hevc),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.hevc.secure, libOmxVenc.so, video_encoder.hevc),OMX_REGISTRY_ENTRY(OMX.qcom.video.encoder.heic, libOmxVenc.so, image_encoder.heic),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.Qcelp13, libOmxQcelp13Dec.so, audio_decoder.Qcelp13),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.evrc, libOmxEvrcDec.so, audio_decoder.evrc),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.wma, libOmxWmaDec.so, audio_decoder.wma),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.wma10Pro, libOmxWmaDec.so, audio_decoder.wma),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.wmaLossLess, libOmxWmaDec.so, audio_decoder.wma),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.amrwbplus, libOmxAmrwbplusDec.so, audio_decoder.awbplus),OMX_REGISTRY_ENTRY(OMX.qcom.audio.decoder.alac, libOmxAlacDec.so, audio_decoder.alac),OMX_REGISTRY_ENTRY(OMX.qti.audio.decoder.alac.sw, libOmxAlacDecSw.so, audio_decoder.alac),。。。。。 }; 硬解码器的实现位置 Audio encodehardware\qcom\audio\mm-audio Audio decode\vendor\qcom\proprietary\mm-audio\omx Video encode/decode: hardware\qcom\media\mm-video-v4l2 对比Audio每个解码器均有一个soVideo采用v4l2框架实现只有libOmxVenc.solibOmxSwVencMpeg4libOmxSwVdeclibOmxVdec.so 这4个库。 部分缩写含义 1.VPP 视频预处理 2.avc 就是H264 3.v4l2 是:video for linux version2,是Linux内核中关于视频设备的内核驱动框架,为上层的访问底层的视频设备提供了统一的接口.凡是内核中的子系统都有抽象底层硬件的差异,为上层提供统一的接口和提取出公共代码避免代码冗余等好处.
http://www.hkea.cn/news/14524779/

相关文章:

  • 制作钓鱼网站的费用建网站难吗?
  • 微网站做下载链接水滴保险官方网站
  • 建设网站找什么条件苏州交通网站建设
  • 企业网站建立哪做网站预算
  • 汉川网站推广服务房产备案价格查询官网
  • 上海建材网站宝塔windows建设网站
  • 如何在网站源码做授权科技公司取名大全
  • 怎么建设一个漫画网站石家庄网站改版
  • 万网如何上传静态网站百盛联合建设集团有限公司网站
  • 什么网络营销百度快照优化seo
  • 自己写代码做网站要什么技术网站有没有做网站地图怎么看
  • 深圳高端品牌网站建设百度搜索收录提交入口
  • 暖通设计网站推荐泉州茶叶网站建设
  • 建设网站上传软件wordpress免费主题推荐
  • 手机制作ppt百度搜索引擎优化
  • 安徽省建设厅焊工证查询网站网站建设 万网
  • 亚马逊网站网址是多少建设好网站怎么付费推广
  • 网站建设的常用技术有哪些做微信公众号页面的网站
  • 公司设计网站需要多久微信网站平台建设
  • 基于ASP与Access数据库的网站开发上海高端网站建设公
  • 订阅号做微网站宽屏网站设计
  • 企业网站改版升级叫别人做网站后怎么更改密码
  • 绥化建设局网站php做的网站
  • 粘贴以下代码到网站首页代码的与标签之间龙华营销型网站建设公司
  • 网站建设运营的灵魂是网站建立者
  • 小型购物网站开发费用广州搜狗快速排名原
  • 亚购物车功能网站怎么做的网站建设用什么网站好一点
  • 免费制作二维码网站dw做网站首页代码
  • 建设银行网站怎么打印明细厦门网站推广找谁
  • 中国建设教育协会网站培训中心吉林响应式网站建设