攝像頭驅動(一)————V4L2框架淺析
V4L2 :video for linux version 2 ,是 linux 裡一套標準的視訊驅動,它支援 uvc 標準的攝像頭。本文來分析一下它的核心框架。
整個v4l2的框架分為三層:
在應用層,我們可以在 /dev 目錄發現 video0 類似的裝置節點,上層的攝像頭程式開啟裝置節點進行資料捕獲,顯示視訊畫面。裝置節點的名字很統一,video0 video1 video2...這些裝置節點在是核心層註冊。
核心層 v4l2-dev.c,承上啟下,對於每一個硬體相關層註冊進來的裝置,設定一個統一的介面 v4l2_fops ,既然是統一的介面必然不是具體的視訊裝置的操作函式,應用層呼叫 v4l2_fops 中的函式最終將呼叫到硬體相關層的 video_device 的 fops 。
硬體相關層,與具體的視訊硬體打交道,分配、設定、註冊 video_device 結構體。
[cpp] view plain copy print?- staticint __init videodev_init(void)
- {
- /* 申請裝置號,留給 video 裝置使用 */
- dev_t dev = MKDEV(VIDEO_MAJOR, 0);
- ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
- /* 建立 video 類 */
-
ret = class_register(&video_class);
- return 0;
- }
- struct video_device
- {
- /* device ops */
- conststruct v4l2_file_operations *fops;
- /* sysfs */
- struct device dev; /* v4l device */
- struct cdev *cdev; /* character device */
-
/* Set either parent or v4l2_dev if your driver uses v4l2_device */
- struct device *parent; /* device parent */
- struct v4l2_device *v4l2_dev; /* v4l2_device parent */
- /* Control handler associated with this device node. May be NULL. */
- struct v4l2_ctrl_handler *ctrl_handler;
- /* Priority state. If NULL, then v4l2_dev->prio will be used. */
- struct v4l2_prio_state *prio;
- /* device info */
- char name[32];
- int vfl_type;
- /* 'minor' is set to -1 if the registration failed */
- int minor;
- u16 num;
- /* use bitops to set/clear/test flags */
- unsigned long flags;
- /* attribute to differentiate multiple indices on one physical device */
- int index;
- /* V4L2 file handles */
- spinlock_t fh_lock; /* Lock for all v4l2_fhs */
- struct list_head fh_list; /* List of struct v4l2_fh */
- int debug; /* Activates debug level*/
- /* Video standard vars */
- v4l2_std_id tvnorms; /* Supported tv norms */
- v4l2_std_id current_norm; /* Current tvnorm */
- /* callbacks */
- void (*release)(struct video_device *vdev);
- /* ioctl callbacks */
- conststruct v4l2_ioctl_ops *ioctl_ops;
- DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
- /* serialization lock */
- DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE);
- struct mutex *lock;
- };
- struct v4l2_device {
- struct device *dev;
- /* used to keep track of the registered subdevs */
- struct list_head subdevs;
- spinlock_t lock;
- char name[V4L2_DEVICE_NAME_SIZE];
- void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg);
- struct v4l2_ctrl_handler *ctrl_handler;
- struct v4l2_prio_state prio;
- struct mutex ioctl_lock;
- struct kref ref;
- void (*release)(struct v4l2_device *v4l2_dev);
- };
- staticinlineint __must_check video_register_device(struct video_device *vdev,
- int type, int nr)
- {
- return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
- }
- int __video_register_device(struct video_device *vdev, int type, int nr,
- int warn_if_nr_in_use, struct module *owner)
- {
- int i = 0;
- int ret;
- int minor_offset = 0;
- int minor_cnt = VIDEO_NUM_DEVICES;
- constchar *name_base;
- /* A minor value of -1 marks this video device as never having been registered */
- vdev->minor = -1;
- /* 視訊裝置的裝置節點一般為 video0 ..video 就是由此而來 */
- switch (type) {
- case VFL_TYPE_GRABBER:
- name_base = "video";
- break;
- case VFL_TYPE_VBI:
- name_base = "vbi";
- break;
- ...
- }
- vdev->vfl_type = type;
- vdev->cdev = NULL;
- /* Part 2: find a free minor, device node number and device index. */
- #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
- switch (type) {
- case VFL_TYPE_GRABBER:
- minor_offset = 0;
- minor_cnt = 64;
- break;
- ...
- #endif
- /* 尋找一個空的項,這個好像並不重要 */
- mutex_lock(&videodev_lock);
- nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
- if (nr == minor_cnt)
- nr = devnode_find(vdev, 0, minor_cnt);
- if (nr == minor_cnt) {
- printk(KERN_ERR "could not get a free device node number\n");
- mutex_unlock(&videodev_lock);
- return -ENFILE;
- }
- #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
- /* 1-on-1 mapping of device node number to minor number */
- i = nr;
- #else
- /* 在全域性 video_deivce 陣列中尋找一個空的項,下標+minor_offset作為裝置的次裝置號 */
- for (i = 0; i < VIDEO_NUM_DEVICES; i++)
- if (video_device[i] == NULL)
- break;
- if (i == VIDEO_NUM_DEVICES) {
- mutex_unlock(&videodev_lock);
- printk(KERN_ERR "could not get a free minor\n");
- return -ENFILE;
- }
- #endif
- vdev->minor = i + minor_offset;
- vdev->num = nr;
- devnode_set(vdev);
- if (vdev->ioctl_ops)
- determine_valid_ioctls(vdev);
- /* 註冊字元裝置 */
- vdev->cdev = cdev_alloc();
- vdev->cdev->ops = &v4l2_fops;
- vdev->cdev->owner = owner;
- ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
- /* 得把device註冊進核心,mdev才能自動建立裝置節點,/dev 目錄下的video0 等就是來自這裡 */
- vdev->dev.class = &video_class;
- vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
- if (vdev->parent)
- vdev->dev.parent = vdev->parent;
- dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
- ret = device_register(&vdev->dev);
- vdev->dev.release = v4l2_device_release;
- /* Part 6: Activate this minor. The char device can now be used. */
- set_bit(V4L2_FL_REGISTERED, &vdev->flags);
- mutex_lock(&videodev_lock);
- video_device[vdev->minor] = vdev;
- mutex_unlock(&videodev_lock);
- return 0;
- }
- EXPORT_SYMBOL(__video_register_device);
- staticconststruct file_operations v4l2_fops = {
- .owner = THIS_MODULE,
- .read = v4l2_read,
- .write = v4l2_write,
- .open = v4l2_open,
- .get_unmapped_area = v4l2_get_unmapped_area,
- .mmap = v4l2_mmap,
- .unlocked_ioctl = v4l2_ioctl,
- #ifdef CONFIG_COMPAT
- .compat_ioctl = v4l2_compat_ioctl32,
- #endif
- .release = v4l2_release,
- .poll = v4l2_poll,
- .llseek = no_llseek,
- };
相關推薦
攝像頭驅動(一)————V4L2框架淺析
V4L2 :video for linux version 2 ,是 linux 裡一套標準的視訊驅動,它支援 uvc 標準的攝像頭。本文來分析一下它的核心框架。 整個v4l2的框架分為三層: 在應用層,我們可以在 /dev 目錄發現 video0 類
攝像頭驅動(二)————V4L2 虛擬攝像頭驅動vivi深入分析
本文基於:linux3.5 前面一篇文章中,簡單分析了 V4L2 大框架,本文藉助核心中的虛擬攝像頭驅動 vivi 來分析一個完整的攝像頭驅動程式。vivi 相對於後面要分析的 usb 攝像頭驅動程式,它沒有真正的硬體相關層的操作,也就是說拋開了複雜的 us
V4L2攝像頭測試(一)
利用VIDIOC_G_CTRL得到一些設定: 一些具體的設定,如曝光模式(Exposure Type),曝光值(Exposure),增益(Gain),白平衡(WHITE_BALANCE),亮度(BRIGHTNESS),飽和度(SATURATION),對比度(CONTRAST)等資訊。
OpenGL在MFC中的使用總結(一)——基本框架
palette 接受 white 要求 無效 結構 del 一次 是你 項目中要畫3D顯示的模型,於是要用到OpenGL,加上是在MFC中,並且是在MFC中的ActiveX中使用。再並且鑒於他們程序主框架的設定。常規的方法還不一定能實現。所以還是查過不少資料,在此一一總
python selenium系列(一):框架介紹及安裝
row pre ive AS baidu mar 在操作 pan 但是 一 selenium是什麽?引用百度百科的介紹selenium的一段話:“Selenium 是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的
Scrapy框架學習(一)Scrapy框架介紹
Scrapy框架的架構圖如上。 Scrapy中的資料流由引擎控制,資料流的過程如下: 1.Engine開啟一個網站,找到處理該網站的Sprider,並向該Sprider請求第一個要爬取得URL。 2.Engine從Sprider中獲取到第一個要爬的URL,並通過Scheduler以Requ
(一)flask框架使用教程系列——準備環境
一、安裝Python2.7(python3.6同理) Mac 下使用Python2.7 Windows下使用Python2.7 2.1 從Python 官網下載Python2.7的版本; 2.2 雙擊Python2.7,然後選擇安裝路徑,全部下一步安裝就可以了; 2.
crm銷售管理系統(一)SSM框架搭建
前言:ssm框架是spring+springMvc+Mybatis的縮寫,是繼SSH框架後又一個主流的java EE企業級框架,適用於搭建各種大型的企業級應用系統。這不,我所在公司的產品也是基於該主流框架進行搭建的。初識SSM框架是各種的不適應,不過使用久了發現ssm框架異常順手。使用幾個月下來可以說在開發公
GAN(一):基本框架
GAN(一):基本框架 一、GAN的概念 二、algorithm 小白的第一篇部落格,寫的有不對的地方,望各位批評指正; 一、GAN的概念 1)generator:Neural Network image generation: 給定一個
微信小程式學習筆記(一)之框架及工具
文章目錄 一、app.json的配置 1. 決定頁面檔案路徑 2. 配置視窗表現 3. 配置tab標籤導航 4. 設定網路超時時間 5. 配置debug模式 二、App()函式使用
SSH框架學習(一)——匯入框架所需jar包
SSH框架學習(一)——匯入框架所需jar包 一、建立一個web專案 二、匯入Struts2的jar包 三、匯入Hibernate的jar包 四、匯入Spring的jar包 IOC開發: AOP開發: 五、引入整合
電商大資料分析平臺專案(一)專案框架
開發可以在web專案中內嵌的js sdk。每當使用者瀏覽到網站頁面或者觸發某種事件時,會呼叫js程式碼,根據使用者cookie傳送一個session資訊這時到我們的nginx伺服器中。 nginx伺服器在接收到傳送的session後會將其寫入日誌檔案中記錄下來,這時監聽日誌檔案的flume會將session
Spring框架學習之路(一)——Spring框架基本介紹
Spring的出現是為了取代EJB(Enterprise JavaBean)的臃腫、低效、脫離現實的缺點。Spring致力於J2EE應用的各層(表現層、業務層、持久層)的解決方案,Spring是企業應用開發的“一站式”選擇。 1.Spring定義: Spring是分層的J
深入理解Plasma(一)Plasma 框架
這一系列文章將圍繞以太坊的二層擴容框架,介紹其基本執行原理,具體操作細節,安全性討論以及未來研究方向等。本篇文章作為開篇,主要目的是理解 Plasma 框架。 Plasma 作為以太坊的二層擴容框架,自從 2017 年被 Joseph Poon(Lightnin
springboot視訊教程系列(一)SpringBoot框架初相識-王勇-專題視訊課程
springboot視訊教程系列(一)SpringBoot框架初相識—126人已學習 課程介紹 本章主要介紹什麼是SpringBoot框架?SpringBoot開發框架的主要特性以及
UE4移動元件詳解(一)——移動框架與實現原理
前言 關於UE4的移動元件,我寫了一篇非常詳細的分析文件。由於篇幅比較大,我將其拆分成三個部分。分別從移動框架與實現原理,移動的網路同步,移動元件的優化與改造三個方面來寫。這三篇文件中難免有問題和漏洞,所以我也會在發現問題時及時更新和修改,也希望大家能給出一些
vue從入門到女裝??:從零開始搭建後臺管理系統(一)安裝框架
安裝及執行都是基於node的,不會node的可以自行百度,網上教程很多,也不難 專案效果預覽: demo1 demo2 原始碼下載 開始安裝框架: vue element-ui 注意如果報錯安裝失敗就重新安裝,不然雖然本地有element的依賴包但是可能會出一些奇怪的錯誤 另外element-ui
Linux塊裝置驅動(一)————塊裝置的結構及磁碟的結構
塊裝置的結構及磁碟的結構 1、扇區 磁碟上的每個磁軌被等分成若干個弧段,這些弧段便是磁碟的扇區。磁碟驅動器在向磁碟讀寫資料時,都是以扇區為單位。一般為512個位元組,但也有1024或者
Spring 註解驅動(一)基本使用規則
Spring 註解驅動(一)基本使用規則 Spring 系列目錄(https://www.cnblogs.com/binarylei/p/10198698.html) 一、基本使用 @Configuration @ComponentScan(basePackages = "com.github.bina
一步一步教你構建一個MPU6050(I2C類)驅動(一)
1 i2c基本協議和時序 i2c基礎的知識這裡就不提了,直接從時序開始,直接來看看i2c的波形 2 i2c子系統軟體框架 先來看看i2c匯流排的分層思想: 在分層圖中我們可以看到,driver和device在核心層中分別成為了2條連結串列,核心層會按一定的