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

目前建设网站辽宁省建设工程造价总站网站

目前建设网站,辽宁省建设工程造价总站网站,it网上做笔记的网站,深圳网站建设服务中心官网V4L2#xff1a;Video4Linux2#xff0c;是 Linux 内核中的一个框架#xff0c;提供了一套用于视频设备驱动程序开发的 API。它是一个开放的、通用的、模块化的视频设备驱动程序框架#xff0c;允许 Linux 操作系统和应用程序与各种视频设备#xff08;如摄像头、视频采集…V4L2Video4Linux2是 Linux 内核中的一个框架提供了一套用于视频设备驱动程序开发的 API。它是一个开放的、通用的、模块化的视频设备驱动程序框架允许 Linux 操作系统和应用程序与各种视频设备如摄像头、视频采集卡等进行交互。 V4L2 提供了一个通用的 API使应用程序能够访问和控制视频设备包括获取设备信息、设置设备参数、采集视频数据、控制设备状态等。V4L2 还提供了一个统一的视频数据格式允许应用程序在处理视频数据时无需考虑设备的具体格式。 Video for Linux two(Video4Linux2)简称 V4L2是 V4L 的改进版。V4L2 支持三种方式来采集图像内存映射方式(mmap)、直接读取方式(read)和用户指针。内存映射的方式采集速度较快一般用于连续视频数据的采集实际工作中的应用概率更高直接读取的方式相对速度慢一些所以常用于静态图片数据的采集用户指针使用较少。 V4L2 的主要特性 模块化的架构V4L2 是一个模块化的架构允许多个设备驱动程序同时存在并共享同一个 API。每个设备驱动程序都是一个独立的内核模块可以在运行时加载和卸载。这种架构可以使开发人员更容易地开发新的视频设备驱动程序并允许多个驱动程序同时使用相同的 API。 统一的设备节点V4L2 提供了一种统一的设备节点使应用程序可以使用相同的方式访问不同类型的视频设备。这种节点通常是 /dev/videoX其中 X 是一个数字表示设备的编号。应用程序可以通过打开这个节点来访问设备并使用 V4L2 API 进行数据采集和控制。 统一的视频数据格式V4L2 提供了一个统一的视频数据格式称为 V4L2_PIX_FMT允许应用程序在处理视频数据时无需考虑设备的具体格式。V4L2_PIX_FMT 包括了许多常见的视频格式如 RGB、YUV 等。应用程序可以使用 V4L2 API 来查询设备支持的数据格式并选择适当的格式进行数据采集和处理。 支持多种视频设备V4L2 支持许多不同类型的视频设备包括摄像头、视频采集卡、TV 卡等。每个设备都有自己的驱动程序提供了相应的 V4L2 API。这些驱动程序可以根据设备的不同特性提供不同的采集模式、数据格式、控制参数等。 支持流式 I/OV4L2 支持流式 I/O即通过内存映射的方式将视频数据从设备直接传输到应用程序中。这种方式可以减少数据复制的次数提高数据传输的效率。 支持控制参数V4L2 允许应用程序通过 API 来控制视频设备的参数包括亮度、对比度、色彩饱和度、曝光时间等。应用程序可以使用 V4L2 API 来查询设备支持的参数并设置适当的值。 支持事件通知V4L2 支持事件通知当视频设备状态发生变化时如视频信号丢失、帧率变化等V4L2 驱动程序可以向应用程序发送通知以便应用程序做出相应的处理。 从上面的特征可以看出V4L2 提供了一套通用、灵活、可扩展的视频设备驱动程序框架使得 Linux 操作系统和应用程序可以方便地与各种视频设备进行交互并且不需要关心设备的具体实现细节。从而让开发人员能够更加专注于应用程序的开发。 V4L2 视频采集步骤 摄像头使用流程 open打开设备节点 /dev/videoXioctl VIDIOC_QUERYCAPQuery Capbility查询能力比如 确认它是否是捕获设备因为有些节点是输出设备确认它是否支持 mmap 操作还是仅支持 read/write 操作 ioctl VIDIOC_ENUM_FMT枚举它支持的格式ioctl VIDIOC_S_FMT在上面枚举出来的格式里选择一个来设置格式ioctl VIDIOC_REQBUFS申请 bufferAPP 可以申请很多个 buffer但是驱动程序不一定能申请到ioctl VIDIOC_QUERYBUF 和 mmap查询 buffer 信息、映射 如果申请到了 N 个 buffer这个 ioctl 就应该执行 N 次执行 mmap 后APP 就可以直接读写这些 buffer ioctl VIDIOC_QBUF把 buffer 放入空闲链表 如果申请到了 N 个 buffer这个 ioctl 就应该执行 N 次 ioctl VIDIOC_STREAMON启动摄像头这里是一个循环使用 poll/select 监测 buffer然后从完成链表中取出 buffer处理后再放入空闲链表 poll/selectioctl VIDIOC_DQBUF从完成链表中取出 buffer处理前面使用 mmap 映射了每个 buffer 的地址处理时就可以直接使用地址来访问 bufferioclt VIDIOC_QBUF把 buffer 放入空闲链表 ioctl VIDIOC_STREAMOFF停止摄像头 demo #include config.h #include video_manager.h #include disp_manager.h#include sys/types.h #include sys/stat.h #include fcntl.h #include sys/mman.h #include poll.h #include sys/ioctl.h #include string.h #include unistd.hstatic int g_aiSupportedFormats[] {V4L2_PIX_FMT_YUYV, V4L2_PIX_FMT_MJPEG, V4L2_PIX_FMT_RGB565};static int V4l2GetFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf); static int V4l2PutFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf); static T_VideoOpr g_tV4l2VideoOpr;static int isSupportThisFormat(int iPixelFormat) {int i;for (i 0; i sizeof(g_aiSupportedFormats)/sizeof(g_aiSupportedFormats[0]); i){if (g_aiSupportedFormats[i] iPixelFormat)return 1;}return 0; }/* 参考 luvcview *//* open* VIDIOC_QUERYCAP 确定它是否视频捕捉设备,支持哪种接口(streaming/read,write)* VIDIOC_ENUM_FMT 查询支持哪种格式* VIDIOC_S_FMT 设置摄像头使用哪种格式* VIDIOC_REQBUFS 申请buffer对于 streaming:* VIDIOC_QUERYBUF 确定每一个buffer的信息 并且 mmap* VIDIOC_QBUF 放入队列* VIDIOC_STREAMON 启动设备* poll 等待有数据* VIDIOC_DQBUF 从队列中取出* 处理....* VIDIOC_QBUF 放入队列* ....对于read,write:read处理....read* VIDIOC_STREAMOFF 停止设备**/static int V4l2InitDevice(char *strDevName, PT_VideoDevice ptVideoDevice) {int i;int iFd;int iError;struct v4l2_capability tV4l2Cap;struct v4l2_fmtdesc tFmtDesc;struct v4l2_format tV4l2Fmt;struct v4l2_requestbuffers tV4l2ReqBuffs;struct v4l2_buffer tV4l2Buf;int iLcdWidth;int iLcdHeigt;int iLcdBpp;iFd open(strDevName, O_RDWR);if (iFd 0){DBG_PRINTF(can not open %s\n, strDevName);return -1;}ptVideoDevice-iFd iFd;iError ioctl(iFd, VIDIOC_QUERYCAP, tV4l2Cap);memset(tV4l2Cap, 0, sizeof(struct v4l2_capability));iError ioctl(iFd, VIDIOC_QUERYCAP, tV4l2Cap);if (iError) {DBG_PRINTF(Error opening device %s: unable to query device.\n, strDevName);goto err_exit;}if (!(tV4l2Cap.capabilities V4L2_CAP_VIDEO_CAPTURE)){DBG_PRINTF(%s is not a video capture device\n, strDevName);goto err_exit;}if (tV4l2Cap.capabilities V4L2_CAP_STREAMING) {DBG_PRINTF(%s supports streaming i/o\n, strDevName);}if (tV4l2Cap.capabilities V4L2_CAP_READWRITE) {DBG_PRINTF(%s supports read i/o\n, strDevName);}memset(tFmtDesc, 0, sizeof(tFmtDesc));tFmtDesc.index 0;tFmtDesc.type V4L2_BUF_TYPE_VIDEO_CAPTURE;while ((iError ioctl(iFd, VIDIOC_ENUM_FMT, tFmtDesc)) 0) {if (isSupportThisFormat(tFmtDesc.pixelformat)){ptVideoDevice-iPixelFormat tFmtDesc.pixelformat;break;}tFmtDesc.index;}if (!ptVideoDevice-iPixelFormat){DBG_PRINTF(can not support the format of this device\n);goto err_exit; }/* set format in */GetDispResolution(iLcdWidth, iLcdHeigt, iLcdBpp);memset(tV4l2Fmt, 0, sizeof(struct v4l2_format));tV4l2Fmt.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2Fmt.fmt.pix.pixelformat ptVideoDevice-iPixelFormat;tV4l2Fmt.fmt.pix.width iLcdWidth;tV4l2Fmt.fmt.pix.height iLcdHeigt;tV4l2Fmt.fmt.pix.field V4L2_FIELD_ANY;/* 如果驱动程序发现无法某些参数(比如分辨率),* 它会调整这些参数, 并且返回给应用程序*/iError ioctl(iFd, VIDIOC_S_FMT, tV4l2Fmt); if (iError) {DBG_PRINTF(Unable to set format\n);goto err_exit; }ptVideoDevice-iWidth tV4l2Fmt.fmt.pix.width;ptVideoDevice-iHeight tV4l2Fmt.fmt.pix.height;/* request buffers */memset(tV4l2ReqBuffs, 0, sizeof(struct v4l2_requestbuffers));tV4l2ReqBuffs.count NB_BUFFER;tV4l2ReqBuffs.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2ReqBuffs.memory V4L2_MEMORY_MMAP;iError ioctl(iFd, VIDIOC_REQBUFS, tV4l2ReqBuffs);if (iError) {DBG_PRINTF(Unable to allocate buffers.\n);goto err_exit; }ptVideoDevice-iVideoBufCnt tV4l2ReqBuffs.count;if (tV4l2Cap.capabilities V4L2_CAP_STREAMING){/* map the buffers */for (i 0; i ptVideoDevice-iVideoBufCnt; i) {memset(tV4l2Buf, 0, sizeof(struct v4l2_buffer));tV4l2Buf.index i;tV4l2Buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2Buf.memory V4L2_MEMORY_MMAP;iError ioctl(iFd, VIDIOC_QUERYBUF, tV4l2Buf);if (iError) {DBG_PRINTF(Unable to query buffer.\n);goto err_exit;}ptVideoDevice-iVideoBufMaxLen tV4l2Buf.length;ptVideoDevice-pucVideBuf[i] mmap(0 /* start anywhere */ ,tV4l2Buf.length, PROT_READ, MAP_SHARED, iFd,tV4l2Buf.m.offset);if (ptVideoDevice-pucVideBuf[i] MAP_FAILED) {DBG_PRINTF(Unable to map buffer\n);goto err_exit;}} /* Queue the buffers. */for (i 0; i ptVideoDevice-iVideoBufCnt; i) {memset(tV4l2Buf, 0, sizeof(struct v4l2_buffer));tV4l2Buf.index i;tV4l2Buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2Buf.memory V4L2_MEMORY_MMAP;iError ioctl(iFd, VIDIOC_QBUF, tV4l2Buf);if (iError){DBG_PRINTF(Unable to queue buffer.\n);goto err_exit;}}}else if (tV4l2Cap.capabilities V4L2_CAP_READWRITE){g_tV4l2VideoOpr.GetFrame V4l2GetFrameForReadWrite;g_tV4l2VideoOpr.PutFrame V4l2PutFrameForReadWrite;/* read(fd, buf, size) */ptVideoDevice-iVideoBufCnt 1;/* 在这个程序所能支持的格式里, 一个象素最多只需要4字节 */ptVideoDevice-iVideoBufMaxLen ptVideoDevice-iWidth * ptVideoDevice-iHeight * 4;ptVideoDevice-pucVideBuf[0] malloc(ptVideoDevice-iVideoBufMaxLen);}ptVideoDevice-ptOPr g_tV4l2VideoOpr;return 0;err_exit: close(iFd);return -1; }static int V4l2ExitDevice(PT_VideoDevice ptVideoDevice) {int i;for (i 0; i ptVideoDevice-iVideoBufCnt; i){if (ptVideoDevice-pucVideBuf[i]){munmap(ptVideoDevice-pucVideBuf[i], ptVideoDevice-iVideoBufMaxLen);ptVideoDevice-pucVideBuf[i] NULL;}}close(ptVideoDevice-iFd);return 0; }static int V4l2GetFrameForStreaming(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) {struct pollfd tFds[1];int iRet;struct v4l2_buffer tV4l2Buf;/* poll */tFds[0].fd ptVideoDevice-iFd;tFds[0].events POLLIN;iRet poll(tFds, 1, -1);if (iRet 0){DBG_PRINTF(poll error!\n);return -1;}/* VIDIOC_DQBUF */memset(tV4l2Buf, 0, sizeof(struct v4l2_buffer));tV4l2Buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2Buf.memory V4L2_MEMORY_MMAP;iRet ioctl(ptVideoDevice-iFd, VIDIOC_DQBUF, tV4l2Buf);if (iRet 0) {DBG_PRINTF(Unable to dequeue buffer.\n);return -1;}ptVideoDevice-iVideoBufCurIndex tV4l2Buf.index;ptVideoBuf-iPixelFormat ptVideoDevice-iPixelFormat;ptVideoBuf-tPixelDatas.iWidth ptVideoDevice-iWidth;ptVideoBuf-tPixelDatas.iHeight ptVideoDevice-iHeight;ptVideoBuf-tPixelDatas.iBpp (ptVideoDevice-iPixelFormat V4L2_PIX_FMT_YUYV) ? 16 : \(ptVideoDevice-iPixelFormat V4L2_PIX_FMT_MJPEG) ? 0 : \(ptVideoDevice-iPixelFormat V4L2_PIX_FMT_RGB565) ? 16 : \0;ptVideoBuf-tPixelDatas.iLineBytes ptVideoDevice-iWidth * ptVideoBuf-tPixelDatas.iBpp / 8;ptVideoBuf-tPixelDatas.iTotalBytes tV4l2Buf.bytesused;ptVideoBuf-tPixelDatas.aucPixelDatas ptVideoDevice-pucVideBuf[tV4l2Buf.index]; return 0; }static int V4l2PutFrameForStreaming(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) {/* VIDIOC_QBUF */struct v4l2_buffer tV4l2Buf;int iError;memset(tV4l2Buf, 0, sizeof(struct v4l2_buffer));tV4l2Buf.index ptVideoDevice-iVideoBufCurIndex;tV4l2Buf.type V4L2_BUF_TYPE_VIDEO_CAPTURE;tV4l2Buf.memory V4L2_MEMORY_MMAP;iError ioctl(ptVideoDevice-iFd, VIDIOC_QBUF, tV4l2Buf);if (iError) {DBG_PRINTF(Unable to queue buffer.\n);return -1;}return 0; }static int V4l2GetFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) {int iRet;iRet read(ptVideoDevice-iFd, ptVideoDevice-pucVideBuf[0], ptVideoDevice-iVideoBufMaxLen);if (iRet 0){return -1;}ptVideoBuf-iPixelFormat ptVideoDevice-iPixelFormat;ptVideoBuf-tPixelDatas.iWidth ptVideoDevice-iWidth;ptVideoBuf-tPixelDatas.iHeight ptVideoDevice-iHeight;ptVideoBuf-tPixelDatas.iBpp (ptVideoDevice-iPixelFormat V4L2_PIX_FMT_YUYV) ? 16 : \(ptVideoDevice-iPixelFormat V4L2_PIX_FMT_MJPEG) ? 0 : \(ptVideoDevice-iPixelFormat V4L2_PIX_FMT_RGB565)? 16 : \0;ptVideoBuf-tPixelDatas.iLineBytes ptVideoDevice-iWidth * ptVideoBuf-tPixelDatas.iBpp / 8;ptVideoBuf-tPixelDatas.iTotalBytes iRet;ptVideoBuf-tPixelDatas.aucPixelDatas ptVideoDevice-pucVideBuf[0]; return 0; }static int V4l2PutFrameForReadWrite(PT_VideoDevice ptVideoDevice, PT_VideoBuf ptVideoBuf) {return 0; }static int V4l2StartDevice(PT_VideoDevice ptVideoDevice) {int iType V4L2_BUF_TYPE_VIDEO_CAPTURE;int iError;iError ioctl(ptVideoDevice-iFd, VIDIOC_STREAMON, iType);if (iError) {DBG_PRINTF(Unable to start capture.\n);return -1;}return 0; }static int V4l2StopDevice(PT_VideoDevice ptVideoDevice) {int iType V4L2_BUF_TYPE_VIDEO_CAPTURE;int iError;iError ioctl(ptVideoDevice-iFd, VIDIOC_STREAMOFF, iType);if (iError) {DBG_PRINTF(Unable to stop capture.\n);return -1;}return 0; }static int V4l2GetFormat(PT_VideoDevice ptVideoDevice) {return ptVideoDevice-iPixelFormat; }/* 构造一个VideoOpr结构体 */ static T_VideoOpr g_tV4l2VideoOpr {.name v4l2,.InitDevice V4l2InitDevice,.ExitDevice V4l2ExitDevice,.GetFormat V4l2GetFormat,.GetFrame V4l2GetFrameForStreaming,.PutFrame V4l2PutFrameForStreaming,.StartDevice V4l2StartDevice,.StopDevice V4l2StopDevice, };/* 注册这个结构体 */ int V4l2Init(void) {return RegisterVideoOpr(g_tV4l2VideoOpr); }
http://www.pierceye.com/news/88599/

