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

重庆网站平台建设公司组织架构图怎么设计

重庆网站平台建设,公司组织架构图怎么设计,南京做网站的额,网站路径这一节开始我们就来学习 ACodec 的实现 1、创建 ACodec ACodec 是在 MediaCodec 中创建的#xff0c;这里先贴出创建部分的代码#xff1a; mCodec mGetCodecBase(name, owner);if (mCodec NULL) {ALOGE(Getting codec base with name %s (owner%s) failed, n… 这一节开始我们就来学习 ACodec 的实现 1、创建 ACodec ACodec 是在 MediaCodec 中创建的这里先贴出创建部分的代码 mCodec mGetCodecBase(name, owner);if (mCodec NULL) {ALOGE(Getting codec base with name %s (owner%s) failed, name.c_str(), owner);return NAME_NOT_FOUND;}if (mDomain DOMAIN_VIDEO) {// video codec needs dedicated looperif (mCodecLooper NULL) {status_t err OK;mCodecLooper new ALooper;mCodecLooper-setName(CodecLooper);err mCodecLooper-start(false, false, ANDROID_PRIORITY_AUDIO);if (OK ! err) {ALOGE(Codec Looper failed to start);return err;}}mCodecLooper-registerHandler(mCodec);} else {mLooper-registerHandler(mCodec);}从前面的学习我们可以知道MediaCodec 使用的是异步消息处理的机制创建MediaCodec 时需要传入一个 ALooper 对象用于处理发送给 MediaCodec 的消息。同样的 ACodec 也是用的异步消息处理机制它也需要一个 ALooper这个 ALooper 应该由上一级 MediaCodec 传递从上面的代码我们可以知道如果创建的是音频解码器那么 ACodec 将会复用 MediaCodec 的 ALooper也就是它们的消息处理会在相同线程当中如果是视频解码器那么 MediaCodec 会创建一个专门的 ALooper 给 ACodec 使用ACodec 和 MediaCodec 的消息处理在不同线程中。 ACodec::ACodec(): mSampleRate(0),mNodeGeneration(0),mUsingNativeWindow(false),mNativeWindowUsageBits(0),mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),mIsVideo(false),mIsImage(false),mIsEncoder(false),mFatalError(false),mShutdownInProgress(false),mExplicitShutdown(false),mIsLegacyVP9Decoder(false),mIsStreamCorruptFree(false),mIsLowLatency(false),mEncoderDelay(0),mEncoderPadding(0),mRotationDegrees(0),mChannelMaskPresent(false),mChannelMask(0),mDequeueCounter(0),mMetadataBuffersToSubmit(0),mNumUndequeuedBuffers(0),mRepeatFrameDelayUs(-1LL),mMaxPtsGapUs(0LL),mMaxFps(-1),mFps(-1.0),mCaptureFps(-1.0),mCreateInputBuffersSuspended(false),mTunneled(false),mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),mDescribeHDR10PlusInfoIndex((OMX_INDEXTYPE)0),mStateGeneration(0),mVendorExtensionsStatus(kExtensionsUnchecked) {memset(mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));mUninitializedState new UninitializedState(this);mLoadedState new LoadedState(this);mLoadedToIdleState new LoadedToIdleState(this);mIdleToExecutingState new IdleToExecutingState(this);mExecutingState new ExecutingState(this);mOutputPortSettingsChangedState new OutputPortSettingsChangedState(this);mExecutingToIdleState new ExecutingToIdleState(this);mIdleToLoadedState new IdleToLoadedState(this);mFlushingState new FlushingState(this);mPortEOS[kPortIndexInput] mPortEOS[kPortIndexOutput] false;mInputEOSResult OK;mPortMode[kPortIndexInput] IOMX::kPortModePresetByteBuffer;mPortMode[kPortIndexOutput] IOMX::kPortModePresetByteBuffer;memset(mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));changeState(mUninitializedState); }ACodec 的构造函数主要是初始化了成员对象实例化了各个状态对象并且将状态切换到了 UninitializedState这时候我们就要去查看它的 stateEntered 方法 void ACodec::UninitializedState::stateEntered() {ALOGV(Now uninitialized);if (mDeathNotifier ! NULL) {if (mCodec-mOMXNode ! NULL) {auto tOmxNode mCodec-mOMXNode-getHalInterfaceIOmxNode();if (tOmxNode) {tOmxNode-unlinkToDeath(mDeathNotifier);}}mDeathNotifier.clear();}mCodec-mUsingNativeWindow false;mCodec-mNativeWindow.clear();mCodec-mNativeWindowUsageBits 0;mCodec-mOMX.clear();mCodec-mOMXNode.clear();mCodec-mFlags 0;mCodec-mPortMode[kPortIndexInput] IOMX::kPortModePresetByteBuffer;mCodec-mPortMode[kPortIndexOutput] IOMX::kPortModePresetByteBuffer;mCodec-mConverter[0].clear();mCodec-mConverter[1].clear();mCodec-mComponentName.clear(); }UninitializedState::stateEntered 主要是将与 OMX 组件相关的成员对象重置初始化。 2、initiateAllocateComponent 创建 MediaCodec 时ACodec 也就被创建了随后就会调用 initiateAllocateComponent 方法创建 OMX 组件ACodec 创建之后处在 UninitializedState所以消息最终在该状态中被处理 bool ACodec::UninitializedState::onAllocateComponent(const spAMessage msg) {ALOGV(onAllocateComponent);CHECK(mCodec-mOMXNode NULL);mCodec-mFatalError false;// 创建 Callback 消息并且设置好 notifyspAMessage notify new AMessage(kWhatOMXMessageList, mCodec);// notify 的 generation 为 nodegeneration 1这是因为进入 loaded 状态后mNodeGeneration 会 1notify-setInt32(generation, mCodec-mNodeGeneration 1);// 需要检查 codecInfo 才能创建 OMXNodespRefBase obj;CHECK(msg-findObject(codecInfo, obj));spMediaCodecInfo info (MediaCodecInfo *)obj.get();if (info nullptr) {ALOGE(Unexpected nullptr for codec information);mCodec-signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);return false;}AString owner (info-getOwnerName() nullptr) ? default : info-getOwnerName();AString componentName;CHECK(msg-findString(componentName, componentName));// 创建 callback 对象spCodecObserver observer new CodecObserver(notify);spIOMX omx;spIOMXNode omxNode;status_t err NAME_NOT_FOUND;// 创建 OMXClientOMXClient client;// 获取 IOmx 服务if (client.connect(owner.c_str()) ! OK) {mCodec-signalError(OMX_ErrorUndefined, NO_INIT);return false;}// 将获取到的 IOmx 服务代理封装为 Legacy 模式omx client.interface();pid_t tid gettid();int prevPriority androidGetThreadPriority(tid);androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);// 创建 IOmxNode 服务代理并且封装为 IOMXNodeerr omx-allocateNode(componentName.c_str(), observer, omxNode);androidSetThreadPriority(tid, prevPriority);mDeathNotifier new DeathNotifier(new AMessage(kWhatOMXDied, mCodec));auto tOmxNode omxNode-getHalInterfaceIOmxNode();if (tOmxNode !tOmxNode-linkToDeath(mDeathNotifier, 0)) {mDeathNotifier.clear();}// 记录新的状态下的 ACodec 状态mCodec-mNodeGeneration;mCodec-mComponentName componentName;mCodec-mRenderTracker.setComponentName(componentName);mCodec-mFlags 0;// 记录是否创建的是 secure 组件if (componentName.endsWith(.secure)) {mCodec-mFlags | kFlagIsSecure;mCodec-mFlags | kFlagIsGrallocUsageProtected;mCodec-mFlags | kFlagPushBlankBuffersToNativeWindowOnShutdown;}mCodec-mOMX omx;mCodec-mOMXNode omxNode;// 调用 callback 通知 MediaCodec 完成阻塞调用mCodec-mCallback-onComponentAllocated(mCodec-mComponentName.c_str());// 切换状态到 LoadedStatemCodec-changeState(mCodec-mLoadedState);return true; }这里涉及的内容比较多 创建 notify 对象并且传入到 CodecObserver 对象中CodecObserver 会把 OMX 发送回来的消息重新封装再通过 notify message 转发给 ACodec最后在不同状态中处理。这里有个是 mNodeGeneration 用于检查 OMX 消息及时性的但是实际并未启用。这里有一点需要注意这些 State 状态类都是 ACodec 的内部类C11之后内部类可以访问外部类的私有成员以及私有方法所以虽然这些类并不是 ACodec 的友元但是同样是可以调用 ACodec 所有方法的。创建 OMXNode 之前会先检查从 MediaCodec 层获取到的 MediaCodecInfo如果没有这个信息将会报错这里算是一个双重检查防止强行越过 MediaCodecList 的检查调用 OMXClient 的方法获取 IOmx 的代理并用该代理创建 IOmxNode 代理传入参数为组件名称如果组件名称以 secure 结尾那么说明需要创建安全组件并且记录到 ACodec mFlags 成员中调用 onComponentAllocated 通知 MediaCodec 完成阻塞调用切换状态到 LoadedState 在看 LoadedState 的 stateEntered 方法之前我们要先看下 BaseState 给出的 stateExited 方法这里用到了 mStateGeneration用来记录 ACodec 当前的状态变化在处理消息时如果传来的消息 generation 不等于当前的generation说明状态机发生错误这和之前看到的部分是不一样的具体什么情况会出现不一样我们后续再做了解。 void ACodec::BaseState::stateExited() {mCodec-mStateGeneration; }从上面的代码我们可以知道每次状态切换mStateGeneration数都会加 1 。 接下来看 LoadedState 的 stateEntered void ACodec::LoadedState::stateEntered() {ALOGV([%s] Now Loaded, mCodec-mComponentName.c_str());mCodec-mPortEOS[kPortIndexInput] mCodec-mPortEOS[kPortIndexOutput] false;mCodec-mInputEOSResult OK;mCodec-mDequeueCounter 0;mCodec-mMetadataBuffersToSubmit 0;mCodec-mRepeatFrameDelayUs -1LL;mCodec-mInputFormat.clear();mCodec-mOutputFormat.clear();mCodec-mBaseOutputFormat.clear();mCodec-mGraphicBufferSource.clear();if (mCodec-mShutdownInProgress) {bool keepComponentAllocated mCodec-mKeepComponentAllocated;mCodec-mShutdownInProgress false;mCodec-mKeepComponentAllocated false;onShutdown(keepComponentAllocated);}mCodec-mExplicitShutdown false;mCodec-processDeferredMessages(); }LoadedState::stateEntered 会对编解码过程中记录信息的成员变量进行重置后面是关于 shutdown 的处理流程这里暂时不看。 到这里我们先做一个小结MediaCodec 创建完成后ACodec 最终会进入到 LoadedState这个状态代表了内部的 OMX 组件已经创建完成UninitializedState 则表示OMX组件还未创建或者是已经销毁的状态。 3、initiateConfigureComponent 组件创建完成后就要开始配置组件了这时候状态在 LoadedState所以我们去这个状态下找对应的处理 bool ACodec::LoadedState::onConfigureComponent(const spAMessage msg) {ALOGV(onConfigureComponent);CHECK(mCodec-mOMXNode ! NULL);status_t err OK;// 检查 mime type调用 configureCodec 方法AString mime;if (!msg-findString(mime, mime)) {err BAD_VALUE;} else {err mCodec-configureCodec(mime.c_str(), msg);}if (err ! OK) {ALOGE([%s] configureCodec returning error %d,mCodec-mComponentName.c_str(), err);mCodec-signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));return false;}// 调用 CallbackmCodec-mCallback-onComponentConfigured(mCodec-mInputFormat, mCodec-mOutputFormat);return true; }onConfigureComponent 会先去检查 mime type如果没有将会返回error如果有则会再调用 ACodec 的 configureCodec 方法做组件的配置这个方法会比较复杂我们留到下一节来讲最后会调用 callback 完成 MediaCodec 阻塞调用同时把 input format 和 output format 回传给 MediaCodec需要注意的是这里的 output format 并不一定是准确的可能是 omx 设定的默认值在decoder解出相关序列信息之后会把真正的 output format 再回传回来。
http://www.zqtcl.cn/news/739850/

