summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--v4l2-apps/libv4l/ChangeLog8
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/Makefile12
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c4
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/helper-funcs.h76
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/helper.c224
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h16
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c28
-rw-r--r--v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c63
8 files changed, 407 insertions, 24 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog
index ce0ea821d..dbcff3b54 100644
--- a/v4l2-apps/libv4l/ChangeLog
+++ b/v4l2-apps/libv4l/ChangeLog
@@ -2,10 +2,10 @@ libv4l-0.6.0
------------
* Recognize disabled controls and replace with fake equivalents where
available
-* Add support for decompressing ov518 "JPEG", note this code is not
- LGPL yet, I'm waiting for a license change permission. If I do not
- get one this will be moved to an external helper and the data
- will be piped through this, to keep libv4l2.so LGPL
+* Add support for decompressing ov518 "JPEG", by piping data through an
+ external helper as I've failed to contact Mark W. McClelland to get
+ permission to relicense the code. If you know a working email address for
+ Mark W. McClelland, please let me know.
libv4l-0.5.99
-------------
diff --git a/v4l2-apps/libv4l/libv4lconvert/Makefile b/v4l2-apps/libv4l/libv4lconvert/Makefile
index 997bd6bff..86d6012ac 100644
--- a/v4l2-apps/libv4l/libv4lconvert/Makefile
+++ b/v4l2-apps/libv4l/libv4lconvert/Makefile
@@ -14,11 +14,11 @@ endif
CONVERT_OBJS = libv4lconvert.o tinyjpeg.o sn9c10x.o sn9c20x.o pac207.o \
mr97310a.o flip.o crop.o jidctflt.o spca561-decompress.o \
- rgbyuv.o spca501.o sq905c.o bayer.o hm12.o ov518-decomp.o \
+ rgbyuv.o spca501.o sq905c.o bayer.o hm12.o helper.o \
control/libv4lcontrol.o processing/libv4lprocessing.o \
processing/whitebalance.o processing/autogain.o \
processing/gamma.o
-TARGETS = $(CONVERT_LIB) libv4lconvert.pc
+TARGETS = $(CONVERT_LIB) libv4lconvert.pc ov518-decomp
INCLUDES = ../include/libv4lconvert.h
ifeq ($(LIB_RELEASE),)
@@ -33,6 +33,8 @@ ifeq ($(LIBDIR),)
LIBDIR = $(PREFIX)/lib
endif
+override CPPFLAGS += -DLIBDIR=\"$(LIBDIR)/\"
+
all: $(TARGETS)
-include $(CONVERT_OBJS:.o=.d)
@@ -53,15 +55,15 @@ libv4lconvert.pc:
install: all
mkdir -p $(DESTDIR)$(PREFIX)/include
install -p -m 644 $(INCLUDES) $(DESTDIR)$(PREFIX)/include
- mkdir -p $(DESTDIR)$(LIBDIR)
+ mkdir -p $(DESTDIR)$(LIBDIR)/libv4l
ifeq ($(LINKTYPE),static)
- mkdir -p $(DESTDIR)$(LIBDIR)
install -m 644 $(CONVERT_LIB) $(DESTDIR)$(LIBDIR)
else
install -m 755 $(CONVERT_LIB).$(LIB_RELEASE) $(DESTDIR)$(LIBDIR)
cd $(DESTDIR)$(LIBDIR) && \
ln -f -s $(CONVERT_LIB).$(LIB_RELEASE) $(CONVERT_LIB)
endif
+ install -m 755 *-decomp $(DESTDIR)$(LIBDIR)/libv4l
mkdir -p $(DESTDIR)$(LIBDIR)/pkgconfig
install -m 644 libv4lconvert.pc $(DESTDIR)$(LIBDIR)/pkgconfig
@@ -78,3 +80,5 @@ clean::
%.a:
$(AR) cqs $@ $^
+
+ov518-decomp: ov518-decomp.o
diff --git a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c
index b50b686df..8a77728a6 100644
--- a/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c
+++ b/v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c
@@ -316,7 +316,7 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = {
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Horizontal flip",
+ .name = "Horizontal flip (sw)",
.minimum = 0,
.maximum = 1,
.step = 1,
@@ -326,7 +326,7 @@ static const struct v4l2_queryctrl fake_controls[V4LCONTROL_COUNT] = {
{
.id = V4L2_CID_VFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical flip",
+ .name = "Vertical flip (sw)",
.minimum = 0,
.maximum = 1,
.step = 1,
diff --git a/v4l2-apps/libv4l/libv4lconvert/helper-funcs.h b/v4l2-apps/libv4l/libv4lconvert/helper-funcs.h
new file mode 100644
index 000000000..e27f21e42
--- /dev/null
+++ b/v4l2-apps/libv4l/libv4lconvert/helper-funcs.h
@@ -0,0 +1,76 @@
+/* Utility functions for decompression helpers
+ *
+ * Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+static int v4lconvert_helper_write(int fd, const void *b, size_t count,
+ char *progname)
+{
+ const unsigned char *buf = b;
+ size_t ret, written = 0;
+
+ while (written < count) {
+ ret = write(fd, buf + written, count - written);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ fprintf(stderr, "%s: error writing: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ written += ret;
+ }
+
+ return 0;
+}
+
+static int v4lconvert_helper_read(int fd, void *b, size_t count,
+ char *progname)
+{
+ unsigned char *buf = b;
+ size_t ret, r = 0;
+
+ while (r < count) {
+ ret = read(fd, buf + r, count - r);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ fprintf(stderr, "%s: error reading: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (ret == 0) /* EOF */
+ exit(0);
+
+ r += ret;
+ }
+
+ return 0;
+}
diff --git a/v4l2-apps/libv4l/libv4lconvert/helper.c b/v4l2-apps/libv4l/libv4lconvert/helper.c
new file mode 100644
index 000000000..c1d55c2e5
--- /dev/null
+++ b/v4l2-apps/libv4l/libv4lconvert/helper.c
@@ -0,0 +1,224 @@
+/*
+# (C) 2009 Hans de Goede <hdegoede@redhat.com>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include "libv4lconvert-priv.h"
+
+#define READ_END 0
+#define WRITE_END 1
+
+/* <sigh> Unfortunately I've failed in contact some Authors of decompression
+ code of out of tree drivers. So I've no permission to relicense their code
+ their code from GPL to LGPL. To work around this, these decompression
+ algorithms are put in separate executables and we pipe data through these
+ to decompress.
+
+ The "protocol" is very simple:
+
+ From libv4l to the helper the following is send:
+ int width
+ int height
+ int flags
+ int data length
+ unsigned char[] data (data length long)
+
+ From the helper to libv4l the following is send:
+ int data length (-1 in case of a decompression error)
+ unsigned char[] data (not present when a decompression error happened)
+*/
+
+static int v4lconvert_helper_start(struct v4lconvert_data *data,
+ const char *helper)
+{
+ if (pipe(data->decompress_in_pipe)) {
+ V4LCONVERT_ERR("with helper pipe: %s\n", strerror(errno));
+ goto error;
+ }
+
+ if (pipe(data->decompress_out_pipe)) {
+ V4LCONVERT_ERR("with helper pipe: %s\n", strerror(errno));
+ goto error_close_in_pipe;
+ }
+
+ data->decompress_pid = fork();
+ if (data->decompress_pid == -1) {
+ V4LCONVERT_ERR("with helper fork: %s\n", strerror(errno));
+ goto error_close_out_pipe;
+ }
+
+ if (data->decompress_pid == 0) {
+ /* We are the child */
+
+ /* Closed unused read / write end of the pipes */
+ close(data->decompress_out_pipe[WRITE_END]);
+ close(data->decompress_in_pipe[READ_END]);
+
+ /* Connect stdin / out to the pipes */
+ if (dup2(data->decompress_out_pipe[READ_END], STDIN_FILENO) == -1) {
+ perror("libv4lconvert: error with helper dup2");
+ exit(1);
+ }
+ if (dup2(data->decompress_in_pipe[WRITE_END], STDOUT_FILENO) == -1) {
+ perror("libv4lconvert: error with helper dup2");
+ exit(1);
+ }
+
+ /* And execute the helper */
+ execl(helper, helper, NULL);
+
+ /* We should never get here */
+ perror("libv4lconvert: error starting helper");
+ exit(1);
+ } else {
+ /* Closed unused read / write end of the pipes */
+ close(data->decompress_out_pipe[READ_END]);
+ close(data->decompress_in_pipe[WRITE_END]);
+ }
+
+ return 0;
+
+error_close_out_pipe:
+ close(data->decompress_out_pipe[READ_END]);
+ close(data->decompress_out_pipe[WRITE_END]);
+error_close_in_pipe:
+ close(data->decompress_in_pipe[READ_END]);
+ close(data->decompress_in_pipe[WRITE_END]);
+error:
+ return -1;
+}
+
+/* IMPROVE ME: we could block SIGPIPE here using pthread_sigmask()
+ and then in case of EPIPE consume the signal using
+ sigtimedwait (we need to check if a blocked signal wasn't present
+ before the write, otherwise we will consume that) and
+ after consuming the signal try to restart the helper.
+
+ Note we currently do not do this, as SIGPIPE only happens if the
+ decompressor crashes, which in case of an embedded decompressor
+ would mean end of program, so by not handling SIGPIPE we treat
+ external decompressors identical. */
+static int v4lconvert_helper_write(struct v4lconvert_data *data,
+ const void *b, size_t count)
+{
+ const unsigned char *buf = b;
+ const int *i = b;
+ size_t ret, written = 0;
+
+ while (written < count) {
+ ret = write(data->decompress_out_pipe[WRITE_END], buf + written,
+ count - written);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ V4LCONVERT_ERR("writing to helper: %s\n", strerror(errno));
+ return -1;
+ }
+ written += ret;
+ }
+
+ return 0;
+}
+
+static int v4lconvert_helper_read(struct v4lconvert_data *data, void *b,
+ size_t count)
+{
+ unsigned char *buf = b;
+ size_t ret, r = 0;
+
+ while (r < count) {
+ ret = read(data->decompress_in_pipe[READ_END], buf + r, count - r);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+
+ V4LCONVERT_ERR("reading from helper: %s\n", strerror(errno));
+ return -1;
+ }
+ if (ret == 0) {
+ V4LCONVERT_ERR("reading from helper: unexpected EOF\n");
+ return -1;
+ }
+ r += ret;
+ }
+
+ return 0;
+}
+
+int v4lconvert_helper_decompress(struct v4lconvert_data *data,
+ const char *helper, const unsigned char *src, int src_size,
+ unsigned char *dest, int dest_size, int width, int height, int flags)
+{
+ int r;
+
+ if (data->decompress_pid == -1) {
+ if (v4lconvert_helper_start(data, helper))
+ return -1;
+ }
+
+ if (v4lconvert_helper_write(data, &width, sizeof(int)))
+ return -1;
+
+ if (v4lconvert_helper_write(data, &height, sizeof(int)))
+ return -1;
+
+ if (v4lconvert_helper_write(data, &flags, sizeof(int)))
+ return -1;
+
+ if (v4lconvert_helper_write(data, &src_size, sizeof(int)))
+ return -1;
+
+ if (v4lconvert_helper_write(data, src, src_size))
+ return -1;
+
+ if (v4lconvert_helper_read(data, &r, sizeof(int)))
+ return -1;
+
+ if (r < 0) {
+ V4LCONVERT_ERR("decompressing frame data\n");
+ return -1;
+ }
+
+ if (dest_size < r) {
+ V4LCONVERT_ERR("destination buffer to small\n");
+ return -1;
+ }
+
+ return v4lconvert_helper_read(data, dest, r);
+}
+
+void v4lconvert_helper_cleanup(struct v4lconvert_data *data)
+{
+ int status;
+
+ if (data->decompress_pid != -1) {
+ kill(data->decompress_pid, SIGTERM);
+ waitpid(data->decompress_pid, &status, 0);
+
+ close(data->decompress_out_pipe[WRITE_END]);
+ close(data->decompress_in_pipe[READ_END]);
+
+ data->decompress_pid = -1;
+ }
+}
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
index a2242e91a..afd111da6 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h
@@ -20,6 +20,7 @@
#define __LIBV4LCONVERT_PRIV_H
#include <stdio.h>
+#include <sys/types.h>
#include "libv4lconvert.h"
#include "control/libv4lcontrol.h"
#include "processing/libv4lprocessing.h"
@@ -126,6 +127,11 @@ struct v4lconvert_data {
unsigned char *convert_pixfmt_buf;
struct v4lcontrol_data *control;
struct v4lprocessing_data *processing;
+
+ /* Data for external decompression helpers code */
+ pid_t decompress_pid;
+ int decompress_in_pipe[2]; /* Data from helper to us */
+ int decompress_out_pipe[2]; /* Data from us to helper */
};
struct v4lconvert_pixfmt {
@@ -186,10 +192,6 @@ void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char *dst,
void v4lconvert_sn9c20x_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
-/* Warning this one modifies its input buffer! */
-void v4lconvert_ov518_to_yuv420(unsigned char *src, unsigned char *dst,
- int width, int height, int yvu, int src_size);
-
void v4lconvert_decode_spca561(const unsigned char *src, unsigned char *dst,
int width, int height);
@@ -232,4 +234,10 @@ void v4lconvert_flip(unsigned char *src, unsigned char *dest,
void v4lconvert_crop(unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt);
+int v4lconvert_helper_decompress(struct v4lconvert_data *data,
+ const char *helper, const unsigned char *src, int src_size,
+ unsigned char *dest, int dest_size, int width, int height, int command);
+
+void v4lconvert_helper_cleanup(struct v4lconvert_data *data);
+
#endif
diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
index 47eb2272e..c9a32ce77 100644
--- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
+++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c
@@ -97,6 +97,7 @@ struct v4lconvert_data *v4lconvert_create(int fd)
return NULL;
data->fd = fd;
+ data->decompress_pid = -1;
/* Check supported formats */
for (i = 0; ; i++) {
@@ -159,6 +160,7 @@ void v4lconvert_destroy(struct v4lconvert_data *data)
tinyjpeg_set_components(data->jdec, comps, 3);
tinyjpeg_free(data->jdec);
}
+ v4lconvert_helper_cleanup(data);
free(data->convert1_buf);
free(data->convert2_buf);
free(data->rotate90_buf);
@@ -505,7 +507,7 @@ static unsigned char *v4lconvert_alloc_buffer(struct v4lconvert_data *data,
}
static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
- unsigned char *src, int src_size, unsigned char *dest,
+ unsigned char *src, int src_size, unsigned char *dest, int dest_size,
struct v4l2_format *fmt, unsigned int dest_pix_fmt)
{
unsigned int header_width, header_height;
@@ -619,6 +621,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
case V4L2_PIX_FMT_OV518:
{
unsigned char *d;
+ int d_size;
int yvu = 0;
if (dest_pix_fmt != V4L2_PIX_FMT_YUV420 &&
@@ -627,8 +630,11 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
&data->convert_pixfmt_buf, &data->convert_pixfmt_buf_size);
if (!d)
return -1;
- } else
+ d_size = width * height * 3 / 2;
+ } else {
d = dest;
+ d_size = dest_size;
+ }
if (dest_pix_fmt == V4L2_PIX_FMT_YVU420)
yvu = 1;
@@ -647,7 +653,12 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
v4lconvert_sn9c20x_to_yuv420(src, d, width, height, yvu);
break;
case V4L2_PIX_FMT_OV518:
- v4lconvert_ov518_to_yuv420(src, d, width, height, yvu, src_size);
+ if (v4lconvert_helper_decompress(data, LIBDIR "/libv4l/ov518-decomp",
+ src, src_size, d, d_size, width, height, yvu)) {
+ /* Corrupt frame, better get another one */
+ errno = -EAGAIN;
+ return -1;
+ }
break;
}
@@ -883,7 +894,9 @@ int v4lconvert_convert(struct v4lconvert_data *data,
int res, dest_needed, temp_needed, processing, convert = 0;
int rotate90, vflip, hflip, crop;
unsigned char *convert1_dest = dest;
+ int convert1_dest_size = dest_size;
unsigned char *convert2_src = src, *convert2_dest = dest;
+ int convert2_dest_size = dest_size;
unsigned char *rotate90_src = src, *rotate90_dest = dest;
unsigned char *flip_src = src, *flip_dest = dest;
unsigned char *crop_src = src;
@@ -960,6 +973,8 @@ int v4lconvert_convert(struct v4lconvert_data *data,
if (!convert1_dest)
return -1;
+ convert1_dest_size =
+ my_src_fmt.fmt.pix.width * my_src_fmt.fmt.pix.height * 3;
convert2_src = convert1_dest;
}
@@ -969,6 +984,7 @@ int v4lconvert_convert(struct v4lconvert_data *data,
if (!convert2_dest)
return -1;
+ convert2_dest_size = temp_needed;
rotate90_src = flip_src = crop_src = convert2_dest;
}
@@ -993,7 +1009,8 @@ int v4lconvert_convert(struct v4lconvert_data *data,
/* Done setting sources / dest and allocating intermediate buffers,
real conversion / processing / ... starts here. */
if (convert == 2) {
- res = v4lconvert_convert_pixfmt(data, src, src_size, convert1_dest,
+ res = v4lconvert_convert_pixfmt(data, src, src_size,
+ convert1_dest, convert1_dest_size,
&my_src_fmt,
V4L2_PIX_FMT_RGB24);
if (res)
@@ -1007,7 +1024,8 @@ int v4lconvert_convert(struct v4lconvert_data *data,
if (convert) {
res = v4lconvert_convert_pixfmt(data, convert2_src, src_size,
- convert2_dest, &my_src_fmt,
+ convert2_dest, convert2_dest_size,
+ &my_src_fmt,
my_dest_fmt.fmt.pix.pixelformat);
if (res)
return res;
diff --git a/v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c b/v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c
index 6944719bc..f8f37649e 100644
--- a/v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c
+++ b/v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c
@@ -1,4 +1,6 @@
-/* FIXME FIXME FIXME: get permission to relicense this to LGPL !! */
+/* We would like to embed this inside libv4l, but we cannot as I've failed
+ to contact Mark W. McClelland to get permission to relicense this,
+ so this lives in an external (GPL licensed) helper */
/* OV518 Decompression Support Module (No-MMX version)
*
@@ -14,7 +16,8 @@
*/
#include <string.h>
-#include "libv4lconvert-priv.h"
+#include <unistd.h>
+#include "helper-funcs.h"
/******************************************************************************
* Compile-time Options
@@ -1400,7 +1403,7 @@ Decompress400(unsigned char *pIn,
* Output format is planar YUV420
* Returns uncompressed data length if success, or zero if error
*/
-void v4lconvert_ov518_to_yuv420(unsigned char *src, unsigned char *dst,
+static int v4lconvert_ov518_to_yuv420(unsigned char *src, unsigned char *dst,
int w, int h, int yvu, int inSize)
{
struct comp_info cinfo;
@@ -1414,10 +1417,60 @@ void v4lconvert_ov518_to_yuv420(unsigned char *src, unsigned char *dst,
cinfo.rawLen = inSize;
if (get_qt_dynamic(src, &cinfo) < 0)
- return;
+ return -1;
/* Decompress, skipping the 8-byte SOF header */
decompress420NoMMXOV518(src + 8, dst, pTmp, w, h, numpix, &cinfo, yvu);
- return;
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int width, height, yvu, src_size, dest_size;
+ unsigned char src_buf[200000];
+ unsigned char dest_buf[500000];
+
+ while (1) {
+ if (v4lconvert_helper_read(STDIN_FILENO, &width, sizeof(int), argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+ if (v4lconvert_helper_read(STDIN_FILENO, &height, sizeof(int), argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+ if (v4lconvert_helper_read(STDIN_FILENO, &yvu, sizeof(int), argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+ if (v4lconvert_helper_read(STDIN_FILENO, &src_size, sizeof(int), argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+ if (src_size > sizeof(src_buf)) {
+ fprintf(stderr, "%s: error: src_buf too small, need: %d\n",
+ argv[0], src_size);
+ return 2;
+ }
+
+ if (v4lconvert_helper_read(STDIN_FILENO, src_buf, src_size, argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+
+ dest_size = width * height * 3 / 2;
+ if (dest_size > sizeof(dest_buf)) {
+ fprintf(stderr, "%s: error: dest_buf too small, need: %d\n",
+ argv[0], dest_size);
+ dest_size = -1;
+ } else if (v4lconvert_ov518_to_yuv420(src_buf, dest_buf, width, height,
+ yvu, src_size))
+ dest_size = -1;
+
+ if (v4lconvert_helper_write(STDOUT_FILENO, &dest_size, sizeof(int),
+ argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+
+ if (dest_size == -1)
+ continue;
+
+ if (v4lconvert_helper_write(STDOUT_FILENO, dest_buf, dest_size, argv[0]))
+ return 1; /* Erm, no way to recover without loosing sync with libv4l */
+ }
}