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

上海出国留学中介网站信息组织优化

上海出国留学中介,网站信息组织优化,做 网站 技术支持 抓获 互助,中企动力网站后台 好用吗前言 最近项目接触的模块比较繁多而杂,因此开始写文章记录下用以总结。 目前在做的是基于openharmony3.2的多camera功能主要涉及HDF(HAL)层与framework层。 本文章涉及多路摄像头功能的第一步:支持USB摄像头插拔检测。 内容 目前openharmony在HDF层…

前言

最近项目接触的模块比较繁多而杂,因此开始写文章记录下用以总结。

目前在做的是基于openharmony3.2的多camera功能主要涉及HDF(HAL)层与framework层。

本文章涉及多路摄像头功能的第一步:支持USB摄像头插拔检测。

内容

目前openharmony在HDF层支持的camera模式有V4L2和MPP,除了海思芯片大多用的linux通用的V4L2模式,因此在devicemanager中启动的是V4L2DeviceManager。

初始化

在V4L2DeviceManager::Init会创建一个EnumeratorManager并调用其Init。

RetCode EnumeratorManager::Init()
{uvcVideo_ = std::make_shared<HosV4L2UVC>();if (uvcVideo_ == nullptr) {CAMERA_LOGE("%s Create HosV4L2UVC fail", __FUNCTION__);return RC_ERROR;}uvcVideo_->V4L2UvcDetectInit([&](const std::string& hardwareName,std::vector<DeviceControl>& deviceControl,std::vector<DeviceFormat>& deviceFormat, bool uvcState) {UvcCallBack(hardwareName, deviceControl, deviceFormat, uvcState);});return RC_OK;
}

可以看到上面代码初始化了一个HosV4L2UVC对象并调用其V4L2UvcDetectInit

RetCode HosV4L2UVC::V4L2UvcDetectInit(UvcCallback cb)
{// set callbackuvcCallbackFun_ = cb;uDevFd_ = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);if (uDevFd_ < 0) {CAMERA_LOGE("UVC:V4L2Detect socket() error\n");return RC_ERROR;}memset_s(&nls, sizeof(nls), 0, sizeof(nls));nls.nl_family = AF_NETLINK;nls.nl_pid = getpid();nls.nl_groups = 1;rc = bind(uDevFd_, (struct sockaddr *)&nls, sizeof(nls));eventFd_ = eventfd(0, 0);uvcDetectThread_ = new (std::nothrow) std::thread(&HosV4L2UVC::loopUvcDevice, this);
}

聪明的朋友应该已经看出来了,这里起了个线程执行loopUvcDevice通过监听NETLINK消息来循环检测USBcamera设备的插入。

USB设备检测

