aboutsummaryrefslogtreecommitdiffstats
path: root/utils/qvidcap
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-08-30 11:26:23 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2018-08-31 14:37:10 +0200
commitf44f00e8b4ac6e9aa05bac8953e3fcc89e1fe198 (patch)
treef3f8039c52b63c713998cab91b84327fe095599f /utils/qvidcap
parentead349e3f32dbdc1c6f6527a4e34f5a9fd162eb0 (diff)
qvidcap: support the new FWHT codec.
It can now decode streams using the new FWHT codec. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Diffstat (limited to 'utils/qvidcap')
-rw-r--r--utils/qvidcap/capture-win-gl.cpp46
-rw-r--r--utils/qvidcap/capture-win-gl.h2
-rw-r--r--utils/qvidcap/qvidcap.cpp6
3 files changed, 39 insertions, 15 deletions
diff --git a/utils/qvidcap/capture-win-gl.cpp b/utils/qvidcap/capture-win-gl.cpp
index 248d9fb7..00baa643 100644
--- a/utils/qvidcap/capture-win-gl.cpp
+++ b/utils/qvidcap/capture-win-gl.cpp
@@ -23,7 +23,6 @@
#include <QApplication>
#include <netinet/in.h>
-#include "v4l-stream.h"
#include "v4l2-info.h"
const __u32 formats[] = {
@@ -190,6 +189,7 @@ CaptureGLWin::CaptureGLWin(QScrollArea *sa, QWidget *parent) :
m_sock(0),
m_v4l_queue(0),
m_frame(0),
+ m_ctx(0),
m_origPixelFormat(0),
m_fps(0),
m_singleStep(false),
@@ -742,6 +742,12 @@ void CaptureGLWin::setModeSocket(int socket, int port)
m_mode = AppModeSocket;
m_sock = socket;
m_port = port;
+ if (m_ctx)
+ free(m_ctx);
+ m_ctx = fwht_alloc(m_v4l_fmt.g_pixelformat(), m_v4l_fmt.g_width(), m_v4l_fmt.g_height(),
+ m_v4l_fmt.g_field(), m_v4l_fmt.g_colorspace(), m_v4l_fmt.g_xfer_func(),
+ m_v4l_fmt.g_ycbcr_enc(), m_v4l_fmt.g_quantization());
+
QSocketNotifier *readSock = new QSocketNotifier(m_sock,
QSocketNotifier::Read, this);
@@ -1097,6 +1103,11 @@ void CaptureGLWin::listenForNewConnection()
pixfmt2s(fmt.g_pixelformat()).c_str());
::close(sock_fd);
}
+ if (m_ctx)
+ free(m_ctx);
+ m_ctx = fwht_alloc(fmt.g_pixelformat(), fmt.g_width(), fmt.g_height(),
+ fmt.g_field(), fmt.g_colorspace(), fmt.g_xfer_func(),
+ fmt.g_ycbcr_enc(), fmt.g_quantization());
setPixelAspect(pixelaspect);
updateOrigValues();
setModeSocket(sock_fd, m_port);
@@ -1136,6 +1147,7 @@ void CaptureGLWin::sockReadEvent()
}
unsigned packet, sz;
+ bool is_fwht;
if (read_u32(packet))
goto new_conn;
@@ -1148,7 +1160,8 @@ void CaptureGLWin::sockReadEvent()
if (read_u32(sz))
goto new_conn;
- if (packet != V4L_STREAM_PACKET_FRAME_VIDEO_RLE) {
+ if (packet != V4L_STREAM_PACKET_FRAME_VIDEO_RLE &&
+ packet != V4L_STREAM_PACKET_FRAME_VIDEO_FWHT) {
char buf[1024];
fprintf(stderr, "expected FRAME_VIDEO, got 0x%08x\n", packet);
@@ -1165,6 +1178,8 @@ void CaptureGLWin::sockReadEvent()
return;
}
+ is_fwht = m_ctx && packet == V4L_STREAM_PACKET_FRAME_VIDEO_FWHT;
+
if (read_u32(sz))
goto new_conn;
@@ -1177,9 +1192,11 @@ void CaptureGLWin::sockReadEvent()
goto new_conn;
for (unsigned p = 0; p < m_v4l_fmt.g_num_planes(); p++) {
- __u32 size;
- __u32 rle_size;
+ __u32 max_size = is_fwht ? m_ctx->comp_max_size : m_curSize[p];
+ __u8 *dst = is_fwht ? m_ctx->state.compressed_frame : m_curData[p];
+ __u32 data_size;
__u32 offset;
+ __u32 size;
if (read_u32(sz))
goto new_conn;
@@ -1187,18 +1204,18 @@ void CaptureGLWin::sockReadEvent()
fprintf(stderr, "unsupported FRAME_VIDEO plane size\n");
goto new_conn;
}
- if (read_u32(size) || read_u32(rle_size))
+ if (read_u32(size) || read_u32(data_size))
goto new_conn;
- offset = size - rle_size;
- sz = rle_size;
+ offset = is_fwht ? 0 : size - data_size;
+ sz = data_size;
- if (size > m_curSize[p]) {
- fprintf(stderr, "plane size is too large (%u > %u)\n",
- size, m_curSize[p]);
+ if (data_size > max_size) {
+ fprintf(stderr, "data size is too large (%u > %u)\n",
+ data_size, max_size);
goto new_conn;
}
while (sz) {
- n = read(m_sock, m_curData[p] + offset, sz);
+ n = read(m_sock, dst + offset, sz);
if (n < 0) {
fprintf(stderr, "error reading %d bytes\n", sz);
goto new_conn;
@@ -1208,8 +1225,11 @@ void CaptureGLWin::sockReadEvent()
offset += n;
sz -= n;
}
- rle_decompress(m_curData[p], size, rle_size,
- rle_calc_bpl(m_v4l_fmt.g_bytesperline(p), m_v4l_fmt.g_pixelformat()));
+ if (is_fwht)
+ fwht_decompress(m_ctx, dst, data_size, m_curData[p], m_curSize[p]);
+ else
+ rle_decompress(dst, size, data_size,
+ rle_calc_bpl(m_v4l_fmt.g_bytesperline(p), m_v4l_fmt.g_pixelformat()));
}
m_frame++;
update();
diff --git a/utils/qvidcap/capture-win-gl.h b/utils/qvidcap/capture-win-gl.h
index d446c1ff..8967c1f0 100644
--- a/utils/qvidcap/capture-win-gl.h
+++ b/utils/qvidcap/capture-win-gl.h
@@ -22,6 +22,7 @@
extern "C" {
#include "v4l2-tpg.h"
+#include "v4l-stream.h"
}
extern const __u32 formats[];
@@ -186,6 +187,7 @@ private:
bool m_updateShader;
QSize m_viewSize;
bool m_canOverrideResolution;
+ codec_ctx *m_ctx;
__u32 m_overridePixelFormat;
__u32 m_overrideWidth;
diff --git a/utils/qvidcap/qvidcap.cpp b/utils/qvidcap/qvidcap.cpp
index d29b4405..04f05546 100644
--- a/utils/qvidcap/qvidcap.cpp
+++ b/utils/qvidcap/qvidcap.cpp
@@ -358,8 +358,10 @@ int initSocket(int port, cv4l_fmt &fmt, v4l2_fract &pixelaspect)
fprintf(stderr, "unknown protocol ID\n");
exit(1);
}
- if (read_u32(sock_fd) != V4L_STREAM_VERSION) {
- fprintf(stderr, "unknown protocol version\n");
+ __u32 version = read_u32(sock_fd);
+
+ if (!version || version > V4L_STREAM_VERSION) {
+ fprintf(stderr, "unknown protocol version %u\n", version);
exit(1);
}
for (;;) {

Privacy Policy