国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Camera | 4.瑞芯微平臺MIPI攝像頭應用程序編寫

這篇具有很好參考價值的文章主要介紹了Camera | 4.瑞芯微平臺MIPI攝像頭應用程序編寫。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前面3篇我們講解了camera的基礎概念,MIPI協議,CSI2,常用命令等,本文帶領大家入門,如何用c語言編寫應用程序來操作攝像頭。

Linux下攝像頭驅動都是基于v4l2架構,要基于該架構編寫攝像頭的應用程序,必須先要搞清楚什么是v4l2。

1. 什么是v4l2

v4l2是video for Linux 2的縮寫,是一套Linux內核視頻設備的驅動框架,該驅動框架為應用層提供一套統一的操作接口(一系列的ioctl)

https://linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/

官網有一個簡單的用于抓圖的程序capture.c。

本文后面基于該實例編寫一個最簡單的抓圖程序。

v4l2接口

V4L2 :video for linux 2 ,是 linux ??套標準的視頻驅動,讓應?層可以像訪問普通?件?樣對**/dev/videoX** 節(jié)點進? open 、 read 、 ioctl 等操作。

V4L2在設計時,是要支持很多廣泛的設備的,它們之中只有一部分在本質上是真正的視頻設備,可以支持多種設備,它可以有以下幾種接口:

1. video capture interface(捕獲):
視頻采集接口,這種接口應用于攝像頭,v4l2在最初設計的時候就是應用于這種功能

2. video output interface(輸出):
視頻輸出接口,將靜止圖像或圖像序列編碼為模擬視頻信號,通過此接口,應用程序可以控制編碼過程并將圖像從用戶空間移動到驅動程序

3. video overlay interface(預覽):
視頻直接傳輸接口,可以將采集到的視頻數據直接傳輸到顯示設備,不需要cpu參與,這種方式的顯示圖像的效率比其他方式高得多

本文主要講解如何使用capture功能。

2. 截取圖象的3種方法

1)用mmap(內存映射)方式截取視頻

mmap( )系統調用使得進程之間通過映射同一個普通文件實現共享內存。普通文件被映射到進程地址空間后,進程可以向訪問普通內存一樣對文件進行訪問,不必再調用read(),write()等操作。

兩個不同進程A、B共享內存的意思是,同一塊物理內存被映射到進程A、B各自的進程地址空間。進程A可以即時看到進程B對共享內存中數據的更新,反之亦然

采用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數據的拷貝

*(1)設置picture的屬性
*(2) 初始化video_mbuf,以得到所映射的buffer的信息

ioctl(vd->fd, VIDIOCGMBUF, &(vd->mbuf))

*(3)可以修改video_mmap和幀狀態(tài)的當前設置

 Eg. vd->mmap.format = VIDEO_PALETTE_RGB24
 vd->framestat[0] = vd->framestat[1] = 0; vd->frame = 0;

*(4)將mmap與video_mbuf綁定

void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )
len //映射到調用進程地址空間的字節(jié)數,它從被映射文件開頭offset個字節(jié)開始算起
Prot //指定共享內存的訪問權限 PROT_READ(可讀), PROT_WRITE (可寫), PROT_EXEC (可執(zhí)行)
flags // MAP_SHARED MAP_PRIVATE中必選一個 // MAP_ FIXED不推薦使用addr //共內存享的起始地址,一般設0,表示由系統分配
Mmap( ) 返回值是系統實際分配的起始地址
if((vd->map = (unsigned char*)mmap(0, vd->mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, vd->fd, 0)) < 0)
{
	perror("v4l_mmap mmap:");
	return -1;
}

*(5)Mmap方式下真正做視頻截取的 VIDIOCMCAPTURE

ioctl(vd->fd, VIDIOCMCAPTURE, &(vd->mmap)) ;
若調用成功,開始一幀的截取,是非阻塞的,
是否截取完畢留給VIDIOCSYNC來判斷

*(6)調用VIDIOCSYNC等待一幀截取結束

if(ioctl(vd->fd, VIDIOCSYNC, &frame) < 0)
{
	perror("v4l_sync:VIDIOCSYNC");
	return -1;
}

