欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

v4l2簡(jiǎn)介

系統(tǒng) 2174 0

V4L是linux內(nèi)核中關(guān)于視頻設(shè)備的子系統(tǒng),為linux下的視頻驅(qū)動(dòng)提供了統(tǒng)一的接口,使應(yīng)用程序可以使用統(tǒng)一的API操作不同的視頻設(shè)備,簡(jiǎn)化視頻系統(tǒng)的開發(fā)與維護(hù)

V4L2相比與V4L有更好的擴(kuò)展性和靈活性

(一)V4L2支持設(shè)備:

V4L2可以支持多種設(shè)備,可以有以下幾種接口:

1)視頻采集接口

2)視頻輸出接口

3)直接傳輸視頻接口:將視頻采集設(shè)備上采集的信號(hào)直接輸出到視頻輸出設(shè)備上,不用經(jīng)過系統(tǒng)CPU

4)視頻間隔消隱信號(hào)接口(VBI Interface):使引用可以訪問傳輸消隱期的視頻信號(hào)

5)收音機(jī)接口:

?

(二)V4L2設(shè)備處理流程

打開V4L2設(shè)備節(jié)點(diǎn)

      
        int
      
       fd = open(
      
        "
      
      
        /dev/video0
      
      
        "
      
      ,O_RDWR |O_NONBLOCK);
    

配置設(shè)備/查詢?cè)O(shè)備屬性

      
        int
      
       ioctl (
      
        int
      
       fd, unsigned 
      
        long
      
      
        int
      
       request, ...
      
        /*
      
      
        args
      
      
        */
      
      ) ;
    

常見的request命令:

VIDIOC_REQBUFS:在內(nèi)核空間中分配幀緩沖區(qū)

      
        struct
      
      
         v4l2_requestbuffers req;

req.count
      
      =
      
        4
      
      
        ;

req.type
      
      =
      
        V4L2_BUF_TYPE_VIDEO_CAPTURE;

req.memory
      
      =
      
        V4L2_MEMORY_MMAP;

ioctl(fd,VIDIOC_REQBUFS,
      
      &req);
    

VIDIOC_QUERYBUF:將REQBUFS中分配的緩存轉(zhuǎn)換成物理地址,并將物理地址映射到用戶空間

      
        for
      
       (n_buffers = 
      
        0
      
      ; n_buffers < req.count; ++
      
        n_buffers)

{

        
      
      
        struct
      
      
         v4l2_buffer buf;

        memset(
      
      &buf,
      
        0
      
      ,
      
        sizeof
      
      
        (buf));

        buf.type 
      
      =
      
        V4L2_BUF_TYPE_VIDEO_CAPTURE;

        buf.memory 
      
      =
      
        V4L2_MEMORY_MMAP;

        buf.index 
      
      =
      
        n_buffers;

        
      
      
        if
      
       (-
      
        1
      
       == ioctl(fd, VIDIOC_QUERYBUF, &
      
        buf))

        {

                printf(
      
      
        "
      
      
        error in VIDIOC_QUERYBUF\n
      
      
        "
      
      
        );

                
      
      
        return
      
       -
      
        1
      
      
        ;

        }

        buffers[n_buffers].length
      
      =
      
         buf.length;

        buffers[n_buffers].start
      
      =mmap (NULL,buf.length,PROT_READ |
      
         PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);

        
      
      
        if
      
       (MAP_FAILED==
      
         buffers[n_buffers].start)

                
      
      
        return
      
       -
      
        1
      
      
        ;

}
      
    

VIDIOC_QUERYCAP:查詢驅(qū)動(dòng)功能

      
        struct
      
      
         v4l2_capability cap;


      
      
        if
      
      ( ioctl(fd,VIDIOC_QUERYCAP,&cap) == -
      
        1
      
      
        )

        printf(
      
      
        "
      
      
        error\n
      
      
        "
      
      
        );

printf(
      
      
        "
      
      
        capability:\n
      
      
        "
      
      
        );

printf(
      
      
        "
      
      
        driver:%s\n
      
      
        "
      
      
        ,cap.driver);

printf(
      
      
        "
      
      
        card:%s\n
      
      
        "
      
      
        ,cap.card);

printf(
      
      
        "
      
      
        bus info:%s\n
      
      
        "
      
      
        ,cap.bus_info);