相关文章:

  • 北京企业网站开发优秀网站推荐
  • dede网站地图文章变量做网站版头图片
  • 做学校网站素材4a广告公司排名
  • 邯郸建立网站费用logo设计商标设计
  • 什么是一学一做视频网站好烟台网站seo外包
  • 做动图的网站seo设计师品牌
  • 辽宁企业网站建设公司wordpress公司主题
  • 东莞网站设襄阳市建设工程质量监督站网站
  • 浦东网站建设公司信息平台网站建设
  • 文登做网站的公司搜索引擎营销成功的案例
  • 福州免费做网站网络公司做的网站我能改后台么
  • 内衣网站建设详细方案抖音代运营如何解除
  • 网站首页样式谭谭心怎么建设网站
  • 怎样在网站上做链接企业网络营销策划案例
  • 如何创建问卷网站久久网招聘信息
  • 做外贸 访问国外网站南宁网络推广服务商
  • 自建网站平台的页面功能东莞松山湖网站建设
  • 网站建设准备网站建设实习目的
  • 做坏事网站软件开发管理软件
  • 微信网站是多少阿里有做网站
  • 廊坊网站建设品牌自己建一个网站怎么赚钱
  • tv做后缀的动漫网站东莞网站建设网站排名优化
  • 国科联创网站建设在线seo超级外链工具
  • 代理备案 网站 安全吗佛山营销网站开发怎么选
  • 做网站建设网站制作开发一个大型网站需要多少钱
  • 石家庄网站设计公司排名企业营销网络建设
  • html 旅游网站陇南市网站建设
  • 超链接 网站wordpress主题是什么
  • 好的策划方案网站做效果图的网站有哪些软件
  • 英文网站建设价格有谁做彩票网站吗