From 8cc65fca3d29e5085323196a50509b95993e8e66 Mon Sep 17 00:00:00 2001 From: Tianshu Qiu Date: Fri, 13 Oct 2017 14:06:25 +0800 Subject: [PATCH 1/3] kernel-ut: nvt: Add ipu3 related formats Change-Id: I6b5f0dd0772dc4a9cd9bd0929b264f4f1be6bb34 Signed-off-by: Tianshu Qiu --- linux/videodev2.h | 11 +++++++++++ v4l2n.c | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/linux/videodev2.h b/linux/videodev2.h index 94f123f..d55ed61 100644 --- a/linux/videodev2.h +++ b/linux/videodev2.h @@ -635,6 +635,17 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ +#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ +#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') /* IPU3 packed 10-bit GBRG bayer */ +#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') /* IPU3 packed 10-bit GRBG bayer */ +#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') /* IPU3 packed 10-bit RGGB bayer */ + +/* Vendor specific - used for IPU3 camera sub-system */ +#define V4L2_META_FMT_IPU3_PARAMS v4l2_fourcc('i', 'p', '3', 'p') /* IPU3 params */ +#define V4L2_META_FMT_IPU3_STAT_3A v4l2_fourcc('i', 'p', '3', 's') /* IPU3 3A statistics */ +#define V4L2_META_FMT_IPU3_STAT_DVS v4l2_fourcc('i', 'p', '3', 'd') /* IPU3 DVS statistics */ +#define V4L2_META_FMT_IPU3_STAT_LACE v4l2_fourcc('i', 'p', '3', 'l') /* IPU3 LACE statistics */ + /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */ diff --git a/v4l2n.c b/v4l2n.c index 0f12596..7b2b35f 100644 --- a/v4l2n.c +++ b/v4l2n.c @@ -506,6 +506,7 @@ static const struct symbol_list v4l2_buf_types[] = { #define V4L2_PIX_FMT "V4L2_PIX_FMT_" #define PIXFMT(id) { V4L2_PIX_FMT_##id, (#id) } +#define METAFMT(id) { V4L2_META_FMT_##id, (#id) } static const struct symbol_list pixelformats[] = { PIXFMT(RGB332), PIXFMT(RGB444), @@ -670,6 +671,14 @@ static const struct symbol_list pixelformats[] = { PIXFMT(YYUV420_V32), PIXFMT(PRIV_MAGIC), PIXFMT(FLAG_PREMUL_ALPHA), + PIXFMT(IPU3_SBGGR10), + PIXFMT(IPU3_SGBRG10), + PIXFMT(IPU3_SGRBG10), + PIXFMT(IPU3_SRGGB10), + METAFMT(IPU3_PARAMS), + METAFMT(IPU3_STAT_3A), + METAFMT(IPU3_STAT_DVS), + METAFMT(IPU3_STAT_LACE), SYMBOL_END }; From b3c14642e676c7200dedfb6643d920db3e7a847d Mon Sep 17 00:00:00 2001 From: Tianshu Qiu Date: Fri, 13 Oct 2017 14:14:50 +0800 Subject: [PATCH 2/3] kernel-ut: nvt: Add support for mplane buffer Change-Id: I61a0958f0b19c6ad7e5eb63fb48774ac0590f6cb Signed-off-by: Tianshu Qiu --- v4l2n.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 234 insertions(+), 51 deletions(-) diff --git a/v4l2n.c b/v4l2n.c index 7b2b35f..de3c494 100644 --- a/v4l2n.c +++ b/v4l2n.c @@ -68,6 +68,12 @@ static unsigned long int _PAGE_MASK; #define MAX_BUFFER_SIZE (64*1024*1024) #define MAX_PIPES 6 +#define V4L2_TYPE_IS_VIDEO(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ + || (type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + typedef unsigned char bool; static char *name = "v4l2n"; @@ -78,6 +84,7 @@ static const int FILLER = 0xFE; * for subsequent QBUF/DQBUF. Buffers are reused for long sequences. */ struct ring_buffer { struct v4l2_buffer querybuf; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; bool queued; void *malloc_p; /* Points to address returned by malloc() */ void *mmap_p; /* Points to address returned by mmap() */ @@ -86,7 +93,7 @@ struct ring_buffer { /* Used for saving each captured frame if saving was requested */ struct capture_buffer { - struct v4l2_pix_format pix_format; + struct v4l2_format format; void *image; int length; /* Length of data in the buffer in bytes */ }; @@ -491,9 +498,9 @@ static const struct symbol_list controls[] = { #define BUFTYPE(id) { V4L2_BUF_TYPE_##id, (#id) } static const struct symbol_list v4l2_buf_types[] = { BUFTYPE(VIDEO_CAPTURE), - // BUFTYPE(VIDEO_CAPTURE_MPLANE), + BUFTYPE(VIDEO_CAPTURE_MPLANE), BUFTYPE(VIDEO_OUTPUT), - // BUFTYPE(VIDEO_OUTPUT_MPLANE), + BUFTYPE(VIDEO_OUTPUT_MPLANE), BUFTYPE(VIDEO_OVERLAY), BUFTYPE(VBI_CAPTURE), BUFTYPE(VBI_OUTPUT), @@ -1173,6 +1180,170 @@ static char *get_v4l2_fract(struct v4l2_fract *f) return buf; } +static __u32 get_buffer_bytesused(struct v4l2_buffer *buffer) +{ + return V4L2_TYPE_IS_MULTIPLANAR(buffer->type) ? buffer->m.planes[0].bytesused : buffer->bytesused; +} + +static void set_buffer_bytesused(struct v4l2_buffer *buffer, __u32 bytesused) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(buffer->type)) + buffer->m.planes[0].bytesused = bytesused; + else + buffer->bytesused = bytesused; +} + +static __u32 get_buffer_length(struct v4l2_buffer *buffer) +{ + return V4L2_TYPE_IS_MULTIPLANAR(buffer->type) ? buffer->m.planes[0].length : buffer->length; +} + +static void set_buffer_length(struct v4l2_buffer *buffer, __u32 length) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(buffer->type)) + buffer->m.planes[0].length = length; + else + buffer->length = length; +} + +static unsigned long get_buffer_uptr(struct v4l2_buffer *buffer) +{ + return V4L2_TYPE_IS_MULTIPLANAR(buffer->type) ? buffer->m.planes[0].m.userptr : buffer->m.userptr; +} + +static void set_buffer_uptr(struct v4l2_buffer *buffer, unsigned long userptr) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(buffer->type)) + buffer->m.planes[0].m.userptr = userptr; + else + buffer->m.userptr = userptr; +} + +static __u32 get_buffer_offset(struct v4l2_buffer *buffer) +{ + return V4L2_TYPE_IS_MULTIPLANAR(buffer->type) ? buffer->m.planes[0].m.mem_offset : buffer->m.offset; +} + +static __u32 get_format_width(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.width; + else + return format->fmt.pix.width; +} + +static void set_format_width(struct v4l2_format *format, __u32 width) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.width = width; + else + format->fmt.pix.width = width; +} + +static __u32 get_format_height(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.height; + else + return format->fmt.pix.height; +} + +static void set_format_height(struct v4l2_format *format, __u32 height) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.height = height; + else + format->fmt.pix.height = height; +} + +static __u32 get_format_code(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.pixelformat; + else + return format->fmt.pix.pixelformat; +} + +static void set_format_code(struct v4l2_format *format, __u32 code) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.pixelformat = code; + else + format->fmt.pix.pixelformat = code; +} + +static __u32 get_format_field(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.field; + else + return format->fmt.pix.field; +} + +static void set_format_field(struct v4l2_format *format, __u32 field) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.field = field; + else + format->fmt.pix.field = field; +} + +static __u32 get_format_bytesperline(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.plane_fmt[0].bytesperline; + else + return format->fmt.pix.bytesperline; +} + +static void set_format_bytesperline(struct v4l2_format *format, __u32 bytesperline) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.plane_fmt[0].bytesperline = bytesperline; + else + format->fmt.pix.bytesperline = bytesperline; +} + +static __u32 get_format_size(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.plane_fmt[0].sizeimage; + else + return format->fmt.pix.sizeimage; +} + +static void set_format_size(struct v4l2_format *format, __u32 size) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.plane_fmt[0].sizeimage = size; + else + format->fmt.pix.sizeimage = size; +} + +static __u32 get_format_colorspace(struct v4l2_format *format) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return format->fmt.pix_mp.colorspace; + else + return format->fmt.pix.colorspace; +} + +static void set_format_colorspace(struct v4l2_format *format, __u32 colorspace) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + format->fmt.pix_mp.colorspace = colorspace; + else + format->fmt.pix.colorspace = colorspace; +} + +static void set_format_priv(struct v4l2_format *format, __u32 priv) +{ + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + return; + else + format->fmt.pix.priv = priv; +} + static void itd_vidioc_enuminput(const char *unused) { static const struct symbol_list type[] = { @@ -1404,16 +1575,14 @@ static void itd_vidioc_parm(const char *s) static void print_v4l2_format(int v, struct v4l2_format *f, char c) { print(v, "%c type: %s\n", c, symbol_str(f->type, v4l2_buf_types)); - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - print(v, "%c width: %i\n", c, f->fmt.pix.width); - print(v, "%c height: %i\n", c, f->fmt.pix.height); - print(v, "%c pixelformat: %s\n", c, symbol_str(f->fmt.pix.pixelformat, pixelformats)); - print(v, "%c field: %i\n", c, f->fmt.pix.field); - print(v, "%c bytesperline: %i\n", c, f->fmt.pix.bytesperline); - print(v, "%c sizeimage: %i\n", c, f->fmt.pix.sizeimage); - print(v, "%c colorspace: %i\n", c, f->fmt.pix.colorspace); - print(v, "%c priv: %i\n", c, f->fmt.pix.priv); + if (V4L2_TYPE_IS_VIDEO(f->type)) { + print(v, "%c width: %i\n", c, get_format_width(f)); + print(v, "%c height: %i\n", c, get_format_height(f)); + print(v, "%c pixelformat: %s\n", c, symbol_str(get_format_code(f), pixelformats)); + print(v, "%c field: %i\n", c, get_format_field(f)); + print(v, "%c bytesperline: %i\n", c, get_format_bytesperline(f)); + print(v, "%c sizeimage: %i\n", c, get_format_size(f)); + print(v, "%c colorspace: %i\n", c, get_format_colorspace(f)); } } @@ -1439,14 +1608,14 @@ static void itd_vidioc_fmt(bool try, const char *s) int val[4]; switch (token_get(list, &s, val)) { case 't': p.type = val[0]; break; - case 'w': p.fmt.pix.width = val[0]; break; - case 'h': p.fmt.pix.height = val[0]; break; - case 'p': p.fmt.pix.pixelformat = val[0]; break; - case 'f': p.fmt.pix.field = val[0]; break; - case 'b': p.fmt.pix.bytesperline = val[0]; break; - case 's': p.fmt.pix.sizeimage = val[0]; break; - case 'c': p.fmt.pix.colorspace = val[0]; break; - case 'r': p.fmt.pix.priv = val[0]; break; + case 'w': set_format_width(&p, val[0]); break; + case 'h': set_format_height(&p, val[0]); break; + case 'p': set_format_code(&p, val[0]); break; + case 'f': set_format_field(&p, val[0]); break; + case 'b': set_format_bytesperline(&p, val[0]); break; + case 's': set_format_size(&p, val[0]); break; + case 'c': set_format_colorspace(&p, val[0]); break; + case 'r': set_format_priv(&p, val[0]); break; } } @@ -1571,10 +1740,6 @@ static void itd_vidioc_sg_selection(const char *s) CLEAR(p); p.type = vars.pipes[vars.pipe].reqbufs.type; - if (p.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (p.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - p.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; while (*s && *s!='?') { int val[4]; @@ -1659,7 +1824,7 @@ static void print_buffer(struct v4l2_buffer *b, char c) const int v = 2; print(v, "%c index: %i\n", c, b->index); print(v, "%c type: %s\n", c, symbol_str(b->type, v4l2_buf_types)); - print(v, "%c bytesused: %i\n", c, b->bytesused); + print(v, "%c bytesused: %i\n", c, get_buffer_bytesused(b)); print(v, "%c flags: %s\n", c, symbol_flag_str(b->flags, buf_flags)); print(v, "%c field: %i\n", c, b->field); print(v, "%c timestamp: %i.%06i\n", c, b->timestamp.tv_sec, b->timestamp.tv_usec); @@ -1669,10 +1834,10 @@ static void print_buffer(struct v4l2_buffer *b, char c) print(v, "%c sequence: %i\n", c, b->sequence); print(v, "%c memory: %s\n", c, symbol_str(b->memory, v4l2_memory)); if (b->memory == V4L2_MEMORY_MMAP) - print(v, "%c offset: 0x%08X\n", c, b->m.offset); + print(v, "%c offset: 0x%08X\n", c, get_buffer_offset(b)); else if (b->memory == V4L2_MEMORY_USERPTR) - print(v, "%c userptr: 0x%08lX\n", c, b->m.userptr); - print(v, "%c length: %i\n", c, b->length); + print(v, "%c userptr: 0x%08lX\n", c, get_buffer_uptr(b)); + print(v, "%c length: %i\n", c, get_buffer_length(b)); // print(v, "%c input: %i\n", c, b->input); } @@ -1684,7 +1849,7 @@ static void itd_vidioc_querybuf_cleanup(void) struct ring_buffer *rb = &vars.pipes[vars.pipe].ring_buffers[i]; free(rb->malloc_p); if (rb->mmap_p) { - int r = munmap(rb->mmap_p, rb->querybuf.length); + int r = munmap(rb->mmap_p, get_buffer_length(&rb->querybuf)); if (r) error("munmap failed"); } CLEAR(*rb); @@ -1701,6 +1866,8 @@ static void itd_vidioc_querybuf(const char *unused) if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE && t != V4L2_BUF_TYPE_VIDEO_OUTPUT && + t != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + t != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && t != V4L2_BUF_TYPE_VIDEO_OVERLAY && t != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) error("unsupported operation type"); @@ -1719,19 +1886,23 @@ static void itd_vidioc_querybuf(const char *unused) rb->querybuf.type = t; rb->querybuf.memory = vars.pipes[vars.pipe].reqbufs.memory; rb->querybuf.index = i; + if (V4L2_TYPE_IS_MULTIPLANAR(t)) { + rb->querybuf.length = 1; + rb->querybuf.m.planes = rb->planes; + } print(1, "VIDIOC_QUERYBUF index:%i\n", rb->querybuf.index); itd_xioctl(VIDIOC_QUERYBUF, &rb->querybuf); print_buffer(&rb->querybuf, '>'); if (rb->querybuf.memory == V4L2_MEMORY_MMAP) { - void *p = mmap(NULL, rb->querybuf.length, - PROT_READ | PROT_WRITE, MAP_SHARED, vars.pipes[vars.pipe].fd, rb->querybuf.m.offset); + void *p = mmap(NULL, get_buffer_length(&rb->querybuf), + PROT_READ | PROT_WRITE, MAP_SHARED, vars.pipes[vars.pipe].fd, get_buffer_offset(&rb->querybuf)); if (p == MAP_FAILED) error("mmap failed"); rb->mmap_p = p; rb->start = p; } else if (rb->querybuf.memory == V4L2_MEMORY_USERPTR) { - int s = PAGE_ALIGN(vars.pipes[vars.pipe].format.fmt.pix.sizeimage) + _PAGE_SIZE - 1; + int s = PAGE_ALIGN(get_format_size(&vars.pipes[vars.pipe].format)) + _PAGE_SIZE - 1; void *p = malloc(s); if (p == NULL) error("malloc failed"); @@ -1756,10 +1927,11 @@ static void capture_buffer_stats(void *image, struct v4l2_format *format) if (!vars.calculate_stats) return; - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) error("bad buffer type for statistics"); - switch (format->fmt.pix.pixelformat) { + switch (get_format_code(format)) { case V4L2_PIX_FMT_SBGGR10: case V4L2_PIX_FMT_SGBRG10: case V4L2_PIX_FMT_SGRBG10: @@ -1776,11 +1948,11 @@ static void capture_buffer_stats(void *image, struct v4l2_format *format) stat[p][MAX] = 0; } - stride = format->fmt.pix.bytesperline; + stride = get_format_bytesperline(format); line = image; - for (y = 0; y < format->fmt.pix.height; y++) { + for (y = 0; y < get_format_height(format); y++) { unsigned char *ptr = line; - for (x = 0; x < format->fmt.pix.width; x++) { + for (x = 0; x < get_format_width(format); x++) { int v = ptr[0] | (ptr[1] << 8); p = ((y & 1) << 1) | (x & 1); stat[p][NUM]++; @@ -1801,8 +1973,8 @@ static void itd_capture_buffer_save(void *image, struct v4l2_format *format, str { struct capture_buffer *cb; - if (buffer->bytesused < 0 || buffer->bytesused >= MAX_BUFFER_SIZE) { - print(1, "Bad buffer size %i bytes. Not processing.\n", buffer->bytesused); + if (get_buffer_bytesused(buffer) < 0 || get_buffer_bytesused(buffer) >= MAX_BUFFER_SIZE) { + print(1, "Bad buffer size %i bytes. Not processing.\n", get_buffer_bytesused(buffer)); return; } @@ -1818,8 +1990,8 @@ static void itd_capture_buffer_save(void *image, struct v4l2_format *format, str } cb = &vars.pipes[vars.pipe].capture_buffers[vars.pipes[vars.pipe].num_capture_buffers++]; - cb->pix_format = format->fmt.pix; - cb->length = buffer->bytesused; + cb->format = *format; + cb->length = get_buffer_bytesused(buffer); cb->image = malloc(cb->length); if (!cb->image) error("out of memory"); @@ -1831,11 +2003,16 @@ static void itd_vidioc_dqbuf(void) enum v4l2_buf_type t = vars.pipes[vars.pipe].reqbufs.type; enum v4l2_memory m = vars.pipes[vars.pipe].reqbufs.memory; struct v4l2_buffer b; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; int i; CLEAR(b); b.type = t; b.memory = m; + if (V4L2_TYPE_IS_MULTIPLANAR(t)) { + b.length = 1; + b.m.planes = planes; + } print(1, "VIDIOC_DQBUF "); itd_xioctl(VIDIOC_DQBUF, &b); print_time(); @@ -1844,12 +2021,12 @@ static void itd_vidioc_dqbuf(void) if (i < 0 || i >= MAX_RING_BUFFERS) error("index out of range"); - if (b.bytesused > vars.pipes[vars.pipe].format.fmt.pix.sizeimage) + if (get_buffer_bytesused(&b) > get_format_size(&vars.pipes[vars.pipe].format)) error("Bad buffer size %i (sizeimage %i)", - b.bytesused, vars.pipes[vars.pipe].format.fmt.pix.sizeimage); - if (b.bytesused > vars.pipes[vars.pipe].ring_buffers[i].querybuf.length) + get_buffer_bytesused(&b), get_format_size(&vars.pipes[vars.pipe].format)); + if (get_buffer_bytesused(&b) > get_buffer_length(&vars.pipes[vars.pipe].ring_buffers[i].querybuf)) print(1, "warning: Bad buffer size %i (querybuf %i)\n", - b.bytesused, vars.pipes[vars.pipe].ring_buffers[i].querybuf.length); + get_buffer_bytesused(&b), get_buffer_length(&vars.pipes[vars.pipe].ring_buffers[i].querybuf)); capture_buffer_stats(vars.pipes[vars.pipe].ring_buffers[i].start, &vars.pipes[vars.pipe].format); itd_capture_buffer_save(vars.pipes[vars.pipe].ring_buffers[i].start, &vars.pipes[vars.pipe].format, &b); @@ -1860,8 +2037,9 @@ static void itd_vidioc_qbuf(void) { enum v4l2_buf_type t = vars.pipes[vars.pipe].reqbufs.type; enum v4l2_memory m = vars.pipes[vars.pipe].reqbufs.memory; - __u32 sizeimage = vars.pipes[vars.pipe].format.fmt.pix.sizeimage; + __u32 sizeimage = get_format_size(&vars.pipes[vars.pipe].format); struct v4l2_buffer b; + struct v4l2_plane planes[VIDEO_MAX_PLANES]; int i; for (i = 0; i < MAX_RING_BUFFERS; i++) @@ -1873,18 +2051,23 @@ static void itd_vidioc_qbuf(void) b.type = t; b.index = i; b.memory = m; + if (V4L2_TYPE_IS_MULTIPLANAR(t)) { + b.length = 1; + b.m.planes = planes; + } if (m == V4L2_MEMORY_USERPTR) { - b.m.userptr = (unsigned long)vars.pipes[vars.pipe].ring_buffers[i].start; - b.length = sizeimage; + set_buffer_uptr(&b, (unsigned long)vars.pipes[vars.pipe].ring_buffers[i].start); + set_buffer_length(&b, sizeimage); } else if (m == V4L2_MEMORY_MMAP) { /* Nothing here */ } else error("unsupported capture memory"); if (t == V4L2_BUF_TYPE_VIDEO_OUTPUT || + t == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || t == V4L2_BUF_TYPE_VIDEO_OVERLAY || t == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) - b.bytesused = sizeimage; + set_buffer_bytesused(&b, sizeimage); memset(vars.pipes[vars.pipe].ring_buffers[i].start, FILLER, sizeimage); if (vars.pipes[vars.pipe].bufdata) { @@ -3254,7 +3437,7 @@ static void capture_buffer_write(struct capture_buffer *cb, char *name, int i) } print(1, "Writing buffer #%03i (%i bytes) format %s to `%s'\n", i, cb->length, - symbol_str(cb->pix_format.pixelformat, pixelformats), b); + symbol_str(get_format_code(&cb->format), pixelformats), b); write_file(b, cb->image, cb->length); } From 6a4f6bc8965ec7fcc877a531069df2b5253f0289 Mon Sep 17 00:00:00 2001 From: Tianshu Qiu Date: Fri, 13 Oct 2017 14:16:32 +0800 Subject: [PATCH 3/3] kernel-ut: nvt: Add support for meta format Change-Id: Id459531f2f25124bced9d45c77096873e38daa3a Signed-off-by: Tianshu Qiu --- linux/videodev2.h | 15 ++++++++++ v4l2n.c | 73 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/linux/videodev2.h b/linux/videodev2.h index d55ed61..aa787a1 100644 --- a/linux/videodev2.h +++ b/linux/videodev2.h @@ -143,6 +143,8 @@ enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, V4L2_BUF_TYPE_SDR_CAPTURE = 11, V4L2_BUF_TYPE_SDR_OUTPUT = 12, + V4L2_BUF_TYPE_META_CAPTURE = 13, + V4L2_BUF_TYPE_META_OUTPUT = 14, /* Deprecated, do not use */ V4L2_BUF_TYPE_PRIVATE = 0x80, }; @@ -440,10 +442,12 @@ struct v4l2_capability { #define V4L2_CAP_SDR_CAPTURE 0x00100000 /* Is a SDR capture device */ #define V4L2_CAP_EXT_PIX_FORMAT 0x00200000 /* Supports the extended pixel format */ #define V4L2_CAP_SDR_OUTPUT 0x00400000 /* Is a SDR output device */ +#define V4L2_CAP_META_CAPTURE 0x00800000 /* Is a metadata capture device */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */ #define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ @@ -2034,6 +2038,16 @@ struct v4l2_sdr_format { __u8 reserved[24]; } __attribute__ ((packed)); +/** + * struct v4l2_meta_format - metadata format definition + * @dataformat: little endian four character code (fourcc) + * @buffersize: maximum size in bytes required for data + */ +struct v4l2_meta_format { + __u32 dataformat; + __u32 buffersize; +} __attribute__ ((packed)); + /** * struct v4l2_format - stream data format * @type: enum v4l2_buf_type; type of the data stream @@ -2053,6 +2067,7 @@ struct v4l2_format { struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ struct v4l2_sdr_format sdr; /* V4L2_BUF_TYPE_SDR_CAPTURE */ + struct v4l2_meta_format meta; __u8 raw_data[200]; /* user-defined */ } fmt; }; diff --git a/v4l2n.c b/v4l2n.c index de3c494..3de13ed 100644 --- a/v4l2n.c +++ b/v4l2n.c @@ -68,6 +68,10 @@ static unsigned long int _PAGE_MASK; #define MAX_BUFFER_SIZE (64*1024*1024) #define MAX_PIPES 6 +#define V4L2_TYPE_IS_META(type) \ + ((type) == V4L2_BUF_TYPE_META_CAPTURE \ + || (type) == V4L2_BUF_TYPE_META_OUTPUT) + #define V4L2_TYPE_IS_VIDEO(type) \ ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE \ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ @@ -508,6 +512,8 @@ static const struct symbol_list v4l2_buf_types[] = { BUFTYPE(SLICED_VBI_OUTPUT), BUFTYPE(VIDEO_OUTPUT_OVERLAY), BUFTYPE(PRIVATE), + BUFTYPE(META_CAPTURE), + BUFTYPE(META_OUTPUT), SYMBOL_END }; @@ -1226,7 +1232,9 @@ static __u32 get_buffer_offset(struct v4l2_buffer *buffer) static __u32 get_format_width(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return format->fmt.meta.buffersize; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.width; else return format->fmt.pix.width; @@ -1234,7 +1242,9 @@ static __u32 get_format_width(struct v4l2_format *format) static void set_format_width(struct v4l2_format *format, __u32 width) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.width = width; else format->fmt.pix.width = width; @@ -1242,7 +1252,9 @@ static void set_format_width(struct v4l2_format *format, __u32 width) static __u32 get_format_height(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return 1; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.height; else return format->fmt.pix.height; @@ -1250,7 +1262,9 @@ static __u32 get_format_height(struct v4l2_format *format) static void set_format_height(struct v4l2_format *format, __u32 height) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.height = height; else format->fmt.pix.height = height; @@ -1258,7 +1272,9 @@ static void set_format_height(struct v4l2_format *format, __u32 height) static __u32 get_format_code(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return format->fmt.meta.dataformat; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.pixelformat; else return format->fmt.pix.pixelformat; @@ -1266,7 +1282,9 @@ static __u32 get_format_code(struct v4l2_format *format) static void set_format_code(struct v4l2_format *format, __u32 code) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + format->fmt.meta.dataformat = code; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.pixelformat = code; else format->fmt.pix.pixelformat = code; @@ -1274,7 +1292,9 @@ static void set_format_code(struct v4l2_format *format, __u32 code) static __u32 get_format_field(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return V4L2_FIELD_NONE; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.field; else return format->fmt.pix.field; @@ -1282,7 +1302,9 @@ static __u32 get_format_field(struct v4l2_format *format) static void set_format_field(struct v4l2_format *format, __u32 field) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.field = field; else format->fmt.pix.field = field; @@ -1290,7 +1312,9 @@ static void set_format_field(struct v4l2_format *format, __u32 field) static __u32 get_format_bytesperline(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return format->fmt.meta.buffersize; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.plane_fmt[0].bytesperline; else return format->fmt.pix.bytesperline; @@ -1298,7 +1322,9 @@ static __u32 get_format_bytesperline(struct v4l2_format *format) static void set_format_bytesperline(struct v4l2_format *format, __u32 bytesperline) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.plane_fmt[0].bytesperline = bytesperline; else format->fmt.pix.bytesperline = bytesperline; @@ -1306,7 +1332,9 @@ static void set_format_bytesperline(struct v4l2_format *format, __u32 bytesperli static __u32 get_format_size(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return format->fmt.meta.buffersize; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.plane_fmt[0].sizeimage; else return format->fmt.pix.sizeimage; @@ -1314,7 +1342,9 @@ static __u32 get_format_size(struct v4l2_format *format) static void set_format_size(struct v4l2_format *format, __u32 size) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + format->fmt.meta.buffersize = size; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.plane_fmt[0].sizeimage = size; else format->fmt.pix.sizeimage = size; @@ -1322,7 +1352,9 @@ static void set_format_size(struct v4l2_format *format, __u32 size) static __u32 get_format_colorspace(struct v4l2_format *format) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return 0; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return format->fmt.pix_mp.colorspace; else return format->fmt.pix.colorspace; @@ -1330,7 +1362,9 @@ static __u32 get_format_colorspace(struct v4l2_format *format) static void set_format_colorspace(struct v4l2_format *format, __u32 colorspace) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) format->fmt.pix_mp.colorspace = colorspace; else format->fmt.pix.colorspace = colorspace; @@ -1338,7 +1372,9 @@ static void set_format_colorspace(struct v4l2_format *format, __u32 colorspace) static void set_format_priv(struct v4l2_format *format, __u32 priv) { - if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) + if (V4L2_TYPE_IS_META(format->type)) + return; + else if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) return; else format->fmt.pix.priv = priv; @@ -1583,6 +1619,9 @@ static void print_v4l2_format(int v, struct v4l2_format *f, char c) print(v, "%c bytesperline: %i\n", c, get_format_bytesperline(f)); print(v, "%c sizeimage: %i\n", c, get_format_size(f)); print(v, "%c colorspace: %i\n", c, get_format_colorspace(f)); + } else if (V4L2_TYPE_IS_META(f->type)) { + print(v, "%c format: %i\n", c, symbol_str(get_format_code(f), pixelformats)); + print(v, "%c size: %i\n", c, get_format_size(f)); } } @@ -1868,6 +1907,8 @@ static void itd_vidioc_querybuf(const char *unused) t != V4L2_BUF_TYPE_VIDEO_OUTPUT && t != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && t != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + t != V4L2_BUF_TYPE_META_CAPTURE && + t != V4L2_BUF_TYPE_META_OUTPUT && t != V4L2_BUF_TYPE_VIDEO_OVERLAY && t != V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) error("unsupported operation type"); @@ -2242,6 +2283,8 @@ static void itd_vidioc_querycap(const char *unused) CAP_FLAG(ASYNCIO), CAP_FLAG(STREAMING), CAP_FLAG(DEVICE_CAPS), + CAP_FLAG(META_CAPTURE), + CAP_FLAG(META_OUTPUT), SYMBOL_END };