896 lines
30 KiB
C++
896 lines
30 KiB
C++
#include "gvideoisp1.h"
|
||
#include <fcntl.h> /* low-level i/o */
|
||
#include <unistd.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/mman.h>
|
||
#include <sys/ioctl.h>
|
||
#include "linux/videodev2.h"
|
||
#include "linux/v4l2-subdev.h"
|
||
#include <dlfcn.h>
|
||
#include "string.h"
|
||
#include <iostream>
|
||
#include <malloc.h>
|
||
#include "applog.h"
|
||
#include "stringex.hpp"
|
||
|
||
static const std::string loggername = "GVideoISP1";
|
||
|
||
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||
|
||
#define V4L2_BUF_TYPE_META_OUTPUT 14
|
||
#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */
|
||
|
||
static struct {
|
||
enum v4l2_buf_type type;
|
||
bool supported;
|
||
const char *name;
|
||
const char *string;
|
||
} buf_types[] = {
|
||
{ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 1, "Video capture mplanes", "capture-mplane", },
|
||
{ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 1, "Video output", "output-mplane", },
|
||
{ V4L2_BUF_TYPE_VIDEO_CAPTURE, 1, "Video capture", "capture", },
|
||
{ V4L2_BUF_TYPE_VIDEO_OUTPUT, 1, "Video output mplanes", "output", },
|
||
{ V4L2_BUF_TYPE_VIDEO_OVERLAY, 0, "Video overlay", "overlay" },
|
||
//{ V4L2_BUF_TYPE_META_CAPTURE, 1, "Meta-data capture", "meta-capture", }//,
|
||
};
|
||
|
||
static struct v4l2_format_info {
|
||
const char *name;
|
||
unsigned int fourcc;
|
||
unsigned char n_planes;
|
||
} pixel_formats[] = {
|
||
{ "RGB332", V4L2_PIX_FMT_RGB332, 1 },
|
||
{ "RGB444", V4L2_PIX_FMT_RGB444, 1 },
|
||
{ "ARGB444", V4L2_PIX_FMT_ARGB444, 1 },
|
||
{ "XRGB444", V4L2_PIX_FMT_XRGB444, 1 },
|
||
{ "RGB555", V4L2_PIX_FMT_RGB555, 1 },
|
||
{ "ARGB555", V4L2_PIX_FMT_ARGB555, 1 },
|
||
{ "XRGB555", V4L2_PIX_FMT_XRGB555, 1 },
|
||
{ "RGB565", V4L2_PIX_FMT_RGB565, 1 },
|
||
{ "RGB555X", V4L2_PIX_FMT_RGB555X, 1 },
|
||
{ "RGB565X", V4L2_PIX_FMT_RGB565X, 1 },
|
||
{ "BGR666", V4L2_PIX_FMT_BGR666, 1 },
|
||
{ "BGR24", V4L2_PIX_FMT_BGR24, 1 },
|
||
{ "RGB24", V4L2_PIX_FMT_RGB24, 1 },
|
||
{ "BGR32", V4L2_PIX_FMT_BGR32, 1 },
|
||
{ "ABGR32", V4L2_PIX_FMT_ABGR32, 1 },
|
||
{ "XBGR32", V4L2_PIX_FMT_XBGR32, 1 },
|
||
{ "RGB32", V4L2_PIX_FMT_RGB32, 1 },
|
||
{ "ARGB32", V4L2_PIX_FMT_ARGB32, 1 },
|
||
{ "XRGB32", V4L2_PIX_FMT_XRGB32, 1 },
|
||
//{ "HSV24", V4L2_PIX_FMT_HSV24, 1 },
|
||
//{ "HSV32", V4L2_PIX_FMT_HSV32, 1 },
|
||
{ "Y8", V4L2_PIX_FMT_GREY, 1 },
|
||
{ "Y10", V4L2_PIX_FMT_Y10, 1 },
|
||
{ "Y12", V4L2_PIX_FMT_Y12, 1 },
|
||
{ "Y16", V4L2_PIX_FMT_Y16, 1 },
|
||
{ "UYVY", V4L2_PIX_FMT_UYVY, 1 },
|
||
{ "VYUY", V4L2_PIX_FMT_VYUY, 1 },
|
||
{ "YUYV", V4L2_PIX_FMT_YUYV, 1 },
|
||
{ "YVYU", V4L2_PIX_FMT_YVYU, 1 },
|
||
{ "NV12", V4L2_PIX_FMT_NV12, 1 },
|
||
{ "NV12M", V4L2_PIX_FMT_NV12M, 2 },
|
||
{ "NV21", V4L2_PIX_FMT_NV21, 1 },
|
||
{ "NV21M", V4L2_PIX_FMT_NV21M, 2 },
|
||
{ "NV16", V4L2_PIX_FMT_NV16, 1 },
|
||
{ "NV16M", V4L2_PIX_FMT_NV16M, 2 },
|
||
{ "NV61", V4L2_PIX_FMT_NV61, 1 },
|
||
{ "NV61M", V4L2_PIX_FMT_NV61M, 2 },
|
||
{ "NV24", V4L2_PIX_FMT_NV24, 1 },
|
||
{ "NV42", V4L2_PIX_FMT_NV42, 1 },
|
||
{ "YUV420M", V4L2_PIX_FMT_YUV420M, 3 },
|
||
{ "YUV422M", V4L2_PIX_FMT_YUV422M, 3 },
|
||
{ "YUV444M", V4L2_PIX_FMT_YUV444M, 3 },
|
||
{ "YVU420M", V4L2_PIX_FMT_YVU420M, 3 },
|
||
{ "YVU422M", V4L2_PIX_FMT_YVU422M, 3 },
|
||
{ "YVU444M", V4L2_PIX_FMT_YVU444M, 3 },
|
||
{ "SBGGR8", V4L2_PIX_FMT_SBGGR8, 1 },
|
||
{ "SGBRG8", V4L2_PIX_FMT_SGBRG8, 1 },
|
||
{ "SGRBG8", V4L2_PIX_FMT_SGRBG8, 1 },
|
||
{ "SRGGB8", V4L2_PIX_FMT_SRGGB8, 1 },
|
||
{ "SBGGR10_DPCM8", V4L2_PIX_FMT_SBGGR10DPCM8, 1 },
|
||
{ "SGBRG10_DPCM8", V4L2_PIX_FMT_SGBRG10DPCM8, 1 },
|
||
{ "SGRBG10_DPCM8", V4L2_PIX_FMT_SGRBG10DPCM8, 1 },
|
||
{ "SRGGB10_DPCM8", V4L2_PIX_FMT_SRGGB10DPCM8, 1 },
|
||
{ "SBGGR10", V4L2_PIX_FMT_SBGGR10, 1 },
|
||
{ "SGBRG10", V4L2_PIX_FMT_SGBRG10, 1 },
|
||
{ "SGRBG10", V4L2_PIX_FMT_SGRBG10, 1 },
|
||
{ "SRGGB10", V4L2_PIX_FMT_SRGGB10, 1 },
|
||
{ "SBGGR10P", V4L2_PIX_FMT_SBGGR10P, 1 },
|
||
{ "SGBRG10P", V4L2_PIX_FMT_SGBRG10P, 1 },
|
||
{ "SGRBG10P", V4L2_PIX_FMT_SGRBG10P, 1 },
|
||
{ "SRGGB10P", V4L2_PIX_FMT_SRGGB10P, 1 },
|
||
{ "SBGGR12", V4L2_PIX_FMT_SBGGR12, 1 },
|
||
{ "SGBRG12", V4L2_PIX_FMT_SGBRG12, 1 },
|
||
{ "SGRBG12", V4L2_PIX_FMT_SGRBG12, 1 },
|
||
{ "SRGGB12", V4L2_PIX_FMT_SRGGB12, 1 },
|
||
{ "DV", V4L2_PIX_FMT_DV, 1 },
|
||
{ "MJPEG", V4L2_PIX_FMT_MJPEG, 1 },
|
||
{ "MPEG", V4L2_PIX_FMT_MPEG, 1 },
|
||
};
|
||
|
||
static const struct {
|
||
const char *name;
|
||
enum v4l2_field field;
|
||
} fields[] = {
|
||
{ "any", V4L2_FIELD_ANY },
|
||
{ "none", V4L2_FIELD_NONE },
|
||
{ "top", V4L2_FIELD_TOP },
|
||
{ "bottom", V4L2_FIELD_BOTTOM },
|
||
{ "interlaced", V4L2_FIELD_INTERLACED },
|
||
{ "seq-tb", V4L2_FIELD_SEQ_TB },
|
||
{ "seq-bt", V4L2_FIELD_SEQ_BT },
|
||
{ "alternate", V4L2_FIELD_ALTERNATE },
|
||
{ "interlaced-tb", V4L2_FIELD_INTERLACED_TB },
|
||
{ "interlaced-bt", V4L2_FIELD_INTERLACED_BT },
|
||
};
|
||
|
||
GVideoISP1::GVideoISP1()
|
||
{
|
||
LOG_INIT();
|
||
dev_name = "/dev/video0";
|
||
}
|
||
|
||
GVideoISP1::~GVideoISP1()
|
||
{
|
||
|
||
}
|
||
|
||
void* GVideoISP1::read_frame(int timeout) {
|
||
if (!wait(timeout)){
|
||
LOG_ERROR("read frame time out!!!\n" );
|
||
return 0;
|
||
}
|
||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||
v4l2_buffer buf;
|
||
int ret;
|
||
memset(&buf, 0, sizeof buf);
|
||
memset(planes, 0, sizeof planes);
|
||
|
||
|
||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
//buf.memory = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
|
||
buf.memory = V4L2_MEMORY_USERPTR;
|
||
buf.length = VIDEO_MAX_PLANES;
|
||
buf.m.planes = planes;
|
||
|
||
ret = ioctl(fd, VIDIOC_DQBUF, &buf);
|
||
if (ret < 0) {
|
||
LOG_TRACE(string_format("Unable to dequeue buffer: %s (%d).",strerror(errno), errno));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_DQBUF sucess"));
|
||
}
|
||
|
||
|
||
ret = ioctl(fd, VIDIOC_QBUF, &buf);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("Unable to requeue buffer: %s (%d).\n",strerror(errno), errno));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_QBUF sucess"));
|
||
}
|
||
LOG_TRACE(string_format("buf.index = %d,buf.addr = %p\n",buf.index,buffers[buf.index].start));
|
||
printf("\n readframe size = %d ",buffers[buf.index].length);
|
||
return buffers[buf.index].start;
|
||
}
|
||
|
||
unsigned int gsp1querybuf_length;
|
||
void GVideoISP1::start_capturing(void) {
|
||
unsigned int i;
|
||
int ret;
|
||
enum v4l2_buf_type type;
|
||
|
||
for (i = 0; i < n_buffers; ++i) {
|
||
struct v4l2_buffer buf;
|
||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||
CLEAR(buf);
|
||
CLEAR(planes);
|
||
for(int j = 0; j < VIDEO_MAX_PLANES; j++)
|
||
{
|
||
//planes[j].length = buffers[i].length;
|
||
planes[j].length = gsp1querybuf_length;
|
||
planes[j].m.userptr =(unsigned long)buffers[i].start;
|
||
}
|
||
buf.index = i;
|
||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
buf.memory = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
|
||
buf.m.planes = planes;
|
||
buf.length = 1;
|
||
|
||
ret = ioctl(fd, VIDIOC_QBUF, &buf);
|
||
if (ret < 0)
|
||
LOG_ERROR(string_format("Unable to queue buffer: %s (%d).",strerror(errno), errno));
|
||
else
|
||
LOG_TRACE(string_format("buf.index = %d VIDIOC_QBUF sucess.",i));
|
||
}
|
||
|
||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
ret = ioctl(fd, VIDIOC_STREAMON, &type);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("Unable to %s streaming: %s (%d).","start", strerror(errno), errno));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_STREAMON sucess."));
|
||
}
|
||
}
|
||
|
||
void GVideoISP1::stop_capturing(void) {
|
||
enum v4l2_buf_type type;
|
||
|
||
type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
if (-1 == ioctl(fd, VIDIOC_STREAMOFF, &type))
|
||
LOG_ERROR(string_format("streamo off"));
|
||
|
||
LOG_TRACE(string_format("gVideo stop_capturing"));
|
||
}
|
||
|
||
static void get_ts_flags(uint32_t flags, const char **ts_type, const char **ts_source)
|
||
{
|
||
switch (flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) {
|
||
case V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN:
|
||
*ts_type = "unk";
|
||
break;
|
||
case V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC:
|
||
*ts_type = "mono";
|
||
break;
|
||
case V4L2_BUF_FLAG_TIMESTAMP_COPY:
|
||
*ts_type = "copy";
|
||
break;
|
||
default:
|
||
*ts_type = "inv";
|
||
}
|
||
switch (flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK) {
|
||
case V4L2_BUF_FLAG_TSTAMP_SRC_EOF:
|
||
*ts_source = "EoF";
|
||
break;
|
||
case V4L2_BUF_FLAG_TSTAMP_SRC_SOE:
|
||
*ts_source = "SoE";
|
||
break;
|
||
default:
|
||
*ts_source = "inv";
|
||
}
|
||
}
|
||
|
||
void GVideoISP1::init_mmap(void) {
|
||
// struct v4l2_requestbuffers req;
|
||
// int ret;
|
||
// unsigned int length;
|
||
// unsigned int offset;
|
||
// unsigned int page_size;
|
||
// int buffer_size = v4l_width * v4l_height * 3;
|
||
// page_size = getpagesize();
|
||
// buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
|
||
|
||
// CLEAR(req);
|
||
|
||
// //6.VIDIOC_REQBUFS
|
||
// req.count = v4l_buffer_count;
|
||
// req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
// req.memory = V4L2_MEMORY_USERPTR;//V4L2_MEMORY_MMAP;
|
||
|
||
// ret = ioctl(fd, VIDIOC_REQBUFS, &req);
|
||
// if (ret < 0) {
|
||
// LOG_ERROR(string_format("Unable to request buffers: %s (%d).", strerror(errno),errno));
|
||
// }
|
||
// else {
|
||
// LOG_TRACE(string_format("%s VIDIOC_REQBUFS sucess",dev_name.c_str()));
|
||
// }
|
||
// LOG_TRACE(string_format("%u buffers requested.", req.count));
|
||
|
||
// buffers.resize(req.count);
|
||
|
||
|
||
// for (n_buffers = 0; n_buffers < buffers.size(); ++n_buffers)
|
||
// {
|
||
// buffers[n_buffers].length = buffer_size;
|
||
// buffers[n_buffers].start = memalign(/* boundary */ page_size, buffer_size);
|
||
|
||
// if (!buffers[n_buffers].start)
|
||
// LOG_ERROR("Out of memory");
|
||
// }
|
||
|
||
struct v4l2_requestbuffers req;
|
||
int ret;
|
||
unsigned int length;
|
||
unsigned int offset;
|
||
unsigned int page_size;
|
||
int buffer_size = v4l_width * v4l_height * 3;
|
||
LOG_TRACE(string_format("init_mmap::buduiqi:changdu: buffer_size= %d\n", buffer_size));
|
||
page_size = getpagesize();
|
||
buffer_size = (buffer_size + page_size - 1) & ~(page_size - 1);
|
||
LOG_TRACE(string_format("init_mmap::shijichangdu:v4l_width = %d,v4l_height = %d\n", v4l_width,v4l_height));
|
||
LOG_TRACE(string_format("init_mmap::duiqi:page_size = %d,buffer_size = %d\n", page_size,buffer_size));
|
||
|
||
CLEAR(req);
|
||
|
||
//6.VIDIOC_REQBUFS
|
||
req.count = v4l_buffer_count;
|
||
//req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
//req.memory = V4L2_MEMORY_MMAP;
|
||
req.memory = V4L2_MEMORY_USERPTR;
|
||
LOG_TRACE(string_format("set v4l_buffer_count = %d\n", req.count));
|
||
LOG_TRACE(string_format("set v4l_buffer_type = %d\n", req.type));
|
||
LOG_TRACE(string_format("set v4l_buffer_memory = %d\n", req.memory));
|
||
|
||
ret = ioctl(fd, VIDIOC_REQBUFS, &req);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("Unable to request buffers: %s (%d).\n", strerror(errno),errno));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("%s VIDIOC_REQBUFS sucess\n",dev_name.c_str()));
|
||
}
|
||
LOG_TRACE(string_format("%u buffers requested.\n", req.count));
|
||
|
||
buffers.resize(req.count);
|
||
if (buffers.empty()) {
|
||
LOG_ERROR("Out of memory\n");
|
||
}
|
||
|
||
//7.VIDIOC_QUERYBUF
|
||
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
|
||
const char *ts_type, *ts_source;
|
||
struct v4l2_buffer buf;
|
||
struct v4l2_plane planes[VIDEO_MAX_PLANES];
|
||
CLEAR(buf);
|
||
CLEAR(planes);
|
||
buf.index = n_buffers;
|
||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
//buf.memory = V4L2_MEMORY_MMAP;
|
||
buf.memory = V4L2_MEMORY_USERPTR;
|
||
buf.length = VIDEO_MAX_PLANES;
|
||
buf.m.planes = planes;
|
||
|
||
ret = ioctl(fd, VIDIOC_QUERYBUF, &buf);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("Unable to query buffer %u: %s (%d).\n", n_buffers,strerror(errno), errno));
|
||
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("index %d VIDIOC_QUERYBUF sucess.\n",n_buffers));
|
||
|
||
}
|
||
get_ts_flags(buf.flags, &ts_type, &ts_source);
|
||
LOG_TRACE(string_format("length: %u offset: %u timestamp type/source: %s/%s\n",
|
||
buf.length, buf.m.offset, ts_type, ts_source));
|
||
|
||
//mmap
|
||
unsigned int length;
|
||
unsigned int offset;
|
||
length = buf.m.planes[0].length;
|
||
offset = buf.m.planes[0].m.mem_offset;
|
||
gsp1querybuf_length = buf.m.planes[0].length;
|
||
LOG_TRACE(string_format("VIDIOC_QUERYBUF:Buffer %u length = %d.\n",n_buffers,length));
|
||
LOG_TRACE(string_format("VIDIOC_QUERYBUF:Buffer %u offset = %d.\n",n_buffers,offset));
|
||
LOG_TRACE(string_format("VIDIOC_QUERYBUF:Buffer %u querybuf_length = %d.\n",n_buffers,gsp1querybuf_length));
|
||
}
|
||
|
||
for (n_buffers = 0; n_buffers < buffers.size(); ++n_buffers)
|
||
{
|
||
buffers[n_buffers].length = gsp1querybuf_length;
|
||
buffers[n_buffers].start = memalign(/* boundary */ 1024, gsp1querybuf_length);
|
||
LOG_TRACE(string_format("memalign:buffers[%d].length = %d\n", n_buffers,buffers[n_buffers].length));
|
||
LOG_TRACE(string_format("memalign:buffers[%d].start = %p\n", n_buffers,buffers[n_buffers].start));
|
||
|
||
if (!buffers[n_buffers].start)
|
||
{
|
||
LOG_TRACE("Out of memory,exit application\n");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
}
|
||
}
|
||
|
||
static const char *v4l2_buf_type_name(__u32 type)
|
||
{
|
||
unsigned int i;
|
||
|
||
for (i = 0; i < ARRAY_SIZE(buf_types); ++i) {
|
||
if (buf_types[i].type == type)
|
||
return buf_types[i].name;
|
||
}
|
||
|
||
if (type & V4L2_BUF_TYPE_PRIVATE)
|
||
return "Private";
|
||
else
|
||
return "Unknown";
|
||
}
|
||
|
||
static const struct v4l2_format_info *v4l2_format_by_fourcc(unsigned int fourcc)
|
||
{
|
||
unsigned int i;
|
||
|
||
for (i = 0; i < ARRAY_SIZE(pixel_formats); ++i) {
|
||
if (pixel_formats[i].fourcc == fourcc)
|
||
return &pixel_formats[i];
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
|
||
static const char *v4l2_format_name(unsigned int fourcc)
|
||
{
|
||
const struct v4l2_format_info *info;
|
||
static char name[5];
|
||
unsigned int i;
|
||
|
||
info = v4l2_format_by_fourcc(fourcc);
|
||
if (info)
|
||
return info->name;
|
||
|
||
for (i = 0; i < 4; ++i) {
|
||
name[i] = fourcc & 0xff;
|
||
fourcc >>= 8;
|
||
}
|
||
|
||
name[4] = '\0';
|
||
return name;
|
||
}
|
||
|
||
static void video_enum_frame_intervals(int fd, __u32 pixelformat,
|
||
unsigned int width, unsigned int height)
|
||
{
|
||
struct v4l2_frmivalenum ival;
|
||
unsigned int i;
|
||
int ret;
|
||
|
||
for (i = 0; ; ++i) {
|
||
memset(&ival, 0, sizeof ival);
|
||
ival.index = i;
|
||
ival.pixel_format = pixelformat;
|
||
ival.width = width;
|
||
ival.height = height;
|
||
ret = ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival);
|
||
if (ret < 0)
|
||
break;
|
||
|
||
if (i != ival.index)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong ival index " "%u.\n", ival.index));
|
||
if (pixelformat != ival.pixel_format)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong ival pixel " "format %08x.\n", ival.pixel_format));
|
||
if (width != ival.width)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong ival width " "%u.\n", ival.width));
|
||
if (height != ival.height)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong ival height " "%u.\n", ival.height));
|
||
|
||
if (i != 0)
|
||
LOG_TRACE(", ");
|
||
|
||
switch (ival.type) {
|
||
case V4L2_FRMIVAL_TYPE_DISCRETE:
|
||
LOG_TRACE(string_format("%u/%u", ival.discrete.numerator, ival.discrete.denominator));
|
||
break;
|
||
|
||
case V4L2_FRMIVAL_TYPE_CONTINUOUS:
|
||
LOG_TRACE(string_format("%u/%u - %u/%u", ival.stepwise.min.numerator, ival.stepwise.min.denominator, ival.stepwise.max.numerator, ival.stepwise.max.denominator));
|
||
return;
|
||
|
||
case V4L2_FRMIVAL_TYPE_STEPWISE:
|
||
LOG_TRACE(string_format("%u/%u - %u/%u (by %u/%u)", ival.stepwise.min.numerator, ival.stepwise.min.denominator, ival.stepwise.max.numerator, ival.stepwise.max.denominator, ival.stepwise.step.numerator, ival.stepwise.step.denominator));
|
||
return;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void video_enum_frame_sizes(int fd, __u32 pixelformat)
|
||
{
|
||
struct v4l2_frmsizeenum frame;
|
||
unsigned int i;
|
||
int ret;
|
||
|
||
for (i = 0; ; ++i) {
|
||
memset(&frame, 0, sizeof frame);
|
||
frame.index = i;
|
||
frame.pixel_format = pixelformat;
|
||
ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frame);
|
||
if (ret < 0)
|
||
break;
|
||
|
||
if (i != frame.index)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong frame index " "%u.\n", frame.index));
|
||
if (pixelformat != frame.pixel_format)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong frame pixel " "format %08x.\n", frame.pixel_format));
|
||
|
||
switch (frame.type) {
|
||
case V4L2_FRMSIZE_TYPE_DISCRETE:
|
||
LOG_TRACE(string_format("\tFrame size: %ux%u (", frame.discrete.width, frame.discrete.height));
|
||
video_enum_frame_intervals(fd, frame.pixel_format, frame.discrete.width, frame.discrete.height);
|
||
break;
|
||
|
||
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
|
||
LOG_TRACE(string_format("\tFrame size: %ux%u - %ux%u (", frame.stepwise.min_width, frame.stepwise.min_height, frame.stepwise.max_width, frame.stepwise.max_height));
|
||
video_enum_frame_intervals(fd, frame.pixel_format, frame.stepwise.max_width, frame.stepwise.max_height);
|
||
break;
|
||
|
||
case V4L2_FRMSIZE_TYPE_STEPWISE:
|
||
LOG_TRACE(string_format("\tFrame size: %ux%u - %ux%u (by %ux%u) (\n", frame.stepwise.min_width, frame.stepwise.min_height, frame.stepwise.max_width, frame.stepwise.max_height, frame.stepwise.step_width, frame.stepwise.step_height));
|
||
video_enum_frame_intervals(fd, frame.pixel_format, frame.stepwise.max_width, frame.stepwise.max_height);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
static void video_enum_formats(int fd, enum v4l2_buf_type type)
|
||
{
|
||
struct v4l2_fmtdesc fmt;
|
||
unsigned int i;
|
||
int ret;
|
||
|
||
for (i = 0; ; ++i) {
|
||
memset(&fmt, 0, sizeof fmt);
|
||
fmt.index = i;
|
||
fmt.type = type;
|
||
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt);
|
||
if (ret < 0)
|
||
break;
|
||
|
||
if (i != fmt.index)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong format index " "%u.\n", fmt.index));
|
||
if (type != fmt.type)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong format type " "%u.\n", fmt.type));
|
||
|
||
LOG_TRACE(string_format("\tFormat %u: %s (%08x)\n", i, v4l2_format_name(fmt.pixelformat), fmt.pixelformat));
|
||
LOG_TRACE(string_format("\tType: %s (%u)\n", v4l2_buf_type_name(fmt.type), fmt.type));
|
||
LOG_TRACE(string_format("\tName: %.32s\n", fmt.description));
|
||
video_enum_frame_sizes(fd, fmt.pixelformat);
|
||
}
|
||
}
|
||
|
||
static void video_enum_inputs(int fd)
|
||
{
|
||
struct v4l2_input input;
|
||
unsigned int i;
|
||
int ret;
|
||
|
||
for (i = 0; ; ++i) {
|
||
memset(&input, 0, sizeof input);
|
||
input.index = i;
|
||
ret = ioctl(fd, VIDIOC_ENUMINPUT, &input);
|
||
if (ret < 0)
|
||
break;
|
||
|
||
if (i != input.index)
|
||
LOG_TRACE(string_format("Warning: driver returned wrong input index " "%u.\n", input.index));
|
||
|
||
LOG_TRACE(string_format("\tInput %u: %s.\n", i, input.name));
|
||
}
|
||
|
||
}
|
||
|
||
static const char *v4l2_field_name(__u32 field)
|
||
{
|
||
unsigned int i;
|
||
|
||
for (i = 0; i < ARRAY_SIZE(fields); ++i) {
|
||
if (fields[i].field == field)
|
||
return fields[i].name;
|
||
}
|
||
|
||
return "unknown";
|
||
}
|
||
|
||
|
||
static void rkisp_sd_set_crop(const char *ispsd, int fd, int pad, int *w, int *h)
|
||
{
|
||
struct v4l2_subdev_selection sel;
|
||
int ret;
|
||
|
||
memset(&sel, 0, sizeof(sel));
|
||
sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||
sel.pad = pad;
|
||
sel.r.width = *w;
|
||
sel.r.height = *h;
|
||
sel.r.left = 0;
|
||
sel.r.top = 0;
|
||
sel.target = V4L2_SEL_TGT_CROP;
|
||
sel.flags = V4L2_SEL_FLAG_LE;
|
||
ret = ioctl(fd, VIDIOC_SUBDEV_S_SELECTION, &sel);
|
||
if (ret) {
|
||
LOG_ERROR(string_format("subdev %s pad %d crop failed, ret = %d\n", ispsd, sel.pad, ret));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_SELECTION sucess.\n"));
|
||
}
|
||
|
||
*w = sel.r.width;
|
||
*h = sel.r.height;
|
||
}
|
||
|
||
static void rkisp_video_set_crop(int fd, int x, int y, int w, int h)
|
||
{
|
||
struct v4l2_selection sel;
|
||
int ret;
|
||
memset(&sel, 0, sizeof(sel));
|
||
sel.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
sel.r.width = w;
|
||
sel.r.height = h;
|
||
sel.r.left = x;
|
||
sel.r.top = y;
|
||
sel.target = V4L2_SEL_TGT_CROP;
|
||
sel.flags = 0;
|
||
ret = ioctl(fd, VIDIOC_S_SELECTION, &sel);
|
||
if (ret) {
|
||
LOG_ERROR(string_format("VIDIOC_S_SELECTION::set output crop(0,0/%dx%d) failed, %s\n", w, h, strerror(errno)));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("sVIDIOC_S_SELECTION scuess\n"));
|
||
}
|
||
|
||
}
|
||
void GVideoISP1::init_device(void) {
|
||
struct v4l2_capability cap;
|
||
struct v4l2_format fmt;
|
||
|
||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
struct v4l2_fmtdesc fmt_1;
|
||
struct v4l2_frmsizeenum frmsize;
|
||
struct v4l2_frmivalenum frmival;
|
||
struct v4l2_subdev_format subdev_fmt;
|
||
int subdev_fd;
|
||
|
||
unsigned int caps;
|
||
bool has_video;
|
||
bool has_meta;
|
||
bool has_capture;
|
||
bool has_output;
|
||
bool has_mplane;
|
||
|
||
int ret;
|
||
int i;
|
||
//---------------------------set /dev/v4l2-subdev*-------------------------------------//
|
||
//----------------------1.v4l2_subdev2 set format----------------------//
|
||
subdev_fd = ::open(subdev2_name.c_str(),O_RDWR,0);
|
||
if (-1 == subdev_fd) {
|
||
LOG_ERROR(string_format("Cannot open '%s'\n", subdev2_name.c_str()));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("open %s success.fd = %d.\n",subdev2_name.c_str(),subdev_fd));
|
||
}
|
||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||
subdev_fmt.pad = 0;
|
||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("VIDIOC_SUBDEV_G_FMT failed.\n"));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:height = %d;width = %d;code = %d.\n", subdev_fmt.format.height,subdev_fmt.format.width,subdev_fmt.format.code));
|
||
|
||
subdev_fmt.format.width = v4l_width;
|
||
subdev_fmt.format.height = v4l_height;
|
||
LOG_TRACE(string_format("set height = %d\n",subdev_fmt.format.height));
|
||
LOG_TRACE(string_format("set width = %d\n",subdev_fmt.format.width));
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("VIDIOC_SUBDEV_S_FMT failed.\n"));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT:height = %d;width = %d;code = %d.\n", subdev_fmt.format.height,subdev_fmt.format.width,subdev_fmt.format.code));
|
||
::close(subdev_fd);
|
||
//-------------------------------------------------------------//
|
||
|
||
//----------------------2.v4l2_subdev0 set format::pad0----------------------//
|
||
subdev_fd = ::open(subdev0_name.c_str(),O_RDWR,0);
|
||
if (-1 == subdev_fd) {
|
||
LOG_ERROR(string_format("Cannot open '%s'\n", subdev0_name.c_str()));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("open %s success.fd = %d.\n",subdev0_name.c_str(),subdev_fd));
|
||
}
|
||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||
subdev_fmt.pad = 0;
|
||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("VIDIOC_SUBDEV_G_FMT failed.\n"));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:pad = %d;height = %d;width = %d;code = %d.\n", subdev_fmt.pad,subdev_fmt.format.height,subdev_fmt.format.width,subdev_fmt.format.code));
|
||
subdev_fmt.format.width = v4l_width;
|
||
subdev_fmt.format.height = v4l_height;
|
||
LOG_TRACE(string_format("set height = %d;width = %d\n",subdev_fmt.format.height,subdev_fmt.format.width));
|
||
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||
if (ret < 0) {
|
||
LOG_ERROR(string_format("VIDIOC_SUBDEV_S_FMT failed.\n"));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT:pad = %d;height = %d;width = %d;code = %d.\n", subdev_fmt.pad,subdev_fmt.format.height,subdev_fmt.format.width,subdev_fmt.format.code));
|
||
rkisp_sd_set_crop(subdev0_name.c_str(),subdev_fd, 0 , &v4l_width, &v4l_height);
|
||
LOG_TRACE(string_format("v4l_set height = %d;width = %d\n",v4l_width,v4l_height));
|
||
//----------------------3.v4l2_subdev0 set format::pad2----------------------//
|
||
rkisp_sd_set_crop(subdev0_name.c_str(),subdev_fd, 2 , &v4l_width, &v4l_height);
|
||
LOG_TRACE(string_format("v4l_set height = %d;width = %d\n",v4l_width,v4l_height));
|
||
memset(&subdev_fmt, 0, sizeof subdev_fmt);
|
||
subdev_fmt.pad = 2;
|
||
subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_G_FMT, &subdev_fmt);
|
||
if (ret < 0)
|
||
{
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT failed.\n"));
|
||
}
|
||
else
|
||
{
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:pad = %d\n",subdev_fmt.pad));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.height = %d\n",subdev_fmt.format.height));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.width = %d\n",subdev_fmt.format.width));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:subdev_fmt.format.code = %d\n",subdev_fmt.format.code));
|
||
subdev_fmt.format.width = v4l_width;
|
||
subdev_fmt.format.height = v4l_height;
|
||
LOG_TRACE(string_format("set height = %d\n",subdev_fmt.format.height));
|
||
LOG_TRACE(string_format("set width = %d\n",subdev_fmt.format.width));
|
||
|
||
ret = ioctl(subdev_fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt);
|
||
if (ret < 0)
|
||
{
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT failed.\n"));
|
||
}
|
||
else
|
||
{
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT SUCESS\n"));
|
||
}
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_G_FMT:pad = %d\n",subdev_fmt.pad));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.height = %d\n",subdev_fmt.format.height));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.width = %d\n",subdev_fmt.format.width));
|
||
LOG_TRACE(string_format("VIDIOC_SUBDEV_S_FMT:subdev_fmt.format.code = %d\n",subdev_fmt.format.code));
|
||
//-------------------------------------------------------------//
|
||
|
||
//-------4.set video selection(crop) because ispsd size changed------------------//
|
||
rkisp_video_set_crop(fd, 0, 0, v4l_width, v4l_height);
|
||
//----------------------1.VIDIOC_QUERYCAP----------------------//
|
||
memset(&cap, 0, sizeof cap);
|
||
if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &cap))
|
||
|
||
ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
|
||
if (ret < 0)
|
||
{
|
||
LOG_TRACE(string_format("VIDIOC_QUERYCAP failed.\n"));
|
||
}
|
||
else
|
||
{
|
||
LOG_TRACE(string_format("cap.capabilities = %x .\n",cap.capabilities));
|
||
LOG_TRACE(string_format("cap.device_caps = %x .\n",cap.device_caps));
|
||
}
|
||
caps = cap.capabilities & V4L2_CAP_DEVICE_CAPS
|
||
? cap.device_caps : cap.capabilities;
|
||
|
||
has_video = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||
V4L2_CAP_VIDEO_CAPTURE |
|
||
V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
||
V4L2_CAP_VIDEO_OUTPUT);
|
||
// has_meta = caps & (V4L2_CAP_META_CAPTURE |
|
||
// V4L2_CAP_META_OUTPUT);
|
||
// has_capture = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||
// V4L2_CAP_VIDEO_CAPTURE |
|
||
// V4L2_CAP_META_CAPTURE);
|
||
has_output = caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
||
V4L2_CAP_VIDEO_OUTPUT |
|
||
V4L2_CAP_META_OUTPUT);
|
||
has_mplane = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
||
V4L2_CAP_VIDEO_OUTPUT_MPLANE);
|
||
|
||
LOG_TRACE(string_format("Device `%s' on `%s' (driver '%s') supports%s%s%s%s %s mplanes.\n", cap.card, cap.bus_info, cap.driver, has_video ? " video," : "", has_meta ? " meta-data," : "", has_capture ? " capture," : "", has_output ? " output," : "", has_mplane ? "with" : "without"));
|
||
|
||
|
||
if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
|
||
LOG_ERROR(string_format("%s does not support streaming i/o\n", dev_name.c_str()));
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("%s support streaming i/o\n", dev_name.c_str()));
|
||
}
|
||
//-------------------------------------------------------------//
|
||
|
||
//----------------------2.VIDIOC_ENUM_FMT----------------------//
|
||
LOG_TRACE(string_format("- Available formats:\n"));
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE = %d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE));
|
||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = %d\n", V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE));
|
||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT = %d\n", V4L2_BUF_TYPE_VIDEO_OUTPUT));
|
||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = %d\n", V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE));
|
||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY = %d\n", V4L2_BUF_TYPE_VIDEO_OVERLAY));
|
||
video_enum_formats(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
//LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_META_CAPTURE = %d\n", V4L2_BUF_TYPE_META_CAPTURE));
|
||
//video_enum_formats(fd, V4L2_BUF_TYPE_META_CAPTURE);
|
||
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
LOG_TRACE(string_format("fmt.type = V4L2_BUF_TYPE_META_OUTPUT = %d\n", V4L2_BUF_TYPE_META_OUTPUT));
|
||
//video_enum_formats(fd, V4L2_BUF_TYPE_META_OUTPUT);
|
||
LOG_TRACE(string_format("------------------------------------------------------\n"));
|
||
//--------------------------------------------------------------//
|
||
|
||
//----------------------3.VIDIOC_ENUMINPUT----------------------//
|
||
LOG_TRACE(string_format("- Available inputs:\n"));
|
||
video_enum_inputs(fd);
|
||
//-------------------------------------------------------------//
|
||
|
||
//----------------------4.VIDIOC_S_FMT-------------------------//
|
||
LOG_TRACE(string_format("..........................................................................\n"));
|
||
CLEAR(fmt);
|
||
//fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
fmt.fmt.pix.width = v4l_width;
|
||
fmt.fmt.pix.height = v4l_height;
|
||
//fmt.fmt.pix.width = 2112;
|
||
//fmt.fmt.pix.height = 1568;
|
||
LOG_TRACE(string_format("v4l2 VIDIOC_S_FMT width:%d, height:%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height));
|
||
//fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
|
||
//fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||
//fmt.fmt.pix_mp.width = 1728;
|
||
//fmt.fmt.pix_mp.height = 1568;
|
||
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_RGB24;
|
||
fmt.fmt.pix_mp.field = 0;
|
||
fmt.fmt.pix_mp.num_planes = 1;
|
||
fmt.fmt.pix_mp.flags = 0;
|
||
fmt.fmt.pix_mp.plane_fmt[0].bytesperline = 0;
|
||
fmt.fmt.pix_mp.plane_fmt[0].sizeimage = 0;
|
||
|
||
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
|
||
if (ret < 0) {
|
||
LOG_TRACE(string_format("Unable to set format: %s (%d).\n", strerror(errno),errno));
|
||
|
||
}
|
||
else {
|
||
LOG_TRACE(string_format("VIDIOC_S_FMT sucess.\n"));
|
||
}
|
||
|
||
LOG_TRACE(string_format("Video format set: %s (%08x) %ux%u field %s, %u planes: \n", v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, v4l2_field_name(fmt.fmt.pix_mp.field), fmt.fmt.pix_mp.num_planes));
|
||
|
||
for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++) {
|
||
LOG_TRACE(string_format(" * bytesperline %u, buffer size %u\n", fmt.fmt.pix_mp.plane_fmt[i].bytesperline, fmt.fmt.pix_mp.plane_fmt[i].sizeimage));
|
||
}
|
||
//-------------------------------------------------------------//
|
||
|
||
//----------------------5.VIDIOC_G_FMT-------------------------//
|
||
memset(&fmt, 0, sizeof fmt);
|
||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
||
ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
|
||
if (ret < 0) {
|
||
LOG_TRACE(string_format("Unable to get format: %s (%d).\n", strerror(errno),errno));
|
||
}
|
||
else {
|
||
LOG_TRACE("VIDIOC_G_FMT sucess.");
|
||
}
|
||
LOG_TRACE(string_format("Video format: %s (%08x) %ux%u field %s, %u planes: \n", v4l2_format_name(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, v4l2_field_name(fmt.fmt.pix_mp.field), fmt.fmt.pix_mp.num_planes));
|
||
for (i = 0; i < fmt.fmt.pix_mp.num_planes; i++)
|
||
LOG_TRACE(string_format(" * bytesperline %u, buffer size %u\n", fmt.fmt.pix_mp.plane_fmt[i].bytesperline, fmt.fmt.pix_mp.plane_fmt[i].sizeimage));
|
||
|
||
::close(subdev_fd);
|
||
//-------------------------------------------------------------//
|
||
|
||
//6.VIDIOC_REQBUFS //7.VIDIOC_QUERYBUF mmmap
|
||
init_mmap();
|
||
//-------------------------------------------------------------//
|
||
} |