Linux V4L2框架先容

打印 上一主题 下一主题

主题 887|帖子 887|积分 2661

linux V4L2框架先容

V4L2框架先容

V4L2,全称Video for Linux 2,是Linux操纵体系下用于视频数据收罗设备的驱动框。它提供了一种标准化的方式使用户空间步调能够与视频设备进行通讯和交互。通过V4L2接口,用户可以方便地实现视频图像数据的收罗、输出、覆盖和编解码等功能,同时,V4L2的架构也为开发者提供了灵活和可扩展的编程接口。
V4L2驱动框架如下

V4L2重要提供以下接口功能:


  • 视频收罗功能接口(video capture interface):从摄像头等设备上获取视频数据。
  • 视频输出功能接口(video output interface):将视频数据编码为模拟信号输出。
  • 直接传输视频功能接口(video overlay interface):将视频收罗设备收罗的信号直接输出到输出设备,而无需经过体系CPU。
  • 视频间隔消隐信号功能接口:提供对VBI(Vertical Blanking Interval)数据的控制,可以发送或抓取VBI数据。
  • 收音机接收功能接口:用于处置处罚从AM或FM高频头设备接收的音频流。
  • 视频数据格式转换、缩放、色域转换等图像处置处罚接口
V4L2设备,在驱动加载乐成后在/dev目录下生成videox设备,用户可以该设备进行open大概close,read/write,同时其重要功能是通过ioctl来实现的。其支持的ioctl的命令能力重要有:
ioctrl codes说明VIDIOC_QUERYCAP查询设备功能VIDIOC_G_PRIORITY获取设备操纵的优先级VIDIOC_S_PRIORITY设置设备操纵的优先级VIDIOC_LOG_STATUS向内核日记打印当前设备的详细状态信息,包罗设备的根本信息、输入输出源、视频格式、分辨率、帧率,设备的状态信息以及设备的错误警告信息等VIDIOC_ENUM_FMT枚举设备支持的图像格式VIDIOC_G_FMT获取设备当前的图像格式VIDIOC_S_FMT设置设备的图像格式VIDIOC_TRY_FMT测试设备是否支持此格式VIDIOC_ENUM_FRAMESIZES枚举设备支持的所有视频分辨率VIDIOC_ENUM_FRAMEINTERVALS枚举设备支持的所有视频帧率VIDIOC_G_PARM获取设备的流范例干系参数VIDIOC_S_PARM设置设备的流范例干系参数VIDIOC_STREAMON开始视频流式收罗VIDIOC_STREAMOFF停止视频流式收罗VIDIOC_REQBUFS申请缓存VIDIOC_QUERYBUF获取缓存信息VIDIOC_QBUF将缓存放入队列中VIDIOC_DQBUF将缓存从队列中取出VIDIOC_EXPBUF导出视频缓冲区VIDIOC_G_FBUF查询当前视频帧缓冲区(framebuffer)的配置信息VIDIOC_S_FBUF设置当前视频帧缓冲区(framebuffer)的配置信息VIDIOC_OVERLAY启动或停止视频覆盖功能VIDIOC_CROPCAP获取图像剪裁缩放能力VIDIOC_G_CROP获取当前的剪裁矩阵VIDIOC_S_CROP设置剪裁矩阵VIDIOC_G_ENC_INDEX获取编码器索引VIDIOC_ENCODER_CMD设置设备的当前编码器行为VIDIOC_TRY_ENCODER_CMD测试设备是否支持此编码器命令VIDIOC_G_INPUT获取当前的视频输入设备VIDIOC_S_INPUT设置视频输入设备VIDIOC_ENUMINPUT枚举视频输入设备VIDIOC_G_OUTPUT获取当前的视频输出设备VIDIOC_S_OUTPUT设备当前的视频输出设备VIDIOC_ENUMOUTPUT枚举视频输出设备VIDIOC_G_STD获取当前正在使用的标准VIDIOC_S_STD设置视频标准VIDIOC_ENUMSTD枚举设备支持的所有标准VIDIOC_QUERYSTD主动侦测输入源的视频标准VIDIOC_QUERYCTRL查询视频设备支持的控制项controlVIDIOC_QUERYMENU查询与特定控制项干系联的菜单项VIDIOC_G_CTRL获取设备指定的control的当前信息VIDIOC_S_CTRL设置设备指定的controlVIDIOC_G_TUNER获取设备调谐器信息VIDIOC_S_TUNER设置设备调谐器信息VIDIOC_ENUMAUDIO枚举音频输入设备VIDIOC_G_AUDIO获取音频输入设备VIDIOC_S_AUDIO设置音频输入设备VIDIOC_ENUMAUDOUT枚举音频输出设备VIDIOC_G_AUDOUT获取音频输出设备VIDIOC_S_AUDOUT设备音频输出设备VIDIOC_G_EDID获取与视频接收器或发射器设备的输入或输出干系联的EDID(Extended Display Identification Data,扩展显示标识数据)VIDIOC_S_EDID设置与视频接收器或发射器设备的输入或输出干系联的EDID(Extended Display Identification Data,扩展显示标识数据)VIDIOC_G_MODULATOR获取调制器(Modulator)的状态和配置信息VIDIOC_S_MODULATOR设置调制器(Modulator)的状态和配置信息VIDIOC_G_FREQUENCY获取当前调谐器或射频调制器(Modulator)的频率值VIDIOC_S_FREQUENCY设置当前调谐器或射频调制器(Modulator)的频率值VIDIOC_G_JPEGCOMP获取JPEG的压缩信息VIDIOC_S_JPEGCOMP设置JPEG的压缩参数VIDIOC_G_SLICED_VBI_CAP查询设备支持哪些范例的VBI数据的切片捕获VIDIOC_G_EXT_CTRLS获取扩展的控制信息VIDIOC_S_EXT_CTRLS设置扩展的控制参数VIDIOC_TRY_EXT_CTRLS测试设备是否支持此扩展功能 V4L2工具——V4L2-Ctl先容

V4L2-Ctl是基于V4L2 API的一个命令行工具,重要用于控制和查询Linux体系中的视频设备信息。能够列出体系中的视频设备、查询和设置视频设备参数,以及对视频进行捕获等功能。它提供了丰富的命令选项,使用户能够灵活地操控视频设备。其重要命令选项有:
v4l2-ctl --help / -h

显示资助信息

v4l2-ctl --help-xxx

显示子选项的资助信息 如v4l2-ctl --help-streaming 显示视频流式传输控制参数信息


v4l2-ctl -D / --info

显示摄像头根本信息

v4l2-ctl --list-devices

列出体系中的所有video设备

v4l2-ctl --log-status

打印v4l2内核态的详细日记

v4l2-ctl --list-ctrls --device /dev/video0

列出指定设备控制值

v4l2-ctl --list-ctls-menus --device /dev/video0

列出Linux体系中V4L2视频捕获设备支持的控制项(controls)和菜单(menus)

v4l2-ctl --get-priority

获取V4L2的操纵优先级

v4l2-ctl --help-vidcap

显示视频捕获设备参数资助信息

v4l2-ctl --list-formats-ext --device /dev/video0

列出指定设备的支持的图像格式、分辨率以及帧率

v4l2-ctl --list-formats --device /dev/video0

列出指定设备的支持图像格式

v4l2-ctl --device /dev/video0 --list-framesizes YUYV

列出当前设备所指定的图像格式下的分辨率

v4l2-ctl --device /dev/video0 --list-frameintervals width=1280,height=720,pixelformat=YUYV

列出设备在指定的图像格式以及分辨率下所支持的帧率

v4l2-ctl --device /dev/video0 --list-fields

列出指定设备所支持的场顺序

v4l2-ctl --get-fmt-video --device /dev/video0

获取指定设备当前所使用的格式

v4l2-ctl --all --device /dev/video0

获取指定设备的所有信息

v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=YUYV --stream-mmap -d /dev/video0

流式输出指定视频设备以及指定格式和分辨率下的数据

v4l2-ctl -d /dev/video0 --stream-mmap

流式输出指定设备的数据

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=100

流式输出指定设备的指定帧数的数据

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=video0.yuv

将指定设备的图像数据流式输出到文件

