IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> android usb摄像头 抓取一张图片 yuv格式 yuyv(yuy2) -> 正文阅读

[游戏开发]android usb摄像头 抓取一张图片 yuv格式 yuyv(yuy2)


//#加了点注释
?
//#Rockie Cheng
?
?
#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 <asm/types.h> ? ? ? ??
#include <linux/videodev2.h>
?
#define CLEAR(x) memset (&(x), 0, sizeof (x))
?
?struct buffer1 {
?? ??? ? void * ?? ??? ??? ??? ? start;
?? ??? ? size_t ?? ??? ??? ??? ? length;
?};
?
?static char *?? ??? ??? ? dev_name?? ??? ? = "/dev/video0";//摄像头设备名
?static int ?? ??? ??? ? fd ?? ??? ??? ? = -1;
?struct buffer1 *?? ??? ? buffers?? ??? ? = NULL;
?static unsigned int?? ? n_buffers?? ??? ? = 0;
?
?FILE *file_fd;
?static unsigned long file_length;
?static unsigned char *file_name;

?
//
//获取一帧数据
//
static int read_framex (void)
{
? ? struct v4l2_buffer buf;
? ? unsigned int i;
? ? CLEAR(buf);
? ? buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
? ? buf.memory = V4L2_MEMORY_MMAP;
? ? ioctl(fd, VIDIOC_DQBUF, &buf); ? //采集的帧缓冲出队列

?? ?printf( "read_framex1.\n" );
? ? assert( buf.index < n_buffers ); ??


?? ?printf( "n_buffers = %d.\n", n_buffers );


?? ?printf( "buffers[buf.index].start = %x.\n", buffers[buf.index].start );
?? ?printf( "buffers[buf.index].length = %d.\n", buffers[buf.index].length );

?? ?
? ? printf( "buf.index dq is %d.\n", buf.index );
? ? fwrite( buffers[buf.index].start, buffers[buf.index].length, 1, file_fd );?
? ? //将其写入文件中
? ? ioctl(fd, VIDIOC_QBUF, &buf);
? ? //再将其入列
? ? return 1;
}


int main_cap_a_picture( int argc, char ** argv )
{
? ? struct v4l2_capability cap;?
? ? struct v4l2_format fmt;
? ? unsigned int i;
? ? enum v4l2_buf_type type;
?
? ? file_fd = fopen("test-mmap.jpg", "w"); ? ?//图片文件名

//此处输出的文件不是jpg格式,而是yuv格式?yuyv(yuy2)

//jpg格式的话需要转换的

//用yuvplayer软件可以打开
? ? fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0); ? ?//打开设备

?? ?CLEAR( cap );?
?? ?macdbg_dmphex(&cap, sizeof(cap));
? ? ioctl(fd, VIDIOC_QUERYCAP, &cap); ? ?//获取摄像头参数
?? ?//fimc_v4l2_querycap(fd);
?? ?//macdbg_dmphex(&cap, sizeof(cap));
?? ?//printf("sizeof(cap) = %d\n", sizeof(cap));
?? ?
? ? CLEAR( fmt ); ??
? ? fmt.type?? ??? ? ? ? = V4L2_BUF_TYPE_VIDEO_CAPTURE;
? ? fmt.fmt.pix.width?? ??? ? = 640;?
? ? fmt.fmt.pix.height ?? ? = 480;

?? ?//fmt.fmt.pix.width?? ??? ? = 1280;?
? ? //fmt.fmt.pix.height ?? ? = 720;
?? ?
? ? fmt.fmt.pix.pixelformat ?= V4L2_PIX_FMT_YUYV;
? ? fmt.fmt.pix.field?? ??? ? = V4L2_FIELD_INTERLACED;


?? ?printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);
? ? ioctl (fd, VIDIOC_S_FMT, &fmt); //设置图像格式
?? ?printf("fmt.fmt.pix.bytesperline = %d\n", fmt.fmt.pix.bytesperline);

