aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-08-30 11:24:42 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2018-08-31 14:37:10 +0200
commitbae4362ba87fcf3013fa7d9c52f1894d1cb2efdd (patch)
treed66f307ec6037b52f14409dfc1a4fa46cdd021d8 /utils
parent4cebd11836135287340f12a4e3df92a881157a5c (diff)
v4l2-ctl/qvidcap: add initial fwht support
This hooks in all the required sources, but it is not used yet. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Diffstat (limited to 'utils')
-rw-r--r--utils/common/v4l-stream.c69
-rw-r--r--utils/common/v4l-stream.h65
-rw-r--r--utils/qvidcap/Makefile.am2
-rw-r--r--utils/qvidcap/capture-win-gl.cpp2
l---------utils/qvidcap/codec-fwht.c1
l---------utils/qvidcap/codec-v4l2-fwht.c1
-rw-r--r--utils/qvidcap/qvidcap.pro1
-rw-r--r--utils/v4l2-ctl/Android.mk2
-rw-r--r--utils/v4l2-ctl/Makefile.am2
l---------utils/v4l2-ctl/codec-fwht.c1
l---------utils/v4l2-ctl/codec-v4l2-fwht.c1
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-streaming.cpp4
12 files changed, 130 insertions, 21 deletions
diff --git a/utils/common/v4l-stream.c b/utils/common/v4l-stream.c
index dadaf894..a45c174d 100644
--- a/utils/common/v4l-stream.c
+++ b/utils/common/v4l-stream.c
@@ -10,6 +10,12 @@
#include <netinet/in.h>
#include "v4l-stream.h"
+#include "codec-fwht.h"
+
+#define MIN_WIDTH 64
+#define MAX_WIDTH 4096
+#define MIN_HEIGHT 64
+#define MAX_HEIGHT 2160
/*
* Since Bayer uses alternating lines of BG and GR color components
@@ -161,3 +167,66 @@ unsigned rle_compress(__u8 *b, unsigned size, unsigned bpl)
}
return (__u8 *)dst - b;
}
+
+struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned w, unsigned h,
+ unsigned field, unsigned colorspace, unsigned xfer_func,
+ unsigned ycbcr_enc, unsigned quantization)
+{
+ struct codec_ctx *ctx;
+ const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_find_pixfmt(pixfmt);
+ unsigned int chroma_div;
+ unsigned int size = w * h;
+
+ if (!info)
+ return NULL;
+
+ ctx = malloc(sizeof(*ctx));
+ if (!ctx)
+ return NULL;
+ ctx->state.width = w;
+ ctx->state.height = h;
+ ctx->state.info = info;
+ ctx->field = field;
+ ctx->state.colorspace = colorspace;
+ ctx->state.xfer_func = xfer_func;
+ ctx->state.ycbcr_enc = ycbcr_enc;
+ ctx->state.quantization = quantization;
+ ctx->flags = 0;
+ chroma_div = info->width_div * info->height_div;
+ ctx->size = size + 2 * size / chroma_div;
+ ctx->state.ref_frame.luma = malloc(ctx->size);
+ ctx->comp_max_size = ctx->size + sizeof(struct fwht_cframe_hdr);
+ ctx->state.compressed_frame = malloc(ctx->comp_max_size);
+ if (!ctx->state.ref_frame.luma || !ctx->state.compressed_frame) {
+ free(ctx->state.ref_frame.luma);
+ free(ctx->state.compressed_frame);
+ free(ctx);
+ return NULL;
+ }
+ ctx->state.ref_frame.width = ctx->state.ref_frame.height = 0;
+ ctx->state.ref_frame.cb = ctx->state.ref_frame.luma + size;
+ ctx->state.ref_frame.cr = ctx->state.ref_frame.cb + size / chroma_div;
+ ctx->state.gop_size = 10;
+ ctx->state.gop_cnt = 0;
+ return ctx;
+}
+
+void fwht_free(struct codec_ctx *ctx)
+{
+ free(ctx->state.ref_frame.luma);
+ free(ctx->state.compressed_frame);
+ free(ctx);
+}
+
+__u8 *fwht_compress(struct codec_ctx *ctx, __u8 *buf, unsigned uncomp_size, unsigned *comp_size)
+{
+ ctx->state.i_frame_qp = ctx->state.p_frame_qp = 20;
+ *comp_size = v4l2_fwht_encode(&ctx->state, buf, ctx->state.compressed_frame);
+ return ctx->state.compressed_frame;
+}
+
+bool fwht_decompress(struct codec_ctx *ctx, __u8 *p_in, unsigned comp_size,
+ __u8 *p_out, unsigned uncomp_size)
+{
+ return !v4l2_fwht_decode(&ctx->state, p_in, p_out);
+}
diff --git a/utils/common/v4l-stream.h b/utils/common/v4l-stream.h
index ccc73a12..fd3ce87a 100644
--- a/utils/common/v4l-stream.h
+++ b/utils/common/v4l-stream.h
@@ -9,6 +9,7 @@
#define _V4L_STREAM_H_
#include <linux/videodev2.h>
+#include <codec-v4l2-fwht.h>
#ifdef __cplusplus
extern "C" {
@@ -24,13 +25,13 @@ extern "C" {
* This is followed by FRAME_VIDEO packets with optional FMT_VIDEO
* packets in between if the format changes from one frame to another.
*
- * Before sending the initial FRAME_VIDEO packet you must sent the
+ * Before sending the initial FRAME_VIDEO packet you must send the
* FMT_VIDEO packet first.
*
* All values (IDs, sizes, etc) are all uint32_t in network order.
*/
#define V4L_STREAM_ID v4l2_fourcc('V', '4', 'L', '2')
-#define V4L_STREAM_VERSION 1
+#define V4L_STREAM_VERSION 2
/*
* Each packet is followed by the size of the packet (not including
@@ -66,12 +67,18 @@ extern "C" {
#define V4L_STREAM_PACKET_FMT_VIDEO_SIZE(planes) (V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT + 4 + \
(planes) * (V4L_STREAM_PACKET_FMT_VIDEO_SIZE_FMT_PLANE + 4))
-#define V4L_STREAM_PACKET_FRAME_VIDEO_X_RLE 0x02dead43
-#define V4L_STREAM_PACKET_FRAME_VIDEO_Y_RLE 0x02dead41
-#define V4L_STREAM_PACKET_FRAME_VIDEO_RPLC 0x02dead42
+/* Run-length encoded frame video packet */
+#define V4L_STREAM_PACKET_FRAME_VIDEO_RLE v4l2_fourcc('f', 'r', 'm', 'v')
+/* FWHT compressed frame video packet */
+#define V4L_STREAM_PACKET_FRAME_VIDEO_FWHT v4l2_fourcc('f', 'r', 'm', 'V')
+
+#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR (8 * 4)
+#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR (8 * 4)
+#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE(planes) (V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR + 4 + \
+ (planes) * (V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR + 4))
/*
- * The frame content is defined as follows:
+ * The frame video packet content is defined as follows:
*
* uint32_t size_hdr; // size in bytes of data after size_hdr until planes[]
* uint32_t field;
@@ -79,12 +86,20 @@ extern "C" {
* struct plane {
* uint32_t size_plane_hdr; // size in bytes of data after size_plane_hdr until data[]
* uint32_t bytesused;
- * uint32_t rle_size;
- * uint8_t data[rle_size];
+ * uint32_t data_size;
+ * uint8_t data[data_size];
* } planes[num_planes];
- *
+ */
+
+/* Run-length encoding desciption: */
+
+#define V4L_STREAM_PACKET_FRAME_VIDEO_X_RLE 0x02dead43
+#define V4L_STREAM_PACKET_FRAME_VIDEO_Y_RLE 0x02dead41
+#define V4L_STREAM_PACKET_FRAME_VIDEO_RPLC 0x02dead42
+
+/*
* The run-length encoding used is optimized for use with test patterns.
- * The rle_size value is always <= bytesused. If it is equal to bytesused
+ * The data_size value is always <= bytesused. If it is equal to bytesused
* then no RLE was used.
*
* The RLE works on groups of 4 bytes. The VIDEO_Y_RLE value is only used
@@ -103,11 +118,16 @@ extern "C" {
* those are replaced by the RPLC value (this makes the encoding very slightly
* lossy)
*/
-#define V4L_STREAM_PACKET_FRAME_VIDEO v4l2_fourcc('f', 'r', 'm', 'v')
-#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR (8 * 4)
-#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR (8 * 4)
-#define V4L_STREAM_PACKET_FRAME_VIDEO_SIZE(planes) (V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR + 4 + \
- (planes) * (V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_PLANE_HDR + 4))
+
+/*
+ * FWHT-compression desciption:
+ *
+ * The compressed encoding is simple but good enough for debugging.
+ * The size value is always <= bytesused + sizeof(struct fwht_cframe_hdr).
+ *
+ * See codec-fwht.h for more information about the compression
+ * details.
+ */
/*
* This packet ends the stream and, after reading this, the socket can be closed
@@ -115,8 +135,23 @@ extern "C" {
*/
#define V4L_STREAM_PACKET_END v4l2_fourcc('e', 'n', 'd', ' ')
+struct codec_ctx {
+ struct v4l2_fwht_state state;
+ unsigned int flags;
+ unsigned int size;
+ u32 field;
+ u32 comp_max_size;
+};
+
unsigned rle_compress(__u8 *buf, unsigned size, unsigned bytesperline);
void rle_decompress(__u8 *buf, unsigned size, unsigned rle_size, unsigned bytesperline);
+struct codec_ctx *fwht_alloc(unsigned pixfmt, unsigned w, unsigned h, unsigned field,
+ unsigned colorspace, unsigned xfer_func, unsigned ycbcr_enc,
+ unsigned quantization);
+void fwht_free(struct codec_ctx *ctx);
+__u8 *fwht_compress(struct codec_ctx *ctx, __u8 *buf, unsigned size, unsigned *comp_size);
+bool fwht_decompress(struct codec_ctx *ctx, __u8 *read_buf, unsigned comp_size,
+ __u8 *buf, unsigned size);
unsigned rle_calc_bpl(unsigned bpl, __u32 pixelformat);
#ifdef __cplusplus
diff --git a/utils/qvidcap/Makefile.am b/utils/qvidcap/Makefile.am
index fad3911e..be15b701 100644
--- a/utils/qvidcap/Makefile.am
+++ b/utils/qvidcap/Makefile.am
@@ -2,7 +2,7 @@ bin_PROGRAMS = qvidcap
man_MANS = qvidcap.1
qvidcap_SOURCES = qvidcap.cpp capture-win-gl.cpp capture-win-gl.h \
- v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-info.cpp
+ v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-info.cpp codec-fwht.c codec-v4l2-fwht.c
nodist_qvidcap_SOURCES = qrc_qvidcap.cpp moc_capture-win-gl.cpp v4l2-convert.h
qvidcap_LDADD = ../../lib/libv4l2/libv4l2.la ../../lib/libv4lconvert/libv4lconvert.la ../libv4l2util/libv4l2util.la \
../libmedia_dev/libmedia_dev.la
diff --git a/utils/qvidcap/capture-win-gl.cpp b/utils/qvidcap/capture-win-gl.cpp
index fe3f5014..248d9fb7 100644
--- a/utils/qvidcap/capture-win-gl.cpp
+++ b/utils/qvidcap/capture-win-gl.cpp
@@ -1148,7 +1148,7 @@ void CaptureGLWin::sockReadEvent()
if (read_u32(sz))
goto new_conn;
- if (packet != V4L_STREAM_PACKET_FRAME_VIDEO) {
+ if (packet != V4L_STREAM_PACKET_FRAME_VIDEO_RLE) {
char buf[1024];
fprintf(stderr, "expected FRAME_VIDEO, got 0x%08x\n", packet);
diff --git a/utils/qvidcap/codec-fwht.c b/utils/qvidcap/codec-fwht.c
new file mode 120000
index 00000000..6370a83b
--- /dev/null
+++ b/utils/qvidcap/codec-fwht.c
@@ -0,0 +1 @@
+../common/codec-fwht.c \ No newline at end of file
diff --git a/utils/qvidcap/codec-v4l2-fwht.c b/utils/qvidcap/codec-v4l2-fwht.c
new file mode 120000
index 00000000..c9e3d4c8
--- /dev/null
+++ b/utils/qvidcap/codec-v4l2-fwht.c
@@ -0,0 +1 @@
+../common/codec-v4l2-fwht.c \ No newline at end of file
diff --git a/utils/qvidcap/qvidcap.pro b/utils/qvidcap/qvidcap.pro
index c0428d11..36ab0027 100644
--- a/utils/qvidcap/qvidcap.pro
+++ b/utils/qvidcap/qvidcap.pro
@@ -24,6 +24,7 @@ HEADERS += ../../config.h
SOURCES += capture-win-gl.cpp
SOURCES += qvidcap.cpp
SOURCES += ../common/v4l-stream.c
+SOURCES += ../common/codec-fwht.c
SOURCES += ../common/v4l2-tpg-core.c
SOURCES += ../common/v4l2-tpg-colors.c
diff --git a/utils/v4l2-ctl/Android.mk b/utils/v4l2-ctl/Android.mk
index 38da4bf6..1eab3cd2 100644
--- a/utils/v4l2-ctl/Android.mk
+++ b/utils/v4l2-ctl/Android.mk
@@ -22,5 +22,5 @@ LOCAL_SRC_FILES := \
v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \
v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \
v4l2-ctl-meta.cpp v4l2-ctl-subdev.cpp v4l2-info.cpp media-info.cpp \
- v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c
+ v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c codec-fwht.c
include $(BUILD_EXECUTABLE)
diff --git a/utils/v4l2-ctl/Makefile.am b/utils/v4l2-ctl/Makefile.am
index 5bddef74..f612e0ee 100644
--- a/utils/v4l2-ctl/Makefile.am
+++ b/utils/v4l2-ctl/Makefile.am
@@ -7,7 +7,7 @@ v4l2_ctl_SOURCES = v4l2-ctl.cpp v4l2-ctl.h v4l2-ctl-common.cpp v4l2-ctl-tuner.cp
v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \
v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \
v4l2-ctl-subdev.cpp v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c v4l2-ctl-meta.cpp \
- media-info.cpp v4l2-info.cpp
+ media-info.cpp v4l2-info.cpp codec-fwht.c codec-v4l2-fwht.c
v4l2_ctl_CPPFLAGS = -I$(top_srcdir)/utils/common
media-bus-format-names.h: ../../include/linux/media-bus-format.h
diff --git a/utils/v4l2-ctl/codec-fwht.c b/utils/v4l2-ctl/codec-fwht.c
new file mode 120000
index 00000000..6370a83b
--- /dev/null
+++ b/utils/v4l2-ctl/codec-fwht.c
@@ -0,0 +1 @@
+../common/codec-fwht.c \ No newline at end of file
diff --git a/utils/v4l2-ctl/codec-v4l2-fwht.c b/utils/v4l2-ctl/codec-v4l2-fwht.c
new file mode 120000
index 00000000..c9e3d4c8
--- /dev/null
+++ b/utils/v4l2-ctl/codec-v4l2-fwht.c
@@ -0,0 +1 @@
+../common/codec-v4l2-fwht.c \ No newline at end of file
diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 80d3b628..8a164116 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -637,7 +637,7 @@ static bool fill_buffer_from_file(cv4l_queue &q, cv4l_buffer &b, FILE *fin)
char buf[1024];
unsigned sz = read_u32(fin);
- if (packet == V4L_STREAM_PACKET_FRAME_VIDEO)
+ if (packet == V4L_STREAM_PACKET_FRAME_VIDEO_RLE)
break;
fprintf(stderr, "expected FRAME_VIDEO, got 0x%08x\n", packet);
@@ -919,7 +919,7 @@ static int do_handle_cap(cv4l_fd &fd, cv4l_queue &q, FILE *fout, int *index,
tot_rle_size += rle_size[j];
tot_used += used - offset;
}
- write_u32(fout, V4L_STREAM_PACKET_FRAME_VIDEO);
+ write_u32(fout, V4L_STREAM_PACKET_FRAME_VIDEO_RLE);
write_u32(fout, V4L_STREAM_PACKET_FRAME_VIDEO_SIZE(buf.g_num_planes()) + tot_rle_size);
write_u32(fout, V4L_STREAM_PACKET_FRAME_VIDEO_SIZE_HDR);
write_u32(fout, buf.g_field());

Privacy Policy