v4l2-ctl --device /dev/video0 --stream-mmap --stream-lossless --stream-to-host 127.0.0.1

./qvidcap -p
流式输出指定设备的数据,并通过网络发送撤除,可通过v4l2-utils/utils/qvidcap工具进行查看

V4L2 video catpture device api先容

打开设备

Linux的open函数打开video设备
  1. //方法用例C++函数
  2. bool V4L2CaptureVideoData::OpenVideoDevice(std::string device_name)
  3. {
  4.     m_video_fd = open(device_name.c_str(), O_RDWR | O_NONBLOCK, 0);
  5.     if (-1 == m_video_fd)
  6.     {
  7.         std::cerr<<"cannot open video device:"<<"device name="<<device_name<<",errno="<<errno<<",strerror="<<strerror(errno)<<std::endl;
  8.         return false;
  9.     }
  10.     return true;
  11. }
复制代码
关闭设备

linux的close函数关闭video设备
  1. //方法用例C++函数
  2. bool V4L2CaptureVideoData::closeVideoDevice()
  3. {
  4.     if(close(m_video_fd)==-1)
  5.     {
  6.         std::cerr<<"close video device failed:"<<"errno="<<errno<<",strerror="<<strerror(errno)<<std::endl;
  7.         m_video_fd=-1;
  8.         return false;
  9.     }
  10.     m_video_fd=-1;
  11.     return true;
  12. }
复制代码
ioctl命令 VIDIOC_QUERYCAP

