2023年12月4日Linux開發手記

2022-04-01 06:02:33 字數 3950 閱讀 2489

ok,經過昨天對v4l2工作流程的學習,現在已經大體了解了v4l2的工作原理,現在開始對v4l2的api的學習,目標:1、開啟攝像頭 2、儲存影象 3、關閉攝像頭,api**:linux media infrastructure userspace api — the linux kernel documentation

具體流程如下:

1、開啟裝置:

static void open_device()

dev_name = "/dev/video0";

fd = open(dev_name, o_rdwr /* required */ | o_nonblock, 0);

2、初始化裝置:

static void init_device()

3、捕獲影象:

static void start_capturing(void)

unsigned int i;

enum v4l2_buf_type type;

for (i = 0; i < n_buffers; ++i) {

struct v4l2_buffer buf;

clear(buf);

buf.type = v4l2_buf_type_video_capture;

buf.memory = v4l2_memory_mmap;

buf.index = i;

if (-1 == xioctl(fd, vidioc_qbuf, &buf))

errno_exit("vidioc_qbuf");

type = v4l2_buf_type_video_capture;

if (-1 == xioctl(fd, vidioc_streamon, &type))

errno_exit("vidioc_streamon");

4、主迴圈

static void mainloop(void)

unsigned int count;

count = frame_count;//幀數70

while (count-- > 0) {

for (;;) {/*select()機制中提供一fd_set的資料結構,實際上是一long型別的陣列,

每乙個陣列元素都能與一開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,

當呼叫select()時,由核心根據io狀態修改fd_set的內容,由此來通知執行了select()的程序哪一socket或檔案可讀*/

fd_set fds; 

struct timeval tv;//時間值

int r;

fd_zero(&fds); /*將set清零使集合中不含任何fd*/

fd_set(fd, &fds);/*將fd加入set集合*/

/* timeout. */

tv.tv_sec = 2; //2s

tv.tv_usec = 0;//0微妙

r = select(fd + 1, &fds, null, null, &tv);//select操作,用於確定乙個或多個套介面的狀態,返回滿足條件的套介面的數目,最多隻等待兩秒,

if (-1 == r) { //所有描述符集清零

if (eintr == errno)//如果錯誤型別為4(中斷系統呼叫)

continue;

errno_exit("select");

if (0 == r) { //超時

fprintf(stderr, "select timeout\\n");

exit(exit_failure);

if (read_frame())//讀取幀

break;

/* eagain - continue select loop. */

5、在主迴圈的過程中讀取幀

static int read_frame(void)

struct v4l2_buffer buf;//v4l2中臨時緩衝器

unsigned int i;

clear(buf);

buf.type = v4l2_buf_type_video_capture;

buf.memory = v4l2_memory_mmap;

if (-1 == xioctl(fd, vidioc_dqbuf, &buf)) {

switch (errno) {

case eagain:

return 0;

case eio:

/* could ignore eio, see spec. */

/* fall through */

default:

errno_exit("vidioc_dqbuf");

assert(buf.index < n_buffers);//斷言,索引小於緩衝區個數

process_image(buffers[buf.index].start, buf.bytesused);//程序對映

if (-1 == xioctl(fd, vidioc_qbuf, &buf))

errno_exit("vidioc_qbuf");

6、讀取幀時開始儲存影象

7、停止捕獲

static void stop_capturing(void)

enum v4l2_buf_type type;

switch (io) {

case io_method_read:

/* nothing to do. */

break;

case io_method_mmap:

case io_method_userptr:

type = v4l2_buf_type_video_capture;

if (-1 == xioctl(fd, vidioc_streamoff, &type))

errno_exit("vidioc_streamoff");

break;

8、釋放記憶體

static void uninit_device(void)

unsigned int i;

switch (io) {

case io_method_read:

free(buffers[0].start);

break;

case io_method_mmap:

for (i = 0; i < n_buffers; ++i)

if (-1 == munmap(buffers[i].start, buffers[i].length))

errno_exit("munmap");

break;

case io_method_userptr:

for (i = 0; i < n_buffers; ++i)

free(buffers[i].start);

break;

free(buffers);

9、關閉裝置

static void close_device(void)

if (-1 == close(fd))

errno_exit("close");

fd = -1;

10、輸出異常

fprintf(stderr, "\\n");

使用v4l2開啟攝像頭獲取影象的流程就是這樣,下一步就是使用python呼叫這個程式,取代cv2.imwrite。

2023年12月12日總結

今天用plsql進行pde檔案匯入時,提示表空間不存在,有兩個伺服器,從a伺服器匯出的pde檔案在b伺服器匯入表,在plsql選擇工具 匯入表,在pl sql developer標籤下的在建立表前打鉤,然後匯入檔案那選擇剛才匯出生成的pde檔案,按匯入,結果出錯,日誌如下 import starte...

2023年12月2日Linux開發手記

知識準備 2.獲得裝置資訊。3.根據需要更改裝置的相關設定。4.獲得採集到的影象資料 在這裡v4l提供了兩種方式,直接通過開啟的裝置讀取資料,使用mmap記憶體對映的方式獲取資料 5.對採集到的資料進行操作 如顯示到螢幕,影象處理,儲存成檔案 知道了流程之後,我們就需要根據流程完成相應的函式。第一步...

2023年12月1日Linux開發手記

配置ubuntu攝像頭 1 設定 新增 usb控制器 相容usb3.0 2 虛擬機器 可移動裝置 web camera 連線 斷開主機 3 檢視是否配置成功,開啟終端,輸入 susb ls dev video 輸出 dev video0 配置成功 4 開啟ubuntu自帶的chesse軟體 茄子 執...