更多内容请访问:鸿蒙技术社区,与华为官方共建https://harmonyos.51cto.com按照上一章的代码,继续往下看,将创建的StreamInfo作为参数丢给StreamOperator创建流。调用流程图1.StreamOperator::CreateStreams()创建过程实例化一个流对象,使用stremInfos中的参数信息为相关成员赋值。创建StreamTunnel对象并将StreamTunnel绑定到流。将每个创建的流对应的stremId放在streamMap_中。//drivers\peripheral\camera\hal\hdi_impl\src\stream_operator\stream_operator.cppCamRetCodeStreamOperator::CreateStreams(conststd::vector>&streamInfos){...for(autoit:streamInfos){...std::shared_ptrstream=StreamFactory::Instance().CreateShared(IStream::g_avaliableStreamType[it->intent_],it->streamId_,it->intent_,pipelineCore_,messenger_);...StreamConfigurationscg;scg.id=it->streamId_;scg.type=it->intent_;scg.width=it->width_;scg.height=it->height_;PixelFormatpf=static_cast(it->format_);scg.format=BufferAdapter::PixelFormatToCameraFormat(pf);scg.dataspace=it->datasapce_;//修复拼写错误scg.tunnelMode=it->tunneledMode_;scg.minFrameDuration=it->minFrameDuration_;scg.encodeType=it->encodeType_;RetCoderc=stream->ConfigStream(scg);...if(it->bufferQueue_!=nullptr){autotunnel=std::make_shared();CHECK_IF_PTR_NULL_RETURN_VALUE(隧道,INSUFFICIENT_RESOURCES);RetCoderc=tunnel->AttachBufferQueue(it->bufferQueue_);CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc,RC_OK,INVALID_ARGUMENT);if(stream->AttachStreamTunnel(tunnel)!=bRC_OK_){[("reattCAid=%{public}d]failed",it->streamId_);返回无效参数;}}{std::lock_guardl(streamLock_);streamMap_[stream->GetStreamId()]=流;}}returnNO_ERROR;}这里需要注意的一点是RetCoderc=tunnel->AttachBufferQueue(it->bufferQueue_);把这段代码单独贴出来看//drivers\peripheral\camera\hal\hdi_impl\src\stream_operator\stream_tunnel.cppRetCodeStreamTunnel::AttachBufferQueue(OHOS::sptr&生产者){CHECK_IF_PTR_NULL_RETURN_VALUE(生产者,RC_ERROR);bufferQueue_=OHOS::SurfaceCreateSurface)er(//AsproduBuffer的生产者使用该函数创建Surface,只能使用生产相关接口CHECK_IF_PTR_NULL_RETURN_VALUE(bufferQueue_,RC_ERROR);returnRC_OK;}该成员函数的作用就是在应用层以StreamCustomer::CreateProducer()得到的producer创建一个“consumer”对应的“generated”Surface作为参数,而StreamTunnel类就是对这个生成的Surface的功能封装。2、StreamOperator::CommitStreams()的源码有点长,去掉一些参数的校验和准备相关代码,调用如下三个函数:StreamBase::CommitStream()、StreamPipelineCore::PreConfig()、StreamPipelineCore::CreatePipeline()查看//drivers\peripheral\camera\hal\hdi_impl\src\stream_operator\stream_operator.cppCamRetCodeStreamOperator::CommitStreams(OperationModemode,conststd::shared_ptr&modeSetting){...{std::lock_guardl(streamLock_);for(autoit:streamMap_){if(it.second->CommitStream()!=RC_OK){CAMERA_LOGE("提交流[id=%{public}d]失败。",it.first);返回设备错误;}}}RetCoderc=streamPipeline_->PreConfig(modeSetting);if(rc!=RC_OK){CAMERA_LOGE("准备模式设置失败");返回设备错误;}rc=streamPipeline_->CreatePipeline(模式);如果(RC!=RC_OK){CAMERA_LOGE("创建管道失败。");返回无效参数;}DFX_LOCAL_HITRACE_END;returnNO_ERROR;}2.1StreamBase::CommitStream()按照代码LOG中的说明将流提交到管道。理解就是通过BufferManager创建并初始化BufferPool数据缓存池,为Stream对应的pipeline创建StreamMgr,让pipeline通过StreamMgr控制Stream。//drivers\peripheral\camera\hal\hdi_impl\src\stream_operator\stream_base.cppRetCodeStreamBase::CommitStream(){...HostStreamInfo信息;info.type_=static_cast(streamType_);info.streamId_=streamId_;info.width_=streamConfig_.width;info.height_=streamConfig_.height;info.format_=streamConfig_.format;info.usage_=streamConfig_.usage;info.encodeType_=streamConfig_.encodeType;if(streamConfig_.tunnelMode){BufferManager*mgr=BufferManager::GetInstance();CHECK_IF_PTR_NULL_RETURN_VALUE(mgr,RC_ERROR);如果(bufferPool_==nullptr){poolId_=mgr->GenerateBufferPoolId();CHECK_IF_EQUAL_RETURN_VALUE(poolId_,0,RC_ERROR);bufferPool_=mgr->GetBufferPool(poolId_);if(bufferPool_==nullptr){CAMERA_LOGE("stream[id:%{public}d]获取缓冲池失败。",streamId_);返回RC_ERROR;}}info.bufferPoolId_=poolId_;info.bufferCount_=GetBufferCount();RetCoderc=bufferPool_->Init(streamConfig_.width,streamConfig_.height,streamConfig_.usage,streamConfig_.format,GetBufferCount(),CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);if(rc!=RC_OK){CAMERA_LOGE("stream[id:%{public}d]初始化缓冲池失败。",streamId_);返回RC_ERROR;}}RetCoderc=hostStreamMgr_->CreateHostStream(info,[this](std::shared_ptrbuffer){HandleResult(buffer);return;});...returnRC_OK;}2.2StreamPipelineCore::PreConfig()这里的代码比较简单。根据参数信息,调用deviceManager的PreConfig接口配置如下硬件设备之前PowerUp中对deviceManager的分析已经说明了Hi3516其实是将硬件适配层相关的代码封装在so中,所以这里实际调用的只是一行代码sysObject_->PreConfig(meta,settings);//drivers\外设\相机\hal\pipeline_core\pipeline_impl\src\stream_pipeline_core.cppRetCodeStreamPipelineCore::PreConfig(constModeMeta&meta){autodeviceManager=IDeviceManager::GetInstance();CHECK_IF_PTR_NULL_RETURN_VALUE(deviceManager,RC_ERROR);std::vector设置={};std::vectorids={};context_->streamMgr_->GetStreamIds(ids);for(autoi:ids){autoinfo=context_->streamMgr_->GetStreamInfo(i);DeviceStreamSettingsetting={info.streamId_,info.bufferCount_,info.width_,info.height_,info.format_,info.usage_,static_cast(info.encodeType_)};settings.emplace_back(设置);}returndeviceManager->PreConfig(meta,settings);}2.3StreamPipelineCore::CreatePipeline()关于stategy、builder、dispatcher实现的功能代码很多。有兴趣自己看的,先说说整体的功能吧:StreamPipelineStrategy负责根据模式从对应的配置文件中创建管道。StreamPipelineBuilder负责创建Node并链接StreamPipelineDispatcher。它负责管理创建的管道。最终建立的StreamPipeline由Node(节点)组成,Node(节点)由Port(端口)组成。端口(port)分为入端口和出端口(可以有多个)。outlinkin最终构建了整个StreamPipelineDemo案例,建立了两条streamPipeline//drivers\peripheral\camera\hal\pipeline_core\pipeline_impl\src\stream_pipeline_core.cppRetCodeStreamPipelineCore::CreatePipeline(constint32_t&mode){std::lock_guardl(mutex_);std::shared_ptrspec=strategy_->GeneratePipelineSpec(mode);if(spec==nullptr){返回RC_ERROR;}std::shared_ptrpipeline=builder_->Build(spec);如果(管道==nullptr){返回RC_ERROR;}returndispatcher_->Update(pipeline);}需要注意几个问题pipeline的配置文件在drivers\peripheral\camera\hal\pipeline_core\pipeline_impl\src\这两个文件config.c和params。strategy\config目录下的c是BUILD.gn脚本生成的。//drivers\peripheral\camera\hal\adapter\chipset\hispark_taurus\BUILD.gnsource="$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c"exec_script("//drivers/framework/tools/hc-gen/build_hcs.py",["-o",rebase_path("$camera_path/pipeline_core/pipeline_impl/src/strategy/config/config.c"),"-t",rebase_path("//vendor/hisilicon/Hi3516DV300/hdf_config/uhdf/camera/hal/mpp/hispark_taurus/pipeline_core/config.hcs"),],"")}ohos_prebuilt_etc("params.c"){source="$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c"exec_script("//drivers/framework/tools/hc-gen/build_hcs.py",["-o",rebase_path("$camera_path/pipeline_core/pipeline_impl/src/strategy/config/params.c"),"-t",rebase_path("//vendor/hisilicon/Hi3516DV300/hdf_config/uhdf/camera/hal/mpp/hispark_taurus/pipeline_core/params.hcs"),],"")}3.总结这个流的创建也已经完成,最后一章会讲解图像获取的代码。更多内容请访问:与华为官方共建的Harmonyos技术社区https://harmonyos.51cto.com