#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <linux/videodev2.h>
#include "video_capture.h"
#include "h264encoder.h"
#include <iostream>
using namespace std;
#define CLEAR(x) memset(&(x),0,sizeof(x))
typedef unsigned char uint8_t;
char h264_file_name[100]="/myvideosave/myvideo.h264";
FILE *h264_fp;
uint8_t *h264_buf;
char yuv_file_name[100]="/myvideosave/myvideo.yuv";
FILE *yuv_fp;
unsigned int n_buffers=0;
Encoder en;
int cnt=0;
void open_camera(camera *cam)
{
cout<<"===>>open camera"<<endl;
struct stat st;
if(-1==stat(cam->device_name,&st))
{
cout<<"Cannot identify device"<<endl;
return;
}
if(!S_ISCHR(st.st_mode))
{
cout<<cam->device_name<<" is no a device"<<endl;
return;
}
cam->fd=open(cam->device_name,O_RDWR,0);
if(-1==cam->fd)
{
cout<<"Cannot open "<<cam->device_name<<endl;
return;
}
else
cout<<"====>>camera open OK"<<endl;
}
void close_camera(camera *cam)
{
if(-1==close(cam->fd))
cout<<"Cannot close camera"<<endl;
cam->fd=-1;
}
void init_file()
{
cout<<"====>>init file"<<endl;
h264_fp=fopen(h264_file_name,"wa+");
yuv_fp=fopen(yuv_file_name,"wa+");
cout<<"====>>init file OK"<<endl;
}
void close_file()
{
fclose(h264_fp);
fclose(yuv_fp);
}
void init_encoder(struct camera*cam)
{
cout<<"====>>init encoder"<<endl;
compress_begin(&en,cam->width,cam->height);
h264_buf=(uint8_t *)malloc(sizeof(uint8_t)*cam->width*cam->height*3);
cout<<"====>>encoder init OK"<<endl;
}
void close_encoder()
{
compress_end(&en);
free(h264_buf);
h264_buf=NULL;
}
void encode_frame(uint8_t *yuv_frame,size_t yuv_length)
{
int h264_length=0;
if(yuv_frame[0]=='\0')
return;
else
cout<<"OK"<<endl;
h264_length=compress_frame(&en,-1,yuv_frame,h264_buf);
if(h264_length>0)
fwrite(h264_buf,h264_length,1,h264_fp);
else
cout<<"h264_length error"<<endl;
cout<<"h264_length :"<<h264_length<<endl;
cout<<"yuv_length :"<<yuv_length<<endl<<endl;
fwrite(yuv_frame,yuv_length,1,yuv_fp);
}
int read_and_encode_frame(camera *cam)
{
struct v4l2_buffer buf;
cout<<"in read a frame"<<endl;
CLEAR(buf);
buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory=V4L2_MEMORY_MMAP;
if(-1==ioctl(cam->fd,VIDIOC_DQBUF,&buf))
{
cout<<"Cannot DQBUF"<<endl;
return -1;
}
encode_frame(cam->buffers[buf.index].start,buf.length);
if(-1==ioctl(cam->fd,VIDIOC_QBUF,&buf))
{
cout<<"Cannot QBUF"<<endl;
return -1;
}
return 1;
}
void start_capturing(camera *cam)
{
cout<<"====>>start capturing"<<endl;
unsigned int i;
enum v4l2_buf_type type;
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(cam->fd,VIDIOC_QBUF,&buf))
{
cout<<"QBUF error"<<endl;
return;
}
}
type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(-1==ioctl(cam->fd,VIDIOC_STREAMON,&type))
{
cout<<"Stream on error"<<endl;
return;
}
cout<<"====>>start capturing OK"<<endl;
}
void stop_capturing(camera *cam)
{
enum v4l2_buf_type type;
type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(-1==ioctl(cam->fd,VIDIOC_STREAMOFF,&type))
{
cout<<"Stream off error"<<endl;
return;
}
}
void uninit_camera(camera *cam)
{
unsigned int i;
for(i=0;i<n_buffers;++i)
if(-1==munmap(cam->buffers[i].start,cam->buffers[i].length))
{
cout<<"Munmap error"<<endl;
return;
}
free(cam->buffers);
cam->buffers=NULL;
}
void init_mmap(camera *cam)
{
cout<<"====>>init mmap"<<endl;
struct v4l2_requestbuffers req;
CLEAR(req);
req.count=4;
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
if(-1==ioctl(cam->fd,VIDIOC_REQBUFS,&req))
{
cout<<"REQBUF error"<<endl;
return;
}
if(req.count<2)
{
cout<<"Insufficient buffer memory on "<<cam->device_name<<endl;
return;
}
cam->buffers=NULL;
cam->buffers=(buffer *)calloc(req.count,sizeof(*(cam->buffers)));
if(!cam->buffers)
{
cout<<"Out of memory"<<endl;
return;
}
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(cam->fd,VIDIOC_QUERYBUF,&buf))
{
cout<<"mmap querybuf error"<<endl;
return;
}
cam->buffers[n_buffers].length=buf.length;
cam->buffers[n_buffers].start=(unsigned char *)mmap(NULL,buf.length,PROT_READ | PROT_WRITE,MAP_SHARED,cam->fd,buf.m.offset);
if(MAP_FAILED==cam->buffers[n_buffers].start)
{
cout<<"mmap error"<<endl;
return;
}
}
cout<<"====>>init mmap OK"<<endl;
}
void init_camera(camera *cam)
{
cout<<"====>>init camera"<<endl;
struct v4l2_capability *cap = &(cam->v4l2_cap);
struct v4l2_cropcap *cropcap = &(cam->v4l2_cropcap);
struct v4l2_crop *crop = &(cam->crop);
struct v4l2_format *fmt = &(cam->v4l2_fmt);
unsigned int min;
if(-1==ioctl(cam->fd,VIDIOC_QUERYCAP,cap))
{
cout<<"Cannot querycap"<<endl;
return;
}
if((cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)==0)
{
cout<<cam->device_name<<" is no video capture device"<<endl;
return;
}
if(!(cap->capabilities & V4L2_CAP_STREAMING))
{
cout<<cam->device_name<<" does not support streaming i/o"<<endl;
return;
}
cout<<"VIDOOC_QUERYCAP information :"<<endl;
cout<<"the camera driver is"<<cap->driver<<endl;
cout<<"the camera card is "<<cap->card<<endl;
cout<<"the camera bus info is "<<cap->bus_info<<endl;
cout<<"the version is "<<cap->version<<endl;
CLEAR(*cropcap);
cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop->c.width = cam->width;
crop->c.height = cam->height;
crop->c.left = 0;
crop->c.top = 0;
crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
CLEAR(*fmt);
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt->fmt.pix.width = cam->width;
fmt->fmt.pix.height = cam->height;
fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; //yuv422
fmt->fmt.pix.field=V4L2_FIELD_INTERLACED;
if(-1==ioctl(cam->fd,VIDIOC_S_FMT,fmt))
{
cout<<"set fromat error"<<endl;
return;
}
min=fmt->fmt.pix.width*2;
if(fmt->fmt.pix.bytesperline<min)
fmt->fmt.pix.bytesperline=min;
min=fmt->fmt.pix.bytesperline*fmt->fmt.pix.height;
if(fmt->fmt.pix.sizeimage<min)
fmt->fmt.pix.sizeimage=min;
init_mmap(cam);
cout<<"====>>init camera OK"<<endl;
}
void v4l2_init(camera *cam)
{
cout<<"====>>v4l2 init"<<endl;
open_camera(cam);
init_camera(cam);
start_capturing(cam);
init_encoder(cam);
init_file();
cout<<"====>>v4l2_init OK"<<endl;
}
void v4l2_close(camera *cam)
{
cout<<"===>>v4l2_closing"<<endl;
stop_capturing(cam);
uninit_camera(cam);
close_camera(cam);
free(cam);
close_file();
close_encoder();
cout<<"v4l2 close completed"<<endl;
}
没有合适的资源?快使用搜索试试~ 我知道了~
基于Qt的摄像头采集数据和264编码,并写入本地文件,可播放
2星 需积分: 50 55 下载量 135 浏览量
2018-01-11
17:17:22
上传
评论 3
收藏 9KB GZ 举报
温馨提示
共12个文件
h:4个
cpp:4个
ui:1个
基于Qt,使用x264对摄像头采集数据进行264编码并将其写入本地文件,可播放。调试麻烦先修改.pro文件中ffmpeg和x264库的动态链接库和文件包含路径
资源推荐
资源详情
资源评论
收起资源包目录
h264camerasaveusedbutton.tar.gz (12个子文件)
h264camerasaveusedbutton
mainwindow.ui 2KB
h264encoder.h 452B
mainwindow.cpp 523B
h264encoder.cpp 4KB
video_capture.cpp 7KB
h264camerasaveusedbutton.pro.user 18KB
main.cpp 172B
h264camerasaveusedbutton.pro 522B
Makefile 9KB
threadreadframe.h 2KB
mainwindow.h 437B
video_capture.h 908B
共 12 条
- 1
资源评论
- 夏天匆匆2过2022-07-11并不是基于QT的QCamera,用的V4L #参考意义不大
- 不熟的地瓜2021-03-05文件夹为空
foxmoke
- 粉丝: 16
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功