Files
v4l2_libs/libv4lconvert/helper.c
svcmobrel-release af90615985 Updating prebuilts and/or headers
f751b481c4a9203345cdbb6459d0f2882f7cdbd9 - include/libv4lconvert.h
6feb5b2b8c99c99712dd1ea7fe9ab674d58bf86b - include/libv4l1.h
f2b73fa5ab10ea7038e58bd9a4461d8e16316249 - include/libv4l1-videodev.h
bc44111fd6b2f0374a9fc67b1b23666c5c498b2c - include/libv4l2rds.h
94434b9692371b7d5f54ddef2141d22d90079ce9 - include/libv4l-plugin.h
c84a9a115a21d1fd20da0f6ca3df7b46dd23cd2a - include/config.h
1edc439e6c0fc98513fa4a69557eb6221d043be0 - include/libv4l2.h
2f55ba765c689500401111747bb381b5aca77b30 - include/libdvbv5/desc_ca.h
4c412880f0c49cd00cb16e56eed082c4744211a5 - include/libdvbv5/countries.h
c1212a9308d96730de547648d3cda2fc144d0e29 - include/libdvbv5/desc_atsc_service_location.h
4fe7def34ff640fc5e327b3596298169fdfe2f1c - include/libdvbv5/mpeg_ts.h
ef979f3276cc3cad6e947865a42643fbba860c69 - include/libdvbv5/mgt.h
ac87e3306569dae329809f27ef227c5d50f0b60e - include/libdvbv5/desc_event_short.h
98365b48442b9e3abb58101983b5da8c14f78289 - include/libdvbv5/dvb-v5-std.h
9a2b20076d6728b5799096e4149e33a73119e1ef - include/libdvbv5/desc_sat.h
c8b4fc511833f0993fa740a529e1f61e0f5a216f - include/libdvbv5/mpeg_es.h
44ab16a8d4eae09690c71a6301927c1da55dda6d - include/libdvbv5/descriptors.h
9d523ee179af955a687662996050ee3cfaacf2ab - include/libdvbv5/crc32.h
c18291ff9009bfe71a2c7c6f0fce75331dc95e30 - include/libdvbv5/sdt.h
02168c58e3c772f116f075085579ac4a8422e819 - include/libdvbv5/desc_terrestrial_delivery.h
bdf514383ca0afe981cf4fd6af86440db2dc6667 - include/libdvbv5/pat.h
22c83d133e5c1d2648efb3028e0d89c970d0aad4 - include/libdvbv5/desc_partial_reception.h
96db22ef84892a36d5df3cffa0b30d5bad01939c - include/libdvbv5/desc_logical_channel.h
73b7b0cf684de0e8a4eae49a8521f81b411d7b72 - include/libdvbv5/desc_ts_info.h
7fb0966c6a1ccdf1a8844aed4a94d4ae1d02fcd7 - include/libdvbv5/dvb-fe.h
6e6fd4c61c1f61006c63214cbe4868d49428ddb9 - include/libdvbv5/mpeg_pes.h
efa3a711499f68ae370d49d98dc1963bf6bafcd8 - include/libdvbv5/desc_extension.h
d562371bb8a3b961c4d63a0f5618453bdff4bcd3 - include/libdvbv5/dvb-log.h
b72b6d1ffcdd81e3e631c7c20bb30e5c287dc7ff - include/libdvbv5/vct.h
92d4c28148d0b537c8afc289e1a76de68435cba0 - include/libdvbv5/dvb-scan.h
6bd2ed0beaf6aa4838e239198564fd8e1d20a3a1 - include/libdvbv5/desc_t2_delivery.h
ad13bfa0b1642fc72cca387e62bc193974c8d5ee - include/libdvbv5/atsc_header.h
450fab787e61210c0c5f527df92c31c90b44a113 - include/libdvbv5/desc_service.h
9b5cfad4a5f41cbf886507da6e79b07314827b32 - include/libdvbv5/desc_language.h
e81b7f75c11f175cf365fc7fb535e80828f10e24 - include/libdvbv5/dvb-file.h
30e9a7240938943de2725f2b335b19ad320179a5 - include/libdvbv5/header.h
188fc2cbec97288787a7f66554a4b6288224f980 - include/libdvbv5/desc_isdbt_delivery.h
7645dda247bcd45628afbb74ec2707a47050992e - include/libdvbv5/nit.h
1ba874a7cad36ff31e4af3bfb37b98c05063d6b2 - include/libdvbv5/desc_event_extended.h
146f4f53fc49c66b59905249c0142efffd72fc54 - include/libdvbv5/desc_network_name.h
5b4a5e7fb30a7f28118be012837e73a7151d2619 - include/libdvbv5/cat.h
d7a096d51e3050c8f52e0e2111d88b71a5313da1 - include/libdvbv5/dvb-demux.h
40a06b5375dbc0de88a15d26cc6c1e9a505119bc - include/libdvbv5/eit.h
7544b5fb8f621a9c637c40d8f7a2a71f6ab4bd63 - include/libdvbv5/desc_hierarchy.h
2560f18846a535a2c02e1ae449511e731f11c011 - include/libdvbv5/desc_ca_identifier.h
100c02ce3bc364ddff895c75f4fb1f928a748d2d - include/libdvbv5/desc_cable_delivery.h
7a6093b13354d054cac78ea118a96e813cac3395 - include/libdvbv5/atsc_eit.h
cabecc6d7c9fdf1c437273bd6a746bf83c156f72 - include/libdvbv5/desc_frequency_list.h
b867a2e7941d718aa64b2f6a1402322b616cb2da - include/libdvbv5/pmt.h
fb8d640da36b6a156cbe0ef12dc25468de89a2a1 - include/libdvbv5/dvb-sat.h
5e2dfc1d9a71805389e9a7932812695d0309050c - include/libdvbv5/dvb-frontend.h
5430e46abb1ac7039ed0309ca338237533ff29c9 - libv4lconvert/sn9c20x.c
f4d73412805f12fa08dd79a43798a7f8d7acece9 - libv4lconvert/pac207.c
3c49d99b9753208a9c1c2a9c738a1e7ad291ca22 - libv4lconvert/jpeg_memsrcdest.h
ddd39b2fe0e2a86a6c64031ccc0d36edfd9b0f1a - libv4lconvert/sn9c10x.c
463725aa4dd3fecaf89c0b8bbf4747f8f7577935 - libv4lconvert/jpeg.c
fa751ff0f78845f3b4591396710df3b165bc8d11 - libv4lconvert/mr97310a.c
3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in
b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c
f08c902ecd48c2739956606b502fc0b8e4007703 - libv4lconvert/crop.c
1949e23fe99ccd0a05dcd084848f6d38b0af7ab6 - libv4lconvert/hm12.c
1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c
8b7644ac3d5c4161cfb6dcc2a34013f4c379c665 - libv4lconvert/libv4lconvert.export
ebebd4b880fc415f09f76597b2ac7f30e79212b9 - libv4lconvert/Makefile
ff7444c48a8da88f8a466cfb138e30e585828cb3 - libv4lconvert/jl2005bcd.c
033894511bd7e8a374a52486889658faa17918c4 - libv4lconvert/flip.c
25130d299463897a09e8b9adf72389dac2e89fa4 - libv4lconvert/tinyjpeg-internal.h
cc3f3e94a21795990610e63887c30528bde7b42e - libv4lconvert/bayer.c
1f1d1e05443c4b824cd697c0ce5efa9ea1277964 - libv4lconvert/ov518-decomp.c
3271d74d02e2f33c16e3e50aeb1268eb9c440782 - libv4lconvert/rgbyuv.c
725c9b8d0bfadba566cf200921e602961cb12705 - libv4lconvert/spca561-decompress.c
84c9c3812d4b5f237c8cd616d37fc1161a212acc - libv4lconvert/se401.c
b694b6348e035b3da880824c2c2768145c9b5199 - libv4lconvert/jpeg_memsrcdest.c
66dd7958319442bd52ba40ede28fbfe31bb4e074 - libv4lconvert/cpia1.c
6ad4947dca51a7e67e056561cdb445d6c354d23c - libv4lconvert/libv4lconvert.c
cc8982bb6f753249181c715fe6430ffefc78c23b - libv4lconvert/stv0680.c
72953a5a3a56b0188d35f49246356b9c8c35756c - libv4lconvert/helper.c
db3c69c666e451c5d4ef6d1b5a3117f4b128baa4 - libv4lconvert/libv4lconvert-priv.h
803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h
fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h
60e29f95ea52df4407d771330897813cdb38340f - libv4lconvert/libv4lsyscall-priv.h
fbbffd8182b4fe2e85289b6e784f70cba7ea7b1d - libv4lconvert/sq905c.c
4eff5c1a5e0b99ce4d6e9aa63645d9628467fdc3 - libv4lconvert/sn9c2028-decomp.c
22a502c238e48f4b939c81de41feccfc7c366766 - libv4lconvert/Makefile.dGPU
d6c1aba89bbcb6fef46a6f22b7ea01025435c44d - libv4lconvert/Makefile.am
be9e3bf3d7d1086b6eed0c1bf2f574c2b1737c00 - libv4lconvert/tinyjpeg.c
f061a4e0e45ca8e0dbab630dd477e19a6c915fda - libv4lconvert/spca501.c
07f8e7c84abfbbe76d49d8bfd1f4eae6ea39a90b - libv4lconvert/jpgl.c
1e08fb01a598d71e3fc69656c4f2291f7dc13105 - libv4lconvert/control/libv4lcontrol.h
70f4992835e964b2698473971904375333e3659b - libv4lconvert/control/libv4lcontrol-priv.h
19a7fd04cdeba61172f281806d030472dee79fcd - libv4lconvert/control/libv4lcontrol.c
0390d660eb130f0e580832bcf8ad5069010d2696 - libv4lconvert/processing/libv4lprocessing.h
7da402829dbff238ca6ac829c037a85476185db6 - libv4lconvert/processing/autogain.c
a54c2cb0439e606af01d0b4f02704f411819d98c - libv4lconvert/processing/libv4lprocessing.c
dae9c69b7f019d7d4494cd56e2cf757e8510824a - libv4lconvert/processing/whitebalance.c
33ab91b54108e8c24cbb80c5c335d96391d440b2 - libv4lconvert/processing/libv4lprocessing-priv.h
ebf12bcf99f35fb9c400b04a1439e68598268249 - libv4lconvert/processing/gamma.c
2835a7389ec7591d4ff4a6d552afe7d947548608 - libv4l2/libv4l2.c
b89578e115fc3704f6e4c0eb73eeea844788c10e - libv4l2/Makefile
2c6d79307968536d738adf5a70109eb77aee4faf - libv4l2/log.c
9d456d1772885d900865a8958c0291e13d509de5 - libv4l2/v4l2convert.c
cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in
766aaca553b0166eb736557e44ad42b69464aa53 - libv4l2/libv4l2.export
2542aabb7fbff4b1a09faaadec6006c4410a6d10 - libv4l2/libv4l2-priv.h
4ba98a607592ed0b8327b387af354544c65c9b67 - libv4l2/v4l2-plugin-android.c
ffecae84262f548deac1da0fa51f1aba6b6f96a0 - libv4l2/Makefile.dGPU
8e335567bf404eeb3d180dd384309f687f2ab944 - libv4l2/Makefile.am
e6516370c43e4869e05a540d2e4ef584ac64890a - libv4l2/v4l2-plugin.c

Change-Id: I3f0c60482ee0214dd1a16e1fc48c6890d39debcf
2024-05-02 11:24:37 -07:00

220 lines
5.8 KiB
C

/*
# (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, version 2.1,
# as published by the Free Software Foundation.
#
# 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 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;
size_t ret, written = 0;
while (written < count) {
ret = write(data->decompress_out_pipe[WRITE_END], buf + written,
count - written);
if ((int)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 ((int)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) {
close(data->decompress_out_pipe[WRITE_END]);
close(data->decompress_in_pipe[READ_END]);
waitpid(data->decompress_pid, &status, 0);
data->decompress_pid = -1;
}
}