跪求大神Qt5.8+V4L2实现USB摄像头实时显示界面!!!!非常急liunx平台
解决方案 »
- kernel 移植,一直停留在 Starting kernel ...
- netfilter 抓包抓不到出去报文的以太网报头 应该怎么设置
- 真机上安装centos 7提示“no suitable images”
- ubuntu 18.04 设置启动怎么这么难
- 求解linux配网得ping不通外网
- c语言中的#line是什么意思 有答案
- zabbix抽取server端mysql数据进行BI可视化!
- linux系统配置网卡信息
- centos7 安装gcc 出现问题
- linux内核版本问题
- Ubuntu 自动锁屏后,输入的密码无效
- centos 7下安装openfire,每次centos 7重启后,都要在网页初始化设置
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include "v4l2grab.h"
#define TRUE 1
#define FALSE 0#define VIDEO_DEV "/dev/video0"
#define BMP "image_bmp.bmp"
#define YUV "image_yuv.yuv"#define IMAGE_WIDTH 1280
#define IMAGE_HEIGHT 720static int fd;
static struct v4l2_capability cap;
struct v4l2_fmtdesc fmtdesc;
struct v4l2_format fmt,fmtack;
struct v4l2_streamparm setfps;
struct v4l2_requestbuffers req;
struct v4l2_buffer buf;
enum v4l2_buf_type type;
unsigned char frame_buffer[IMAGE_WIDTH*IMAGE_HEIGHT*3];
struct buffer
{
void * start;
unsigned int length;
} * buffers;
int init_v4l2(void)
{
int i;
int ret = 0;
//open video
if ((fd = open(VIDEO_DEV, O_RDWR)) == -1)
{
printf("Error opening V4L interface\n");
return (FALSE);
} //query cap
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)
{
printf("Error opening device %s: unable to query device.\n",VIDEO_DEV);
return (FALSE);
}
else
{
printf("driver:\t\t%s\n",cap.driver);
printf("card:\t\t%s\n",cap.card);
printf("bus_info:\t%s\n",cap.bus_info);
printf("version:\t%d\n",cap.version);
printf("capabilities:\t%x\n",cap.capabilities);
if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE)
{
printf("Device %s: supports capture.\n",VIDEO_DEV);
} if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING)
{
printf("Device %s: supports streaming.\n",VIDEO_DEV);
}
}
//emu all support fmt
fmtdesc.index=0;
fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("Support format:\n");
while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
{
printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);
fmtdesc.index++;
}
//set fmt
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.height = IMAGE_HEIGHT;
fmt.fmt.pix.width = IMAGE_WIDTH;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{
printf("Unable to set format\n");
return FALSE;
}
if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{
printf("Unable to get format\n");
return FALSE;
}
{
printf("fmt.type:\t\t%d\n",fmt.type);
printf("pix.pixelformat:\t%c%c%c%c\n",fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,(fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF);
printf("pix.height:\t\t%d\n",fmt.fmt.pix.height);
printf("pix.width:\t\t%d\n",fmt.fmt.pix.width);
printf("pix.field:\t\t%d\n",fmt.fmt.pix.field);
}
printf("init %s \t[OK]\n",VIDEO_DEV);
return TRUE;
}int v4l2_grab(void)
{
unsigned int n_buffers;
//request for 4 buffers
req.count=4;
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
if(ioctl(fd,VIDIOC_REQBUFS,&req)==-1)
{
printf("request for buffers error\n");
} //mmap for buffers
buffers = malloc(req.count*sizeof (*buffers));
if (!buffers)
{
printf ("Out of memory\n");
return(FALSE);
}
for (n_buffers = 0; n_buffers < req.count; n_buffers++)
{
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;
//query buffers
if (ioctl (fd, VIDIOC_QUERYBUF, &buf) == -1)
{
printf("query buffer error\n");
return(FALSE);
} buffers[n_buffers].length = buf.length;
//map
buffers[n_buffers].start = mmap(NULL,buf.length,PROT_READ |PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if (buffers[n_buffers].start == MAP_FAILED)
{
printf("buffer map error\n");
return(FALSE);
}
}
//queue
for (n_buffers = 0; n_buffers < req.count; n_buffers++)
{
buf.index = n_buffers;
ioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ioctl (fd, VIDIOC_STREAMON, &type);
ioctl(fd, VIDIOC_DQBUF, &buf); printf("grab yuyv OK\n");
return(TRUE);
}
int yuyv_2_rgb888(unsigned char *yuv, unsigned char *rgb, int width, int height)
{
int i,j;
unsigned char y1,y2,u,v;
int r1,g1,b1,r2,g2,b2;
char * pointer;
pointer = yuv;
width /=2;
for(i=0;i<height;i++)
{
for(j=0;j<width;j++)
{
y1 = *( pointer + (i*width+j)*4);
u = *( pointer + (i*width+j)*4 + 1);
y2 = *( pointer + (i*width+j)*4 + 2);
v = *( pointer + (i*width+j)*4 + 3);
r1 = y1 + 1.042*(v-128);
g1 = y1 - 0.34414*(u-128) - 0.71414*(v-128);
b1 = y1 + 1.772*(u-128);
r2 = y2 + 1.042*(v-128);
g2 = y2 - 0.34414*(u-128) - 0.71414*(v-128);
b2 = y2 + 1.772*(u-128);
if(r1>255)
r1 = 255;
else if(r1<0)
r1 = 0;
if(b1>255)
b1 = 255;
else if(b1<0)
b1 = 0;
if(g1>255)
g1 = 255;
else if(g1<0)
g1 = 0;
if(r2>255)
r2 = 255;
else if(r2<0)
r2 = 0;
if(b2>255)
b2 = 255;
else if(b2<0)
b2 = 0;
if(g2>255)
g2 = 255;
else if(g2<0)
g2 = 0;
*(rgb + ((height-1-i)*width+j)*6 ) = (unsigned char)b1;
*(rgb + ((height-1-i)*width+j)*6 + 1) = (unsigned char)g1;
*(rgb + ((height-1-i)*width+j)*6 + 2) = (unsigned char)r1;
*(rgb + ((height-1-i)*width+j)*6 + 3) = (unsigned char)b2;
*(rgb + ((height-1-i)*width+j)*6 + 4) = (unsigned char)g2;
*(rgb + ((height-1-i)*width+j)*6 + 5) = (unsigned char)r2;
}
}
printf("change to RGB OK \n");
}int close_v4l2(void)
{
if(fd != -1)
{
close(fd);
return (TRUE);
}
return (FALSE);
}
int main(void)
{
FILE * fp1,* fp2;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
fp1 = fopen(BMP, "wb");
if(!fp1)
{
printf("open "BMP"error\n");
return(FALSE);
}
fp2 = fopen(YUV, "wb");
if(!fp2)
{
printf("open "YUV"error\n");
return(FALSE);
}
if(init_v4l2() == FALSE)
{
return(FALSE);
}
//Set BITMAPINFOHEADER
bi.biSize = 40;
bi.biWidth = IMAGE_WIDTH;
bi.biHeight = IMAGE_HEIGHT;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = 0;
bi.biSizeImage = IMAGE_WIDTH*IMAGE_HEIGHT*3;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//Set BITMAPFILEHEADER
bf.bfType = 0x4d42;
bf.bfSize = 54 + bi.biSizeImage;
bf.bfReserved = 0;
bf.bfOffBits = 54;
v4l2_grab();
fwrite(buffers[0].start, buffers[0].length, 1, fp2);
printf("save yuv OK\n");
yuyv_2_rgb888(buffers[0].start, frame_buffer, IMAGE_WIDTH, IMAGE_HEIGHT);
fwrite(&bf, 14, 1, fp1);
fwrite(&bi, 40, 1, fp1);
fwrite(frame_buffer, bi.biSizeImage, 1, fp1);
printf("save "BMP"OK\n");
fclose(fp1);
fclose(fp2);
close_v4l2();
return(TRUE);
}/****************************************************/
/* */
/* v4lgrab.h */
/* */
/****************************************************/
#ifndef __V4LGRAB_H__
#define __V4LGRAB_H__
#include <stdio.h> //typedef enum { FALSE = 0, TRUE = 1, OK = 2} BOOL; //#define SWAP_HL_WORD(x) {(x) = ((x)<<8) | ((x)>>8);}//#define SWAP_HL_DWORD(x) {(x) = ((x)<<24) | ((x)>>24) | (((x)&0xff0000)>>8) | (((x)&0xff00)<<8);} #define FREE(x) if((x)){free((x));(x)=NULL;} typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;/**/
#pragma pack(1)typedef struct tagBITMAPFILEHEADER{
WORD bfType; // the flag of bmp, value is "BM"
DWORD bfSize; // size BMP file ,unit is bytes
DWORD bfReserved; // 0
DWORD bfOffBits; // must be 54}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // must be 0x28
DWORD biWidth; //
DWORD biHeight; //
WORD biPlanes; // must be 1
WORD biBitCount; //
DWORD biCompression; //
DWORD biSizeImage; //
DWORD biXPelsPerMeter; //
DWORD biYPelsPerMeter; //
DWORD biClrUsed; //
DWORD biClrImportant; //
}BITMAPINFOHEADER;typedef struct tagRGBQUAD{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
}RGBQUAD; #if defined(__cplusplus)
extern "C" { /* Make sure we have C-declarations in C++ programs */
#endif //if successful return 1,or else return 0
int openVideo();
int closeVideo();//data 用来存储数据的空间, size空间大小
void getVideoData(unsigned char *data, int size);
#if defined(__cplusplus)
}#endif
#endif //__V4LGRAB_H___