若成功,表明一幀截取已完成??梢蚤_始做下一次 VIDIOCMCAPTURE

frame是當前截取的幀的序號。

關于雙緩沖:

video_bmuf bmuf.frames = 2;
一幀被處理時可以采集另一幀
int frame; //當前采集的是哪一幀
int framestat[2]; //幀的狀態(tài) 沒開始采集|等待采集結束
幀的地址由vd->map + vd->mbuf.offsets[vd->frame]得到
采集工作結束后調用munmap取消綁定
munmap(vd->map, vd->mbuf.size)

2)視頻截取的第二種方法:直接讀設備

關于緩沖大小,圖象等的屬性須由使用者事先設置

int read (要訪問的文件描述符;指向要讀寫的信息的指針;應該讀寫的字符數);
	返回值為實際讀寫的字符數

實例:

int len ;
unsigned char *vd->map= (unsigned char *) malloc(vd->capability.maxwidth*vd->capability.maxheight );
len = read(vd->fd,vd->map, vd->capability.maxwidth*vd->capability.maxheight*3 );

3)用戶指針

3. v4l2 設備操作說明

對設備的大多數操作都是應用層通過調用ioctl實現的,
不同的命令需要操作不同的文件設備節(jié)點,
具體的需要根據拓撲結構來決定操作那個字符設備。

以下是瑞芯微rk3568平臺的攝像頭拓撲圖,移植了ov13850攝像頭。

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

  1. 其中攝像頭對應的此設備為: /dev/v4l-subdev3
  2. 應用層要配置通用配置、或者獲取圖像,需要操作設備 /dev/video0
  3. 有一些攝像頭專用的命令,我們可以操作 /dev/v4l-subdev3

ov13850攝像頭驅動中注冊了一些命令對應的回調函數:

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

這些回調函數都注冊到了V4L2架構中,我們可以通過字符設備 /dev/videox,、/dev/v4l-subdevx 直接或者間接訪問到這些回調函數。

V4L2定義了一些通用的命令,操作字符設備 /dev/videox即可調用,命令具體定義如下:

kernel\drivers\media\v4l2-core\v4l2-ioctl.c

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器
可以通過數組名+命令對應的數值方式訪問對應的回調函數。
該數組定義如下:

struct v4l2_ioctl_info {
	unsigned int ioctl;
	u32 flags;
	const char * const name;
	int (*func)(const struct v4l2_ioctl_ops *ops, struct file *file,
		    void *fh, void *p);
	void (*debug)(const void *arg, bool write_only);
};

字符設備**/dev/v4l-subdevx**支持的命令如下:

@kernel\drivers\media\v4l2-core\v4l2-subdev.c

