欧美三区_成人在线免费观看视频_欧美极品少妇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)論
主站蜘蛛池模板: 国产一区在线观看免费 | 亚洲国产精品91 | 亚洲国产精品91 | 91免费看片 | 欧美激情免费 | 欧美中文在线视频 | www97影院| 国产区视频在线观看 | 国产精品视频在线播放 | 成人性视频免费网站 | 亚洲一区二区在线视频 | 亚洲色婷婷久久精品AV蜜桃久久 | 亚洲精品国产成人 | 久久九九精品一区二区 | 国产精品自线在线播放 | 日产一一到六区麻豆 | 国产午夜精品视频免费不卡69堂 | 久色乳综合思思在线视频 | 亚洲一区二区三区免费看 | 精品国产AV色一区二区深夜久久 | 蜜桃传媒一区二区亚洲AV | 久久久日韩精品一区二区 | 视频二区 | 97风流梦电影 | 成人免费观看国产高清 | 久久国产乱子伦精品免 | 色综合久久天天综合网 | 无名者电影在线完整版免费 | 精品国产一区二区三区免费 | 成人超碰| 国产精品一区二区三区在线播放 | 欧美成人全部费免网站 | 男女性刺激爽爽免费视频 | 欧美疯狂xxxx乱大交视频 | 国产成人精品一区二区仙踪林 | 免费观看的av | 成人免播放器午夜视频 | 一区二区三区精品视频 | 欧美一区二区三区在线观看视频 | 玖玖啪| 午夜欧美精品 |