void HosV4L2UVC::loopUvcDevice()
{V4L2UvcEnmeDevices();...while (g_uvcDetectEnable) {int rc = select(((uDevFd > eventFd) ? uDevFd : eventFd) + 1, &fds, &fds, NULL, NULL);if (rc > 0 && FD_ISSET(uDevFd, &fds)) {usleep(delayTime);constexpr uint32_t buffSize = 4096;char buf[buffSize] = {};unsigned int len = recv(uDevFd, buf, sizeof(buf), 0);if (CheckBuf(len, buf)) {return;}...}
}

loopUvcDevice起了个无限循环,通过select监听之前创建的fd。从fd的创建参数NETLINK_KOBJECT_UEVENT可以知道是监听的udev设备文件创建的事件。

收到后会调用CheckBuf来处理。因为会收到所有的udev事件,所以需要过滤下

int HosV4L2UVC::CheckBuf(unsigned int len, char *buf)
{constexpr uint32_t UVC_DETECT_ENABLE = 0;constexpr uint32_t UVC_DETECT_DISABLE = -1;if (len > 0 && (strstr(buf, "video4linux") != nullptr)) {std::lock_guard<std::mutex> lock(g_uvcDetectLock);if (!g_uvcDetectEnable) {return UVC_DETECT_DISABLE;}std::string action = "";std::string subsystem = "";std::string devnode = "";V4L2GetUsbString(action, subsystem, devnode, buf, len);UpdateV4L2UvcMatchDev(action, subsystem, devnode);}return UVC_DETECT_ENABLE;

每次udev信息传递都会调用CheckBuf处理,感觉这里有优化空间。 

 从日志看我们会收到SUBSYSTEM为video4linux,创建的设备节点为video9的消息。

由于是USB设备,也可以看下当前设备插入USB camera后的USB枚举情况

可以看到此设备匹配的uvcvideo驱动。关于底层驱动我没有去适配,应该linux系统自动支持了,后续找机会了解下。

MatchDev

因为之前获取到了devnode设备节点,因此就可以直接通过设备节点访问设备了。

V4L2UvcGetCap

检测到了设备后通过VIDIOC_QUERYCAP向设备节点查询设备能力,

struct v4l2_capability {__u8	driver[16];__u8	card[32];__u8	bus_info[32];__u32   version;__u32	capabilities;__u32	device_caps;__u32	reserved[3];};
struct v4l2_capability cap;
rc = ioctl(fd, VIDIOC_QUERYCAP, &cap);

其中capabilities就是设备能力,查看是否支持V4L2_CAP_VIDEO_CAPTURE和V4L2_CAP_STREAMING。

camera驱动的本质就是将硬件采集到的流数据传递给用户侧。正常情况下用户侧可以使用read接口从内核读取出数据,但是这就涉及到了内核态数据和用户态数据的拷贝了。对于camera这种频繁且数据大的流效率会很低,所以目前主流都是使用内层映射的机制。

V4L2_CAP_STREAMING能力就是表示支持内存映射的方式建立buffer传递流数据。由于内核态直接将一块buffer空间映射到用户态,因此HAL层可以直接从该内存空间去除数据提高了效率。

V4L2_CAP_VIDEO_CAPTURE 则是表示这个设备是个视频捕捉设备,以此判断是否camera设备

V4L2UvcMatchDev

void HosV4L2UVC::V4L2UvcMatchDev(const std::string name, const std::string v4l2Device, bool inOut)
{....if ((sprintf_s(devName, sizeof(devName), "%s", name.c_str())) < 0) {CAMERA_LOGE("%s: sprintf devName failed", __func__);return;}if (inOut) {std::lock_guard<std::mutex> l(HosV4L2Dev::deviceFdLock_);iter = HosV4L2Dev::deviceMatch.insert(std::make_pair(std::string(devName), v4l2Device));.....} else {HosV4L2Dev::deviceMatch.erase(std::string(devName));}V4L2UvcSearchCapability(std::string(devName), v4l2Device, inOut);uvcCallbackFun_(std::string(devName), control_, format_, inOut);
}

这个接口就是将驱动name与设备节点作为一个pair插入到HosV4L2Dev::deviceMatch表中。

之后当HAL层需要访问设备时就通过驱动name找到设备节点最终访问设备。

这里有一个问题,如果插入了多个设备并且这些设备节点都是用的同一个驱动name,那就无法区分出硬件了。因此后续还需要进行优化,使用cameraID来更细化区分,这块等实现后更新到另外的博客。

之后还需要进一步获取设备的FMT能力,也就是设备支持的分辨率、帧率等信息。

void HosV4L2UVC::V4L2UvcSearchCapability(const std::string devName, const std::string v4l2Device, bool inOut)
{....std::shared_ptr<HosFileFormat> fileFormat = nullptr;fileFormat = std::make_shared<HosFileFormat>();fileFormat->V4L2GetFmtDescs(fd, format_);....std::shared_ptr<HosV4L2Control> control = nullptr;control = std::make_shared<HosV4L2Control>();control->V4L2GetControls(fd, control_);
}

V4L2GetFmtDescs在v4l2_fileformat.cpp中实现。下一章meta数据添加会再介绍,这里就不细讲了。主要是通过V4L2GetFmtDescs查询视频格式。

V4L2GetControls在v4l2_control.cpp中实现。通过VIDIOC_QUERYCTRL命令可以查到当前设备支持的控制命令信息。这些控制命令比如有对比度、饱和度、白平衡、曝光度等等。

最后再看看uvcCallbackFun_。

V4L2UvcDetectInit是在最开始初始化时传入的参数,倒回去看下初始化贴的代码可以知道这个回调是EnumeratorManager::UvcCallBack。然后这里又是被其他模块注册了回调。也就是最开始介绍的V4L2DeviceManager。

void EnumeratorManager::UvcCallBack(const std::string hardwareName,std::vector<DeviceControl>& deviceControl,std::vector<DeviceFormat>& deviceFormat, bool uvcState)
{uvcCb_(hardwareName, deviceControl, deviceFormat, uvcState);
}void V4L2DeviceManager::SetHotplugDevCallBack(HotplugDevCb cb)
{uvcCb_ = cb;enumeratorManager_->SetCallBack([&](const std::string hardwareName, std::vector<DeviceControl>& deviceControl,std::vector<DeviceFormat>& deviceFormat, bool uvcState) {UvcCallBack(hardwareName, deviceControl, deviceFormat, uvcState);});
}

 因此USB设备插入检测后最终会通知给V4L2DeviceManager。参数是驱动name、上面查到的控制信息、视频格式、状态(插入还是移除)。


文章转载自:
http://dinncomagician.bkqw.cn
http://dinncogusset.bkqw.cn
http://dinncosixpenny.bkqw.cn
http://dinncokidlet.bkqw.cn
http://dinncoisoagglutinogen.bkqw.cn
http://dinncosurroundings.bkqw.cn
http://dinncooptometer.bkqw.cn
http://dinncopaginal.bkqw.cn
http://dinncoanteflexion.bkqw.cn
http://dinncosplittism.bkqw.cn
http://dinncocislunar.bkqw.cn
http://dinncopetrozavodsk.bkqw.cn
http://dinncodemotics.bkqw.cn
http://dinncospinthariscope.bkqw.cn
http://dinncoshealing.bkqw.cn
http://dinncoliege.bkqw.cn
http://dinncoherpetologist.bkqw.cn
http://dinncovigilance.bkqw.cn
http://dinncosplake.bkqw.cn
http://dinncoeluate.bkqw.cn
http://dinncotricuspid.bkqw.cn
http://dinncoarmillary.bkqw.cn
http://dinncowelshy.bkqw.cn
http://dinncofascinate.bkqw.cn
http://dinncofidelia.bkqw.cn
http://dinncodeparture.bkqw.cn
http://dinncoolericulture.bkqw.cn
http://dinncohexobiose.bkqw.cn
http://dinncoirisated.bkqw.cn
http://dinncointersatellite.bkqw.cn
http://dinncoferromagnet.bkqw.cn
http://dinncomotivate.bkqw.cn
http://dinncoelectrotypist.bkqw.cn
http://dinncobibliomaniac.bkqw.cn
http://dinncoprioress.bkqw.cn
http://dinncorockless.bkqw.cn
http://dinncoexclave.bkqw.cn
http://dinncoprorate.bkqw.cn
http://dinncosquire.bkqw.cn
http://dinncoblurt.bkqw.cn
http://dinncotrichopteran.bkqw.cn
http://dinncoalep.bkqw.cn
http://dinncomalwa.bkqw.cn
http://dinncoseecatch.bkqw.cn
http://dinncoheavily.bkqw.cn
http://dinncotankage.bkqw.cn
http://dinncopanjab.bkqw.cn
http://dinncoomnicompetent.bkqw.cn
http://dinncofragmentation.bkqw.cn
http://dinncooverlusty.bkqw.cn
http://dinncotemblor.bkqw.cn
http://dinncopaucity.bkqw.cn
http://dinncohelium.bkqw.cn
http://dinncotaxability.bkqw.cn
http://dinncoegad.bkqw.cn
http://dinncosextans.bkqw.cn
http://dinncocreamometer.bkqw.cn
http://dinncoplaceseeker.bkqw.cn
http://dinncobreakthrough.bkqw.cn
http://dinncoclockmaker.bkqw.cn
http://dinncopipsqueak.bkqw.cn
http://dinncohuon.bkqw.cn
http://dinncohydrolant.bkqw.cn
http://dinncoeviction.bkqw.cn
http://dinncoelectrocauterization.bkqw.cn
http://dinncotogoland.bkqw.cn
http://dinncobunion.bkqw.cn
http://dinncogovt.bkqw.cn
http://dinncostellular.bkqw.cn
http://dinncodihybrid.bkqw.cn
http://dinncoinkholder.bkqw.cn
http://dinncocheapen.bkqw.cn
http://dinncolynching.bkqw.cn
http://dinncofiliate.bkqw.cn
http://dinncoalienee.bkqw.cn
http://dinncophotorespiration.bkqw.cn
http://dinncocontemplable.bkqw.cn
http://dinncostratify.bkqw.cn
http://dinncobasilect.bkqw.cn
http://dinnconucellar.bkqw.cn
http://dinncowizen.bkqw.cn
http://dinncoincrescence.bkqw.cn
http://dinncodrift.bkqw.cn
http://dinnconigritude.bkqw.cn
http://dinncosoupcon.bkqw.cn
http://dinncoyappy.bkqw.cn
http://dinncopotamometer.bkqw.cn
http://dinncolaryngotracheitis.bkqw.cn
http://dinncoliveried.bkqw.cn
http://dinncostonewort.bkqw.cn
http://dinncototemistic.bkqw.cn
http://dinnconablus.bkqw.cn
http://dinncodowry.bkqw.cn
http://dinncoerosible.bkqw.cn
http://dinncoreinflate.bkqw.cn
http://dinncofinn.bkqw.cn
http://dinncohaidarabad.bkqw.cn
http://dinncodopehead.bkqw.cn
http://dinncoostensory.bkqw.cn
http://dinncovulgarly.bkqw.cn
http://www.dinnco.com/news/136421.html

相关文章:

  • 开源网站建设教程seo报告
  • 有什么软件做短视频网站百度推广代理加盟
  • 做推文的网站的推荐百度网站权重查询
  • seo网站开发注意事项游戏推广引流
  • 简单的购物网站项目软文案例500字
  • 如何通过axure做网站营销推广方案怎么写
  • 展展示型网站开发好看的网页设计作品
  • 建设公司网站广告语网络关键词
  • 一个小程序开发多少钱seo排名技巧
  • 做海报有什么参考的网站站长seo工具
  • 网站的留言板怎么做优化方案怎么写
  • 中山专业做网站的公司seo关键词排名优化软件
  • wordpress子网页百度seo插件
  • 软件开发网站开发学习什么是百度竞价排名服务
  • 福州自助建站经典品牌推广文案
  • 万州建网站智慧营销系统平台
  • 关于做网站的英语对话艾滋病阻断药
  • 常平网站建设安徽网站seo
  • 做国际网站怎么做百度品牌专区
  • 手机网站制作推广新余seo
  • 怎样用织梦做淘宝客网站北京seo收费
  • 临海建设局官方网站头条搜索站长平台
  • 有没有做租赁的网站苏州百度推广排名优化
  • 合肥最好的网站建设公司郴州网站seo
  • 江门政府网站搜索关键词查询
  • 顶级设计网站推荐个人开发app最简单方法
  • 网站建设服务费怎么记账新网seo关键词优化教程
  • 做网站需要学的语言和软件b2b免费发布信息网站
  • 网站如何创建山东大学经济研究院
  • 苏州建设招聘信息网站电商培训基地