相关文章:

  • 淘宝客网站开发视频新手 网站建设 书籍
  • 在哪个网站做旅游攻略好做推广便宜的网站
  • 濮阳做网站推广做网站为什么要建站点
  • 摄影网站建设需求分析wordpress一键关注
  • 做学历的网站什么是短视频营销
  • 网站线上推广方式广告海外推广
  • 免费网站注册申请海口网站seo
  • ppt免费下载雷锋网站WordPress5分钟建站
  • 商店网站制作做签名照的网站
  • 自己制作一个网站广州自助网站制作
  • 个人网站吗wordpress超精简主题
  • 手机版免费申请微网站wordpress 跳转链接
  • 网站建设与管理好吗广州白云最新消息
  • 织梦动漫网站模版wordpress 页面文章列表
  • 东莞做网站沃德长沙市网站开发
  • 哪些网站做的最好厦门网站建设网站
  • 网站安全事件应急处置机制建设类似百度的网站
  • 内蒙古知名网站建设网站测速工具
  • 怎样建立网站赚钱怎么登录住建局官网
  • 建站自学网页转向功能网站
  • 网站都有什么费用做酒店网站有哪些目录
  • 本地郑州网站建设东莞网站优化中易
  • 动态域名可以建网站德州公司做网站
  • 深圳建设银行官方网站wordpress 添加qq
  • 甘肃第九建设集团公司网站网站对企业的好处
  • 论坛网站建设规划书公司网站建设与设计制作
  • 做棋牌游戏网站犯法吗如何进行搜索引擎的优化
  • 常见的网站首页布局有哪几种陈光锋网站运营推广新动向
  • 手机网站活动策划方案开一个设计公司
  • 宝塔建设网站教程visual studio 2010 网站开发教程