static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
		……
	switch (cmd) {
	case VIDIOC_QUERYCTRL:
		……
	case VIDIOC_QUERY_EXT_CTRL:
		……
	case VIDIOC_QUERYMENU:
		……
	case VIDIOC_G_CTRL:
		……
	case VIDIOC_S_CTRL:
		……
	case VIDIOC_G_EXT_CTRLS:
		……
	case VIDIOC_S_EXT_CTRLS:
		……
	case VIDIOC_TRY_EXT_CTRLS:
		……
	case VIDIOC_DQEVENT:
		……
	case VIDIOC_SUBSCRIBE_EVENT:
		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
	case VIDIOC_UNSUBSCRIBE_EVENT:
		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
#ifdef CONFIG_VIDEO_ADV_DEBUG
	case VIDIOC_DBG_G_REGISTER:
		……
	case VIDIOC_DBG_S_REGISTER:
		……
	case VIDIOC_DBG_G_CHIP_INFO:
		……
#endif
	case VIDIOC_LOG_STATUS: {
		……
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
	case VIDIOC_SUBDEV_G_FMT: {
		……
	case VIDIOC_SUBDEV_S_FMT: {
		……
	case VIDIOC_SUBDEV_G_CROP: {
		……
	}
	case VIDIOC_SUBDEV_S_CROP: {
		……
	}
	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
		……
	}
	case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
		……
	}
	case VIDIOC_SUBDEV_G_FRAME_INTERVAL: {
		……
	}
	case VIDIOC_SUBDEV_S_FRAME_INTERVAL: {
		……
	}
	case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
		……
	}
	case VIDIOC_SUBDEV_G_SELECTION: {
		……
	}
	case VIDIOC_SUBDEV_S_SELECTION: {
		……
	}
	case VIDIOC_G_EDID: {
		……
	}
	case VIDIOC_S_EDID: {
		……
	}
	case VIDIOC_SUBDEV_DV_TIMINGS_CAP: {
		……
	}
	case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: {
		……
	}
	case VIDIOC_SUBDEV_QUERY_DV_TIMINGS:
		return v4l2_subdev_call(sd, video, query_dv_timings, arg);
	case VIDIOC_SUBDEV_G_DV_TIMINGS:
		return v4l2_subdev_call(sd, video, g_dv_timings, arg);
	case VIDIOC_SUBDEV_S_DV_TIMINGS:
		return v4l2_subdev_call(sd, video, s_dv_timings, arg);
	case VIDIOC_G_INPUT:
		return v4l2_subdev_call(sd, video, g_input_status, arg);
	case VIDIOC_SUBDEV_G_STD:
		return v4l2_subdev_call(sd, video, g_std, arg);
	case VIDIOC_SUBDEV_S_STD: {
		v4l2_std_id *std = arg;
		return v4l2_subdev_call(sd, video, s_std, *std);
	}
	case VIDIOC_SUBDEV_ENUMSTD: {
		……
	}
	case VIDIOC_SUBDEV_QUERYSTD:
		……
	}
	return 0;
}

這其中有一些命令是和字符設備 /dev/videox 的命令重復的,

比如:VIDIOC_S_CTRL,

VIDIOC_SUBDEV_ 開頭的則是subdev私有的。

關于這些命令和回調函數,后續(xù)會再深入講解,對于應用程序開發(fā),

我們首先搞清楚設備的拓撲結構,然后需要知道我們要執(zhí)行的命令功能以及對應的是哪一個設備節(jié)點即可。

4. ioctl命令說明

參見結構體見

 /usr/include/linux/videodev2.h

1)Querying Capabilities

查詢設備的功能

由于V4L2涵蓋了各種各樣的設備,因此并非API的所有方面都適用于所有類型的設備,在使用v4l2設備時,必須調用此API,獲得設備支持的功能(capture、output、overlay…)

ID 描述
VIDIOC_QUERYCAP 查詢設備功能
struct v4l2_capability
{
	u8 driver[16]; // 驅動名字
	u8 card[32]; // 設備名字
	u8 bus_info[32]; // 設備在系統中的位置
	u32 version; // 驅動版本號
	u32 capabilities; // 設備支持的操作
	u32 reserved[4]; // 保留字段
};

capabilities 常用值:

V4L2_CAP_VIDEO_CAPTURE // 是否支持圖像獲取

2)Application Priority

應用優(yōu)先級

當多個應用程序共享設備時,可能需要為它們分配不同的優(yōu)先級。視頻錄制應用程序可以例如阻止其他應用程序改變視頻控制或切換當前的電視頻道。

另一個目標是允許在后臺工作的低優(yōu)先級應用程序,這些應用程序可以被用戶控制的應用程序搶占,并在以后自動重新獲得對設備的控制

ID 描述
VIDIOC_G_PRIORITY 獲取優(yōu)先級
VIDIOC_S_PRIORITY 設置優(yōu)先級

3)Device Inputs and Outputs

輸入和輸出設備

ID 描述
VIDIOC_ENUMINPUT 枚舉視頻輸入設備
VIDIOC_G_INPUT 獲取當前的視頻輸入設備
VIDIOC_S_INPUT 設置視頻輸入設備
VIDIOC_ENUMOUTPUT 枚舉視頻輸出設備
VIDIOC_G_OUTPUT 獲取當前視頻輸出設備
VIDIOC_S_OUTPUT 設置視頻輸出設備
VIDIOC_ENUMAUDIO 枚舉音頻輸入設備
VIDIOC_G_AUDIO 獲取當前音頻輸入設備
VIDIOC_S_AUDIO 設置音頻輸入設備
VIDIOC_ENUMAUDOUT 枚舉音頻輸出設備
VIDIOC_G_OUTPUT 獲取音頻輸出設備
VIDIOC_S_AUDOUT 設置音頻輸出設備

