Linux 下 v4l2采集yuyv用sdl2播放

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>
#include<linux/videodev2.h>
#include<string.h>
#include<errno.h>
#include<sys/mman.h>
#include<SDL2/SDL.h>
#include<assert.h>

#define LOAD_BGRA  0
#define LOAD_RGB24  0
#define LOAD_BGB24  0
#define LOAD_YUYV422P 1


#define PIXEL_W 640
#define PIXEL_H 480
#define SCREEN_W 640
#define SCREEN_H 480

#if LOAD_BGRA 
#define BPP 32
#elif LOAD_RGB24 | LOAD_BRG24
#define BPP 24
#elif LOAD_YUYV422P
#define BPP 16
#endif


int screen_w=SCREEN_W;
int screen_h=SCREEN_H;

const int pixel_w=PIXEL_W;
const int pixel_h=PIXEL_H;

unsigned char buffer[PIXEL_W*PIXEL_H*BPP/8];

unsigned char buffer_convert[PIXEL_W*PIXEL_H*4];


struct buffers
{
	void* start;
	unsigned int length;
}*buffers;





int main()
{

	int fd=open("/dev/video0",O_RDWR);
	if(fd<0)
	{
		printf("open failure\n");
		return -1;
	}

	int ret=-1;
	struct v4l2_capability cap;
	ret=ioctl(fd,VIDIOC_QUERYCAP,&cap);
	if(ret<0)
	{
		perror("ioctl");
		return -1;
	}

	if(!(cap.capabilities & V4L2_BUF_TYPE_VIDEO_CAPTURE))
	{
		printf("not support video capture\n");
		return -1;
	}


	struct v4l2_fmtdesc fmtdesc;
	fmtdesc.index=0;

	fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
	{
		printf("%d\t%d\n",fmtdesc.index+1,fmtdesc.type);
	    fmtdesc.index++;
	}

	struct v4l2_requestbuffers req;
	req.count=4;
	req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	req.memory=V4L2_MEMORY_MMAP;

	ret=ioctl(fd,VIDIOC_REQBUFS,&req);
	if(ret<0)
	{
		printf("out of memory\n");
		return -1;
	}
	

	buffers=(struct buffers*)calloc(req.count,sizeof(*buffers));
	assert(buffers!=NULL);

	struct v4l2_buffer buf;
	for(int n_buffers=0;n_buffers < req.count;n_buffers++)
  	{
		memset(&buf,0,sizeof(buf));
		buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
		buf.memory=V4L2_MEMORY_MMAP;
		buf.index=n_buffers;

		if(ioctl(fd,VIDIOC_QUERYBUF,&buf)==-1)
 		{
			printf(" qurey failure\n");
			return -1;
		}

		buffers[n_buffers].length=buf.length;
		buffers[n_buffers].start=mmap(NULL,buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,fd,buf.m.offset);
		if(MAP_FAILED==buffers[n_buffers].start)
		{
			perror("mmap");
			return -1;
		}

	}
		//capture
		unsigned int i=0;
		enum v4l2_buf_type type;
		for(i=0;i<4;i++)
 		{
			buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
			buf.memory=V4L2_MEMORY_MMAP;
			buf.index=i;

			if(ret=ioctl(fd,VIDIOC_QBUF,&buf)<0)
  			{
				perror("qbuf");
				return -1;
			}
		}
			type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
			ret=ioctl(fd,VIDIOC_STREAMON,&type);
				if(ret<0)
				{
					perror("streamon");
					return -1;
				}


			//sdl broatcast
			if(!(SDL_Init(SDL_INIT_VIDEO)))
			{ 
				printf(" sdl_init failure\n");
				return -1;
			}
            
			SDL_Window* screen=SDL_CreateWindow("simple sdl player",
					SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,/***X,Y postion            ******/ screen_w,screen_h,SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

			if(screen==NULL)
			{
				printf(" sdl create window failure\n");
				return -1;
			}

			SDL_Renderer*  sdlRenderer=SDL_CreateRenderer(screen,-1,0);

			Uint32 pixformat=0;
#if LOAD_BGRA
			pixformat=SDL_PIXFORMAT_ARGB888;
#elif LOAD_BGR24
			pixformat=SDL_PIXFORMAT_BGR888;
#elif LOAD_RGB24
		    pixformat=SDL_PIXFORMAT_RGB888;
#elif LOAD_YUV422P
			pixformat=SDL_PIXFORMAT_YUY2;
#endif
			SDL_Texture* texture=SDL_CreateTexture(sdlRenderer,pixformat,
					SDL_TEXTUREACCESS_STREAMING,pixel_w,pixel_h);

			SDL_Rect sdlRect;
		//struct v4l2_buffer buf;
			while(1)
			{
				buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
				buf.memory=V4L2_MEMORY_MMAP;

				ret=ioctl(fd,VIDIOC_DQBUF,&buf);
				if(ret<0)
  				{
					perror("v4l2_buf");
					return -1;
				}
                
				/**************programe process*****************/

#if LOAD_BGRA
				SDL_UpdateTexture(sdlTexture,NULL,buffer,pixel_w*4);
#elif LOAD_BGR24 | LOAD_RGB24
				convert _24to32(buffer,buffer_convert,pixel_w,pixel_h);
				SDL_UpdateTexture(sdlTexture,NULL,buffer_convert,pixel_w*4);
#elif LOAD_YUV422p
				SDL_UpdateTexture(sdlTexture,NULL,buffer[buf.index].start,pixel_w*2);
#endif


				sdlRect.x=0;
				sdlRect.y=0;
				sdlRect.w=screen_w;
				sdlRect.h=screen_h;
				SDL_RenderPresent(sdlRenderer);
				SDL_Delay(20);

				ret=ioctl(fd,VIDIOC_QBUF,&buf);
				if(ret<0)
				{
					perror("ioctl");
					return -1;
				}
			}
				close(fd);
				return -1;

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值