关于V4L2采集视频缓冲队列不更新求助,buffers[nbuffers].start里的数据始终最开始采集到的那五张图。

本文档详细展示了使用V4L2接口进行视频采集时遇到的缓冲队列不更新的问题。代码示例涵盖了从打开设备到初始化帧缓冲,再到读取和写入帧数据的完整过程。当尝试从/dev/video4设备采集时,发现buffers[nbuffers].start的数据始终是最初的几张图像。问题可能源于缓冲区管理和驱动交互的细节。
摘要由CSDN通过智能技术生成
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <time.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <pthread.h>
#include <opencv2/opencv.hpp>
struct buffer {
    void   *start;
    size_t length;
};
struct size {
int width;
int height;
};
struct options_t {
char *devpath;
int video_width;
int video_height;
//int video_format;


int debug;


int x;
int y;
int screen_width;
int screen_height;


int zorder;
int layer;
int interval_time;
int fps;
};
static struct options_t option = {
.devpath      = "/dev/video4",      
.video_width  = 720,
.video_height = 576,
//.video_format = DISP_FORMAT_YUV420_SP_VUVU,
.debug        = 1,


.x = 0,
.y = 0,
.screen_width  = 720,//511,//400,
.screen_height = 576,//299,//576,


.zorder = 2,
.layer  = 0,
.interval_time = 66,
//.fps = 30,
.fps =25,
};
static struct size disp_size;
static int fd;
static struct buffer *buffers = NULL;
static int nbuffers = 0;
//写入framebuffer   fbp:帧缓冲首地址   fbfd:帧缓冲fd   img_buf:采集到的图片首地址  width:用户的宽 height:用户的高  bits:帧缓冲的位深 
//初始化framebuffer
using namespace cv;
typedef unsigned char    uint_8;
//rgb结构
typedef struct {
uint_8 r; // 红色分量
uint_8 g; // 绿色分量
uint_8 b; // 蓝色分量
uint_8 rgbReserved; // 保留字节(用作Alpha通道或忽略)
} rgb32; 
//帧缓冲中的rgb结构
typedef struct {
uint_8 b; // 蓝色分量
uint_8 g; // 绿色分量
uint_8 r; // 红色分量
uint_8 rgbReserved; // 保留字节(用作Alpha通道或忽略)
} rgb32_frame;
struct info
{
int Frame_fd;
int screensi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于v4l2摄像头的采集的示例代码,仅供参考: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <linux/videodev2.h> #define WIDTH 640 #define HEIGHT 480 #define BUFFER_COUNT 4 struct buffer { void *start; size_t length; }; int main(int argc, char *argv[]) { int fd; struct v4l2_capability cap; struct v4l2_format fmt; struct v4l2_requestbuffers reqbuf; struct v4l2_buffer buf; enum v4l2_buf_type type; struct buffer *buffers; unsigned char *image; int i, j; // 打开摄像头设备文件 fd = open("/dev/video0", O_RDWR); if (fd < 0) { perror("open"); return -1; } // 查询摄像头设备信息 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { perror("ioctl"); return -1; } // 设置摄像头格式 memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt.fmt.pix.width = WIDTH; fmt.fmt.pix.height = HEIGHT; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) { perror("ioctl"); return -1; } // 分配摄像头缓冲区 memset(&reqbuf, 0, sizeof(reqbuf)); reqbuf.count = BUFFER_COUNT; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) { perror("ioctl"); return -1; } // 映射摄像头缓冲buffers = calloc(reqbuf.count, sizeof(*buffers)); for (i = 0; i < reqbuf.count; i++) { memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) { perror("ioctl"); return -1; } buffers[i].length = buf.length; buffers[i].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset); if (buffers[i].start == MAP_FAILED) { perror("mmap"); return -1; } } // 启动摄像头采集 for (i = 0; i < reqbuf.count; i++) { memset(&buf, 0, sizeof(buf)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) { perror("ioctl"); return -1; } } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) { perror("ioctl"); return -1; } // 采集数据 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) { perror("ioctl"); return -1; } image = buffers[buf.index].start; // 处理数据 // TODO: 在这进行处理,例如像增强、降噪、裁剪等 // 保存数据到文件 FILE *fp = fopen("image.raw", "wb"); fwrite(image, 1, WIDTH * HEIGHT * 2, fp); fclose(fp); // 停止摄像头采集 if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) { perror("ioctl"); return -1; } // 释放缓冲区 for (i = 0; i < reqbuf.count; i++) { munmap(buffers[i].start, buffers[i].length); } free(buffers); // 关闭摄像头设备文件 close(fd); return 0; } ``` 该示例代码演示了如何基于v4l2摄像头采集数据,并将采集数据保存为文件。需要注意的是,该示例代码中没有进行任何处理,具体的处理操作可以根据需要在代码中添加。同时,具体的设备文件路径和摄像头参数设置需要根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值