VIDIOC_G_INPUT 和 VIDIOC_S_INPUT 用來查詢和選則當前的 input,一個 video 設備 節(jié)點可能對應多個視頻源,比如 saf7113 可以最多支持四路 cvbs 輸入,如果上層想在四 個cvbs視頻輸入間切換,那么就要調用 ioctl(fd, VIDIOC_S_INPUT, &input) 來切換。

VIDIOC_G_INPUT and VIDIOC_G_OUTPUT 返回當前的 video input和output的index.

struct v4l2_input {
	__u32 index; /* Which input */
	__u8 name[32]; /* Label */
	__u32 type; /* Type of input */
	__u32 audioset; /* Associated audios (bitfield) */
	__u32 tuner; /* Associated tuner */
	v4l2_std_id std;
	__u32 status;
	__u32 reserved[4];
};

我們可以通過VIDIOC_ENUMINPUT and VIDIOC_ENUMOUTPUT 分別列舉一個input或者 output的信息,我們使用一個v4l2_input結構體來存放查詢結果,這個結構體中有一個 index域用來指定你索要查詢的是第幾個input/ouput,如果你所查詢的這個input是當前正 在使用的,那么在v4l2_input還會包含一些當前的狀態(tài)信息,如果所 查詢的input/output 不存在,那么回返回EINVAL錯誤,所以,我們通過循環(huán)查找,直到返回錯誤來遍歷所有的 input/output. VIDIOC_G_INPUT and VIDIOC_G_OUTPUT 返回當前的video input和output 的index.

4) Video Standards

視頻標準

ID 描述
VIDIOC_ENUMSTD 枚舉設備支持的所有標準
VIDIOC_G_STD 獲取當前正在使用的標準
VIDIOC_S_STD 設置視頻標準
VIDIOC_QUERYSTD 有的設備支持自動偵測輸入源的視頻標準,此ioctl獲取檢測到的標準
typedef u64 v4l2_std_id;
	struct v4l2_standard {
	u32 index;
	v4l2_std_id id;
	u8 name[24];
	struct v4l2_fract frameperiod; /* Frames, not fields */
	u32 framelines;
	u32 reserved[4];
};

當然世界上現在有多個視頻標準,如NTSC和PAL,他們又細分為好多種,那么我們的設 備輸入/輸出究竟支持什么樣的標準呢?我們的當前在使用的輸入和輸出正在使用的是哪 個標準呢?我們怎么設置我們的某個輸入輸出使用的標準呢?這都是有方法的。

查詢我們的輸入支持什么標準,首先就得找到當前的這個輸入的index,然后查出它的 屬性,在其屬性里面可以得到該輸入所支持的標準,將它所支持的各個標準與所有的標準 的信息進行比較,就可以獲知所支持的各個標準的屬性。一個輸入所支持的標準應該是一 個集合,而這個集合是用bit與的方式用一個64位數字表示。因此我們所查到的是一個數字。

5) Camera Control Reference

控制屬性

ID 描述
VIDIOC_QUERYCTRL 查詢指定的control詳細信息
VIDIOC_QUERYMENU 查詢menu
VIDIOC_G_CTRL 獲取設備指定control的當前信息
VIDIOC_S_CTRL 設置設備指定的control

6) Image Format

圖像格式

圖像由多種格式YUV和RGB還有壓縮格式等等,其中每種格式又分有多種格式,比如RGB:RGB565、RGB888…

所以在使用設備時,需要對格式進行設置

ID 描述
VIDIOC_ENUM_FMT 枚舉設備支持的圖像格式
VIDIOC_G_FMT 獲取當前設備的圖像格式
VIDIOC_S_FMT 設置圖像格式
VIDIOC_TRY_FMT 測試設備是否支持此格式

查詢并顯示所有支持的格式:VIDIOC_ENUM_FMT