? ? file_length = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; //计算图片大小
? ??
? ? struct v4l2_requestbuffers req;
? ? CLEAR (req);
? ? req.count?? ??? ??? ??? ? = 4;
? ? req.type?? ??? ??? ??? ? = V4L2_BUF_TYPE_VIDEO_CAPTURE;
? ? req.memory ?? ??? ??? ? = V4L2_MEMORY_MMAP;
? ? ioctl(fd, VIDIOC_REQBUFS, &req); ? ?//申请缓冲,count是申请的数量
? ? if (req.count < 2)
?? ? ? ?printf("Insufficient buffer memory\n");
?
? ? buffers = calloc (req.count, sizeof (*buffers));//内存中建立对应空间
? ? for( n_buffers = 0; n_buffers < req.count; ++n_buffers) {
?? ? ? ? struct v4l2_buffer buf; ? //驱动中的一帧
?? ? ? ? CLEAR (buf);
?? ? ? ? buf.type?? ??? ?= V4L2_BUF_TYPE_VIDEO_CAPTURE;
?? ? ? ? buf.memory?? ??? ?= V4L2_MEMORY_MMAP;
?? ? ? ? buf.index?? ??? ?= n_buffers;?
?? ? ? ? if (-1 == ioctl (fd, VIDIOC_QUERYBUF, &buf)) //映射用户空间
?? ? ? ? ? ? printf ("VIDIOC_QUERYBUF error\n");
?? ? ? ? buffers[n_buffers].length = buf.length;
?? ? ? ? buffers[n_buffers].start = mmap( NULL /* start anywhere */,
?? ? ? ? ? ? buf.length,
? ? ? ? ? ? ?PROT_READ | PROT_WRITE /* required */,
? ? ? ? ? ? ?MAP_SHARED /* recommended */,
? ? ? ? ? ? ?fd, buf.m.offset );
? ? ? ? ?//通过mmap建立映射关系
?? ? ? ? if (MAP_FAILED == buffers[n_buffers].start)
?? ? ? ? ? ? printf ("mmap failed\n");
? ? }
? ? ? ? ? ?
? ? 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 == ioctl (fd, VIDIOC_QBUF, &buf))//申请到的缓冲进入列队
?? ? ? ? ? ? printf ("VIDIOC_QBUF failed\n");
? ? }

? ? #if 1?? ??? ??? ??? ??
? ? type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
? ? if( -1 == ioctl(fd, VIDIOC_STREAMON, &type) ){?
? ? ? ? //开始捕捉图像数据
? ? ? ? printf ("VIDIOC_STREAMON failed\n");
? ? }
?? ?#endif

//如果不打开,抓取的数据将会是全零
?? ?
? ? for( ; ; ){
?? ??? ? //这一段涉及到异步IO
?? ? ? ? fd_set fds;
? ? ? ? ?struct timeval tv;
? ? ? ? ?int r;
? ? ? ? ?FD_ZERO (&fds); ? ? //将指定的文件描述符集清空
? ? ? ? ?FD_SET (fd, &fds); ?//在文件描述符集合中增加一个新的文件描述符
? ? ? ? ?/* Timeout. */
? ? ? ? ?tv.tv_sec ?= 2;
? ? ? ? ?tv.tv_usec = 0;
? ? ? ? ?r = select (fd + 1, &fds, NULL, NULL, &tv);
? ? ? ? ?//判断是否可读(即摄像头是否准备好),tv是定时
? ? ? ? ?if( -1 == r ){
?? ? ? ? ? ? if( EINTR == errno ){
?? ? ? ? ? ? ? ? continue;
?? ? ? ? ? ? }
?? ? ? ? ? ? printf ("select err\n");
? ? ? ? ?} ? ?
? ? ? ? ?if( 0 == r ){
? ? ? ? ? ? ?fprintf (stderr, "select timeout\n");
? ? ? ? ? ? ?exit(EXIT_FAILURE);
? ? ? ? ?}
? ? ? ? ?if( read_framex() ){
?? ??? ? ?? ? //如果可读,执行read_frame()函数,并跳出循环
? ? ? ? ? ? ?break;
? ? ? ? ?}
? ? }
unmap:
? ? for( i=0; i<n_buffers; ++i ){
?? ? ? ? if( -1 == munmap(buffers[i].start, buffers[i].length) ){
?? ? ? ? ? ? printf ("munmap error");
?? ? ? ? }
? ? }
? ? close (fd);
? ? fclose (file_fd);
? ? exit(EXIT_SUCCESS);
? ? return 0;
}


?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:09:00  更:2022-03-13 22:09:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/23 10:29:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计