diff options
-rw-r--r-- | v4l2-apps/libv4l/ChangeLog | 8 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/Makefile | 12 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/control/libv4lcontrol.c | 4 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/helper-funcs.h | 76 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/helper.c | 224 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h | 16 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 28 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/ov518-decomp.c | 63 |
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 */ + } } |