struct v4l2_fmtdesc
{
	u32 index; // 要查詢的格式序號,應用程序設置
	enum v4l2_buf_type type; // 幀類型,應用程序設置
	u32 flags; // 是否為壓縮格式
	u8 description[32]; // 格式名稱
	u32 pixelformat; // 格式
	u32 reserved[4]; // 保留
};

查看或設置當前格式: VIDIOC_G_FMT, VIDIOC_S_FMT

struct v4l2_format
{
	enum v4l2_buf_type type; // 幀類型,應用程序設置
	union fmt
	{
		struct v4l2_pix_format pix; // 視頻設備使用	
		struct v4l2_window win;	
		struct v4l2_vbi_format vbi;	
		struct v4l2_sliced_vbi_format sliced;	
		u8 raw_data[200];	
	};
};

struct v4l2_pix_format
{
	u32 width; // 幀寬,單位像素	
	u32 height; // 幀高,單位像素	
	u32 pixelformat; // 幀格式	
	enum v4l2_field field;	
	u32 bytesperline;	
	u32 sizeimage;	
	enum v4l2_colorspace colorspace;	
	u32 priv;
};

7) Cropping, composing and scaling

圖像裁剪、插入與縮放

ID 描述
VIDIOC_CROPCAP 獲取圖像裁剪縮放能力
VIDIOC_G_CROP 獲取當前的裁剪矩陣
VIDIOC_S_CROP 設置裁剪矩陣

Cropping 和 scaling 主要指的是圖像的取景范圍及圖片的比例縮放的支持。Crop 就 是把得到的數據作一定的裁剪和伸縮,裁剪可以只取樣我們可以得到的圖像大小的一部分, 剪裁的主要參數是位置、長度、寬度。而 scale 的設置是通過 VIDIOC_G_FMT 和 VIDIOC_S_FMT 來獲得和設置當前的 image 的長度,寬度來實現的。
看下圖:
瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

我們可以假設 bounds 是 sensor 最大能捕捉到的圖像范圍,而 defrect 是設備默認 的最大取樣范圍,這個可以通過 VIDIOC_CROPCAP 的 ioctl 來獲得設備的 crap 相關的屬 性 v4l2_cropcap,其中的 bounds 就是這個 bounds,其實就是上限。每個設備都有個默 認的取樣范圍,就是 defrect,就是 default rect 的意思,它比 bounds 要小一些。這 個范圍也是通過 VIDIOC_CROPCAP 的 ioctl 來獲得的 v4l2_cropcap 結構中的 defrect 來表示的,我們可以通過 VIDIOC_G_CROP 和 VIDIOC_S_CROP 來獲取和設置設備當前的 crop 設置。

設置設備捕捉能力的參數

struct v4l2_cropcap
{
	enum v4l2_buf_type type; // 數據流的類型,應用程序設置
	struct v4l2_rect bounds; // 這是 camera 的鏡頭能捕捉到的窗口大小的局限
	struct v4l2_rect defrect; // 定義默認窗口大小,包括起點位置及長,寬的大小,大小以像素為單位
	struct v4l2_fract pixelaspect; // 定義了圖片的寬高比
};

設置窗口取景參數 VIDIOC_G_CROP 和 VIDIOC_S_CROP

struct v4l2_crop
{
	enum v4l2_buf_type type;// 應用程序設置
	struct v4l2_rect c;
}

8) buf Input/Output

數據的輸入和輸出

內核中使用緩存隊列對圖像數據進行管理,用戶空間獲取圖像數據有兩種方式,一種是通過read、write方式讀取內核空間的緩存,一種是將內核空間的緩存映射到用戶空間,即streaming。在操作v4l2設備時,通過VIDIOC_QUERYCAP獲取設備支持哪種方式。
streaming就是在內核空間中維護一個緩存隊列,然后將內存映射到用戶空間,應用讀取圖像數據就是一個不斷地出隊列和入隊列的過程,如下圖所示

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

ID 描述
VIDIOC_REQBUFS 申請緩存
VIDIOC_QUERYBUF 獲取緩存信息
VIDIOC_QBUF 將緩存放入隊列中
VIDIOC_DQBUF 將緩存從隊列中取出