查询设备功能
  1. //命令字段定义
  2. #define VIDIOC_QUERYCAP      _IOR('V',  0, struct v4l2_capability)
  3. //所使用到的结构体信息
  4. struct v4l2_capability {
  5.     __u8   driver[16];     // 驱动程序名称
  6.     __u8   card[32];       // 设备名称
  7.     __u8   bus_info[32];   // 总线信息
  8.     __u32  version;        // V4L2 版本号
  9.     __u32  capabilities;   // 设备的能力标志
  10.     __u32  device_caps;    // 设备特定能力标志
  11.     __u32  reserved[3];    // 保留字段
  12. };
  13. //方法用例C++函数
  14. bool V4L2CaptureVideoData::GetVideoDeviceCapability(v4l2_capability &cap)
  15. {
  16.     int ret=0;
  17.     do
  18.     {
  19.         ret=ioctl(m_video_fd, VIDIOC_QUERYCAP, &cap);
  20.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  21.    
  22.     if(ret!=0)
  23.     {
  24.         std::cerr<<"ioctl VIDIOC_QUERYCAP failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  25.         return false;
  26.     }
  27.     return true;
  28. }
复制代码
ioctl命令 VIDIOC_ENUM_FMT

枚举视频设备支持的图像格式
  1. //命令字段定义
  2. #define VIDIOC_ENUM_FMT         _IOWR('V',  2, struct v4l2_fmtdesc)
  3. //所使用到的结构体信息
  4. struct v4l2_fmtdesc {
  5.     __u32               index;       // 格式编号,从0开始递增
  6.     __u32               type;        // 帧类型,如V4L2_BUF_TYPE_VIDEO_CAPTURE表示视频捕捉
  7.     __u32               flags;       // 格式标志,如V4L2_FMT_FLAG_COMPRESSED表示压缩格式
  8.     __u8                description[32]; // 格式描述字符串,如"YUV 4:2:2 (YUYV)"
  9.     __u32               pixelformat; // 格式的四字符代码(Four-Character Code, FCC),如V4L2_PIX_FMT_UYVY
  10.     __u32               reserved[4]; // 保留字段,用于未来扩展
  11. };
  12. //方法用例C++函数
  13. bool V4L2CaptureVideoData::EnumVideoDeviceFormat(std::list<struct v4l2_fmtdesc> &fmtdesc)
  14. {
  15.     fmtdesc.clear();
  16.     struct v4l2_fmtdesc tmp_fmtdesc;
  17.     tmp_fmtdesc.index = 0;
  18.     tmp_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  19.     int ret=0;
  20.     while(!((ret == -1) && (errno != EINTR) && (errno != EAGAIN)))
  21.     {
  22.         ret=ioctl(m_video_fd,VIDIOC_ENUM_FMT,&tmp_fmtdesc);
  23.         if(ret==0)
  24.         {
  25.             fmtdesc.push_back(tmp_fmtdesc);
  26.             tmp_fmtdesc.index++;
  27.         }
  28.     }
  29.     return true;
  30. }
复制代码
ioctl命令 VIDIOC_G_FMT

获取设备当前使用的图像格式
  1. //命令字段定义
  2. #define VIDIOC_G_FMT        _IOWR('V',  4, struct v4l2_format)
  3. //所使用到的结构体信息
  4. struct v4l2_format {
  5.     enum v4l2_buf_type type;   // 帧类型,指示这个格式是用于捕获、输出还是其他类型
  6.     union {
  7.         struct v4l2_pix_format pix;       // 像素格式信息,用于视频捕获等
  8.         struct v4l2_window win;           // 窗口信息,用于视频输出覆盖
  9.         struct v4l2_vbi_format vbi;       // VBI(Vertical Blanking Interval)格式信息
  10.         struct v4l2_sliced_vbi_format sliced; // 切片VBI格式信息
  11.         __u8 raw_data[200];               // 原始数据,用于用户自定义格式
  12.     } fmt;
  13. };
  14. struct v4l2_pix_format {
  15.     __u32           width;         // 视频帧的宽度(像素)
  16.     __u32           height;        // 视频帧的高度(像素)
  17.     __u32           pixelformat;   // 像素格式,使用四字符代码(Four-Character Code, FCC)表示
  18.     __u32           field;         // 字段顺序,如V4L2_FIELD_INTERLACED表示隔行扫描
  19.     __u32           bytesperline;  // 每行的字节数(对于压缩格式,可能表示压缩块的大小)
  20.     __u32           sizeimage;     // 整个图像的大小(字节)
  21.     __u32           colorspace;    // 颜色空间,如V4L2_COLORSPACE_SMPTE170M表示SMPTE 170M标准
  22.     __u32           priv;          // 私有数据,供驱动使用
  23.     __u32           flags;         // 格式标志,如V4L2_PIX_FMT_FLAG_PREMUL_ALPHA表示alpha通道已预乘
  24.    union {
  25.         /* enum v4l2_ycbcr_encoding */
  26.         __u32           ycbcr_enc;
  27.         /* enum v4l2_hsv_encoding */
  28.         __u32           hsv_enc;
  29.     };
  30.     __u32           quantization;   /* enum v4l2_quantization  量化方式*/
  31.     __u32           xfer_func;  /* enum v4l2_xfer_func 传输函数 */
  32. };
  33. //方法用例C++函数
  34. bool V4L2CaptureVideoData::GetVideoDeviceFormat(v4l2_format &fmt)
  35. {
  36.     fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  37.     int ret=0;
  38.     do
  39.     {
  40.         ret=ioctl(m_video_fd, VIDIOC_G_FMT, &fmt);
  41.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  42.    
  43.     if(ret!=0)
  44.     {
  45.         std::cerr<<"ioctl VIDIOC_G_FMT failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  46.         return false;
  47.     }
  48.     return true;
  49. }
复制代码
ioctl命令 VIDIOC_S_FMT

设置设备当前使用的图像格式
  1. //命令字段定义
  2. #define VIDIOC_S_FMT        _IOWR('V',  5, struct v4l2_format)
  3. //所使用到的结构体信息
  4. struct v4l2_format {
  5.     enum v4l2_buf_type type;   // 帧类型,指示这个格式是用于捕获、输出还是其他类型
  6.     union {
  7.         struct v4l2_pix_format pix;       // 像素格式信息,用于视频捕获等
  8.         struct v4l2_window win;           // 窗口信息,用于视频输出覆盖
  9.         struct v4l2_vbi_format vbi;       // VBI(Vertical Blanking Interval)格式信息
  10.         struct v4l2_sliced_vbi_format sliced; // 切片VBI格式信息
  11.         __u8 raw_data[200];               // 原始数据,用于用户自定义格式
  12.     } fmt;
  13. };
  14. struct v4l2_pix_format {
  15.     __u32           width;         // 视频帧的宽度(像素)
  16.     __u32           height;        // 视频帧的高度(像素)
  17.     __u32           pixelformat;   // 像素格式,使用四字符代码(Four-Character Code, FCC)表示
  18.     __u32           field;         // 字段顺序,如V4L2_FIELD_INTERLACED表示隔行扫描
  19.     __u32           bytesperline;  // 每行的字节数(对于压缩格式,可能表示压缩块的大小)
  20.     __u32           sizeimage;     // 整个图像的大小(字节)
  21.     __u32           colorspace;    // 颜色空间,如V4L2_COLORSPACE_SMPTE170M表示SMPTE 170M标准
  22.     __u32           priv;          // 私有数据,供驱动使用
  23.     __u32           flags;         // 格式标志,如V4L2_PIX_FMT_FLAG_PREMUL_ALPHA表示alpha通道已预乘
  24.    union {
  25.         /* enum v4l2_ycbcr_encoding */
  26.         __u32           ycbcr_enc;
  27.         /* enum v4l2_hsv_encoding */
  28.         __u32           hsv_enc;
  29.     };
  30.     __u32           quantization;   /* enum v4l2_quantization  量化方式*/
  31.     __u32           xfer_func;  /* enum v4l2_xfer_func 传输函数 */
  32. };
  33. //方法用例C++函数
  34. bool V4L2CaptureVideoData::SetVideoDeviceFormat(const v4l2_format &fmt)
  35. {
  36.     int ret=0;
  37.     do
  38.     {
  39.         ret=ioctl(m_video_fd, VIDIOC_S_FMT, &fmt);
  40.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  41.    
  42.     if(ret!=0)
  43.     {
  44.         std::cerr<<"ioctl VIDIOC_S_FMT failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  45.         return false;
  46.     }
  47.     return true;
  48. }
复制代码
ioctl命令 VIDIOC_ENUM_FRAMESIZES

枚举视频设备指定的图像格式下所支持的所有图像分辨率
  1. //命令字段定义
  2. #define VIDIOC_ENUM_FRAMESIZES  _IOWR('V', 74, struct v4l2_frmsizeenum)
  3. //所使用到的结构体信息
  4. struct v4l2_frmsizeenum {
  5.     __u32   index;              // 索引,从 0 开始
  6.     __u32   pixel_format;       // 像素格式(例如 V4L2_PIX_FMT_YUYV)
  7.     __u32   type;             // 帧尺寸类型,可以是离散、连续或步进
  8.     union {
  9.         struct v4l2_frmsize_discrete {
  10.             __u32   width;      // 宽度
  11.             __u32   height;     // 高度
  12.         } discrete;              // 离散帧大小
  13.         struct v4l2_frmsize_stepwise {
  14.             __u32   min_width;   // 最小宽度
  15.             __u32   min_height;  // 最小高度
  16.             __u32   max_width;   // 最大宽度
  17.             __u32   max_height;  // 最大高度
  18.             __u32   step_width;   // 步长宽度
  19.             __u32   step_height;  // 步长高度
  20.         } stepwise;              // 逐步帧大小
  21.     } frm_size;                 // 帧大小信息
  22.     __u32   reserved[2];        // 保留字段
  23. };
  24. //方法用例C++函数
  25. bool V4L2CaptureVideoData::EnumVideoDeviceFrameSize(const unsigned int pixel_format,std::list<struct v4l2_frmsizeenum> &frmsize)
  26. {
  27.     frmsize.clear();
  28.     struct v4l2_frmsizeenum tmp_frmsize;
  29.     tmp_frmsize.index=0;
  30.     tmp_frmsize.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  31.     tmp_frmsize.pixel_format = pixel_format;
  32.     int ret=0;
  33.     while(!((ret == -1) && (errno != EINTR) && (errno != EAGAIN)))
  34.     {
  35.         ret=ioctl(m_video_fd,VIDIOC_ENUM_FRAMESIZES,&tmp_frmsize);
  36.         if(ret==0)
  37.         {
  38.             frmsize.push_back(tmp_frmsize);
  39.             tmp_frmsize.index++;
  40.         }
  41.     }
  42.     return true;
  43. }
复制代码
ioctl命令 VI4DIOC_ENUM_FRAMEINTERVALS

枚举设备在指定的图像格式以及分辨率下所支持的所有视频帧率
  1. //命令字段定义
  2. #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum)
  3. //所使用到的结构体信息
  4. struct v4l2_frmivalenum {
  5.     __u32 index;            // 枚举索引,用于遍历所有支持的帧率和帧间隔
  6.     __u32 pixel_format;     // 像素格式,使用四字符代码(FCC)表示
  7.     __u32 width;            // 帧宽度
  8.     __u32 height;           // 帧高度
  9.     __u32 type;             // 帧间隔类型,可以是离散、连续或步进
  10.     union {
  11.         struct v4l2_fract discrete;  // 离散帧间隔(或帧率)
  12.         struct v4l2_frmival_stepwise stepwise;  // 步进帧间隔(或帧率)
  13.     };
  14.     __u32 reserved[2];      // 保留字段,供未来扩展使用
  15. };
  16. struct v4l2_fract {
  17.     __u32 numerator;   // 分子
  18.     __u32 denominator; // 分母
  19. };
  20. struct v4l2_frmival_stepwise {
  21.     struct v4l2_fract min;   // 最小帧间隔(或帧率)
  22.     struct v4l2_fract max;   // 最大帧间隔(或帧率)
  23.     struct v4l2_fract step;  // 步长
  24. };
  25. //方法用例C++函数
  26. bool V4L2CaptureVideoData::EnumVideoDeviceFrameIntervals(const unsigned int pixel_format,const unsigned int width,const unsigned int height,std::list<struct v4l2_frmivalenum> &frmivals)
  27. {
  28.     frmivals.clear();
  29.     struct v4l2_frmivalenum tmp_frmival;
  30.     tmp_frmival.index = 0;
  31.     tmp_frmival.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  32.     tmp_frmival.pixel_format = pixel_format;
  33.     tmp_frmival.width = width;
  34.     tmp_frmival.height = height;
  35.     int ret=0;
  36.     while(!((ret == -1) && (errno != EINTR) && (errno != EAGAIN)))
  37.     {
  38.         ret=ioctl(m_video_fd, VIDIOC_ENUM_FRAMEINTERVALS, &tmp_frmival);
  39.         if(ret==0)
  40.         {
  41.             frmivals.push_back(tmp_frmival);
  42.             tmp_frmival.index++;
  43.         }
  44.     }
  45.     return true;
  46. }
复制代码
ioctl命令 VIDIOC_STREAMON

开始视频流式收罗
  1. //命令字段定义
  2. #define VIDIOC_STREAMON      _IOW('V', 18, int)
  3. //方法用例C++函数
  4. bool V4L2CaptureVideoData::StartVideoStreamCapture()
  5. {
  6.     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  7.     int ret=0;
  8.     do
  9.     {
  10.         ret=ioctl(m_video_fd, VIDIOC_STREAMON, &type);
  11.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  12.    
  13.     if(ret!=0)
  14.     {
  15.         std::cerr<<"ioctl VIDIOC_STREAMON failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  16.         return false;
  17.     }
  18.     return true;
  19. }
复制代码
ioctl命令 VIDIOC_STREAMOFF

停止视频流式收罗
  1. //命令字段定义
  2. #define VIDIOC_STREAMOFF     _IOW('V', 19, int)
  3. //方法用例C++函数
  4. bool V4L2CaptureVideoData::StopVideoStreamCapture()
  5. {
  6.     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  7.     int ret=0;
  8.     do
  9.     {
  10.         ret=ioctl(m_video_fd, VIDIOC_STREAMOFF, &type);
  11.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  12.    
  13.     if(ret!=0)
  14.     {
  15.         std::cerr<<"ioctl VIDIOC_STREAMOFF failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  16.         return false;
  17.     }
  18.     return true;
  19. }
复制代码
ioctl命令 VIDIOC_REQBUFS

申请设备的视频数据缓存buffer
  1. //命令字段定义
  2. #define VIDIOC_REQBUFS      _IOWR('V',  8, struct v4l2_requestbuffers)
  3. //所使用到的结构体信息
  4. struct v4l2_requestbuffers {
  5.     __u32   count;             // 请求的缓冲区数量
  6.     __u32   type;              // 缓冲区类型(例如 V4L2_BUF_TYPE_VIDEO_CAPTURE)
  7.     __u32   memory;            // 内存类型(例如 V4L2_MEMORY_MMAP)
  8.     __u32   reserved[2];       // 保留字段
  9. };
  10. //方法用例C++函数
  11. bool V4L2CaptureVideoData::RequestVideoBuffer(const unsigned int request_count,const unsigned int memeory_type,v4l2_requestbuffers &requestbuf)
  12. {
  13.     requestbuf.count=request_count;
  14.     requestbuf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  15.     requestbuf.memory=memeory_type;
  16.     int ret=0;
  17.     do
  18.     {
  19.         ret=ioctl(m_video_fd, VIDIOC_REQBUFS, &requestbuf);
  20.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  21.     if(ret!=0)
  22.     {
  23.         std::cerr<<"ioctl VIDIOC_REQBUFS failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  24.         return false;
  25.     }
  26.     return true;
  27. }
复制代码
ioctl命令 VIDIOC_QUERYBUF

获取设备已经申请到的缓存buffer信息
  1. //命令字段定义
  2. #define VIDIOC_QUERYBUF     _IOWR('V',  9, struct v4l2_buffer)
  3. //所使用到的结构体信息
  4. struct v4l2_buffer {
  5.     __u32               index;          // 缓冲区索引
  6.     __u32               type;           // 缓冲区类型(例如 V4L2_BUF_TYPE_VIDEO_CAPTURE)
  7.     __u32               bytesused;      // 使用的字节数
  8.     __u32               flags;          // 标志位
  9.     __u32               field;          // 场类型(例如 V4L2_FIELD_NONE)
  10.     struct timeval      timestamp;   // 缓冲区的时间戳
  11.     struct v4l2_timecode    timecode;   // 时间码(如果设备支持)
  12.     __u32           sequence;   // 缓冲区序列号(如果设备支持)
  13.     /* memory location */
  14.     __u32           memory;     // 缓冲区的内存类型
  15.     union {
  16.         __u32           offset;  //mmap的偏移量
  17.         unsigned long   userptr;   // 用户空间指针
  18.         struct v4l2_plane *planes;  // 平面地址数组,用于多平面格式
  19.         __s32       fd;
  20.     } m;
  21.     __u32           length;     // 缓冲区长度(以字节为单位)
  22.     __u32           reserved2;
  23.     union {
  24.         __s32       request_fd;
  25.         __u32       reserved;
  26.     };
  27. };
  28. //方法用例C++函数
  29. bool V4L2CaptureVideoData::GetVideoBuffer(const unsigned int memory_type,unsigned int index,struct v4l2_buffer &video_buffer)
  30. {
  31.     video_buffer.index = index;
  32.     video_buffer.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  33.     video_buffer.memory = memory_type;
  34.     int ret=0;
  35.     do
  36.     {
  37.         ret=ioctl(m_video_fd, VIDIOC_QUERYBUF, &video_buffer);
  38.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  39.     if(ret!=0)
  40.     {
  41.         std::cerr<<"ioctl VIDIOC_QUERYBUF failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  42.         return false;
  43.     }
  44.     return true;
  45. }
复制代码
ioctl命令 VIDIOC_QBUF

将设备已经申请好的缓存buffer放入到数据捕获队列中
  1. //命令字段定义
  2. #define VIDIOC_QBUF     _IOWR('V', 15, struct v4l2_buffer)
  3. //所使用到的结构体信息
  4. struct v4l2_buffer {
  5.     __u32               index;          // 缓冲区索引
  6.     __u32               type;           // 缓冲区类型(例如 V4L2_BUF_TYPE_VIDEO_CAPTURE)
  7.     __u32               bytesused;      // 使用的字节数
  8.     __u32               flags;          // 标志位
  9.     __u32               field;          // 场类型(例如 V4L2_FIELD_NONE)
  10.     struct timeval      timestamp;   // 缓冲区的时间戳
  11.     struct v4l2_timecode    timecode;   // 时间码(如果设备支持)
  12.     __u32           sequence;   // 缓冲区序列号(如果设备支持)
  13.     /* memory location */
  14.     __u32           memory;     // 缓冲区的内存类型
  15.     union {
  16.         __u32           offset;  //mmap的偏移量
  17.         unsigned long   userptr;   // 用户空间指针
  18.         struct v4l2_plane *planes;  // 平面地址数组,用于多平面格式
  19.         __s32       fd;
  20.     } m;
  21.     __u32           length;     // 缓冲区长度(以字节为单位)
  22.     __u32           reserved2;
  23.     union {
  24.         __s32       request_fd;
  25.         __u32       reserved;
  26.     };
  27. };
  28. //方法用例C++函数
  29. bool V4L2CaptureVideoData::PushVideoBuffer(const v4l2_buffer &video_buffer)
  30. {
  31.     int ret=0;
  32.     do
  33.     {
  34.         ret=ioctl(m_video_fd, VIDIOC_QBUF, &video_buffer);
  35.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  36.    
  37.     if(ret!=0)
  38.     {
  39.         std::cerr<<"ioctl VIDIOC_QBUF failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  40.         return false;
  41.     }
  42.     return true;
  43. }
复制代码
ioctl命令 VIDIOC_DQBUF

将设备已经申请好的缓存buffer从视频数据捕获队列中取出
  1. //命令字段定义
  2. #define VIDIOC_DQBUF        _IOWR('V', 17, struct v4l2_buffer)
  3. //所使用到的结构体信息
  4. struct v4l2_buffer {
  5.     __u32               index;          // 缓冲区索引
  6.     __u32               type;           // 缓冲区类型(例如 V4L2_BUF_TYPE_VIDEO_CAPTURE)
  7.     __u32               bytesused;      // 使用的字节数
  8.     __u32               flags;          // 标志位
  9.     __u32               field;          // 场类型(例如 V4L2_FIELD_NONE)
  10.     struct timeval      timestamp;   // 缓冲区的时间戳
  11.     struct v4l2_timecode    timecode;   // 时间码(如果设备支持)
  12.     __u32           sequence;   // 缓冲区序列号(如果设备支持)
  13.     /* memory location */
  14.     __u32           memory;     // 缓冲区的内存类型
  15.     union {
  16.         __u32           offset;  //mmap的偏移量
  17.         unsigned long   userptr;   // 用户空间指针
  18.         struct v4l2_plane *planes;  // 平面地址数组,用于多平面格式
  19.         __s32       fd;
  20.     } m;
  21.     __u32           length;     // 缓冲区长度(以字节为单位)
  22.     __u32           reserved2;
  23.     union {
  24.         __s32       request_fd;
  25.         __u32       reserved;
  26.     };
  27. };
  28. //方法用例C++函数
  29. bool V4L2CaptureVideoData::PopVideoBuffer(const unsigned int memory_type,struct v4l2_buffer &video_buffer)
  30. {
  31.     video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  32.     video_buffer.memory = memory_type;
  33.     int ret=0;
  34.     do
  35.     {
  36.         ret=ioctl(m_video_fd, VIDIOC_DQBUF, &video_buffer);
  37.     } while (ret == -1 && ((errno == EINTR) || (errno == EAGAIN)));
  38.    
  39.     if(ret!=0)
  40.     {
  41.         std::cerr<<"ioctl VIDIOC_DQBUF failed:("<<"errno="<<errno<<",strerror="<<strerror(errno)<<")"<<std::endl;
  42.         return false;
  43.     }
  44.     return true;
  45. }
复制代码
V4L2四种模式下的视频设备数据收罗

摄像头原始数据读取——V4L2(read模式,V4L2_CAP_READWRITE)
摄像头原始数据读取——V4L2(mmap模式,V4L2_MEMORY_MMAP)
摄像头原始数据读取——V4L2(userptr模式,V4L2_MEMORY_USERPTR)
摄像头原始数据读取——V4L2(dmabuf模式,V4L2_MEMORY_DMABUF)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

杀鸡焉用牛刀

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表