summaryrefslogtreecommitdiff
path: root/v4l2-apps
diff options
context:
space:
mode:
authorhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-06-08 11:16:43 +0200
committerhans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain>2009-06-08 11:16:43 +0200
commit77e3c46ba9e763ac240f56d9365208c422fc6b20 (patch)
tree78748bd6426f4924452b65651f69d372b1f392b5 /v4l2-apps
parent8589234d1984a6acce63c0debf804c59c8414588 (diff)
downloadmediapointer-dvb-s2-77e3c46ba9e763ac240f56d9365208c422fc6b20.tar.gz
mediapointer-dvb-s2-77e3c46ba9e763ac240f56d9365208c422fc6b20.tar.bz2
libv4l: move ov518 decompression code to an external helper
From: Hans de Goede <hdegoede@redhat.com> Change support for decompressing ov518 "JPEG" to 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. Priority: normal Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'v4l2-apps')
-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 */
+ }
}