1. 向設備申請緩沖區(qū) VIDIOC_REQBUFS

struct v4l2_requestbuffers
{
	u32 count; // 緩沖區(qū)內緩沖幀的數目
	enum v4l2_buf_type type; // 緩沖幀數據格式
	enum v4l2_memory memory; // 區(qū)別是內存映射還是用戶指針方式
	u32 reserved[2];
};
enum v4l2_memoy
{
	V4L2_MEMORY_MMAP, V4L2_MEMORY_USERPTR
};

獲取緩沖幀的地址,長度:VIDIOC_QUERYBUF

struct v4l2_buffer
{
	u32 index; //buffer 序號
	enum v4l2_buf_type type; //buffer 類型
	u32 byteused; //buffer 中已使用的字節(jié)數
	u32 flags; // 區(qū)分是MMAP 還是USERPTR	
	enum v4l2_field field;	
	struct timeval timestamp; // 獲取第一個字節(jié)時的系統時間	
	struct v4l2_timecode timecode;	
	u32 sequence; // 隊列中的序號	
	enum v4l2_memory memory; //IO 方式,被應用程序設置	
	union m	
	{	
		u32 offset; // 緩沖幀地址,只對MMAP 有效	
		unsigned long userptr;	
	};	
	u32 length; // 緩沖幀長度	
	u32 input;	
	u32 reserved;
};

2. 內存映射MMAP 及定義一個結構體來映射每個緩沖幀。
相關結構體:

struct buffer
{
	void* start;
	unsigned int length;
}*buffers;

相關函數:

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
參數:
addr 映射起始地址,一般為NULL ,讓內核自動選擇
length 被映射內存塊的長度
prot 標志映射后能否被讀寫,其值為PROT_EXEC,PROT_READ,PROT_WRITE, PROT_NONE
flags 確定此內存映射能否被其他進程共享,MAP_SHARED,MAP_PRIVATE
fd,offset, 確定被映射的內存地址 返回成功映射后的地址,不成功返回MAP_FAILED ((void*)-1)

3.將所有的緩存放入隊列

struct v4l2_buffer v4l2_buffer;

for(i = 0; i < nr_bufs; i++)
{
	memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
	v4l2_buffer.index = i; //想要放入隊列的緩存
	v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	v4l2_buffer.memory = V4L2_MEMORY_MMAP;	

    ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buffer);
    if(ret < 0)
    {
        printf("Unable to queue buffer.\n");
        return -1;
    }
}

9)啟動 或 停止數據流

VIDIOC_STREAMON, VIDIOC_STREAMOFF

type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl (fd, VIDIOC_STREAMON, &type);

5. v4l2設備抓幀程序編寫

v4l2設備的命令比較多,其實常用的并不是很多,下面通過一個實例來詳細講解,如何操作v4l2設備。

1)設備配置

本例,將常用的攝像頭配置參數等裝成結構體:

struct v4l2_dev
{
    int fd;   //videoO對應的設備描述符
    int sub_fd; 
    const char *path; //字符設備 /dev/videoO
    const char *name; //攝像頭名稱
    const char *subdev_path;//字符設備 /dev/v4l-subdev3
    const char *out_type; //輸出圖像格式
    enum v4l2_buf_type buf_type;//緩存類型
    int format; //像素格式
    int width;  //圖像寬度
    int height; //圖像高度
    unsigned int req_count; //緩存數量
    enum v4l2_memory memory_type; //讀取圖像的方法,DMA還是MMAP
    struct buffer *buffers; //緩沖區(qū)
    unsigned long int timestamp;//時長度
    int data_len;//圖像數據長度
    unsigned char *out_data;//圖像數據
};

本例填寫的攝像頭ov13850的配置信息如下:

struct v4l2_dev ov13850 = {
    .fd = -1,
    .sub_fd = -1,
    .path = "/dev/video0",
    .name = "ov13850",
    .subdev_path = "/dev/v4l-subdev3",
    .out_type = "nv12",
    .buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
    .format = V4L2_PIX_FMT_NV12,
    .width = 800,
    .height = 600,
    .req_count = 4,
    .memory_type = V4L2_MEMORY_MMAP,
    .buffers = NULL,
    .timestamp = 0,
    .data_len = 0,
    .out_data = NULL,
};

