欧美三区_成人在线免费观看视频_欧美极品少妇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)論
主站蜘蛛池模板: 99精品视频在线免费观看 | 久久网精品视频 | 国产日韩中文字幕 | 国产一区二区三区在线视频 | 成片在线看一区二区草莓 | 中文在线视频 | av天天看 | 97成人精品 | 香蕉视频黄色 | 欧美日韩亚洲区久久综合 | 久久精品99 | 精品一区二区三区在线观看l | 杀破狼在线观看 | 乱子伦xxxxvideos| 国产在线不卡 | 毛片黄片 | 97婷婷狠狠成人免费视频 | 亚洲欧美中文日韩在线v日本 | 欧美一级黄视频 | 国产精品久久久久久久久久久久久 | 91在线 | porny | 欧美| 丁香综合五月 | 伊人久久99亚洲精品久久频 | 日韩激情中文字幕一区二区 | 91视频观看 | 亚洲国产日产韩国欧美综合 | 国内精品视频 | 夜夜夜操操操 | 亚洲激情视频在线观看 | 久久久入口 | 日本一本久 | 污网站观看| 国产一区二区三区久久 | 君岛美绪一区二区三区 | 成人毛片免费视频播放 | 国产精品成人免费观看 | 一起射综合网 | 成人黄色在线视频 | 色婷婷综合久久久中字幕精品久久 | 91视频观看 | 天天操天天干天天爽 |