#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 "fbg.h"
#include <asm/types.h>
#include <linux/videodev2.h>
#define CLEAR(x) memset (&(x), 0, sizeof (x))
#define PIC_NUM 100
int width=176, height=144,i,choice,flag;
int fd0,fd1,fd2;
unsigned char *rgb888_buf = NULL;
unsigned char *rgb565_buf = NULL;
static unsigned int n_buffers = 0;
int byte_size,size;
static unsigned long file_length;
static char * dev_name1 = "/dev/video0";//摄像头设备名
static char * dev_name2 = "/dev/video1";//摄像头设备名
struct buffer * buffers1 = NULL;
struct buffer * buffers2 = NULL;
struct buffer {
void * start;
size_t length;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int convert_yuv_to_rgb_pixel(int y, int u, int v)
{
unsigned int pixel32 = 0;
unsigned char *pixel = (unsigned char *)&pixel32;
int r, g, b;
r = y + (int)((1.370705 * ((float)(v-128))));
g = y - (int)((0.698001 * ((float)(v-128)))) - (int)((0.337633 * ((float)(u-128))));
b = y + (int)((1.732446 * ((float)(u-128))));
if(r > 255) r = 255;
if(g > 255) g = 255;
if(b > 255) b = 255;
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
pixel[0] = b * 31 / 255;
pixel[1] = r * 31 / 255;
pixel[2] = g * 63 / 255;
return pixel32;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
{
unsigned int in, out = 0;
unsigned int pixel_16;
unsigned char pixel_24[3];
unsigned int pixel32;
int y0, u, y1, v;
for(in = 0; in < width * height * 2; in += 4) {
pixel_16 = yuv[in + 3] << 24 | yuv[in + 2] << 16 | yuv[in + 1] << 8 | yuv[in + 0];
y0 = (pixel_16 & 0x000000ff);
u = (pixel_16 & 0x0000ff00) >> 8;
y1 = (pixel_16 & 0x00ff0000) >> 16;
v = (pixel_16 & 0xff000000) >> 24;
pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
pixel_24[0] = (pixel32 & 0x000000ff);
pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
rgb[out++] = pixel_24[0];
rgb[out++] = pixel_24[1];
rgb[out++] = pixel_24[2];
pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
pixel_24[0] = (pixel32 & 0x000000ff);
pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
rgb[out++] = pixel_24[0];
rgb[out++] = pixel_24[1];
rgb[out++] = pixel_24[2];
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void convert_rgb888_to_rgb565_buffer(unsigned char *rgb888_buf, unsigned char *rgb565_buf, unsigned int width, unsigned int height,int biasn,int biasm)
{
int m,n,l;
char r,g1,g2,b;
for( m = 0; m < height; m++ )
for( n = 0; n < width; n++ )
{
r = (rgb888_buf[3*(m*width+n) + 0]);
g1 = g2 = (rgb888_buf[3*(m*width+n) + 1]);
b = (rgb888_buf[3*(m*width+n) + 2]);
l = ( n + biasn ) * (vinfo.bits_per_pixel/8) + ( m + biasm ) * (finfo.line_length);
rgb565_buf[l+0]=( (r >> 3) << 3 ) + ( g1 >> 5 );
rgb565_buf[l+1]=( ((g2 << 3) >> 5) << 5 ) + ( b >> 3 );
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int read_frame (void)
{
struct v4l2_buffer buf1,buf2;
if(choice == 1 || choice ==3)
{
CLEAR (buf1);
buf1.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf1.memory = V4L2_MEMORY_MMAP;
ioctl (fd1, VIDIOC_DQBUF, &buf1); //出列采集的帧缓冲
assert (buf1.index < n_buffers);
convert_yuv_to_rgb_buffer(buffers1[buf1.index].start,rgb888_buf, width,height);
convert_rgb888_to_rgb565_buffer(rgb888_buf,rgb565_buf, width,height,32,64);
}
if(choice == 2 || choice ==3)
{
CLEAR (buf2);
buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf2.memory = V4L2_MEMORY_MMAP;
ioctl (fd2, VIDIOC_DQBUF, &buf2); //出列采集的帧缓冲
assert (buf2.index < n_buffers);
convert_yuv_to_rgb_buffer(buffers2[buf2.index].start,rgb888_buf, width,height);
convert_rgb888_to_rgb565_buffer(rgb888_buf,rgb565_buf, width,height,272,64);
}
size=write(fd0,rgb565_buf,480*272*2);
close (fd0);
if((fd0 = open("/dev/fb0", O_RDWR)) < 0){
handle_error("when open framebuffer device");
}
ioctl (fd1, VIDIOC_QBUF, &buf1); //再将其入列
ioctl (fd2, VIDIOC_QBUF, &buf2); //再将其入列
//printf("size=%d\n",size);
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void framebuffer_init(void)
{
printf("I am framebuffer\n");
if((fd0 = open("/dev/fb0", O_RDWR)) < 0){
handle_error("when open framebuffer device");
}
if(ioctl(fd0, FBIOGET_FSCREENINFO, &finfo)){
handle_error("FBIOGET_FSCREENINFO");
}
if(ioctl(fd0, FBIOGET_VSCREENINFO, &vinfo)){
handle_error("FBIOGET_VSCREENINFO");
}
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
printf("screensize=%d\n",screensize);
printf("vinfo.xres=%d\n",vinfo.xres);
printf("vinfo.yres=%d\n",vinfo.yres);
printf("vinfo.bits.per.pixel=%d\n",vinfo.bits_per_pixel);
printf("finfo.line_length=%d\n",finfo.line_length);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cma1_init(void)
{
struct v4l2_format fmt;
struct v4l2_capability cap;
fd1 = open (dev_name1, O_RDWR /* required */ | O_NONBLOCK, 0);//打开设备
ioctl (fd1, VIDIOC_QUERYCAP, &cap);//获取摄像头参数
CLEAR (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;
ioctl (fd1, VIDIOC_S_FMT, &fmt); //设置图像格式
file_length = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; //计算图片大小
printf ("cam1_whidth = %d\n",fmt.fmt.pix.width);
printf ("cam1_height = %d\n",fmt.fmt.pix.height);
printf ("cam1_picsize = %d\n\n",file_length);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void cam1_mmap(void)
{
struct v4l2_requestbuffers req;
CLEAR (req);
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ioctl (fd1, VIDIOC_REQBUFS, &req); //申请缓冲,count是申请的数量
if (req.count < 2)
printf("Insufficient buffer memory\n");
buffers1 = calloc (req.count, sizeof (*buffers1));//内存中建立对应空间
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 (fd1, VIDIOC_QUERYBUF, &buf)) //映射用户空间
printf ("VIDIOC_QUERYBUF error\n");
buffers1[n_buffers].length = buf.length;
buffers1[n_buffers].start = mmap (NULL,/*通过mmap建立映射关系*/ buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,fd1, buf.m.offset);
if (MAP_FAILED == buffers1[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 (fd1, VIDIOC_QBUF, &buf))//申请到的缓冲进入列队
printf ("VIDIOC_QBUF failed\n");
}
}
////
基于video4linux2的双usb摄像头图像获取显示
5星 · 超过95%的资源 需积分: 44 179 浏览量
2011-06-22
10:05:36
上传
评论 5
收藏 4KB RAR 举报
maxrooming
- 粉丝: 2
- 资源: 28
最新资源
- KIMI大模型浏览器插件
- b61fa64a08a02de0e0d49d53bb84c444.amr
- 5ffd9193f6aec31bbf16030a46680dc7.avi
- DA14531-蓝牙传感器连接传输数据固件
- logisim实验MIPS运算器(ALU)设计(内含4位先行进位74182、四位快速加法器、32位快速加法器)-Educoder_logisim里面连线,实现4位先行进位74182和4位快速加法器-C
- 高等数学第一章第二节数列的极限
- Python 版冒泡排序算法源代码
- 基于YOLOv8的教室人脸识别 附源码 预训练模型
- 基于JAVA实现的用于全局监控网络请求错误并记录日志的library
- tensorflow-gpu-2.7.2-cp38-cp38-manylinux2010-x86-64.whl
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
前往页