/*
* TEST V4L2
*
* bushi@mizi.com
*
* preview : 240x160 overlay on 240x320 16bpp LCD
*
* capture : 640x480
*
*
*/
#include <sys/time.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <jpeglib.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include "videodev.h"
#include <linux/fb.h>
#define PIXFMT_NUM 5
#define INPUT_NUM 5
#define CTRL_NUM 100
#define V4L2_DEV_NODE "/dev/v4l2/capture0"
#define FB_DEV_NODE "/dev/fb/0"
#define RGB_FILE "rgb.jpg"
#define YUV420_FILE "yuv420.jpg"
typedef struct v4l2_input V_INPUT;
typedef struct v4l2_format V_FORMAT;
typedef struct v4l2_fmtdesc V_FMTDESC;
typedef struct v4l2_queryctrl V_QRYCTRL;
typedef struct fb_var_screeninfo F_VINFO;
static struct jpeg_compress_struct cinfo;
static int quality = 100;
static struct jpeg_error_mgr jerr;
static char *name_of_ctrl_type[] = {
[V4L2_CTRL_TYPE_INTEGER] = "INTEGER",
[V4L2_CTRL_TYPE_BOOLEAN] = "BOOLEAN",
[V4L2_CTRL_TYPE_MENU] = "MENU",
[V4L2_CTRL_TYPE_BUTTON] = "BUTTON",
};
static void v4l2_print_settings(int fd,
V_INPUT *inp, V_FORMAT *fmt, V_FMTDESC *pix, V_QRYCTRL *qc)
{
int i;
int pixnum = 0;
int inputnum = 0;
int ctrlnum = 0;
V_INPUT *inp_0 = inp;
V_FMTDESC *pix_0 = pix;
V_QRYCTRL *qc_0 = qc;
for (i = 0; i < INPUT_NUM; i++) {
inp->index = i;
if (ioctl(fd, VIDIOC_ENUMINPUT, inp) < 0) {
break;
}
inp++;
inputnum++;
}
for (i = 0; i < PIXFMT_NUM; i++) {
pix->index = i;
if (ioctl(fd, VIDIOC_ENUM_PIXFMT, pix) < 0)
break;
pix++;
pixnum++;
}
for (i = 0; i < CTRL_NUM; i++) {
qc->id = V4L2_CID_BASE + i;
if (ioctl(fd, VIDIOC_QUERYCTRL, qc) < 0)
break;
if (!(qc->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_GRABBED))) {
ctrlnum++;
qc++;
}
}
for (i = 0; i < CTRL_NUM; i++) {
qc->id = V4L2_CID_PRIVATE_BASE + i;
if (ioctl(fd, VIDIOC_QUERYCTRL, qc) < 0)
break;
if (!(qc->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_GRABBED))) {
ctrlnum++;
qc++;
}
}
qc->id = 0;
fmt->type = V4L2_BUF_TYPE_CAPTURE;
if (ioctl(fd, VIDIOC_G_FMT, fmt) < 0)
perror("getting video format");
printf(" available inputs are:\n");
inp = inp_0;
for (i = 0; i < inputnum; i++) {
printf(" [%02d] - %s\n", inp->index, inp->name);
inp++;
}
printf("\n");
printf(" available fomats are:\n");
pix = pix_0;
for (i = 0; i < pixnum; i++) {
printf(" [%02d] - %-15s (%d bpp), 0x%x\n",
pix->index, pix->description, pix->depth, pix->pixelformat);
pix++;
}
printf("\n");
printf(" available controls are:\n");
qc = qc_0;
for (i = 0; i < ctrlnum; i++) {
printf(" [%2d] - \"%s\" [%7s] %d~%d (step:%d default:%d)\n", i
, qc->name
, name_of_ctrl_type[qc->type]
, qc->minimum, qc->maximum, qc->step, qc->default_value);
qc++;
}
printf("\n");
printf(" driver's current selection is:\n");
inp = inp_0;
printf(" %d x %d @ %d bpp from input [%d] (%s)\n",
fmt->fmt.pix.width, fmt->fmt.pix.height, fmt->fmt.pix.depth,
inp->index, inp->name);
printf("\n");
}
static void v4l2_config_for_preview(int fd, V_FORMAT *fmt, V_FMTDESC *pix)
{
int i;
V_FORMAT fmt_req;
V_FORMAT fmt_ret;
for (i=0; i < PIXFMT_NUM; i++) {
if (pix->pixelformat == V4L2_PIX_FMT_RGB565)
break;
pix++;
}
if (i == PIXFMT_NUM) {
printf("there is not pixel format for preview\n");
exit (EXIT_FAILURE);
}
memcpy(&fmt_req, fmt, sizeof(V_FORMAT));
fmt_req.type = V4L2_BUF_TYPE_CAPTURE;
fmt_req.fmt.pix.width = 240;
fmt_req.fmt.pix.height = 160;
fmt_req.fmt.pix.depth = 16;
fmt_req.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
if (ioctl(fd, VIDIOC_S_FMT, &fmt_req) < 0) {
perror("VIDIOC_S_FMT");
exit (EXIT_FAILURE);
}
fmt_ret.type = V4L2_BUF_TYPE_CAPTURE;
if (ioctl(fd, VIDIOC_G_FMT, &fmt_ret) < 0)
perror("getting video format");
printf(" driver's modified selection is:\n");
printf(" %d x %d @ %d bpp, RGB565\n",
fmt_ret.fmt.pix.width, fmt_ret.fmt.pix.height,
fmt_ret.fmt.pix.depth);
printf("\n");
}
static void v4l2_config_for_rgb_capture(int fd, V_FORMAT *fmt, V_FMTDESC *pix)
{
int i;
V_FORMAT fmt_req;
V_FORMAT fmt_ret;
for (i=0; i < PIXFMT_NUM; i++) {
if (pix->pixelformat == V4L2_PIX_FMT_RGB32)
break;
pix++;
}
if (i == PIXFMT_NUM) {
printf("there is not pixel format for capture\n");
exit (EXIT_FAILURE);
}
memcpy(&fmt_req, fmt, sizeof(V_FORMAT));
fmt_req.type = V4L2_BUF_TYPE_CAPTURE;
fmt_req.fmt.pix.width = 640;
fmt_req.fmt.pix.height = 480;
fmt_req.fmt.pix.depth = 32;
fmt_req.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
if (ioctl(fd, VIDIOC_S_FMT, &fmt_req) < 0) {
perror("VIDIOC_S_FMT");
exit (EXIT_FAILURE);
}
fmt_ret.type = V4L2_BUF_TYPE_CAPTURE;
if (ioctl(fd, VIDIOC_G_FMT, &fmt_ret) < 0)
perror("getting video format");
printf(" driver's modified selection is:\n");
printf(" %d x %d @ %d bpp, RGB32\n",
fmt_ret.fmt.pix.width, fmt_ret.fmt.pix.height,
fmt_ret.fmt.pix.depth);
printf("\n");
}
static void v4l2_config_for_yuv420_capture(int fd, V_FORMAT *fmt, V_FMTDESC *pix)
{
int i;
V_FORMAT fmt_req;
V_FORMAT fmt_ret;
for (i=0; i < PIXFMT_NUM; i++) {
if (pix->pixelformat == V4L2_PIX_FMT_YUV420)
break;
pix++;
}
if (i == PIXFMT_NUM) {
printf("there is not pixel format for capture\n");
exit (EXIT_FAILURE);
}
memcpy(&fmt_req, fmt, sizeof(V_FORMAT));
fmt_req.type = V4L2_BUF_TYPE_CAPTURE;
fmt_req.fmt.pix.width = 640;
fmt_req.fmt.pix.height = 480;
fmt_req.fmt.pix.depth = 12;
fmt_req.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
if (ioctl(fd, VIDIOC_S_FMT, &fmt_req) < 0) {
perror("VIDIOC_S_FMT");
exit (EXIT_FAILURE);
}
fmt_ret.type = V4L2_BUF_TYPE_CAPTURE;
if (ioctl(fd, VIDIOC_G_FMT, &fmt_ret) < 0)
perror("getting video format");
printf(" driver's modified selection is:\n");
printf(" %d x %d @ %d bpp, YUV420\n",
fmt_ret.fmt.pix.width, fmt_ret.fmt.pix.height,
fmt_ret.fmt.pix.depth);
printf("\n");
}
static void v4l2_show_on_fb(int fd, char *fbmem, int frames)
{
int i;
int ret;
char preview_buf[240*160*2];
for (i = 0; i < frames; i++) {
if ((ret = read (fd, &preview_buf, 240*160*2)) < 0) {
perror("read");
return;
}
#if 0
{
int y;
for (y = 0; y < 160; y++)
memcpy(fbmem + 240*2*y, preview_buf + 240*2*y, 240*2);
}
#else
memcpy(fbmem, &preview_buf, 240*160*2);
#endif
printf("\r%3d", i);
fflush(stdout);
}
printf("\n");
}
#if 0
static void v4l2_save_rgb32_to_jpg(int fd)
{
char rgb32buf[640*480*4];
unsigned int y,x = 0;
FILE *jpg_fp = NULL;
unsigned long *rgb32 = (unsigned long*)&rgb32buf[0];
unsigned long *rgb32_p = rgb32;
unsigned char *rgb24 = &rgb32buf[0];
unsigned long tmp;
char *base;
JSAMPROW row_pointer[1] = {(JSAMPROW)rgb24};
if ((read (fd, &rgb32buf, 640*480*4)) < 0) {
perror("read");
return;
}
jpg_fp = fopen(RGB_FILE, "wb");
if (!jpg_fp) {
perror(RGB_FILE);
return;
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, jpg_fp);
cinfo.image_width = 640;
cinfo.image_height = 480;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
/* xRGB -> RGB */
for (y = 0; y < 480; y++) {
rgb32_p = rgb32 + y*640;
base = rgb24;
for (x = 0; x < 640; x++) {
tmp = *(rgb32_p + x);
*base++ = (tmp >> 16) & 0xff;
*base++ = (tmp >> 8) & 0xff;
*base++ = (tmp >> 0) & 0xff;
}
jp
v4l2_test.rar_2440_s3c2440_v4l_v4l2_test.rar_摄像头测试
版权申诉
132 浏览量
2022-09-21
03:46:54
上传
评论
收藏 16KB RAR 举报
小波思基
- 粉丝: 70
- 资源: 1万+
最新资源
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.dta
- 上市公司-股票性质数据-工具变量(民企、国企、央企)2003-2022年.xlsx
- Reeds+Shepp曲线算法讲解和实现.pdf
- 毕业设计基于SpringBoot+MyBatisPlus+MySQL+Vue的外卖配送信息系统源代码+数据库
- 词向量(Word Embeddings)是自然语言处理(NLP)领域的一种重要技术.txt
- Surfer,线性函数
- MyBatis 的动态 SQL 是其核心特性之一.txt
- 时代的sdddsddsddsd
- 基于哈希链表的简单人员信息管理系统
- 其他类别JdonFramework开源框架 v5.1 Build20071025-jdonframework-5.1.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0