2)v4l2設備一般操作流程(抓幀)

v4l2設備一般操作流程如下圖所示:

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

各功能對應的ioctrl命令如下:

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

測試程序一口君已經上傳到gitee:

https://gitee.com/yikoulinux/v4l2-app

git clone git@gitee.com:yikoulinux/v4l2-app.git

瑞芯微 攝像頭 demo,瑞芯微,原創(chuàng),Linux驅動,linux,運維,服務器

歡迎各位老鐵star。

3)程序執(zhí)行l(wèi)og

以下是在瑞芯微rk3568實際測試的log。

rk3568_r:/ # /data/capture                                       
/data/capture                                                    
Open /dev/video0 succeed - 3                                     
                                                                 
Open /dev/v4l-subdev3 succeed                                    
                                                                 
------- VIDIOC_QUERYCAP ----                                     
  driver: rkisp_v5                                               
  card: rkisp_mainpath                                           
  bus_info: platform:rkisp-vir0                                  
  version: 1.8.0                                                 
  capabilities: 84201000                                         
        Video Capture Mplane                                     
        Streaming                                                
                                                                 
VIDIOC_S_FMT succeed!                                            
width 800, height 600, size 720000, bytesperline 0, format NV12  
                                                                 
VIDIOC_REQBUFS succeed!                                          
                                                                 
Memory map succeed!                                              
                                                                 
VIDIOC_QBUF succeed!                                             
                                                                 
VIDIOC_STREAMON succeed!                                         
                                                                 
image: sequence = 0, timestamp = 1115378780                      
image: sequence = 1, timestamp = 1115511890                      
image: sequence = 2, timestamp = 1115645004                      
image: sequence = 3, timestamp = 1115778130                      
image: sequence = 4, timestamp = 1115911257                      
image: sequence = 5, timestamp = 1116044365                      
image: sequence = 6, timestamp = 1116177498                      
image: sequence = 7, timestamp = 1116310610                      
image: sequence = 8, timestamp = 1116443739                      
image: sequence = 9, timestamp = 1116576844                      
Save one frame to /data/ov13850.nv12 succeed!                    
                                                                 
VIDIOC_STREAMOFF succeed!                                        

文中各種mipi技術文檔,后臺回復關鍵字:mipi

掌握了這些命令,我們就可以調試攝像頭了。

后面還會繼續(xù)更新幾篇Camera文章,

建議大家訂閱本專題!

也可以后臺留言,加一口君好友yikoupeng,

拉你進高質量技術交流群。文章來源地址http://www.zghlxwxcb.cn/news/detail-802592.html

