[csharp] view plaincopyide
結構 ui
struct v4l2_fmtdes fmtdes; url
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdes); spa
struct v4l2_fmtdesc { .net
__u32 index; /* Format number */ orm
enum v4l2_buf_type type; /* buffer type */ 視頻
__u32 flags; blog
__u8 description[32]; /* Description string */ ip
__u32 pixelformat; /* Format fourcc */ get
__u32 reserved[4];
};
驅動
static int s3c_fimc_v4l2_enum_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_fmtdesc *f)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
int index = f->index;
if (index >= S3C_FIMC_MAX_CAPTURE_FORMATS)
return -EINVAL;
memset(f, 0, sizeof(*f));
memcpy(f, ctrl->v4l2.fmtdesc + index, sizeof(*f));
return 0;
}
#define S3C_FIMC_MAX_CAPTURE_FORMATS ARRAY_SIZE(s3c_fimc_capture_formats)
const static struct v4l2_fmtdesc s3c_fimc_capture_formats[] = {
{
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PLANAR,
.description = "4:2:0, planar, Y-Cb-Cr",
.pixelformat = V4L2_PIX_FMT_YUV420,
},
{
.index = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PLANAR,
.description = "4:2:2, planar, Y-Cb-Cr",
.pixelformat = V4L2_PIX_FMT_YUV422P,
},
{
.index = 2,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PACKED,
.description = "4:2:2, packed, YCBYCR",
.pixelformat = V4L2_PIX_FMT_YUYV,
},
{
.index = 3,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PACKED,
.description = "4:2:2, packed, CBYCRY",
.pixelformat = V4L2_PIX_FMT_UYVY,
}
};
const static struct v4l2_fmtdesc s3c_fimc_overlay_formats[] = {
{
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
.flags = FORMAT_FLAGS_PACKED,
.description = "16 bpp RGB, le",
.pixelformat = V4L2_PIX_FMT_RGB565,
},
{
.index = 1,
.type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
.flags = FORMAT_FLAGS_PACKED,
.description = "24 bpp RGB, le",
.pixelformat = V4L2_PIX_FMT_RGB24,
},
};
應用層
static int video_fmtdesc(int fd)
{
/***********Format Enumeration************/
int ret = 0;
struct v4l2_fmtdesc fmtdes;
CLEAR(fmtdes);
fmtdes.index = 0;
fmtdes.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("\n**********vidioc enumeration stream format informations:****\n");
while (1) {
ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdes);
if (ret < 0)
break;
printf("{ pixelformat = %c%c%c%c, description = %s }\n",
(fmtdes.pixelformat & 0xFF),
(fmtdes.pixelformat >> 8) & 0xFF,
(fmtdes.pixelformat >> 16) & 0xFF,
(fmtdes.pixelformat >> 24) & 0xFF,
fmtdes.description);
if (fmtdes.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
printf("video capture type:\n");
if (fmtdes.pixelformat == V4L2_PIX_FMT_YUYV)
printf("V4L2_PIX_FMT_YUYV\n");
fmtdes.index++;
}
return 0;
}
[csharp] view plaincopy
結構體
幀格式包括寬度和高度
struct v4l2_format fmt;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
struct v4l2_format {
enum v4l2_buf_type type;//數據流類型,必須是V4L2_BUF_TYPE_VIDEO_CAPTURE
union {
struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
__u8 raw_data[200]; /* user-defined */
} fmt;
};
struct v4l2_pix_format {
__u32 pixelformat;//視頻數據存儲類型,例如是YUV4:2:2仍是RGB
}
驅動
static int s3c_fimc_v4l2_s_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_format *f)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
ctrl->v4l2.frmbuf.fmt = f->fmt.pix;
if (f->fmt.pix.priv == V4L2_FMT_IN)
s3c_fimc_set_input_frame(ctrl, &f->fmt.pix);
else
s3c_fimc_set_output_frame(ctrl, &f->fmt.pix);
return 0;
}
int s3c_fimc_set_input_frame(struct s3c_fimc_control *ctrl,
struct v4l2_pix_format *fmt)
{
s3c_fimc_set_input_format(ctrl, fmt);
return 0;
}
static void s3c_fimc_set_input_format(struct s3c_fimc_control *ctrl,
struct v4l2_pix_format *fmt)
{
struct s3c_fimc_in_frame *frame = &ctrl->in_frame;
frame->width = fmt->width;
frame->height = fmt->height;
switch (fmt->pixelformat) {
case V4L2_PIX_FMT_RGB565:
frame->format = FORMAT_RGB565;
frame->planes = 1;
break;
case V4L2_PIX_FMT_RGB24:
frame->format = FORMAT_RGB888;
frame->planes = 1;
break;
case V4L2_PIX_FMT_NV12:
frame->format = FORMAT_YCBCR420;
frame->planes = 2;
frame->order_2p = LSB_CBCR;
break;
case V4L2_PIX_FMT_NV21:
frame->format = FORMAT_YCBCR420;
frame->planes = 2;
frame->order_2p = LSB_CRCB;
break;
case V4L2_PIX_FMT_NV12X:
frame->format = FORMAT_YCBCR420;
frame->planes = 2;
frame->order_2p = MSB_CBCR;
break;
case V4L2_PIX_FMT_NV21X:
frame->format = FORMAT_YCBCR420;
frame->planes = 2;
frame->order_2p = MSB_CRCB;
break;
case V4L2_PIX_FMT_YUV420:
frame->format = FORMAT_YCBCR420;
frame->planes = 3;
break;
case V4L2_PIX_FMT_YUYV:
frame->format = FORMAT_YCBCR422;
frame->planes = 1;
frame->order_1p = IN_ORDER422_YCBYCR;
break;
case V4L2_PIX_FMT_YVYU:
frame->format = FORMAT_YCBCR422;
frame->planes = 1;
frame->order_1p = IN_ORDER422_YCRYCB;
break;
case V4L2_PIX_FMT_UYVY:
frame->format = FORMAT_YCBCR422;
frame->planes = 1;
frame->order_1p = IN_ORDER422_CBYCRY;
break;
case V4L2_PIX_FMT_VYUY:
frame->format = FORMAT_YCBCR422;
frame->planes = 1;
frame->order_1p = IN_ORDER422_CRYCBY;
break;
case V4L2_PIX_FMT_NV16:
frame->format = FORMAT_YCBCR422;
frame->planes = 2;
frame->order_1p = LSB_CBCR;
break;
case V4L2_PIX_FMT_NV61:
frame->format = FORMAT_YCBCR422;
frame->planes = 2;
frame->order_1p = LSB_CRCB;
break;
case V4L2_PIX_FMT_NV16X:
frame->format = FORMAT_YCBCR422;
frame->planes = 2;
frame->order_1p = MSB_CBCR;
break;
case V4L2_PIX_FMT_NV61X:
frame->format = FORMAT_YCBCR422;
frame->planes = 2;
frame->order_1p = MSB_CRCB;
break;
case V4L2_PIX_FMT_YUV422P:
frame->format = FORMAT_YCBCR422;
frame->planes = 3;
break;
}
}
應用層
static int video_setfmt(int fd)
{
/***********set Stream data format********/
int ret = 0;
struct v4l2_format fmt;
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//for PAL
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
if (ret < 0) {
perror("VIDIOC_S_FMT");
return ret;
}
return 0;