代码拉取完成,页面将自动刷新
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <sys/types.h>
#include <sys/select.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <asm/types.h>
#include <sys/stat.h>
#include "file_list.h"
#include <dirent.h>
struct video_buffer {
void *start;
size_t length;
size_t offset;
int out_height;
int out_width;
int dis_x_off;
int dis_y_off;
};
pFileList read_video_devs()
{
DIR *root = opendir("/dev");
if (NULL == root)
return NULL;
pFileList head;
initHead(&head);
struct dirent *filedir;
while ((filedir = readdir(root)) != NULL)
{
#ifdef DEBUG_NO
printf("type:%d name:%s\n",filedir->d_type, filedir->d_name);
#endif
if (filedir->d_type == DT_CHR && !strncmp(filedir->d_name,"video",5))
{
int ret = insertTail(head, filedir->d_name);
if (ret < 0)
{
printf("insert name error.\n");
}
}
}
return head;
}
void printFMT(int fmt)
{
printf("FMT is %c%c%c%c\n",fmt & 0xff, fmt >> 8 &0xff, fmt >> 16 & 0xff, fmt >> 24 & 0xff);
}
int main(int argc, char *argv[])
{
int ret = 0;
struct v4l2_capability cap;
// pFileList video_devs = read_video_devs();
// if (NULL == video_devs)
// {
// printf("Couldn't find video devices.\n");
// return -1;
// }
while (1)
{
char devname[32] = {"/dev/"};
strncat(devname, "video0", ARRAY_SIZE);
int fd = open(devname, O_RDWR);
if (fd < 0)
{
printf("Couldn't open video device file:%s\n", devname);
break;
}
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if (ret < 0)
{
printf("Get video card capabilities error!\n");
continue;
}
printf("%s : %s %s 0x%x; cap:0x%x\n",devname, cap.driver,cap.bus_info, cap.version, cap.capabilities);
printf(" VIDEO OUTPUT: %d\n", V4L2_CAP_VIDEO_OUTPUT & cap.capabilities);
printf(" VIDEO CAPTURE: %d\n", V4L2_CAP_VIDEO_CAPTURE & cap.capabilities);
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index = 0;
fmtdesc.type = V4L2_CAP_VIDEO_CAPTURE_MPLANE;
while((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)) == 0)
{
printf(" Index: %d Desc: %s 0x%x\n",fmtdesc.index, fmtdesc.description,fmtdesc.pixelformat);
fmtdesc.index++;
}
int chs = -1;
struct v4l2_input input;
input.index = 0;
if (ret = ioctl(fd, VIDIOC_ENUMINPUT, &input) < 0) {
printf("ioctl(VIDIOC_G_INPUT): ret = %d\n", ret);
// av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_G_INPUT): %s\n", av_err2str(res));
close(fd);
return 0;
}
// V4L2_INPUT_TYPE_CAMERA
printf("当前视频输入源索引号:%d\n", input.index);
printf("当前视频输入源类型:%d\n", input.type);
printf("当前视频输入源名称:%s\n", input.name);
struct v4l2_format format;
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if ((ret = ioctl(fd, VIDIOC_G_FMT, &format)) < 0)
{
perror("VIDIOC_G_FMT error:");
return -1;
}
struct v4l2_pix_format_mplane *fmtp = &format.fmt.pix_mp;
printf("Size(%d,%d), Pix Format:%d, num_planes:%d \n", fmtp->width, fmtp->height, fmtp->pixelformat, fmtp->num_planes);
printFMT(fmtp->pixelformat);
for (int i = 0; i < fmtp->num_planes; i++)
{
struct v4l2_plane_pix_format * ppfmt = &fmtp->plane_fmt[i];
printf("plane(%d), sizeimage(%d), bytesperline(%d)\n", i, ppfmt->sizeimage, ppfmt->bytesperline);
}
memset(&format, 0, sizeof(format));
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
format.fmt.pix_mp.width = 3840;
format.fmt.pix_mp.height = 2160;
format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB24;
format.fmt.pix_mp.field = V4L2_FIELD_ANY;
if (ret = ioctl(fd, VIDIOC_S_FMT, &format) < 0)
{
perror("VIDIOC_S_FMT error!\n");
return -1;
}
printFMT(format.fmt.pix_mp.pixelformat);
struct v4l2_requestbuffers req_bufs;
req_bufs.count = 1;
req_bufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
req_bufs.memory = V4L2_MEMORY_MMAP;
if (ret = ioctl(fd, VIDIOC_REQBUFS, &req_bufs) < 0)
{
perror("VIDIOC_REQBUFS error!\n");
return -1;
}
struct v4l2_buffer buf;
struct v4l2_plane *plane_buf = calloc(format.fmt.pix_mp.num_planes, sizeof(struct v4l2_plane));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
buf.index = 0;
buf.memory = V4L2_MEMORY_MMAP;
buf.m.planes = plane_buf;
buf.length = format.fmt.pix_mp.num_planes;
if (ret = ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0)
{
perror("VIDIOC_QUERYBUF error!\n");
return -1;
}
struct video_buffer vbuf;
vbuf.length = buf.m.planes[0].length;
vbuf.offset = buf.m.planes[0].m.mem_offset;
printf("planes len = %d\n",buf.m.planes->length);
vbuf.start = mmap(NULL, buf.m.planes->length, PROT_READ |PROT_WRITE, MAP_SHARED, fd, vbuf.offset);
struct v4l2_plane *tplane = calloc(1, sizeof(struct v4l2_plane));
struct v4l2_buffer qbuf;
memset(&qbuf, 0, sizeof(qbuf));
qbuf.memory = V4L2_MEMORY_MMAP;
qbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
qbuf.m.planes = tplane;
qbuf.length = 1;
printf("vbuf len:%d, memoffset:%d\n", vbuf.length, vbuf.offset);
qbuf.m.planes->length = vbuf.length;
qbuf.m.planes->m.mem_offset = vbuf.offset;
if (ret = ioctl(fd, VIDIOC_QBUF, &qbuf) < 0)
{
perror("VIDIOC_QBUF1 error!\n");
return -1;
}
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
if (ioctl(fd, VIDIOC_STREAMON, &type))
{
perror("VIDIOC_STREAMON error!\n");
return -1;
}
int num = 0;
// struct v4l2_plane * tmp_plane = calloc(1, sizeof(struct v4l2_plane));
// tmp_plane->m.userptr =(unsigned long)malloc(buf.m.planes->length);
fd_set fds;
struct timeval tt;
struct v4l2_buffer data_buf;
int count = 20;
tt.tv_sec = 10;
tt.tv_usec = 0;
int write_fd = open("./output.rgb24", O_RDWR | O_CREAT, S_IRUSR|S_IRGRP|S_IWUSR);
if (write_fd < 0)
{
perror("write file opne error:");
}
while (count-- > 0)
{
FD_ZERO(&fds);
FD_SET(fd, &fds);
int ret = select(fd+1, &fds, NULL, NULL, &tt);
if (ret == -1)
{
if (EINTR == errno)
{
continue;
}
perror("select error:");
}
if (ret == 0)
{
perror("select timeout\n");
// count --;
// if (count <= 0)
// break;
}
if (FD_ISSET(fd, &fds))
{
memset((void*)&data_buf, 0, sizeof(struct v4l2_buffer));
memset(tplane, 0, sizeof(*tplane));
data_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
data_buf.memory = V4L2_MEMORY_MMAP;
data_buf.m.planes = tplane;
data_buf.length = 1;
if (ioctl(fd, VIDIOC_DQBUF, &buf))
{
perror("VIDIOC_DQBUF error");
// break;
continue;
}
printf("length(%d), used(%d), data offset:(%d)\n",tplane->length, tplane->bytesused, tplane->data_offset);
struct v4l2_buffer bbbuf;
struct v4l2_plane *planes;
planes = malloc(1 * sizeof(*planes));
if (!planes) {
printf("alloc plane fail\n");
return -1;
}
memset(&bbbuf, 0, sizeof(bbbuf));
bbbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
bbbuf.memory = V4L2_MEMORY_MMAP;
bbbuf.m.planes = planes;
bbbuf.length = 1;
bbbuf.index = 0;
bbbuf.m.planes[0].length = vbuf.length;
bbbuf.m.planes[0].m.mem_offset = vbuf.offset;
if (ioctl(fd, VIDIOC_QBUF, &bbbuf) < 0)
{
printf("VIDIOC_QBUF2 error\n");
}
printf("palnes len = %d\n", bbbuf.m.planes[0].length);
write(write_fd, vbuf.start, bbbuf.m.planes[0].length);
free(planes);
count--;
}
}
close(write_fd);
close(fd);
return 0;
// devfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
// devfmt.fmt.pix.width = 640;
// devfmt.fmt.pix.height = 480;
// devfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
// devfmt.fmt.pix.field = V4L2_FIELD_NONE;
// if ((ret = ioctl(fd, VIDIOC_S_FMT, &devfmt)) < 0)
// {
// perror("Set FMT:");
// }
// printf(" ------------ \n");
// video_devs = video_devs->next;
break;
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。