到了這里,關于Camera | 4.瑞芯微平臺MIPI攝像頭應用程序編寫的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • RK3568 android11 調試mipi攝像頭 gc2093

    RK3568 android11 調試mipi攝像頭 gc2093

    GC2093是一個高質量的1080P CMOS圖像傳感器,用于安全相機產品、數碼相機產品和手機相機應用程序。包含了一個1920H x 1080V像素陣列、片上10位ADC和圖像信號處理器。高性能和低功耗功能的全面集成使GC2093最適合設計,減少了實現過程,并延長了運動相機、汽車DVR和各種移動應用

    2024年01月17日
    瀏覽(137)
  • rk3568mipi攝像頭調試(gc2385 + gc2053)

    RK3568平臺僅有一個標準物理mipi csi2 dphy,可以工作在full mode 和split mode兩個模式, 拆分為csi2_dphy0/csi2_dphy1/csi2_dphy2三個邏輯dphy Full Mode: 僅使用csi2_dphy0,csi2_dphy0與csi2_dphy1/csi2_dphy2互斥,不可同時使用; data lane最大4 lanes; 最大速率2.5Gbps/lane; Split Mode: 僅使用csi2_dphy1和csi2_dphy2, 與csi2_dph

    2024年02月16日
    瀏覽(105)
  • 基于RK3399 Android11適配OV13850 MIPI攝像頭

    基于RK3399 Android11適配OV13850 MIPI攝像頭

    ??從上圖可看出,我們需要關心的,①MIPI數據和時鐘接口使用的是MIPI_TX1/RX1 ②I2C使用的是I2C4總線 ③RST復位引腳使用的是GPIO2_D2 ④PWDN使用的是GPIO1_C7 ⑤MCLK使用的是GPIO3_B7 ⑥需要保證紅色框框的供電電源正常。 ??結合RK提供的文檔,如下攝像頭數據采集拓撲圖所示,我們

    2024年03月14日
    瀏覽(22)
  • android 13.0 Camera2 去掉后置攝像頭 僅支持前置攝像頭功能

    在定制化13.0系統rom定制化開發(fā)中,當產品只有一個前置攝像頭單攝像頭,這時調用相機時就需要默認打開前置攝像頭就需要來看調用攝像頭這塊的代碼,屏蔽掉后置攝像頭的調用api就可以了,接下來就來具體實現相關功能的開發(fā) Camera2 API 概述 Camera2 API的包名是android.hardware

    2024年01月21日
    瀏覽(32)
  • 攝像頭標定--camera_calibration

    攝像頭標定--camera_calibration

    參考鏈接:camera_calibration - ROS Wiki 普通相機成像誤差的主要來源有兩部分,第一是相機感光元件制造產生的誤差,比如成 像單元不是正方形、歪斜等;第二是鏡頭制造和安裝產生的誤差,鏡頭一般存在非線性的徑 向畸變。 在對相機成像和三維空間中位置關系對應比較嚴格的

    2024年02月06日
    瀏覽(20)
  • android 12.0Camera旋轉攝像頭方向

    在12.0 產品定制化開發(fā)中,由于攝像頭方向默認是豎屏的,但是平板電腦一般都是要橫屏拍攝的 所以就需要旋轉攝像頭方向,來適應拍攝的需要,這就需要在Camera中打開攝像頭的時候,設置參數旋轉攝像頭方向

    2024年02月13日
    瀏覽(27)
  • 全網最簡單實用Android攝像頭開發(fā),同時預覽多個攝像頭,雙目攝像頭,同時打開手機前后攝像頭(紅外攝像頭、人臉識別、活體檢測、Android Camera、縮放、焦距、旋轉、鏡像、截圖保存)

    如果你受夠了網上那些亂七八糟的代碼,你可以了解下我這個,能同時打開多個攝像頭,在界面上預覽,并且可以取得攝像頭數據,byte[] 轉為 Bitmap,保存為 jpg圖片。 最近我們的某個項目要加上Android人臉識別,雖然有別人寫好的“考勤”、“門口閘機”這些,但不能直接用

    2024年02月08日
    瀏覽(21)
  • Android studio APK切換多個攝像頭(Camera2)

    Android studio APK切換多個攝像頭(Camera2)

    1.先設置camera的權限 2.布局 3.主界面代碼 這部分代碼是用來授權AndroidManifest.xml里面權限的第三方sdk代碼 效果:

    2024年02月11日
    瀏覽(26)
  • Camera簡介(一):攝像頭模組CCM的結構和原理簡述

    Camera簡介(一):攝像頭模組CCM的結構和原理簡述

    我們常說的 Sensor 也就是圖像傳感器只是整個攝像頭模組的一部分,主要負責將接收到的光信號轉換成電信號,實際上整個 攝像頭模組 (Camera Compact Module,CCM)由很多部分組成,除Sensor以外的其他模塊會負責完成對焦、濾光、減震、數據傳輸等功能,以便更好地采集圖像。 索尼

    2024年02月16日
    瀏覽(22)
  • 一個成功的camera案例:ros2+gazebo+攝像頭

    一個成功的camera案例:ros2+gazebo+攝像頭

    各位看:隨著大物體的移動,在涉嫌頭的位置也發(fā)生了改變-----右上角那個/camera的位置也變了 右上角那個是攝像頭圖案,以下是倉庫鏈接: ros-ign-gazebo-camera: https://github.com/arashsm79/ros-ign-gazebo-camera.git一個ros2+攝像頭的示例 ?如果你輸入: ? 輸入: 這位高人的攝像頭是確實在

    2024年01月22日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包