接着上一接博客继续写。
采集YUV视频很简单,比采集bmp图片更简单,因为采集图片还要考虑图片格式,要做YUV到RGB的格式转换等工作。而采集YUV视频直接把采集的YUV数据丢进一个文件里就行了。
在上一篇博客里,修改一点点代码就可以完成采集YUV视频的工作了。
static int readfram()
{
struct pollfd pollfd;
int ret,i;
char filename[50];
for(;;){
memset(&pollfd, 0, sizeof(pollfd));
pollfd.fd = fd;
pollfd.events = POLLIN;
ret = poll(&pollfd, 1, 800);
if(-1 == ret){
perror("VIDIOC_QBUF fail.\n");
return -1;
}else if(0 == ret){
printf("poll time out\n");
continue;
}
printf("-------------poll success---------------\n");
// static struct v4l2_buffer buf;
if(pollfd.revents & POLLIN){
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
if(0 != ret){
perror("VIDIOC_QBUF fail.\n");
return -1;
}
//v4l2_buffer
// 直接保存的yuyv数据的视频
ret = fwrite((char*)framebuf[buf.index].start, 1, buf.length, file);
// RGB格式数据的bmp图片
/*
starter = (unsigned char*)framebuf[buf.index].start;
newBuf = (unsigned char*)calloc((unsigned int)(framebuf[buf.index].length*3/2),sizeof(unsigned char));
yuv422_2_rgb();
create_bmp_header();
//yuyv422toBGRY(starter);
sprintf(filename,"rgb%d.bmp",i);
FILE *file1 = fopen(filename, "wb");
fwrite(&bfh,sizeof(bfh),1,file1);
fwrite(&bih,sizeof(bih),1,file1);
fwrite(newBuf, 1, buf.length*3/2, file1);
//fwrite(rgb, 1, width*height*3, file1);
fclose(file1);
*/
ret = ioctl(fd, VIDIOC_QBUF, &buf);
}
}
return ret;
}
仅仅把readfram()函数做了一点修改,然后打开和关闭在这个文件在main()函数中完成。
file = fopen(YUV_VIDEO, "wa+");
readfram();
fclose(file);
源码可以从我的git上下载:
“`
git clone https://github.com/zhangdalei/v4l2-.git
···
和上一节博客一样,采集视频的代码也是不能再PC上正常运行,采集的视频有条纹等各种问题,在我的开发版上可以正常使用,采集的视频可以正常播放。
采集的视频格式是.yuv格式,使用的播放器是pYUV。在使用这个播放器是,打开视频时会设置一些选项,这是设置界面的截图:
图片里最后一行有两个可勾选的选项,第一项是Interleaved,这是必须要勾选,不然播放会有问题。这叫做隔行扫描,因为在应用中设置视频格式是就设置的隔行扫描。
播放效果: