内核配置完并且烧录镜像后,就可以编写应用程序了。这里使用迅为提供的测试程序,该程序的功能是通过OV5640录制一段50帧(大小可设置)的视频,并生成out.yuv视频文件,可以通过yuv播放器或二进制编辑器进行验证。
该程序调用了V4L2,那什么是V4L2呢? V4L2为linux下视频设备程序提供了一套接口规范。包括一套数据结构和底层V4L2驱动接口。只能在linux下使用。它使程序有发现设备和操作设备的能力。它主要是用一系列的回调函数来实现这些功能。像设置摄像头的频率、帧频、视频压缩格式和图像参数等等。当然也可以用于其他多媒体的开发,如音频等。
可以参考这篇文章学习V4L2——v4l2的学习建议和流程解析
应用程序,YUV播放器及二进制编辑器下载:https://download.csdn.net/download/q1449516487/11231366
下面是应用程序的代码及注释:包含4个文件(build.sh、camera.h、camera.c、main.c)
build.sh:运行build.sh进行编译
#build.sh
arm-none-linux-gnueabi-g++ -o camera camera.cpp main.cpp -static
camera.h:摄像头的h文件
#ifndef CAMERA_H
#define CAMERA_H
#include <sys/types.h>
#define CLEAR(x) memset (&(x), 0, sizeof (x))
//视频IO模式
typedef enum {
IO_METHOD_READ, IO_METHOD_MMAP, IO_METHOD_USERPTR,
} io_method;
//本地缓存区
struct buffer {
void * start;
size_t length;//buffer's length is different from cap_image_size
};
class Camera
{
public:
Camera(char *DEV_NAME,int w,int h, int camer_type);
~Camera();
bool OpenDevice();//打开设备
void CloseDevice();
bool GetBuffer(unsigned char *image);//获取数据流
unsigned int getImageSize();
private:
char dev_name[50];//设备名称
io_method io;//IO
int fd;//描述符
int width;//宽
int height;//高
struct buffer * buffers ;//共享内存
unsigned int n_buffers ;//index
unsigned int cap_image_size ;//to keep the real image size!! //图像大小
bool init_device(void);//初始化设备
//void init_read(unsigned int buffer_size);
bool init_mmap(void);//创建共享内存
//void init_userp(unsigned int buffer_size);
void uninit_device(void);//卸载设备
bool start_capturing(void);//开始捕获
void stop_capturing(void);//停止捕获
void mainloop(unsigned char *image);//
int read_frame(unsigned char *image);//读帧
void close_device(void);//关闭设备
bool open_device(void);//打开设备
bool process_image(unsigned char *image,const void * p);//处理图像
void errno_exit(const char * s);//错误退出
int xioctl(int fd, int request, void * arg);//ioctl
};
#endif // CAMERA_H
camera.c:摄像头的c文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h> /* getopt_long() */
#include <fcntl.h> /* low-level i/o */
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h> /* for videodev2.h */
#include <linux/videodev2.h>
#include "camera.h"
int c_camera_type = 0;
Camera::Camera(char *DEV_NAME, int w, int h, int camera_type)
{
memcpy(dev_name,DEV_NAME,strlen(DEV_NAME));
//设置IO模式
io = IO_METHOD_MMAP;//IO_METHOD_READ;//IO_METHOD_MMAP;
cap_image_size=0;//图像大小
width=w;//宽
height=h;//高
if(1 == camera_type)
{
c_camera_type = 1;//摄像头类型(1:UVC,0:ITU)
}
}
Camera::~Camera(){
}
//返回图像大小
unsigned int Camera::getImageSize(){
return cap_image_size;
}
void Camera::CloseDevice() {
stop_capturing();
uninit_device();
close_device();
}
void Camera::errno_exit(const char * s) {
fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
exit(EXIT_FAILURE);
}
int Camera::xioctl(int fd, int request, void * arg) {
int r;
do
r = ioctl(fd, request, arg);
while (-1 == r && EINTR == errno);
return r;
}
//读取图像帧
int Camera::read_frame(unsigned char *image) {
s