mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
15131 lines
638 KiB
Diff
15131 lines
638 KiB
Diff
From 5344f534e55eed401d2b6f7cd4f85c1b535327f6 Mon Sep 17 00:00:00 2001
|
|
From: zhengbin <zhengbin13@huawei.com>
|
|
Date: Sun, 18 Aug 2019 22:51:30 -0300
|
|
Subject: [PATCH] media: mc-device.c: fix memleak in
|
|
media_device_register_entity
|
|
|
|
In media_device_register_entity, if media_graph_walk_init fails,
|
|
need to free the previously memory.
|
|
|
|
Reported-by: Hulk Robot <hulkci@huawei.com>
|
|
Signed-off-by: zhengbin <zhengbin13@huawei.com>
|
|
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 713f871b30a66dc4daff4d17b760c9916aaaf2e1)
|
|
---
|
|
drivers/media/mc/mc-device.c | 65 ++++++++++++++++++++++----------------------
|
|
1 file changed, 33 insertions(+), 32 deletions(-)
|
|
|
|
diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c
|
|
index e19df5165e78..da8088351135 100644
|
|
--- a/drivers/media/mc/mc-device.c
|
|
+++ b/drivers/media/mc/mc-device.c
|
|
@@ -575,6 +575,38 @@ static void media_device_release(struct media_devnode *devnode)
|
|
dev_dbg(devnode->parent, "Media device released\n");
|
|
}
|
|
|
|
+static void __media_device_unregister_entity(struct media_entity *entity)
|
|
+{
|
|
+ struct media_device *mdev = entity->graph_obj.mdev;
|
|
+ struct media_link *link, *tmp;
|
|
+ struct media_interface *intf;
|
|
+ unsigned int i;
|
|
+
|
|
+ ida_free(&mdev->entity_internal_idx, entity->internal_idx);
|
|
+
|
|
+ /* Remove all interface links pointing to this entity */
|
|
+ list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
|
|
+ list_for_each_entry_safe(link, tmp, &intf->links, list) {
|
|
+ if (link->entity == entity)
|
|
+ __media_remove_intf_link(link);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Remove all data links that belong to this entity */
|
|
+ __media_entity_remove_links(entity);
|
|
+
|
|
+ /* Remove all pads that belong to this entity */
|
|
+ for (i = 0; i < entity->num_pads; i++)
|
|
+ media_gobj_destroy(&entity->pads[i].graph_obj);
|
|
+
|
|
+ /* Remove the entity */
|
|
+ media_gobj_destroy(&entity->graph_obj);
|
|
+
|
|
+ /* invoke entity_notify callbacks to handle entity removal?? */
|
|
+
|
|
+ entity->graph_obj.mdev = NULL;
|
|
+}
|
|
+
|
|
/**
|
|
* media_device_register_entity - Register an entity with a media device
|
|
* @mdev: The media device
|
|
@@ -632,6 +664,7 @@ int __must_check media_device_register_entity(struct media_device *mdev,
|
|
*/
|
|
ret = media_graph_walk_init(&new, mdev);
|
|
if (ret) {
|
|
+ __media_device_unregister_entity(entity);
|
|
mutex_unlock(&mdev->graph_mutex);
|
|
return ret;
|
|
}
|
|
@@ -644,38 +677,6 @@ int __must_check media_device_register_entity(struct media_device *mdev,
|
|
}
|
|
EXPORT_SYMBOL_GPL(media_device_register_entity);
|
|
|
|
-static void __media_device_unregister_entity(struct media_entity *entity)
|
|
-{
|
|
- struct media_device *mdev = entity->graph_obj.mdev;
|
|
- struct media_link *link, *tmp;
|
|
- struct media_interface *intf;
|
|
- unsigned int i;
|
|
-
|
|
- ida_free(&mdev->entity_internal_idx, entity->internal_idx);
|
|
-
|
|
- /* Remove all interface links pointing to this entity */
|
|
- list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
|
|
- list_for_each_entry_safe(link, tmp, &intf->links, list) {
|
|
- if (link->entity == entity)
|
|
- __media_remove_intf_link(link);
|
|
- }
|
|
- }
|
|
-
|
|
- /* Remove all data links that belong to this entity */
|
|
- __media_entity_remove_links(entity);
|
|
-
|
|
- /* Remove all pads that belong to this entity */
|
|
- for (i = 0; i < entity->num_pads; i++)
|
|
- media_gobj_destroy(&entity->pads[i].graph_obj);
|
|
-
|
|
- /* Remove the entity */
|
|
- media_gobj_destroy(&entity->graph_obj);
|
|
-
|
|
- /* invoke entity_notify callbacks to handle entity removal?? */
|
|
-
|
|
- entity->graph_obj.mdev = NULL;
|
|
-}
|
|
-
|
|
void media_device_unregister_entity(struct media_entity *entity)
|
|
{
|
|
struct media_device *mdev = entity->graph_obj.mdev;
|
|
|
|
From 7d7c0708130924ce7ed139d0adf825b37367a1d4 Mon Sep 17 00:00:00 2001
|
|
From: Shuah Khan <skhan@linuxfoundation.org>
|
|
Date: Tue, 17 Sep 2019 13:35:08 -0300
|
|
Subject: [PATCH] media: vimc: Collapse component structure into a single
|
|
monolithic driver
|
|
|
|
vimc uses Component API to split the driver into functional components.
|
|
The real hardware resembles a monolith structure than component and
|
|
component structure added a level of complexity making it hard to
|
|
maintain without adding any real benefit.
|
|
|
|
The sensor is one vimc component that would makes sense to be a separate
|
|
module to closely align with the real hardware. It would be easier to
|
|
collapse vimc into single monolithic driver first and then split the
|
|
sensor off as a separate module.
|
|
|
|
Collapse it into a single monolithic driver removing the Component API.
|
|
This patch removes the component API and makes minimal changes to the
|
|
code base preserving the functional division of the code structure.
|
|
Preserving the functional structure allows us to split the sensor off
|
|
as a separate module in the future.
|
|
|
|
Major design elements in this change are:
|
|
- Use existing struct vimc_ent_config and struct vimc_pipeline_config
|
|
to drive the initialization of the functional components.
|
|
- Make vimc_device and vimc_ent_config global by moving them to
|
|
vimc-common.h
|
|
- Add two new hooks add and rm to initialize and register, unregister
|
|
and free subdevs.
|
|
- All component API is now gone and bind and unbind hooks are modified
|
|
to do "add" and "rm" with minimal changes to just add and rm subdevs.
|
|
- vimc-core's bind and unbind are now register and unregister.
|
|
- Add a new field to vimc_device structure for saving the pointers to
|
|
struct vimc_ent_device(s) subdevs create in their "add" hooks. These
|
|
get used to create links and removing the subdevs. vimc-core allocates
|
|
this array which sized to number of entries in the topology defined in
|
|
the vimc_pipeline_config structure.
|
|
- vimc-core invokes "add" hooks from its vimc_register_devices().
|
|
The "add" hooks remain the same and register subdevs. They don't
|
|
create platform devices of their own and use vimc's pdev.dev as
|
|
their reference device. Each "add" hook returns pointer to its struct
|
|
vimc_ent_device. This is saved in the vimc_device ent_devs array.
|
|
- vimc-core invokes "rm" hooks from its unregister to unregister subdevs
|
|
and cleanup.
|
|
- vimc-core invokes "add" and "rm" hooks with pointer to struct vimc_device
|
|
and the corresponding vimc_ent_device saved in the ent_devs.
|
|
|
|
The following configure and stream test works on all devices.
|
|
|
|
media-ctl -d platform:vimc -V '"Sensor A":0[fmt:SBGGR8_1X8/640x480]'
|
|
media-ctl -d platform:vimc -V '"Debayer A":0[fmt:SBGGR8_1X8/640x480]'
|
|
media-ctl -d platform:vimc -V '"Sensor B":0[fmt:SBGGR8_1X8/640x480]'
|
|
media-ctl -d platform:vimc -V '"Debayer B":0[fmt:SBGGR8_1X8/640x480]'
|
|
|
|
v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
|
|
v4l2-ctl -z platform:vimc -d "Raw Capture 0" -v pixelformat=BA81
|
|
v4l2-ctl -z platform:vimc -d "Raw Capture 1" -v pixelformat=BA81
|
|
|
|
v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video1
|
|
v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video2
|
|
v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video3
|
|
|
|
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit f13d5f3619599d257b4bcb941245085f5d118af8)
|
|
---
|
|
drivers/media/platform/vimc/Makefile | 7 +-
|
|
drivers/media/platform/vimc/vimc-capture.c | 81 ++---------
|
|
drivers/media/platform/vimc/vimc-common.h | 54 +++++++
|
|
drivers/media/platform/vimc/vimc-core.c | 216 +++++++++++-----------------
|
|
drivers/media/platform/vimc/vimc-debayer.c | 73 ++--------
|
|
drivers/media/platform/vimc/vimc-scaler.c | 75 ++--------
|
|
drivers/media/platform/vimc/vimc-sensor.c | 73 ++--------
|
|
drivers/media/platform/vimc/vimc-streamer.c | 1 -
|
|
8 files changed, 195 insertions(+), 385 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile
|
|
index 96d06f030c31..a53b2b532e9f 100644
|
|
--- a/drivers/media/platform/vimc/Makefile
|
|
+++ b/drivers/media/platform/vimc/Makefile
|
|
@@ -1,5 +1,6 @@
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
-vimc-y := vimc-core.o vimc-common.o vimc-streamer.o
|
|
+vimc-y := vimc-core.o vimc-common.o vimc-streamer.o vimc-capture.o \
|
|
+ vimc-debayer.o vimc-scaler.o vimc-sensor.o
|
|
+
|
|
+obj-$(CONFIG_VIDEO_VIMC) += vimc.o
|
|
|
|
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc-capture.o vimc-debayer.o \
|
|
- vimc-scaler.o vimc-sensor.o
|
|
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
|
|
index 1d56b91830ba..602f80323031 100644
|
|
--- a/drivers/media/platform/vimc/vimc-capture.c
|
|
+++ b/drivers/media/platform/vimc/vimc-capture.c
|
|
@@ -5,10 +5,6 @@
|
|
* Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
|
|
*/
|
|
|
|
-#include <linux/component.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/mod_devicetable.h>
|
|
-#include <linux/platform_device.h>
|
|
#include <media/v4l2-ioctl.h>
|
|
#include <media/videobuf2-core.h>
|
|
#include <media/videobuf2-vmalloc.h>
|
|
@@ -16,8 +12,6 @@
|
|
#include "vimc-common.h"
|
|
#include "vimc-streamer.h"
|
|
|
|
-#define VIMC_CAP_DRV_NAME "vimc-capture"
|
|
-
|
|
struct vimc_cap_device {
|
|
struct vimc_ent_device ved;
|
|
struct video_device vdev;
|
|
@@ -340,13 +334,11 @@ static void vimc_cap_release(struct video_device *vdev)
|
|
kfree(vcap);
|
|
}
|
|
|
|
-static void vimc_cap_comp_unbind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
{
|
|
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
|
|
- struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
|
|
- ved);
|
|
+ struct vimc_cap_device *vcap;
|
|
|
|
+ vcap = container_of(ved, struct vimc_cap_device, ved);
|
|
vb2_queue_release(&vcap->queue);
|
|
media_entity_cleanup(ved->ent);
|
|
video_unregister_device(&vcap->vdev);
|
|
@@ -391,11 +383,10 @@ static void *vimc_cap_process_frame(struct vimc_ent_device *ved,
|
|
return NULL;
|
|
}
|
|
|
|
-static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name)
|
|
{
|
|
- struct v4l2_device *v4l2_dev = master_data;
|
|
- struct vimc_platform_data *pdata = comp->platform_data;
|
|
+ struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
|
|
const struct vimc_pix_map *vpix;
|
|
struct vimc_cap_device *vcap;
|
|
struct video_device *vdev;
|
|
@@ -405,7 +396,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
/* Allocate the vimc_cap_device struct */
|
|
vcap = kzalloc(sizeof(*vcap), GFP_KERNEL);
|
|
if (!vcap)
|
|
- return -ENOMEM;
|
|
+ return NULL;
|
|
|
|
/* Allocate the pads */
|
|
vcap->ved.pads =
|
|
@@ -416,7 +407,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
}
|
|
|
|
/* Initialize the media entity */
|
|
- vcap->vdev.entity.name = pdata->entity_name;
|
|
+ vcap->vdev.entity.name = vcfg_name;
|
|
vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
|
|
ret = media_entity_pads_init(&vcap->vdev.entity,
|
|
1, vcap->ved.pads);
|
|
@@ -440,8 +431,8 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
|
|
ret = vb2_queue_init(q);
|
|
if (ret) {
|
|
- dev_err(comp, "%s: vb2 queue init failed (err=%d)\n",
|
|
- pdata->entity_name, ret);
|
|
+ dev_err(&vimc->pdev.dev, "%s: vb2 queue init failed (err=%d)\n",
|
|
+ vcfg_name, ret);
|
|
goto err_clean_m_ent;
|
|
}
|
|
|
|
@@ -460,8 +451,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
vcap->ved.ent = &vcap->vdev.entity;
|
|
vcap->ved.process_frame = vimc_cap_process_frame;
|
|
vcap->ved.vdev_get_format = vimc_cap_get_format;
|
|
- dev_set_drvdata(comp, &vcap->ved);
|
|
- vcap->dev = comp;
|
|
+ vcap->dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the video_device struct */
|
|
vdev = &vcap->vdev;
|
|
@@ -474,18 +464,18 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
vdev->queue = q;
|
|
vdev->v4l2_dev = v4l2_dev;
|
|
vdev->vfl_dir = VFL_DIR_RX;
|
|
- strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name));
|
|
+ strscpy(vdev->name, vcfg_name, sizeof(vdev->name));
|
|
video_set_drvdata(vdev, &vcap->ved);
|
|
|
|
/* Register the video_device with the v4l2 and the media framework */
|
|
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
|
|
if (ret) {
|
|
- dev_err(comp, "%s: video register failed (err=%d)\n",
|
|
+ dev_err(&vimc->pdev.dev, "%s: video register failed (err=%d)\n",
|
|
vcap->vdev.name, ret);
|
|
goto err_release_queue;
|
|
}
|
|
|
|
- return 0;
|
|
+ return &vcap->ved;
|
|
|
|
err_release_queue:
|
|
vb2_queue_release(q);
|
|
@@ -496,46 +486,5 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master,
|
|
err_free_vcap:
|
|
kfree(vcap);
|
|
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static const struct component_ops vimc_cap_comp_ops = {
|
|
- .bind = vimc_cap_comp_bind,
|
|
- .unbind = vimc_cap_comp_unbind,
|
|
-};
|
|
-
|
|
-static int vimc_cap_probe(struct platform_device *pdev)
|
|
-{
|
|
- return component_add(&pdev->dev, &vimc_cap_comp_ops);
|
|
-}
|
|
-
|
|
-static int vimc_cap_remove(struct platform_device *pdev)
|
|
-{
|
|
- component_del(&pdev->dev, &vimc_cap_comp_ops);
|
|
-
|
|
- return 0;
|
|
+ return NULL;
|
|
}
|
|
-
|
|
-static const struct platform_device_id vimc_cap_driver_ids[] = {
|
|
- {
|
|
- .name = VIMC_CAP_DRV_NAME,
|
|
- },
|
|
- { }
|
|
-};
|
|
-
|
|
-static struct platform_driver vimc_cap_pdrv = {
|
|
- .probe = vimc_cap_probe,
|
|
- .remove = vimc_cap_remove,
|
|
- .id_table = vimc_cap_driver_ids,
|
|
- .driver = {
|
|
- .name = VIMC_CAP_DRV_NAME,
|
|
- },
|
|
-};
|
|
-
|
|
-module_platform_driver(vimc_cap_pdrv);
|
|
-
|
|
-MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids);
|
|
-
|
|
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Capture");
|
|
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
|
|
-MODULE_LICENSE("GPL");
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index 9c2e0e216c6b..d7aaf31175bc 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -8,6 +8,7 @@
|
|
#ifndef _VIMC_COMMON_H_
|
|
#define _VIMC_COMMON_H_
|
|
|
|
+#include <linux/platform_device.h>
|
|
#include <linux/slab.h>
|
|
#include <media/media-device.h>
|
|
#include <media/v4l2-device.h>
|
|
@@ -111,6 +112,59 @@ struct vimc_ent_device {
|
|
struct v4l2_pix_format *fmt);
|
|
};
|
|
|
|
+/**
|
|
+ * struct vimc_device - main device for vimc driver
|
|
+ *
|
|
+ * @pdev pointer to the platform device
|
|
+ * @pipe_cfg pointer to the vimc pipeline configuration structure
|
|
+ * @ent_devs array of vimc_ent_device pointers
|
|
+ * @mdev the associated media_device parent
|
|
+ * @v4l2_dev Internal v4l2 parent device
|
|
+ */
|
|
+struct vimc_device {
|
|
+ struct platform_device pdev;
|
|
+ const struct vimc_pipeline_config *pipe_cfg;
|
|
+ struct vimc_ent_device **ent_devs;
|
|
+ struct media_device mdev;
|
|
+ struct v4l2_device v4l2_dev;
|
|
+};
|
|
+
|
|
+/**
|
|
+ * struct vimc_ent_config Structure which describes individual
|
|
+ * configuration for each entity
|
|
+ *
|
|
+ * @name entity name
|
|
+ * @ved pointer to vimc_ent_device (a node in the
|
|
+ * topology)
|
|
+ * @add subdev add hook - initializes and registers
|
|
+ * subdev called from vimc-core
|
|
+ * @rm subdev rm hook - unregisters and frees
|
|
+ * subdev called from vimc-core
|
|
+ */
|
|
+struct vimc_ent_config {
|
|
+ const char *name;
|
|
+ struct vimc_ent_device *(*add)(struct vimc_device *vimc,
|
|
+ const char *vcfg_name);
|
|
+ void (*rm)(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
+};
|
|
+
|
|
+/* prototypes for vimc_ent_config add and rm hooks */
|
|
+struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name);
|
|
+void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
+
|
|
+struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name);
|
|
+void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
+
|
|
+struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name);
|
|
+void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
+
|
|
+struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name);
|
|
+void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
+
|
|
/**
|
|
* vimc_pads_init - initialize pads
|
|
*
|
|
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
|
|
index 571c55aa0e16..6e3e5c91ae39 100644
|
|
--- a/drivers/media/platform/vimc/vimc-core.c
|
|
+++ b/drivers/media/platform/vimc/vimc-core.c
|
|
@@ -5,7 +5,6 @@
|
|
* Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
|
|
*/
|
|
|
|
-#include <linux/component.h>
|
|
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
#include <linux/platform_device.h>
|
|
@@ -24,29 +23,6 @@
|
|
.flags = link_flags, \
|
|
}
|
|
|
|
-struct vimc_device {
|
|
- /* The platform device */
|
|
- struct platform_device pdev;
|
|
-
|
|
- /* The pipeline configuration */
|
|
- const struct vimc_pipeline_config *pipe_cfg;
|
|
-
|
|
- /* The Associated media_device parent */
|
|
- struct media_device mdev;
|
|
-
|
|
- /* Internal v4l2 parent device*/
|
|
- struct v4l2_device v4l2_dev;
|
|
-
|
|
- /* Subdevices */
|
|
- struct platform_device **subdevs;
|
|
-};
|
|
-
|
|
-/* Structure which describes individual configuration for each entity */
|
|
-struct vimc_ent_config {
|
|
- const char *name;
|
|
- const char *drv;
|
|
-};
|
|
-
|
|
/* Structure which describes links between entities */
|
|
struct vimc_ent_link {
|
|
unsigned int src_ent;
|
|
@@ -68,43 +44,52 @@ struct vimc_pipeline_config {
|
|
* Topology Configuration
|
|
*/
|
|
|
|
-static const struct vimc_ent_config ent_config[] = {
|
|
+static struct vimc_ent_config ent_config[] = {
|
|
{
|
|
.name = "Sensor A",
|
|
- .drv = "vimc-sensor",
|
|
+ .add = vimc_sen_add,
|
|
+ .rm = vimc_sen_rm,
|
|
},
|
|
{
|
|
.name = "Sensor B",
|
|
- .drv = "vimc-sensor",
|
|
+ .add = vimc_sen_add,
|
|
+ .rm = vimc_sen_rm,
|
|
},
|
|
{
|
|
.name = "Debayer A",
|
|
- .drv = "vimc-debayer",
|
|
+ .add = vimc_deb_add,
|
|
+ .rm = vimc_deb_rm,
|
|
},
|
|
{
|
|
.name = "Debayer B",
|
|
- .drv = "vimc-debayer",
|
|
+ .add = vimc_deb_add,
|
|
+ .rm = vimc_deb_rm,
|
|
},
|
|
{
|
|
.name = "Raw Capture 0",
|
|
- .drv = "vimc-capture",
|
|
+ .add = vimc_cap_add,
|
|
+ .rm = vimc_cap_rm,
|
|
},
|
|
{
|
|
.name = "Raw Capture 1",
|
|
- .drv = "vimc-capture",
|
|
+ .add = vimc_cap_add,
|
|
+ .rm = vimc_cap_rm,
|
|
},
|
|
{
|
|
- .name = "RGB/YUV Input",
|
|
/* TODO: change this to vimc-input when it is implemented */
|
|
- .drv = "vimc-sensor",
|
|
+ .name = "RGB/YUV Input",
|
|
+ .add = vimc_sen_add,
|
|
+ .rm = vimc_sen_rm,
|
|
},
|
|
{
|
|
.name = "Scaler",
|
|
- .drv = "vimc-scaler",
|
|
+ .add = vimc_sca_add,
|
|
+ .rm = vimc_sca_rm,
|
|
},
|
|
{
|
|
.name = "RGB/YUV Capture",
|
|
- .drv = "vimc-capture",
|
|
+ .add = vimc_cap_add,
|
|
+ .rm = vimc_cap_rm,
|
|
},
|
|
};
|
|
|
|
@@ -127,7 +112,7 @@ static const struct vimc_ent_link ent_links[] = {
|
|
VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
|
|
};
|
|
|
|
-static const struct vimc_pipeline_config pipe_cfg = {
|
|
+static struct vimc_pipeline_config pipe_cfg = {
|
|
.ents = ent_config,
|
|
.num_ents = ARRAY_SIZE(ent_config),
|
|
.links = ent_links,
|
|
@@ -136,6 +121,14 @@ static const struct vimc_pipeline_config pipe_cfg = {
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
+static void vimc_rm_links(struct vimc_device *vimc)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
|
|
+ media_entity_remove_links(vimc->ent_devs[i]->ent);
|
|
+}
|
|
+
|
|
static int vimc_create_links(struct vimc_device *vimc)
|
|
{
|
|
unsigned int i;
|
|
@@ -144,32 +137,58 @@ static int vimc_create_links(struct vimc_device *vimc)
|
|
/* Initialize the links between entities */
|
|
for (i = 0; i < vimc->pipe_cfg->num_links; i++) {
|
|
const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i];
|
|
- /*
|
|
- * TODO: Check another way of retrieving ved struct without
|
|
- * relying on platform_get_drvdata
|
|
- */
|
|
+
|
|
struct vimc_ent_device *ved_src =
|
|
- platform_get_drvdata(vimc->subdevs[link->src_ent]);
|
|
+ vimc->ent_devs[link->src_ent];
|
|
struct vimc_ent_device *ved_sink =
|
|
- platform_get_drvdata(vimc->subdevs[link->sink_ent]);
|
|
+ vimc->ent_devs[link->sink_ent];
|
|
|
|
ret = media_create_pad_link(ved_src->ent, link->src_pad,
|
|
ved_sink->ent, link->sink_pad,
|
|
link->flags);
|
|
if (ret)
|
|
- return ret;
|
|
+ goto err_rm_links;
|
|
}
|
|
|
|
return 0;
|
|
+
|
|
+err_rm_links:
|
|
+ vimc_rm_links(vimc);
|
|
+ return ret;
|
|
}
|
|
|
|
-static int vimc_comp_bind(struct device *master)
|
|
+static int vimc_add_subdevs(struct vimc_device *vimc)
|
|
{
|
|
- struct vimc_device *vimc = container_of(to_platform_device(master),
|
|
- struct vimc_device, pdev);
|
|
- int ret;
|
|
+ unsigned int i;
|
|
+ struct vimc_ent_device *ved;
|
|
+
|
|
+ for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
|
|
+ dev_dbg(&vimc->pdev.dev, "new entity for %s\n",
|
|
+ vimc->pipe_cfg->ents[i].name);
|
|
+ ved = vimc->pipe_cfg->ents[i].add(vimc,
|
|
+ vimc->pipe_cfg->ents[i].name);
|
|
+ if (!ved) {
|
|
+ dev_err(&vimc->pdev.dev, "add new entity for %s\n",
|
|
+ vimc->pipe_cfg->ents[i].name);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ vimc->ent_devs[i] = ved;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void vimc_rm_subdevs(struct vimc_device *vimc)
|
|
+{
|
|
+ unsigned int i;
|
|
|
|
- dev_dbg(master, "bind");
|
|
+ for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
|
|
+ if (vimc->ent_devs[i])
|
|
+ vimc->pipe_cfg->ents[i].rm(vimc, vimc->ent_devs[i]);
|
|
+}
|
|
+
|
|
+static int vimc_register_devices(struct vimc_device *vimc)
|
|
+{
|
|
+ int ret;
|
|
|
|
/* Register the v4l2 struct */
|
|
ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev);
|
|
@@ -179,22 +198,30 @@ static int vimc_comp_bind(struct device *master)
|
|
return ret;
|
|
}
|
|
|
|
- /* Bind subdevices */
|
|
- ret = component_bind_all(master, &vimc->v4l2_dev);
|
|
- if (ret)
|
|
+ /* allocate ent_devs */
|
|
+ vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
|
|
+ sizeof(*vimc->ent_devs),
|
|
+ GFP_KERNEL);
|
|
+ if (!vimc->ent_devs)
|
|
goto err_v4l2_unregister;
|
|
|
|
+ /* Invoke entity config hooks to initialize and register subdevs */
|
|
+ ret = vimc_add_subdevs(vimc);
|
|
+ if (ret)
|
|
+ /* remove sundevs that got added */
|
|
+ goto err_rm_subdevs;
|
|
+
|
|
/* Initialize links */
|
|
ret = vimc_create_links(vimc);
|
|
if (ret)
|
|
- goto err_comp_unbind_all;
|
|
+ goto err_rm_subdevs;
|
|
|
|
/* Register the media device */
|
|
ret = media_device_register(&vimc->mdev);
|
|
if (ret) {
|
|
dev_err(vimc->mdev.dev,
|
|
"media device register failed (err=%d)\n", ret);
|
|
- goto err_comp_unbind_all;
|
|
+ goto err_rm_subdevs;
|
|
}
|
|
|
|
/* Expose all subdev's nodes*/
|
|
@@ -211,98 +238,32 @@ static int vimc_comp_bind(struct device *master)
|
|
err_mdev_unregister:
|
|
media_device_unregister(&vimc->mdev);
|
|
media_device_cleanup(&vimc->mdev);
|
|
-err_comp_unbind_all:
|
|
- component_unbind_all(master, NULL);
|
|
+err_rm_subdevs:
|
|
+ vimc_rm_subdevs(vimc);
|
|
+ kfree(vimc->ent_devs);
|
|
err_v4l2_unregister:
|
|
v4l2_device_unregister(&vimc->v4l2_dev);
|
|
|
|
return ret;
|
|
}
|
|
|
|
-static void vimc_comp_unbind(struct device *master)
|
|
+static void vimc_unregister(struct vimc_device *vimc)
|
|
{
|
|
- struct vimc_device *vimc = container_of(to_platform_device(master),
|
|
- struct vimc_device, pdev);
|
|
-
|
|
- dev_dbg(master, "unbind");
|
|
-
|
|
media_device_unregister(&vimc->mdev);
|
|
media_device_cleanup(&vimc->mdev);
|
|
- component_unbind_all(master, NULL);
|
|
v4l2_device_unregister(&vimc->v4l2_dev);
|
|
+ kfree(vimc->ent_devs);
|
|
}
|
|
|
|
-static int vimc_comp_compare(struct device *comp, void *data)
|
|
-{
|
|
- return comp == data;
|
|
-}
|
|
-
|
|
-static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
|
|
-{
|
|
- struct component_match *match = NULL;
|
|
- struct vimc_platform_data pdata;
|
|
- int i;
|
|
-
|
|
- for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
|
|
- dev_dbg(&vimc->pdev.dev, "new pdev for %s\n",
|
|
- vimc->pipe_cfg->ents[i].drv);
|
|
-
|
|
- strscpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name,
|
|
- sizeof(pdata.entity_name));
|
|
-
|
|
- vimc->subdevs[i] = platform_device_register_data(&vimc->pdev.dev,
|
|
- vimc->pipe_cfg->ents[i].drv,
|
|
- PLATFORM_DEVID_AUTO,
|
|
- &pdata,
|
|
- sizeof(pdata));
|
|
- if (IS_ERR(vimc->subdevs[i])) {
|
|
- match = ERR_CAST(vimc->subdevs[i]);
|
|
- while (--i >= 0)
|
|
- platform_device_unregister(vimc->subdevs[i]);
|
|
-
|
|
- return match;
|
|
- }
|
|
-
|
|
- component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare,
|
|
- &vimc->subdevs[i]->dev);
|
|
- }
|
|
-
|
|
- return match;
|
|
-}
|
|
-
|
|
-static void vimc_rm_subdevs(struct vimc_device *vimc)
|
|
-{
|
|
- unsigned int i;
|
|
-
|
|
- for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
|
|
- platform_device_unregister(vimc->subdevs[i]);
|
|
-}
|
|
-
|
|
-static const struct component_master_ops vimc_comp_ops = {
|
|
- .bind = vimc_comp_bind,
|
|
- .unbind = vimc_comp_unbind,
|
|
-};
|
|
-
|
|
static int vimc_probe(struct platform_device *pdev)
|
|
{
|
|
struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev);
|
|
- struct component_match *match = NULL;
|
|
int ret;
|
|
|
|
dev_dbg(&pdev->dev, "probe");
|
|
|
|
memset(&vimc->mdev, 0, sizeof(vimc->mdev));
|
|
|
|
- /* Create platform_device for each entity in the topology*/
|
|
- vimc->subdevs = devm_kcalloc(&vimc->pdev.dev, vimc->pipe_cfg->num_ents,
|
|
- sizeof(*vimc->subdevs), GFP_KERNEL);
|
|
- if (!vimc->subdevs)
|
|
- return -ENOMEM;
|
|
-
|
|
- match = vimc_add_subdevs(vimc);
|
|
- if (IS_ERR(match))
|
|
- return PTR_ERR(match);
|
|
-
|
|
/* Link the media device within the v4l2_device */
|
|
vimc->v4l2_dev.mdev = &vimc->mdev;
|
|
|
|
@@ -314,12 +275,9 @@ static int vimc_probe(struct platform_device *pdev)
|
|
vimc->mdev.dev = &pdev->dev;
|
|
media_device_init(&vimc->mdev);
|
|
|
|
- /* Add self to the component system */
|
|
- ret = component_master_add_with_match(&pdev->dev, &vimc_comp_ops,
|
|
- match);
|
|
+ ret = vimc_register_devices(vimc);
|
|
if (ret) {
|
|
media_device_cleanup(&vimc->mdev);
|
|
- vimc_rm_subdevs(vimc);
|
|
return ret;
|
|
}
|
|
|
|
@@ -332,8 +290,8 @@ static int vimc_remove(struct platform_device *pdev)
|
|
|
|
dev_dbg(&pdev->dev, "remove");
|
|
|
|
- component_master_del(&pdev->dev, &vimc_comp_ops);
|
|
vimc_rm_subdevs(vimc);
|
|
+ vimc_unregister(vimc);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index b72b8385067b..2c291447807e 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -5,9 +5,7 @@
|
|
* Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
|
|
*/
|
|
|
|
-#include <linux/component.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/mod_devicetable.h>
|
|
+#include <linux/moduleparam.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/v4l2-mediabus.h>
|
|
@@ -15,8 +13,6 @@
|
|
|
|
#include "vimc-common.h"
|
|
|
|
-#define VIMC_DEB_DRV_NAME "vimc-debayer"
|
|
-
|
|
static unsigned int deb_mean_win_size = 3;
|
|
module_param(deb_mean_win_size, uint, 0000);
|
|
MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
|
|
@@ -491,44 +487,40 @@ static const struct v4l2_subdev_internal_ops vimc_deb_int_ops = {
|
|
.release = vimc_deb_release,
|
|
};
|
|
|
|
-static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
{
|
|
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
|
|
- struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
|
|
- ved);
|
|
+ struct vimc_deb_device *vdeb;
|
|
|
|
+ vdeb = container_of(ved, struct vimc_deb_device, ved);
|
|
vimc_ent_sd_unregister(ved, &vdeb->sd);
|
|
}
|
|
|
|
-static int vimc_deb_comp_bind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name)
|
|
{
|
|
- struct v4l2_device *v4l2_dev = master_data;
|
|
- struct vimc_platform_data *pdata = comp->platform_data;
|
|
+ struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
|
|
struct vimc_deb_device *vdeb;
|
|
int ret;
|
|
|
|
/* Allocate the vdeb struct */
|
|
vdeb = kzalloc(sizeof(*vdeb), GFP_KERNEL);
|
|
if (!vdeb)
|
|
- return -ENOMEM;
|
|
+ return NULL;
|
|
|
|
/* Initialize ved and sd */
|
|
ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
|
|
- pdata->entity_name,
|
|
+ vcfg_name,
|
|
MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
|
|
(const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
|
MEDIA_PAD_FL_SOURCE},
|
|
&vimc_deb_int_ops, &vimc_deb_ops);
|
|
if (ret) {
|
|
kfree(vdeb);
|
|
- return ret;
|
|
+ return NULL;
|
|
}
|
|
|
|
vdeb->ved.process_frame = vimc_deb_process_frame;
|
|
- dev_set_drvdata(comp, &vdeb->ved);
|
|
- vdeb->dev = comp;
|
|
+ vdeb->dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vdeb->sink_fmt = sink_fmt_default;
|
|
@@ -541,46 +533,5 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master,
|
|
vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
|
|
vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
|
|
|
|
- return 0;
|
|
+ return &vdeb->ved;
|
|
}
|
|
-
|
|
-static const struct component_ops vimc_deb_comp_ops = {
|
|
- .bind = vimc_deb_comp_bind,
|
|
- .unbind = vimc_deb_comp_unbind,
|
|
-};
|
|
-
|
|
-static int vimc_deb_probe(struct platform_device *pdev)
|
|
-{
|
|
- return component_add(&pdev->dev, &vimc_deb_comp_ops);
|
|
-}
|
|
-
|
|
-static int vimc_deb_remove(struct platform_device *pdev)
|
|
-{
|
|
- component_del(&pdev->dev, &vimc_deb_comp_ops);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static const struct platform_device_id vimc_deb_driver_ids[] = {
|
|
- {
|
|
- .name = VIMC_DEB_DRV_NAME,
|
|
- },
|
|
- { }
|
|
-};
|
|
-
|
|
-static struct platform_driver vimc_deb_pdrv = {
|
|
- .probe = vimc_deb_probe,
|
|
- .remove = vimc_deb_remove,
|
|
- .id_table = vimc_deb_driver_ids,
|
|
- .driver = {
|
|
- .name = VIMC_DEB_DRV_NAME,
|
|
- },
|
|
-};
|
|
-
|
|
-module_platform_driver(vimc_deb_pdrv);
|
|
-
|
|
-MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids);
|
|
-
|
|
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Debayer");
|
|
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
|
|
-MODULE_LICENSE("GPL");
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index 49ab8d9dd9c9..f72200de2535 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -5,18 +5,13 @@
|
|
* Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
|
|
*/
|
|
|
|
-#include <linux/component.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/mod_devicetable.h>
|
|
-#include <linux/platform_device.h>
|
|
+#include <linux/moduleparam.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/v4l2-mediabus.h>
|
|
#include <media/v4l2-subdev.h>
|
|
|
|
#include "vimc-common.h"
|
|
|
|
-#define VIMC_SCA_DRV_NAME "vimc-scaler"
|
|
-
|
|
static unsigned int sca_mult = 3;
|
|
module_param(sca_mult, uint, 0000);
|
|
MODULE_PARM_DESC(sca_mult, " the image size multiplier");
|
|
@@ -350,89 +345,43 @@ static const struct v4l2_subdev_internal_ops vimc_sca_int_ops = {
|
|
.release = vimc_sca_release,
|
|
};
|
|
|
|
-static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
{
|
|
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
|
|
- struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device,
|
|
- ved);
|
|
+ struct vimc_sca_device *vsca;
|
|
|
|
+ vsca = container_of(ved, struct vimc_sca_device, ved);
|
|
vimc_ent_sd_unregister(ved, &vsca->sd);
|
|
}
|
|
|
|
-
|
|
-static int vimc_sca_comp_bind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name)
|
|
{
|
|
- struct v4l2_device *v4l2_dev = master_data;
|
|
- struct vimc_platform_data *pdata = comp->platform_data;
|
|
+ struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
|
|
struct vimc_sca_device *vsca;
|
|
int ret;
|
|
|
|
/* Allocate the vsca struct */
|
|
vsca = kzalloc(sizeof(*vsca), GFP_KERNEL);
|
|
if (!vsca)
|
|
- return -ENOMEM;
|
|
+ return NULL;
|
|
|
|
/* Initialize ved and sd */
|
|
ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
|
|
- pdata->entity_name,
|
|
+ vcfg_name,
|
|
MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
|
|
(const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
|
MEDIA_PAD_FL_SOURCE},
|
|
&vimc_sca_int_ops, &vimc_sca_ops);
|
|
if (ret) {
|
|
kfree(vsca);
|
|
- return ret;
|
|
+ return NULL;
|
|
}
|
|
|
|
vsca->ved.process_frame = vimc_sca_process_frame;
|
|
- dev_set_drvdata(comp, &vsca->ved);
|
|
- vsca->dev = comp;
|
|
+ vsca->dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vsca->sink_fmt = sink_fmt_default;
|
|
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static const struct component_ops vimc_sca_comp_ops = {
|
|
- .bind = vimc_sca_comp_bind,
|
|
- .unbind = vimc_sca_comp_unbind,
|
|
-};
|
|
-
|
|
-static int vimc_sca_probe(struct platform_device *pdev)
|
|
-{
|
|
- return component_add(&pdev->dev, &vimc_sca_comp_ops);
|
|
+ return &vsca->ved;
|
|
}
|
|
-
|
|
-static int vimc_sca_remove(struct platform_device *pdev)
|
|
-{
|
|
- component_del(&pdev->dev, &vimc_sca_comp_ops);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static const struct platform_device_id vimc_sca_driver_ids[] = {
|
|
- {
|
|
- .name = VIMC_SCA_DRV_NAME,
|
|
- },
|
|
- { }
|
|
-};
|
|
-
|
|
-static struct platform_driver vimc_sca_pdrv = {
|
|
- .probe = vimc_sca_probe,
|
|
- .remove = vimc_sca_remove,
|
|
- .id_table = vimc_sca_driver_ids,
|
|
- .driver = {
|
|
- .name = VIMC_SCA_DRV_NAME,
|
|
- },
|
|
-};
|
|
-
|
|
-module_platform_driver(vimc_sca_pdrv);
|
|
-
|
|
-MODULE_DEVICE_TABLE(platform, vimc_sca_driver_ids);
|
|
-
|
|
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Scaler");
|
|
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
|
|
-MODULE_LICENSE("GPL");
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 6c53b9fc1617..1f15637ca8bb 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -5,10 +5,6 @@
|
|
* Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
|
|
*/
|
|
|
|
-#include <linux/component.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/mod_devicetable.h>
|
|
-#include <linux/platform_device.h>
|
|
#include <linux/v4l2-mediabus.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <media/v4l2-ctrls.h>
|
|
@@ -18,8 +14,6 @@
|
|
|
|
#include "vimc-common.h"
|
|
|
|
-#define VIMC_SEN_DRV_NAME "vimc-sensor"
|
|
-
|
|
struct vimc_sen_device {
|
|
struct vimc_ent_device ved;
|
|
struct v4l2_subdev sd;
|
|
@@ -304,13 +298,11 @@ static const struct v4l2_subdev_internal_ops vimc_sen_int_ops = {
|
|
.release = vimc_sen_release,
|
|
};
|
|
|
|
-static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
{
|
|
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
|
|
- struct vimc_sen_device *vsen =
|
|
- container_of(ved, struct vimc_sen_device, ved);
|
|
+ struct vimc_sen_device *vsen;
|
|
|
|
+ vsen = container_of(ved, struct vimc_sen_device, ved);
|
|
vimc_ent_sd_unregister(ved, &vsen->sd);
|
|
}
|
|
|
|
@@ -331,18 +323,17 @@ static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
|
|
.qmenu = tpg_pattern_strings,
|
|
};
|
|
|
|
-static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|
- void *master_data)
|
|
+struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
+ const char *vcfg_name)
|
|
{
|
|
- struct v4l2_device *v4l2_dev = master_data;
|
|
- struct vimc_platform_data *pdata = comp->platform_data;
|
|
+ struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
|
|
struct vimc_sen_device *vsen;
|
|
int ret;
|
|
|
|
/* Allocate the vsen struct */
|
|
vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
|
|
if (!vsen)
|
|
- return -ENOMEM;
|
|
+ return NULL;
|
|
|
|
v4l2_ctrl_handler_init(&vsen->hdl, 4);
|
|
|
|
@@ -368,7 +359,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|
|
|
/* Initialize ved and sd */
|
|
ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
|
|
- pdata->entity_name,
|
|
+ vcfg_name,
|
|
MEDIA_ENT_F_CAM_SENSOR, 1,
|
|
(const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
|
|
&vimc_sen_int_ops, &vimc_sen_ops);
|
|
@@ -376,8 +367,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|
goto err_free_hdl;
|
|
|
|
vsen->ved.process_frame = vimc_sen_process_frame;
|
|
- dev_set_drvdata(comp, &vsen->ved);
|
|
- vsen->dev = comp;
|
|
+ vsen->dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vsen->mbus_format = fmt_default;
|
|
@@ -389,7 +379,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|
if (ret)
|
|
goto err_unregister_ent_sd;
|
|
|
|
- return 0;
|
|
+ return &vsen->ved;
|
|
|
|
err_unregister_ent_sd:
|
|
vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
|
|
@@ -398,46 +388,5 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
|
|
err_free_vsen:
|
|
kfree(vsen);
|
|
|
|
- return ret;
|
|
+ return NULL;
|
|
}
|
|
-
|
|
-static const struct component_ops vimc_sen_comp_ops = {
|
|
- .bind = vimc_sen_comp_bind,
|
|
- .unbind = vimc_sen_comp_unbind,
|
|
-};
|
|
-
|
|
-static int vimc_sen_probe(struct platform_device *pdev)
|
|
-{
|
|
- return component_add(&pdev->dev, &vimc_sen_comp_ops);
|
|
-}
|
|
-
|
|
-static int vimc_sen_remove(struct platform_device *pdev)
|
|
-{
|
|
- component_del(&pdev->dev, &vimc_sen_comp_ops);
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-static const struct platform_device_id vimc_sen_driver_ids[] = {
|
|
- {
|
|
- .name = VIMC_SEN_DRV_NAME,
|
|
- },
|
|
- { }
|
|
-};
|
|
-
|
|
-static struct platform_driver vimc_sen_pdrv = {
|
|
- .probe = vimc_sen_probe,
|
|
- .remove = vimc_sen_remove,
|
|
- .id_table = vimc_sen_driver_ids,
|
|
- .driver = {
|
|
- .name = VIMC_SEN_DRV_NAME,
|
|
- },
|
|
-};
|
|
-
|
|
-module_platform_driver(vimc_sen_pdrv);
|
|
-
|
|
-MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids);
|
|
-
|
|
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor");
|
|
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
|
|
-MODULE_LICENSE("GPL");
|
|
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
|
|
index 048d770e498b..faa2879c25df 100644
|
|
--- a/drivers/media/platform/vimc/vimc-streamer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-streamer.c
|
|
@@ -7,7 +7,6 @@
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
-#include <linux/module.h>
|
|
#include <linux/freezer.h>
|
|
#include <linux/kthread.h>
|
|
|
|
|
|
From 5ae32d4958c0976b86dd7ae4cda70c34a1cebf6d Mon Sep 17 00:00:00 2001
|
|
From: Shuah Khan <skhan@linuxfoundation.org>
|
|
Date: Tue, 17 Sep 2019 13:35:09 -0300
|
|
Subject: [PATCH] media: vimc: Fix gpf in rmmod path when stream is active
|
|
|
|
If vimc module is removed while streaming is in progress, sensor subdev
|
|
unregister runs into general protection fault when it tries to unregister
|
|
media entities. This is a common subdev problem related to releasing
|
|
pads from v4l2_device_unregister_subdev() before calling unregister.
|
|
Unregister references pads during unregistering subdev.
|
|
|
|
The sd release handler is the right place for releasing all sd resources
|
|
including pads. The release handlers currently release all resources
|
|
except the pads.
|
|
|
|
Fix v4l2_device_unregister_subdev() not release pads and release pads
|
|
from the sd_int_op release handlers.
|
|
|
|
kernel: [ 4136.715839] general protection fault: 0000 [#1] SMP PTI
|
|
kernel: [ 4136.715847] CPU: 2 PID: 1972 Comm: bash Not tainted 5.3.0-rc2+ #4
|
|
kernel: [ 4136.715850] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013
|
|
kernel: [ 4136.715858] RIP: 0010:media_gobj_destroy.part.16+0x1f/0x60
|
|
kernel: [ 4136.715863] Code: ff 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 fe 48 89 e5 53 48 89 fb 48 c7 c7 00 7f cf b0 e8 24 fa ff ff 48 8b 03 <48> 83 80 a0 00 00 00 01 48 8b 43 18 48 8b 53 10 48 89 42 08 48 89
|
|
kernel: [ 4136.715866] RSP: 0018:ffff9b2248fe3cb0 EFLAGS: 00010246
|
|
kernel: [ 4136.715870] RAX: bcf2bfbfa0d63c2f RBX: ffff88c3eb37e9c0 RCX: 00000000802a0018
|
|
kernel: [ 4136.715873] RDX: ffff88c3e4f6a078 RSI: ffff88c3eb37e9c0 RDI: ffffffffb0cf7f00
|
|
kernel: [ 4136.715876] RBP: ffff9b2248fe3cb8 R08: 0000000001000002 R09: ffffffffb0492b00
|
|
kernel: [ 4136.715879] R10: ffff9b2248fe3c28 R11: 0000000000000001 R12: 0000000000000038
|
|
kernel: [ 4136.715881] R13: ffffffffc09a1628 R14: ffff88c3e4f6a028 R15: fffffffffffffff2
|
|
kernel: [ 4136.715885] FS: 00007f8389647740(0000) GS:ffff88c465500000(0000) knlGS:0000000000000000
|
|
kernel: [ 4136.715888] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
kernel: [ 4136.715891] CR2: 000055d008f80fd8 CR3: 00000001996ec005 CR4: 00000000000606e0
|
|
kernel: [ 4136.715894] Call Trace:
|
|
kernel: [ 4136.715903] media_gobj_destroy+0x14/0x20
|
|
kernel: [ 4136.715908] __media_device_unregister_entity+0xb3/0xe0
|
|
kernel: [ 4136.715915] media_device_unregister_entity+0x30/0x40
|
|
kernel: [ 4136.715920] v4l2_device_unregister_subdev+0xa8/0xe0
|
|
kernel: [ 4136.715928] vimc_ent_sd_unregister+0x1e/0x30 [vimc]
|
|
kernel: [ 4136.715933] vimc_sen_rm+0x16/0x20 [vimc]
|
|
kernel: [ 4136.715938] vimc_remove+0x3e/0xa0 [vimc]
|
|
kernel: [ 4136.715945] platform_drv_remove+0x25/0x50
|
|
kernel: [ 4136.715951] device_release_driver_internal+0xe0/0x1b0
|
|
kernel: [ 4136.715956] device_driver_detach+0x14/0x20
|
|
kernel: [ 4136.715960] unbind_store+0xd1/0x130
|
|
kernel: [ 4136.715965] drv_attr_store+0x27/0x40
|
|
kernel: [ 4136.715971] sysfs_kf_write+0x48/0x60
|
|
kernel: [ 4136.715976] kernfs_fop_write+0x128/0x1b0
|
|
kernel: [ 4136.715982] __vfs_write+0x1b/0x40
|
|
kernel: [ 4136.715987] vfs_write+0xc3/0x1d0
|
|
kernel: [ 4136.715993] ksys_write+0xaa/0xe0
|
|
kernel: [ 4136.715999] __x64_sys_write+0x1a/0x20
|
|
kernel: [ 4136.716005] do_syscall_64+0x5a/0x130
|
|
kernel: [ 4136.716010] entry_SYSCALL_64_after_hwframe+0x4
|
|
|
|
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit d7fb5c361c2a2666d20e044206e1756bc8e87df2)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.c | 3 +--
|
|
drivers/media/platform/vimc/vimc-debayer.c | 1 +
|
|
drivers/media/platform/vimc/vimc-scaler.c | 1 +
|
|
drivers/media/platform/vimc/vimc-sensor.c | 1 +
|
|
4 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 7e1ae0b12f1e..a3120f4f7a90 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -375,7 +375,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
{
|
|
int ret;
|
|
|
|
- /* Allocate the pads */
|
|
+ /* Allocate the pads. Should be released from the sd_int_op release */
|
|
ved->pads = vimc_pads_init(num_pads, pads_flag);
|
|
if (IS_ERR(ved->pads))
|
|
return PTR_ERR(ved->pads);
|
|
@@ -424,7 +424,6 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
|
|
void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
|
|
{
|
|
media_entity_cleanup(ved->ent);
|
|
- vimc_pads_cleanup(ved->pads);
|
|
v4l2_device_unregister_subdev(sd);
|
|
}
|
|
EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index 2c291447807e..4125159e8f31 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -480,6 +480,7 @@ static void vimc_deb_release(struct v4l2_subdev *sd)
|
|
struct vimc_deb_device *vdeb =
|
|
container_of(sd, struct vimc_deb_device, sd);
|
|
|
|
+ vimc_pads_cleanup(vdeb->ved.pads);
|
|
kfree(vdeb);
|
|
}
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index f72200de2535..1a593d81ea7c 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -338,6 +338,7 @@ static void vimc_sca_release(struct v4l2_subdev *sd)
|
|
struct vimc_sca_device *vsca =
|
|
container_of(sd, struct vimc_sca_device, sd);
|
|
|
|
+ vimc_pads_cleanup(vsca->ved.pads);
|
|
kfree(vsca);
|
|
}
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 1f15637ca8bb..46dc6a535abe 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -291,6 +291,7 @@ static void vimc_sen_release(struct v4l2_subdev *sd)
|
|
|
|
v4l2_ctrl_handler_free(&vsen->hdl);
|
|
tpg_free(&vsen->tpg);
|
|
+ vimc_pads_cleanup(vsen->ved.pads);
|
|
kfree(vsen);
|
|
}
|
|
|
|
|
|
From 20a2fc9e8748cae89c526ffb493efa4d482b133e Mon Sep 17 00:00:00 2001
|
|
From: Shuah Khan <skhan@linuxfoundation.org>
|
|
Date: Tue, 17 Sep 2019 13:35:10 -0300
|
|
Subject: [PATCH] media: vimc: move duplicated IS_SRC and IS_SINK to common
|
|
header
|
|
|
|
Move duplicated IS_SRC and IS_SINK dfines to common header. Rename
|
|
them to VIMC_IS_SRC and VIM_IS_SINK.
|
|
|
|
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3a9e69f1404f174ea8e0432d308aff20d04a9eeb)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.h | 4 ++++
|
|
drivers/media/platform/vimc/vimc-debayer.c | 11 ++++-------
|
|
drivers/media/platform/vimc/vimc-scaler.c | 8 +++-----
|
|
3 files changed, 11 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index d7aaf31175bc..698db7c07645 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -27,6 +27,10 @@
|
|
|
|
#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
|
|
|
|
+/* Source and sink pad checks */
|
|
+#define VIMC_IS_SRC(pad) (pad)
|
|
+#define VIMC_IS_SINK(pad) (!(pad))
|
|
+
|
|
/**
|
|
* struct vimc_colorimetry_clamp - Adjust colorimetry parameters
|
|
*
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index 4125159e8f31..feac47d79449 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -20,9 +20,6 @@ MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
|
|
"stays in the center of the window, otherwise the next odd number "
|
|
"is considered");
|
|
|
|
-#define IS_SINK(pad) (!pad)
|
|
-#define IS_SRC(pad) (pad)
|
|
-
|
|
enum vimc_deb_rgb_colors {
|
|
VIMC_DEB_RED = 0,
|
|
VIMC_DEB_GREEN = 1,
|
|
@@ -155,7 +152,7 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
|
|
struct v4l2_subdev_mbus_code_enum *code)
|
|
{
|
|
/* We only support one format for source pads */
|
|
- if (IS_SRC(code->pad)) {
|
|
+ if (VIMC_IS_SRC(code->pad)) {
|
|
struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
|
|
|
|
if (code->index)
|
|
@@ -181,7 +178,7 @@ static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
|
|
if (fse->index)
|
|
return -EINVAL;
|
|
|
|
- if (IS_SINK(fse->pad)) {
|
|
+ if (VIMC_IS_SINK(fse->pad)) {
|
|
const struct vimc_deb_pix_map *vpix =
|
|
vimc_deb_pix_map_by_code(fse->code);
|
|
|
|
@@ -211,7 +208,7 @@ static int vimc_deb_get_fmt(struct v4l2_subdev *sd,
|
|
vdeb->sink_fmt;
|
|
|
|
/* Set the right code for the source pad */
|
|
- if (IS_SRC(fmt->pad))
|
|
+ if (VIMC_IS_SRC(fmt->pad))
|
|
fmt->format.code = vdeb->src_code;
|
|
|
|
return 0;
|
|
@@ -258,7 +255,7 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
|
|
* Do not change the format of the source pad,
|
|
* it is propagated from the sink
|
|
*/
|
|
- if (IS_SRC(fmt->pad)) {
|
|
+ if (VIMC_IS_SRC(fmt->pad)) {
|
|
fmt->format = *sink_fmt;
|
|
/* TODO: Add support for other formats */
|
|
fmt->format.code = vdeb->src_code;
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index 1a593d81ea7c..a6a3cc5be872 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -16,8 +16,6 @@ static unsigned int sca_mult = 3;
|
|
module_param(sca_mult, uint, 0000);
|
|
MODULE_PARM_DESC(sca_mult, " the image size multiplier");
|
|
|
|
-#define IS_SINK(pad) (!pad)
|
|
-#define IS_SRC(pad) (pad)
|
|
#define MAX_ZOOM 8
|
|
|
|
struct vimc_sca_device {
|
|
@@ -93,7 +91,7 @@ static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd,
|
|
fse->min_width = VIMC_FRAME_MIN_WIDTH;
|
|
fse->min_height = VIMC_FRAME_MIN_HEIGHT;
|
|
|
|
- if (IS_SINK(fse->pad)) {
|
|
+ if (VIMC_IS_SINK(fse->pad)) {
|
|
fse->max_width = VIMC_FRAME_MAX_WIDTH;
|
|
fse->max_height = VIMC_FRAME_MAX_HEIGHT;
|
|
} else {
|
|
@@ -116,7 +114,7 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
|
|
vsca->sink_fmt;
|
|
|
|
/* Scale the frame size for the source pad */
|
|
- if (IS_SRC(format->pad)) {
|
|
+ if (VIMC_IS_SRC(format->pad)) {
|
|
format->format.width = vsca->sink_fmt.width * sca_mult;
|
|
format->format.height = vsca->sink_fmt.height * sca_mult;
|
|
}
|
|
@@ -165,7 +163,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
|
|
* Do not change the format of the source pad,
|
|
* it is propagated from the sink
|
|
*/
|
|
- if (IS_SRC(fmt->pad)) {
|
|
+ if (VIMC_IS_SRC(fmt->pad)) {
|
|
fmt->format = *sink_fmt;
|
|
fmt->format.width = sink_fmt->width * sca_mult;
|
|
fmt->format.height = sink_fmt->height * sca_mult;
|
|
|
|
From e9c459c152516d20cb783181dfe12b26aaa47ffc Mon Sep 17 00:00:00 2001
|
|
From: Shuah Khan <skhan@linuxfoundation.org>
|
|
Date: Tue, 17 Sep 2019 13:35:11 -0300
|
|
Subject: [PATCH] media: doc: media: vimc: Update module parameter usage
|
|
information
|
|
|
|
vimc driver is now a monolithic driver. Update the module parameter
|
|
usage information to reflect that.
|
|
|
|
[m.chehab+samsung@kernel.org: fix two warnings due to wrontly added spaces]
|
|
|
|
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 78364ccffd3396d9c6f7c50416b5c79d57412547)
|
|
---
|
|
Documentation/media/v4l-drivers/vimc.rst | 12 ++++++------
|
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/vimc.rst b/Documentation/media/v4l-drivers/vimc.rst
|
|
index 406417680db5..d567046b6a55 100644
|
|
--- a/Documentation/media/v4l-drivers/vimc.rst
|
|
+++ b/Documentation/media/v4l-drivers/vimc.rst
|
|
@@ -76,22 +76,22 @@ vimc-capture:
|
|
* 1 Pad sink
|
|
* 1 Pad source
|
|
|
|
+
|
|
Module options
|
|
----------------
|
|
+--------------
|
|
|
|
-Vimc has a few module parameters to configure the driver. You should pass
|
|
-those arguments to each subdevice, not to the vimc module. For example::
|
|
+Vimc has a few module parameters to configure the driver.
|
|
|
|
- vimc_subdevice.param=value
|
|
+ param=value
|
|
|
|
-* ``vimc_scaler.sca_mult=<unsigned int>``
|
|
+* ``sca_mult=<unsigned int>``
|
|
|
|
Image size multiplier factor to be used to multiply both width and
|
|
height, so the image size will be ``sca_mult^2`` bigger than the
|
|
original one. Currently, only supports scaling up (the default value
|
|
is 3).
|
|
|
|
-* ``vimc_debayer.deb_mean_win_size=<unsigned int>``
|
|
+* ``deb_mean_win_size=<unsigned int>``
|
|
|
|
Window size to calculate the mean. Note: the window size needs to be an
|
|
odd number, as the main pixel stays in the center of the window,
|
|
|
|
From a24b65dec356843b9044db3b15c812fd8a6ef116 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 30 Aug 2019 06:26:22 -0300
|
|
Subject: [PATCH] media: cedrus: fill in bus_info for media device
|
|
|
|
Fixes this compliance warning:
|
|
|
|
$ v4l2-compliance -m0
|
|
v4l2-compliance SHA: b514d615166bdc0901a4c71261b87db31e89f464, 32 bits
|
|
|
|
Compliance test for cedrus device /dev/media0:
|
|
|
|
Media Driver Info:
|
|
Driver name : cedrus
|
|
Model : cedrus
|
|
Serial :
|
|
Bus info :
|
|
Media version : 5.3.0
|
|
Hardware revision: 0x00000000 (0)
|
|
Driver version : 5.3.0
|
|
|
|
Required ioctls:
|
|
warn: v4l2-test-media.cpp(51): empty bus_info
|
|
test MEDIA_IOC_DEVICE_INFO: OK
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit ae0688f659adb17ae6ae5710c886b20b5406e5c4)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
index 2d3ea8b74dfd..3439f6ad6338 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
@@ -357,6 +357,8 @@ static int cedrus_probe(struct platform_device *pdev)
|
|
|
|
dev->mdev.dev = &pdev->dev;
|
|
strscpy(dev->mdev.model, CEDRUS_NAME, sizeof(dev->mdev.model));
|
|
+ strscpy(dev->mdev.bus_info, "platform:" CEDRUS_NAME,
|
|
+ sizeof(dev->mdev.bus_info));
|
|
|
|
media_device_init(&dev->mdev);
|
|
dev->mdev.ops = &cedrus_m2m_media_ops;
|
|
|
|
From 532a1e7c0cee8bfb21b67dac8160ed9dd7d819d3 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 30 Aug 2019 06:26:23 -0300
|
|
Subject: [PATCH] media: cedrus: choose default pixelformat in try_fmt
|
|
|
|
If an unsupported pixelformat is passed to try_fmt, then pick
|
|
the first valid pixelformat instead. This is more standard V4L2
|
|
behavior.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit dec555256f2cb61ee94975727ec2d4a8d592ac92)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 46 ++++++++++-------------
|
|
1 file changed, 20 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
index eeee3efd247b..d69c9bcdb8e2 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
@@ -62,33 +62,30 @@ static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
|
|
static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
|
|
unsigned int capabilities)
|
|
{
|
|
+ struct cedrus_format *first_valid_fmt = NULL;
|
|
struct cedrus_format *fmt;
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
|
|
fmt = &cedrus_formats[i];
|
|
|
|
- if (fmt->capabilities && (fmt->capabilities & capabilities) !=
|
|
- fmt->capabilities)
|
|
+ if ((fmt->capabilities & capabilities) != fmt->capabilities ||
|
|
+ !(fmt->directions & directions))
|
|
continue;
|
|
|
|
- if (fmt->pixelformat == pixelformat &&
|
|
- (fmt->directions & directions) != 0)
|
|
+ if (fmt->pixelformat == pixelformat)
|
|
break;
|
|
+
|
|
+ if (!first_valid_fmt)
|
|
+ first_valid_fmt = fmt;
|
|
}
|
|
|
|
if (i == CEDRUS_FORMATS_COUNT)
|
|
- return NULL;
|
|
+ return first_valid_fmt;
|
|
|
|
return &cedrus_formats[i];
|
|
}
|
|
|
|
-static bool cedrus_check_format(u32 pixelformat, u32 directions,
|
|
- unsigned int capabilities)
|
|
-{
|
|
- return cedrus_find_format(pixelformat, directions, capabilities);
|
|
-}
|
|
-
|
|
static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
|
{
|
|
unsigned int width = pix_fmt->width;
|
|
@@ -252,11 +249,14 @@ static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
|
|
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
|
|
+ struct cedrus_format *fmt =
|
|
+ cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
|
|
+ dev->capabilities);
|
|
|
|
- if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
|
|
- dev->capabilities))
|
|
+ if (!fmt)
|
|
return -EINVAL;
|
|
|
|
+ pix_fmt->pixelformat = fmt->pixelformat;
|
|
cedrus_prepare_format(pix_fmt);
|
|
|
|
return 0;
|
|
@@ -268,15 +268,18 @@ static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
|
|
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
|
|
+ struct cedrus_format *fmt =
|
|
+ cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
|
|
+ dev->capabilities);
|
|
|
|
- if (!cedrus_check_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
|
|
- dev->capabilities))
|
|
+ if (!fmt)
|
|
return -EINVAL;
|
|
|
|
/* Source image size has to be provided by userspace. */
|
|
if (pix_fmt->sizeimage == 0)
|
|
return -EINVAL;
|
|
|
|
+ pix_fmt->pixelformat = fmt->pixelformat;
|
|
cedrus_prepare_format(pix_fmt);
|
|
|
|
return 0;
|
|
@@ -364,21 +367,12 @@ static int cedrus_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
|
|
struct device *alloc_devs[])
|
|
{
|
|
struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
|
|
- struct cedrus_dev *dev = ctx->dev;
|
|
struct v4l2_pix_format *pix_fmt;
|
|
- u32 directions;
|
|
|
|
- if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
|
|
- directions = CEDRUS_DECODE_SRC;
|
|
+ if (V4L2_TYPE_IS_OUTPUT(vq->type))
|
|
pix_fmt = &ctx->src_fmt;
|
|
- } else {
|
|
- directions = CEDRUS_DECODE_DST;
|
|
+ else
|
|
pix_fmt = &ctx->dst_fmt;
|
|
- }
|
|
-
|
|
- if (!cedrus_check_format(pix_fmt->pixelformat, directions,
|
|
- dev->capabilities))
|
|
- return -EINVAL;
|
|
|
|
if (*nplanes) {
|
|
if (sizes[0] < pix_fmt->sizeimage)
|
|
|
|
From a5c635a0a00ea1718a94621f55a4d82f5fc291b0 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 30 Aug 2019 06:26:24 -0300
|
|
Subject: [PATCH] media: cedrus: fix various format-related compliance issues
|
|
|
|
Initialize the context on open() with valid capture and output
|
|
formats. It is good practice to always have valid formats internally.
|
|
|
|
This solves one vb2 warning in the kernel log where the sizeimage
|
|
value of the output format was 0 when requesting buffers, which is
|
|
not allowed.
|
|
|
|
It also simplifies the g_fmt ioctl implementations since they no longer
|
|
have to check if a valid format was ever set.
|
|
|
|
cedrus_prepare_format() now also validates sizeimage for the output
|
|
formats, ensuring userspace can't set it to 0 since that would cause
|
|
the same vb2 warning.
|
|
|
|
Finally remove the sizeimage == 0 check in cedrus_try_fmt_vid_out()
|
|
since cedrus_prepare_format() will now adjust this value.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 965c71e8adcff315e16b58c00cd312598fc0222c)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus.c | 10 ++++++++
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 28 +++--------------------
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.h | 1 +
|
|
3 files changed, 14 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
index 3439f6ad6338..0cf637c8a1e3 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
@@ -241,6 +241,16 @@ static int cedrus_open(struct file *file)
|
|
ret = PTR_ERR(ctx->fh.m2m_ctx);
|
|
goto err_ctrls;
|
|
}
|
|
+ ctx->dst_fmt.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12;
|
|
+ cedrus_prepare_format(&ctx->dst_fmt);
|
|
+ ctx->src_fmt.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
|
|
+ /*
|
|
+ * TILED_NV12 has more strict requirements, so copy the width and
|
|
+ * height to src_fmt to ensure that is matches the dst_fmt resolution.
|
|
+ */
|
|
+ ctx->src_fmt.width = ctx->dst_fmt.width;
|
|
+ ctx->src_fmt.height = ctx->dst_fmt.height;
|
|
+ cedrus_prepare_format(&ctx->src_fmt);
|
|
|
|
v4l2_fh_add(&ctx->fh);
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
index d69c9bcdb8e2..3ec3a2db790c 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
@@ -86,7 +86,7 @@ static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
|
|
return &cedrus_formats[i];
|
|
}
|
|
|
|
-static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
|
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
|
{
|
|
unsigned int width = pix_fmt->width;
|
|
unsigned int height = pix_fmt->height;
|
|
@@ -104,7 +104,8 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
|
case V4L2_PIX_FMT_H264_SLICE:
|
|
/* Zero bytes per line for encoded source. */
|
|
bytesperline = 0;
|
|
-
|
|
+ /* Choose some minimum size since this can't be 0 */
|
|
+ sizeimage = max_t(u32, SZ_1K, sizeimage);
|
|
break;
|
|
|
|
case V4L2_PIX_FMT_SUNXI_TILED_NV12:
|
|
@@ -211,16 +212,7 @@ static int cedrus_g_fmt_vid_cap(struct file *file, void *priv,
|
|
{
|
|
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
|
|
|
- /* Fall back to dummy default by lack of hardware configuration. */
|
|
- if (!ctx->dst_fmt.width || !ctx->dst_fmt.height) {
|
|
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12;
|
|
- cedrus_prepare_format(&f->fmt.pix);
|
|
-
|
|
- return 0;
|
|
- }
|
|
-
|
|
f->fmt.pix = ctx->dst_fmt;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -229,17 +221,7 @@ static int cedrus_g_fmt_vid_out(struct file *file, void *priv,
|
|
{
|
|
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
|
|
|
|
- /* Fall back to dummy default by lack of hardware configuration. */
|
|
- if (!ctx->dst_fmt.width || !ctx->dst_fmt.height) {
|
|
- f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
|
|
- f->fmt.pix.sizeimage = SZ_1K;
|
|
- cedrus_prepare_format(&f->fmt.pix);
|
|
-
|
|
- return 0;
|
|
- }
|
|
-
|
|
f->fmt.pix = ctx->src_fmt;
|
|
-
|
|
return 0;
|
|
}
|
|
|
|
@@ -275,10 +257,6 @@ static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
|
|
if (!fmt)
|
|
return -EINVAL;
|
|
|
|
- /* Source image size has to be provided by userspace. */
|
|
- if (pix_fmt->sizeimage == 0)
|
|
- return -EINVAL;
|
|
-
|
|
pix_fmt->pixelformat = fmt->pixelformat;
|
|
cedrus_prepare_format(pix_fmt);
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.h b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
|
|
index 0e4f7a8cccf2..05050c0a0921 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.h
|
|
@@ -26,5 +26,6 @@ extern const struct v4l2_ioctl_ops cedrus_ioctl_ops;
|
|
|
|
int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
|
|
struct vb2_queue *dst_vq);
|
|
+void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt);
|
|
|
|
#endif
|
|
|
|
From afd60eef266fdd7f0509eabf5a528aabeb05e92e Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sun, 1 Sep 2019 07:09:21 -0300
|
|
Subject: [PATCH] media: ext-ctrls-flash.rst: fix typo
|
|
|
|
to synchronises -> to synchronise
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 4a0cad6dcaa17b499717d2ed9c2376fe0cd6fac5)
|
|
---
|
|
Documentation/media/uapi/v4l/ext-ctrls-flash.rst | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst b/Documentation/media/uapi/v4l/ext-ctrls-flash.rst
|
|
index eff056b17167..b9a6b08fbf32 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-flash.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-flash.rst
|
|
@@ -98,7 +98,7 @@ Flash Control IDs
|
|
V4L2_CID_FLASH_STROBE control.
|
|
* - ``V4L2_FLASH_STROBE_SOURCE_EXTERNAL``
|
|
- The flash strobe is triggered by an external source. Typically
|
|
- this is a sensor, which makes it possible to synchronises the
|
|
+ this is a sensor, which makes it possible to synchronise the
|
|
flash strobe start to exposure start.
|
|
|
|
|
|
|
|
From e81808e9763ce9a47d472cfbe055ea2fd8724c22 Mon Sep 17 00:00:00 2001
|
|
From: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Date: Thu, 5 Sep 2019 07:25:54 -0300
|
|
Subject: [PATCH] media: hantro: streamline open, reuse error path
|
|
|
|
This adds a label to the error path to avoid calling
|
|
v4l2_m2m_ctx_init() and kfree(ctx) in two places each.
|
|
|
|
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3f5e1e2f6e3dac77d882dfbdc84972e782d9735d)
|
|
---
|
|
drivers/staging/media/hantro/hantro_drv.c | 13 ++++++-------
|
|
1 file changed, 6 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
|
|
index 6d9d41170832..23569299977b 100644
|
|
--- a/drivers/staging/media/hantro/hantro_drv.c
|
|
+++ b/drivers/staging/media/hantro/hantro_drv.c
|
|
@@ -413,20 +413,18 @@ static int hantro_open(struct file *filp)
|
|
if (func->id == MEDIA_ENT_F_PROC_VIDEO_ENCODER) {
|
|
allowed_codecs = vpu->variant->codec & HANTRO_ENCODERS;
|
|
ctx->buf_finish = hantro_enc_buf_finish;
|
|
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
|
|
- queue_init);
|
|
} else if (func->id == MEDIA_ENT_F_PROC_VIDEO_DECODER) {
|
|
allowed_codecs = vpu->variant->codec & HANTRO_DECODERS;
|
|
ctx->buf_finish = hantro_dec_buf_finish;
|
|
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx,
|
|
- queue_init);
|
|
} else {
|
|
- ctx->fh.m2m_ctx = ERR_PTR(-ENODEV);
|
|
+ ret = -ENODEV;
|
|
+ goto err_ctx_free;
|
|
}
|
|
+
|
|
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx, queue_init);
|
|
if (IS_ERR(ctx->fh.m2m_ctx)) {
|
|
ret = PTR_ERR(ctx->fh.m2m_ctx);
|
|
- kfree(ctx);
|
|
- return ret;
|
|
+ goto err_ctx_free;
|
|
}
|
|
|
|
v4l2_fh_init(&ctx->fh, vdev);
|
|
@@ -447,6 +445,7 @@ static int hantro_open(struct file *filp)
|
|
err_fh_free:
|
|
v4l2_fh_del(&ctx->fh);
|
|
v4l2_fh_exit(&ctx->fh);
|
|
+err_ctx_free:
|
|
kfree(ctx);
|
|
return ret;
|
|
}
|
|
|
|
From a999caad069269f17ff8858a25eaf1f396c901c9 Mon Sep 17 00:00:00 2001
|
|
From: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Date: Thu, 5 Sep 2019 10:12:54 -0300
|
|
Subject: [PATCH] media: uapi: h264: clarify dec_ref_pic_marking_bit_size
|
|
fields
|
|
|
|
Since dec_ref_pic_marking_bit_size is not a syntax element
|
|
itself, explicitly state that this is the size in bits of
|
|
the dec_ref_pic_marking() syntax element contained in the
|
|
slice.
|
|
|
|
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3ff8b2c646095c621a456327bd4d7036b7cb55fa)
|
|
---
|
|
Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
index bc5dd8e76567..de5990038bb2 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
@@ -1796,7 +1796,7 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
|
-
|
|
* - __u32
|
|
- ``dec_ref_pic_marking_bit_size``
|
|
- -
|
|
+ - Size in bits of the dec_ref_pic_marking() syntax element.
|
|
* - __u32
|
|
- ``pic_order_cnt_bit_size``
|
|
-
|
|
|
|
From 4b6fd09782bd268b20177a5e476af1946e059aed Mon Sep 17 00:00:00 2001
|
|
From: Kefeng Wang <wangkefeng.wang@huawei.com>
|
|
Date: Sun, 8 Sep 2019 01:12:54 -0300
|
|
Subject: [PATCH] media: vim2m: Fix BUG_ON in vim2m_device_release()
|
|
|
|
If v4l2_m2m_init() fails, m2m_dev pointer will be set ERR_PTR(-ENOMEM),
|
|
then kfree m2m_dev will trigger BUG_ON, see below, fix it by setting m2m_dev
|
|
to NULL.
|
|
|
|
vim2m vim2m.0: Failed to init mem2mem device
|
|
------------[ cut here ]------------
|
|
kernel BUG at mm/slub.c:3944!
|
|
invalid opcode: 0000 [#1] SMP PTI
|
|
CPU: 11 PID: 9061 Comm: insmod Tainted: G E 5.2.0-rc2 #81
|
|
Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
|
|
RIP: 0010:kfree+0x11a/0x160
|
|
|
|
Call Trace:
|
|
vim2m_device_release+0x3f/0x50 [vim2m]
|
|
device_release+0x27/0x80
|
|
kobject_release+0x68/0x190
|
|
vim2m_probe+0x20f/0x280 [vim2m]
|
|
platform_drv_probe+0x37/0x90
|
|
really_probe+0xef/0x3d0
|
|
driver_probe_device+0x110/0x120
|
|
device_driver_attach+0x4f/0x60
|
|
__driver_attach+0x9a/0x140
|
|
? device_driver_attach+0x60/0x60
|
|
bus_for_each_dev+0x76/0xc0
|
|
? klist_add_tail+0x57/0x70
|
|
bus_add_driver+0x141/0x210
|
|
driver_register+0x5b/0xe0
|
|
vim2m_init+0x29/0x1000 [vim2m]
|
|
do_one_initcall+0x46/0x1f4
|
|
? __slab_alloc+0x1c/0x30
|
|
? kmem_cache_alloc_trace+0x167/0x1b0
|
|
do_init_module+0x5b/0x21f
|
|
load_module+0x1add/0x1fb0
|
|
? __do_sys_finit_module+0xe9/0x110
|
|
__do_sys_finit_module+0xe9/0x110
|
|
do_syscall_64+0x5b/0x1c0
|
|
entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
|
|
|
Fixes: ea6c7e34f3b2 ("media: vim2m: replace devm_kzalloc by kzalloc")
|
|
Reported-by: Hulk Robot <hulkci@huawei.com>
|
|
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 2455d417c03aa0cbafed04c46cbb354643238318)
|
|
---
|
|
drivers/media/platform/vim2m.c | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
|
|
index acd3bd48c7e2..eb8f398d41f4 100644
|
|
--- a/drivers/media/platform/vim2m.c
|
|
+++ b/drivers/media/platform/vim2m.c
|
|
@@ -1343,6 +1343,7 @@ static int vim2m_probe(struct platform_device *pdev)
|
|
if (IS_ERR(dev->m2m_dev)) {
|
|
v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
|
|
ret = PTR_ERR(dev->m2m_dev);
|
|
+ dev->m2m_dev = NULL;
|
|
goto error_dev;
|
|
}
|
|
|
|
|
|
From ff9b57fbae4052b5128f96ccf4cfea3ad839c300 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Mon, 9 Sep 2019 04:16:27 -0300
|
|
Subject: [PATCH] media: v4l2-dv-timings.c: fix format string
|
|
|
|
It should be "%u.%02u" instead of "%u.%u".
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reported-by: Bard Winther <bwinther@cisco.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 1adbb8276f216df6b06e2989ebf9eb3427b01030)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dv-timings.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
index 4f23e939ead0..0607a5d0d051 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
@@ -293,7 +293,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
|
|
if (prefix == NULL)
|
|
prefix = "";
|
|
|
|
- pr_info("%s: %s%ux%u%s%u.%u (%ux%u)\n", dev_prefix, prefix,
|
|
+ pr_info("%s: %s%ux%u%s%u.%02u (%ux%u)\n", dev_prefix, prefix,
|
|
bt->width, bt->height, bt->interlaced ? "i" : "p",
|
|
fps / 100, fps % 100, htot, vtot);
|
|
|
|
|
|
From e68ab52ad1839e1b4749703f05106a99de1daf44 Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Mon, 9 Sep 2019 06:43:31 -0300
|
|
Subject: [PATCH] media: vivid: Set vid_cap_streaming and vid_out_streaming to
|
|
true
|
|
|
|
When vbi stream is started, followed by video streaming,
|
|
the vid_cap_streaming and vid_out_streaming were not being set to true,
|
|
which would cause the video stream to stop when vbi stream is stopped.
|
|
This patch allows to set vid_cap_streaming and vid_out_streaming to true.
|
|
According to Hans Verkuil it appears that these 'if (dev->kthread_vid_cap)'
|
|
checks are a left-over from the original vivid development and should never
|
|
have been there.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Cc: <stable@vger.kernel.org> # for v3.18 and up
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit b4add02d2236fd5f568db141cfd8eb4290972eb3)
|
|
---
|
|
drivers/media/platform/vivid/vivid-vid-cap.c | 3 ---
|
|
drivers/media/platform/vivid/vivid-vid-out.c | 3 ---
|
|
2 files changed, 6 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
index 8cbaa0c998ed..2d030732feac 100644
|
|
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
@@ -223,9 +223,6 @@ static int vid_cap_start_streaming(struct vb2_queue *vq, unsigned count)
|
|
if (vb2_is_streaming(&dev->vb_vid_out_q))
|
|
dev->can_loop_video = vivid_vid_can_loop(dev);
|
|
|
|
- if (dev->kthread_vid_cap)
|
|
- return 0;
|
|
-
|
|
dev->vid_cap_seq_count = 0;
|
|
dprintk(dev, 1, "%s\n", __func__);
|
|
for (i = 0; i < VIDEO_MAX_FRAME; i++)
|
|
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
index 148b663a6075..a0364ac497f9 100644
|
|
--- a/drivers/media/platform/vivid/vivid-vid-out.c
|
|
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
@@ -161,9 +161,6 @@ static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count)
|
|
if (vb2_is_streaming(&dev->vb_vid_cap_q))
|
|
dev->can_loop_video = vivid_vid_can_loop(dev);
|
|
|
|
- if (dev->kthread_vid_out)
|
|
- return 0;
|
|
-
|
|
dev->vid_out_seq_count = 0;
|
|
dprintk(dev, 1, "%s\n", __func__);
|
|
if (dev->start_streaming_error) {
|
|
|
|
From b13ac824c228d23a4668ed8411e56e792c4877d1 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Thu, 12 Sep 2019 15:55:55 -0300
|
|
Subject: [PATCH] media: vim2m: Fix abort issue
|
|
|
|
Currently, if start streaming -> stop streaming -> start streaming
|
|
sequence is executed, driver will end job prematurely, if ctx->translen
|
|
is higher than 1, because "aborting" flag is still set from previous
|
|
stop streaming command.
|
|
|
|
Fix that by clearing "aborting" flag in start streaming handler.
|
|
|
|
Fixes: 96d8eab5d0a1 ("V4L/DVB: [v5,2/2] v4l: Add a mem-to-mem videobuf framework test device")
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit c362f77a243bfd1daec21b6c36491c061ee2f31b)
|
|
---
|
|
drivers/media/platform/vim2m.c | 3 +++
|
|
1 file changed, 3 insertions(+)
|
|
|
|
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
|
|
index eb8f398d41f4..e17792f837f8 100644
|
|
--- a/drivers/media/platform/vim2m.c
|
|
+++ b/drivers/media/platform/vim2m.c
|
|
@@ -1073,6 +1073,9 @@ static int vim2m_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
if (!q_data)
|
|
return -EINVAL;
|
|
|
|
+ if (V4L2_TYPE_IS_OUTPUT(q->type))
|
|
+ ctx->aborting = 0;
|
|
+
|
|
q_data->sequence = 0;
|
|
return 0;
|
|
}
|
|
|
|
From a263fce916fc52e3e6123d333fb339a876eccbd7 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Wed, 25 Sep 2019 11:09:37 -0300
|
|
Subject: [PATCH] media: vidioc-g-fbuf.rst: remove duplicate 'struct'
|
|
|
|
"struct struct" -> "struct"
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 5adff604a51ef13edd00656f26a9ba66865b42af)
|
|
---
|
|
Documentation/media/uapi/v4l/vidioc-g-fbuf.rst | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst
|
|
index 7b6179627803..2d197e6bba8f 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst
|
|
@@ -63,7 +63,7 @@ EINVAL error code when overlays are not supported.
|
|
|
|
To set the parameters for a *Video Output Overlay*, applications must
|
|
initialize the ``flags`` field of a struct
|
|
-struct :c:type:`v4l2_framebuffer`. Since the framebuffer is
|
|
+:c:type:`v4l2_framebuffer`. Since the framebuffer is
|
|
implemented on the TV card all other parameters are determined by the
|
|
driver. When an application calls :ref:`VIDIOC_S_FBUF <VIDIOC_G_FBUF>` with a pointer to
|
|
this structure, the driver prepares for the overlay and returns the
|
|
|
|
From 1194a6fa89c50e4da9156cc1b9ad847442a1d8d0 Mon Sep 17 00:00:00 2001
|
|
From: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Date: Tue, 3 Sep 2019 15:17:08 -0300
|
|
Subject: [PATCH] media: hantro: Simplify macroblock macros
|
|
|
|
It seems all codecs are using a 16x16 size macroblock,
|
|
and so it's possible to have just one set of macroblock macros.
|
|
|
|
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 05e58c83d6311f95677038cf816062234630727e)
|
|
---
|
|
drivers/staging/media/hantro/hantro.h | 18 +++---------------
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 2 +-
|
|
drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c | 4 ++--
|
|
drivers/staging/media/hantro/hantro_g1_vp8_dec.c | 4 ++--
|
|
drivers/staging/media/hantro/hantro_h1_jpeg_enc.c | 4 ++--
|
|
drivers/staging/media/hantro/rk3288_vpu_hw.c | 16 ++++++++--------
|
|
drivers/staging/media/hantro/rk3399_vpu_hw.c | 12 ++++++------
|
|
drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c | 4 ++--
|
|
drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 4 ++--
|
|
drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c | 4 ++--
|
|
10 files changed, 30 insertions(+), 42 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
|
|
index f670bbde4159..c151133b8c86 100644
|
|
--- a/drivers/staging/media/hantro/hantro.h
|
|
+++ b/drivers/staging/media/hantro/hantro.h
|
|
@@ -26,21 +26,9 @@
|
|
|
|
#include "hantro_hw.h"
|
|
|
|
-#define VP8_MB_DIM 16
|
|
-#define VP8_MB_WIDTH(w) DIV_ROUND_UP(w, VP8_MB_DIM)
|
|
-#define VP8_MB_HEIGHT(h) DIV_ROUND_UP(h, VP8_MB_DIM)
|
|
-
|
|
-#define H264_MB_DIM 16
|
|
-#define H264_MB_WIDTH(w) DIV_ROUND_UP(w, H264_MB_DIM)
|
|
-#define H264_MB_HEIGHT(h) DIV_ROUND_UP(h, H264_MB_DIM)
|
|
-
|
|
-#define MPEG2_MB_DIM 16
|
|
-#define MPEG2_MB_WIDTH(w) DIV_ROUND_UP(w, MPEG2_MB_DIM)
|
|
-#define MPEG2_MB_HEIGHT(h) DIV_ROUND_UP(h, MPEG2_MB_DIM)
|
|
-
|
|
-#define JPEG_MB_DIM 16
|
|
-#define JPEG_MB_WIDTH(w) DIV_ROUND_UP(w, JPEG_MB_DIM)
|
|
-#define JPEG_MB_HEIGHT(h) DIV_ROUND_UP(h, JPEG_MB_DIM)
|
|
+#define MB_DIM 16
|
|
+#define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM)
|
|
+#define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM)
|
|
|
|
struct hantro_ctx;
|
|
struct hantro_codec_ops;
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index 7ab534936843..d42c4004fe35 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -251,7 +251,7 @@ static void set_buffers(struct hantro_ctx *ctx)
|
|
size_t mv_offset = round_up(pic_size, 8);
|
|
|
|
if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
|
|
- mv_offset += 32 * H264_MB_WIDTH(ctx->dst_fmt.width);
|
|
+ mv_offset += 32 * MB_WIDTH(ctx->dst_fmt.width);
|
|
|
|
vdpu_write_relaxed(vpu, dst_dma + mv_offset,
|
|
G1_REG_ADDR_DIR_MV);
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
index 80f0e94f8afa..314a72208812 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
@@ -207,8 +207,8 @@ void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx)
|
|
G1_REG_DEC_AXI_WR_ID(0);
|
|
vdpu_write_relaxed(vpu, reg, G1_SWREG(3));
|
|
|
|
- reg = G1_REG_PIC_MB_WIDTH(MPEG2_MB_WIDTH(ctx->dst_fmt.width)) |
|
|
- G1_REG_PIC_MB_HEIGHT_P(MPEG2_MB_HEIGHT(ctx->dst_fmt.height)) |
|
|
+ reg = G1_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
|
|
+ G1_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
|
|
G1_REG_ALT_SCAN_E(picture->alternate_scan) |
|
|
G1_REG_TOPFIELDFIRST_E(picture->top_field_first);
|
|
vdpu_write_relaxed(vpu, reg, G1_SWREG(4));
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
index 6d99c2be01cf..e9d3361ed385 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
@@ -470,8 +470,8 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx)
|
|
vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0);
|
|
|
|
/* Frame dimensions */
|
|
- mb_width = VP8_MB_WIDTH(width);
|
|
- mb_height = VP8_MB_HEIGHT(height);
|
|
+ mb_width = MB_WIDTH(width);
|
|
+ mb_height = MB_HEIGHT(height);
|
|
reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(mb_width) |
|
|
G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(mb_height) |
|
|
G1_REG_DEC_CTRL1_PIC_MB_W_EXT(mb_width >> 9) |
|
|
diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
|
|
index ecd34a7db190..938b48d4d3d9 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
|
|
@@ -116,8 +116,8 @@ void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx)
|
|
/* Make sure that all registers are written at this point. */
|
|
vepu_write(vpu, reg, H1_REG_AXI_CTRL);
|
|
|
|
- reg = H1_REG_ENC_CTRL_WIDTH(JPEG_MB_WIDTH(ctx->src_fmt.width))
|
|
- | H1_REG_ENC_CTRL_HEIGHT(JPEG_MB_HEIGHT(ctx->src_fmt.height))
|
|
+ reg = H1_REG_ENC_CTRL_WIDTH(MB_WIDTH(ctx->src_fmt.width))
|
|
+ | H1_REG_ENC_CTRL_HEIGHT(MB_HEIGHT(ctx->src_fmt.height))
|
|
| H1_REG_ENC_CTRL_ENC_MODE_JPEG
|
|
| H1_REG_ENC_PIC_INTRA
|
|
| H1_REG_ENC_CTRL_EN_BIT;
|
|
diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
index 6bfcc47d1e58..c0bdd6c02520 100644
|
|
--- a/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
+++ b/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
@@ -48,10 +48,10 @@ static const struct hantro_fmt rk3288_vpu_enc_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 96,
|
|
.max_width = 8192,
|
|
- .step_width = JPEG_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 32,
|
|
.max_height = 8192,
|
|
- .step_height = JPEG_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
};
|
|
@@ -68,10 +68,10 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
.max_width = 3840,
|
|
- .step_width = H264_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 48,
|
|
.max_height = 2160,
|
|
- .step_height = H264_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
{
|
|
@@ -81,10 +81,10 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
.max_width = 1920,
|
|
- .step_width = MPEG2_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 48,
|
|
.max_height = 1088,
|
|
- .step_height = MPEG2_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
{
|
|
@@ -94,10 +94,10 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
.max_width = 3840,
|
|
- .step_width = VP8_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 48,
|
|
.max_height = 2160,
|
|
- .step_height = VP8_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
};
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c
|
|
index 14d14bc6b12b..9ac1f2cb6a16 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw.c
|
|
@@ -47,10 +47,10 @@ static const struct hantro_fmt rk3399_vpu_enc_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 96,
|
|
.max_width = 8192,
|
|
- .step_width = JPEG_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 32,
|
|
.max_height = 8192,
|
|
- .step_height = JPEG_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
};
|
|
@@ -67,10 +67,10 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
.max_width = 1920,
|
|
- .step_width = MPEG2_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 48,
|
|
.max_height = 1088,
|
|
- .step_height = MPEG2_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
{
|
|
@@ -80,10 +80,10 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = {
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
.max_width = 3840,
|
|
- .step_width = VP8_MB_DIM,
|
|
+ .step_width = MB_DIM,
|
|
.min_height = 48,
|
|
.max_height = 2160,
|
|
- .step_height = VP8_MB_DIM,
|
|
+ .step_height = MB_DIM,
|
|
},
|
|
},
|
|
};
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
|
|
index 06162f569b5e..067892345b5d 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
|
|
@@ -149,8 +149,8 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx)
|
|
reg = VEPU_REG_AXI_CTRL_BURST_LEN(16);
|
|
vepu_write_relaxed(vpu, reg, VEPU_REG_AXI_CTRL);
|
|
|
|
- reg = VEPU_REG_MB_WIDTH(JPEG_MB_WIDTH(ctx->src_fmt.width))
|
|
- | VEPU_REG_MB_HEIGHT(JPEG_MB_HEIGHT(ctx->src_fmt.height))
|
|
+ reg = VEPU_REG_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width))
|
|
+ | VEPU_REG_MB_HEIGHT(MB_HEIGHT(ctx->src_fmt.height))
|
|
| VEPU_REG_FRAME_TYPE_INTRA
|
|
| VEPU_REG_ENCODE_FORMAT_JPEG
|
|
| VEPU_REG_ENCODE_ENABLE;
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
index e7ba5c0441cc..263ec81f209b 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
@@ -223,8 +223,8 @@ void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx)
|
|
VDPU_REG_DEC_CLK_GATE_E(1);
|
|
vdpu_write_relaxed(vpu, reg, VDPU_SWREG(57));
|
|
|
|
- reg = VDPU_REG_PIC_MB_WIDTH(MPEG2_MB_WIDTH(ctx->dst_fmt.width)) |
|
|
- VDPU_REG_PIC_MB_HEIGHT_P(MPEG2_MB_HEIGHT(ctx->dst_fmt.height)) |
|
|
+ reg = VDPU_REG_PIC_MB_WIDTH(MB_WIDTH(ctx->dst_fmt.width)) |
|
|
+ VDPU_REG_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->dst_fmt.height)) |
|
|
VDPU_REG_ALT_SCAN_E(picture->alternate_scan) |
|
|
VDPU_REG_TOPFIELDFIRST_E(picture->top_field_first);
|
|
vdpu_write_relaxed(vpu, reg, VDPU_SWREG(120));
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
index f17e32620b08..7d32a0283d93 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
@@ -563,8 +563,8 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx)
|
|
hantro_reg_write(vpu, &vp8_dec_filter_disable, 1);
|
|
|
|
/* Frame dimensions */
|
|
- mb_width = VP8_MB_WIDTH(width);
|
|
- mb_height = VP8_MB_HEIGHT(height);
|
|
+ mb_width = MB_WIDTH(width);
|
|
+ mb_height = MB_HEIGHT(height);
|
|
|
|
hantro_reg_write(vpu, &vp8_dec_mb_width, mb_width);
|
|
hantro_reg_write(vpu, &vp8_dec_mb_height, mb_height);
|
|
|
|
From 140922fb85818273b7124ce726c9b432467dd4b6 Mon Sep 17 00:00:00 2001
|
|
From: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Date: Tue, 3 Sep 2019 15:17:09 -0300
|
|
Subject: [PATCH] media: hantro: Simplify buffer helpers
|
|
|
|
Modify hantro_get_ref() and hantro_h264_get_ref_buf() helpers
|
|
to return the buffer DMA address, this makes the code simpler
|
|
and at the same time will allow easier enablement of the
|
|
post-processing feature.
|
|
|
|
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit f71193af439304f7b6e140c00270075c83d4716a)
|
|
---
|
|
drivers/staging/media/hantro/hantro.h | 2 +-
|
|
drivers/staging/media/hantro/hantro_drv.c | 3 ++-
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 5 ++---
|
|
drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c | 7 ++-----
|
|
drivers/staging/media/hantro/hantro_g1_vp8_dec.c | 7 +++----
|
|
drivers/staging/media/hantro/hantro_h264.c | 19 ++++++++-----------
|
|
drivers/staging/media/hantro/hantro_hw.h | 4 ++--
|
|
.../staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c | 7 ++-----
|
|
drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c | 8 +++-----
|
|
9 files changed, 25 insertions(+), 37 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
|
|
index c151133b8c86..deb90ae37859 100644
|
|
--- a/drivers/staging/media/hantro/hantro.h
|
|
+++ b/drivers/staging/media/hantro/hantro.h
|
|
@@ -367,7 +367,7 @@ static inline void hantro_reg_write(struct hantro_dev *vpu,
|
|
bool hantro_is_encoder_ctx(const struct hantro_ctx *ctx);
|
|
|
|
void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id);
|
|
-dma_addr_t hantro_get_ref(struct vb2_queue *q, u64 ts);
|
|
+dma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts);
|
|
|
|
static inline struct vb2_v4l2_buffer *
|
|
hantro_get_src_buf(struct hantro_ctx *ctx)
|
|
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
|
|
index 23569299977b..26108c96b674 100644
|
|
--- a/drivers/staging/media/hantro/hantro_drv.c
|
|
+++ b/drivers/staging/media/hantro/hantro_drv.c
|
|
@@ -43,8 +43,9 @@ void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id)
|
|
return ctrl ? ctrl->p_cur.p : NULL;
|
|
}
|
|
|
|
-dma_addr_t hantro_get_ref(struct vb2_queue *q, u64 ts)
|
|
+dma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts)
|
|
{
|
|
+ struct vb2_queue *q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
|
|
struct vb2_buffer *buf;
|
|
int index;
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index d42c4004fe35..29130946dea4 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -220,10 +220,9 @@ static void set_ref(struct hantro_ctx *ctx)
|
|
|
|
/* Set up addresses of DPB buffers. */
|
|
for (i = 0; i < HANTRO_H264_DPB_SIZE; i++) {
|
|
- struct vb2_buffer *buf = hantro_h264_get_ref_buf(ctx, i);
|
|
+ dma_addr_t dma_addr = hantro_h264_get_ref_buf(ctx, i);
|
|
|
|
- vdpu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr(buf, 0),
|
|
- G1_REG_ADDR_REF(i));
|
|
+ vdpu_write_relaxed(vpu, dma_addr, G1_REG_ADDR_REF(i));
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
index 314a72208812..f3bf67d8a289 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
|
|
@@ -105,17 +105,14 @@ hantro_g1_mpeg2_dec_set_buffers(struct hantro_dev *vpu, struct hantro_ctx *ctx,
|
|
{
|
|
dma_addr_t forward_addr = 0, backward_addr = 0;
|
|
dma_addr_t current_addr, addr;
|
|
- struct vb2_queue *vq;
|
|
-
|
|
- vq = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
|
|
|
|
switch (picture->picture_coding_type) {
|
|
case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
|
|
- backward_addr = hantro_get_ref(vq,
|
|
+ backward_addr = hantro_get_ref(ctx,
|
|
slice_params->backward_ref_ts);
|
|
/* fall-through */
|
|
case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
|
|
- forward_addr = hantro_get_ref(vq,
|
|
+ forward_addr = hantro_get_ref(ctx,
|
|
slice_params->forward_ref_ts);
|
|
}
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
index e9d3361ed385..cad18094fee0 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
|
|
@@ -370,19 +370,18 @@ static void cfg_tap(struct hantro_ctx *ctx,
|
|
static void cfg_ref(struct hantro_ctx *ctx,
|
|
const struct v4l2_ctrl_vp8_frame_header *hdr)
|
|
{
|
|
- struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
struct hantro_dev *vpu = ctx->dev;
|
|
struct vb2_v4l2_buffer *vb2_dst;
|
|
dma_addr_t ref;
|
|
|
|
vb2_dst = hantro_get_dst_buf(ctx);
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->last_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->last_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(0));
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->golden_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->golden_frame_ts);
|
|
WARN_ON(!ref && hdr->golden_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
@@ -390,7 +389,7 @@ static void cfg_ref(struct hantro_ctx *ctx,
|
|
ref |= G1_REG_ADDR_REF_TOPC_E;
|
|
vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(4));
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->alt_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->alt_frame_ts);
|
|
WARN_ON(!ref && hdr->alt_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 0d758e0c0f99..2227b4e12067 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -537,22 +537,18 @@ static void update_dpb(struct hantro_ctx *ctx)
|
|
}
|
|
}
|
|
|
|
-struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
|
- unsigned int dpb_idx)
|
|
+dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
|
+ unsigned int dpb_idx)
|
|
{
|
|
- struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
|
|
- struct vb2_buffer *buf;
|
|
- int buf_idx = -1;
|
|
+ dma_addr_t dma_addr = 0;
|
|
|
|
if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
|
- buf_idx = vb2_find_timestamp(cap_q,
|
|
- dpb[dpb_idx].reference_ts, 0);
|
|
+ dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts);
|
|
|
|
- if (buf_idx >= 0) {
|
|
- buf = vb2_get_buffer(cap_q, buf_idx);
|
|
- } else {
|
|
+ if (!dma_addr) {
|
|
struct vb2_v4l2_buffer *dst_buf;
|
|
+ struct vb2_buffer *buf;
|
|
|
|
/*
|
|
* If a DPB entry is unused or invalid, address of current
|
|
@@ -560,9 +556,10 @@ struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
|
*/
|
|
dst_buf = hantro_get_dst_buf(ctx);
|
|
buf = &dst_buf->vb2_buf;
|
|
+ dma_addr = vb2_dma_contig_plane_dma_addr(buf, 0);
|
|
}
|
|
|
|
- return buf;
|
|
+ return dma_addr;
|
|
}
|
|
|
|
int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx)
|
|
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
|
|
index 2fab655bf098..69b88f4d3fb3 100644
|
|
--- a/drivers/staging/media/hantro/hantro_hw.h
|
|
+++ b/drivers/staging/media/hantro/hantro_hw.h
|
|
@@ -158,8 +158,8 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx);
|
|
int hantro_jpeg_enc_init(struct hantro_ctx *ctx);
|
|
void hantro_jpeg_enc_exit(struct hantro_ctx *ctx);
|
|
|
|
-struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
|
- unsigned int dpb_idx);
|
|
+dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
|
|
+ unsigned int dpb_idx);
|
|
int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx);
|
|
void hantro_g1_h264_dec_run(struct hantro_ctx *ctx);
|
|
int hantro_h264_dec_init(struct hantro_ctx *ctx);
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
index 263ec81f209b..b40d2cdf832f 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
|
|
@@ -107,17 +107,14 @@ rk3399_vpu_mpeg2_dec_set_buffers(struct hantro_dev *vpu,
|
|
{
|
|
dma_addr_t forward_addr = 0, backward_addr = 0;
|
|
dma_addr_t current_addr, addr;
|
|
- struct vb2_queue *vq;
|
|
-
|
|
- vq = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx);
|
|
|
|
switch (picture->picture_coding_type) {
|
|
case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
|
|
- backward_addr = hantro_get_ref(vq,
|
|
+ backward_addr = hantro_get_ref(ctx,
|
|
slice_params->backward_ref_ts);
|
|
/* fall-through */
|
|
case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
|
|
- forward_addr = hantro_get_ref(vq,
|
|
+ forward_addr = hantro_get_ref(ctx,
|
|
slice_params->forward_ref_ts);
|
|
}
|
|
|
|
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
index 7d32a0283d93..76d7ed3fd69a 100644
|
|
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
|
|
@@ -449,18 +449,16 @@ static void cfg_ref(struct hantro_ctx *ctx,
|
|
{
|
|
struct hantro_dev *vpu = ctx->dev;
|
|
struct vb2_v4l2_buffer *vb2_dst;
|
|
- struct vb2_queue *cap_q;
|
|
dma_addr_t ref;
|
|
|
|
- cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
vb2_dst = hantro_get_dst_buf(ctx);
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->last_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->last_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF0);
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->golden_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->golden_frame_ts);
|
|
WARN_ON(!ref && hdr->golden_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
@@ -468,7 +466,7 @@ static void cfg_ref(struct hantro_ctx *ctx,
|
|
ref |= VDPU_REG_VP8_GREF_SIGN_BIAS;
|
|
vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(2));
|
|
|
|
- ref = hantro_get_ref(cap_q, hdr->alt_frame_ts);
|
|
+ ref = hantro_get_ref(ctx, hdr->alt_frame_ts);
|
|
WARN_ON(!ref && hdr->alt_frame_ts);
|
|
if (!ref)
|
|
ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
|
|
|
|
From 8a8badb64db8b2cb7cb020b0770675ce8ecd1be2 Mon Sep 17 00:00:00 2001
|
|
From: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Date: Mon, 9 Sep 2019 04:28:13 -0300
|
|
Subject: [PATCH] media: hantro: h264: Fix a comment in b1_ref_list_cmp()
|
|
|
|
So it matches the code and the spec.
|
|
|
|
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Tested-by: Francois Buergisser <fbuergisser@chromium.org>
|
|
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3e5ba2ac850806efe01e7b2b5451d10468a7dcd1)
|
|
---
|
|
drivers/staging/media/hantro/hantro_h264.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 2227b4e12067..648c8a81efa8 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -429,7 +429,7 @@ static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
|
|
/*
|
|
* Short term pics with POC > cur POC first in POC ascending order
|
|
- * followed by short term pics with POC > cur POC in POC descending
|
|
+ * followed by short term pics with POC < cur POC in POC descending
|
|
* order.
|
|
*/
|
|
if ((poca < builder->curpoc) != (pocb < builder->curpoc))
|
|
|
|
From ec3cb458cca67805bf3debd5bda350c0404010bc Mon Sep 17 00:00:00 2001
|
|
From: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Date: Mon, 9 Sep 2019 04:28:14 -0300
|
|
Subject: [PATCH] media: hantro: h264: Rename POC_CMP() into HANTRO_CMP()
|
|
|
|
And use it for all native type comparisons, even if it's not strictly
|
|
required. By doing that we make the code more consistent and prevent
|
|
from potential incorrect results in case of overflow or when the the
|
|
values being compared are both negative.
|
|
|
|
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Tested-by: Francois Buergisser <fbuergisser@chromium.org>
|
|
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit e00cc83ecc3dc4ac9bd9db4f2d6f927d6f43bfd0)
|
|
---
|
|
drivers/staging/media/hantro/hantro_h264.c | 22 +++++++++++-----------
|
|
1 file changed, 11 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 648c8a81efa8..4557f148583a 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -22,7 +22,7 @@
|
|
#define POC_BUFFER_SIZE 34
|
|
#define SCALING_LIST_SIZE (6 * 16 + 6 * 64)
|
|
|
|
-#define POC_CMP(p0, p1) ((p0) < (p1) ? -1 : 1)
|
|
+#define HANTRO_CMP(a, b) ((a) < (b) ? -1 : 1)
|
|
|
|
/* Data structure describing auxiliary buffer format. */
|
|
struct hantro_h264_dec_priv_tbl {
|
|
@@ -353,9 +353,9 @@ static int p_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
* ascending order.
|
|
*/
|
|
if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
|
|
- return b->frame_num - a->frame_num;
|
|
+ return HANTRO_CMP(b->frame_num, a->frame_num);
|
|
|
|
- return a->pic_num - b->pic_num;
|
|
+ return HANTRO_CMP(a->pic_num, b->pic_num);
|
|
}
|
|
|
|
static int b0_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
@@ -381,7 +381,7 @@ static int b0_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
|
|
/* Long term pics in ascending pic num order. */
|
|
if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
|
- return a->pic_num - b->pic_num;
|
|
+ return HANTRO_CMP(a->pic_num, b->pic_num);
|
|
|
|
poca = builder->pocs[idxa];
|
|
pocb = builder->pocs[idxb];
|
|
@@ -392,11 +392,11 @@ static int b0_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
* order.
|
|
*/
|
|
if ((poca < builder->curpoc) != (pocb < builder->curpoc))
|
|
- return POC_CMP(poca, pocb);
|
|
+ return HANTRO_CMP(poca, pocb);
|
|
else if (poca < builder->curpoc)
|
|
- return POC_CMP(pocb, poca);
|
|
+ return HANTRO_CMP(pocb, poca);
|
|
|
|
- return POC_CMP(poca, pocb);
|
|
+ return HANTRO_CMP(poca, pocb);
|
|
}
|
|
|
|
static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
@@ -422,7 +422,7 @@ static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
|
|
/* Long term pics in ascending pic num order. */
|
|
if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
|
|
- return a->pic_num - b->pic_num;
|
|
+ return HANTRO_CMP(a->pic_num, b->pic_num);
|
|
|
|
poca = builder->pocs[idxa];
|
|
pocb = builder->pocs[idxb];
|
|
@@ -433,11 +433,11 @@ static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
* order.
|
|
*/
|
|
if ((poca < builder->curpoc) != (pocb < builder->curpoc))
|
|
- return POC_CMP(pocb, poca);
|
|
+ return HANTRO_CMP(pocb, poca);
|
|
else if (poca < builder->curpoc)
|
|
- return POC_CMP(pocb, poca);
|
|
+ return HANTRO_CMP(pocb, poca);
|
|
|
|
- return POC_CMP(poca, pocb);
|
|
+ return HANTRO_CMP(poca, pocb);
|
|
}
|
|
|
|
static void
|
|
|
|
From e4fa0d7dbda0552cdf9a2d4336fda5bdbab3a3d9 Mon Sep 17 00:00:00 2001
|
|
From: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Date: Mon, 9 Sep 2019 04:28:15 -0300
|
|
Subject: [PATCH] media: hantro: h264: Fix the frame_num wraparound case
|
|
|
|
Step '8.2.4.1 Decoding process for picture numbers' was missing in the
|
|
reflist creation logic, leading to invalid P reflists when a
|
|
->frame_num wraparound happens.
|
|
|
|
Fixes: a9471e25629b ("media: hantro: Add core bits to support H264 decoding")
|
|
Reported-by: Francois Buergisser <fbuergisser@google.com>
|
|
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Tested-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Tested-by: Francois Buergisser <fbuergisser@chromium.org>
|
|
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 9db5f87f6723678a7e7e5e3165439c5c4378edbb)
|
|
---
|
|
drivers/staging/media/hantro/hantro_h264.c | 23 ++++++++++++++++++++++-
|
|
1 file changed, 22 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 4557f148583a..02cbe7761769 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -271,6 +271,7 @@ struct hantro_h264_reflist_builder {
|
|
const struct v4l2_h264_dpb_entry *dpb;
|
|
s32 pocs[HANTRO_H264_DPB_SIZE];
|
|
u8 unordered_reflist[HANTRO_H264_DPB_SIZE];
|
|
+ int frame_nums[HANTRO_H264_DPB_SIZE];
|
|
s32 curpoc;
|
|
u8 num_valid;
|
|
};
|
|
@@ -294,13 +295,20 @@ static void
|
|
init_reflist_builder(struct hantro_ctx *ctx,
|
|
struct hantro_h264_reflist_builder *b)
|
|
{
|
|
+ const struct v4l2_ctrl_h264_slice_params *slice_params;
|
|
const struct v4l2_ctrl_h264_decode_params *dec_param;
|
|
+ const struct v4l2_ctrl_h264_sps *sps;
|
|
struct vb2_v4l2_buffer *buf = hantro_get_dst_buf(ctx);
|
|
const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
|
|
struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
+ int cur_frame_num, max_frame_num;
|
|
unsigned int i;
|
|
|
|
dec_param = ctx->h264_dec.ctrls.decode;
|
|
+ slice_params = &ctx->h264_dec.ctrls.slices[0];
|
|
+ sps = ctx->h264_dec.ctrls.sps;
|
|
+ max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
|
|
+ cur_frame_num = slice_params->frame_num;
|
|
|
|
memset(b, 0, sizeof(*b));
|
|
b->dpb = dpb;
|
|
@@ -318,6 +326,18 @@ init_reflist_builder(struct hantro_ctx *ctx,
|
|
continue;
|
|
|
|
buf = to_vb2_v4l2_buffer(vb2_get_buffer(cap_q, buf_idx));
|
|
+
|
|
+ /*
|
|
+ * Handle frame_num wraparound as described in section
|
|
+ * '8.2.4.1 Decoding process for picture numbers' of the spec.
|
|
+ * TODO: This logic will have to be adjusted when we start
|
|
+ * supporting interlaced content.
|
|
+ */
|
|
+ if (dpb[i].frame_num > cur_frame_num)
|
|
+ b->frame_nums[i] = (int)dpb[i].frame_num - max_frame_num;
|
|
+ else
|
|
+ b->frame_nums[i] = dpb[i].frame_num;
|
|
+
|
|
b->pocs[i] = get_poc(buf->field, dpb[i].top_field_order_cnt,
|
|
dpb[i].bottom_field_order_cnt);
|
|
b->unordered_reflist[b->num_valid] = i;
|
|
@@ -353,7 +373,8 @@ static int p_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
|
|
* ascending order.
|
|
*/
|
|
if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
|
|
- return HANTRO_CMP(b->frame_num, a->frame_num);
|
|
+ return HANTRO_CMP(builder->frame_nums[idxb],
|
|
+ builder->frame_nums[idxa]);
|
|
|
|
return HANTRO_CMP(a->pic_num, b->pic_num);
|
|
}
|
|
|
|
From 89451e5248ae441638f9aa115f4d772bbb64f36b Mon Sep 17 00:00:00 2001
|
|
From: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Date: Tue, 10 Sep 2019 07:20:30 -0300
|
|
Subject: [PATCH] media: uapi: h264: clarify V4L2_PIX_FMT_H264_SLICE format
|
|
|
|
Document that the slice headers must be included for the benefit of
|
|
decoders that parse them (partially) in hardware, and that the start
|
|
code is optional. Add a link to the ITU-T Rec. H.264 specification
|
|
section that describes the slice format.
|
|
|
|
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 8255b4d21967e978f96a87cf032471f527149794)
|
|
---
|
|
Documentation/media/uapi/v4l/pixfmt-compressed.rst | 12 ++++++++----
|
|
1 file changed, 8 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
index 292fdc116c77..55d8d690f22f 100644
|
|
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
@@ -61,10 +61,10 @@ Compressed Formats
|
|
|
|
- ``V4L2_PIX_FMT_H264_SLICE``
|
|
- 'S264'
|
|
- - H264 parsed slice data, without the start code and as
|
|
- extracted from the H264 bitstream. This format is adapted for
|
|
- stateless video decoders that implement an H264 pipeline
|
|
- (using the :ref:`mem2mem` and :ref:`media-request-api`).
|
|
+ - H264 parsed slice data, including slice headers, either with or
|
|
+ without the start code, as extracted from the H264 bitstream.
|
|
+ This format is adapted for stateless video decoders that implement an
|
|
+ H264 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
|
|
This pixelformat has two modifiers that must be set at least once
|
|
through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE``
|
|
and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls.
|
|
@@ -80,6 +80,10 @@ Compressed Formats
|
|
appropriate number of macroblocks to decode a full
|
|
corresponding frame to the matching capture buffer.
|
|
|
|
+ The syntax for this format is documented in :ref:`h264`, section
|
|
+ 7.3.2.8 "Slice layer without partitioning RBSP syntax" and the following
|
|
+ sections.
|
|
+
|
|
.. note::
|
|
|
|
This format is not yet part of the public kernel API and it
|
|
|
|
From 76a12c87556c66fd26f800be0f0ffd62a7a1a3b7 Mon Sep 17 00:00:00 2001
|
|
From: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Date: Tue, 10 Sep 2019 07:22:39 -0300
|
|
Subject: [PATCH] media: uapi: h264: clarify num_ref_idx_l[01]_(default_)active
|
|
fields
|
|
|
|
Since the uapi does not contain the num_ref_idx_active_override_flag,
|
|
drivers for decoders that do not parse slices themselves don't know
|
|
how to choose between the num_ref_idx_l[01]_default_active and the
|
|
num_ref_idx_l[01]_active override fields.
|
|
|
|
Instead, userspace must set the override fields to the default values
|
|
if the slice does not have the num_ref_idx_active_override flag set.
|
|
The drivers will then always enable the override internally and ignore
|
|
the default fields completely.
|
|
|
|
Clarify this requirement in the API documentation.
|
|
|
|
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 187ef7c5c78153acdce8c8714e5918b1018c710b)
|
|
---
|
|
Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
index de5990038bb2..6bb901de0939 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
@@ -1820,10 +1820,12 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
|
-
|
|
* - __u8
|
|
- ``num_ref_idx_l0_active_minus1``
|
|
- -
|
|
+ - If num_ref_idx_active_override_flag is not set, this field must be
|
|
+ set to the value of num_ref_idx_l0_default_active_minus1.
|
|
* - __u8
|
|
- ``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``
|
|
-
|
|
|
|
From 4b795aabfe95a9dfbb2e0ac793f376e346f68995 Mon Sep 17 00:00:00 2001
|
|
From: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Date: Mon, 23 Sep 2019 06:09:46 -0300
|
|
Subject: [PATCH] media: v4l: fwnode: Make v4l2_fwnode_endpoint_free() safer
|
|
|
|
Assign vep->link_frequencies to NULL after releasing its memory. Without
|
|
this change, multiple calls to v4l2_fwnode_endpoint_free() would result in
|
|
double kfree calls.
|
|
|
|
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 355047f411c0516533b8c9c96eb6cea252bc78f0)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-fwnode.c | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
|
|
index 3bd1888787eb..192cac076761 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
|
|
@@ -512,6 +512,7 @@ void v4l2_fwnode_endpoint_free(struct v4l2_fwnode_endpoint *vep)
|
|
return;
|
|
|
|
kfree(vep->link_frequencies);
|
|
+ vep->link_frequencies = NULL;
|
|
}
|
|
EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_free);
|
|
|
|
|
|
From 4405346a8d18c7a94f95621500485b51148d8934 Mon Sep 17 00:00:00 2001
|
|
From: Wei Yongjun <weiyongjun1@huawei.com>
|
|
Date: Tue, 8 Oct 2019 06:01:33 -0300
|
|
Subject: [PATCH] media: vimc: Fix error return code in vimc_register_devices()
|
|
|
|
Fix to return a negative error code from the error handling
|
|
case instead of 0, as done elsewhere in this function.
|
|
|
|
Fixes: f13d5f361959 ("media: vimc: Collapse component structure into a single monolithic driver")
|
|
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 1edfa9b1687ed8aac39a0423345f8a76a1cff58c)
|
|
---
|
|
drivers/media/platform/vimc/vimc-core.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
|
|
index 6e3e5c91ae39..2d20a7c10398 100644
|
|
--- a/drivers/media/platform/vimc/vimc-core.c
|
|
+++ b/drivers/media/platform/vimc/vimc-core.c
|
|
@@ -202,8 +202,10 @@ static int vimc_register_devices(struct vimc_device *vimc)
|
|
vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
|
|
sizeof(*vimc->ent_devs),
|
|
GFP_KERNEL);
|
|
- if (!vimc->ent_devs)
|
|
+ if (!vimc->ent_devs) {
|
|
+ ret = -ENOMEM;
|
|
goto err_v4l2_unregister;
|
|
+ }
|
|
|
|
/* Invoke entity config hooks to initialize and register subdevs */
|
|
ret = vimc_add_subdevs(vimc);
|
|
|
|
From 2d75fbc2053043f736df23bb1c7aa672351817a5 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:29 -0300
|
|
Subject: [PATCH] media: v4l2-core: Implement v4l2_ctrl_new_std_compound
|
|
|
|
Currently compound controls do not have a simple way of initializing its
|
|
values. This results in ofuscated code with type_ops init.
|
|
|
|
This patch introduces a new field on the control with the default value
|
|
for the compound control that can be set with the brand new
|
|
v4l2_ctrl_new_std_compound function
|
|
|
|
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
[hverkuil@xs4all.nl: fix checkpatch warning]
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit b35d6c02aa3ca88f80c8da099ebabfe426fab759)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 50 +++++++++++++++++++++++++++++++-----
|
|
include/media/v4l2-ctrls.h | 22 ++++++++++++++++
|
|
2 files changed, 65 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index 1d8f38824631..219d8aeefa20 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -29,6 +29,8 @@
|
|
#define call_op(master, op) \
|
|
(has_op(master, op) ? master->ops->op(master) : 0)
|
|
|
|
+static const union v4l2_ctrl_ptr ptr_null;
|
|
+
|
|
/* Internal temporary helper struct, one for each v4l2_ext_control */
|
|
struct v4l2_ctrl_helper {
|
|
/* Pointer to the control reference of the master control */
|
|
@@ -1530,7 +1532,10 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
|
struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
|
void *p = ptr.p + idx * ctrl->elem_size;
|
|
|
|
- memset(p, 0, ctrl->elem_size);
|
|
+ if (ctrl->p_def.p)
|
|
+ memcpy(p, ctrl->p_def.p, ctrl->elem_size);
|
|
+ else
|
|
+ memset(p, 0, ctrl->elem_size);
|
|
|
|
/*
|
|
* The cast is needed to get rid of a gcc warning complaining that
|
|
@@ -2354,7 +2359,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
s64 min, s64 max, u64 step, s64 def,
|
|
const u32 dims[V4L2_CTRL_MAX_DIMS], u32 elem_size,
|
|
u32 flags, const char * const *qmenu,
|
|
- const s64 *qmenu_int, void *priv)
|
|
+ const s64 *qmenu_int, const union v4l2_ctrl_ptr p_def,
|
|
+ void *priv)
|
|
{
|
|
struct v4l2_ctrl *ctrl;
|
|
unsigned sz_extra;
|
|
@@ -2460,6 +2466,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
is_array)
|
|
sz_extra += 2 * tot_ctrl_size;
|
|
|
|
+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p)
|
|
+ sz_extra += elem_size;
|
|
+
|
|
ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
|
|
if (ctrl == NULL) {
|
|
handler_set_err(hdl, -ENOMEM);
|
|
@@ -2503,6 +2512,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
ctrl->p_new.p = &ctrl->val;
|
|
ctrl->p_cur.p = &ctrl->cur.val;
|
|
}
|
|
+
|
|
+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p) {
|
|
+ ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
|
|
+ memcpy(ctrl->p_def.p, p_def.p, elem_size);
|
|
+ }
|
|
+
|
|
for (idx = 0; idx < elems; idx++) {
|
|
ctrl->type_ops->init(ctrl, idx, ctrl->p_cur);
|
|
ctrl->type_ops->init(ctrl, idx, ctrl->p_new);
|
|
@@ -2554,7 +2569,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
|
|
type, min, max,
|
|
is_menu ? cfg->menu_skip_mask : step, def,
|
|
cfg->dims, cfg->elem_size,
|
|
- flags, qmenu, qmenu_int, priv);
|
|
+ flags, qmenu, qmenu_int, ptr_null, priv);
|
|
if (ctrl)
|
|
ctrl->is_private = cfg->is_private;
|
|
return ctrl;
|
|
@@ -2579,7 +2594,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
|
|
}
|
|
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
|
|
min, max, step, def, NULL, 0,
|
|
- flags, NULL, NULL, NULL);
|
|
+ flags, NULL, NULL, ptr_null, NULL);
|
|
}
|
|
EXPORT_SYMBOL(v4l2_ctrl_new_std);
|
|
|
|
@@ -2612,7 +2627,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
|
|
}
|
|
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
|
|
0, max, mask, def, NULL, 0,
|
|
- flags, qmenu, qmenu_int, NULL);
|
|
+ flags, qmenu, qmenu_int, ptr_null, NULL);
|
|
}
|
|
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
|
|
|
|
@@ -2644,11 +2659,32 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
|
|
}
|
|
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
|
|
0, max, mask, def, NULL, 0,
|
|
- flags, qmenu, NULL, NULL);
|
|
+ flags, qmenu, NULL, ptr_null, NULL);
|
|
|
|
}
|
|
EXPORT_SYMBOL(v4l2_ctrl_new_std_menu_items);
|
|
|
|
+/* Helper function for standard compound controls */
|
|
+struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
|
|
+ const struct v4l2_ctrl_ops *ops, u32 id,
|
|
+ const union v4l2_ctrl_ptr p_def)
|
|
+{
|
|
+ const char *name;
|
|
+ enum v4l2_ctrl_type type;
|
|
+ u32 flags;
|
|
+ s64 min, max, step, def;
|
|
+
|
|
+ v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
|
|
+ if (type < V4L2_CTRL_COMPOUND_TYPES) {
|
|
+ handler_set_err(hdl, -EINVAL);
|
|
+ return NULL;
|
|
+ }
|
|
+ return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
|
|
+ min, max, step, def, NULL, 0,
|
|
+ flags, NULL, NULL, p_def, NULL);
|
|
+}
|
|
+EXPORT_SYMBOL(v4l2_ctrl_new_std_compound);
|
|
+
|
|
/* Helper function for standard integer menu controls */
|
|
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
|
|
const struct v4l2_ctrl_ops *ops,
|
|
@@ -2669,7 +2705,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
|
|
}
|
|
return v4l2_ctrl_new(hdl, ops, NULL, id, name, type,
|
|
0, max, 0, def, NULL, 0,
|
|
- flags, NULL, qmenu_int, NULL);
|
|
+ flags, NULL, qmenu_int, ptr_null, NULL);
|
|
}
|
|
EXPORT_SYMBOL(v4l2_ctrl_new_int_menu);
|
|
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index 570ff4b0205a..fb0883836548 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -200,6 +200,9 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
|
|
* not freed when the control is deleted. Should this be needed
|
|
* then a new internal bitfield can be added to tell the framework
|
|
* to free this pointer.
|
|
+ * @p_def: The control's default value represented via a union which
|
|
+ * provides a standard way of accessing control types
|
|
+ * through a pointer (for compound controls only).
|
|
* @p_cur: The control's current value represented via a union which
|
|
* provides a standard way of accessing control types
|
|
* through a pointer.
|
|
@@ -254,6 +257,7 @@ struct v4l2_ctrl {
|
|
s32 val;
|
|
} cur;
|
|
|
|
+ union v4l2_ctrl_ptr p_def;
|
|
union v4l2_ctrl_ptr p_new;
|
|
union v4l2_ctrl_ptr p_cur;
|
|
};
|
|
@@ -646,6 +650,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
|
|
u64 mask, u8 def,
|
|
const char * const *qmenu);
|
|
|
|
+/**
|
|
+ * v4l2_ctrl_new_std_compound() - Allocate and initialize a new standard V4L2
|
|
+ * compound control.
|
|
+ *
|
|
+ * @hdl: The control handler.
|
|
+ * @ops: The control ops.
|
|
+ * @id: The control ID.
|
|
+ * @p_def: The control's default value.
|
|
+ *
|
|
+ * Sames as v4l2_ctrl_new_std(), but with support to compound controls, thanks
|
|
+ * to the @p_def field.
|
|
+ *
|
|
+ */
|
|
+struct v4l2_ctrl *v4l2_ctrl_new_std_compound(struct v4l2_ctrl_handler *hdl,
|
|
+ const struct v4l2_ctrl_ops *ops,
|
|
+ u32 id,
|
|
+ const union v4l2_ctrl_ptr p_def);
|
|
+
|
|
/**
|
|
* v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
|
|
*
|
|
|
|
From 7b9f1c0c824a6d57ba47aca7a1a0c1497aaa709e Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:31 -0300
|
|
Subject: [PATCH] media: add V4L2_CTRL_TYPE_AREA control type
|
|
|
|
This type contains the width and the height of a rectangular area.
|
|
|
|
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit d1dc49370f8371b00e682ac409aa1987ce641e93)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 21 ++++++++++++++++++
|
|
include/media/v4l2-ctrls.h | 42 ++++++++++++++++++++++++++++++++++++
|
|
include/uapi/linux/videodev2.h | 6 ++++++
|
|
3 files changed, 69 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index 219d8aeefa20..96cab2e173d3 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -1677,6 +1677,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_area *area;
|
|
void *p = ptr.p + idx * ctrl->elem_size;
|
|
|
|
switch ((u32)ctrl->type) {
|
|
@@ -1753,6 +1754,11 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
|
zero_padding(p_vp8_frame_header->entropy_header);
|
|
zero_padding(p_vp8_frame_header->coder_state);
|
|
break;
|
|
+ case V4L2_CTRL_TYPE_AREA:
|
|
+ area = p;
|
|
+ if (!area->width || !area->height)
|
|
+ return -EINVAL;
|
|
+ break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
@@ -2427,6 +2433,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
|
|
elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header);
|
|
break;
|
|
+ case V4L2_CTRL_TYPE_AREA:
|
|
+ elem_size = sizeof(struct v4l2_area);
|
|
+ break;
|
|
default:
|
|
if (type < V4L2_CTRL_COMPOUND_TYPES)
|
|
elem_size = sizeof(s32);
|
|
@@ -4116,6 +4125,18 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
|
|
}
|
|
EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);
|
|
|
|
+int __v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl,
|
|
+ const struct v4l2_area *area)
|
|
+{
|
|
+ lockdep_assert_held(ctrl->handler->lock);
|
|
+
|
|
+ /* It's a driver bug if this happens. */
|
|
+ WARN_ON(ctrl->type != V4L2_CTRL_TYPE_AREA);
|
|
+ *ctrl->p_new.p_area = *area;
|
|
+ return set_ctrl(NULL, ctrl, 0);
|
|
+}
|
|
+EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_area);
|
|
+
|
|
void v4l2_ctrl_request_complete(struct media_request *req,
|
|
struct v4l2_ctrl_handler *main_hdl)
|
|
{
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index fb0883836548..c9ca867ef32b 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -50,6 +50,7 @@ struct poll_table_struct;
|
|
* @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_vp8_frame_header: Pointer to a VP8 frame header structure.
|
|
+ * @p_area: Pointer to an area.
|
|
* @p: Pointer to a compound value.
|
|
*/
|
|
union v4l2_ctrl_ptr {
|
|
@@ -68,6 +69,7 @@ union v4l2_ctrl_ptr {
|
|
struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
|
|
struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
|
|
struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
|
|
+ struct v4l2_area *p_area;
|
|
void *p;
|
|
};
|
|
|
|
@@ -1087,6 +1089,46 @@ static inline int v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
|
|
return rval;
|
|
}
|
|
|
|
+/**
|
|
+ * __v4l2_ctrl_s_ctrl_area() - Unlocked variant of v4l2_ctrl_s_ctrl_area().
|
|
+ *
|
|
+ * @ctrl: The control.
|
|
+ * @area: The new area.
|
|
+ *
|
|
+ * This sets the control's new area safely by going through the control
|
|
+ * framework. This function assumes the control's handler is already locked,
|
|
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
|
|
+ *
|
|
+ * This function is for area type controls only.
|
|
+ */
|
|
+int __v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl,
|
|
+ const struct v4l2_area *area);
|
|
+
|
|
+/**
|
|
+ * v4l2_ctrl_s_ctrl_area() - Helper function to set a control's area value
|
|
+ * from within a driver.
|
|
+ *
|
|
+ * @ctrl: The control.
|
|
+ * @area: The new area.
|
|
+ *
|
|
+ * This sets the control's new area safely by going through the control
|
|
+ * framework. This function will lock the control's handler, so it cannot be
|
|
+ * used from within the &v4l2_ctrl_ops functions.
|
|
+ *
|
|
+ * This function is for area type controls only.
|
|
+ */
|
|
+static inline int v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl,
|
|
+ const struct v4l2_area *area)
|
|
+{
|
|
+ int rval;
|
|
+
|
|
+ v4l2_ctrl_lock(ctrl);
|
|
+ rval = __v4l2_ctrl_s_ctrl_area(ctrl, area);
|
|
+ v4l2_ctrl_unlock(ctrl);
|
|
+
|
|
+ return rval;
|
|
+}
|
|
+
|
|
/* Internal helper functions that deal with control events. */
|
|
extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
|
|
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index 530638dffd93..b3c0961b62a0 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -422,6 +422,11 @@ struct v4l2_fract {
|
|
__u32 denominator;
|
|
};
|
|
|
|
+struct v4l2_area {
|
|
+ __u32 width;
|
|
+ __u32 height;
|
|
+};
|
|
+
|
|
/**
|
|
* struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP
|
|
*
|
|
@@ -1720,6 +1725,7 @@ enum v4l2_ctrl_type {
|
|
V4L2_CTRL_TYPE_U8 = 0x0100,
|
|
V4L2_CTRL_TYPE_U16 = 0x0101,
|
|
V4L2_CTRL_TYPE_U32 = 0x0102,
|
|
+ V4L2_CTRL_TYPE_AREA = 0x0106,
|
|
};
|
|
|
|
/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
|
|
|
|
From 86607212f202f22fbb7d6ccf1ea2cbab2aff2163 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:32 -0300
|
|
Subject: [PATCH] media: Documentation: media: Document V4L2_CTRL_TYPE_AREA
|
|
|
|
A struct v4l2_area containing the width and the height of a rectangular
|
|
area.
|
|
|
|
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 8ae3a0862993c09a8ef0f9abb379553370c517e3)
|
|
---
|
|
Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 6 ++++++
|
|
Documentation/media/videodev2.h.rst.exceptions | 1 +
|
|
2 files changed, 7 insertions(+)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
index a3d56ffbf4cc..33aff21b7d11 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
@@ -443,6 +443,12 @@ See also the examples in :ref:`control`.
|
|
- n/a
|
|
- A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
|
|
quantization matrices for stateless video decoders.
|
|
+ * - ``V4L2_CTRL_TYPE_AREA``
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - A struct :c:type:`v4l2_area`, containing the width and the height
|
|
+ of a rectangular area. Units depend on the use case.
|
|
* - ``V4L2_CTRL_TYPE_H264_SPS``
|
|
- n/a
|
|
- n/a
|
|
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
|
|
index adeb6b7a15cb..b58e381bdf7b 100644
|
|
--- a/Documentation/media/videodev2.h.rst.exceptions
|
|
+++ b/Documentation/media/videodev2.h.rst.exceptions
|
|
@@ -141,6 +141,7 @@ replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
|
|
+replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
|
|
|
|
# V4L2 capability defines
|
|
replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
|
|
|
|
From 5edc3ce46d0d4f9f500a25e30324637107ac6b2d Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:33 -0300
|
|
Subject: [PATCH] media: add V4L2_CID_UNIT_CELL_SIZE control
|
|
|
|
This control returns the unit cell size in nanometres. The struct provides
|
|
the width and the height in separated fields to take into consideration
|
|
asymmetric pixels and/or hardware binning.
|
|
This control is required for automatic calibration of sensors/cameras.
|
|
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 61fd036d01111679b01e4b92e6bd0cdd33809aea)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 5 +++++
|
|
include/uapi/linux/v4l2-controls.h | 1 +
|
|
2 files changed, 6 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index 96cab2e173d3..bf50d37ef6c1 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -996,6 +996,7 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|
case V4L2_CID_AUTO_FOCUS_RANGE: return "Auto Focus, Range";
|
|
case V4L2_CID_PAN_SPEED: return "Pan, Speed";
|
|
case V4L2_CID_TILT_SPEED: return "Tilt, Speed";
|
|
+ case V4L2_CID_UNIT_CELL_SIZE: return "Unit Cell Size";
|
|
|
|
/* FM Radio Modulator controls */
|
|
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
|
|
@@ -1377,6 +1378,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
|
case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:
|
|
*type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER;
|
|
break;
|
|
+ case V4L2_CID_UNIT_CELL_SIZE:
|
|
+ *type = V4L2_CTRL_TYPE_AREA;
|
|
+ *flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
+ break;
|
|
default:
|
|
*type = V4L2_CTRL_TYPE_INTEGER;
|
|
break;
|
|
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
|
|
index a2669b79b294..5a7bedee2b0e 100644
|
|
--- a/include/uapi/linux/v4l2-controls.h
|
|
+++ b/include/uapi/linux/v4l2-controls.h
|
|
@@ -1034,6 +1034,7 @@ enum v4l2_jpeg_chroma_subsampling {
|
|
#define V4L2_CID_TEST_PATTERN_GREENR (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5)
|
|
#define V4L2_CID_TEST_PATTERN_BLUE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6)
|
|
#define V4L2_CID_TEST_PATTERN_GREENB (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7)
|
|
+#define V4L2_CID_UNIT_CELL_SIZE (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8)
|
|
|
|
|
|
/* Image processing controls */
|
|
|
|
From 59a84a093b9f0ea8c332adb4d7dc5b864be1bc7e Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:34 -0300
|
|
Subject: [PATCH] media: Documentation: media: Describe V4L2_CID_UNIT_CELL_SIZE
|
|
|
|
New control to pass to userspace the width/height of a pixel. Which is
|
|
needed for calibration and lens selection.
|
|
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3f0a700624d0a4014998b2ed5c1f964aa1b784a6)
|
|
---
|
|
Documentation/media/uapi/v4l/ext-ctrls-image-source.rst | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst b/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst
|
|
index 2c3ab5796d76..2d3e2b83d6dd 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-image-source.rst
|
|
@@ -55,3 +55,13 @@ Image Source Control IDs
|
|
|
|
``V4L2_CID_TEST_PATTERN_GREENB (integer)``
|
|
Test pattern green (next to blue) colour component.
|
|
+
|
|
+``V4L2_CID_UNIT_CELL_SIZE (struct)``
|
|
+ This control returns the unit cell size in nanometers. The struct
|
|
+ :c:type:`v4l2_area` provides the width and the height in separate
|
|
+ fields to take into consideration asymmetric pixels.
|
|
+ This control does not take into consideration any possible hardware
|
|
+ binning.
|
|
+ The unit cell consists of the whole area of the pixel, sensitive and
|
|
+ non-sensitive.
|
|
+ This control is required for automatic calibration of sensors/cameras.
|
|
|
|
From 486afec10b61e9fe67a87647faff468c0fa4f291 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 7 Oct 2019 12:06:35 -0300
|
|
Subject: [PATCH] media: v4l2-ctrl: Add new helper v4l2_ctrl_ptr_create
|
|
|
|
This helper function simplifies the code by not needing a union
|
|
v4l2_ctrl_ptr and an assignment every time we need to use
|
|
a ctrl_ptr.
|
|
|
|
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 2e8db63e1f64b6085cc84a03484213af565c81fb)
|
|
---
|
|
include/media/v4l2-ctrls.h | 12 ++++++++++++
|
|
1 file changed, 12 insertions(+)
|
|
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index c9ca867ef32b..26205ba3a0a0 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -73,6 +73,18 @@ union v4l2_ctrl_ptr {
|
|
void *p;
|
|
};
|
|
|
|
+/**
|
|
+ * v4l2_ctrl_ptr_create() - Helper function to return a v4l2_ctrl_ptr from a
|
|
+ * void pointer
|
|
+ * @ptr: The void pointer
|
|
+ */
|
|
+static inline union v4l2_ctrl_ptr v4l2_ctrl_ptr_create(void *ptr)
|
|
+{
|
|
+ union v4l2_ctrl_ptr p = { .p = ptr };
|
|
+
|
|
+ return p;
|
|
+}
|
|
+
|
|
/**
|
|
* struct v4l2_ctrl_ops - The control operations that the driver has to provide.
|
|
*
|
|
|
|
From e902e2d16d2958fe78e3ca8cc7bc0bb85966fab0 Mon Sep 17 00:00:00 2001
|
|
From: Benoit Parrot <bparrot@ti.com>
|
|
Date: Mon, 7 Oct 2019 12:10:07 -0300
|
|
Subject: [PATCH] media: v4l2-common: add pixel encoding support
|
|
|
|
It is often useful to figure out if a pixel_format is either YUV or RGB
|
|
especially for driver who can perform the pixel encoding conversion.
|
|
|
|
Instead of having each driver implement its own "is_this_yuv/rgb"
|
|
function based on a restricted set of pixel value, it is better to do
|
|
this in centralized manner.
|
|
|
|
We therefore add a pixel_enc member to the v4l2_format_info structure to
|
|
quickly identify the related pixel encoding.
|
|
And add helper functions to check pixel encoding.
|
|
|
|
Signed-off-by: Benoit Parrot <bparrot@ti.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit d5a897c8428b38053df4b427a4277b1a0722bfa0)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-common.c | 126 +++++++++++++++++-----------------
|
|
include/media/v4l2-common.h | 33 ++++++++-
|
|
2 files changed, 95 insertions(+), 64 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
|
|
index 62f7aa92ac29..09a3915b98a3 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-common.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-common.c
|
|
@@ -236,77 +236,77 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
|
|
{
|
|
static const struct v4l2_format_info formats[] = {
|
|
/* RGB formats */
|
|
- { .format = V4L2_PIX_FMT_BGR24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_RGB24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_HSV24, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_BGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_XBGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_BGRX32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_RGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_XRGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_RGBX32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_HSV32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_ARGB32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_RGBA32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_ABGR32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_BGRA32, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_GREY, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
|
|
/* YUV packed formats */
|
|
- { .format = V4L2_PIX_FMT_YUYV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_YVYU, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_UYVY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_VYUY, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
|
|
/* YUV planar formats */
|
|
- { .format = V4L2_PIX_FMT_NV12, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_NV21, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_NV16, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_NV61, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_NV24, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_NV42, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
-
|
|
- { .format = V4L2_PIX_FMT_YUV410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
|
|
- { .format = V4L2_PIX_FMT_YVU410, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
|
|
- { .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_YUV420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_YVU420, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+
|
|
+ { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
|
|
+ { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 },
|
|
+ { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
|
|
/* YUV planar formats, non contiguous variant */
|
|
- { .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
-
|
|
- { .format = V4L2_PIX_FMT_NV12M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_NV21M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
- { .format = V4L2_PIX_FMT_NV16M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_NV61M, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+
|
|
+ { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 },
|
|
+ { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
|
|
/* Bayer RGB formats */
|
|
- { .format = V4L2_PIX_FMT_SBGGR8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGBRG8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGRBG8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SRGGB8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SBGGR10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGBRG10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGRBG10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SRGGB10, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SBGGR12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGBRG12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SGRBG12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
- { .format = V4L2_PIX_FMT_SRGGB12, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
};
|
|
unsigned int i;
|
|
|
|
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
|
|
index c070d8ae11e5..d8c29e089000 100644
|
|
--- a/include/media/v4l2-common.h
|
|
+++ b/include/media/v4l2-common.h
|
|
@@ -456,9 +456,25 @@ int v4l2_s_parm_cap(struct video_device *vdev,
|
|
|
|
/* Pixel format and FourCC helpers */
|
|
|
|
+/**
|
|
+ * enum v4l2_pixel_encoding - specifies the pixel encoding value
|
|
+ *
|
|
+ * @V4L2_PIXEL_ENC_UNKNOWN: Pixel encoding is unknown/un-initialized
|
|
+ * @V4L2_PIXEL_ENC_YUV: Pixel encoding is YUV
|
|
+ * @V4L2_PIXEL_ENC_RGB: Pixel encoding is RGB
|
|
+ * @V4L2_PIXEL_ENC_BAYER: Pixel encoding is Bayer
|
|
+ */
|
|
+enum v4l2_pixel_encoding {
|
|
+ V4L2_PIXEL_ENC_UNKNOWN = 0,
|
|
+ V4L2_PIXEL_ENC_YUV = 1,
|
|
+ V4L2_PIXEL_ENC_RGB = 2,
|
|
+ V4L2_PIXEL_ENC_BAYER = 3,
|
|
+};
|
|
+
|
|
/**
|
|
* struct v4l2_format_info - information about a V4L2 format
|
|
* @format: 4CC format identifier (V4L2_PIX_FMT_*)
|
|
+ * @pixel_enc: Pixel encoding (see enum v4l2_pixel_encoding above)
|
|
* @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4).
|
|
* @comp_planes: Number of component planes, which includes the alpha plane (1 to 4).
|
|
* @bpp: Array of per-plane bytes per pixel
|
|
@@ -469,6 +485,7 @@ int v4l2_s_parm_cap(struct video_device *vdev,
|
|
*/
|
|
struct v4l2_format_info {
|
|
u32 format;
|
|
+ u8 pixel_enc;
|
|
u8 mem_planes;
|
|
u8 comp_planes;
|
|
u8 bpp[4];
|
|
@@ -478,8 +495,22 @@ struct v4l2_format_info {
|
|
u8 block_h[4];
|
|
};
|
|
|
|
-const struct v4l2_format_info *v4l2_format_info(u32 format);
|
|
+static inline bool v4l2_is_format_rgb(const struct v4l2_format_info *f)
|
|
+{
|
|
+ return f && f->pixel_enc == V4L2_PIXEL_ENC_RGB;
|
|
+}
|
|
|
|
+static inline bool v4l2_is_format_yuv(const struct v4l2_format_info *f)
|
|
+{
|
|
+ return f && f->pixel_enc == V4L2_PIXEL_ENC_YUV;
|
|
+}
|
|
+
|
|
+static inline bool v4l2_is_format_bayer(const struct v4l2_format_info *f)
|
|
+{
|
|
+ return f && f->pixel_enc == V4L2_PIXEL_ENC_BAYER;
|
|
+}
|
|
+
|
|
+const struct v4l2_format_info *v4l2_format_info(u32 format);
|
|
void v4l2_apply_frmsize_constraints(u32 *width, u32 *height,
|
|
const struct v4l2_frmsize_stepwise *frmsize);
|
|
int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat,
|
|
|
|
From 9b087df53ed23f9ae9f4105936b852f0b3d0030d Mon Sep 17 00:00:00 2001
|
|
From: Benoit Parrot <bparrot@ti.com>
|
|
Date: Mon, 7 Oct 2019 12:10:08 -0300
|
|
Subject: [PATCH] media: v4l2-common: add RGB565 and RGB55 to v4l2_format_info
|
|
|
|
Add RGB565 and RGB555 to the v4l2_format_info table.
|
|
|
|
Signed-off-by: Benoit Parrot <bparrot@ti.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit b373f84d77e1c409aacb4ff5bb5726c45fc8b166)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-common.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
|
|
index 09a3915b98a3..d0e5ebc736f9 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-common.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-common.c
|
|
@@ -251,6 +251,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
|
|
{ .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
{ .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
{ .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
+ { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
|
|
|
|
/* YUV packed formats */
|
|
{ .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 },
|
|
|
|
From 10f3efddea61013d1876f5eac512adf7a64cf21b Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 11 Oct 2019 06:32:40 -0300
|
|
Subject: [PATCH] media: vb2: add V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF
|
|
|
|
This patch adds support for the V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF
|
|
flag.
|
|
|
|
It also adds a new V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF
|
|
capability.
|
|
|
|
Drivers should set vb2_queue->subsystem_flags to
|
|
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF to indicate support
|
|
for this flag.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 137272cdf7cc5be835f44216e6003769d1638480)
|
|
---
|
|
Documentation/media/uapi/v4l/buffer.rst | 13 +++++++++++++
|
|
Documentation/media/uapi/v4l/vidioc-reqbufs.rst | 6 ++++++
|
|
drivers/media/common/videobuf2/videobuf2-v4l2.c | 12 ++++++++++--
|
|
include/media/videobuf2-core.h | 3 +++
|
|
include/media/videobuf2-v4l2.h | 5 +++++
|
|
include/uapi/linux/videodev2.h | 13 ++++++++-----
|
|
6 files changed, 45 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst
|
|
index 1cbd9cde57f3..9149b57728e5 100644
|
|
--- a/Documentation/media/uapi/v4l/buffer.rst
|
|
+++ b/Documentation/media/uapi/v4l/buffer.rst
|
|
@@ -607,6 +607,19 @@ Buffer Flags
|
|
applications shall use this flag for output buffers if the data in
|
|
this buffer has not been created by the CPU but by some
|
|
DMA-capable unit, in which case caches have not been used.
|
|
+ * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`:
|
|
+
|
|
+ - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF``
|
|
+ - 0x00000200
|
|
+ - Only valid if ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` is
|
|
+ set. It is typically used with stateless decoders where multiple
|
|
+ output buffers each decode to a slice of the decoded frame.
|
|
+ Applications can set this flag when queueing the output buffer
|
|
+ to prevent the driver from dequeueing the capture buffer after
|
|
+ the output buffer has been decoded (i.e. the capture buffer is
|
|
+ 'held'). If the timestamp of this output buffer differs from that
|
|
+ of the previous output buffer, then that indicates the start of a
|
|
+ new frame and the previously held capture buffer is dequeued.
|
|
* .. _`V4L2-BUF-FLAG-LAST`:
|
|
|
|
- ``V4L2_BUF_FLAG_LAST``
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst
|
|
index d7faef10e39b..d0c643db477a 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst
|
|
@@ -125,6 +125,7 @@ aborting or finishing any DMA in progress, an implicit
|
|
.. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
|
|
.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
|
|
.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
|
|
+.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF:
|
|
|
|
.. cssclass:: longtable
|
|
|
|
@@ -150,6 +151,11 @@ aborting or finishing any DMA in progress, an implicit
|
|
- The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still
|
|
mapped or exported via DMABUF. These orphaned buffers will be freed
|
|
when they are unmapped or when the exported DMABUF fds are closed.
|
|
+ * - ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF``
|
|
+ - 0x00000020
|
|
+ - Only valid for stateless decoders. If set, then userspace can set the
|
|
+ ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the
|
|
+ capture buffer until the OUTPUT timestamp changes.
|
|
|
|
Return Value
|
|
============
|
|
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
|
|
index 5a9ba3846f0a..e652f4318284 100644
|
|
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
|
|
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
|
|
@@ -49,8 +49,11 @@ module_param(debug, int, 0644);
|
|
V4L2_BUF_FLAG_REQUEST_FD | \
|
|
V4L2_BUF_FLAG_TIMESTAMP_MASK)
|
|
/* Output buffer flags that should be passed on to the driver */
|
|
-#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \
|
|
- V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE)
|
|
+#define V4L2_BUFFER_OUT_FLAGS (V4L2_BUF_FLAG_PFRAME | \
|
|
+ V4L2_BUF_FLAG_BFRAME | \
|
|
+ V4L2_BUF_FLAG_KEYFRAME | \
|
|
+ V4L2_BUF_FLAG_TIMECODE | \
|
|
+ V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF)
|
|
|
|
/*
|
|
* __verify_planes_array() - verify that the planes array passed in struct
|
|
@@ -194,6 +197,7 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b
|
|
}
|
|
vbuf->sequence = 0;
|
|
vbuf->request_fd = -1;
|
|
+ vbuf->is_held = false;
|
|
|
|
if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
|
|
switch (b->memory) {
|
|
@@ -321,6 +325,8 @@ static int vb2_fill_vb2_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b
|
|
*/
|
|
vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE;
|
|
vbuf->field = b->field;
|
|
+ if (!(q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF))
|
|
+ vbuf->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF;
|
|
} else {
|
|
/* Zero any output buffer flags as this is a capture buffer */
|
|
vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
|
|
@@ -654,6 +660,8 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
|
|
*caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR;
|
|
if (q->io_modes & VB2_DMABUF)
|
|
*caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF;
|
|
+ if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)
|
|
+ *caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
|
|
#ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API
|
|
if (q->supports_requests)
|
|
*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS;
|
|
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
|
|
index 640aabe69450..a2b2208b02da 100644
|
|
--- a/include/media/videobuf2-core.h
|
|
+++ b/include/media/videobuf2-core.h
|
|
@@ -505,6 +505,8 @@ struct vb2_buf_ops {
|
|
* @buf_ops: callbacks to deliver buffer information.
|
|
* between user-space and kernel-space.
|
|
* @drv_priv: driver private data.
|
|
+ * @subsystem_flags: Flags specific to the subsystem (V4L2/DVB/etc.). Not used
|
|
+ * by the vb2 core.
|
|
* @buf_struct_size: size of the driver-specific buffer structure;
|
|
* "0" indicates the driver doesn't want to use a custom buffer
|
|
* structure type. for example, ``sizeof(struct vb2_v4l2_buffer)``
|
|
@@ -571,6 +573,7 @@ struct vb2_queue {
|
|
const struct vb2_buf_ops *buf_ops;
|
|
|
|
void *drv_priv;
|
|
+ u32 subsystem_flags;
|
|
unsigned int buf_struct_size;
|
|
u32 timestamp_flags;
|
|
gfp_t gfp_flags;
|
|
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
|
|
index 8a10889dc2fd..59bf33a12648 100644
|
|
--- a/include/media/videobuf2-v4l2.h
|
|
+++ b/include/media/videobuf2-v4l2.h
|
|
@@ -33,6 +33,7 @@
|
|
* @timecode: frame timecode.
|
|
* @sequence: sequence count of this frame.
|
|
* @request_fd: the request_fd associated with this buffer
|
|
+ * @is_held: if true, then this capture buffer was held
|
|
* @planes: plane information (userptr/fd, length, bytesused, data_offset).
|
|
*
|
|
* Should contain enough information to be able to cover all the fields
|
|
@@ -46,9 +47,13 @@ struct vb2_v4l2_buffer {
|
|
struct v4l2_timecode timecode;
|
|
__u32 sequence;
|
|
__s32 request_fd;
|
|
+ bool is_held;
|
|
struct vb2_plane planes[VB2_MAX_PLANES];
|
|
};
|
|
|
|
+/* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */
|
|
+#define VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 0)
|
|
+
|
|
/*
|
|
* to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer *
|
|
*/
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index b3c0961b62a0..9f4e66affac4 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -920,11 +920,12 @@ struct v4l2_requestbuffers {
|
|
};
|
|
|
|
/* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */
|
|
-#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0)
|
|
-#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
|
|
-#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
|
|
-#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
|
|
-#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)
|
|
+#define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5)
|
|
|
|
/**
|
|
* struct v4l2_plane - plane info for multi-planar buffers
|
|
@@ -1046,6 +1047,8 @@ static inline __u64 v4l2_timeval_to_ns(const struct timeval *tv)
|
|
#define V4L2_BUF_FLAG_IN_REQUEST 0x00000080
|
|
/* timecode field is valid */
|
|
#define V4L2_BUF_FLAG_TIMECODE 0x00000100
|
|
+/* Don't return the capture buffer until OUTPUT timestamp changes */
|
|
+#define V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF 0x00000200
|
|
/* Buffer is prepared for queuing */
|
|
#define V4L2_BUF_FLAG_PREPARED 0x00000400
|
|
/* Cache handling flags */
|
|
|
|
From ff041a7a3d59fe9491fc0905b6269e34a4c958db Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 11 Oct 2019 06:32:41 -0300
|
|
Subject: [PATCH] media: v4l2-mem2mem: support held capture buffers
|
|
|
|
Check for held buffers that are ready to be returned to vb2 in
|
|
__v4l2_m2m_try_queue(). This avoids drivers having to handle this
|
|
case.
|
|
|
|
Add v4l2_m2m_buf_done_and_job_finish() to correctly return source
|
|
and destination buffers and mark the job as finished while taking
|
|
a held destination buffer into account (i.e. that buffer won't be
|
|
returned). This has to be done while job_spinlock is held to avoid
|
|
race conditions.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit f8cca8c97a63d77f48334cde81d15014f43530ef)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-mem2mem.c | 130 ++++++++++++++++++++++++---------
|
|
include/media/v4l2-mem2mem.h | 33 ++++++++-
|
|
2 files changed, 128 insertions(+), 35 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
index 19937dd3c6f6..79c3656f24f7 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
@@ -284,7 +284,8 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
|
|
static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
struct v4l2_m2m_ctx *m2m_ctx)
|
|
{
|
|
- unsigned long flags_job, flags_out, flags_cap;
|
|
+ unsigned long flags_job;
|
|
+ struct vb2_v4l2_buffer *dst, *src;
|
|
|
|
dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx);
|
|
|
|
@@ -307,20 +308,30 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
goto job_unlock;
|
|
}
|
|
|
|
- spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out);
|
|
- if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)
|
|
- && !m2m_ctx->out_q_ctx.buffered) {
|
|
+ src = v4l2_m2m_next_src_buf(m2m_ctx);
|
|
+ dst = v4l2_m2m_next_dst_buf(m2m_ctx);
|
|
+ if (!src && !m2m_ctx->out_q_ctx.buffered) {
|
|
dprintk("No input buffers available\n");
|
|
- goto out_unlock;
|
|
+ goto job_unlock;
|
|
}
|
|
- spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap);
|
|
- if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)
|
|
- && !m2m_ctx->cap_q_ctx.buffered) {
|
|
+ if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
|
|
dprintk("No output buffers available\n");
|
|
- goto cap_unlock;
|
|
+ goto job_unlock;
|
|
+ }
|
|
+
|
|
+ if (src && dst &&
|
|
+ dst->is_held && dst->vb2_buf.copied_timestamp &&
|
|
+ dst->vb2_buf.timestamp != src->vb2_buf.timestamp) {
|
|
+ dst->is_held = false;
|
|
+ v4l2_m2m_dst_buf_remove(m2m_ctx);
|
|
+ v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
|
|
+ dst = v4l2_m2m_next_dst_buf(m2m_ctx);
|
|
+
|
|
+ if (!dst && !m2m_ctx->cap_q_ctx.buffered) {
|
|
+ dprintk("No output buffers available after returning held buffer\n");
|
|
+ goto job_unlock;
|
|
+ }
|
|
}
|
|
- spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap);
|
|
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out);
|
|
|
|
if (m2m_dev->m2m_ops->job_ready
|
|
&& (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
|
|
@@ -331,13 +342,6 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
list_add_tail(&m2m_ctx->queue, &m2m_dev->job_queue);
|
|
m2m_ctx->job_flags |= TRANS_QUEUED;
|
|
|
|
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
|
|
- return;
|
|
-
|
|
-cap_unlock:
|
|
- spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap);
|
|
-out_unlock:
|
|
- spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out);
|
|
job_unlock:
|
|
spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
|
|
}
|
|
@@ -412,37 +416,97 @@ static void v4l2_m2m_cancel_job(struct v4l2_m2m_ctx *m2m_ctx)
|
|
}
|
|
}
|
|
|
|
-void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
- struct v4l2_m2m_ctx *m2m_ctx)
|
|
+/*
|
|
+ * Schedule the next job, called from v4l2_m2m_job_finish() or
|
|
+ * v4l2_m2m_buf_done_and_job_finish().
|
|
+ */
|
|
+static void v4l2_m2m_schedule_next_job(struct v4l2_m2m_dev *m2m_dev,
|
|
+ struct v4l2_m2m_ctx *m2m_ctx)
|
|
{
|
|
- unsigned long flags;
|
|
+ /*
|
|
+ * This instance might have more buffers ready, but since we do not
|
|
+ * allow more than one job on the job_queue per instance, each has
|
|
+ * to be scheduled separately after the previous one finishes.
|
|
+ */
|
|
+ __v4l2_m2m_try_queue(m2m_dev, m2m_ctx);
|
|
|
|
- spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
|
|
+ /*
|
|
+ * We might be running in atomic context,
|
|
+ * but the job must be run in non-atomic context.
|
|
+ */
|
|
+ schedule_work(&m2m_dev->job_work);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Assumes job_spinlock is held, called from v4l2_m2m_job_finish() or
|
|
+ * v4l2_m2m_buf_done_and_job_finish().
|
|
+ */
|
|
+static bool _v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
+ struct v4l2_m2m_ctx *m2m_ctx)
|
|
+{
|
|
if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx != m2m_ctx) {
|
|
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
|
|
dprintk("Called by an instance not currently running\n");
|
|
- return;
|
|
+ return false;
|
|
}
|
|
|
|
list_del(&m2m_dev->curr_ctx->queue);
|
|
m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
|
|
wake_up(&m2m_dev->curr_ctx->finished);
|
|
m2m_dev->curr_ctx = NULL;
|
|
+ return true;
|
|
+}
|
|
|
|
- spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
|
|
-
|
|
- /* This instance might have more buffers ready, but since we do not
|
|
- * allow more than one job on the job_queue per instance, each has
|
|
- * to be scheduled separately after the previous one finishes. */
|
|
- __v4l2_m2m_try_queue(m2m_dev, m2m_ctx);
|
|
+void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
+ struct v4l2_m2m_ctx *m2m_ctx)
|
|
+{
|
|
+ unsigned long flags;
|
|
+ bool schedule_next;
|
|
|
|
- /* We might be running in atomic context,
|
|
- * but the job must be run in non-atomic context.
|
|
+ /*
|
|
+ * This function should not be used for drivers that support
|
|
+ * holding capture buffers. Those should use
|
|
+ * v4l2_m2m_buf_done_and_job_finish() instead.
|
|
*/
|
|
- schedule_work(&m2m_dev->job_work);
|
|
+ WARN_ON(m2m_ctx->cap_q_ctx.q.subsystem_flags &
|
|
+ VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF);
|
|
+ spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
|
|
+ schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
|
|
+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
|
|
+
|
|
+ if (schedule_next)
|
|
+ v4l2_m2m_schedule_next_job(m2m_dev, m2m_ctx);
|
|
}
|
|
EXPORT_SYMBOL(v4l2_m2m_job_finish);
|
|
|
|
+void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
+ struct v4l2_m2m_ctx *m2m_ctx,
|
|
+ enum vb2_buffer_state state)
|
|
+{
|
|
+ struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
|
+ bool schedule_next = false;
|
|
+ unsigned long flags;
|
|
+
|
|
+ spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
|
|
+ src_buf = v4l2_m2m_src_buf_remove(m2m_ctx);
|
|
+ dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx);
|
|
+
|
|
+ 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);
|
|
+ v4l2_m2m_buf_done(dst_buf, state);
|
|
+ }
|
|
+ schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
|
|
+unlock:
|
|
+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
|
|
+
|
|
+ if (schedule_next)
|
|
+ v4l2_m2m_schedule_next_job(m2m_dev, m2m_ctx);
|
|
+}
|
|
+EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish);
|
|
+
|
|
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 0b9c3a287061..229d9f5d4370 100644
|
|
--- a/include/media/v4l2-mem2mem.h
|
|
+++ b/include/media/v4l2-mem2mem.h
|
|
@@ -21,7 +21,8 @@
|
|
* callback.
|
|
* The job does NOT have to end before this callback returns
|
|
* (and it will be the usual case). When the job finishes,
|
|
- * v4l2_m2m_job_finish() has to be called.
|
|
+ * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish()
|
|
+ * has to be called.
|
|
* @job_ready: optional. Should return 0 if the driver does not have a job
|
|
* fully prepared to run yet (i.e. it will not be able to finish a
|
|
* transaction without sleeping). If not provided, it will be
|
|
@@ -33,7 +34,8 @@
|
|
* stop the device safely; e.g. in the next interrupt handler),
|
|
* even if the transaction would not have been finished by then.
|
|
* After the driver performs the necessary steps, it has to call
|
|
- * v4l2_m2m_job_finish() (as if the transaction ended normally).
|
|
+ * v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as
|
|
+ * if the transaction ended normally.
|
|
* This function does not have to (and will usually not) wait
|
|
* until the device enters a state when it can be stopped.
|
|
*/
|
|
@@ -173,6 +175,33 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx);
|
|
void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
struct v4l2_m2m_ctx *m2m_ctx);
|
|
|
|
+/**
|
|
+ * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with
|
|
+ * state and inform the framework that a job has been finished and have it
|
|
+ * clean up
|
|
+ *
|
|
+ * @m2m_dev: opaque pointer to the internal data to handle M2M context
|
|
+ * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx
|
|
+ * @state: vb2 buffer state passed to v4l2_m2m_buf_done().
|
|
+ *
|
|
+ * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this
|
|
+ * function instead of job_finish() to take held buffers into account. It is
|
|
+ * optional for other drivers.
|
|
+ *
|
|
+ * This function removes the source buffer from the ready list and returns
|
|
+ * it with the given state. The same is done for the destination buffer, unless
|
|
+ * it is marked 'held'. In that case the buffer is kept on the ready list.
|
|
+ *
|
|
+ * After that the job is finished (see job_finish()).
|
|
+ *
|
|
+ * This allows for multiple output buffers to be used to fill in a single
|
|
+ * capture buffer. This is typically used by stateless decoders where
|
|
+ * multiple e.g. H.264 slices contribute to a single decoded frame.
|
|
+ */
|
|
+void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
+ struct v4l2_m2m_ctx *m2m_ctx,
|
|
+ enum vb2_buffer_state state);
|
|
+
|
|
static inline void
|
|
v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
|
|
{
|
|
|
|
From 30199c98243c8fedb05e97a13953d23ad78bfd8c Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 11 Oct 2019 06:32:42 -0300
|
|
Subject: [PATCH] media: videodev2.h: add V4L2_DEC_CMD_FLUSH
|
|
|
|
Add this new V4L2_DEC_CMD_FLUSH decoder command and document it.
|
|
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit bac06ec36ea2012ff0daa9767d0f77bf9c6064ec)
|
|
---
|
|
Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst | 10 +++++++++-
|
|
Documentation/media/videodev2.h.rst.exceptions | 1 +
|
|
include/uapi/linux/videodev2.h | 1 +
|
|
3 files changed, 11 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
|
|
index 57f0066f4cff..f1a504836f31 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
|
|
@@ -208,7 +208,15 @@ introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decod
|
|
been started yet, the driver will return an ``EPERM`` error code. When
|
|
the decoder is already running, this command does nothing. No
|
|
flags are defined for this command.
|
|
-
|
|
+ * - ``V4L2_DEC_CMD_FLUSH``
|
|
+ - 4
|
|
+ - Flush any held capture buffers. Only valid for stateless decoders.
|
|
+ This command is typically used when the application reached the
|
|
+ end of the stream and the last output buffer had the
|
|
+ ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag set. This would prevent
|
|
+ dequeueing the capture buffer containing the last decoded frame.
|
|
+ So this command can be used to explicitly flush that final decoded
|
|
+ frame. This command does nothing if there are no held capture buffers.
|
|
|
|
Return Value
|
|
============
|
|
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
|
|
index b58e381bdf7b..c23e5ef30c78 100644
|
|
--- a/Documentation/media/videodev2.h.rst.exceptions
|
|
+++ b/Documentation/media/videodev2.h.rst.exceptions
|
|
@@ -435,6 +435,7 @@ replace define V4L2_DEC_CMD_START decoder-cmds
|
|
replace define V4L2_DEC_CMD_STOP decoder-cmds
|
|
replace define V4L2_DEC_CMD_PAUSE decoder-cmds
|
|
replace define V4L2_DEC_CMD_RESUME decoder-cmds
|
|
+replace define V4L2_DEC_CMD_FLUSH decoder-cmds
|
|
|
|
replace define V4L2_DEC_CMD_START_MUTE_AUDIO decoder-cmds
|
|
replace define V4L2_DEC_CMD_PAUSE_TO_BLACK decoder-cmds
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index 9f4e66affac4..d969842bbfe2 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -1984,6 +1984,7 @@ struct v4l2_encoder_cmd {
|
|
#define V4L2_DEC_CMD_STOP (1)
|
|
#define V4L2_DEC_CMD_PAUSE (2)
|
|
#define V4L2_DEC_CMD_RESUME (3)
|
|
+#define V4L2_DEC_CMD_FLUSH (4)
|
|
|
|
/* Flags for V4L2_DEC_CMD_START */
|
|
#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0)
|
|
|
|
From b4b269cc0615037bf4f8cacd98f4c6e194eddb2c Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Fri, 11 Oct 2019 06:32:43 -0300
|
|
Subject: [PATCH] media: v4l2-mem2mem: add stateless_(try_)decoder_cmd ioctl
|
|
helpers
|
|
|
|
These helpers are used by stateless codecs when they support multiple
|
|
slices per frame and hold capture buffer flag is set. It's expected that
|
|
all such codecs will use this code.
|
|
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Co-developed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit bef41d93aac64b54c3008ca6170bec54f85784f5)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-mem2mem.c | 53 ++++++++++++++++++++++++++++++++++
|
|
include/media/v4l2-mem2mem.h | 4 +++
|
|
2 files changed, 57 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
index 79c3656f24f7..b46d2c388349 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
@@ -1218,6 +1218,59 @@ int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh,
|
|
}
|
|
EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_try_decoder_cmd);
|
|
|
|
+int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,
|
|
+ struct v4l2_decoder_cmd *dc)
|
|
+{
|
|
+ if (dc->cmd != V4L2_DEC_CMD_FLUSH)
|
|
+ return -EINVAL;
|
|
+
|
|
+ dc->flags = 0;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_try_decoder_cmd);
|
|
+
|
|
+int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv,
|
|
+ struct v4l2_decoder_cmd *dc)
|
|
+{
|
|
+ struct v4l2_fh *fh = file->private_data;
|
|
+ struct vb2_v4l2_buffer *out_vb, *cap_vb;
|
|
+ struct v4l2_m2m_dev *m2m_dev = fh->m2m_ctx->m2m_dev;
|
|
+ unsigned long flags;
|
|
+ int ret;
|
|
+
|
|
+ ret = v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, dc);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
|
|
+ out_vb = v4l2_m2m_last_src_buf(fh->m2m_ctx);
|
|
+ cap_vb = v4l2_m2m_last_dst_buf(fh->m2m_ctx);
|
|
+
|
|
+ /*
|
|
+ * If there is an out buffer pending, then clear any HOLD flag.
|
|
+ *
|
|
+ * By clearing this flag we ensure that when this output
|
|
+ * buffer is processed any held capture buffer will be released.
|
|
+ */
|
|
+ if (out_vb) {
|
|
+ out_vb->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF;
|
|
+ } else if (cap_vb && cap_vb->is_held) {
|
|
+ /*
|
|
+ * If there were no output buffers, but there is a
|
|
+ * capture buffer that is held, then release that
|
|
+ * buffer.
|
|
+ */
|
|
+ cap_vb->is_held = false;
|
|
+ v4l2_m2m_dst_buf_remove(fh->m2m_ctx);
|
|
+ v4l2_m2m_buf_done(cap_vb, VB2_BUF_STATE_DONE);
|
|
+ }
|
|
+ spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_decoder_cmd);
|
|
+
|
|
/*
|
|
* v4l2_file_operations helpers. It is assumed here same lock is used
|
|
* for the output and the capture buffer queue.
|
|
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
|
|
index 229d9f5d4370..3d9e48ed8817 100644
|
|
--- a/include/media/v4l2-mem2mem.h
|
|
+++ b/include/media/v4l2-mem2mem.h
|
|
@@ -701,6 +701,10 @@ int v4l2_m2m_ioctl_try_encoder_cmd(struct file *file, void *fh,
|
|
struct v4l2_encoder_cmd *ec);
|
|
int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh,
|
|
struct v4l2_decoder_cmd *dc);
|
|
+int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh,
|
|
+ struct v4l2_decoder_cmd *dc);
|
|
+int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv,
|
|
+ struct v4l2_decoder_cmd *dc);
|
|
int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma);
|
|
__poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait);
|
|
|
|
|
|
From 02134af62ec81c5522bbebdb492eac2734f28850 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Fri, 11 Oct 2019 06:32:44 -0300
|
|
Subject: [PATCH] media: v4l2-mem2mem: add new_frame detection
|
|
|
|
Drivers that support VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF
|
|
typically want to know if a new frame is started (i.e. the first
|
|
slice is about to be processed). Add a new_frame bool to v4l2_m2m_ctx
|
|
and set it accordingly.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit f07602ac388723233e9e3c5a05b54baf34e0a3e9)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-mem2mem.c | 11 +++++++++--
|
|
include/media/v4l2-mem2mem.h | 7 +++++++
|
|
2 files changed, 16 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
index b46d2c388349..db07ef3bf3d0 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
@@ -319,8 +319,10 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
goto job_unlock;
|
|
}
|
|
|
|
- if (src && dst &&
|
|
- dst->is_held && dst->vb2_buf.copied_timestamp &&
|
|
+ m2m_ctx->new_frame = true;
|
|
+
|
|
+ if (src && dst && dst->is_held &&
|
|
+ dst->vb2_buf.copied_timestamp &&
|
|
dst->vb2_buf.timestamp != src->vb2_buf.timestamp) {
|
|
dst->is_held = false;
|
|
v4l2_m2m_dst_buf_remove(m2m_ctx);
|
|
@@ -333,6 +335,11 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
}
|
|
}
|
|
|
|
+ if (src && dst && (m2m_ctx->cap_q_ctx.q.subsystem_flags &
|
|
+ VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF))
|
|
+ m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp ||
|
|
+ dst->vb2_buf.timestamp != src->vb2_buf.timestamp;
|
|
+
|
|
if (m2m_dev->m2m_ops->job_ready
|
|
&& (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
|
|
dprintk("Driver not ready\n");
|
|
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
|
|
index 3d9e48ed8817..1d85e24791e4 100644
|
|
--- a/include/media/v4l2-mem2mem.h
|
|
+++ b/include/media/v4l2-mem2mem.h
|
|
@@ -75,6 +75,11 @@ struct v4l2_m2m_queue_ctx {
|
|
* struct v4l2_m2m_ctx - Memory to memory context structure
|
|
*
|
|
* @q_lock: struct &mutex lock
|
|
+ * @new_frame: valid in the device_run callback: if true, then this
|
|
+ * starts a new frame; if false, then this is a new slice
|
|
+ * for an existing frame. This is always true unless
|
|
+ * V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set, which
|
|
+ * indicates slicing support.
|
|
* @m2m_dev: opaque pointer to the internal data to handle M2M context
|
|
* @cap_q_ctx: Capture (output to memory) queue context
|
|
* @out_q_ctx: Output (input from memory) queue context
|
|
@@ -91,6 +96,8 @@ struct v4l2_m2m_ctx {
|
|
/* optional cap/out vb2 queues lock */
|
|
struct mutex *q_lock;
|
|
|
|
+ bool new_frame;
|
|
+
|
|
/* internal use only */
|
|
struct v4l2_m2m_dev *m2m_dev;
|
|
|
|
|
|
From bbca2f90a99be232a3f6fecd99ea05e03e08a337 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Fri, 11 Oct 2019 06:32:45 -0300
|
|
Subject: [PATCH] media: cedrus: h264: Support multiple slices per frame
|
|
|
|
With recent changes, support for decoding multi-slice frames can be
|
|
easily added now.
|
|
|
|
Signal VPU if current slice is first in frame or not and add information
|
|
about first macroblock coordinates.
|
|
|
|
When frame contains multiple slices and driver works in slice mode, it's
|
|
more efficient to hold capture buffer in queue until all slices of a
|
|
same frame are decoded.
|
|
|
|
Add support for that to Cedrus driver by exposing and implementing
|
|
V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF capability.
|
|
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
[hverkuil-cisco@xs4all.nl: rewritten to use v4l2_m2m_buf_done_and_job_finish]
|
|
[hverkuil-cisco@xs4all.nl: removed unnecessary (u32) cast]
|
|
[hverkuil-cisco@xs4all.nl: use new_frame v4l2_m2m_ctx bool]
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit eabf10e5e3009e0c7e9a9b98a7f8299e690bcc55)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 12 +++++++++++-
|
|
drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 16 ++--------------
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 14 ++++++++++++++
|
|
3 files changed, 27 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index d6a782703c9b..cd85668f9c80 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -301,6 +301,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
|
dma_addr_t src_buf_addr;
|
|
u32 offset = slice->header_bit_size;
|
|
u32 len = (slice->size * 8) - offset;
|
|
+ unsigned int pic_width_in_mbs;
|
|
+ bool mbaff_pic;
|
|
u32 reg;
|
|
|
|
cedrus_write(dev, VE_H264_VLD_LEN, len);
|
|
@@ -370,12 +372,20 @@ 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) &&
|
|
+ (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
|
|
+ pic_width_in_mbs = sps->pic_width_in_mbs_minus1 + 1;
|
|
+
|
|
// slice parameters
|
|
reg = 0;
|
|
+ reg |= ((slice->first_mb_in_slice % pic_width_in_mbs) & 0xff) << 24;
|
|
+ reg |= (((slice->first_mb_in_slice / pic_width_in_mbs) *
|
|
+ (mbaff_pic + 1)) & 0xff) << 16;
|
|
reg |= decode->nal_ref_idc ? BIT(12) : 0;
|
|
reg |= (slice->slice_type & 0xf) << 8;
|
|
reg |= slice->cabac_init_idc & 0x3;
|
|
- reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
|
|
+ if (ctx->fh.m2m_ctx->new_frame)
|
|
+ reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
|
|
if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
|
|
reg |= VE_H264_SHS_FIELD_PIC;
|
|
if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
index a942cd9bed57..e7e18424bab1 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
@@ -103,7 +103,6 @@ static irqreturn_t cedrus_irq(int irq, void *data)
|
|
{
|
|
struct cedrus_dev *dev = data;
|
|
struct cedrus_ctx *ctx;
|
|
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
|
enum vb2_buffer_state state;
|
|
enum cedrus_irq_status status;
|
|
|
|
@@ -121,24 +120,13 @@ static irqreturn_t cedrus_irq(int irq, void *data)
|
|
dev->dec_ops[ctx->current_codec]->irq_disable(ctx);
|
|
dev->dec_ops[ctx->current_codec]->irq_clear(ctx);
|
|
|
|
- src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
|
|
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
|
|
-
|
|
- if (!src_buf || !dst_buf) {
|
|
- v4l2_err(&dev->v4l2_dev,
|
|
- "Missing source and/or destination buffers\n");
|
|
- return IRQ_HANDLED;
|
|
- }
|
|
-
|
|
if (status == CEDRUS_IRQ_ERROR)
|
|
state = VB2_BUF_STATE_ERROR;
|
|
else
|
|
state = VB2_BUF_STATE_DONE;
|
|
|
|
- v4l2_m2m_buf_done(src_buf, state);
|
|
- v4l2_m2m_buf_done(dst_buf, state);
|
|
-
|
|
- v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
|
|
+ v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx,
|
|
+ state);
|
|
|
|
return IRQ_HANDLED;
|
|
}
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
index 3ec3a2db790c..f745f66c4440 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
@@ -303,6 +303,17 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
|
|
|
|
ctx->src_fmt = f->fmt.pix;
|
|
|
|
+ switch (ctx->src_fmt.pixelformat) {
|
|
+ case V4L2_PIX_FMT_H264_SLICE:
|
|
+ vq->subsystem_flags |=
|
|
+ VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
|
|
+ break;
|
|
+ default:
|
|
+ vq->subsystem_flags &=
|
|
+ ~VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
|
|
+ break;
|
|
+ }
|
|
+
|
|
/* Propagate colorspace information to capture. */
|
|
ctx->dst_fmt.colorspace = f->fmt.pix.colorspace;
|
|
ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func;
|
|
@@ -336,6 +347,9 @@ const struct v4l2_ioctl_ops cedrus_ioctl_ops = {
|
|
.vidioc_streamon = v4l2_m2m_ioctl_streamon,
|
|
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
|
|
|
|
+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd,
|
|
+ .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd,
|
|
+
|
|
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
|
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
|
};
|
|
|
|
From 89e5f6fe61a76025d0279ab60c3b31c1b556632c Mon Sep 17 00:00:00 2001
|
|
From: Alexandre Courbot <acourbot@chromium.org>
|
|
Date: Thu, 15 Aug 2019 11:44:55 -0300
|
|
Subject: [PATCH] media: docs-rst: Document m2m stateless video decoder
|
|
interface
|
|
|
|
Documents the protocol that user-space should follow when
|
|
communicating with stateless video decoders.
|
|
|
|
The stateless video decoding API makes use of the new request and tags
|
|
APIs. While it has been implemented with the Cedrus driver so far, it
|
|
should probably still be considered staging for a short while.
|
|
|
|
Signed-off-by: Alexandre Courbot <acourbot@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 6ce1d376d33eb775331b36a38afa28f9f08945e3)
|
|
---
|
|
Documentation/media/uapi/v4l/dev-mem2mem.rst | 1 +
|
|
.../media/uapi/v4l/dev-stateless-decoder.rst | 424 +++++++++++++++++++++
|
|
2 files changed, 425 insertions(+)
|
|
create mode 100644 Documentation/media/uapi/v4l/dev-stateless-decoder.rst
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/dev-mem2mem.rst b/Documentation/media/uapi/v4l/dev-mem2mem.rst
|
|
index caa05f5f6380..70953958cee6 100644
|
|
--- a/Documentation/media/uapi/v4l/dev-mem2mem.rst
|
|
+++ b/Documentation/media/uapi/v4l/dev-mem2mem.rst
|
|
@@ -46,3 +46,4 @@ devices are given in the following sections.
|
|
:maxdepth: 1
|
|
|
|
dev-decoder
|
|
+ dev-stateless-decoder
|
|
diff --git a/Documentation/media/uapi/v4l/dev-stateless-decoder.rst b/Documentation/media/uapi/v4l/dev-stateless-decoder.rst
|
|
new file mode 100644
|
|
index 000000000000..4a26646eeec5
|
|
--- /dev/null
|
|
+++ b/Documentation/media/uapi/v4l/dev-stateless-decoder.rst
|
|
@@ -0,0 +1,424 @@
|
|
+.. SPDX-License-Identifier: GPL-2.0
|
|
+
|
|
+.. _stateless_decoder:
|
|
+
|
|
+**************************************************
|
|
+Memory-to-memory Stateless Video Decoder Interface
|
|
+**************************************************
|
|
+
|
|
+A stateless decoder is a decoder that works without retaining any kind of state
|
|
+between processed frames. This means that each frame is decoded independently
|
|
+of any previous and future frames, and that the client is responsible for
|
|
+maintaining the decoding state and providing it to the decoder with each
|
|
+decoding request. This is in contrast to the stateful video decoder interface,
|
|
+where the hardware and driver maintain the decoding state and all the client
|
|
+has to do is to provide the raw encoded stream and dequeue decoded frames in
|
|
+display order.
|
|
+
|
|
+This section describes how user-space ("the client") is expected to communicate
|
|
+with stateless decoders in order to successfully decode an encoded stream.
|
|
+Compared to stateful codecs, the decoder/client sequence is simpler, but the
|
|
+cost of this simplicity is extra complexity in the client which is responsible
|
|
+for maintaining a consistent decoding state.
|
|
+
|
|
+Stateless decoders make use of the :ref:`media-request-api`. A stateless
|
|
+decoder must expose the ``V4L2_BUF_CAP_SUPPORTS_REQUESTS`` capability on its
|
|
+``OUTPUT`` queue when :c:func:`VIDIOC_REQBUFS` or :c:func:`VIDIOC_CREATE_BUFS`
|
|
+are invoked.
|
|
+
|
|
+Depending on the encoded formats supported by the decoder, a single decoded
|
|
+frame may be the result of several decode requests (for instance, H.264 streams
|
|
+with multiple slices per frame). Decoders that support such formats must also
|
|
+expose the ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` capability on their
|
|
+``OUTPUT`` queue.
|
|
+
|
|
+Querying capabilities
|
|
+=====================
|
|
+
|
|
+1. To enumerate the set of coded formats supported by the decoder, the client
|
|
+ calls :c:func:`VIDIOC_ENUM_FMT` on the ``OUTPUT`` queue.
|
|
+
|
|
+ * The driver must always return the full set of supported ``OUTPUT`` formats,
|
|
+ irrespective of the format currently set on the ``CAPTURE`` queue.
|
|
+
|
|
+ * Simultaneously, the driver must restrain the set of values returned by
|
|
+ codec-specific capability controls (such as H.264 profiles) to the set
|
|
+ actually supported by the hardware.
|
|
+
|
|
+2. To enumerate the set of supported raw formats, the client calls
|
|
+ :c:func:`VIDIOC_ENUM_FMT` on the ``CAPTURE`` queue.
|
|
+
|
|
+ * The driver must return only the formats supported for the format currently
|
|
+ active on the ``OUTPUT`` queue.
|
|
+
|
|
+ * Depending on the currently set ``OUTPUT`` format, the set of supported raw
|
|
+ formats may depend on the value of some codec-dependent controls.
|
|
+ The client is responsible for making sure that these controls are set
|
|
+ before querying the ``CAPTURE`` queue. Failure to do so will result in the
|
|
+ default values for these controls being used, and a returned set of formats
|
|
+ that may not be usable for the media the client is trying to decode.
|
|
+
|
|
+3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
|
|
+ resolutions for a given format, passing desired pixel format in
|
|
+ :c:type:`v4l2_frmsizeenum`'s ``pixel_format``.
|
|
+
|
|
+4. Supported profiles and levels for the current ``OUTPUT`` format, if
|
|
+ applicable, may be queried using their respective controls via
|
|
+ :c:func:`VIDIOC_QUERYCTRL`.
|
|
+
|
|
+Initialization
|
|
+==============
|
|
+
|
|
+1. Set the coded format on the ``OUTPUT`` queue via :c:func:`VIDIOC_S_FMT`.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``type``
|
|
+ a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
|
|
+
|
|
+ ``pixelformat``
|
|
+ a coded pixel format.
|
|
+
|
|
+ ``width``, ``height``
|
|
+ coded width and height parsed from the stream.
|
|
+
|
|
+ other fields
|
|
+ follow standard semantics.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
|
|
+ format. The driver will derive a new ``CAPTURE`` format from the
|
|
+ ``OUTPUT`` format being set, including resolution, colorimetry
|
|
+ parameters, etc. If the client needs a specific ``CAPTURE`` format,
|
|
+ it must adjust it afterwards.
|
|
+
|
|
+2. Call :c:func:`VIDIOC_S_EXT_CTRLS` to set all the controls (parsed headers,
|
|
+ etc.) required by the ``OUTPUT`` format to enumerate the ``CAPTURE`` formats.
|
|
+
|
|
+3. Call :c:func:`VIDIOC_G_FMT` for ``CAPTURE`` queue to get the format for the
|
|
+ destination buffers parsed/decoded from the bytestream.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``type``
|
|
+ a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
|
|
+
|
|
+ * **Returned fields:**
|
|
+
|
|
+ ``width``, ``height``
|
|
+ frame buffer resolution for the decoded frames.
|
|
+
|
|
+ ``pixelformat``
|
|
+ pixel format for decoded frames.
|
|
+
|
|
+ ``num_planes`` (for _MPLANE ``type`` only)
|
|
+ number of planes for pixelformat.
|
|
+
|
|
+ ``sizeimage``, ``bytesperline``
|
|
+ as per standard semantics; matching frame buffer format.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ The value of ``pixelformat`` may be any pixel format supported for the
|
|
+ ``OUTPUT`` format, based on the hardware capabilities. It is suggested
|
|
+ that the driver chooses the preferred/optimal format for the current
|
|
+ configuration. For example, a YUV format may be preferred over an RGB
|
|
+ format, if an additional conversion step would be required for RGB.
|
|
+
|
|
+4. *[optional]* Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
|
|
+ the ``CAPTURE`` queue. The client may use this ioctl to discover which
|
|
+ alternative raw formats are supported for the current ``OUTPUT`` format and
|
|
+ select one of them via :c:func:`VIDIOC_S_FMT`.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ The driver will return only formats supported for the currently selected
|
|
+ ``OUTPUT`` format and currently set controls, even if more formats may be
|
|
+ supported by the decoder in general.
|
|
+
|
|
+ For example, a decoder may support YUV and RGB formats for
|
|
+ resolutions 1920x1088 and lower, but only YUV for higher resolutions (due
|
|
+ to hardware limitations). After setting a resolution of 1920x1088 or lower
|
|
+ as the ``OUTPUT`` format, :c:func:`VIDIOC_ENUM_FMT` may return a set of
|
|
+ YUV and RGB pixel formats, but after setting a resolution higher than
|
|
+ 1920x1088, the driver will not return RGB pixel formats, since they are
|
|
+ unsupported for this resolution.
|
|
+
|
|
+5. *[optional]* Choose a different ``CAPTURE`` format than suggested via
|
|
+ :c:func:`VIDIOC_S_FMT` on ``CAPTURE`` queue. It is possible for the client to
|
|
+ choose a different format than selected/suggested by the driver in
|
|
+ :c:func:`VIDIOC_G_FMT`.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``type``
|
|
+ a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
|
|
+
|
|
+ ``pixelformat``
|
|
+ a raw pixel format.
|
|
+
|
|
+ ``width``, ``height``
|
|
+ frame buffer resolution of the decoded stream; typically unchanged from
|
|
+ what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
|
|
+ if the hardware supports composition and/or scaling.
|
|
+
|
|
+ After performing this step, the client must perform step 3 again in order
|
|
+ to obtain up-to-date information about the buffers size and layout.
|
|
+
|
|
+6. Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
|
|
+ ``OUTPUT`` queue.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``count``
|
|
+ requested number of buffers to allocate; greater than zero.
|
|
+
|
|
+ ``type``
|
|
+ a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
|
|
+
|
|
+ ``memory``
|
|
+ follows standard semantics.
|
|
+
|
|
+ * **Return fields:**
|
|
+
|
|
+ ``count``
|
|
+ actual number of buffers allocated.
|
|
+
|
|
+ * If required, the driver will adjust ``count`` to be equal or bigger to the
|
|
+ minimum of required number of ``OUTPUT`` buffers for the given format and
|
|
+ requested count. The client must check this value after the ioctl returns
|
|
+ to get the actual number of buffers allocated.
|
|
+
|
|
+7. Allocate destination (raw format) buffers via :c:func:`VIDIOC_REQBUFS` on the
|
|
+ ``CAPTURE`` queue.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``count``
|
|
+ requested number of buffers to allocate; greater than zero. The client
|
|
+ is responsible for deducing the minimum number of buffers required
|
|
+ for the stream to be properly decoded (taking e.g. reference frames
|
|
+ into account) and pass an equal or bigger number.
|
|
+
|
|
+ ``type``
|
|
+ a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
|
|
+
|
|
+ ``memory``
|
|
+ follows standard semantics. ``V4L2_MEMORY_USERPTR`` is not supported
|
|
+ for ``CAPTURE`` buffers.
|
|
+
|
|
+ * **Return fields:**
|
|
+
|
|
+ ``count``
|
|
+ adjusted to allocated number of buffers, in case the codec requires
|
|
+ more buffers than requested.
|
|
+
|
|
+ * The driver must adjust count to the minimum of required number of
|
|
+ ``CAPTURE`` buffers for the current format, stream configuration and
|
|
+ requested count. The client must check this value after the ioctl
|
|
+ returns to get the number of buffers allocated.
|
|
+
|
|
+8. Allocate requests (likely one per ``OUTPUT`` buffer) via
|
|
+ :c:func:`MEDIA_IOC_REQUEST_ALLOC` on the media device.
|
|
+
|
|
+9. Start streaming on both ``OUTPUT`` and ``CAPTURE`` queues via
|
|
+ :c:func:`VIDIOC_STREAMON`.
|
|
+
|
|
+Decoding
|
|
+========
|
|
+
|
|
+For each frame, the client is responsible for submitting at least one request to
|
|
+which the following is attached:
|
|
+
|
|
+* The amount of encoded data expected by the codec for its current
|
|
+ configuration, as a buffer submitted to the ``OUTPUT`` queue. Typically, this
|
|
+ corresponds to one frame worth of encoded data, but some formats may allow (or
|
|
+ require) different amounts per unit.
|
|
+* All the metadata needed to decode the submitted encoded data, in the form of
|
|
+ controls relevant to the format being decoded.
|
|
+
|
|
+The amount of data and contents of the source ``OUTPUT`` buffer, as well as the
|
|
+controls that must be set on the request, depend on the active coded pixel
|
|
+format and might be affected by codec-specific extended controls, as stated in
|
|
+documentation of each format.
|
|
+
|
|
+If there is a possibility that the decoded frame will require one or more
|
|
+decode requests after the current one in order to be produced, then the client
|
|
+must set the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag on the ``OUTPUT``
|
|
+buffer. This will result in the (potentially partially) decoded ``CAPTURE``
|
|
+buffer not being made available for dequeueing, and reused for the next decode
|
|
+request if the timestamp of the next ``OUTPUT`` buffer has not changed.
|
|
+
|
|
+A typical frame would thus be decoded using the following sequence:
|
|
+
|
|
+1. Queue an ``OUTPUT`` buffer containing one unit of encoded bytestream data for
|
|
+ the decoding request, using :c:func:`VIDIOC_QBUF`.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``index``
|
|
+ index of the buffer being queued.
|
|
+
|
|
+ ``type``
|
|
+ type of the buffer.
|
|
+
|
|
+ ``bytesused``
|
|
+ number of bytes taken by the encoded data frame in the buffer.
|
|
+
|
|
+ ``flags``
|
|
+ the ``V4L2_BUF_FLAG_REQUEST_FD`` flag must be set. Additionally, if
|
|
+ we are not sure that the current decode request is the last one needed
|
|
+ to produce a fully decoded frame, then
|
|
+ ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` must also be set.
|
|
+
|
|
+ ``request_fd``
|
|
+ must be set to the file descriptor of the decoding request.
|
|
+
|
|
+ ``timestamp``
|
|
+ must be set to a unique value per frame. This value will be propagated
|
|
+ into the decoded frame's buffer and can also be used to use this frame
|
|
+ as the reference of another. If using multiple decode requests per
|
|
+ frame, then the timestamps of all the ``OUTPUT`` buffers for a given
|
|
+ frame must be identical. If the timestamp changes, then the currently
|
|
+ held ``CAPTURE`` buffer will be made available for dequeuing and the
|
|
+ current request will work on a new ``CAPTURE`` buffer.
|
|
+
|
|
+2. Set the codec-specific controls for the decoding request, using
|
|
+ :c:func:`VIDIOC_S_EXT_CTRLS`.
|
|
+
|
|
+ * **Required fields:**
|
|
+
|
|
+ ``which``
|
|
+ must be ``V4L2_CTRL_WHICH_REQUEST_VAL``.
|
|
+
|
|
+ ``request_fd``
|
|
+ must be set to the file descriptor of the decoding request.
|
|
+
|
|
+ other fields
|
|
+ other fields are set as usual when setting controls. The ``controls``
|
|
+ array must contain all the codec-specific controls required to decode
|
|
+ a frame.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ It is possible to specify the controls in different invocations of
|
|
+ :c:func:`VIDIOC_S_EXT_CTRLS`, or to overwrite a previously set control, as
|
|
+ long as ``request_fd`` and ``which`` are properly set. The controls state
|
|
+ at the moment of request submission is the one that will be considered.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ The order in which steps 1 and 2 take place is interchangeable.
|
|
+
|
|
+3. Submit the request by invoking :c:func:`MEDIA_REQUEST_IOC_QUEUE` on the
|
|
+ request FD.
|
|
+
|
|
+ If the request is submitted without an ``OUTPUT`` buffer, or if some of the
|
|
+ required controls are missing from the request, then
|
|
+ :c:func:`MEDIA_REQUEST_IOC_QUEUE` will return ``-ENOENT``. If more than one
|
|
+ ``OUTPUT`` buffer is queued, then it will return ``-EINVAL``.
|
|
+ :c:func:`MEDIA_REQUEST_IOC_QUEUE` returning non-zero means that no
|
|
+ ``CAPTURE`` buffer will be produced for this request.
|
|
+
|
|
+``CAPTURE`` buffers must not be part of the request, and are queued
|
|
+independently. They are returned in decode order (i.e. the same order as coded
|
|
+frames were submitted to the ``OUTPUT`` queue).
|
|
+
|
|
+Runtime decoding errors are signaled by the dequeued ``CAPTURE`` buffers
|
|
+carrying the ``V4L2_BUF_FLAG_ERROR`` flag. If a decoded reference frame has an
|
|
+error, then all following decoded frames that refer to it also have the
|
|
+``V4L2_BUF_FLAG_ERROR`` flag set, although the decoder will still try to
|
|
+produce (likely corrupted) frames.
|
|
+
|
|
+Buffer management while decoding
|
|
+================================
|
|
+Contrary to stateful decoders, a stateless decoder does not perform any kind of
|
|
+buffer management: it only guarantees that dequeued ``CAPTURE`` buffers can be
|
|
+used by the client for as long as they are not queued again. "Used" here
|
|
+encompasses using the buffer for compositing or display.
|
|
+
|
|
+A dequeued capture buffer can also be used as the reference frame of another
|
|
+buffer.
|
|
+
|
|
+A frame is specified as reference by converting its timestamp into nanoseconds,
|
|
+and storing it into the relevant member of a codec-dependent control structure.
|
|
+The :c:func:`v4l2_timeval_to_ns` function must be used to perform that
|
|
+conversion. The timestamp of a frame can be used to reference it as soon as all
|
|
+its units of encoded data are successfully submitted to the ``OUTPUT`` queue.
|
|
+
|
|
+A decoded buffer containing a reference frame must not be reused as a decoding
|
|
+target until all the frames referencing it have been decoded. The safest way to
|
|
+achieve this is to refrain from queueing a reference buffer until all the
|
|
+decoded frames referencing it have been dequeued. However, if the driver can
|
|
+guarantee that buffers queued to the ``CAPTURE`` queue are processed in queued
|
|
+order, then user-space can take advantage of this guarantee and queue a
|
|
+reference buffer when the following conditions are met:
|
|
+
|
|
+1. All the requests for frames affected by the reference frame have been
|
|
+ queued, and
|
|
+
|
|
+2. A sufficient number of ``CAPTURE`` buffers to cover all the decoded
|
|
+ referencing frames have been queued.
|
|
+
|
|
+When queuing a decoding request, the driver will increase the reference count of
|
|
+all the resources associated with reference frames. This means that the client
|
|
+can e.g. close the DMABUF file descriptors of reference frame buffers if it
|
|
+won't need them afterwards.
|
|
+
|
|
+Seeking
|
|
+=======
|
|
+In order to seek, the client just needs to submit requests using input buffers
|
|
+corresponding to the new stream position. It must however be aware that
|
|
+resolution may have changed and follow the dynamic resolution change sequence in
|
|
+that case. Also depending on the codec used, picture parameters (e.g. SPS/PPS
|
|
+for H.264) may have changed and the client is responsible for making sure that a
|
|
+valid state is sent to the decoder.
|
|
+
|
|
+The client is then free to ignore any returned ``CAPTURE`` buffer that comes
|
|
+from the pre-seek position.
|
|
+
|
|
+Pausing
|
|
+=======
|
|
+
|
|
+In order to pause, the client can just cease queuing buffers onto the ``OUTPUT``
|
|
+queue. Without source bytestream data, there is no data to process and the codec
|
|
+will remain idle.
|
|
+
|
|
+Dynamic resolution change
|
|
+=========================
|
|
+
|
|
+If the client detects a resolution change in the stream, it will need to perform
|
|
+the initialization sequence again with the new resolution:
|
|
+
|
|
+1. If the last submitted request resulted in a ``CAPTURE`` buffer being
|
|
+ held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
|
|
+ last frame is not available on the ``CAPTURE`` queue. In this case, a
|
|
+ ``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
|
|
+ dequeue the held ``CAPTURE`` buffer.
|
|
+
|
|
+2. Wait until all submitted requests have completed and dequeue the
|
|
+ corresponding output buffers.
|
|
+
|
|
+3. Call :c:func:`VIDIOC_STREAMOFF` on both the ``OUTPUT`` and ``CAPTURE``
|
|
+ queues.
|
|
+
|
|
+4. Free all ``CAPTURE`` buffers by calling :c:func:`VIDIOC_REQBUFS` on the
|
|
+ ``CAPTURE`` queue with a buffer count of zero.
|
|
+
|
|
+5. Perform the initialization sequence again (minus the allocation of
|
|
+ ``OUTPUT`` buffers), with the new resolution set on the ``OUTPUT`` queue.
|
|
+ Note that due to resolution constraints, a different format may need to be
|
|
+ picked on the ``CAPTURE`` queue.
|
|
+
|
|
+Drain
|
|
+=====
|
|
+
|
|
+If the last submitted request resulted in a ``CAPTURE`` buffer being
|
|
+held by the use of the ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag, then the
|
|
+last frame is not available on the ``CAPTURE`` queue. In this case, a
|
|
+``V4L2_DEC_CMD_FLUSH`` command shall be sent. This will make the driver
|
|
+dequeue the held ``CAPTURE`` buffer.
|
|
+
|
|
+After that, in order to drain the stream on a stateless decoder, the client
|
|
+just needs to wait until all the submitted requests are completed.
|
|
|
|
From c7bb71e7ba07fe201694af8cf0b7aa3ba9cb740e Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Mon, 14 Oct 2019 05:40:19 -0300
|
|
Subject: [PATCH] media: v4l2-core: correctly validate video and metadata
|
|
ioctls
|
|
|
|
If the type is VFL_TYPE_GRABBER, then also check device_caps
|
|
to see if the video device supports video and/or metadata and
|
|
disable unneeded ioctls.
|
|
|
|
Without this change, format ioctls for both video and metadata devices
|
|
could be called on both device nodes. This is true for other ioctls as
|
|
well, even if the device supports only video or metadata.
|
|
|
|
Metadata devices act similar to VBI devices w.r.t. which ioctls should
|
|
be enabled. This makes sense since VBI *is* metadata.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Co-developed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 96f49c1ac370c23ae55c63c67a0b40d83928bfbd)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dev.c | 62 +++++++++++++++++++++++-------------
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 16 ++++++++--
|
|
2 files changed, 52 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
|
|
index 4037689a945a..1bf543932e4f 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dev.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dev.c
|
|
@@ -533,13 +533,23 @@ static int get_index(struct video_device *vdev)
|
|
*/
|
|
static void determine_valid_ioctls(struct video_device *vdev)
|
|
{
|
|
+ const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
|
|
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
|
+ V4L2_CAP_VIDEO_OUTPUT |
|
|
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
|
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
|
|
+ const u32 meta_caps = V4L2_CAP_META_CAPTURE |
|
|
+ V4L2_CAP_META_OUTPUT;
|
|
DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
|
|
const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
|
|
- bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
|
|
+ bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER &&
|
|
+ (vdev->device_caps & vid_caps);
|
|
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
|
|
bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
|
|
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
|
|
bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
|
|
+ bool is_meta = vdev->vfl_type == VFL_TYPE_GRABBER &&
|
|
+ (vdev->device_caps & meta_caps);
|
|
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
|
|
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
|
|
|
|
@@ -587,39 +597,31 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
|
|
|
|
if (is_vid || is_tch) {
|
|
- /* video and metadata specific ioctls */
|
|
+ /* video and touch specific ioctls */
|
|
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
|
|
- ops->vidioc_enum_fmt_vid_overlay ||
|
|
- ops->vidioc_enum_fmt_meta_cap)) ||
|
|
- (is_tx && (ops->vidioc_enum_fmt_vid_out ||
|
|
- ops->vidioc_enum_fmt_meta_out)))
|
|
+ ops->vidioc_enum_fmt_vid_overlay)) ||
|
|
+ (is_tx && ops->vidioc_enum_fmt_vid_out))
|
|
set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
|
|
if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
|
|
ops->vidioc_g_fmt_vid_cap_mplane ||
|
|
- ops->vidioc_g_fmt_vid_overlay ||
|
|
- ops->vidioc_g_fmt_meta_cap)) ||
|
|
+ ops->vidioc_g_fmt_vid_overlay)) ||
|
|
(is_tx && (ops->vidioc_g_fmt_vid_out ||
|
|
ops->vidioc_g_fmt_vid_out_mplane ||
|
|
- ops->vidioc_g_fmt_vid_out_overlay ||
|
|
- ops->vidioc_g_fmt_meta_out)))
|
|
+ ops->vidioc_g_fmt_vid_out_overlay)))
|
|
set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
|
|
if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
|
|
ops->vidioc_s_fmt_vid_cap_mplane ||
|
|
- ops->vidioc_s_fmt_vid_overlay ||
|
|
- ops->vidioc_s_fmt_meta_cap)) ||
|
|
+ ops->vidioc_s_fmt_vid_overlay)) ||
|
|
(is_tx && (ops->vidioc_s_fmt_vid_out ||
|
|
ops->vidioc_s_fmt_vid_out_mplane ||
|
|
- ops->vidioc_s_fmt_vid_out_overlay ||
|
|
- ops->vidioc_s_fmt_meta_out)))
|
|
+ ops->vidioc_s_fmt_vid_out_overlay)))
|
|
set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
|
|
if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
|
|
ops->vidioc_try_fmt_vid_cap_mplane ||
|
|
- ops->vidioc_try_fmt_vid_overlay ||
|
|
- ops->vidioc_try_fmt_meta_cap)) ||
|
|
+ ops->vidioc_try_fmt_vid_overlay)) ||
|
|
(is_tx && (ops->vidioc_try_fmt_vid_out ||
|
|
ops->vidioc_try_fmt_vid_out_mplane ||
|
|
- ops->vidioc_try_fmt_vid_out_overlay ||
|
|
- ops->vidioc_try_fmt_meta_out)))
|
|
+ ops->vidioc_try_fmt_vid_out_overlay)))
|
|
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
|
|
@@ -641,7 +643,21 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection);
|
|
- } else if (is_vbi) {
|
|
+ }
|
|
+ if (is_meta && is_rx) {
|
|
+ /* metadata capture specific ioctls */
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_cap);
|
|
+ } else if (is_meta && is_tx) {
|
|
+ /* metadata output specific ioctls */
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out);
|
|
+ }
|
|
+ if (is_vbi) {
|
|
/* vbi specific ioctls */
|
|
if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||
|
|
ops->vidioc_g_fmt_sliced_vbi_cap)) ||
|
|
@@ -681,8 +697,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
|
|
}
|
|
|
|
- if (is_vid || is_vbi || is_sdr || is_tch) {
|
|
- /* ioctls valid for video, metadata, vbi or sdr */
|
|
+ if (is_vid || is_vbi || is_sdr || is_tch || is_meta) {
|
|
+ /* ioctls valid for video, vbi, sdr, touch and metadata */
|
|
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
|
|
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
|
|
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
|
|
@@ -694,8 +710,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
|
|
}
|
|
|
|
- if (is_vid || is_vbi || is_tch) {
|
|
- /* ioctls valid for video or vbi */
|
|
+ if (is_vid || is_vbi || is_tch || is_meta) {
|
|
+ /* ioctls valid for video, vbi, touch and metadata */
|
|
if (ops->vidioc_s_std)
|
|
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index 51b912743f0f..20b3107dd4e8 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -932,12 +932,22 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
|
|
|
|
static int check_fmt(struct file *file, enum v4l2_buf_type type)
|
|
{
|
|
+ const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE |
|
|
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE |
|
|
+ V4L2_CAP_VIDEO_OUTPUT |
|
|
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE |
|
|
+ V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE;
|
|
+ const u32 meta_caps = V4L2_CAP_META_CAPTURE |
|
|
+ V4L2_CAP_META_OUTPUT;
|
|
struct video_device *vfd = video_devdata(file);
|
|
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
|
|
- bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
|
|
+ bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER &&
|
|
+ (vfd->device_caps & vid_caps);
|
|
bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
|
|
bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
|
|
bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
|
|
+ bool is_meta = vfd->vfl_type == VFL_TYPE_GRABBER &&
|
|
+ (vfd->device_caps & meta_caps);
|
|
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
|
|
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
|
|
|
|
@@ -996,11 +1006,11 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
|
|
return 0;
|
|
break;
|
|
case V4L2_BUF_TYPE_META_CAPTURE:
|
|
- if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
|
|
+ if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap)
|
|
return 0;
|
|
break;
|
|
case V4L2_BUF_TYPE_META_OUTPUT:
|
|
- if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out)
|
|
+ if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
|
|
return 0;
|
|
break;
|
|
default:
|
|
|
|
From 2e0e6d619dd52d6ee65329ce4af6d32efd4c05a0 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Mon, 14 Oct 2019 05:40:20 -0300
|
|
Subject: [PATCH] media: v4l2-dev: simplify the SDR checks
|
|
|
|
In determine_valid_ioctls() we can use SET_VALID_IOCTL to enable
|
|
ioctls for SDR, simplifying the code.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 8e72244b4e8f1a163d358c271f39c737b5b8106a)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dev.c | 24 ++++++++----------------
|
|
1 file changed, 8 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
|
|
index 1bf543932e4f..27fb96a6c2a8 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dev.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dev.c
|
|
@@ -677,24 +677,16 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
|
|
} else if (is_sdr && is_rx) {
|
|
/* SDR receiver specific ioctls */
|
|
- if (ops->vidioc_enum_fmt_sdr_cap)
|
|
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
|
|
- if (ops->vidioc_g_fmt_sdr_cap)
|
|
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
|
|
- if (ops->vidioc_s_fmt_sdr_cap)
|
|
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
|
|
- if (ops->vidioc_try_fmt_sdr_cap)
|
|
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_cap);
|
|
} else if (is_sdr && is_tx) {
|
|
/* SDR transmitter specific ioctls */
|
|
- if (ops->vidioc_enum_fmt_sdr_out)
|
|
- set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
|
|
- if (ops->vidioc_g_fmt_sdr_out)
|
|
- set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
|
|
- if (ops->vidioc_s_fmt_sdr_out)
|
|
- set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
|
|
- if (ops->vidioc_try_fmt_sdr_out)
|
|
- set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_sdr_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_sdr_out);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_sdr_out);
|
|
}
|
|
|
|
if (is_vid || is_vbi || is_sdr || is_tch || is_meta) {
|
|
|
|
From c26845f8a3a5a4963c90e5822c849bfdecd2f9a3 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Mon, 14 Oct 2019 05:40:21 -0300
|
|
Subject: [PATCH] media: v4l2-dev: fix is_tch checks
|
|
|
|
Touch devices mark too many ioctls as valid. Restrict the list of
|
|
valid ioctls for touch devices.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 4fbd54bbd24360c28ceec2ae9ee2c950b743aee1)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dev.c | 24 ++++++++++++++++++------
|
|
1 file changed, 18 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
|
|
index 27fb96a6c2a8..cec588b04711 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dev.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dev.c
|
|
@@ -596,8 +596,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator)
|
|
set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls);
|
|
|
|
- if (is_vid || is_tch) {
|
|
- /* video and touch specific ioctls */
|
|
+ if (is_vid) {
|
|
+ /* video specific ioctls */
|
|
if ((is_rx && (ops->vidioc_enum_fmt_vid_cap ||
|
|
ops->vidioc_enum_fmt_vid_overlay)) ||
|
|
(is_tx && ops->vidioc_enum_fmt_vid_out))
|
|
@@ -675,6 +675,19 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
ops->vidioc_try_fmt_sliced_vbi_out)))
|
|
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
|
|
+ } else if (is_tch) {
|
|
+ /* touch specific ioctls */
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_vid_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_vid_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_vid_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_vid_cap);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_PARM, vidioc_g_parm);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
|
|
} else if (is_sdr && is_rx) {
|
|
/* SDR receiver specific ioctls */
|
|
SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_sdr_cap);
|
|
@@ -702,8 +715,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
|
|
}
|
|
|
|
- if (is_vid || is_vbi || is_tch || is_meta) {
|
|
- /* ioctls valid for video, vbi, touch and metadata */
|
|
+ if (is_vid || is_vbi || is_meta) {
|
|
+ /* ioctls valid for video, vbi and metadata */
|
|
if (ops->vidioc_s_std)
|
|
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
|
|
@@ -727,8 +740,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout);
|
|
}
|
|
- if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
|
|
- ops->vidioc_g_std))
|
|
+ if (ops->vidioc_g_parm || ops->vidioc_g_std)
|
|
set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
|
|
|
|
From e9974421002243362d9757a2954e35d5d7d9d73d Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Mon, 14 Oct 2019 09:01:05 -0300
|
|
Subject: [PATCH] media: v4l2-dev: disable frequency and tuner ioctls for touch
|
|
|
|
Touch devices have obviously no tuner, so don't attempt to enable those
|
|
ioctls for such devices.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 8669d8474a58268295414b9f78a41659698bdb87)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dev.c | 8 +++++---
|
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
|
|
index cec588b04711..da42d172714a 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dev.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dev.c
|
|
@@ -581,8 +581,10 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls);
|
|
if (vdev->ctrl_handler || ops->vidioc_querymenu)
|
|
set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls);
|
|
- SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
|
|
- SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
|
|
+ if (!is_tch) {
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency);
|
|
+ SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency);
|
|
+ }
|
|
SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status);
|
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
|
set_bit(_IOC_NR(VIDIOC_DBG_G_CHIP_INFO), valid_ioctls);
|
|
@@ -754,7 +756,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
|
|
}
|
|
- if (is_rx) {
|
|
+ if (is_rx && !is_tch) {
|
|
/* receiver only ioctls */
|
|
SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner);
|
|
SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner);
|
|
|
|
From 0286e347bad26e4af45140c9fd086c593bfb6d87 Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Tue, 15 Oct 2019 07:40:15 -0300
|
|
Subject: [PATCH] media: vivid: Add metadata capture support
|
|
|
|
This patch adds meatadata capture support in vivid driver.
|
|
Adds new files for metadata capture.
|
|
Adds vivid controls to generate PTS and SCR for metadata stream.
|
|
also fixes v4l2-compliance issues seen on metadata device.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit d5797cf685a0a3310457d89ef640be68a1de0743)
|
|
---
|
|
drivers/media/platform/vivid/Makefile | 2 +-
|
|
drivers/media/platform/vivid/vivid-core.c | 109 +++++++++++-
|
|
drivers/media/platform/vivid/vivid-core.h | 14 ++
|
|
drivers/media/platform/vivid/vivid-ctrls.c | 65 ++++++++
|
|
drivers/media/platform/vivid/vivid-kthread-cap.c | 54 +++++-
|
|
drivers/media/platform/vivid/vivid-meta-cap.c | 201 +++++++++++++++++++++++
|
|
drivers/media/platform/vivid/vivid-meta-cap.h | 29 ++++
|
|
drivers/media/platform/vivid/vivid-vid-cap.c | 5 +-
|
|
8 files changed, 465 insertions(+), 14 deletions(-)
|
|
create mode 100644 drivers/media/platform/vivid/vivid-meta-cap.c
|
|
create mode 100644 drivers/media/platform/vivid/vivid-meta-cap.h
|
|
|
|
diff --git a/drivers/media/platform/vivid/Makefile b/drivers/media/platform/vivid/Makefile
|
|
index 2f5762e3309a..af94abf9bce6 100644
|
|
--- a/drivers/media/platform/vivid/Makefile
|
|
+++ b/drivers/media/platform/vivid/Makefile
|
|
@@ -3,7 +3,7 @@ vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
|
|
vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
|
|
vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
|
|
vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
|
|
- vivid-osd.o
|
|
+ vivid-osd.o vivid-meta-cap.o
|
|
ifeq ($(CONFIG_VIDEO_VIVID_CEC),y)
|
|
vivid-objs += vivid-cec.o
|
|
endif
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
|
|
index 53315c8dd2bb..a44984536ad0 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.c
|
|
+++ b/drivers/media/platform/vivid/vivid-core.c
|
|
@@ -37,6 +37,7 @@
|
|
#include "vivid-osd.h"
|
|
#include "vivid-cec.h"
|
|
#include "vivid-ctrls.h"
|
|
+#include "vivid-meta-cap.h"
|
|
|
|
#define VIVID_MODULE_NAME "vivid"
|
|
|
|
@@ -79,6 +80,10 @@ static int radio_tx_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
module_param_array(radio_tx_nr, int, NULL, 0444);
|
|
MODULE_PARM_DESC(radio_tx_nr, " radioX start number, -1 is autodetect");
|
|
|
|
+static int meta_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
+module_param_array(meta_cap_nr, int, NULL, 0444);
|
|
+MODULE_PARM_DESC(meta_cap_nr, " videoX start number, -1 is autodetect");
|
|
+
|
|
static int ccs_cap_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
module_param_array(ccs_cap_mode, int, NULL, 0444);
|
|
MODULE_PARM_DESC(ccs_cap_mode, " capture crop/compose/scale mode:\n"
|
|
@@ -95,10 +100,15 @@ static unsigned multiplanar[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 1
|
|
module_param_array(multiplanar, uint, NULL, 0444);
|
|
MODULE_PARM_DESC(multiplanar, " 1 (default) creates a single planar device, 2 creates a multiplanar device.");
|
|
|
|
-/* Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr + vbi-out + vid-out */
|
|
-static unsigned node_types[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 0x1d3d };
|
|
+/*
|
|
+ * Default: video + vbi-cap (raw and sliced) + radio rx + radio tx + sdr +
|
|
+ * vbi-out + vid-out + meta-cap
|
|
+ */
|
|
+static unsigned int node_types[VIVID_MAX_DEVS] = {
|
|
+ [0 ... (VIVID_MAX_DEVS - 1)] = 0x21d3d
|
|
+};
|
|
module_param_array(node_types, uint, NULL, 0444);
|
|
-MODULE_PARM_DESC(node_types, " node types, default is 0x1d3d. Bitmask with the following meaning:\n"
|
|
+MODULE_PARM_DESC(node_types, " node types, default is 0x21d3d. Bitmask with the following meaning:\n"
|
|
"\t\t bit 0: Video Capture node\n"
|
|
"\t\t bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
|
|
"\t\t bit 4: Radio Receiver node\n"
|
|
@@ -106,7 +116,8 @@ MODULE_PARM_DESC(node_types, " node types, default is 0x1d3d. Bitmask with the f
|
|
"\t\t bit 8: Video Output node\n"
|
|
"\t\t bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
|
|
"\t\t bit 12: Radio Transmitter node\n"
|
|
- "\t\t bit 16: Framebuffer for testing overlays");
|
|
+ "\t\t bit 16: Framebuffer for testing overlays\n"
|
|
+ "\t\t bit 17: Metadata Capture node\n");
|
|
|
|
/* Default: 4 inputs */
|
|
static unsigned num_inputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 4 };
|
|
@@ -205,7 +216,7 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|
cap->capabilities = dev->vid_cap_caps | dev->vid_out_caps |
|
|
dev->vbi_cap_caps | dev->vbi_out_caps |
|
|
dev->radio_rx_caps | dev->radio_tx_caps |
|
|
- dev->sdr_cap_caps | V4L2_CAP_DEVICE_CAPS;
|
|
+ dev->sdr_cap_caps | dev->meta_cap_caps | V4L2_CAP_DEVICE_CAPS;
|
|
return 0;
|
|
}
|
|
|
|
@@ -433,7 +444,8 @@ static bool vivid_is_last_user(struct vivid_dev *dev)
|
|
vivid_is_in_use(&dev->vbi_out_dev) +
|
|
vivid_is_in_use(&dev->sdr_cap_dev) +
|
|
vivid_is_in_use(&dev->radio_rx_dev) +
|
|
- vivid_is_in_use(&dev->radio_tx_dev);
|
|
+ vivid_is_in_use(&dev->radio_tx_dev) +
|
|
+ vivid_is_in_use(&dev->meta_cap_dev);
|
|
|
|
return uses == 1;
|
|
}
|
|
@@ -459,6 +471,7 @@ static int vivid_fop_release(struct file *file)
|
|
set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
|
|
set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
|
|
set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
|
|
+ set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
|
|
}
|
|
mutex_unlock(&dev->mutex);
|
|
if (file->private_data == dev->overlay_cap_owner)
|
|
@@ -604,6 +617,11 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
|
|
.vidioc_log_status = vidioc_log_status,
|
|
.vidioc_subscribe_event = vidioc_subscribe_event,
|
|
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
|
+
|
|
+ .vidioc_enum_fmt_meta_cap = vidioc_enum_fmt_meta_cap,
|
|
+ .vidioc_g_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
+ .vidioc_s_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
+ .vidioc_try_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
};
|
|
|
|
/* -----------------------------------------------------------------
|
|
@@ -818,6 +836,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->has_scaler_out ? 'Y' : 'N');
|
|
}
|
|
|
|
+ /* do we create a meta capture device */
|
|
+ dev->has_meta_cap = node_type & 0x20000;
|
|
+
|
|
/* end detecting feature set */
|
|
|
|
if (dev->has_vid_cap) {
|
|
@@ -875,6 +896,16 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->radio_tx_caps = V4L2_CAP_RDS_OUTPUT | V4L2_CAP_MODULATOR |
|
|
V4L2_CAP_READWRITE;
|
|
|
|
+ /* set up the capabilities of meta capture device */
|
|
+ if (dev->has_meta_cap) {
|
|
+ dev->meta_cap_caps = V4L2_CAP_META_CAPTURE |
|
|
+ V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
|
+ if (dev->has_audio_inputs)
|
|
+ dev->meta_cap_caps |= V4L2_CAP_AUDIO;
|
|
+ if (in_type_counter[TV])
|
|
+ dev->meta_cap_caps |= V4L2_CAP_TUNER;
|
|
+ }
|
|
+
|
|
ret = -ENOMEM;
|
|
/* initialize the test pattern generator */
|
|
tpg_init(&dev->tpg, 640, 360);
|
|
@@ -934,6 +965,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_AUDIO);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_AUDIO);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_ENUMAUDIO);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_AUDIO);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_AUDIO);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_ENUMAUDIO);
|
|
}
|
|
if (!dev->has_audio_outputs) {
|
|
v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_AUDOUT);
|
|
@@ -959,12 +993,16 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_FREQUENCY);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_FREQUENCY);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_FREQUENCY);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_FREQUENCY);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_FREQUENCY);
|
|
}
|
|
if (!has_tuner) {
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_TUNER);
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_G_TUNER);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_TUNER);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_G_TUNER);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_TUNER);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_G_TUNER);
|
|
}
|
|
if (in_type_counter[HDMI] == 0) {
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_EDID);
|
|
@@ -990,6 +1028,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
|
|
v4l2_disable_ioctl(&dev->vbi_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
|
|
v4l2_disable_ioctl(&dev->sdr_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
|
|
+ v4l2_disable_ioctl(&dev->meta_cap_dev, VIDIOC_S_HW_FREQ_SEEK);
|
|
v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_S_FREQUENCY);
|
|
v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_G_FREQUENCY);
|
|
v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMESIZES);
|
|
@@ -1078,6 +1117,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
INIT_LIST_HEAD(&dev->vbi_cap_active);
|
|
INIT_LIST_HEAD(&dev->vbi_out_active);
|
|
INIT_LIST_HEAD(&dev->sdr_cap_active);
|
|
+ INIT_LIST_HEAD(&dev->meta_cap_active);
|
|
|
|
INIT_LIST_HEAD(&dev->cec_work_list);
|
|
spin_lock_init(&dev->cec_slock);
|
|
@@ -1225,6 +1265,27 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->fb_info.node);
|
|
}
|
|
|
|
+ if (dev->has_meta_cap) {
|
|
+ /* initialize meta_cap queue */
|
|
+ q = &dev->vb_meta_cap_q;
|
|
+ q->type = V4L2_BUF_TYPE_META_CAPTURE;
|
|
+ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
|
+ if (!allocator)
|
|
+ q->io_modes |= VB2_USERPTR;
|
|
+ q->drv_priv = dev;
|
|
+ q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
+ q->ops = &vivid_meta_cap_qops;
|
|
+ q->mem_ops = vivid_mem_ops[allocator];
|
|
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
+ q->min_buffers_needed = 2;
|
|
+ q->lock = &dev->mutex;
|
|
+ q->dev = dev->v4l2_dev.dev;
|
|
+ q->supports_requests = true;
|
|
+ ret = vb2_queue_init(q);
|
|
+ if (ret)
|
|
+ goto unreg_dev;
|
|
+ }
|
|
+
|
|
#ifdef CONFIG_VIDEO_VIVID_CEC
|
|
if (dev->has_vid_cap && in_type_counter[HDMI]) {
|
|
struct cec_adapter *adap;
|
|
@@ -1265,6 +1326,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_rx);
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
|
|
+ v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
|
|
|
|
/* finally start creating the device nodes */
|
|
if (dev->has_vid_cap) {
|
|
@@ -1492,6 +1554,35 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
video_device_node_name(vfd));
|
|
}
|
|
|
|
+ if (dev->has_meta_cap) {
|
|
+ vfd = &dev->meta_cap_dev;
|
|
+ snprintf(vfd->name, sizeof(vfd->name),
|
|
+ "vivid-%03d-meta-cap", inst);
|
|
+ vfd->fops = &vivid_fops;
|
|
+ vfd->ioctl_ops = &vivid_ioctl_ops;
|
|
+ vfd->device_caps = dev->meta_cap_caps;
|
|
+ vfd->release = video_device_release_empty;
|
|
+ vfd->v4l2_dev = &dev->v4l2_dev;
|
|
+ vfd->queue = &dev->vb_meta_cap_q;
|
|
+ vfd->lock = &dev->mutex;
|
|
+ vfd->tvnorms = tvnorms_cap;
|
|
+ video_set_drvdata(vfd, dev);
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
+ dev->meta_cap_pad.flags = MEDIA_PAD_FL_SINK;
|
|
+ ret = media_entity_pads_init(&vfd->entity, 1,
|
|
+ &dev->meta_cap_pad);
|
|
+ if (ret)
|
|
+ goto unreg_dev;
|
|
+#endif
|
|
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER,
|
|
+ meta_cap_nr[inst]);
|
|
+ if (ret < 0)
|
|
+ goto unreg_dev;
|
|
+ v4l2_info(&dev->v4l2_dev,
|
|
+ "V4L2 metadata capture device registered as %s\n",
|
|
+ video_device_node_name(vfd));
|
|
+ }
|
|
+
|
|
#ifdef CONFIG_MEDIA_CONTROLLER
|
|
/* Register the media device */
|
|
ret = media_device_register(&dev->mdev);
|
|
@@ -1508,6 +1599,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
return 0;
|
|
|
|
unreg_dev:
|
|
+ video_unregister_device(&dev->meta_cap_dev);
|
|
video_unregister_device(&dev->radio_tx_dev);
|
|
video_unregister_device(&dev->radio_rx_dev);
|
|
video_unregister_device(&dev->sdr_cap_dev);
|
|
@@ -1624,6 +1716,11 @@ static int vivid_remove(struct platform_device *pdev)
|
|
unregister_framebuffer(&dev->fb_info);
|
|
vivid_fb_release_buffers(dev);
|
|
}
|
|
+ if (dev->has_meta_cap) {
|
|
+ v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
|
|
+ video_device_node_name(&dev->meta_cap_dev));
|
|
+ video_unregister_device(&dev->meta_cap_dev);
|
|
+ }
|
|
cec_unregister_adapter(dev->cec_rx_adap);
|
|
for (j = 0; j < MAX_OUTPUTS; j++)
|
|
cec_unregister_adapter(dev->cec_tx_adap[j]);
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
|
|
index 7ebb14673c75..fd601345a17c 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.h
|
|
+++ b/drivers/media/platform/vivid/vivid-core.h
|
|
@@ -131,6 +131,7 @@ struct vivid_dev {
|
|
struct media_pad vbi_cap_pad;
|
|
struct media_pad vbi_out_pad;
|
|
struct media_pad sdr_cap_pad;
|
|
+ struct media_pad meta_cap_pad;
|
|
#endif
|
|
struct v4l2_ctrl_handler ctrl_hdl_user_gen;
|
|
struct v4l2_ctrl_handler ctrl_hdl_user_vid;
|
|
@@ -153,6 +154,9 @@ struct vivid_dev {
|
|
struct v4l2_ctrl_handler ctrl_hdl_radio_tx;
|
|
struct video_device sdr_cap_dev;
|
|
struct v4l2_ctrl_handler ctrl_hdl_sdr_cap;
|
|
+ struct video_device meta_cap_dev;
|
|
+ struct v4l2_ctrl_handler ctrl_hdl_meta_cap;
|
|
+
|
|
spinlock_t slock;
|
|
struct mutex mutex;
|
|
|
|
@@ -164,6 +168,7 @@ struct vivid_dev {
|
|
u32 sdr_cap_caps;
|
|
u32 radio_rx_caps;
|
|
u32 radio_tx_caps;
|
|
+ u32 meta_cap_caps;
|
|
|
|
/* supported features */
|
|
bool multiplanar;
|
|
@@ -189,6 +194,7 @@ struct vivid_dev {
|
|
bool has_radio_tx;
|
|
bool has_sdr_cap;
|
|
bool has_fb;
|
|
+ bool has_meta_cap;
|
|
|
|
bool can_loop_video;
|
|
|
|
@@ -390,6 +396,8 @@ struct vivid_dev {
|
|
struct list_head vid_cap_active;
|
|
struct vb2_queue vb_vbi_cap_q;
|
|
struct list_head vbi_cap_active;
|
|
+ struct vb2_queue vb_meta_cap_q;
|
|
+ struct list_head meta_cap_active;
|
|
|
|
/* thread for generating video capture stream */
|
|
struct task_struct *kthread_vid_cap;
|
|
@@ -407,6 +415,9 @@ struct vivid_dev {
|
|
u32 vbi_cap_seq_count;
|
|
bool vbi_cap_streaming;
|
|
bool stream_sliced_vbi_cap;
|
|
+ u32 meta_cap_seq_start;
|
|
+ u32 meta_cap_seq_count;
|
|
+ bool meta_cap_streaming;
|
|
|
|
/* video output */
|
|
const struct vivid_fmt *fmt_out;
|
|
@@ -527,6 +538,9 @@ struct vivid_dev {
|
|
/* CEC OSD String */
|
|
char osd[14];
|
|
unsigned long osd_jiffies;
|
|
+
|
|
+ bool meta_pts;
|
|
+ bool meta_scr;
|
|
};
|
|
|
|
static inline bool vivid_is_webcam(const struct vivid_dev *dev)
|
|
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
index cb19a9a73092..36e5944b51bb 100644
|
|
--- a/drivers/media/platform/vivid/vivid-ctrls.c
|
|
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
@@ -94,6 +94,9 @@
|
|
|
|
#define VIVID_CID_SDR_CAP_FM_DEVIATION (VIVID_CID_VIVID_BASE + 110)
|
|
|
|
+#define VIVID_CID_META_CAP_GENERATE_PTS (VIVID_CID_VIVID_BASE + 111)
|
|
+#define VIVID_CID_META_CAP_GENERATE_SCR (VIVID_CID_VIVID_BASE + 112)
|
|
+
|
|
/* General User Controls */
|
|
|
|
static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
@@ -110,6 +113,7 @@ static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
|
|
clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
|
|
clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
|
|
+ clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
|
|
break;
|
|
case VIVID_CID_BUTTON:
|
|
dev->button_pressed = 30;
|
|
@@ -1421,6 +1425,47 @@ static const struct v4l2_ctrl_config vivid_ctrl_sdr_cap_fm_deviation = {
|
|
.step = 1,
|
|
};
|
|
|
|
+/* Metadata Capture Control */
|
|
+
|
|
+static int vivid_meta_cap_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
+{
|
|
+ struct vivid_dev *dev = container_of(ctrl->handler, struct vivid_dev,
|
|
+ ctrl_hdl_meta_cap);
|
|
+
|
|
+ switch (ctrl->id) {
|
|
+ case VIVID_CID_META_CAP_GENERATE_PTS:
|
|
+ dev->meta_pts = ctrl->val;
|
|
+ break;
|
|
+ case VIVID_CID_META_CAP_GENERATE_SCR:
|
|
+ dev->meta_scr = ctrl->val;
|
|
+ break;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct v4l2_ctrl_ops vivid_meta_cap_ctrl_ops = {
|
|
+ .s_ctrl = vivid_meta_cap_s_ctrl,
|
|
+};
|
|
+
|
|
+static const struct v4l2_ctrl_config vivid_ctrl_meta_has_pts = {
|
|
+ .ops = &vivid_meta_cap_ctrl_ops,
|
|
+ .id = VIVID_CID_META_CAP_GENERATE_PTS,
|
|
+ .name = "Generate PTS",
|
|
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
+ .max = 1,
|
|
+ .def = 1,
|
|
+ .step = 1,
|
|
+};
|
|
+
|
|
+static const struct v4l2_ctrl_config vivid_ctrl_meta_has_src_clk = {
|
|
+ .ops = &vivid_meta_cap_ctrl_ops,
|
|
+ .id = VIVID_CID_META_CAP_GENERATE_SCR,
|
|
+ .name = "Generate SCR",
|
|
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
+ .max = 1,
|
|
+ .def = 1,
|
|
+ .step = 1,
|
|
+};
|
|
|
|
static const struct v4l2_ctrl_config vivid_ctrl_class = {
|
|
.ops = &vivid_user_gen_ctrl_ops,
|
|
@@ -1448,6 +1493,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
struct v4l2_ctrl_handler *hdl_radio_rx = &dev->ctrl_hdl_radio_rx;
|
|
struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
|
|
struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
|
|
+ struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
|
|
+
|
|
struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
|
|
.ops = &vivid_vid_cap_ctrl_ops,
|
|
.id = VIVID_CID_DV_TIMINGS,
|
|
@@ -1486,6 +1533,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
v4l2_ctrl_new_custom(hdl_radio_tx, &vivid_ctrl_class, NULL);
|
|
v4l2_ctrl_handler_init(hdl_sdr_cap, 19);
|
|
v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
|
|
+ v4l2_ctrl_handler_init(hdl_meta_cap, 2);
|
|
+ v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
|
|
|
|
/* User Controls */
|
|
dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
|
|
@@ -1743,6 +1792,13 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
v4l2_ctrl_new_custom(hdl_sdr_cap,
|
|
&vivid_ctrl_sdr_cap_fm_deviation, NULL);
|
|
}
|
|
+ if (dev->has_meta_cap) {
|
|
+ v4l2_ctrl_new_custom(hdl_meta_cap,
|
|
+ &vivid_ctrl_meta_has_pts, NULL);
|
|
+ v4l2_ctrl_new_custom(hdl_meta_cap,
|
|
+ &vivid_ctrl_meta_has_src_clk, NULL);
|
|
+ }
|
|
+
|
|
if (hdl_user_gen->error)
|
|
return hdl_user_gen->error;
|
|
if (hdl_user_vid->error)
|
|
@@ -1817,6 +1873,14 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
return hdl_sdr_cap->error;
|
|
dev->sdr_cap_dev.ctrl_handler = hdl_sdr_cap;
|
|
}
|
|
+ if (dev->has_meta_cap) {
|
|
+ v4l2_ctrl_add_handler(hdl_meta_cap, hdl_user_gen, NULL, false);
|
|
+ v4l2_ctrl_add_handler(hdl_meta_cap, hdl_streaming, NULL, false);
|
|
+ if (hdl_meta_cap->error)
|
|
+ return hdl_meta_cap->error;
|
|
+ dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -1836,4 +1900,5 @@ void vivid_free_controls(struct vivid_dev *dev)
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
|
|
+ v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
|
|
}
|
|
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
index 003319d7816d..9f981e8bae6e 100644
|
|
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
@@ -39,6 +39,7 @@
|
|
#include "vivid-osd.h"
|
|
#include "vivid-ctrls.h"
|
|
#include "vivid-kthread-cap.h"
|
|
+#include "vivid-meta-cap.h"
|
|
|
|
static inline v4l2_std_id vivid_get_std_cap(const struct vivid_dev *dev)
|
|
{
|
|
@@ -677,6 +678,7 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
|
|
{
|
|
struct vivid_buffer *vid_cap_buf = NULL;
|
|
struct vivid_buffer *vbi_cap_buf = NULL;
|
|
+ struct vivid_buffer *meta_cap_buf = NULL;
|
|
u64 f_time = 0;
|
|
|
|
dprintk(dev, 1, "Video Capture Thread Tick\n");
|
|
@@ -704,15 +706,19 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
|
|
list_del(&vbi_cap_buf->list);
|
|
}
|
|
}
|
|
+ if (!list_empty(&dev->meta_cap_active)) {
|
|
+ meta_cap_buf = list_entry(dev->meta_cap_active.next,
|
|
+ struct vivid_buffer, list);
|
|
+ list_del(&meta_cap_buf->list);
|
|
+ }
|
|
+
|
|
spin_unlock(&dev->slock);
|
|
|
|
- if (!vid_cap_buf && !vbi_cap_buf)
|
|
+ if (!vid_cap_buf && !vbi_cap_buf && !meta_cap_buf)
|
|
goto update_mv;
|
|
|
|
f_time = dev->cap_frame_period * dev->vid_cap_seq_count +
|
|
dev->cap_stream_start + dev->time_wrap_offset;
|
|
- if (!dev->tstamp_src_is_soe)
|
|
- f_time += dev->cap_frame_eof_offset;
|
|
|
|
if (vid_cap_buf) {
|
|
v4l2_ctrl_request_setup(vid_cap_buf->vb.vb2_buf.req_obj.req,
|
|
@@ -735,6 +741,8 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
|
|
vid_cap_buf->vb.vb2_buf.index);
|
|
|
|
vid_cap_buf->vb.vb2_buf.timestamp = f_time;
|
|
+ if (!dev->tstamp_src_is_soe)
|
|
+ vid_cap_buf->vb.vb2_buf.timestamp += dev->cap_frame_eof_offset;
|
|
}
|
|
|
|
if (vbi_cap_buf) {
|
|
@@ -756,8 +764,22 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
|
|
/* If capturing a VBI, offset by 0.05 */
|
|
vbi_period = dev->cap_frame_period * 5;
|
|
do_div(vbi_period, 100);
|
|
- vbi_cap_buf->vb.vb2_buf.timestamp = f_time + vbi_period;
|
|
+ vbi_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset + vbi_period;
|
|
+ }
|
|
+
|
|
+ if (meta_cap_buf) {
|
|
+ v4l2_ctrl_request_setup(meta_cap_buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_cap);
|
|
+ vivid_meta_cap_fillbuff(dev, meta_cap_buf, f_time);
|
|
+ v4l2_ctrl_request_complete(meta_cap_buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_cap);
|
|
+ vb2_buffer_done(&meta_cap_buf->vb.vb2_buf, dev->dqbuf_error ?
|
|
+ VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
|
|
+ dprintk(dev, 2, "meta_cap %d done\n",
|
|
+ meta_cap_buf->vb.vb2_buf.index);
|
|
+ meta_cap_buf->vb.vb2_buf.timestamp = f_time + dev->cap_frame_eof_offset;
|
|
}
|
|
+
|
|
dev->dqbuf_error = false;
|
|
|
|
update_mv:
|
|
@@ -835,6 +857,7 @@ static int vivid_thread_vid_cap(void *data)
|
|
dev->cap_seq_count = buffers_since_start + dev->cap_seq_offset;
|
|
dev->vid_cap_seq_count = dev->cap_seq_count - dev->vid_cap_seq_start;
|
|
dev->vbi_cap_seq_count = dev->cap_seq_count - dev->vbi_cap_seq_start;
|
|
+ dev->meta_cap_seq_count = dev->cap_seq_count - dev->meta_cap_seq_start;
|
|
|
|
vivid_thread_vid_cap_tick(dev, dropped_bufs);
|
|
|
|
@@ -883,8 +906,10 @@ int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
|
|
|
|
if (pstreaming == &dev->vid_cap_streaming)
|
|
dev->vid_cap_seq_start = seq_count;
|
|
- else
|
|
+ else if (pstreaming == &dev->vbi_cap_streaming)
|
|
dev->vbi_cap_seq_start = seq_count;
|
|
+ else
|
|
+ dev->meta_cap_seq_start = seq_count;
|
|
*pstreaming = true;
|
|
return 0;
|
|
}
|
|
@@ -894,6 +919,7 @@ int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
|
|
|
|
dev->vid_cap_seq_start = dev->seq_wrap * 128;
|
|
dev->vbi_cap_seq_start = dev->seq_wrap * 128;
|
|
+ dev->meta_cap_seq_start = dev->seq_wrap * 128;
|
|
|
|
dev->kthread_vid_cap = kthread_run(vivid_thread_vid_cap, dev,
|
|
"%s-vid-cap", dev->v4l2_dev.name);
|
|
@@ -951,7 +977,23 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
|
|
}
|
|
}
|
|
|
|
- if (dev->vid_cap_streaming || dev->vbi_cap_streaming)
|
|
+ if (pstreaming == &dev->meta_cap_streaming) {
|
|
+ while (!list_empty(&dev->meta_cap_active)) {
|
|
+ struct vivid_buffer *buf;
|
|
+
|
|
+ buf = list_entry(dev->meta_cap_active.next,
|
|
+ struct vivid_buffer, list);
|
|
+ list_del(&buf->list);
|
|
+ v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_cap);
|
|
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
|
|
+ dprintk(dev, 2, "meta_cap buffer %d done\n",
|
|
+ buf->vb.vb2_buf.index);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (dev->vid_cap_streaming || dev->vbi_cap_streaming ||
|
|
+ dev->meta_cap_streaming)
|
|
return;
|
|
|
|
/* shutdown control thread */
|
|
diff --git a/drivers/media/platform/vivid/vivid-meta-cap.c b/drivers/media/platform/vivid/vivid-meta-cap.c
|
|
new file mode 100644
|
|
index 000000000000..780f96860a6d
|
|
--- /dev/null
|
|
+++ b/drivers/media/platform/vivid/vivid-meta-cap.c
|
|
@@ -0,0 +1,201 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * vivid-meta-cap.c - meta capture support functions.
|
|
+ */
|
|
+
|
|
+#include <linux/errno.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/videodev2.h>
|
|
+#include <media/v4l2-common.h>
|
|
+#include <linux/usb/video.h>
|
|
+
|
|
+#include "vivid-core.h"
|
|
+#include "vivid-kthread-cap.h"
|
|
+#include "vivid-meta-cap.h"
|
|
+
|
|
+static int meta_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
|
+ unsigned int *nplanes, unsigned int sizes[],
|
|
+ struct device *alloc_devs[])
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+ unsigned int size = sizeof(struct vivid_uvc_meta_buf);
|
|
+
|
|
+ if (!vivid_is_webcam(dev))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (*nplanes) {
|
|
+ if (sizes[0] < size)
|
|
+ return -EINVAL;
|
|
+ } else {
|
|
+ sizes[0] = size;
|
|
+ }
|
|
+
|
|
+ if (vq->num_buffers + *nbuffers < 2)
|
|
+ *nbuffers = 2 - vq->num_buffers;
|
|
+
|
|
+ *nplanes = 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int meta_cap_buf_prepare(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ unsigned int size = sizeof(struct vivid_uvc_meta_buf);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+
|
|
+ if (dev->buf_prepare_error) {
|
|
+ /*
|
|
+ * Error injection: test what happens if buf_prepare() returns
|
|
+ * an error.
|
|
+ */
|
|
+ dev->buf_prepare_error = false;
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (vb2_plane_size(vb, 0) < size) {
|
|
+ dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
|
|
+ __func__, vb2_plane_size(vb, 0), size);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ vb2_set_plane_payload(vb, 0, size);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void meta_cap_buf_queue(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+
|
|
+ spin_lock(&dev->slock);
|
|
+ list_add_tail(&buf->list, &dev->meta_cap_active);
|
|
+ spin_unlock(&dev->slock);
|
|
+}
|
|
+
|
|
+static int meta_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+ int err;
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+ dev->meta_cap_seq_count = 0;
|
|
+ if (dev->start_streaming_error) {
|
|
+ dev->start_streaming_error = false;
|
|
+ err = -EINVAL;
|
|
+ } else {
|
|
+ err = vivid_start_generating_vid_cap(dev,
|
|
+ &dev->meta_cap_streaming);
|
|
+ }
|
|
+ if (err) {
|
|
+ struct vivid_buffer *buf, *tmp;
|
|
+
|
|
+ list_for_each_entry_safe(buf, tmp,
|
|
+ &dev->meta_cap_active, list) {
|
|
+ list_del(&buf->list);
|
|
+ vb2_buffer_done(&buf->vb.vb2_buf,
|
|
+ VB2_BUF_STATE_QUEUED);
|
|
+ }
|
|
+ }
|
|
+ return err;
|
|
+}
|
|
+
|
|
+/* abort streaming and wait for last buffer */
|
|
+static void meta_cap_stop_streaming(struct vb2_queue *vq)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+ vivid_stop_generating_vid_cap(dev, &dev->meta_cap_streaming);
|
|
+}
|
|
+
|
|
+static void meta_cap_buf_request_complete(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+
|
|
+ v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_cap);
|
|
+}
|
|
+
|
|
+const struct vb2_ops vivid_meta_cap_qops = {
|
|
+ .queue_setup = meta_cap_queue_setup,
|
|
+ .buf_prepare = meta_cap_buf_prepare,
|
|
+ .buf_queue = meta_cap_buf_queue,
|
|
+ .start_streaming = meta_cap_start_streaming,
|
|
+ .stop_streaming = meta_cap_stop_streaming,
|
|
+ .buf_request_complete = meta_cap_buf_request_complete,
|
|
+ .wait_prepare = vb2_ops_wait_prepare,
|
|
+ .wait_finish = vb2_ops_wait_finish,
|
|
+};
|
|
+
|
|
+int vidioc_enum_fmt_meta_cap(struct file *file, void *priv,
|
|
+ struct v4l2_fmtdesc *f)
|
|
+{
|
|
+ struct vivid_dev *dev = video_drvdata(file);
|
|
+
|
|
+ if (!vivid_is_webcam(dev))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (f->index > 0)
|
|
+ return -EINVAL;
|
|
+
|
|
+ f->type = V4L2_BUF_TYPE_META_CAPTURE;
|
|
+ f->pixelformat = V4L2_META_FMT_UVC;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
|
|
+ struct v4l2_format *f)
|
|
+{
|
|
+ struct vivid_dev *dev = video_drvdata(file);
|
|
+ struct v4l2_meta_format *meta = &f->fmt.meta;
|
|
+
|
|
+ if (!vivid_is_webcam(dev) || !dev->has_meta_cap)
|
|
+ return -EINVAL;
|
|
+
|
|
+ meta->dataformat = V4L2_META_FMT_UVC;
|
|
+ meta->buffersize = sizeof(struct vivid_uvc_meta_buf);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
|
|
+ struct vivid_buffer *buf, u64 soe)
|
|
+{
|
|
+ struct vivid_uvc_meta_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
|
+ int buf_off = 0;
|
|
+
|
|
+ buf->vb.sequence = dev->meta_cap_seq_count;
|
|
+ if (dev->field_cap == V4L2_FIELD_ALTERNATE)
|
|
+ buf->vb.sequence /= 2;
|
|
+ memset(meta, 1, vb2_plane_size(&buf->vb.vb2_buf, 0));
|
|
+
|
|
+ meta->ns = ktime_get_ns();
|
|
+ meta->sof = buf->vb.sequence * 30;
|
|
+ meta->length = sizeof(*meta) - offsetof(struct vivid_uvc_meta_buf, length);
|
|
+ meta->flags = UVC_STREAM_EOH | UVC_STREAM_EOF;
|
|
+
|
|
+ if ((buf->vb.sequence % 2) == 0)
|
|
+ meta->flags |= UVC_STREAM_FID;
|
|
+
|
|
+ dprintk(dev, 2, "%s ns:%llu sof:%4d len:%u flags: 0x%02x",
|
|
+ __func__, meta->ns, meta->sof, meta->length, meta->flags);
|
|
+ if (dev->meta_pts) {
|
|
+ meta->flags |= UVC_STREAM_PTS;
|
|
+ meta->buf[0] = div_u64(soe, VIVID_META_CLOCK_UNIT);
|
|
+ buf_off = 4;
|
|
+ dprintk(dev, 2, " pts: %u\n", *(__u32 *)(meta->buf));
|
|
+ }
|
|
+
|
|
+ if (dev->meta_scr) {
|
|
+ meta->flags |= UVC_STREAM_SCR;
|
|
+ meta->buf[buf_off] = div_u64((soe + dev->cap_frame_eof_offset),
|
|
+ VIVID_META_CLOCK_UNIT);
|
|
+
|
|
+ meta->buf[buf_off + 4] = (buf->vb.sequence * 30) % 1000;
|
|
+ dprintk(dev, 2, " stc: %u, sof counter: %u\n",
|
|
+ *(__u32 *)(meta->buf + buf_off),
|
|
+ *(__u16 *)(meta->buf + buf_off + 4));
|
|
+ }
|
|
+ dprintk(dev, 2, "\n");
|
|
+}
|
|
diff --git a/drivers/media/platform/vivid/vivid-meta-cap.h b/drivers/media/platform/vivid/vivid-meta-cap.h
|
|
new file mode 100644
|
|
index 000000000000..4670d00d1576
|
|
--- /dev/null
|
|
+++ b/drivers/media/platform/vivid/vivid-meta-cap.h
|
|
@@ -0,0 +1,29 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-only */
|
|
+/*
|
|
+ * vivid-meta-cap.h - meta capture support functions.
|
|
+ */
|
|
+#ifndef _VIVID_META_CAP_H_
|
|
+#define _VIVID_META_CAP_H_
|
|
+
|
|
+#define VIVID_META_CLOCK_UNIT 10 /* 100 MHz */
|
|
+
|
|
+struct vivid_uvc_meta_buf {
|
|
+ __u64 ns;
|
|
+ __u16 sof;
|
|
+ __u8 length;
|
|
+ __u8 flags;
|
|
+ __u8 buf[10]; /* PTS(4)+STC(4)+SOF(2) */
|
|
+} __packed;
|
|
+
|
|
+void vivid_meta_cap_fillbuff(struct vivid_dev *dev,
|
|
+ struct vivid_buffer *buf, u64 soe);
|
|
+
|
|
+int vidioc_enum_fmt_meta_cap(struct file *file, void *priv,
|
|
+ struct v4l2_fmtdesc *f);
|
|
+
|
|
+int vidioc_g_fmt_meta_cap(struct file *file, void *priv,
|
|
+ struct v4l2_format *f);
|
|
+
|
|
+extern const struct vb2_ops vivid_meta_cap_qops;
|
|
+
|
|
+#endif
|
|
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
index 2d030732feac..e94beef008c8 100644
|
|
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
|
|
@@ -1356,7 +1356,9 @@ int vidioc_s_input(struct file *file, void *priv, unsigned i)
|
|
if (i == dev->input)
|
|
return 0;
|
|
|
|
- if (vb2_is_busy(&dev->vb_vid_cap_q) || vb2_is_busy(&dev->vb_vbi_cap_q))
|
|
+ if (vb2_is_busy(&dev->vb_vid_cap_q) ||
|
|
+ vb2_is_busy(&dev->vb_vbi_cap_q) ||
|
|
+ vb2_is_busy(&dev->vb_meta_cap_q))
|
|
return -EBUSY;
|
|
|
|
dev->input = i;
|
|
@@ -1366,6 +1368,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned i)
|
|
dev->vid_cap_dev.tvnorms = V4L2_STD_ALL;
|
|
}
|
|
dev->vbi_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
|
|
+ dev->meta_cap_dev.tvnorms = dev->vid_cap_dev.tvnorms;
|
|
vivid_update_format_cap(dev, false);
|
|
|
|
if (dev->colorspace) {
|
|
|
|
From 9613d94dbf4baebb6f4ce12e3433143ffc66965d Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Thu, 17 Oct 2019 03:43:08 -0300
|
|
Subject: [PATCH] media: Documentation:media:v4l2:Add vivid metadata doc
|
|
|
|
Adds new file for describing new metadata format V4L2_META_FMT_VIVID added in vivid driver.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit a2e31ce91de97e7797fe9c68f3671df2905842aa)
|
|
---
|
|
Documentation/media/uapi/v4l/meta-formats.rst | 1 +
|
|
Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst | 60 ++++++++++++++++++++++
|
|
2 files changed, 61 insertions(+)
|
|
create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
|
|
index b10ca9ee3968..74c8659ee9d6 100644
|
|
--- a/Documentation/media/uapi/v4l/meta-formats.rst
|
|
+++ b/Documentation/media/uapi/v4l/meta-formats.rst
|
|
@@ -24,3 +24,4 @@ These formats are used for the :ref:`metadata` interface only.
|
|
pixfmt-meta-uvc
|
|
pixfmt-meta-vsp1-hgo
|
|
pixfmt-meta-vsp1-hgt
|
|
+ pixfmt-meta-vivid
|
|
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst b/Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst
|
|
new file mode 100644
|
|
index 000000000000..eed20eaefe24
|
|
--- /dev/null
|
|
+++ b/Documentation/media/uapi/v4l/pixfmt-meta-vivid.rst
|
|
@@ -0,0 +1,60 @@
|
|
+.. This file is dual-licensed: you can use it either under the terms
|
|
+.. of the GPL 2.0 or the GFDL 1.1+ license, at your option. Note that this
|
|
+.. dual licensing only applies to this file, and not this project as a
|
|
+.. whole.
|
|
+..
|
|
+.. a) This file is free software; you can redistribute it and/or
|
|
+.. modify it under the terms of the GNU General Public License as
|
|
+.. published by the Free Software Foundation version 2 of
|
|
+.. the License.
|
|
+..
|
|
+.. This file is distributed in the hope that it will be useful,
|
|
+.. but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+.. GNU General Public License for more details.
|
|
+..
|
|
+.. Or, alternatively,
|
|
+..
|
|
+.. b) Permission is granted to copy, distribute and/or modify this
|
|
+.. document under the terms of the GNU Free Documentation License,
|
|
+.. Version 1.1 or any later version published by the Free Software
|
|
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
|
|
+.. and no Back-Cover Texts. A copy of the license is included at
|
|
+.. Documentation/media/uapi/fdl-appendix.rst.
|
|
+..
|
|
+.. TODO: replace it to GPL-2.0 OR GFDL-1.1-or-later WITH no-invariant-sections
|
|
+
|
|
+.. _v4l2-meta-fmt-vivid:
|
|
+
|
|
+*******************************
|
|
+V4L2_META_FMT_VIVID ('VIVD')
|
|
+*******************************
|
|
+
|
|
+VIVID Metadata Format
|
|
+
|
|
+
|
|
+Description
|
|
+===========
|
|
+
|
|
+This describes metadata format used by the vivid driver.
|
|
+
|
|
+It sets Brightness, Saturation, Contrast and Hue, each of which maps to
|
|
+corresponding controls of the vivid driver with respect to the range and default values.
|
|
+
|
|
+It contains the following fields:
|
|
+
|
|
+.. flat-table:: VIVID Metadata
|
|
+ :widths: 1 4
|
|
+ :header-rows: 1
|
|
+ :stub-columns: 0
|
|
+
|
|
+ * - Field
|
|
+ - Description
|
|
+ * - u16 brightness;
|
|
+ - Image brightness, the value is in the range 0 to 255, with the default value as 128.
|
|
+ * - u16 contrast;
|
|
+ - Image contrast, the value is in the range 0 to 255, with the default value as 128.
|
|
+ * - u16 saturation;
|
|
+ - Image color saturation, the value is in the range 0 to 255, with the default value as 128.
|
|
+ * - s16 hue;
|
|
+ - Image color balance, the value is in the range -128 to 128, with the default value as 0.
|
|
|
|
From e8d0e12c7617a19f34c23b0f35be992d5f005272 Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Tue, 15 Oct 2019 07:40:16 -0300
|
|
Subject: [PATCH] media: v4l2-core: Add new metadata format
|
|
|
|
Add new metadata format to support metadata output in vivid.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 78892b6ba3ba7a6c20bc21548ee90fc980fdfbf4)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
|
|
include/uapi/linux/videodev2.h | 1 +
|
|
2 files changed, 2 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index 20b3107dd4e8..2753073cf340 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -1340,6 +1340,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
|
|
case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
|
|
case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break;
|
|
case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break;
|
|
+ case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break;
|
|
|
|
default:
|
|
/* Compressed formats */
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index d969842bbfe2..f98bbcced8ff 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -760,6 +760,7 @@ struct v4l2_pix_format {
|
|
#define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */
|
|
#define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */
|
|
#define V4L2_META_FMT_D4XX v4l2_fourcc('D', '4', 'X', 'X') /* D4XX Payload Header metadata */
|
|
+#define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D') /* Vivid Metadata */
|
|
|
|
/* priv field value to indicates that subsequent fields are valid. */
|
|
#define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
|
|
|
|
From a40c3fa675f97225cfb6036a70817386a47463d7 Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Tue, 15 Oct 2019 07:40:17 -0300
|
|
Subject: [PATCH] media: vivid: Add metadata output support
|
|
|
|
Support metadata output in vivid driver.
|
|
Metadata output is used to set brightness, contrast, saturation
|
|
and hue.
|
|
Adds new files for metadata output.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 746facd39370cc10038eba695f37269c6a401fda)
|
|
---
|
|
drivers/media/platform/vivid/Makefile | 2 +-
|
|
drivers/media/platform/vivid/vivid-core.c | 98 ++++++++++++-
|
|
drivers/media/platform/vivid/vivid-core.h | 10 ++
|
|
drivers/media/platform/vivid/vivid-ctrls.c | 12 +-
|
|
drivers/media/platform/vivid/vivid-kthread-out.c | 49 ++++++-
|
|
drivers/media/platform/vivid/vivid-meta-out.c | 174 +++++++++++++++++++++++
|
|
drivers/media/platform/vivid/vivid-meta-out.h | 25 ++++
|
|
drivers/media/platform/vivid/vivid-vid-out.c | 5 +-
|
|
8 files changed, 364 insertions(+), 11 deletions(-)
|
|
create mode 100644 drivers/media/platform/vivid/vivid-meta-out.c
|
|
create mode 100644 drivers/media/platform/vivid/vivid-meta-out.h
|
|
|
|
diff --git a/drivers/media/platform/vivid/Makefile b/drivers/media/platform/vivid/Makefile
|
|
index af94abf9bce6..e8a50c506dc9 100644
|
|
--- a/drivers/media/platform/vivid/Makefile
|
|
+++ b/drivers/media/platform/vivid/Makefile
|
|
@@ -3,7 +3,7 @@ vivid-objs := vivid-core.o vivid-ctrls.o vivid-vid-common.o vivid-vbi-gen.o \
|
|
vivid-vid-cap.o vivid-vid-out.o vivid-kthread-cap.o vivid-kthread-out.o \
|
|
vivid-radio-rx.o vivid-radio-tx.o vivid-radio-common.o \
|
|
vivid-rds-gen.o vivid-sdr-cap.o vivid-vbi-cap.o vivid-vbi-out.o \
|
|
- vivid-osd.o vivid-meta-cap.o
|
|
+ vivid-osd.o vivid-meta-cap.o vivid-meta-out.o
|
|
ifeq ($(CONFIG_VIDEO_VIVID_CEC),y)
|
|
vivid-objs += vivid-cec.o
|
|
endif
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
|
|
index a44984536ad0..dadfc59c92c5 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.c
|
|
+++ b/drivers/media/platform/vivid/vivid-core.c
|
|
@@ -38,6 +38,7 @@
|
|
#include "vivid-cec.h"
|
|
#include "vivid-ctrls.h"
|
|
#include "vivid-meta-cap.h"
|
|
+#include "vivid-meta-out.h"
|
|
|
|
#define VIVID_MODULE_NAME "vivid"
|
|
|
|
@@ -84,6 +85,10 @@ static int meta_cap_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
module_param_array(meta_cap_nr, int, NULL, 0444);
|
|
MODULE_PARM_DESC(meta_cap_nr, " videoX start number, -1 is autodetect");
|
|
|
|
+static int meta_out_nr[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
+module_param_array(meta_out_nr, int, NULL, 0444);
|
|
+MODULE_PARM_DESC(meta_out_nr, " videoX start number, -1 is autodetect");
|
|
+
|
|
static int ccs_cap_mode[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = -1 };
|
|
module_param_array(ccs_cap_mode, int, NULL, 0444);
|
|
MODULE_PARM_DESC(ccs_cap_mode, " capture crop/compose/scale mode:\n"
|
|
@@ -105,10 +110,10 @@ MODULE_PARM_DESC(multiplanar, " 1 (default) creates a single planar device, 2 cr
|
|
* vbi-out + vid-out + meta-cap
|
|
*/
|
|
static unsigned int node_types[VIVID_MAX_DEVS] = {
|
|
- [0 ... (VIVID_MAX_DEVS - 1)] = 0x21d3d
|
|
+ [0 ... (VIVID_MAX_DEVS - 1)] = 0x61d3d
|
|
};
|
|
module_param_array(node_types, uint, NULL, 0444);
|
|
-MODULE_PARM_DESC(node_types, " node types, default is 0x21d3d. Bitmask with the following meaning:\n"
|
|
+MODULE_PARM_DESC(node_types, " node types, default is 0x61d3d. Bitmask with the following meaning:\n"
|
|
"\t\t bit 0: Video Capture node\n"
|
|
"\t\t bit 2-3: VBI Capture node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
|
|
"\t\t bit 4: Radio Receiver node\n"
|
|
@@ -117,7 +122,8 @@ MODULE_PARM_DESC(node_types, " node types, default is 0x21d3d. Bitmask with the
|
|
"\t\t bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n"
|
|
"\t\t bit 12: Radio Transmitter node\n"
|
|
"\t\t bit 16: Framebuffer for testing overlays\n"
|
|
- "\t\t bit 17: Metadata Capture node\n");
|
|
+ "\t\t bit 17: Metadata Capture node\n"
|
|
+ "\t\t bit 18: Metadata Output node\n");
|
|
|
|
/* Default: 4 inputs */
|
|
static unsigned num_inputs[VIVID_MAX_DEVS] = { [0 ... (VIVID_MAX_DEVS - 1)] = 4 };
|
|
@@ -216,7 +222,8 @@ static int vidioc_querycap(struct file *file, void *priv,
|
|
cap->capabilities = dev->vid_cap_caps | dev->vid_out_caps |
|
|
dev->vbi_cap_caps | dev->vbi_out_caps |
|
|
dev->radio_rx_caps | dev->radio_tx_caps |
|
|
- dev->sdr_cap_caps | dev->meta_cap_caps | V4L2_CAP_DEVICE_CAPS;
|
|
+ dev->sdr_cap_caps | dev->meta_cap_caps |
|
|
+ dev->meta_out_caps | V4L2_CAP_DEVICE_CAPS;
|
|
return 0;
|
|
}
|
|
|
|
@@ -445,7 +452,8 @@ static bool vivid_is_last_user(struct vivid_dev *dev)
|
|
vivid_is_in_use(&dev->sdr_cap_dev) +
|
|
vivid_is_in_use(&dev->radio_rx_dev) +
|
|
vivid_is_in_use(&dev->radio_tx_dev) +
|
|
- vivid_is_in_use(&dev->meta_cap_dev);
|
|
+ vivid_is_in_use(&dev->meta_cap_dev) +
|
|
+ vivid_is_in_use(&dev->meta_out_dev);
|
|
|
|
return uses == 1;
|
|
}
|
|
@@ -472,6 +480,7 @@ static int vivid_fop_release(struct file *file)
|
|
set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
|
|
set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
|
|
set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
|
|
+ set_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
|
|
}
|
|
mutex_unlock(&dev->mutex);
|
|
if (file->private_data == dev->overlay_cap_owner)
|
|
@@ -622,6 +631,11 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
|
|
.vidioc_g_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
.vidioc_s_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
.vidioc_try_fmt_meta_cap = vidioc_g_fmt_meta_cap,
|
|
+
|
|
+ .vidioc_enum_fmt_meta_out = vidioc_enum_fmt_meta_out,
|
|
+ .vidioc_g_fmt_meta_out = vidioc_g_fmt_meta_out,
|
|
+ .vidioc_s_fmt_meta_out = vidioc_g_fmt_meta_out,
|
|
+ .vidioc_try_fmt_meta_out = vidioc_g_fmt_meta_out,
|
|
};
|
|
|
|
/* -----------------------------------------------------------------
|
|
@@ -839,6 +853,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
/* do we create a meta capture device */
|
|
dev->has_meta_cap = node_type & 0x20000;
|
|
|
|
+ /* do we create a metadata output device */
|
|
+ dev->has_meta_out = node_type & 0x40000;
|
|
+
|
|
/* end detecting feature set */
|
|
|
|
if (dev->has_vid_cap) {
|
|
@@ -905,6 +922,13 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
if (in_type_counter[TV])
|
|
dev->meta_cap_caps |= V4L2_CAP_TUNER;
|
|
}
|
|
+ /* set up the capabilities of meta output device */
|
|
+ if (dev->has_meta_out) {
|
|
+ dev->meta_out_caps = V4L2_CAP_META_OUTPUT |
|
|
+ V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
|
+ if (dev->has_audio_outputs)
|
|
+ dev->meta_out_caps |= V4L2_CAP_AUDIO;
|
|
+ }
|
|
|
|
ret = -ENOMEM;
|
|
/* initialize the test pattern generator */
|
|
@@ -976,6 +1000,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_AUDOUT);
|
|
v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_AUDOUT);
|
|
v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_ENUMAUDOUT);
|
|
+ v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_AUDOUT);
|
|
+ v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_AUDOUT);
|
|
+ v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_ENUMAUDOUT);
|
|
}
|
|
if (!in_type_counter[TV] && !in_type_counter[SVID]) {
|
|
v4l2_disable_ioctl(&dev->vid_cap_dev, VIDIOC_S_STD);
|
|
@@ -1035,6 +1062,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_disable_ioctl(&dev->vid_out_dev, VIDIOC_ENUM_FRAMEINTERVALS);
|
|
v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_S_FREQUENCY);
|
|
v4l2_disable_ioctl(&dev->vbi_out_dev, VIDIOC_G_FREQUENCY);
|
|
+ v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_S_FREQUENCY);
|
|
+ v4l2_disable_ioctl(&dev->meta_out_dev, VIDIOC_G_FREQUENCY);
|
|
|
|
/* configure internal data */
|
|
dev->fmt_cap = &vivid_formats[0];
|
|
@@ -1118,6 +1147,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
INIT_LIST_HEAD(&dev->vbi_out_active);
|
|
INIT_LIST_HEAD(&dev->sdr_cap_active);
|
|
INIT_LIST_HEAD(&dev->meta_cap_active);
|
|
+ INIT_LIST_HEAD(&dev->meta_out_active);
|
|
|
|
INIT_LIST_HEAD(&dev->cec_work_list);
|
|
spin_lock_init(&dev->cec_slock);
|
|
@@ -1286,6 +1316,27 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
+ if (dev->has_meta_out) {
|
|
+ /* initialize meta_out queue */
|
|
+ q = &dev->vb_meta_out_q;
|
|
+ q->type = V4L2_BUF_TYPE_META_OUTPUT;
|
|
+ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE;
|
|
+ if (!allocator)
|
|
+ q->io_modes |= VB2_USERPTR;
|
|
+ q->drv_priv = dev;
|
|
+ q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
+ q->ops = &vivid_meta_out_qops;
|
|
+ q->mem_ops = vivid_mem_ops[allocator];
|
|
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
+ q->min_buffers_needed = 1;
|
|
+ q->lock = &dev->mutex;
|
|
+ q->dev = dev->v4l2_dev.dev;
|
|
+ q->supports_requests = true;
|
|
+ ret = vb2_queue_init(q);
|
|
+ if (ret)
|
|
+ goto unreg_dev;
|
|
+ }
|
|
+
|
|
#ifdef CONFIG_VIDEO_VIVID_CEC
|
|
if (dev->has_vid_cap && in_type_counter[HDMI]) {
|
|
struct cec_adapter *adap;
|
|
@@ -1327,6 +1378,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_radio_tx);
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_sdr_cap);
|
|
v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_cap);
|
|
+ v4l2_ctrl_handler_setup(&dev->ctrl_hdl_meta_out);
|
|
|
|
/* finally start creating the device nodes */
|
|
if (dev->has_vid_cap) {
|
|
@@ -1583,6 +1635,36 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
video_device_node_name(vfd));
|
|
}
|
|
|
|
+ if (dev->has_meta_out) {
|
|
+ vfd = &dev->meta_out_dev;
|
|
+ snprintf(vfd->name, sizeof(vfd->name),
|
|
+ "vivid-%03d-meta-out", inst);
|
|
+ vfd->vfl_dir = VFL_DIR_TX;
|
|
+ vfd->fops = &vivid_fops;
|
|
+ vfd->ioctl_ops = &vivid_ioctl_ops;
|
|
+ vfd->device_caps = dev->meta_out_caps;
|
|
+ vfd->release = video_device_release_empty;
|
|
+ vfd->v4l2_dev = &dev->v4l2_dev;
|
|
+ vfd->queue = &dev->vb_meta_out_q;
|
|
+ vfd->lock = &dev->mutex;
|
|
+ vfd->tvnorms = tvnorms_out;
|
|
+ video_set_drvdata(vfd, dev);
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
+ dev->meta_out_pad.flags = MEDIA_PAD_FL_SOURCE;
|
|
+ ret = media_entity_pads_init(&vfd->entity, 1,
|
|
+ &dev->meta_out_pad);
|
|
+ if (ret)
|
|
+ goto unreg_dev;
|
|
+#endif
|
|
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER,
|
|
+ meta_out_nr[inst]);
|
|
+ if (ret < 0)
|
|
+ goto unreg_dev;
|
|
+ v4l2_info(&dev->v4l2_dev,
|
|
+ "V4L2 metadata output device registered as %s\n",
|
|
+ video_device_node_name(vfd));
|
|
+ }
|
|
+
|
|
#ifdef CONFIG_MEDIA_CONTROLLER
|
|
/* Register the media device */
|
|
ret = media_device_register(&dev->mdev);
|
|
@@ -1599,6 +1681,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
return 0;
|
|
|
|
unreg_dev:
|
|
+ video_unregister_device(&dev->meta_out_dev);
|
|
video_unregister_device(&dev->meta_cap_dev);
|
|
video_unregister_device(&dev->radio_tx_dev);
|
|
video_unregister_device(&dev->radio_rx_dev);
|
|
@@ -1721,6 +1804,11 @@ static int vivid_remove(struct platform_device *pdev)
|
|
video_device_node_name(&dev->meta_cap_dev));
|
|
video_unregister_device(&dev->meta_cap_dev);
|
|
}
|
|
+ if (dev->has_meta_out) {
|
|
+ v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
|
|
+ video_device_node_name(&dev->meta_out_dev));
|
|
+ video_unregister_device(&dev->meta_out_dev);
|
|
+ }
|
|
cec_unregister_adapter(dev->cec_rx_adap);
|
|
for (j = 0; j < MAX_OUTPUTS; j++)
|
|
cec_unregister_adapter(dev->cec_tx_adap[j]);
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
|
|
index fd601345a17c..d57066ed31f0 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.h
|
|
+++ b/drivers/media/platform/vivid/vivid-core.h
|
|
@@ -132,6 +132,7 @@ struct vivid_dev {
|
|
struct media_pad vbi_out_pad;
|
|
struct media_pad sdr_cap_pad;
|
|
struct media_pad meta_cap_pad;
|
|
+ struct media_pad meta_out_pad;
|
|
#endif
|
|
struct v4l2_ctrl_handler ctrl_hdl_user_gen;
|
|
struct v4l2_ctrl_handler ctrl_hdl_user_vid;
|
|
@@ -156,6 +157,8 @@ struct vivid_dev {
|
|
struct v4l2_ctrl_handler ctrl_hdl_sdr_cap;
|
|
struct video_device meta_cap_dev;
|
|
struct v4l2_ctrl_handler ctrl_hdl_meta_cap;
|
|
+ struct video_device meta_out_dev;
|
|
+ struct v4l2_ctrl_handler ctrl_hdl_meta_out;
|
|
|
|
spinlock_t slock;
|
|
struct mutex mutex;
|
|
@@ -169,6 +172,7 @@ struct vivid_dev {
|
|
u32 radio_rx_caps;
|
|
u32 radio_tx_caps;
|
|
u32 meta_cap_caps;
|
|
+ u32 meta_out_caps;
|
|
|
|
/* supported features */
|
|
bool multiplanar;
|
|
@@ -195,6 +199,7 @@ struct vivid_dev {
|
|
bool has_sdr_cap;
|
|
bool has_fb;
|
|
bool has_meta_cap;
|
|
+ bool has_meta_out;
|
|
|
|
bool can_loop_video;
|
|
|
|
@@ -432,6 +437,8 @@ struct vivid_dev {
|
|
struct list_head vid_out_active;
|
|
struct vb2_queue vb_vbi_out_q;
|
|
struct list_head vbi_out_active;
|
|
+ struct vb2_queue vb_meta_out_q;
|
|
+ struct list_head meta_out_active;
|
|
|
|
/* video loop precalculated rectangles */
|
|
|
|
@@ -472,6 +479,9 @@ struct vivid_dev {
|
|
u32 vbi_out_seq_count;
|
|
bool vbi_out_streaming;
|
|
bool stream_sliced_vbi_out;
|
|
+ u32 meta_out_seq_start;
|
|
+ u32 meta_out_seq_count;
|
|
+ bool meta_out_streaming;
|
|
|
|
/* SDR capture */
|
|
struct vb2_queue vb_sdr_cap_q;
|
|
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
index 36e5944b51bb..b250fc3764e2 100644
|
|
--- a/drivers/media/platform/vivid/vivid-ctrls.c
|
|
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
@@ -1494,6 +1494,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
struct v4l2_ctrl_handler *hdl_radio_tx = &dev->ctrl_hdl_radio_tx;
|
|
struct v4l2_ctrl_handler *hdl_sdr_cap = &dev->ctrl_hdl_sdr_cap;
|
|
struct v4l2_ctrl_handler *hdl_meta_cap = &dev->ctrl_hdl_meta_cap;
|
|
+ struct v4l2_ctrl_handler *hdl_meta_out = &dev->ctrl_hdl_meta_out;
|
|
|
|
struct v4l2_ctrl_config vivid_ctrl_dv_timings = {
|
|
.ops = &vivid_vid_cap_ctrl_ops,
|
|
@@ -1535,6 +1536,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
v4l2_ctrl_new_custom(hdl_sdr_cap, &vivid_ctrl_class, NULL);
|
|
v4l2_ctrl_handler_init(hdl_meta_cap, 2);
|
|
v4l2_ctrl_new_custom(hdl_meta_cap, &vivid_ctrl_class, NULL);
|
|
+ v4l2_ctrl_handler_init(hdl_meta_out, 2);
|
|
+ v4l2_ctrl_new_custom(hdl_meta_out, &vivid_ctrl_class, NULL);
|
|
|
|
/* User Controls */
|
|
dev->volume = v4l2_ctrl_new_std(hdl_user_aud, NULL,
|
|
@@ -1880,7 +1883,13 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
return hdl_meta_cap->error;
|
|
dev->meta_cap_dev.ctrl_handler = hdl_meta_cap;
|
|
}
|
|
-
|
|
+ if (dev->has_meta_out) {
|
|
+ v4l2_ctrl_add_handler(hdl_meta_out, hdl_user_gen, NULL, false);
|
|
+ v4l2_ctrl_add_handler(hdl_meta_out, hdl_streaming, NULL, false);
|
|
+ if (hdl_meta_out->error)
|
|
+ return hdl_meta_out->error;
|
|
+ dev->meta_out_dev.ctrl_handler = hdl_meta_out;
|
|
+ }
|
|
return 0;
|
|
}
|
|
|
|
@@ -1901,4 +1910,5 @@ void vivid_free_controls(struct vivid_dev *dev)
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
|
|
v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_cap);
|
|
+ v4l2_ctrl_handler_free(&dev->ctrl_hdl_meta_out);
|
|
}
|
|
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
index ce5bcda2348c..c974235d7de3 100644
|
|
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
@@ -38,11 +38,13 @@
|
|
#include "vivid-osd.h"
|
|
#include "vivid-ctrls.h"
|
|
#include "vivid-kthread-out.h"
|
|
+#include "vivid-meta-out.h"
|
|
|
|
static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
|
|
{
|
|
struct vivid_buffer *vid_out_buf = NULL;
|
|
struct vivid_buffer *vbi_out_buf = NULL;
|
|
+ struct vivid_buffer *meta_out_buf = NULL;
|
|
|
|
dprintk(dev, 1, "Video Output Thread Tick\n");
|
|
|
|
@@ -69,9 +71,14 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
|
|
struct vivid_buffer, list);
|
|
list_del(&vbi_out_buf->list);
|
|
}
|
|
+ if (!list_empty(&dev->meta_out_active)) {
|
|
+ meta_out_buf = list_entry(dev->meta_out_active.next,
|
|
+ struct vivid_buffer, list);
|
|
+ list_del(&meta_out_buf->list);
|
|
+ }
|
|
spin_unlock(&dev->slock);
|
|
|
|
- if (!vid_out_buf && !vbi_out_buf)
|
|
+ if (!vid_out_buf && !vbi_out_buf && !meta_out_buf)
|
|
return;
|
|
|
|
if (vid_out_buf) {
|
|
@@ -111,6 +118,21 @@ static void vivid_thread_vid_out_tick(struct vivid_dev *dev)
|
|
dprintk(dev, 2, "vbi_out buffer %d done\n",
|
|
vbi_out_buf->vb.vb2_buf.index);
|
|
}
|
|
+ if (meta_out_buf) {
|
|
+ v4l2_ctrl_request_setup(meta_out_buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_out);
|
|
+ v4l2_ctrl_request_complete(meta_out_buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_out);
|
|
+ vivid_meta_out_process(dev, meta_out_buf);
|
|
+ meta_out_buf->vb.sequence = dev->meta_out_seq_count;
|
|
+ meta_out_buf->vb.vb2_buf.timestamp =
|
|
+ ktime_get_ns() + dev->time_wrap_offset;
|
|
+ vb2_buffer_done(&meta_out_buf->vb.vb2_buf, dev->dqbuf_error ?
|
|
+ VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
|
|
+ dprintk(dev, 2, "meta_out buffer %d done\n",
|
|
+ meta_out_buf->vb.vb2_buf.index);
|
|
+ }
|
|
+
|
|
dev->dqbuf_error = false;
|
|
}
|
|
|
|
@@ -136,6 +158,7 @@ static int vivid_thread_vid_out(void *data)
|
|
dev->out_seq_count = 0xffffff80U;
|
|
dev->jiffies_vid_out = jiffies;
|
|
dev->vid_out_seq_start = dev->vbi_out_seq_start = 0;
|
|
+ dev->meta_out_seq_start = 0;
|
|
dev->out_seq_resync = false;
|
|
|
|
for (;;) {
|
|
@@ -178,6 +201,7 @@ static int vivid_thread_vid_out(void *data)
|
|
dev->out_seq_count = buffers_since_start + dev->out_seq_offset;
|
|
dev->vid_out_seq_count = dev->out_seq_count - dev->vid_out_seq_start;
|
|
dev->vbi_out_seq_count = dev->out_seq_count - dev->vbi_out_seq_start;
|
|
+ dev->meta_out_seq_count = dev->out_seq_count - dev->meta_out_seq_start;
|
|
|
|
vivid_thread_vid_out_tick(dev);
|
|
mutex_unlock(&dev->mutex);
|
|
@@ -229,8 +253,10 @@ int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
|
|
|
|
if (pstreaming == &dev->vid_out_streaming)
|
|
dev->vid_out_seq_start = seq_count;
|
|
- else
|
|
+ else if (pstreaming == &dev->vbi_out_streaming)
|
|
dev->vbi_out_seq_start = seq_count;
|
|
+ else
|
|
+ dev->meta_out_seq_start = seq_count;
|
|
*pstreaming = true;
|
|
return 0;
|
|
}
|
|
@@ -239,6 +265,7 @@ int vivid_start_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
|
|
dev->jiffies_vid_out = jiffies;
|
|
dev->vid_out_seq_start = dev->seq_wrap * 128;
|
|
dev->vbi_out_seq_start = dev->seq_wrap * 128;
|
|
+ dev->meta_out_seq_start = dev->seq_wrap * 128;
|
|
|
|
dev->kthread_vid_out = kthread_run(vivid_thread_vid_out, dev,
|
|
"%s-vid-out", dev->v4l2_dev.name);
|
|
@@ -296,7 +323,23 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
|
|
}
|
|
}
|
|
|
|
- if (dev->vid_out_streaming || dev->vbi_out_streaming)
|
|
+ if (pstreaming == &dev->meta_out_streaming) {
|
|
+ while (!list_empty(&dev->meta_out_active)) {
|
|
+ struct vivid_buffer *buf;
|
|
+
|
|
+ buf = list_entry(dev->meta_out_active.next,
|
|
+ struct vivid_buffer, list);
|
|
+ list_del(&buf->list);
|
|
+ v4l2_ctrl_request_complete(buf->vb.vb2_buf.req_obj.req,
|
|
+ &dev->ctrl_hdl_meta_out);
|
|
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
|
|
+ dprintk(dev, 2, "meta_out buffer %d done\n",
|
|
+ buf->vb.vb2_buf.index);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (dev->vid_out_streaming || dev->vbi_out_streaming ||
|
|
+ dev->meta_out_streaming)
|
|
return;
|
|
|
|
/* shutdown control thread */
|
|
diff --git a/drivers/media/platform/vivid/vivid-meta-out.c b/drivers/media/platform/vivid/vivid-meta-out.c
|
|
new file mode 100644
|
|
index 000000000000..ff8a039aba72
|
|
--- /dev/null
|
|
+++ b/drivers/media/platform/vivid/vivid-meta-out.c
|
|
@@ -0,0 +1,174 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-only
|
|
+/*
|
|
+ * vivid-meta-out.c - meta output support functions.
|
|
+ */
|
|
+
|
|
+#include <linux/errno.h>
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/videodev2.h>
|
|
+#include <media/v4l2-common.h>
|
|
+#include <linux/usb/video.h>
|
|
+
|
|
+#include "vivid-core.h"
|
|
+#include "vivid-kthread-out.h"
|
|
+#include "vivid-meta-out.h"
|
|
+
|
|
+static int meta_out_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
|
|
+ unsigned int *nplanes, unsigned int sizes[],
|
|
+ struct device *alloc_devs[])
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+ unsigned int size = sizeof(struct vivid_meta_out_buf);
|
|
+
|
|
+ if (!vivid_is_webcam(dev))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (*nplanes) {
|
|
+ if (sizes[0] < size)
|
|
+ return -EINVAL;
|
|
+ } else {
|
|
+ sizes[0] = size;
|
|
+ }
|
|
+
|
|
+ if (vq->num_buffers + *nbuffers < 2)
|
|
+ *nbuffers = 2 - vq->num_buffers;
|
|
+
|
|
+ *nplanes = 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int meta_out_buf_prepare(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ unsigned int size = sizeof(struct vivid_meta_out_buf);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+
|
|
+ if (dev->buf_prepare_error) {
|
|
+ /*
|
|
+ * Error injection: test what happens if buf_prepare() returns
|
|
+ * an error.
|
|
+ */
|
|
+ dev->buf_prepare_error = false;
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (vb2_plane_size(vb, 0) < size) {
|
|
+ dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
|
|
+ __func__, vb2_plane_size(vb, 0), size);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ vb2_set_plane_payload(vb, 0, size);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void meta_out_buf_queue(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+ struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+
|
|
+ spin_lock(&dev->slock);
|
|
+ list_add_tail(&buf->list, &dev->meta_out_active);
|
|
+ spin_unlock(&dev->slock);
|
|
+}
|
|
+
|
|
+static int meta_out_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+ int err;
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+ dev->meta_out_seq_count = 0;
|
|
+ if (dev->start_streaming_error) {
|
|
+ dev->start_streaming_error = false;
|
|
+ err = -EINVAL;
|
|
+ } else {
|
|
+ err = vivid_start_generating_vid_out(dev,
|
|
+ &dev->meta_out_streaming);
|
|
+ }
|
|
+ if (err) {
|
|
+ struct vivid_buffer *buf, *tmp;
|
|
+
|
|
+ list_for_each_entry_safe(buf, tmp,
|
|
+ &dev->meta_out_active, list) {
|
|
+ list_del(&buf->list);
|
|
+ vb2_buffer_done(&buf->vb.vb2_buf,
|
|
+ VB2_BUF_STATE_QUEUED);
|
|
+ }
|
|
+ }
|
|
+ return err;
|
|
+}
|
|
+
|
|
+/* abort streaming and wait for last buffer */
|
|
+static void meta_out_stop_streaming(struct vb2_queue *vq)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vq);
|
|
+
|
|
+ dprintk(dev, 1, "%s\n", __func__);
|
|
+ vivid_stop_generating_vid_out(dev, &dev->meta_out_streaming);
|
|
+}
|
|
+
|
|
+static void meta_out_buf_request_complete(struct vb2_buffer *vb)
|
|
+{
|
|
+ struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
|
|
+
|
|
+ v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_out);
|
|
+}
|
|
+
|
|
+const struct vb2_ops vivid_meta_out_qops = {
|
|
+ .queue_setup = meta_out_queue_setup,
|
|
+ .buf_prepare = meta_out_buf_prepare,
|
|
+ .buf_queue = meta_out_buf_queue,
|
|
+ .start_streaming = meta_out_start_streaming,
|
|
+ .stop_streaming = meta_out_stop_streaming,
|
|
+ .buf_request_complete = meta_out_buf_request_complete,
|
|
+ .wait_prepare = vb2_ops_wait_prepare,
|
|
+ .wait_finish = vb2_ops_wait_finish,
|
|
+};
|
|
+
|
|
+int vidioc_enum_fmt_meta_out(struct file *file, void *priv,
|
|
+ struct v4l2_fmtdesc *f)
|
|
+{
|
|
+ struct vivid_dev *dev = video_drvdata(file);
|
|
+
|
|
+ if (!vivid_is_webcam(dev))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (f->index > 0)
|
|
+ return -EINVAL;
|
|
+
|
|
+ f->type = V4L2_BUF_TYPE_META_OUTPUT;
|
|
+ f->pixelformat = V4L2_META_FMT_VIVID;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int vidioc_g_fmt_meta_out(struct file *file, void *priv,
|
|
+ struct v4l2_format *f)
|
|
+{
|
|
+ struct vivid_dev *dev = video_drvdata(file);
|
|
+ struct v4l2_meta_format *meta = &f->fmt.meta;
|
|
+
|
|
+ if (!vivid_is_webcam(dev) || !dev->has_meta_out)
|
|
+ return -EINVAL;
|
|
+
|
|
+ meta->dataformat = V4L2_META_FMT_VIVID;
|
|
+ meta->buffersize = sizeof(struct vivid_meta_out_buf);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void vivid_meta_out_process(struct vivid_dev *dev,
|
|
+ struct vivid_buffer *buf)
|
|
+{
|
|
+ struct vivid_meta_out_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
|
|
+
|
|
+ tpg_s_brightness(&dev->tpg, meta->brightness);
|
|
+ tpg_s_contrast(&dev->tpg, meta->contrast);
|
|
+ tpg_s_saturation(&dev->tpg, meta->saturation);
|
|
+ tpg_s_hue(&dev->tpg, meta->hue);
|
|
+ dprintk(dev, 2, " %s brightness %u contrast %u saturation %u hue %d\n",
|
|
+ __func__, meta->brightness, meta->contrast,
|
|
+ meta->saturation, meta->hue);
|
|
+}
|
|
diff --git a/drivers/media/platform/vivid/vivid-meta-out.h b/drivers/media/platform/vivid/vivid-meta-out.h
|
|
new file mode 100644
|
|
index 000000000000..0c639b7c2842
|
|
--- /dev/null
|
|
+++ b/drivers/media/platform/vivid/vivid-meta-out.h
|
|
@@ -0,0 +1,25 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-only */
|
|
+/*
|
|
+ * vivid-meta-out.h - meta output support functions.
|
|
+ */
|
|
+#ifndef _VIVID_META_OUT_H_
|
|
+#define _VIVID_META_OUT_H_
|
|
+
|
|
+struct vivid_meta_out_buf {
|
|
+ u16 brightness;
|
|
+ u16 contrast;
|
|
+ u16 saturation;
|
|
+ s16 hue;
|
|
+};
|
|
+
|
|
+void vivid_meta_out_process(struct vivid_dev *dev, struct vivid_buffer *buf);
|
|
+int vidioc_enum_fmt_meta_out(struct file *file, void *priv,
|
|
+ struct v4l2_fmtdesc *f);
|
|
+int vidioc_g_fmt_meta_out(struct file *file, void *priv,
|
|
+ struct v4l2_format *f);
|
|
+int vidioc_s_fmt_meta_out(struct file *file, void *priv,
|
|
+ struct v4l2_format *f);
|
|
+
|
|
+extern const struct vb2_ops vivid_meta_out_qops;
|
|
+
|
|
+#endif
|
|
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
index a0364ac497f9..ee3446e3217c 100644
|
|
--- a/drivers/media/platform/vivid/vivid-vid-out.c
|
|
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
|
|
@@ -1079,7 +1079,9 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o)
|
|
if (o == dev->output)
|
|
return 0;
|
|
|
|
- if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q))
|
|
+ if (vb2_is_busy(&dev->vb_vid_out_q) ||
|
|
+ vb2_is_busy(&dev->vb_vbi_out_q) ||
|
|
+ vb2_is_busy(&dev->vb_meta_out_q))
|
|
return -EBUSY;
|
|
|
|
dev->output = o;
|
|
@@ -1090,6 +1092,7 @@ int vidioc_s_output(struct file *file, void *priv, unsigned o)
|
|
dev->vid_out_dev.tvnorms = 0;
|
|
|
|
dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
|
|
+ dev->meta_out_dev.tvnorms = dev->vid_out_dev.tvnorms;
|
|
vivid_update_format_out(dev);
|
|
|
|
v4l2_ctrl_activate(dev->ctrl_display_present, vivid_is_hdmi_out(dev));
|
|
|
|
From 5e1b29e32e378f895353c5692416afade0645abf Mon Sep 17 00:00:00 2001
|
|
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Date: Tue, 22 Oct 2019 12:26:50 -0300
|
|
Subject: [PATCH] media: cedrus: Fix undefined shift with a SHIFT_AND_MASK_BITS
|
|
macro
|
|
|
|
We need to shift and mask values at different occasions to fill up
|
|
cedrus registers. This was done using macros that don't explicitly
|
|
treat arguments as unsigned, leading to possibly undefined behavior.
|
|
|
|
Introduce the SHIFT_AND_MASK_BITS macro and use it where possible.
|
|
In cases where it doesn't apply as-is, explicitly cast to unsigned
|
|
instead.
|
|
|
|
This macro should be moved to include/linux/bits.h eventually.
|
|
|
|
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 06eff2150d4db991ca236f3d05a9dc0101475aea)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 31 +++++++++++++-----------
|
|
1 file changed, 17 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index ddd29788d685..f9dd8cbf3458 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -10,6 +10,9 @@
|
|
#ifndef _CEDRUS_REGS_H_
|
|
#define _CEDRUS_REGS_H_
|
|
|
|
+#define SHIFT_AND_MASK_BITS(v, h, l) \
|
|
+ (((unsigned long)(v) << (l)) & GENMASK(h, l))
|
|
+
|
|
/*
|
|
* Common acronyms and contractions used in register descriptions:
|
|
* * VLD : Variable-Length Decoder
|
|
@@ -37,8 +40,8 @@
|
|
#define VE_PRIMARY_CHROMA_BUF_LEN 0xc4
|
|
#define VE_PRIMARY_FB_LINE_STRIDE 0xc8
|
|
|
|
-#define VE_PRIMARY_FB_LINE_STRIDE_CHROMA(s) (((s) << 16) & GENMASK(31, 16))
|
|
-#define VE_PRIMARY_FB_LINE_STRIDE_LUMA(s) (((s) << 0) & GENMASK(15, 0))
|
|
+#define VE_PRIMARY_FB_LINE_STRIDE_CHROMA(s) SHIFT_AND_MASK_BITS(s, 31, 16)
|
|
+#define VE_PRIMARY_FB_LINE_STRIDE_LUMA(s) SHIFT_AND_MASK_BITS(s, 15, 0)
|
|
|
|
#define VE_CHROMA_BUF_LEN 0xe8
|
|
|
|
@@ -46,7 +49,7 @@
|
|
#define VE_SECONDARY_OUT_FMT_EXT (0x01 << 30)
|
|
#define VE_SECONDARY_OUT_FMT_YU12 (0x02 << 30)
|
|
#define VE_SECONDARY_OUT_FMT_YV12 (0x03 << 30)
|
|
-#define VE_CHROMA_BUF_LEN_SDRT(l) ((l) & GENMASK(27, 0))
|
|
+#define VE_CHROMA_BUF_LEN_SDRT(l) SHIFT_AND_MASK_BITS(l, 27, 0)
|
|
|
|
#define VE_PRIMARY_OUT_FMT 0xec
|
|
|
|
@@ -69,15 +72,15 @@
|
|
|
|
#define VE_DEC_MPEG_MP12HDR (VE_ENGINE_DEC_MPEG + 0x00)
|
|
|
|
-#define VE_DEC_MPEG_MP12HDR_SLICE_TYPE(t) (((t) << 28) & GENMASK(30, 28))
|
|
+#define VE_DEC_MPEG_MP12HDR_SLICE_TYPE(t) SHIFT_AND_MASK_BITS(t, 30, 28)
|
|
#define VE_DEC_MPEG_MP12HDR_F_CODE_SHIFT(x, y) (24 - 4 * (y) - 8 * (x))
|
|
#define VE_DEC_MPEG_MP12HDR_F_CODE(__x, __y, __v) \
|
|
- (((__v) & GENMASK(3, 0)) << VE_DEC_MPEG_MP12HDR_F_CODE_SHIFT(__x, __y))
|
|
+ (((unsigned long)(__v) & GENMASK(3, 0)) << VE_DEC_MPEG_MP12HDR_F_CODE_SHIFT(__x, __y))
|
|
|
|
#define VE_DEC_MPEG_MP12HDR_INTRA_DC_PRECISION(p) \
|
|
- (((p) << 10) & GENMASK(11, 10))
|
|
+ SHIFT_AND_MASK_BITS(p, 11, 10)
|
|
#define VE_DEC_MPEG_MP12HDR_INTRA_PICTURE_STRUCTURE(s) \
|
|
- (((s) << 8) & GENMASK(9, 8))
|
|
+ SHIFT_AND_MASK_BITS(s, 9, 8)
|
|
#define VE_DEC_MPEG_MP12HDR_TOP_FIELD_FIRST(v) \
|
|
((v) ? BIT(7) : 0)
|
|
#define VE_DEC_MPEG_MP12HDR_FRAME_PRED_FRAME_DCT(v) \
|
|
@@ -98,19 +101,19 @@
|
|
#define VE_DEC_MPEG_PICCODEDSIZE (VE_ENGINE_DEC_MPEG + 0x08)
|
|
|
|
#define VE_DEC_MPEG_PICCODEDSIZE_WIDTH(w) \
|
|
- ((DIV_ROUND_UP((w), 16) << 8) & GENMASK(15, 8))
|
|
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP((w), 16), 15, 8)
|
|
#define VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(h) \
|
|
- ((DIV_ROUND_UP((h), 16) << 0) & GENMASK(7, 0))
|
|
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP((h), 16), 7, 0)
|
|
|
|
#define VE_DEC_MPEG_PICBOUNDSIZE (VE_ENGINE_DEC_MPEG + 0x0c)
|
|
|
|
-#define VE_DEC_MPEG_PICBOUNDSIZE_WIDTH(w) (((w) << 16) & GENMASK(27, 16))
|
|
-#define VE_DEC_MPEG_PICBOUNDSIZE_HEIGHT(h) (((h) << 0) & GENMASK(11, 0))
|
|
+#define VE_DEC_MPEG_PICBOUNDSIZE_WIDTH(w) SHIFT_AND_MASK_BITS(w, 27, 16)
|
|
+#define VE_DEC_MPEG_PICBOUNDSIZE_HEIGHT(h) SHIFT_AND_MASK_BITS(h, 11, 0)
|
|
|
|
#define VE_DEC_MPEG_MBADDR (VE_ENGINE_DEC_MPEG + 0x10)
|
|
|
|
-#define VE_DEC_MPEG_MBADDR_X(w) (((w) << 8) & GENMASK(15, 8))
|
|
-#define VE_DEC_MPEG_MBADDR_Y(h) (((h) << 0) & GENMASK(7, 0))
|
|
+#define VE_DEC_MPEG_MBADDR_X(w) SHIFT_AND_MASK_BITS(w, 15, 8)
|
|
+#define VE_DEC_MPEG_MBADDR_Y(h) SHIFT_AND_MASK_BITS(h, 7, 0)
|
|
|
|
#define VE_DEC_MPEG_CTRL (VE_ENGINE_DEC_MPEG + 0x14)
|
|
|
|
@@ -225,7 +228,7 @@
|
|
#define VE_DEC_MPEG_IQMINPUT_FLAG_INTRA (0x01 << 14)
|
|
#define VE_DEC_MPEG_IQMINPUT_FLAG_NON_INTRA (0x00 << 14)
|
|
#define VE_DEC_MPEG_IQMINPUT_WEIGHT(i, v) \
|
|
- (((v) & GENMASK(7, 0)) | (((i) << 8) & GENMASK(13, 8)))
|
|
+ (SHIFT_AND_MASK_BITS(i, 13, 8) | SHIFT_AND_MASK_BITS(v, 7, 0))
|
|
|
|
#define VE_DEC_MPEG_ERROR (VE_ENGINE_DEC_MPEG + 0xc4)
|
|
#define VE_DEC_MPEG_CRTMBADDR (VE_ENGINE_DEC_MPEG + 0xc8)
|
|
|
|
From 914dd00a8d57fd0050d02296d24c5b888c82c90c Mon Sep 17 00:00:00 2001
|
|
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Date: Tue, 22 Oct 2019 12:26:51 -0300
|
|
Subject: [PATCH] media: cedrus: Remove unnecessary parenthesis around
|
|
DIV_ROUND_UP
|
|
|
|
DIV_ROUND_UP's first argument doesn't need to be wrapped in parenthesis
|
|
since that is already being taken care of in the macro's definition.
|
|
|
|
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit c3b32900fbf5178473c6b39260e891e19067edc2)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index f9dd8cbf3458..21676a1797f1 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -101,9 +101,9 @@
|
|
#define VE_DEC_MPEG_PICCODEDSIZE (VE_ENGINE_DEC_MPEG + 0x08)
|
|
|
|
#define VE_DEC_MPEG_PICCODEDSIZE_WIDTH(w) \
|
|
- SHIFT_AND_MASK_BITS(DIV_ROUND_UP((w), 16), 15, 8)
|
|
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP(w, 16), 15, 8)
|
|
#define VE_DEC_MPEG_PICCODEDSIZE_HEIGHT(h) \
|
|
- SHIFT_AND_MASK_BITS(DIV_ROUND_UP((h), 16), 7, 0)
|
|
+ SHIFT_AND_MASK_BITS(DIV_ROUND_UP(h, 16), 7, 0)
|
|
|
|
#define VE_DEC_MPEG_PICBOUNDSIZE (VE_ENGINE_DEC_MPEG + 0x0c)
|
|
|
|
|
|
From 9e89a600b802259784605df1dcc8f22f5f618c70 Mon Sep 17 00:00:00 2001
|
|
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Date: Tue, 22 Oct 2019 12:26:52 -0300
|
|
Subject: [PATCH] media: v4l: Add definitions for HEVC stateless decoding
|
|
|
|
This introduces the required definitions for HEVC decoding support with
|
|
stateless VPUs. The controls associated to the HEVC slice format provide
|
|
the required meta-data for decoding slices extracted from the bitstream.
|
|
|
|
They are not exported to the public V4L2 API since reworking this API
|
|
will likely be needed for covering various use-cases and new hardware.
|
|
|
|
Multi-slice decoding is exposed as a valid decoding mode to match current
|
|
H.264 support but it is not yet implemented.
|
|
|
|
The interface comes with the following limitations:
|
|
* No custom quantization matrices (scaling lists);
|
|
* Support for a single temporal layer only;
|
|
* No slice entry point offsets support;
|
|
* No conformance window support;
|
|
* No VUI parameters support;
|
|
* No support for SPS extensions: range, multilayer, 3d, scc, 4 bits;
|
|
* No support for PPS extensions: range, multilayer, 3d, scc, 4 bits.
|
|
|
|
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
[hverkuil-cisco@xs4all.nl: use 1ULL in flags defines in hevc-ctrls.h]
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 256fa3920874b0f1f4cb79ad6766493a22187153)
|
|
---
|
|
Documentation/media/uapi/v4l/biblio.rst | 9 +
|
|
Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 553 +++++++++++++++++++++-
|
|
Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 18 +
|
|
Documentation/media/videodev2.h.rst.exceptions | 3 +
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 109 ++++-
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
|
|
include/media/hevc-ctrls.h | 212 +++++++++
|
|
include/media/v4l2-ctrls.h | 7 +
|
|
8 files changed, 908 insertions(+), 4 deletions(-)
|
|
create mode 100644 include/media/hevc-ctrls.h
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
|
|
index ad2ff258afa8..8095f57d3d75 100644
|
|
--- a/Documentation/media/uapi/v4l/biblio.rst
|
|
+++ b/Documentation/media/uapi/v4l/biblio.rst
|
|
@@ -131,6 +131,15 @@ ITU-T Rec. H.264 Specification (04/2017 Edition)
|
|
|
|
:author: International Telecommunication Union (http://www.itu.ch)
|
|
|
|
+.. _hevc:
|
|
+
|
|
+ITU H.265/HEVC
|
|
+==============
|
|
+
|
|
+:title: ITU-T Rec. H.265 | ISO/IEC 23008-2 "High Efficiency Video Coding"
|
|
+
|
|
+:author: International Telecommunication Union (http://www.itu.ch), International Organisation for Standardisation (http://www.iso.ch)
|
|
+
|
|
.. _jfif:
|
|
|
|
JFIF
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
index 6bb901de0939..a1209f68c5e8 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
@@ -1985,9 +1985,9 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
|
- ``reference_ts``
|
|
- Timestamp of the V4L2 capture buffer to use as reference, used
|
|
with B-coded and P-coded frames. The timestamp refers to the
|
|
- ``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.
|
|
+ ``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``
|
|
-
|
|
@@ -3695,3 +3695,550 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
|
|
Indicates whether to generate SPS and PPS at every IDR. Setting it to 0
|
|
disables generating SPS and PPS at every IDR. Setting it to one enables
|
|
generating SPS and PPS at every IDR.
|
|
+
|
|
+.. _v4l2-mpeg-hevc:
|
|
+
|
|
+``V4L2_CID_MPEG_VIDEO_HEVC_SPS (struct)``
|
|
+ Specifies the Sequence Parameter Set fields (as extracted from the
|
|
+ bitstream) for the associated HEVC slice data.
|
|
+ These bitstream parameters are defined according to :ref:`hevc`.
|
|
+ They are described in section 7.4.3.2 "Sequence parameter set RBSP
|
|
+ semantics" of the specification.
|
|
+
|
|
+.. c:type:: v4l2_ctrl_hevc_sps
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table:: struct v4l2_ctrl_hevc_sps
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - __u16
|
|
+ - ``pic_width_in_luma_samples``
|
|
+ -
|
|
+ * - __u16
|
|
+ - ``pic_height_in_luma_samples``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``bit_depth_luma_minus8``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``bit_depth_chroma_minus8``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_max_pic_order_cnt_lsb_minus4``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``sps_max_dec_pic_buffering_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``sps_max_num_reorder_pics``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``sps_max_latency_increase_plus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_min_luma_coding_block_size_minus3``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_diff_max_min_luma_coding_block_size``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_min_luma_transform_block_size_minus2``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_diff_max_min_luma_transform_block_size``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``max_transform_hierarchy_depth_inter``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``max_transform_hierarchy_depth_intra``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``pcm_sample_bit_depth_luma_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``pcm_sample_bit_depth_chroma_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_min_pcm_luma_coding_block_size_minus3``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_diff_max_min_pcm_luma_coding_block_size``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_short_term_ref_pic_sets``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_long_term_ref_pics_sps``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``chroma_format_idc``
|
|
+ -
|
|
+ * - __u64
|
|
+ - ``flags``
|
|
+ - See :ref:`Sequence Parameter Set Flags <hevc_sps_flags>`
|
|
+
|
|
+.. _hevc_sps_flags:
|
|
+
|
|
+``Sequence Parameter Set Flags``
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table::
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE``
|
|
+ - 0x00000001
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED``
|
|
+ - 0x00000002
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_AMP_ENABLED``
|
|
+ - 0x00000004
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET``
|
|
+ - 0x00000008
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_PCM_ENABLED``
|
|
+ - 0x00000010
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED``
|
|
+ - 0x00000020
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT``
|
|
+ - 0x00000040
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED``
|
|
+ - 0x00000080
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED``
|
|
+ - 0x00000100
|
|
+ -
|
|
+
|
|
+``V4L2_CID_MPEG_VIDEO_HEVC_PPS (struct)``
|
|
+ Specifies the Picture Parameter Set fields (as extracted from the
|
|
+ bitstream) for the associated HEVC slice data.
|
|
+ These bitstream parameters are defined according to :ref:`hevc`.
|
|
+ They are described in section 7.4.3.3 "Picture parameter set RBSP
|
|
+ semantics" of the specification.
|
|
+
|
|
+.. c:type:: v4l2_ctrl_hevc_pps
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table:: struct v4l2_ctrl_hevc_pps
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - __u8
|
|
+ - ``num_extra_slice_header_bits``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``init_qp_minus26``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``diff_cu_qp_delta_depth``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``pps_cb_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``pps_cr_qp_offset``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_tile_columns_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_tile_rows_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``column_width_minus1[20]``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``row_height_minus1[22]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``pps_beta_offset_div2``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``pps_tc_offset_div2``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``log2_parallel_merge_level_minus2``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``padding[4]``
|
|
+ - Applications and drivers must set this to zero.
|
|
+ * - __u64
|
|
+ - ``flags``
|
|
+ - See :ref:`Picture Parameter Set Flags <hevc_pps_flags>`
|
|
+
|
|
+.. _hevc_pps_flags:
|
|
+
|
|
+``Picture Parameter Set Flags``
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table::
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT``
|
|
+ - 0x00000001
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT``
|
|
+ - 0x00000002
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED``
|
|
+ - 0x00000004
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT``
|
|
+ - 0x00000008
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED``
|
|
+ - 0x00000010
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED``
|
|
+ - 0x00000020
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED``
|
|
+ - 0x00000040
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT``
|
|
+ - 0x00000080
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED``
|
|
+ - 0x00000100
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED``
|
|
+ - 0x00000200
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED``
|
|
+ - 0x00000400
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_TILES_ENABLED``
|
|
+ - 0x00000800
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED``
|
|
+ - 0x00001000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED``
|
|
+ - 0x00002000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED``
|
|
+ - 0x00004000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED``
|
|
+ - 0x00008000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER``
|
|
+ - 0x00010000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT``
|
|
+ - 0x00020000
|
|
+ -
|
|
+ * - ``V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT``
|
|
+ - 0x00040000
|
|
+ -
|
|
+
|
|
+``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (struct)``
|
|
+ Specifies various slice-specific parameters, especially from the NAL unit
|
|
+ header, general slice segment header and weighted prediction parameter
|
|
+ parts of the bitstream.
|
|
+ These bitstream parameters are defined according to :ref:`hevc`.
|
|
+ They are described in section 7.4.7 "General slice segment header
|
|
+ semantics" of the specification.
|
|
+
|
|
+.. c:type:: v4l2_ctrl_hevc_slice_params
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table:: struct v4l2_ctrl_hevc_slice_params
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - __u32
|
|
+ - ``bit_size``
|
|
+ - Size (in bits) of the current slice data.
|
|
+ * - __u32
|
|
+ - ``data_bit_offset``
|
|
+ - Offset (in bits) to the video data in the current slice data.
|
|
+ * - __u8
|
|
+ - ``nal_unit_type``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``nuh_temporal_id_plus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``slice_type``
|
|
+ -
|
|
+ (V4L2_HEVC_SLICE_TYPE_I, V4L2_HEVC_SLICE_TYPE_P or
|
|
+ V4L2_HEVC_SLICE_TYPE_B).
|
|
+ * - __u8
|
|
+ - ``colour_plane_id``
|
|
+ -
|
|
+ * - __u16
|
|
+ - ``slice_pic_order_cnt``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_ref_idx_l0_active_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_ref_idx_l1_active_minus1``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``collocated_ref_idx``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``five_minus_max_num_merge_cand``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_qp_delta``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_cb_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_cr_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_act_y_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_act_cb_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_act_cr_qp_offset``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_beta_offset_div2``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``slice_tc_offset_div2``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``pic_struct``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``num_active_dpb_entries``
|
|
+ - The number of entries in ``dpb``.
|
|
+ * - __u8
|
|
+ - ``ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ - The list of L0 reference elements as indices in the DPB.
|
|
+ * - __u8
|
|
+ - ``ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ - The list of L1 reference elements as indices in the DPB.
|
|
+ * - __u8
|
|
+ - ``num_rps_poc_st_curr_before``
|
|
+ - The number of reference pictures in the short-term set that come before
|
|
+ the current frame.
|
|
+ * - __u8
|
|
+ - ``num_rps_poc_st_curr_after``
|
|
+ - The number of reference pictures in the short-term set that come after
|
|
+ the current frame.
|
|
+ * - __u8
|
|
+ - ``num_rps_poc_lt_curr``
|
|
+ - The number of reference pictures in the long-term set.
|
|
+ * - __u8
|
|
+ - ``padding[7]``
|
|
+ - Applications and drivers must set this to zero.
|
|
+ * - struct :c:type:`v4l2_hevc_dpb_entry`
|
|
+ - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ - The decoded picture buffer, for meta-data about reference frames.
|
|
+ * - struct :c:type:`v4l2_hevc_pred_weight_table`
|
|
+ - ``pred_weight_table``
|
|
+ - The prediction weight coefficients for inter-picture prediction.
|
|
+ * - __u64
|
|
+ - ``flags``
|
|
+ - See :ref:`Slice Parameters Flags <hevc_slice_params_flags>`
|
|
+
|
|
+.. _hevc_slice_params_flags:
|
|
+
|
|
+``Slice Parameters Flags``
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table::
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA``
|
|
+ - 0x00000001
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA``
|
|
+ - 0x00000002
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED``
|
|
+ - 0x00000004
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO``
|
|
+ - 0x00000008
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT``
|
|
+ - 0x00000010
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0``
|
|
+ - 0x00000020
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV``
|
|
+ - 0x00000040
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED``
|
|
+ - 0x00000080
|
|
+ -
|
|
+ * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED``
|
|
+ - 0x00000100
|
|
+ -
|
|
+
|
|
+.. c:type:: v4l2_hevc_dpb_entry
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table:: struct v4l2_hevc_dpb_entry
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - __u64
|
|
+ - ``timestamp``
|
|
+ - Timestamp of the V4L2 capture buffer to use as reference, used
|
|
+ with B-coded and P-coded frames. The timestamp refers to the
|
|
+ ``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.
|
|
+ * - __u8
|
|
+ - ``rps``
|
|
+ - The reference set for the reference frame
|
|
+ (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
|
|
+ V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
|
|
+ V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
|
|
+ * - __u8
|
|
+ - ``field_pic``
|
|
+ - Whether the reference is a field picture or a frame.
|
|
+ * - __u16
|
|
+ - ``pic_order_cnt[2]``
|
|
+ - The picture order count of the reference. Only the first element of the
|
|
+ array is used for frame pictures, while the first element identifies the
|
|
+ top field and the second the bottom field in field-coded pictures.
|
|
+ * - __u8
|
|
+ - ``padding[2]``
|
|
+ - Applications and drivers must set this to zero.
|
|
+
|
|
+.. c:type:: v4l2_hevc_pred_weight_table
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table:: struct v4l2_hevc_pred_weight_table
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - __u8
|
|
+ - ``luma_log2_weight_denom``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``delta_chroma_log2_weight_denom``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
|
|
+ -
|
|
+ * - __s8
|
|
+ - ``chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2]``
|
|
+ -
|
|
+ * - __u8
|
|
+ - ``padding[6]``
|
|
+ - Applications and drivers must set this to zero.
|
|
+
|
|
+``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)``
|
|
+ Specifies the decoding mode to use. Currently exposes slice-based and
|
|
+ frame-based decoding but new modes might be added later on.
|
|
+ This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
|
|
+ pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
|
|
+ are required to set this control in order to specify the decoding mode
|
|
+ that is expected for the buffer.
|
|
+ Drivers may expose a single or multiple decoding modes, depending
|
|
+ on what they can support.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ This menu control is not yet part of the public kernel API and
|
|
+ it is expected to change.
|
|
+
|
|
+.. c:type:: v4l2_mpeg_video_hevc_decode_mode
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table::
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED``
|
|
+ - 0
|
|
+ - Decoding is done at the slice granularity.
|
|
+ The OUTPUT buffer must contain a single slice.
|
|
+ * - ``V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED``
|
|
+ - 1
|
|
+ - 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.
|
|
+
|
|
+``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (enum)``
|
|
+ Specifies the HEVC slice start code expected for each slice.
|
|
+ This control is used as a modifier for V4L2_PIX_FMT_HEVC_SLICE
|
|
+ pixel format. Applications that support V4L2_PIX_FMT_HEVC_SLICE
|
|
+ are required to set this control in order to specify the start code
|
|
+ that is expected for the buffer.
|
|
+ Drivers may expose a single or multiple start codes, depending
|
|
+ on what they can support.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ This menu control is not yet part of the public kernel API and
|
|
+ it is expected to change.
|
|
+
|
|
+.. c:type:: v4l2_mpeg_video_hevc_start_code
|
|
+
|
|
+.. cssclass:: longtable
|
|
+
|
|
+.. flat-table::
|
|
+ :header-rows: 0
|
|
+ :stub-columns: 0
|
|
+ :widths: 1 1 2
|
|
+
|
|
+ * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE``
|
|
+ - 0
|
|
+ - Selecting this value specifies that HEVC slices are passed
|
|
+ to the driver without any start code.
|
|
+ * - ``V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B``
|
|
+ - 1
|
|
+ - Selecting this value specifies that HEVC slices are expected
|
|
+ to be prefixed by Annex B start codes. According to :ref:`hevc`
|
|
+ valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
index 33aff21b7d11..6690928e657b 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
|
|
@@ -479,6 +479,24 @@ See also the examples in :ref:`control`.
|
|
- n/a
|
|
- A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
|
|
decode parameters for stateless video decoders.
|
|
+ * - ``V4L2_CTRL_TYPE_HEVC_SPS``
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - A struct :c:type:`v4l2_ctrl_hevc_sps`, containing HEVC Sequence
|
|
+ Parameter Set for stateless video decoders.
|
|
+ * - ``V4L2_CTRL_TYPE_HEVC_PPS``
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - A struct :c:type:`v4l2_ctrl_hevc_pps`, containing HEVC Picture
|
|
+ Parameter Set for stateless video decoders.
|
|
+ * - ``V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS``
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - n/a
|
|
+ - A struct :c:type:`v4l2_ctrl_hevc_slice_params`, containing HEVC
|
|
+ slice parameters for stateless video decoders.
|
|
|
|
.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
|
|
|
|
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
|
|
index c23e5ef30c78..cb6ccf91776e 100644
|
|
--- a/Documentation/media/videodev2.h.rst.exceptions
|
|
+++ b/Documentation/media/videodev2.h.rst.exceptions
|
|
@@ -141,6 +141,9 @@ replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
|
|
+replace symbol V4L2_CTRL_TYPE_HEVC_SPS :c:type:`v4l2_ctrl_type`
|
|
+replace symbol V4L2_CTRL_TYPE_HEVC_PPS :c:type:`v4l2_ctrl_type`
|
|
+replace symbol V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
|
|
replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type`
|
|
|
|
# V4L2 capability defines
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index bf50d37ef6c1..b4caf2d4d076 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -568,6 +568,16 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
|
|
"Disabled at slice boundary",
|
|
"NULL",
|
|
};
|
|
+ static const char * const hevc_decode_mode[] = {
|
|
+ "Slice-Based",
|
|
+ "Frame-Based",
|
|
+ NULL,
|
|
+ };
|
|
+ static const char * const hevc_start_code[] = {
|
|
+ "No Start Code",
|
|
+ "Annex B Start Code",
|
|
+ NULL,
|
|
+ };
|
|
|
|
switch (id) {
|
|
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
|
|
@@ -689,7 +699,10 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
|
|
return hevc_tier;
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
|
|
return hevc_loop_filter_mode;
|
|
-
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:
|
|
+ return hevc_decode_mode;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
|
|
+ return hevc_start_code;
|
|
default:
|
|
return NULL;
|
|
}
|
|
@@ -959,6 +972,11 @@ const char *v4l2_ctrl_get_name(u32 id)
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD: return "HEVC Size of Length Field";
|
|
case V4L2_CID_MPEG_VIDEO_REF_NUMBER_FOR_PFRAMES: return "Reference Frames for a P-Frame";
|
|
case V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR: return "Prepend SPS and PPS to IDR";
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_SPS: return "HEVC Sequence Parameter Set";
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_PPS: return "HEVC Picture Parameter Set";
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: return "HEVC Slice Parameters";
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE: return "HEVC Decode Mode";
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE: return "HEVC Start Code";
|
|
|
|
/* CAMERA controls */
|
|
/* Keep the order of the 'case's the same as in v4l2-controls.h! */
|
|
@@ -1268,6 +1286,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_TIER:
|
|
case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:
|
|
*type = V4L2_CTRL_TYPE_MENU;
|
|
break;
|
|
case V4L2_CID_LINK_FREQ:
|
|
@@ -1378,6 +1398,15 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
|
|
case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:
|
|
*type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER;
|
|
break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_SPS:
|
|
+ *type = V4L2_CTRL_TYPE_HEVC_SPS;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_PPS:
|
|
+ *type = V4L2_CTRL_TYPE_HEVC_PPS;
|
|
+ break;
|
|
+ case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:
|
|
+ *type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS;
|
|
+ break;
|
|
case V4L2_CID_UNIT_CELL_SIZE:
|
|
*type = V4L2_CTRL_TYPE_AREA;
|
|
*flags |= V4L2_CTRL_FLAG_READ_ONLY;
|
|
@@ -1682,8 +1711,12 @@ 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_hevc_sps *p_hevc_sps;
|
|
+ struct v4l2_ctrl_hevc_pps *p_hevc_pps;
|
|
+ struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
|
|
struct v4l2_area *area;
|
|
void *p = ptr.p + idx * ctrl->elem_size;
|
|
+ unsigned int i;
|
|
|
|
switch ((u32)ctrl->type) {
|
|
case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
|
|
@@ -1759,11 +1792,76 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
|
zero_padding(p_vp8_frame_header->entropy_header);
|
|
zero_padding(p_vp8_frame_header->coder_state);
|
|
break;
|
|
+
|
|
+ case V4L2_CTRL_TYPE_HEVC_SPS:
|
|
+ p_hevc_sps = p;
|
|
+
|
|
+ if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) {
|
|
+ p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0;
|
|
+ p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0;
|
|
+ p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0;
|
|
+ p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0;
|
|
+ }
|
|
+
|
|
+ if (!(p_hevc_sps->flags &
|
|
+ V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT))
|
|
+ p_hevc_sps->num_long_term_ref_pics_sps = 0;
|
|
+ break;
|
|
+
|
|
+ case V4L2_CTRL_TYPE_HEVC_PPS:
|
|
+ p_hevc_pps = p;
|
|
+
|
|
+ if (!(p_hevc_pps->flags &
|
|
+ V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED))
|
|
+ p_hevc_pps->diff_cu_qp_delta_depth = 0;
|
|
+
|
|
+ if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) {
|
|
+ p_hevc_pps->num_tile_columns_minus1 = 0;
|
|
+ p_hevc_pps->num_tile_rows_minus1 = 0;
|
|
+ memset(&p_hevc_pps->column_width_minus1, 0,
|
|
+ sizeof(p_hevc_pps->column_width_minus1));
|
|
+ memset(&p_hevc_pps->row_height_minus1, 0,
|
|
+ sizeof(p_hevc_pps->row_height_minus1));
|
|
+
|
|
+ p_hevc_pps->flags &=
|
|
+ ~V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED;
|
|
+ }
|
|
+
|
|
+ if (p_hevc_pps->flags &
|
|
+ V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) {
|
|
+ p_hevc_pps->pps_beta_offset_div2 = 0;
|
|
+ p_hevc_pps->pps_tc_offset_div2 = 0;
|
|
+ }
|
|
+
|
|
+ zero_padding(*p_hevc_pps);
|
|
+ break;
|
|
+
|
|
+ case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
|
+ p_hevc_slice_params = p;
|
|
+
|
|
+ if (p_hevc_slice_params->num_active_dpb_entries >
|
|
+ V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
|
|
+ return -EINVAL;
|
|
+
|
|
+ zero_padding(p_hevc_slice_params->pred_weight_table);
|
|
+
|
|
+ for (i = 0; i < p_hevc_slice_params->num_active_dpb_entries;
|
|
+ i++) {
|
|
+ struct v4l2_hevc_dpb_entry *dpb_entry =
|
|
+ &p_hevc_slice_params->dpb[i];
|
|
+
|
|
+ zero_padding(*dpb_entry);
|
|
+ }
|
|
+
|
|
+ zero_padding(*p_hevc_slice_params);
|
|
+ break;
|
|
+
|
|
case V4L2_CTRL_TYPE_AREA:
|
|
area = p;
|
|
if (!area->width || !area->height)
|
|
return -EINVAL;
|
|
break;
|
|
+
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
@@ -2438,6 +2536,15 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
|
|
elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header);
|
|
break;
|
|
+ case V4L2_CTRL_TYPE_HEVC_SPS:
|
|
+ elem_size = sizeof(struct v4l2_ctrl_hevc_sps);
|
|
+ break;
|
|
+ case V4L2_CTRL_TYPE_HEVC_PPS:
|
|
+ elem_size = sizeof(struct v4l2_ctrl_hevc_pps);
|
|
+ break;
|
|
+ case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
|
|
+ elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
|
|
+ break;
|
|
case V4L2_CTRL_TYPE_AREA:
|
|
elem_size = sizeof(struct v4l2_area);
|
|
break;
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index 2753073cf340..d26c83d4c255 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -1367,6 +1367,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
|
|
case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break;
|
|
case V4L2_PIX_FMT_VP9: descr = "VP9"; break;
|
|
case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */
|
|
+ case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break;
|
|
case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */
|
|
case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */
|
|
case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break;
|
|
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
|
|
new file mode 100644
|
|
index 000000000000..1009cf0891cc
|
|
--- /dev/null
|
|
+++ b/include/media/hevc-ctrls.h
|
|
@@ -0,0 +1,212 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * These are the HEVC state controls for use with stateless HEVC
|
|
+ * codec drivers.
|
|
+ *
|
|
+ * It turns out that these structs are not stable yet and will undergo
|
|
+ * more changes. So keep them private until they are stable and ready to
|
|
+ * become part of the official public API.
|
|
+ */
|
|
+
|
|
+#ifndef _HEVC_CTRLS_H_
|
|
+#define _HEVC_CTRLS_H_
|
|
+
|
|
+#include <linux/videodev2.h>
|
|
+
|
|
+/* The pixel format isn't stable at the moment and will likely be renamed. */
|
|
+#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') /* HEVC parsed slices */
|
|
+
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_SPS (V4L2_CID_MPEG_BASE + 1008)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_PPS (V4L2_CID_MPEG_BASE + 1009)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS (V4L2_CID_MPEG_BASE + 1010)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (V4L2_CID_MPEG_BASE + 1015)
|
|
+#define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE (V4L2_CID_MPEG_BASE + 1016)
|
|
+
|
|
+/* enum v4l2_ctrl_type type values */
|
|
+#define V4L2_CTRL_TYPE_HEVC_SPS 0x0120
|
|
+#define V4L2_CTRL_TYPE_HEVC_PPS 0x0121
|
|
+#define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122
|
|
+
|
|
+enum v4l2_mpeg_video_hevc_decode_mode {
|
|
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
|
+ V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_FRAME_BASED,
|
|
+};
|
|
+
|
|
+enum v4l2_mpeg_video_hevc_start_code {
|
|
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
|
|
+ V4L2_MPEG_VIDEO_HEVC_START_CODE_ANNEX_B,
|
|
+};
|
|
+
|
|
+#define V4L2_HEVC_SLICE_TYPE_B 0
|
|
+#define V4L2_HEVC_SLICE_TYPE_P 1
|
|
+#define V4L2_HEVC_SLICE_TYPE_I 2
|
|
+
|
|
+#define V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE (1ULL << 0)
|
|
+#define V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED (1ULL << 1)
|
|
+#define V4L2_HEVC_SPS_FLAG_AMP_ENABLED (1ULL << 2)
|
|
+#define V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET (1ULL << 3)
|
|
+#define V4L2_HEVC_SPS_FLAG_PCM_ENABLED (1ULL << 4)
|
|
+#define V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED (1ULL << 5)
|
|
+#define V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT (1ULL << 6)
|
|
+#define V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED (1ULL << 7)
|
|
+#define V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED (1ULL << 8)
|
|
+
|
|
+/* The controls are not stable at the moment and will likely be reworked. */
|
|
+struct v4l2_ctrl_hevc_sps {
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Sequence parameter set */
|
|
+ __u16 pic_width_in_luma_samples;
|
|
+ __u16 pic_height_in_luma_samples;
|
|
+ __u8 bit_depth_luma_minus8;
|
|
+ __u8 bit_depth_chroma_minus8;
|
|
+ __u8 log2_max_pic_order_cnt_lsb_minus4;
|
|
+ __u8 sps_max_dec_pic_buffering_minus1;
|
|
+ __u8 sps_max_num_reorder_pics;
|
|
+ __u8 sps_max_latency_increase_plus1;
|
|
+ __u8 log2_min_luma_coding_block_size_minus3;
|
|
+ __u8 log2_diff_max_min_luma_coding_block_size;
|
|
+ __u8 log2_min_luma_transform_block_size_minus2;
|
|
+ __u8 log2_diff_max_min_luma_transform_block_size;
|
|
+ __u8 max_transform_hierarchy_depth_inter;
|
|
+ __u8 max_transform_hierarchy_depth_intra;
|
|
+ __u8 pcm_sample_bit_depth_luma_minus1;
|
|
+ __u8 pcm_sample_bit_depth_chroma_minus1;
|
|
+ __u8 log2_min_pcm_luma_coding_block_size_minus3;
|
|
+ __u8 log2_diff_max_min_pcm_luma_coding_block_size;
|
|
+ __u8 num_short_term_ref_pic_sets;
|
|
+ __u8 num_long_term_ref_pics_sps;
|
|
+ __u8 chroma_format_idc;
|
|
+
|
|
+ __u8 padding;
|
|
+
|
|
+ __u64 flags;
|
|
+};
|
|
+
|
|
+#define V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT (1ULL << 0)
|
|
+#define V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT (1ULL << 1)
|
|
+#define V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED (1ULL << 2)
|
|
+#define V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT (1ULL << 3)
|
|
+#define V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED (1ULL << 4)
|
|
+#define V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED (1ULL << 5)
|
|
+#define V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED (1ULL << 6)
|
|
+#define V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT (1ULL << 7)
|
|
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED (1ULL << 8)
|
|
+#define V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED (1ULL << 9)
|
|
+#define V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED (1ULL << 10)
|
|
+#define V4L2_HEVC_PPS_FLAG_TILES_ENABLED (1ULL << 11)
|
|
+#define V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED (1ULL << 12)
|
|
+#define V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED (1ULL << 13)
|
|
+#define V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 14)
|
|
+#define V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED (1ULL << 15)
|
|
+#define V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER (1ULL << 16)
|
|
+#define V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT (1ULL << 17)
|
|
+#define V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT (1ULL << 18)
|
|
+
|
|
+struct v4l2_ctrl_hevc_pps {
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture parameter set */
|
|
+ __u8 num_extra_slice_header_bits;
|
|
+ __s8 init_qp_minus26;
|
|
+ __u8 diff_cu_qp_delta_depth;
|
|
+ __s8 pps_cb_qp_offset;
|
|
+ __s8 pps_cr_qp_offset;
|
|
+ __u8 num_tile_columns_minus1;
|
|
+ __u8 num_tile_rows_minus1;
|
|
+ __u8 column_width_minus1[20];
|
|
+ __u8 row_height_minus1[22];
|
|
+ __s8 pps_beta_offset_div2;
|
|
+ __s8 pps_tc_offset_div2;
|
|
+ __u8 log2_parallel_merge_level_minus2;
|
|
+
|
|
+ __u8 padding[4];
|
|
+ __u64 flags;
|
|
+};
|
|
+
|
|
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE 0x01
|
|
+#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER 0x02
|
|
+#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR 0x03
|
|
+
|
|
+#define V4L2_HEVC_DPB_ENTRIES_NUM_MAX 16
|
|
+
|
|
+struct v4l2_hevc_dpb_entry {
|
|
+ __u64 timestamp;
|
|
+ __u8 rps;
|
|
+ __u8 field_pic;
|
|
+ __u16 pic_order_cnt[2];
|
|
+ __u8 padding[2];
|
|
+};
|
|
+
|
|
+struct v4l2_hevc_pred_weight_table {
|
|
+ __s8 delta_luma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+ __s8 luma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+ __s8 delta_chroma_weight_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
|
+ __s8 chroma_offset_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
|
+
|
|
+ __s8 delta_luma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+ __s8 luma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+ __s8 delta_chroma_weight_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
|
+ __s8 chroma_offset_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX][2];
|
|
+
|
|
+ __u8 padding[6];
|
|
+
|
|
+ __u8 luma_log2_weight_denom;
|
|
+ __s8 delta_chroma_log2_weight_denom;
|
|
+};
|
|
+
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA (1ULL << 0)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA (1ULL << 1)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED (1ULL << 2)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO (1ULL << 3)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT (1ULL << 4)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0 (1ULL << 5)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV (1ULL << 6)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7)
|
|
+#define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8)
|
|
+
|
|
+struct v4l2_ctrl_hevc_slice_params {
|
|
+ __u32 bit_size;
|
|
+ __u32 data_bit_offset;
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */
|
|
+ __u8 nal_unit_type;
|
|
+ __u8 nuh_temporal_id_plus1;
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
|
+ __u8 slice_type;
|
|
+ __u8 colour_plane_id;
|
|
+ __u16 slice_pic_order_cnt;
|
|
+ __u8 num_ref_idx_l0_active_minus1;
|
|
+ __u8 num_ref_idx_l1_active_minus1;
|
|
+ __u8 collocated_ref_idx;
|
|
+ __u8 five_minus_max_num_merge_cand;
|
|
+ __s8 slice_qp_delta;
|
|
+ __s8 slice_cb_qp_offset;
|
|
+ __s8 slice_cr_qp_offset;
|
|
+ __s8 slice_act_y_qp_offset;
|
|
+ __s8 slice_act_cb_qp_offset;
|
|
+ __s8 slice_act_cr_qp_offset;
|
|
+ __s8 slice_beta_offset_div2;
|
|
+ __s8 slice_tc_offset_div2;
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Picture timing SEI message */
|
|
+ __u8 pic_struct;
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
|
+ __u8 num_active_dpb_entries;
|
|
+ __u8 ref_idx_l0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+ __u8 ref_idx_l1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+
|
|
+ __u8 num_rps_poc_st_curr_before;
|
|
+ __u8 num_rps_poc_st_curr_after;
|
|
+ __u8 num_rps_poc_lt_curr;
|
|
+
|
|
+ __u8 padding;
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */
|
|
+ struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX];
|
|
+
|
|
+ /* ISO/IEC 23008-2, ITU-T Rec. H.265: Weighted prediction parameter */
|
|
+ struct v4l2_hevc_pred_weight_table pred_weight_table;
|
|
+
|
|
+ __u64 flags;
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index 26205ba3a0a0..e719d56fc024 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -21,6 +21,7 @@
|
|
#include <media/fwht-ctrls.h>
|
|
#include <media/h264-ctrls.h>
|
|
#include <media/vp8-ctrls.h>
|
|
+#include <media/hevc-ctrls.h>
|
|
|
|
/* forward references */
|
|
struct file;
|
|
@@ -50,6 +51,9 @@ struct poll_table_struct;
|
|
* @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_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.
|
|
+ * @p_hevc_slice_params: Pointer to an HEVC slice parameters structure.
|
|
* @p_area: Pointer to an area.
|
|
* @p: Pointer to a compound value.
|
|
*/
|
|
@@ -69,6 +73,9 @@ union v4l2_ctrl_ptr {
|
|
struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
|
|
struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
|
|
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;
|
|
+ struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
|
|
struct v4l2_area *p_area;
|
|
void *p;
|
|
};
|
|
|
|
From e08abe32742aabb9d6f383909e970188d89332cf Mon Sep 17 00:00:00 2001
|
|
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Date: Tue, 22 Oct 2019 12:26:53 -0300
|
|
Subject: [PATCH] media: pixfmt: Document the HEVC slice pixel format
|
|
|
|
Document the current state of the HEVC slice pixel format.
|
|
The format will need to evolve in the future, which is why it is
|
|
not part of the public API.
|
|
|
|
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit de06f289283298e2938445019999cec46435375c)
|
|
---
|
|
Documentation/media/uapi/v4l/pixfmt-compressed.rst | 23 ++++++++++++++++++++++
|
|
1 file changed, 23 insertions(+)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
index 55d8d690f22f..561bda112809 100644
|
|
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
|
|
@@ -192,6 +192,29 @@ Compressed Formats
|
|
If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
|
|
then the decoder has no requirements since it can parse all the
|
|
information from the raw bytestream.
|
|
+ * .. _V4L2-PIX-FMT-HEVC-SLICE:
|
|
+
|
|
+ - ``V4L2_PIX_FMT_HEVC_SLICE``
|
|
+ - 'S265'
|
|
+ - HEVC parsed slice data, as extracted from the HEVC bitstream.
|
|
+ This format is adapted for stateless video decoders that implement a
|
|
+ HEVC pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
|
|
+ This pixelformat has two modifiers that must be set at least once
|
|
+ through the ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE``
|
|
+ and ``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE`` controls.
|
|
+ Metadata associated with the frame to decode is required to be passed
|
|
+ through the following controls :
|
|
+ * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS``
|
|
+ * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS``
|
|
+ * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS``
|
|
+ See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`.
|
|
+ Buffers associated with this pixel format must contain the appropriate
|
|
+ number of macroblocks to decode a full corresponding frame.
|
|
+
|
|
+ .. note::
|
|
+
|
|
+ This format is not yet part of the public kernel API and it
|
|
+ is expected to change.
|
|
* .. _V4L2-PIX-FMT-FWHT:
|
|
|
|
- ``V4L2_PIX_FMT_FWHT``
|
|
|
|
From c291fab558edebd784bafe81dafe6a65fa61dd8d Mon Sep 17 00:00:00 2001
|
|
From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Date: Tue, 22 Oct 2019 12:26:54 -0300
|
|
Subject: [PATCH] media: cedrus: Add HEVC/H.265 decoding support
|
|
|
|
This introduces support for HEVC/H.265 to the Cedrus VPU driver, with
|
|
both uni-directional and bi-directional prediction modes supported.
|
|
|
|
Field-coded (interlaced) pictures, custom quantization matrices and
|
|
10-bit output are not supported at this point.
|
|
|
|
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 86caab29da78961d73e489554c8b2573fae523d5)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/Makefile | 2 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus.c | 52 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus.h | 18 +
|
|
drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 9 +
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 616 ++++++++++++++++++++++
|
|
drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 4 +
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 271 ++++++++++
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 10 +
|
|
8 files changed, 977 insertions(+), 5 deletions(-)
|
|
create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
|
|
index c85ac6db0302..1bce49d3e7e2 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/Makefile
|
|
+++ b/drivers/staging/media/sunxi/cedrus/Makefile
|
|
@@ -2,4 +2,4 @@
|
|
obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
|
|
|
|
sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
|
|
- cedrus_mpeg2.o cedrus_h264.o
|
|
+ cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
index 0cf637c8a1e3..c6ddd46eff82 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
|
|
@@ -95,6 +95,45 @@ static const struct cedrus_control cedrus_controls[] = {
|
|
.codec = CEDRUS_CODEC_H264,
|
|
.required = false,
|
|
},
|
|
+ {
|
|
+ .cfg = {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SPS,
|
|
+ },
|
|
+ .codec = CEDRUS_CODEC_H265,
|
|
+ .required = true,
|
|
+ },
|
|
+ {
|
|
+ .cfg = {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_PPS,
|
|
+ },
|
|
+ .codec = CEDRUS_CODEC_H265,
|
|
+ .required = true,
|
|
+ },
|
|
+ {
|
|
+ .cfg = {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS,
|
|
+ },
|
|
+ .codec = CEDRUS_CODEC_H265,
|
|
+ .required = true,
|
|
+ },
|
|
+ {
|
|
+ .cfg = {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE,
|
|
+ .max = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
|
+ .def = V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED,
|
|
+ },
|
|
+ .codec = CEDRUS_CODEC_H265,
|
|
+ .required = false,
|
|
+ },
|
|
+ {
|
|
+ .cfg = {
|
|
+ .id = V4L2_CID_MPEG_VIDEO_HEVC_START_CODE,
|
|
+ .max = V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
|
|
+ .def = V4L2_MPEG_VIDEO_HEVC_START_CODE_NONE,
|
|
+ },
|
|
+ .codec = CEDRUS_CODEC_H265,
|
|
+ .required = false,
|
|
+ },
|
|
};
|
|
|
|
#define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
|
|
@@ -340,6 +379,7 @@ static int cedrus_probe(struct platform_device *pdev)
|
|
|
|
dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
|
|
dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
|
|
+ dev->dec_ops[CEDRUS_CODEC_H265] = &cedrus_dec_ops_h265;
|
|
|
|
mutex_init(&dev->dev_mutex);
|
|
|
|
@@ -450,22 +490,26 @@ static const struct cedrus_variant sun8i_a33_cedrus_variant = {
|
|
};
|
|
|
|
static const struct cedrus_variant sun8i_h3_cedrus_variant = {
|
|
- .capabilities = CEDRUS_CAPABILITY_UNTILED,
|
|
+ .capabilities = CEDRUS_CAPABILITY_UNTILED |
|
|
+ CEDRUS_CAPABILITY_H265_DEC,
|
|
.mod_rate = 402000000,
|
|
};
|
|
|
|
static const struct cedrus_variant sun50i_a64_cedrus_variant = {
|
|
- .capabilities = CEDRUS_CAPABILITY_UNTILED,
|
|
+ .capabilities = CEDRUS_CAPABILITY_UNTILED |
|
|
+ CEDRUS_CAPABILITY_H265_DEC,
|
|
.mod_rate = 402000000,
|
|
};
|
|
|
|
static const struct cedrus_variant sun50i_h5_cedrus_variant = {
|
|
- .capabilities = CEDRUS_CAPABILITY_UNTILED,
|
|
+ .capabilities = CEDRUS_CAPABILITY_UNTILED |
|
|
+ CEDRUS_CAPABILITY_H265_DEC,
|
|
.mod_rate = 402000000,
|
|
};
|
|
|
|
static const struct cedrus_variant sun50i_h6_cedrus_variant = {
|
|
- .capabilities = CEDRUS_CAPABILITY_UNTILED,
|
|
+ .capabilities = CEDRUS_CAPABILITY_UNTILED |
|
|
+ CEDRUS_CAPABILITY_H265_DEC,
|
|
.quirks = CEDRUS_QUIRK_NO_DMA_OFFSET,
|
|
.mod_rate = 600000000,
|
|
};
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
index 2f017a651848..986e059e3202 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
@@ -27,12 +27,14 @@
|
|
#define CEDRUS_NAME "cedrus"
|
|
|
|
#define CEDRUS_CAPABILITY_UNTILED BIT(0)
|
|
+#define CEDRUS_CAPABILITY_H265_DEC BIT(1)
|
|
|
|
#define CEDRUS_QUIRK_NO_DMA_OFFSET BIT(0)
|
|
|
|
enum cedrus_codec {
|
|
CEDRUS_CODEC_MPEG2,
|
|
CEDRUS_CODEC_H264,
|
|
+ CEDRUS_CODEC_H265,
|
|
CEDRUS_CODEC_LAST,
|
|
};
|
|
|
|
@@ -67,6 +69,12 @@ struct cedrus_mpeg2_run {
|
|
const struct v4l2_ctrl_mpeg2_quantization *quantization;
|
|
};
|
|
|
|
+struct cedrus_h265_run {
|
|
+ const struct v4l2_ctrl_hevc_sps *sps;
|
|
+ const struct v4l2_ctrl_hevc_pps *pps;
|
|
+ const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
|
+};
|
|
+
|
|
struct cedrus_run {
|
|
struct vb2_v4l2_buffer *src;
|
|
struct vb2_v4l2_buffer *dst;
|
|
@@ -74,6 +82,7 @@ struct cedrus_run {
|
|
union {
|
|
struct cedrus_h264_run h264;
|
|
struct cedrus_mpeg2_run mpeg2;
|
|
+ struct cedrus_h265_run h265;
|
|
};
|
|
};
|
|
|
|
@@ -110,6 +119,14 @@ struct cedrus_ctx {
|
|
void *neighbor_info_buf;
|
|
dma_addr_t neighbor_info_buf_dma;
|
|
} h264;
|
|
+ struct {
|
|
+ void *mv_col_buf;
|
|
+ dma_addr_t mv_col_buf_addr;
|
|
+ ssize_t mv_col_buf_size;
|
|
+ ssize_t mv_col_buf_unit_size;
|
|
+ void *neighbor_info_buf;
|
|
+ dma_addr_t neighbor_info_buf_addr;
|
|
+ } h265;
|
|
} codec;
|
|
};
|
|
|
|
@@ -155,6 +172,7 @@ struct cedrus_dev {
|
|
|
|
extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
|
|
extern struct cedrus_dec_ops cedrus_dec_ops_h264;
|
|
+extern struct cedrus_dec_ops cedrus_dec_ops_h265;
|
|
|
|
static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
|
|
{
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
|
index 56ca4c9ad01c..4a2fc33a1d79 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
|
|
@@ -59,6 +59,15 @@ void cedrus_device_run(void *priv)
|
|
V4L2_CID_MPEG_VIDEO_H264_SPS);
|
|
break;
|
|
|
|
+ case V4L2_PIX_FMT_HEVC_SLICE:
|
|
+ run.h265.sps = cedrus_find_control_data(ctx,
|
|
+ V4L2_CID_MPEG_VIDEO_HEVC_SPS);
|
|
+ run.h265.pps = cedrus_find_control_data(ctx,
|
|
+ V4L2_CID_MPEG_VIDEO_HEVC_PPS);
|
|
+ run.h265.slice_params = cedrus_find_control_data(ctx,
|
|
+ V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS);
|
|
+ break;
|
|
+
|
|
default:
|
|
break;
|
|
}
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
new file mode 100644
|
|
index 000000000000..9bc921866f70
|
|
--- /dev/null
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
@@ -0,0 +1,616 @@
|
|
+// SPDX-License-Identifier: GPL-2.0-or-later
|
|
+/*
|
|
+ * Cedrus VPU driver
|
|
+ *
|
|
+ * Copyright (C) 2013 Jens Kuske <jenskuske@gmail.com>
|
|
+ * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
+ * Copyright (C) 2018 Bootlin
|
|
+ */
|
|
+
|
|
+#include <linux/types.h>
|
|
+
|
|
+#include <media/videobuf2-dma-contig.h>
|
|
+
|
|
+#include "cedrus.h"
|
|
+#include "cedrus_hw.h"
|
|
+#include "cedrus_regs.h"
|
|
+
|
|
+/*
|
|
+ * These are the sizes for side buffers required by the hardware for storing
|
|
+ * internal decoding metadata. They match the values used by the early BSP
|
|
+ * implementations, that were initially exposed in libvdpau-sunxi.
|
|
+ * Subsequent BSP implementations seem to double the neighbor info buffer size
|
|
+ * for the H6 SoC, which may be related to 10 bit H265 support.
|
|
+ */
|
|
+#define CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE (397 * SZ_1K)
|
|
+#define CEDRUS_H265_ENTRY_POINTS_BUF_SIZE (4 * SZ_1K)
|
|
+#define CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE 160
|
|
+
|
|
+struct cedrus_h265_sram_frame_info {
|
|
+ __le32 top_pic_order_cnt;
|
|
+ __le32 bottom_pic_order_cnt;
|
|
+ __le32 top_mv_col_buf_addr;
|
|
+ __le32 bottom_mv_col_buf_addr;
|
|
+ __le32 luma_addr;
|
|
+ __le32 chroma_addr;
|
|
+} __packed;
|
|
+
|
|
+struct cedrus_h265_sram_pred_weight {
|
|
+ __s8 delta_weight;
|
|
+ __s8 offset;
|
|
+} __packed;
|
|
+
|
|
+static enum cedrus_irq_status cedrus_h265_irq_status(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+ u32 reg;
|
|
+
|
|
+ reg = cedrus_read(dev, VE_DEC_H265_STATUS);
|
|
+ reg &= VE_DEC_H265_STATUS_CHECK_MASK;
|
|
+
|
|
+ if (reg & VE_DEC_H265_STATUS_CHECK_ERROR ||
|
|
+ !(reg & VE_DEC_H265_STATUS_SUCCESS))
|
|
+ return CEDRUS_IRQ_ERROR;
|
|
+
|
|
+ return CEDRUS_IRQ_OK;
|
|
+}
|
|
+
|
|
+static void cedrus_h265_irq_clear(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_CHECK_MASK);
|
|
+}
|
|
+
|
|
+static void cedrus_h265_irq_disable(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+ u32 reg = cedrus_read(dev, VE_DEC_H265_CTRL);
|
|
+
|
|
+ reg &= ~VE_DEC_H265_CTRL_IRQ_MASK;
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_CTRL, reg);
|
|
+}
|
|
+
|
|
+static void cedrus_h265_sram_write_offset(struct cedrus_dev *dev, u32 offset)
|
|
+{
|
|
+ cedrus_write(dev, VE_DEC_H265_SRAM_OFFSET, offset);
|
|
+}
|
|
+
|
|
+static void cedrus_h265_sram_write_data(struct cedrus_dev *dev, void *data,
|
|
+ unsigned int size)
|
|
+{
|
|
+ u32 *word = data;
|
|
+
|
|
+ while (size >= sizeof(u32)) {
|
|
+ cedrus_write(dev, VE_DEC_H265_SRAM_DATA, *word++);
|
|
+ size -= sizeof(u32);
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline dma_addr_t
|
|
+cedrus_h265_frame_info_mv_col_buf_addr(struct cedrus_ctx *ctx,
|
|
+ unsigned int index, unsigned int field)
|
|
+{
|
|
+ return ctx->codec.h265.mv_col_buf_addr + index *
|
|
+ ctx->codec.h265.mv_col_buf_unit_size +
|
|
+ field * ctx->codec.h265.mv_col_buf_unit_size / 2;
|
|
+}
|
|
+
|
|
+static void cedrus_h265_frame_info_write_single(struct cedrus_ctx *ctx,
|
|
+ unsigned int index,
|
|
+ bool field_pic,
|
|
+ u32 pic_order_cnt[],
|
|
+ int buffer_index)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+ dma_addr_t dst_luma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 0);
|
|
+ dma_addr_t dst_chroma_addr = cedrus_dst_buf_addr(ctx, buffer_index, 1);
|
|
+ dma_addr_t mv_col_buf_addr[2] = {
|
|
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index, 0),
|
|
+ cedrus_h265_frame_info_mv_col_buf_addr(ctx, buffer_index,
|
|
+ field_pic ? 1 : 0)
|
|
+ };
|
|
+ u32 offset = VE_DEC_H265_SRAM_OFFSET_FRAME_INFO +
|
|
+ VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT * index;
|
|
+ struct cedrus_h265_sram_frame_info frame_info = {
|
|
+ .top_pic_order_cnt = cpu_to_le32(pic_order_cnt[0]),
|
|
+ .bottom_pic_order_cnt = cpu_to_le32(field_pic ?
|
|
+ pic_order_cnt[1] :
|
|
+ pic_order_cnt[0]),
|
|
+ .top_mv_col_buf_addr =
|
|
+ cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
|
|
+ .bottom_mv_col_buf_addr = cpu_to_le32(field_pic ?
|
|
+ VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[1]) :
|
|
+ VE_DEC_H265_SRAM_DATA_ADDR_BASE(mv_col_buf_addr[0])),
|
|
+ .luma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_luma_addr)),
|
|
+ .chroma_addr = cpu_to_le32(VE_DEC_H265_SRAM_DATA_ADDR_BASE(dst_chroma_addr)),
|
|
+ };
|
|
+
|
|
+ cedrus_h265_sram_write_offset(dev, offset);
|
|
+ cedrus_h265_sram_write_data(dev, &frame_info, sizeof(frame_info));
|
|
+}
|
|
+
|
|
+static void cedrus_h265_frame_info_write_dpb(struct cedrus_ctx *ctx,
|
|
+ const struct v4l2_hevc_dpb_entry *dpb,
|
|
+ u8 num_active_dpb_entries)
|
|
+{
|
|
+ struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
|
|
+ V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < num_active_dpb_entries; i++) {
|
|
+ int buffer_index = vb2_find_timestamp(vq, dpb[i].timestamp, 0);
|
|
+ u32 pic_order_cnt[2] = {
|
|
+ dpb[i].pic_order_cnt[0],
|
|
+ dpb[i].pic_order_cnt[1]
|
|
+ };
|
|
+
|
|
+ cedrus_h265_frame_info_write_single(ctx, i, dpb[i].field_pic,
|
|
+ pic_order_cnt,
|
|
+ buffer_index);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
|
|
+ const struct v4l2_hevc_dpb_entry *dpb,
|
|
+ const u8 list[],
|
|
+ u8 num_ref_idx_active,
|
|
+ u32 sram_offset)
|
|
+{
|
|
+ unsigned int i;
|
|
+ u32 word = 0;
|
|
+
|
|
+ cedrus_h265_sram_write_offset(dev, sram_offset);
|
|
+
|
|
+ for (i = 0; i < num_ref_idx_active; i++) {
|
|
+ unsigned int shift = (i % 4) * 8;
|
|
+ unsigned int index = list[i];
|
|
+ u8 value = list[i];
|
|
+
|
|
+ if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
|
|
+ value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
|
|
+
|
|
+ /* Each SRAM word gathers up to 4 references. */
|
|
+ word |= value << shift;
|
|
+
|
|
+ /* Write the word to SRAM and clear it for the next batch. */
|
|
+ if ((i % 4) == 3 || i == (num_ref_idx_active - 1)) {
|
|
+ cedrus_h265_sram_write_data(dev, &word, sizeof(word));
|
|
+ word = 0;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void cedrus_h265_pred_weight_write(struct cedrus_dev *dev,
|
|
+ const s8 delta_luma_weight[],
|
|
+ const s8 luma_offset[],
|
|
+ const s8 delta_chroma_weight[][2],
|
|
+ const s8 chroma_offset[][2],
|
|
+ u8 num_ref_idx_active,
|
|
+ u32 sram_luma_offset,
|
|
+ u32 sram_chroma_offset)
|
|
+{
|
|
+ struct cedrus_h265_sram_pred_weight pred_weight[2] = { { 0 } };
|
|
+ unsigned int i, j;
|
|
+
|
|
+ cedrus_h265_sram_write_offset(dev, sram_luma_offset);
|
|
+
|
|
+ for (i = 0; i < num_ref_idx_active; i++) {
|
|
+ unsigned int index = i % 2;
|
|
+
|
|
+ pred_weight[index].delta_weight = delta_luma_weight[i];
|
|
+ pred_weight[index].offset = luma_offset[i];
|
|
+
|
|
+ if (index == 1 || i == (num_ref_idx_active - 1))
|
|
+ cedrus_h265_sram_write_data(dev, (u32 *)&pred_weight,
|
|
+ sizeof(pred_weight));
|
|
+ }
|
|
+
|
|
+ cedrus_h265_sram_write_offset(dev, sram_chroma_offset);
|
|
+
|
|
+ for (i = 0; i < num_ref_idx_active; i++) {
|
|
+ for (j = 0; j < 2; j++) {
|
|
+ pred_weight[j].delta_weight = delta_chroma_weight[i][j];
|
|
+ pred_weight[j].offset = chroma_offset[i][j];
|
|
+ }
|
|
+
|
|
+ cedrus_h265_sram_write_data(dev, &pred_weight,
|
|
+ sizeof(pred_weight));
|
|
+ }
|
|
+}
|
|
+
|
|
+static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
|
+ struct cedrus_run *run)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+ const struct v4l2_ctrl_hevc_sps *sps;
|
|
+ const struct v4l2_ctrl_hevc_pps *pps;
|
|
+ const struct v4l2_ctrl_hevc_slice_params *slice_params;
|
|
+ const struct v4l2_hevc_pred_weight_table *pred_weight_table;
|
|
+ dma_addr_t src_buf_addr;
|
|
+ dma_addr_t src_buf_end_addr;
|
|
+ u32 chroma_log2_weight_denom;
|
|
+ u32 output_pic_list_index;
|
|
+ u32 pic_order_cnt[2];
|
|
+ u32 reg;
|
|
+
|
|
+ sps = run->h265.sps;
|
|
+ pps = run->h265.pps;
|
|
+ slice_params = run->h265.slice_params;
|
|
+ pred_weight_table = &slice_params->pred_weight_table;
|
|
+
|
|
+ /* MV column buffer size and allocation. */
|
|
+ if (!ctx->codec.h265.mv_col_buf_size) {
|
|
+ unsigned int num_buffers =
|
|
+ run->dst->vb2_buf.vb2_queue->num_buffers;
|
|
+ unsigned int log2_max_luma_coding_block_size =
|
|
+ sps->log2_min_luma_coding_block_size_minus3 + 3 +
|
|
+ sps->log2_diff_max_min_luma_coding_block_size;
|
|
+ unsigned int ctb_size_luma =
|
|
+ 1UL << log2_max_luma_coding_block_size;
|
|
+
|
|
+ /*
|
|
+ * Each CTB requires a MV col buffer with a specific unit size.
|
|
+ * Since the address is given with missing lsb bits, 1 KiB is
|
|
+ * added to each buffer to ensure proper alignment.
|
|
+ */
|
|
+ ctx->codec.h265.mv_col_buf_unit_size =
|
|
+ DIV_ROUND_UP(ctx->src_fmt.width, ctb_size_luma) *
|
|
+ DIV_ROUND_UP(ctx->src_fmt.height, ctb_size_luma) *
|
|
+ CEDRUS_H265_MV_COL_BUF_UNIT_CTB_SIZE + SZ_1K;
|
|
+
|
|
+ ctx->codec.h265.mv_col_buf_size = num_buffers *
|
|
+ ctx->codec.h265.mv_col_buf_unit_size;
|
|
+
|
|
+ ctx->codec.h265.mv_col_buf =
|
|
+ dma_alloc_coherent(dev->dev,
|
|
+ ctx->codec.h265.mv_col_buf_size,
|
|
+ &ctx->codec.h265.mv_col_buf_addr,
|
|
+ GFP_KERNEL);
|
|
+ if (!ctx->codec.h265.mv_col_buf) {
|
|
+ ctx->codec.h265.mv_col_buf_size = 0;
|
|
+ // TODO: Abort the process here.
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Activate H265 engine. */
|
|
+ cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
|
+
|
|
+ /* Source offset and length in bits. */
|
|
+
|
|
+ reg = slice_params->data_bit_offset;
|
|
+ cedrus_write(dev, VE_DEC_H265_BITS_OFFSET, reg);
|
|
+
|
|
+ reg = slice_params->bit_size - slice_params->data_bit_offset;
|
|
+ cedrus_write(dev, VE_DEC_H265_BITS_LEN, reg);
|
|
+
|
|
+ /* Source beginning and end addresses. */
|
|
+
|
|
+ src_buf_addr = vb2_dma_contig_plane_dma_addr(&run->src->vb2_buf, 0);
|
|
+
|
|
+ reg = VE_DEC_H265_BITS_ADDR_BASE(src_buf_addr);
|
|
+ reg |= VE_DEC_H265_BITS_ADDR_VALID_SLICE_DATA;
|
|
+ reg |= VE_DEC_H265_BITS_ADDR_LAST_SLICE_DATA;
|
|
+ reg |= VE_DEC_H265_BITS_ADDR_FIRST_SLICE_DATA;
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_BITS_ADDR, reg);
|
|
+
|
|
+ src_buf_end_addr = src_buf_addr +
|
|
+ DIV_ROUND_UP(slice_params->bit_size, 8);
|
|
+
|
|
+ reg = VE_DEC_H265_BITS_END_ADDR_BASE(src_buf_end_addr);
|
|
+ cedrus_write(dev, VE_DEC_H265_BITS_END_ADDR, reg);
|
|
+
|
|
+ /* Coding tree block address: start at the beginning. */
|
|
+ reg = VE_DEC_H265_DEC_CTB_ADDR_X(0) | VE_DEC_H265_DEC_CTB_ADDR_Y(0);
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_ADDR, reg);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_TILE_START_CTB, 0);
|
|
+ cedrus_write(dev, VE_DEC_H265_TILE_END_CTB, 0);
|
|
+
|
|
+ /* Clear the number of correctly-decoded coding tree blocks. */
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_CTB_NUM, 0);
|
|
+
|
|
+ /* Initialize bitstream access. */
|
|
+ cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_INIT_SWDEC);
|
|
+
|
|
+ /* Bitstream parameters. */
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_NAL_HDR_NAL_UNIT_TYPE(slice_params->nal_unit_type) |
|
|
+ VE_DEC_H265_DEC_NAL_HDR_NUH_TEMPORAL_ID_PLUS1(slice_params->nuh_temporal_id_plus1);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_NAL_HDR, reg);
|
|
+
|
|
+ /* SPS. */
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA(sps->max_transform_hierarchy_depth_intra) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTER(sps->max_transform_hierarchy_depth_inter) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_TRANSFORM_BLOCK_SIZE(sps->log2_diff_max_min_luma_transform_block_size) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_TRANSFORM_BLOCK_SIZE_MINUS2(sps->log2_min_luma_transform_block_size_minus2) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_luma_coding_block_size) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_luma_coding_block_size_minus3) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(sps->bit_depth_chroma_minus8) |
|
|
+ VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(sps->chroma_format_idc);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_STRONG_INTRA_SMOOTHING_ENABLE,
|
|
+ V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED,
|
|
+ sps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SPS_TEMPORAL_MVP_ENABLED,
|
|
+ V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED,
|
|
+ sps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SAMPLE_ADAPTIVE_OFFSET_ENABLED,
|
|
+ V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET,
|
|
+ sps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_AMP_ENABLED,
|
|
+ V4L2_HEVC_SPS_FLAG_AMP_ENABLED, sps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SPS_HDR_FLAG_SEPARATE_COLOUR_PLANE,
|
|
+ V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE,
|
|
+ sps->flags);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_SPS_HDR, reg);
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_PCM_CTRL_LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE(sps->log2_diff_max_min_pcm_luma_coding_block_size) |
|
|
+ VE_DEC_H265_DEC_PCM_CTRL_LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE_MINUS3(sps->log2_min_pcm_luma_coding_block_size_minus3) |
|
|
+ VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_CHROMA_MINUS1(sps->pcm_sample_bit_depth_chroma_minus1) |
|
|
+ VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_LUMA_MINUS1(sps->pcm_sample_bit_depth_luma_minus1);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_ENABLED,
|
|
+ V4L2_HEVC_SPS_FLAG_PCM_ENABLED, sps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_LOOP_FILTER_DISABLED,
|
|
+ V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED,
|
|
+ sps->flags);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_PCM_CTRL, reg);
|
|
+
|
|
+ /* PPS. */
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(pps->pps_cr_qp_offset) |
|
|
+ VE_DEC_H265_DEC_PPS_CTRL0_PPS_CB_QP_OFFSET(pps->pps_cb_qp_offset) |
|
|
+ VE_DEC_H265_DEC_PPS_CTRL0_INIT_QP_MINUS26(pps->init_qp_minus26) |
|
|
+ VE_DEC_H265_DEC_PPS_CTRL0_DIFF_CU_QP_DELTA_DEPTH(pps->diff_cu_qp_delta_depth);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CU_QP_DELTA_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_TRANSFORM_SKIP_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CONSTRAINED_INTRA_PRED,
|
|
+ V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL0_FLAG_SIGN_DATA_HIDING_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL0, reg);
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_PPS_CTRL1_LOG2_PARALLEL_MERGE_LEVEL_MINUS2(pps->log2_parallel_merge_level_minus2);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_ENTROPY_CODING_SYNC_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ /* TODO: VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED */
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED,
|
|
+ V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED,
|
|
+ pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_BIPRED,
|
|
+ V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED, pps->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_PRED,
|
|
+ V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED, pps->flags);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_PPS_CTRL1, reg);
|
|
+
|
|
+ /* Slice Parameters. */
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO0_PICTURE_TYPE(slice_params->pic_struct) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIVE_MINUS_MAX_NUM_MERGE_CAND(slice_params->five_minus_max_num_merge_cand) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L1_ACTIVE_MINUS1(slice_params->num_ref_idx_l1_active_minus1) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L0_ACTIVE_MINUS1(slice_params->num_ref_idx_l0_active_minus1) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLLOCATED_REF_IDX(slice_params->collocated_ref_idx) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(slice_params->colour_plane_id) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(slice_params->slice_type);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_COLLOCATED_FROM_L0,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_COLLOCATED_FROM_L0,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_CABAC_INIT,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_CABAC_INIT,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_MVD_L1_ZERO,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_MVD_L1_ZERO,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_CHROMA,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_CHROMA,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_LUMA,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_SAO_LUMA,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_TEMPORAL_MVP_ENABLE,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_TEMPORAL_MVP_ENABLED,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT,
|
|
+ V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT,
|
|
+ pps->flags);
|
|
+
|
|
+ /* FIXME: For multi-slice support. */
|
|
+ reg |= VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC;
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO0, reg);
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(slice_params->slice_tc_offset_div2) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(slice_params->slice_beta_offset_div2) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(slice_params->num_rps_poc_st_curr_after == 0) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(slice_params->slice_cr_qp_offset) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(slice_params->slice_cb_qp_offset) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(slice_params->slice_qp_delta);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED,
|
|
+ slice_params->flags);
|
|
+
|
|
+ reg |= VE_DEC_H265_FLAG(VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
|
|
+ V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED,
|
|
+ slice_params->flags);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO1, reg);
|
|
+
|
|
+ chroma_log2_weight_denom = pred_weight_table->luma_log2_weight_denom +
|
|
+ pred_weight_table->delta_chroma_log2_weight_denom;
|
|
+ reg = VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(0) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(chroma_log2_weight_denom) |
|
|
+ VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(pred_weight_table->luma_log2_weight_denom);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_SLICE_HDR_INFO2, reg);
|
|
+
|
|
+ /* Decoded picture size. */
|
|
+
|
|
+ reg = VE_DEC_H265_DEC_PIC_SIZE_WIDTH(ctx->src_fmt.width) |
|
|
+ VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(ctx->src_fmt.height);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_DEC_PIC_SIZE, reg);
|
|
+
|
|
+ /* Scaling list. */
|
|
+
|
|
+ reg = VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT;
|
|
+ cedrus_write(dev, VE_DEC_H265_SCALING_LIST_CTRL0, reg);
|
|
+
|
|
+ /* Neightbor information address. */
|
|
+ reg = VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(ctx->codec.h265.neighbor_info_buf_addr);
|
|
+ cedrus_write(dev, VE_DEC_H265_NEIGHBOR_INFO_ADDR, reg);
|
|
+
|
|
+ /* Write decoded picture buffer in pic list. */
|
|
+ cedrus_h265_frame_info_write_dpb(ctx, slice_params->dpb,
|
|
+ slice_params->num_active_dpb_entries);
|
|
+
|
|
+ /* Output frame. */
|
|
+
|
|
+ output_pic_list_index = V4L2_HEVC_DPB_ENTRIES_NUM_MAX;
|
|
+ pic_order_cnt[0] = slice_params->slice_pic_order_cnt;
|
|
+ pic_order_cnt[1] = slice_params->slice_pic_order_cnt;
|
|
+
|
|
+ cedrus_h265_frame_info_write_single(ctx, output_pic_list_index,
|
|
+ slice_params->pic_struct != 0,
|
|
+ pic_order_cnt,
|
|
+ run->dst->vb2_buf.index);
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_OUTPUT_FRAME_IDX, output_pic_list_index);
|
|
+
|
|
+ /* Reference picture list 0 (for P/B frames). */
|
|
+ if (slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_I) {
|
|
+ cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
|
+ slice_params->ref_idx_l0,
|
|
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
|
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0);
|
|
+
|
|
+ if ((pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED) ||
|
|
+ (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED))
|
|
+ cedrus_h265_pred_weight_write(dev,
|
|
+ pred_weight_table->delta_luma_weight_l0,
|
|
+ pred_weight_table->luma_offset_l0,
|
|
+ pred_weight_table->delta_chroma_weight_l0,
|
|
+ pred_weight_table->chroma_offset_l0,
|
|
+ slice_params->num_ref_idx_l0_active_minus1 + 1,
|
|
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0,
|
|
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0);
|
|
+ }
|
|
+
|
|
+ /* Reference picture list 1 (for B frames). */
|
|
+ if (slice_params->slice_type == V4L2_HEVC_SLICE_TYPE_B) {
|
|
+ cedrus_h265_ref_pic_list_write(dev, slice_params->dpb,
|
|
+ slice_params->ref_idx_l1,
|
|
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
|
+ VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1);
|
|
+
|
|
+ if (pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED)
|
|
+ cedrus_h265_pred_weight_write(dev,
|
|
+ pred_weight_table->delta_luma_weight_l1,
|
|
+ pred_weight_table->luma_offset_l1,
|
|
+ pred_weight_table->delta_chroma_weight_l1,
|
|
+ pred_weight_table->chroma_offset_l1,
|
|
+ slice_params->num_ref_idx_l1_active_minus1 + 1,
|
|
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1,
|
|
+ VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1);
|
|
+ }
|
|
+
|
|
+ /* Enable appropriate interruptions. */
|
|
+ cedrus_write(dev, VE_DEC_H265_CTRL, VE_DEC_H265_CTRL_IRQ_MASK);
|
|
+}
|
|
+
|
|
+static int cedrus_h265_start(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+
|
|
+ /* The buffer size is calculated at setup time. */
|
|
+ ctx->codec.h265.mv_col_buf_size = 0;
|
|
+
|
|
+ ctx->codec.h265.neighbor_info_buf =
|
|
+ dma_alloc_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
|
+ &ctx->codec.h265.neighbor_info_buf_addr,
|
|
+ GFP_KERNEL);
|
|
+ if (!ctx->codec.h265.neighbor_info_buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void cedrus_h265_stop(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+
|
|
+ if (ctx->codec.h265.mv_col_buf_size > 0) {
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h265.mv_col_buf_size,
|
|
+ ctx->codec.h265.mv_col_buf,
|
|
+ ctx->codec.h265.mv_col_buf_addr);
|
|
+
|
|
+ ctx->codec.h265.mv_col_buf_size = 0;
|
|
+ }
|
|
+
|
|
+ dma_free_coherent(dev->dev, CEDRUS_H265_NEIGHBOR_INFO_BUF_SIZE,
|
|
+ ctx->codec.h265.neighbor_info_buf,
|
|
+ ctx->codec.h265.neighbor_info_buf_addr);
|
|
+}
|
|
+
|
|
+static void cedrus_h265_trigger(struct cedrus_ctx *ctx)
|
|
+{
|
|
+ struct cedrus_dev *dev = ctx->dev;
|
|
+
|
|
+ cedrus_write(dev, VE_DEC_H265_TRIGGER, VE_DEC_H265_TRIGGER_DEC_SLICE);
|
|
+}
|
|
+
|
|
+struct cedrus_dec_ops cedrus_dec_ops_h265 = {
|
|
+ .irq_clear = cedrus_h265_irq_clear,
|
|
+ .irq_disable = cedrus_h265_irq_disable,
|
|
+ .irq_status = cedrus_h265_irq_status,
|
|
+ .setup = cedrus_h265_setup,
|
|
+ .start = cedrus_h265_start,
|
|
+ .stop = cedrus_h265_stop,
|
|
+ .trigger = cedrus_h265_trigger,
|
|
+};
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
index e7e18424bab1..570a9165dd5d 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
@@ -50,6 +50,10 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
|
reg |= VE_MODE_DEC_H264;
|
|
break;
|
|
|
|
+ case CEDRUS_CODEC_H265:
|
|
+ reg |= VE_MODE_DEC_H265;
|
|
+ break;
|
|
+
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index 21676a1797f1..6fc28d21a6c7 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -21,10 +21,17 @@
|
|
* * MC: Motion Compensation
|
|
* * STCD: Start Code Detect
|
|
* * SDRT: Scale Down and Rotate
|
|
+ * * WB: Writeback
|
|
+ * * BITS/BS: Bitstream
|
|
+ * * MB: Macroblock
|
|
+ * * CTU: Coding Tree Unit
|
|
+ * * CTB: Coding Tree Block
|
|
+ * * IDX: Index
|
|
*/
|
|
|
|
#define VE_ENGINE_DEC_MPEG 0x100
|
|
#define VE_ENGINE_DEC_H264 0x200
|
|
+#define VE_ENGINE_DEC_H265 0x500
|
|
|
|
#define VE_MODE 0x00
|
|
|
|
@@ -235,6 +242,270 @@
|
|
#define VE_DEC_MPEG_ROT_LUMA (VE_ENGINE_DEC_MPEG + 0xcc)
|
|
#define VE_DEC_MPEG_ROT_CHROMA (VE_ENGINE_DEC_MPEG + 0xd0)
|
|
|
|
+#define VE_DEC_H265_DEC_NAL_HDR (VE_ENGINE_DEC_H265 + 0x00)
|
|
+
|
|
+#define VE_DEC_H265_DEC_NAL_HDR_NUH_TEMPORAL_ID_PLUS1(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 8, 6)
|
|
+#define VE_DEC_H265_DEC_NAL_HDR_NAL_UNIT_TYPE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 5, 0)
|
|
+
|
|
+#define VE_DEC_H265_FLAG(reg_flag, ctrl_flag, flags) \
|
|
+ (((flags) & (ctrl_flag)) ? reg_flag : 0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SPS_HDR (VE_ENGINE_DEC_H265 + 0x04)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_FLAG_STRONG_INTRA_SMOOTHING_ENABLE BIT(26)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_FLAG_SPS_TEMPORAL_MVP_ENABLED BIT(25)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_FLAG_SAMPLE_ADAPTIVE_OFFSET_ENABLED BIT(24)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_FLAG_AMP_ENABLED BIT(23)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_FLAG_SEPARATE_COLOUR_PLANE BIT(2)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 22, 20)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTER(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 19, 17)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_TRANSFORM_BLOCK_SIZE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 16, 15)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_TRANSFORM_BLOCK_SIZE_MINUS2(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 14, 13)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 12, 11)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 10, 9)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_CHROMA_MINUS8(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 8, 6)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_BIT_DEPTH_LUMA_MINUS8(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 5, 3)
|
|
+#define VE_DEC_H265_DEC_SPS_HDR_CHROMA_FORMAT_IDC(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 1, 0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PIC_SIZE (VE_ENGINE_DEC_H265 + 0x08)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PIC_SIZE_WIDTH(w) (((w) << 0) & GENMASK(13, 0))
|
|
+#define VE_DEC_H265_DEC_PIC_SIZE_HEIGHT(h) (((h) << 16) & GENMASK(29, 16))
|
|
+
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL (VE_ENGINE_DEC_H265 + 0x0c)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_ENABLED BIT(15)
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_FLAG_PCM_LOOP_FILTER_DISABLED BIT(14)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 11, 10)
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE_MINUS3(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 9, 8)
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_CHROMA_MINUS1(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 7, 4)
|
|
+#define VE_DEC_H265_DEC_PCM_CTRL_PCM_SAMPLE_BIT_DEPTH_LUMA_MINUS1(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 3, 0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0 (VE_ENGINE_DEC_H265 + 0x10)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CU_QP_DELTA_ENABLED BIT(3)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_FLAG_TRANSFORM_SKIP_ENABLED BIT(2)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_FLAG_CONSTRAINED_INTRA_PRED BIT(1)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_FLAG_SIGN_DATA_HIDING_ENABLED BIT(0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_PPS_CR_QP_OFFSET(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 29, 24)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_PPS_CB_QP_OFFSET(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 21, 16)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_INIT_QP_MINUS26(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 14, 8)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL0_DIFF_CU_QP_DELTA_DEPTH(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 5, 4)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1 (VE_ENGINE_DEC_H265 + 0x14)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(6)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED BIT(5)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_ENTROPY_CODING_SYNC_ENABLED BIT(4)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TILES_ENABLED BIT(3)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_TRANSQUANT_BYPASS_ENABLED BIT(2)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_BIPRED BIT(1)
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_FLAG_WEIGHTED_PRED BIT(0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_PPS_CTRL1_LOG2_PARALLEL_MERGE_LEVEL_MINUS2(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 10, 8)
|
|
+
|
|
+#define VE_DEC_H265_SCALING_LIST_CTRL0 (VE_ENGINE_DEC_H265 + 0x18)
|
|
+
|
|
+#define VE_DEC_H265_SCALING_LIST_CTRL0_FLAG_ENABLED BIT(31)
|
|
+
|
|
+#define VE_DEC_H265_SCALING_LIST_CTRL0_SRAM (0 << 30)
|
|
+#define VE_DEC_H265_SCALING_LIST_CTRL0_DEFAULT (1 << 30)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0 (VE_ENGINE_DEC_H265 + 0x20)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_COLLOCATED_FROM_L0 BIT(11)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_CABAC_INIT BIT(10)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_MVD_L1_ZERO BIT(9)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_CHROMA BIT(8)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_SAO_LUMA BIT(7)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_SLICE_TEMPORAL_MVP_ENABLE BIT(6)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_DEPENDENT_SLICE_SEGMENT BIT(1)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FLAG_FIRST_SLICE_SEGMENT_IN_PIC BIT(0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_PICTURE_TYPE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 29, 28)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_FIVE_MINUS_MAX_NUM_MERGE_CAND(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 26, 24)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L1_ACTIVE_MINUS1(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 23, 20)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_NUM_REF_IDX_L0_ACTIVE_MINUS1(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 19, 16)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLLOCATED_REF_IDX(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 15, 12)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_COLOUR_PLANE_ID(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 5, 4)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO0_SLICE_TYPE(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 3, 2)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1 (VE_ENGINE_DEC_H265 + 0x24)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED BIT(23)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED BIT(22)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_TC_OFFSET_DIV2(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 31, 28)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_BETA_OFFSET_DIV2(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 27, 24)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_POC_BIGEST_IN_RPS_ST(v) \
|
|
+ ((v) ? BIT(21) : 0)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CR_QP_OFFSET(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 20, 16)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_CB_QP_OFFSET(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 12, 8)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO1_SLICE_QP_DELTA(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 6, 0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO2 (VE_ENGINE_DEC_H265 + 0x28)
|
|
+
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO2_NUM_ENTRY_POINT_OFFSETS(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 21, 8)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO2_CHROMA_LOG2_WEIGHT_DENOM(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 6, 4)
|
|
+#define VE_DEC_H265_DEC_SLICE_HDR_INFO2_LUMA_LOG2_WEIGHT_DENOM(v) \
|
|
+ SHIFT_AND_MASK_BITS(v, 2, 0)
|
|
+
|
|
+#define VE_DEC_H265_DEC_CTB_ADDR (VE_ENGINE_DEC_H265 + 0x2c)
|
|
+
|
|
+#define VE_DEC_H265_DEC_CTB_ADDR_Y(y) SHIFT_AND_MASK_BITS(y, 25, 16)
|
|
+#define VE_DEC_H265_DEC_CTB_ADDR_X(x) SHIFT_AND_MASK_BITS(x, 9, 0)
|
|
+
|
|
+#define VE_DEC_H265_CTRL (VE_ENGINE_DEC_H265 + 0x30)
|
|
+
|
|
+#define VE_DEC_H265_CTRL_DDR_CONSISTENCY_EN BIT(31)
|
|
+#define VE_DEC_H265_CTRL_STCD_EN BIT(25)
|
|
+#define VE_DEC_H265_CTRL_EPTB_DEC_BYPASS_EN BIT(24)
|
|
+#define VE_DEC_H265_CTRL_TQ_BYPASS_EN BIT(12)
|
|
+#define VE_DEC_H265_CTRL_VLD_BYPASS_EN BIT(11)
|
|
+#define VE_DEC_H265_CTRL_NCRI_CACHE_DISABLE BIT(10)
|
|
+#define VE_DEC_H265_CTRL_ROTATE_SCALE_OUT_EN BIT(9)
|
|
+#define VE_DEC_H265_CTRL_MC_NO_WRITEBACK BIT(8)
|
|
+#define VE_DEC_H265_CTRL_VLD_DATA_REQ_IRQ_EN BIT(2)
|
|
+#define VE_DEC_H265_CTRL_ERROR_IRQ_EN BIT(1)
|
|
+#define VE_DEC_H265_CTRL_FINISH_IRQ_EN BIT(0)
|
|
+#define VE_DEC_H265_CTRL_IRQ_MASK \
|
|
+ (VE_DEC_H265_CTRL_FINISH_IRQ_EN | VE_DEC_H265_CTRL_ERROR_IRQ_EN | \
|
|
+ VE_DEC_H265_CTRL_VLD_DATA_REQ_IRQ_EN)
|
|
+
|
|
+#define VE_DEC_H265_TRIGGER (VE_ENGINE_DEC_H265 + 0x34)
|
|
+
|
|
+#define VE_DEC_H265_TRIGGER_STCD_VC1 (0x02 << 4)
|
|
+#define VE_DEC_H265_TRIGGER_STCD_AVS (0x01 << 4)
|
|
+#define VE_DEC_H265_TRIGGER_STCD_HEVC (0x00 << 4)
|
|
+#define VE_DEC_H265_TRIGGER_DEC_SLICE (0x08 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_INIT_SWDEC (0x07 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_BYTE_ALIGN (0x06 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_GET_VLCUE (0x05 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_GET_VLCSE (0x04 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_FLUSH_BITS (0x03 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_GET_BITS (0x02 << 0)
|
|
+#define VE_DEC_H265_TRIGGER_SHOW_BITS (0x01 << 0)
|
|
+
|
|
+#define VE_DEC_H265_STATUS (VE_ENGINE_DEC_H265 + 0x38)
|
|
+
|
|
+#define VE_DEC_H265_STATUS_STCD BIT(24)
|
|
+#define VE_DEC_H265_STATUS_STCD_BUSY BIT(21)
|
|
+#define VE_DEC_H265_STATUS_WB_BUSY BIT(20)
|
|
+#define VE_DEC_H265_STATUS_BS_DMA_BUSY BIT(19)
|
|
+#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(18)
|
|
+#define VE_DEC_H265_STATUS_INTER_BUSY BIT(17)
|
|
+#define VE_DEC_H265_STATUS_MORE_DATA BIT(16)
|
|
+#define VE_DEC_H265_STATUS_VLD_BUSY BIT(14)
|
|
+#define VE_DEC_H265_STATUS_DEBLOCKING_BUSY BIT(13)
|
|
+#define VE_DEC_H265_STATUS_DEBLOCKING_DRAM_BUSY BIT(12)
|
|
+#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(11)
|
|
+#define VE_DEC_H265_STATUS_SAO_BUSY BIT(10)
|
|
+#define VE_DEC_H265_STATUS_MVP_BUSY BIT(9)
|
|
+#define VE_DEC_H265_STATUS_SWDEC_BUSY BIT(8)
|
|
+#define VE_DEC_H265_STATUS_OVER_TIME BIT(3)
|
|
+#define VE_DEC_H265_STATUS_VLD_DATA_REQ BIT(2)
|
|
+#define VE_DEC_H265_STATUS_ERROR BIT(1)
|
|
+#define VE_DEC_H265_STATUS_SUCCESS BIT(0)
|
|
+#define VE_DEC_H265_STATUS_STCD_TYPE_MASK GENMASK(23, 22)
|
|
+#define VE_DEC_H265_STATUS_CHECK_MASK \
|
|
+ (VE_DEC_H265_STATUS_SUCCESS | VE_DEC_H265_STATUS_ERROR | \
|
|
+ VE_DEC_H265_STATUS_VLD_DATA_REQ)
|
|
+#define VE_DEC_H265_STATUS_CHECK_ERROR \
|
|
+ (VE_DEC_H265_STATUS_ERROR | VE_DEC_H265_STATUS_VLD_DATA_REQ)
|
|
+
|
|
+#define VE_DEC_H265_DEC_CTB_NUM (VE_ENGINE_DEC_H265 + 0x3c)
|
|
+
|
|
+#define VE_DEC_H265_BITS_ADDR (VE_ENGINE_DEC_H265 + 0x40)
|
|
+
|
|
+#define VE_DEC_H265_BITS_ADDR_FIRST_SLICE_DATA BIT(30)
|
|
+#define VE_DEC_H265_BITS_ADDR_LAST_SLICE_DATA BIT(29)
|
|
+#define VE_DEC_H265_BITS_ADDR_VALID_SLICE_DATA BIT(28)
|
|
+#define VE_DEC_H265_BITS_ADDR_BASE(a) (((a) >> 8) & GENMASK(27, 0))
|
|
+
|
|
+#define VE_DEC_H265_BITS_OFFSET (VE_ENGINE_DEC_H265 + 0x44)
|
|
+#define VE_DEC_H265_BITS_LEN (VE_ENGINE_DEC_H265 + 0x48)
|
|
+
|
|
+#define VE_DEC_H265_BITS_END_ADDR (VE_ENGINE_DEC_H265 + 0x4c)
|
|
+
|
|
+#define VE_DEC_H265_BITS_END_ADDR_BASE(a) ((a) >> 8)
|
|
+
|
|
+#define VE_DEC_H265_SDRT_CTRL (VE_ENGINE_DEC_H265 + 0x50)
|
|
+#define VE_DEC_H265_SDRT_LUMA_ADDR (VE_ENGINE_DEC_H265 + 0x54)
|
|
+#define VE_DEC_H265_SDRT_CHROMA_ADDR (VE_ENGINE_DEC_H265 + 0x58)
|
|
+
|
|
+#define VE_DEC_H265_OUTPUT_FRAME_IDX (VE_ENGINE_DEC_H265 + 0x5c)
|
|
+
|
|
+#define VE_DEC_H265_NEIGHBOR_INFO_ADDR (VE_ENGINE_DEC_H265 + 0x60)
|
|
+
|
|
+#define VE_DEC_H265_NEIGHBOR_INFO_ADDR_BASE(a) ((a) >> 8)
|
|
+
|
|
+#define VE_DEC_H265_ENTRY_POINT_OFFSET_ADDR (VE_ENGINE_DEC_H265 + 0x64)
|
|
+#define VE_DEC_H265_TILE_START_CTB (VE_ENGINE_DEC_H265 + 0x68)
|
|
+#define VE_DEC_H265_TILE_END_CTB (VE_ENGINE_DEC_H265 + 0x6c)
|
|
+
|
|
+#define VE_DEC_H265_LOW_ADDR (VE_ENGINE_DEC_H265 + 0x80)
|
|
+
|
|
+#define VE_DEC_H265_LOW_ADDR_PRIMARY_CHROMA(a) \
|
|
+ SHIFT_AND_MASK_BITS(a, 31, 24)
|
|
+#define VE_DEC_H265_LOW_ADDR_SECONDARY_CHROMA(a) \
|
|
+ SHIFT_AND_MASK_BITS(a, 23, 16)
|
|
+#define VE_DEC_H265_LOW_ADDR_ENTRY_POINTS_BUF(a) \
|
|
+ SHIFT_AND_MASK_BITS(a, 7, 0)
|
|
+
|
|
+#define VE_DEC_H265_SRAM_OFFSET (VE_ENGINE_DEC_H265 + 0xe0)
|
|
+
|
|
+#define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0 0x00
|
|
+#define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L0 0x20
|
|
+#define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L1 0x60
|
|
+#define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_CHROMA_L1 0x80
|
|
+#define VE_DEC_H265_SRAM_OFFSET_FRAME_INFO 0x400
|
|
+#define VE_DEC_H265_SRAM_OFFSET_FRAME_INFO_UNIT 0x20
|
|
+#define VE_DEC_H265_SRAM_OFFSET_SCALING_LISTS 0x800
|
|
+#define VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST0 0xc00
|
|
+#define VE_DEC_H265_SRAM_OFFSET_REF_PIC_LIST1 0xc10
|
|
+
|
|
+#define VE_DEC_H265_SRAM_DATA (VE_ENGINE_DEC_H265 + 0xe4)
|
|
+
|
|
+#define VE_DEC_H265_SRAM_DATA_ADDR_BASE(a) ((a) >> 8)
|
|
+#define VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF BIT(7)
|
|
+
|
|
#define VE_H264_SPS 0x200
|
|
#define VE_H264_SPS_MBS_ONLY BIT(18)
|
|
#define VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD BIT(17)
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
index f745f66c4440..cc15a5cf107d 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
@@ -41,6 +41,11 @@ static struct cedrus_format cedrus_formats[] = {
|
|
.pixelformat = V4L2_PIX_FMT_H264_SLICE,
|
|
.directions = CEDRUS_DECODE_SRC,
|
|
},
|
|
+ {
|
|
+ .pixelformat = V4L2_PIX_FMT_HEVC_SLICE,
|
|
+ .directions = CEDRUS_DECODE_SRC,
|
|
+ .capabilities = CEDRUS_CAPABILITY_H265_DEC,
|
|
+ },
|
|
{
|
|
.pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12,
|
|
.directions = CEDRUS_DECODE_DST,
|
|
@@ -102,6 +107,7 @@ void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
|
|
switch (pix_fmt->pixelformat) {
|
|
case V4L2_PIX_FMT_MPEG2_SLICE:
|
|
case V4L2_PIX_FMT_H264_SLICE:
|
|
+ case V4L2_PIX_FMT_HEVC_SLICE:
|
|
/* Zero bytes per line for encoded source. */
|
|
bytesperline = 0;
|
|
/* Choose some minimum size since this can't be 0 */
|
|
@@ -439,6 +445,10 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|
ctx->current_codec = CEDRUS_CODEC_H264;
|
|
break;
|
|
|
|
+ case V4L2_PIX_FMT_HEVC_SLICE:
|
|
+ ctx->current_codec = CEDRUS_CODEC_H265;
|
|
+ break;
|
|
+
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
From 1b3898c63abbf6e077caae7f4d5018c66768c58f Mon Sep 17 00:00:00 2001
|
|
From: Fabio Estevam <festevam@gmail.com>
|
|
Date: Tue, 15 Oct 2019 13:00:39 -0300
|
|
Subject: [PATCH] media: imx.rst: Specify the sabreauto variant
|
|
|
|
Improve the documentation by specifying that the instructions
|
|
are related to the i.MX6Q sabreauto variant.
|
|
|
|
This avoids confusion if someone follows these steps on a i.MX6DL
|
|
sabreauto, which has different numbering on the I2C bus and
|
|
I2C muxes.
|
|
|
|
Signed-off-by: Fabio Estevam <festevam@gmail.com>
|
|
Acked-by: Steve Longerbeam <slongerbeam@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 5ea537161d3ac227b4960ea588ebfb44a296a188)
|
|
---
|
|
Documentation/media/v4l-drivers/imx.rst | 6 +++---
|
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
|
|
index 1d7eb8c7bd5c..3d72e411b93d 100644
|
|
--- a/Documentation/media/v4l-drivers/imx.rst
|
|
+++ b/Documentation/media/v4l-drivers/imx.rst
|
|
@@ -515,10 +515,10 @@ Streaming can then begin independently on the capture device nodes
|
|
be used to select any supported YUV pixelformat on the capture device
|
|
nodes, including planar.
|
|
|
|
-SabreAuto with ADV7180 decoder
|
|
-------------------------------
|
|
+i.MX6Q SabreAuto with ADV7180 decoder
|
|
+-------------------------------------
|
|
|
|
-On the SabreAuto, an on-board ADV7180 SD decoder is connected to the
|
|
+On the i.MX6Q SabreAuto, an on-board ADV7180 SD decoder is connected to the
|
|
parallel bus input on the internal video mux to IPU1 CSI0.
|
|
|
|
The following example configures a pipeline to capture from the ADV7180
|
|
|
|
From 3a5a0a7eea70a913ad7467272702cd54d99183f4 Mon Sep 17 00:00:00 2001
|
|
From: Fabio Estevam <festevam@gmail.com>
|
|
Date: Tue, 15 Oct 2019 13:00:40 -0300
|
|
Subject: [PATCH] media: imx.rst: Provide a real example for the output format
|
|
|
|
In the i.MX6Q sabreauto pipeline example, it is better to provide
|
|
a real example for the output format, so do it just like in the
|
|
previous lines for consistency.
|
|
|
|
Signed-off-by: Fabio Estevam <festevam@gmail.com>
|
|
Acked-by: Steve Longerbeam <slongerbeam@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit f3398f328a5ca8926aee9f5b477d2984ada210a2)
|
|
---
|
|
Documentation/media/v4l-drivers/imx.rst | 4 +---
|
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
|
|
index 3d72e411b93d..36e8d1226ac6 100644
|
|
--- a/Documentation/media/v4l-drivers/imx.rst
|
|
+++ b/Documentation/media/v4l-drivers/imx.rst
|
|
@@ -547,8 +547,6 @@ This example configures a pipeline to capture from the ADV7180
|
|
video decoder, assuming PAL 720x576 input signals, with Motion
|
|
Compensated de-interlacing. The adv7180 must output sequential or
|
|
alternating fields (field type 'seq-tb' for PAL, or 'alternate').
|
|
-$outputfmt can be any format supported by the ipu1_ic_prpvf entity
|
|
-at its output pad:
|
|
|
|
.. code-block:: none
|
|
|
|
@@ -565,7 +563,7 @@ at its output pad:
|
|
media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
|
|
media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
|
|
media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
|
|
- media-ctl -V "'ipu1_ic_prpvf':1 [fmt:$outputfmt field:none]"
|
|
+ media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
|
|
|
|
Streaming can then begin on the capture device node at
|
|
"ipu1_ic_prpvf capture". The v4l2-ctl tool can be used to select any
|
|
|
|
From 8e15620b54201ed8e2065f034caef1bfc383ed10 Mon Sep 17 00:00:00 2001
|
|
From: Fabio Estevam <festevam@gmail.com>
|
|
Date: Tue, 15 Oct 2019 13:00:41 -0300
|
|
Subject: [PATCH] media: imx.rst: Provide instructions for the i.MX6DL
|
|
sabreauto
|
|
|
|
The i.MX6DL sabreauto has different numbering on the I2C bus and
|
|
I2C muxes compared to the i.MX6Q as shown in the kernel log below:
|
|
|
|
[ 5.159423] imx-media: ipu1_csi0_mux:5 -> ipu1_csi0:0
|
|
[ 5.164618] imx-media: ipu1_csi1_mux:5 -> ipu1_csi1:0
|
|
[ 5.169953] imx-media: adv7180 4-0021:0 -> ipu1_csi0_mux:4
|
|
|
|
To avoid confusion, add an entry that shows how to setup the links and
|
|
configure the pads that are specific to the i.MX6DL sabreauto.
|
|
|
|
Signed-off-by: Fabio Estevam <festevam@gmail.com>
|
|
Acked-by: Steve Longerbeam <slongerbeam@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit bdb5b5911c4e82b1b911c48f722a5a52ac48cf97)
|
|
---
|
|
Documentation/media/v4l-drivers/imx.rst | 58 +++++++++++++++++++++++++++++++++
|
|
1 file changed, 58 insertions(+)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
|
|
index 36e8d1226ac6..aab68d8ef2c9 100644
|
|
--- a/Documentation/media/v4l-drivers/imx.rst
|
|
+++ b/Documentation/media/v4l-drivers/imx.rst
|
|
@@ -572,6 +572,64 @@ supported YUV or RGB pixelformat on the capture device node.
|
|
This platform accepts Composite Video analog inputs to the ADV7180 on
|
|
Ain1 (connector J42).
|
|
|
|
+i.MX6DL SabreAuto with ADV7180 decoder
|
|
+--------------------------------------
|
|
+
|
|
+On the i.MX6DL SabreAuto, an on-board ADV7180 SD decoder is connected to the
|
|
+parallel bus input on the internal video mux to IPU1 CSI0.
|
|
+
|
|
+The following example configures a pipeline to capture from the ADV7180
|
|
+video decoder, assuming NTSC 720x480 input signals, using simple
|
|
+interweave (unconverted and without motion compensation). The adv7180
|
|
+must output sequential or alternating fields (field type 'seq-bt' for
|
|
+NTSC, or 'alternate'):
|
|
+
|
|
+.. code-block:: none
|
|
+
|
|
+ # Setup links
|
|
+ media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
|
|
+ media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
|
|
+ media-ctl -l "'ipu1_csi0':2 -> 'ipu1_csi0 capture':0[1]"
|
|
+ # Configure pads
|
|
+ media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x480 field:seq-bt]"
|
|
+ media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x480]"
|
|
+ media-ctl -V "'ipu1_csi0':2 [fmt:AYUV32/720x480]"
|
|
+ # Configure "ipu1_csi0 capture" interface (assumed at /dev/video0)
|
|
+ v4l2-ctl -d0 --set-fmt-video=field=interlaced_bt
|
|
+
|
|
+Streaming can then begin on /dev/video0. The v4l2-ctl tool can also be
|
|
+used to select any supported YUV pixelformat on /dev/video0.
|
|
+
|
|
+This example configures a pipeline to capture from the ADV7180
|
|
+video decoder, assuming PAL 720x576 input signals, with Motion
|
|
+Compensated de-interlacing. The adv7180 must output sequential or
|
|
+alternating fields (field type 'seq-tb' for PAL, or 'alternate').
|
|
+
|
|
+.. code-block:: none
|
|
+
|
|
+ # Setup links
|
|
+ media-ctl -l "'adv7180 4-0021':0 -> 'ipu1_csi0_mux':4[1]"
|
|
+ media-ctl -l "'ipu1_csi0_mux':5 -> 'ipu1_csi0':0[1]"
|
|
+ media-ctl -l "'ipu1_csi0':1 -> 'ipu1_vdic':0[1]"
|
|
+ media-ctl -l "'ipu1_vdic':2 -> 'ipu1_ic_prp':0[1]"
|
|
+ media-ctl -l "'ipu1_ic_prp':2 -> 'ipu1_ic_prpvf':0[1]"
|
|
+ media-ctl -l "'ipu1_ic_prpvf':1 -> 'ipu1_ic_prpvf capture':0[1]"
|
|
+ # Configure pads
|
|
+ media-ctl -V "'adv7180 4-0021':0 [fmt:UYVY2X8/720x576 field:seq-tb]"
|
|
+ media-ctl -V "'ipu1_csi0_mux':5 [fmt:UYVY2X8/720x576]"
|
|
+ media-ctl -V "'ipu1_csi0':1 [fmt:AYUV32/720x576]"
|
|
+ media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
|
|
+ media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
|
|
+ media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
|
|
+ # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
|
|
+ v4l2-ctl -d2 --set-fmt-video=field=none
|
|
+
|
|
+Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
|
|
+used to select any supported YUV pixelformat on /dev/video2.
|
|
+
|
|
+This platform accepts Composite Video analog inputs to the ADV7180 on
|
|
+Ain1 (connector J42).
|
|
+
|
|
SabreSD with MIPI CSI-2 OV5640
|
|
------------------------------
|
|
|
|
|
|
From 62778a8dd6e9ff7ce069bf745bd031c91e2f13d4 Mon Sep 17 00:00:00 2001
|
|
From: Fabio Estevam <festevam@gmail.com>
|
|
Date: Tue, 15 Oct 2019 13:00:42 -0300
|
|
Subject: [PATCH] media: imx.rst: Pass the v4l2-ctl configuration
|
|
|
|
Pass the v4l2-ctl configuration for the imx6q-sabreauto PAL
|
|
example for completeness and consistency.
|
|
|
|
Suggested-by: Steve Longerbeam <slongerbeam@gmail.com>
|
|
Signed-off-by: Fabio Estevam <festevam@gmail.com>
|
|
Acked-by: Steve Longerbeam <slongerbeam@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 11893eb845679b7d3773b768950dbde246d43bfc)
|
|
---
|
|
Documentation/media/v4l-drivers/imx.rst | 7 ++++---
|
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst
|
|
index aab68d8ef2c9..1246573c1019 100644
|
|
--- a/Documentation/media/v4l-drivers/imx.rst
|
|
+++ b/Documentation/media/v4l-drivers/imx.rst
|
|
@@ -564,10 +564,11 @@ alternating fields (field type 'seq-tb' for PAL, or 'alternate').
|
|
media-ctl -V "'ipu1_vdic':2 [fmt:AYUV32/720x576 field:none]"
|
|
media-ctl -V "'ipu1_ic_prp':2 [fmt:AYUV32/720x576 field:none]"
|
|
media-ctl -V "'ipu1_ic_prpvf':1 [fmt:AYUV32/720x576 field:none]"
|
|
+ # Configure "ipu1_ic_prpvf capture" interface (assumed at /dev/video2)
|
|
+ v4l2-ctl -d2 --set-fmt-video=field=none
|
|
|
|
-Streaming can then begin on the capture device node at
|
|
-"ipu1_ic_prpvf capture". The v4l2-ctl tool can be used to select any
|
|
-supported YUV or RGB pixelformat on the capture device node.
|
|
+Streaming can then begin on /dev/video2. The v4l2-ctl tool can also be
|
|
+used to select any supported YUV pixelformat on /dev/video2.
|
|
|
|
This platform accepts Composite Video analog inputs to the ADV7180 on
|
|
Ain1 (connector J42).
|
|
|
|
From 872d462f6fdf9cb7d24030aff6687b858d18c622 Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Mon, 7 Oct 2019 10:49:59 -0300
|
|
Subject: [PATCH] media: vimc: initialize vim entity pointers to NULL
|
|
|
|
since NULL value for vimc entity pointer indicates
|
|
that entity creation failed and this is tested, the
|
|
pointers should be initialized to NULL.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 817d0b3278f52d4d20b9706e41c808287ee909e4)
|
|
---
|
|
drivers/media/platform/vimc/vimc-core.c | 5 ++---
|
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
|
|
index 2d20a7c10398..65048bd7d80b 100644
|
|
--- a/drivers/media/platform/vimc/vimc-core.c
|
|
+++ b/drivers/media/platform/vimc/vimc-core.c
|
|
@@ -199,9 +199,8 @@ static int vimc_register_devices(struct vimc_device *vimc)
|
|
}
|
|
|
|
/* allocate ent_devs */
|
|
- vimc->ent_devs = kmalloc_array(vimc->pipe_cfg->num_ents,
|
|
- sizeof(*vimc->ent_devs),
|
|
- GFP_KERNEL);
|
|
+ vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents,
|
|
+ sizeof(*vimc->ent_devs), GFP_KERNEL);
|
|
if (!vimc->ent_devs) {
|
|
ret = -ENOMEM;
|
|
goto err_v4l2_unregister;
|
|
|
|
From cdb3b345ddeedc8b484c8194b2d37be707e95763 Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Mon, 7 Oct 2019 10:50:00 -0300
|
|
Subject: [PATCH] media: vimc: cleanup code that assigns entity in entities
|
|
array
|
|
|
|
Since the add callback returns NULL on failure and the array
|
|
is initialized to NULLs, there is no need for the intermediate
|
|
assignment to local var.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 4996992c4f7410e9a43aa3047e8034756cece21a)
|
|
---
|
|
drivers/media/platform/vimc/vimc-core.c | 6 ++----
|
|
1 file changed, 2 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
|
|
index 65048bd7d80b..97a272f3350a 100644
|
|
--- a/drivers/media/platform/vimc/vimc-core.c
|
|
+++ b/drivers/media/platform/vimc/vimc-core.c
|
|
@@ -160,19 +160,17 @@ static int vimc_create_links(struct vimc_device *vimc)
|
|
static int vimc_add_subdevs(struct vimc_device *vimc)
|
|
{
|
|
unsigned int i;
|
|
- struct vimc_ent_device *ved;
|
|
|
|
for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
|
|
dev_dbg(&vimc->pdev.dev, "new entity for %s\n",
|
|
vimc->pipe_cfg->ents[i].name);
|
|
- ved = vimc->pipe_cfg->ents[i].add(vimc,
|
|
+ vimc->ent_devs[i] = vimc->pipe_cfg->ents[i].add(vimc,
|
|
vimc->pipe_cfg->ents[i].name);
|
|
- if (!ved) {
|
|
+ if (!vimc->ent_devs[i]) {
|
|
dev_err(&vimc->pdev.dev, "add new entity for %s\n",
|
|
vimc->pipe_cfg->ents[i].name);
|
|
return -EINVAL;
|
|
}
|
|
- vimc->ent_devs[i] = ved;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
From 7dbfa577fd6a4a1a23ee7d22733d59ca8e493671 Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Mon, 7 Oct 2019 10:50:01 -0300
|
|
Subject: [PATCH] media: vimc: sen: register subdevice only after
|
|
initialization
|
|
|
|
vimc_sen_add function first registers the subdevice and then
|
|
calls tpg_alloc. If tpg_alloc fails it unregisters the subdevice
|
|
and then frees vsen, this cause double free since the release
|
|
callback that follows subdevice unregistration also frees vsen.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 291aca4e7bdd87a01e21d90382fd0b231b280272)
|
|
---
|
|
drivers/media/platform/vimc/vimc-sensor.c | 20 ++++++++++----------
|
|
1 file changed, 10 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 46dc6a535abe..ee2306c08569 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -358,6 +358,13 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
goto err_free_vsen;
|
|
}
|
|
|
|
+ /* Initialize the test pattern generator */
|
|
+ tpg_init(&vsen->tpg, vsen->mbus_format.width,
|
|
+ vsen->mbus_format.height);
|
|
+ ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
|
|
+ if (ret)
|
|
+ goto err_free_hdl;
|
|
+
|
|
/* Initialize ved and sd */
|
|
ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
|
|
vcfg_name,
|
|
@@ -365,7 +372,7 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
(const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
|
|
&vimc_sen_int_ops, &vimc_sen_ops);
|
|
if (ret)
|
|
- goto err_free_hdl;
|
|
+ goto err_free_tpg;
|
|
|
|
vsen->ved.process_frame = vimc_sen_process_frame;
|
|
vsen->dev = &vimc->pdev.dev;
|
|
@@ -373,17 +380,10 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
/* Initialize the frame format */
|
|
vsen->mbus_format = fmt_default;
|
|
|
|
- /* Initialize the test pattern generator */
|
|
- tpg_init(&vsen->tpg, vsen->mbus_format.width,
|
|
- vsen->mbus_format.height);
|
|
- ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
|
|
- if (ret)
|
|
- goto err_unregister_ent_sd;
|
|
-
|
|
return &vsen->ved;
|
|
|
|
-err_unregister_ent_sd:
|
|
- vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
|
|
+err_free_tpg:
|
|
+ tpg_free(&vsen->tpg);
|
|
err_free_hdl:
|
|
v4l2_ctrl_handler_free(&vsen->hdl);
|
|
err_free_vsen:
|
|
|
|
From 14cd75bd0288eeeb1fe756a1286d76b1a942239f Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Mon, 7 Oct 2019 10:50:02 -0300
|
|
Subject: [PATCH] media: vimc: move media_entity_cleanup to release callbacks
|
|
|
|
according to the docs, this function must be called during
|
|
the cleanup phase after unregistering the entity.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 9fb82aaa85d3d4b7be80a15dd0e740aab45bc491)
|
|
---
|
|
drivers/media/platform/vimc/vimc-capture.c | 2 +-
|
|
drivers/media/platform/vimc/vimc-common.c | 1 -
|
|
drivers/media/platform/vimc/vimc-debayer.c | 1 +
|
|
drivers/media/platform/vimc/vimc-scaler.c | 1 +
|
|
drivers/media/platform/vimc/vimc-sensor.c | 1 +
|
|
5 files changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
|
|
index 602f80323031..5f353c20e605 100644
|
|
--- a/drivers/media/platform/vimc/vimc-capture.c
|
|
+++ b/drivers/media/platform/vimc/vimc-capture.c
|
|
@@ -330,6 +330,7 @@ static void vimc_cap_release(struct video_device *vdev)
|
|
struct vimc_cap_device *vcap =
|
|
container_of(vdev, struct vimc_cap_device, vdev);
|
|
|
|
+ media_entity_cleanup(vcap->ved.ent);
|
|
vimc_pads_cleanup(vcap->ved.pads);
|
|
kfree(vcap);
|
|
}
|
|
@@ -340,7 +341,6 @@ void vimc_cap_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
|
|
vcap = container_of(ved, struct vimc_cap_device, ved);
|
|
vb2_queue_release(&vcap->queue);
|
|
- media_entity_cleanup(ved->ent);
|
|
video_unregister_device(&vcap->vdev);
|
|
}
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index a3120f4f7a90..999bc353fb10 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -423,7 +423,6 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
|
|
|
|
void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
|
|
{
|
|
- media_entity_cleanup(ved->ent);
|
|
v4l2_device_unregister_subdev(sd);
|
|
}
|
|
EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index feac47d79449..e1bad6713cde 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -477,6 +477,7 @@ static void vimc_deb_release(struct v4l2_subdev *sd)
|
|
struct vimc_deb_device *vdeb =
|
|
container_of(sd, struct vimc_deb_device, sd);
|
|
|
|
+ media_entity_cleanup(vdeb->ved.ent);
|
|
vimc_pads_cleanup(vdeb->ved.pads);
|
|
kfree(vdeb);
|
|
}
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index a6a3cc5be872..1982bc089af5 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -336,6 +336,7 @@ static void vimc_sca_release(struct v4l2_subdev *sd)
|
|
struct vimc_sca_device *vsca =
|
|
container_of(sd, struct vimc_sca_device, sd);
|
|
|
|
+ media_entity_cleanup(vsca->ved.ent);
|
|
vimc_pads_cleanup(vsca->ved.pads);
|
|
kfree(vsca);
|
|
}
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index ee2306c08569..63fe024ccea5 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -291,6 +291,7 @@ static void vimc_sen_release(struct v4l2_subdev *sd)
|
|
|
|
v4l2_ctrl_handler_free(&vsen->hdl);
|
|
tpg_free(&vsen->tpg);
|
|
+ media_entity_cleanup(vsen->ved.ent);
|
|
vimc_pads_cleanup(vsen->ved.pads);
|
|
kfree(vsen);
|
|
}
|
|
|
|
From 6cf7feeb6535cb48bf9a763b98c2a35d41f59c0c Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Mon, 7 Oct 2019 10:50:03 -0300
|
|
Subject: [PATCH] media: vimc: remove the helper function
|
|
vimc_ent_sd_unregister
|
|
|
|
since this function only calls v4l2_device_unregister_subdev,
|
|
it is pointless.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit b4aa975cbd8775cd7b0e68531b2ff9a16e215181)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.c | 5 -----
|
|
drivers/media/platform/vimc/vimc-common.h | 12 ------------
|
|
drivers/media/platform/vimc/vimc-debayer.c | 2 +-
|
|
drivers/media/platform/vimc/vimc-scaler.c | 2 +-
|
|
drivers/media/platform/vimc/vimc-sensor.c | 2 +-
|
|
5 files changed, 3 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 999bc353fb10..67b53dc1849d 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -421,8 +421,3 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
}
|
|
EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
|
|
|
|
-void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
|
|
-{
|
|
- v4l2_device_unregister_subdev(sd);
|
|
-}
|
|
-EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index 698db7c07645..af5b1166dc1f 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -251,18 +251,6 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
const struct v4l2_subdev_internal_ops *sd_int_ops,
|
|
const struct v4l2_subdev_ops *sd_ops);
|
|
|
|
-/**
|
|
- * vimc_ent_sd_unregister - cleanup and unregister a subdev node
|
|
- *
|
|
- * @ved: the vimc_ent_device struct to be cleaned up
|
|
- * @sd: the v4l2_subdev struct to be unregistered
|
|
- *
|
|
- * Helper function cleanup and unregister the struct vimc_ent_device and struct
|
|
- * v4l2_subdev which represents a subdev node in the topology
|
|
- */
|
|
-void vimc_ent_sd_unregister(struct vimc_ent_device *ved,
|
|
- struct v4l2_subdev *sd);
|
|
-
|
|
/**
|
|
* vimc_link_validate - validates a media link
|
|
*
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index e1bad6713cde..4e5316c671e0 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -491,7 +491,7 @@ void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
struct vimc_deb_device *vdeb;
|
|
|
|
vdeb = container_of(ved, struct vimc_deb_device, ved);
|
|
- vimc_ent_sd_unregister(ved, &vdeb->sd);
|
|
+ v4l2_device_unregister_subdev(&vdeb->sd);
|
|
}
|
|
|
|
struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index 1982bc089af5..4fe2ba578652 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -350,7 +350,7 @@ void vimc_sca_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
struct vimc_sca_device *vsca;
|
|
|
|
vsca = container_of(ved, struct vimc_sca_device, ved);
|
|
- vimc_ent_sd_unregister(ved, &vsca->sd);
|
|
+ v4l2_device_unregister_subdev(&vsca->sd);
|
|
}
|
|
|
|
struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 63fe024ccea5..14838362d871 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -305,7 +305,7 @@ void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
struct vimc_sen_device *vsen;
|
|
|
|
vsen = container_of(ved, struct vimc_sen_device, ved);
|
|
- vimc_ent_sd_unregister(ved, &vsen->sd);
|
|
+ v4l2_device_unregister_subdev(&vsen->sd);
|
|
}
|
|
|
|
/* Image Processing Controls */
|
|
|
|
From c169a3e1e4e8b243a429555d44b4ef63c4e3db5b Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Tue, 22 Oct 2019 05:46:07 -0300
|
|
Subject: [PATCH] media: vimc: remove EXPORT_SYMBOL_GPL declarations
|
|
|
|
vimc is a single kernel module and does not need to
|
|
export any symbols therefore there is no need for these
|
|
declarations.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 3b04de4e7a56caf40c6d84994f58a4e5e985a6cd)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.c | 8 --------
|
|
drivers/media/platform/vimc/vimc-streamer.c | 1 -
|
|
2 files changed, 9 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 67b53dc1849d..611f4e0448b8 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -171,7 +171,6 @@ const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
|
|
|
|
return &vimc_pix_map_list[i];
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
|
|
|
|
const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
|
|
{
|
|
@@ -183,7 +182,6 @@ const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
|
|
}
|
|
return NULL;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
|
|
|
|
const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
|
|
{
|
|
@@ -195,7 +193,6 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
|
|
}
|
|
return NULL;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat);
|
|
|
|
/* Helper function to allocate and initialize pads */
|
|
struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
|
|
@@ -216,7 +213,6 @@ struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
|
|
|
|
return pads;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_pads_init);
|
|
|
|
int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
|
|
{
|
|
@@ -245,7 +241,6 @@ int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
|
|
|
|
return 0;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_pipeline_s_stream);
|
|
|
|
static int vimc_get_mbus_format(struct media_pad *pad,
|
|
struct v4l2_subdev_format *fmt)
|
|
@@ -357,7 +352,6 @@ int vimc_link_validate(struct media_link *link)
|
|
|
|
return 0;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_link_validate);
|
|
|
|
static const struct media_entity_operations vimc_ent_sd_mops = {
|
|
.link_validate = vimc_link_validate,
|
|
@@ -419,5 +413,3 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
vimc_pads_cleanup(ved->pads);
|
|
return ret;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
|
|
-
|
|
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
|
|
index faa2879c25df..092833623ac1 100644
|
|
--- a/drivers/media/platform/vimc/vimc-streamer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-streamer.c
|
|
@@ -216,4 +216,3 @@ int vimc_streamer_s_stream(struct vimc_stream *stream,
|
|
|
|
return 0;
|
|
}
|
|
-EXPORT_SYMBOL_GPL(vimc_streamer_s_stream);
|
|
|
|
From 1d103c5aafe2ca6ae0afb79fdabf912530eedd4f Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Tue, 22 Oct 2019 05:46:08 -0300
|
|
Subject: [PATCH] media: vimc: common: remove unused function
|
|
'vimc_pipeline_s_stream'
|
|
|
|
The function 'vimc_pipeline_s_stream' is not used and can be
|
|
removed.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit af2bdbbe2d4314a0dd85c4f7243d3ac7893078c4)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.c | 28 ----------------------------
|
|
drivers/media/platform/vimc/vimc-common.h | 11 -----------
|
|
2 files changed, 39 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 611f4e0448b8..31bd198f16fe 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -214,34 +214,6 @@ struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
|
|
return pads;
|
|
}
|
|
|
|
-int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
|
|
-{
|
|
- struct v4l2_subdev *sd;
|
|
- struct media_pad *pad;
|
|
- unsigned int i;
|
|
- int ret;
|
|
-
|
|
- for (i = 0; i < ent->num_pads; i++) {
|
|
- if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
|
|
- continue;
|
|
-
|
|
- /* Start the stream in the subdevice direct connected */
|
|
- pad = media_entity_remote_pad(&ent->pads[i]);
|
|
- if (!pad)
|
|
- continue;
|
|
-
|
|
- if (!is_media_entity_v4l2_subdev(pad->entity))
|
|
- return -EINVAL;
|
|
-
|
|
- sd = media_entity_to_v4l2_subdev(pad->entity);
|
|
- ret = v4l2_subdev_call(sd, video, s_stream, enable);
|
|
- if (ret && ret != -ENOIOCTLCMD)
|
|
- return ret;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static int vimc_get_mbus_format(struct media_pad *pad,
|
|
struct v4l2_subdev_format *fmt)
|
|
{
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index af5b1166dc1f..c4471e72ad2b 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -192,17 +192,6 @@ static inline void vimc_pads_cleanup(struct media_pad *pads)
|
|
kfree(pads);
|
|
}
|
|
|
|
-/**
|
|
- * vimc_pipeline_s_stream - start stream through the pipeline
|
|
- *
|
|
- * @ent: the pointer to struct media_entity for the node
|
|
- * @enable: 1 to start the stream and 0 to stop
|
|
- *
|
|
- * Helper function to call the s_stream of the subdevices connected
|
|
- * in all the sink pads of the entity
|
|
- */
|
|
-int vimc_pipeline_s_stream(struct media_entity *ent, int enable);
|
|
-
|
|
/**
|
|
* vimc_pix_map_by_index - get vimc_pix_map struct by its index
|
|
*
|
|
|
|
From 3c88624e09ca455e2e99f7ae43022cb32d6701bf Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Wed, 9 Oct 2019 16:09:26 -0300
|
|
Subject: [PATCH] media: vimc: remove unused struct declaration
|
|
vimc_platform_data
|
|
|
|
the struct vimc_platform_data is not used anymore and can be removed.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit ad1cec89db964cc3391fa67b1d1d93482727a439)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.h | 15 ---------------
|
|
1 file changed, 15 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index c4471e72ad2b..1f8da4f8d4db 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -57,21 +57,6 @@ do { \
|
|
(fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT; \
|
|
} while (0)
|
|
|
|
-/**
|
|
- * struct vimc_platform_data - platform data to components
|
|
- *
|
|
- * @entity_name: The name of the entity to be created
|
|
- *
|
|
- * Board setup code will often provide additional information using the device's
|
|
- * platform_data field to hold additional information.
|
|
- * When injecting a new platform_device in the component system the core needs
|
|
- * to provide to the corresponding submodules the name of the entity that should
|
|
- * be used when registering the subdevice in the Media Controller system.
|
|
- */
|
|
-struct vimc_platform_data {
|
|
- char entity_name[32];
|
|
-};
|
|
-
|
|
/**
|
|
* struct vimc_pix_map - maps media bus code with v4l2 pixel format
|
|
*
|
|
|
|
From f7df01eabef1c33150dd9b8d3feead4a78ae318f Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Thu, 3 Oct 2019 09:59:42 -0300
|
|
Subject: [PATCH] media: vimc: embed the pads of entities in the entities'
|
|
structs
|
|
|
|
since the pads array is of known small size, there is no reason to
|
|
allocate it separately. Instead, it is embedded in the entity struct.
|
|
This also conforms to the media controller doc:
|
|
'Most drivers will embed the pads array in a driver-specific structure,
|
|
avoiding dynamic allocation.'
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
[hverkuil-cisco@xs4all.nl: remove unused vimc_pads_init()]
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 23df45d038662da2b1e017cf38165a88dfd7f543)
|
|
---
|
|
drivers/media/platform/vimc/vimc-capture.c | 17 ++++-----------
|
|
drivers/media/platform/vimc/vimc-common.c | 33 +++---------------------------
|
|
drivers/media/platform/vimc/vimc-common.h | 33 +++++-------------------------
|
|
drivers/media/platform/vimc/vimc-debayer.c | 8 +++++---
|
|
drivers/media/platform/vimc/vimc-scaler.c | 8 +++++---
|
|
drivers/media/platform/vimc/vimc-sensor.c | 6 +++---
|
|
6 files changed, 25 insertions(+), 80 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
|
|
index 5f353c20e605..936bfb96ebaa 100644
|
|
--- a/drivers/media/platform/vimc/vimc-capture.c
|
|
+++ b/drivers/media/platform/vimc/vimc-capture.c
|
|
@@ -30,6 +30,7 @@ struct vimc_cap_device {
|
|
struct mutex lock;
|
|
u32 sequence;
|
|
struct vimc_stream stream;
|
|
+ struct media_pad pad;
|
|
};
|
|
|
|
static const struct v4l2_pix_format fmt_default = {
|
|
@@ -331,7 +332,6 @@ static void vimc_cap_release(struct video_device *vdev)
|
|
container_of(vdev, struct vimc_cap_device, vdev);
|
|
|
|
media_entity_cleanup(vcap->ved.ent);
|
|
- vimc_pads_cleanup(vcap->ved.pads);
|
|
kfree(vcap);
|
|
}
|
|
|
|
@@ -398,21 +398,14 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
if (!vcap)
|
|
return NULL;
|
|
|
|
- /* Allocate the pads */
|
|
- vcap->ved.pads =
|
|
- vimc_pads_init(1, (const unsigned long[1]) {MEDIA_PAD_FL_SINK});
|
|
- if (IS_ERR(vcap->ved.pads)) {
|
|
- ret = PTR_ERR(vcap->ved.pads);
|
|
- goto err_free_vcap;
|
|
- }
|
|
-
|
|
/* Initialize the media entity */
|
|
vcap->vdev.entity.name = vcfg_name;
|
|
vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
|
|
+ vcap->pad.flags = MEDIA_PAD_FL_SINK;
|
|
ret = media_entity_pads_init(&vcap->vdev.entity,
|
|
- 1, vcap->ved.pads);
|
|
+ 1, &vcap->pad);
|
|
if (ret)
|
|
- goto err_clean_pads;
|
|
+ goto err_free_vcap;
|
|
|
|
/* Initialize the lock */
|
|
mutex_init(&vcap->lock);
|
|
@@ -481,8 +474,6 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
vb2_queue_release(q);
|
|
err_clean_m_ent:
|
|
media_entity_cleanup(&vcap->vdev.entity);
|
|
-err_clean_pads:
|
|
- vimc_pads_cleanup(vcap->ved.pads);
|
|
err_free_vcap:
|
|
kfree(vcap);
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 31bd198f16fe..2a0c40e9ae88 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -194,26 +194,6 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
|
|
return NULL;
|
|
}
|
|
|
|
-/* Helper function to allocate and initialize pads */
|
|
-struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
|
|
-{
|
|
- struct media_pad *pads;
|
|
- unsigned int i;
|
|
-
|
|
- /* Allocate memory for the pads */
|
|
- pads = kcalloc(num_pads, sizeof(*pads), GFP_KERNEL);
|
|
- if (!pads)
|
|
- return ERR_PTR(-ENOMEM);
|
|
-
|
|
- /* Initialize the pads */
|
|
- for (i = 0; i < num_pads; i++) {
|
|
- pads[i].index = i;
|
|
- pads[i].flags = pads_flag[i];
|
|
- }
|
|
-
|
|
- return pads;
|
|
-}
|
|
-
|
|
static int vimc_get_mbus_format(struct media_pad *pad,
|
|
struct v4l2_subdev_format *fmt)
|
|
{
|
|
@@ -335,17 +315,12 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
const char *const name,
|
|
u32 function,
|
|
u16 num_pads,
|
|
- const unsigned long *pads_flag,
|
|
+ struct media_pad *pads,
|
|
const struct v4l2_subdev_internal_ops *sd_int_ops,
|
|
const struct v4l2_subdev_ops *sd_ops)
|
|
{
|
|
int ret;
|
|
|
|
- /* Allocate the pads. Should be released from the sd_int_op release */
|
|
- ved->pads = vimc_pads_init(num_pads, pads_flag);
|
|
- if (IS_ERR(ved->pads))
|
|
- return PTR_ERR(ved->pads);
|
|
-
|
|
/* Fill the vimc_ent_device struct */
|
|
ved->ent = &sd->entity;
|
|
|
|
@@ -364,9 +339,9 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
|
|
|
|
/* Initialize the media entity */
|
|
- ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
|
|
+ ret = media_entity_pads_init(&sd->entity, num_pads, pads);
|
|
if (ret)
|
|
- goto err_clean_pads;
|
|
+ return ret;
|
|
|
|
/* Register the subdev with the v4l2 and the media framework */
|
|
ret = v4l2_device_register_subdev(v4l2_dev, sd);
|
|
@@ -381,7 +356,5 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
|
|
err_clean_m_ent:
|
|
media_entity_cleanup(&sd->entity);
|
|
-err_clean_pads:
|
|
- vimc_pads_cleanup(ved->pads);
|
|
return ret;
|
|
}
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index 1f8da4f8d4db..ac01182e8b27 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -75,10 +75,10 @@ struct vimc_pix_map {
|
|
};
|
|
|
|
/**
|
|
- * struct vimc_ent_device - core struct that represents a node in the topology
|
|
+ * struct vimc_ent_device - core struct that represents an entity in the
|
|
+ * topology
|
|
*
|
|
* @ent: the pointer to struct media_entity for the node
|
|
- * @pads: the list of pads of the node
|
|
* @process_frame: callback send a frame to that node
|
|
* @vdev_get_format: callback that returns the current format a pad, used
|
|
* only when is_media_entity_v4l2_video_device(ent) returns
|
|
@@ -94,7 +94,6 @@ struct vimc_pix_map {
|
|
*/
|
|
struct vimc_ent_device {
|
|
struct media_entity *ent;
|
|
- struct media_pad *pads;
|
|
void * (*process_frame)(struct vimc_ent_device *ved,
|
|
const void *frame);
|
|
void (*vdev_get_format)(struct vimc_ent_device *ved,
|
|
@@ -154,29 +153,6 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
const char *vcfg_name);
|
|
void vimc_sen_rm(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
|
|
-/**
|
|
- * vimc_pads_init - initialize pads
|
|
- *
|
|
- * @num_pads: number of pads to initialize
|
|
- * @pads_flags: flags to use in each pad
|
|
- *
|
|
- * Helper functions to allocate/initialize pads
|
|
- */
|
|
-struct media_pad *vimc_pads_init(u16 num_pads,
|
|
- const unsigned long *pads_flag);
|
|
-
|
|
-/**
|
|
- * vimc_pads_cleanup - free pads
|
|
- *
|
|
- * @pads: pointer to the pads
|
|
- *
|
|
- * Helper function to free the pads initialized with vimc_pads_init
|
|
- */
|
|
-static inline void vimc_pads_cleanup(struct media_pad *pads)
|
|
-{
|
|
- kfree(pads);
|
|
-}
|
|
-
|
|
/**
|
|
* vimc_pix_map_by_index - get vimc_pix_map struct by its index
|
|
*
|
|
@@ -208,7 +184,8 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
|
|
* unique.
|
|
* @function: media entity function defined by MEDIA_ENT_F_* macros
|
|
* @num_pads: number of pads to initialize
|
|
- * @pads_flag: flags to use in each pad
|
|
+ * @pads: the array of pads of the entity, the caller should set the
|
|
+ flags of the pads
|
|
* @sd_int_ops: pointer to &struct v4l2_subdev_internal_ops
|
|
* @sd_ops: pointer to &struct v4l2_subdev_ops.
|
|
*
|
|
@@ -221,7 +198,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
const char *const name,
|
|
u32 function,
|
|
u16 num_pads,
|
|
- const unsigned long *pads_flag,
|
|
+ struct media_pad *pads,
|
|
const struct v4l2_subdev_internal_ops *sd_int_ops,
|
|
const struct v4l2_subdev_ops *sd_ops);
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index 4e5316c671e0..a601ca3a0a54 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -44,6 +44,7 @@ struct vimc_deb_device {
|
|
u8 *src_frame;
|
|
const struct vimc_deb_pix_map *sink_pix_map;
|
|
unsigned int sink_bpp;
|
|
+ struct media_pad pads[2];
|
|
};
|
|
|
|
static const struct v4l2_mbus_framefmt sink_fmt_default = {
|
|
@@ -478,7 +479,6 @@ static void vimc_deb_release(struct v4l2_subdev *sd)
|
|
container_of(sd, struct vimc_deb_device, sd);
|
|
|
|
media_entity_cleanup(vdeb->ved.ent);
|
|
- vimc_pads_cleanup(vdeb->ved.pads);
|
|
kfree(vdeb);
|
|
}
|
|
|
|
@@ -507,11 +507,13 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
return NULL;
|
|
|
|
/* Initialize ved and sd */
|
|
+ vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
|
|
+ vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
|
|
+
|
|
ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
|
|
vcfg_name,
|
|
MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
|
|
- (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
|
- MEDIA_PAD_FL_SOURCE},
|
|
+ vdeb->pads,
|
|
&vimc_deb_int_ops, &vimc_deb_ops);
|
|
if (ret) {
|
|
kfree(vdeb);
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index 4fe2ba578652..88a2f6e3218e 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -30,6 +30,7 @@ struct vimc_sca_device {
|
|
u8 *src_frame;
|
|
unsigned int src_line_size;
|
|
unsigned int bpp;
|
|
+ struct media_pad pads[2];
|
|
};
|
|
|
|
static const struct v4l2_mbus_framefmt sink_fmt_default = {
|
|
@@ -337,7 +338,6 @@ static void vimc_sca_release(struct v4l2_subdev *sd)
|
|
container_of(sd, struct vimc_sca_device, sd);
|
|
|
|
media_entity_cleanup(vsca->ved.ent);
|
|
- vimc_pads_cleanup(vsca->ved.pads);
|
|
kfree(vsca);
|
|
}
|
|
|
|
@@ -366,11 +366,13 @@ struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
|
|
return NULL;
|
|
|
|
/* Initialize ved and sd */
|
|
+ vsca->pads[0].flags = MEDIA_PAD_FL_SINK;
|
|
+ vsca->pads[1].flags = MEDIA_PAD_FL_SOURCE;
|
|
+
|
|
ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
|
|
vcfg_name,
|
|
MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
|
|
- (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
|
|
- MEDIA_PAD_FL_SOURCE},
|
|
+ vsca->pads,
|
|
&vimc_sca_int_ops, &vimc_sca_ops);
|
|
if (ret) {
|
|
kfree(vsca);
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 14838362d871..b41e24a7d029 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -24,6 +24,7 @@ struct vimc_sen_device {
|
|
/* The active format */
|
|
struct v4l2_mbus_framefmt mbus_format;
|
|
struct v4l2_ctrl_handler hdl;
|
|
+ struct media_pad pad;
|
|
};
|
|
|
|
static const struct v4l2_mbus_framefmt fmt_default = {
|
|
@@ -292,7 +293,6 @@ static void vimc_sen_release(struct v4l2_subdev *sd)
|
|
v4l2_ctrl_handler_free(&vsen->hdl);
|
|
tpg_free(&vsen->tpg);
|
|
media_entity_cleanup(vsen->ved.ent);
|
|
- vimc_pads_cleanup(vsen->ved.pads);
|
|
kfree(vsen);
|
|
}
|
|
|
|
@@ -367,10 +367,10 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
goto err_free_hdl;
|
|
|
|
/* Initialize ved and sd */
|
|
+ vsen->pad.flags = MEDIA_PAD_FL_SOURCE;
|
|
ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
|
|
vcfg_name,
|
|
- MEDIA_ENT_F_CAM_SENSOR, 1,
|
|
- (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
|
|
+ MEDIA_ENT_F_CAM_SENSOR, 1, &vsen->pad,
|
|
&vimc_sen_int_ops, &vimc_sen_ops);
|
|
if (ret)
|
|
goto err_free_tpg;
|
|
|
|
From a79d6d5b16dd01a69a908863c6670aaf313ee3c4 Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Wed, 9 Oct 2019 12:53:14 -0300
|
|
Subject: [PATCH] media: vimc: move the dev field of each entity to
|
|
vimc_ent_dev
|
|
|
|
Since the 'struct device *dev' field exists in each of the
|
|
entity structs, it can be moved to the common struct vimc_ent_devevice.
|
|
It is then used to replace 'pr_err' with 'dev_err' in the streamer
|
|
code.
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit b1f8e9316e790bcde517c5312eaaea4f696e0f75)
|
|
---
|
|
drivers/media/platform/vimc/vimc-capture.c | 7 +++----
|
|
drivers/media/platform/vimc/vimc-common.h | 2 ++
|
|
drivers/media/platform/vimc/vimc-debayer.c | 15 +++++++--------
|
|
drivers/media/platform/vimc/vimc-scaler.c | 11 +++++------
|
|
drivers/media/platform/vimc/vimc-sensor.c | 5 ++---
|
|
drivers/media/platform/vimc/vimc-streamer.c | 4 ++--
|
|
6 files changed, 21 insertions(+), 23 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
|
|
index 936bfb96ebaa..a5d79fb25dff 100644
|
|
--- a/drivers/media/platform/vimc/vimc-capture.c
|
|
+++ b/drivers/media/platform/vimc/vimc-capture.c
|
|
@@ -15,7 +15,6 @@
|
|
struct vimc_cap_device {
|
|
struct vimc_ent_device ved;
|
|
struct video_device vdev;
|
|
- struct device *dev;
|
|
struct v4l2_pix_format format;
|
|
struct vb2_queue queue;
|
|
struct list_head buf_list;
|
|
@@ -125,7 +124,7 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
|
|
if (ret)
|
|
return ret;
|
|
|
|
- dev_dbg(vcap->dev, "%s: format update: "
|
|
+ dev_dbg(vcap->ved.dev, "%s: format update: "
|
|
"old:%dx%d (0x%x, %d, %d, %d, %d) "
|
|
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
|
|
/* old */
|
|
@@ -301,7 +300,7 @@ static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
|
|
unsigned long size = vcap->format.sizeimage;
|
|
|
|
if (vb2_plane_size(vb, 0) < size) {
|
|
- dev_err(vcap->dev, "%s: buffer too small (%lu < %lu)\n",
|
|
+ dev_err(vcap->ved.dev, "%s: buffer too small (%lu < %lu)\n",
|
|
vcap->vdev.name, vb2_plane_size(vb, 0), size);
|
|
return -EINVAL;
|
|
}
|
|
@@ -444,7 +443,7 @@ struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
vcap->ved.ent = &vcap->vdev.entity;
|
|
vcap->ved.process_frame = vimc_cap_process_frame;
|
|
vcap->ved.vdev_get_format = vimc_cap_get_format;
|
|
- vcap->dev = &vimc->pdev.dev;
|
|
+ vcap->ved.dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the video_device struct */
|
|
vdev = &vcap->vdev;
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index ac01182e8b27..348ee3b0fce2 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -78,6 +78,7 @@ struct vimc_pix_map {
|
|
* struct vimc_ent_device - core struct that represents an entity in the
|
|
* topology
|
|
*
|
|
+ * @dev: a pointer of the device struct of the driver
|
|
* @ent: the pointer to struct media_entity for the node
|
|
* @process_frame: callback send a frame to that node
|
|
* @vdev_get_format: callback that returns the current format a pad, used
|
|
@@ -93,6 +94,7 @@ struct vimc_pix_map {
|
|
* media_entity
|
|
*/
|
|
struct vimc_ent_device {
|
|
+ struct device *dev;
|
|
struct media_entity *ent;
|
|
void * (*process_frame)(struct vimc_ent_device *ved,
|
|
const void *frame);
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index a601ca3a0a54..68ae45021830 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -34,7 +34,6 @@ struct vimc_deb_pix_map {
|
|
struct vimc_deb_device {
|
|
struct vimc_ent_device ved;
|
|
struct v4l2_subdev sd;
|
|
- struct device *dev;
|
|
/* The active format */
|
|
struct v4l2_mbus_framefmt sink_fmt;
|
|
u32 src_code;
|
|
@@ -264,7 +263,7 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
|
|
/* Set the new format in the sink pad */
|
|
vimc_deb_adjust_sink_fmt(&fmt->format);
|
|
|
|
- dev_dbg(vdeb->dev, "%s: sink format update: "
|
|
+ dev_dbg(vdeb->ved.dev, "%s: sink format update: "
|
|
"old:%dx%d (0x%x, %d, %d, %d, %d) "
|
|
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vdeb->sd.name,
|
|
/* old */
|
|
@@ -387,7 +386,7 @@ static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
|
|
|
|
/* Sum the values of the colors in the mean window */
|
|
|
|
- dev_dbg(vdeb->dev,
|
|
+ dev_dbg(vdeb->ved.dev,
|
|
"deb: %s: --- Calc pixel %dx%d, window mean %d, seek %d ---\n",
|
|
vdeb->sd.name, lin, col, vdeb->sink_fmt.height, seek);
|
|
|
|
@@ -420,7 +419,7 @@ static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
|
|
vdeb->sink_fmt.width,
|
|
vdeb->sink_bpp);
|
|
|
|
- dev_dbg(vdeb->dev,
|
|
+ dev_dbg(vdeb->ved.dev,
|
|
"deb: %s: RGB CALC: frame index %d, win pos %dx%d, color %d\n",
|
|
vdeb->sd.name, index, wlin, wcol, color);
|
|
|
|
@@ -431,21 +430,21 @@ static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
|
|
/* Save how many values we already added */
|
|
n_rgb[color]++;
|
|
|
|
- dev_dbg(vdeb->dev, "deb: %s: RGB CALC: val %d, n %d\n",
|
|
+ dev_dbg(vdeb->ved.dev, "deb: %s: RGB CALC: val %d, n %d\n",
|
|
vdeb->sd.name, rgb[color], n_rgb[color]);
|
|
}
|
|
}
|
|
|
|
/* Calculate the mean */
|
|
for (i = 0; i < 3; i++) {
|
|
- dev_dbg(vdeb->dev,
|
|
+ dev_dbg(vdeb->ved.dev,
|
|
"deb: %s: PRE CALC: %dx%d Color %d, val %d, n %d\n",
|
|
vdeb->sd.name, lin, col, i, rgb[i], n_rgb[i]);
|
|
|
|
if (n_rgb[i])
|
|
rgb[i] = rgb[i] / n_rgb[i];
|
|
|
|
- dev_dbg(vdeb->dev,
|
|
+ dev_dbg(vdeb->ved.dev,
|
|
"deb: %s: FINAL CALC: %dx%d Color %d, val %d\n",
|
|
vdeb->sd.name, lin, col, i, rgb[i]);
|
|
}
|
|
@@ -521,7 +520,7 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
}
|
|
|
|
vdeb->ved.process_frame = vimc_deb_process_frame;
|
|
- vdeb->dev = &vimc->pdev.dev;
|
|
+ vdeb->ved.dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vdeb->sink_fmt = sink_fmt_default;
|
|
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
|
|
index 88a2f6e3218e..2f88a7d9d67b 100644
|
|
--- a/drivers/media/platform/vimc/vimc-scaler.c
|
|
+++ b/drivers/media/platform/vimc/vimc-scaler.c
|
|
@@ -21,7 +21,6 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier");
|
|
struct vimc_sca_device {
|
|
struct vimc_ent_device ved;
|
|
struct v4l2_subdev sd;
|
|
- struct device *dev;
|
|
/* NOTE: the source fmt is the same as the sink
|
|
* with the width and hight multiplied by mult
|
|
*/
|
|
@@ -172,7 +171,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
|
|
/* Set the new format in the sink pad */
|
|
vimc_sca_adjust_sink_fmt(&fmt->format);
|
|
|
|
- dev_dbg(vsca->dev, "%s: sink format update: "
|
|
+ dev_dbg(vsca->ved.dev, "%s: sink format update: "
|
|
"old:%dx%d (0x%x, %d, %d, %d, %d) "
|
|
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsca->sd.name,
|
|
/* old */
|
|
@@ -272,7 +271,7 @@ static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
|
|
vsca->bpp);
|
|
pixel = &sink_frame[index];
|
|
|
|
- dev_dbg(vsca->dev,
|
|
+ dev_dbg(vsca->ved.dev,
|
|
"sca: %s: --- scale_pix sink pos %dx%d, index %d ---\n",
|
|
vsca->sd.name, lin, col, index);
|
|
|
|
@@ -282,7 +281,7 @@ static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
|
|
index = VIMC_FRAME_INDEX(lin * sca_mult, col * sca_mult,
|
|
vsca->sink_fmt.width * sca_mult, vsca->bpp);
|
|
|
|
- dev_dbg(vsca->dev, "sca: %s: scale_pix src pos %dx%d, index %d\n",
|
|
+ dev_dbg(vsca->ved.dev, "sca: %s: scale_pix src pos %dx%d, index %d\n",
|
|
vsca->sd.name, lin * sca_mult, col * sca_mult, index);
|
|
|
|
/* Repeat this pixel mult times */
|
|
@@ -291,7 +290,7 @@ static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
|
|
* pixel repetition in a line
|
|
*/
|
|
for (j = 0; j < sca_mult * vsca->bpp; j += vsca->bpp) {
|
|
- dev_dbg(vsca->dev,
|
|
+ dev_dbg(vsca->ved.dev,
|
|
"sca: %s: sca: scale_pix src pos %d\n",
|
|
vsca->sd.name, index + j);
|
|
|
|
@@ -380,7 +379,7 @@ struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc,
|
|
}
|
|
|
|
vsca->ved.process_frame = vimc_sca_process_frame;
|
|
- vsca->dev = &vimc->pdev.dev;
|
|
+ vsca->ved.dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vsca->sink_fmt = sink_fmt_default;
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index b41e24a7d029..25ee89a067f7 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -17,7 +17,6 @@
|
|
struct vimc_sen_device {
|
|
struct vimc_ent_device ved;
|
|
struct v4l2_subdev sd;
|
|
- struct device *dev;
|
|
struct tpg_data tpg;
|
|
struct task_struct *kthread_sen;
|
|
u8 *frame;
|
|
@@ -159,7 +158,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
|
|
/* Set the new format */
|
|
vimc_sen_adjust_fmt(&fmt->format);
|
|
|
|
- dev_dbg(vsen->dev, "%s: format update: "
|
|
+ dev_dbg(vsen->ved.dev, "%s: format update: "
|
|
"old:%dx%d (0x%x, %d, %d, %d, %d) "
|
|
"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
|
|
/* old */
|
|
@@ -376,7 +375,7 @@ struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc,
|
|
goto err_free_tpg;
|
|
|
|
vsen->ved.process_frame = vimc_sen_process_frame;
|
|
- vsen->dev = &vimc->pdev.dev;
|
|
+ vsen->ved.dev = &vimc->pdev.dev;
|
|
|
|
/* Initialize the frame format */
|
|
vsen->mbus_format = fmt_default;
|
|
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
|
|
index 092833623ac1..1349be188a5b 100644
|
|
--- a/drivers/media/platform/vimc/vimc-streamer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-streamer.c
|
|
@@ -96,8 +96,8 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
|
|
sd = media_entity_to_v4l2_subdev(ved->ent);
|
|
ret = v4l2_subdev_call(sd, video, s_stream, 1);
|
|
if (ret && ret != -ENOIOCTLCMD) {
|
|
- pr_err("subdev_call error %s\n",
|
|
- ved->ent->name);
|
|
+ dev_err(ved->dev, "subdev_call error %s\n",
|
|
+ ved->ent->name);
|
|
vimc_streamer_pipeline_terminate(stream);
|
|
return ret;
|
|
}
|
|
|
|
From 7806538d07d100295326ea0fcd12c5daf4b88364 Mon Sep 17 00:00:00 2001
|
|
From: Arthur Moraes do Lago <arthurmoraeslago@gmail.com>
|
|
Date: Tue, 1 Oct 2019 21:46:33 -0300
|
|
Subject: [PATCH] media: vimc: Implement debayer control for mean window size
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Add mean window size parameter for debayer filter as a control in
|
|
vimc-debayer.
|
|
|
|
vimc-debayer was patched to allow changing mean window parameter
|
|
of the filter without needing to reload the driver. The parameter
|
|
can now be set using a v4l2-ctl control(mean_window_size).
|
|
|
|
Co-developed-by: Laís Pessine do Carmo <laispc19@gmail.com>
|
|
Signed-off-by: Laís Pessine do Carmo <laispc19@gmail.com>
|
|
Signed-off-by: Arthur Moraes do Lago <arthurmoraeslago@gmail.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 76df2e6c7c782775e41153802489904ce3bd55b8)
|
|
---
|
|
Documentation/media/v4l-drivers/vimc.rst | 10 +---
|
|
drivers/media/platform/vimc/vimc-common.h | 1 +
|
|
drivers/media/platform/vimc/vimc-debayer.c | 81 +++++++++++++++++++++++++-----
|
|
3 files changed, 71 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/vimc.rst b/Documentation/media/v4l-drivers/vimc.rst
|
|
index d567046b6a55..8f5d7f8d83bb 100644
|
|
--- a/Documentation/media/v4l-drivers/vimc.rst
|
|
+++ b/Documentation/media/v4l-drivers/vimc.rst
|
|
@@ -80,9 +80,7 @@ vimc-capture:
|
|
Module options
|
|
--------------
|
|
|
|
-Vimc has a few module parameters to configure the driver.
|
|
-
|
|
- param=value
|
|
+Vimc has a module parameter to configure the driver.
|
|
|
|
* ``sca_mult=<unsigned int>``
|
|
|
|
@@ -91,12 +89,6 @@ Vimc has a few module parameters to configure the driver.
|
|
original one. Currently, only supports scaling up (the default value
|
|
is 3).
|
|
|
|
-* ``deb_mean_win_size=<unsigned int>``
|
|
-
|
|
- Window size to calculate the mean. Note: the window size needs to be an
|
|
- odd number, as the main pixel stays in the center of the window,
|
|
- otherwise the next odd number is considered (the default value is 3).
|
|
-
|
|
Source code documentation
|
|
-------------------------
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index 348ee3b0fce2..c75401a36312 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -19,6 +19,7 @@
|
|
#define VIMC_CID_VIMC_BASE (0x00f00000 | 0xf000)
|
|
#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)
|
|
#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)
|
|
+#define VIMC_CID_MEAN_WIN_SIZE (VIMC_CID_VIMC_BASE + 1)
|
|
|
|
#define VIMC_FRAME_MAX_WIDTH 4096
|
|
#define VIMC_FRAME_MAX_HEIGHT 2160
|
|
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
|
|
index 68ae45021830..5d1b67d684bb 100644
|
|
--- a/drivers/media/platform/vimc/vimc-debayer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-debayer.c
|
|
@@ -9,17 +9,12 @@
|
|
#include <linux/platform_device.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/v4l2-mediabus.h>
|
|
+#include <media/v4l2-ctrls.h>
|
|
+#include <media/v4l2-event.h>
|
|
#include <media/v4l2-subdev.h>
|
|
|
|
#include "vimc-common.h"
|
|
|
|
-static unsigned int deb_mean_win_size = 3;
|
|
-module_param(deb_mean_win_size, uint, 0000);
|
|
-MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
|
|
- "NOTE: the window size needs to be an odd number, as the main pixel "
|
|
- "stays in the center of the window, otherwise the next odd number "
|
|
- "is considered");
|
|
-
|
|
enum vimc_deb_rgb_colors {
|
|
VIMC_DEB_RED = 0,
|
|
VIMC_DEB_GREEN = 1,
|
|
@@ -43,6 +38,8 @@ struct vimc_deb_device {
|
|
u8 *src_frame;
|
|
const struct vimc_deb_pix_map *sink_pix_map;
|
|
unsigned int sink_bpp;
|
|
+ unsigned int mean_win_size;
|
|
+ struct v4l2_ctrl_handler hdl;
|
|
struct media_pad pads[2];
|
|
};
|
|
|
|
@@ -344,11 +341,18 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
|
|
return 0;
|
|
}
|
|
|
|
+static const struct v4l2_subdev_core_ops vimc_deb_core_ops = {
|
|
+ .log_status = v4l2_ctrl_subdev_log_status,
|
|
+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
|
|
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
|
+};
|
|
+
|
|
static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
|
|
.s_stream = vimc_deb_s_stream,
|
|
};
|
|
|
|
static const struct v4l2_subdev_ops vimc_deb_ops = {
|
|
+ .core = &vimc_deb_core_ops,
|
|
.pad = &vimc_deb_pad_ops,
|
|
.video = &vimc_deb_video_ops,
|
|
};
|
|
@@ -382,7 +386,7 @@ static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
|
|
* the top left corner of the mean window (considering the current
|
|
* pixel as the center)
|
|
*/
|
|
- seek = deb_mean_win_size / 2;
|
|
+ seek = vdeb->mean_win_size / 2;
|
|
|
|
/* Sum the values of the colors in the mean window */
|
|
|
|
@@ -469,14 +473,33 @@ static void *vimc_deb_process_frame(struct vimc_ent_device *ved,
|
|
}
|
|
|
|
return vdeb->src_frame;
|
|
+}
|
|
+
|
|
+static int vimc_deb_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
+{
|
|
+ struct vimc_deb_device *vdeb =
|
|
+ container_of(ctrl->handler, struct vimc_deb_device, hdl);
|
|
|
|
+ switch (ctrl->id) {
|
|
+ case VIMC_CID_MEAN_WIN_SIZE:
|
|
+ vdeb->mean_win_size = ctrl->val;
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ return 0;
|
|
}
|
|
|
|
+static const struct v4l2_ctrl_ops vimc_deb_ctrl_ops = {
|
|
+ .s_ctrl = vimc_deb_s_ctrl,
|
|
+};
|
|
+
|
|
static void vimc_deb_release(struct v4l2_subdev *sd)
|
|
{
|
|
struct vimc_deb_device *vdeb =
|
|
container_of(sd, struct vimc_deb_device, sd);
|
|
|
|
+ v4l2_ctrl_handler_free(&vdeb->hdl);
|
|
media_entity_cleanup(vdeb->ved.ent);
|
|
kfree(vdeb);
|
|
}
|
|
@@ -493,6 +516,24 @@ void vimc_deb_rm(struct vimc_device *vimc, struct vimc_ent_device *ved)
|
|
v4l2_device_unregister_subdev(&vdeb->sd);
|
|
}
|
|
|
|
+static const struct v4l2_ctrl_config vimc_deb_ctrl_class = {
|
|
+ .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
|
|
+ .id = VIMC_CID_VIMC_CLASS,
|
|
+ .name = "VIMC Controls",
|
|
+ .type = V4L2_CTRL_TYPE_CTRL_CLASS,
|
|
+};
|
|
+
|
|
+static const struct v4l2_ctrl_config vimc_deb_ctrl_mean_win_size = {
|
|
+ .ops = &vimc_deb_ctrl_ops,
|
|
+ .id = VIMC_CID_MEAN_WIN_SIZE,
|
|
+ .name = "Debayer Mean Window Size",
|
|
+ .type = V4L2_CTRL_TYPE_INTEGER,
|
|
+ .min = 1,
|
|
+ .max = 25,
|
|
+ .step = 2,
|
|
+ .def = 3,
|
|
+};
|
|
+
|
|
struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
const char *vcfg_name)
|
|
{
|
|
@@ -505,6 +546,16 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
if (!vdeb)
|
|
return NULL;
|
|
|
|
+ /* Create controls: */
|
|
+ v4l2_ctrl_handler_init(&vdeb->hdl, 2);
|
|
+ v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_class, NULL);
|
|
+ v4l2_ctrl_new_custom(&vdeb->hdl, &vimc_deb_ctrl_mean_win_size, NULL);
|
|
+ vdeb->sd.ctrl_handler = &vdeb->hdl;
|
|
+ if (vdeb->hdl.error) {
|
|
+ ret = vdeb->hdl.error;
|
|
+ goto err_free_vdeb;
|
|
+ }
|
|
+
|
|
/* Initialize ved and sd */
|
|
vdeb->pads[0].flags = MEDIA_PAD_FL_SINK;
|
|
vdeb->pads[1].flags = MEDIA_PAD_FL_SOURCE;
|
|
@@ -514,13 +565,12 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
|
|
vdeb->pads,
|
|
&vimc_deb_int_ops, &vimc_deb_ops);
|
|
- if (ret) {
|
|
- kfree(vdeb);
|
|
- return NULL;
|
|
- }
|
|
+ if (ret)
|
|
+ goto err_free_hdl;
|
|
|
|
vdeb->ved.process_frame = vimc_deb_process_frame;
|
|
vdeb->ved.dev = &vimc->pdev.dev;
|
|
+ vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def;
|
|
|
|
/* Initialize the frame format */
|
|
vdeb->sink_fmt = sink_fmt_default;
|
|
@@ -534,4 +584,11 @@ struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc,
|
|
vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
|
|
|
|
return &vdeb->ved;
|
|
+
|
|
+err_free_hdl:
|
|
+ v4l2_ctrl_handler_free(&vdeb->hdl);
|
|
+err_free_vdeb:
|
|
+ kfree(vdeb);
|
|
+
|
|
+ return NULL;
|
|
}
|
|
|
|
From 8c6503be46e4d51e24b3970f75ace087faeff990 Mon Sep 17 00:00:00 2001
|
|
From: Bingbu Cao <bingbu.cao@intel.com>
|
|
Date: Tue, 8 Oct 2019 01:21:27 -0300
|
|
Subject: [PATCH] media: doc-rst: add more info for resolution change blocks in
|
|
ipu3
|
|
|
|
This patch add more details for the resolution change blocks
|
|
It can help the developer to understand the main resolution
|
|
change blocks in ImgU.
|
|
|
|
[sakari.ailus@linux.intel.com: Add new files to MAINTAINERS]
|
|
|
|
Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
|
|
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 4147dca25d1f2aae2a44ac02647eaf29ef8d028a)
|
|
---
|
|
Documentation/media/v4l-drivers/ipu3.rst | 53 ++++-
|
|
Documentation/media/v4l-drivers/ipu3_rcb.svg | 331 +++++++++++++++++++++++++++
|
|
MAINTAINERS | 1 +
|
|
drivers/staging/media/ipu3/TODO | 1 -
|
|
4 files changed, 377 insertions(+), 9 deletions(-)
|
|
create mode 100644 Documentation/media/v4l-drivers/ipu3_rcb.svg
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/ipu3.rst b/Documentation/media/v4l-drivers/ipu3.rst
|
|
index c9f780404eee..e4904ab44e60 100644
|
|
--- a/Documentation/media/v4l-drivers/ipu3.rst
|
|
+++ b/Documentation/media/v4l-drivers/ipu3.rst
|
|
@@ -265,19 +265,56 @@ below.
|
|
|
|
yavta -w "0x009819A1 1" /dev/v4l-subdev7
|
|
|
|
-RAW Bayer frames go through the following ImgU pipeline HW blocks to have the
|
|
+Certain hardware blocks in ImgU pipeline can change the frame resolution by
|
|
+cropping or scaling, these hardware blocks include Input Feeder(IF), Bayer Down
|
|
+Scaler (BDS) and Geometric Distortion Correction (GDC).
|
|
+There is also a block which can change the frame resolution - YUV Scaler, it is
|
|
+only applicable to the secondary output.
|
|
+
|
|
+RAW Bayer frames go through these ImgU pipeline hardware blocks and the final
|
|
processed image output to the DDR memory.
|
|
|
|
-RAW Bayer frame -> Input Feeder -> Bayer Down Scaling (BDS) -> Geometric
|
|
-Distortion Correction (GDC) -> DDR
|
|
+.. kernel-figure:: ipu3_rcb.svg
|
|
+ :alt: ipu3 resolution blocks image
|
|
|
|
-The ImgU V4L2 subdev has to be configured with the supported resolutions in all
|
|
-the above HW blocks, for a given input resolution.
|
|
+ IPU3 resolution change hardware blocks
|
|
+
|
|
+**Input Feeder**
|
|
+
|
|
+Input Feeder gets the Bayer frame data from the sensor, it can enable cropping
|
|
+of lines and columns from the frame and then store pixels into device's internal
|
|
+pixel buffer which are ready to readout by following blocks.
|
|
+
|
|
+**Bayer Down Scaler**
|
|
+
|
|
+Bayer Down Scaler is capable of performing image scaling in Bayer domain, the
|
|
+downscale factor can be configured from 1X to 1/4X in each axis with
|
|
+configuration steps of 0.03125 (1/32).
|
|
|
|
+**Geometric Distortion Correction**
|
|
+
|
|
+Geometric Distortion Correction is used to performe correction of distortions
|
|
+and image filtering. It needs some extra filter and envelop padding pixels to
|
|
+work, so the input resolution of GDC should be larger than the output
|
|
+resolution.
|
|
+
|
|
+**YUV Scaler**
|
|
+
|
|
+YUV Scaler which similar with BDS, but it is mainly do image down scaling in
|
|
+YUV domain, it can support up to 1/12X down scaling, but it can not be applied
|
|
+to the main output.
|
|
+
|
|
+The ImgU V4L2 subdev has to be configured with the supported resolutions in all
|
|
+the above hardware blocks, for a given input resolution.
|
|
For a given supported resolution for an input frame, the Input Feeder, Bayer
|
|
-Down Scaling and GDC blocks should be configured with the supported resolutions.
|
|
-This information can be obtained by looking at the following IPU3 ImgU
|
|
-configuration table.
|
|
+Down Scaler and GDC blocks should be configured with the supported resolutions
|
|
+as each hardware block has its own alignment requirement.
|
|
+
|
|
+You must configure the output resolution of the hardware blocks smartly to meet
|
|
+the hardware requirement along with keeping the maximum field of view.
|
|
+The intermediate resolutions can be generated by specific tool and this
|
|
+information can be obtained by looking at the following IPU3 ImgU configuration
|
|
+table.
|
|
|
|
https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master
|
|
|
|
diff --git a/Documentation/media/v4l-drivers/ipu3_rcb.svg b/Documentation/media/v4l-drivers/ipu3_rcb.svg
|
|
new file mode 100644
|
|
index 000000000000..d878421b42a0
|
|
--- /dev/null
|
|
+++ b/Documentation/media/v4l-drivers/ipu3_rcb.svg
|
|
@@ -0,0 +1,331 @@
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="774pt" height="152pt" viewBox="0 0 774 152" version="1.1">
|
|
+<defs>
|
|
+<g>
|
|
+<symbol overflow="visible" id="glyph0-0">
|
|
+<path style="stroke:none;" d="M 1 0 L 1 -15 L 9 -15 L 9 0 Z M 8 -1 L 8 -14 L 2 -14 L 2 -1 Z M 8 -1 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-1">
|
|
+<path style="stroke:none;" d="M 4.6875 -1.15625 C 5.519531 -1.15625 6.15625 -1.316406 6.59375 -1.640625 C 7.039062 -1.960938 7.265625 -2.441406 7.265625 -3.078125 C 7.265625 -3.460938 7.179688 -3.789062 7.015625 -4.0625 C 6.859375 -4.34375 6.644531 -4.582031 6.375 -4.78125 C 6.113281 -4.988281 5.816406 -5.171875 5.484375 -5.328125 C 5.148438 -5.484375 4.804688 -5.628906 4.453125 -5.765625 C 4.054688 -5.921875 3.675781 -6.097656 3.3125 -6.296875 C 2.945312 -6.492188 2.617188 -6.726562 2.328125 -7 C 2.046875 -7.269531 1.820312 -7.582031 1.65625 -7.9375 C 1.488281 -8.300781 1.40625 -8.726562 1.40625 -9.21875 C 1.40625 -10.300781 1.742188 -11.144531 2.421875 -11.75 C 3.097656 -12.351562 4.046875 -12.65625 5.265625 -12.65625 C 5.597656 -12.65625 5.925781 -12.628906 6.25 -12.578125 C 6.570312 -12.535156 6.875 -12.476562 7.15625 -12.40625 C 7.4375 -12.34375 7.6875 -12.265625 7.90625 -12.171875 C 8.125 -12.085938 8.300781 -12 8.4375 -11.90625 L 7.921875 -10.515625 C 7.648438 -10.679688 7.28125 -10.84375 6.8125 -11 C 6.351562 -11.15625 5.835938 -11.234375 5.265625 -11.234375 C 4.660156 -11.234375 4.140625 -11.082031 3.703125 -10.78125 C 3.265625 -10.488281 3.046875 -10.039062 3.046875 -9.4375 C 3.046875 -9.09375 3.109375 -8.800781 3.234375 -8.5625 C 3.359375 -8.320312 3.53125 -8.109375 3.75 -7.921875 C 3.96875 -7.742188 4.222656 -7.582031 4.515625 -7.4375 C 4.804688 -7.289062 5.128906 -7.144531 5.484375 -7 C 5.984375 -6.789062 6.441406 -6.578125 6.859375 -6.359375 C 7.285156 -6.148438 7.648438 -5.894531 7.953125 -5.59375 C 8.253906 -5.300781 8.488281 -4.953125 8.65625 -4.546875 C 8.820312 -4.148438 8.90625 -3.664062 8.90625 -3.09375 C 8.90625 -2.019531 8.539062 -1.191406 7.8125 -0.609375 C 7.082031 -0.0234375 6.039062 0.265625 4.6875 0.265625 C 4.238281 0.265625 3.820312 0.234375 3.4375 0.171875 C 3.050781 0.109375 2.707031 0.03125 2.40625 -0.0625 C 2.101562 -0.15625 1.835938 -0.25 1.609375 -0.34375 C 1.390625 -0.4375 1.21875 -0.519531 1.09375 -0.59375 L 1.59375 -1.953125 C 1.863281 -1.804688 2.257812 -1.632812 2.78125 -1.4375 C 3.300781 -1.25 3.9375 -1.15625 4.6875 -1.15625 Z M 4.6875 -1.15625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-2">
|
|
+<path style="stroke:none;" d="M 5.1875 -9.5 C 6.4375 -9.5 7.398438 -9.109375 8.078125 -8.328125 C 8.753906 -7.546875 9.09375 -6.363281 9.09375 -4.78125 L 9.09375 -4.203125 L 2.453125 -4.203125 C 2.523438 -3.242188 2.84375 -2.515625 3.40625 -2.015625 C 3.976562 -1.515625 4.773438 -1.265625 5.796875 -1.265625 C 6.390625 -1.265625 6.890625 -1.3125 7.296875 -1.40625 C 7.710938 -1.5 8.023438 -1.597656 8.234375 -1.703125 L 8.453125 -0.296875 C 8.253906 -0.191406 7.894531 -0.0820312 7.375 0.03125 C 6.851562 0.15625 6.269531 0.21875 5.625 0.21875 C 4.820312 0.21875 4.113281 0.0976562 3.5 -0.140625 C 2.894531 -0.390625 2.394531 -0.726562 2 -1.15625 C 1.601562 -1.582031 1.300781 -2.09375 1.09375 -2.6875 C 0.894531 -3.28125 0.796875 -3.925781 0.796875 -4.625 C 0.796875 -5.445312 0.921875 -6.164062 1.171875 -6.78125 C 1.429688 -7.394531 1.765625 -7.898438 2.171875 -8.296875 C 2.585938 -8.703125 3.054688 -9.003906 3.578125 -9.203125 C 4.097656 -9.398438 4.632812 -9.5 5.1875 -9.5 Z M 7.421875 -5.546875 C 7.421875 -6.328125 7.210938 -6.945312 6.796875 -7.40625 C 6.390625 -7.863281 5.84375 -8.09375 5.15625 -8.09375 C 4.769531 -8.09375 4.421875 -8.019531 4.109375 -7.875 C 3.796875 -7.726562 3.523438 -7.535156 3.296875 -7.296875 C 3.066406 -7.054688 2.882812 -6.78125 2.75 -6.46875 C 2.625 -6.164062 2.539062 -5.859375 2.5 -5.546875 Z M 7.421875 -5.546875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-3">
|
|
+<path style="stroke:none;" d="M 1.421875 -9.015625 C 2.015625 -9.160156 2.609375 -9.273438 3.203125 -9.359375 C 3.796875 -9.441406 4.351562 -9.484375 4.875 -9.484375 C 6.113281 -9.484375 7.050781 -9.160156 7.6875 -8.515625 C 8.320312 -7.878906 8.640625 -6.851562 8.640625 -5.4375 L 8.640625 0 L 7 0 L 7 -5.140625 C 7 -5.742188 6.945312 -6.226562 6.84375 -6.59375 C 6.738281 -6.96875 6.585938 -7.257812 6.390625 -7.46875 C 6.191406 -7.675781 5.957031 -7.816406 5.6875 -7.890625 C 5.414062 -7.972656 5.117188 -8.015625 4.796875 -8.015625 C 4.535156 -8.015625 4.253906 -8 3.953125 -7.96875 C 3.648438 -7.9375 3.359375 -7.894531 3.078125 -7.84375 L 3.078125 0 L 1.421875 0 Z M 1.421875 -9.015625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-4">
|
|
+<path style="stroke:none;" d="M 7.015625 -2.3125 C 7.015625 -2.644531 6.878906 -2.914062 6.609375 -3.125 C 6.335938 -3.34375 6 -3.53125 5.59375 -3.6875 C 5.1875 -3.851562 4.742188 -4.015625 4.265625 -4.171875 C 3.785156 -4.328125 3.335938 -4.515625 2.921875 -4.734375 C 2.515625 -4.960938 2.175781 -5.242188 1.90625 -5.578125 C 1.632812 -5.910156 1.5 -6.34375 1.5 -6.875 C 1.5 -7.625 1.800781 -8.25 2.40625 -8.75 C 3.007812 -9.25 3.960938 -9.5 5.265625 -9.5 C 5.765625 -9.5 6.285156 -9.460938 6.828125 -9.390625 C 7.367188 -9.316406 7.832031 -9.21875 8.21875 -9.09375 L 7.921875 -7.625 C 7.816406 -7.675781 7.671875 -7.726562 7.484375 -7.78125 C 7.296875 -7.84375 7.082031 -7.894531 6.84375 -7.9375 C 6.601562 -7.988281 6.34375 -8.023438 6.0625 -8.046875 C 5.789062 -8.078125 5.53125 -8.09375 5.28125 -8.09375 C 3.84375 -8.09375 3.125 -7.703125 3.125 -6.921875 C 3.125 -6.640625 3.257812 -6.398438 3.53125 -6.203125 C 3.800781 -6.015625 4.144531 -5.835938 4.5625 -5.671875 C 4.976562 -5.515625 5.425781 -5.351562 5.90625 -5.1875 C 6.382812 -5.019531 6.828125 -4.816406 7.234375 -4.578125 C 7.648438 -4.335938 7.992188 -4.046875 8.265625 -3.703125 C 8.546875 -3.367188 8.6875 -2.941406 8.6875 -2.421875 C 8.6875 -1.578125 8.359375 -0.925781 7.703125 -0.46875 C 7.046875 -0.0078125 6.007812 0.21875 4.59375 0.21875 C 3.957031 0.21875 3.375 0.164062 2.84375 0.0625 C 2.3125 -0.0390625 1.800781 -0.203125 1.3125 -0.421875 L 1.640625 -1.921875 C 2.109375 -1.703125 2.597656 -1.523438 3.109375 -1.390625 C 3.617188 -1.253906 4.171875 -1.1875 4.765625 -1.1875 C 6.265625 -1.1875 7.015625 -1.5625 7.015625 -2.3125 Z M 7.015625 -2.3125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-5">
|
|
+<path style="stroke:none;" d="M 9.203125 -4.640625 C 9.203125 -3.910156 9.097656 -3.25 8.890625 -2.65625 C 8.679688 -2.0625 8.390625 -1.550781 8.015625 -1.125 C 7.640625 -0.695312 7.191406 -0.363281 6.671875 -0.125 C 6.160156 0.101562 5.597656 0.21875 4.984375 0.21875 C 4.378906 0.21875 3.820312 0.101562 3.3125 -0.125 C 2.800781 -0.363281 2.359375 -0.695312 1.984375 -1.125 C 1.609375 -1.550781 1.316406 -2.0625 1.109375 -2.65625 C 0.898438 -3.25 0.796875 -3.910156 0.796875 -4.640625 C 0.796875 -5.367188 0.898438 -6.035156 1.109375 -6.640625 C 1.316406 -7.242188 1.609375 -7.753906 1.984375 -8.171875 C 2.359375 -8.585938 2.800781 -8.910156 3.3125 -9.140625 C 3.820312 -9.378906 4.378906 -9.5 4.984375 -9.5 C 5.597656 -9.5 6.160156 -9.378906 6.671875 -9.140625 C 7.191406 -8.910156 7.640625 -8.585938 8.015625 -8.171875 C 8.390625 -7.753906 8.679688 -7.242188 8.890625 -6.640625 C 9.097656 -6.035156 9.203125 -5.367188 9.203125 -4.640625 Z M 7.5 -4.640625 C 7.5 -5.691406 7.269531 -6.519531 6.8125 -7.125 C 6.363281 -7.738281 5.753906 -8.046875 4.984375 -8.046875 C 4.222656 -8.046875 3.617188 -7.738281 3.171875 -7.125 C 2.722656 -6.519531 2.5 -5.691406 2.5 -4.640625 C 2.5 -3.597656 2.722656 -2.773438 3.171875 -2.171875 C 3.617188 -1.566406 4.222656 -1.265625 4.984375 -1.265625 C 5.753906 -1.265625 6.363281 -1.566406 6.8125 -2.171875 C 7.269531 -2.773438 7.5 -3.597656 7.5 -4.640625 Z M 7.5 -4.640625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-6">
|
|
+<path style="stroke:none;" d="M 2.140625 0 L 2.140625 -8.78125 C 3.503906 -9.25 4.878906 -9.484375 6.265625 -9.484375 C 6.691406 -9.484375 7.097656 -9.460938 7.484375 -9.421875 C 7.867188 -9.390625 8.296875 -9.320312 8.765625 -9.21875 L 8.453125 -7.765625 C 8.023438 -7.878906 7.648438 -7.953125 7.328125 -7.984375 C 7.003906 -8.023438 6.648438 -8.046875 6.265625 -8.046875 C 5.453125 -8.046875 4.625 -7.929688 3.78125 -7.703125 L 3.78125 0 Z M 2.140625 0 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-7">
|
|
+<path style="stroke:none;" d="M 5.8125 -10.984375 L 5.8125 -1.40625 L 8.21875 -1.40625 L 8.21875 0 L 1.78125 0 L 1.78125 -1.40625 L 4.1875 -1.40625 L 4.1875 -10.984375 L 1.78125 -10.984375 L 1.78125 -12.375 L 8.21875 -12.375 L 8.21875 -10.984375 Z M 5.8125 -10.984375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-8">
|
|
+<path style="stroke:none;" d="M 1.8125 0 L 1.8125 -12.375 L 8.84375 -12.375 L 8.84375 -10.984375 L 3.453125 -10.984375 L 3.453125 -7.125 L 8.203125 -7.125 L 8.203125 -5.734375 L 3.453125 -5.734375 L 3.453125 0 Z M 1.8125 0 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-9">
|
|
+<path style="stroke:none;" d="M 4.078125 0.09375 C 3.878906 0.09375 3.644531 0.0859375 3.375 0.078125 C 3.113281 0.0664062 2.847656 0.0507812 2.578125 0.03125 C 2.316406 0.0078125 2.050781 -0.0195312 1.78125 -0.0625 C 1.507812 -0.101562 1.273438 -0.148438 1.078125 -0.203125 L 1.078125 -12.203125 C 1.273438 -12.253906 1.503906 -12.300781 1.765625 -12.34375 C 2.023438 -12.382812 2.289062 -12.410156 2.5625 -12.421875 C 2.84375 -12.441406 3.113281 -12.457031 3.375 -12.46875 C 3.632812 -12.488281 3.867188 -12.5 4.078125 -12.5 C 4.691406 -12.5 5.265625 -12.445312 5.796875 -12.34375 C 6.328125 -12.238281 6.789062 -12.054688 7.1875 -11.796875 C 7.582031 -11.546875 7.890625 -11.210938 8.109375 -10.796875 C 8.328125 -10.390625 8.4375 -9.878906 8.4375 -9.265625 C 8.4375 -8.960938 8.390625 -8.675781 8.296875 -8.40625 C 8.203125 -8.132812 8.070312 -7.878906 7.90625 -7.640625 C 7.738281 -7.398438 7.546875 -7.1875 7.328125 -7 C 7.109375 -6.820312 6.875 -6.6875 6.625 -6.59375 C 7.300781 -6.40625 7.867188 -6.0625 8.328125 -5.5625 C 8.785156 -5.0625 9.015625 -4.414062 9.015625 -3.625 C 9.015625 -2.394531 8.617188 -1.46875 7.828125 -0.84375 C 7.046875 -0.21875 5.796875 0.09375 4.078125 0.09375 Z M 2.71875 -5.78125 L 2.71875 -1.359375 C 2.75 -1.347656 2.898438 -1.332031 3.171875 -1.3125 C 3.441406 -1.289062 3.785156 -1.28125 4.203125 -1.28125 C 4.609375 -1.28125 5 -1.3125 5.375 -1.375 C 5.757812 -1.445312 6.097656 -1.570312 6.390625 -1.75 C 6.691406 -1.925781 6.929688 -2.160156 7.109375 -2.453125 C 7.285156 -2.753906 7.375 -3.132812 7.375 -3.59375 C 7.375 -4.007812 7.289062 -4.359375 7.125 -4.640625 C 6.957031 -4.921875 6.738281 -5.144531 6.46875 -5.3125 C 6.195312 -5.476562 5.878906 -5.597656 5.515625 -5.671875 C 5.160156 -5.742188 4.789062 -5.78125 4.40625 -5.78125 Z M 2.71875 -7.140625 L 4.015625 -7.140625 C 4.347656 -7.140625 4.679688 -7.171875 5.015625 -7.234375 C 5.347656 -7.304688 5.644531 -7.414062 5.90625 -7.5625 C 6.175781 -7.707031 6.390625 -7.90625 6.546875 -8.15625 C 6.710938 -8.414062 6.796875 -8.738281 6.796875 -9.125 C 6.796875 -9.476562 6.722656 -9.78125 6.578125 -10.03125 C 6.429688 -10.289062 6.238281 -10.5 6 -10.65625 C 5.757812 -10.820312 5.484375 -10.9375 5.171875 -11 C 4.859375 -11.0625 4.53125 -11.09375 4.1875 -11.09375 C 3.832031 -11.09375 3.523438 -11.085938 3.265625 -11.078125 C 3.003906 -11.078125 2.820312 -11.066406 2.71875 -11.046875 Z M 2.71875 -7.140625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-10">
|
|
+<path style="stroke:none;" d="M 9.203125 -6.203125 C 9.203125 -5.054688 9.054688 -4.082031 8.765625 -3.28125 C 8.484375 -2.476562 8.09375 -1.828125 7.59375 -1.328125 C 7.09375 -0.828125 6.5 -0.460938 5.8125 -0.234375 C 5.125 -0.015625 4.378906 0.09375 3.578125 0.09375 C 2.753906 0.09375 1.921875 -0.00390625 1.078125 -0.203125 L 1.078125 -12.203125 C 1.921875 -12.398438 2.753906 -12.5 3.578125 -12.5 C 4.378906 -12.5 5.125 -12.382812 5.8125 -12.15625 C 6.5 -11.925781 7.09375 -11.554688 7.59375 -11.046875 C 8.09375 -10.546875 8.484375 -9.894531 8.765625 -9.09375 C 9.054688 -8.300781 9.203125 -7.335938 9.203125 -6.203125 Z M 2.71875 -1.375 C 3.050781 -1.332031 3.390625 -1.3125 3.734375 -1.3125 C 4.335938 -1.3125 4.875 -1.398438 5.34375 -1.578125 C 5.8125 -1.765625 6.203125 -2.054688 6.515625 -2.453125 C 6.835938 -2.847656 7.082031 -3.351562 7.25 -3.96875 C 7.425781 -4.59375 7.515625 -5.335938 7.515625 -6.203125 C 7.515625 -7.878906 7.191406 -9.109375 6.546875 -9.890625 C 5.898438 -10.679688 4.945312 -11.078125 3.6875 -11.078125 C 3.507812 -11.078125 3.335938 -11.070312 3.171875 -11.0625 C 3.003906 -11.0625 2.851562 -11.046875 2.71875 -11.015625 Z M 2.71875 -1.375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-11">
|
|
+<path style="stroke:none;" d="M 7.453125 -6.09375 L 9.09375 -6.09375 L 9.09375 -0.296875 C 8.84375 -0.203125 8.4375 -0.0859375 7.875 0.046875 C 7.320312 0.191406 6.664062 0.265625 5.90625 0.265625 C 5.15625 0.265625 4.472656 0.125 3.859375 -0.15625 C 3.242188 -0.445312 2.71875 -0.863281 2.28125 -1.40625 C 1.851562 -1.957031 1.519531 -2.632812 1.28125 -3.4375 C 1.039062 -4.25 0.921875 -5.171875 0.921875 -6.203125 C 0.921875 -7.242188 1.050781 -8.160156 1.3125 -8.953125 C 1.582031 -9.753906 1.945312 -10.425781 2.40625 -10.96875 C 2.863281 -11.519531 3.398438 -11.9375 4.015625 -12.21875 C 4.628906 -12.507812 5.289062 -12.65625 6 -12.65625 C 6.457031 -12.65625 6.859375 -12.617188 7.203125 -12.546875 C 7.546875 -12.484375 7.835938 -12.40625 8.078125 -12.3125 C 8.328125 -12.226562 8.53125 -12.132812 8.6875 -12.03125 C 8.851562 -11.925781 8.976562 -11.847656 9.0625 -11.796875 L 8.515625 -10.421875 C 8.210938 -10.660156 7.847656 -10.851562 7.421875 -11 C 7.003906 -11.15625 6.5625 -11.234375 6.09375 -11.234375 C 5.59375 -11.234375 5.125 -11.113281 4.6875 -10.875 C 4.257812 -10.632812 3.890625 -10.296875 3.578125 -9.859375 C 3.273438 -9.421875 3.035156 -8.890625 2.859375 -8.265625 C 2.679688 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.453125 2.671875 -4.769531 2.828125 -4.15625 C 2.984375 -3.539062 3.207031 -3.015625 3.5 -2.578125 C 3.789062 -2.140625 4.148438 -1.796875 4.578125 -1.546875 C 5.015625 -1.304688 5.515625 -1.1875 6.078125 -1.1875 C 6.460938 -1.1875 6.757812 -1.210938 6.96875 -1.265625 C 7.1875 -1.316406 7.347656 -1.367188 7.453125 -1.421875 Z M 7.453125 -6.09375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph0-12">
|
|
+<path style="stroke:none;" d="M 9.203125 -0.515625 C 8.734375 -0.253906 8.234375 -0.0625 7.703125 0.0625 C 7.179688 0.195312 6.617188 0.265625 6.015625 0.265625 C 5.285156 0.265625 4.609375 0.132812 3.984375 -0.125 C 3.367188 -0.382812 2.832031 -0.773438 2.375 -1.296875 C 1.925781 -1.828125 1.570312 -2.5 1.3125 -3.3125 C 1.050781 -4.132812 0.921875 -5.097656 0.921875 -6.203125 C 0.921875 -7.253906 1.054688 -8.179688 1.328125 -8.984375 C 1.597656 -9.785156 1.96875 -10.457031 2.4375 -11 C 2.90625 -11.539062 3.453125 -11.953125 4.078125 -12.234375 C 4.703125 -12.515625 5.367188 -12.65625 6.078125 -12.65625 C 6.566406 -12.65625 7.066406 -12.585938 7.578125 -12.453125 C 8.097656 -12.328125 8.601562 -12.109375 9.09375 -11.796875 L 8.625 -10.4375 C 7.738281 -10.945312 6.910156 -11.203125 6.140625 -11.203125 C 5.585938 -11.203125 5.09375 -11.082031 4.65625 -10.84375 C 4.226562 -10.613281 3.859375 -10.28125 3.546875 -9.84375 C 3.242188 -9.40625 3.007812 -8.878906 2.84375 -8.265625 C 2.675781 -7.648438 2.59375 -6.960938 2.59375 -6.203125 C 2.59375 -5.347656 2.679688 -4.609375 2.859375 -3.984375 C 3.046875 -3.359375 3.296875 -2.835938 3.609375 -2.421875 C 3.929688 -2.003906 4.316406 -1.695312 4.765625 -1.5 C 5.210938 -1.300781 5.695312 -1.203125 6.21875 -1.203125 C 6.601562 -1.203125 7.007812 -1.25 7.4375 -1.34375 C 7.863281 -1.445312 8.304688 -1.625 8.765625 -1.875 Z M 9.203125 -0.515625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-0">
|
|
+<path style="stroke:none;" d="M 0.59375 0 L 0.59375 -9 L 5.40625 -9 L 5.40625 0 Z M 4.796875 -0.59375 L 4.796875 -8.40625 L 1.203125 -8.40625 L 1.203125 -0.59375 Z M 4.796875 -0.59375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-1">
|
|
+<path style="stroke:none;" d="M 2.515625 0 L 2.515625 -2.765625 C 2.023438 -3.554688 1.582031 -4.332031 1.1875 -5.09375 C 0.789062 -5.851562 0.445312 -6.628906 0.15625 -7.421875 L 1.265625 -7.421875 C 1.492188 -6.753906 1.757812 -6.113281 2.0625 -5.5 C 2.363281 -4.882812 2.6875 -4.253906 3.03125 -3.609375 C 3.394531 -4.285156 3.71875 -4.929688 4 -5.546875 C 4.28125 -6.160156 4.539062 -6.785156 4.78125 -7.421875 L 5.859375 -7.421875 C 5.554688 -6.640625 5.207031 -5.875 4.8125 -5.125 C 4.414062 -4.382812 3.976562 -3.601562 3.5 -2.78125 L 3.5 0 Z M 2.515625 0 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-2">
|
|
+<path style="stroke:none;" d="M 3 0.15625 C 2.5625 0.15625 2.1875 0.09375 1.875 -0.03125 C 1.570312 -0.164062 1.320312 -0.347656 1.125 -0.578125 C 0.9375 -0.804688 0.796875 -1.085938 0.703125 -1.421875 C 0.617188 -1.765625 0.578125 -2.144531 0.578125 -2.5625 L 0.578125 -7.421875 L 1.5625 -7.421875 L 1.5625 -2.65625 C 1.5625 -2.28125 1.59375 -1.96875 1.65625 -1.71875 C 1.726562 -1.46875 1.828125 -1.265625 1.953125 -1.109375 C 2.078125 -0.960938 2.222656 -0.859375 2.390625 -0.796875 C 2.566406 -0.734375 2.769531 -0.703125 3 -0.703125 C 3.226562 -0.703125 3.425781 -0.734375 3.59375 -0.796875 C 3.769531 -0.859375 3.921875 -0.960938 4.046875 -1.109375 C 4.171875 -1.265625 4.265625 -1.46875 4.328125 -1.71875 C 4.398438 -1.96875 4.4375 -2.28125 4.4375 -2.65625 L 4.4375 -7.421875 L 5.421875 -7.421875 L 5.421875 -2.5625 C 5.421875 -2.144531 5.375 -1.765625 5.28125 -1.421875 C 5.195312 -1.085938 5.054688 -0.804688 4.859375 -0.578125 C 4.671875 -0.347656 4.421875 -0.164062 4.109375 -0.03125 C 3.804688 0.09375 3.4375 0.15625 3 0.15625 Z M 3 0.15625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-3">
|
|
+<path style="stroke:none;" d="M 1.21875 -7.421875 C 1.320312 -6.921875 1.445312 -6.375 1.59375 -5.78125 C 1.738281 -5.1875 1.890625 -4.585938 2.046875 -3.984375 C 2.210938 -3.390625 2.378906 -2.820312 2.546875 -2.28125 C 2.722656 -1.738281 2.882812 -1.265625 3.03125 -0.859375 C 3.15625 -1.265625 3.300781 -1.742188 3.46875 -2.296875 C 3.644531 -2.847656 3.816406 -3.421875 3.984375 -4.015625 C 4.148438 -4.609375 4.304688 -5.203125 4.453125 -5.796875 C 4.609375 -6.390625 4.734375 -6.929688 4.828125 -7.421875 L 5.859375 -7.421875 C 5.796875 -7.109375 5.691406 -6.679688 5.546875 -6.140625 C 5.398438 -5.597656 5.226562 -4.992188 5.03125 -4.328125 C 4.832031 -3.660156 4.609375 -2.953125 4.359375 -2.203125 C 4.117188 -1.453125 3.863281 -0.71875 3.59375 0 L 2.375 0 C 2.125 -0.71875 1.878906 -1.445312 1.640625 -2.1875 C 1.410156 -2.9375 1.195312 -3.644531 1 -4.3125 C 0.800781 -4.976562 0.628906 -5.582031 0.484375 -6.125 C 0.335938 -6.675781 0.226562 -7.109375 0.15625 -7.421875 Z M 1.21875 -7.421875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-4">
|
|
+<path style="stroke:none;" d=""/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-5">
|
|
+<path style="stroke:none;" d="M 5.515625 -3.71875 C 5.515625 -3.03125 5.425781 -2.445312 5.25 -1.96875 C 5.082031 -1.488281 4.847656 -1.097656 4.546875 -0.796875 C 4.253906 -0.492188 3.898438 -0.273438 3.484375 -0.140625 C 3.078125 -0.00390625 2.628906 0.0625 2.140625 0.0625 C 1.648438 0.0625 1.148438 0 0.640625 -0.125 L 0.640625 -7.3125 C 1.148438 -7.4375 1.648438 -7.5 2.140625 -7.5 C 2.628906 -7.5 3.078125 -7.429688 3.484375 -7.296875 C 3.898438 -7.160156 4.253906 -6.941406 4.546875 -6.640625 C 4.847656 -6.335938 5.082031 -5.941406 5.25 -5.453125 C 5.425781 -4.972656 5.515625 -4.394531 5.515625 -3.71875 Z M 1.625 -0.828125 C 1.832031 -0.804688 2.039062 -0.796875 2.25 -0.796875 C 2.601562 -0.796875 2.921875 -0.847656 3.203125 -0.953125 C 3.484375 -1.054688 3.71875 -1.226562 3.90625 -1.46875 C 4.101562 -1.707031 4.253906 -2.007812 4.359375 -2.375 C 4.460938 -2.75 4.515625 -3.195312 4.515625 -3.71875 C 4.515625 -4.726562 4.316406 -5.46875 3.921875 -5.9375 C 3.535156 -6.40625 2.960938 -6.640625 2.203125 -6.640625 C 2.097656 -6.640625 1.992188 -6.640625 1.890625 -6.640625 C 1.796875 -6.640625 1.707031 -6.628906 1.625 -6.609375 Z M 1.625 -0.828125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-6">
|
|
+<path style="stroke:none;" d="M 5.515625 -2.78125 C 5.515625 -2.34375 5.453125 -1.945312 5.328125 -1.59375 C 5.203125 -1.238281 5.023438 -0.929688 4.796875 -0.671875 C 4.578125 -0.410156 4.3125 -0.210938 4 -0.078125 C 3.695312 0.0546875 3.359375 0.125 2.984375 0.125 C 2.628906 0.125 2.296875 0.0546875 1.984375 -0.078125 C 1.679688 -0.210938 1.414062 -0.410156 1.1875 -0.671875 C 0.96875 -0.929688 0.796875 -1.238281 0.671875 -1.59375 C 0.546875 -1.945312 0.484375 -2.34375 0.484375 -2.78125 C 0.484375 -3.21875 0.546875 -3.617188 0.671875 -3.984375 C 0.796875 -4.347656 0.96875 -4.65625 1.1875 -4.90625 C 1.414062 -5.15625 1.679688 -5.347656 1.984375 -5.484375 C 2.296875 -5.628906 2.628906 -5.703125 2.984375 -5.703125 C 3.359375 -5.703125 3.695312 -5.628906 4 -5.484375 C 4.3125 -5.347656 4.578125 -5.15625 4.796875 -4.90625 C 5.023438 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.21875 5.515625 -2.78125 Z M 4.5 -2.78125 C 4.5 -3.414062 4.363281 -3.914062 4.09375 -4.28125 C 3.820312 -4.644531 3.453125 -4.828125 2.984375 -4.828125 C 2.523438 -4.828125 2.160156 -4.644531 1.890625 -4.28125 C 1.628906 -3.914062 1.5 -3.414062 1.5 -2.78125 C 1.5 -2.15625 1.628906 -1.660156 1.890625 -1.296875 C 2.160156 -0.929688 2.523438 -0.75 2.984375 -0.75 C 3.453125 -0.75 3.820312 -0.929688 4.09375 -1.296875 C 4.363281 -1.660156 4.5 -2.15625 4.5 -2.78125 Z M 4.5 -2.78125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-7">
|
|
+<path style="stroke:none;" d="M 4.109375 0 C 3.992188 -0.269531 3.890625 -0.515625 3.796875 -0.734375 C 3.710938 -0.960938 3.628906 -1.1875 3.546875 -1.40625 C 3.460938 -1.632812 3.378906 -1.867188 3.296875 -2.109375 C 3.210938 -2.359375 3.113281 -2.640625 3 -2.953125 C 2.882812 -2.640625 2.78125 -2.359375 2.6875 -2.109375 C 2.601562 -1.867188 2.519531 -1.632812 2.4375 -1.40625 C 2.351562 -1.1875 2.265625 -0.960938 2.171875 -0.734375 C 2.085938 -0.515625 1.984375 -0.269531 1.859375 0 L 1.109375 0 C 0.890625 -0.976562 0.707031 -1.953125 0.5625 -2.921875 C 0.414062 -3.890625 0.304688 -4.769531 0.234375 -5.5625 L 1.15625 -5.5625 C 1.1875 -5.25 1.210938 -4.941406 1.234375 -4.640625 C 1.265625 -4.347656 1.300781 -4.035156 1.34375 -3.703125 C 1.382812 -3.378906 1.429688 -3.023438 1.484375 -2.640625 C 1.535156 -2.253906 1.59375 -1.820312 1.65625 -1.34375 C 1.78125 -1.664062 1.882812 -1.945312 1.96875 -2.1875 C 2.0625 -2.425781 2.144531 -2.648438 2.21875 -2.859375 C 2.289062 -3.078125 2.359375 -3.296875 2.421875 -3.515625 C 2.492188 -3.742188 2.570312 -4 2.65625 -4.28125 L 3.390625 -4.28125 C 3.472656 -4 3.546875 -3.742188 3.609375 -3.515625 C 3.671875 -3.296875 3.738281 -3.078125 3.8125 -2.859375 C 3.882812 -2.648438 3.957031 -2.425781 4.03125 -2.1875 C 4.113281 -1.945312 4.21875 -1.671875 4.34375 -1.359375 C 4.414062 -1.796875 4.476562 -2.203125 4.53125 -2.578125 C 4.59375 -2.953125 4.640625 -3.304688 4.671875 -3.640625 C 4.710938 -3.972656 4.75 -4.296875 4.78125 -4.609375 C 4.820312 -4.921875 4.851562 -5.238281 4.875 -5.5625 L 5.765625 -5.5625 C 5.734375 -5.164062 5.6875 -4.738281 5.625 -4.28125 C 5.570312 -3.820312 5.503906 -3.351562 5.421875 -2.875 C 5.335938 -2.394531 5.25 -1.910156 5.15625 -1.421875 C 5.0625 -0.929688 4.960938 -0.457031 4.859375 0 Z M 4.109375 0 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-8">
|
|
+<path style="stroke:none;" d="M 0.859375 -5.40625 C 1.210938 -5.5 1.566406 -5.566406 1.921875 -5.609375 C 2.273438 -5.660156 2.609375 -5.6875 2.921875 -5.6875 C 3.671875 -5.6875 4.234375 -5.492188 4.609375 -5.109375 C 4.992188 -4.722656 5.1875 -4.109375 5.1875 -3.265625 L 5.1875 0 L 4.203125 0 L 4.203125 -3.078125 C 4.203125 -3.441406 4.171875 -3.734375 4.109375 -3.953125 C 4.046875 -4.179688 3.953125 -4.359375 3.828125 -4.484375 C 3.710938 -4.609375 3.570312 -4.691406 3.40625 -4.734375 C 3.25 -4.785156 3.070312 -4.8125 2.875 -4.8125 C 2.71875 -4.8125 2.546875 -4.800781 2.359375 -4.78125 C 2.179688 -4.757812 2.007812 -4.734375 1.84375 -4.703125 L 1.84375 0 L 0.859375 0 Z M 0.859375 -5.40625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-9">
|
|
+<path style="stroke:none;" d="M 4.21875 -1.390625 C 4.21875 -1.585938 4.132812 -1.75 3.96875 -1.875 C 3.800781 -2.007812 3.59375 -2.125 3.34375 -2.21875 C 3.101562 -2.3125 2.835938 -2.40625 2.546875 -2.5 C 2.265625 -2.59375 2 -2.707031 1.75 -2.84375 C 1.507812 -2.976562 1.304688 -3.144531 1.140625 -3.34375 C 0.984375 -3.539062 0.90625 -3.800781 0.90625 -4.125 C 0.90625 -4.570312 1.082031 -4.945312 1.4375 -5.25 C 1.800781 -5.550781 2.375 -5.703125 3.15625 -5.703125 C 3.457031 -5.703125 3.769531 -5.675781 4.09375 -5.625 C 4.414062 -5.582031 4.695312 -5.523438 4.9375 -5.453125 L 4.75 -4.578125 C 4.6875 -4.609375 4.597656 -4.640625 4.484375 -4.671875 C 4.367188 -4.710938 4.238281 -4.742188 4.09375 -4.765625 C 3.957031 -4.796875 3.804688 -4.816406 3.640625 -4.828125 C 3.472656 -4.847656 3.316406 -4.859375 3.171875 -4.859375 C 2.304688 -4.859375 1.875 -4.625 1.875 -4.15625 C 1.875 -3.988281 1.953125 -3.84375 2.109375 -3.71875 C 2.273438 -3.601562 2.484375 -3.5 2.734375 -3.40625 C 2.984375 -3.3125 3.25 -3.210938 3.53125 -3.109375 C 3.820312 -3.015625 4.09375 -2.894531 4.34375 -2.75 C 4.59375 -2.601562 4.796875 -2.425781 4.953125 -2.21875 C 5.117188 -2.019531 5.203125 -1.765625 5.203125 -1.453125 C 5.203125 -0.953125 5.003906 -0.5625 4.609375 -0.28125 C 4.222656 -0.0078125 3.609375 0.125 2.765625 0.125 C 2.378906 0.125 2.023438 0.09375 1.703125 0.03125 C 1.378906 -0.03125 1.078125 -0.125 0.796875 -0.25 L 0.984375 -1.15625 C 1.265625 -1.019531 1.554688 -0.910156 1.859375 -0.828125 C 2.171875 -0.742188 2.503906 -0.703125 2.859375 -0.703125 C 3.765625 -0.703125 4.21875 -0.929688 4.21875 -1.390625 Z M 4.21875 -1.390625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-10">
|
|
+<path style="stroke:none;" d="M 0.59375 -2.765625 C 0.59375 -3.273438 0.671875 -3.710938 0.828125 -4.078125 C 0.984375 -4.441406 1.203125 -4.742188 1.484375 -4.984375 C 1.765625 -5.234375 2.09375 -5.414062 2.46875 -5.53125 C 2.84375 -5.644531 3.238281 -5.703125 3.65625 -5.703125 C 3.925781 -5.703125 4.195312 -5.679688 4.46875 -5.640625 C 4.738281 -5.609375 5.023438 -5.546875 5.328125 -5.453125 L 5.09375 -4.59375 C 4.832031 -4.6875 4.59375 -4.75 4.375 -4.78125 C 4.15625 -4.8125 3.929688 -4.828125 3.703125 -4.828125 C 3.421875 -4.828125 3.148438 -4.785156 2.890625 -4.703125 C 2.640625 -4.628906 2.414062 -4.507812 2.21875 -4.34375 C 2.03125 -4.1875 1.878906 -3.976562 1.765625 -3.71875 C 1.660156 -3.457031 1.609375 -3.140625 1.609375 -2.765625 C 1.609375 -2.421875 1.660156 -2.117188 1.765625 -1.859375 C 1.867188 -1.609375 2.015625 -1.398438 2.203125 -1.234375 C 2.390625 -1.078125 2.613281 -0.957031 2.875 -0.875 C 3.144531 -0.789062 3.4375 -0.75 3.75 -0.75 C 4.007812 -0.75 4.253906 -0.765625 4.484375 -0.796875 C 4.722656 -0.828125 4.984375 -0.890625 5.265625 -0.984375 L 5.40625 -0.15625 C 5.125 -0.0507812 4.835938 0.0195312 4.546875 0.0625 C 4.265625 0.101562 3.957031 0.125 3.625 0.125 C 3.175781 0.125 2.765625 0.0664062 2.390625 -0.046875 C 2.023438 -0.171875 1.707031 -0.351562 1.4375 -0.59375 C 1.164062 -0.832031 0.957031 -1.132812 0.8125 -1.5 C 0.664062 -1.863281 0.59375 -2.285156 0.59375 -2.765625 Z M 0.59375 -2.765625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-11">
|
|
+<path style="stroke:none;" d="M 3.0625 -0.703125 C 3.3125 -0.703125 3.53125 -0.707031 3.71875 -0.71875 C 3.914062 -0.738281 4.082031 -0.765625 4.21875 -0.796875 L 4.21875 -2.453125 C 4.082031 -2.492188 3.925781 -2.523438 3.75 -2.546875 C 3.570312 -2.566406 3.382812 -2.578125 3.1875 -2.578125 C 3 -2.578125 2.816406 -2.5625 2.640625 -2.53125 C 2.460938 -2.507812 2.304688 -2.460938 2.171875 -2.390625 C 2.035156 -2.316406 1.921875 -2.222656 1.828125 -2.109375 C 1.742188 -1.992188 1.703125 -1.847656 1.703125 -1.671875 C 1.703125 -1.304688 1.820312 -1.050781 2.0625 -0.90625 C 2.3125 -0.769531 2.644531 -0.703125 3.0625 -0.703125 Z M 2.96875 -5.703125 C 3.382812 -5.703125 3.734375 -5.648438 4.015625 -5.546875 C 4.296875 -5.441406 4.523438 -5.296875 4.703125 -5.109375 C 4.878906 -4.929688 5.003906 -4.707031 5.078125 -4.4375 C 5.148438 -4.175781 5.1875 -3.890625 5.1875 -3.578125 L 5.1875 -0.09375 C 4.957031 -0.0507812 4.648438 -0.00390625 4.265625 0.046875 C 3.890625 0.0976562 3.5 0.125 3.09375 0.125 C 2.789062 0.125 2.492188 0.0976562 2.203125 0.046875 C 1.921875 -0.00390625 1.664062 -0.09375 1.4375 -0.21875 C 1.21875 -0.351562 1.039062 -0.535156 0.90625 -0.765625 C 0.769531 -0.992188 0.703125 -1.289062 0.703125 -1.65625 C 0.703125 -1.976562 0.769531 -2.25 0.90625 -2.46875 C 1.039062 -2.6875 1.21875 -2.863281 1.4375 -3 C 1.664062 -3.132812 1.921875 -3.234375 2.203125 -3.296875 C 2.484375 -3.359375 2.769531 -3.390625 3.0625 -3.390625 C 3.445312 -3.390625 3.832031 -3.34375 4.21875 -3.25 L 4.21875 -3.53125 C 4.21875 -3.695312 4.195312 -3.859375 4.15625 -4.015625 C 4.125 -4.171875 4.054688 -4.3125 3.953125 -4.4375 C 3.847656 -4.5625 3.707031 -4.660156 3.53125 -4.734375 C 3.363281 -4.816406 3.144531 -4.859375 2.875 -4.859375 C 2.53125 -4.859375 2.226562 -4.832031 1.96875 -4.78125 C 1.71875 -4.738281 1.523438 -4.691406 1.390625 -4.640625 L 1.265625 -5.453125 C 1.398438 -5.523438 1.625 -5.582031 1.9375 -5.625 C 2.257812 -5.675781 2.601562 -5.703125 2.96875 -5.703125 Z M 2.96875 -5.703125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-12">
|
|
+<path style="stroke:none;" d="M 4.0625 0.125 C 3.707031 0.125 3.410156 0.078125 3.171875 -0.015625 C 2.941406 -0.109375 2.757812 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 L 2.25 -7.421875 L 0.640625 -7.421875 L 0.640625 -8.25 L 3.234375 -8.25 L 3.234375 -2.140625 C 3.234375 -1.867188 3.25 -1.644531 3.28125 -1.46875 C 3.320312 -1.289062 3.378906 -1.144531 3.453125 -1.03125 C 3.535156 -0.925781 3.628906 -0.851562 3.734375 -0.8125 C 3.847656 -0.769531 3.984375 -0.75 4.140625 -0.75 C 4.367188 -0.75 4.582031 -0.773438 4.78125 -0.828125 C 4.988281 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5 -0.015625 4.875 0.015625 C 4.757812 0.046875 4.628906 0.0703125 4.484375 0.09375 C 4.347656 0.113281 4.207031 0.125 4.0625 0.125 Z M 4.0625 0.125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-13">
|
|
+<path style="stroke:none;" d="M 2.515625 -6.4375 C 2.304688 -6.4375 2.125 -6.503906 1.96875 -6.640625 C 1.8125 -6.785156 1.734375 -6.984375 1.734375 -7.234375 C 1.734375 -7.484375 1.8125 -7.679688 1.96875 -7.828125 C 2.125 -7.972656 2.304688 -8.046875 2.515625 -8.046875 C 2.722656 -8.046875 2.898438 -7.972656 3.046875 -7.828125 C 3.203125 -7.679688 3.28125 -7.484375 3.28125 -7.234375 C 3.28125 -6.984375 3.203125 -6.785156 3.046875 -6.640625 C 2.898438 -6.503906 2.722656 -6.4375 2.515625 -6.4375 Z M 2.25 -4.734375 L 0.640625 -4.734375 L 0.640625 -5.5625 L 3.234375 -5.5625 L 3.234375 -2.140625 C 3.234375 -1.585938 3.3125 -1.21875 3.46875 -1.03125 C 3.625 -0.84375 3.851562 -0.75 4.15625 -0.75 C 4.382812 -0.75 4.597656 -0.773438 4.796875 -0.828125 C 4.992188 -0.890625 5.144531 -0.953125 5.25 -1.015625 L 5.40625 -0.1875 C 5.351562 -0.15625 5.28125 -0.117188 5.1875 -0.078125 C 5.101562 -0.046875 5.003906 -0.015625 4.890625 0.015625 C 4.773438 0.046875 4.644531 0.0703125 4.5 0.09375 C 4.363281 0.113281 4.21875 0.125 4.0625 0.125 C 3.71875 0.125 3.425781 0.078125 3.1875 -0.015625 C 2.957031 -0.109375 2.769531 -0.25 2.625 -0.4375 C 2.488281 -0.632812 2.390625 -0.875 2.328125 -1.15625 C 2.273438 -1.4375 2.25 -1.765625 2.25 -2.140625 Z M 2.25 -4.734375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-14">
|
|
+<path style="stroke:none;" d="M 4.15625 -0.515625 C 4.039062 -0.453125 3.863281 -0.382812 3.625 -0.3125 C 3.394531 -0.238281 3.128906 -0.203125 2.828125 -0.203125 C 2.503906 -0.203125 2.195312 -0.253906 1.90625 -0.359375 C 1.625 -0.472656 1.378906 -0.640625 1.171875 -0.859375 C 0.960938 -1.078125 0.796875 -1.351562 0.671875 -1.6875 C 0.546875 -2.03125 0.484375 -2.4375 0.484375 -2.90625 C 0.484375 -3.3125 0.539062 -3.679688 0.65625 -4.015625 C 0.769531 -4.359375 0.9375 -4.65625 1.15625 -4.90625 C 1.375 -5.15625 1.644531 -5.347656 1.96875 -5.484375 C 2.289062 -5.628906 2.65625 -5.703125 3.0625 -5.703125 C 3.539062 -5.703125 3.945312 -5.664062 4.28125 -5.59375 C 4.625 -5.53125 4.910156 -5.46875 5.140625 -5.40625 L 5.140625 -0.4375 C 5.140625 0.425781 4.921875 1.050781 4.484375 1.4375 C 4.054688 1.820312 3.398438 2.015625 2.515625 2.015625 C 2.160156 2.015625 1.835938 1.984375 1.546875 1.921875 C 1.253906 1.867188 0.992188 1.804688 0.765625 1.734375 L 0.953125 0.859375 C 1.160156 0.941406 1.394531 1.007812 1.65625 1.0625 C 1.925781 1.125 2.222656 1.15625 2.546875 1.15625 C 3.117188 1.15625 3.53125 1.035156 3.78125 0.796875 C 4.03125 0.566406 4.15625 0.191406 4.15625 -0.328125 Z M 4.15625 -4.6875 C 4.0625 -4.71875 3.925781 -4.75 3.75 -4.78125 C 3.582031 -4.8125 3.359375 -4.828125 3.078125 -4.828125 C 2.554688 -4.828125 2.160156 -4.648438 1.890625 -4.296875 C 1.628906 -3.941406 1.5 -3.472656 1.5 -2.890625 C 1.5 -2.566406 1.535156 -2.289062 1.609375 -2.0625 C 1.691406 -1.84375 1.796875 -1.65625 1.921875 -1.5 C 2.054688 -1.351562 2.207031 -1.242188 2.375 -1.171875 C 2.539062 -1.109375 2.722656 -1.078125 2.921875 -1.078125 C 3.160156 -1.078125 3.390625 -1.113281 3.609375 -1.1875 C 3.835938 -1.257812 4.019531 -1.34375 4.15625 -1.4375 Z M 4.15625 -4.6875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-15">
|
|
+<path style="stroke:none;" d="M 2.8125 -0.703125 C 3.3125 -0.703125 3.691406 -0.796875 3.953125 -0.984375 C 4.222656 -1.171875 4.359375 -1.457031 4.359375 -1.84375 C 4.359375 -2.082031 4.304688 -2.28125 4.203125 -2.4375 C 4.109375 -2.601562 3.984375 -2.75 3.828125 -2.875 C 3.671875 -3 3.488281 -3.109375 3.28125 -3.203125 C 3.082031 -3.296875 2.878906 -3.378906 2.671875 -3.453125 C 2.429688 -3.546875 2.203125 -3.648438 1.984375 -3.765625 C 1.765625 -3.890625 1.566406 -4.03125 1.390625 -4.1875 C 1.222656 -4.351562 1.085938 -4.546875 0.984375 -4.765625 C 0.890625 -4.984375 0.84375 -5.238281 0.84375 -5.53125 C 0.84375 -6.175781 1.046875 -6.679688 1.453125 -7.046875 C 1.859375 -7.410156 2.425781 -7.59375 3.15625 -7.59375 C 3.351562 -7.59375 3.550781 -7.578125 3.75 -7.546875 C 3.945312 -7.523438 4.128906 -7.492188 4.296875 -7.453125 C 4.460938 -7.410156 4.609375 -7.359375 4.734375 -7.296875 C 4.867188 -7.242188 4.976562 -7.191406 5.0625 -7.140625 L 4.75 -6.3125 C 4.59375 -6.40625 4.375 -6.5 4.09375 -6.59375 C 3.8125 -6.695312 3.5 -6.75 3.15625 -6.75 C 2.789062 -6.75 2.476562 -6.65625 2.21875 -6.46875 C 1.957031 -6.289062 1.828125 -6.019531 1.828125 -5.65625 C 1.828125 -5.457031 1.863281 -5.285156 1.9375 -5.140625 C 2.007812 -4.992188 2.113281 -4.863281 2.25 -4.75 C 2.382812 -4.644531 2.535156 -4.546875 2.703125 -4.453125 C 2.878906 -4.367188 3.070312 -4.285156 3.28125 -4.203125 C 3.59375 -4.078125 3.875 -3.945312 4.125 -3.8125 C 4.375 -3.6875 4.585938 -3.535156 4.765625 -3.359375 C 4.953125 -3.179688 5.09375 -2.972656 5.1875 -2.734375 C 5.289062 -2.492188 5.34375 -2.203125 5.34375 -1.859375 C 5.34375 -1.210938 5.125 -0.710938 4.6875 -0.359375 C 4.25 -0.015625 3.625 0.15625 2.8125 0.15625 C 2.539062 0.15625 2.289062 0.132812 2.0625 0.09375 C 1.832031 0.0625 1.625 0.0195312 1.4375 -0.03125 C 1.257812 -0.09375 1.101562 -0.148438 0.96875 -0.203125 C 0.832031 -0.253906 0.726562 -0.304688 0.65625 -0.359375 L 0.953125 -1.171875 C 1.117188 -1.085938 1.359375 -0.988281 1.671875 -0.875 C 1.984375 -0.757812 2.363281 -0.703125 2.8125 -0.703125 Z M 2.8125 -0.703125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-16">
|
|
+<path style="stroke:none;" d="M 3.109375 -5.703125 C 3.859375 -5.703125 4.4375 -5.46875 4.84375 -5 C 5.25 -4.53125 5.453125 -3.820312 5.453125 -2.875 L 5.453125 -2.515625 L 1.46875 -2.515625 C 1.507812 -1.941406 1.703125 -1.503906 2.046875 -1.203125 C 2.390625 -0.898438 2.867188 -0.75 3.484375 -0.75 C 3.835938 -0.75 4.132812 -0.773438 4.375 -0.828125 C 4.625 -0.890625 4.8125 -0.953125 4.9375 -1.015625 L 5.078125 -0.1875 C 4.953125 -0.113281 4.734375 -0.046875 4.421875 0.015625 C 4.109375 0.0859375 3.757812 0.125 3.375 0.125 C 2.894531 0.125 2.472656 0.0507812 2.109375 -0.09375 C 1.742188 -0.238281 1.441406 -0.4375 1.203125 -0.6875 C 0.960938 -0.945312 0.78125 -1.253906 0.65625 -1.609375 C 0.539062 -1.960938 0.484375 -2.347656 0.484375 -2.765625 C 0.484375 -3.265625 0.554688 -3.695312 0.703125 -4.0625 C 0.859375 -4.4375 1.0625 -4.742188 1.3125 -4.984375 C 1.5625 -5.222656 1.835938 -5.398438 2.140625 -5.515625 C 2.453125 -5.640625 2.773438 -5.703125 3.109375 -5.703125 Z M 4.453125 -3.328125 C 4.453125 -3.796875 4.328125 -4.164062 4.078125 -4.4375 C 3.828125 -4.71875 3.5 -4.859375 3.09375 -4.859375 C 2.863281 -4.859375 2.65625 -4.8125 2.46875 -4.71875 C 2.28125 -4.632812 2.117188 -4.519531 1.984375 -4.375 C 1.847656 -4.226562 1.738281 -4.0625 1.65625 -3.875 C 1.570312 -3.695312 1.519531 -3.515625 1.5 -3.328125 Z M 4.453125 -3.328125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-17">
|
|
+<path style="stroke:none;" d="M 4.15625 -4.390625 C 4.039062 -4.492188 3.875 -4.59375 3.65625 -4.6875 C 3.445312 -4.78125 3.222656 -4.828125 2.984375 -4.828125 C 2.722656 -4.828125 2.5 -4.773438 2.3125 -4.671875 C 2.125 -4.566406 1.96875 -4.421875 1.84375 -4.234375 C 1.726562 -4.054688 1.640625 -3.84375 1.578125 -3.59375 C 1.523438 -3.34375 1.5 -3.070312 1.5 -2.78125 C 1.5 -2.132812 1.648438 -1.632812 1.953125 -1.28125 C 2.253906 -0.925781 2.648438 -0.75 3.140625 -0.75 C 3.390625 -0.75 3.597656 -0.757812 3.765625 -0.78125 C 3.941406 -0.8125 4.070312 -0.835938 4.15625 -0.859375 Z M 4.15625 -8.140625 L 5.140625 -8.3125 L 5.140625 -0.15625 C 4.929688 -0.09375 4.65625 -0.03125 4.3125 0.03125 C 3.976562 0.09375 3.585938 0.125 3.140625 0.125 C 2.742188 0.125 2.378906 0.0546875 2.046875 -0.078125 C 1.722656 -0.210938 1.441406 -0.40625 1.203125 -0.65625 C 0.972656 -0.90625 0.796875 -1.207031 0.671875 -1.5625 C 0.546875 -1.925781 0.484375 -2.332031 0.484375 -2.78125 C 0.484375 -3.21875 0.535156 -3.613281 0.640625 -3.96875 C 0.742188 -4.320312 0.898438 -4.625 1.109375 -4.875 C 1.316406 -5.132812 1.566406 -5.335938 1.859375 -5.484375 C 2.148438 -5.628906 2.488281 -5.703125 2.875 -5.703125 C 3.164062 -5.703125 3.421875 -5.664062 3.640625 -5.59375 C 3.867188 -5.519531 4.039062 -5.441406 4.15625 -5.359375 Z M 4.15625 -8.140625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-18">
|
|
+<path style="stroke:none;" d="M 1.28125 0 L 1.28125 -5.265625 C 2.101562 -5.546875 2.925781 -5.6875 3.75 -5.6875 C 4.007812 -5.6875 4.253906 -5.675781 4.484375 -5.65625 C 4.722656 -5.632812 4.976562 -5.59375 5.25 -5.53125 L 5.078125 -4.65625 C 4.816406 -4.726562 4.585938 -4.773438 4.390625 -4.796875 C 4.203125 -4.816406 3.988281 -4.828125 3.75 -4.828125 C 3.269531 -4.828125 2.773438 -4.757812 2.265625 -4.625 L 2.265625 0 Z M 1.28125 0 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-19">
|
|
+<path style="stroke:none;" d="M 0.609375 1.046875 C 0.679688 1.085938 0.78125 1.117188 0.90625 1.140625 C 1.039062 1.160156 1.164062 1.171875 1.28125 1.171875 C 1.675781 1.171875 1.984375 1.082031 2.203125 0.90625 C 2.421875 0.738281 2.625 0.460938 2.8125 0.078125 C 2.363281 -0.773438 1.941406 -1.6875 1.546875 -2.65625 C 1.148438 -3.625 0.828125 -4.59375 0.578125 -5.5625 L 1.65625 -5.5625 C 1.738281 -5.25 1.832031 -4.90625 1.9375 -4.53125 C 2.039062 -4.15625 2.160156 -3.769531 2.296875 -3.375 C 2.441406 -2.988281 2.585938 -2.597656 2.734375 -2.203125 C 2.890625 -1.804688 3.054688 -1.425781 3.234375 -1.0625 C 3.367188 -1.4375 3.488281 -1.800781 3.59375 -2.15625 C 3.707031 -2.519531 3.8125 -2.882812 3.90625 -3.25 C 4.007812 -3.613281 4.109375 -3.984375 4.203125 -4.359375 C 4.296875 -4.742188 4.394531 -5.144531 4.5 -5.5625 L 5.53125 -5.5625 C 5.269531 -4.53125 4.984375 -3.523438 4.671875 -2.546875 C 4.359375 -1.566406 4.019531 -0.660156 3.65625 0.171875 C 3.519531 0.484375 3.375 0.753906 3.21875 0.984375 C 3.0625 1.222656 2.890625 1.414062 2.703125 1.5625 C 2.523438 1.71875 2.316406 1.832031 2.078125 1.90625 C 1.847656 1.976562 1.585938 2.015625 1.296875 2.015625 C 1.140625 2.015625 0.972656 1.992188 0.796875 1.953125 C 0.617188 1.910156 0.5 1.875 0.4375 1.84375 Z M 0.609375 1.046875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-20">
|
|
+<path style="stroke:none;" d="M 0.34375 -3.71875 C 0.34375 -4.382812 0.40625 -4.960938 0.53125 -5.453125 C 0.664062 -5.941406 0.847656 -6.34375 1.078125 -6.65625 C 1.304688 -6.96875 1.582031 -7.203125 1.90625 -7.359375 C 2.238281 -7.515625 2.601562 -7.59375 3 -7.59375 C 3.394531 -7.59375 3.753906 -7.515625 4.078125 -7.359375 C 4.410156 -7.203125 4.691406 -6.96875 4.921875 -6.65625 C 5.148438 -6.34375 5.328125 -5.941406 5.453125 -5.453125 C 5.585938 -4.960938 5.65625 -4.382812 5.65625 -3.71875 C 5.65625 -3.050781 5.585938 -2.472656 5.453125 -1.984375 C 5.328125 -1.503906 5.148438 -1.101562 4.921875 -0.78125 C 4.691406 -0.457031 4.410156 -0.21875 4.078125 -0.0625 C 3.753906 0.0820312 3.394531 0.15625 3 0.15625 C 2.601562 0.15625 2.238281 0.0820312 1.90625 -0.0625 C 1.582031 -0.21875 1.304688 -0.457031 1.078125 -0.78125 C 0.847656 -1.101562 0.664062 -1.503906 0.53125 -1.984375 C 0.40625 -2.472656 0.34375 -3.050781 0.34375 -3.71875 Z M 1.359375 -3.71875 C 1.359375 -2.738281 1.488281 -1.988281 1.75 -1.46875 C 2.007812 -0.957031 2.414062 -0.703125 2.96875 -0.703125 C 3.53125 -0.703125 3.953125 -0.957031 4.234375 -1.46875 C 4.515625 -1.988281 4.65625 -2.738281 4.65625 -3.71875 C 4.65625 -4.695312 4.515625 -5.445312 4.234375 -5.96875 C 3.953125 -6.488281 3.53125 -6.75 2.96875 -6.75 C 2.414062 -6.75 2.007812 -6.488281 1.75 -5.96875 C 1.488281 -5.445312 1.359375 -4.695312 1.359375 -3.71875 Z M 1.359375 -3.71875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-21">
|
|
+<path style="stroke:none;" d="M 5.140625 -0.15625 C 4.929688 -0.101562 4.644531 -0.046875 4.28125 0.015625 C 3.925781 0.0859375 3.507812 0.125 3.03125 0.125 C 2.613281 0.125 2.265625 0.0625 1.984375 -0.0625 C 1.703125 -0.1875 1.472656 -0.363281 1.296875 -0.59375 C 1.117188 -0.820312 0.992188 -1.09375 0.921875 -1.40625 C 0.847656 -1.71875 0.8125 -2.0625 0.8125 -2.4375 L 0.8125 -5.5625 L 1.796875 -5.5625 L 1.796875 -2.65625 C 1.796875 -1.96875 1.894531 -1.476562 2.09375 -1.1875 C 2.300781 -0.894531 2.644531 -0.75 3.125 -0.75 C 3.226562 -0.75 3.332031 -0.753906 3.4375 -0.765625 C 3.550781 -0.773438 3.65625 -0.785156 3.75 -0.796875 C 3.851562 -0.804688 3.9375 -0.816406 4 -0.828125 C 4.070312 -0.847656 4.125 -0.859375 4.15625 -0.859375 L 4.15625 -5.5625 L 5.140625 -5.5625 Z M 5.140625 -0.15625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-22">
|
|
+<path style="stroke:none;" d="M 2.921875 -5.5625 L 5.265625 -5.5625 L 5.265625 -4.734375 L 2.921875 -4.734375 L 2.921875 -2.140625 C 2.921875 -1.867188 2.9375 -1.644531 2.96875 -1.46875 C 3.007812 -1.289062 3.078125 -1.144531 3.171875 -1.03125 C 3.265625 -0.925781 3.382812 -0.851562 3.53125 -0.8125 C 3.675781 -0.769531 3.851562 -0.75 4.0625 -0.75 C 4.34375 -0.75 4.570312 -0.773438 4.75 -0.828125 C 4.925781 -0.878906 5.09375 -0.941406 5.25 -1.015625 L 5.40625 -0.1875 C 5.289062 -0.132812 5.109375 -0.0703125 4.859375 0 C 4.617188 0.0820312 4.316406 0.125 3.953125 0.125 C 3.546875 0.125 3.207031 0.078125 2.9375 -0.015625 C 2.675781 -0.109375 2.46875 -0.25 2.3125 -0.4375 C 2.164062 -0.632812 2.066406 -0.875 2.015625 -1.15625 C 1.960938 -1.4375 1.9375 -1.765625 1.9375 -2.140625 L 1.9375 -4.734375 L 0.75 -4.734375 L 0.75 -5.5625 L 1.9375 -5.5625 L 1.9375 -7.125 L 2.921875 -7.296875 Z M 2.921875 -5.5625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-23">
|
|
+<path style="stroke:none;" d="M 4.5 -2.765625 C 4.5 -3.421875 4.347656 -3.925781 4.046875 -4.28125 C 3.742188 -4.632812 3.347656 -4.8125 2.859375 -4.8125 C 2.585938 -4.8125 2.375 -4.796875 2.21875 -4.765625 C 2.0625 -4.742188 1.9375 -4.71875 1.84375 -4.6875 L 1.84375 -1.171875 C 1.957031 -1.066406 2.117188 -0.96875 2.328125 -0.875 C 2.546875 -0.789062 2.773438 -0.75 3.015625 -0.75 C 3.273438 -0.75 3.5 -0.800781 3.6875 -0.90625 C 3.875 -1.007812 4.023438 -1.148438 4.140625 -1.328125 C 4.265625 -1.515625 4.351562 -1.726562 4.40625 -1.96875 C 4.46875 -2.21875 4.5 -2.484375 4.5 -2.765625 Z M 5.515625 -2.765625 C 5.515625 -2.347656 5.460938 -1.957031 5.359375 -1.59375 C 5.253906 -1.238281 5.097656 -0.929688 4.890625 -0.671875 C 4.679688 -0.421875 4.429688 -0.222656 4.140625 -0.078125 C 3.847656 0.0546875 3.507812 0.125 3.125 0.125 C 2.832031 0.125 2.570312 0.0859375 2.34375 0.015625 C 2.125 -0.046875 1.957031 -0.125 1.84375 -0.21875 L 1.84375 1.984375 L 0.859375 1.984375 L 0.859375 -5.40625 C 1.066406 -5.46875 1.34375 -5.53125 1.6875 -5.59375 C 2.03125 -5.65625 2.421875 -5.6875 2.859375 -5.6875 C 3.253906 -5.6875 3.613281 -5.617188 3.9375 -5.484375 C 4.269531 -5.347656 4.550781 -5.15625 4.78125 -4.90625 C 5.019531 -4.65625 5.203125 -4.347656 5.328125 -3.984375 C 5.453125 -3.617188 5.515625 -3.210938 5.515625 -2.765625 Z M 5.515625 -2.765625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph1-24">
|
|
+<path style="stroke:none;" d="M 3.015625 -3.734375 L 4.15625 -7.421875 L 5.09375 -7.421875 C 5.25 -6.253906 5.359375 -5.054688 5.421875 -3.828125 C 5.492188 -2.609375 5.554688 -1.332031 5.609375 0 L 4.65625 0 C 4.644531 -0.425781 4.632812 -0.890625 4.625 -1.390625 C 4.625 -1.898438 4.613281 -2.421875 4.59375 -2.953125 C 4.582031 -3.492188 4.570312 -4.039062 4.5625 -4.59375 C 4.550781 -5.144531 4.539062 -5.679688 4.53125 -6.203125 L 3.4375 -2.8125 L 2.578125 -2.8125 L 1.46875 -6.203125 C 1.46875 -5.679688 1.457031 -5.144531 1.4375 -4.59375 C 1.425781 -4.050781 1.414062 -3.507812 1.40625 -2.96875 C 1.394531 -2.425781 1.382812 -1.898438 1.375 -1.390625 C 1.363281 -0.890625 1.351562 -0.425781 1.34375 0 L 0.390625 0 C 0.410156 -0.601562 0.4375 -1.222656 0.46875 -1.859375 C 0.5 -2.503906 0.535156 -3.144531 0.578125 -3.78125 C 0.617188 -4.414062 0.671875 -5.039062 0.734375 -5.65625 C 0.796875 -6.269531 0.863281 -6.859375 0.9375 -7.421875 L 1.84375 -7.421875 Z M 3.015625 -3.734375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-0">
|
|
+<path style="stroke:none;" d="M 0.640625 2.296875 L 0.640625 -9.171875 L 7.140625 -9.171875 L 7.140625 2.296875 Z M 1.375 1.578125 L 6.421875 1.578125 L 6.421875 -8.4375 L 1.375 -8.4375 Z M 1.375 1.578125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-1">
|
|
+<path style="stroke:none;" d="M 6.34375 -6.84375 L 6.34375 -5.75 C 6.007812 -5.925781 5.675781 -6.0625 5.34375 -6.15625 C 5.007812 -6.25 4.675781 -6.296875 4.34375 -6.296875 C 3.582031 -6.296875 2.992188 -6.050781 2.578125 -5.5625 C 2.160156 -5.082031 1.953125 -4.410156 1.953125 -3.546875 C 1.953125 -2.679688 2.160156 -2.007812 2.578125 -1.53125 C 2.992188 -1.050781 3.582031 -0.8125 4.34375 -0.8125 C 4.675781 -0.8125 5.007812 -0.851562 5.34375 -0.9375 C 5.675781 -1.03125 6.007812 -1.171875 6.34375 -1.359375 L 6.34375 -0.265625 C 6.019531 -0.117188 5.679688 -0.0078125 5.328125 0.0625 C 4.984375 0.144531 4.613281 0.1875 4.21875 0.1875 C 3.144531 0.1875 2.289062 -0.144531 1.65625 -0.8125 C 1.03125 -1.488281 0.71875 -2.398438 0.71875 -3.546875 C 0.71875 -4.703125 1.035156 -5.613281 1.671875 -6.28125 C 2.304688 -6.945312 3.179688 -7.28125 4.296875 -7.28125 C 4.648438 -7.28125 5 -7.242188 5.34375 -7.171875 C 5.6875 -7.097656 6.019531 -6.988281 6.34375 -6.84375 Z M 6.34375 -6.84375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-2">
|
|
+<path style="stroke:none;" d="M 5.34375 -6.015625 C 5.207031 -6.085938 5.0625 -6.140625 4.90625 -6.171875 C 4.757812 -6.210938 4.59375 -6.234375 4.40625 -6.234375 C 3.75 -6.234375 3.242188 -6.019531 2.890625 -5.59375 C 2.535156 -5.164062 2.359375 -4.550781 2.359375 -3.75 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.597656 -6.4375 2.914062 -6.757812 3.3125 -6.96875 C 3.707031 -7.175781 4.1875 -7.28125 4.75 -7.28125 C 4.832031 -7.28125 4.921875 -7.273438 5.015625 -7.265625 C 5.109375 -7.253906 5.21875 -7.238281 5.34375 -7.21875 Z M 5.34375 -6.015625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-3">
|
|
+<path style="stroke:none;" d="M 3.984375 -6.296875 C 3.359375 -6.296875 2.863281 -6.050781 2.5 -5.5625 C 2.132812 -5.070312 1.953125 -4.398438 1.953125 -3.546875 C 1.953125 -2.691406 2.128906 -2.019531 2.484375 -1.53125 C 2.847656 -1.050781 3.347656 -0.8125 3.984375 -0.8125 C 4.597656 -0.8125 5.085938 -1.054688 5.453125 -1.546875 C 5.816406 -2.035156 6 -2.703125 6 -3.546875 C 6 -4.390625 5.816406 -5.054688 5.453125 -5.546875 C 5.085938 -6.046875 4.597656 -6.296875 3.984375 -6.296875 Z M 3.984375 -7.28125 C 4.992188 -7.28125 5.789062 -6.945312 6.375 -6.28125 C 6.957031 -5.625 7.25 -4.710938 7.25 -3.546875 C 7.25 -2.378906 6.957031 -1.460938 6.375 -0.796875 C 5.789062 -0.140625 4.992188 0.1875 3.984375 0.1875 C 2.960938 0.1875 2.160156 -0.140625 1.578125 -0.796875 C 1.003906 -1.460938 0.71875 -2.378906 0.71875 -3.546875 C 0.71875 -4.710938 1.003906 -5.625 1.578125 -6.28125 C 2.160156 -6.945312 2.960938 -7.28125 3.984375 -7.28125 Z M 3.984375 -7.28125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-4">
|
|
+<path style="stroke:none;" d="M 2.359375 -1.0625 L 2.359375 2.703125 L 1.1875 2.703125 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 Z M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 6.328125 -3.546875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-5">
|
|
+<path style="stroke:none;" d="M 5.75 -6.90625 L 5.75 -5.796875 C 5.425781 -5.960938 5.085938 -6.085938 4.734375 -6.171875 C 4.378906 -6.253906 4.007812 -6.296875 3.625 -6.296875 C 3.039062 -6.296875 2.601562 -6.207031 2.3125 -6.03125 C 2.03125 -5.851562 1.890625 -5.585938 1.890625 -5.234375 C 1.890625 -4.960938 1.988281 -4.75 2.1875 -4.59375 C 2.394531 -4.445312 2.816406 -4.300781 3.453125 -4.15625 L 3.84375 -4.0625 C 4.675781 -3.882812 5.265625 -3.632812 5.609375 -3.3125 C 5.960938 -2.988281 6.140625 -2.539062 6.140625 -1.96875 C 6.140625 -1.300781 5.878906 -0.773438 5.359375 -0.390625 C 4.835938 -0.00390625 4.117188 0.1875 3.203125 0.1875 C 2.816406 0.1875 2.414062 0.148438 2 0.078125 C 1.59375 0.00390625 1.160156 -0.109375 0.703125 -0.265625 L 0.703125 -1.46875 C 1.140625 -1.238281 1.566406 -1.066406 1.984375 -0.953125 C 2.398438 -0.847656 2.8125 -0.796875 3.21875 -0.796875 C 3.769531 -0.796875 4.191406 -0.890625 4.484375 -1.078125 C 4.785156 -1.265625 4.9375 -1.53125 4.9375 -1.875 C 4.9375 -2.1875 4.828125 -2.425781 4.609375 -2.59375 C 4.398438 -2.769531 3.9375 -2.9375 3.21875 -3.09375 L 2.8125 -3.1875 C 2.082031 -3.34375 1.554688 -3.578125 1.234375 -3.890625 C 0.910156 -4.203125 0.75 -4.632812 0.75 -5.1875 C 0.75 -5.851562 0.984375 -6.367188 1.453125 -6.734375 C 1.929688 -7.097656 2.609375 -7.28125 3.484375 -7.28125 C 3.910156 -7.28125 4.316406 -7.25 4.703125 -7.1875 C 5.085938 -7.125 5.4375 -7.03125 5.75 -6.90625 Z M 5.75 -6.90625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-6">
|
|
+<path style="stroke:none;" d="M 4.453125 -3.578125 C 3.515625 -3.578125 2.863281 -3.46875 2.5 -3.25 C 2.132812 -3.03125 1.953125 -2.660156 1.953125 -2.140625 C 1.953125 -1.734375 2.085938 -1.40625 2.359375 -1.15625 C 2.628906 -0.914062 3 -0.796875 3.46875 -0.796875 C 4.113281 -0.796875 4.632812 -1.023438 5.03125 -1.484375 C 5.425781 -1.941406 5.625 -2.550781 5.625 -3.3125 L 5.625 -3.578125 Z M 6.78125 -4.0625 L 6.78125 0 L 5.625 0 L 5.625 -1.078125 C 5.351562 -0.648438 5.019531 -0.332031 4.625 -0.125 C 4.226562 0.0820312 3.738281 0.1875 3.15625 0.1875 C 2.425781 0.1875 1.847656 -0.015625 1.421875 -0.421875 C 0.992188 -0.835938 0.78125 -1.382812 0.78125 -2.0625 C 0.78125 -2.863281 1.046875 -3.46875 1.578125 -3.875 C 2.117188 -4.28125 2.921875 -4.484375 3.984375 -4.484375 L 5.625 -4.484375 L 5.625 -4.609375 C 5.625 -5.140625 5.445312 -5.550781 5.09375 -5.84375 C 4.738281 -6.144531 4.238281 -6.296875 3.59375 -6.296875 C 3.1875 -6.296875 2.789062 -6.242188 2.40625 -6.140625 C 2.019531 -6.046875 1.648438 -5.898438 1.296875 -5.703125 L 1.296875 -6.78125 C 1.722656 -6.945312 2.140625 -7.070312 2.546875 -7.15625 C 2.953125 -7.238281 3.34375 -7.28125 3.71875 -7.28125 C 4.75 -7.28125 5.515625 -7.015625 6.015625 -6.484375 C 6.523438 -5.953125 6.78125 -5.144531 6.78125 -4.0625 Z M 6.78125 -4.0625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-7">
|
|
+<path style="stroke:none;" d="M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-8">
|
|
+<path style="stroke:none;" d="M 7.3125 -3.84375 L 7.3125 -3.28125 L 1.9375 -3.28125 C 1.988281 -2.46875 2.226562 -1.851562 2.65625 -1.4375 C 3.09375 -1.019531 3.695312 -0.8125 4.46875 -0.8125 C 4.914062 -0.8125 5.347656 -0.863281 5.765625 -0.96875 C 6.191406 -1.082031 6.613281 -1.25 7.03125 -1.46875 L 7.03125 -0.359375 C 6.613281 -0.179688 6.179688 -0.046875 5.734375 0.046875 C 5.296875 0.140625 4.851562 0.1875 4.40625 0.1875 C 3.269531 0.1875 2.367188 -0.140625 1.703125 -0.796875 C 1.046875 -1.460938 0.71875 -2.359375 0.71875 -3.484375 C 0.71875 -4.648438 1.03125 -5.570312 1.65625 -6.25 C 2.289062 -6.9375 3.140625 -7.28125 4.203125 -7.28125 C 5.160156 -7.28125 5.914062 -6.972656 6.46875 -6.359375 C 7.03125 -5.742188 7.3125 -4.90625 7.3125 -3.84375 Z M 6.140625 -4.1875 C 6.128906 -4.820312 5.945312 -5.332031 5.59375 -5.71875 C 5.25 -6.101562 4.789062 -6.296875 4.21875 -6.296875 C 3.5625 -6.296875 3.035156 -6.109375 2.640625 -5.734375 C 2.253906 -5.367188 2.03125 -4.851562 1.96875 -4.1875 Z M 6.140625 -4.1875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-9">
|
|
+<path style="stroke:none;" d="M 6.328125 -3.546875 C 6.328125 -4.410156 6.148438 -5.082031 5.796875 -5.5625 C 5.441406 -6.050781 4.957031 -6.296875 4.34375 -6.296875 C 3.726562 -6.296875 3.242188 -6.050781 2.890625 -5.5625 C 2.535156 -5.082031 2.359375 -4.410156 2.359375 -3.546875 C 2.359375 -2.691406 2.535156 -2.019531 2.890625 -1.53125 C 3.242188 -1.039062 3.726562 -0.796875 4.34375 -0.796875 C 4.957031 -0.796875 5.441406 -1.039062 5.796875 -1.53125 C 6.148438 -2.019531 6.328125 -2.691406 6.328125 -3.546875 Z M 2.359375 -6.03125 C 2.597656 -6.457031 2.90625 -6.769531 3.28125 -6.96875 C 3.65625 -7.175781 4.101562 -7.28125 4.625 -7.28125 C 5.488281 -7.28125 6.191406 -6.9375 6.734375 -6.25 C 7.273438 -5.5625 7.546875 -4.660156 7.546875 -3.546875 C 7.546875 -2.429688 7.273438 -1.53125 6.734375 -0.84375 C 6.191406 -0.15625 5.488281 0.1875 4.625 0.1875 C 4.101562 0.1875 3.65625 0.0820312 3.28125 -0.125 C 2.90625 -0.332031 2.597656 -0.644531 2.359375 -1.0625 L 2.359375 0 L 1.1875 0 L 1.1875 -9.875 L 2.359375 -9.875 Z M 2.359375 -6.03125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-10">
|
|
+<path style="stroke:none;" d="M 1.21875 -7.109375 L 2.390625 -7.109375 L 2.390625 0 L 1.21875 0 Z M 1.21875 -9.875 L 2.390625 -9.875 L 2.390625 -8.390625 L 1.21875 -8.390625 Z M 1.21875 -9.875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-11">
|
|
+<path style="stroke:none;" d="M 7.140625 -4.296875 L 7.140625 0 L 5.96875 0 L 5.96875 -4.25 C 5.96875 -4.925781 5.835938 -5.429688 5.578125 -5.765625 C 5.316406 -6.097656 4.921875 -6.265625 4.390625 -6.265625 C 3.765625 -6.265625 3.269531 -6.0625 2.90625 -5.65625 C 2.539062 -5.257812 2.359375 -4.710938 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.640625 -6.425781 2.96875 -6.742188 3.34375 -6.953125 C 3.71875 -7.171875 4.15625 -7.28125 4.65625 -7.28125 C 5.46875 -7.28125 6.082031 -7.023438 6.5 -6.515625 C 6.925781 -6.015625 7.140625 -5.273438 7.140625 -4.296875 Z M 7.140625 -4.296875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-12">
|
|
+<path style="stroke:none;" d="M 5.90625 -3.640625 C 5.90625 -4.484375 5.726562 -5.132812 5.375 -5.59375 C 5.03125 -6.0625 4.539062 -6.296875 3.90625 -6.296875 C 3.28125 -6.296875 2.789062 -6.0625 2.4375 -5.59375 C 2.09375 -5.132812 1.921875 -4.484375 1.921875 -3.640625 C 1.921875 -2.796875 2.09375 -2.140625 2.4375 -1.671875 C 2.789062 -1.210938 3.28125 -0.984375 3.90625 -0.984375 C 4.539062 -0.984375 5.03125 -1.210938 5.375 -1.671875 C 5.726562 -2.140625 5.90625 -2.796875 5.90625 -3.640625 Z M 7.078125 -0.875 C 7.078125 0.332031 6.804688 1.226562 6.265625 1.8125 C 5.722656 2.40625 4.898438 2.703125 3.796875 2.703125 C 3.390625 2.703125 3.003906 2.671875 2.640625 2.609375 C 2.273438 2.546875 1.921875 2.453125 1.578125 2.328125 L 1.578125 1.1875 C 1.921875 1.375 2.257812 1.507812 2.59375 1.59375 C 2.925781 1.6875 3.265625 1.734375 3.609375 1.734375 C 4.378906 1.734375 4.953125 1.535156 5.328125 1.140625 C 5.710938 0.742188 5.90625 0.140625 5.90625 -0.671875 L 5.90625 -1.25 C 5.664062 -0.832031 5.351562 -0.519531 4.96875 -0.3125 C 4.59375 -0.101562 4.144531 0 3.625 0 C 2.75 0 2.046875 -0.332031 1.515625 -1 C 0.984375 -1.664062 0.71875 -2.546875 0.71875 -3.640625 C 0.71875 -4.734375 0.984375 -5.613281 1.515625 -6.28125 C 2.046875 -6.945312 2.75 -7.28125 3.625 -7.28125 C 4.144531 -7.28125 4.59375 -7.175781 4.96875 -6.96875 C 5.351562 -6.757812 5.664062 -6.445312 5.90625 -6.03125 L 5.90625 -7.109375 L 7.078125 -7.109375 Z M 7.078125 -0.875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-13">
|
|
+<path style="stroke:none;" d="M 5.125 -8.609375 C 4.1875 -8.609375 3.441406 -8.257812 2.890625 -7.5625 C 2.347656 -6.875 2.078125 -5.929688 2.078125 -4.734375 C 2.078125 -3.535156 2.347656 -2.585938 2.890625 -1.890625 C 3.441406 -1.203125 4.1875 -0.859375 5.125 -0.859375 C 6.050781 -0.859375 6.785156 -1.203125 7.328125 -1.890625 C 7.878906 -2.585938 8.15625 -3.535156 8.15625 -4.734375 C 8.15625 -5.929688 7.878906 -6.875 7.328125 -7.5625 C 6.785156 -8.257812 6.050781 -8.609375 5.125 -8.609375 Z M 5.125 -9.65625 C 6.445312 -9.65625 7.503906 -9.207031 8.296875 -8.3125 C 9.097656 -7.414062 9.5 -6.222656 9.5 -4.734375 C 9.5 -3.234375 9.097656 -2.035156 8.296875 -1.140625 C 7.503906 -0.253906 6.445312 0.1875 5.125 0.1875 C 3.789062 0.1875 2.722656 -0.253906 1.921875 -1.140625 C 1.128906 -2.035156 0.734375 -3.234375 0.734375 -4.734375 C 0.734375 -6.222656 1.128906 -7.414062 1.921875 -8.3125 C 2.722656 -9.207031 3.789062 -9.65625 5.125 -9.65625 Z M 5.125 -9.65625 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-14">
|
|
+<path style="stroke:none;" d="M 1.109375 -2.8125 L 1.109375 -7.109375 L 2.265625 -7.109375 L 2.265625 -2.84375 C 2.265625 -2.175781 2.394531 -1.671875 2.65625 -1.328125 C 2.925781 -0.992188 3.320312 -0.828125 3.84375 -0.828125 C 4.476562 -0.828125 4.976562 -1.023438 5.34375 -1.421875 C 5.707031 -1.828125 5.890625 -2.378906 5.890625 -3.078125 L 5.890625 -7.109375 L 7.0625 -7.109375 L 7.0625 0 L 5.890625 0 L 5.890625 -1.09375 C 5.609375 -0.65625 5.28125 -0.332031 4.90625 -0.125 C 4.53125 0.0820312 4.09375 0.1875 3.59375 0.1875 C 2.78125 0.1875 2.160156 -0.0664062 1.734375 -0.578125 C 1.316406 -1.085938 1.109375 -1.832031 1.109375 -2.8125 Z M 4.046875 -7.28125 Z M 4.046875 -7.28125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-15">
|
|
+<path style="stroke:none;" d="M 2.375 -9.125 L 2.375 -7.109375 L 4.78125 -7.109375 L 4.78125 -6.203125 L 2.375 -6.203125 L 2.375 -2.34375 C 2.375 -1.757812 2.453125 -1.382812 2.609375 -1.21875 C 2.773438 -1.0625 3.101562 -0.984375 3.59375 -0.984375 L 4.78125 -0.984375 L 4.78125 0 L 3.59375 0 C 2.6875 0 2.0625 -0.164062 1.71875 -0.5 C 1.375 -0.84375 1.203125 -1.457031 1.203125 -2.34375 L 1.203125 -6.203125 L 0.34375 -6.203125 L 0.34375 -7.109375 L 1.203125 -7.109375 L 1.203125 -9.125 Z M 2.375 -9.125 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-16">
|
|
+<path style="stroke:none;" d=""/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-17">
|
|
+<path style="stroke:none;" d="M 1.28125 -9.484375 L 6.71875 -9.484375 L 6.71875 -8.390625 L 2.5625 -8.390625 L 2.5625 -5.609375 L 6.3125 -5.609375 L 6.3125 -4.53125 L 2.5625 -4.53125 L 2.5625 0 L 1.28125 0 Z M 1.28125 -9.484375 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-18">
|
|
+<path style="stroke:none;" d="M 6.765625 -5.75 C 7.054688 -6.269531 7.40625 -6.65625 7.8125 -6.90625 C 8.21875 -7.15625 8.695312 -7.28125 9.25 -7.28125 C 9.988281 -7.28125 10.554688 -7.019531 10.953125 -6.5 C 11.359375 -5.976562 11.5625 -5.242188 11.5625 -4.296875 L 11.5625 0 L 10.390625 0 L 10.390625 -4.25 C 10.390625 -4.9375 10.265625 -5.441406 10.015625 -5.765625 C 9.773438 -6.097656 9.410156 -6.265625 8.921875 -6.265625 C 8.316406 -6.265625 7.835938 -6.0625 7.484375 -5.65625 C 7.128906 -5.257812 6.953125 -4.710938 6.953125 -4.015625 L 6.953125 0 L 5.78125 0 L 5.78125 -4.25 C 5.78125 -4.9375 5.660156 -5.441406 5.421875 -5.765625 C 5.179688 -6.097656 4.804688 -6.265625 4.296875 -6.265625 C 3.703125 -6.265625 3.226562 -6.0625 2.875 -5.65625 C 2.53125 -5.25 2.359375 -4.703125 2.359375 -4.015625 L 2.359375 0 L 1.1875 0 L 1.1875 -7.109375 L 2.359375 -7.109375 L 2.359375 -6 C 2.617188 -6.4375 2.9375 -6.757812 3.3125 -6.96875 C 3.6875 -7.175781 4.128906 -7.28125 4.640625 -7.28125 C 5.160156 -7.28125 5.597656 -7.148438 5.953125 -6.890625 C 6.316406 -6.628906 6.585938 -6.25 6.765625 -5.75 Z M 6.765625 -5.75 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-19">
|
|
+<path style="stroke:none;" d="M 6.953125 -9.171875 L 6.953125 -7.921875 C 6.472656 -8.148438 6.015625 -8.320312 5.578125 -8.4375 C 5.148438 -8.550781 4.734375 -8.609375 4.328125 -8.609375 C 3.628906 -8.609375 3.085938 -8.472656 2.703125 -8.203125 C 2.328125 -7.929688 2.140625 -7.546875 2.140625 -7.046875 C 2.140625 -6.628906 2.265625 -6.3125 2.515625 -6.09375 C 2.773438 -5.882812 3.253906 -5.710938 3.953125 -5.578125 L 4.734375 -5.421875 C 5.679688 -5.234375 6.382812 -4.910156 6.84375 -4.453125 C 7.300781 -3.992188 7.53125 -3.378906 7.53125 -2.609375 C 7.53125 -1.691406 7.222656 -0.992188 6.609375 -0.515625 C 5.992188 -0.046875 5.085938 0.1875 3.890625 0.1875 C 3.441406 0.1875 2.960938 0.132812 2.453125 0.03125 C 1.953125 -0.0703125 1.429688 -0.222656 0.890625 -0.421875 L 0.890625 -1.734375 C 1.410156 -1.441406 1.921875 -1.222656 2.421875 -1.078125 C 2.921875 -0.929688 3.410156 -0.859375 3.890625 -0.859375 C 4.628906 -0.859375 5.195312 -1 5.59375 -1.28125 C 5.988281 -1.570312 6.1875 -1.984375 6.1875 -2.515625 C 6.1875 -2.984375 6.039062 -3.347656 5.75 -3.609375 C 5.46875 -3.867188 5.003906 -4.066406 4.359375 -4.203125 L 3.578125 -4.359375 C 2.617188 -4.546875 1.925781 -4.84375 1.5 -5.25 C 1.070312 -5.65625 0.859375 -6.21875 0.859375 -6.9375 C 0.859375 -7.78125 1.148438 -8.441406 1.734375 -8.921875 C 2.328125 -9.410156 3.144531 -9.65625 4.1875 -9.65625 C 4.625 -9.65625 5.070312 -9.613281 5.53125 -9.53125 C 6 -9.445312 6.472656 -9.328125 6.953125 -9.171875 Z M 6.953125 -9.171875 "/>
|
|
+</symbol>
|
|
+<symbol overflow="visible" id="glyph2-20">
|
|
+<path style="stroke:none;" d="M 4.1875 0.65625 C 3.851562 1.507812 3.53125 2.0625 3.21875 2.3125 C 2.90625 2.570312 2.488281 2.703125 1.96875 2.703125 L 1.03125 2.703125 L 1.03125 1.734375 L 1.71875 1.734375 C 2.039062 1.734375 2.289062 1.65625 2.46875 1.5 C 2.644531 1.34375 2.835938 0.984375 3.046875 0.421875 L 3.265625 -0.109375 L 0.390625 -7.109375 L 1.625 -7.109375 L 3.84375 -1.546875 L 6.0625 -7.109375 L 7.3125 -7.109375 Z M 4.1875 0.65625 "/>
|
|
+</symbol>
|
|
+</g>
|
|
+</defs>
|
|
+<g id="surface268880">
|
|
+<rect x="0" y="0" width="774" height="152" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 21.75297 10.408118 L 26.433829 10.408118 L 26.433829 12.281165 L 21.75297 12.281165 Z M 21.75297 10.408118 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 29.079728 10.51222 L 32.829728 10.51222 L 32.829728 12.149915 L 29.079728 12.149915 Z M 29.079728 10.51222 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph0-1" x="20.171875" y="57.705621"/>
|
|
+ <use xlink:href="#glyph0-2" x="30.171875" y="57.705621"/>
|
|
+ <use xlink:href="#glyph0-3" x="40.171875" y="57.705621"/>
|
|
+ <use xlink:href="#glyph0-4" x="50.171875" y="57.705621"/>
|
|
+ <use xlink:href="#glyph0-5" x="60.171875" y="57.705621"/>
|
|
+ <use xlink:href="#glyph0-6" x="70.171875" y="57.705621"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph0-7" x="174.203125" y="60.053277"/>
|
|
+ <use xlink:href="#glyph0-8" x="184.203125" y="60.053277"/>
|
|
+</g>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.925236 10.544446 L 44.675236 10.544446 L 44.675236 12.090345 L 40.925236 12.090345 Z M 40.925236 10.544446 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.883439 10.536634 L 38.633439 10.536634 L 38.633439 12.120032 L 34.883439 12.120032 Z M 34.883439 10.536634 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 47.084806 10.484876 L 52.045743 10.484876 L 52.045743 12.130774 L 47.084806 12.130774 Z M 47.084806 10.484876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.980118 10.376868 L 59.866642 10.376868 L 59.866642 12.279603 L 53.980118 12.279603 Z M 53.980118 10.376868 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.048478 13.825501 L 59.868009 13.825501 L 59.868009 15.490345 L 54.048478 15.490345 Z M 54.048478 13.825501 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 26.481876 11.338001 L 28.593009 11.332337 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.968009 11.33136 L 28.468595 11.582728 L 28.593009 11.332337 L 28.467228 11.082728 Z M 28.968009 11.33136 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 32.876798 11.329798 L 34.396525 11.328626 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.771525 11.328431 L 34.27172 11.578821 L 34.396525 11.328626 L 34.271329 11.078821 Z M 34.771525 11.328431 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 38.633439 11.328431 L 40.438517 11.319642 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 40.813517 11.317884 L 40.314689 11.570228 L 40.438517 11.319642 L 40.312345 11.070423 Z M 40.813517 11.317884 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 44.675236 11.317298 L 46.597892 11.309876 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 46.972892 11.308313 L 46.473868 11.560267 L 46.597892 11.309876 L 46.471915 11.060267 Z M 46.972892 11.308313 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 52.045743 11.307923 L 53.4934 11.323157 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.8684 11.327063 L 53.365861 11.57179 L 53.4934 11.323157 L 53.370939 11.07179 Z M 53.8684 11.327063 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph0-9" x="286.757813" y="60.611871"/>
|
|
+ <use xlink:href="#glyph0-10" x="296.757813" y="60.611871"/>
|
|
+ <use xlink:href="#glyph0-1" x="306.757813" y="60.611871"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph0-11" x="405.660156" y="59.904839"/>
|
|
+ <use xlink:href="#glyph0-10" x="415.660156" y="59.904839"/>
|
|
+ <use xlink:href="#glyph0-12" x="425.660156" y="59.904839"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph1-1" x="511.308594" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-2" x="517.308757" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-3" x="523.308919" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-4" x="529.309082" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-5" x="535.309245" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-6" x="541.309408" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-7" x="547.30957" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-8" x="553.309733" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-9" x="559.309896" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-10" x="565.310059" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-11" x="571.310221" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-12" x="577.310384" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-13" x="583.310547" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-8" x="589.31071" y="58.064616"/>
|
|
+ <use xlink:href="#glyph1-14" x="595.310872" y="58.064616"/>
|
|
+</g>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 45.671915 11.342298 L 45.655704 11.342298 L 45.655704 14.657923 L 53.561759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.936759 14.657923 L 53.436759 14.907923 L 53.561759 14.657923 L 53.436759 14.407923 Z M 53.936759 14.657923 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph1-15" x="657.078125" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-16" x="663.078288" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-10" x="669.078451" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-6" x="675.078613" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-8" x="681.078776" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-17" x="687.078939" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-11" x="693.079102" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-18" x="699.079264" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-19" x="705.079427" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-4" x="711.07959" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-20" x="717.079753" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-21" x="723.079915" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-22" x="729.080078" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-23" x="735.080241" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-21" x="741.080404" y="57.724772"/>
|
|
+ <use xlink:href="#glyph1-22" x="747.080566" y="57.724772"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph1-24" x="673.335938" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-11" x="679.3361" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-13" x="685.336263" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-8" x="691.336426" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-4" x="697.336589" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-20" x="703.336751" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-21" x="709.336914" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-22" x="715.337077" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-23" x="721.33724" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-21" x="727.337402" y="124.170085"/>
|
|
+ <use xlink:href="#glyph1-22" x="733.337565" y="124.170085"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph2-1" x="168.71875" y="31.959093"/>
|
|
+ <use xlink:href="#glyph2-2" x="175.866102" y="31.959093"/>
|
|
+ <use xlink:href="#glyph2-3" x="180.92551" y="31.959093"/>
|
|
+ <use xlink:href="#glyph2-4" x="188.879069" y="31.959093"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph2-5" x="288.109375" y="31.681749"/>
|
|
+ <use xlink:href="#glyph2-1" x="294.882378" y="31.681749"/>
|
|
+ <use xlink:href="#glyph2-6" x="302.029731" y="31.681749"/>
|
|
+ <use xlink:href="#glyph2-7" x="309.996039" y="31.681749"/>
|
|
+ <use xlink:href="#glyph2-8" x="313.607964" y="31.681749"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph2-5" x="535.988281" y="33.365343"/>
|
|
+ <use xlink:href="#glyph2-1" x="542.761285" y="33.365343"/>
|
|
+ <use xlink:href="#glyph2-6" x="549.908637" y="33.365343"/>
|
|
+ <use xlink:href="#glyph2-7" x="557.874946" y="33.365343"/>
|
|
+ <use xlink:href="#glyph2-8" x="561.486871" y="33.365343"/>
|
|
+</g>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph2-9" x="26.695313" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-10" x="34.947266" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-11" x="38.559191" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-11" x="46.798394" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-10" x="55.037598" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-11" x="58.649523" y="32.365343"/>
|
|
+ <use xlink:href="#glyph2-12" x="66.888726" y="32.365343"/>
|
|
+</g>
|
|
+<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.14,0.14;stroke-miterlimit:10;" d="M 45.300431 9.486438 L 60.373478 9.486438 L 60.373478 16.175696 L 45.300431 16.175696 Z M 45.300431 9.486438 " transform="matrix(20,0,0,20,-434.059401,-172.47877)"/>
|
|
+<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
|
+ <use xlink:href="#glyph2-13" x="532.003906" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-14" x="542.236382" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-15" x="550.475586" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-4" x="555.5727" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-14" x="563.824653" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-15" x="572.063856" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-16" x="577.16097" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-17" x="581.293186" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-3" x="588.307346" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-2" x="596.260905" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-18" x="601.377279" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-6" x="614.040853" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-15" x="622.007161" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-15" x="627.104275" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-8" x="632.201389" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-2" x="640.199436" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-16" x="645.544217" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-19" x="649.676432" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-20" x="657.928385" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-5" x="665.621799" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-15" x="672.394803" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-8" x="677.491916" y="11.904405"/>
|
|
+ <use xlink:href="#glyph2-18" x="685.489963" y="11.904405"/>
|
|
+</g>
|
|
+</g>
|
|
+</svg>
|
|
diff --git a/MAINTAINERS b/MAINTAINERS
|
|
index 9d3a5c54a41d..3497e493dd6f 100644
|
|
--- a/MAINTAINERS
|
|
+++ b/MAINTAINERS
|
|
@@ -8329,6 +8329,7 @@ S: Maintained
|
|
F: drivers/staging/media/ipu3/
|
|
F: Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
|
|
F: Documentation/media/v4l-drivers/ipu3.rst
|
|
+F: Documentation/media/v4l-drivers/ipu3_rcb.svg
|
|
|
|
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
|
|
M: Krzysztof Halasa <khalasa@piap.pl>
|
|
diff --git a/drivers/staging/media/ipu3/TODO b/drivers/staging/media/ipu3/TODO
|
|
index 5e55baeaea1a..1fae569c7a48 100644
|
|
--- a/drivers/staging/media/ipu3/TODO
|
|
+++ b/drivers/staging/media/ipu3/TODO
|
|
@@ -9,7 +9,6 @@ staging directory.
|
|
relevant. (Sakari)
|
|
|
|
- IPU3 driver documentation (Laurent)
|
|
- Add diagram in driver rst to describe output capability.
|
|
Comments on configuring v4l2 subdevs for CIO2 and ImgU.
|
|
|
|
- uAPI documentation:
|
|
|
|
From de05be692b944ad66ccac57a748aec4d20aed99a Mon Sep 17 00:00:00 2001
|
|
From: zhong jiang <zhongjiang@huawei.com>
|
|
Date: Wed, 9 Oct 2019 11:55:25 -0300
|
|
Subject: [PATCH] media: v4l2-dv-timings: Use DIV_ROUND_CLOSEST directly to
|
|
make it readable
|
|
|
|
The kernel.h macro DIV_ROUND_CLOSEST performs the computation (x + d/2)/d
|
|
but is perhaps more readable.
|
|
|
|
Signed-off-by: zhong jiang <zhongjiang@huawei.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit d973933858eea01dcaa150da581b11933802e415)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-dv-timings.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
index 0607a5d0d051..230d65a64217 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
|
|
@@ -757,7 +757,7 @@ bool v4l2_detect_gtf(unsigned frame_height,
|
|
pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN;
|
|
|
|
hsync = (frame_width * 8 + 50) / 100;
|
|
- hsync = ((hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN) * GTF_CELL_GRAN;
|
|
+ hsync = DIV_ROUND_CLOSEST(hsync, GTF_CELL_GRAN) * GTF_CELL_GRAN;
|
|
|
|
h_fp = h_blank / 2 - hsync;
|
|
|
|
|
|
From 8c2f4c1f2696eee5112802df95c129f34aa585eb Mon Sep 17 00:00:00 2001
|
|
From: YueHaibing <yuehaibing@huawei.com>
|
|
Date: Wed, 16 Oct 2019 05:56:04 -0300
|
|
Subject: [PATCH] media: staging: media: cedrus: use
|
|
devm_platform_ioremap_resource() to simplify code
|
|
|
|
Use devm_platform_ioremap_resource() to simplify the code a bit.
|
|
This is detected by coccinelle.
|
|
|
|
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 60afcc06ad4129af6705c1b053a4275c94d97c50)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 4 +---
|
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
index 570a9165dd5d..93347d3ba360 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
@@ -138,7 +138,6 @@ static irqreturn_t cedrus_irq(int irq, void *data)
|
|
int cedrus_hw_probe(struct cedrus_dev *dev)
|
|
{
|
|
const struct cedrus_variant *variant;
|
|
- struct resource *res;
|
|
int irq_dec;
|
|
int ret;
|
|
|
|
@@ -217,8 +216,7 @@ int cedrus_hw_probe(struct cedrus_dev *dev)
|
|
goto err_sram;
|
|
}
|
|
|
|
- res = platform_get_resource(dev->pdev, IORESOURCE_MEM, 0);
|
|
- dev->base = devm_ioremap_resource(dev->dev, res);
|
|
+ dev->base = devm_platform_ioremap_resource(dev->pdev, 0);
|
|
if (IS_ERR(dev->base)) {
|
|
dev_err(dev->dev, "Failed to map registers\n");
|
|
|
|
|
|
From c58517e547ae108f56ca67c4df0d7254b4525c47 Mon Sep 17 00:00:00 2001
|
|
From: Janusz Krzysztofik <jmkrzyszt@gmail.com>
|
|
Date: Fri, 18 Oct 2019 12:31:40 -0300
|
|
Subject: [PATCH] media: v4l2-subdev: Don't use __u32 internally
|
|
|
|
Commit a8fa55078a77 ("media: v4l2-subdev: Verify arguments in
|
|
v4l2_subdev_call()") and commit 374d62e7aa50 ("media: v4l2-subdev:
|
|
Verify v4l2_subdev_call() pad config argument") introduced a few local
|
|
functions, unfortunately with arguments of type __u32, reserved for use
|
|
in Linux uAPI. Use u32 instead.
|
|
|
|
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
|
|
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 3cbd3d99fd85096da2175b9ae0111893b91b7ad0)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-subdev.c | 6 +++---
|
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
|
|
index f725cd9b66b9..9e987c0f840e 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-subdev.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
|
|
@@ -112,7 +112,7 @@ static int subdev_close(struct file *file)
|
|
return 0;
|
|
}
|
|
|
|
-static inline int check_which(__u32 which)
|
|
+static inline int check_which(u32 which)
|
|
{
|
|
if (which != V4L2_SUBDEV_FORMAT_TRY &&
|
|
which != V4L2_SUBDEV_FORMAT_ACTIVE)
|
|
@@ -121,7 +121,7 @@ static inline int check_which(__u32 which)
|
|
return 0;
|
|
}
|
|
|
|
-static inline int check_pad(struct v4l2_subdev *sd, __u32 pad)
|
|
+static inline int check_pad(struct v4l2_subdev *sd, u32 pad)
|
|
{
|
|
#if defined(CONFIG_MEDIA_CONTROLLER)
|
|
if (sd->entity.num_pads) {
|
|
@@ -136,7 +136,7 @@ static inline int check_pad(struct v4l2_subdev *sd, __u32 pad)
|
|
return 0;
|
|
}
|
|
|
|
-static int check_cfg(__u32 which, struct v4l2_subdev_pad_config *cfg)
|
|
+static int check_cfg(u32 which, struct v4l2_subdev_pad_config *cfg)
|
|
{
|
|
if (which == V4L2_SUBDEV_FORMAT_TRY && !cfg)
|
|
return -EINVAL;
|
|
|
|
From eebe559cf4fc3bfbf6f562f7fb2d78c5903d4d64 Mon Sep 17 00:00:00 2001
|
|
From: Vandana BN <bnvandana@gmail.com>
|
|
Date: Tue, 22 Oct 2019 04:51:40 -0300
|
|
Subject: [PATCH] media: v4l2-core: fix touch support in v4l_g_fmt
|
|
|
|
v4l_s_fmt, for VFL_TYPE_TOUCH, sets unneeded members of
|
|
the v4l2_pix_format structure to default values.This was
|
|
missing in v4l_g_fmt, which would lead to failures in
|
|
v4l2-compliance tests.
|
|
|
|
Signed-off-by: Vandana BN <bnvandana@gmail.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 545b618cfb5cadacd00c25066b9a36540e5ca9e9)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 33 ++++++++++++++++++---------------
|
|
1 file changed, 18 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index d26c83d4c255..315ac12c3e0a 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -1478,10 +1478,26 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
|
|
return ret;
|
|
}
|
|
|
|
+static void v4l_pix_format_touch(struct v4l2_pix_format *p)
|
|
+{
|
|
+ /*
|
|
+ * The v4l2_pix_format structure contains fields that make no sense for
|
|
+ * touch. Set them to default values in this case.
|
|
+ */
|
|
+
|
|
+ p->field = V4L2_FIELD_NONE;
|
|
+ p->colorspace = V4L2_COLORSPACE_RAW;
|
|
+ p->flags = 0;
|
|
+ p->ycbcr_enc = 0;
|
|
+ p->quantization = 0;
|
|
+ p->xfer_func = 0;
|
|
+}
|
|
+
|
|
static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
|
|
struct file *file, void *fh, void *arg)
|
|
{
|
|
struct v4l2_format *p = arg;
|
|
+ struct video_device *vfd = video_devdata(file);
|
|
int ret = check_fmt(file, p->type);
|
|
|
|
if (ret)
|
|
@@ -1519,6 +1535,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
|
|
ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
|
|
/* just in case the driver zeroed it again */
|
|
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
|
|
+ if (vfd->vfl_type == VFL_TYPE_TOUCH)
|
|
+ v4l_pix_format_touch(&p->fmt.pix);
|
|
return ret;
|
|
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
|
|
return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
|
|
@@ -1556,21 +1574,6 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
|
|
return -EINVAL;
|
|
}
|
|
|
|
-static void v4l_pix_format_touch(struct v4l2_pix_format *p)
|
|
-{
|
|
- /*
|
|
- * The v4l2_pix_format structure contains fields that make no sense for
|
|
- * touch. Set them to default values in this case.
|
|
- */
|
|
-
|
|
- p->field = V4L2_FIELD_NONE;
|
|
- p->colorspace = V4L2_COLORSPACE_RAW;
|
|
- p->flags = 0;
|
|
- p->ycbcr_enc = 0;
|
|
- p->quantization = 0;
|
|
- p->xfer_func = 0;
|
|
-}
|
|
-
|
|
static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
|
|
struct file *file, void *fh, void *arg)
|
|
{
|
|
|
|
From a2aafcb26e867be0d8c02cb86996bf89107e7b1d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=
|
|
<nfraprado@protonmail.com>
|
|
Date: Wed, 30 Oct 2019 09:30:40 -0300
|
|
Subject: [PATCH] media: vimc: Make capture devices and subdevices use
|
|
different link_validates
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Instead of validating the links to capture devices and subdevices with
|
|
the same function, use the default v4l function for links between
|
|
subdevices and only use a different function for validating between
|
|
capture device and subdevice.
|
|
This change should also ease future work to associate multiple mbus
|
|
codes for the same pixelformat in vimc_pix_map.
|
|
|
|
These changes were tested with
|
|
v4l2-compliance SHA: 3f806630e2ecbcebe31872b865c5c4b42f111a99, 64 bits
|
|
and passed all tests:
|
|
Grand Total for vimc device /dev/media0: 451, Succeeded: 451, Failed: 0, Warnings: 0
|
|
|
|
Signed-off-by: Nícolas F. R. A. Prado <nfraprado@protonmail.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 31172e520b688524acaac61de1f1f9fc89665ee7)
|
|
---
|
|
drivers/media/platform/vimc/vimc-capture.c | 2 +-
|
|
drivers/media/platform/vimc/vimc-common.c | 85 +++++++++++++++---------------
|
|
drivers/media/platform/vimc/vimc-common.h | 4 +-
|
|
3 files changed, 46 insertions(+), 45 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
|
|
index a5d79fb25dff..76c015898cfd 100644
|
|
--- a/drivers/media/platform/vimc/vimc-capture.c
|
|
+++ b/drivers/media/platform/vimc/vimc-capture.c
|
|
@@ -322,7 +322,7 @@ static const struct vb2_ops vimc_cap_qops = {
|
|
};
|
|
|
|
static const struct media_entity_operations vimc_cap_mops = {
|
|
- .link_validate = vimc_link_validate,
|
|
+ .link_validate = vimc_vdev_link_validate,
|
|
};
|
|
|
|
static void vimc_cap_release(struct video_device *vdev)
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 2a0c40e9ae88..43e6fa5886da 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -194,35 +194,36 @@ const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
|
|
return NULL;
|
|
}
|
|
|
|
-static int vimc_get_mbus_format(struct media_pad *pad,
|
|
- struct v4l2_subdev_format *fmt)
|
|
+static int vimc_get_pix_format(struct media_pad *pad,
|
|
+ struct v4l2_pix_format *fmt)
|
|
{
|
|
if (is_media_entity_v4l2_subdev(pad->entity)) {
|
|
struct v4l2_subdev *sd =
|
|
media_entity_to_v4l2_subdev(pad->entity);
|
|
+ struct v4l2_subdev_format sd_fmt;
|
|
+ const struct vimc_pix_map *pix_map;
|
|
int ret;
|
|
|
|
- fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
|
- fmt->pad = pad->index;
|
|
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
|
+ sd_fmt.pad = pad->index;
|
|
|
|
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
|
|
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ v4l2_fill_pix_format(fmt, &sd_fmt.format);
|
|
+ pix_map = vimc_pix_map_by_code(sd_fmt.format.code);
|
|
+ fmt->pixelformat = pix_map->pixelformat;
|
|
} else if (is_media_entity_v4l2_video_device(pad->entity)) {
|
|
struct video_device *vdev = container_of(pad->entity,
|
|
struct video_device,
|
|
entity);
|
|
struct vimc_ent_device *ved = video_get_drvdata(vdev);
|
|
- const struct vimc_pix_map *vpix;
|
|
- struct v4l2_pix_format vdev_fmt;
|
|
|
|
if (!ved->vdev_get_format)
|
|
return -ENOIOCTLCMD;
|
|
|
|
- ved->vdev_get_format(ved, &vdev_fmt);
|
|
- vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
|
|
- v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
|
|
+ ved->vdev_get_format(ved, fmt);
|
|
} else {
|
|
return -EINVAL;
|
|
}
|
|
@@ -230,16 +231,16 @@ static int vimc_get_mbus_format(struct media_pad *pad,
|
|
return 0;
|
|
}
|
|
|
|
-int vimc_link_validate(struct media_link *link)
|
|
+int vimc_vdev_link_validate(struct media_link *link)
|
|
{
|
|
- struct v4l2_subdev_format source_fmt, sink_fmt;
|
|
+ struct v4l2_pix_format source_fmt, sink_fmt;
|
|
int ret;
|
|
|
|
- ret = vimc_get_mbus_format(link->source, &source_fmt);
|
|
+ ret = vimc_get_pix_format(link->source, &source_fmt);
|
|
if (ret)
|
|
return ret;
|
|
|
|
- ret = vimc_get_mbus_format(link->sink, &sink_fmt);
|
|
+ ret = vimc_get_pix_format(link->sink, &sink_fmt);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -248,21 +249,21 @@ int vimc_link_validate(struct media_link *link)
|
|
"%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
|
|
/* src */
|
|
link->source->entity->name,
|
|
- source_fmt.format.width, source_fmt.format.height,
|
|
- source_fmt.format.code, source_fmt.format.colorspace,
|
|
- source_fmt.format.quantization, source_fmt.format.xfer_func,
|
|
- source_fmt.format.ycbcr_enc,
|
|
+ source_fmt.width, source_fmt.height,
|
|
+ source_fmt.pixelformat, source_fmt.colorspace,
|
|
+ source_fmt.quantization, source_fmt.xfer_func,
|
|
+ source_fmt.ycbcr_enc,
|
|
/* sink */
|
|
link->sink->entity->name,
|
|
- sink_fmt.format.width, sink_fmt.format.height,
|
|
- sink_fmt.format.code, sink_fmt.format.colorspace,
|
|
- sink_fmt.format.quantization, sink_fmt.format.xfer_func,
|
|
- sink_fmt.format.ycbcr_enc);
|
|
-
|
|
- /* The width, height and code must match. */
|
|
- if (source_fmt.format.width != sink_fmt.format.width
|
|
- || source_fmt.format.height != sink_fmt.format.height
|
|
- || source_fmt.format.code != sink_fmt.format.code)
|
|
+ sink_fmt.width, sink_fmt.height,
|
|
+ sink_fmt.pixelformat, sink_fmt.colorspace,
|
|
+ sink_fmt.quantization, sink_fmt.xfer_func,
|
|
+ sink_fmt.ycbcr_enc);
|
|
+
|
|
+ /* The width, height and pixelformat must match. */
|
|
+ if (source_fmt.width != sink_fmt.width ||
|
|
+ source_fmt.height != sink_fmt.height ||
|
|
+ source_fmt.pixelformat != sink_fmt.pixelformat)
|
|
return -EPIPE;
|
|
|
|
/*
|
|
@@ -270,43 +271,43 @@ int vimc_link_validate(struct media_link *link)
|
|
* to support interlaced hardware connected to bridges that support
|
|
* progressive formats only.
|
|
*/
|
|
- if (source_fmt.format.field != sink_fmt.format.field &&
|
|
- sink_fmt.format.field != V4L2_FIELD_NONE)
|
|
+ if (source_fmt.field != sink_fmt.field &&
|
|
+ sink_fmt.field != V4L2_FIELD_NONE)
|
|
return -EPIPE;
|
|
|
|
/*
|
|
* If colorspace is DEFAULT, then assume all the colorimetry is also
|
|
* DEFAULT, return 0 to skip comparing the other colorimetry parameters
|
|
*/
|
|
- if (source_fmt.format.colorspace == V4L2_COLORSPACE_DEFAULT
|
|
- || sink_fmt.format.colorspace == V4L2_COLORSPACE_DEFAULT)
|
|
+ if (source_fmt.colorspace == V4L2_COLORSPACE_DEFAULT ||
|
|
+ sink_fmt.colorspace == V4L2_COLORSPACE_DEFAULT)
|
|
return 0;
|
|
|
|
/* Colorspace must match. */
|
|
- if (source_fmt.format.colorspace != sink_fmt.format.colorspace)
|
|
+ if (source_fmt.colorspace != sink_fmt.colorspace)
|
|
return -EPIPE;
|
|
|
|
/* Colorimetry must match if they are not set to DEFAULT */
|
|
- if (source_fmt.format.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT
|
|
- && sink_fmt.format.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT
|
|
- && source_fmt.format.ycbcr_enc != sink_fmt.format.ycbcr_enc)
|
|
+ if (source_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
|
|
+ sink_fmt.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT &&
|
|
+ source_fmt.ycbcr_enc != sink_fmt.ycbcr_enc)
|
|
return -EPIPE;
|
|
|
|
- if (source_fmt.format.quantization != V4L2_QUANTIZATION_DEFAULT
|
|
- && sink_fmt.format.quantization != V4L2_QUANTIZATION_DEFAULT
|
|
- && source_fmt.format.quantization != sink_fmt.format.quantization)
|
|
+ if (source_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
|
|
+ sink_fmt.quantization != V4L2_QUANTIZATION_DEFAULT &&
|
|
+ source_fmt.quantization != sink_fmt.quantization)
|
|
return -EPIPE;
|
|
|
|
- if (source_fmt.format.xfer_func != V4L2_XFER_FUNC_DEFAULT
|
|
- && sink_fmt.format.xfer_func != V4L2_XFER_FUNC_DEFAULT
|
|
- && source_fmt.format.xfer_func != sink_fmt.format.xfer_func)
|
|
+ if (source_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
|
|
+ sink_fmt.xfer_func != V4L2_XFER_FUNC_DEFAULT &&
|
|
+ source_fmt.xfer_func != sink_fmt.xfer_func)
|
|
return -EPIPE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct media_entity_operations vimc_ent_sd_mops = {
|
|
- .link_validate = vimc_link_validate,
|
|
+ .link_validate = v4l2_subdev_link_validate,
|
|
};
|
|
|
|
int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index c75401a36312..bf729fcde6a9 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -206,12 +206,12 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
|
|
const struct v4l2_subdev_ops *sd_ops);
|
|
|
|
/**
|
|
- * vimc_link_validate - validates a media link
|
|
+ * vimc_vdev_link_validate - validates a media link
|
|
*
|
|
* @link: pointer to &struct media_link
|
|
*
|
|
* This function calls validates if a media link is valid for streaming.
|
|
*/
|
|
-int vimc_link_validate(struct media_link *link);
|
|
+int vimc_vdev_link_validate(struct media_link *link);
|
|
|
|
#endif
|
|
|
|
From 859e7f78eac0c673786b229e49019db55006e8ac Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sat, 2 Nov 2019 14:35:41 -0300
|
|
Subject: [PATCH] media: vivid: media_device_cleanup was called too early
|
|
|
|
Running the contrib/test/test-media script in v4l-utils with the vivid argument
|
|
will cause this kernel warning:
|
|
|
|
[ 104.748720] videodev: v4l2_release
|
|
[ 104.748731] ------------[ cut here ]------------
|
|
[ 104.748750] DEBUG_LOCKS_WARN_ON(lock->magic != lock)
|
|
[ 104.748790] WARNING: CPU: 6 PID: 1823 at kernel/locking/mutex.c:938 __mutex_lock+0x919/0xc10
|
|
[ 104.748800] Modules linked in: rc_cec vivid v4l2_tpg videobuf2_dma_contig cec rc_core v4l2_dv_timings videobuf2_vmalloc videobuf2_memops
|
|
videobuf2_v4l2 videobuf2_common videodev mc vmw_balloon vmw_vmci button vmwgfx
|
|
[ 104.748845] CPU: 6 PID: 1823 Comm: sleep Not tainted 5.4.0-rc1-test-no #150
|
|
[ 104.748853] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
|
|
[ 104.748867] RIP: 0010:__mutex_lock+0x919/0xc10
|
|
[ 104.748878] Code: 59 83 e8 9a fc 16 ff 44 8b 05 23 61 38 01 45 85 c0 0f 85 ef f7 ff ff 48 c7 c6 a0 1f 87 82 48 c7 c7 a0 1e 87 82 e8 cd bb
|
|
f7 fe <0f> 0b e9 d5 f7 ff ff f6 c3 04 0f 84 3b fd ff ff 49 89 df 41 83 e7
|
|
[ 104.748886] RSP: 0018:ffff88811a357b80 EFLAGS: 00010286
|
|
[ 104.748895] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
|
|
[ 104.748902] RDX: 0000000000000003 RSI: 0000000000000004 RDI: ffffed102346af62
|
|
[ 104.748910] RBP: ffff88811a357cf0 R08: ffffffff81217c91 R09: fffffbfff061c271
|
|
[ 104.748917] R10: fffffbfff061c270 R11: ffffffff830e1383 R12: ffff8881a46103c0
|
|
[ 104.748924] R13: 0000000000000000 R14: ffff8881a4614f90 R15: ffff8881a46153d0
|
|
[ 104.748933] FS: 0000000000000000(0000) GS:ffff8881b6780000(0000) knlGS:0000000000000000
|
|
[ 104.748940] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
[ 104.748949] CR2: 00007f163fc9ca20 CR3: 0000000003013004 CR4: 00000000001606e0
|
|
[ 104.749036] Call Trace:
|
|
[ 104.749051] ? _raw_spin_unlock+0x1f/0x30
|
|
[ 104.749067] ? llist_add_batch+0x33/0x50
|
|
[ 104.749081] ? tick_nohz_tick_stopped+0x19/0x30
|
|
[ 104.749130] ? v4l2_release.cold+0x6c/0xd6 [videodev]
|
|
[ 104.749143] ? mutex_lock_io_nested+0xb80/0xb80
|
|
[ 104.749153] ? vprintk_emit+0xf2/0x220
|
|
[ 104.749191] ? vivid_req_validate+0x40/0x40 [vivid]
|
|
[ 104.749201] ? printk+0xad/0xde
|
|
[ 104.749211] ? kmsg_dump_rewind_nolock+0x54/0x54
|
|
[ 104.749226] ? locks_remove_file+0x78/0x2b0
|
|
[ 104.749248] ? __fsnotify_update_child_dentry_flags.part.0+0x170/0x170
|
|
[ 104.749281] ? vivid_req_validate+0x40/0x40 [vivid]
|
|
[ 104.749321] ? v4l2_release.cold+0x6c/0xd6 [videodev]
|
|
[ 104.749361] v4l2_release.cold+0x6c/0xd6 [videodev]
|
|
[ 104.749378] __fput+0x15a/0x390
|
|
[ 104.749393] task_work_run+0xb2/0xe0
|
|
[ 104.749407] do_exit+0x4d0/0x1200
|
|
[ 104.749422] ? do_user_addr_fault+0x367/0x610
|
|
[ 104.749431] ? release_task+0x990/0x990
|
|
[ 104.749449] ? rwsem_spin_on_owner+0x170/0x170
|
|
[ 104.749463] ? vmacache_find+0xb2/0x100
|
|
[ 104.749476] do_group_exit+0x85/0x130
|
|
[ 104.749487] __x64_sys_exit_group+0x23/0x30
|
|
[ 104.749500] do_syscall_64+0x5e/0x1c0
|
|
[ 104.749511] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
|
[ 104.749520] RIP: 0033:0x7f163fc5c9d6
|
|
[ 104.749536] Code: Bad RIP value.
|
|
[ 104.749543] RSP: 002b:00007ffe6f3bec58 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
|
|
[ 104.749553] RAX: ffffffffffffffda RBX: 00007f163fd4d760 RCX: 00007f163fc5c9d6
|
|
[ 104.749560] RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
|
|
[ 104.749567] RBP: 0000000000000000 R08: 00000000000000e7 R09: ffffffffffffff80
|
|
[ 104.749574] R10: 00007ffe6f3beb24 R11: 0000000000000246 R12: 00007f163fd4d760
|
|
[ 104.749581] R13: 0000000000000002 R14: 00007f163fd56428 R15: 0000000000000000
|
|
[ 104.749597] ---[ end trace 66f20f73fc0daf79 ]---
|
|
|
|
This is caused by media_device_cleanup() which destroys
|
|
v4l2_dev->mdev->req_queue_mutex. But v4l2_release() tries to lock
|
|
that mutex after media_device_cleanup() is called.
|
|
|
|
By moving media_device_cleanup() to the v4l2_device's release function it is
|
|
guaranteed that the mutex is valid whenever v4l2_release is called.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 8ffd573c25e5fac1daeeffc592e2ed6bc6a3d947)
|
|
---
|
|
drivers/media/platform/vivid/vivid-core.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
|
|
index dadfc59c92c5..b204c636dba6 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.c
|
|
+++ b/drivers/media/platform/vivid/vivid-core.c
|
|
@@ -648,6 +648,9 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev)
|
|
|
|
vivid_free_controls(dev);
|
|
v4l2_device_unregister(&dev->v4l2_dev);
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
+ media_device_cleanup(&dev->mdev);
|
|
+#endif
|
|
vfree(dev->scaled_line);
|
|
vfree(dev->blended_line);
|
|
vfree(dev->edid);
|
|
@@ -1755,7 +1758,6 @@ static int vivid_remove(struct platform_device *pdev)
|
|
|
|
#ifdef CONFIG_MEDIA_CONTROLLER
|
|
media_device_unregister(&dev->mdev);
|
|
- media_device_cleanup(&dev->mdev);
|
|
#endif
|
|
|
|
if (dev->has_vid_cap) {
|
|
|
|
From c72ded8a4b7c12c5743f1ace3f651e42f2bb88f7 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sun, 3 Nov 2019 15:01:42 +0100
|
|
Subject: [PATCH] media: vivid: add vivid_create_queue() helper
|
|
|
|
Refactor some of the vivid_create_instance code by using a
|
|
new vivid_create_queue() helper function.
|
|
|
|
Also add some sanity checks for the node_types vs input/output_types
|
|
module options.
|
|
|
|
This patch resolves these two smatch parse errors:
|
|
|
|
drivers/media/platform/vivid/vivid-core.c:1679 vivid_create_instance() parse error: OOM: 3002600Kb sm_state_count = 6160113
|
|
drivers/media/platform/vivid/vivid-core.c: drivers/media/platform/vivid/vivid-core.c:1679
|
|
vivid_create_instance() parse error: __split_smt: function too hairy. Giving up after 33 seconds
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 0c90f649d2f5b9c6c585cab293a4e40172ddaa73)
|
|
---
|
|
drivers/media/platform/vivid/vivid-cec.c | 7 +-
|
|
drivers/media/platform/vivid/vivid-core.c | 257 +++++++++++++-----------------
|
|
drivers/media/platform/vivid/vivid-core.h | 1 +
|
|
3 files changed, 116 insertions(+), 149 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vivid/vivid-cec.c b/drivers/media/platform/vivid/vivid-cec.c
|
|
index 4d822dbed972..4d2413e87730 100644
|
|
--- a/drivers/media/platform/vivid/vivid-cec.c
|
|
+++ b/drivers/media/platform/vivid/vivid-cec.c
|
|
@@ -276,12 +276,11 @@ struct cec_adapter *vivid_cec_alloc_adap(struct vivid_dev *dev,
|
|
unsigned int idx,
|
|
bool is_source)
|
|
{
|
|
- char name[sizeof(dev->vid_out_dev.name) + 2];
|
|
u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
|
|
+ char name[32];
|
|
|
|
- snprintf(name, sizeof(name), "%s%d",
|
|
- is_source ? dev->vid_out_dev.name : dev->vid_cap_dev.name,
|
|
- idx);
|
|
+ snprintf(name, sizeof(name), "vivid-%03d-vid-%s%d",
|
|
+ dev->inst, is_source ? "out" : "cap", idx);
|
|
return cec_allocate_adapter(&vivid_cec_adap_ops, dev,
|
|
name, caps, 1);
|
|
}
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
|
|
index b204c636dba6..c184f9b0be69 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.c
|
|
+++ b/drivers/media/platform/vivid/vivid-core.c
|
|
@@ -680,14 +680,44 @@ static const struct media_device_ops vivid_media_ops = {
|
|
};
|
|
#endif
|
|
|
|
+static int vivid_create_queue(struct vivid_dev *dev,
|
|
+ struct vb2_queue *q,
|
|
+ u32 buf_type,
|
|
+ unsigned int min_buffers_needed,
|
|
+ const struct vb2_ops *ops)
|
|
+{
|
|
+ if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->multiplanar)
|
|
+ buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
|
|
+ else if (buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT && dev->multiplanar)
|
|
+ buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
|
|
+ else if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE && !dev->has_raw_vbi_cap)
|
|
+ buf_type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
|
+ else if (buf_type == V4L2_BUF_TYPE_VBI_OUTPUT && !dev->has_raw_vbi_out)
|
|
+ buf_type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
|
|
+
|
|
+ q->type = buf_type;
|
|
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
|
|
+ q->io_modes |= V4L2_TYPE_IS_OUTPUT(buf_type) ? VB2_WRITE : VB2_READ;
|
|
+ if (allocators[dev->inst] != 1)
|
|
+ q->io_modes |= VB2_USERPTR;
|
|
+ q->drv_priv = dev;
|
|
+ q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
+ q->ops = ops;
|
|
+ q->mem_ops = allocators[dev->inst] == 1 ? &vb2_dma_contig_memops :
|
|
+ &vb2_vmalloc_memops;
|
|
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
+ q->min_buffers_needed = min_buffers_needed;
|
|
+ q->lock = &dev->mutex;
|
|
+ q->dev = dev->v4l2_dev.dev;
|
|
+ q->supports_requests = true;
|
|
+
|
|
+ return vb2_queue_init(q);
|
|
+}
|
|
+
|
|
static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
{
|
|
static const struct v4l2_dv_timings def_dv_timings =
|
|
V4L2_DV_BT_CEA_1280X720P60;
|
|
- static const struct vb2_mem_ops * const vivid_mem_ops[2] = {
|
|
- &vb2_vmalloc_memops,
|
|
- &vb2_dma_contig_memops,
|
|
- };
|
|
unsigned in_type_counter[4] = { 0, 0, 0, 0 };
|
|
unsigned out_type_counter[4] = { 0, 0, 0, 0 };
|
|
int ccs_cap = ccs_cap_mode[inst];
|
|
@@ -696,9 +726,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
bool has_modulator;
|
|
struct vivid_dev *dev;
|
|
struct video_device *vfd;
|
|
- struct vb2_queue *q;
|
|
unsigned node_type = node_types[inst];
|
|
- unsigned int allocator = allocators[inst];
|
|
v4l2_std_id tvnorms_cap = 0, tvnorms_out = 0;
|
|
int ret;
|
|
int i;
|
|
@@ -793,6 +821,25 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->has_vbi_cap = dev->has_raw_vbi_cap | dev->has_sliced_vbi_cap;
|
|
}
|
|
|
|
+ /* do we create a meta capture device */
|
|
+ dev->has_meta_cap = node_type & 0x20000;
|
|
+
|
|
+ /* sanity checks */
|
|
+ if ((in_type_counter[WEBCAM] || in_type_counter[HDMI]) &&
|
|
+ !dev->has_vid_cap && !dev->has_meta_cap) {
|
|
+ v4l2_warn(&dev->v4l2_dev,
|
|
+ "Webcam or HDMI input without video or metadata nodes\n");
|
|
+ kfree(dev);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if ((in_type_counter[TV] || in_type_counter[SVID]) &&
|
|
+ !dev->has_vid_cap && !dev->has_vbi_cap && !dev->has_meta_cap) {
|
|
+ v4l2_warn(&dev->v4l2_dev,
|
|
+ "TV or S-Video input without video, VBI or metadata nodes\n");
|
|
+ kfree(dev);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
/* do we create a video output device? */
|
|
dev->has_vid_out = node_type & 0x0100;
|
|
|
|
@@ -803,6 +850,24 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->has_vbi_out = dev->has_raw_vbi_out | dev->has_sliced_vbi_out;
|
|
}
|
|
|
|
+ /* do we create a metadata output device */
|
|
+ dev->has_meta_out = node_type & 0x40000;
|
|
+
|
|
+ /* sanity checks */
|
|
+ if (out_type_counter[SVID] &&
|
|
+ !dev->has_vid_out && !dev->has_vbi_out && !dev->has_meta_out) {
|
|
+ v4l2_warn(&dev->v4l2_dev,
|
|
+ "S-Video output without video, VBI or metadata nodes\n");
|
|
+ kfree(dev);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+ if (out_type_counter[HDMI] && !dev->has_vid_out && !dev->has_meta_out) {
|
|
+ v4l2_warn(&dev->v4l2_dev,
|
|
+ "HDMI output without video or metadata nodes\n");
|
|
+ kfree(dev);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
/* do we create a radio receiver device? */
|
|
dev->has_radio_rx = node_type & 0x0010;
|
|
|
|
@@ -812,6 +877,9 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
/* do we create a software defined radio capture device? */
|
|
dev->has_sdr_cap = node_type & 0x0020;
|
|
|
|
+ /* do we have a TV tuner? */
|
|
+ dev->has_tv_tuner = in_type_counter[TV];
|
|
+
|
|
/* do we have a tuner? */
|
|
has_tuner = ((dev->has_vid_cap || dev->has_vbi_cap) && in_type_counter[TV]) ||
|
|
dev->has_radio_rx || dev->has_sdr_cap;
|
|
@@ -853,12 +921,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->has_scaler_out ? 'Y' : 'N');
|
|
}
|
|
|
|
- /* do we create a meta capture device */
|
|
- dev->has_meta_cap = node_type & 0x20000;
|
|
-
|
|
- /* do we create a metadata output device */
|
|
- dev->has_meta_out = node_type & 0x40000;
|
|
-
|
|
/* end detecting feature set */
|
|
|
|
if (dev->has_vid_cap) {
|
|
@@ -869,7 +931,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->vid_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
|
if (dev->has_audio_inputs)
|
|
dev->vid_cap_caps |= V4L2_CAP_AUDIO;
|
|
- if (in_type_counter[TV])
|
|
+ if (dev->has_tv_tuner)
|
|
dev->vid_cap_caps |= V4L2_CAP_TUNER;
|
|
}
|
|
if (dev->has_vid_out) {
|
|
@@ -890,7 +952,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
dev->vbi_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
|
if (dev->has_audio_inputs)
|
|
dev->vbi_cap_caps |= V4L2_CAP_AUDIO;
|
|
- if (in_type_counter[TV])
|
|
+ if (dev->has_tv_tuner)
|
|
dev->vbi_cap_caps |= V4L2_CAP_TUNER;
|
|
}
|
|
if (dev->has_vbi_out) {
|
|
@@ -922,7 +984,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
|
|
if (dev->has_audio_inputs)
|
|
dev->meta_cap_caps |= V4L2_CAP_AUDIO;
|
|
- if (in_type_counter[TV])
|
|
+ if (dev->has_tv_tuner)
|
|
dev->meta_cap_caps |= V4L2_CAP_TUNER;
|
|
}
|
|
/* set up the capabilities of meta output device */
|
|
@@ -1165,181 +1227,82 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
- if (allocator == 1)
|
|
+ if (allocators[inst] == 1)
|
|
dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
|
- else if (allocator >= ARRAY_SIZE(vivid_mem_ops))
|
|
- allocator = 0;
|
|
|
|
/* start creating the vb2 queues */
|
|
if (dev->has_vid_cap) {
|
|
- snprintf(dev->vid_cap_dev.name, sizeof(dev->vid_cap_dev.name),
|
|
- "vivid-%03d-vid-cap", inst);
|
|
/* initialize vid_cap queue */
|
|
- q = &dev->vb_vid_cap_q;
|
|
- q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
|
|
- V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_vid_cap_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 2;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
-
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_vid_cap_q,
|
|
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, 2,
|
|
+ &vivid_vid_cap_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
if (dev->has_vid_out) {
|
|
- snprintf(dev->vid_out_dev.name, sizeof(dev->vid_out_dev.name),
|
|
- "vivid-%03d-vid-out", inst);
|
|
/* initialize vid_out queue */
|
|
- q = &dev->vb_vid_out_q;
|
|
- q->type = dev->multiplanar ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
|
|
- V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_vid_out_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 2;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
-
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_vid_out_q,
|
|
+ V4L2_BUF_TYPE_VIDEO_OUTPUT, 2,
|
|
+ &vivid_vid_out_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
if (dev->has_vbi_cap) {
|
|
/* initialize vbi_cap queue */
|
|
- q = &dev->vb_vbi_cap_q;
|
|
- q->type = dev->has_raw_vbi_cap ? V4L2_BUF_TYPE_VBI_CAPTURE :
|
|
- V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_vbi_cap_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 2;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
-
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_vbi_cap_q,
|
|
+ V4L2_BUF_TYPE_VBI_CAPTURE, 2,
|
|
+ &vivid_vbi_cap_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
if (dev->has_vbi_out) {
|
|
/* initialize vbi_out queue */
|
|
- q = &dev->vb_vbi_out_q;
|
|
- q->type = dev->has_raw_vbi_out ? V4L2_BUF_TYPE_VBI_OUTPUT :
|
|
- V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_vbi_out_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 2;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
-
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_vbi_out_q,
|
|
+ V4L2_BUF_TYPE_VBI_OUTPUT, 2,
|
|
+ &vivid_vbi_out_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
if (dev->has_sdr_cap) {
|
|
/* initialize sdr_cap queue */
|
|
- q = &dev->vb_sdr_cap_q;
|
|
- q->type = V4L2_BUF_TYPE_SDR_CAPTURE;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_sdr_cap_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 8;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
-
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_sdr_cap_q,
|
|
+ V4L2_BUF_TYPE_SDR_CAPTURE, 8,
|
|
+ &vivid_sdr_cap_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
- if (dev->has_fb) {
|
|
- /* Create framebuffer for testing capture/output overlay */
|
|
- ret = vivid_fb_init(dev);
|
|
- if (ret)
|
|
- goto unreg_dev;
|
|
- v4l2_info(&dev->v4l2_dev, "Framebuffer device registered as fb%d\n",
|
|
- dev->fb_info.node);
|
|
- }
|
|
-
|
|
if (dev->has_meta_cap) {
|
|
/* initialize meta_cap queue */
|
|
- q = &dev->vb_meta_cap_q;
|
|
- q->type = V4L2_BUF_TYPE_META_CAPTURE;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_meta_cap_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 2;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_meta_cap_q,
|
|
+ V4L2_BUF_TYPE_META_CAPTURE, 2,
|
|
+ &vivid_meta_cap_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
if (dev->has_meta_out) {
|
|
/* initialize meta_out queue */
|
|
- q = &dev->vb_meta_out_q;
|
|
- q->type = V4L2_BUF_TYPE_META_OUTPUT;
|
|
- q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_WRITE;
|
|
- if (!allocator)
|
|
- q->io_modes |= VB2_USERPTR;
|
|
- q->drv_priv = dev;
|
|
- q->buf_struct_size = sizeof(struct vivid_buffer);
|
|
- q->ops = &vivid_meta_out_qops;
|
|
- q->mem_ops = vivid_mem_ops[allocator];
|
|
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
|
- q->min_buffers_needed = 1;
|
|
- q->lock = &dev->mutex;
|
|
- q->dev = dev->v4l2_dev.dev;
|
|
- q->supports_requests = true;
|
|
- ret = vb2_queue_init(q);
|
|
+ ret = vivid_create_queue(dev, &dev->vb_meta_out_q,
|
|
+ V4L2_BUF_TYPE_META_OUTPUT, 1,
|
|
+ &vivid_meta_out_qops);
|
|
if (ret)
|
|
goto unreg_dev;
|
|
}
|
|
|
|
+ if (dev->has_fb) {
|
|
+ /* Create framebuffer for testing capture/output overlay */
|
|
+ ret = vivid_fb_init(dev);
|
|
+ if (ret)
|
|
+ goto unreg_dev;
|
|
+ v4l2_info(&dev->v4l2_dev, "Framebuffer device registered as fb%d\n",
|
|
+ dev->fb_info.node);
|
|
+ }
|
|
+
|
|
#ifdef CONFIG_VIDEO_VIVID_CEC
|
|
if (dev->has_vid_cap && in_type_counter[HDMI]) {
|
|
struct cec_adapter *adap;
|
|
@@ -1386,6 +1349,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
/* finally start creating the device nodes */
|
|
if (dev->has_vid_cap) {
|
|
vfd = &dev->vid_cap_dev;
|
|
+ snprintf(vfd->name, sizeof(vfd->name),
|
|
+ "vivid-%03d-vid-cap", inst);
|
|
vfd->fops = &vivid_fops;
|
|
vfd->ioctl_ops = &vivid_ioctl_ops;
|
|
vfd->device_caps = dev->vid_cap_caps;
|
|
@@ -1431,6 +1396,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
|
|
|
|
if (dev->has_vid_out) {
|
|
vfd = &dev->vid_out_dev;
|
|
+ snprintf(vfd->name, sizeof(vfd->name),
|
|
+ "vivid-%03d-vid-out", inst);
|
|
vfd->vfl_dir = VFL_DIR_TX;
|
|
vfd->fops = &vivid_fops;
|
|
vfd->ioctl_ops = &vivid_ioctl_ops;
|
|
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
|
|
index d57066ed31f0..59192b67231c 100644
|
|
--- a/drivers/media/platform/vivid/vivid-core.h
|
|
+++ b/drivers/media/platform/vivid/vivid-core.h
|
|
@@ -200,6 +200,7 @@ struct vivid_dev {
|
|
bool has_fb;
|
|
bool has_meta_cap;
|
|
bool has_meta_out;
|
|
+ bool has_tv_tuner;
|
|
|
|
bool can_loop_video;
|
|
|
|
|
|
From 993f6e56dd4cda73394308756ef5366e51dc2625 Mon Sep 17 00:00:00 2001
|
|
From: Alexander Popov <alex.popov@linux.com>
|
|
Date: Sun, 3 Nov 2019 23:17:19 +0100
|
|
Subject: [PATCH] media: vivid: Fix wrong locking that causes race conditions
|
|
on streaming stop
|
|
|
|
There is the same incorrect approach to locking implemented in
|
|
vivid_stop_generating_vid_cap(), vivid_stop_generating_vid_out() and
|
|
sdr_cap_stop_streaming().
|
|
|
|
These functions are called during streaming stopping with vivid_dev.mutex
|
|
locked. And they all do the same mistake while stopping their kthreads,
|
|
which need to lock this mutex as well. See the example from
|
|
vivid_stop_generating_vid_cap():
|
|
/* shutdown control thread */
|
|
vivid_grab_controls(dev, false);
|
|
mutex_unlock(&dev->mutex);
|
|
kthread_stop(dev->kthread_vid_cap);
|
|
dev->kthread_vid_cap = NULL;
|
|
mutex_lock(&dev->mutex);
|
|
|
|
But when this mutex is unlocked, another vb2_fop_read() can lock it
|
|
instead of vivid_thread_vid_cap() and manipulate the buffer queue.
|
|
That causes a use-after-free access later.
|
|
|
|
To fix those issues let's:
|
|
1. avoid unlocking the mutex in vivid_stop_generating_vid_cap(),
|
|
vivid_stop_generating_vid_out() and sdr_cap_stop_streaming();
|
|
2. use mutex_trylock() with schedule_timeout_uninterruptible() in
|
|
the loops of the vivid kthread handlers.
|
|
|
|
Signed-off-by: Alexander Popov <alex.popov@linux.com>
|
|
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Cc: <stable@vger.kernel.org> # for v3.18 and up
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 6dcd5d7a7a29c1e4b8016a06aed78cd650cd8c27)
|
|
---
|
|
drivers/media/platform/vivid/vivid-kthread-cap.c | 8 +++++---
|
|
drivers/media/platform/vivid/vivid-kthread-out.c | 8 +++++---
|
|
drivers/media/platform/vivid/vivid-sdr-cap.c | 8 +++++---
|
|
3 files changed, 15 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
index 9f981e8bae6e..01a9d671b947 100644
|
|
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
|
|
@@ -818,7 +818,11 @@ static int vivid_thread_vid_cap(void *data)
|
|
if (kthread_should_stop())
|
|
break;
|
|
|
|
- mutex_lock(&dev->mutex);
|
|
+ if (!mutex_trylock(&dev->mutex)) {
|
|
+ schedule_timeout_uninterruptible(1);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
cur_jiffies = jiffies;
|
|
if (dev->cap_seq_resync) {
|
|
dev->jiffies_vid_cap = cur_jiffies;
|
|
@@ -998,8 +1002,6 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming)
|
|
|
|
/* shutdown control thread */
|
|
vivid_grab_controls(dev, false);
|
|
- mutex_unlock(&dev->mutex);
|
|
kthread_stop(dev->kthread_vid_cap);
|
|
dev->kthread_vid_cap = NULL;
|
|
- mutex_lock(&dev->mutex);
|
|
}
|
|
diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
index c974235d7de3..6780687978f9 100644
|
|
--- a/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
+++ b/drivers/media/platform/vivid/vivid-kthread-out.c
|
|
@@ -166,7 +166,11 @@ static int vivid_thread_vid_out(void *data)
|
|
if (kthread_should_stop())
|
|
break;
|
|
|
|
- mutex_lock(&dev->mutex);
|
|
+ if (!mutex_trylock(&dev->mutex)) {
|
|
+ schedule_timeout_uninterruptible(1);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
cur_jiffies = jiffies;
|
|
if (dev->out_seq_resync) {
|
|
dev->jiffies_vid_out = cur_jiffies;
|
|
@@ -344,8 +348,6 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming)
|
|
|
|
/* shutdown control thread */
|
|
vivid_grab_controls(dev, false);
|
|
- mutex_unlock(&dev->mutex);
|
|
kthread_stop(dev->kthread_vid_out);
|
|
dev->kthread_vid_out = NULL;
|
|
- mutex_lock(&dev->mutex);
|
|
}
|
|
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
|
|
index 9acc709b0740..2b7522e16efc 100644
|
|
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
|
|
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
|
|
@@ -141,7 +141,11 @@ static int vivid_thread_sdr_cap(void *data)
|
|
if (kthread_should_stop())
|
|
break;
|
|
|
|
- mutex_lock(&dev->mutex);
|
|
+ if (!mutex_trylock(&dev->mutex)) {
|
|
+ schedule_timeout_uninterruptible(1);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
cur_jiffies = jiffies;
|
|
if (dev->sdr_cap_seq_resync) {
|
|
dev->jiffies_sdr_cap = cur_jiffies;
|
|
@@ -303,10 +307,8 @@ static void sdr_cap_stop_streaming(struct vb2_queue *vq)
|
|
}
|
|
|
|
/* shutdown control thread */
|
|
- mutex_unlock(&dev->mutex);
|
|
kthread_stop(dev->kthread_sdr_cap);
|
|
dev->kthread_sdr_cap = NULL;
|
|
- mutex_lock(&dev->mutex);
|
|
}
|
|
|
|
static void sdr_cap_buf_request_complete(struct vb2_buffer *vb)
|
|
|
|
From c1d6ff706ab25b9c8c4d513e379c43546ba0ce4d Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:18 +0100
|
|
Subject: [PATCH] media: v4l2_ctrl: Add p_def to v4l2_ctrl_config
|
|
|
|
This allows setting the default value on compound controls created via
|
|
v4l2_ctrl_new_custom.
|
|
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 3b98a21a3202aeb9a47c0b57cab3d3ed420c1e05)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 2 +-
|
|
include/media/v4l2-ctrls.h | 2 ++
|
|
2 files changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index b4caf2d4d076..73d99c3561ce 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -2690,7 +2690,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
|
|
type, min, max,
|
|
is_menu ? cfg->menu_skip_mask : step, def,
|
|
cfg->dims, cfg->elem_size,
|
|
- flags, qmenu, qmenu_int, ptr_null, priv);
|
|
+ flags, qmenu, qmenu_int, cfg->p_def, priv);
|
|
if (ctrl)
|
|
ctrl->is_private = cfg->is_private;
|
|
return ctrl;
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index e719d56fc024..78a97b10c89e 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -382,6 +382,7 @@ struct v4l2_ctrl_handler {
|
|
* @max: The control's maximum value.
|
|
* @step: The control's step value for non-menu controls.
|
|
* @def: The control's default value.
|
|
+ * @p_def: The control's default value for compound controls.
|
|
* @dims: The size of each dimension.
|
|
* @elem_size: The size in bytes of the control.
|
|
* @flags: The control's flags.
|
|
@@ -410,6 +411,7 @@ struct v4l2_ctrl_config {
|
|
s64 max;
|
|
u64 step;
|
|
s64 def;
|
|
+ union v4l2_ctrl_ptr p_def;
|
|
u32 dims[V4L2_CTRL_MAX_DIMS];
|
|
u32 elem_size;
|
|
u32 flags;
|
|
|
|
From f751b367865b94428bcd9467bf23f876ed14006d Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:19 +0100
|
|
Subject: [PATCH] media: v4l2_ctrl: Add const pointer to ctrl_ptr
|
|
|
|
This pointer is used to point to data that is constant. Thanks to this
|
|
we can avoid a lot of casting and we make more clear when the data is
|
|
constant or variable.
|
|
|
|
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit f1bd5eae7de76ef8eabc9e393f5a8718d8f25d2a)
|
|
---
|
|
include/media/v4l2-ctrls.h | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
|
|
index 78a97b10c89e..7db9e719a583 100644
|
|
--- a/include/media/v4l2-ctrls.h
|
|
+++ b/include/media/v4l2-ctrls.h
|
|
@@ -56,6 +56,7 @@ struct poll_table_struct;
|
|
* @p_hevc_slice_params: Pointer to an HEVC slice parameters structure.
|
|
* @p_area: Pointer to an area.
|
|
* @p: Pointer to a compound value.
|
|
+ * @p_const: Pointer to a constant compound value.
|
|
*/
|
|
union v4l2_ctrl_ptr {
|
|
s32 *p_s32;
|
|
@@ -78,6 +79,7 @@ union v4l2_ctrl_ptr {
|
|
struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
|
|
struct v4l2_area *p_area;
|
|
void *p;
|
|
+ const void *p_const;
|
|
};
|
|
|
|
/**
|
|
|
|
From c33745e39cef44f4db889ee48e01fc1af5e094a1 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:20 +0100
|
|
Subject: [PATCH] media: vivid: Add an area control
|
|
|
|
This control represents a generic read/write area.
|
|
|
|
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 483b2217dbb05f1326578767c6d7fb5ec2dc1c51)
|
|
---
|
|
drivers/media/platform/vivid/vivid-ctrls.c | 14 ++++++++++++++
|
|
1 file changed, 14 insertions(+)
|
|
|
|
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
index b250fc3764e2..68e8124c7973 100644
|
|
--- a/drivers/media/platform/vivid/vivid-ctrls.c
|
|
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
|
|
@@ -32,6 +32,7 @@
|
|
#define VIVID_CID_U32_ARRAY (VIVID_CID_CUSTOM_BASE + 8)
|
|
#define VIVID_CID_U16_MATRIX (VIVID_CID_CUSTOM_BASE + 9)
|
|
#define VIVID_CID_U8_4D_ARRAY (VIVID_CID_CUSTOM_BASE + 10)
|
|
+#define VIVID_CID_AREA (VIVID_CID_CUSTOM_BASE + 11)
|
|
|
|
#define VIVID_CID_VIVID_BASE (0x00f00000 | 0xf000)
|
|
#define VIVID_CID_VIVID_CLASS (0x00f00000 | 1)
|
|
@@ -266,6 +267,18 @@ static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
|
|
.type = V4L2_CTRL_TYPE_BUTTON,
|
|
};
|
|
|
|
+static const struct v4l2_area area = {
|
|
+ .width = 1000,
|
|
+ .height = 2000,
|
|
+};
|
|
+
|
|
+static const struct v4l2_ctrl_config vivid_ctrl_area = {
|
|
+ .ops = &vivid_user_gen_ctrl_ops,
|
|
+ .id = VIVID_CID_AREA,
|
|
+ .name = "Area",
|
|
+ .type = V4L2_CTRL_TYPE_AREA,
|
|
+ .p_def.p_const = &area,
|
|
+};
|
|
|
|
/* Framebuffer Controls */
|
|
|
|
@@ -1574,6 +1587,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
|
|
dev->string = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_string, NULL);
|
|
dev->bitmask = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_bitmask, NULL);
|
|
dev->int_menu = v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_int_menu, NULL);
|
|
+ v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_area, NULL);
|
|
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u32_array, NULL);
|
|
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u16_matrix, NULL);
|
|
v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_u8_4d_array, NULL);
|
|
|
|
From 4c2221a0b46f59db38c2e77fff46741a1b20dd03 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:21 +0100
|
|
Subject: [PATCH] media: v4l2_core: Add p_area to struct v4l2_ext_control
|
|
|
|
Allow accessing V4L2_CTRL_TYPE_AREA controls without any casting.
|
|
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 134f9e9ef202f72296f4d9a6e80e84d6efabbba7)
|
|
---
|
|
include/uapi/linux/videodev2.h | 1 +
|
|
1 file changed, 1 insertion(+)
|
|
|
|
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|
|
index f98bbcced8ff..04481c717fee 100644
|
|
--- a/include/uapi/linux/videodev2.h
|
|
+++ b/include/uapi/linux/videodev2.h
|
|
@@ -1684,6 +1684,7 @@ struct v4l2_ext_control {
|
|
__u8 __user *p_u8;
|
|
__u16 __user *p_u16;
|
|
__u32 __user *p_u32;
|
|
+ struct v4l2_area __user *p_area;
|
|
void __user *ptr;
|
|
};
|
|
} __attribute__ ((packed));
|
|
|
|
From f918e000e6d220c89b03737c302611fbc4614cfd Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:22 +0100
|
|
Subject: [PATCH] media: Documentation: v42l_core: v4l2_ext_control
|
|
|
|
Describe p_area field from v4l2_ext_ctrl
|
|
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 8508a2d519ed190a77061c5159b000f1035b3522)
|
|
---
|
|
Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst | 5 +++++
|
|
1 file changed, 5 insertions(+)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
|
|
index 13dc1a986249..271cac18afbb 100644
|
|
--- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
|
|
+++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst
|
|
@@ -198,6 +198,11 @@ still cause this situation.
|
|
- ``p_u32``
|
|
- A pointer to a matrix control of unsigned 32-bit values. Valid if
|
|
this control is of type ``V4L2_CTRL_TYPE_U32``.
|
|
+ * -
|
|
+ - :c:type:`v4l2_area` *
|
|
+ - ``p_area``
|
|
+ - A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
|
|
+ of type ``V4L2_CTRL_TYPE_AREA``.
|
|
* -
|
|
- void *
|
|
- ``ptr``
|
|
|
|
From 92b651661f6970ab807d546754fa154e39483c66 Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Mon, 4 Nov 2019 14:09:23 +0100
|
|
Subject: [PATCH] media: v4l2-ctrl: Use p_const when possible
|
|
|
|
After adding a const pointer to ctrl_ptr, lets use it where it make
|
|
sense.
|
|
|
|
Suggested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 57d024f8db65ca3188d23487ca6980150356b7a3)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 17 +++++++++--------
|
|
1 file changed, 9 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index 73d99c3561ce..a565ae3ba7e4 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -1556,7 +1556,8 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
|
|
if (ctrl->is_int)
|
|
return ptr1.p_s32[idx] == ptr2.p_s32[idx];
|
|
idx *= ctrl->elem_size;
|
|
- return !memcmp(ptr1.p + idx, ptr2.p + idx, ctrl->elem_size);
|
|
+ return !memcmp(ptr1.p_const + idx, ptr2.p_const + idx,
|
|
+ ctrl->elem_size);
|
|
}
|
|
}
|
|
|
|
@@ -1566,8 +1567,8 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
|
|
struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
|
|
void *p = ptr.p + idx * ctrl->elem_size;
|
|
|
|
- if (ctrl->p_def.p)
|
|
- memcpy(p, ctrl->p_def.p, ctrl->elem_size);
|
|
+ if (ctrl->p_def.p_const)
|
|
+ memcpy(p, ctrl->p_def.p_const, ctrl->elem_size);
|
|
else
|
|
memset(p, 0, ctrl->elem_size);
|
|
|
|
@@ -1954,7 +1955,7 @@ static int ptr_to_user(struct v4l2_ext_control *c,
|
|
u32 len;
|
|
|
|
if (ctrl->is_ptr && !ctrl->is_string)
|
|
- return copy_to_user(c->ptr, ptr.p, c->size) ?
|
|
+ return copy_to_user(c->ptr, ptr.p_const, c->size) ?
|
|
-EFAULT : 0;
|
|
|
|
switch (ctrl->type) {
|
|
@@ -2069,7 +2070,7 @@ static void ptr_to_ptr(struct v4l2_ctrl *ctrl,
|
|
{
|
|
if (ctrl == NULL)
|
|
return;
|
|
- memcpy(to.p, from.p, ctrl->elems * ctrl->elem_size);
|
|
+ memcpy(to.p, from.p_const, ctrl->elems * ctrl->elem_size);
|
|
}
|
|
|
|
/* Copy the new value to the current value. */
|
|
@@ -2587,7 +2588,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
is_array)
|
|
sz_extra += 2 * tot_ctrl_size;
|
|
|
|
- if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p)
|
|
+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const)
|
|
sz_extra += elem_size;
|
|
|
|
ctrl = kvzalloc(sizeof(*ctrl) + sz_extra, GFP_KERNEL);
|
|
@@ -2634,9 +2635,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
|
|
ctrl->p_cur.p = &ctrl->cur.val;
|
|
}
|
|
|
|
- if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p) {
|
|
+ if (type >= V4L2_CTRL_COMPOUND_TYPES && p_def.p_const) {
|
|
ctrl->p_def.p = ctrl->p_cur.p + tot_ctrl_size;
|
|
- memcpy(ctrl->p_def.p, p_def.p, elem_size);
|
|
+ memcpy(ctrl->p_def.p, p_def.p_const, elem_size);
|
|
}
|
|
|
|
for (idx = 0; idx < elems; idx++) {
|
|
|
|
From e748cc61402a8fac9057e74fcf22a12495f970f1 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Tue, 5 Nov 2019 09:17:28 +0100
|
|
Subject: [PATCH] media: v4l2-device.h: fix typo: putss -> puts
|
|
|
|
Fix typo: putss -> puts
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit b95182a6e82209fa3c98bde8ec79c51b1870aca5)
|
|
---
|
|
include/media/v4l2-device.h | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
|
|
index e0b8f2602670..5f36e0d2ede6 100644
|
|
--- a/include/media/v4l2-device.h
|
|
+++ b/include/media/v4l2-device.h
|
|
@@ -72,7 +72,7 @@ static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
|
|
}
|
|
|
|
/**
|
|
- * v4l2_device_put - putss a V4L2 device reference
|
|
+ * v4l2_device_put - puts a V4L2 device reference
|
|
*
|
|
* @v4l2_dev: pointer to struct &v4l2_device
|
|
*
|
|
|
|
From 7816d434ebc7e005ecbf508e357cb1d22a6f2645 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Sat, 26 Oct 2019 09:27:51 +0200
|
|
Subject: [PATCH] media: cedrus: Fix decoding for some H264 videos
|
|
|
|
It seems that for some H264 videos at least one bitstream parsing
|
|
trigger must be called in order to be decoded correctly. There is no
|
|
explanation why this helps, but it was observed that two sample videos
|
|
with this fix are now decoded correctly and there is no regression with
|
|
others.
|
|
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 61ad123318c28679b8846baab0df9240c29c21c9)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 30 +++++++++++++++++++++---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 3 +++
|
|
2 files changed, 30 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index cd85668f9c80..db336449c4f2 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -6,6 +6,7 @@
|
|
* Copyright (c) 2018 Bootlin
|
|
*/
|
|
|
|
+#include <linux/delay.h>
|
|
#include <linux/types.h>
|
|
|
|
#include <media/videobuf2-dma-contig.h>
|
|
@@ -289,6 +290,28 @@ static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * It turns out that using VE_H264_VLD_OFFSET to skip bits is not reliable. In
|
|
+ * rare cases frame is not decoded correctly. However, setting offset to 0 and
|
|
+ * skipping appropriate amount of bits with flush bits trigger always works.
|
|
+ */
|
|
+static void cedrus_skip_bits(struct cedrus_dev *dev, int num)
|
|
+{
|
|
+ int count = 0;
|
|
+
|
|
+ while (count < num) {
|
|
+ int tmp = min(num - count, 32);
|
|
+
|
|
+ cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
|
+ VE_H264_TRIGGER_TYPE_FLUSH_BITS |
|
|
+ VE_H264_TRIGGER_TYPE_N_BITS(tmp));
|
|
+ while (cedrus_read(dev, VE_H264_STATUS) & VE_H264_STATUS_VLD_BUSY)
|
|
+ udelay(1);
|
|
+
|
|
+ count += tmp;
|
|
+ }
|
|
+}
|
|
+
|
|
static void cedrus_set_params(struct cedrus_ctx *ctx,
|
|
struct cedrus_run *run)
|
|
{
|
|
@@ -299,14 +322,13 @@ 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 offset = slice->header_bit_size;
|
|
- u32 len = (slice->size * 8) - offset;
|
|
+ u32 len = slice->size * 8;
|
|
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_OFFSET, offset);
|
|
+ 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,
|
|
@@ -325,6 +347,8 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
|
cedrus_write(dev, VE_H264_TRIGGER_TYPE,
|
|
VE_H264_TRIGGER_TYPE_INIT_SWDEC);
|
|
|
|
+ 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)) ||
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index 6fc28d21a6c7..4275a307d282 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -541,13 +541,16 @@
|
|
VE_H264_CTRL_SLICE_DECODE_INT)
|
|
|
|
#define VE_H264_TRIGGER_TYPE 0x224
|
|
+#define VE_H264_TRIGGER_TYPE_N_BITS(x) (((x) & 0x3f) << 8)
|
|
#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
|
|
#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
|
|
+#define VE_H264_TRIGGER_TYPE_FLUSH_BITS (3 << 0)
|
|
|
|
#define VE_H264_STATUS 0x228
|
|
#define VE_H264_STATUS_VLD_DATA_REQ_INT VE_H264_CTRL_VLD_DATA_REQ_INT
|
|
#define VE_H264_STATUS_DECODE_ERR_INT VE_H264_CTRL_DECODE_ERR_INT
|
|
#define VE_H264_STATUS_SLICE_DECODE_INT VE_H264_CTRL_SLICE_DECODE_INT
|
|
+#define VE_H264_STATUS_VLD_BUSY BIT(8)
|
|
|
|
#define VE_H264_STATUS_INT_MASK VE_H264_CTRL_INT_MASK
|
|
|
|
|
|
From a65339816a53f30b59e47f70a6872ff6b0071ba7 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Sat, 26 Oct 2019 09:27:52 +0200
|
|
Subject: [PATCH] media: cedrus: Use helpers to access capture queue
|
|
|
|
Accessing capture queue structue directly is not safe. Use helpers for
|
|
that.
|
|
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 1fd50a2c294457508f06b8b631d01a58de81cdd2)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus.h | 8 ++++++--
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 8 ++++++--
|
|
2 files changed, 12 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
index 986e059e3202..c45fb9a7ad07 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
@@ -197,12 +197,16 @@ static inline dma_addr_t cedrus_buf_addr(struct vb2_buffer *buf,
|
|
static inline dma_addr_t cedrus_dst_buf_addr(struct cedrus_ctx *ctx,
|
|
int index, unsigned int plane)
|
|
{
|
|
- struct vb2_buffer *buf;
|
|
+ struct vb2_buffer *buf = NULL;
|
|
+ struct vb2_queue *vq;
|
|
|
|
if (index < 0)
|
|
return 0;
|
|
|
|
- buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index];
|
|
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
+ if (vq)
|
|
+ buf = vb2_get_buffer(vq, index);
|
|
+
|
|
return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
|
|
}
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index db336449c4f2..7487f6ab7576 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -97,7 +97,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
|
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 = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
+ struct vb2_queue *cap_q;
|
|
struct cedrus_buffer *output_buf;
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
unsigned long used_dpbs = 0;
|
|
@@ -105,6 +105,8 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
|
|
unsigned int output = 0;
|
|
unsigned int i;
|
|
|
|
+ cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
+
|
|
memset(pic_list, 0, sizeof(pic_list));
|
|
|
|
for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
|
|
@@ -168,12 +170,14 @@ static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
|
|
enum cedrus_h264_sram_off sram)
|
|
{
|
|
const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
|
|
- struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
+ struct vb2_queue *cap_q;
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
u8 sram_array[CEDRUS_MAX_REF_IDX];
|
|
unsigned int i;
|
|
size_t size;
|
|
|
|
+ cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
+
|
|
memset(sram_array, 0, sizeof(sram_array));
|
|
|
|
for (i = 0; i < num_ref; i++) {
|
|
|
|
From 6831d4cad08fdaed8bb38bfc04fc489d3f02fcbe Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Tue, 29 Oct 2019 01:00:51 +0100
|
|
Subject: [PATCH] media: uapi: h264: clarify expected scaling_list_4x4/8x8
|
|
order
|
|
|
|
Clarify that the expected order of scaling lists should follow the order
|
|
they are listed in the H264 standard.
|
|
|
|
The expected scaling list order,
|
|
for 4x4: Intra Y, Intra Cb, Intra Cr, Inter Y, Inter Cb, Inter Cr,
|
|
for 8x8: Intra Y, Inter Y, Intra Cb, Inter Cb, Intra Cr, Inter Cr.
|
|
|
|
Also clarify that the values in a scaling list should be in matrix order,
|
|
the same value order that vaapi, vdpau and nvdec use.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 0b0393d59eb4a58456d128a782c42f924eedab16)
|
|
---
|
|
Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 8 ++++++--
|
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
index a1209f68c5e8..28313c0f4e7c 100644
|
|
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
|
|
@@ -1713,10 +1713,14 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
|
|
|
|
* - __u8
|
|
- ``scaling_list_4x4[6][16]``
|
|
- -
|
|
+ - Scaling matrix after applying the inverse scanning process.
|
|
+ Expected list order is Intra Y, Intra Cb, Intra Cr, Inter Y,
|
|
+ Inter Cb, Inter Cr.
|
|
* - __u8
|
|
- ``scaling_list_8x8[6][64]``
|
|
- -
|
|
+ - Scaling matrix after applying the inverse scanning process.
|
|
+ Expected list order is Intra Y, Inter Y, Intra Cb, Inter Cb,
|
|
+ Intra Cr, Inter Cr.
|
|
|
|
``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
|
|
Specifies the slice parameters (as extracted from the bitstream)
|
|
|
|
From 4556c1fba4fad8164aa32ee2bc49c2db6d60af4c Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Tue, 29 Oct 2019 01:00:52 +0100
|
|
Subject: [PATCH] media: cedrus: Use correct H264 8x8 scaling list
|
|
|
|
Documentation now defines the expected order of scaling lists,
|
|
change to use correct indices.
|
|
|
|
Fixes: 6eb9b758e307 ("media: cedrus: Add H264 decoding support")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit a6b8feae7c88343212686120740cf7551dd16e08)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index 7487f6ab7576..74e4c5e3894e 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -245,8 +245,8 @@ static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
|
|
sizeof(scaling->scaling_list_8x8[0]));
|
|
|
|
cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_1,
|
|
- scaling->scaling_list_8x8[3],
|
|
- sizeof(scaling->scaling_list_8x8[3]));
|
|
+ scaling->scaling_list_8x8[1],
|
|
+ sizeof(scaling->scaling_list_8x8[1]));
|
|
|
|
cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_4x4,
|
|
scaling->scaling_list_4x4,
|
|
|
|
From 0a4e67064ec7a5e5f0567d9ee64bc0dff9594faa Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Tue, 29 Oct 2019 01:00:53 +0100
|
|
Subject: [PATCH] media: hantro: Do not reorder H264 scaling list
|
|
|
|
Scaling list supplied from userspace should be in matrix order
|
|
and can be used without applying the inverse scanning process.
|
|
|
|
The HW also only support 8x8 scaling list for the Y component, indices 0
|
|
and 1 in the scaling list supplied from userspace.
|
|
|
|
Remove reordering and write the scaling matrix in an order expected by
|
|
the VPU, also only allocate memory for the two 8x8 lists supported.
|
|
|
|
Fixes: a9471e25629b ("media: hantro: Add core bits to support H264 decoding")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit e17f08e3166635d2eaa6a894afeb28ca651ddd35)
|
|
---
|
|
drivers/staging/media/hantro/hantro_h264.c | 51 +++++++-----------------------
|
|
1 file changed, 12 insertions(+), 39 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 02cbe7761769..694a330f508e 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -20,7 +20,7 @@
|
|
/* Size with u32 units. */
|
|
#define CABAC_INIT_BUFFER_SIZE (460 * 2)
|
|
#define POC_BUFFER_SIZE 34
|
|
-#define SCALING_LIST_SIZE (6 * 16 + 6 * 64)
|
|
+#define SCALING_LIST_SIZE (6 * 16 + 2 * 64)
|
|
|
|
#define HANTRO_CMP(a, b) ((a) < (b) ? -1 : 1)
|
|
|
|
@@ -194,23 +194,6 @@ static const u32 h264_cabac_table[] = {
|
|
0x1f0c2517, 0x1f261440
|
|
};
|
|
|
|
-/*
|
|
- * NOTE: The scaling lists are in zig-zag order, apply inverse scanning process
|
|
- * to get the values in matrix order. In addition, the hardware requires bytes
|
|
- * swapped within each subsequent 4 bytes. Both arrays below include both
|
|
- * transformations.
|
|
- */
|
|
-static const u32 zig_zag_4x4[] = {
|
|
- 3, 2, 7, 11, 6, 1, 0, 5, 10, 15, 14, 9, 4, 8, 13, 12
|
|
-};
|
|
-
|
|
-static const u32 zig_zag_8x8[] = {
|
|
- 3, 2, 11, 19, 10, 1, 0, 9, 18, 27, 35, 26, 17, 8, 7, 6,
|
|
- 15, 16, 25, 34, 43, 51, 42, 33, 24, 23, 14, 5, 4, 13, 22, 31,
|
|
- 32, 41, 50, 59, 58, 49, 40, 39, 30, 21, 12, 20, 29, 38, 47, 48,
|
|
- 57, 56, 55, 46, 37, 28, 36, 45, 54, 63, 62, 53, 44, 52, 61, 60
|
|
-};
|
|
-
|
|
static void
|
|
reorder_scaling_list(struct hantro_ctx *ctx)
|
|
{
|
|
@@ -218,33 +201,23 @@ reorder_scaling_list(struct hantro_ctx *ctx)
|
|
const struct v4l2_ctrl_h264_scaling_matrix *scaling = ctrls->scaling;
|
|
const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4);
|
|
const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[0]);
|
|
- const size_t num_list_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8);
|
|
const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]);
|
|
struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
|
|
- u8 *dst = tbl->scaling_list;
|
|
- const u8 *src;
|
|
+ u32 *dst = (u32 *)tbl->scaling_list;
|
|
+ const u32 *src;
|
|
int i, j;
|
|
|
|
- BUILD_BUG_ON(ARRAY_SIZE(zig_zag_4x4) != list_len_4x4);
|
|
- BUILD_BUG_ON(ARRAY_SIZE(zig_zag_8x8) != list_len_8x8);
|
|
- BUILD_BUG_ON(ARRAY_SIZE(tbl->scaling_list) !=
|
|
- num_list_4x4 * list_len_4x4 +
|
|
- num_list_8x8 * list_len_8x8);
|
|
-
|
|
- src = &scaling->scaling_list_4x4[0][0];
|
|
- for (i = 0; i < num_list_4x4; ++i) {
|
|
- for (j = 0; j < list_len_4x4; ++j)
|
|
- dst[zig_zag_4x4[j]] = src[j];
|
|
- src += list_len_4x4;
|
|
- dst += list_len_4x4;
|
|
+ for (i = 0; i < num_list_4x4; i++) {
|
|
+ src = (u32 *)&scaling->scaling_list_4x4[i];
|
|
+ for (j = 0; j < list_len_4x4 / 4; j++)
|
|
+ *dst++ = swab32(src[j]);
|
|
}
|
|
|
|
- src = &scaling->scaling_list_8x8[0][0];
|
|
- for (i = 0; i < num_list_8x8; ++i) {
|
|
- for (j = 0; j < list_len_8x8; ++j)
|
|
- dst[zig_zag_8x8[j]] = src[j];
|
|
- src += list_len_8x8;
|
|
- dst += list_len_8x8;
|
|
+ /* Only Intra/Inter Y lists */
|
|
+ for (i = 0; i < 2; i++) {
|
|
+ src = (u32 *)&scaling->scaling_list_8x8[i];
|
|
+ for (j = 0; j < list_len_8x8 / 4; j++)
|
|
+ *dst++ = swab32(src[j]);
|
|
}
|
|
}
|
|
|
|
|
|
From b82abc83697c975959f82f4f0b41762d9c7195da Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Tue, 29 Oct 2019 02:24:47 +0100
|
|
Subject: [PATCH] media: hantro: Fix H264 max frmsize supported on RK3288
|
|
|
|
TRM specify supported image size 48x48 to 4096x2304 at step size 16 pixels,
|
|
change frmsize max_width/max_height to match TRM at [1].
|
|
|
|
This patch makes it possible to decode the 4096x2304 sample at [2].
|
|
|
|
[1] http://www.t-firefly.com/download/firefly-rk3288/docs/TRM/rk3288-chapter-25-video-encoder-decoder-unit-(vcodec).pdf
|
|
[2] https://4ksamples.com/puppies-bath-in-4k/
|
|
|
|
Fixes: 760327930e10 ("media: hantro: Enable H264 decoding on rk3288")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Tested-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit edeb237884d6c3158387528b0490e98fb9bb5e8d)
|
|
---
|
|
drivers/staging/media/hantro/rk3288_vpu_hw.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
index c0bdd6c02520..f8db6fcaad73 100644
|
|
--- a/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
+++ b/drivers/staging/media/hantro/rk3288_vpu_hw.c
|
|
@@ -67,10 +67,10 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
|
|
.max_depth = 2,
|
|
.frmsize = {
|
|
.min_width = 48,
|
|
- .max_width = 3840,
|
|
+ .max_width = 4096,
|
|
.step_width = MB_DIM,
|
|
.min_height = 48,
|
|
- .max_height = 2160,
|
|
+ .max_height = 2304,
|
|
.step_height = MB_DIM,
|
|
},
|
|
},
|
|
|
|
From 0c7eff93ce35911709a39148c20421bef7413fc5 Mon Sep 17 00:00:00 2001
|
|
From: Francois Buergisser <fbuergisser@chromium.org>
|
|
Date: Tue, 29 Oct 2019 02:24:47 +0100
|
|
Subject: [PATCH] media: hantro: Fix motion vectors usage condition
|
|
|
|
The setting of the motion vectors usage and the setting of motion
|
|
vectors address are currently done under different conditions.
|
|
|
|
When decoding pre-recorded videos, this results of leaving the motion
|
|
vectors address unset, resulting in faulty memory accesses. Fix it
|
|
by using the same condition everywhere, which matches the profiles
|
|
that support motion vectors.
|
|
|
|
Fixes: dea0a82f3d22 ("media: hantro: Add support for H264 decoding on G1")
|
|
Signed-off-by: Francois Buergisser <fbuergisser@chromium.org>
|
|
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Tested-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Cc: <stable@vger.kernel.org> # for v5.4 and up
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 658f9d9921d7e76af03f689b5f0ffde042b8bf5b)
|
|
---
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index 29130946dea4..a1cb18680200 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -35,7 +35,7 @@ static void set_params(struct hantro_ctx *ctx)
|
|
if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
|
|
reg |= G1_REG_DEC_CTRL0_SEQ_MBAFF_E;
|
|
reg |= G1_REG_DEC_CTRL0_PICORD_COUNT_E;
|
|
- if (dec_param->nal_ref_idc)
|
|
+ if (sps->profile_idc > 66 && dec_param->nal_ref_idc)
|
|
reg |= G1_REG_DEC_CTRL0_WRITE_MVS_E;
|
|
|
|
if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) &&
|
|
@@ -245,7 +245,7 @@ static void set_buffers(struct hantro_ctx *ctx)
|
|
vdpu_write_relaxed(vpu, dst_dma, G1_REG_ADDR_DST);
|
|
|
|
/* Higher profiles require DMV buffer appended to reference frames. */
|
|
- if (ctrls->sps->profile_idc > 66) {
|
|
+ if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc) {
|
|
size_t pic_size = ctx->h264_dec.pic_size;
|
|
size_t mv_offset = round_up(pic_size, 8);
|
|
|
|
|
|
From ef162c3e58d4a48435620f87ca02f5b4f6416d9f Mon Sep 17 00:00:00 2001
|
|
From: Francois Buergisser <fbuergisser@chromium.org>
|
|
Date: Tue, 29 Oct 2019 02:24:48 +0100
|
|
Subject: [PATCH] media: hantro: Fix picture order count table enable
|
|
|
|
The picture order count table only makes sense for profiles
|
|
higher than Baseline. This is confirmed by the H.264 specification
|
|
(See 8.2.1 Decoding process for picture order count), which
|
|
clarifies how POC are used for features not present in Baseline.
|
|
|
|
"""
|
|
Picture order counts are used to determine initial picture orderings
|
|
for reference pictures in the decoding of B slices, to represent picture
|
|
order differences between frames or fields for motion vector derivation
|
|
in temporal direct mode, for implicit mode weighted prediction in B slices,
|
|
and for decoder conformance checking.
|
|
"""
|
|
|
|
As a side note, this change matches various vendors downstream codebases,
|
|
including ChromiumOS and IMX VPU libraries.
|
|
|
|
Fixes: dea0a82f3d22 ("media: hantro: Add support for H264 decoding on G1")
|
|
Signed-off-by: Francois Buergisser <fbuergisser@chromium.org>
|
|
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Tested-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Cc: <stable@vger.kernel.org> # for v5.4 and up
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 58c93a548b0248fad6437f8c8921f9b031c3892a)
|
|
---
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 8 +++++---
|
|
1 file changed, 5 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index a1cb18680200..70a6b5b26477 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -34,9 +34,11 @@ static void set_params(struct hantro_ctx *ctx)
|
|
reg = G1_REG_DEC_CTRL0_DEC_AXI_WR_ID(0x0);
|
|
if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
|
|
reg |= G1_REG_DEC_CTRL0_SEQ_MBAFF_E;
|
|
- reg |= G1_REG_DEC_CTRL0_PICORD_COUNT_E;
|
|
- if (sps->profile_idc > 66 && dec_param->nal_ref_idc)
|
|
- reg |= G1_REG_DEC_CTRL0_WRITE_MVS_E;
|
|
+ if (sps->profile_idc > 66) {
|
|
+ reg |= G1_REG_DEC_CTRL0_PICORD_COUNT_E;
|
|
+ if (dec_param->nal_ref_idc)
|
|
+ reg |= G1_REG_DEC_CTRL0_WRITE_MVS_E;
|
|
+ }
|
|
|
|
if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) &&
|
|
(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD ||
|
|
|
|
From 87b9ef86e59eb1de41f378529a773ce077e0e10d Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Tue, 5 Nov 2019 18:53:17 +0100
|
|
Subject: [PATCH] media: vimc: sen: remove unused kthread_sen field
|
|
|
|
The field kthread_sen in the vimc_sen_device is
|
|
not set and used. So remove the field and
|
|
the code that check if it is non NULL
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Cc: <stable@vger.kernel.org> # for v5.4 and up
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 3ea35d5db448c27807acbcc7a2306cf65c5e6397)
|
|
---
|
|
drivers/media/platform/vimc/vimc-sensor.c | 5 -----
|
|
1 file changed, 5 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
|
|
index 25ee89a067f7..32380f504591 100644
|
|
--- a/drivers/media/platform/vimc/vimc-sensor.c
|
|
+++ b/drivers/media/platform/vimc/vimc-sensor.c
|
|
@@ -18,7 +18,6 @@ struct vimc_sen_device {
|
|
struct vimc_ent_device ved;
|
|
struct v4l2_subdev sd;
|
|
struct tpg_data tpg;
|
|
- struct task_struct *kthread_sen;
|
|
u8 *frame;
|
|
/* The active format */
|
|
struct v4l2_mbus_framefmt mbus_format;
|
|
@@ -202,10 +201,6 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
|
|
const struct vimc_pix_map *vpix;
|
|
unsigned int frame_size;
|
|
|
|
- if (vsen->kthread_sen)
|
|
- /* tpg is already executing */
|
|
- return 0;
|
|
-
|
|
/* Calculate the frame size */
|
|
vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
|
|
frame_size = vsen->mbus_format.width * vpix->bpp *
|
|
|
|
From c3083480946f5288ef3c7cb4a7b8418a7d921345 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Wed, 6 Nov 2019 08:02:53 +0100
|
|
Subject: [PATCH] media: v4l2-mem2mem: Fix hold buf flag checks
|
|
|
|
Hold buf flag is set on output queue, not capture. Fix that.
|
|
|
|
Fixes: f07602ac3887 ("media: v4l2-mem2mem: add new_frame detection")
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 1076df3a77b490d33429560a9e0603b3673223e2)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
index db07ef3bf3d0..1afd9c6ad908 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
|
|
@@ -335,7 +335,7 @@ static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev,
|
|
}
|
|
}
|
|
|
|
- if (src && dst && (m2m_ctx->cap_q_ctx.q.subsystem_flags &
|
|
+ if (src && dst && (m2m_ctx->out_q_ctx.q.subsystem_flags &
|
|
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF))
|
|
m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp ||
|
|
dst->vb2_buf.timestamp != src->vb2_buf.timestamp;
|
|
@@ -474,7 +474,7 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
|
|
* holding capture buffers. Those should use
|
|
* v4l2_m2m_buf_done_and_job_finish() instead.
|
|
*/
|
|
- WARN_ON(m2m_ctx->cap_q_ctx.q.subsystem_flags &
|
|
+ WARN_ON(m2m_ctx->out_q_ctx.q.subsystem_flags &
|
|
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF);
|
|
spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
|
|
schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx);
|
|
|
|
From f5d232fb97ad92567f0efb4b0d4d6cc8f4985861 Mon Sep 17 00:00:00 2001
|
|
From: zhong jiang <zhongjiang@huawei.com>
|
|
Date: Sun, 10 Nov 2019 07:22:17 +0100
|
|
Subject: [PATCH] media: v4l2: Use FIELD_SIZEOF directly
|
|
|
|
It's more clear to use FIELD_SIZEOF instead of its implementation.
|
|
|
|
Signed-off-by: zhong jiang <zhongjiang@huawei.com>
|
|
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 40ee7524722836bd5fd40d45f8ee872a41f6ea8e)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index 315ac12c3e0a..60453b21a855 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -2652,7 +2652,7 @@ struct v4l2_ioctl_info {
|
|
/* Zero struct from after the field to the end */
|
|
#define INFO_FL_CLEAR(v4l2_struct, field) \
|
|
((offsetof(struct v4l2_struct, field) + \
|
|
- sizeof(((struct v4l2_struct *)0)->field)) << 16)
|
|
+ FIELD_SIZEOF(struct v4l2_struct, field)) << 16)
|
|
#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
|
|
|
|
#define DEFINE_V4L_STUB_FUNC(_vidioc) \
|
|
|
|
From a663275bc9ed610159eb98476822fec57564464c Mon Sep 17 00:00:00 2001
|
|
From: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Date: Sun, 10 Nov 2019 07:25:03 +0100
|
|
Subject: [PATCH] media: vimc: upon streaming, check that the pipeline starts
|
|
with a source entity
|
|
|
|
Userspace can disable links and create pipelines that
|
|
do not start with a source entity. Trying to stream
|
|
from such a pipeline should fail with -EPIPE
|
|
currently this is not handled and cause kernel crash.
|
|
|
|
Reproducing the crash:
|
|
media-ctl -d0 -l "5:1->21:0[0]" -v
|
|
v4l2-ctl -z platform:vimc -d "RGB/YUV Capture" -v width=1920,height=1440
|
|
v4l2-ctl --stream-mmap --stream-count=100 -d /dev/video2
|
|
|
|
Panic message:
|
|
[ 39.078841][ T248] BUG: kernel NULL pointer dereference, address: 0000000000000000
|
|
[ 39.079338][ T248] #PF: supervisor read access in kernel mode
|
|
[ 39.079704][ T248] #PF: error_code(0x0000) - not-present page
|
|
[ 39.080071][ T248] PGD 0 P4D 0
|
|
[ 39.080279][ T248] Oops: 0000 [#1] SMP PTI
|
|
[ 39.080546][ T248] CPU: 0 PID: 248 Comm: vimc-streamer t Not tainted 5.4.0-rc1+ #17
|
|
[ 39.081030][ T248] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014
|
|
[ 39.081779][ T248] RIP: 0010:vimc_sca_process_frame+0xdb/0x210 [vimc]
|
|
[ 39.082191][ T248] Code: 44 8d 0c 28 8b 93 a4 01 00 00 48 8b 8b 98 01 00 00 85 d2 74 40 48 8b 74 24 10 8d 7a ff 4c 01 c9 31 d2 4c 01 fe eb 03 4c 89 c2 <44> 0f b6 04 16 44 88 04 11 4c 8d 42 01 48 39 fa 75 eb 8b 93 a4 01
|
|
[ 39.083436][ T248] RSP: 0018:ffffb15a005abe90 EFLAGS: 00010246
|
|
[ 39.083808][ T248] RAX: 0000000000000000 RBX: ffffa3fdc46d2e00 RCX: ffffb15a02579000
|
|
[ 39.084298][ T248] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
|
|
[ 39.084792][ T248] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
|
|
[ 39.085280][ T248] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
|
|
[ 39.085770][ T248] R13: ffffa3fdc46d2ee0 R14: 0000000000000000 R15: 0000000000000000
|
|
[ 39.086258][ T248] FS: 0000000000000000(0000) GS:ffffa3fdc7800000(0000) knlGS:0000000000000000
|
|
[ 39.086806][ T248] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
[ 39.087217][ T248] CR2: 0000000000000000 CR3: 0000000003c92005 CR4: 0000000000360ef0
|
|
[ 39.087706][ T248] Call Trace:
|
|
[ 39.087909][ T248] ? vimc_streamer_pipeline_terminate+0x90/0x90 [vimc]
|
|
[ 39.088318][ T248] vimc_streamer_thread+0x7c/0xe0 [vimc]
|
|
[ 39.088663][ T248] kthread+0x10d/0x130
|
|
[ 39.088919][ T248] ? kthread_park+0x80/0x80
|
|
[ 39.089205][ T248] ret_from_fork+0x35/0x40
|
|
[ 39.089475][ T248] Modules linked in: vimc videobuf2_vmalloc videobuf2_memops v4l2_tpg videobuf2_v4l2 videobuf2_common videodev mc
|
|
[ 39.090208][ T248] CR2: 0000000000000000
|
|
[ 39.090463][ T248] ---[ end trace 697650fefbf78bee ]---
|
|
[ 39.090796][ T248] RIP: 0010:vimc_sca_process_frame+0xdb/0x210 [vimc]
|
|
[ 39.091209][ T248] Code: 44 8d 0c 28 8b 93 a4 01 00 00 48 8b 8b 98 01 00 00 85 d2 74 40 48 8b 74 24 10 8d 7a ff 4c 01 c9 31 d2 4c 01 fe eb 03 4c 89 c2 <44> 0f b6 04 16 44 88 04 11 4c 8d 42 01 48 39 fa 75 eb 8b 93 a4 01
|
|
[ 39.092417][ T248] RSP: 0018:ffffb15a005abe90 EFLAGS: 00010246
|
|
[ 39.092789][ T248] RAX: 0000000000000000 RBX: ffffa3fdc46d2e00 RCX: ffffb15a02579000
|
|
[ 39.093278][ T248] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002
|
|
[ 39.093766][ T248] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
|
|
[ 39.094254][ T248] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
|
|
[ 39.094742][ T248] R13: ffffa3fdc46d2ee0 R14: 0000000000000000 R15: 0000000000000000
|
|
[ 39.095309][ T248] FS: 0000000000000000(0000) GS:ffffa3fdc7800000(0000) knlGS:0000000000000000
|
|
[ 39.095974][ T248] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
[ 39.096372][ T248] CR2: 0000000000000000 CR3: 0000000003c92005 CR4: 0000000000360ef0
|
|
|
|
Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
|
Acked-by: Helen Koike <helen.koike@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit c20df61861b702605046a7b61b1da6143c05fc4d)
|
|
---
|
|
drivers/media/platform/vimc/vimc-common.c | 10 ++++++++++
|
|
drivers/media/platform/vimc/vimc-common.h | 8 ++++++++
|
|
drivers/media/platform/vimc/vimc-streamer.c | 13 +++++++++++--
|
|
3 files changed, 29 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
|
|
index 43e6fa5886da..16ce9f3b7c75 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.c
|
|
+++ b/drivers/media/platform/vimc/vimc-common.c
|
|
@@ -164,6 +164,16 @@ static const struct vimc_pix_map vimc_pix_map_list[] = {
|
|
},
|
|
};
|
|
|
|
+bool vimc_is_source(struct media_entity *ent)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < ent->num_pads; i++)
|
|
+ if (ent->pads[i].flags & MEDIA_PAD_FL_SINK)
|
|
+ return false;
|
|
+ return true;
|
|
+}
|
|
+
|
|
const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
|
|
{
|
|
if (i >= ARRAY_SIZE(vimc_pix_map_list))
|
|
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
|
|
index bf729fcde6a9..87eb8259c2a8 100644
|
|
--- a/drivers/media/platform/vimc/vimc-common.h
|
|
+++ b/drivers/media/platform/vimc/vimc-common.h
|
|
@@ -139,6 +139,14 @@ struct vimc_ent_config {
|
|
void (*rm)(struct vimc_device *vimc, struct vimc_ent_device *ved);
|
|
};
|
|
|
|
+/**
|
|
+ * vimc_is_source - returns true if the entity has only source pads
|
|
+ *
|
|
+ * @ent: pointer to &struct media_entity
|
|
+ *
|
|
+ */
|
|
+bool vimc_is_source(struct media_entity *ent);
|
|
+
|
|
/* prototypes for vimc_ent_config add and rm hooks */
|
|
struct vimc_ent_device *vimc_cap_add(struct vimc_device *vimc,
|
|
const char *vcfg_name);
|
|
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
|
|
index 1349be188a5b..cd6b55433c9e 100644
|
|
--- a/drivers/media/platform/vimc/vimc-streamer.c
|
|
+++ b/drivers/media/platform/vimc/vimc-streamer.c
|
|
@@ -104,9 +104,18 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
|
|
}
|
|
|
|
entity = vimc_get_source_entity(ved->ent);
|
|
- /* Check if the end of the pipeline was reached*/
|
|
- if (!entity)
|
|
+ /* Check if the end of the pipeline was reached */
|
|
+ if (!entity) {
|
|
+ /* the first entity of the pipe should be source only */
|
|
+ if (!vimc_is_source(ved->ent)) {
|
|
+ dev_err(ved->dev,
|
|
+ "first entity in the pipe '%s' is not a source\n",
|
|
+ ved->ent->name);
|
|
+ vimc_streamer_pipeline_terminate(stream);
|
|
+ return -EPIPE;
|
|
+ }
|
|
return 0;
|
|
+ }
|
|
|
|
/* Get the next device in the pipeline */
|
|
if (is_media_entity_v4l2_subdev(entity)) {
|
|
|
|
From 6587305b01463222d6eecbfa704a36d567de6a20 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sun, 10 Nov 2019 07:27:04 +0100
|
|
Subject: [PATCH] media: v4l2-ioctl.c: zero reserved fields for S/TRY_FMT
|
|
|
|
v4l2_vbi_format, v4l2_sliced_vbi_format and v4l2_sdr_format
|
|
have a reserved array at the end that should be zeroed by drivers
|
|
as per the V4L2 spec. Older drivers often do not do this, so just
|
|
handle this in the core.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit ee8951e56c0f960b9621636603a822811cef3158)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ioctl.c | 24 ++++++++++++------------
|
|
1 file changed, 12 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
index 60453b21a855..4e700583659b 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|
|
@@ -1617,12 +1617,12 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
|
|
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
|
if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.vbi);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
|
|
return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
|
|
if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sliced);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
|
|
return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
|
|
if (unlikely(!ops->vidioc_s_fmt_vid_out))
|
|
@@ -1648,22 +1648,22 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
|
|
case V4L2_BUF_TYPE_VBI_OUTPUT:
|
|
if (unlikely(!ops->vidioc_s_fmt_vbi_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.vbi);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
|
|
return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
|
|
if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sliced);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
|
|
return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SDR_CAPTURE:
|
|
if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sdr);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
|
|
return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SDR_OUTPUT:
|
|
if (unlikely(!ops->vidioc_s_fmt_sdr_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sdr);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
|
|
return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_META_CAPTURE:
|
|
if (unlikely(!ops->vidioc_s_fmt_meta_cap))
|
|
@@ -1719,12 +1719,12 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
|
|
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
|
if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.vbi);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
|
|
return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
|
|
if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sliced);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
|
|
return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
|
|
if (unlikely(!ops->vidioc_try_fmt_vid_out))
|
|
@@ -1750,22 +1750,22 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
|
|
case V4L2_BUF_TYPE_VBI_OUTPUT:
|
|
if (unlikely(!ops->vidioc_try_fmt_vbi_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.vbi);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.vbi.flags);
|
|
return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
|
|
if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sliced);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sliced.io_size);
|
|
return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SDR_CAPTURE:
|
|
if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sdr);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
|
|
return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
|
|
case V4L2_BUF_TYPE_SDR_OUTPUT:
|
|
if (unlikely(!ops->vidioc_try_fmt_sdr_out))
|
|
break;
|
|
- CLEAR_AFTER_FIELD(p, fmt.sdr);
|
|
+ CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize);
|
|
return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
|
|
case V4L2_BUF_TYPE_META_CAPTURE:
|
|
if (unlikely(!ops->vidioc_try_fmt_meta_cap))
|
|
|
|
From 32980a8e0329a5e1cff741284e1eefdaf595fd30 Mon Sep 17 00:00:00 2001
|
|
From: Pi-Hsun Shih <pihsun@chromium.org>
|
|
Date: Sun, 10 Nov 2019 07:29:10 +0100
|
|
Subject: [PATCH] media: v4l2-ctrl: Lock main_hdl on operations of
|
|
requests_queued.
|
|
|
|
There's a race condition between the list_del_init in the
|
|
v4l2_ctrl_request_complete, and the list_add_tail in the
|
|
v4l2_ctrl_request_queue, since they can be called in different thread
|
|
and the requests_queued list is not protected by a lock. This can lead
|
|
to that the v4l2_ctrl_handler is still in the requests_queued list while
|
|
the request_is_queued is already set to false, which would cause
|
|
use-after-free if the v4l2_ctrl_handler is later released.
|
|
|
|
Fix this by locking the ->lock of main_hdl (which is the owner of the
|
|
requests_queued list) when doing list operations on the
|
|
->requests_queued list.
|
|
|
|
Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit df4a3e7f88e3b0d7ae46d70b9ff8e3c0ea730785)
|
|
---
|
|
drivers/media/v4l2-core/v4l2-ctrls.c | 7 +++++++
|
|
1 file changed, 7 insertions(+)
|
|
|
|
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
index a565ae3ba7e4..2928c5e0a73d 100644
|
|
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
|
|
@@ -3302,6 +3302,7 @@ static void v4l2_ctrl_request_queue(struct media_request_object *obj)
|
|
struct v4l2_ctrl_handler *prev_hdl = NULL;
|
|
struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL;
|
|
|
|
+ mutex_lock(main_hdl->lock);
|
|
if (list_empty(&main_hdl->requests_queued))
|
|
goto queue;
|
|
|
|
@@ -3333,18 +3334,22 @@ static void v4l2_ctrl_request_queue(struct media_request_object *obj)
|
|
queue:
|
|
list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
|
|
hdl->request_is_queued = true;
|
|
+ mutex_unlock(main_hdl->lock);
|
|
}
|
|
|
|
static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
|
|
{
|
|
struct v4l2_ctrl_handler *hdl =
|
|
container_of(obj, struct v4l2_ctrl_handler, req_obj);
|
|
+ struct v4l2_ctrl_handler *main_hdl = obj->priv;
|
|
|
|
list_del_init(&hdl->requests);
|
|
+ mutex_lock(main_hdl->lock);
|
|
if (hdl->request_is_queued) {
|
|
list_del_init(&hdl->requests_queued);
|
|
hdl->request_is_queued = false;
|
|
}
|
|
+ mutex_unlock(main_hdl->lock);
|
|
}
|
|
|
|
static void v4l2_ctrl_request_release(struct media_request_object *obj)
|
|
@@ -4298,9 +4303,11 @@ void v4l2_ctrl_request_complete(struct media_request *req,
|
|
v4l2_ctrl_unlock(ctrl);
|
|
}
|
|
|
|
+ mutex_lock(main_hdl->lock);
|
|
WARN_ON(!hdl->request_is_queued);
|
|
list_del_init(&hdl->requests_queued);
|
|
hdl->request_is_queued = false;
|
|
+ mutex_unlock(main_hdl->lock);
|
|
media_request_object_complete(obj);
|
|
media_request_object_put(obj);
|
|
}
|
|
|
|
From 538378c5a4b78d449f2a4003fd0bf51941aea310 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Sun, 10 Nov 2019 07:30:01 +0100
|
|
Subject: [PATCH] media: cedrus: Properly signal size in mode register
|
|
|
|
Mode register also holds information if video width is bigger than 2048
|
|
and if it is equal to 4096.
|
|
|
|
Rework cedrus_engine_enable() to properly signal this properties.
|
|
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 3aef46bd5bf24a845e05d2531ed61f53ee8c7797)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 2 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h265.c | 2 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 9 +++++++--
|
|
drivers/staging/media/sunxi/cedrus/cedrus_hw.h | 2 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c | 2 +-
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 2 ++
|
|
6 files changed, 13 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index 74e4c5e3894e..8a09a08b1af2 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -485,7 +485,7 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
|
{
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
|
|
- cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
|
|
+ cedrus_engine_enable(ctx, CEDRUS_CODEC_H264);
|
|
|
|
cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
|
|
cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
index 9bc921866f70..6945dc74e1d7 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
|
|
@@ -276,7 +276,7 @@ static void cedrus_h265_setup(struct cedrus_ctx *ctx,
|
|
}
|
|
|
|
/* Activate H265 engine. */
|
|
- cedrus_engine_enable(dev, CEDRUS_CODEC_H265);
|
|
+ cedrus_engine_enable(ctx, CEDRUS_CODEC_H265);
|
|
|
|
/* Source offset and length in bits. */
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
index 93347d3ba360..daf5f244f93b 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
|
|
@@ -30,7 +30,7 @@
|
|
#include "cedrus_hw.h"
|
|
#include "cedrus_regs.h"
|
|
|
|
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
|
+int cedrus_engine_enable(struct cedrus_ctx *ctx, enum cedrus_codec codec)
|
|
{
|
|
u32 reg = 0;
|
|
|
|
@@ -58,7 +58,12 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
|
|
return -EINVAL;
|
|
}
|
|
|
|
- cedrus_write(dev, VE_MODE, reg);
|
|
+ if (ctx->src_fmt.width == 4096)
|
|
+ reg |= VE_MODE_PIC_WIDTH_IS_4096;
|
|
+ if (ctx->src_fmt.width > 2048)
|
|
+ reg |= VE_MODE_PIC_WIDTH_MORE_2048;
|
|
+
|
|
+ cedrus_write(ctx->dev, VE_MODE, reg);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
|
index 27d0882397aa..604ff932fbf5 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.h
|
|
@@ -16,7 +16,7 @@
|
|
#ifndef _CEDRUS_HW_H_
|
|
#define _CEDRUS_HW_H_
|
|
|
|
-int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec);
|
|
+int cedrus_engine_enable(struct cedrus_ctx *ctx, enum cedrus_codec codec);
|
|
void cedrus_engine_disable(struct cedrus_dev *dev);
|
|
|
|
void cedrus_dst_format_set(struct cedrus_dev *dev,
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
|
index 13c34927bad5..8bcd6b8f9e2d 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_mpeg2.c
|
|
@@ -96,7 +96,7 @@ static void cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
|
|
quantization = run->mpeg2.quantization;
|
|
|
|
/* Activate MPEG engine. */
|
|
- cedrus_engine_enable(dev, CEDRUS_CODEC_MPEG2);
|
|
+ cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2);
|
|
|
|
/* Set intra quantization matrix. */
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index 4275a307d282..ace3d49fcd82 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -35,6 +35,8 @@
|
|
|
|
#define VE_MODE 0x00
|
|
|
|
+#define VE_MODE_PIC_WIDTH_IS_4096 BIT(22)
|
|
+#define VE_MODE_PIC_WIDTH_MORE_2048 BIT(21)
|
|
#define VE_MODE_REC_WR_MODE_2MB (0x01 << 20)
|
|
#define VE_MODE_REC_WR_MODE_1MB (0x00 << 20)
|
|
#define VE_MODE_DDR_MODE_BW_128 (0x03 << 16)
|
|
|
|
From 515b592c54aacc047ca6e22b980cda16f91d6d38 Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Wed, 6 Nov 2019 22:05:37 +0100
|
|
Subject: [PATCH] media: cedrus: Fix H264 4k support
|
|
|
|
H264 decoder needs additional or bigger buffers in order to decode 4k
|
|
videos.
|
|
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 03e612e701a61aa9cc9fd8e25cd47d8d685ef675)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus.h | 7 ++
|
|
drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 91 +++++++++++++++++++++---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 11 +++
|
|
3 files changed, 101 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
index c45fb9a7ad07..96765555ab8a 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
|
|
@@ -116,8 +116,15 @@ struct cedrus_ctx {
|
|
ssize_t mv_col_buf_size;
|
|
void *pic_info_buf;
|
|
dma_addr_t pic_info_buf_dma;
|
|
+ ssize_t pic_info_buf_size;
|
|
void *neighbor_info_buf;
|
|
dma_addr_t neighbor_info_buf_dma;
|
|
+ void *deblk_buf;
|
|
+ dma_addr_t deblk_buf_dma;
|
|
+ ssize_t deblk_buf_size;
|
|
+ void *intra_pred_buf;
|
|
+ dma_addr_t intra_pred_buf_dma;
|
|
+ ssize_t intra_pred_buf_size;
|
|
} h264;
|
|
struct {
|
|
void *mv_col_buf;
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
index 8a09a08b1af2..bfb4a4820a67 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
|
|
@@ -39,7 +39,7 @@ struct cedrus_h264_sram_ref_pic {
|
|
#define CEDRUS_H264_FRAME_NUM 18
|
|
|
|
#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
|
|
-#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
|
|
+#define CEDRUS_MIN_PIC_INFO_BUF_SIZE (130 * SZ_1K)
|
|
|
|
static void cedrus_h264_write_sram(struct cedrus_dev *dev,
|
|
enum cedrus_h264_sram_off off,
|
|
@@ -342,6 +342,20 @@ static void cedrus_set_params(struct cedrus_ctx *ctx,
|
|
VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
|
|
VE_H264_VLD_ADDR_LAST);
|
|
|
|
+ if (ctx->src_fmt.width > 2048) {
|
|
+ cedrus_write(dev, VE_BUF_CTRL,
|
|
+ VE_BUF_CTRL_INTRAPRED_MIXED_RAM |
|
|
+ VE_BUF_CTRL_DBLK_MIXED_RAM);
|
|
+ cedrus_write(dev, VE_DBLK_DRAM_BUF_ADDR,
|
|
+ ctx->codec.h264.deblk_buf_dma);
|
|
+ cedrus_write(dev, VE_INTRAPRED_DRAM_BUF_ADDR,
|
|
+ ctx->codec.h264.intra_pred_buf_dma);
|
|
+ } else {
|
|
+ cedrus_write(dev, VE_BUF_CTRL,
|
|
+ VE_BUF_CTRL_INTRAPRED_INT_SRAM |
|
|
+ VE_BUF_CTRL_DBLK_INT_SRAM);
|
|
+ }
|
|
+
|
|
/*
|
|
* FIXME: Since the bitstream parsing is done in software, and
|
|
* in userspace, this shouldn't be needed anymore. But it
|
|
@@ -502,18 +516,30 @@ static void cedrus_h264_setup(struct cedrus_ctx *ctx,
|
|
static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
|
{
|
|
struct cedrus_dev *dev = ctx->dev;
|
|
+ unsigned int pic_info_size;
|
|
unsigned int field_size;
|
|
unsigned int mv_col_size;
|
|
int ret;
|
|
|
|
+ /* Formula for picture buffer size is taken from CedarX source. */
|
|
+
|
|
+ if (ctx->src_fmt.width > 2048)
|
|
+ pic_info_size = CEDRUS_H264_FRAME_NUM * 0x4000;
|
|
+ else
|
|
+ pic_info_size = CEDRUS_H264_FRAME_NUM * 0x1000;
|
|
+
|
|
/*
|
|
- * FIXME: It seems that the H6 cedarX code is using a formula
|
|
- * here based on the size of the frame, while all the older
|
|
- * code is using a fixed size, so that might need to be
|
|
- * changed at some point.
|
|
+ * FIXME: If V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY is set,
|
|
+ * there is no need to multiply by 2.
|
|
*/
|
|
+ pic_info_size += ctx->src_fmt.height * 2 * 64;
|
|
+
|
|
+ if (pic_info_size < CEDRUS_MIN_PIC_INFO_BUF_SIZE)
|
|
+ pic_info_size = CEDRUS_MIN_PIC_INFO_BUF_SIZE;
|
|
+
|
|
+ ctx->codec.h264.pic_info_buf_size = pic_info_size;
|
|
ctx->codec.h264.pic_info_buf =
|
|
- dma_alloc_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
|
|
+ dma_alloc_coherent(dev->dev, ctx->codec.h264.pic_info_buf_size,
|
|
&ctx->codec.h264.pic_info_buf_dma,
|
|
GFP_KERNEL);
|
|
if (!ctx->codec.h264.pic_info_buf)
|
|
@@ -566,15 +592,56 @@ static int cedrus_h264_start(struct cedrus_ctx *ctx)
|
|
goto err_neighbor_buf;
|
|
}
|
|
|
|
+ if (ctx->src_fmt.width > 2048) {
|
|
+ /*
|
|
+ * Formulas for deblock and intra prediction buffer sizes
|
|
+ * are taken from CedarX source.
|
|
+ */
|
|
+
|
|
+ ctx->codec.h264.deblk_buf_size =
|
|
+ ALIGN(ctx->src_fmt.width, 32) * 12;
|
|
+ ctx->codec.h264.deblk_buf =
|
|
+ dma_alloc_coherent(dev->dev,
|
|
+ ctx->codec.h264.deblk_buf_size,
|
|
+ &ctx->codec.h264.deblk_buf_dma,
|
|
+ GFP_KERNEL);
|
|
+ if (!ctx->codec.h264.deblk_buf) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err_mv_col_buf;
|
|
+ }
|
|
+
|
|
+ ctx->codec.h264.intra_pred_buf_size =
|
|
+ ALIGN(ctx->src_fmt.width, 64) * 5;
|
|
+ ctx->codec.h264.intra_pred_buf =
|
|
+ dma_alloc_coherent(dev->dev,
|
|
+ ctx->codec.h264.intra_pred_buf_size,
|
|
+ &ctx->codec.h264.intra_pred_buf_dma,
|
|
+ GFP_KERNEL);
|
|
+ if (!ctx->codec.h264.intra_pred_buf) {
|
|
+ ret = -ENOMEM;
|
|
+ goto err_deblk_buf;
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
+err_deblk_buf:
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
|
+ ctx->codec.h264.deblk_buf,
|
|
+ ctx->codec.h264.deblk_buf_dma);
|
|
+
|
|
+err_mv_col_buf:
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
|
|
+ ctx->codec.h264.mv_col_buf,
|
|
+ ctx->codec.h264.mv_col_buf_dma);
|
|
+
|
|
err_neighbor_buf:
|
|
dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
|
ctx->codec.h264.neighbor_info_buf,
|
|
ctx->codec.h264.neighbor_info_buf_dma);
|
|
|
|
err_pic_buf:
|
|
- dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.pic_info_buf_size,
|
|
ctx->codec.h264.pic_info_buf,
|
|
ctx->codec.h264.pic_info_buf_dma);
|
|
return ret;
|
|
@@ -590,9 +657,17 @@ static void cedrus_h264_stop(struct cedrus_ctx *ctx)
|
|
dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
|
|
ctx->codec.h264.neighbor_info_buf,
|
|
ctx->codec.h264.neighbor_info_buf_dma);
|
|
- dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.pic_info_buf_size,
|
|
ctx->codec.h264.pic_info_buf,
|
|
ctx->codec.h264.pic_info_buf_dma);
|
|
+ if (ctx->codec.h264.deblk_buf_size)
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.deblk_buf_size,
|
|
+ ctx->codec.h264.deblk_buf,
|
|
+ ctx->codec.h264.deblk_buf_dma);
|
|
+ if (ctx->codec.h264.intra_pred_buf_size)
|
|
+ dma_free_coherent(dev->dev, ctx->codec.h264.intra_pred_buf_size,
|
|
+ ctx->codec.h264.intra_pred_buf,
|
|
+ ctx->codec.h264.intra_pred_buf_dma);
|
|
}
|
|
|
|
static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
index ace3d49fcd82..7beb03d3bb39 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
|
|
@@ -46,6 +46,17 @@
|
|
#define VE_MODE_DEC_H264 (0x01 << 0)
|
|
#define VE_MODE_DEC_MPEG (0x00 << 0)
|
|
|
|
+#define VE_BUF_CTRL 0x50
|
|
+
|
|
+#define VE_BUF_CTRL_INTRAPRED_EXT_RAM (0x02 << 2)
|
|
+#define VE_BUF_CTRL_INTRAPRED_MIXED_RAM (0x01 << 2)
|
|
+#define VE_BUF_CTRL_INTRAPRED_INT_SRAM (0x00 << 2)
|
|
+#define VE_BUF_CTRL_DBLK_EXT_RAM (0x02 << 0)
|
|
+#define VE_BUF_CTRL_DBLK_MIXED_RAM (0x01 << 0)
|
|
+#define VE_BUF_CTRL_DBLK_INT_SRAM (0x00 << 0)
|
|
+
|
|
+#define VE_DBLK_DRAM_BUF_ADDR 0x54
|
|
+#define VE_INTRAPRED_DRAM_BUF_ADDR 0x58
|
|
#define VE_PRIMARY_CHROMA_BUF_LEN 0xc4
|
|
#define VE_PRIMARY_FB_LINE_STRIDE 0xc8
|
|
|
|
|
|
From c2db69a81e21e9f3d39a77c445af0c0692d5fece Mon Sep 17 00:00:00 2001
|
|
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Date: Wed, 6 Nov 2019 22:05:38 +0100
|
|
Subject: [PATCH] media: cedrus: Increase maximum supported size
|
|
|
|
There are few variations of 4k resolutions. The biggest one is
|
|
4096x2304 which is also supported by HW. It has also nice property that
|
|
both width and size are divisible by maximum HEVC CTB size, which is 64.
|
|
|
|
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
|
Acked-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 0b3e5c15f9cb8b56599c50e6bf4f46ee1c1253bc)
|
|
---
|
|
drivers/staging/media/sunxi/cedrus/cedrus_video.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
index cc15a5cf107d..15cf1f10221b 100644
|
|
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
|
|
@@ -29,8 +29,8 @@
|
|
|
|
#define CEDRUS_MIN_WIDTH 16U
|
|
#define CEDRUS_MIN_HEIGHT 16U
|
|
-#define CEDRUS_MAX_WIDTH 3840U
|
|
-#define CEDRUS_MAX_HEIGHT 2160U
|
|
+#define CEDRUS_MAX_WIDTH 4096U
|
|
+#define CEDRUS_MAX_HEIGHT 2304U
|
|
|
|
static struct cedrus_format cedrus_formats[] = {
|
|
{
|
|
|
|
From 2bde57c192c63d5f6eb619e6409834f91937f22a Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sat, 9 Nov 2019 14:03:08 +0100
|
|
Subject: [PATCH] media: vim2m: media_device_cleanup was called too early
|
|
|
|
Running the contrib/test/test-media script in v4l-utils with the vim2m argument
|
|
will cause this kernel warning:
|
|
|
|
[ 554.430157] ------------[ cut here ]------------
|
|
[ 554.433034] DEBUG_LOCKS_WARN_ON(lock->magic != lock)
|
|
[ 554.433064] WARNING: CPU: 0 PID: 616 at kernel/locking/mutex.c:938 __mutex_lock+0xd7a/0x1380
|
|
[ 554.439736] Modules linked in: vim2m v4l2_mem2mem vivid rc_cec videobuf2_dma_contig v4l2_dv_timings cec videobuf2_vmalloc videobuf2_memops v4l2_tpg videobuf2_v4l2 videobuf2_common videodev mc rc_core [last unloaded: vivid]
|
|
[ 554.445794] CPU: 0 PID: 616 Comm: sleep Not tainted 5.4.0-rc1-virtme #1
|
|
[ 554.448481] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-0-ga698c8995f-prebuilt.qemu.org 04/01/2014
|
|
[ 554.453088] RIP: 0010:__mutex_lock+0xd7a/0x1380
|
|
[ 554.454955] Code: d2 0f 85 de 05 00 00 44 8b 05 82 d9 f7 00 45 85 c0 0f 85 bf f3 ff ff 48 c7 c6 e0 30 a6 b7 48 c7 c7 e0 2e a6 b7 e8 5c 76 36 fe <0f> 0b e9 a5 f3 ff ff 65 48 8b 1c 25 80 ef 01 00 be 08 00 00 00 48
|
|
[ 554.462836] RSP: 0018:ffff88803a4cfad0 EFLAGS: 00010282
|
|
[ 554.465129] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffffb5a3d24f
|
|
[ 554.468143] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffffb85273f4
|
|
[ 554.471000] RBP: ffff88803a4cfc50 R08: fffffbfff701e681 R09: fffffbfff701e681
|
|
[ 554.473990] R10: fffffbfff701e680 R11: ffffffffb80f3403 R12: 0000000000000000
|
|
[ 554.476831] R13: dffffc0000000000 R14: ffffffffb9714f00 R15: ffff888053103fc8
|
|
[ 554.479622] FS: 00007fac6358a540(0000) GS:ffff88805d000000(0000) knlGS:0000000000000000
|
|
[ 554.482673] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
[ 554.484949] CR2: 00007fac6343faf0 CR3: 0000000036c22000 CR4: 00000000003406f0
|
|
[ 554.487811] Call Trace:
|
|
[ 554.488860] ? v4l2_release+0x1b8/0x390 [videodev]
|
|
[ 554.490818] ? do_exit+0x946/0x2980
|
|
[ 554.492269] ? mutex_lock_io_nested+0x1250/0x1250
|
|
[ 554.494128] ? __lock_acquire+0xe90/0x3c30
|
|
[ 554.495774] ? fsnotify_first_mark+0x120/0x120
|
|
[ 554.497487] ? vim2m_device_release+0x50/0x50 [vim2m]
|
|
[ 554.499469] ? v4l2_release+0x1b8/0x390 [videodev]
|
|
[ 554.501493] v4l2_release+0x1b8/0x390 [videodev]
|
|
[ 554.503430] __fput+0x256/0x790
|
|
[ 554.504711] task_work_run+0x109/0x190
|
|
[ 554.506145] do_exit+0x95e/0x2980
|
|
[ 554.507421] ? vfs_lock_file+0x21/0xf0
|
|
[ 554.509013] ? find_held_lock+0x33/0x1c0
|
|
[ 554.510382] ? __close_fd+0xee/0x190
|
|
[ 554.511862] ? release_task.part.21+0x1310/0x1310
|
|
[ 554.513701] ? lock_downgrade+0x6d0/0x6d0
|
|
[ 554.515299] do_group_exit+0xeb/0x2d0
|
|
[ 554.516862] __x64_sys_exit_group+0x35/0x40
|
|
[ 554.518610] do_syscall_64+0x90/0x450
|
|
[ 554.520142] entry_SYSCALL_64_after_hwframe+0x49/0xbe
|
|
[ 554.522289] RIP: 0033:0x7fac6348ecf6
|
|
[ 554.523876] Code: Bad RIP value.
|
|
[ 554.525294] RSP: 002b:00007ffe6373dc58 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
|
|
[ 554.528555] RAX: ffffffffffffffda RBX: 00007fac6357f760 RCX: 00007fac6348ecf6
|
|
[ 554.531537] RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
|
|
[ 554.534709] RBP: 0000000000000000 R08: 00000000000000e7 R09: ffffffffffffff80
|
|
[ 554.536752] R10: 00007ffe6373db24 R11: 0000000000000246 R12: 00007fac6357f760
|
|
[ 554.538643] R13: 0000000000000002 R14: 00007fac63588428 R15: 0000000000000000
|
|
[ 554.540634] irq event stamp: 21731
|
|
[ 554.541618] hardirqs last enabled at (21731): [<ffffffffb75b3cd4>] _raw_spin_unlock_irq+0x24/0x30
|
|
[ 554.544145] hardirqs last disabled at (21730): [<ffffffffb75b3ada>] _raw_spin_lock_irq+0xa/0x40
|
|
[ 554.547027] softirqs last enabled at (20148): [<ffffffffb780064d>] __do_softirq+0x64d/0x906
|
|
[ 554.550385] softirqs last disabled at (19857): [<ffffffffb5926bd5>] irq_exit+0x175/0x1a0
|
|
[ 554.553668] ---[ end trace a389c80c2ca84244 ]---
|
|
|
|
This is caused by media_device_cleanup() which destroys
|
|
v4l2_dev->mdev->req_queue_mutex. But v4l2_release() tries to lock
|
|
that mutex after media_device_cleanup() is called.
|
|
|
|
By moving media_device_cleanup() to the video_device's release function it is
|
|
guaranteed that the mutex is valid whenever v4l2_release is called.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 9f22e88a4bba270d3427684cee84dfbf67489e86)
|
|
---
|
|
drivers/media/platform/vim2m.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
|
|
index e17792f837f8..8d6b09623d88 100644
|
|
--- a/drivers/media/platform/vim2m.c
|
|
+++ b/drivers/media/platform/vim2m.c
|
|
@@ -1275,6 +1275,9 @@ static void vim2m_device_release(struct video_device *vdev)
|
|
|
|
v4l2_device_unregister(&dev->v4l2_dev);
|
|
v4l2_m2m_release(dev->m2m_dev);
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
+ media_device_cleanup(&dev->mdev);
|
|
+#endif
|
|
kfree(dev);
|
|
}
|
|
|
|
@@ -1399,7 +1402,6 @@ static int vim2m_remove(struct platform_device *pdev)
|
|
#ifdef CONFIG_MEDIA_CONTROLLER
|
|
media_device_unregister(&dev->mdev);
|
|
v4l2_m2m_unregister_media_controller(dev->m2m_dev);
|
|
- media_device_cleanup(&dev->mdev);
|
|
#endif
|
|
video_unregister_device(&dev->vfd);
|
|
|
|
|
|
From 2be33bcf4943c063365c97bd0945f776ef49a0c6 Mon Sep 17 00:00:00 2001
|
|
From: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Date: Sat, 9 Nov 2019 15:06:18 +0100
|
|
Subject: [PATCH] media: vicodec: media_device_cleanup was called too early
|
|
|
|
Running the contrib/test/test-media script in v4l-utils with the vicodec argument
|
|
will cause this kernel warning:
|
|
|
|
[ 372.298824] ------------[ cut here ]------------
|
|
[ 372.298848] DEBUG_LOCKS_WARN_ON(lock->magic != lock)
|
|
[ 372.298896] WARNING: CPU: 11 PID: 2220 at kernel/locking/mutex.c:938 __mutex_lock+0x919/0xc10
|
|
[ 372.298907] Modules linked in: vicodec v4l2_mem2mem vivid rc_cec v4l2_tpg videobuf2_dma_contig cec rc_core v4l2_dv_timings videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev mc vmw_balloon vmw_vmci button vmwgfx [last unloaded: vimc]
|
|
[ 372.298961] CPU: 11 PID: 2220 Comm: sleep Not tainted 5.4.0-rc1-test-no #150
|
|
[ 372.298970] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
|
|
[ 372.298983] RIP: 0010:__mutex_lock+0x919/0xc10
|
|
[ 372.298995] Code: 59 83 e8 9a fc 16 ff 44 8b 05 23 61 38 01 45 85 c0 0f 85 ef f7 ff ff 48 c7 c6 a0 1f 87 82 48 c7 c7 a0 1e 87 82 e8 cd bb f7 fe <0f> 0b e9 d5 f7 ff ff f6 c3 04 0f 84 3b fd ff ff 49 89 df 41 83 e7
|
|
[ 372.299004] RSP: 0018:ffff8881b400fb80 EFLAGS: 00010286
|
|
[ 372.299014] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
|
|
[ 372.299022] RDX: 0000000000000003 RSI: 0000000000000004 RDI: ffffed1036801f62
|
|
[ 372.299030] RBP: ffff8881b400fcf0 R08: ffffffff81217c91 R09: fffffbfff061c271
|
|
[ 372.299038] R10: fffffbfff061c270 R11: ffffffff830e1383 R12: ffff88814761dc80
|
|
[ 372.299046] R13: 0000000000000000 R14: ffff88814761cbf0 R15: ffff88814761d030
|
|
[ 372.299055] FS: 0000000000000000(0000) GS:ffff8881b68c0000(0000) knlGS:0000000000000000
|
|
[ 372.299063] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
|
[ 372.299071] CR2: 00007f606d78aa20 CR3: 0000000003013002 CR4: 00000000001606e0
|
|
[ 372.299153] Call Trace:
|
|
[ 372.299176] ? __kasan_slab_free+0x12f/0x180
|
|
[ 372.299187] ? kmem_cache_free+0x9b/0x250
|
|
[ 372.299200] ? do_exit+0xcdf/0x1200
|
|
[ 372.299210] ? do_group_exit+0x85/0x130
|
|
[ 372.299220] ? __x64_sys_exit_group+0x23/0x30
|
|
[ 372.299231] ? do_syscall_64+0x5e/0x1c0
|
|
[ 372.299241] ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
|
[ 372.299295] ? v4l2_release+0xed/0x190 [videodev]
|
|
[ 372.299309] ? mutex_lock_io_nested+0xb80/0xb80
|
|
[ 372.299323] ? find_held_lock+0x85/0xa0
|
|
[ 372.299335] ? fsnotify+0x5b0/0x600
|
|
[ 372.299351] ? locks_remove_file+0x78/0x2b0
|
|
[ 372.299363] ? __fsnotify_update_child_dentry_flags.part.0+0x170/0x170
|
|
[ 372.299383] ? vidioc_querycap+0x50/0x50 [vicodec]
|
|
[ 372.299426] ? v4l2_release+0xed/0x190 [videodev]
|
|
[ 372.299467] v4l2_release+0xed/0x190 [videodev]
|
|
[ 372.299484] __fput+0x15a/0x390
|
|
[ 372.299499] task_work_run+0xb2/0xe0
|
|
[ 372.299512] do_exit+0x4d0/0x1200
|
|
[ 372.299528] ? do_user_addr_fault+0x367/0x610
|
|
[ 372.299538] ? release_task+0x990/0x990
|
|
[ 372.299552] ? rwsem_spin_on_owner+0x170/0x170
|
|
[ 372.299567] ? vmacache_find+0xb2/0x100
|
|
[ 372.299580] do_group_exit+0x85/0x130
|
|
[ 372.299592] __x64_sys_exit_group+0x23/0x30
|
|
[ 372.299602] do_syscall_64+0x5e/0x1c0
|
|
[ 372.299614] entry_SYSCALL_64_after_hwframe+0x44/0xa9
|
|
[ 372.299624] RIP: 0033:0x7f606d74a9d6
|
|
[ 372.299640] Code: Bad RIP value.
|
|
[ 372.299648] RSP: 002b:00007fff65364468 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7
|
|
[ 372.299658] RAX: ffffffffffffffda RBX: 00007f606d83b760 RCX: 00007f606d74a9d6
|
|
[ 372.299666] RDX: 0000000000000000 RSI: 000000000000003c RDI: 0000000000000000
|
|
[ 372.299673] RBP: 0000000000000000 R08: 00000000000000e7 R09: ffffffffffffff80
|
|
[ 372.299681] R10: 00007fff65364334 R11: 0000000000000246 R12: 00007f606d83b760
|
|
[ 372.299689] R13: 0000000000000002 R14: 00007f606d844428 R15: 0000000000000000
|
|
[ 372.299704] ---[ end trace add7d62ca4bc65e3 ]---
|
|
|
|
This is caused by media_device_cleanup() which destroys
|
|
v4l2_dev->mdev->req_queue_mutex. But v4l2_release() tries to lock
|
|
that mutex after media_device_cleanup() is called.
|
|
|
|
By moving media_device_cleanup() to the v4l2_device's release function it is
|
|
guaranteed that the mutex is valid whenever v4l2_release is called.
|
|
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
(cherry picked from commit 693c5f144aeb9636ae161a3c61a838c50b2ae41c)
|
|
---
|
|
drivers/media/platform/vicodec/vicodec-core.c | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
|
|
index 0ee143ae0f6b..82350097503e 100644
|
|
--- a/drivers/media/platform/vicodec/vicodec-core.c
|
|
+++ b/drivers/media/platform/vicodec/vicodec-core.c
|
|
@@ -2139,6 +2139,9 @@ static void vicodec_v4l2_dev_release(struct v4l2_device *v4l2_dev)
|
|
v4l2_m2m_release(dev->stateful_enc.m2m_dev);
|
|
v4l2_m2m_release(dev->stateful_dec.m2m_dev);
|
|
v4l2_m2m_release(dev->stateless_dec.m2m_dev);
|
|
+#ifdef CONFIG_MEDIA_CONTROLLER
|
|
+ media_device_cleanup(&dev->mdev);
|
|
+#endif
|
|
kfree(dev);
|
|
}
|
|
|
|
@@ -2250,7 +2253,6 @@ static int vicodec_remove(struct platform_device *pdev)
|
|
v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
|
|
v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
|
|
v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
|
|
- media_device_cleanup(&dev->mdev);
|
|
#endif
|
|
|
|
video_unregister_device(&dev->stateful_enc.vfd);
|
|
|
|
From a3415fcc470a3f53c951b98acca487c0ddd2d306 Mon Sep 17 00:00:00 2001
|
|
From: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Date: Mon, 7 Oct 2019 19:45:02 +0200
|
|
Subject: [PATCH] media: hantro: Fix s_fmt for dynamic resolution changes
|
|
|
|
Commit 953aaa1492c53 ("media: rockchip/vpu: Prepare things to support decoders")
|
|
changed the conditions under S_FMT was allowed for OUTPUT
|
|
CAPTURE buffers.
|
|
|
|
However, and according to the mem-to-mem stateless decoder specification,
|
|
in order to support dynamic resolution changes, S_FMT should be allowed
|
|
even if OUTPUT buffers have been allocated.
|
|
|
|
Relax decoder S_FMT restrictions on OUTPUT buffers, allowing a
|
|
resolution modification, provided the pixel format stays the same.
|
|
|
|
Tested on RK3288 platforms using ChromiumOS Video Decode/Encode
|
|
Accelerator Unittests.
|
|
|
|
[hverkuil: fix typo: In other -> In order]
|
|
|
|
Fixes: 953aaa1492c53 ("media: rockchip/vpu: Prepare things to support decoders")
|
|
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Cc: <stable@vger.kernel.org> # for v5.4 and up
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit ae02d49493b5d32bb3e035fdeb1655346f5e1ea5)
|
|
---
|
|
drivers/staging/media/hantro/hantro_v4l2.c | 28 +++++++++++++++++++---------
|
|
1 file changed, 19 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
|
|
index 3dae52abb96c..fcf95c1d39ca 100644
|
|
--- a/drivers/staging/media/hantro/hantro_v4l2.c
|
|
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
|
|
@@ -367,19 +367,26 @@ vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
|
|
{
|
|
struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
|
|
struct hantro_ctx *ctx = fh_to_ctx(priv);
|
|
+ struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
|
|
const struct hantro_fmt *formats;
|
|
unsigned int num_fmts;
|
|
- struct vb2_queue *vq;
|
|
int ret;
|
|
|
|
- /* Change not allowed if queue is busy. */
|
|
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
|
|
- if (vb2_is_busy(vq))
|
|
- return -EBUSY;
|
|
+ ret = vidioc_try_fmt_out_mplane(file, priv, f);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
if (!hantro_is_encoder_ctx(ctx)) {
|
|
struct vb2_queue *peer_vq;
|
|
|
|
+ /*
|
|
+ * In order to support dynamic resolution change,
|
|
+ * the decoder admits a resolution change, as long
|
|
+ * as the pixelformat remains. Can't be done if streaming.
|
|
+ */
|
|
+ if (vb2_is_streaming(vq) || (vb2_is_busy(vq) &&
|
|
+ pix_mp->pixelformat != ctx->src_fmt.pixelformat))
|
|
+ return -EBUSY;
|
|
/*
|
|
* Since format change on the OUTPUT queue will reset
|
|
* the CAPTURE queue, we can't allow doing so
|
|
@@ -389,12 +396,15 @@ vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
|
|
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
|
if (vb2_is_busy(peer_vq))
|
|
return -EBUSY;
|
|
+ } else {
|
|
+ /*
|
|
+ * The encoder doesn't admit a format change if
|
|
+ * there are OUTPUT buffers allocated.
|
|
+ */
|
|
+ if (vb2_is_busy(vq))
|
|
+ return -EBUSY;
|
|
}
|
|
|
|
- ret = vidioc_try_fmt_out_mplane(file, priv, f);
|
|
- if (ret)
|
|
- return ret;
|
|
-
|
|
formats = hantro_get_formats(ctx, &num_fmts);
|
|
ctx->vpu_src_fmt = hantro_find_format(formats, num_fmts,
|
|
pix_mp->pixelformat);
|
|
|
|
From a658b212463bb2d125e5dff85adb96842848204b Mon Sep 17 00:00:00 2001
|
|
From: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Date: Fri, 25 Oct 2019 11:47:06 +0200
|
|
Subject: [PATCH] media: Documentation: media: *_DEFAULT targets for subdevs
|
|
|
|
Some sensors have optical blanking areas, this is, pixels that are
|
|
painted and do not account for light, only noise.
|
|
|
|
These special pixels are very useful for calibrating the sensor, but
|
|
should not be displayed on a DEFAULT target.
|
|
|
|
Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org>
|
|
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 4edead77fa16ac4ec880ebceed83da2415401d18)
|
|
---
|
|
Documentation/media/uapi/v4l/v4l2-selection-targets.rst | 4 +++-
|
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst
|
|
index f74f239b0510..aae0c0013eb1 100644
|
|
--- a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst
|
|
+++ b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst
|
|
@@ -38,8 +38,10 @@ of the two interfaces they are used.
|
|
* - ``V4L2_SEL_TGT_CROP_DEFAULT``
|
|
- 0x0001
|
|
- Suggested cropping rectangle that covers the "whole picture".
|
|
+ This includes only active pixels and excludes other non-active
|
|
+ pixels such as black pixels.
|
|
+ - Yes
|
|
- Yes
|
|
- - No
|
|
* - ``V4L2_SEL_TGT_CROP_BOUNDS``
|
|
- 0x0002
|
|
- Bounds of the crop rectangle. All valid crop rectangles fit inside
|
|
|
|
From 1adb49eed13a6f8742bf988577886ba93350e276 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Wed, 6 Nov 2019 23:34:20 +0100
|
|
Subject: [PATCH] media: hantro: Fix H264 motion vector buffer offset
|
|
|
|
A decoded 8-bit 4:2:0 frame need memory for up to 448 bytes per
|
|
macroblock and is laid out in memory as follow:
|
|
|
|
+---------------------------+
|
|
| Y-plane 256 bytes x MBs |
|
|
+---------------------------+
|
|
| UV-plane 128 bytes x MBs |
|
|
+---------------------------+
|
|
| MV buffer 64 bytes x MBs |
|
|
+---------------------------+
|
|
|
|
The motion vector buffer offset is currently correct for 4:2:0 because
|
|
the extra space for motion vectors is overallocated with an extra
|
|
64 bytes x MBs.
|
|
|
|
Wrong offset for both destination and motion vector buffer are used
|
|
for the bottom field of field encoded content, wrong offset is
|
|
also used for 4:0:0 (monochrome) content.
|
|
|
|
Fix this by setting the motion vector address to the expected 384 bytes
|
|
x MBs offset for 4:2:0 and 256 bytes x MBs offset for 4:0:0 content.
|
|
|
|
Also use correct destination and motion vector buffer offset
|
|
for the bottom field of field encoded content.
|
|
|
|
While at it also extend the check for 4:0:0 (monochrome) to include an
|
|
additional check for High Profile (100).
|
|
|
|
Fixes: dea0a82f3d22 ("media: hantro: Add support for H264 decoding on G1")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 329f268821509b9a3713f1bc3680d298d61d6230)
|
|
---
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 31 ++++++++++++++++-------
|
|
1 file changed, 22 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index 70a6b5b26477..30d977c3d529 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -81,7 +81,7 @@ static void set_params(struct hantro_ctx *ctx)
|
|
reg |= G1_REG_DEC_CTRL4_CABAC_E;
|
|
if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
|
|
reg |= G1_REG_DEC_CTRL4_DIR_8X8_INFER_E;
|
|
- if (sps->chroma_format_idc == 0)
|
|
+ if (sps->profile_idc >= 100 && sps->chroma_format_idc == 0)
|
|
reg |= G1_REG_DEC_CTRL4_BLACKWHITE_E;
|
|
if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
|
|
reg |= G1_REG_DEC_CTRL4_WEIGHT_PRED_E;
|
|
@@ -234,6 +234,7 @@ static void set_buffers(struct hantro_ctx *ctx)
|
|
struct vb2_v4l2_buffer *src_buf, *dst_buf;
|
|
struct hantro_dev *vpu = ctx->dev;
|
|
dma_addr_t src_dma, dst_dma;
|
|
+ size_t offset = 0;
|
|
|
|
src_buf = hantro_get_src_buf(ctx);
|
|
dst_buf = hantro_get_dst_buf(ctx);
|
|
@@ -244,18 +245,30 @@ static void set_buffers(struct hantro_ctx *ctx)
|
|
|
|
/* Destination (decoded frame) buffer. */
|
|
dst_dma = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
|
|
- vdpu_write_relaxed(vpu, dst_dma, G1_REG_ADDR_DST);
|
|
+ /* Adjust dma addr to start at second line for bottom field */
|
|
+ if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
|
|
+ offset = ALIGN(ctx->src_fmt.width, MB_DIM);
|
|
+ vdpu_write_relaxed(vpu, dst_dma + offset, G1_REG_ADDR_DST);
|
|
|
|
/* Higher profiles require DMV buffer appended to reference frames. */
|
|
if (ctrls->sps->profile_idc > 66 && ctrls->decode->nal_ref_idc) {
|
|
- size_t pic_size = ctx->h264_dec.pic_size;
|
|
- size_t mv_offset = round_up(pic_size, 8);
|
|
-
|
|
+ unsigned int bytes_per_mb = 384;
|
|
+
|
|
+ /* DMV buffer for monochrome start directly after Y-plane */
|
|
+ if (ctrls->sps->profile_idc >= 100 &&
|
|
+ ctrls->sps->chroma_format_idc == 0)
|
|
+ bytes_per_mb = 256;
|
|
+ offset = bytes_per_mb * MB_WIDTH(ctx->src_fmt.width) *
|
|
+ MB_HEIGHT(ctx->src_fmt.height);
|
|
+
|
|
+ /*
|
|
+ * 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)
|
|
- mv_offset += 32 * MB_WIDTH(ctx->dst_fmt.width);
|
|
-
|
|
- vdpu_write_relaxed(vpu, dst_dma + mv_offset,
|
|
- G1_REG_ADDR_DIR_MV);
|
|
+ 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);
|
|
}
|
|
|
|
/* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */
|
|
|
|
From da6581be9271f0109917f168468cad8bf224cfd6 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Wed, 6 Nov 2019 23:34:21 +0100
|
|
Subject: [PATCH] media: hantro: Reduce H264 extra space for motion vectors
|
|
|
|
A decoded 8-bit 4:2:0 frame need memory for up to 448 bytes per
|
|
macroblock with additional 32 bytes on multi-core variants.
|
|
|
|
Memory layout is as follow:
|
|
|
|
+---------------------------+
|
|
| Y-plane 256 bytes x MBs |
|
|
+---------------------------+
|
|
| UV-plane 128 bytes x MBs |
|
|
+---------------------------+
|
|
| MV buffer 64 bytes x MBs |
|
|
+---------------------------+
|
|
| MC sync 32 bytes |
|
|
+---------------------------+
|
|
|
|
Reduce the extra space allocated now that motion vector buffer offset no
|
|
longer is based on the extra space.
|
|
|
|
Only allocate extra space for 64 bytes x MBs of motion vector buffer
|
|
and 32 bytes for multi-core sync.
|
|
|
|
Fixes: a9471e25629b ("media: hantro: Add core bits to support H264 decoding")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit a8fe996084e358c6f4ec7c51ec28fd3c1ddf68d1)
|
|
---
|
|
drivers/staging/media/hantro/hantro_v4l2.c | 20 ++++++++++++++++++--
|
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
|
|
index fcf95c1d39ca..1dae76f20034 100644
|
|
--- a/drivers/staging/media/hantro/hantro_v4l2.c
|
|
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
|
|
@@ -240,14 +240,30 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
|
|
v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
|
|
pix_mp->height);
|
|
/*
|
|
+ * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
|
|
+ * 448 bytes per macroblock with additional 32 bytes on
|
|
+ * multi-core variants.
|
|
+ *
|
|
* The H264 decoder needs extra space on the output buffers
|
|
* to store motion vectors. This is needed for reference
|
|
* frames.
|
|
+ *
|
|
+ * Memory layout is as follow:
|
|
+ *
|
|
+ * +---------------------------+
|
|
+ * | Y-plane 256 bytes x MBs |
|
|
+ * +---------------------------+
|
|
+ * | UV-plane 128 bytes x MBs |
|
|
+ * +---------------------------+
|
|
+ * | MV buffer 64 bytes x MBs |
|
|
+ * +---------------------------+
|
|
+ * | MC sync 32 bytes |
|
|
+ * +---------------------------+
|
|
*/
|
|
if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
|
|
pix_mp->plane_fmt[0].sizeimage +=
|
|
- 128 * DIV_ROUND_UP(pix_mp->width, 16) *
|
|
- DIV_ROUND_UP(pix_mp->height, 16);
|
|
+ 64 * MB_WIDTH(pix_mp->width) *
|
|
+ MB_WIDTH(pix_mp->height) + 32;
|
|
} else if (!pix_mp->plane_fmt[0].sizeimage) {
|
|
/*
|
|
* For coded formats the application can specify
|
|
|
|
From 820d9302b1972d314e810bf1c592f5cc95d44471 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Wed, 6 Nov 2019 23:34:22 +0100
|
|
Subject: [PATCH] media: hantro: Use output buffer width and height for H264
|
|
decoding
|
|
|
|
Calculations for motion vector buffer offset is based on width and height
|
|
from the configured output format, lets use the same values for macroblock
|
|
width and height hw regs.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 79c523291ea22f5b3289d92f180ed6b76fd80502)
|
|
---
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index 30d977c3d529..27d40d8d3728 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -51,8 +51,8 @@ static void set_params(struct hantro_ctx *ctx)
|
|
vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0);
|
|
|
|
/* Decoder control register 1. */
|
|
- reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(sps->pic_width_in_mbs_minus1 + 1) |
|
|
- G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(sps->pic_height_in_map_units_minus1 + 1) |
|
|
+ reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(MB_WIDTH(ctx->src_fmt.width)) |
|
|
+ G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(MB_HEIGHT(ctx->src_fmt.height)) |
|
|
G1_REG_DEC_CTRL1_REF_FRAMES(sps->max_num_ref_frames);
|
|
vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL1);
|
|
|
|
|
|
From 72841c8a43e394ce218af95c28038bc24f3c79f9 Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Wed, 6 Nov 2019 23:35:10 +0100
|
|
Subject: [PATCH] media: hantro: Remove now unused H264 pic_size
|
|
|
|
pic_size in hantro_h264_dec_hw_ctx struct is no longer used,
|
|
lets remove it.
|
|
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit 0875962af488e1bbfe6dc4f773495529459d2a28)
|
|
---
|
|
drivers/staging/media/hantro/hantro_h264.c | 5 -----
|
|
drivers/staging/media/hantro/hantro_hw.h | 3 ---
|
|
2 files changed, 8 deletions(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
|
|
index 694a330f508e..568640eab3a6 100644
|
|
--- a/drivers/staging/media/hantro/hantro_h264.c
|
|
+++ b/drivers/staging/media/hantro/hantro_h264.c
|
|
@@ -618,7 +618,6 @@ int hantro_h264_dec_init(struct hantro_ctx *ctx)
|
|
struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
|
|
struct hantro_aux_buf *priv = &h264_dec->priv;
|
|
struct hantro_h264_dec_priv_tbl *tbl;
|
|
- struct v4l2_pix_format_mplane pix_mp;
|
|
|
|
priv->cpu = dma_alloc_coherent(vpu->dev, sizeof(*tbl), &priv->dma,
|
|
GFP_KERNEL);
|
|
@@ -629,9 +628,5 @@ int hantro_h264_dec_init(struct hantro_ctx *ctx)
|
|
tbl = priv->cpu;
|
|
memcpy(tbl->cabac_table, h264_cabac_table, sizeof(tbl->cabac_table));
|
|
|
|
- v4l2_fill_pixfmt_mp(&pix_mp, ctx->dst_fmt.pixelformat,
|
|
- ctx->dst_fmt.width, ctx->dst_fmt.height);
|
|
- h264_dec->pic_size = pix_mp.plane_fmt[0].sizeimage;
|
|
-
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
|
|
index 69b88f4d3fb3..fa91dd1848b7 100644
|
|
--- a/drivers/staging/media/hantro/hantro_hw.h
|
|
+++ b/drivers/staging/media/hantro/hantro_hw.h
|
|
@@ -80,15 +80,12 @@ struct hantro_h264_dec_reflists {
|
|
* @dpb: DPB
|
|
* @reflists: P/B0/B1 reflists
|
|
* @ctrls: V4L2 controls attached to a run
|
|
- * @pic_size: Size in bytes of decoded picture, this is needed
|
|
- * to pass the location of motion vectors.
|
|
*/
|
|
struct hantro_h264_dec_hw_ctx {
|
|
struct hantro_aux_buf priv;
|
|
struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE];
|
|
struct hantro_h264_dec_reflists reflists;
|
|
struct hantro_h264_dec_ctrls ctrls;
|
|
- size_t pic_size;
|
|
};
|
|
|
|
/**
|
|
|
|
From 06e06be61b0e2edab79c115acc2bb6b401c1cbcb Mon Sep 17 00:00:00 2001
|
|
From: Jonas Karlman <jonas@kwiboo.se>
|
|
Date: Wed, 6 Nov 2019 23:35:11 +0100
|
|
Subject: [PATCH] media: hantro: Set H264 FIELDPIC_FLAG_E flag correctly
|
|
|
|
The FIELDPIC_FLAG_E bit should be set when field_pic_flag exists in stream,
|
|
it is currently set based on field_pic_flag of current frame.
|
|
The PIC_FIELDMODE_E bit is correctly set based on the field_pic_flag.
|
|
|
|
Fix this by setting the FIELDPIC_FLAG_E bit when frame_mbs_only is not set.
|
|
|
|
Fixes: dea0a82f3d22 ("media: hantro: Add support for H264 decoding on G1")
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
|
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
|
|
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
|
|
(cherry picked from commit a2cbf80a842add9663522bf898cf13cb2ac4e423)
|
|
---
|
|
drivers/staging/media/hantro/hantro_g1_h264_dec.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
index 27d40d8d3728..3cd40a8f0daa 100644
|
|
--- a/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
|
|
@@ -63,7 +63,7 @@ static void set_params(struct hantro_ctx *ctx)
|
|
/* always use the matrix sent from userspace */
|
|
reg |= G1_REG_DEC_CTRL2_TYPE1_QUANT_E;
|
|
|
|
- if (slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
|
|
+ if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY))
|
|
reg |= G1_REG_DEC_CTRL2_FIELDPIC_FLAG_E;
|
|
vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL2);
|
|
|