惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
C
Cybersecurity and Infrastructure Security Agency CISA
N
News and Events Feed by Topic
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
Scott Helme
Scott Helme
P
Palo Alto Networks Blog
S
Schneier on Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Tor Project blog
量子位
G
Google Developers Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
B
Blog RSS Feed
NISL@THU
NISL@THU
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
AWS News Blog
AWS News Blog
爱范儿
爱范儿
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
Security Archives - TechRepublic
Security Archives - TechRepublic
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
S
Secure Thoughts
Cloudbric
Cloudbric
aimingoo的专栏
aimingoo的专栏
L
Lohrmann on Cybersecurity
TaoSecurity Blog
TaoSecurity Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Hacker News: Ask HN
Hacker News: Ask HN
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
S
Security @ Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
P
Proofpoint News Feed
V
V2EX
Martin Fowler
Martin Fowler
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Cloudflare Blog
SecWiki News
SecWiki News
罗磊的独立博客
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
小众软件
小众软件
The Last Watchdog
The Last Watchdog

博客园 - 邗影

关于音频PA结构腔体 球面渲染 关于linux和shi脚本常用的通配符 关于fread读不满一块和读不满count的返回值 如何去掉merge UBI的覆盖写和擦除 DTSI 多个模块共用同一个 GPIO 引脚冲突 问题汇总 debug比release程序启动的快 关于CPU占用优先级的调整 关于蜂鸣器发声 麦序与声源定位 关于squashfs压缩挂载 软连接生成 线程退出未定义行为 linux文件查找 C语言弱函数 数据传输报错port unreachable D3D11绘制三角形 关于延迟测试 v4l2检测 关于数据库的性能 流媒体小记包含一些面试问题 流媒体ZLM配置vscode远程开发 关于SPS中的帧率问题 Linux编译问题 SSl冲突问题 D3D初始化窗口显示 关于线程池
v4l2视频采集
邗影 · 2025-08-10 · via 博客园 - 邗影
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/mman.h>
#include<linux/videodev2.h>

int main()
{
    int fd = open("/dev/video0",O_RDWR);
    if(fd <0)
    {
       printf("open error");
       return -1;
    }
    
    struct v4l2_fmtdesc fmt;
    
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//must
    int i =0;
    while(1)
    {
            fmt.index=i++;//must 
        int ret =ioctl(fd,VIDIOC_ENUM_FMT,&fmt);
        if(ret <0){
           printf("----ioctl enum ok-- %d\n",fmt.index);
           break;
        }
        else{
            printf("fmt index:%d\n",fmt.index);
             printf("fmt flag:%d\n",fmt.flags);
              printf("fmt description: %s\n",fmt.description);
              unsigned char*ptr=&fmt.pixelformat;
               printf("fmt pixel fmt: %c %c %c %c\n",ptr[0],ptr[1],ptr[2],ptr[3]);
        }
    }
    //set cap fmt  video0:1jpeg,2YUV
    struct v4l2_format  sfmt;
    sfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    sfmt.fmt.pix.width = 1920;
    sfmt.fmt.pix.height =1080;
    sfmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
    int ret =ioctl(fd,VIDIOC_S_FMT,&sfmt);
    if(ret <0)
    {
        printf("set fmt error\n");
        
    }
    
    struct v4l2_format  sfmt2;
    sfmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    ret =ioctl(fd,VIDIOC_G_FMT,&sfmt2);
    if(ret <0)
    {
        printf("set fmt error\n");
        
    }else{
    //设置的与实际采集得到的可能并不一样,比如设置1080P,实际采集的是720P
     printf("sfmt.fmt.pix.width %d\n",sfmt.fmt.pix.width);
     printf("sfmt.fmt.pix.height %d\n",sfmt.fmt.pix.height);
    
    }
    
    //malloc kernal space
    struct v4l2_requestbuffers v4l2buf;
    v4l2buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
    v4l2buf.count = 4;//max is 4
    v4l2buf.memory = V4L2_MEMORY_MMAP;//ying she
    ret =ioctl(fd,VIDIOC_REQBUFS,&v4l2buf);
    if(ret <0)
    {
        printf("req memory error");
    }
    //printf("-----------------2--------------\n");
    //map
    struct v4l2_buffer buf;
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    unsigned char* mptr[4];//save map to user mem first address
    int lensize[4];
    //check kernal memory
    for(int i =0;i<4;i++)
    {
        buf.index = i;
        ret =ioctl(fd,VIDIOC_QUERYBUF,&buf);
        if(ret <0)
        {
            printf("check kernal mem error\n");
        }else{
          //map user memory
          mptr[i]=mmap(NULL,buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,buf.m.offset);
          lensize[i] = buf.length;
          //use over
          ret =ioctl(fd,VIDIOC_QBUF,&buf);
          if(ret<0)
          {
             printf("mmp error");
          }
        }
    }
    //printf("-----------------3--------------\n");
    //start cap
    int type =V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd,VIDIOC_STREAMON,&type);
    if(ret <0)
    {
        printf("stream on error");
    }
    //printf("-----------------3-0-------------\n");
    
    //get data from queue
    FILE* fp=fopen("./m.yuyv","w+");
    int capnum =100;
    while(capnum-- >0)//帧率有单独的控制属性可以设置
    {
        
        struct v4l2_buffer readbuf;
        readbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        ret =ioctl(fd,VIDIOC_DQBUF,&readbuf);//use virtul machine usb 3.1,or not will hold
        if(ret <0)
        {
            printf("read data error");
        }else{
            
            int size = fwrite(mptr[readbuf.index],readbuf.length,1,fp);
            fflush(fp);
            printf("write size:%d",size);
            ret = ioctl(fd,VIDIOC_QBUF,&readbuf);
            
            if(ret <0)
            {
            printf("qbuf error\n");
            }
            
        }
    
    }
    printf("-----------------4--------------\n");
    //stop cap
    ret = ioctl(fd,VIDIOC_STREAMOFF,&type);
    if(ret <0)
    {
        printf("stop error\n");
    }
    //release map
    
    for(int i = 0;i<4;i++)
    {
      munmap(mptr[i],lensize[i]);
    }
    
    fclose(fp);
    close(fd);
    return 0;
}