From 38df0b8506130c9d94178b2e7d48a21b26e8903b Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 17 Jul 2020 16:53:15 +0200 Subject: media: v4l2-subdev: Introduce [get|set]_mbus_config pad ops Introduce two new pad operations to allow retrieving and configuring the media bus parameters on a subdevice pad. The newly introduced operations aims to replace the s/g_mbus_config video operations, which have been on their way for deprecation since a long time. Signed-off-by: Jacopo Mondi Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index d4e3b44cf14c..4d7e7e5cf96d 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -670,6 +670,30 @@ struct v4l2_subdev_pad_config { * * @set_frame_desc: set the low level media bus frame parameters, @fd array * may be adjusted by the subdev driver to device capabilities. + * + * @get_mbus_config: get the media bus configuration of a remote sub-device. + * The media bus configuration is usually retrieved from the + * firmware interface at sub-device probe time, immediately + * applied to the hardware and eventually adjusted by the + * driver. Remote sub-devices (usually video receivers) shall + * use this operation to query the transmitting end bus + * configuration in order to adjust their own one accordingly. + * Callers should make sure they get the most up-to-date as + * possible configuration from the remote end, likely calling + * this operation as close as possible to stream on time. The + * operation shall fail if the pad index it has been called on + * is not valid or in case of unrecoverable failures. + * + * @set_mbus_config: set the media bus configuration of a remote sub-device. + * This operations is intended to allow, in combination with + * the get_mbus_config operation, the negotiation of media bus + * configuration parameters between media sub-devices. The + * operation shall not fail if the requested configuration is + * not supported, but the driver shall update the content of + * the %config argument to reflect what has been actually + * applied to the hardware. The operation shall fail if the + * pad index it has been called on is not valid or in case of + * unrecoverable failures. */ struct v4l2_subdev_pad_ops { int (*init_cfg)(struct v4l2_subdev *sd, @@ -710,6 +734,10 @@ struct v4l2_subdev_pad_ops { struct v4l2_mbus_frame_desc *fd); int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, struct v4l2_mbus_frame_desc *fd); + int (*get_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_config *config); + int (*set_mbus_config)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_config *config); }; /** -- cgit v1.2.3 From d9857a6d81d327f39ef7a1ead50ebab458dd5564 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 17 Jul 2020 16:53:19 +0200 Subject: media: v4l2-subdev: Remove [s|g]_mbus_config video ops With all sensor and platform drivers now converted to use the new get_mbus_config and set_mbus_config pad operations, remove the deprecated video operations g_mbus_config and s_mbus_config. Signed-off-by: Jacopo Mondi Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 4d7e7e5cf96d..6f6795bab737 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -402,12 +402,6 @@ struct v4l2_mbus_frame_desc { * * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code. * - * @g_mbus_config: get supported mediabus configurations - * - * @s_mbus_config: set a certain mediabus configuration. This operation is added - * for compatibility with soc-camera drivers and should not be used by new - * software. - * * @s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev * can adjust @size to a lower value and must not write more data to the * buffer starting at @data than the original value of @size. @@ -435,10 +429,6 @@ struct v4l2_subdev_video_ops { struct v4l2_dv_timings *timings); int (*query_dv_timings)(struct v4l2_subdev *sd, struct v4l2_dv_timings *timings); - int (*g_mbus_config)(struct v4l2_subdev *sd, - struct v4l2_mbus_config *cfg); - int (*s_mbus_config)(struct v4l2_subdev *sd, - const struct v4l2_mbus_config *cfg); int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, unsigned int *size); }; -- cgit v1.2.3 From ddf5c927bd362b8b7c5e09e2e2271e4348e76b76 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 17 Jul 2020 16:53:20 +0200 Subject: media: v4l2- mediabus: Add usage note for V4L2_MBUS_* With the removal of the legacy g_mbus_config and s_mbus_config video operations, the sole users of V4L2_MBUS_* flags are now the newly introduced get_mbus_config and set_mbus_config pad operations. As the semantic of the new operations differs from the semantic of the legacy ones, add a usage note in the v4l2-mediabus.h header to specify how to use the flags. Also add a TODO note to record that we intend to replace the existing flags with fields, to prevent users from mixing conflicting values in a single operation call. Signed-off-by: Jacopo Mondi Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mediabus.h | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 45f88f0248c4..59b1de197114 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -11,9 +11,34 @@ #include #include +/* + * How to use the V4L2_MBUS_* flags: + * Flags are defined for each of the possible states and values of a media + * bus configuration parameter. One and only one bit of each group of flags + * shall be set by the users of the v4l2_subdev_pad_ops.get_mbus_config and + * v4l2_subdev_pad_ops.set_mbus_config operations to ensure that no + * conflicting settings are specified when reporting and setting the media bus + * configuration with the two operations respectively. For example, it is + * invalid to set or clear both the V4L2_MBUS_HSYNC_ACTIVE_HIGH and the + * V4L2_MBUS_HSYNC_ACTIVE_LOW flag at the same time. Instead either flag + * V4L2_MBUS_HSYNC_ACTIVE_HIGH or flag V4L2_MBUS_HSYNC_ACTIVE_LOW shall be + * set. The same is true for the V4L2_MBUS_CSI2_1/2/3/4_LANE flags group: only + * one of these four bits shall be set. + * + * TODO: replace the existing V4L2_MBUS_* flags with structures of fields + * to avoid conflicting settings. + * + * In example: + * #define V4L2_MBUS_HSYNC_ACTIVE_HIGH BIT(2) + * #define V4L2_MBUS_HSYNC_ACTIVE_LOW BIT(3) + * will be replaced by a field whose value reports the intended active state of + * the signal: + * unsigned int v4l2_mbus_hsync_active : 1; + */ + /* Parallel flags */ /* - * Can the client run in master or in slave mode. By "Master mode" an operation + * The client runs in master or in slave mode. By "Master mode" an operation * mode is meant, when the client (e.g., a camera sensor) is producing * horizontal and vertical synchronisation. In "Slave mode" the host is * providing these signals to the slave. @@ -45,17 +70,17 @@ #define V4L2_MBUS_DATA_ENABLE_LOW BIT(15) /* Serial flags */ -/* How many lanes the client can use */ +/* CSI-2 D-PHY number of data lanes. */ #define V4L2_MBUS_CSI2_1_LANE BIT(0) #define V4L2_MBUS_CSI2_2_LANE BIT(1) #define V4L2_MBUS_CSI2_3_LANE BIT(2) #define V4L2_MBUS_CSI2_4_LANE BIT(3) -/* On which channels it can send video data */ +/* CSI-2 Virtual Channel identifiers. */ #define V4L2_MBUS_CSI2_CHANNEL_0 BIT(4) #define V4L2_MBUS_CSI2_CHANNEL_1 BIT(5) #define V4L2_MBUS_CSI2_CHANNEL_2 BIT(6) #define V4L2_MBUS_CSI2_CHANNEL_3 BIT(7) -/* Does it support only continuous or also non-continuous clock mode */ +/* Clock non-continuous mode support. */ #define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK BIT(8) #define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK BIT(9) -- cgit v1.2.3 From b305dfe2e93434b12d438434461b709641f62af4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 20 Aug 2020 12:47:16 +0200 Subject: media: videodev2.h: RGB BT2020 and HSV are always full range The default RGB quantization range for BT.2020 is full range (just as for all the other RGB pixel encodings), not limited range. Update the V4L2_MAP_QUANTIZATION_DEFAULT macro and documentation accordingly. Also mention that HSV is always full range and cannot be limited range. When RGB BT2020 was introduced in V4L2 it was not clear whether it should be limited or full range, but full range is the right (and consistent) choice. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/colorspaces-defs.rst | 9 ++++----- .../userspace-api/media/v4l/colorspaces-details.rst | 5 ++--- include/uapi/linux/videodev2.h | 17 ++++++++--------- 3 files changed, 14 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/colorspaces-defs.rst b/Documentation/userspace-api/media/v4l/colorspaces-defs.rst index 01404e1f609a..4089f426258d 100644 --- a/Documentation/userspace-api/media/v4l/colorspaces-defs.rst +++ b/Documentation/userspace-api/media/v4l/colorspaces-defs.rst @@ -36,8 +36,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum :c:type:`v4l2_hsv_encoding` specifies which encoding is used. .. note:: The default R'G'B' quantization is full range for all - colorspaces except for BT.2020 which uses limited range R'G'B' - quantization. + colorspaces. HSV formats are always full range. .. tabularcolumns:: |p{6.7cm}|p{10.8cm}| @@ -169,8 +168,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum - Details * - ``V4L2_QUANTIZATION_DEFAULT`` - Use the default quantization encoding as defined by the - colorspace. This is always full range for R'G'B' (except for the - BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr. + colorspace. This is always full range for R'G'B' and HSV. + It is usually limited range for Y'CbCr. * - ``V4L2_QUANTIZATION_FULL_RANGE`` - Use the full range quantization encoding. I.e. the range [0…1] is mapped to [0…255] (with possible clipping to [1…254] to avoid the @@ -180,4 +179,4 @@ whole range, 0-255, dividing the angular value by 1.41. The enum * - ``V4L2_QUANTIZATION_LIM_RANGE`` - Use the limited range quantization encoding. I.e. the range [0…1] is mapped to [16…235]. Cb and Cr are mapped from [-0.5…0.5] to - [16…240]. + [16…240]. Limited Range cannot be used with HSV. diff --git a/Documentation/userspace-api/media/v4l/colorspaces-details.rst b/Documentation/userspace-api/media/v4l/colorspaces-details.rst index 300c5d2e7d0f..cf1b825ec34a 100644 --- a/Documentation/userspace-api/media/v4l/colorspaces-details.rst +++ b/Documentation/userspace-api/media/v4l/colorspaces-details.rst @@ -377,9 +377,8 @@ Colorspace BT.2020 (V4L2_COLORSPACE_BT2020) The :ref:`itu2020` standard defines the colorspace used by Ultra-high definition television (UHDTV). The default transfer function is ``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is -``V4L2_YCBCR_ENC_BT2020``. The default R'G'B' quantization is limited -range (!), and so is the default Y'CbCr quantization. The chromaticities -of the primary colors and the white reference are: +``V4L2_YCBCR_ENC_BT2020``. The default Y'CbCr quantization is limited range. +The chromaticities of the primary colors and the white reference are: diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index c7b70ff53bc1..4769628790da 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -375,9 +375,9 @@ enum v4l2_hsv_encoding { enum v4l2_quantization { /* - * The default for R'G'B' quantization is always full range, except - * for the BT2020 colorspace. For Y'CbCr the quantization is always - * limited range, except for COLORSPACE_JPEG: this is full range. + * The default for R'G'B' quantization is always full range. + * For Y'CbCr the quantization is always limited range, except + * for COLORSPACE_JPEG: this is full range. */ V4L2_QUANTIZATION_DEFAULT = 0, V4L2_QUANTIZATION_FULL_RANGE = 1, @@ -386,14 +386,13 @@ enum v4l2_quantization { /* * Determine how QUANTIZATION_DEFAULT should map to a proper quantization. - * This depends on whether the image is RGB or not, the colorspace and the - * Y'CbCr encoding. + * This depends on whether the image is RGB or not, the colorspace. + * The Y'CbCr encoding is not used anymore, but is still there for backwards + * compatibility. */ #define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb_or_hsv, colsp, ycbcr_enc) \ - (((is_rgb_or_hsv) && (colsp) == V4L2_COLORSPACE_BT2020) ? \ - V4L2_QUANTIZATION_LIM_RANGE : \ - (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ - V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) + (((is_rgb_or_hsv) || (colsp) == V4L2_COLORSPACE_JPEG) ? \ + V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE) /* * Deprecated names for opRGB colorspace (IEC 61966-2-5) -- cgit v1.2.3 From 45c2044ccbedd48bc2a8cddde9ce7e82f03d588c Mon Sep 17 00:00:00 2001 From: Peilin Ye Date: Fri, 21 Aug 2020 17:13:43 +0200 Subject: media: v4l2-tpg: Clamp hue in tpg_s_hue() Setting `hue` by calling tpg_s_hue() directly is risky, since it does not perform range check. Clamp `hue` to the valid range in tpg_s_hue(). Suggested-by: Hans Verkuil Signed-off-by: Peilin Ye Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/tpg/v4l2-tpg.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/tpg/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h index 0b0ddb87380e..181dcbe777f3 100644 --- a/include/media/tpg/v4l2-tpg.h +++ b/include/media/tpg/v4l2-tpg.h @@ -325,6 +325,7 @@ static inline void tpg_s_saturation(struct tpg_data *tpg, static inline void tpg_s_hue(struct tpg_data *tpg, s16 hue) { + hue = clamp_t(s16, hue, -128, 128); if (tpg->hue == hue) return; tpg->hue = hue; -- cgit v1.2.3 From f729ef5796d82a95758d9edc7eea5879a3a12b25 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 13 Jul 2020 13:30:42 +0200 Subject: media: videobuf2-v4l2.c: add vb2_video_unregister_device helper function If a driver calls (_)vb2_fop_release(), then such a driver should also call vb2_video_unregister_device() instead of video_unregister_device(). This helper will call vb2_queue_release() if a filehandle is marked as owner of the queue. This ensures that at unregister time any streaming is cancelled and all buffers are returned to userspace. This is very useful for complex drivers since this stops all streaming in all subdevs in the pipeline controlled by this video device. Otherwise this would be delayed until the owner filehandle is closed, which can be quite some time later. Bonus points for ordering the includes :-) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/videobuf2/videobuf2-v4l2.c | 51 ++++++++++++++++++++++--- include/media/videobuf2-v4l2.h | 17 +++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 30caad27281e..2068305ad458 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -14,21 +14,22 @@ * the Free Software Foundation. */ +#include #include +#include #include -#include +#include #include +#include #include -#include #include -#include -#include +#include +#include #include #include -#include #include -#include +#include #include @@ -1234,6 +1235,44 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, EXPORT_SYMBOL_GPL(vb2_fop_get_unmapped_area); #endif +void vb2_video_unregister_device(struct video_device *vdev) +{ + /* Check if vdev was ever registered at all */ + if (!vdev || !video_is_registered(vdev)) + return; + + /* + * Calling this function only makes sense if vdev->queue is set. + * If it is NULL, then just call video_unregister_device() instead. + */ + WARN_ON(!vdev->queue); + + /* + * Take a reference to the device since video_unregister_device() + * calls device_unregister(), but we don't want that to release + * the device since we want to clean up the queue first. + */ + get_device(&vdev->dev); + video_unregister_device(vdev); + if (vdev->queue && vdev->queue->owner) { + struct mutex *lock = vdev->queue->lock ? + vdev->queue->lock : vdev->lock; + + if (lock) + mutex_lock(lock); + vb2_queue_release(vdev->queue); + vdev->queue->owner = NULL; + if (lock) + mutex_unlock(lock); + } + /* + * Now we put the device, and in most cases this will release + * everything. + */ + put_device(&vdev->dev); +} +EXPORT_SYMBOL_GPL(vb2_video_unregister_device); + /* vb2_ops helpers. Only use if vq->lock is non-NULL. */ void vb2_ops_wait_prepare(struct vb2_queue *vq) diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index b7b5a9cb5a28..c203047eb834 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -23,6 +23,8 @@ #error VB2_MAX_PLANES != VIDEO_MAX_PLANES #endif +struct video_device; + /** * struct vb2_v4l2_buffer - video buffer information for v4l2. * @@ -319,6 +321,21 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); #endif +/** + * vb2_video_unregister_device - unregister the video device and release queue + * + * @vdev: pointer to &struct video_device + * + * If the driver uses vb2_fop_release()/_vb2_fop_release(), then it should use + * vb2_video_unregister_device() instead of video_unregister_device(). + * + * This function will call video_unregister_device() and then release the + * vb2_queue if streaming is in progress. This will stop streaming and + * this will simplify the unbind sequence since after this call all subdevs + * will have stopped streaming as well. + */ +void vb2_video_unregister_device(struct video_device *vdev); + /** * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue * -- cgit v1.2.3 From cf5153e4338c4cca655a4a4eff6d54c6a0adcdb7 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Wed, 12 Aug 2020 02:27:19 +0200 Subject: media: gpu: host1x: mipi: Keep MIPI clock enabled and mutex locked till calibration done With the split of MIPI calibration into tegra_mipi_calibrate() and tegra_mipi_wait(), MIPI clock is not kept enabled and mutex is not locked till the calibration is done. So, this patch keeps MIPI clock enabled and mutex locked after triggering start of calibration till its done. To let calibration process go through its finite sequence codes before calibration logic waiting for pads idle state added wait time of 75usec to make sure it sees idle state to apply the results. This patch renames tegra_mipi_calibrate() as tegra_mipi_start_calibration() and tegra_mipi_wait() as tegra_mipi_finish_calibration() to be inline with their usage. Reviewed-by: Dmitry Osipenko Signed-off-by: Sowjanya Komatineni Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/gpu/drm/tegra/dsi.c | 4 ++-- drivers/gpu/host1x/mipi.c | 22 ++++++++++------------ include/linux/host1x.h | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 3820e8dff14b..a7864e91fc0b 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -694,11 +694,11 @@ static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi) DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3); tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3); - err = tegra_mipi_calibrate(dsi->mipi); + err = tegra_mipi_start_calibration(dsi->mipi); if (err < 0) return err; - return tegra_mipi_wait(dsi->mipi); + return tegra_mipi_finish_calibration(dsi->mipi); } static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk, diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index e606464aa43c..2efe12dde8bc 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -293,19 +293,13 @@ int tegra_mipi_disable(struct tegra_mipi_device *dev) } EXPORT_SYMBOL(tegra_mipi_disable); -int tegra_mipi_wait(struct tegra_mipi_device *device) +int tegra_mipi_finish_calibration(struct tegra_mipi_device *device) { struct tegra_mipi *mipi = device->mipi; void __iomem *status_reg = mipi->regs + (MIPI_CAL_STATUS << 2); u32 value; int err; - err = clk_enable(device->mipi->clk); - if (err < 0) - return err; - - mutex_lock(&device->mipi->lock); - err = readl_relaxed_poll_timeout(status_reg, value, !(value & MIPI_CAL_STATUS_ACTIVE) && (value & MIPI_CAL_STATUS_DONE), 50, @@ -315,9 +309,9 @@ int tegra_mipi_wait(struct tegra_mipi_device *device) return err; } -EXPORT_SYMBOL(tegra_mipi_wait); +EXPORT_SYMBOL(tegra_mipi_finish_calibration); -int tegra_mipi_calibrate(struct tegra_mipi_device *device) +int tegra_mipi_start_calibration(struct tegra_mipi_device *device) { const struct tegra_mipi_soc *soc = device->mipi->soc; unsigned int i; @@ -381,12 +375,16 @@ int tegra_mipi_calibrate(struct tegra_mipi_device *device) value |= MIPI_CAL_CTRL_START; tegra_mipi_writel(device->mipi, value, MIPI_CAL_CTRL); - mutex_unlock(&device->mipi->lock); - clk_disable(device->mipi->clk); + /* + * Wait for min 72uS to let calibration logic finish calibration + * sequence codes before waiting for pads idle state to apply the + * results. + */ + usleep_range(75, 80); return 0; } -EXPORT_SYMBOL(tegra_mipi_calibrate); +EXPORT_SYMBOL(tegra_mipi_start_calibration); static const struct tegra_mipi_pad tegra114_mipi_pads[] = { { .data = MIPI_CAL_CONFIG_CSIA }, diff --git a/include/linux/host1x.h b/include/linux/host1x.h index 20c885d0bddc..ce59a6a6a008 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -333,7 +333,7 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device, void tegra_mipi_free(struct tegra_mipi_device *device); int tegra_mipi_enable(struct tegra_mipi_device *device); int tegra_mipi_disable(struct tegra_mipi_device *device); -int tegra_mipi_calibrate(struct tegra_mipi_device *device); -int tegra_mipi_wait(struct tegra_mipi_device *device); +int tegra_mipi_start_calibration(struct tegra_mipi_device *device); +int tegra_mipi_finish_calibration(struct tegra_mipi_device *device); #endif -- cgit v1.2.3 From 911ea8ec42dea0e28083a6e92b1b4a5a0ad5acca Mon Sep 17 00:00:00 2001 From: Pi-Hsun Shih Date: Fri, 14 Aug 2020 09:11:40 +0200 Subject: media: v4l2-mem2mem: add v4l2_m2m_suspend, v4l2_m2m_resume Add two functions that can be used to stop new jobs from being queued / continue running queued job. This can be used while a driver using m2m helper is going to suspend / wake up from resume, and can ensure that there's no job running in suspend process. Signed-off-by: Pi-Hsun Shih Signed-off-by: Jerry-ch Chen Reviewed-by: Tomasz Figa Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 41 ++++++++++++++++++++++++++++++++++ include/media/v4l2-mem2mem.h | 22 ++++++++++++++++++ 2 files changed, 63 insertions(+) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 95a8f2dc5341..6a80240e9228 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -43,6 +43,10 @@ module_param(debug, bool, 0644); #define TRANS_ABORT (1 << 2) +/* The job queue is not running new jobs */ +#define QUEUE_PAUSED (1 << 0) + + /* Offset base for buffers on the destination queue - used to distinguish * between source and destination buffers when mmapping - they receive the same * offsets but for different queues */ @@ -84,6 +88,7 @@ static const char * const m2m_entity_name[] = { * @job_queue: instances queued to run * @job_spinlock: protects job_queue * @job_work: worker to run queued jobs. + * @job_queue_flags: flags of the queue status, %QUEUE_PAUSED. * @m2m_ops: driver callbacks */ struct v4l2_m2m_dev { @@ -101,6 +106,7 @@ struct v4l2_m2m_dev { struct list_head job_queue; spinlock_t job_spinlock; struct work_struct job_work; + unsigned long job_queue_flags; const struct v4l2_m2m_ops *m2m_ops; }; @@ -263,6 +269,12 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) return; } + if (m2m_dev->job_queue_flags & QUEUE_PAUSED) { + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + dprintk("Running new jobs is paused\n"); + return; + } + m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue, struct v4l2_m2m_ctx, queue); m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING; @@ -504,6 +516,7 @@ void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, if (WARN_ON(!src_buf || !dst_buf)) goto unlock; + v4l2_m2m_buf_done(src_buf, state); dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; if (!dst_buf->is_held) { v4l2_m2m_dst_buf_remove(m2m_ctx); @@ -528,6 +541,34 @@ unlock: } EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish); +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev) +{ + unsigned long flags; + struct v4l2_m2m_ctx *curr_ctx; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + m2m_dev->job_queue_flags |= QUEUE_PAUSED; + curr_ctx = m2m_dev->curr_ctx; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + + if (curr_ctx) + wait_event(curr_ctx->finished, + !(curr_ctx->job_flags & TRANS_RUNNING)); +} +EXPORT_SYMBOL(v4l2_m2m_suspend); + +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&m2m_dev->job_spinlock, flags); + m2m_dev->job_queue_flags &= ~QUEUE_PAUSED; + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); + + v4l2_m2m_try_run(m2m_dev); +} +EXPORT_SYMBOL(v4l2_m2m_resume); + int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs) { diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 98753f00df7e..5a91b548ecc0 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -304,6 +304,28 @@ v4l2_m2m_is_last_draining_src_buf(struct v4l2_m2m_ctx *m2m_ctx, void v4l2_m2m_last_buffer_done(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf); +/** + * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job + * to finish + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Called by a driver in the suspend hook. Stop new jobs from being run, and + * wait for current running job to finish. + */ +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev); + +/** + * v4l2_m2m_resume() - resume job running and try to run a queued job + * + * @m2m_dev: opaque pointer to the internal data to handle M2M context + * + * Called by a driver in the resume hook. This reverts the operation of + * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if + * there is any. + */ +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev); + /** * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer * -- cgit v1.2.3 From 5d0d7b9009feb3b411814b9c1b7dddabbb10a5fb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Aug 2020 15:36:02 +0200 Subject: media: cec: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/core/cec-core.c | 27 ++++++++------------------- include/media/cec.h | 2 -- 2 files changed, 8 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index c599cd94dd62..562792f545ac 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -359,27 +359,16 @@ int cec_register_adapter(struct cec_adapter *adap, if (!top_cec_dir) return 0; - adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), top_cec_dir); - if (IS_ERR_OR_NULL(adap->cec_dir)) { - pr_warn("cec-%s: Failed to create debugfs dir\n", adap->name); - return 0; - } - adap->status_file = debugfs_create_devm_seqfile(&adap->devnode.dev, - "status", adap->cec_dir, cec_adap_status); - if (IS_ERR_OR_NULL(adap->status_file)) { - pr_warn("cec-%s: Failed to create status file\n", adap->name); - debugfs_remove_recursive(adap->cec_dir); - adap->cec_dir = NULL; - return 0; - } + adap->cec_dir = debugfs_create_dir(dev_name(&adap->devnode.dev), + top_cec_dir); + + debugfs_create_devm_seqfile(&adap->devnode.dev, "status", adap->cec_dir, + cec_adap_status); + if (!adap->ops->error_inj_show || !adap->ops->error_inj_parse_line) return 0; - adap->error_inj_file = debugfs_create_file("error-inj", 0644, - adap->cec_dir, adap, - &cec_error_inj_fops); - if (IS_ERR_OR_NULL(adap->error_inj_file)) - pr_warn("cec-%s: Failed to create error-inj file\n", - adap->name); + debugfs_create_file("error-inj", 0644, adap->cec_dir, adap, + &cec_error_inj_fops); #endif return 0; } diff --git a/include/media/cec.h b/include/media/cec.h index c48b5f2e4b50..cd35ae6b7560 100644 --- a/include/media/cec.h +++ b/include/media/cec.h @@ -248,8 +248,6 @@ struct cec_adapter { #endif struct dentry *cec_dir; - struct dentry *status_file; - struct dentry *error_inj_file; u32 sequence; -- cgit v1.2.3 From e000e1fa4bdbd783149e7f97cf3be61e1c0bab8c Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Tue, 25 Aug 2020 05:52:27 +0200 Subject: media: uapi: h264: Update reference lists When dealing with interlaced frames, reference lists must tell if each particular reference is meant for top or bottom field. This info is currently not provided at all in the H264 related controls. Change reference lists to hold a structure, which specifies an index into the DPB array and the field/frame specification for the picture. Currently the only user of these lists is Cedrus which is just compile fixed here. Actual usage of will come in a following commit. Signed-off-by: Jernej Skrabec Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 44 +++++++++++++++++++++- drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 6 +-- include/media/h264-ctrls.h | 21 ++++++++--- 3 files changed, 60 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index d0d506a444b1..df1c4fc5cb48 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1843,10 +1843,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u32 - ``slice_group_change_cycle`` - - * - __u8 + * - struct :c:type:`v4l2_h264_reference` - ``ref_pic_list0[32]`` - Reference picture list after applying the per-slice modifications - * - __u8 + * - struct :c:type:`v4l2_h264_reference` - ``ref_pic_list1[32]`` - Reference picture list after applying the per-slice modifications * - __u32 @@ -1926,6 +1926,46 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``chroma_offset[32][2]`` - +``Picture Reference`` + +.. c:type:: v4l2_h264_reference + +.. cssclass:: longtable + +.. flat-table:: struct v4l2_h264_reference + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u8 + - ``fields`` + - Specifies how the picture is referenced. See :ref:`Reference Fields ` + * - __u8 + - ``index`` + - Index into the :c:type:`v4l2_ctrl_h264_decode_params`.dpb array. + +.. _h264_ref_fields: + +``Reference Fields`` + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - ``V4L2_H264_TOP_FIELD_REF`` + - 0x1 + - The top field in field pair is used for short-term reference. + * - ``V4L2_H264_BOTTOM_FIELD_REF`` + - 0x2 + - The bottom field in field pair is used for short-term reference. + * - ``V4L2_H264_FRAME_REF`` + - 0x3 + - The frame (or the top/bottom fields, if it's a field pair) + is used for short-term reference. + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)`` Specifies the decode parameters (as extracted from the bitstream) for the associated H264 slice data. This includes the necessary diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index 54ee2aa423e2..cce527bbdf86 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -166,8 +166,8 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, struct cedrus_run *run, - const u8 *ref_list, u8 num_ref, - enum cedrus_h264_sram_off sram) + const struct v4l2_h264_reference *ref_list, + u8 num_ref, enum cedrus_h264_sram_off sram) { const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params; struct vb2_queue *cap_q; @@ -188,7 +188,7 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx, int buf_idx; u8 dpb_idx; - dpb_idx = ref_list[i]; + dpb_idx = ref_list[i].index; dpb = &decode->dpb[dpb_idx]; if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 080fd1293c42..3c613b84e5ae 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -19,6 +19,8 @@ */ #define V4L2_H264_NUM_DPB_ENTRIES 16 +#define V4L2_H264_REF_LIST_LEN (2 * V4L2_H264_NUM_DPB_ENTRIES) + /* Our pixel format isn't stable at the moment */ #define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */ @@ -140,6 +142,17 @@ struct v4l2_h264_pred_weight_table { #define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04 #define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08 +#define V4L2_H264_TOP_FIELD_REF 0x1 +#define V4L2_H264_BOTTOM_FIELD_REF 0x2 +#define V4L2_H264_FRAME_REF 0x3 + +struct v4l2_h264_reference { + __u8 fields; + + /* Index into v4l2_ctrl_h264_decode_params.dpb[] */ + __u8 index; +}; + struct v4l2_ctrl_h264_slice_params { /* Size in bytes, including header */ __u32 size; @@ -178,12 +191,8 @@ struct v4l2_ctrl_h264_slice_params { __u8 num_ref_idx_l1_active_minus1; __u32 slice_group_change_cycle; - /* - * Entries on each list are indices into - * v4l2_ctrl_h264_decode_params.dpb[]. - */ - __u8 ref_pic_list0[32]; - __u8 ref_pic_list1[32]; + struct v4l2_h264_reference ref_pic_list0[V4L2_H264_REF_LIST_LEN]; + struct v4l2_h264_reference ref_pic_list1[V4L2_H264_REF_LIST_LEN]; __u32 flags; }; -- cgit v1.2.3 From eb44c6c9c236b1568985816254faf520fde21776 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:29 +0200 Subject: media: uapi: h264: Split prediction weight parameters The prediction weight parameters are only required under certain conditions, which depend on slice header parameters. As specified in section 7.3.3 Slice header syntax, the prediction weight table is present if: ((weighted_pred_flag && (slice_type == P || slice_type == SP)) || \ (weighted_bipred_idc == 1 && slice_type == B)) Given its size, it makes sense to move this table to its control, so applications can avoid passing it if the slice doesn't specify it. Before this change struct v4l2_ctrl_h264_slice_params was 960 bytes. With this change, it's 188 bytes and struct v4l2_ctrl_h264_pred_weight is 772 bytes. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 19 ++++++++++++------- drivers/media/v4l2-core/v4l2-ctrls.c | 8 ++++++++ drivers/staging/media/sunxi/cedrus/cedrus.c | 7 +++++++ drivers/staging/media/sunxi/cedrus/cedrus.h | 1 + drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 2 ++ drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 12 +++--------- include/media/h264-ctrls.h | 12 ++++++++++-- include/media/v4l2-ctrls.h | 2 ++ 8 files changed, 45 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 2cce412f5be1..9e4421a7c6a6 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1879,18 +1879,23 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - 0x00000008 - -``Prediction Weight Table`` +``V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (struct)`` + Prediction weight table defined according to :ref:`h264`, + section 7.4.3.2 "Prediction Weight Table Semantics". + The prediction weight table must be passed by applications + under the conditions explained in section 7.3.3 "Slice header + syntax". - The bitstream parameters are defined according to :ref:`h264`, - section 7.4.3.2 "Prediction Weight Table Semantics". For further - documentation, refer to the above specification, unless there is - an explicit comment stating otherwise. + .. note:: + + This compound control is not yet part of the public kernel API and + it is expected to change. -.. c:type:: v4l2_h264_pred_weight_table +.. c:type:: v4l2_ctrl_h264_pred_weights .. cssclass:: longtable -.. flat-table:: struct v4l2_h264_pred_weight_table +.. flat-table:: struct v4l2_ctrl_h264_pred_weights :header-rows: 0 :stub-columns: 0 :widths: 1 1 2 diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 3f3fbcd60cc6..76c8dc8fb31c 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -897,6 +897,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters"; case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE: return "H264 Decode Mode"; case V4L2_CID_MPEG_VIDEO_H264_START_CODE: return "H264 Start Code"; + case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS: return "H264 Prediction Weight Table"; case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL: return "MPEG2 Level"; case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE: return "MPEG2 Profile"; case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value"; @@ -1412,6 +1413,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS; break; + case V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS: + *type = V4L2_CTRL_TYPE_H264_PRED_WEIGHTS; + break; case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: *type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER; break; @@ -1790,6 +1794,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, case V4L2_CTRL_TYPE_H264_SPS: case V4L2_CTRL_TYPE_H264_PPS: case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: + case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: break; @@ -2553,6 +2558,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: elem_size = sizeof(struct v4l2_ctrl_h264_decode_params); break; + case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: + elem_size = sizeof(struct v4l2_ctrl_h264_pred_weights); + break; case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header); break; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index bc27f9430eeb..826324faad7e 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -78,6 +78,13 @@ static const struct cedrus_control cedrus_controls[] = { .codec = CEDRUS_CODEC_H264, .required = true, }, + { + .cfg = { + .id = V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS, + }, + .codec = CEDRUS_CODEC_H264, + .required = false, + }, { .cfg = { .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 96765555ab8a..93c843ae14bb 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -62,6 +62,7 @@ struct cedrus_h264_run { const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; const struct v4l2_ctrl_h264_slice_params *slice_params; const struct v4l2_ctrl_h264_sps *sps; + const struct v4l2_ctrl_h264_pred_weights *pred_weights; }; struct cedrus_mpeg2_run { diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index 58c48e4fdfe9..6385026d1b6b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -57,6 +57,8 @@ void cedrus_device_run(void *priv) V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS); run.h264.sps = cedrus_find_control_data(ctx, V4L2_CID_MPEG_VIDEO_H264_SPS); + run.h264.pred_weights = cedrus_find_control_data(ctx, + V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS); break; case V4L2_PIX_FMT_HEVC_SLICE: diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index cce527bbdf86..d5636dbbb622 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -256,10 +256,8 @@ static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx, static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx, struct cedrus_run *run) { - const struct v4l2_ctrl_h264_slice_params *slice = - run->h264.slice_params; - const struct v4l2_h264_pred_weight_table *pred_weight = - &slice->pred_weight_table; + const struct v4l2_ctrl_h264_pred_weights *pred_weight = + run->h264.pred_weights; struct cedrus_dev *dev = ctx->dev; int i, j, k; @@ -367,11 +365,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, cedrus_skip_bits(dev, slice->header_bit_size); - if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && - (slice->slice_type == V4L2_H264_SLICE_TYPE_P || - slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) || - (pps->weighted_bipred_idc == 1 && - slice->slice_type == V4L2_H264_SLICE_TYPE_B)) + if (V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice)) cedrus_write_pred_weight_table(ctx, run); if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) || diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 3c613b84e5ae..31c6f4c5963b 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -36,6 +36,7 @@ #define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004) #define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (V4L2_CID_MPEG_BASE+1005) #define V4L2_CID_MPEG_VIDEO_H264_START_CODE (V4L2_CID_MPEG_BASE+1006) +#define V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (V4L2_CID_MPEG_BASE+1007) /* enum v4l2_ctrl_type type values */ #define V4L2_CTRL_TYPE_H264_SPS 0x0110 @@ -43,6 +44,7 @@ #define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112 #define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113 #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114 +#define V4L2_CTRL_TYPE_H264_PRED_WEIGHTS 0x0115 enum v4l2_mpeg_video_h264_decode_mode { V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED, @@ -125,7 +127,14 @@ struct v4l2_h264_weight_factors { __s16 chroma_offset[32][2]; }; -struct v4l2_h264_pred_weight_table { +#define V4L2_H264_CTRL_PRED_WEIGHTS_REQUIRED(pps, slice) \ + ((((pps)->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) && \ + ((slice)->slice_type == V4L2_H264_SLICE_TYPE_P || \ + (slice)->slice_type == V4L2_H264_SLICE_TYPE_SP)) || \ + ((pps)->weighted_bipred_idc == 1 && \ + (slice)->slice_type == V4L2_H264_SLICE_TYPE_B)) + +struct v4l2_ctrl_h264_pred_weights { __u16 luma_log2_weight_denom; __u16 chroma_log2_weight_denom; struct v4l2_h264_weight_factors weight_factors[2]; @@ -175,7 +184,6 @@ struct v4l2_ctrl_h264_slice_params { __s32 delta_pic_order_cnt0; __s32 delta_pic_order_cnt1; - struct v4l2_h264_pred_weight_table pred_weight_table; /* Size in bits of dec_ref_pic_marking() syntax element. */ __u32 dec_ref_pic_marking_bit_size; /* Size in bits of pic order count syntax. */ diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index f40e2cbb21d3..cb25f345e9ad 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -51,6 +51,7 @@ struct video_device; * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix. * @p_h264_slice_params: Pointer to a struct v4l2_ctrl_h264_slice_params. * @p_h264_decode_params: Pointer to a struct v4l2_ctrl_h264_decode_params. + * @p_h264_pred_weights: Pointer to a struct v4l2_ctrl_h264_pred_weights. * @p_vp8_frame_header: Pointer to a VP8 frame header structure. * @p_hevc_sps: Pointer to an HEVC sequence parameter set structure. * @p_hevc_pps: Pointer to an HEVC picture parameter set structure. @@ -74,6 +75,7 @@ union v4l2_ctrl_ptr { struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix; struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; struct v4l2_ctrl_h264_decode_params *p_h264_decode_params; + struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights; struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; struct v4l2_ctrl_hevc_sps *p_hevc_sps; struct v4l2_ctrl_hevc_pps *p_hevc_pps; -- cgit v1.2.3 From 4245232fa6ca58f79710732bd16cefe78b8b8bc4 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:31 +0200 Subject: media: uapi: h264: Increase size of 'first_mb_in_slice' field Slice header syntax element 'first_mb_in_slice' can point to the last macroblock, currently the field can only reference 65536 macroblocks which is insufficient for 8K videos. Although unlikely, a 8192x4320 video (where macroblocks are 16x16), would contain 138240 macroblocks on a frame. As per the H264 specification, 'first_mb_in_slice' can be up to PicSizeInMbs - 1, so increase the size of the field to 32-bits. Note that v4l2_ctrl_h264_slice_params struct will be modified in a follow-up commit, and so we defer its 64-bit padding. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 2 +- include/media/h264-ctrls.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 591d3d35c429..a417a1ae50d5 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1774,7 +1774,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u32 - ``header_bit_size`` - - * - __u16 + * - __u32 - ``first_mb_in_slice`` - * - __u8 diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 31c6f4c5963b..9a6722edf004 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -172,7 +172,8 @@ struct v4l2_ctrl_h264_slice_params { /* Offset in bits to slice_data() from the beginning of this slice. */ __u32 header_bit_size; - __u16 first_mb_in_slice; + __u32 first_mb_in_slice; + __u8 slice_type; __u8 pic_parameter_set_id; __u8 colour_plane_id; -- cgit v1.2.3 From c02ff21952a6a19ca375b9dc4f9a5609616a82b8 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:32 +0200 Subject: media: uapi: h264: Clean DPB entry interface As discussed recently, the current interface for the Decoded Picture Buffer is not enough to properly support field coding. This commit introduces enough semantics to support frame and field coding, and to signal how DPB entries are "used for reference". Reserved fields will be added by a follow-up commit. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 24 +++++++--------------- drivers/media/v4l2-core/v4l2-h264.c | 4 ++-- drivers/staging/media/rkvdec/rkvdec-h264.c | 17 +++++++-------- include/media/h264-ctrls.h | 2 +- 4 files changed, 19 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index a417a1ae50d5..49febae8fd0f 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -2057,6 +2057,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u16 - ``pic_num`` - + * - __u8 + - ``fields`` + - Specifies how the DPB entry is referenced. See :ref:`Reference Fields ` * - __s32 - ``top_field_order_cnt`` - @@ -2080,29 +2083,16 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID`` - 0x00000001 - - The DPB entry is valid and should be considered + - The DPB entry is valid (non-empty) and should be considered. * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE`` - 0x00000002 - - The DPB entry is currently being used as a reference frame + - The DPB entry is used for reference. * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM`` - 0x00000004 - - The DPB entry is a long term reference frame + - The DPB entry is used for long-term reference. * - ``V4L2_H264_DPB_ENTRY_FLAG_FIELD`` - 0x00000008 - - The DPB entry is a field reference, which means only one of the field - will be used when decoding the new frame/field. When not set the DPB - entry is a frame reference (both fields will be used). Note that this - flag does not say anything about the number of fields contained in the - reference frame, it just describes the one used to decode the new - field/frame - * - ``V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD`` - - 0x00000010 - - The DPB entry is a bottom field reference (only the bottom field of the - reference frame is needed to decode the new frame/field). Only valid if - V4L2_H264_DPB_ENTRY_FLAG_FIELD is set. When - V4L2_H264_DPB_ENTRY_FLAG_FIELD is set but - V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD is not, that means the - DPB entry is a top field reference + - The DPB entry is a single field or a complementary field pair. ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)`` Specifies the decoding mode to use. Currently exposes slice-based and diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c index edf6225f0522..f4742408436b 100644 --- a/drivers/media/v4l2-core/v4l2-h264.c +++ b/drivers/media/v4l2-core/v4l2-h264.c @@ -66,10 +66,10 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, else b->refs[i].frame_num = dpb[i].frame_num; - if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) + if (dpb[i].fields == V4L2_H264_FRAME_REF) pic_order_count = min(dpb[i].top_field_order_cnt, dpb[i].bottom_field_order_cnt); - else if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD) + else if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) pic_order_count = dpb[i].bottom_field_order_cnt; else pic_order_count = dpb[i].top_field_order_cnt; diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c index 7b66e2743a4f..d1f2715f30ae 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -949,16 +949,17 @@ static void config_registers(struct rkvdec_ctx *ctx, for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { struct vb2_buffer *vb_buf = get_ref_buf(ctx, run, i); - refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0) | - RKVDEC_COLMV_USED_FLAG_REF; + refer_addr = vb2_dma_contig_plane_dma_addr(vb_buf, 0); - if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) - refer_addr |= RKVDEC_TOPFIELD_USED_REF | - RKVDEC_BOTFIELD_USED_REF; - else if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD) - refer_addr |= RKVDEC_BOTFIELD_USED_REF; - else + if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) + refer_addr |= RKVDEC_COLMV_USED_FLAG_REF; + if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD) + refer_addr |= RKVDEC_FIELD_REF; + + if (dpb[i].fields & V4L2_H264_TOP_FIELD_REF) refer_addr |= RKVDEC_TOPFIELD_USED_REF; + if (dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF) + refer_addr |= RKVDEC_BOTFIELD_USED_REF; writel_relaxed(dpb[i].top_field_order_cnt, rkvdec->regs + poc_reg_tbl_top_field[i]); diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 9a6722edf004..0529e75cce5f 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -210,12 +210,12 @@ struct v4l2_ctrl_h264_slice_params { #define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02 #define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04 #define V4L2_H264_DPB_ENTRY_FLAG_FIELD 0x08 -#define V4L2_H264_DPB_ENTRY_FLAG_BOTTOM_FIELD 0x10 struct v4l2_h264_dpb_entry { __u64 reference_ts; __u16 frame_num; __u16 pic_num; + __u8 fields; /* Note that field is indicated by v4l2_buffer.field */ __s32 top_field_order_cnt; __s32 bottom_field_order_cnt; -- cgit v1.2.3 From f9879eb378295e8a912d2d10c872c45f3e19421b Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:33 +0200 Subject: media: uapi: h264: Increase size of DPB entry pic_num DPB entry PicNum maximum value is 2*MaxFrameNum for interlaced content (field_pic_flag=1). As specified, MaxFrameNum is 2^(log2_max_frame_num_minus4 + 4) and log2_max_frame_num_minus4 is in the range of 0 to 12, which means pic_num should be a 32-bit field. The v4l2_h264_dpb_entry struct needs to be padded to avoid a hole, which might be also useful to allow future uAPI extensions. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 9 ++++++--- drivers/media/v4l2-core/v4l2-ctrls.c | 13 +++++++++++++ include/media/h264-ctrls.h | 3 ++- include/media/v4l2-h264.h | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 49febae8fd0f..3808c46718ad 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -2051,15 +2051,18 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()` function to convert the struct :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64. - * - __u16 - - ``frame_num`` + * - __u32 + - ``pic_num`` - * - __u16 - - ``pic_num`` + - ``frame_num`` - * - __u8 - ``fields`` - Specifies how the DPB entry is referenced. See :ref:`Reference Fields ` + * - __u8 + - ``reserved[5]`` + - Applications and drivers must set this to zero. * - __s32 - ``top_field_order_cnt`` - diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 76c8dc8fb31c..b9457789fa55 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1725,6 +1725,8 @@ static void std_log(const struct v4l2_ctrl *ctrl) #define zero_padding(s) \ memset(&(s).padding, 0, sizeof((s).padding)) +#define zero_reserved(s) \ + memset(&(s).reserved, 0, sizeof((s).reserved)) /* * Compound controls validation requires setting unused fields/flags to zero @@ -1735,6 +1737,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, { struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; + struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; struct v4l2_ctrl_hevc_sps *p_hevc_sps; struct v4l2_ctrl_hevc_pps *p_hevc_pps; struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params; @@ -1796,7 +1799,17 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: + break; + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: + p_h264_dec_params = p; + + for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) { + struct v4l2_h264_dpb_entry *dpb_entry = + &p_h264_dec_params->dpb[i]; + + zero_reserved(*dpb_entry); + } break; case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 0529e75cce5f..91f6f0d43e11 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -213,9 +213,10 @@ struct v4l2_ctrl_h264_slice_params { struct v4l2_h264_dpb_entry { __u64 reference_ts; + __u32 pic_num; __u16 frame_num; - __u16 pic_num; __u8 fields; + __u8 reserved[5]; /* Note that field is indicated by v4l2_buffer.field */ __s32 top_field_order_cnt; __s32 bottom_field_order_cnt; diff --git a/include/media/v4l2-h264.h b/include/media/v4l2-h264.h index bc9ebb560ccf..1a5f26fc2a9a 100644 --- a/include/media/v4l2-h264.h +++ b/include/media/v4l2-h264.h @@ -33,7 +33,7 @@ struct v4l2_h264_reflist_builder { struct { s32 pic_order_count; int frame_num; - u16 pic_num; + u32 pic_num; u16 longterm : 1; } refs[V4L2_H264_NUM_DPB_ENTRIES]; s32 cur_pic_order_count; -- cgit v1.2.3 From f6f0d58edfa77d18c41777740958f467de615728 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:34 +0200 Subject: media: uapi: h264: Drop SLICE_PARAMS 'size' field The SLICE_PARAMS control is intended for slice-based devices. In this mode, the OUTPUT buffer contains a single slice, and so the buffer's plane payload size can be used to query the slice size. To reduce the API surface drop the size from the SLICE_PARAMS control. A follow-up change will remove other members in SLICE_PARAMS so we don't need to add padding fields here. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 3 --- drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 7 +++---- include/media/h264-ctrls.h | 3 --- 3 files changed, 3 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 3808c46718ad..e74a2531ab67 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1760,9 +1760,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :stub-columns: 0 :widths: 1 1 2 - * - __u32 - - ``size`` - - * - __u32 - ``start_byte_offset`` Offset (in bytes) from the beginning of the OUTPUT buffer to the start diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index d5636dbbb622..7d9bd5860a1b 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -324,17 +324,16 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, struct vb2_buffer *src_buf = &run->src->vb2_buf; struct cedrus_dev *dev = ctx->dev; dma_addr_t src_buf_addr; - u32 len = slice->size * 8; + size_t slice_bytes = vb2_get_plane_payload(src_buf, 0); unsigned int pic_width_in_mbs; bool mbaff_pic; u32 reg; - cedrus_write(dev, VE_H264_VLD_LEN, len); + cedrus_write(dev, VE_H264_VLD_LEN, slice_bytes * 8); cedrus_write(dev, VE_H264_VLD_OFFSET, 0); src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); - cedrus_write(dev, VE_H264_VLD_END, - src_buf_addr + vb2_get_plane_payload(src_buf, 0)); + cedrus_write(dev, VE_H264_VLD_END, src_buf_addr + slice_bytes); cedrus_write(dev, VE_H264_VLD_ADDR, VE_H264_VLD_ADDR_VAL(src_buf_addr) | VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID | diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 91f6f0d43e11..77d0ec51ae43 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -163,9 +163,6 @@ struct v4l2_h264_reference { }; struct v4l2_ctrl_h264_slice_params { - /* Size in bytes, including header */ - __u32 size; - /* Offset in bytes to the start of slice in the OUTPUT buffer. */ __u32 start_byte_offset; -- cgit v1.2.3 From 2287c5e65cbcc99633c412dbfe1d39bd9f7bf1ce Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:35 +0200 Subject: media: uapi: h264: Clarify SLICE_BASED mode Currently, the SLICE_BASED and FRAME_BASED modes documentation is misleading and not matching the intended use-cases. Drop non-required fields SLICE_PARAMS 'start_byte_offset' and DECODE_PARAMS 'num_slices' and clarify the decoding modes in the documentation. On SLICE_BASED mode, a single slice is expected per OUTPUT buffer, and therefore 'start_byte_offset' is not needed (since the offset to the slice is the start of the buffer). This mode requires the use of CAPTURE buffer holding, and so the number of slices shall not be required. On FRAME_BASED mode, the devices are expected to take care of slice parsing. Neither SLICE_PARAMS are required (and shouldn't be exposed by frame-based drivers), nor the number of slices. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 39 ++++++---------------- include/media/h264-ctrls.h | 4 --- 2 files changed, 10 insertions(+), 33 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index e74a2531ab67..304b6012b358 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1748,9 +1748,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - This compound control is not yet part of the public kernel API and it is expected to change. - This structure is expected to be passed as an array, with one - entry for each slice included in the bitstream buffer. - .. c:type:: v4l2_ctrl_h264_slice_params .. cssclass:: longtable @@ -1760,17 +1757,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :stub-columns: 0 :widths: 1 1 2 - * - __u32 - - ``start_byte_offset`` - Offset (in bytes) from the beginning of the OUTPUT buffer to the start - of the slice. If the slice starts with a start code, then this is the - offset to such start code. When operating in slice-based decoding mode - (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should - be set to 0. When operating in frame-based decoding mode, this field - should be 0 for the first slice. * - __u32 - ``header_bit_size`` - - + - Offset in bits to slice_data() from the beginning of this slice. * - __u32 - ``first_mb_in_slice`` - @@ -1998,12 +1987,6 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - struct :c:type:`v4l2_h264_dpb_entry` - ``dpb[16]`` - - * - __u16 - - ``num_slices`` - - Number of slices needed to decode the current frame/field. When - operating in slice-based decoding mode (see - :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field - should always be set to one. * - __u16 - ``nal_ref_idc`` - NAL reference ID value coming from the NAL Unit header @@ -2121,22 +2104,20 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED`` - 0 - Decoding is done at the slice granularity. - In this mode, ``num_slices`` field in struct - :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1, - and ``start_byte_offset`` in struct - :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0. The OUTPUT buffer must contain a single slice. + When this mode is selected, the ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` + control shall be set. When multiple slices compose a frame, + use of ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` flag + is required. * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED`` - 1 - - Decoding is done at the frame granularity. - In this mode, ``num_slices`` field in struct - :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number - of slices in the frame, and ``start_byte_offset`` in struct - :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly - for each slice. For the first slice, ``start_byte_offset`` should - be zero. + - Decoding is done at the frame granularity, The OUTPUT buffer must contain all slices needed to decode the frame. The OUTPUT buffer must also contain both fields. + This mode will be supported by devices that + parse the slice(s) header(s) in hardware. When this mode is + selected, the ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` + control shall not be set. ``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)`` Specifies the H264 slice start code expected for each slice. diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 77d0ec51ae43..e4cae02a765f 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -163,9 +163,6 @@ struct v4l2_h264_reference { }; struct v4l2_ctrl_h264_slice_params { - /* Offset in bytes to the start of slice in the OUTPUT buffer. */ - __u32 start_byte_offset; - /* Offset in bits to slice_data() from the beginning of this slice. */ __u32 header_bit_size; @@ -224,7 +221,6 @@ struct v4l2_h264_dpb_entry { struct v4l2_ctrl_h264_decode_params { struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]; - __u16 num_slices; __u16 nal_ref_idc; __s32 top_field_order_cnt; __s32 bottom_field_order_cnt; -- cgit v1.2.3 From d9358563179a7f01f9020ebbe201c7e54ba3af48 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:36 +0200 Subject: media: uapi: h264: Clean slice invariants syntax elements The H.264 specification requires in section 7.4.3 "Slice header semantics", that the following values shall be the same in all slice headers: pic_parameter_set_id frame_num field_pic_flag bottom_field_flag idr_pic_id pic_order_cnt_lsb delta_pic_order_cnt_bottom delta_pic_order_cnt[ 0 ] delta_pic_order_cnt[ 1 ] sp_for_switch_flag slice_group_change_cycle These bitstream fields are part of the slice header, and therefore passed redundantly on each slice. The purpose of the redundancy is to make the codec fault-tolerant in network scenarios. This is of course not needed to be reflected in the V4L2 controls, given the bitstream has already been parsed by applications. Therefore, move the redundant fields to the per-frame decode parameters control (DECODE_PARAMS). Field 'pic_parameter_set_id' is simply removed in this case, because the PPS control must currently contain the active PPS. Syntax elements dec_ref_pic_marking() and those related to pic order count, remain invariant as well, and therefore, the fields dec_ref_pic_marking_bit_size and pic_order_cnt_bit_size are also common to all slices. Signed-off-by: Ezequiel Garcia Reviewed-by: Nicolas Dufresne Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 86 +++++++++++----------- drivers/media/v4l2-core/v4l2-ctrls.c | 7 ++ drivers/media/v4l2-core/v4l2-h264.c | 8 +- drivers/staging/media/hantro/hantro_g1_h264_dec.c | 21 +++--- drivers/staging/media/hantro/hantro_h264.c | 3 +- drivers/staging/media/rkvdec/rkvdec-h264.c | 6 +- drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 9 +-- include/media/h264-ctrls.h | 39 +++++----- include/media/v4l2-h264.h | 1 - 9 files changed, 90 insertions(+), 90 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 304b6012b358..4cd9fd9c5a89 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1766,44 +1766,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u8 - ``slice_type`` - - * - __u8 - - ``pic_parameter_set_id`` - - * - __u8 - ``colour_plane_id`` - * - __u8 - ``redundant_pic_cnt`` - - * - __u16 - - ``frame_num`` - - - * - __u16 - - ``idr_pic_id`` - - - * - __u16 - - ``pic_order_cnt_lsb`` - - - * - __s32 - - ``delta_pic_order_cnt_bottom`` - - - * - __s32 - - ``delta_pic_order_cnt0`` - - - * - __s32 - - ``delta_pic_order_cnt1`` - - - * - struct :c:type:`v4l2_h264_pred_weight_table` - - ``pred_weight_table`` - - - * - __u32 - - ``dec_ref_pic_marking_bit_size`` - - Size in bits of the dec_ref_pic_marking() syntax element. - * - __u32 - - ``pic_order_cnt_bit_size`` - - Combined size in bits of the picture order count related syntax - elements: pic_order_cnt_lsb, delta_pic_order_cnt_bottom, - delta_pic_order_cnt0, and delta_pic_order_cnt1. * - __u8 - ``cabac_init_idc`` - @@ -1830,9 +1798,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - - ``num_ref_idx_l1_active_minus1`` - If num_ref_idx_active_override_flag is not set, this field must be set to the value of num_ref_idx_l1_default_active_minus1. - * - __u32 - - ``slice_group_change_cycle`` - - + * - __u8 + - ``reserved`` + - Applications and drivers must set this to zero. * - struct :c:type:`v4l2_h264_reference` - ``ref_pic_list0[32]`` - Reference picture list after applying the per-slice modifications @@ -1854,17 +1822,11 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - :stub-columns: 0 :widths: 1 1 2 - * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC`` - - 0x00000001 - - - * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD`` - - 0x00000002 - - * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED`` - - 0x00000004 + - 0x00000001 - * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH`` - - 0x00000008 + - 0x00000002 - ``V4L2_CID_MPEG_VIDEO_H264_PRED_WEIGHTS (struct)`` @@ -1990,12 +1952,44 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - __u16 - ``nal_ref_idc`` - NAL reference ID value coming from the NAL Unit header + * - __u16 + - ``frame_num`` + - * - __s32 - ``top_field_order_cnt`` - Picture Order Count for the coded top field * - __s32 - ``bottom_field_order_cnt`` - Picture Order Count for the coded bottom field + * - __u16 + - ``idr_pic_id`` + - + * - __u16 + - ``pic_order_cnt_lsb`` + - + * - __s32 + - ``delta_pic_order_cnt_bottom`` + - + * - __s32 + - ``delta_pic_order_cnt0`` + - + * - __s32 + - ``delta_pic_order_cnt1`` + - + * - __u32 + - ``dec_ref_pic_marking_bit_size`` + - Size in bits of the dec_ref_pic_marking() syntax element. + * - __u32 + - ``pic_order_cnt_bit_size`` + - Combined size in bits of the picture order count related syntax + elements: pic_order_cnt_lsb, delta_pic_order_cnt_bottom, + delta_pic_order_cnt0, and delta_pic_order_cnt1. + * - __u32 + - ``slice_group_change_cycle`` + - + * - __u32 + - ``reserved`` + - Applications and drivers must set this to zero. * - __u32 - ``flags`` - See :ref:`Decode Parameters Flags ` @@ -2014,6 +2008,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC`` - 0x00000001 - That picture is an IDR picture + * - ``V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC`` + - 0x00000002 + - + * - ``V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD`` + - 0x00000004 + - .. c:type:: v4l2_h264_dpb_entry diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index b9457789fa55..b846f5b089c9 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1737,6 +1737,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, { struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; + struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; struct v4l2_ctrl_h264_decode_params *p_h264_dec_params; struct v4l2_ctrl_hevc_sps *p_hevc_sps; struct v4l2_ctrl_hevc_pps *p_hevc_pps; @@ -1798,7 +1799,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, case V4L2_CTRL_TYPE_H264_PPS: case V4L2_CTRL_TYPE_H264_SCALING_MATRIX: case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS: + break; + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS: + p_h264_slice_params = p; + + zero_reserved(*p_h264_slice_params); break; case V4L2_CTRL_TYPE_H264_DECODE_PARAMS: @@ -1810,6 +1816,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx, zero_reserved(*dpb_entry); } + zero_reserved(*p_h264_dec_params); break; case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c index f4742408436b..5633a242520a 100644 --- a/drivers/media/v4l2-core/v4l2-h264.c +++ b/drivers/media/v4l2-core/v4l2-h264.c @@ -18,14 +18,12 @@ * * @b: the builder context to initialize * @dec_params: decode parameters control - * @slice_params: first slice parameters control * @sps: SPS control * @dpb: DPB to use when creating the reference list */ void v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, const struct v4l2_ctrl_h264_decode_params *dec_params, - const struct v4l2_ctrl_h264_slice_params *slice_params, const struct v4l2_ctrl_h264_sps *sps, const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]) { @@ -33,13 +31,13 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, unsigned int i; max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); - cur_frame_num = slice_params->frame_num; + cur_frame_num = dec_params->frame_num; memset(b, 0, sizeof(*b)); - if (!(slice_params->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) + if (!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) b->cur_pic_order_count = min(dec_params->bottom_field_order_cnt, dec_params->top_field_order_cnt); - else if (slice_params->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + else if (dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) b->cur_pic_order_count = dec_params->bottom_field_order_cnt; else b->cur_pic_order_count = dec_params->top_field_order_cnt; diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c index 424c648ce9fc..f9839e9c6da5 100644 --- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c @@ -23,7 +23,6 @@ static void set_params(struct hantro_ctx *ctx) { const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls; const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode; - const struct v4l2_ctrl_h264_slice_params *slices = ctrls->slices; const struct v4l2_ctrl_h264_sps *sps = ctrls->sps; const struct v4l2_ctrl_h264_pps *pps = ctrls->pps; struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx); @@ -42,11 +41,11 @@ static void set_params(struct hantro_ctx *ctx) if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || - slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)) + dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)) reg |= G1_REG_DEC_CTRL0_PIC_INTERLACE_E; - if (slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) + if (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) reg |= G1_REG_DEC_CTRL0_PIC_FIELDMODE_E; - if (!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)) + if (!(dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD)) reg |= G1_REG_DEC_CTRL0_PIC_TOPFIELD_E; vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0); @@ -75,7 +74,7 @@ static void set_params(struct hantro_ctx *ctx) /* Decoder control register 4. */ reg = G1_REG_DEC_CTRL4_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) | - G1_REG_DEC_CTRL4_FRAMENUM(slices[0].frame_num) | + G1_REG_DEC_CTRL4_FRAMENUM(dec_param->frame_num) | G1_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc); if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) reg |= G1_REG_DEC_CTRL4_CABAC_E; @@ -88,8 +87,8 @@ static void set_params(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4); /* Decoder control register 5. */ - reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) | - G1_REG_DEC_CTRL5_IDR_PIC_ID(slices[0].idr_pic_id); + reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(dec_param->dec_ref_pic_marking_bit_size) | + G1_REG_DEC_CTRL5_IDR_PIC_ID(dec_param->idr_pic_id); if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) reg |= G1_REG_DEC_CTRL5_CONST_INTRA_E; if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) @@ -103,10 +102,10 @@ static void set_params(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL5); /* Decoder control register 6. */ - reg = G1_REG_DEC_CTRL6_PPS_ID(slices[0].pic_parameter_set_id) | + reg = G1_REG_DEC_CTRL6_PPS_ID(pps->pic_parameter_set_id) | G1_REG_DEC_CTRL6_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) | G1_REG_DEC_CTRL6_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) | - G1_REG_DEC_CTRL6_POC_LENGTH(slices[0].pic_order_cnt_bit_size); + G1_REG_DEC_CTRL6_POC_LENGTH(dec_param->pic_order_cnt_bit_size); vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL6); /* Error concealment register. */ @@ -246,7 +245,7 @@ static void set_buffers(struct hantro_ctx *ctx) /* Destination (decoded frame) buffer. */ dst_dma = hantro_get_dec_buf_addr(ctx, &dst_buf->vb2_buf); /* Adjust dma addr to start at second line for bottom field */ - if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) offset = ALIGN(ctx->src_fmt.width, MB_DIM); vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DST); @@ -265,7 +264,7 @@ static void set_buffers(struct hantro_ctx *ctx) * DMV buffer is split in two for field encoded frames, * adjust offset for bottom field */ - if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + if (ctrls->decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) offset += 32 * MB_WIDTH(ctx->src_fmt.width) * MB_HEIGHT(ctx->src_fmt.height); vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DIR_MV); diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c index 6dcd47bd9ed3..7578a4fc1b16 100644 --- a/drivers/staging/media/hantro/hantro_h264.c +++ b/drivers/staging/media/hantro/hantro_h264.c @@ -372,8 +372,7 @@ int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx) /* Build the P/B{0,1} ref lists. */ v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode, - &ctrls->slices[0], ctrls->sps, - ctx->h264_dec.dpb); + ctrls->sps, ctx->h264_dec.dpb); v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, h264_ctx->reflists.b1); diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c index d1f2715f30ae..90f211839be2 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -730,7 +730,6 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run) { const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; - const struct v4l2_ctrl_h264_slice_params *sl_params = &run->slices_params[0]; const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; struct rkvdec_h264_ctx *h264_ctx = ctx->priv; const struct v4l2_ctrl_h264_sps *sps = run->sps; @@ -754,7 +753,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx, continue; if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM || - dpb[i].frame_num < sl_params->frame_num) { + dpb[i].frame_num < dec_params->frame_num) { p[i] = dpb[i].frame_num; continue; } @@ -1094,8 +1093,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx) /* Build the P/B{0,1} ref lists. */ v4l2_h264_init_reflist_builder(&reflist_builder, run.decode_params, - &run.slices_params[0], run.sps, - run.decode_params->dpb); + run.sps, run.decode_params->dpb); h264_ctx->reflists.num_valid = reflist_builder.num_valid; v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p); v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c index 7d9bd5860a1b..c8f626fdd3dd 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c @@ -95,7 +95,6 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, { struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM]; const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params; - const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params; const struct v4l2_ctrl_h264_sps *sps = run->h264.sps; struct vb2_queue *cap_q; struct cedrus_buffer *output_buf; @@ -144,7 +143,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx, output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf); output_buf->codec.h264.position = position; - if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) + if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD; else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF; @@ -407,7 +406,7 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE; cedrus_write(dev, VE_H264_SPS, reg); - mbaff_pic = !(slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) && + mbaff_pic = !(decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) && (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD); pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1; @@ -421,9 +420,9 @@ static void cedrus_set_params(struct cedrus_ctx *ctx, reg |= slice->cabac_init_idc & 0x3; if (ctx->fh.m2m_ctx->new_frame) reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC; - if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC) + if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC) reg |= VE_H264_SHS_FIELD_PIC; - if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD) + if (decode->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD) reg |= VE_H264_SHS_BOTTOM_FIELD; if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED) reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED; diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index e4cae02a765f..0c15ff938873 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -146,10 +146,8 @@ struct v4l2_ctrl_h264_pred_weights { #define V4L2_H264_SLICE_TYPE_SP 3 #define V4L2_H264_SLICE_TYPE_SI 4 -#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01 -#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02 -#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04 -#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08 +#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x01 +#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x02 #define V4L2_H264_TOP_FIELD_REF 0x1 #define V4L2_H264_BOTTOM_FIELD_REF 0x2 @@ -169,21 +167,8 @@ struct v4l2_ctrl_h264_slice_params { __u32 first_mb_in_slice; __u8 slice_type; - __u8 pic_parameter_set_id; __u8 colour_plane_id; __u8 redundant_pic_cnt; - __u16 frame_num; - __u16 idr_pic_id; - __u16 pic_order_cnt_lsb; - __s32 delta_pic_order_cnt_bottom; - __s32 delta_pic_order_cnt0; - __s32 delta_pic_order_cnt1; - - /* Size in bits of dec_ref_pic_marking() syntax element. */ - __u32 dec_ref_pic_marking_bit_size; - /* Size in bits of pic order count syntax. */ - __u32 pic_order_cnt_bit_size; - __u8 cabac_init_idc; __s8 slice_qp_delta; __s8 slice_qs_delta; @@ -192,7 +177,8 @@ struct v4l2_ctrl_h264_slice_params { __s8 slice_beta_offset_div2; __u8 num_ref_idx_l0_active_minus1; __u8 num_ref_idx_l1_active_minus1; - __u32 slice_group_change_cycle; + + __u8 reserved; struct v4l2_h264_reference ref_pic_list0[V4L2_H264_REF_LIST_LEN]; struct v4l2_h264_reference ref_pic_list1[V4L2_H264_REF_LIST_LEN]; @@ -217,13 +203,28 @@ struct v4l2_h264_dpb_entry { __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */ }; -#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01 +#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01 +#define V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC 0x02 +#define V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD 0x04 struct v4l2_ctrl_h264_decode_params { struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]; __u16 nal_ref_idc; + __u16 frame_num; __s32 top_field_order_cnt; __s32 bottom_field_order_cnt; + __u16 idr_pic_id; + __u16 pic_order_cnt_lsb; + __s32 delta_pic_order_cnt_bottom; + __s32 delta_pic_order_cnt0; + __s32 delta_pic_order_cnt1; + /* Size in bits of dec_ref_pic_marking() syntax element. */ + __u32 dec_ref_pic_marking_bit_size; + /* Size in bits of pic order count syntax. */ + __u32 pic_order_cnt_bit_size; + __u32 slice_group_change_cycle; + + __u32 reserved; __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */ }; diff --git a/include/media/v4l2-h264.h b/include/media/v4l2-h264.h index 1a5f26fc2a9a..f08ba181263d 100644 --- a/include/media/v4l2-h264.h +++ b/include/media/v4l2-h264.h @@ -44,7 +44,6 @@ struct v4l2_h264_reflist_builder { void v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b, const struct v4l2_ctrl_h264_decode_params *dec_params, - const struct v4l2_ctrl_h264_slice_params *slice_params, const struct v4l2_ctrl_h264_sps *sps, const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]); -- cgit v1.2.3 From 54889c51b833d236228f983be16212fbe806bb89 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 25 Aug 2020 05:52:37 +0200 Subject: media: uapi: h264: Rename and clarify PPS_FLAG_SCALING_MATRIX_PRESENT Applications are expected to fill V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX if a non-flat scaling matrix applies to the picture. This is the case if SPS scaling_matrix_present_flag or PPS pic_scaling_matrix_present_flag are set, and should be handled by applications. On one hand, the PPS bitstream syntax element signals the presence of a Picture scaling matrix modifying the Sequence (SPS) scaling matrix. On the other hand, our flag should indicate if the scaling matrix V4L2 control is applicable to this request. Rename the flag from PPS_FLAG_PIC_SCALING_MATRIX_PRESENT to PPS_FLAG_SCALING_MATRIX_PRESENT, to avoid mixing this flag with bitstream syntax element pic_scaling_matrix_present_flag, and clarify the meaning of our flag. Signed-off-by: Ezequiel Garcia Tested-by: Jonas Karlman Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 5 +++-- include/media/h264-ctrls.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 4cd9fd9c5a89..e2b94b1d0ab0 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -1695,9 +1695,10 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type - * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE`` - 0x00000040 - - * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT`` + * - ``V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT`` - 0x00000080 - - + - Indicates that ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX`` + must be used for this picture. ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)`` Specifies the scaling matrix (as extracted from the bitstream) for diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h index 0c15ff938873..ec4799154438 100644 --- a/include/media/h264-ctrls.h +++ b/include/media/h264-ctrls.h @@ -99,7 +99,7 @@ struct v4l2_ctrl_h264_sps { #define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010 #define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020 #define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040 -#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080 +#define V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT 0x0080 struct v4l2_ctrl_h264_pps { __u8 pic_parameter_set_id; -- cgit v1.2.3 From 4ad1b0d410c88c7c8e8fd1298c9d2293b651e35c Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Sat, 23 May 2020 03:05:26 +0200 Subject: media: v4l2-ctrls: Add encoder constant quality control When V4L2_CID_MPEG_VIDEO_BITRATE_MODE value is V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, encoder will produce constant quality output indicated by V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY control value. Encoder will choose appropriate quantization parameter and bitrate to produce requested frame quality level. Signed-off-by: Maheshwar Ajja Reviewed-by: Hans Verkuil Signed-off-by: Stanimir Varbanov Signed-off-by: Mauro Carvalho Chehab --- Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 10 ++++++++++ drivers/media/v4l2-core/v4l2-ctrls.c | 2 ++ include/uapi/linux/v4l2-controls.h | 2 ++ 3 files changed, 14 insertions(+) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index e2b94b1d0ab0..ebd367dcf8b9 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -581,6 +581,8 @@ enum v4l2_mpeg_video_bitrate_mode - - Variable bitrate * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_CBR`` - Constant bitrate + * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_CQ`` + - Constant quality @@ -592,6 +594,14 @@ enum v4l2_mpeg_video_bitrate_mode - the average video bitrate. It is ignored if the video bitrate mode is set to constant bitrate. +``V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY (integer)`` + Constant quality level control. This control is applicable when + ``V4L2_CID_MPEG_VIDEO_BITRATE_MODE`` value is + ``V4L2_MPEG_VIDEO_BITRATE_MODE_CQ``. Valid range is 1 to 100 + where 1 indicates lowest quality and 100 indicates highest quality. + Encoder will decide the appropriate quantization parameter and + bitrate to produce requested frame quality. + ``V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (integer)`` For every captured frame, skip this many subsequent frames (default 0). diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index b846f5b089c9..83372789eec3 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -200,6 +200,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id) static const char * const mpeg_video_bitrate_mode[] = { "Variable Bitrate", "Constant Bitrate", + "Constant Quality", NULL }; static const char * const mpeg_stream_type[] = { @@ -832,6 +833,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: return "Video GOP Closure"; case V4L2_CID_MPEG_VIDEO_PULLDOWN: return "Video Pulldown"; case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: return "Video Bitrate Mode"; + case V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY: return "Constant Quality"; case V4L2_CID_MPEG_VIDEO_BITRATE: return "Video Bitrate"; case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: return "Video Peak Bitrate"; case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION: return "Video Temporal Decimation"; diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 62271418c1be..0f7e4388dcce 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -375,6 +375,7 @@ enum v4l2_mpeg_video_aspect { enum v4l2_mpeg_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, + V4L2_MPEG_VIDEO_BITRATE_MODE_CQ = 2, }; #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) @@ -742,6 +743,7 @@ enum v4l2_cid_mpeg_video_hevc_size_of_length_field { #define V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L6_BR (V4L2_CID_MPEG_BASE + 642) #define V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_BASE + 643) #define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_BASE + 644) +#define V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY (V4L2_CID_MPEG_BASE + 645) /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) -- cgit v1.2.3 From 44f5b2fffc3213c919f53adddadb1a05519bdc0e Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Sun, 5 Jul 2020 01:41:00 +0200 Subject: media: v4l2-ctrl: Add frame-skip std encoder control Adds encoders standard v4l2 control for frame-skip. The control is a copy of a custom encoder control so that other v4l2 encoder drivers can use it. Signed-off-by: Stanimir Varbanov Reviewed-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 38 ++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls.c | 10 ++++++ include/uapi/linux/v4l2-controls.h | 6 ++++ 3 files changed, 54 insertions(+) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index ebd367dcf8b9..750a6d4fadaf 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -602,6 +602,40 @@ enum v4l2_mpeg_video_bitrate_mode - Encoder will decide the appropriate quantization parameter and bitrate to produce requested frame quality. + +``V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE (enum)`` + +enum v4l2_mpeg_video_frame_skip_mode - + Indicates in what conditions the encoder should skip frames. If + encoding a frame would cause the encoded stream to be larger then a + chosen data limit then the frame will be skipped. Possible values + are: + + +.. tabularcolumns:: |p{9.2cm}|p{8.3cm}| + +.. raw:: latex + + \small + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + * - ``V4L2_MPEG_FRAME_SKIP_MODE_DISABLED`` + - Frame skip mode is disabled. + * - ``V4L2_MPEG_FRAME_SKIP_MODE_LEVEL_LIMIT`` + - Frame skip mode enabled and buffer limit is set by the chosen + level and is defined by the standard. + * - ``V4L2_MPEG_FRAME_SKIP_MODE_BUF_LIMIT`` + - Frame skip mode enabled and buffer limit is set by the + :ref:`VBV (MPEG1/2/4) ` or + :ref:`CPB (H264) buffer size ` control. + +.. raw:: latex + + \normalsize + ``V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (integer)`` For every captured frame, skip this many subsequent frames (default 0). @@ -1173,6 +1207,8 @@ enum v4l2_mpeg_video_h264_entropy_mode - Quantization parameter for an B frame for MPEG4. Valid range: from 1 to 31. +.. _v4l2-mpeg-video-vbv-size: + ``V4L2_CID_MPEG_VIDEO_VBV_SIZE (integer)`` The Video Buffer Verifier size in kilobytes, it is used as a limitation of frame skip. The VBV is defined in the standard as a @@ -1210,6 +1246,8 @@ enum v4l2_mpeg_video_h264_entropy_mode - Force a key frame for the next queued buffer. Applicable to encoders. This is a general, codec-agnostic keyframe control. +.. _v4l2-mpeg-video-h264-cpb-size: + ``V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (integer)`` The Coded Picture Buffer size in kilobytes, it is used as a limitation of frame skip. The CPB is defined in the H264 standard as diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 83372789eec3..c138914f507b 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -591,6 +591,12 @@ const char * const *v4l2_ctrl_get_menu(u32 id) "External", NULL, }; + static const char * const mpeg_video_frame_skip[] = { + "Disabled", + "Level Limit", + "VBV/CPB Limit", + NULL, + }; switch (id) { case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: @@ -652,6 +658,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id) return flash_strobe_source; case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return header_mode; + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: + return mpeg_video_frame_skip; case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: return multi_slice; case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: @@ -846,6 +854,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: return "H264 MB Level Rate Control"; case V4L2_CID_MPEG_VIDEO_HEADER_MODE: return "Sequence Header Mode"; case V4L2_CID_MPEG_VIDEO_MAX_REF_PIC: return "Max Number of Reference Pics"; + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: return "Frame Skip Mode"; case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP: return "H263 I-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP: return "H263 P-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP: return "H263 B-Frame QP Value"; @@ -1268,6 +1277,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_FLASH_LED_MODE: case V4L2_CID_FLASH_STROBE_SOURCE: case V4L2_CID_MPEG_VIDEO_HEADER_MODE: + case V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE: case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: case V4L2_CID_MPEG_VIDEO_H264_LEVEL: diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 0f7e4388dcce..053827cda8e6 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -744,6 +744,12 @@ enum v4l2_cid_mpeg_video_hevc_size_of_length_field { #define V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES (V4L2_CID_MPEG_BASE + 643) #define V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR (V4L2_CID_MPEG_BASE + 644) #define V4L2_CID_MPEG_VIDEO_CONSTANT_QUALITY (V4L2_CID_MPEG_BASE + 645) +#define V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_BASE + 646) +enum v4l2_mpeg_video_frame_skip_mode { + V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) -- cgit v1.2.3 From 1faa39e0f3bcfe47dc7a61a72c234b24005c3a1a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 Sep 2020 11:09:26 +0200 Subject: media: videobuf-dma-sg: number of pages should be unsigned long As reported by smatch: drivers/media/v4l2-core/videobuf-dma-sg.c:245 videobuf_dma_init_kernel() warn: should 'nr_pages << 12' be a 64 bit type? The printk should not be using %d for the number of pages. After looking better, the real problem here is that the number of pages should be long int. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf-dma-sg.c | 22 ++++++++++++---------- include/media/videobuf-dma-sg.h | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index 46ff19df9f53..8dd0562de287 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c @@ -180,7 +180,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, if (rw == READ) flags |= FOLL_WRITE; - dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n", + dprintk(1, "init user [0x%lx+0x%lx => %lu pages]\n", data, size, dma->nr_pages); err = pin_user_pages(data & PAGE_MASK, dma->nr_pages, @@ -188,7 +188,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, if (err != dma->nr_pages) { dma->nr_pages = (err >= 0) ? err : 0; - dprintk(1, "pin_user_pages: err=%d [%d]\n", err, + dprintk(1, "pin_user_pages: err=%d [%lu]\n", err, dma->nr_pages); return err < 0 ? err : -EINVAL; } @@ -208,11 +208,11 @@ static int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, } static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, - int nr_pages) + unsigned long nr_pages) { int i; - dprintk(1, "init kernel [%d pages]\n", nr_pages); + dprintk(1, "init kernel [%lu pages]\n", nr_pages); dma->direction = direction; dma->vaddr_pages = kcalloc(nr_pages, sizeof(*dma->vaddr_pages), @@ -238,11 +238,11 @@ static int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction, dma->vaddr = vmap(dma->vaddr_pages, nr_pages, VM_MAP | VM_IOREMAP, PAGE_KERNEL); if (NULL == dma->vaddr) { - dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages); + dprintk(1, "vmalloc_32(%lu pages) failed\n", nr_pages); goto out_free_pages; } - dprintk(1, "vmalloc is at addr %p, size=%d\n", + dprintk(1, "vmalloc is at addr %p, size=%lu\n", dma->vaddr, nr_pages << PAGE_SHIFT); memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT); @@ -267,9 +267,9 @@ out_free_pages: } static int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, - dma_addr_t addr, int nr_pages) + dma_addr_t addr, unsigned long nr_pages) { - dprintk(1, "init overlay [%d pages @ bus 0x%lx]\n", + dprintk(1, "init overlay [%lu pages @ bus 0x%lx]\n", nr_pages, (unsigned long)addr); dma->direction = direction; @@ -500,9 +500,11 @@ static int __videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, struct v4l2_framebuffer *fbuf) { - int err, pages; - dma_addr_t bus; struct videobuf_dma_sg_memory *mem = vb->priv; + unsigned long pages; + dma_addr_t bus; + int err; + BUG_ON(!mem); MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index 34450f7ad510..930ff8d454fc 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -60,7 +60,7 @@ struct videobuf_dmabuf { /* common */ struct scatterlist *sglist; int sglen; - int nr_pages; + unsigned long nr_pages; int direction; }; -- cgit v1.2.3 From 528222d853f9283110f0118dd71d9f0ad686d586 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sun, 23 Aug 2020 19:23:05 +0200 Subject: media: rc: harmonize infrared durations to microseconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rc-core kapi uses nanoseconds for infrared durations for receiving, and microseconds for sending. The uapi already uses microseconds for both, so this patch does not change the uapi. Infrared durations do not need nanosecond resolution. IR protocols do not have durations shorter than about 100 microseconds. Some IR hardware offers 250 microseconds resolution, which is sufficient for most protocols. Better hardware has 50 microsecond resolution and is enough for every protocol I am aware off. Unify on microseconds everywhere. This simplifies the code since less conversion between microseconds and nanoseconds needs to be done. This affects: - rx_resolution member of struct rc_dev - timeout member of struct rc_dev - duration member in struct ir_raw_event Cc: "Bruno Prémont" Cc: Hans Verkuil Cc: Maxim Levitsky Cc: Patrick Lerda Cc: Kevin Hilman Cc: Neil Armstrong Cc: Jerome Brunet Cc: Martin Blumenstingl Cc: Sean Wang Cc: Matthias Brugger Cc: Patrice Chotard Cc: Maxime Ripard Cc: Chen-Yu Tsai Cc: "David Härdeman" Cc: Benjamin Valentin Cc: Antti Palosaari Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/hid/hid-picolcd_cir.c | 10 ++++---- drivers/media/cec/core/cec-core.c | 2 +- drivers/media/cec/platform/seco/seco-cec.c | 2 +- drivers/media/common/siano/smsir.c | 4 ++-- drivers/media/i2c/cx25840/cx25840-ir.c | 2 +- drivers/media/pci/cx23885/cx23888-ir.c | 2 +- drivers/media/pci/cx88/cx88-input.c | 4 ++-- drivers/media/pci/smipcie/smipcie-ir.c | 7 +++--- drivers/media/rc/ene_ir.c | 18 +++++++-------- drivers/media/rc/fintek-cir.c | 8 +++---- drivers/media/rc/igorplugusb.c | 6 ++--- drivers/media/rc/iguanair.c | 4 ++-- drivers/media/rc/imon_raw.c | 2 +- drivers/media/rc/ir-hix5hd2.c | 8 +++---- drivers/media/rc/ir-imon-decoder.c | 10 ++++---- drivers/media/rc/ir-jvc-decoder.c | 6 ++--- drivers/media/rc/ir-mce_kbd-decoder.c | 6 ++--- drivers/media/rc/ir-nec-decoder.c | 6 ++--- drivers/media/rc/ir-rc5-decoder.c | 6 ++--- drivers/media/rc/ir-rc6-decoder.c | 6 ++--- drivers/media/rc/ir-rcmm-decoder.c | 18 +++++++-------- drivers/media/rc/ir-sanyo-decoder.c | 6 ++--- drivers/media/rc/ir-sharp-decoder.c | 6 ++--- drivers/media/rc/ir-sony-decoder.c | 6 ++--- drivers/media/rc/ir-xmp-decoder.c | 15 ++++++------ drivers/media/rc/ir_toy.c | 14 +++++------ drivers/media/rc/ite-cir.c | 10 ++++---- drivers/media/rc/ite-cir.h | 4 ++-- drivers/media/rc/lirc_dev.c | 37 ++++++++++++------------------ drivers/media/rc/mceusb.c | 12 +++++----- drivers/media/rc/meson-ir.c | 4 ++-- drivers/media/rc/mtk-cir.c | 4 ++-- drivers/media/rc/nuvoton-cir.c | 10 ++++---- drivers/media/rc/nuvoton-cir.h | 2 +- drivers/media/rc/rc-core-priv.h | 1 - drivers/media/rc/rc-ir-raw.c | 14 +++++------ drivers/media/rc/rc-loopback.c | 8 +++---- drivers/media/rc/redrat3.c | 17 +++++++------- drivers/media/rc/serial_ir.c | 10 ++++---- drivers/media/rc/sir_ir.c | 2 +- drivers/media/rc/st_rc.c | 6 ++--- drivers/media/rc/streamzap.c | 10 +++----- drivers/media/rc/sunxi-cir.c | 4 ++-- drivers/media/rc/ttusbir.c | 18 +++++++-------- drivers/media/rc/winbond-cir.c | 10 ++++---- drivers/media/rc/xbox_remote.c | 2 +- drivers/media/usb/au0828/au0828-input.c | 8 +++---- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 4 ++-- drivers/media/usb/dvb-usb/technisat-usb2.c | 4 ++-- include/media/rc-core.h | 11 ++++----- 50 files changed, 188 insertions(+), 208 deletions(-) (limited to 'include') diff --git a/drivers/hid/hid-picolcd_cir.c b/drivers/hid/hid-picolcd_cir.c index 34da38d5b0cd..d6faa0e00f95 100644 --- a/drivers/hid/hid-picolcd_cir.c +++ b/drivers/hid/hid-picolcd_cir.c @@ -59,10 +59,10 @@ int picolcd_raw_cir(struct picolcd_data *data, for (i = 0; i+1 < sz; i += 2) { w = (raw_data[i] << 8) | (raw_data[i+1]); rawir.pulse = !!(w & 0x8000); - rawir.duration = US_TO_NS(rawir.pulse ? (65536 - w) : w); + rawir.duration = rawir.pulse ? (65536 - w) : w; /* Quirk!! - see above */ - if (i == 0 && rawir.duration > 15000000) - rawir.duration -= 15000000; + if (i == 0 && rawir.duration > 15000) + rawir.duration -= 15000; ir_raw_event_store(data->rc_dev, &rawir); } ir_raw_event_handle(data->rc_dev); @@ -114,8 +114,8 @@ int picolcd_init_cir(struct picolcd_data *data, struct hid_report *report) rdev->dev.parent = &data->hdev->dev; rdev->driver_name = PICOLCD_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->timeout = MS_TO_NS(100); - rdev->rx_resolution = US_TO_NS(1); + rdev->timeout = MS_TO_US(100); + rdev->rx_resolution = 1; ret = rc_register_device(rdev); if (ret) diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index 562792f545ac..3ee16f672d68 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -309,7 +309,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, adap->rc->allowed_protocols = RC_PROTO_BIT_CEC; adap->rc->priv = adap; adap->rc->map_name = RC_MAP_CEC; - adap->rc->timeout = MS_TO_NS(550); + adap->rc->timeout = MS_TO_US(550); #endif return adap; } diff --git a/drivers/media/cec/platform/seco/seco-cec.c b/drivers/media/cec/platform/seco/seco-cec.c index 075dd79beb6f..ae138cc253fd 100644 --- a/drivers/media/cec/platform/seco/seco-cec.c +++ b/drivers/media/cec/platform/seco/seco-cec.c @@ -369,7 +369,7 @@ static int secocec_ir_probe(void *priv) cec->ir->allowed_protocols = RC_PROTO_BIT_RC5; cec->ir->priv = cec; cec->ir->map_name = RC_MAP_HAUPPAUGE; - cec->ir->timeout = MS_TO_NS(100); + cec->ir->timeout = MS_TO_US(100); /* Clear the status register */ status = smb_rd16(SECOCEC_STATUS_REG_1, &val); diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c index 79bd627f84b8..d85c78c104b9 100644 --- a/drivers/media/common/siano/smsir.c +++ b/drivers/media/common/siano/smsir.c @@ -27,7 +27,7 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len) for (i = 0; i < len >> 2; i++) { struct ir_raw_event ev = { - .duration = abs(samples[i]) * 1000, /* Convert to ns */ + .duration = abs(samples[i]), .pulse = (samples[i] > 0) ? false : true }; @@ -48,7 +48,7 @@ int sms_ir_init(struct smscore_device_t *coredev) return -ENOMEM; coredev->ir.controller = 0; /* Todo: vega/nova SPI number */ - coredev->ir.timeout = IR_DEFAULT_TIMEOUT; + coredev->ir.timeout = US_TO_NS(IR_DEFAULT_TIMEOUT); pr_debug("IR port %d, timeout %d ms\n", coredev->ir.controller, coredev->ir.timeout); diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index 2181c8a347fc..2cf3e6a1f9e1 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -688,7 +688,7 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, } v = (unsigned) pulse_width_count_to_ns( - (u16) (p->hw_fifo_data & FIFO_RXTX), divider); + (u16)(p->hw_fifo_data & FIFO_RXTX), divider) / 1000; if (v > IR_MAX_DURATION) v = IR_MAX_DURATION; diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index ad7f8ccad526..ddfd2eb37484 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -663,7 +663,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, } v = (unsigned) pulse_width_count_to_ns( - (u16) (p->hw_fifo_data & FIFO_RXTX), divider); + (u16)(p->hw_fifo_data & FIFO_RXTX), divider) / 1000; if (v > IR_MAX_DURATION) v = IR_MAX_DURATION; diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index 7e0fed9cd200..ce0ef0b8186f 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -479,7 +479,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) dev->scancode_mask = hardware_mask; if (ir->sampling) { - dev->timeout = 10 * 1000 * 1000; /* 10 ms */ + dev->timeout = MS_TO_US(10); /* 10 ms */ } else { dev->driver_type = RC_DRIVER_SCANCODE; dev->allowed_protocols = rc_proto; @@ -544,7 +544,7 @@ void cx88_ir_irq(struct cx88_core *core) for (todo = 32; todo > 0; todo -= bits) { ev.pulse = samples & 0x80000000 ? false : true; bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); - ev.duration = (bits * (NSEC_PER_SEC / 1000)) / ir_samplerate; + ev.duration = (bits * (USEC_PER_SEC / 1000)) / ir_samplerate; ir_raw_event_store_with_filter(ir->dev, &ev); samples <<= bits; } diff --git a/drivers/media/pci/smipcie/smipcie-ir.c b/drivers/media/pci/smipcie/smipcie-ir.c index 9445d792bfc9..e6b74e161a05 100644 --- a/drivers/media/pci/smipcie/smipcie-ir.c +++ b/drivers/media/pci/smipcie/smipcie-ir.c @@ -87,8 +87,7 @@ static void smi_ir_decode(struct smi_rc *ir) struct ir_raw_event rawir = {}; rawir.pulse = 0; - rawir.duration = US_TO_NS(SMI_SAMPLE_PERIOD * - SMI_SAMPLE_IDLEMIN); + rawir.duration = SMI_SAMPLE_PERIOD * SMI_SAMPLE_IDLEMIN; ir_raw_event_store_with_filter(rc_dev, &rawir); smi_set(IR_Init_Reg, rbIRhighidle); } @@ -151,8 +150,8 @@ int smi_ir_init(struct smi_dev *dev) rc_dev->dev.parent = &dev->pci_dev->dev; rc_dev->map_name = dev->info->rc_map; - rc_dev->timeout = MS_TO_NS(100); - rc_dev->rx_resolution = US_TO_NS(SMI_SAMPLE_PERIOD); + rc_dev->timeout = MS_TO_US(100); + rc_dev->rx_resolution = SMI_SAMPLE_PERIOD; ir->rc_dev = rc_dev; ir->dev = dev; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 82867a2a60b0..6049e5c95394 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -432,27 +432,27 @@ static void ene_rx_setup(struct ene_device *dev) select_timeout: if (dev->rx_fan_input_inuse) { - dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); + dev->rdev->rx_resolution = ENE_FW_SAMPLE_PERIOD_FAN; /* Fan input doesn't support timeouts, it just ends the input with a maximum sample */ dev->rdev->min_timeout = dev->rdev->max_timeout = - US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * - ENE_FW_SAMPLE_PERIOD_FAN); + ENE_FW_SMPL_BUF_FAN_MSK * + ENE_FW_SAMPLE_PERIOD_FAN; } else { - dev->rdev->rx_resolution = US_TO_NS(sample_period); + dev->rdev->rx_resolution = sample_period; /* Theoreticly timeout is unlimited, but we cap it * because it was seen that on one device, it * would stop sending spaces after around 250 msec. * Besides, this is close to 2^32 anyway and timeout is u32. */ - dev->rdev->min_timeout = US_TO_NS(127 * sample_period); - dev->rdev->max_timeout = US_TO_NS(200000); + dev->rdev->min_timeout = 127 * sample_period; + dev->rdev->max_timeout = 200000; } if (dev->hw_learning_and_tx_capable) - dev->rdev->tx_resolution = US_TO_NS(sample_period); + dev->rdev->tx_resolution = sample_period; if (dev->rdev->timeout > dev->rdev->max_timeout) dev->rdev->timeout = dev->rdev->max_timeout; @@ -798,7 +798,7 @@ static irqreturn_t ene_isr(int irq, void *data) dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); - ev.duration = US_TO_NS(hw_sample); + ev.duration = hw_sample; ev.pulse = pulse; ir_raw_event_store_with_filter(dev->rdev, &ev); } @@ -818,7 +818,7 @@ static void ene_setup_default_settings(struct ene_device *dev) dev->learning_mode_enabled = learning_mode_force; /* Set reasonable default timeout */ - dev->rdev->timeout = US_TO_NS(150000); + dev->rdev->timeout = MS_TO_US(150); } /* Upload all hardware settings at once. Used at load and resume time */ diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 8e3177c5b586..b0d580566e4e 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -299,8 +299,8 @@ static void fintek_process_rx_ir_data(struct fintek_dev *fintek) case PARSE_IRDATA: fintek->rem--; rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); - rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK) - * CIR_SAMPLE_PERIOD); + rawir.duration = (sample & BUF_SAMPLE_MASK) + * CIR_SAMPLE_PERIOD; fit_dbg("Storing %s with duration %d", rawir.pulse ? "pulse" : "space", @@ -524,9 +524,9 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id rdev->dev.parent = &pdev->dev; rdev->driver_name = FINTEK_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->timeout = US_TO_NS(1000); + rdev->timeout = 1000; /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ - rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); + rdev->rx_resolution = CIR_SAMPLE_PERIOD; fintek->rdev = rdev; diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index b981f7290c1b..effaa5751d6c 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -69,7 +69,7 @@ static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len) overflow); do { - rawir.duration = ir->buf_in[i] * 85333; + rawir.duration = ir->buf_in[i] * 85; rawir.pulse = i & 1; ir_raw_event_store_with_filter(ir->rc, &rawir); @@ -202,8 +202,8 @@ static int igorplugusb_probe(struct usb_interface *intf, rc->priv = ir; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_HAUPPAUGE; - rc->timeout = MS_TO_NS(100); - rc->rx_resolution = 85333; + rc->timeout = MS_TO_US(100); + rc->rx_resolution = 85; ir->rc = rc; ret = rc_register_device(rc); diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index b5b993b33b80..84949baf9f6b 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -59,7 +59,7 @@ struct iguanair { #define MAX_IN_PACKET 8u #define MAX_OUT_PACKET (sizeof(struct send_packet) + BUF_SIZE) #define TIMEOUT 1000 -#define RX_RESOLUTION 21333 +#define RX_RESOLUTION 21 struct packet { uint16_t start; @@ -124,7 +124,7 @@ static void process_ir_data(struct iguanair *ir, unsigned len) for (i = 0; i < 7; i++) { if (ir->buf_in[i] == 0x80) { rawir.pulse = false; - rawir.duration = US_TO_NS(21845); + rawir.duration = 21845; } else { rawir.pulse = (ir->buf_in[i] & 0x80) == 0; rawir.duration = ((ir->buf_in[i] & 0x7f) + 1) * diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index aae0a3cc9479..d41580f6e4c7 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -8,7 +8,7 @@ #include /* Each bit is 250us */ -#define BIT_DURATION 250000 +#define BIT_DURATION 250 struct imon { struct device *dev; diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c index d80cfa455c73..0ffc27514fab 100644 --- a/drivers/media/rc/ir-hix5hd2.c +++ b/drivers/media/rc/ir-hix5hd2.c @@ -214,12 +214,12 @@ static irqreturn_t hix5hd2_ir_rx_interrupt(int irq, void *data) data_h = ((symb_val >> 16) & 0xffff) * 10; symb_time = (data_l + data_h) / 10; - ev.duration = US_TO_NS(data_l); + ev.duration = data_l; ev.pulse = true; ir_raw_event_store(priv->rdev, &ev); if (symb_time < IR_CFG_SYMBOL_MAXWIDTH) { - ev.duration = US_TO_NS(data_h); + ev.duration = data_h; ev.pulse = false; ir_raw_event_store(priv->rdev, &ev); } else { @@ -311,8 +311,8 @@ static int hix5hd2_ir_probe(struct platform_device *pdev) rdev->input_id.vendor = 0x0001; rdev->input_id.product = 0x0001; rdev->input_id.version = 0x0100; - rdev->rx_resolution = US_TO_NS(10); - rdev->timeout = US_TO_NS(IR_CFG_SYMBOL_MAXWIDTH * 10); + rdev->rx_resolution = 10; + rdev->timeout = IR_CFG_SYMBOL_MAXWIDTH * 10; ret = rc_register_device(rdev); if (ret < 0) diff --git a/drivers/media/rc/ir-imon-decoder.c b/drivers/media/rc/ir-imon-decoder.c index a0efe2605393..41dbbef27fa6 100644 --- a/drivers/media/rc/ir-imon-decoder.c +++ b/drivers/media/rc/ir-imon-decoder.c @@ -8,7 +8,7 @@ #include #include "rc-core-priv.h" -#define IMON_UNIT 415662 /* ns */ +#define IMON_UNIT 416 /* us */ #define IMON_BITS 30 #define IMON_CHKBITS (BIT(30) | BIT(25) | BIT(24) | BIT(22) | \ BIT(21) | BIT(20) | BIT(19) | BIT(18) | \ @@ -102,8 +102,7 @@ static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) dev_dbg(&dev->dev, "iMON decode started at state %d bitno %d (%uus %s)\n", - data->state, data->count, TO_US(ev.duration), - TO_STR(ev.pulse)); + data->state, data->count, ev.duration, TO_STR(ev.pulse)); /* * Since iMON protocol is a series of bits, if at any point @@ -116,7 +115,7 @@ static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) * we're at a new scancode. */ if (data->state == STATE_ERROR) { - if (!ev.pulse && ev.duration > MS_TO_NS(10)) + if (!ev.pulse && ev.duration > MS_TO_US(10)) data->state = STATE_INACTIVE; return 0; } @@ -169,8 +168,7 @@ static int ir_imon_decode(struct rc_dev *dev, struct ir_raw_event ev) err_out: dev_dbg(&dev->dev, "iMON decode failed at state %d bitno %d (%uus %s)\n", - data->state, data->count, TO_US(ev.duration), - TO_STR(ev.pulse)); + data->state, data->count, ev.duration, TO_STR(ev.pulse)); data->state = STATE_ERROR; diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c index 864d9e316c33..470f2e1fd507 100644 --- a/drivers/media/rc/ir-jvc-decoder.c +++ b/drivers/media/rc/ir-jvc-decoder.c @@ -9,7 +9,7 @@ #include "rc-core-priv.h" #define JVC_NBITS 16 /* dev(8) + func(8) */ -#define JVC_UNIT 525000 /* ns */ +#define JVC_UNIT 525 /* us */ #define JVC_HEADER_PULSE (16 * JVC_UNIT) /* lack of header -> repeat */ #define JVC_HEADER_SPACE (8 * JVC_UNIT) #define JVC_BIT_PULSE (1 * JVC_UNIT) @@ -49,7 +49,7 @@ static int ir_jvc_decode(struct rc_dev *dev, struct ir_raw_event ev) goto out; dev_dbg(&dev->dev, "JVC decode started at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); again: switch (data->state) { @@ -157,7 +157,7 @@ again: out: dev_dbg(&dev->dev, "JVC decode failed at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c index cfe837f773c1..90350f25d8dd 100644 --- a/drivers/media/rc/ir-mce_kbd-decoder.c +++ b/drivers/media/rc/ir-mce_kbd-decoder.c @@ -21,7 +21,7 @@ * input device for the remote, rather than the keyboard/mouse one. */ -#define MCIR2_UNIT 333333 /* ns */ +#define MCIR2_UNIT 333 /* us */ #define MCIR2_HEADER_NBITS 5 #define MCIR2_MOUSE_NBITS 29 #define MCIR2_KEYBOARD_NBITS 32 @@ -231,7 +231,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev) again: dev_dbg(&dev->dev, "started at state %i (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); if (!geq_margin(ev.duration, MCIR2_UNIT, MCIR2_UNIT / 2)) return 0; @@ -353,7 +353,7 @@ again: out: dev_dbg(&dev->dev, "failed at state %i (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index 6a8973ae3684..b4c3e4baf34d 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -8,7 +8,7 @@ #include "rc-core-priv.h" #define NEC_NBITS 32 -#define NEC_UNIT 562500 /* ns */ +#define NEC_UNIT 563 /* us */ #define NEC_HEADER_PULSE (16 * NEC_UNIT) #define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ #define NEC_HEADER_SPACE (8 * NEC_UNIT) @@ -50,7 +50,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "NEC decode started at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); switch (data->state) { @@ -163,7 +163,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "NEC decode failed at count %d state %d (%uus %s)\n", - data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->count, data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 63624654a71e..d58b6226afeb 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -16,7 +16,7 @@ #define RC5_SZ_NBITS 15 #define RC5X_NBITS 20 #define CHECK_RC5X_NBITS 8 -#define RC5_UNIT 888888 /* ns */ +#define RC5_UNIT 889 /* us */ #define RC5_BIT_START (1 * RC5_UNIT) #define RC5_BIT_END (1 * RC5_UNIT) #define RC5X_SPACE (4 * RC5_UNIT) @@ -55,7 +55,7 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev) again: dev_dbg(&dev->dev, "RC5(x/sz) decode started at state %i (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2)) return 0; @@ -164,7 +164,7 @@ again: out: dev_dbg(&dev->dev, "RC5(x/sz) decode failed at state %i count %d (%uus %s)\n", - data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, data->count, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index 95727ca910f7..df8cd53a9005 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -15,7 +15,7 @@ * RC6-6A-32 (MCE version with toggle bit in body) */ -#define RC6_UNIT 444444 /* nanosecs */ +#define RC6_UNIT 444 /* microseconds */ #define RC6_HEADER_NBITS 4 /* not including toggle bit */ #define RC6_0_NBITS 16 #define RC6_6A_32_NBITS 32 @@ -95,7 +95,7 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev) again: dev_dbg(&dev->dev, "RC6 decode started at state %i (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) return 0; @@ -270,7 +270,7 @@ again: out: dev_dbg(&dev->dev, "RC6 decode failed at state %i (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-rcmm-decoder.c b/drivers/media/rc/ir-rcmm-decoder.c index 028df5cb1828..fd9ec69a3718 100644 --- a/drivers/media/rc/ir-rcmm-decoder.c +++ b/drivers/media/rc/ir-rcmm-decoder.c @@ -6,12 +6,12 @@ #include "rc-core-priv.h" #include -#define RCMM_UNIT 166667 /* nanosecs */ -#define RCMM_PREFIX_PULSE 416666 /* 166666.666666666*2.5 */ -#define RCMM_PULSE_0 277777 /* 166666.666666666*(1+2/3) */ -#define RCMM_PULSE_1 444444 /* 166666.666666666*(2+2/3) */ -#define RCMM_PULSE_2 611111 /* 166666.666666666*(3+2/3) */ -#define RCMM_PULSE_3 777778 /* 166666.666666666*(4+2/3) */ +#define RCMM_UNIT 166 /* microseconds */ +#define RCMM_PREFIX_PULSE 417 /* 166.666666666666*2.5 */ +#define RCMM_PULSE_0 278 /* 166.666666666666*(1+2/3) */ +#define RCMM_PULSE_1 444 /* 166.666666666666*(2+2/3) */ +#define RCMM_PULSE_2 611 /* 166.666666666666*(3+2/3) */ +#define RCMM_PULSE_3 778 /* 166.666666666666*(4+2/3) */ enum rcmm_state { STATE_INACTIVE, @@ -64,8 +64,8 @@ static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev) int value; if (!(dev->enabled_protocols & (RC_PROTO_BIT_RCMM32 | - RC_PROTO_BIT_RCMM24 | - RC_PROTO_BIT_RCMM12))) + RC_PROTO_BIT_RCMM24 | + RC_PROTO_BIT_RCMM12))) return 0; if (!is_timing_event(ev)) { @@ -165,7 +165,7 @@ static int ir_rcmm_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "RC-MM decode failed at count %d state %d (%uus %s)\n", - data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->count, data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c index dd6ee1e339d6..bfc181be1044 100644 --- a/drivers/media/rc/ir-sanyo-decoder.c +++ b/drivers/media/rc/ir-sanyo-decoder.c @@ -17,7 +17,7 @@ #include "rc-core-priv.h" #define SANYO_NBITS (13+13+8+8) -#define SANYO_UNIT 562500 /* ns */ +#define SANYO_UNIT 563 /* us */ #define SANYO_HEADER_PULSE (16 * SANYO_UNIT) #define SANYO_HEADER_SPACE (8 * SANYO_UNIT) #define SANYO_BIT_PULSE (1 * SANYO_UNIT) @@ -59,7 +59,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "SANYO decode started at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); switch (data->state) { @@ -158,7 +158,7 @@ static int ir_sanyo_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "SANYO decode failed at count %d state %d (%uus %s)\n", - data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->count, data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c index 37fab0919131..d09c38c07dbd 100644 --- a/drivers/media/rc/ir-sharp-decoder.c +++ b/drivers/media/rc/ir-sharp-decoder.c @@ -12,7 +12,7 @@ #include "rc-core-priv.h" #define SHARP_NBITS 15 -#define SHARP_UNIT 40000 /* ns */ +#define SHARP_UNIT 40 /* us */ #define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */ #define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */ #define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */ @@ -47,7 +47,7 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "Sharp decode started at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); switch (data->state) { @@ -159,7 +159,7 @@ static int ir_sharp_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "Sharp decode failed at count %d state %d (%uus %s)\n", - data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->count, data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c index 9fa58d92eb09..52207541f9f6 100644 --- a/drivers/media/rc/ir-sony-decoder.c +++ b/drivers/media/rc/ir-sony-decoder.c @@ -8,7 +8,7 @@ #include #include "rc-core-priv.h" -#define SONY_UNIT 600000 /* ns */ +#define SONY_UNIT 600 /* us */ #define SONY_HEADER_PULSE (4 * SONY_UNIT) #define SONY_HEADER_SPACE (1 * SONY_UNIT) #define SONY_BIT_0_PULSE (1 * SONY_UNIT) @@ -48,7 +48,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) goto out; dev_dbg(&dev->dev, "Sony decode started at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); switch (data->state) { @@ -154,7 +154,7 @@ static int ir_sony_decode(struct rc_dev *dev, struct ir_raw_event ev) out: dev_dbg(&dev->dev, "Sony decode failed at state %d (%uus %s)\n", - data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; diff --git a/drivers/media/rc/ir-xmp-decoder.c b/drivers/media/rc/ir-xmp-decoder.c index 4c3d03876200..ff94f48bda32 100644 --- a/drivers/media/rc/ir-xmp-decoder.c +++ b/drivers/media/rc/ir-xmp-decoder.c @@ -12,11 +12,12 @@ #include #include "rc-core-priv.h" -#define XMP_UNIT 136000 /* ns */ -#define XMP_LEADER 210000 /* ns */ -#define XMP_NIBBLE_PREFIX 760000 /* ns */ -#define XMP_HALFFRAME_SPACE 13800000 /* ns */ -#define XMP_TRAILER_SPACE 20000000 /* should be 80ms but not all dureation supliers can go that high */ +#define XMP_UNIT 136 /* us */ +#define XMP_LEADER 210 /* us */ +#define XMP_NIBBLE_PREFIX 760 /* us */ +#define XMP_HALFFRAME_SPACE 13800 /* us */ +/* should be 80ms but not all duration supliers can go that high */ +#define XMP_TRAILER_SPACE 20000 enum xmp_state { STATE_INACTIVE, @@ -42,7 +43,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "XMP decode started at state %d %d (%uus %s)\n", - data->state, data->count, TO_US(ev.duration), TO_STR(ev.pulse)); + data->state, data->count, ev.duration, TO_STR(ev.pulse)); switch (data->state) { @@ -183,7 +184,7 @@ static int ir_xmp_decode(struct rc_dev *dev, struct ir_raw_event ev) } dev_dbg(&dev->dev, "XMP decode failed at count %d state %d (%uus %s)\n", - data->count, data->state, TO_US(ev.duration), TO_STR(ev.pulse)); + data->count, data->state, ev.duration, TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; } diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 5c7a7500a925..e0242c9b6aeb 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -38,8 +38,8 @@ static const u8 COMMAND_TXSTART[] = { 0x26, 0x24, 0x25, 0x03 }; #define LEN_SAMPLEMODEPROTO 3 #define MIN_FW_VERSION 20 -#define UNIT_NS 21333 -#define MAX_TIMEOUT_NS (UNIT_NS * U16_MAX) +#define UNIT_US 21 +#define MAX_TIMEOUT_US (UNIT_US * U16_MAX) #define MAX_PACKET 64 @@ -131,7 +131,7 @@ static void irtoy_response(struct irtoy *irtoy, u32 len) if (v == 0xffff) { rawir.pulse = false; } else { - rawir.duration = v * UNIT_NS; + rawir.duration = v * UNIT_US; ir_raw_event_store_with_timeout(irtoy->rc, &rawir); } @@ -302,7 +302,7 @@ static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count) return -ENOMEM; for (i = 0; i < count; i++) { - u16 v = DIV_ROUND_CLOSEST(US_TO_NS(txbuf[i]), UNIT_NS); + u16 v = DIV_ROUND_CLOSEST(txbuf[i], UNIT_US); if (!v) v = 1; @@ -438,7 +438,7 @@ static int irtoy_probe(struct usb_interface *intf, rc->tx_ir = irtoy_tx; rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->map_name = RC_MAP_RC6_MCE; - rc->rx_resolution = UNIT_NS; + rc->rx_resolution = UNIT_US; rc->timeout = IR_DEFAULT_TIMEOUT; /* @@ -450,8 +450,8 @@ static int irtoy_probe(struct usb_interface *intf, * * So, make timeout a largish minimum which works with most protocols. */ - rc->min_timeout = MS_TO_NS(40); - rc->max_timeout = MAX_TIMEOUT_NS; + rc->min_timeout = MS_TO_US(40); + rc->max_timeout = MAX_TIMEOUT_US; err = rc_register_device(rc); if (err) diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 07667c04c1d2..a905113fef6e 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -176,14 +176,14 @@ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int if (next_one > 0) { ev.pulse = true; ev.duration = - ITE_BITS_TO_NS(next_one, sample_period); + ITE_BITS_TO_US(next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); } while (next_one < size) { next_zero = find_next_zero_bit_le(ldata, size, next_one + 1); ev.pulse = false; - ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period); + ev.duration = ITE_BITS_TO_US(next_zero - next_one, sample_period); ir_raw_event_store_with_filter(dev->rdev, &ev); if (next_zero < size) { @@ -193,7 +193,7 @@ static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int next_zero + 1); ev.pulse = true; ev.duration = - ITE_BITS_TO_NS(next_one - next_zero, + ITE_BITS_TO_US(next_one - next_zero, sample_period); ir_raw_event_store_with_filter (dev->rdev, &ev); @@ -1555,9 +1555,9 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id rdev->timeout = IR_DEFAULT_TIMEOUT; rdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; rdev->rx_resolution = ITE_BAUDRATE_DIVISOR * - itdev->params.sample_period; + itdev->params.sample_period / 1000; rdev->tx_resolution = ITE_BAUDRATE_DIVISOR * - itdev->params.sample_period; + itdev->params.sample_period / 1000; /* set up transmitter related values if needed */ if (itdev->params.hw_tx_capable) { diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h index f04c4b34ff0c..4954470448a7 100644 --- a/drivers/media/rc/ite-cir.h +++ b/drivers/media/rc/ite-cir.h @@ -146,8 +146,8 @@ struct ite_dev { #define ITE_DEFAULT_CARRIER_FREQ 38000 /* convert bits to us */ -#define ITE_BITS_TO_NS(bits, sample_period) \ -((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period)) +#define ITE_BITS_TO_US(bits, sample_period) \ +((u32)((bits) * ITE_BAUDRATE_DIVISOR * (sample_period) / 1000)) /* * n in RDCR produces a tolerance of +/- n * 6.25% around the center diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index bea52a2fae2b..cde817e744b7 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -67,17 +67,16 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) dev->gap = true; dev->gap_duration = ev.duration; - sample = LIRC_TIMEOUT(ev.duration / 1000); + sample = LIRC_TIMEOUT(ev.duration); dev_dbg(&dev->dev, "timeout report (duration: %d)\n", sample); /* Normal sample */ } else { if (dev->gap) { - dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(), + dev->gap_duration += ktime_to_us(ktime_sub(ktime_get(), dev->gap_start)); - /* Convert to ms and cap by LIRC_VALUE_MASK */ - do_div(dev->gap_duration, 1000); + /* Cap by LIRC_VALUE_MASK */ dev->gap_duration = min_t(u64, dev->gap_duration, LIRC_VALUE_MASK); @@ -89,10 +88,10 @@ void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev) dev->gap = false; } - sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) : - LIRC_SPACE(ev.duration / 1000); + sample = ev.pulse ? LIRC_PULSE(ev.duration) : + LIRC_SPACE(ev.duration); dev_dbg(&dev->dev, "delivering %uus %s to lirc_dev\n", - TO_US(ev.duration), TO_STR(ev.pulse)); + ev.duration, TO_STR(ev.pulse)); } /* @@ -296,8 +295,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, } for (i = 0; i < count; i++) - /* Convert from NS to US */ - txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000); + txbuf[i] = raw[i].duration; if (dev->s_tx_carrier) { int carrier = ir_raw_encode_carrier(scan.rc_proto); @@ -325,7 +323,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, } for (i = 0; i < count; i++) { - if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) { + if (txbuf[i] > IR_MAX_DURATION - duration || !txbuf[i]) { ret = -EINVAL; goto out_kfree; } @@ -517,7 +515,7 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, if (!dev->rx_resolution) ret = -ENOTTY; else - val = dev->rx_resolution / 1000; + val = dev->rx_resolution; break; case LIRC_SET_WIDEBAND_RECEIVER: @@ -539,31 +537,26 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, if (!dev->max_timeout) ret = -ENOTTY; else - val = DIV_ROUND_UP(dev->min_timeout, 1000); + val = dev->min_timeout; break; case LIRC_GET_MAX_TIMEOUT: if (!dev->max_timeout) ret = -ENOTTY; else - val = dev->max_timeout / 1000; + val = dev->max_timeout; break; case LIRC_SET_REC_TIMEOUT: if (!dev->max_timeout) { ret = -ENOTTY; - } else if (val > U32_MAX / 1000) { - /* Check for multiply overflow */ - ret = -EINVAL; } else { - u32 tmp = val * 1000; - - if (tmp < dev->min_timeout || tmp > dev->max_timeout) + if (val < dev->min_timeout || val > dev->max_timeout) ret = -EINVAL; else if (dev->s_timeout) - ret = dev->s_timeout(dev, tmp); + ret = dev->s_timeout(dev, val); else - dev->timeout = tmp; + dev->timeout = val; } break; @@ -571,7 +564,7 @@ static long ir_lirc_ioctl(struct file *file, unsigned int cmd, if (!dev->timeout) ret = -ENOTTY; else - val = DIV_ROUND_UP(dev->timeout, 1000); + val = dev->timeout; break; case LIRC_SET_REC_TIMEOUT_REPORTS: diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index f9616158bcf4..989dd573c669 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1070,7 +1070,7 @@ static int mceusb_set_timeout(struct rc_dev *dev, unsigned int timeout) struct mceusb_dev *ir = dev->priv; unsigned int units; - units = DIV_ROUND_CLOSEST(timeout, US_TO_NS(MCE_TIME_UNIT)); + units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT); cmdbuf[2] = units >> 8; cmdbuf[3] = units; @@ -1196,7 +1196,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, u8 *buf_in) switch (subcmd) { /* 2-byte return value commands */ case MCE_RSP_EQIRTIMEOUT: - ir->rc->timeout = US_TO_NS((*hi << 8 | *lo) * MCE_TIME_UNIT); + ir->rc->timeout = (*hi << 8 | *lo) * MCE_TIME_UNIT; break; case MCE_RSP_EQIRNUMPORTS: ir->num_txports = *hi; @@ -1291,9 +1291,9 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ir->pulse_tunit += rawir.duration; ir->pulse_count++; } - rawir.duration *= US_TO_NS(MCE_TIME_UNIT); + rawir.duration *= MCE_TIME_UNIT; - dev_dbg(ir->dev, "Storing %s %u ns (%02x)", + dev_dbg(ir->dev, "Storing %s %u us (%02x)", rawir.pulse ? "pulse" : "space", rawir.duration, ir->buf_in[i]); @@ -1605,8 +1605,8 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->dev.parent = dev; rc->priv = ir; rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - rc->min_timeout = US_TO_NS(MCE_TIME_UNIT); - rc->timeout = MS_TO_NS(100); + rc->min_timeout = MCE_TIME_UNIT; + rc->timeout = MS_TO_US(100); if (!mceusb_model[ir->model].broken_irtimeout) { rc->s_timeout = mceusb_set_timeout; rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c index 51c6dd3406a0..dad55950dfc6 100644 --- a/drivers/media/rc/meson-ir.c +++ b/drivers/media/rc/meson-ir.c @@ -86,7 +86,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id) duration = readl_relaxed(ir->reg + IR_DEC_REG1); duration = FIELD_GET(REG1_TIME_IV_MASK, duration); - rawir.duration = US_TO_NS(duration * MESON_TRATE); + rawir.duration = duration * MESON_TRATE; status = readl_relaxed(ir->reg + IR_DEC_STATUS); rawir.pulse = !!(status & STATUS_IR_DEC_IN); @@ -133,7 +133,7 @@ static int meson_ir_probe(struct platform_device *pdev) map_name = of_get_property(node, "linux,rc-map-name", NULL); ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); + ir->rc->rx_resolution = MESON_TRATE; ir->rc->min_timeout = 1; ir->rc->timeout = IR_DEFAULT_TIMEOUT; ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c index a0c94ab322c7..5051a5e5244b 100644 --- a/drivers/media/rc/mtk-cir.c +++ b/drivers/media/rc/mtk-cir.c @@ -52,8 +52,8 @@ #define MTK_IR_END(v, p) ((v) == MTK_MAX_SAMPLES && (p) == 0) /* Number of registers to record the pulse width */ #define MTK_CHKDATA_SZ 17 -/* Sample period in ns */ -#define MTK_IR_SAMPLE 46000 +/* Sample period in us */ +#define MTK_IR_SAMPLE 46 enum mtk_fields { /* Register to setting software sampling period */ diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 52d246dc5b3d..8a37f083fe3d 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -653,8 +653,7 @@ static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev, /* Inspect the ir samples */ for (i = 0, count = 0; i < ret && count < WAKEUP_MAX_SIZE; ++i) { - /* NS to US */ - val = DIV_ROUND_UP(raw[i].duration, 1000L) / SAMPLE_PERIOD; + val = raw[i].duration / SAMPLE_PERIOD; /* Split too large values into several smaller ones */ while (val > 0 && count < WAKEUP_MAX_SIZE) { @@ -721,8 +720,7 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) sample = nvt->buf[i]; rawir.pulse = ((sample & BUF_PULSE_BIT) != 0); - rawir.duration = US_TO_NS((sample & BUF_LEN_MASK) - * SAMPLE_PERIOD); + rawir.duration = (sample & BUF_LEN_MASK) * SAMPLE_PERIOD; nvt_dbg("Storing %s with duration %d", rawir.pulse ? "pulse" : "space", rawir.duration); @@ -1000,9 +998,9 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) rdev->input_id.version = nvt->chip_minor; rdev->driver_name = NVT_DRIVER_NAME; rdev->map_name = RC_MAP_RC6_MCE; - rdev->timeout = MS_TO_NS(100); + rdev->timeout = MS_TO_US(100); /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ - rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); + rdev->rx_resolution = CIR_SAMPLE_PERIOD; #if 0 rdev->min_timeout = XYZ; rdev->max_timeout = XYZ; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 0cf301d1e163..ed7d93beaa28 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -94,7 +94,7 @@ struct nvt_dev { #define CIR_IOREG_LENGTH 0x0f /* RX limit length, 8 high bits for SLCH, 8 low bits for SLCL */ -#define CIR_RX_LIMIT_COUNT (IR_DEFAULT_TIMEOUT / US_TO_NS(SAMPLE_PERIOD)) +#define CIR_RX_LIMIT_COUNT (IR_DEFAULT_TIMEOUT / SAMPLE_PERIOD) /* CIR Regs */ #define CIR_IRCON 0x00 diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 1eeab277a08e..a59c6c416a18 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -193,7 +193,6 @@ static inline bool is_timing_event(struct ir_raw_event ev) return !ev.carrier_report && !ev.reset; } -#define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") /* functions for IR encoders */ diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 39dd46bbd0c1..820d33aa156e 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -77,7 +77,7 @@ int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev) return -EINVAL; dev_dbg(&dev->dev, "sample: (%05dus %s)\n", - TO_US(ev->duration), TO_STR(ev->pulse)); + ev->duration, TO_STR(ev->pulse)); if (!kfifo_put(&dev->raw->kfifo, *ev)) { dev_err(&dev->dev, "IR event FIFO is full!\n"); @@ -108,7 +108,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse) return -EINVAL; now = ktime_get(); - ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); + ev.duration = ktime_to_us(ktime_sub(now, dev->raw->last_event)); ev.pulse = !pulse; return ir_raw_event_store_with_timeout(dev, &ev); @@ -275,7 +275,7 @@ static int change_protocol(struct rc_dev *dev, u64 *rc_proto) if (timeout == 0) timeout = IR_DEFAULT_TIMEOUT; else - timeout += MS_TO_NS(10); + timeout += MS_TO_US(10); if (timeout < dev->min_timeout) timeout = dev->min_timeout; @@ -561,17 +561,17 @@ static void ir_raw_edge_handle(struct timer_list *t) spin_lock_irqsave(&dev->raw->edge_spinlock, flags); interval = ktime_sub(ktime_get(), dev->raw->last_event); - if (ktime_to_ns(interval) >= dev->timeout) { + if (ktime_to_us(interval) >= dev->timeout) { struct ir_raw_event ev = { .timeout = true, - .duration = ktime_to_ns(interval) + .duration = ktime_to_us(interval) }; ir_raw_event_store(dev, &ev); } else { mod_timer(&dev->raw->edge_handle, - jiffies + nsecs_to_jiffies(dev->timeout - - ktime_to_ns(interval))); + jiffies + usecs_to_jiffies(dev->timeout - + ktime_to_us(interval))); } spin_unlock_irqrestore(&dev->raw->edge_spinlock, flags); diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index ef8b83b707df..1ba3f96ffa7d 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -113,7 +113,7 @@ static int loop_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count) for (i = 0; i < count; i++) { rawir.pulse = i % 2 ? false : true; - rawir.duration = txbuf[i] * 1000; + rawir.duration = txbuf[i]; if (rawir.duration) ir_raw_event_store_with_filter(dev, &rawir); } @@ -219,11 +219,11 @@ static int __init loop_init(void) rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; rc->allowed_wakeup_protocols = RC_PROTO_BIT_ALL_IR_ENCODER; rc->encode_wakeup = true; - rc->timeout = 100 * 1000 * 1000; /* 100 ms */ + rc->timeout = MS_TO_US(100); /* 100 ms */ rc->min_timeout = 1; rc->max_timeout = UINT_MAX; - rc->rx_resolution = 1000; - rc->tx_resolution = 1000; + rc->rx_resolution = 1; + rc->tx_resolution = 1; rc->s_tx_mask = loop_set_tx_mask; rc->s_tx_carrier = loop_set_tx_carrier; rc->s_tx_duty_cycle = loop_set_tx_duty_cycle; diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index aad9526f3754..2cf3377ec63a 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -340,7 +340,7 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) { struct ir_raw_event rawir = {}; struct device *dev; - unsigned int i, sig_size, single_len, offset, val; + unsigned int i, sig_size, offset, val; u32 mod_freq; dev = rr3->dev; @@ -361,7 +361,6 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) for (i = 0; i < sig_size; i++) { offset = rr3->irdata.sigdata[i]; val = get_unaligned_be16(&rr3->irdata.lens[offset]); - single_len = redrat3_len_to_us(val); /* we should always get pulse/space/pulse/space samples */ if (i % 2) @@ -369,7 +368,7 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3) else rawir.pulse = true; - rawir.duration = US_TO_NS(single_len); + rawir.duration = redrat3_len_to_us(val); /* cap the value to IR_MAX_DURATION */ rawir.duration = (rawir.duration > IR_MAX_DURATION) ? IR_MAX_DURATION : rawir.duration; @@ -495,7 +494,7 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3) return timeout; } -static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutns) +static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus) { struct redrat3_dev *rr3 = rc_dev->priv; struct usb_device *udev = rr3->udev; @@ -507,7 +506,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutns) if (!timeout) return -ENOMEM; - *timeout = cpu_to_be32(redrat3_us_to_len(timeoutns / 1000)); + *timeout = cpu_to_be32(redrat3_us_to_len(timeoutus)); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout), @@ -947,15 +946,15 @@ static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3) rc->dev.parent = dev; rc->priv = rr3; rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; - rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT); - rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT); - rc->timeout = US_TO_NS(redrat3_get_timeout(rr3)); + rc->min_timeout = MS_TO_US(RR3_RX_MIN_TIMEOUT); + rc->max_timeout = MS_TO_US(RR3_RX_MAX_TIMEOUT); + rc->timeout = redrat3_get_timeout(rr3); rc->s_timeout = redrat3_set_timeout; rc->tx_ir = redrat3_transmit_ir; rc->s_tx_carrier = redrat3_set_tx_carrier; rc->s_carrier_report = redrat3_wideband_receiver; rc->driver_name = DRIVER_NAME; - rc->rx_resolution = US_TO_NS(2); + rc->rx_resolution = 2; rc->map_name = RC_MAP_HAUPPAUGE; ret = rc_register_device(rc); diff --git a/drivers/media/rc/serial_ir.c b/drivers/media/rc/serial_ir.c index 5b5b3203f5a0..8cc28c92d05d 100644 --- a/drivers/media/rc/serial_ir.c +++ b/drivers/media/rc/serial_ir.c @@ -269,7 +269,7 @@ static void frbwrite(unsigned int l, bool is_pulse) if (ptr > 0 && is_pulse) { pulse += l; - if (pulse > 250000) { + if (pulse > 250) { ev.duration = space; ev.pulse = false; ir_raw_event_store_with_filter(serial_ir.rcdev, &ev); @@ -283,13 +283,13 @@ static void frbwrite(unsigned int l, bool is_pulse) } if (!is_pulse) { if (ptr == 0) { - if (l > 20000000) { + if (l > 20000) { space = l; ptr++; return; } } else { - if (l > 20000000) { + if (l > 20000) { space += pulse; if (space > IR_MAX_DURATION) space = IR_MAX_DURATION; @@ -376,7 +376,7 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah) sense = sense ? 0 : 1; } } else { - data = ktime_to_ns(delkt); + data = ktime_to_us(delkt); } frbwrite(data, !(dcd ^ sense)); serial_ir.lastkt = kt; @@ -528,7 +528,7 @@ static int serial_ir_probe(struct platform_device *dev) rcdev->min_timeout = 1; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; - rcdev->rx_resolution = 250000; + rcdev->rx_resolution = 250; serial_ir.rcdev = rcdev; diff --git a/drivers/media/rc/sir_ir.c b/drivers/media/rc/sir_ir.c index 80b3a6736dbd..6ec96dc34586 100644 --- a/drivers/media/rc/sir_ir.c +++ b/drivers/media/rc/sir_ir.c @@ -110,7 +110,7 @@ static void add_read_queue(int flag, unsigned long val) } else { val += TIME_CONST / 2; } - ev.duration = US_TO_NS(val); + ev.duration = val; ir_raw_event_store_with_filter(rcdev, &ev); } diff --git a/drivers/media/rc/st_rc.c b/drivers/media/rc/st_rc.c index 1dc4e2e33705..3237fef5d502 100644 --- a/drivers/media/rc/st_rc.c +++ b/drivers/media/rc/st_rc.c @@ -134,12 +134,12 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data) mark /= dev->sample_div; } - ev.duration = US_TO_NS(mark); + ev.duration = mark; ev.pulse = true; ir_raw_event_store(dev->rdev, &ev); if (!last_symbol) { - ev.duration = US_TO_NS(symbol); + ev.duration = symbol; ev.pulse = false; ir_raw_event_store(dev->rdev, &ev); } else { @@ -292,7 +292,7 @@ static int st_rc_probe(struct platform_device *pdev) rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* rx sampling rate is 10Mhz */ rdev->rx_resolution = 100; - rdev->timeout = US_TO_NS(MAX_SYMB_TIME); + rdev->timeout = MAX_SYMB_TIME; rdev->priv = rc_dev; rdev->open = st_rc_open; rdev->close = st_rc_close; diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index 79a41fc7161c..9f3cd9fb6b6e 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -137,7 +137,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, } else { rawir.duration = delta; rawir.duration -= sz->sum; - rawir.duration = US_TO_NS(rawir.duration); rawir.duration = (rawir.duration > IR_MAX_DURATION) ? IR_MAX_DURATION : rawir.duration; } @@ -151,7 +150,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, rawir.duration = ((int) value) * SZ_RESOLUTION; rawir.duration += SZ_RESOLUTION / 2; sz->sum += rawir.duration; - rawir.duration = US_TO_NS(rawir.duration); rawir.duration = (rawir.duration > IR_MAX_DURATION) ? IR_MAX_DURATION : rawir.duration; sz_push(sz, rawir); @@ -172,7 +170,6 @@ static void sz_push_full_space(struct streamzap_ir *sz, rawir.duration = ((int) value) * SZ_RESOLUTION; rawir.duration += SZ_RESOLUTION / 2; sz->sum += rawir.duration; - rawir.duration = US_TO_NS(rawir.duration); sz_push(sz, rawir); } @@ -403,13 +400,12 @@ static int streamzap_probe(struct usb_interface *intf, sz->decoder_state = PulseSpace; /* FIXME: don't yet have a way to set this */ sz->timeout_enabled = true; - sz->rdev->timeout = ((US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION) & - IR_MAX_DURATION) | 0x03000000); + sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION; #if 0 /* not yet supported, depends on patches from maxim */ /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ - sz->min_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION); - sz->max_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION); + sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION; + sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION; #endif sz->signal_start = ktime_get_real(); diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c index e222b4c98be4..ddee6ee37bab 100644 --- a/drivers/media/rc/sunxi-cir.c +++ b/drivers/media/rc/sunxi-cir.c @@ -241,8 +241,8 @@ static int sunxi_ir_probe(struct platform_device *pdev) ir->rc->dev.parent = dev; ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; /* Frequency after IR internal divider with sample period in ns */ - ir->rc->rx_resolution = (1000000000ul / (b_clk_freq / 64)); - ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); + ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64)); + ir->rc->timeout = MS_TO_US(SUNXI_IR_TIMEOUT); ir->rc->driver_name = SUNXI_IR_DEV; ret = rc_register_device(ir->rc); diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 011a8b620d86..629787d53ee1 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -20,8 +20,8 @@ * messages per second (!), whether IR is idle or not. */ #define NUM_URBS 4 -#define NS_PER_BYTE 62500 -#define NS_PER_BIT (NS_PER_BYTE/8) +#define US_PER_BYTE 62 +#define US_PER_BIT (US_PER_BYTE / 8) struct ttusbir { struct rc_dev *rc; @@ -117,13 +117,13 @@ static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf) switch (v) { case 0xfe: rawir.pulse = false; - rawir.duration = NS_PER_BYTE; + rawir.duration = US_PER_BYTE; if (ir_raw_event_store_with_filter(tt->rc, &rawir)) event = true; break; case 0: rawir.pulse = true; - rawir.duration = NS_PER_BYTE; + rawir.duration = US_PER_BYTE; if (ir_raw_event_store_with_filter(tt->rc, &rawir)) event = true; break; @@ -137,12 +137,12 @@ static void ttusbir_process_ir_data(struct ttusbir *tt, uint8_t *buf) rawir.pulse = false; } - rawir.duration = NS_PER_BIT * (8 - b); + rawir.duration = US_PER_BIT * (8 - b); if (ir_raw_event_store_with_filter(tt->rc, &rawir)) event = true; rawir.pulse = !rawir.pulse; - rawir.duration = NS_PER_BIT * b; + rawir.duration = US_PER_BIT * b; if (ir_raw_event_store_with_filter(tt->rc, &rawir)) event = true; break; @@ -311,10 +311,10 @@ static int ttusbir_probe(struct usb_interface *intf, rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; /* - * The precision is NS_PER_BIT, but since every 8th bit can be - * overwritten with garbage the accuracy is at best 2 * NS_PER_BIT. + * The precision is US_PER_BIT, but since every 8th bit can be + * overwritten with garbage the accuracy is at best 2 * US_PER_BIT. */ - rc->rx_resolution = NS_PER_BIT; + rc->rx_resolution = 2 * US_PER_BIT; ret = rc_register_device(rc); if (ret) { diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 630e376d3688..aed23ca0fa6c 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -354,7 +354,6 @@ wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device) { u8 irdata; struct ir_raw_event rawir = {}; - unsigned duration; /* Since RXHDLEV is set, at least 8 bytes are in the FIFO */ while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) { @@ -362,13 +361,12 @@ wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device) if (data->rxstate == WBCIR_RXSTATE_ERROR) continue; - duration = ((irdata & 0x7F) + 1) * + rawir.duration = ((irdata & 0x7F) + 1) * (data->carrier_report_enabled ? 2 : 10); rawir.pulse = irdata & 0x80 ? false : true; - rawir.duration = US_TO_NS(duration); if (rawir.pulse) - data->pulse_duration += duration; + data->pulse_duration += rawir.duration; ir_raw_event_store_with_filter(data->dev, &rawir); } @@ -519,7 +517,7 @@ wbcir_set_carrier_report(struct rc_dev *dev, int enable) /* Set a higher sampling resolution if carrier reports are enabled */ wbcir_select_bank(data, WBCIR_BANK_2); - data->dev->rx_resolution = US_TO_NS(enable ? 2 : 10); + data->dev->rx_resolution = enable ? 2 : 10; outb(enable ? 0x03 : 0x0f, data->sbase + WBCIR_REG_SP3_BGDL); outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH); @@ -1076,7 +1074,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->min_timeout = 1; data->dev->timeout = IR_DEFAULT_TIMEOUT; data->dev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; - data->dev->rx_resolution = US_TO_NS(2); + data->dev->rx_resolution = 2; data->dev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; data->dev->allowed_wakeup_protocols = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC5 | diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c index 4a3f2cc4ef18..98d0b43608ad 100644 --- a/drivers/media/rc/xbox_remote.c +++ b/drivers/media/rc/xbox_remote.c @@ -157,7 +157,7 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) rdev->device_name = xbox_remote->rc_name; rdev->input_phys = xbox_remote->rc_phys; - rdev->timeout = MS_TO_NS(10); + rdev->timeout = MS_TO_US(10); usb_to_input_id(xbox_remote->udev, &rdev->input_id); rdev->dev.parent = &xbox_remote->interface->dev; diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 4befa920246c..3d3368202cd0 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -104,11 +104,11 @@ static int au8522_rc_andor(struct au0828_rc *ir, u16 reg, u8 mask, u8 value) /* Remote Controller time units */ -#define AU8522_UNIT 200000 /* ns */ -#define NEC_START_SPACE (4500000 / AU8522_UNIT) -#define NEC_START_PULSE (562500 * 16) +#define AU8522_UNIT 200 /* us */ +#define NEC_START_SPACE (4500 / AU8522_UNIT) +#define NEC_START_PULSE (563 * 16) #define RC5_START_SPACE (4 * AU8522_UNIT) -#define RC5_START_PULSE 888888 +#define RC5_START_PULSE 889 static int au0828_get_key_au8522(struct au0828_rc *ir) { diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 2080f6ef4be1..91460e4d0c30 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1781,7 +1781,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) /* pass data to Kernel IR decoder */ for (i = 0; i < len; i++) { ev.pulse = buf[i] >> 7; - ev.duration = 50800 * (buf[i] & 0x7f); + ev.duration = 51 * (buf[i] & 0x7f); ir_raw_event_store_with_filter(d->rc_dev, &ev); } @@ -1809,7 +1809,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d, rc->query = rtl2832u_rc_query; rc->interval = 200; /* we program idle len to 0xc0, set timeout to one less */ - rc->timeout = 0xbf * 50800; + rc->timeout = 0xbf * 51; return 0; } diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index f172120db2aa..a9ed26ce1be6 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -656,14 +656,14 @@ unlock: for (i = 1; i < ARRAY_SIZE(state->buf); i++) { if (buf[i] == 0xff) { ev.pulse = 0; - ev.duration = 888888*2; + ev.duration = 889 * 2; ir_raw_event_store(d->rc_dev, &ev); break; } ev.pulse = !ev.pulse; ev.duration = (buf[i] * FIRMWARE_CLOCK_DIVISOR * - FIRMWARE_CLOCK_TICK) / 1000; + FIRMWARE_CLOCK_TICK) / (1000 * 1000); ir_raw_event_store(d->rc_dev, &ev); } diff --git a/include/media/rc-core.h b/include/media/rc-core.h index d3f85df64bb2..a1019c4ab5e8 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -128,8 +128,8 @@ struct lirc_fh { * @timeout: optional time after which device stops sending data * @min_timeout: minimum timeout supported by device * @max_timeout: maximum timeout supported by device - * @rx_resolution : resolution (in ns) of input sampler - * @tx_resolution: resolution (in ns) of output sampler + * @rx_resolution : resolution (in us) of input sampler + * @tx_resolution: resolution (in us) of output sampler * @lirc_dev: lirc device * @lirc_cdev: lirc char cdev * @gap_start: time when gap starts @@ -157,7 +157,7 @@ struct lirc_fh { * @s_wakeup_filter: set the wakeup scancode filter. If the mask is zero * then wakeup should be disabled. wakeup_protocol will be set to * a valid protocol if mask is nonzero. - * @s_timeout: set hardware timeout in ns + * @s_timeout: set hardware timeout in us */ struct rc_dev { struct device dev; @@ -309,11 +309,10 @@ struct ir_raw_event { unsigned carrier_report:1; }; -#define IR_DEFAULT_TIMEOUT MS_TO_NS(125) -#define IR_MAX_DURATION 500000000 /* 500 ms */ #define US_TO_NS(usec) ((usec) * 1000) #define MS_TO_US(msec) ((msec) * 1000) -#define MS_TO_NS(msec) ((msec) * 1000 * 1000) +#define IR_MAX_DURATION MS_TO_US(500) +#define IR_DEFAULT_TIMEOUT MS_TO_US(125) void ir_raw_event_handle(struct rc_dev *dev); int ir_raw_event_store(struct rc_dev *dev, struct ir_raw_event *ev); -- cgit v1.2.3 From 6c11631480e9a0554ae5ee89dc12acaa1f1a93a0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 11 Aug 2020 22:59:35 +0200 Subject: media: v4l2-async: Document asd allocation requirements The v4l2_async_notifier_add_subdev() function requires the asd pointer it receives to be allocated dynamically, but doesn't explicitly say so. Only one driver out of 13 get its right (atmel-sama5d2-isc.c, but with memory leaks in the error paths), clearly showing we have an issue. Update the v4l2_async_notifier_add_subdev() documentation to clearly state the allocation requirement. Whether this will be enough to avoid new offending code isn't certain, but it's a good first step nonetheless. Fixes: 9ca465312132 ("media: v4l: fwnode: Support generic parsing of graph endpoints in a device") Signed-off-by: Laurent Pinchart Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-async.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 8319284c93cb..d6e31234826f 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -154,8 +154,9 @@ void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier); * @notifier: pointer to &struct v4l2_async_notifier * @asd: pointer to &struct v4l2_async_subdev * - * Call this function before registering a notifier to link the - * provided asd to the notifiers master @asd_list. + * Call this function before registering a notifier to link the provided @asd to + * the notifiers master @asd_list. The @asd must be allocated with k*alloc() as + * it will be freed by the framework when the notifier is destroyed. */ int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd); -- cgit v1.2.3 From 2e654432a260d968cd505898e1c056ce6ab63c31 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Sep 2020 10:16:57 +0200 Subject: media: v4l2-fwnode: Make number of data lanes a character The maximum is currently four (4). No short is needed. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-fwnode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index c47b70636e42..81e7eb123294 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -40,7 +40,7 @@ struct v4l2_fwnode_bus_mipi_csi2 { unsigned int flags; unsigned char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES]; unsigned char clock_lane; - unsigned short num_data_lanes; + unsigned char num_data_lanes; bool lane_polarities[1 + V4L2_FWNODE_CSI2_MAX_DATA_LANES]; }; -- cgit v1.2.3 From bb4bba9232fc90f173a2215035334ceec0457f2f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Sep 2020 10:20:28 +0200 Subject: media: v4l2-fwnode: Make bus configuration a struct The bus specific parameters were a union. This made providing bus specific defaults impossible as the memory used to store the defaults for multiple different busses was the same. Make it struct instead. It's not large so the size isn't really an issue. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-fwnode.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index 81e7eb123294..d04f39b60096 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -78,7 +78,7 @@ struct v4l2_fwnode_bus_mipi_csi1 { * struct v4l2_fwnode_endpoint - the endpoint data structure * @base: fwnode endpoint of the v4l2_fwnode * @bus_type: bus type - * @bus: union with bus configuration data structure + * @bus: bus configuration data structure * @bus.parallel: embedded &struct v4l2_fwnode_bus_parallel. * Used if the bus is parallel. * @bus.mipi_csi1: embedded &struct v4l2_fwnode_bus_mipi_csi1. @@ -99,7 +99,7 @@ struct v4l2_fwnode_endpoint { * v4l2_fwnode_endpoint_parse() */ enum v4l2_mbus_type bus_type; - union { + struct { struct v4l2_fwnode_bus_parallel parallel; struct v4l2_fwnode_bus_mipi_csi1 mipi_csi1; struct v4l2_fwnode_bus_mipi_csi2 mipi_csi2; -- cgit v1.2.3 From da5c791cfcdf11d6c2be276896cf0cb8181da1fd Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 8 Sep 2020 10:23:29 +0200 Subject: media: v4l2-fwnode: Document new usage patterns of v4l2_fwnode_endpoint_parse Document that it is possible to provide defaults for multiple bus types to v4l2_fwnode_endpoint_parse and v4l2_fwnode_endpoint_alloc_parse. Also underline the fact that detecting the bus type without bus-type property is only for the old drivers. Also correct capitalisation of BT.656. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-fwnode.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h index d04f39b60096..c09074276543 100644 --- a/include/media/v4l2-fwnode.h +++ b/include/media/v4l2-fwnode.h @@ -226,11 +226,10 @@ struct v4l2_fwnode_connector { * call this function once the correct type is found --- with a default * configuration valid for that type. * - * As a compatibility means guessing the bus type is also supported by setting - * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default - * configuration in this case as the defaults are specific to a given bus type. - * This functionality is deprecated and should not be used in new drivers and it - * is only supported for CSI-2 D-PHY, parallel and Bt.656 buses. + * It is also allowed to set @vep.bus_type to V4L2_MBUS_UNKNOWN. USING THIS + * FEATURE REQUIRES "bus-type" PROPERTY IN DT BINDINGS. For old drivers, + * guessing @vep.bus_type between CSI-2 D-PHY, parallel and BT.656 busses is + * supported. NEVER RELY ON GUESSING @vep.bus_type IN NEW DRIVERS! * * The function does not change the V4L2 fwnode endpoint state if it fails. * @@ -269,11 +268,10 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep); * call this function once the correct type is found --- with a default * configuration valid for that type. * - * As a compatibility means guessing the bus type is also supported by setting - * @vep.bus_type to V4L2_MBUS_UNKNOWN. The caller may not provide a default - * configuration in this case as the defaults are specific to a given bus type. - * This functionality is deprecated and should not be used in new drivers and it - * is only supported for CSI-2 D-PHY, parallel and Bt.656 buses. + * It is also allowed to set @vep.bus_type to V4L2_MBUS_UNKNOWN. USING THIS + * FEATURE REQUIRES "bus-type" PROPERTY IN DT BINDINGS. For old drivers, + * guessing @vep.bus_type between CSI-2 D-PHY, parallel and BT.656 busses is + * supported. NEVER RELY ON GUESSING @vep.bus_type IN NEW DRIVERS! * * The function does not change the V4L2 fwnode endpoint state if it fails. * -- cgit v1.2.3 From 5823833c9adab5a9ce5500e7f1ce7deeff00ee73 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Sat, 11 Jul 2020 14:52:36 +0200 Subject: media: v4l2-ctrl: Add VP9 codec levels Add menu control for VP9 codec levels. A total of 14 levels are defined for Profile 0 (8bit) and Profile 2 (10bit). Each level is a set of constrained bitstreams coded with targeted resolutions, frame rates, and bitrates. The definitions have been taken from webm project [1]. [1] https://www.webmproject.org/vp9/levels/ Signed-off-by: Stanimir Varbanov Reviewed-by: Nicolas Dufresne Reviewed-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/ext-ctrls-codec.rst | 43 ++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ctrls.c | 21 +++++++++++ include/uapi/linux/v4l2-controls.h | 17 +++++++++ 3 files changed, 81 insertions(+) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index 289d380e2cf0..ce728c757eaf 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -3383,6 +3383,49 @@ enum v4l2_mpeg_video_vp9_profile - * - ``V4L2_MPEG_VIDEO_VP9_PROFILE_3`` - Profile 3 +.. _v4l2-mpeg-video-vp9-level: + +``V4L2_CID_MPEG_VIDEO_VP9_LEVEL (enum)`` + +enum v4l2_mpeg_video_vp9_level - + This control allows selecting the level for VP9 encoder. + This is also used to enumerate supported levels by VP9 encoder or decoder. + More information can be found at + `webmproject `__. Possible values are: + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_1_0`` + - Level 1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_1_1`` + - Level 1.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_2_0`` + - Level 2 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_2_1`` + - Level 2.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_3_0`` + - Level 3 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_3_1`` + - Level 3.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_4_0`` + - Level 4 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_4_1`` + - Level 4.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_5_0`` + - Level 5 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_5_1`` + - Level 5.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_5_2`` + - Level 5.2 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_6_0`` + - Level 6 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_6_1`` + - Level 6.1 + * - ``V4L2_MPEG_VIDEO_VP9_LEVEL_6_2`` + - Level 6.2 + High Efficiency Video Coding (HEVC/H.265) Control Reference =========================================================== diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 73f3d65957ff..bd7f330c941c 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -475,6 +475,23 @@ const char * const *v4l2_ctrl_get_menu(u32 id) "3", NULL, }; + static const char * const vp9_level[] = { + "1", + "1.1", + "2", + "2.1", + "3", + "3.1", + "4", + "4.1", + "5", + "5.1", + "5.2", + "6", + "6.1", + "6.2", + NULL, + }; static const char * const flash_led_mode[] = { "Off", @@ -694,6 +711,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id) return vp8_profile; case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return vp9_profile; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: + return vp9_level; case V4L2_CID_JPEG_CHROMA_SUBSAMPLING: return jpeg_chroma_subsampling; case V4L2_CID_DV_TX_MODE: @@ -950,6 +969,7 @@ const char *v4l2_ctrl_get_name(u32 id) case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP: return "VPX P-Frame QP Value"; case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: return "VP8 Profile"; case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: return "VP9 Profile"; + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: return "VP9 Level"; case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: return "VP8 Frame Header"; /* HEVC controls */ @@ -1307,6 +1327,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL: case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: + case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: case V4L2_CID_DETECT_MD_MODE: case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index 053827cda8e6..a184c4939438 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -651,6 +651,23 @@ enum v4l2_mpeg_video_vp9_profile { V4L2_MPEG_VIDEO_VP9_PROFILE_2 = 2, V4L2_MPEG_VIDEO_VP9_PROFILE_3 = 3, }; +#define V4L2_CID_MPEG_VIDEO_VP9_LEVEL (V4L2_CID_MPEG_BASE+513) +enum v4l2_mpeg_video_vp9_level { + V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 = 1, + V4L2_MPEG_VIDEO_VP9_LEVEL_2_0 = 2, + V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 = 3, + V4L2_MPEG_VIDEO_VP9_LEVEL_3_0 = 4, + V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 = 5, + V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 = 6, + V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 = 7, + V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 = 8, + V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 = 9, + V4L2_MPEG_VIDEO_VP9_LEVEL_5_2 = 10, + V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 = 11, + V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 = 12, + V4L2_MPEG_VIDEO_VP9_LEVEL_6_2 = 13, +}; /* CIDs for HEVC encoding. */ -- cgit v1.2.3 From 6d885330fa3daede6bf24b7422da9d6d9a577eb8 Mon Sep 17 00:00:00 2001 From: Stanimir Varbanov Date: Mon, 17 Aug 2020 10:27:22 +0200 Subject: media: firmware: qcom_scm: Add memory protect virtual address ranges This adds a new SCM memprotect command to set virtual address ranges. Signed-off-by: Stanimir Varbanov Reviewed-by: Elliot Berman Acked-by: Bjorn Andersson Signed-off-by: Mauro Carvalho Chehab --- drivers/firmware/qcom_scm.c | 24 ++++++++++++++++++++++++ drivers/firmware/qcom_scm.h | 1 + include/linux/qcom_scm.h | 7 +++++++ 3 files changed, 32 insertions(+) (limited to 'include') diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index e8bbf2d38ae7..7be48c1bec96 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -756,6 +756,30 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) } EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); +int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, + u32 cp_nonpixel_size) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_VIDEO_VAR, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL, + QCOM_SCM_VAL, QCOM_SCM_VAL), + .args[0] = cp_start, + .args[1] = cp_size, + .args[2] = cp_nonpixel_start, + .args[3] = cp_nonpixel_size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; +} +EXPORT_SYMBOL(qcom_scm_mem_protect_video_var); + static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz) diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 38ea614d29fe..95cd1ac30ab0 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -97,6 +97,7 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, #define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 +#define QCOM_SCM_MP_VIDEO_VAR 0x08 #define QCOM_SCM_MP_ASSIGN 0x16 #define QCOM_SCM_SVC_OCMEM 0x0f diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 2e1193a3fb5f..0165824c5128 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -84,6 +84,9 @@ extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); +extern int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, + u32 cp_nonpixel_size); extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *src, const struct qcom_scm_vmperm *newvm, @@ -141,6 +144,10 @@ static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; } static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; } +extern inline int qcom_scm_mem_protect_video_var(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, + u32 cp_nonpixel_size) + { return -ENODEV; } static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *src, const struct qcom_scm_vmperm *newvm, unsigned int dest_cnt) { return -ENODEV; } -- cgit v1.2.3 From b38c73ca1c213bbf8a872b334a6bb835becfaba5 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 27 Aug 2020 21:46:08 +0200 Subject: media: v4l2: add support for colorspace conversion API (CSC) for video capture For video capture it is the driver that reports the colorspace, transfer function, Y'CbCr/HSV encoding and quantization range used by the video, and there is no way to request something different, even though many HDTV receivers have some sort of colorspace conversion capabilities. For output video this feature already exists since the application specifies this information for the video format it will send out, and the transmitter will enable any available CSC if a format conversion has to be performed in order to match the capabilities of the sink. For video capture we propose adding new v4l2_pix_format flag: V4L2_PIX_FMT_FLAG_SET_CSC. The flag is set by the application, the driver will interpret the colorspace, xfer_func, ycbcr_enc/hsv_enc and quantization fields as the requested colorspace information and will attempt to do the conversion it supports. Drivers set the flags V4L2_FMT_FLAG_CSC_COLORSPACE, V4L2_FMT_FLAG_CSC_XFER_FUNC, V4L2_FMT_FLAG_CSC_YCBCR_ENC/V4L2_FMT_FLAG_CSC_HSV_ENC, V4L2_FMT_FLAG_CSC_QUANTIZATION, in the flags field of the struct v4l2_fmtdesc during enumeration to indicate that they support colorspace conversion for the respective field. Drivers do not have to actually look at the flags. If the flags are not set, then the fields 'colorspace', 'xfer_func', 'ycbcr_enc/hsv_enc', and 'quantization' are set to the default values by the core, i.e. just pass on the received format without conversion. Signed-off-by: Hans Verkuil Signed-off-by: Philipp Zabel Signed-off-by: Dafna Hirschfeld Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/pixfmt-v4l2-mplane.rst | 16 ++---- .../userspace-api/media/v4l/pixfmt-v4l2.rst | 64 ++++++++++++++++++++-- .../userspace-api/media/v4l/vidioc-enum-fmt.rst | 35 ++++++++++++ .../userspace-api/media/videodev2.h.rst.exceptions | 5 ++ include/uapi/linux/videodev2.h | 6 ++ 5 files changed, 109 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst b/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst index ac82882135ae..977facc3a1f4 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-v4l2-mplane.rst @@ -98,29 +98,21 @@ describing all planes of that format. * - __u8 - ``ycbcr_enc`` - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. - This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + See struct :c:type:`v4l2_pix_format`. * - __u8 - ``hsv_enc`` - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`. - This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + See struct :c:type:`v4l2_pix_format`. * - } - * - __u8 - ``quantization`` - Quantization range, from enum :c:type:`v4l2_quantization`. - This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + See struct :c:type:`v4l2_pix_format`. * - __u8 - ``xfer_func`` - Transfer function, from enum :c:type:`v4l2_xfer_func`. - This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + See struct :c:type:`v4l2_pix_format`. * - __u8 - ``reserved[7]`` - Reserved for future extensions. Should be zeroed by drivers and diff --git a/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst b/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst index 8424d6f53b0c..71e828093310 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-v4l2.rst @@ -109,7 +109,14 @@ Single-planar format structure - Image colorspace, from enum :c:type:`v4l2_colorspace`. This information supplements the ``pixelformat`` and must be set by the driver for capture streams and by the application for - output streams, see :ref:`colorspaces`. + output streams, see :ref:`colorspaces`. If the application sets the + flag ``V4L2_PIX_FMT_FLAG_SET_CSC`` then the application can set + this field for a capture stream to request a specific colorspace + for the captured image data. If the driver cannot handle requested + conversion, it will return another supported colorspace. + The driver indicates that colorspace conversion is supported by setting + the flag V4L2_FMT_FLAG_CSC_COLORSPACE in the corresponding struct + :c:type:`v4l2_fmtdesc` during enumeration. See :ref:`fmtdesc-flags`. * - __u32 - ``priv`` - This field indicates whether the remaining fields of the @@ -146,13 +153,29 @@ Single-planar format structure - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + streams, see :ref:`colorspaces`. If the application sets the + flag ``V4L2_PIX_FMT_FLAG_SET_CSC`` then the application can set + this field for a capture stream to request a specific Y'CbCr encoding + for the captured image data. If the driver cannot handle requested + conversion, it will return another supported encoding. + This field is ignored for HSV pixelformats. The driver indicates that + ycbcr_enc conversion is supported by setting the flag + V4L2_FMT_FLAG_CSC_YCBCR_ENC in the corresponding struct + :c:type:`v4l2_fmtdesc` during enumeration. See :ref:`fmtdesc-flags`. * - __u32 - ``hsv_enc`` - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`. This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + streams, see :ref:`colorspaces`. If the application sets the flag + ``V4L2_PIX_FMT_FLAG_SET_CSC`` then the application can set this + field for a capture stream to request a specific HSV encoding for the + captured image data. If the driver cannot handle requested + conversion, it will return another supported encoding. + This field is ignored for non-HSV pixelformats. The driver indicates + that hsv_enc conversion is supported by setting the flag + V4L2_FMT_FLAG_CSC_HSV_ENC in the corresponding struct + :c:type:`v4l2_fmtdesc` during enumeration. See :ref:`fmtdesc-flags`. * - } - * - __u32 @@ -160,13 +183,27 @@ Single-planar format structure - Quantization range, from enum :c:type:`v4l2_quantization`. This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + streams, see :ref:`colorspaces`. If the application sets the flag + ``V4L2_PIX_FMT_FLAG_SET_CSC`` then the application can set + this field for a capture stream to request a specific quantization + range for the captured image data. If the driver cannot handle requested + conversion, it will return another supported quantization. + The driver indicates that quantization conversion is supported by setting + the flag V4L2_FMT_FLAG_CSC_QUANTIZATION in the corresponding struct + :c:type:`v4l2_fmtdesc` during enumeration. See :ref:`fmtdesc-flags`. * - __u32 - ``xfer_func`` - Transfer function, from enum :c:type:`v4l2_xfer_func`. This information supplements the ``colorspace`` and must be set by the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + streams, see :ref:`colorspaces`. If the application sets the flag + ``V4L2_PIX_FMT_FLAG_SET_CSC`` then the application can set + this field for a capture stream to request a specific transfer function + for the captured image data. If the driver cannot handle requested + conversion, it will return another supported transfer function. + The driver indicates that xfer_func conversion is supported by setting + the flag V4L2_FMT_FLAG_CSC_XFER_FUNC in the corresponding struct + :c:type:`v4l2_fmtdesc` during enumeration. See :ref:`fmtdesc-flags`. .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| @@ -184,3 +221,20 @@ Single-planar format structure by RGBA values (128, 192, 255, 128), the same pixel described with premultiplied colors would be described by RGBA values (64, 96, 128, 128) + * .. _`v4l2-pix-fmt-flag-set-csc`: + + - ``V4L2_PIX_FMT_FLAG_SET_CSC`` + - 0x00000002 + - Set by the application. It is only used for capture and is + ignored for output streams. If set, then request the device to do + colorspace conversion from the received colorspace to the requested + colorspace values. If the colorimetry field (``colorspace``, ``xfer_func``, + ``ycbcr_enc``, ``hsv_enc`` or ``quantization``) is set to ``*_DEFAULT``, + then that colorimetry setting will remain unchanged from what was received. + So in order to change the quantization, only the ``quantization`` field shall + be set to non default value (``V4L2_QUANTIZATION_FULL_RANGE`` or + ``V4L2_QUANTIZATION_LIM_RANGE``) and all other colorimetry fields shall + be set to ``*_DEFAULT``. + + To check which conversions are supported by the hardware for the current + pixel format, see :ref:`fmtdesc-flags`. diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst index 296b7d437431..b8347a96a554 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst @@ -191,6 +191,41 @@ the ``mbus_code`` field is handled differently: This flag can only be used in combination with the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed formats only. This flag is valid for stateful encoders only. + * - ``V4L2_FMT_FLAG_CSC_COLORSPACE`` + - 0x0020 + - The driver allows the application to try to change the default + colorspace. This flag is relevant only for capture devices. + The application can ask to configure the colorspace of the capture device + when calling the :ref:`VIDIOC_S_FMT ` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC ` set. + * - ``V4L2_FMT_FLAG_CSC_XFER_FUNC`` + - 0x0040 + - The driver allows the application to try to change the default + transfer function. This flag is relevant only for capture devices. + The application can ask to configure the transfer function of the capture + device when calling the :ref:`VIDIOC_S_FMT ` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC ` set. + * - ``V4L2_FMT_FLAG_CSC_YCBCR_ENC`` + - 0x0080 + - The driver allows the application to try to change the default + Y'CbCr encoding. This flag is relevant only for capture devices. + The application can ask to configure the Y'CbCr encoding of the capture device + when calling the :ref:`VIDIOC_S_FMT ` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC ` set. + * - ``V4L2_FMT_FLAG_CSC_HSV_ENC`` + - 0x0080 + - The driver allows the application to try to change the default + HSV encoding. This flag is relevant only for capture devices. + The application can ask to configure the HSV encoding of the capture device + when calling the :ref:`VIDIOC_S_FMT ` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC ` set. + * - ``V4L2_FMT_FLAG_CSC_QUANTIZATION`` + - 0x0100 + - The driver allows the application to try to change the default + quantization. This flag is relevant only for capture devices. + The application can ask to configure the quantization of the capture + device when calling the :ref:`VIDIOC_S_FMT ` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC ` set. Return Value diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions index 659799cc1eca..121e396a2779 100644 --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions @@ -188,6 +188,11 @@ replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags replace define V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL fmtdesc-flags +replace define V4L2_FMT_FLAG_CSC_COLORSPACE fmtdesc-flags +replace define V4L2_FMT_FLAG_CSC_XFER_FUNC fmtdesc-flags +replace define V4L2_FMT_FLAG_CSC_YCBCR_ENC fmtdesc-flags +replace define V4L2_FMT_FLAG_CSC_HSV_ENC fmtdesc-flags +replace define V4L2_FMT_FLAG_CSC_QUANTIZATION fmtdesc-flags # V4L2 timecode types replace define V4L2_TC_TYPE_24FPS timecode-type diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 4769628790da..b2bc83f37024 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -777,6 +777,7 @@ struct v4l2_pix_format { /* Flags */ #define V4L2_PIX_FMT_FLAG_PREMUL_ALPHA 0x00000001 +#define V4L2_PIX_FMT_FLAG_SET_CSC 0x00000002 /* * F O R M A T E N U M E R A T I O N @@ -796,6 +797,11 @@ struct v4l2_fmtdesc { #define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM 0x0004 #define V4L2_FMT_FLAG_DYN_RESOLUTION 0x0008 #define V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL 0x0010 +#define V4L2_FMT_FLAG_CSC_COLORSPACE 0x0020 +#define V4L2_FMT_FLAG_CSC_XFER_FUNC 0x0040 +#define V4L2_FMT_FLAG_CSC_YCBCR_ENC 0x0080 +#define V4L2_FMT_FLAG_CSC_HSV_ENC V4L2_FMT_FLAG_CSC_YCBCR_ENC +#define V4L2_FMT_FLAG_CSC_QUANTIZATION 0x0100 /* Frame Size and frame rate enumeration */ /* -- cgit v1.2.3 From 2f491463497ad43bc06968a334747c6b6b20fc74 Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 27 Aug 2020 21:46:09 +0200 Subject: media: vivid: Add support to the CSC API The CSC API (Colorspace conversion) allows userspace to try to configure the colorspace, transfer function, Y'CbCr/HSV encoding and the quantization for capture devices. This patch adds support to the CSC API in vivid. Using the CSC API, userspace is allowed to do the following: - Set the colorspace. - Set the xfer_func. - Set the ycbcr_enc function for YUV formats. - Set the hsv_enc function for HSV formats - Set the quantization for YUV and RGB formats. Signed-off-by: Dafna Hirschfeld Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 38 ++++++++++++++++++---- .../media/test-drivers/vivid/vivid-vid-common.c | 25 ++++++++++++++ include/media/v4l2-common.h | 29 +++++++++++++++++ 3 files changed, 86 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index e94beef008c8..eadf28ab1e39 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -560,6 +560,7 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, unsigned factor = 1; unsigned w, h; unsigned p; + bool user_set_csc = !!(mp->flags & V4L2_PIX_FMT_FLAG_SET_CSC); fmt = vivid_get_format(dev, mp->pixelformat); if (!fmt) { @@ -633,13 +634,30 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, (fmt->bit_depth[p] / fmt->vdownsampling[p])) / (fmt->bit_depth[0] / fmt->vdownsampling[0]); - mp->colorspace = vivid_colorspace_cap(dev); - if (fmt->color_enc == TGP_COLOR_ENC_HSV) - mp->hsv_enc = vivid_hsv_enc_cap(dev); - else + if (!user_set_csc || !v4l2_is_colorspace_valid(mp->colorspace)) + mp->colorspace = vivid_colorspace_cap(dev); + + if (!user_set_csc || !v4l2_is_xfer_func_valid(mp->xfer_func)) + mp->xfer_func = vivid_xfer_func_cap(dev); + + if (fmt->color_enc == TGP_COLOR_ENC_HSV) { + if (!user_set_csc || !v4l2_is_hsv_enc_valid(mp->hsv_enc)) + mp->hsv_enc = vivid_hsv_enc_cap(dev); + } else if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) { + if (!user_set_csc || !v4l2_is_ycbcr_enc_valid(mp->ycbcr_enc)) + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + } else { mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); - mp->xfer_func = vivid_xfer_func_cap(dev); - mp->quantization = vivid_quantization_cap(dev); + } + + if (fmt->color_enc == TGP_COLOR_ENC_YCBCR || + fmt->color_enc == TGP_COLOR_ENC_RGB) { + if (!user_set_csc || !v4l2_is_quant_valid(mp->quantization)) + mp->quantization = vivid_quantization_cap(dev); + } else { + mp->quantization = vivid_quantization_cap(dev); + } + memset(mp->reserved, 0, sizeof(mp->reserved)); return 0; } @@ -769,6 +787,14 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, if (vivid_is_sdtv_cap(dev)) dev->tv_field_cap = mp->field; tpg_update_mv_step(&dev->tpg); + dev->tpg.colorspace = mp->colorspace; + dev->tpg.xfer_func = mp->xfer_func; + if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_YCBCR) + dev->tpg.ycbcr_enc = mp->ycbcr_enc; + else + dev->tpg.hsv_enc = mp->hsv_enc; + dev->tpg.quantization = mp->quantization; + return 0; } diff --git a/drivers/media/test-drivers/vivid/vivid-vid-common.c b/drivers/media/test-drivers/vivid/vivid-vid-common.c index 76b0be670ebb..19701fe72030 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-common.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-common.c @@ -920,6 +920,31 @@ int vivid_enum_fmt_vid(struct file *file, void *priv, fmt = &vivid_formats[f->index]; f->pixelformat = fmt->fourcc; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return 0; + /* + * For capture devices, we support the CSC API. + * We allow userspace to: + * 1. set the colorspace + * 2. set the xfer_func + * 3. set the ycbcr_enc on YUV formats + * 4. set the hsv_enc on HSV formats + * 5. set the quantization on YUV and RGB formats + */ + f->flags |= V4L2_FMT_FLAG_CSC_COLORSPACE; + f->flags |= V4L2_FMT_FLAG_CSC_XFER_FUNC; + + if (fmt->color_enc == TGP_COLOR_ENC_YCBCR) { + f->flags |= V4L2_FMT_FLAG_CSC_YCBCR_ENC; + f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION; + } else if (fmt->color_enc == TGP_COLOR_ENC_HSV) { + f->flags |= V4L2_FMT_FLAG_CSC_HSV_ENC; + } else if (fmt->color_enc == TGP_COLOR_ENC_RGB) { + f->flags |= V4L2_FMT_FLAG_CSC_QUANTIZATION; + } + return 0; } diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 150ee16ebd81..a3083529b698 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -539,4 +539,33 @@ static inline void v4l2_buffer_set_timestamp(struct v4l2_buffer *buf, buf->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC; } +static inline bool v4l2_is_colorspace_valid(__u32 colorspace) +{ + return colorspace > V4L2_COLORSPACE_DEFAULT && + colorspace <= V4L2_COLORSPACE_DCI_P3; +} + +static inline bool v4l2_is_xfer_func_valid(__u32 xfer_func) +{ + return xfer_func > V4L2_XFER_FUNC_DEFAULT && + xfer_func <= V4L2_XFER_FUNC_SMPTE2084; +} + +static inline bool v4l2_is_ycbcr_enc_valid(__u8 ycbcr_enc) +{ + return ycbcr_enc > V4L2_YCBCR_ENC_DEFAULT && + ycbcr_enc <= V4L2_YCBCR_ENC_SMPTE240M; +} + +static inline bool v4l2_is_hsv_enc_valid(__u8 hsv_enc) +{ + return hsv_enc == V4L2_HSV_ENC_180 || hsv_enc == V4L2_HSV_ENC_256; +} + +static inline bool v4l2_is_quant_valid(__u8 quantization) +{ + return quantization == V4L2_QUANTIZATION_FULL_RANGE || + quantization == V4L2_QUANTIZATION_LIM_RANGE; +} + #endif /* V4L2_COMMON_H_ */ -- cgit v1.2.3 From 62aacfa9bf93f94f6949338e0c7a2ed4c4bd2c2a Mon Sep 17 00:00:00 2001 From: Dafna Hirschfeld Date: Thu, 27 Aug 2020 21:46:10 +0200 Subject: media: v4l2: extend the CSC API to subdevice. This patch extends the CSC API in video devices to be supported also on sub-devices. The flag V4L2_MBUS_FRAMEFMT_SET_CSC set by the application when calling VIDIOC_SUBDEV_S_FMT ioctl. The flags: V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE, V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC, V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC/V4L2_SUBDEV_MBUS_CODE_CSC_HSV_ENC V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION are set by the driver in the VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl. New 'flags' fields were added to the structs v4l2_subdev_mbus_code_enum, v4l2_mbus_framefmt which are borrowed from the 'reserved' field The patch also replaces the 'ycbcr_enc' field in 'struct v4l2_mbus_framefmt' with a union that includes 'hsv_enc' Signed-off-by: Dafna Hirschfeld Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- .../userspace-api/media/v4l/subdev-formats.rst | 95 +++++++++++++++++++--- .../media/v4l/vidioc-subdev-enum-mbus-code.rst | 51 +++++++++++- include/uapi/linux/v4l2-mediabus.h | 15 +++- include/uapi/linux/v4l2-subdev.h | 10 ++- 4 files changed, 157 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst index dd2f037b74dd..c9b7bb3ca089 100644 --- a/Documentation/userspace-api/media/v4l/subdev-formats.rst +++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst @@ -34,32 +34,107 @@ Media Bus Formats :ref:`field-order` for details. * - __u32 - ``colorspace`` - - Image colorspace, from enum - :c:type:`v4l2_colorspace`. See - :ref:`colorspaces` for details. + - Image colorspace, from enum :c:type:`v4l2_colorspace`. + Must be set by the driver for subdevices. If the application sets the + flag ``V4L2_MBUS_FRAMEFMT_SET_CSC`` then the application can set this + field on the source pad to request a specific colorspace for the media + bus data. If the driver cannot handle the requested conversion, it will + return another supported colorspace. The driver indicates that colorspace + conversion is supported by setting the flag + V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE in the corresponding struct + :c:type:`v4l2_subdev_mbus_code_enum` during enumeration. + See :ref:`v4l2-subdev-mbus-code-flags`. + * - union { + - (anonymous) * - __u16 - ``ycbcr_enc`` - Y'CbCr encoding, from enum :c:type:`v4l2_ycbcr_encoding`. This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + the driver for subdevices, see :ref:`colorspaces`. If the application + sets the flag ``V4L2_MBUS_FRAMEFMT_SET_CSC`` then the application can set + this field on a source pad to request a specific Y'CbCr encoding + for the media bus data. If the driver cannot handle the requested + conversion, it will return another supported encoding. + This field is ignored for HSV media bus formats. The driver indicates + that ycbcr_enc conversion is supported by setting the flag + V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC in the corresponding struct + :c:type:`v4l2_subdev_mbus_code_enum` during enumeration. + See :ref:`v4l2-subdev-mbus-code-flags`. + * - __u16 + - ``hsv_enc`` + - HSV encoding, from enum :c:type:`v4l2_hsv_encoding`. + This information supplements the ``colorspace`` and must be set by + the driver for subdevices, see :ref:`colorspaces`. If the application + sets the flag ``V4L2_MBUS_FRAMEFMT_SET_CSC`` then the application can set + this field on a source pad to request a specific HSV encoding + for the media bus data. If the driver cannot handle the requested + conversion, it will return another supported encoding. + This field is ignored for Y'CbCr media bus formats. The driver indicates + that hsv_enc conversion is supported by setting the flag + V4L2_SUBDEV_MBUS_CODE_CSC_HSV_ENC in the corresponding struct + :c:type:`v4l2_subdev_mbus_code_enum` during enumeration. + See :ref:`v4l2-subdev-mbus-code-flags` + * - } + - * - __u16 - ``quantization`` - Quantization range, from enum :c:type:`v4l2_quantization`. This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + the driver for subdevices, see :ref:`colorspaces`. If the application + sets the flag ``V4L2_MBUS_FRAMEFMT_SET_CSC`` then the application can set + this field on a source pad to request a specific quantization + for the media bus data. If the driver cannot handle the requested + conversion, it will return another supported quantization. + The driver indicates that quantization conversion is supported by + setting the flag V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION in the + corresponding struct :c:type:`v4l2_subdev_mbus_code_enum` + during enumeration. See :ref:`v4l2-subdev-mbus-code-flags`. + * - __u16 - ``xfer_func`` - Transfer function, from enum :c:type:`v4l2_xfer_func`. This information supplements the ``colorspace`` and must be set by - the driver for capture streams and by the application for output - streams, see :ref:`colorspaces`. + the driver for subdevices, see :ref:`colorspaces`. If the application + sets the flag ``V4L2_MBUS_FRAMEFMT_SET_CSC`` then the application can set + this field on a source pad to request a specific transfer + function for the media bus data. If the driver cannot handle the requested + conversion, it will return another supported transfer function. + The driver indicates that the transfer function conversion is supported by + setting the flag V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC in the + corresponding struct :c:type:`v4l2_subdev_mbus_code_enum` + during enumeration. See :ref:`v4l2-subdev-mbus-code-flags`. * - __u16 - - ``reserved``\ [11] + - ``flags`` + - flags See: :ref:v4l2-mbus-framefmt-flags + * - __u16 + - ``reserved``\ [10] - Reserved for future extensions. Applications and drivers must set the array to zero. +.. _v4l2-mbus-framefmt-flags: + +.. flat-table:: v4l2_mbus_framefmt Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`mbus-framefmt-set-csc`: + + - ``V4L2_MBUS_FRAMEFMT_SET_CSC`` + - 0x0001 + - Set by the application. It is only used for source pads and is + ignored for sink pads. If set, then request the subdevice to do + colorspace conversion from the received colorspace to the requested + colorspace values. If the colorimetry field (``colorspace``, ``xfer_func``, + ``ycbcr_enc``, ``hsv_enc`` or ``quantization``) is set to ``*_DEFAULT``, + then that colorimetry setting will remain unchanged from what was received. + So in order to change the quantization, only the ``quantization`` field shall + be set to non default value (``V4L2_QUANTIZATION_FULL_RANGE`` or + ``V4L2_QUANTIZATION_LIM_RANGE``) and all other colorimetry fields shall + be set to ``*_DEFAULT``. + + To check which conversions are supported by the hardware for the current + media bus frame format, see :ref:`v4l2-subdev-mbus-code-flags`. .. _v4l2-mbus-pixelcode: diff --git a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst index 9db76f7d240f..3b6a8044c391 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-subdev-enum-mbus-code.rst @@ -72,11 +72,60 @@ information about the try formats. - Media bus format codes to be enumerated, from enum :ref:`v4l2_subdev_format_whence `. * - __u32 - - ``reserved``\ [8] + - ``flags`` + - See :ref:`v4l2-subdev-mbus-code-flags` + * - __u32 + - ``reserved``\ [7] - Reserved for future extensions. Applications and drivers must set the array to zero. + +.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{7.7cm}| + +.. _v4l2-subdev-mbus-code-flags: + +.. flat-table:: Subdev Media Bus Code Enumerate Flags + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE + - 0x00000001 + - The driver allows the application to try to change the default colorspace + encoding. The application can ask to configure the colorspace of the + subdevice when calling the :ref:`VIDIOC_SUBDEV_S_FMT ` + ioctl with :ref:`V4L2_MBUS_FRAMEFMT_SET_CSC ` set. + See :ref:`v4l2-mbus-format` on how to do this. + * - V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC + - 0x00000002 + - The driver allows the application to try to change the default transform function. + The application can ask to configure the transform function of + the subdevice when calling the :ref:`VIDIOC_SUBDEV_S_FMT ` + ioctl with :ref:`V4L2_MBUS_FRAMEFMT_SET_CSC ` set. + See :ref:`v4l2-mbus-format` on how to do this. + * - V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC + - 0x00000004 + - The driver allows the application to try to change the default Y'CbCr + encoding. The application can ask to configure the Y'CbCr encoding of the + subdevice when calling the :ref:`VIDIOC_SUBDEV_S_FMT ` + ioctl with :ref:`V4L2_MBUS_FRAMEFMT_SET_CSC ` set. + See :ref:`v4l2-mbus-format` on how to do this. + * - V4L2_SUBDEV_MBUS_CODE_CSC_HSV_ENC + - 0x00000004 + - The driver allows the application to try to change the default HSV + encoding. The application can ask to configure the HSV encoding of the + subdevice when calling the :ref:`VIDIOC_SUBDEV_S_FMT ` + ioctl with :ref:`V4L2_MBUS_FRAMEFMT_SET_CSC ` set. + See :ref:`v4l2-mbus-format` on how to do this. + * - V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION + - 0x00000008 + - The driver allows the application to try to change the default + quantization. The application can ask to configure the quantization of + the subdevice when calling the :ref:`VIDIOC_SUBDEV_S_FMT ` + ioctl with :ref:`V4L2_MBUS_FRAMEFMT_SET_CSC ` set. + See :ref:`v4l2-mbus-format` on how to do this. + Return Value ============ diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h index 123a231001a8..903e67b16711 100644 --- a/include/uapi/linux/v4l2-mediabus.h +++ b/include/uapi/linux/v4l2-mediabus.h @@ -16,6 +16,8 @@ #include #include +#define V4L2_MBUS_FRAMEFMT_SET_CSC 0x0001 + /** * struct v4l2_mbus_framefmt - frame format on the media bus * @width: image width @@ -24,8 +26,11 @@ * @field: used interlacing type (from enum v4l2_field) * @colorspace: colorspace of the data (from enum v4l2_colorspace) * @ycbcr_enc: YCbCr encoding of the data (from enum v4l2_ycbcr_encoding) + * @hsv_enc: HSV encoding of the data (from enum v4l2_hsv_encoding) * @quantization: quantization of the data (from enum v4l2_quantization) * @xfer_func: transfer function of the data (from enum v4l2_xfer_func) + * @flags: flags (V4L2_MBUS_FRAMEFMT_*) + * @reserved: reserved bytes that can be later used */ struct v4l2_mbus_framefmt { __u32 width; @@ -33,10 +38,16 @@ struct v4l2_mbus_framefmt { __u32 code; __u32 field; __u32 colorspace; - __u16 ycbcr_enc; + union { + /* enum v4l2_ycbcr_encoding */ + __u16 ycbcr_enc; + /* enum v4l2_hsv_encoding */ + __u16 hsv_enc; + }; __u16 quantization; __u16 xfer_func; - __u16 reserved[11]; + __u16 flags; + __u16 reserved[10]; }; #ifndef __KERNEL__ diff --git a/include/uapi/linux/v4l2-subdev.h b/include/uapi/linux/v4l2-subdev.h index 5d2a1dab7911..00850b98078a 100644 --- a/include/uapi/linux/v4l2-subdev.h +++ b/include/uapi/linux/v4l2-subdev.h @@ -65,19 +65,27 @@ struct v4l2_subdev_crop { __u32 reserved[8]; }; +#define V4L2_SUBDEV_MBUS_CODE_CSC_COLORSPACE 0x00000001 +#define V4L2_SUBDEV_MBUS_CODE_CSC_XFER_FUNC 0x00000002 +#define V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC 0x00000004 +#define V4L2_SUBDEV_MBUS_CODE_CSC_HSV_ENC V4L2_SUBDEV_MBUS_CODE_CSC_YCBCR_ENC +#define V4L2_SUBDEV_MBUS_CODE_CSC_QUANTIZATION 0x00000008 + /** * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration * @pad: pad number, as reported by the media API * @index: format index during enumeration * @code: format code (MEDIA_BUS_FMT_ definitions) * @which: format type (from enum v4l2_subdev_format_whence) + * @flags: flags set by the driver, (V4L2_SUBDEV_MBUS_CODE_*) */ struct v4l2_subdev_mbus_code_enum { __u32 pad; __u32 index; __u32 code; __u32 which; - __u32 reserved[8]; + __u32 flags; + __u32 reserved[7]; }; /** -- cgit v1.2.3 From 8162a0b5a209b541e89336f53b96ea0c22b63945 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Sep 2020 11:15:36 +0200 Subject: media: v4l2-subdev.h: fix a kernel-doc markup As reported by Sphinx: ./Documentation/driver-api/media/v4l2-subdev:490: ./include/media/v4l2-subdev.h:384: WARNING: Unparseable C cross-reference: 'struct' Invalid C declaration: Expected identifier in nested name, got keyword: struct [error at 6] struct ------^ The markup there is wrong: &struct &v4l2_input -> &struct v4l2_input Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 6f6795bab737..1de960bfcab9 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -381,7 +381,7 @@ struct v4l2_mbus_frame_desc { * OUTPUT device. This is ignored by video capture devices. * * @g_input_status: get input status. Same as the status field in the - * &struct &v4l2_input + * &struct v4l2_input * * @s_stream: used to notify the driver that a video stream will start or has * stopped. -- cgit v1.2.3