printf(
      
      
        "
      
      
        version:%d\n
      
      
        "
      
      
        ,cap.version);

printf(
      
      
        "
      
      
        capabilities:%x\n
      
      
        "
      
      ,cap.capabilities);
    

VIDIOC_ENUM_FMT:獲取當(dāng)前驅(qū)動(dòng)支持的視頻格式

      
        struct
      
      
         v4l2_fmtdesc fmtdesc;

fmtdesc.index 
      
      = 
      
        0
      
      
        ;

fmtdesc.type
      
      =
      
        V4L2_BUF_TYPE_VIDEO_CAPTURE;

printf(
      
      
        "
      
      
        fmtdesc:\n
      
      
        "
      
      
        );


      
      
        while
      
      (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -
      
        1
      
      
        )

{

        printf(
      
      
        "
      
      
        \t%d.%s\n
      
      
        "
      
      ,fmtdesc.index+
      
        1
      
      
        ,fmtdesc.description);

        fmtdesc.index
      
      ++
      
        ;

}
      
    

VIDIOC_G/S_FMT:讀取/設(shè)置當(dāng)前驅(qū)動(dòng)的視頻捕捉格式

      
        struct
      
      
         v4l2_format format;

memset(
      
      &format, 
      
        0
      
      , 
      
        sizeof
      
      (
      
        struct
      
      
         v4l2_format));

format.type 
      
      =
      
         V4L2_BUF_TYPE_VIDEO_CAPTURE;


      
      
        if
      
      ( ioctl(fd, VIDIOC_G_FMT, &format) == -
      
        1
      
      
        )

{

        printf(
      
      
        "
      
      
        VIDIOC_G_FMT error\n
      
      
        "
      
      
        );

        
      
      
        return
      
       -
      
        1
      
      
        ;

}


      
      
        struct
      
      
         v4l2_pix_format pix_format;

pix_format 
      
      =
      
         format.fmt.pix;

printf(
      
      
        "
      
      
        pix_format\n
      
      
        "
      
      
        );

printf(
      
      
        "
      
      
        width:%d\n
      
      
        "
      
      
        ,pix_format.width);

printf(
      
      
        "
      
      
        height:%d\n
      
      
        "
      
      
        ,pix_format.height);

printf(
      
      
        "
      
      
        bytesperline:%d\n
      
      
        "
      
      
        ,pix_format.bytesperline);

printf(
      
      
        "
      
      
        sizeimage:%d\n
      
      
        "
      
      ,pix_format.sizeimage);
    

VIDIOC_TRY_FMT:驗(yàn)證當(dāng)前驅(qū)動(dòng)的顯示格式

VIDIOC_CROPCAP:查詢驅(qū)動(dòng)的修剪能力

VIDIOC_G/S_CROP:讀取/設(shè)置視頻信號(hào)的邊框

      
        struct
      
      
         v4l2_cropcap cropcap;


      
      
        struct
      
      
         v4l2_crop crop;

cropcap.type 
      
      =
      
         V4L2_BUF_TYPE_VIDEO_CAPTURE;  


      
      
        if
      
      (
      
        0
      
       == ioctl(fd, VIDIOC_CROPCAP, &
      
        cropcap))  

{  

        crop.type 
      
      =
      
         V4L2_BUF_TYPE_VIDEO_CAPTURE;  

        crop.c 
      
      =
      
         cropcap.defrect;  

        
      
      
        if
      
      (-
      
        1
      
       == ioctl(fd, VIDIOC_S_CROP, &
      
        crop))

        {

                printf(
      
      
        "
      
      
        VIDIOC_S_CROP error\n
      
      
        "
      
      
        );

                
      
      
        return
      
       -
      
        1
      
      
        ;

        }

}
      
    

VIDIOC_QBUF:把緩存區(qū)放入緩存隊(duì)列

VIDIOC_DQBUF:把緩存去從緩存隊(duì)列中取出

      unsigned 
      
        int
      
      
         i;


      
      
        enum
      
      
         v4l2_buf_type type;


      
      
        for
      
       (i = 
      
        0
      
      ; i< 
      
        4
      
      ; ++
      
        i)

{

        
      
      
        struct
      
      
         v4l2_buffer buf;

        buf.type 
      
      =
      
        V4L2_BUF_TYPE_VIDEO_CAPTURE;

        buf.memory 
      
      =
      
        V4L2_MEMORY_MMAP;

        buf.index 
      
      =
      
         i;

        ioctl (fd,VIDIOC_QBUF, 
      
      &
      
        buf);

}

