余姚网站建设在哪里,东莞网站建设收费,厦门制作网页公司,前端开发培训机构济南七里河系列文章的目的是什么#xff1f;
粗略#xff1a;
解码需要哪些基础的服务#xff1f;标准解码的调用流程#xff1f;各个流程的作用是什么#xff1f;解码框架的层次#xff1f;各个层次的作用#xff1f;
细化#xff1a;
解码参数的配置#xff1f;解码输入数…系列文章的目的是什么
粗略
解码需要哪些基础的服务标准解码的调用流程各个流程的作用是什么解码框架的层次各个层次的作用
细化
解码参数的配置解码输入数据包的流转?解码输出帧内存的申请和管理 文章目录 HIDL上游HIDL 下游HIDL接口基础的codec2 服务 首先从MediaCodec 到具体的解码Component 梳理出一条路径然后在具体理解里面的细节。 本文就从MediaCodec出发 理解Android 解码框架的各个层次 总的来说可以分为三个部分
HIDL 层之上这一层主要是对外部的应用提供接口 并提供输入和输出buffer的管理流程的控制等等。HIDL 层之下提供创建具体的解码组件解码组件的实现对数据包解码 并返会解码后的图像。codec service提供创建解码组件的服务HIDL层之上通过这个服务调用到HIDL 之下。
HIDL上游
如图所示 上游主要包含了以下这些部分。
MediaCodec
MediaCodec 首先会创建出ccodec后续的操作都是通过ccodec 这个codecbase进行调用这里是为了兼容ACodec 和 Codec2的情况。同时也通过这个ccodec获取codec创建的CCodecBufferChannel。
创建codecbase 这里就是CCodec 在MediaCodec 这一级是调用到CCodec。将创建好的ccodec 注册到looper 中。这个looper是应用层设置到mediacodec中的。注册CodecCallback到ccodec注册BufferCallback到CCodecBufferChannel。
CCodec 创建 CCodecBufferChannel 和 CCodecConfig。通过codec2的service 获取componentStore 并通过componentStore来创建解码器的component。这里面主要是通过codec2client 这个类来完成的。将创建好的组件设置到CCodecBufferChannel以便后续调用。回调一些错误等信息到MediaCodec。
codec2client
和下游HIDL进行交互 的客户端 主要是调用IComponetStore 和IComponet的接口。
查看codec2client是如何创建出来的
std::shared_ptrCodec2Client client _CreateFromIndex(index);std::shared_ptrCodec2Client Codec2Client::_CreateFromIndex(size_t index) {std::string const name GetServiceNames()[index];LOG(WARNING) Creating a Codec2 client to service \ name \;spBase baseStore Base::getService(name);CHECK(baseStore) Codec2 service \ name \ inaccessible for unknown reasons.;LOG(WARNING) Client to Codec2 service \ name \ created;return std::make_sharedCodec2Client(baseStore, index);
}
GetServiceNames()。 通过Manifest来获取hal的名字
Manifest定义了HAL的名字”android.hardware.media.c2”, hidl传输方式”hwbinder”,interface的名字”IComponentStore”,instance的名字”default”。而GetServiceNames也是通过这些信息去定位到具体的HAL。 Base::getService(name) 其中Base是IComponentStore类型也就是service 端。通过名字获取到service端的服务。 然后赋值到baseStore。 接着用这个baseStore初始化创建codec2client也就是mBase 是baseStore。 std::make_sharedCodec2Client(baseStore, index) 所以说codecclinet 调用的接口会调用到service 端的ComponentStore。
CCodecBufferChannel管理输入和输出buffer的地方当时有输入和输出buffer的时候通过回调上报到MediaCodec 随后MediaCodec上报到应用
HIDL 下游
下游包括两个方面 一个是componentStore 另一个是Componet componetStore 调用关系以createComponent 为例。调用流程如下 codec2client-----(HIDL)compometStore获取真正的store------C2PlatformComponentStore(或者vendor自己实现的componetstore ----- C2SoftAvcDecFactory . 在HIDL 上层 codec2clinet 获取componetStore服务的时候 会调用下面的函数返回C2PlatformComponentStore。而后调用createCompoent就调用到这个类当中。 在这个类的创建componet中会根据具体的名字找到componet调用其的createComponent比如avc的C2SoftAvcDecFactory 的 createComponent
c2store.cpp
std::shared_ptrC2ComponentStore GetCodec2PlatformComponentStore() {static std::mutex mutex;static std::weak_ptrC2ComponentStore platformStore;std::lock_guardstd::mutex lock(mutex);std::shared_ptrC2ComponentStore store platformStore.lock();if (store nullptr) {store std::make_sharedC2PlatformComponentStore();platformStore store;}return store;
}c2_status_t C2PlatformComponentStore::createComponent(C2String name, std::shared_ptrC2Component *const component) {// This method SHALL return within 100ms.component-reset();std::shared_ptrComponentModule module;c2_status_t res findComponent(name, module);if (res C2_OK) {// TODO: get a unique node IDres module-createComponent(0, component);}return res;
}component compont的调用 也是通过HIDL的接口调用到 SimpleC2Component 然后 SimpleC2Component 调用具体的avc、hevc等等的componet。 SimpleC2Component 是每个compont的基类。 以queue接口为例 HIDL上层的codec2bufferChannel 会调用具体解码组件的queue接口 将待解码的数据包放入的具体的component中 首先调用到Codec2Client 这个调用componet的queue然后调用到SimpleC2Component的queue_nb queue_nb发送消息 在消息处理线程中调用子类的process函数。 c2_status_t Codec2Client::Component::queue(std::liststd::unique_ptrC2Work* const items) {ReturnStatus transStatus mBase1_0-queue(workBundle);
}// Methods from ::android::hardware::media::c2::V1_1::IComponent
ReturnStatus Component::queue(const WorkBundle workBundle) {return static_castStatus(mComponent-queue_nb(c2works));
}c2_status_t SimpleC2Component::queue_nb(std::liststd::unique_ptrC2Work * const items) {{if (queueWasEmpty) {(new AMessage(WorkHandler::kWhatProcess, mHandler))-post();}
}bool SimpleC2Component::processQueue() {}process(work, mOutputBlockPool);
}HIDL接口 IComponentStore C2ComponentStore这定义了各种接口 codec2client/C2PlatformComponentStore都继承他并实现里面的接口。 有哪些接口 主要是 createComponent 创建各种编解码器组件 createInterface创建定义各种组件的配置 listComponents列出所有的组件。 IComponent 主要定义了对组件的各种操作 实际可以分为数据流和控制流 数据流包括配置编码输入surface解码输出surface输入解码包清空编解码数据。控制流启动组件、退出组件、释放组件等等操作 connectToInputSurface使用surface启动组件 queue: 将work 放到组件中。 drain: 清空组件不是堵塞运行的。 setOutputSurface: 设置输出的surface。 start: 启动组件。 stop: stop组件。
基础的codec2 服务
frameworks\av\media\codec2\hidl\services\vendor.cpp 在这里面的rc 中会启动一个android.hardware.media.c21.2-default-service 这个main函数中实现的是一个componentStore。 store new utils::ComponentStore(std::make_sharedStoreImpl());constexpr char const* serviceName default;if (store-registerAsService(serviceName) ! OK) {LOG(ERROR) Cannot register Codec2s IComponentStore service with instance name \ serviceName \.;} else {LOG(DEBUG) Codec2s IComponentStore service registered. Instance name: \ serviceName \.;}