1. 程式人生 > >V4L2視訊應用程式程式設計架構

V4L2視訊應用程式程式設計架構

參考 http://blog.csdn.net/tsuibeyond/article/details/50654823

         http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html

      1.開啟裝置fd = open(FILE_VIDEO1, O_RDWR))

       2.取得裝置的capability 看看裝置具有什麼功能 比如是否具有視訊輸入 或者音訊輸入輸出等 VIDIOC QUERYCAP struct v4l2 capabilit

      3 選擇視訊輸入 一個視訊裝置可以有多個視訊輸入 VIDIOC S INPUT struct v4l2 input

      4 設定視訊的制式和幀格式 制式包括PAL NTSC 幀的格式個包括寬度和高度等 VIDIOC S STD VIDIOC S FMT struct v4l2 std id struct v4l2 format 

      5 向驅動申請幀緩衝 一般不超過5個 struct v4l2 requestbuffers 

      6 將申請到的幀緩衝對映到使用者空間 這樣就可以直接操作採集到的幀了 而不必去複製 mmap 

      7 將申請到的幀緩衝全部入佇列 以便存放採集到的資料 VIDIOC QBUF struct v4l2 buffer 

      8 開始視訊的採集 VIDIOC STREAMON

      9 出佇列以取得已採集資料的幀緩衝 取得原始採集資料 VIDIOC DQBUF 

      10 將緩衝重新入佇列尾 這樣可以迴圈採集 VIDIOC QBUF 

     11 停止視訊的採集 VIDIOC STREAMOFF 12 關閉視訊裝置 close fd ;

  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <linux/videodev2.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <sys/ioctl.h>
  8. #include <sys/mman.h>
  9. #include <unistd.h>
  10. #include <opencv2/core/core.hpp>
  11. #include <opencv2/highgui/highgui.hpp>
  12. #include <iostream>
  13. uchar *buffer;                          //buffers 指標記錄緩衝幀
  14. #define IMAGEWIDTH 640
  15. #define IMAGEHEIGHT 480
  16. #define TRUE 1
  17. #define FALSE 0
  18. #define FILE_VIDEO1 "/dev/video0"
  19. staticint fd;                          //裝置描述符
  20. struct v4l2_streamparm setfps;          //結構體v4l2_streamparm來描述視訊流的屬性
  21. struct v4l2_capability cap;             //取得裝置的capability,看看裝置具有什麼功能,比如是否具有視訊輸入,或者音訊輸入輸出等
  22. struct v4l2_fmtdesc fmtdesc;            //列舉裝置所支援的image format:  VIDIOC_ENUM_FMT
  23. struct v4l2_format fmt,fmtack;          //子結構體struct v4l2_pix_format設定攝像頭採集視訊的寬高和型別:V4L2_PIX_FMT_YYUV V4L2_PIX_FMT_YUYV
  24. struct v4l2_requestbuffers req;         //向驅動申請幀緩衝的請求,裡面包含申請的個數
  25. struct v4l2_buffer buf;                 //代表驅動中的一幀
  26. enum   v4l2_buf_type type;              //幀型別
  27. int init_v4l2(void);                    //初始化
  28. int v4l2_grab(void);                    //採集
  29. int main()  
  30. {  
  31.         printf("first~~\n");  
  32.         if(init_v4l2() == FALSE){      //開啟攝像頭
  33.             printf("Init fail~~\n");  
  34.             exit(1);  
  35.         }  
  36.         printf("second~~\n");  
  37.         if(v4l2_grab() == FALSE){  
  38.             printf("grab fail~~\n");  
  39.             exit(2);  
  40.         }  
  41.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;           //Stream 或者Buffer的型別。此處肯定為V4L2_BUF_TYPE_VIDEO_CAPTURE
  42.         buf.memory = V4L2_MEMORY_MMAP;                    //既然是Memory Mapping模式,則此處設定為:V4L2_MEMORY_MMAP
  43.         printf("third~~\n");  
  44.         cvNamedWindow("one",CV_WINDOW_AUTOSIZE);  
  45.         IplImage* img;  
  46.         CvMat cvmat;  
  47.         int i = 100;  
  48.         double t;  
  49.         while(1){  
  50.                 t = (double)cvGetTickCount();                      //呼叫時鐘測時間
  51.                 ioctl(fd,VIDIOC_DQBUF,&buf);  
  52.                 buf.index = 0;  
  53.                 cvmat = cvMat(IMAGEHEIGHT,IMAGEWIDTH,CV_8UC3,(void*)buffer);//CV_8UC3
  54.                 //t = (double)cvGetTickCount();
  55.                 img = cvDecodeImage(&cvmat,1);  
  56.                 //t=(double)cvGetTickCount()-t;
  57.                 //printf("used time is %gms\n",(t/(cvGetTickFrequency()*1000)));
  58.                 if(!img)    printf("No img\n");  
  59.                 cvShowImage("one",img);  
  60.                 cvReleaseImage(&img);  
  61.                 ioctl(fd,VIDIOC_QBUF,&buf);                      //在 driver 內部管理著兩個 buffer queues ,一個輸入佇列,一個輸出佇列。
  62.                                                  //對於 capture device 來說,當輸入佇列中的 buffer 被塞滿資料以後會自動變為輸出佇列,
  63.                                                  //等待呼叫 VIDIOC_DQBUF 將資料進行處理以後重新呼叫 VIDIOC_QBUF 將 buffer 重新放進輸入佇列.
  64.                 if((cvWaitKey(1)&255) == 27)    exit(0);  
  65.                 t=(double)cvGetTickCount()-t;  
  66.                 printf("used time is %gms\n",(t/(cvGetTickFrequency()*1000)));  
  67.         }  
  68.         ioctl(fd,VIDIOC_STREAMOFF,&type);         // 停止視訊採集命令,應用程式呼叫VIDIOC_ STREAMOFF停止視訊採集命令後,視訊裝置驅動程式不在採集視訊資料。
  69.         return 0;  
  70. }  
  71. int init_v4l2(void){  
  72.         if ((fd = open(FILE_VIDEO1, O_RDWR)) == -1){  
  73.             printf("Opening video device error\n");  
  74.             return FALSE;  
  75.         }  
  76.         if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1){               // 查詢視訊裝置的功能
  77.                 printf("unable Querying Capabilities\n");  
  78.                 return FALSE;  
  79.         }  
  80.         else
  81. /* 
  82.         { 
  83.         printf( "Driver Caps:\n" 
  84.                 "  Driver: \"%s\"\n" 
  85.                 "  Card: \"%s\"\n" 
  86.                 "  Bus: \"%s\"\n" 
  87.                 "  Version: %d\n" 
  88.                 "  Capabilities: %x\n", 
  89.                 cap.driver, 
  90.                 cap.card, 
  91.                 cap.bus_info, 
  92.                 cap.version, 
  93.                 cap.capabilities); 
  94.         } 
  95.         if((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE){ 
  96.             printf("Camera device %s: support capture\n",FILE_VIDEO1); 
  97.         } 
  98.         if((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING){ 
  99.             printf("Camera device %s: support streaming.\n",FILE_VIDEO1); 
  100.         } 
  101. */
  102.         fmtdesc.index = 0;  
  103.         fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  104.         printf("Support format: \n");  
  105.         while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) != -1){        // 獲取當前視訊裝置支援的視訊格式
  106.             printf("\t%d. %s\n",fmtdesc.index+1,fmtdesc.description);  
  107.             fmtdesc.index++;  
  108.         }  
  109.         //set fmt
  110.         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  111.         fmt.fmt.pix.width = IMAGEWIDTH;                    
  112.         fmt.fmt.pix.height = IMAGEHEIGHT;  
  113.         fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //*************************V4L2_PIX_FMT_YUYV****************可以選擇
  114.         fmt.fmt.pix.field = V4L2_FIELD_NONE;  
  115.         if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1){    // 設定視訊裝置的視訊資料格式,例如設定視訊影象資料的長、寬,影象格式(JPEG、YUYV格式)
  116.             printf("Setting Pixel Format error\n");  
  117.             return FALSE;  
  118.         }  
  119.         if(ioctl(fd,VIDIOC_G_FMT,&fmt) == -1){   //獲取影象格式
  120.             printf("Unable to get format\n");  
  121.             return FALSE;  
  122.         }  
  123. //        else
  124. /*        {  
  125.             printf("fmt.type:\t%d\n",fmt.type);         //可以輸出影象的格式
  126.             printf("pix.pixelformat:\t%c%c%c%c\n",fmt.fmt.pix.pixelformat & 0xFF,(fmt.fmt.pix.pixelformat >> 8) & 0xFF,\  
  127.                    (fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF);  
  128.             printf("pix.height:\t%d\n",fmt.fmt.pix.height);  
  129.             printf("pix.field:\t%d\n",fmt.fmt.pix.field);  
  130.         }  
  131. */  
  132. /* 
  133.         setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
  134.         setfps.parm.capture.timeperframe.numerator = 100; 
  135.         setfps.parm.capture.timeperframe.denominator = 100; 
  136.         printf("init %s is OK\n",FILE_VIDEO1); 
  137. */
  138.         return TRUE;  
  139. }  
  140. int v4l2_grab(void){  
  141.     //struct v4l2_requestbuffers req = {0};
  142.     //4  request for 4 buffers
  143.     req.count = 1;  
  144.     req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  145.     req.memory = V4L2_MEMORY_MMAP;  
  146. 相關推薦

    V4L2視訊應用程式程式設計架構

    參考 http://blog.csdn.net/tsuibeyond/article/details/50654823         http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.ht

    V4L2視訊採集裝置應用程式程式設計總結(原)

    Linux2.x核心中,一部分視訊裝置(特別是視訊輸入和採集裝置)採用了V4L2模型進行驅動程式設計。同時提供V4L2的API函式及相關資料結構以供應用程式使用.這裡對V4L2視訊採集裝置的應用程式程式設計進行總結. 1.使用的標頭檔案:V4L2模型使用統一的標頭檔案來包含相

    js之陣列API(應用程式程式設計介面)

    資料API是陣列原型中(Array.prototype.*)的陣列方法 1.新增元素    unshift() 方法(佇列方法) 新增到開頭,返回陣列的length     push()方法(棧方法)  arr.push(1

    23 Flask mega-tutorial 第23章應用程式程式設計介面(API)

    如需轉載請註明出處。 win10 64位、Python 3.6.3、Notepad++、Chrome 67.0.3396.99(正式版本)(64 位) 注:作者編寫時間2018-05-09,linux、python 3.5.2 以下內容均是加入自己的理解與增刪,

    Kubernetes雲原生應用程式庫,分散式應用程式編寫架構Metaparticle_Kubernetes中文社群

    自動部署、擴充套件和管理Container應用程式的開源系統Kubernetes共同創辦人Brendan Burns於KubeCon上,發表分散式應用程式編寫架構Metaparticle,這是一套為雲原生應用程式而生的Kubernetes標準庫,目的是讓開發者使用自己熟悉的程式語言,就能開發分

    MFC應用程式程式設計

    九MFC的訊息分類 MFC的訊息分類按照處理方式來分。主要分為4類: 1 視窗訊息 例如WM_CREATE、WM_PAINT、滑鼠、鍵盤等訊息,這些訊息的處理方式是直接呼叫訊息處理函式. 這類訊息使用的巨集:     ON_MESSAGE(  )     ON_WM_XXXXX( ): ON_WM_CREA

    Z-Stack 作業系統抽像層應用程式程式設計介面

    【轉】http://bbs.eeworld.com.cn/thread-375521-1-1.html 1.介紹 1.1目的 本檔案的目的是詳細說明作業系統抽象層(OSAL)API 。該API允許Z-stack寫自己內部的軟體元件而與具體的作業系統、核心、或者任務環境無關(包括控制迴圈或

    C語言高階應用---操作linux下V4L2攝像頭應用程式

    #include "CameralOpt.h" int video_fd ; int length ; char *yuv[COUNT] ; struct v4l2_buffer enqueue , dequeue ; //定義出入隊的操作結構體成員 int Init_Cameral(int

    windows基礎應用程式程式設計(一):基本框架

    從一開始程式設計時,大家面對著黑乎乎的控制檯視窗,就開始幻想什麼時候能進入windows下進行程式設計。能夠編寫出具有形形色色視窗的人往往都被我們認為是牛人。而從控制檯視窗進入windows下進行程式設計,對於初學者來講,絕對是一個很難跨越的坎。對此,自己也深有體會。因此,

    FFmpeg-音訊和視訊應用程式的瑞士軍刀

    FFmpeg是一個開源免費跨平臺的視訊和音訊流方案,屬於自由軟體,採用LGPL或GPL許可證(依據你選擇的元件)。它提供了錄製、轉換以及流化音視訊的完整解決方案。它包含了非常先進的音訊/視訊編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec裡很多codec都是從頭開發的。

    達夢資料庫 ODBC應用程式程式設計

    DM7 ODBC程式設計 DM ODBC 3.0 遵照Microsoft ODBC 3.0規範設計與開發,實現了ODBC應用與DM資料庫的互連線口。 ODBC API 在<sql.h>標頭檔案中對ODBC中使用的控制代碼定義如下: /*handle

    windows基礎應用程式程式設計(七)滑鼠訊息

    上一篇中,我們介紹了鍵盤訊息,接下來,我們來了解一下滑鼠訊息。 在上一篇中,我們知道Windows只把鍵盤訊息傳送給擁有輸入焦點的視窗。滑鼠訊息與此不同,只要滑鼠跨越視窗或者在某視窗中按下滑鼠鍵,那麼視窗過程就會受到滑鼠訊息,而不管該視窗是否活動或者是否擁有輸入焦點。同鍵盤

    android應用程式的介面程式設計

    要點 android的介面與view元件 view元件和viewgroup元件 android控制程式的三種方式 通過繼承view開發自定義view android常見的佈局管理器 文字框元件:textview和edittext 按鈕元件:button 特殊按鈕元件:radiobut

    JavaWeb高階程式設計(九)—— 使用過濾器改進應用程式

    一、瞭解過濾器         過濾器是可以攔截訪問資源的請求、資源的響應或者同時攔截兩者的應用元件,它們將以某種方式作用於這些請求或響應。過濾器可以檢測和修改請求或響應,它們甚至可以拒絕、重定向或轉發請求。如同Servlet一樣,過濾器可以在部署描述

    《java併發程式設計實戰》筆記(一) 結構化併發應用程式

    下載地址 連結:https://pan.baidu.com/s/1i6FlscH 密碼:m21n 1.任務執行 任務是一組邏輯執行單元,執行緒是使得任務非同步執行的機制 不可取的所謂執行緒開啟的方式: 1.所有任務放在單個執行緒中序列執行 2.每一個任務都開啟一個執行緒,無限

    實驗十五 GUI程式設計練習與應用程式部署

                                                &

    中國視訊BIGO應用程式登上了印度

      觀看視訊的熱潮以及Reliance Jio的資料訪問正在推動印度視訊流應用的使用,其中大多數是中國應用。 印度使用者以區域語言建立,使用和分享視訊內容的意願是共同的主線。幾乎所有應用程式都被建模為流行媒體應用程式的本地化,本地化版本。 從政治笑話到當前新聞的一切都在這些應用

    MCU應用程式架構整理(轉)

    應用程式架構 簡單的前後臺順序執行程式:多數人的使用方法,無需考慮程式的具體架構,直接通過順序編寫應用程式即可; 時間片輪詢法: 介於順序執行與作業系統之間的一種方法; 作業系統:應用程式編寫的最優辦法,對mcu ram 有一定的要求。 詳細介紹 順序執行法 這種方

    通過混合程式設計分析的方法和機器學習預測Web應用程式的漏洞

    通過混合程式設計分析的方法和機器學習預測Web應用程式的漏洞 由於時間和資源的限制,web軟體工程師需要支援識別出有漏洞的程式碼。一個實用的方法用來預測漏洞程式碼可以提高他們安全審計的工作效率。在這篇文章中,作者提出使用混合(靜態和動態)程式碼屬性來識別輸入驗證和輸入檢查的程式碼模式以用來標識web應用

    window 應用程式的組成及程式設計步驟

    1、應用程式的組成 2、源程式 的組成 2.1、WinMain函式 視窗初始化: b)註冊視窗類 window系統本身提供部分預定義視窗類,程式設計師也可以自定義視窗類。 視窗類必須先註冊後使用,視