type 
      
      =
      
        V4L2_BUF_TYPE_VIDEO_CAPTURE;

ioctl (fd,VIDIOC_STREAMON, 
      
      &
      
        type);


      
      
        struct
      
      
         v4l2_buffer buf;

buf.type 
      
      =
      
         V4L2_BUF_TYPE_VIDEO_CAPTURE;

buf.memory 
      
      =
      
        V4L2_MEMORY_MMAP;


      
      
        if
      
      ( ioctl (fd,VIDIOC_DQBUF, &buf)==-
      
        1
      
      
        )

{

        printf(
      
      
        "
      
      
        error in VIDIOC_DQBUF\n
      
      
        "
      
      
        );

        
      
      
        return
      
       -
      
        1
      
      
        ;

}
      
    

VIDIOC_STREAMON:開始視頻顯示函數(shù)

VIDIOC_STREAMOFF:結(jié)束視頻顯示函數(shù)

VIDIOC_QUERYSTD:檢查當(dāng)前視頻設(shè)備支持的標(biāo)準(zhǔn),亞洲一般使用PAL制式攝像頭,歐洲一般使用NTSC攝像頭

      
        v4l2_std_id std;


      
      
        int
      
      
         ret;


      
      
        do
      
      
        

{

          ret 
      
      = ioctl(fd,VIDIOC_QUERYSTD,&
      
        std);                  

}
      
      
        while
      
      (-
      
        1
      
      ==ret && errno==
      
        EAGAIN);


      
      
        switch
      
      
        (std)

{


      
      
        case
      
      
         V4L2_STD_NTSC:

   
      
      
        //


      
      
        case
      
      
         V4L2_STD_PAL:

   
      
      
        //
      
         

} 
    

處理v4l2視頻數(shù)據(jù)

v4l2設(shè)定了三種應(yīng)用程序與驅(qū)動(dòng)的交互方式:

1)直接讀取設(shè)備文件方式read/write

2)mmap映射方式

3)用戶指針方式

mmap方式:驅(qū)動(dòng)將內(nèi)部數(shù)據(jù)空間映射到應(yīng)用程序空間上,雙方直接在這個(gè)空間上進(jìn)行數(shù)據(jù)交換

用戶指針方式:首先由應(yīng)用程序申請(qǐng)一段緩沖區(qū),然后將緩沖區(qū)傳給驅(qū)動(dòng),驅(qū)動(dòng)將其作為緩沖區(qū),從而實(shí)現(xiàn)內(nèi)存共享

直接read/write:一般配合select使用,直接讀取設(shè)備文件的方式進(jìn)行I/O

關(guān)閉設(shè)備

調(diào)用close關(guān)閉文件描述符,如果進(jìn)行了內(nèi)存映射,關(guān)閉之前還需要munmap解除映射

v4l2簡(jiǎn)介


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 欧美区在线 | 久草视频手机在线观看 | 亚洲精品久久久久中文字幕欢迎你 | 欧美第5页 | 香港三级日本三级韩国三级韩 | 国产精品色在线网站 | 国产www视频| 国产精品中文字幕在线观看 | 九九爱国产 | 久久免费看少妇高潮A片JA | 五月丁香啪啪. | 超碰伊人网 | 午夜小视频免费 | 色偷偷偷| 欧美十区| 成人精品视频一区二区三区 | 91亚洲国产成人久久精品网站 | 日韩免费视频播播 | 一级@片 | 免费人成又黄又爽的视频强 | 嫩草www | 激情五月激情综合网 | 免费观看性欧美大片无片 | 丰满岳妇乱一区二区三区 | 精品视频麻豆入口 | 2022国产成人精彩在线视频 | 一级毛片直接看 | 一级做a爰片久久毛片人呢 达达兔午夜起神影院在线观看麻烦 | 超碰97人 | 97婷婷狠狠成人免费视频 | 91精品啪国产在线观看免费牛牛 | 亚洲国产精品久久久久网站 | 婷婷久月| 欧美三极 | 中文字幕无线码一区二区三区 | 美女下面直流白浆视频 | 91高清在线成人免费观看 | 亚洲国产日韩在线观看 | 欧美一区二区三区在线播放 | 久久一级 | 欧美精品一区二区三区免费播放 |