aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android-config.h243
-rwxr-xr-xbootstrap.sh2
-rw-r--r--contrib/decode_tm6000/decode_tm6000.c2
-rw-r--r--contrib/freebsd/include/linux/v4l2-controls.h293
-rw-r--r--contrib/freebsd/include/linux/videodev2.h6
-rw-r--r--contrib/test/sliced-vbi-detect.c7
-rw-r--r--contrib/test/sliced-vbi-test.c8
-rwxr-xr-xcontrib/test/test-media6
-rw-r--r--contrib/test/v4l2grab.c482
-rw-r--r--include/linux/bpf.h76
-rw-r--r--include/linux/v4l2-controls.h293
-rw-r--r--include/linux/videodev2.h6
-rw-r--r--include/v4l-getsubopt.h259
-rw-r--r--lib/libdvbv5/dvb-dev-remote.c4
-rw-r--r--lib/libv4lconvert/Android.mk2
-rw-r--r--lib/libv4lconvert/Makefile.am2
-rw-r--r--lib/libv4lconvert/libv4lconvert-priv.h6
-rw-r--r--lib/libv4lconvert/libv4lconvert.c12
-rw-r--r--lib/libv4lconvert/nv12_16l16.c (renamed from lib/libv4lconvert/hm12.c)16
-rw-r--r--m4/ax_pthread.m4255
-rw-r--r--m4/visibility.m482
-rwxr-xr-xsync-with-kernel.sh2
-rw-r--r--utils/cec-compliance/cec-compliance.h1
-rw-r--r--utils/cec-compliance/cec-test-power.cpp2
-rw-r--r--utils/cec-compliance/cec-test.cpp5
-rw-r--r--utils/common/v4l2-pix-formats.h2
-rw-r--r--utils/cx18-ctl/cx18-ctl.c3
-rw-r--r--utils/ivtv-ctl/ivtv-ctl.c5
-rw-r--r--utils/libcecutil/cec-parse.cpp3
-rw-r--r--utils/qv4l2/capture-win.cpp23
-rw-r--r--utils/qv4l2/capture-win.h2
-rw-r--r--utils/qv4l2/qv4l2.cpp6
-rw-r--r--utils/rds-ctl/rds-ctl.cpp3
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.cpp33
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.h2
-rw-r--r--utils/v4l2-compliance/v4l2-test-buffers.cpp12
-rw-r--r--utils/v4l2-compliance/v4l2-test-controls.cpp28
-rw-r--r--utils/v4l2-compliance/v4l2-test-io-config.cpp2
-rw-r--r--utils/v4l2-compliance/v4l2-test-media.cpp49
-rw-r--r--utils/v4l2-compliance/v4l2-test-subdevs.cpp3
-rw-r--r--utils/v4l2-compliance/v4l2-test-time32-64.cpp4
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-common.cpp5
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-edid.cpp2
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-stds.cpp2
-rw-r--r--utils/v4l2-ctl/v4l2-ctl-streaming.cpp4
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.cpp6
-rw-r--r--utils/v4l2-ctl/v4l2-ctl.h1
-rw-r--r--utils/v4l2-dbg/v4l2-dbg.cpp3
48 files changed, 1775 insertions, 500 deletions
diff --git a/android-config.h b/android-config.h
index 9f12b8fc..bd4ef2fb 100644
--- a/android-config.h
+++ b/android-config.h
@@ -117,247 +117,4 @@
/* Define to `int' if <sys/types.h> does not define. */
/* #undef mode_t */
-/*
- * Import strchrnul(...) from uClibc version 0.9.33.2 since this feature is
- * missing in the Android C library.
- */
-
-/* Copyright (C) 1991,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
- with help from Dan Sahlin (dan@sics.se) and
- bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
- adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
- and implemented by Roland McGrath (roland@ai.mit.edu).
-
- The GNU C Library 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.
-
- The GNU C Library 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 the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <string.h>
-#include <stdlib.h>
-
-/* Find the first occurrence of C in S or the final NUL byte. */
-static inline char *strchrnul (const char *s, int c_in)
-{
- const unsigned char *char_ptr;
- const unsigned long int *longword_ptr;
- unsigned long int longword, magic_bits, charmask;
- unsigned char c;
-
- c = (unsigned char) c_in;
-
- /* Handle the first few characters by reading one character at a time.
- Do this until CHAR_PTR is aligned on a longword boundary. */
- for (char_ptr = (const unsigned char *) s;
- ((unsigned long int) char_ptr & (sizeof (longword) - 1)) != 0;
- ++char_ptr)
- if (*char_ptr == c || *char_ptr == '\0')
- return (char *) char_ptr;
-
- /* All these elucidatory comments refer to 4-byte longwords,
- but the theory applies equally well to 8-byte longwords. */
-
- longword_ptr = (unsigned long int *) char_ptr;
-
- /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
- the "holes." Note that there is a hole just to the left of
- each byte, with an extra at the end:
-
- bits: 01111110 11111110 11111110 11111111
- bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
-
- The 1-bits make sure that carries propagate to the next 0-bit.
- The 0-bits provide holes for carries to fall into. */
- switch (sizeof (longword))
- {
- case 4: magic_bits = 0x7efefeffL; break;
- case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
- default:
- abort ();
- }
-
- /* Set up a longword, each of whose bytes is C. */
- charmask = c | (c << 8);
- charmask |= charmask << 16;
- if (sizeof (longword) > 4)
- /* Do the shift in two steps to avoid a warning if long has 32 bits. */
- charmask |= (charmask << 16) << 16;
- if (sizeof (longword) > 8)
- abort ();
-
- /* Instead of the traditional loop which tests each character,
- we will test a longword at a time. The tricky part is testing
- if *any of the four* bytes in the longword in question are zero. */
- for (;;)
- {
- /* We tentatively exit the loop if adding MAGIC_BITS to
- LONGWORD fails to change any of the hole bits of LONGWORD.
-
- 1) Is this safe? Will it catch all the zero bytes?
- Suppose there is a byte with all zeros. Any carry bits
- propagating from its left will fall into the hole at its
- least significant bit and stop. Since there will be no
- carry from its most significant bit, the LSB of the
- byte to the left will be unchanged, and the zero will be
- detected.
-
- 2) Is this worthwhile? Will it ignore everything except
- zero bytes? Suppose every byte of LONGWORD has a bit set
- somewhere. There will be a carry into bit 8. If bit 8
- is set, this will carry into bit 16. If bit 8 is clear,
- one of bits 9-15 must be set, so there will be a carry
- into bit 16. Similarly, there will be a carry into bit
- 24. If one of bits 24-30 is set, there will be a carry
- into bit 31, so all of the hole bits will be changed.
-
- The one misfire occurs when bits 24-30 are clear and bit
- 31 is set; in this case, the hole at bit 31 is not
- changed. If we had access to the processor carry flag,
- we could close this loophole by putting the fourth hole
- at bit 32!
-
- So it ignores everything except 128's, when they're aligned
- properly.
-
- 3) But wait! Aren't we looking for C as well as zero?
- Good point. So what we do is XOR LONGWORD with a longword,
- each of whose bytes is C. This turns each byte that is C
- into a zero. */
-
- longword = *longword_ptr++;
-
- /* Add MAGIC_BITS to LONGWORD. */
- if ((((longword + magic_bits)
-
- /* Set those bits that were unchanged by the addition. */
- ^ ~longword)
-
- /* Look at only the hole bits. If any of the hole bits
- are unchanged, most likely one of the bytes was a
- zero. */
- & ~magic_bits) != 0 ||
-
- /* That caught zeroes. Now test for C. */
- ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
- & ~magic_bits) != 0)
- {
- /* Which of the bytes was C or zero?
- If none of them were, it was a misfire; continue the search. */
-
- const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
-
- if (*cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (sizeof (longword) > 4)
- {
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- if (*++cp == c || *cp == '\0')
- return (char *) cp;
- }
- }
- }
-
- /* This should never happen. */
- return NULL;
-}
-
-/*
- * Import getsubopt(...) from uClibc version 0.9.33.2 since this feature is
- * missing in the Android C library.
- */
-
-/* Parse comma separate list into words.
- Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-
- The GNU C Library 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.
-
- The GNU C Library 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 the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Parse comma separated suboption from *OPTIONP and match against
- strings in TOKENS. If found return index and set *VALUEP to
- optional value introduced by an equal sign. If the suboption is
- not part of TOKENS return in *VALUEP beginning of unknown
- suboption. On exit *OPTIONP is set to the beginning of the next
- token or at the terminating NUL character. */
-static inline int
-getsubopt (char **optionp, char *const *tokens, char **valuep)
-{
- char *endp, *vstart;
- int cnt;
-
- if (**optionp == '\0')
- return -1;
-
- /* Find end of next token. */
- endp = strchrnul (*optionp, ',');
-
- /* Find start of value. */
- vstart = (char *) memchr (*optionp, '=', endp - *optionp);
- if (vstart == NULL)
- vstart = endp;
-
- /* Try to match the characters between *OPTIONP and VSTART against
- one of the TOKENS. */
- for (cnt = 0; tokens[cnt] != NULL; ++cnt)
- if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0
- && tokens[cnt][vstart - *optionp] == '\0')
- {
- /* We found the current option in TOKENS. */
- *valuep = vstart != endp ? vstart + 1 : NULL;
-
- if (*endp != '\0')
- *endp++ = '\0';
- *optionp = endp;
-
- return cnt;
- }
-
- /* The current suboption does not match any option. */
- *valuep = *optionp;
-
- if (*endp != '\0')
- *endp++ = '\0';
- *optionp = endp;
-
- return -1;
-}
#endif
diff --git a/bootstrap.sh b/bootstrap.sh
index 0e9eb2d4..0ad344c3 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -4,7 +4,7 @@ mkdir build-aux/ 2>/dev/null
touch build-aux/config.rpath libdvbv5-po/Makefile.in.in v4l-utils-po/Makefile.in.in
autoreconf -vfi
-GETTEXTIZE=$(which gettextize)
+GETTEXTIZE=$(command -v gettextize)
if [ "GETTEXTIZE" != "" ]; then
VER=$(gettextize --version|perl -ne 'print $1 if (m/(\d\.\d.*)/)')
diff --git a/contrib/decode_tm6000/decode_tm6000.c b/contrib/decode_tm6000/decode_tm6000.c
index bd9b2dd4..564b22dc 100644
--- a/contrib/decode_tm6000/decode_tm6000.c
+++ b/contrib/decode_tm6000/decode_tm6000.c
@@ -250,7 +250,7 @@ int main (int argc, char*argv[])
{
int fd;
unsigned int i;
- unsigned char buf[TM6000_URB_MSG_LEN], img[720*2*480];
+ unsigned char buf[TM6000_URB_MSG_LEN], img[720*2*480] = {};
unsigned int cmd, size, field, block, line, pos=0;
unsigned long header=0;
int linesize=720*2,skip=0;
diff --git a/contrib/freebsd/include/linux/v4l2-controls.h b/contrib/freebsd/include/linux/v4l2-controls.h
index e44ea1cc..175e4169 100644
--- a/contrib/freebsd/include/linux/v4l2-controls.h
+++ b/contrib/freebsd/include/linux/v4l2-controls.h
@@ -132,6 +132,7 @@ enum v4l2_colorfx {
V4L2_COLORFX_SOLARIZATION = 13,
V4L2_COLORFX_ANTIQUE = 14,
V4L2_COLORFX_SET_CBCR = 15,
+ V4L2_COLORFX_SET_RGB = 16,
};
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
@@ -149,9 +150,10 @@ enum v4l2_colorfx {
#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
+#define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE+43)
/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+44)
/* USER-class private control IDs */
@@ -215,6 +217,11 @@ enum v4l2_colorfx {
* We reserve 128 controls for this driver.
*/
#define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0)
+/*
+ * The base for Allegro driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170)
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
@@ -2013,6 +2020,290 @@ struct v4l2_ctrl_hdr10_mastering_display {
__u32 min_display_mastering_luminance;
};
+/* Stateless VP9 controls */
+
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2
+
+/**
+ * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
+ *
+ * @ref_deltas: contains the adjustment needed for the filter level based on the
+ * chosen reference frame. If this syntax element is not present in the bitstream,
+ * users should pass its last value.
+ * @mode_deltas: contains the adjustment needed for the filter level based on the
+ * chosen mode. If this syntax element is not present in the bitstream, users should
+ * pass its last value.
+ * @level: indicates the loop filter strength.
+ * @sharpness: indicates the sharpness level.
+ * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * This structure contains all loop filter related parameters. See sections
+ * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_loop_filter {
+ __s8 ref_deltas[4];
+ __s8 mode_deltas[2];
+ __u8 level;
+ __u8 sharpness;
+ __u8 flags;
+ __u8 reserved[7];
+};
+
+/**
+ * struct v4l2_vp9_quantization - VP9 quantization parameters
+ *
+ * @base_q_idx: indicates the base frame qindex.
+ * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx.
+ * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx.
+ * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.9 Quantization params
+ * syntax' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_quantization {
+ __u8 base_q_idx;
+ __s8 delta_q_y_dc;
+ __s8 delta_q_uv_dc;
+ __s8 delta_q_uv_ac;
+ __u8 reserved[4];
+};
+
+#define V4L2_VP9_SEGMENTATION_FLAG_ENABLED 0x01
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x04
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA 0x08
+#define V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE 0x10
+
+#define V4L2_VP9_SEG_LVL_ALT_Q 0
+#define V4L2_VP9_SEG_LVL_ALT_L 1
+#define V4L2_VP9_SEG_LVL_REF_FRAME 2
+#define V4L2_VP9_SEG_LVL_SKIP 3
+#define V4L2_VP9_SEG_LVL_MAX 4
+
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) (1 << (id))
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK 0xf
+
+/**
+ * struct v4l2_vp9_segmentation - VP9 segmentation parameters
+ *
+ * @feature_data: data attached to each feature. Data entry is only valid if
+ * the feature is enabled. The array shall be indexed with segment number as
+ * the first dimension (0..7) and one of V4L2_VP9_SEG_{} as the second dimension.
+ * @feature_enabled: bitmask defining which features are enabled in each segment.
+ * The value for each segment is a combination of V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)
+ * values where id is one of V4L2_VP9_SEG_LVL_{}.
+ * @tree_probs: specifies the probability values to be used when decoding a
+ * Segment-ID. See '5.15. Segmentation map' section of the VP9 specification
+ * for more details.
+ * @pred_probs: specifies the probability values to be used when decoding a
+ * Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section of :ref:`vp9`
+ * for more details.
+ * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.10 Segmentation params syntax' of
+ * the VP9 specification for more details.
+ */
+struct v4l2_vp9_segmentation {
+ __s16 feature_data[8][4];
+ __u8 feature_enabled[8];
+ __u8 tree_probs[7];
+ __u8 pred_probs[3];
+ __u8 flags;
+ __u8 reserved[5];
+};
+
+#define V4L2_VP9_FRAME_FLAG_KEY_FRAME 0x001
+#define V4L2_VP9_FRAME_FLAG_SHOW_FRAME 0x002
+#define V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT 0x004
+#define V4L2_VP9_FRAME_FLAG_INTRA_ONLY 0x008
+#define V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV 0x010
+#define V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX 0x020
+#define V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE 0x040
+#define V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING 0x080
+#define V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING 0x100
+#define V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING 0x200
+
+#define V4L2_VP9_SIGN_BIAS_LAST 0x1
+#define V4L2_VP9_SIGN_BIAS_GOLDEN 0x2
+#define V4L2_VP9_SIGN_BIAS_ALT 0x4
+
+#define V4L2_VP9_RESET_FRAME_CTX_NONE 0
+#define V4L2_VP9_RESET_FRAME_CTX_SPEC 1
+#define V4L2_VP9_RESET_FRAME_CTX_ALL 2
+
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP 0
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH 1
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP 2
+#define V4L2_VP9_INTERP_FILTER_BILINEAR 3
+#define V4L2_VP9_INTERP_FILTER_SWITCHABLE 4
+
+#define V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE 0
+#define V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE 1
+#define V4L2_VP9_REFERENCE_MODE_SELECT 2
+
+#define V4L2_VP9_PROFILE_MAX 3
+
+#define V4L2_CID_STATELESS_VP9_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 300)
+/**
+ * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
+ *
+ * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details.
+ * @quant: quantization parameters. See &v4l2_vp9_quantization for more details.
+ * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details.
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_{} flags.
+ * @compressed_header_size: compressed header size in bytes.
+ * @uncompressed_header_size: uncompressed header size in bytes.
+ * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed in pixels.
+ * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed in pixels.
+ * @render_width_minus_1: add 1 to it and you'll get the expected render width expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @render_height_minus_1: add 1 to it and you'll get the expected render height expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @last_frame_ts: "last" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @golden_frame_ts: "golden" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @alt_frame_ts: "alt" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set for a given
+ * reference frame. Either of V4L2_VP9_SIGN_BIAS_{}.
+ * @reset_frame_context: specifies whether the frame context should be reset to default values.
+ * Either of V4L2_VP9_RESET_FRAME_CTX_{}.
+ * @frame_context_idx: frame context that should be used/updated.
+ * @profile: VP9 profile. Can be 0, 1, 2 or 3.
+ * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all profiles support
+ * 10 and/or 12 bits depths.
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ * Set to one of V4L2_VP9_INTERP_FILTER_{}.
+ * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile (where the width
+ * is measured in units of 8x8 blocks). Shall be less than or equal to 6.
+ * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile (where the height
+ * is measured in units of 8x8 blocks).
+ * @reference_mode: specifies the type of inter prediction to be used.
+ * Set to one of V4L2_VP9_REFERENCE_MODE_{}.
+ * @reserved: padding field. Should be zeroed by applications.
+ */
+struct v4l2_ctrl_vp9_frame {
+ struct v4l2_vp9_loop_filter lf;
+ struct v4l2_vp9_quantization quant;
+ struct v4l2_vp9_segmentation seg;
+ __u32 flags;
+ __u16 compressed_header_size;
+ __u16 uncompressed_header_size;
+ __u16 frame_width_minus_1;
+ __u16 frame_height_minus_1;
+ __u16 render_width_minus_1;
+ __u16 render_height_minus_1;
+ __u64 last_frame_ts;
+ __u64 golden_frame_ts;
+ __u64 alt_frame_ts;
+ __u8 ref_frame_sign_bias;
+ __u8 reset_frame_context;
+ __u8 frame_context_idx;
+ __u8 profile;
+ __u8 bit_depth;
+ __u8 interpolation_filter;
+ __u8 tile_cols_log2;
+ __u8 tile_rows_log2;
+ __u8 reference_mode;
+ __u8 reserved[7];
+};
+
+#define V4L2_VP9_NUM_FRAME_CTX 4
+
+/**
+ * struct v4l2_vp9_mv_probs - VP9 Motion vector probability updates
+ * @joint: motion vector joint probability updates.
+ * @sign: motion vector sign probability updates.
+ * @classes: motion vector class probability updates.
+ * @class0_bit: motion vector class0 bit probability updates.
+ * @bits: motion vector bits probability updates.
+ * @class0_fr: motion vector class0 fractional bit probability updates.
+ * @fr: motion vector fractional bit probability updates.
+ * @class0_hp: motion vector class0 high precision fractional bit probability updates.
+ * @hp: motion vector high precision fractional bit probability updates.
+ *
+ * This structure contains new values of motion vector probabilities.
+ * A value of zero in an array element means there is no update of the relevant probability.
+ * See `struct v4l2_vp9_prob_updates` for details.
+ */
+struct v4l2_vp9_mv_probs {
+ __u8 joint[3];
+ __u8 sign[2];
+ __u8 classes[2][10];
+ __u8 class0_bit[2];
+ __u8 bits[2][10];
+ __u8 class0_fr[2][2][3];
+ __u8 fr[2][3];
+ __u8 class0_hp[2];
+ __u8 hp[2];
+};
+
+#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (V4L2_CID_CODEC_STATELESS_BASE + 301)
+
+#define V4L2_VP9_TX_MODE_ONLY_4X4 0
+#define V4L2_VP9_TX_MODE_ALLOW_8X8 1
+#define V4L2_VP9_TX_MODE_ALLOW_16X16 2
+#define V4L2_VP9_TX_MODE_ALLOW_32X32 3
+#define V4L2_VP9_TX_MODE_SELECT 4
+
+/**
+ * struct v4l2_ctrl_vp9_compressed_hdr - VP9 probability updates control
+ * @tx_mode: specifies the TX mode. Set to one of V4L2_VP9_TX_MODE_{}.
+ * @tx8: TX 8x8 probability updates.
+ * @tx16: TX 16x16 probability updates.
+ * @tx32: TX 32x32 probability updates.
+ * @coef: coefficient probability updates.
+ * @skip: skip probability updates.
+ * @inter_mode: inter mode probability updates.
+ * @interp_filter: interpolation filter probability updates.
+ * @is_inter: is inter-block probability updates.
+ * @comp_mode: compound prediction mode probability updates.
+ * @single_ref: single ref probability updates.
+ * @comp_ref: compound ref probability updates.
+ * @y_mode: Y prediction mode probability updates.
+ * @uv_mode: UV prediction mode probability updates.
+ * @partition: partition probability updates.
+ * @mv: motion vector probability updates.
+ *
+ * This structure holds the probabilities update as parsed in the compressed
+ * header (Spec 6.3). These values represent the value of probability update after
+ * being translated with inv_map_table[] (see 6.3.5). A value of zero in an array element
+ * means that there is no update of the relevant probability.
+ *
+ * This control is optional and needs to be used when dealing with the hardware which is
+ * not capable of parsing the compressed header itself. Only drivers which need it will
+ * implement it.
+ */
+struct v4l2_ctrl_vp9_compressed_hdr {
+ __u8 tx_mode;
+ __u8 tx8[2][1];
+ __u8 tx16[2][2];
+ __u8 tx32[2][3];
+ __u8 coef[4][2][2][6][6][3];
+ __u8 skip[3];
+ __u8 inter_mode[7][3];
+ __u8 interp_filter[4][2];
+ __u8 is_inter[4];
+ __u8 comp_mode[5];
+ __u8 single_ref[5][2];
+ __u8 comp_ref[5];
+ __u8 y_mode[4][9];
+ __u8 uv_mode[10][9];
+ __u8 partition[16][3];
+
+ struct v4l2_vp9_mv_probs mv;
+};
+
/* MPEG-compression definitions kept for backwards compatibility */
#define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC
#define V4L2_CID_MPEG_CLASS V4L2_CID_CODEC_CLASS
diff --git a/contrib/freebsd/include/linux/videodev2.h b/contrib/freebsd/include/linux/videodev2.h
index 27411eb3..5fcaefd0 100644
--- a/contrib/freebsd/include/linux/videodev2.h
+++ b/contrib/freebsd/include/linux/videodev2.h
@@ -731,6 +731,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed frame */
#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
+#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed frame */
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
@@ -1764,6 +1765,8 @@ struct v4l2_ext_control {
struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
+ struct v4l2_ctrl_vp9_compressed_hdr *p_vp9_compressed_hdr_probs;
+ struct v4l2_ctrl_vp9_frame *p_vp9_frame;
void *ptr;
};
} __attribute__ ((packed));
@@ -1824,6 +1827,9 @@ enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250,
V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251,
V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
+
+ V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
+ V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
};
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
diff --git a/contrib/test/sliced-vbi-detect.c b/contrib/test/sliced-vbi-detect.c
index b3c49539..83df966d 100644
--- a/contrib/test/sliced-vbi-detect.c
+++ b/contrib/test/sliced-vbi-detect.c
@@ -26,19 +26,12 @@
*/
#include <unistd.h>
-#include <features.h> /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <inttypes.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <math.h>
#include <linux/videodev2.h>
diff --git a/contrib/test/sliced-vbi-test.c b/contrib/test/sliced-vbi-test.c
index 47fec05e..5dee9053 100644
--- a/contrib/test/sliced-vbi-test.c
+++ b/contrib/test/sliced-vbi-test.c
@@ -24,19 +24,13 @@
*/
#include <unistd.h>
-#include <features.h> /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <inttypes.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdint.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <math.h>
#include <linux/videodev2.h>
diff --git a/contrib/test/test-media b/contrib/test/test-media
index 4f453557..b928c39f 100755
--- a/contrib/test/test-media
+++ b/contrib/test/test-media
@@ -187,7 +187,7 @@ fi
rmmod vivid 2&>/dev/null
modprobe vivid n_devs=3 multiplanar=1,2,2 cache_hints=1,0,0 #allocators=0,1,1
-sleep 1
+sleep 3
tmp=`mktemp`
@@ -314,8 +314,8 @@ if [ $vivid -eq 1 -a $setup -eq 0 ]; then
echo
fi
- modprobe vivid n_devs=3 multiplanar=1,2,2 #allocators=0,1,1
- sleep 1
+ modprobe vivid n_devs=3 multiplanar=1,2,2 cache_hints=1,0,0 #allocators=0,1,1
+ sleep 3
$v4l2_ctl -z platform:vivid-002 -d vivid-002-vid-cap -i3 -v width=3840,height=2160,pixelformat=NV24
$v4l2_ctl -z platform:vivid-002 -d vivid-002-vid-out -o1 -x width=3840,height=2160,pixelformat=NM16
diff --git a/contrib/test/v4l2grab.c b/contrib/test/v4l2grab.c
index aab76927..a19f7196 100644
--- a/contrib/test/v4l2grab.c
+++ b/contrib/test/v4l2grab.c
@@ -30,6 +30,8 @@
#define CLEAR_P(x,s) memset((x), 0, s)
#define CLEAR(x) CLEAR_P(&(x), sizeof(x))
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*a))
+
static int libv4l = 1;
static int ppm_output = 1;
@@ -63,6 +65,101 @@ static void xioctl(int fh, unsigned long int request, void *arg)
}
}
+struct video_formats {
+ unsigned int pixformat;
+ unsigned int depth;
+ unsigned int y_decimation;
+ unsigned int x_decimation;
+
+ unsigned int is_rgb:1;
+};
+
+struct colorspace_parms {
+ enum v4l2_colorspace colorspace;
+ enum v4l2_xfer_func xfer_func;
+ enum v4l2_ycbcr_encoding ycbcr_enc;
+ enum v4l2_quantization quantization;
+};
+
+static const struct video_formats supported_formats[] = {
+ { V4L2_PIX_FMT_BGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_ABGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_XBGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_ARGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_XRGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_BGR24, 24, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB24, 24, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB565, 16, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB565X, 16, 0, 0, 1},
+ { V4L2_PIX_FMT_YUYV, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_UYVY, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_YVYU, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_VYUY, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_NV12, 8, 1, 0, 0},
+ { V4L2_PIX_FMT_NV21, 8, 1, 0, 0},
+ { V4L2_PIX_FMT_YUV420, 8, 1, 1, 0},
+ { V4L2_PIX_FMT_YVU420, 8, 1, 1, 0},
+};
+
+static const struct video_formats *video_fmt_props(unsigned int pixformat)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(supported_formats); i++)
+ if (supported_formats[i].pixformat == pixformat)
+ return &supported_formats[i];
+
+ return NULL;
+}
+
+static int is_format_supported(unsigned int pixformat)
+{
+ if (video_fmt_props(pixformat))
+ return 1;
+ return 0;
+}
+
+static void get_colorspace_data(struct colorspace_parms *c,
+ struct v4l2_format *fmt)
+{
+ const struct video_formats *video_fmt;
+
+ memset(c, 0, sizeof(*c));
+
+ video_fmt = video_fmt_props(fmt->fmt.pix.pixelformat);
+ if (!video_fmt)
+ return;
+
+ /*
+ * A more complete colorspace default detection would need to
+ * implement timings API, in order to check for SDTV/HDTV.
+ */
+ if (fmt->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT)
+ c->colorspace = video_fmt->is_rgb ?
+ V4L2_COLORSPACE_SRGB :
+ V4L2_COLORSPACE_REC709;
+ else
+ c->colorspace = fmt->fmt.pix.colorspace;
+
+ if (fmt->fmt.pix.xfer_func == V4L2_XFER_FUNC_DEFAULT)
+ c->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(c->colorspace);
+ else
+ c->xfer_func = fmt->fmt.pix.xfer_func;
+
+ if (!video_fmt->is_rgb) {
+ if (fmt->fmt.pix.ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
+ c->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(c->colorspace);
+ else
+ c->ycbcr_enc = fmt->fmt.pix.ycbcr_enc;
+ }
+
+ if (fmt->fmt.pix.quantization == V4L2_QUANTIZATION_DEFAULT)
+ c->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(video_fmt->is_rgb,
+ c->colorspace,
+ c->ycbcr_enc);
+}
+
/*
* Querycap implementation
*/
@@ -185,12 +282,238 @@ static void querycap(char *fname, int fd, enum io_method method)
}
}
+#define CLAMP(a) ((a) < 0 ? 0 : (a) > 255 ? 255 : (a))
+
+static void convert_yuv(struct colorspace_parms *c,
+ int32_t y, int32_t u, int32_t v,
+ unsigned char **dst)
+{
+ if (c->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ y *= 65536;
+ else
+ y = (y - 16) * 76284;
+
+ u -= 128;
+ v -= 128;
+
+ /*
+ * TODO: add BT2020 and SMPTE240M and better handle
+ * other differences
+ */
+ switch (c->ycbcr_enc) {
+ case V4L2_YCBCR_ENC_601:
+ case V4L2_YCBCR_ENC_XV601:
+ case V4L2_YCBCR_ENC_SYCC:
+ /*
+ * ITU-R BT.601 matrix:
+ * R = 1.164 * y + 0.0 * u + 1.596 * v
+ * G = 1.164 * y + -0.392 * u + -0.813 * v
+ * B = 1.164 * y + 2.017 * u + 0.0 * v
+ */
+ *(*dst)++ = CLAMP((y + 104595 * v) >> 16);
+ *(*dst)++ = CLAMP((y - 25690 * u - 53281 * v) >> 16);
+ *(*dst)++ = CLAMP((y + 132186 * u ) >> 16);
+ break;
+ default:
+ /*
+ * ITU-R BT.709 matrix:
+ * R = 1.164 * y + 0.0 * u + 1.793 * v
+ * G = 1.164 * y + -0.213 * u + -0.533 * v
+ * B = 1.164 * y + 2.112 * u + 0.0 * v
+ */
+ *(*dst)++ = CLAMP((y + 117506 * v) >> 16);
+ *(*dst)++ = CLAMP((y - 13959 * u - 34931 * v) >> 16);
+ *(*dst)++ = CLAMP((y + 138412 * u ) >> 16);
+ break;
+ }
+}
+
+static void copy_two_pixels(struct v4l2_format *fmt,
+ struct colorspace_parms *c,
+ unsigned char *plane0,
+ unsigned char *plane1,
+ unsigned char *plane2,
+ unsigned char **dst)
+{
+ uint32_t fourcc = fmt->fmt.pix.pixelformat;
+ int32_t y_off, u_off, u, v;
+ uint16_t pix;
+ int i;
+
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
+ for (i = 0; i < 2; i++) {
+ pix = (plane0[0] << 8) + plane0[1];
+
+ *(*dst)++ = (unsigned char)(((pix & 0xf800) >> 11) << 3) | 0x07;
+ *(*dst)++ = (unsigned char)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
+ *(*dst)++ = (unsigned char)((pix & 0x1f) << 3) | 0x07;
+
+ plane0 += 2;
+ }
+ break;
+ case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
+ for (i = 0; i < 2; i++) {
+ pix = (plane0[1] << 8) + plane0[0];
+
+ *(*dst)++ = (unsigned char)(((pix & 0xf800) >> 11) << 3) | 0x07;
+ *(*dst)++ = (unsigned char)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
+ *(*dst)++ = (unsigned char)((pix & 0x1f) << 3) | 0x07;
+
+ plane0 += 2;
+ }
+ break;
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ case V4L2_PIX_FMT_YVYU:
+ case V4L2_PIX_FMT_VYUY:
+ y_off = (fourcc == V4L2_PIX_FMT_YUYV || fourcc == V4L2_PIX_FMT_YVYU) ? 0 : 1;
+ u_off = (fourcc == V4L2_PIX_FMT_YUYV || fourcc == V4L2_PIX_FMT_UYVY) ? 0 : 2;
+
+ u = plane0[(1 - y_off) + u_off];
+ v = plane0[(1 - y_off) + (2 - u_off)];
+
+ for (i = 0; i < 2; i++)
+ convert_yuv(c, plane0[y_off + (i << 1)], u, v, dst);
+
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ if (fourcc == V4L2_PIX_FMT_NV12) {
+ u = plane1[0];
+ v = plane1[1];
+ } else {
+ u = plane1[1];
+ v = plane1[0];
+ }
+
+ for (i = 0; i < 2; i++)
+ convert_yuv(c, plane0[i], u, v, dst);
+
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ if (fourcc == V4L2_PIX_FMT_YUV420) {
+ u = plane1[0];
+ v = plane2[0];
+ } else {
+ u = plane2[0];
+ v = plane1[0];
+ }
+
+ for (i = 0; i < 2; i++)
+ convert_yuv(c, plane0[i], u, v, dst);
+
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ case V4L2_PIX_FMT_ARGB32:
+ case V4L2_PIX_FMT_XRGB32:
+ for (i = 0; i < 2; i++) {
+ *(*dst)++ = plane0[1];
+ *(*dst)++ = plane0[2];
+ *(*dst)++ = plane0[3];
+
+ plane0 += 4;
+ }
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ case V4L2_PIX_FMT_ABGR32:
+ case V4L2_PIX_FMT_XBGR32:
+ for (i = 0; i < 2; i++) {
+ *(*dst)++ = plane0[2];
+ *(*dst)++ = plane0[1];
+ *(*dst)++ = plane0[0];
+
+ plane0 += 4;
+ }
+ break;
+ default:
+ case V4L2_PIX_FMT_BGR24:
+ for (i = 0; i < 2; i++) {
+ *(*dst)++ = plane0[2];
+ *(*dst)++ = plane0[1];
+ *(*dst)++ = plane0[0];
+
+ plane0 += 3;
+ }
+ break;
+ }
+}
+
+static unsigned int convert_to_rgb24(struct v4l2_format *fmt,
+ unsigned char *plane0,
+ unsigned char *p_out)
+{
+ uint32_t width = fmt->fmt.pix.width;
+ uint32_t height = fmt->fmt.pix.height;
+ uint32_t bytesperline = fmt->fmt.pix.bytesperline;
+ const struct video_formats *video_fmt;
+ unsigned char *plane0_start = plane0;
+ unsigned char *plane1_start = NULL;
+ unsigned char *plane2_start = NULL;
+ unsigned char *plane1 = NULL;
+ unsigned char *plane2 = NULL;
+ struct colorspace_parms c;
+ unsigned int x, y, depth;
+ uint32_t num_planes = 1;
+ unsigned char *p_start;
+ uint32_t plane0_size;
+ uint32_t w_dec = 0;
+ uint32_t h_dec = 0;
+
+ get_colorspace_data(&c, fmt);
+
+ video_fmt = video_fmt_props(fmt->fmt.pix.pixelformat);
+ if (!video_fmt)
+ return 0;
+
+ depth = video_fmt->depth;
+ h_dec = video_fmt->y_decimation;
+ w_dec = video_fmt->x_decimation;
+
+ if (h_dec)
+ num_planes++;
+
+ if (w_dec)
+ num_planes++;
+
+ p_start = p_out;
+
+ if (num_planes > 1) {
+ plane0_size = (width * height * depth) >> 3;
+ plane1_start = plane0_start + plane0_size;
+ }
+
+ if (num_planes > 2)
+ plane2_start = plane1_start + (plane0_size >> (w_dec + h_dec));
+
+ for (y = 0; y < height; y++) {
+ plane0 = plane0_start + bytesperline * y;
+ if (num_planes > 1)
+ plane1 = plane1_start + (bytesperline >> w_dec) * (y >> h_dec);
+ if (num_planes > 2)
+ plane2 = plane2_start + (bytesperline >> w_dec) * (y >> h_dec);
+
+ for (x = 0; x < width >> 1; x++) {
+ copy_two_pixels(fmt, &c, plane0, plane1, plane2, &p_out);
+
+ plane0 += depth >> 2;
+ if (num_planes > 1)
+ plane1 += depth >> (2 + w_dec);
+ if (num_planes > 2)
+ plane2 += depth >> (2 + w_dec);
+ }
+ }
+
+ return p_out - p_start;
+}
+
/*
* Read I/O
*/
static int read_capture_loop(int fd, struct buffer *buffers,
struct v4l2_format *fmt, int n_frames,
- char *out_dir)
+ unsigned char *out_buf, char *out_dir)
{
unsigned int i;
struct timeval tv;
@@ -239,20 +562,29 @@ static int read_capture_loop(int fd, struct buffer *buffers,
fprintf(fout, "P6\n%d %d 255\n",
fmt->fmt.pix.width, fmt->fmt.pix.height);
- fwrite(buffers[0].start, size, 1, fout);
+ if (!ppm_output || !out_buf) {
+ out_buf = buffers[0].start;
+ } else {
+ size = convert_to_rgb24(fmt, buffers[0].start, out_buf);
+ }
+
+ fwrite(out_buf, size, 1, fout);
fclose(fout);
}
return 0;
}
-static int read_capture(int fd, int n_frames, char *out_dir,
- struct v4l2_format *fmt)
+static int read_capture(int fd, int n_frames, unsigned char *out_buf, char *out_dir,
+ struct v4l2_format *fmt, struct timeval *start)
{
struct buffer *buffers;
+ struct timezone tz = { 0 };
buffers = calloc(1, sizeof(*buffers));
- return read_capture_loop(fd, buffers, fmt, n_frames, out_dir);
+ gettimeofday(start, &tz);
+
+ return read_capture_loop(fd, buffers, fmt, n_frames, out_buf, out_dir);
}
/*
@@ -260,7 +592,7 @@ static int read_capture(int fd, int n_frames, char *out_dir,
*/
static int userptr_capture_loop(int fd, struct buffer *buffers,
int n_buffers, struct v4l2_format *fmt,
- int n_frames, char *out_dir)
+ int n_frames, unsigned char *out_buf, char *out_dir)
{
struct v4l2_buffer buf;
unsigned int i;
@@ -268,6 +600,7 @@ static int userptr_capture_loop(int fd, struct buffer *buffers,
int r;
fd_set fds;
FILE *fout;
+ unsigned int size;
char out_name[25 + strlen(out_dir)];
for (i = 0; i < n_frames; i++) {
@@ -307,7 +640,15 @@ static int userptr_capture_loop(int fd, struct buffer *buffers,
fprintf(fout, "P6\n%d %d 255\n",
fmt->fmt.pix.width, fmt->fmt.pix.height);
- fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
+ if (!ppm_output || !out_buf) {
+ out_buf = buffers[buf.index].start;
+ size = buf.bytesused;
+ } else {
+ size = convert_to_rgb24(fmt, buffers[buf.index].start,
+ out_buf);
+ }
+
+ fwrite(out_buf, size, 1, fout);
fclose(fout);
if (i + 1 < n_frames)
@@ -316,13 +657,14 @@ static int userptr_capture_loop(int fd, struct buffer *buffers,
return 0;
}
-static int userptr_capture(int fd, int n_frames, char *out_dir,
- struct v4l2_format *fmt)
+static int userptr_capture(int fd, int n_frames, unsigned char *out_buf, char *out_dir,
+ struct v4l2_format *fmt, struct timeval *start)
{
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
unsigned int ret, i, n_buffers;
struct buffer *buffers;
+ struct timezone tz = { 0 };
CLEAR(req);
req.count = 2;
@@ -336,6 +678,10 @@ static int userptr_capture(int fd, int n_frames, char *out_dir,
exit(EXIT_FAILURE);
}
+ /* Some compressed formats could return zero */
+ if (!fmt->fmt.pix.sizeimage)
+ fmt->fmt.pix.sizeimage = fmt->fmt.pix.width * fmt->fmt.pix.height * 3;
+
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
buffers[n_buffers].length = fmt->fmt.pix.sizeimage;
buffers[n_buffers].start = calloc(1, fmt->fmt.pix.sizeimage);
@@ -358,8 +704,10 @@ static int userptr_capture(int fd, int n_frames, char *out_dir,
xioctl(fd, VIDIOC_STREAMON, &req.type);
+ gettimeofday(start, &tz);
+
ret = userptr_capture_loop(fd, buffers, req.count, fmt,
- n_frames, out_dir);
+ n_frames, out_buf, out_dir);
xioctl(fd, VIDIOC_STREAMOFF, &req.type);
@@ -438,10 +786,11 @@ static void *produce_buffer (void * p)
* this array and 'render' them */
static int mmap_capture_threads(int fd, struct buffer *buffers,
int bufpool_size, struct v4l2_format *fmt,
- int n_frames, char *out_dir, int sleep_ms)
+ int n_frames, unsigned char *out_buf, char *out_dir,
+ int sleep_ms)
{
struct v4l2_buffer buf;
- unsigned int i;
+ unsigned int i, size;
struct buffer_queue buf_queue;
pthread_t producer;
char out_name[25 + strlen(out_dir)];
@@ -495,7 +844,16 @@ static int mmap_capture_threads(int fd, struct buffer *buffers,
buf = buf_queue.buffers[buf_queue.read_pos %
buf_queue.buffers_size];
- fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
+
+ if (!ppm_output || !out_buf) {
+ out_buf = buffers[buf.index].start;
+ size = buf.bytesused;
+ } else {
+ size = convert_to_rgb24(fmt, buffers[buf.index].start,
+ out_buf);
+ }
+
+ fwrite(out_buf, size, 1, fout);
fclose(fout);
xioctl(fd, VIDIOC_QBUF, &buf);
@@ -515,12 +873,13 @@ static int mmap_capture_threads(int fd, struct buffer *buffers,
static int mmap_capture_loop(int fd, struct buffer *buffers,
struct v4l2_format *fmt, int n_frames,
- char *out_dir)
+ unsigned char *out_buf, char *out_dir)
{
struct v4l2_buffer buf;
unsigned int i;
struct timeval tv;
int r;
+ unsigned int size;
fd_set fds;
FILE *fout;
char out_name[25 + strlen(out_dir)];
@@ -560,7 +919,14 @@ static int mmap_capture_loop(int fd, struct buffer *buffers,
fprintf(fout, "P6\n%d %d 255\n",
fmt->fmt.pix.width, fmt->fmt.pix.height);
- fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
+ if (!out_buf) {
+ out_buf = buffers[buf.index].start;
+ size = buf.bytesused;
+ } else {
+ size = convert_to_rgb24(fmt, buffers[buf.index].start,
+ out_buf);
+ }
+ fwrite(out_buf, size, 1, fout);
fclose(fout);
if (i + 1 < n_frames)
@@ -569,15 +935,16 @@ static int mmap_capture_loop(int fd, struct buffer *buffers,
return 0;
}
-static int mmap_capture(int fd, int n_frames, char *out_dir,
- int threads, int sleep_ms,
- struct v4l2_format *fmt)
+static int mmap_capture(int fd, int n_frames, unsigned char *out_buf,
+ char *out_dir, int threads, int sleep_ms,
+ struct v4l2_format *fmt, struct timeval *start)
{
struct v4l2_buffer buf;
struct v4l2_requestbuffers req;
enum v4l2_buf_type type;
unsigned int i, n_buffers;
struct buffer *buffers;
+ struct timezone tz = { 0 };
CLEAR(req);
req.count = 2;
@@ -626,11 +993,14 @@ static int mmap_capture(int fd, int n_frames, char *out_dir,
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);
+
+ gettimeofday(start, &tz);
+
if (threads)
- mmap_capture_threads(fd, buffers, 2, fmt, n_frames, out_dir,
- sleep_ms);
+ mmap_capture_threads(fd, buffers, 2, fmt, n_frames, out_buf,
+ out_dir, sleep_ms);
else
- mmap_capture_loop(fd, buffers, fmt, n_frames, out_dir);
+ mmap_capture_loop(fd, buffers, fmt, n_frames, out_buf, out_dir);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF, &type);
@@ -662,6 +1032,7 @@ static const struct argp_option options[] = {
{"yres", 'y', "YRES", 0, "vertical resolution", 0},
{"fourcc", 'f', "FOURCC", 0, "Linux fourcc code", 0},
{"userptr", 'u', NULL, 0, "Use user-defined memory capture method", 0},
+ {"raw", 'R', NULL, 0, "Save image in raw mode", 0},
{"read", 'r', NULL, 0, "Use read capture method", 0},
{"n-frames", 'n', "NFRAMES", 0, "number of frames to capture", 0},
{"thread-enable", 't', "THREADS", 0, "if different threads should capture and save", 0},
@@ -679,6 +1050,7 @@ static int n_frames = 20;
static int threads = 0;
static int block = 0;
static int sleep_ms = 0;
+static int raw_mode = 0;
static uint32_t fourcc = V4L2_PIX_FMT_RGB24;
enum io_method method = IO_METHOD_MMAP;
@@ -733,6 +1105,9 @@ static error_t parse_opt(int k, char *arg, struct argp_state *state)
case 'r':
method = IO_METHOD_READ;
break;
+ case 'R':
+ raw_mode = 1;
+ break;
case 's':
val = atoi(arg);
if (val)
@@ -750,11 +1125,29 @@ static struct argp argp = {
.doc = doc,
};
+static int elapsed_time(struct timeval *x, struct timeval *y)
+{
+ long int res;
+ int nsec;
+
+ nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+ y->tv_usec -= 1000000 * nsec;
+ y->tv_sec += nsec;
+
+ res = (x->tv_sec - y->tv_sec) * 1000000;
+ res += x->tv_usec - y->tv_usec;
+
+ return res;
+}
int main(int argc, char **argv)
{
struct v4l2_format fmt;
int ret = EXIT_FAILURE, fd = -1;
+ unsigned char *out_buf = NULL;
+ struct timezone tz = { 0 };
+ struct timeval start, end;
+ long int elapsed;
argp_parse(&argp, argc, argv, 0, 0, 0);
@@ -786,13 +1179,29 @@ int main(int argc, char **argv)
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
xioctl(fd, VIDIOC_S_FMT, &fmt);
- if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
- if (libv4l) {
- printf("Libv4l didn't accept RGB24 format. Can't proceed.\n");
- exit(EXIT_FAILURE);
+ if (raw_mode) {
+ printf("Raw mode: libv4l won't be used.\n");
+
+ libv4l = 0;
+ ppm_output = 0;
+ } else {
+ if (is_format_supported(fmt.fmt.pix.pixelformat)) {
+ out_buf = malloc(3 * x_res * y_res);
+ if (!out_buf) {
+ perror("Cannot allocate memory");
+ exit(EXIT_FAILURE);
+ }
} else {
- printf("File output won't be in PPM format.\n");
- ppm_output = 0;
+ /* Unknown formats */
+ if (libv4l) {
+ char *p = (void *)&fmt.fmt.pix.pixelformat;
+ printf("Doesn't know how to convert %c%c%c%c to PPM.\n",
+ p[0], p[1], p[2], p[3]);
+ exit(EXIT_FAILURE);
+ } else {
+ printf("File output won't be in PPM format.\n");
+ ppm_output = 0;
+ }
}
}
if ((fmt.fmt.pix.width != x_res) || (fmt.fmt.pix.height != y_res))
@@ -802,17 +1211,28 @@ int main(int argc, char **argv)
/* Calls the desired capture method */
switch (method) {
case IO_METHOD_READ:
- ret = read_capture(fd, n_frames, out_dir, &fmt);
+ ret = read_capture(fd, n_frames, out_buf, out_dir,
+ &fmt, &start);
break;
case IO_METHOD_MMAP:
- ret = mmap_capture(fd, n_frames, out_dir,
- threads, sleep_ms, &fmt);
+ ret = mmap_capture(fd, n_frames, out_buf, out_dir,
+ threads, sleep_ms, &fmt, &start);
break;
case IO_METHOD_USERPTR:
- ret = userptr_capture(fd, n_frames, out_dir, &fmt);
+ ret = userptr_capture(fd, n_frames, out_buf, out_dir, &fmt,
+ &start);
break;
}
+ if (!ret) {
+ gettimeofday(&end, &tz);
+
+ elapsed = elapsed_time(&end, &start);
+
+ printf("Received %d frames in %.2f seconds: %.2f fps\n",
+ n_frames, elapsed / 1000000., 1000000. * n_frames/ elapsed);
+ }
+
/* Closes the file descriptor */
if (libv4l)
v4l2_close(fd);
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 177cdc57..0c3a514a 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -906,6 +906,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_RINGBUF,
BPF_MAP_TYPE_INODE_STORAGE,
BPF_MAP_TYPE_TASK_STORAGE,
+ BPF_MAP_TYPE_BLOOM_FILTER,
};
/* Note that tracing related programs such as
@@ -1274,6 +1275,13 @@ union bpf_attr {
* struct stored as the
* map value
*/
+ /* Any per-map-type extra fields
+ *
+ * BPF_MAP_TYPE_BLOOM_FILTER - the lowest 4 bits indicate the
+ * number of hash functions (if 0, the bloom filter will default
+ * to using 5 hash functions).
+ */
+ __u64 map_extra;
};
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
@@ -1629,7 +1637,7 @@ union bpf_attr {
* u32 bpf_get_smp_processor_id(void)
* Description
* Get the SMP (symmetric multiprocessing) processor id. Note that
- * all programs run with preemption disabled, which means that the
+ * all programs run with migration disabled, which means that the
* SMP processor id is stable during all the execution of the
* program.
* Return
@@ -4046,7 +4054,7 @@ union bpf_attr {
* arguments. The *data* are a **u64** array and corresponding format string
* values are stored in the array. For strings and pointers where pointees
* are accessed, only the pointer values are stored in the *data* array.
- * The *data_len* is the size of *data* in bytes.
+ * The *data_len* is the size of *data* in bytes - must be a multiple of 8.
*
* Formats **%s**, **%p{i,I}{4,6}** requires to read kernel memory.
* Reading kernel memory may fail due to either invalid address or
@@ -4751,7 +4759,8 @@ union bpf_attr {
* Each format specifier in **fmt** corresponds to one u64 element
* in the **data** array. For strings and pointers where pointees
* are accessed, only the pointer values are stored in the *data*
- * array. The *data_len* is the size of *data* in bytes.
+ * array. The *data_len* is the size of *data* in bytes - must be
+ * a multiple of 8.
*
* Formats **%s** and **%p{i,I}{4,6}** require to read kernel
* memory. Reading kernel memory may fail due to either invalid
@@ -4877,6 +4886,58 @@ union bpf_attr {
* Get the struct pt_regs associated with **task**.
* Return
* A pointer to struct pt_regs.
+ *
+ * long bpf_get_branch_snapshot(void *entries, u32 size, u64 flags)
+ * Description
+ * Get branch trace from hardware engines like Intel LBR. The
+ * hardware engine is stopped shortly after the helper is
+ * called. Therefore, the user need to filter branch entries
+ * based on the actual use case. To capture branch trace
+ * before the trigger point of the BPF program, the helper
+ * should be called at the beginning of the BPF program.
+ *
+ * The data is stored as struct perf_branch_entry into output
+ * buffer *entries*. *size* is the size of *entries* in bytes.
+ * *flags* is reserved for now and must be zero.
+ *
+ * Return
+ * On success, number of bytes written to *buf*. On error, a
+ * negative value.
+ *
+ * **-EINVAL** if *flags* is not zero.
+ *
+ * **-ENOENT** if architecture does not support branch records.
+ *
+ * long bpf_trace_vprintk(const char *fmt, u32 fmt_size, const void *data, u32 data_len)
+ * Description
+ * Behaves like **bpf_trace_printk**\ () helper, but takes an array of u64
+ * to format and can handle more format args as a result.
+ *
+ * Arguments are to be used as in **bpf_seq_printf**\ () helper.
+ * Return
+ * The number of bytes written to the buffer, or a negative error
+ * in case of failure.
+ *
+ * struct unix_sock *bpf_skc_to_unix_sock(void *sk)
+ * Description
+ * Dynamically cast a *sk* pointer to a *unix_sock* pointer.
+ * Return
+ * *sk* if casting is valid, or **NULL** otherwise.
+ *
+ * long bpf_kallsyms_lookup_name(const char *name, int name_sz, int flags, u64 *res)
+ * Description
+ * Get the address of a kernel symbol, returned in *res*. *res* is
+ * set to 0 if the symbol is not found.
+ * Return
+ * On success, zero. On error, a negative value.
+ *
+ * **-EINVAL** if *flags* is not zero.
+ *
+ * **-EINVAL** if string *name* is not the same size as *name_sz*.
+ *
+ * **-ENOENT** if symbol is not found.
+ *
+ * **-EPERM** if caller does not have permission to obtain kernel address.
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -5055,6 +5116,10 @@ union bpf_attr {
FN(get_func_ip), \
FN(get_attach_cookie), \
FN(task_pt_regs), \
+ FN(get_branch_snapshot), \
+ FN(trace_vprintk), \
+ FN(skc_to_unix_sock), \
+ FN(kallsyms_lookup_name), \
/* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
@@ -5284,6 +5349,8 @@ struct __sk_buff {
__u32 gso_segs;
__bpf_md_ptr(struct bpf_sock *, sk);
__u32 gso_size;
+ __u32 :32; /* Padding, future use. */
+ __u64 hwtstamp;
};
struct bpf_tunnel_key {
@@ -5577,6 +5644,7 @@ struct bpf_prog_info {
__u64 run_time_ns;
__u64 run_cnt;
__u64 recursion_misses;
+ __u32 verified_insns;
} __attribute__((aligned(8)));
struct bpf_map_info {
@@ -5594,6 +5662,8 @@ struct bpf_map_info {
__u32 btf_id;
__u32 btf_key_type_id;
__u32 btf_value_type_id;
+ __u32 :32; /* alignment pad */
+ __u64 map_extra;
} __attribute__((aligned(8)));
struct bpf_btf_info {
diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h
index e44ea1cc..175e4169 100644
--- a/include/linux/v4l2-controls.h
+++ b/include/linux/v4l2-controls.h
@@ -132,6 +132,7 @@ enum v4l2_colorfx {
V4L2_COLORFX_SOLARIZATION = 13,
V4L2_COLORFX_ANTIQUE = 14,
V4L2_COLORFX_SET_CBCR = 15,
+ V4L2_COLORFX_SET_RGB = 16,
};
#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
@@ -149,9 +150,10 @@ enum v4l2_colorfx {
#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41)
#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42)
+#define V4L2_CID_COLORFX_RGB (V4L2_CID_BASE+43)
/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+44)
/* USER-class private control IDs */
@@ -215,6 +217,11 @@ enum v4l2_colorfx {
* We reserve 128 controls for this driver.
*/
#define V4L2_CID_USER_CCS_BASE (V4L2_CID_USER_BASE + 0x10f0)
+/*
+ * The base for Allegro driver controls.
+ * We reserve 16 controls for this driver.
+ */
+#define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170)
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
@@ -2013,6 +2020,290 @@ struct v4l2_ctrl_hdr10_mastering_display {
__u32 min_display_mastering_luminance;
};
+/* Stateless VP9 controls */
+
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED 0x1
+#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE 0x2
+
+/**
+ * struct v4l2_vp9_loop_filter - VP9 loop filter parameters
+ *
+ * @ref_deltas: contains the adjustment needed for the filter level based on the
+ * chosen reference frame. If this syntax element is not present in the bitstream,
+ * users should pass its last value.
+ * @mode_deltas: contains the adjustment needed for the filter level based on the
+ * chosen mode. If this syntax element is not present in the bitstream, users should
+ * pass its last value.
+ * @level: indicates the loop filter strength.
+ * @sharpness: indicates the sharpness level.
+ * @flags: combination of V4L2_VP9_LOOP_FILTER_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * This structure contains all loop filter related parameters. See sections
+ * '7.2.8 Loop filter semantics' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_loop_filter {
+ __s8 ref_deltas[4];
+ __s8 mode_deltas[2];
+ __u8 level;
+ __u8 sharpness;
+ __u8 flags;
+ __u8 reserved[7];
+};
+
+/**
+ * struct v4l2_vp9_quantization - VP9 quantization parameters
+ *
+ * @base_q_idx: indicates the base frame qindex.
+ * @delta_q_y_dc: indicates the Y DC quantizer relative to base_q_idx.
+ * @delta_q_uv_dc: indicates the UV DC quantizer relative to base_q_idx.
+ * @delta_q_uv_ac: indicates the UV AC quantizer relative to base_q_idx.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.9 Quantization params
+ * syntax' of the VP9 specification for more details.
+ */
+struct v4l2_vp9_quantization {
+ __u8 base_q_idx;
+ __s8 delta_q_y_dc;
+ __s8 delta_q_uv_dc;
+ __s8 delta_q_uv_ac;
+ __u8 reserved[4];
+};
+
+#define V4L2_VP9_SEGMENTATION_FLAG_ENABLED 0x01
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP 0x02
+#define V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE 0x04
+#define V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA 0x08
+#define V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE 0x10
+
+#define V4L2_VP9_SEG_LVL_ALT_Q 0
+#define V4L2_VP9_SEG_LVL_ALT_L 1
+#define V4L2_VP9_SEG_LVL_REF_FRAME 2
+#define V4L2_VP9_SEG_LVL_SKIP 3
+#define V4L2_VP9_SEG_LVL_MAX 4
+
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED(id) (1 << (id))
+#define V4L2_VP9_SEGMENT_FEATURE_ENABLED_MASK 0xf
+
+/**
+ * struct v4l2_vp9_segmentation - VP9 segmentation parameters
+ *
+ * @feature_data: data attached to each feature. Data entry is only valid if
+ * the feature is enabled. The array shall be indexed with segment number as
+ * the first dimension (0..7) and one of V4L2_VP9_SEG_{} as the second dimension.
+ * @feature_enabled: bitmask defining which features are enabled in each segment.
+ * The value for each segment is a combination of V4L2_VP9_SEGMENT_FEATURE_ENABLED(id)
+ * values where id is one of V4L2_VP9_SEG_LVL_{}.
+ * @tree_probs: specifies the probability values to be used when decoding a
+ * Segment-ID. See '5.15. Segmentation map' section of the VP9 specification
+ * for more details.
+ * @pred_probs: specifies the probability values to be used when decoding a
+ * Predicted-Segment-ID. See '6.4.14. Get segment id syntax' section of :ref:`vp9`
+ * for more details.
+ * @flags: combination of V4L2_VP9_SEGMENTATION_FLAG_{} flags.
+ * @reserved: padding field. Should be zeroed by applications.
+ *
+ * Encodes the quantization parameters. See section '7.2.10 Segmentation params syntax' of
+ * the VP9 specification for more details.
+ */
+struct v4l2_vp9_segmentation {
+ __s16 feature_data[8][4];
+ __u8 feature_enabled[8];
+ __u8 tree_probs[7];
+ __u8 pred_probs[3];
+ __u8 flags;
+ __u8 reserved[5];
+};
+
+#define V4L2_VP9_FRAME_FLAG_KEY_FRAME 0x001
+#define V4L2_VP9_FRAME_FLAG_SHOW_FRAME 0x002
+#define V4L2_VP9_FRAME_FLAG_ERROR_RESILIENT 0x004
+#define V4L2_VP9_FRAME_FLAG_INTRA_ONLY 0x008
+#define V4L2_VP9_FRAME_FLAG_ALLOW_HIGH_PREC_MV 0x010
+#define V4L2_VP9_FRAME_FLAG_REFRESH_FRAME_CTX 0x020
+#define V4L2_VP9_FRAME_FLAG_PARALLEL_DEC_MODE 0x040
+#define V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING 0x080
+#define V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING 0x100
+#define V4L2_VP9_FRAME_FLAG_COLOR_RANGE_FULL_SWING 0x200
+
+#define V4L2_VP9_SIGN_BIAS_LAST 0x1
+#define V4L2_VP9_SIGN_BIAS_GOLDEN 0x2
+#define V4L2_VP9_SIGN_BIAS_ALT 0x4
+
+#define V4L2_VP9_RESET_FRAME_CTX_NONE 0
+#define V4L2_VP9_RESET_FRAME_CTX_SPEC 1
+#define V4L2_VP9_RESET_FRAME_CTX_ALL 2
+
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP 0
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SMOOTH 1
+#define V4L2_VP9_INTERP_FILTER_EIGHTTAP_SHARP 2
+#define V4L2_VP9_INTERP_FILTER_BILINEAR 3
+#define V4L2_VP9_INTERP_FILTER_SWITCHABLE 4
+
+#define V4L2_VP9_REFERENCE_MODE_SINGLE_REFERENCE 0
+#define V4L2_VP9_REFERENCE_MODE_COMPOUND_REFERENCE 1
+#define V4L2_VP9_REFERENCE_MODE_SELECT 2
+
+#define V4L2_VP9_PROFILE_MAX 3
+
+#define V4L2_CID_STATELESS_VP9_FRAME (V4L2_CID_CODEC_STATELESS_BASE + 300)
+/**
+ * struct v4l2_ctrl_vp9_frame - VP9 frame decoding control
+ *
+ * @lf: loop filter parameters. See &v4l2_vp9_loop_filter for more details.
+ * @quant: quantization parameters. See &v4l2_vp9_quantization for more details.
+ * @seg: segmentation parameters. See &v4l2_vp9_segmentation for more details.
+ * @flags: combination of V4L2_VP9_FRAME_FLAG_{} flags.
+ * @compressed_header_size: compressed header size in bytes.
+ * @uncompressed_header_size: uncompressed header size in bytes.
+ * @frame_width_minus_1: add 1 to it and you'll get the frame width expressed in pixels.
+ * @frame_height_minus_1: add 1 to it and you'll get the frame height expressed in pixels.
+ * @render_width_minus_1: add 1 to it and you'll get the expected render width expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @render_height_minus_1: add 1 to it and you'll get the expected render height expressed in
+ * pixels. This is not used during the decoding process but might be used by HW scalers
+ * to prepare a frame that's ready for scanout.
+ * @last_frame_ts: "last" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @golden_frame_ts: "golden" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @alt_frame_ts: "alt" reference buffer timestamp.
+ * The timestamp refers to the timestamp field in struct v4l2_buffer.
+ * Use v4l2_timeval_to_ns() to convert the struct timeval to a __u64.
+ * @ref_frame_sign_bias: a bitfield specifying whether the sign bias is set for a given
+ * reference frame. Either of V4L2_VP9_SIGN_BIAS_{}.
+ * @reset_frame_context: specifies whether the frame context should be reset to default values.
+ * Either of V4L2_VP9_RESET_FRAME_CTX_{}.
+ * @frame_context_idx: frame context that should be used/updated.
+ * @profile: VP9 profile. Can be 0, 1, 2 or 3.
+ * @bit_depth: bits per components. Can be 8, 10 or 12. Note that not all profiles support
+ * 10 and/or 12 bits depths.
+ * @interpolation_filter: specifies the filter selection used for performing inter prediction.
+ * Set to one of V4L2_VP9_INTERP_FILTER_{}.
+ * @tile_cols_log2: specifies the base 2 logarithm of the width of each tile (where the width
+ * is measured in units of 8x8 blocks). Shall be less than or equal to 6.
+ * @tile_rows_log2: specifies the base 2 logarithm of the height of each tile (where the height
+ * is measured in units of 8x8 blocks).
+ * @reference_mode: specifies the type of inter prediction to be used.
+ * Set to one of V4L2_VP9_REFERENCE_MODE_{}.
+ * @reserved: padding field. Should be zeroed by applications.
+ */
+struct v4l2_ctrl_vp9_frame {
+ struct v4l2_vp9_loop_filter lf;
+ struct v4l2_vp9_quantization quant;
+ struct v4l2_vp9_segmentation seg;
+ __u32 flags;
+ __u16 compressed_header_size;
+ __u16 uncompressed_header_size;
+ __u16 frame_width_minus_1;
+ __u16 frame_height_minus_1;
+ __u16 render_width_minus_1;
+ __u16 render_height_minus_1;
+ __u64 last_frame_ts;
+ __u64 golden_frame_ts;
+ __u64 alt_frame_ts;
+ __u8 ref_frame_sign_bias;
+ __u8 reset_frame_context;
+ __u8 frame_context_idx;
+ __u8 profile;
+ __u8 bit_depth;
+ __u8 interpolation_filter;
+ __u8 tile_cols_log2;
+ __u8 tile_rows_log2;
+ __u8 reference_mode;
+ __u8 reserved[7];
+};
+
+#define V4L2_VP9_NUM_FRAME_CTX 4
+
+/**
+ * struct v4l2_vp9_mv_probs - VP9 Motion vector probability updates
+ * @joint: motion vector joint probability updates.
+ * @sign: motion vector sign probability updates.
+ * @classes: motion vector class probability updates.
+ * @class0_bit: motion vector class0 bit probability updates.
+ * @bits: motion vector bits probability updates.
+ * @class0_fr: motion vector class0 fractional bit probability updates.
+ * @fr: motion vector fractional bit probability updates.
+ * @class0_hp: motion vector class0 high precision fractional bit probability updates.
+ * @hp: motion vector high precision fractional bit probability updates.
+ *
+ * This structure contains new values of motion vector probabilities.
+ * A value of zero in an array element means there is no update of the relevant probability.
+ * See `struct v4l2_vp9_prob_updates` for details.
+ */
+struct v4l2_vp9_mv_probs {
+ __u8 joint[3];
+ __u8 sign[2];
+ __u8 classes[2][10];
+ __u8 class0_bit[2];
+ __u8 bits[2][10];
+ __u8 class0_fr[2][2][3];
+ __u8 fr[2][3];
+ __u8 class0_hp[2];
+ __u8 hp[2];
+};
+
+#define V4L2_CID_STATELESS_VP9_COMPRESSED_HDR (V4L2_CID_CODEC_STATELESS_BASE + 301)
+
+#define V4L2_VP9_TX_MODE_ONLY_4X4 0
+#define V4L2_VP9_TX_MODE_ALLOW_8X8 1
+#define V4L2_VP9_TX_MODE_ALLOW_16X16 2
+#define V4L2_VP9_TX_MODE_ALLOW_32X32 3
+#define V4L2_VP9_TX_MODE_SELECT 4
+
+/**
+ * struct v4l2_ctrl_vp9_compressed_hdr - VP9 probability updates control
+ * @tx_mode: specifies the TX mode. Set to one of V4L2_VP9_TX_MODE_{}.
+ * @tx8: TX 8x8 probability updates.
+ * @tx16: TX 16x16 probability updates.
+ * @tx32: TX 32x32 probability updates.
+ * @coef: coefficient probability updates.
+ * @skip: skip probability updates.
+ * @inter_mode: inter mode probability updates.
+ * @interp_filter: interpolation filter probability updates.
+ * @is_inter: is inter-block probability updates.
+ * @comp_mode: compound prediction mode probability updates.
+ * @single_ref: single ref probability updates.
+ * @comp_ref: compound ref probability updates.
+ * @y_mode: Y prediction mode probability updates.
+ * @uv_mode: UV prediction mode probability updates.
+ * @partition: partition probability updates.
+ * @mv: motion vector probability updates.
+ *
+ * This structure holds the probabilities update as parsed in the compressed
+ * header (Spec 6.3). These values represent the value of probability update after
+ * being translated with inv_map_table[] (see 6.3.5). A value of zero in an array element
+ * means that there is no update of the relevant probability.
+ *
+ * This control is optional and needs to be used when dealing with the hardware which is
+ * not capable of parsing the compressed header itself. Only drivers which need it will
+ * implement it.
+ */
+struct v4l2_ctrl_vp9_compressed_hdr {
+ __u8 tx_mode;
+ __u8 tx8[2][1];
+ __u8 tx16[2][2];
+ __u8 tx32[2][3];
+ __u8 coef[4][2][2][6][6][3];
+ __u8 skip[3];
+ __u8 inter_mode[7][3];
+ __u8 interp_filter[4][2];
+ __u8 is_inter[4];
+ __u8 comp_mode[5];
+ __u8 single_ref[5][2];
+ __u8 comp_ref[5];
+ __u8 y_mode[4][9];
+ __u8 uv_mode[10][9];
+ __u8 partition[16][3];
+
+ struct v4l2_vp9_mv_probs mv;
+};
+
/* MPEG-compression definitions kept for backwards compatibility */
#define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC
#define V4L2_CID_MPEG_CLASS V4L2_CID_CODEC_CLASS
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 8b61d775..0c90b942 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -697,6 +697,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') /* VP8 parsed frame */
#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
+#define V4L2_PIX_FMT_VP9_FRAME v4l2_fourcc('V', 'P', '9', 'F') /* VP9 parsed frame */
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') /* Stateless FWHT (vicodec) */
@@ -1730,6 +1731,8 @@ struct v4l2_ext_control {
struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quantisation;
+ struct v4l2_ctrl_vp9_compressed_hdr *p_vp9_compressed_hdr_probs;
+ struct v4l2_ctrl_vp9_frame *p_vp9_frame;
void *ptr;
};
} __attribute__ ((packed));
@@ -1790,6 +1793,9 @@ enum v4l2_ctrl_type {
V4L2_CTRL_TYPE_MPEG2_QUANTISATION = 0x0250,
V4L2_CTRL_TYPE_MPEG2_SEQUENCE = 0x0251,
V4L2_CTRL_TYPE_MPEG2_PICTURE = 0x0252,
+
+ V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR = 0x0260,
+ V4L2_CTRL_TYPE_VP9_FRAME = 0x0261,
};
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
diff --git a/include/v4l-getsubopt.h b/include/v4l-getsubopt.h
new file mode 100644
index 00000000..60e7b976
--- /dev/null
+++ b/include/v4l-getsubopt.h
@@ -0,0 +1,259 @@
+#ifndef __V4L_GETSUBOPT__
+#define __V4L_GETSUBOPT__
+
+/*
+ * Apparently non-glibc variants of getsubopt behave slightly
+ * differently, and on some OSes (Android) it is missing altogether.
+ * So add support for it here, if needed.
+ */
+
+#if defined(__GLIBC__)
+
+#define v4l_getsubopt getsubopt
+
+#else
+
+/*
+ * Import strchrnul(...) from uClibc version 0.9.33.2 since this feature is
+ * missing in the Android C library.
+ */
+
+/* Copyright (C) 1991,93,94,95,96,97,99,2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
+ with help from Dan Sahlin (dan@sics.se) and
+ bug fix and commentary by Jim Blandy (jimb@ai.mit.edu);
+ adaptation to strchr suggested by Dick Karpinski (dick@cca.ucsf.edu),
+ and implemented by Roland McGrath (roland@ai.mit.edu).
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <string.h>
+#include <stdlib.h>
+
+/* Find the first occurrence of C in S or the final NUL byte. */
+static inline char *v4l_strchrnul (const char *s, int c_in)
+{
+ const unsigned char *char_ptr;
+ const unsigned long int *longword_ptr;
+ unsigned long int longword, magic_bits, charmask;
+ unsigned char c;
+
+ c = (unsigned char) c_in;
+
+ /* Handle the first few characters by reading one character at a time.
+ Do this until CHAR_PTR is aligned on a longword boundary. */
+ for (char_ptr = (const unsigned char *) s;
+ ((unsigned long int) char_ptr & (sizeof (longword) - 1)) != 0;
+ ++char_ptr)
+ if (*char_ptr == c || *char_ptr == '\0')
+ return (char *) char_ptr;
+
+ /* All these elucidatory comments refer to 4-byte longwords,
+ but the theory applies equally well to 8-byte longwords. */
+
+ longword_ptr = (unsigned long int *) char_ptr;
+
+ /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits
+ the "holes." Note that there is a hole just to the left of
+ each byte, with an extra at the end:
+
+ bits: 01111110 11111110 11111110 11111111
+ bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
+
+ The 1-bits make sure that carries propagate to the next 0-bit.
+ The 0-bits provide holes for carries to fall into. */
+ switch (sizeof (longword))
+ {
+ case 4: magic_bits = 0x7efefeffL; break;
+ case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
+ default:
+ abort ();
+ }
+
+ /* Set up a longword, each of whose bytes is C. */
+ charmask = c | (c << 8);
+ charmask |= charmask << 16;
+ if (sizeof (longword) > 4)
+ /* Do the shift in two steps to avoid a warning if long has 32 bits. */
+ charmask |= (charmask << 16) << 16;
+ if (sizeof (longword) > 8)
+ abort ();
+
+ /* Instead of the traditional loop which tests each character,
+ we will test a longword at a time. The tricky part is testing
+ if *any of the four* bytes in the longword in question are zero. */
+ for (;;)
+ {
+ /* We tentatively exit the loop if adding MAGIC_BITS to
+ LONGWORD fails to change any of the hole bits of LONGWORD.
+
+ 1) Is this safe? Will it catch all the zero bytes?
+ Suppose there is a byte with all zeros. Any carry bits
+ propagating from its left will fall into the hole at its
+ least significant bit and stop. Since there will be no
+ carry from its most significant bit, the LSB of the
+ byte to the left will be unchanged, and the zero will be
+ detected.
+
+ 2) Is this worthwhile? Will it ignore everything except
+ zero bytes? Suppose every byte of LONGWORD has a bit set
+ somewhere. There will be a carry into bit 8. If bit 8
+ is set, this will carry into bit 16. If bit 8 is clear,
+ one of bits 9-15 must be set, so there will be a carry
+ into bit 16. Similarly, there will be a carry into bit
+ 24. If one of bits 24-30 is set, there will be a carry
+ into bit 31, so all of the hole bits will be changed.
+
+ The one misfire occurs when bits 24-30 are clear and bit
+ 31 is set; in this case, the hole at bit 31 is not
+ changed. If we had access to the processor carry flag,
+ we could close this loophole by putting the fourth hole
+ at bit 32!
+
+ So it ignores everything except 128's, when they're aligned
+ properly.
+
+ 3) But wait! Aren't we looking for C as well as zero?
+ Good point. So what we do is XOR LONGWORD with a longword,
+ each of whose bytes is C. This turns each byte that is C
+ into a zero. */
+
+ longword = *longword_ptr++;
+
+ /* Add MAGIC_BITS to LONGWORD. */
+ if ((((longword + magic_bits)
+
+ /* Set those bits that were unchanged by the addition. */
+ ^ ~longword)
+
+ /* Look at only the hole bits. If any of the hole bits
+ are unchanged, most likely one of the bytes was a
+ zero. */
+ & ~magic_bits) != 0 ||
+
+ /* That caught zeroes. Now test for C. */
+ ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
+ & ~magic_bits) != 0)
+ {
+ /* Which of the bytes was C or zero?
+ If none of them were, it was a misfire; continue the search. */
+
+ const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
+
+ if (*cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (sizeof (longword) > 4)
+ {
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ if (*++cp == c || *cp == '\0')
+ return (char *) cp;
+ }
+ }
+ }
+
+ /* This should never happen. */
+ return NULL;
+}
+
+/*
+ * Import getsubopt(...) from uClibc version 0.9.33.2 since this feature is
+ * missing in the Android C library.
+ */
+
+/* Parse comma separate list into words.
+ Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library 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.
+
+ The GNU C Library 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Parse comma separated suboption from *OPTIONP and match against
+ strings in TOKENS. If found return index and set *VALUEP to
+ optional value introduced by an equal sign. If the suboption is
+ not part of TOKENS return in *VALUEP beginning of unknown
+ suboption. On exit *OPTIONP is set to the beginning of the next
+ token or at the terminating NUL character. */
+static inline int
+v4l_getsubopt (char **optionp, char *const *tokens, char **valuep)
+{
+ char *endp, *vstart;
+ int cnt;
+
+ if (**optionp == '\0')
+ return -1;
+
+ /* Find end of next token. */
+ endp = v4l_strchrnul (*optionp, ',');
+
+ /* Find start of value. */
+ vstart = (char *) memchr (*optionp, '=', endp - *optionp);
+ if (vstart == NULL)
+ vstart = endp;
+
+ /* Try to match the characters between *OPTIONP and VSTART against
+ one of the TOKENS. */
+ for (cnt = 0; tokens[cnt] != NULL; ++cnt)
+ if (strncmp (*optionp, tokens[cnt], vstart - *optionp) == 0
+ && tokens[cnt][vstart - *optionp] == '\0')
+ {
+ /* We found the current option in TOKENS. */
+ *valuep = vstart != endp ? vstart + 1 : NULL;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return cnt;
+ }
+
+ /* The current suboption does not match any option. */
+ *valuep = *optionp;
+
+ if (*endp != '\0')
+ *endp++ = '\0';
+ *optionp = endp;
+
+ return -1;
+}
+
+#endif
+
+#endif
diff --git a/lib/libdvbv5/dvb-dev-remote.c b/lib/libdvbv5/dvb-dev-remote.c
index 3ef9d67c..cd783858 100644
--- a/lib/libdvbv5/dvb-dev-remote.c
+++ b/lib/libdvbv5/dvb-dev-remote.c
@@ -228,11 +228,11 @@ static ssize_t prepare_data(struct dvb_v5_fe_parms_priv *parms,
}
static struct queued_msg *send_fmt(struct dvb_device_priv *dvb, int fd,
- const char cmd[CMD_SIZE], const char *fmt, ...)
+ const char *cmd, const char *fmt, ...)
__attribute__ (( format( printf, 4, 5 )));
static struct queued_msg *send_fmt(struct dvb_device_priv *dvb, int fd,
- const char cmd[CMD_SIZE], const char *fmt, ...)
+ const char *cmd, const char *fmt, ...)
{
struct dvb_v5_fe_parms_priv *parms = (void *)dvb->d.fe_parms;
struct dvb_dev_remote_priv *priv = dvb->priv;
diff --git a/lib/libv4lconvert/Android.mk b/lib/libv4lconvert/Android.mk
index 99a136b4..a4e75c95 100644
--- a/lib/libv4lconvert/Android.mk
+++ b/lib/libv4lconvert/Android.mk
@@ -8,7 +8,7 @@ LOCAL_SRC_FILES := \
crop.c \
flip.c \
helper.c \
- hm12.c \
+ nv12_16l16.c \
jidctflt.c \
jl2005bcd.c \
jpeg.c \
diff --git a/lib/libv4lconvert/Makefile.am b/lib/libv4lconvert/Makefile.am
index f266f3e7..71152b54 100644
--- a/lib/libv4lconvert/Makefile.am
+++ b/lib/libv4lconvert/Makefile.am
@@ -13,7 +13,7 @@ endif
libv4lconvert_la_SOURCES = \
libv4lconvert.c tinyjpeg.c sn9c10x.c sn9c20x.c pac207.c mr97310a.c \
flip.c crop.c jidctflt.c spca561-decompress.c \
- rgbyuv.c sn9c2028-decomp.c spca501.c sq905c.c bayer.c hm12.c \
+ rgbyuv.c sn9c2028-decomp.c spca501.c sq905c.c bayer.c nv12_16l16.c \
stv0680.c cpia1.c se401.c jpgl.c jpeg.c jl2005bcd.c \
control/libv4lcontrol.c control/libv4lcontrol.h control/libv4lcontrol-priv.h \
processing/libv4lprocessing.c processing/whitebalance.c processing/autogain.c \
diff --git a/lib/libv4lconvert/libv4lconvert-priv.h b/lib/libv4lconvert/libv4lconvert-priv.h
index ce5970c9..6b9128ce 100644
--- a/lib/libv4lconvert/libv4lconvert-priv.h
+++ b/lib/libv4lconvert/libv4lconvert-priv.h
@@ -274,13 +274,13 @@ void v4lconvert_bayer10p_to_bayer8(unsigned char *bayer10p,
void v4lconvert_bayer16_to_bayer8(unsigned char *bayer16,
unsigned char *bayer8, int width, int height);
-void v4lconvert_hm12_to_rgb24(const unsigned char *src,
+void v4lconvert_nv12_16l16_to_rgb24(const unsigned char *src,
unsigned char *dst, int width, int height);
-void v4lconvert_hm12_to_bgr24(const unsigned char *src,
+void v4lconvert_nv12_16l16_to_bgr24(const unsigned char *src,
unsigned char *dst, int width, int height);
-void v4lconvert_hm12_to_yuv420(const unsigned char *src,
+void v4lconvert_nv12_16l16_to_yuv420(const unsigned char *src,
unsigned char *dst, int width, int height, int yvu);
void v4lconvert_hsv_to_rgb24(const unsigned char *src, unsigned char *dest,
diff --git a/lib/libv4lconvert/libv4lconvert.c b/lib/libv4lconvert/libv4lconvert.c
index 5945be43..e794ec00 100644
--- a/lib/libv4lconvert/libv4lconvert.c
+++ b/lib/libv4lconvert/libv4lconvert.c
@@ -138,7 +138,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = {
{ V4L2_PIX_FMT_KONICA420, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_SN9C20X_I420, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_M420, 12, 6, 3, 1 },
- { V4L2_PIX_FMT_HM12, 12, 6, 3, 1 },
+ { V4L2_PIX_FMT_NV12_16L16, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_NV12, 12, 6, 3, 1 },
{ V4L2_PIX_FMT_CPIA1, 0, 6, 3, 1 },
/* JPEG and variants */
@@ -916,19 +916,19 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data,
}
/* Conexant cx2341x raw video macroblock format */
- case V4L2_PIX_FMT_HM12:
+ case V4L2_PIX_FMT_NV12_16L16:
switch (dest_pix_fmt) {
case V4L2_PIX_FMT_RGB24:
- v4lconvert_hm12_to_rgb24(src, dest, width, height);
+ v4lconvert_nv12_16l16_to_rgb24(src, dest, width, height);
break;
case V4L2_PIX_FMT_BGR24:
- v4lconvert_hm12_to_bgr24(src, dest, width, height);
+ v4lconvert_nv12_16l16_to_bgr24(src, dest, width, height);
break;
case V4L2_PIX_FMT_YUV420:
- v4lconvert_hm12_to_yuv420(src, dest, width, height, 0);
+ v4lconvert_nv12_16l16_to_yuv420(src, dest, width, height, 0);
break;
case V4L2_PIX_FMT_YVU420:
- v4lconvert_hm12_to_yuv420(src, dest, width, height, 1);
+ v4lconvert_nv12_16l16_to_yuv420(src, dest, width, height, 1);
break;
}
break;
diff --git a/lib/libv4lconvert/hm12.c b/lib/libv4lconvert/nv12_16l16.c
index 4286ce2c..d44a5485 100644
--- a/lib/libv4lconvert/hm12.c
+++ b/lib/libv4lconvert/nv12_16l16.c
@@ -1,6 +1,6 @@
/*
-cx2341x HM12 conversion routines
+cx2341x NV12_16L16 conversion routines
(C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
@@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
#include "libv4lconvert-priv.h"
#include <string.h>
-/* The HM12 format is used in the Conexant cx23415/6/8 MPEG encoder devices.
+/* The NV12_16L16 format is used in the Conexant cx23415/6/8 MPEG encoder devices.
It is a macroblock format with separate Y and UV planes, each plane
consisting of 16x16 values. All lines are always 720 bytes long. If the
width of the image is less than 720, then the remainder is padding.
@@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
static const int stride = 720;
-static void v4lconvert_hm12_to_rgb(const unsigned char *src, unsigned char *dest,
+static void v4lconvert_nv12_16l16_to_rgb(const unsigned char *src, unsigned char *dest,
int width, int height, int rgb)
{
unsigned int y, x, i, j;
@@ -91,16 +91,16 @@ static void v4lconvert_hm12_to_rgb(const unsigned char *src, unsigned char *dest
}
}
-void v4lconvert_hm12_to_rgb24(const unsigned char *src, unsigned char *dest,
+void v4lconvert_nv12_16l16_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height)
{
- v4lconvert_hm12_to_rgb(src, dest, width, height, 1);
+ v4lconvert_nv12_16l16_to_rgb(src, dest, width, height, 1);
}
-void v4lconvert_hm12_to_bgr24(const unsigned char *src, unsigned char *dest,
+void v4lconvert_nv12_16l16_to_bgr24(const unsigned char *src, unsigned char *dest,
int width, int height)
{
- v4lconvert_hm12_to_rgb(src, dest, width, height, 0);
+ v4lconvert_nv12_16l16_to_rgb(src, dest, width, height, 0);
}
static void de_macro_uv(unsigned char *dstu, unsigned char *dstv,
@@ -146,7 +146,7 @@ static void de_macro_y(unsigned char *dst, const unsigned char *src,
}
}
-void v4lconvert_hm12_to_yuv420(const unsigned char *src, unsigned char *dest,
+void v4lconvert_nv12_16l16_to_yuv420(const unsigned char *src, unsigned char *dest,
int width, int height, int yvu)
{
de_macro_y(dest, src, width, height);
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
index 4c4051ea..9f35d139 100644
--- a/m4/ax_pthread.m4
+++ b/m4/ax_pthread.m4
@@ -1,5 +1,5 @@
# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
+# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
@@ -14,20 +14,24 @@
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
-# Also sets PTHREAD_CC to any special C compiler that is needed for
-# multi-threaded programs (defaults to the value of CC otherwise). (This
-# is necessary on AIX to use the special cc_r compiler alias.)
+# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
+# needed for multi-threaded programs (defaults to the value of CC
+# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
+# special cc_r/CC_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also to link with them as well. For example, you might link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
+# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threaded programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
+# CXX="$PTHREAD_CXX"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
@@ -55,6 +59,7 @@
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
+# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -67,7 +72,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
+# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -82,7 +87,7 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
-#serial 23
+#serial 31
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
@@ -104,6 +109,7 @@ if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+ AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
@@ -123,10 +129,12 @@ fi
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
-# Create a list of thread flags to try. Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
+# Create a list of thread flags to try. Items with a "," contain both
+# C compiler flags (before ",") and linker flags (after ","). Other items
+# starting with a "-" are C compiler flags, and remaining items are
+# library names, except for "none" which indicates that we try without
+# any flags at all, and "pthread-config" which is a program returning
+# the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
@@ -194,14 +202,47 @@ case $host_os in
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
- ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
;;
esac
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+ [ax_cv_PTHREAD_CLANG],
+ [ax_cv_PTHREAD_CLANG=no
+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
+ if test "x$GCC" = "xyes"; then
+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+# if defined(__clang__) && defined(__llvm__)
+ AX_PTHREAD_CC_IS_CLANG
+# endif
+ ],
+ [ax_cv_PTHREAD_CLANG=yes])
+ fi
+ ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+# Note that for GCC and Clang -pthread generally implies -lpthread,
+# except when -nostdlib is passed.
+# This is problematic using libtool to build C++ shared libraries with pthread:
+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
+# To solve this, first try -pthread together with -lpthread for GCC
+
AS_IF([test "x$GCC" = "xyes"],
- [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
+ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
+
+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
+
+AS_IF([test "x$ax_pthread_clang" = "xyes"],
+ [ax_pthread_flags="-pthread,-lpthread -pthread"])
+
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
@@ -224,25 +265,86 @@ AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
-# Are we compiling with Clang?
-AC_CACHE_CHECK([whether $CC is Clang],
- [ax_cv_PTHREAD_CLANG],
- [ax_cv_PTHREAD_CLANG=no
- # Note that Autoconf sets GCC=yes for Clang as well as GCC
- if test "x$GCC" = "xyes"; then
- AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
- [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
-# if defined(__clang__) && defined(__llvm__)
- AX_PTHREAD_CC_IS_CLANG
-# endif
- ],
- [ax_cv_PTHREAD_CLANG=yes])
- fi
- ])
-ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+ case $ax_pthread_try_flag in
+ none)
+ AC_MSG_CHECKING([whether pthreads work without any flags])
+ ;;
+
+ *,*)
+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
+ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
+ ;;
+
+ -*)
+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
+ ;;
+
+ pthread-config)
+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+ PTHREAD_CFLAGS="`pthread-config --cflags`"
+ PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+ ;;
+
+ *)
+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
+ ;;
+ esac
+
+ ax_pthread_save_CFLAGS="$CFLAGS"
+ ax_pthread_save_LIBS="$LIBS"
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ LIBS="$PTHREAD_LIBS $LIBS"
+
+ # Check for various functions. We must include pthread.h,
+ # since some functions may be macros. (On the Sequent, we
+ # need a special flag -Kthread to make this header compile.)
+ # We check for pthread_join because it is in -lpthread on IRIX
+ # while pthread_create is in libc. We check for pthread_attr_init
+ # due to DEC craziness with -lpthreads. We check for
+ # pthread_cleanup_push because it is one of the few pthread
+ # functions on Solaris that doesn't have a non-functional libc stub.
+ # We try pthread_create on general principles.
+
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+# if $ax_pthread_check_cond
+# error "$ax_pthread_check_macro must be defined"
+# endif
+ static void *some_global = NULL;
+ static void routine(void *a)
+ {
+ /* To avoid any unused-parameter or
+ unused-but-set-parameter warning. */
+ some_global = a;
+ }
+ static void *start_routine(void *a) { return a; }],
+ [pthread_t th; pthread_attr_t attr;
+ pthread_create(&th, 0, start_routine, 0);
+ pthread_join(th, 0);
+ pthread_attr_init(&attr);
+ pthread_cleanup_push(routine, 0);
+ pthread_cleanup_pop(0) /* ; */])],
+ [ax_pthread_ok=yes],
+ [])
+
+ CFLAGS="$ax_pthread_save_CFLAGS"
+ LIBS="$ax_pthread_save_LIBS"
+
+ AC_MSG_RESULT([$ax_pthread_ok])
+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+ PTHREAD_LIBS=""
+ PTHREAD_CFLAGS=""
+done
+fi
-ax_pthread_clang_warning=no
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
@@ -261,11 +363,6 @@ if test "x$ax_pthread_clang" = "xyes"; then
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
- PTHREAD_CFLAGS="-pthread"
- PTHREAD_LIBS=
-
- ax_pthread_ok=yes
-
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
@@ -294,7 +391,7 @@ if test "x$ax_pthread_clang" = "xyes"; then
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
- ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
@@ -320,78 +417,7 @@ if test "x$ax_pthread_clang" = "xyes"; then
fi # $ax_pthread_clang = yes
-if test "x$ax_pthread_ok" = "xno"; then
-for ax_pthread_try_flag in $ax_pthread_flags; do
-
- case $ax_pthread_try_flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
- -mt,pthread)
- AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
- PTHREAD_CFLAGS="-mt"
- PTHREAD_LIBS="-lpthread"
- ;;
-
- -*)
- AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
- PTHREAD_CFLAGS="$ax_pthread_try_flag"
- ;;
- pthread-config)
- AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
- AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
- AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
- PTHREAD_LIBS="-l$ax_pthread_try_flag"
- ;;
- esac
-
- ax_pthread_save_CFLAGS="$CFLAGS"
- ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
- LIBS="$PTHREAD_LIBS $LIBS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
- # need a special flag -Kthread to make this header compile.)
- # We check for pthread_join because it is in -lpthread on IRIX
- # while pthread_create is in libc. We check for pthread_attr_init
- # due to DEC craziness with -lpthreads. We check for
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
-
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-# if $ax_pthread_check_cond
-# error "$ax_pthread_check_macro must be defined"
-# endif
- static void routine(void *a) { a = 0; }
- static void *start_routine(void *a) { return a; }],
- [pthread_t th; pthread_attr_t attr;
- pthread_create(&th, 0, start_routine, 0);
- pthread_join(th, 0);
- pthread_attr_init(&attr);
- pthread_cleanup_push(routine, 0);
- pthread_cleanup_pop(0) /* ; */])],
- [ax_pthread_ok=yes],
- [])
-
- CFLAGS="$ax_pthread_save_CFLAGS"
- LIBS="$ax_pthread_save_LIBS"
-
- AC_MSG_RESULT([$ax_pthread_ok])
- AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
-done
-fi
# Various other checks:
if test "x$ax_pthread_ok" = "xyes"; then
@@ -438,7 +464,8 @@ if test "x$ax_pthread_ok" = "xyes"; then
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
- [[int i = PTHREAD_PRIO_INHERIT;]])],
+ [[int i = PTHREAD_PRIO_INHERIT;
+ return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
@@ -460,18 +487,28 @@ if test "x$ax_pthread_ok" = "xyes"; then
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
- [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
- [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+ [
+ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
+ AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
+ ],
+ [
+ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
+ AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
+ ]
+ )
+ ])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
+AC_SUBST([PTHREAD_CXX])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "x$ax_pthread_ok" = "xyes"; then
diff --git a/m4/visibility.m4 b/m4/visibility.m4
new file mode 100644
index 00000000..d161bd7f
--- /dev/null
+++ b/m4/visibility.m4
@@ -0,0 +1,82 @@
+# visibility.m4 serial 8
+dnl Copyright (C) 2005, 2008, 2010-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Tests whether the compiler supports the command-line option
+dnl -fvisibility=hidden and the function and variable attributes
+dnl __attribute__((__visibility__("hidden"))) and
+dnl __attribute__((__visibility__("default"))).
+dnl Does *not* test for __visibility__("protected") - which has tricky
+dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on
+dnl Mac OS X.
+dnl Does *not* test for __visibility__("internal") - which has processor
+dnl dependent semantics.
+dnl Does *not* test for #pragma GCC visibility push(hidden) - which is
+dnl "really only recommended for legacy code".
+dnl Set the variable CFLAG_VISIBILITY.
+dnl Defines and sets the variable HAVE_VISIBILITY.
+
+AC_DEFUN([gl_VISIBILITY],
+[
+ AC_REQUIRE([AC_PROG_CC])
+ CFLAG_VISIBILITY=
+ HAVE_VISIBILITY=0
+ if test -n "$GCC"; then
+ dnl First, check whether -Werror can be added to the command line, or
+ dnl whether it leads to an error because of some other option that the
+ dnl user has put into $CC $CFLAGS $CPPFLAGS.
+ AC_CACHE_CHECK([whether the -Werror option is usable],
+ [gl_cv_cc_vis_werror],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_vis_werror=yes],
+ [gl_cv_cc_vis_werror=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+ dnl Now check whether visibility declarations are supported.
+ AC_CACHE_CHECK([for simple visibility declarations],
+ [gl_cv_cc_visibility],
+ [gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+ dnl We use the option -Werror and a function dummyfunc, because on some
+ dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning
+ dnl "visibility attribute not supported in this configuration; ignored"
+ dnl at the first function definition in every compilation unit, and we
+ dnl don't want to use the option in this case.
+ if test $gl_cv_cc_vis_werror = yes; then
+ CFLAGS="$CFLAGS -Werror"
+ fi
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[extern __attribute__((__visibility__("hidden"))) int hiddenvar;
+ extern __attribute__((__visibility__("default"))) int exportedvar;
+ extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void);
+ extern __attribute__((__visibility__("default"))) int exportedfunc (void);
+ void dummyfunc (void);
+ int hiddenvar;
+ int exportedvar;
+ int hiddenfunc (void) { return 51; }
+ int exportedfunc (void) { return 1225736919; }
+ void dummyfunc (void) {}
+ ]],
+ [[]])],
+ [gl_cv_cc_visibility=yes],
+ [gl_cv_cc_visibility=no])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+ if test $gl_cv_cc_visibility = yes; then
+ CFLAG_VISIBILITY="-fvisibility=hidden"
+ HAVE_VISIBILITY=1
+ fi
+ fi
+ AC_SUBST([CFLAG_VISIBILITY])
+ AC_SUBST([HAVE_VISIBILITY])
+ AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY],
+ [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.])
+])
diff --git a/sync-with-kernel.sh b/sync-with-kernel.sh
index e3a70a0b..8ae078c5 100755
--- a/sync-with-kernel.sh
+++ b/sync-with-kernel.sh
@@ -51,7 +51,7 @@ patch -d ${TOPSRCDIR} --no-backup-if-mismatch -p1 <${TOPSRCDIR}/utils/common/v4l
cp -a ${KERNEL_DIR}/drivers/media/test-drivers/vicodec/codec-fwht.[ch] ${TOPSRCDIR}/utils/common/
cp -a ${KERNEL_DIR}/drivers/media/test-drivers/vicodec/codec-v4l2-fwht.[ch] ${TOPSRCDIR}/utils/common/
patch -d ${TOPSRCDIR} --no-backup-if-mismatch -p1 <${TOPSRCDIR}/utils/common/codec-fwht.patch
-grep V4L2_.*_FMT.*descr ${KERNEL_DIR}/drivers/media/v4l2-core/v4l2-ioctl.c | grep -v V4L2_PIX_FMT_VP8_FRAME | grep -v V4L2_PIX_FMT_HEVC_SLICE | perl -pe 's/.*V4L2_(.*)_FMT/\tcase V4L2_\1_FMT/; s/:.*descr = /: return /; s/;.*/;/;' >${TOPSRCDIR}/utils/common/v4l2-pix-formats.h
+grep V4L2_.*_FMT.*descr ${KERNEL_DIR}/drivers/media/v4l2-core/v4l2-ioctl.c | grep -v V4L2_PIX_FMT_HEVC_SLICE | perl -pe 's/.*V4L2_(.*)_FMT/\tcase V4L2_\1_FMT/; s/:.*descr = /: return /; s/;.*/;/;' >${TOPSRCDIR}/utils/common/v4l2-pix-formats.h
function keytable {
SRCDIR=${TOPSRCDIR}/utils/keytable
diff --git a/utils/cec-compliance/cec-compliance.h b/utils/cec-compliance/cec-compliance.h
index 2ef5a1f5..34ed9a81 100644
--- a/utils/cec-compliance/cec-compliance.h
+++ b/utils/cec-compliance/cec-compliance.h
@@ -472,6 +472,7 @@ extern const vec_remote_subtests audio_rate_ctl_subtests;
// cec-test-power.cpp
bool util_interactive_ensure_power_state(struct node *node, unsigned me, unsigned la, bool interactive,
__u8 target_pwr);
+int standby_resume_wakeup(struct node *node, unsigned me, unsigned la, bool interactive);
extern const vec_remote_subtests standby_subtests;
extern const vec_remote_subtests one_touch_play_subtests;
extern const vec_remote_subtests power_status_subtests;
diff --git a/utils/cec-compliance/cec-test-power.cpp b/utils/cec-compliance/cec-test-power.cpp
index f1e302d6..c811af59 100644
--- a/utils/cec-compliance/cec-test-power.cpp
+++ b/utils/cec-compliance/cec-test-power.cpp
@@ -490,7 +490,7 @@ static int wakeup_source(struct node *node, unsigned me, unsigned la)
return wakeup_rc(node, me, la);
}
-static int standby_resume_wakeup(struct node *node, unsigned me, unsigned la, bool interactive)
+int standby_resume_wakeup(struct node *node, unsigned me, unsigned la, bool interactive)
{
if (!node->remote[la].in_standby)
return NOTAPPLICABLE;
diff --git a/utils/cec-compliance/cec-test.cpp b/utils/cec-compliance/cec-test.cpp
index 6a6a9040..5c8aa159 100644
--- a/utils/cec-compliance/cec-test.cpp
+++ b/utils/cec-compliance/cec-test.cpp
@@ -264,6 +264,7 @@ int core_abort(struct node *node, unsigned me, unsigned la, bool interactive)
}
static const vec_remote_subtests core_subtests{
+ { "Wake up", CEC_LOG_ADDR_MASK_ALL, standby_resume_wakeup, true },
{ "Feature aborts unknown messages", CEC_LOG_ADDR_MASK_ALL, core_unknown },
{ "Feature aborts Abort message", CEC_LOG_ADDR_MASK_ALL, core_abort },
};
@@ -1160,10 +1161,6 @@ void testRemote(struct node *node, unsigned me, unsigned la, unsigned test_tags,
if (!util_interactive_ensure_power_state(node, me, la, interactive, CEC_OP_POWER_STATUS_ON))
return;
- if (node->remote[la].in_standby && !interactive) {
- announce("The remote device is in standby. It should be powered on when testing. Aborting.");
- return;
- }
if (!node->remote[la].has_power_status) {
announce("The device didn't support Give Device Power Status.");
announce("Assuming that the device is powered on.");
diff --git a/utils/common/v4l2-pix-formats.h b/utils/common/v4l2-pix-formats.h
index 24ecc85a..c3fd2bf2 100644
--- a/utils/common/v4l2-pix-formats.h
+++ b/utils/common/v4l2-pix-formats.h
@@ -187,7 +187,9 @@
case V4L2_PIX_FMT_VC1_ANNEX_G: return "VC-1 (SMPTE 412M Annex G)";
case V4L2_PIX_FMT_VC1_ANNEX_L: return "VC-1 (SMPTE 412M Annex L)";
case V4L2_PIX_FMT_VP8: return "VP8";
+ case V4L2_PIX_FMT_VP8_FRAME: return "VP8 Frame";
case V4L2_PIX_FMT_VP9: return "VP9";
+ case V4L2_PIX_FMT_VP9_FRAME: return "VP9 Frame";
case V4L2_PIX_FMT_HEVC: return "HEVC";
case V4L2_PIX_FMT_FWHT: return "FWHT";
case V4L2_PIX_FMT_FWHT_STATELESS: return "FWHT Stateless";
diff --git a/utils/cx18-ctl/cx18-ctl.c b/utils/cx18-ctl/cx18-ctl.c
index bf8ee967..16a2c82f 100644
--- a/utils/cx18-ctl/cx18-ctl.c
+++ b/utils/cx18-ctl/cx18-ctl.c
@@ -36,6 +36,7 @@
#include <math.h>
#include <linux/videodev2.h>
+#include <v4l-getsubopt.h>
/* copied from cx18-driver.h */
#define CX18_DBGFLG_WARN (1 << 0)
@@ -279,7 +280,7 @@ int main(int argc, char **argv)
case OptSetGPIO:
subs = optarg;
while (*subs != '\0') {
- switch (getsubopt(&subs, subopts, &value)) {
+ switch (v4l_getsubopt(&subs, subopts, &value)) {
case SUB_DIR:
if (value == NULL) {
fprintf(stderr,
diff --git a/utils/ivtv-ctl/ivtv-ctl.c b/utils/ivtv-ctl/ivtv-ctl.c
index 9923827e..b42b3489 100644
--- a/utils/ivtv-ctl/ivtv-ctl.c
+++ b/utils/ivtv-ctl/ivtv-ctl.c
@@ -35,6 +35,7 @@
#include <math.h>
#include <linux/videodev2.h>
+#include <v4l-getsubopt.h>
/* copied from ivtv-driver.h */
#define IVTV_DBGFLG_WARN (1 << 0)
@@ -316,7 +317,7 @@ int main(int argc, char **argv)
{
subs = optarg;
while (*subs != '\0') {
- switch (getsubopt(&subs, subopts, &value)) {
+ switch (v4l_getsubopt(&subs, subopts, &value)) {
case SUB_YUV_MODE:
if (value == NULL) {
fprintf(stderr,
@@ -360,7 +361,7 @@ int main(int argc, char **argv)
case OptSetGPIO:
subs = optarg;
while (*subs != '\0') {
- switch (getsubopt(&subs, subopts, &value)) {
+ switch (v4l_getsubopt(&subs, subopts, &value)) {
case SUB_DIR:
if (value == NULL) {
fprintf(stderr,
diff --git a/utils/libcecutil/cec-parse.cpp b/utils/libcecutil/cec-parse.cpp
index fd37f5b8..aa703136 100644
--- a/utils/libcecutil/cec-parse.cpp
+++ b/utils/libcecutil/cec-parse.cpp
@@ -10,6 +10,7 @@
#include <unistd.h>
#include <linux/cec-funcs.h>
+#include <v4l-getsubopt.h>
#include "cec-htng-funcs.h"
#include "cec-log.h"
#include "cec-parse.h"
@@ -147,7 +148,7 @@ static __u8 *args2short_aud_fmt_codes(__u8 audio_format_code1,
int cec_parse_subopt(char **subs, const char * const *subopts, char **value)
{
- int opt = getsubopt(subs, const_cast<char * const *>(subopts), value);
+ int opt = v4l_getsubopt(subs, const_cast<char * const *>(subopts), value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
diff --git a/utils/qv4l2/capture-win.cpp b/utils/qv4l2/capture-win.cpp
index 5667e7e7..8add18f8 100644
--- a/utils/qv4l2/capture-win.cpp
+++ b/utils/qv4l2/capture-win.cpp
@@ -44,9 +44,6 @@ CaptureWin::CaptureWin(ApplicationWindow *aw) :
m_appWin(aw)
{
setWindowTitle("V4L2 Capture");
- m_hotkeyClose = new QShortcut(Qt::CTRL+Qt::Key_W, this);
- connect(m_hotkeyClose, SIGNAL(activated()), this, SLOT(close()));
- connect(new QShortcut(Qt::Key_Q, this), SIGNAL(activated()), this, SLOT(close()));
m_hotkeyScaleReset = new QShortcut(Qt::CTRL+Qt::Key_F, this);
connect(m_hotkeyScaleReset, SIGNAL(activated()), this, SLOT(resetSize()));
connect(aw->m_resetScalingAct, SIGNAL(triggered()), this, SLOT(resetSize()));
@@ -55,9 +52,25 @@ CaptureWin::CaptureWin(ApplicationWindow *aw) :
m_hotkeyToggleFullscreen = new QShortcut(Qt::Key_F, this);
connect(m_hotkeyToggleFullscreen, SIGNAL(activated()), aw->m_makeFullScreenAct, SLOT(toggle()));
m_exitFullScreen = new QAction(QIcon(":/fullscreenexit.png"), "Exit Fullscreen", this);
+ m_exitFullScreen->setShortcut(m_hotkeyToggleFullscreen->key());
connect(m_exitFullScreen, SIGNAL(triggered()), this, SLOT(escape()));
m_enterFullScreen = new QAction(QIcon(":/fullscreen.png"), "Show Fullscreen", this);
+ m_enterFullScreen ->setShortcut(m_hotkeyToggleFullscreen->key());
connect(m_enterFullScreen, SIGNAL(triggered()), this, SLOT(fullScreen()));
+ // Add the action to allow the hotkey to start/stop the stream
+ addAction(m_appWin->m_capStartAct);
+
+ m_closeWindowAct = new QAction(QIcon(":/fileclose.png"), "&Close Window", this);
+ m_closeWindowAct->setStatusTip("Close");
+ QList<QKeySequence> shortcuts;
+ // More standard close window shortcut
+ shortcuts << Qt::CTRL+Qt::Key_W;
+ // Historic qv4l2 shortcut
+ shortcuts << Qt::Key_Q;
+ m_closeWindowAct->setShortcuts(shortcuts);
+ addAction(m_closeWindowAct);
+ connect(m_closeWindowAct, SIGNAL(triggered()), this, SLOT(close()));
+
m_frame.format = 0;
m_frame.size.setWidth(0);
m_frame.size.setHeight(0);
@@ -84,7 +97,6 @@ CaptureWin::~CaptureWin()
layout()->removeWidget(this);
delete layout();
- delete m_hotkeyClose;
delete m_hotkeyScaleReset;
}
@@ -365,6 +377,8 @@ void CaptureWin::customMenuRequested(QPoint pos)
menu->addAction(m_enterFullScreen);
}
+ menu->addAction(m_appWin->m_capStartAct);
+ menu->addAction(m_appWin->m_capStepAct);
menu->addAction(m_appWin->m_resetScalingAct);
if (m_appWin->m_useBlendingAct)
menu->addAction(m_appWin->m_useBlendingAct);
@@ -376,6 +390,7 @@ void CaptureWin::customMenuRequested(QPoint pos)
menu->addMenu(m_appWin->m_overrideXferFuncMenu);
menu->addMenu(m_appWin->m_overrideYCbCrEncMenu);
menu->addMenu(m_appWin->m_overrideQuantizationMenu);
+ menu->addAction(m_closeWindowAct);
menu->popup(mapToGlobal(pos));
}
diff --git a/utils/qv4l2/capture-win.h b/utils/qv4l2/capture-win.h
index c16fa7ce..f6ca6f2b 100644
--- a/utils/qv4l2/capture-win.h
+++ b/utils/qv4l2/capture-win.h
@@ -78,6 +78,7 @@ public:
void makeFullScreen(bool);
QAction *m_exitFullScreen;
QAction *m_enterFullScreen;
+ QAction *m_closeWindowAct;
/**
* @brief Set a frame into the capture window.
@@ -214,7 +215,6 @@ private:
ApplicationWindow *m_appWin;
static double m_pixelAspectRatio;
static CropMethod m_cropMethod;
- QShortcut *m_hotkeyClose;
QShortcut *m_hotkeyScaleReset;
QShortcut *m_hotkeyExitFullscreen;
QShortcut *m_hotkeyToggleFullscreen;
diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp
index b57178e4..d9141ad1 100644
--- a/utils/qv4l2/qv4l2.cpp
+++ b/utils/qv4l2/qv4l2.cpp
@@ -456,9 +456,9 @@ void ApplicationWindow::setDevice(const QString &device, bool rawOpen)
else
m_convertData = v4lconvert_create(g_fd());
bool canStream = has_rw() || has_streaming();
- bool isCapture = v4l_type_is_capture(g_type());
- m_capStartAct->setEnabled(canStream);
- m_capStepAct->setEnabled(canStream && isCapture);
+ bool isCapture = v4l_type_is_capture(g_type()) && !has_radio_tx();
+ m_capStartAct->setEnabled(canStream || isCapture);
+ m_capStepAct->setEnabled(canStream && isCapture && !has_radio_rx());
m_saveRawAct->setEnabled(canStream && has_vid_cap());
m_snapshotAct->setEnabled(canStream && has_vid_cap());
m_capMenu->setEnabled(canStream && isCapture && !has_radio_rx());
diff --git a/utils/rds-ctl/rds-ctl.cpp b/utils/rds-ctl/rds-ctl.cpp
index 80a9396a..2a17b430 100644
--- a/utils/rds-ctl/rds-ctl.cpp
+++ b/utils/rds-ctl/rds-ctl.cpp
@@ -26,6 +26,7 @@
#include <linux/videodev2.h>
#include <libv4l2rds.h>
+#include <v4l-getsubopt.h>
using dev_vec = std::vector<std::string>;
using dev_map = std::map<std::string, std::string>;
@@ -362,7 +363,7 @@ static dev_vec list_devices()
static int parse_subopt(char **subs, const char * const *subopts, char **value)
{
- int opt = getsubopt(subs, const_cast<char * const *>(subopts), value);
+ int opt = v4l_getsubopt(subs, const_cast<char * const *>(subopts), value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp
index 798c4221..c53a55ba 100644
--- a/utils/v4l2-compliance/v4l2-compliance.cpp
+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
@@ -32,6 +32,7 @@
#include "v4l2-compliance.h"
#include <media-info.h>
+#include <v4l-getsubopt.h>
/* Short option list
@@ -84,8 +85,10 @@ bool show_colors;
bool exit_on_fail;
bool exit_on_warn;
bool is_vivid;
+bool is_uvcvideo;
int media_fd = -1;
unsigned warnings;
+bool has_mmu = true;
static unsigned color_component;
static unsigned color_skip;
@@ -150,8 +153,21 @@ static struct option long_options[] = {
static void print_sha()
{
+ int fd = open("/dev/null", O_RDONLY);
+
+ if (fd >= 0) {
+ // FIONBIO is a write-only ioctl that takes an int argument that
+ // enables (!= 0) or disables (== 0) nonblocking mode of a fd.
+ //
+ // Passing a nullptr should return EFAULT on MMU capable machines,
+ // and it works if there is no MMU.
+ has_mmu = ioctl(fd, FIONBIO, nullptr);
+ close(fd);
+ }
printf("v4l2-compliance %s%s, ", PACKAGE_VERSION, STRING(GIT_COMMIT_CNT));
- printf("%zd bits, %zd-bit time_t\n", sizeof(void *) * 8, sizeof(time_t) * 8);
+ printf("%zd bits, %zd-bit time_t%s\n",
+ sizeof(void *) * 8, sizeof(time_t) * 8,
+ has_mmu ? "" : ", has no MMU");
if (strlen(STRING(GIT_SHA)))
printf("v4l2-compliance SHA: %s %s\n",
STRING(GIT_SHA), STRING(GIT_COMMIT_DATE));
@@ -575,6 +591,7 @@ static void determine_codec_mask(struct node &node)
case V4L2_PIX_FMT_MPEG2_SLICE:
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_VP8_FRAME:
+ case V4L2_PIX_FMT_VP9_FRAME:
case V4L2_PIX_FMT_FWHT_STATELESS:
mask |= STATELESS_DECODER;
break;
@@ -620,9 +637,9 @@ static int testCap(struct node *node)
V4L2_CAP_VIDEO_M2M;
memset(&vcap, 0xff, sizeof(vcap));
- // Must always be there
- fail_on_test(doioctl(node, VIDIOC_QUERYCAP, nullptr) != EFAULT);
fail_on_test(doioctl(node, VIDIOC_QUERYCAP, &vcap));
+ if (has_mmu)
+ fail_on_test(doioctl(node, VIDIOC_QUERYCAP, nullptr) != EFAULT);
fail_on_test(check_ustring(vcap.driver, sizeof(vcap.driver)));
fail_on_test(check_ustring(vcap.card, sizeof(vcap.card)));
fail_on_test(check_ustring(vcap.bus_info, sizeof(vcap.bus_info)));
@@ -818,7 +835,7 @@ static void streamingSetup(struct node *node)
static int parse_subopt(char **subs, const char * const *subopts, char **value)
{
- int opt = getsubopt(subs, const_cast<char * const *>(subopts), value);
+ int opt = v4l_getsubopt(subs, const_cast<char * const *>(subopts), value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
@@ -959,6 +976,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
if (node.is_v4l2()) {
doioctl(&node, VIDIOC_QUERYCAP, &vcap);
driver = reinterpret_cast<const char *>(vcap.driver);
+ is_uvcvideo = driver == "uvcvideo";
is_vivid = driver == "vivid";
if (is_vivid)
node.bus_info = reinterpret_cast<const char *>(vcap.bus_info);
@@ -984,11 +1002,10 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
}
if (driver.empty())
- printf("Compliance test for device %s%s:\n\n",
- node.device, node.g_direct() ? "" : " (using libv4l2)");
+ printf("Compliance test for device ");
else
- printf("Compliance test for %s device %s%s:\n\n",
- driver.c_str(), node.device, node.g_direct() ? "" : " (using libv4l2)");
+ printf("Compliance test for %s device ", driver.c_str());
+ printf("%s%s:\n\n", node.device, node.g_direct() ? "" : " (using libv4l2)");
if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_SLICED_VBI_CAPTURE |
diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h
index 419d1498..7255161f 100644
--- a/utils/v4l2-compliance/v4l2-compliance.h
+++ b/utils/v4l2-compliance/v4l2-compliance.h
@@ -54,9 +54,11 @@ extern bool no_progress;
extern bool exit_on_fail;
extern bool exit_on_warn;
extern bool is_vivid; // We're testing the vivid driver
+extern bool is_uvcvideo; // We're testing the uvc driver
extern int kernel_version;
extern int media_fd;
extern unsigned warnings;
+extern bool has_mmu;
enum poll_mode {
POLL_MODE_NONE,
diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp
index 7f9ee153..fbf92653 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -1820,7 +1820,9 @@ static int setupDmaBuf(struct node *expbuf_node, struct node *node,
fail_on_test(buf.check(q, Unqueued, i));
fail_on_test(exp_q.g_num_planes() < buf.g_num_planes());
for (unsigned p = 0; p < buf.g_num_planes(); p++) {
- fail_on_test(exp_q.g_length(p) < buf.g_length(p));
+ if (exp_q.g_length(p) < buf.g_length(p))
+ return fail("exp_q.g_length(%u) < buf.g_length(%u): %u < %u\n",
+ p, p, exp_q.g_length(p), buf.g_length(p));
// This should not work!
fail_on_test(node->mmap(buf.g_length(p), 0) != MAP_FAILED);
q.s_fd(i, p, exp_q.g_fd(i, p));
@@ -2529,7 +2531,7 @@ public:
*/
if (!done) {
pthread_kill(thread, SIGUSR1);
- usleep(100000);
+ sleep(1);
}
/*
@@ -2538,7 +2540,7 @@ public:
*/
if (!done) {
pthread_cancel(thread);
- usleep(100000);
+ sleep(1);
}
pthread_join(thread, nullptr);
@@ -2633,7 +2635,7 @@ static int testBlockingDQBuf(struct node *node, cv4l_queue &q)
thread_dqbuf.start();
/* Wait for the child thread to start and block */
- usleep(100000);
+ sleep(1);
/* Check that it is really blocking */
fail_on_test(thread_dqbuf.done);
@@ -2641,7 +2643,7 @@ static int testBlockingDQBuf(struct node *node, cv4l_queue &q)
thread_streamoff.start();
/* Wait for the second child to start and exit */
- usleep(250000);
+ sleep(3);
fail_on_test(!thread_streamoff.done);
fail_on_test(node->streamoff(q.g_type()));
diff --git a/utils/v4l2-compliance/v4l2-test-controls.cpp b/utils/v4l2-compliance/v4l2-test-controls.cpp
index 22e8decc..8731c9eb 100644
--- a/utils/v4l2-compliance/v4l2-test-controls.cpp
+++ b/utils/v4l2-compliance/v4l2-test-controls.cpp
@@ -485,6 +485,8 @@ int testSimpleControls(struct node *node)
} else if (ret == EILSEQ) {
warn("s_ctrl returned EILSEQ\n");
ret = 0;
+ } else if (ret == EACCES && is_uvcvideo) {
+ ret = 0;
} else if (ret) {
return fail("s_ctrl returned an error (%d)\n", ret);
}
@@ -498,7 +500,8 @@ int testSimpleControls(struct node *node)
ctrl.id = qctrl.id;
ctrl.value = qctrl.minimum - 1;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
- if (ret && ret != EIO && ret != EILSEQ && ret != ERANGE)
+ if (ret && ret != EIO && ret != EILSEQ && ret != ERANGE &&
+ !(ret == EACCES && is_uvcvideo))
return fail("invalid minimum range check\n");
if (!ret && checkSimpleCtrl(ctrl, qctrl))
return fail("invalid control %08x\n", qctrl.id);
@@ -508,7 +511,8 @@ int testSimpleControls(struct node *node)
ctrl.id = qctrl.id;
ctrl.value = qctrl.maximum + 1;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
- if (ret && ret != EIO && ret != EILSEQ && ret != ERANGE)
+ if (ret && ret != EIO && ret != EILSEQ && ret != ERANGE &&
+ !(ret == EACCES && is_uvcvideo))
return fail("invalid maximum range check\n");
if (!ret && checkSimpleCtrl(ctrl, qctrl))
return fail("invalid control %08x\n", qctrl.id);
@@ -521,7 +525,8 @@ int testSimpleControls(struct node *node)
if (ret == ERANGE)
warn("%s: returns ERANGE for in-range, but non-step-multiple value\n",
qctrl.name);
- else if (ret && ret != EIO && ret != EILSEQ)
+ else if (ret && ret != EIO && ret != EILSEQ &&
+ !(ret == EACCES && is_uvcvideo))
return fail("returns error for in-range, but non-step-multiple value\n");
}
@@ -539,6 +544,8 @@ int testSimpleControls(struct node *node)
ctrl.id = qctrl.id;
ctrl.value = i;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
+ if (valid && ret == EACCES && is_uvcvideo)
+ continue;
if (valid && ret)
return fail("could not set valid menu item %d\n", i);
if (!valid && !ret)
@@ -551,15 +558,18 @@ int testSimpleControls(struct node *node)
ctrl.id = qctrl.id;
ctrl.value = qctrl.minimum;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
- if (ret && ret != EIO && ret != EILSEQ)
+ if (ret && ret != EIO && ret != EILSEQ &&
+ !(ret == EACCES && is_uvcvideo))
return fail("could not set minimum value\n");
ctrl.value = qctrl.maximum;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
- if (ret && ret != EIO && ret != EILSEQ)
+ if (ret && ret != EIO && ret != EILSEQ &&
+ !(ret == EACCES && is_uvcvideo))
return fail("could not set maximum value\n");
ctrl.value = qctrl.default_value;
ret = doioctl(node, VIDIOC_S_CTRL, &ctrl);
- if (ret && ret != EIO && ret != EILSEQ)
+ if (ret && ret != EIO && ret != EILSEQ &&
+ !(ret == EACCES && is_uvcvideo))
return fail("could not set default value\n");
}
}
@@ -731,6 +741,8 @@ int testExtendedControls(struct node *node)
} else if (ret == EILSEQ) {
warn("s_ext_ctrls returned EILSEQ\n");
ret = 0;
+ } else if (ret == EACCES && is_uvcvideo) {
+ ret = 0;
}
if (ret)
return fail("s_ext_ctrls returned an error (%d)\n", ret);
@@ -807,6 +819,8 @@ int testExtendedControls(struct node *node)
} else if (ret == EILSEQ) {
warn("s_ext_ctrls returned EILSEQ\n");
ret = 0;
+ } else if (ret == EACCES && is_uvcvideo) {
+ ret = 0;
}
if (ret)
return fail("could not set all controls\n");
@@ -837,7 +851,7 @@ int testExtendedControls(struct node *node)
warn("s_ext_ctrls returned EILSEQ\n");
ret = 0;
}
- if (ret && !multiple_classes)
+ if (ret && !(ret == EACCES && is_uvcvideo) && !multiple_classes)
return fail("could not set all controls of a specific class\n");
if (ret != EINVAL && multiple_classes)
return fail("should get EINVAL when setting mixed-class controls\n");
diff --git a/utils/v4l2-compliance/v4l2-test-io-config.cpp b/utils/v4l2-compliance/v4l2-test-io-config.cpp
index 6f2a9ba9..dcab40b8 100644
--- a/utils/v4l2-compliance/v4l2-test-io-config.cpp
+++ b/utils/v4l2-compliance/v4l2-test-io-config.cpp
@@ -577,6 +577,8 @@ static int checkEdid(struct node *node, unsigned pad, bool is_input)
fail_on_test(edid.blocks == 0 || edid.blocks >= 256);
fail_on_test(edid.pad != pad);
}
+ if (!has_mmu)
+ return 0;
edid.blocks = 1;
edid.pad = pad;
edid.edid = nullptr;
diff --git a/utils/v4l2-compliance/v4l2-test-media.cpp b/utils/v4l2-compliance/v4l2-test-media.cpp
index ef2982c0..28af0d83 100644
--- a/utils/v4l2-compliance/v4l2-test-media.cpp
+++ b/utils/v4l2-compliance/v4l2-test-media.cpp
@@ -32,8 +32,9 @@ int testMediaDeviceInfo(struct node *node)
struct media_device_info mdinfo;
memset(&mdinfo, 0xff, sizeof(mdinfo));
- fail_on_test(doioctl(node, MEDIA_IOC_DEVICE_INFO, nullptr) != EFAULT);
fail_on_test(doioctl(node, MEDIA_IOC_DEVICE_INFO, &mdinfo));
+ if (has_mmu)
+ fail_on_test(doioctl(node, MEDIA_IOC_DEVICE_INFO, nullptr) != EFAULT);
fail_on_test(check_0(mdinfo.reserved, sizeof(mdinfo.reserved)));
fail_on_test(check_string(mdinfo.driver, sizeof(mdinfo.driver)));
fail_on_test(mdinfo.model[0] && check_string(mdinfo.model, sizeof(mdinfo.model)));
@@ -127,21 +128,23 @@ int testMediaTopology(struct node *node)
fail_on_test(topology.reserved2);
fail_on_test(topology.reserved3);
fail_on_test(topology.reserved4);
- topology.ptr_entities = 4;
- fail_on_test(doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
- topology.ptr_entities = 0;
- topology.ptr_interfaces = 4;
- fail_on_test(topology.num_interfaces &&
- doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
- topology.ptr_interfaces = 0;
- topology.ptr_pads = 4;
- fail_on_test(topology.num_pads &&
- doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
- topology.ptr_pads = 0;
- topology.ptr_links = 4;
- fail_on_test(topology.num_links &&
- doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
- topology.ptr_links = 0;
+ if (has_mmu) {
+ topology.ptr_entities = 4;
+ fail_on_test(doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
+ topology.ptr_entities = 0;
+ topology.ptr_interfaces = 4;
+ fail_on_test(topology.num_interfaces &&
+ doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
+ topology.ptr_interfaces = 0;
+ topology.ptr_pads = 4;
+ fail_on_test(topology.num_pads &&
+ doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
+ topology.ptr_pads = 0;
+ topology.ptr_links = 4;
+ fail_on_test(topology.num_links &&
+ doioctl(node, MEDIA_IOC_G_TOPOLOGY, &topology) != EFAULT);
+ topology.ptr_links = 0;
+ }
v2_ents = new media_v2_entity[topology.num_entities];
memset(v2_ents, 0xff, topology.num_entities * sizeof(*v2_ents));
topology.ptr_entities = (uintptr_t)v2_ents;
@@ -394,12 +397,14 @@ int testMediaEnum(struct node *node)
fail_on_test(links.entity != ent.id);
fail_on_test(links.pads);
fail_on_test(links.links);
- links.pads = (struct media_pad_desc *)4;
- fail_on_test(ent.pads && doioctl(node, MEDIA_IOC_ENUM_LINKS, &links) != EFAULT);
- links.pads = nullptr;
- links.links = (struct media_link_desc *)4;
- fail_on_test(ent.links && doioctl(node, MEDIA_IOC_ENUM_LINKS, &links) != EFAULT);
- links.links = nullptr;
+ if (has_mmu) {
+ links.pads = (struct media_pad_desc *)4;
+ fail_on_test(ent.pads && doioctl(node, MEDIA_IOC_ENUM_LINKS, &links) != EFAULT);
+ links.pads = nullptr;
+ links.links = (struct media_link_desc *)4;
+ fail_on_test(ent.links && doioctl(node, MEDIA_IOC_ENUM_LINKS, &links) != EFAULT);
+ links.links = nullptr;
+ }
links.pads = new media_pad_desc[ent.pads];
memset(links.pads, 0xff, ent.pads * sizeof(*links.pads));
links.links = new media_link_desc[ent.links];
diff --git a/utils/v4l2-compliance/v4l2-test-subdevs.cpp b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
index 68f97205..f3d85771 100644
--- a/utils/v4l2-compliance/v4l2-test-subdevs.cpp
+++ b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
@@ -33,8 +33,9 @@ int testSubDevCap(struct node *node)
memset(&caps, 0xff, sizeof(caps));
// Must always be there
- fail_on_test(doioctl(node, VIDIOC_SUBDEV_QUERYCAP, nullptr) != EFAULT);
fail_on_test(doioctl(node, VIDIOC_SUBDEV_QUERYCAP, &caps));
+ if (has_mmu)
+ fail_on_test(doioctl(node, VIDIOC_SUBDEV_QUERYCAP, nullptr) != EFAULT);
fail_on_test(check_0(caps.reserved, sizeof(caps.reserved)));
fail_on_test((caps.version >> 16) < 5);
fail_on_test(caps.capabilities & ~VALID_SUBDEV_CAPS);
diff --git a/utils/v4l2-compliance/v4l2-test-time32-64.cpp b/utils/v4l2-compliance/v4l2-test-time32-64.cpp
index 1c515ca3..e175c055 100644
--- a/utils/v4l2-compliance/v4l2-test-time32-64.cpp
+++ b/utils/v4l2-compliance/v4l2-test-time32-64.cpp
@@ -161,7 +161,7 @@ int testTime32_64(struct node *node)
fail_on_test(check_0(ev32.reserved, sizeof(ev32.reserved)));
__u64 ev32_ts = ev32.timestamp.tv_sec * 1000000000ULL + ev32.timestamp.tv_nsec;
__s64 delta_ms = (ev32_ts - ev_ts) / 1000000;
- fail_on_test(delta_ms > 10);
+ fail_on_test_val(delta_ms > 500, (int)delta_ms);
info("VIDIOC_DQEVENT 32-bit timespec: %lld ms\n", delta_ms);
}
@@ -172,7 +172,7 @@ int testTime32_64(struct node *node)
fail_on_test(check_0(ev64.reserved, sizeof(ev64.reserved)));
__u64 ev64_ts = ev64.timestamp.tv_sec * 1000000000ULL + ev64.timestamp.tv_nsec;
__s64 delta_ms = (ev64_ts - ev_ts) / 1000000;
- fail_on_test(delta_ms > 10);
+ fail_on_test_val(delta_ms > 500, (int)delta_ms);
info("VIDIOC_DQEVENT 64-bit timespec: %lld ms\n", delta_ms);
}
diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp
index c9401714..89a9553d 100644
--- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
@@ -626,6 +626,9 @@ static void print_qctrl(int fd, const v4l2_query_ext_ctrl &qc,
case V4L2_CTRL_TYPE_VP8_FRAME:
printf("%31s %#8.8x (vp8-frame):", s.c_str(), qc.id);
break;
+ case V4L2_CTRL_TYPE_VP9_FRAME:
+ printf("%31s %#8.8x (vp9-frame):", s.c_str(), qc.id);
+ break;
case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
printf("%31s %#8.8x (mpeg2-quantisation):", s.c_str(), qc.id);
break;
@@ -959,7 +962,7 @@ static bool parse_next_subopt(char **subs, char **value)
static char *const subopts[] = {
nullptr
};
- int opt = getsubopt(subs, subopts, value);
+ int opt = v4l_getsubopt(subs, subopts, value);
if (opt < 0 || *value)
return false;
diff --git a/utils/v4l2-ctl/v4l2-ctl-edid.cpp b/utils/v4l2-ctl/v4l2-ctl-edid.cpp
index c3a4a28a..96659377 100644
--- a/utils/v4l2-ctl/v4l2-ctl-edid.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-edid.cpp
@@ -1150,7 +1150,7 @@ void edid_cmd(int ch, char *optarg)
nullptr
};
- int opt = getsubopt(&subs, (char* const*)subopts, &value);
+ int opt = v4l_getsubopt(&subs, (char* const*)subopts, &value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
diff --git a/utils/v4l2-ctl/v4l2-ctl-stds.cpp b/utils/v4l2-ctl/v4l2-ctl-stds.cpp
index 08154df4..6b596d00 100644
--- a/utils/v4l2-ctl/v4l2-ctl-stds.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-stds.cpp
@@ -185,7 +185,7 @@ static int parse_timing_subopt(char **subopt_str, int *value)
nullptr
};
- opt = getsubopt(subopt_str, (char* const*) subopt_list, &opt_str);
+ opt = v4l_getsubopt(subopt_str, (char* const*) subopt_list, &opt_str);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 7e24e0ec..752ea140 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -1258,7 +1258,9 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf
return QUEUE_STOPPED;
if (fmt.g_pixelformat() == V4L2_PIX_FMT_FWHT_STATELESS) {
- int media_fd = mi_get_media_fd(fd.g_fd());
+ struct v4l2_capability vcap = {};
+ fd.querycap(vcap);
+ int media_fd = mi_get_media_fd(fd.g_fd(), (const char *)vcap.bus_info);
if (media_fd < 0) {
fprintf(stderr, "%s: mi_get_media_fd failed\n", __func__);
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index 95b8a2e7..764a7c71 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -347,7 +347,7 @@ static bool is_rgb_or_hsv(__u32 pixelformat)
case V4L2_PIX_FMT_YUV410:
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_HI240:
- case V4L2_PIX_FMT_HM12:
+ case V4L2_PIX_FMT_NV12_16L16:
case V4L2_PIX_FMT_M420:
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
@@ -663,7 +663,7 @@ void print_video_formats_ext(cv4l_fd &fd, __u32 type, unsigned int mbus_code)
int parse_subopt(char **subs, const char * const *subopts, char **value)
{
- int opt = getsubopt(subs, const_cast<char * const *>(subopts), value);
+ int opt = v4l_getsubopt(subs, const_cast<char * const *>(subopts), value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");
@@ -1351,7 +1351,7 @@ int main(int argc, char **argv)
capabilities = vcap.device_caps;
}
- media_fd = mi_get_media_fd(fd);
+ media_fd = mi_get_media_fd(fd, is_subdev ? 0 : (const char *)vcap.bus_info);
priv_magic = (capabilities & V4L2_CAP_EXT_PIX_FORMAT) ?
V4L2_PIX_FMT_PRIV_MAGIC : 0;
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
index 24eee3d7..39161466 100644
--- a/utils/v4l2-ctl/v4l2-ctl.h
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -9,6 +9,7 @@
#include <linux/videodev2.h>
#include <linux/v4l2-subdev.h>
+#include <v4l-getsubopt.h>
#include <v4l2-info.h>
diff --git a/utils/v4l2-dbg/v4l2-dbg.cpp b/utils/v4l2-dbg/v4l2-dbg.cpp
index d711c9e4..98064fa2 100644
--- a/utils/v4l2-dbg/v4l2-dbg.cpp
+++ b/utils/v4l2-dbg/v4l2-dbg.cpp
@@ -38,6 +38,7 @@
#endif
#include <linux/videodev2.h>
+#include <v4l-getsubopt.h>
#include "v4l2-dbg-bttv.h"
#include "v4l2-dbg-saa7134.h"
@@ -364,7 +365,7 @@ static int doioctl(int fd, unsigned long int request, void *parm, const char *na
static int parse_subopt(char **subs, const char * const *subopts, char **value)
{
- int opt = getsubopt(subs, const_cast<char * const *>(subopts), value);
+ int opt = v4l_getsubopt(subs, const_cast<char * const *>(subopts), value);
if (opt == -1) {
fprintf(stderr, "Invalid suboptions specified\n");

Privacy Policy