2020-03-13 01:47:15

by Helen Koike

[permalink] [raw]
Subject: [PATCH 0/3] media: staging: rkisp1: allow simultaneous streaming from multiple capture devices

Hi,

This series adds support for simultaneous streaming from both capture
devices (rkisp1_selfpath and rkisp1_mainpath).

Patch 1/3 fixes return error handling from pm functions, which was
preventing the second stream to start.

Patch 2/3 don't allow .s_stream entity callback to be called if a stream is
already enabled. Which fixes the issue when stopping one stream would
also stop the other.

Patch 3/3 serializes start/stop streaming calls, since they both read
and modify the streaming status of all the entities in the piipeline.

This series was tested with:

SEN_DEV=/dev/v4l-subdev3
ISP_DEV=/dev/v4l-subdev0
RSZ_SP_DEV=/dev/v4l-subdev2
RSZ_MP_DEV=/dev/v4l-subdev1
CAP_SP_DEV=/dev/video1
CAP_MP_DEV=/dev/video0

WIDTH=1920
HEIGHT=1080
RAW_CODE=SRGGB10_1X10
YUV_CODE=YUYV8_2X8

v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$RAW_CODE -d $SEN_DEV

v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$RAW_CODE -d $ISP_DEV
v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $ISP_DEV

v4l2-ctl --set-subdev-selection pad=2,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $ISP_DEV
v4l2-ctl --set-subdev-fmt pad=2,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $ISP_DEV

v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_SP_DEV
v4l2-ctl --set-subdev-fmt pad=1,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_SP_DEV

v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $RSZ_SP_DEV

v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_MP_DEV
v4l2-ctl --set-subdev-fmt pad=1,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_MP_DEV

v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $RSZ_MP_DEV

v4l2-ctl -v width=$WIDTH,height=$HEIGHT,pixelformat=NV12 -d $CAP_SP_DEV
v4l2-ctl -v width=$WIDTH,height=$HEIGHT,pixelformat=NV12 -d $CAP_MP_DEV

sleep 1

v4l2-ctl --stream-mmap --stream-count=100 -d $CAP_SP_DEV --stream-to=/tmp/test_sp.raw &
v4l2-ctl --stream-mmap --stream-count=100 -d $CAP_MP_DEV --stream-to=/tmp/test_mp.raw &

wait
echo "Completed"



Helen Koike (3):
media: staging: rkisp1: cap: fix return values from pm functions
media: staging: rkisp1: do not call s_stream if the entity is still in
use
media: staging: rkisp1: cap: serialize start/stop stream

drivers/staging/media/rkisp1/rkisp1-capture.c | 25 ++++++++++++++++---
drivers/staging/media/rkisp1/rkisp1-common.h | 2 ++
drivers/staging/media/rkisp1/rkisp1-dev.c | 2 ++
3 files changed, 25 insertions(+), 4 deletions(-)

--
2.25.0


2020-03-13 01:47:21

by Helen Koike

[permalink] [raw]
Subject: [PATCH 1/3] media: staging: rkisp1: cap: fix return values from pm functions

If no errors occurs, pm functions return usage counters, so they can
return positive numbers.
This happens when streaming from multiple capture devices (mainpath and
selfpath).

Fix simultaneous streaming from mainpath and selfpath by not failing
when pm usage counters returns a positive number.

Signed-off-by: Helen Koike <[email protected]>
---

drivers/staging/media/rkisp1/rkisp1-capture.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
index 524e0dd38c1b..97091e5a6e6c 100644
--- a/drivers/staging/media/rkisp1/rkisp1-capture.c
+++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
@@ -938,11 +938,11 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
rkisp1_return_all_buffers(cap, VB2_BUF_STATE_ERROR);

ret = v4l2_pipeline_pm_use(&node->vdev.entity, 0);
- if (ret)
+ if (ret < 0)
dev_err(rkisp1->dev, "pipeline close failed error:%d\n", ret);

ret = pm_runtime_put(rkisp1->dev);
- if (ret)
+ if (ret < 0)
dev_err(rkisp1->dev, "power down failed error:%d\n", ret);

rkisp1_dummy_buf_destroy(cap);
@@ -995,12 +995,12 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
goto err_ret_buffers;

ret = pm_runtime_get_sync(cap->rkisp1->dev);
- if (ret) {
+ if (ret < 0) {
dev_err(cap->rkisp1->dev, "power up failed %d\n", ret);
goto err_destroy_dummy;
}
ret = v4l2_pipeline_pm_use(entity, 1);
- if (ret) {
+ if (ret < 0) {
dev_err(cap->rkisp1->dev, "open cif pipeline failed %d\n", ret);
goto err_pipe_pm_put;
}
--
2.25.0

2020-03-13 01:47:57

by Helen Koike

[permalink] [raw]
Subject: [PATCH 3/3] media: staging: rkisp1: cap: serialize start/stop stream

In order to support simultaneous streaming from both capture devices,
start/stop vb2 calls need to be serialized to allow multiple concurrent
calls.

This is required to synchronize who starts/stops the shared entities in
the pipeline.

Signed-off-by: Helen Koike <[email protected]>

---

drivers/staging/media/rkisp1/rkisp1-capture.c | 9 +++++++++
drivers/staging/media/rkisp1/rkisp1-common.h | 2 ++
drivers/staging/media/rkisp1/rkisp1-dev.c | 2 ++
3 files changed, 13 insertions(+)

diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
index e665381b5af0..30d7a72aa554 100644
--- a/drivers/staging/media/rkisp1/rkisp1-capture.c
+++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
@@ -935,6 +935,8 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
struct rkisp1_device *rkisp1 = cap->rkisp1;
int ret;

+ mutex_lock(&cap->rkisp1->stream_lock);
+
rkisp1_stream_stop(cap);
media_pipeline_stop(&node->vdev.entity);
ret = rkisp1_pipeline_sink_walk(&node->vdev.entity, NULL,
@@ -954,6 +956,8 @@ static void rkisp1_vb2_stop_streaming(struct vb2_queue *queue)
dev_err(rkisp1->dev, "power down failed error:%d\n", ret);

rkisp1_dummy_buf_destroy(cap);
+
+ mutex_unlock(&cap->rkisp1->stream_lock);
}

/*
@@ -998,6 +1002,8 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
struct media_entity *entity = &cap->vnode.vdev.entity;
int ret;

+ mutex_lock(&cap->rkisp1->stream_lock);
+
ret = rkisp1_dummy_buf_create(cap);
if (ret)
goto err_ret_buffers;
@@ -1027,6 +1033,8 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
goto err_pipe_disable;
}

+ mutex_unlock(&cap->rkisp1->stream_lock);
+
return 0;

err_pipe_disable:
@@ -1040,6 +1048,7 @@ rkisp1_vb2_start_streaming(struct vb2_queue *queue, unsigned int count)
rkisp1_dummy_buf_destroy(cap);
err_ret_buffers:
rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED);
+ mutex_unlock(&cap->rkisp1->stream_lock);

return ret;
}
diff --git a/drivers/staging/media/rkisp1/rkisp1-common.h b/drivers/staging/media/rkisp1/rkisp1-common.h
index 369a401b098a..f74fca3985e3 100644
--- a/drivers/staging/media/rkisp1/rkisp1-common.h
+++ b/drivers/staging/media/rkisp1/rkisp1-common.h
@@ -244,6 +244,7 @@ struct rkisp1_debug {
* @rkisp1_capture: capture video device
* @stats: ISP statistics output device
* @params: ISP input parameters device
+ * @stream_lock: lock to serialize start/stop streaming in capture devices.
*/
struct rkisp1_device {
void __iomem *base_addr;
@@ -263,6 +264,7 @@ struct rkisp1_device {
struct rkisp1_params params;
struct media_pipeline pipe;
struct vb2_alloc_ctx *alloc_ctx;
+ struct mutex stream_lock;
struct rkisp1_debug debug;
};

diff --git a/drivers/staging/media/rkisp1/rkisp1-dev.c b/drivers/staging/media/rkisp1/rkisp1-dev.c
index 558126e66465..2977c494925f 100644
--- a/drivers/staging/media/rkisp1/rkisp1-dev.c
+++ b/drivers/staging/media/rkisp1/rkisp1-dev.c
@@ -472,6 +472,8 @@ static int rkisp1_probe(struct platform_device *pdev)
dev_set_drvdata(dev, rkisp1);
rkisp1->dev = dev;

+ mutex_init(&rkisp1->stream_lock);
+
rkisp1->base_addr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rkisp1->base_addr))
return PTR_ERR(rkisp1->base_addr);
--
2.25.0

2020-03-13 01:48:42

by Helen Koike

[permalink] [raw]
Subject: [PATCH 2/3] media: staging: rkisp1: do not call s_stream if the entity is still in use

If stream is being used by another stream, then .s_stream callback
shouldn't be called.

This fixes the following behaviour:

When performing smultaneos stream from both capture devices, stopping one
streaming would make the other to stall, since it disables all the shared
entities from both pipelines.

Signed-off-by: Helen Koike <[email protected]>

---

Hi,

I'm not sure if it is ok to check for entity->pipe, since I didn't see
other drivers doing this.
Please let me know if you have any other suggestion to verity if the entity
is marked as streaming.

Thanks

---
drivers/staging/media/rkisp1/rkisp1-capture.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/staging/media/rkisp1/rkisp1-capture.c b/drivers/staging/media/rkisp1/rkisp1-capture.c
index 97091e5a6e6c..e665381b5af0 100644
--- a/drivers/staging/media/rkisp1/rkisp1-capture.c
+++ b/drivers/staging/media/rkisp1/rkisp1-capture.c
@@ -892,6 +892,10 @@ static int rkisp1_pipeline_disable_cb(struct media_entity *from,
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(curr);

+ /* subdevice is already enabled */
+ if (curr->pipe)
+ return 0;
+
return v4l2_subdev_call(sd, video, s_stream, false);
}

@@ -900,6 +904,10 @@ static int rkisp1_pipeline_enable_cb(struct media_entity *from,
{
struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(curr);

+ /* don't disable subdevice if it is still in use by another stream */
+ if (curr->pipe)
+ return 0;
+
return v4l2_subdev_call(sd, video, s_stream, true);
}

--
2.25.0

2020-03-13 16:54:08

by Helen Koike

[permalink] [raw]
Subject: Re: [PATCH 0/3] media: staging: rkisp1: allow simultaneous streaming from multiple capture devices



On 3/12/20 10:46 PM, Helen Koike wrote:
> Hi,
>
> This series adds support for simultaneous streaming from both capture
> devices (rkisp1_selfpath and rkisp1_mainpath).
>
> Patch 1/3 fixes return error handling from pm functions, which was
> preventing the second stream to start.
>
> Patch 2/3 don't allow .s_stream entity callback to be called if a stream is
> already enabled. Which fixes the issue when stopping one stream would
> also stop the other.
>
> Patch 3/3 serializes start/stop streaming calls, since they both read
> and modify the streaming status of all the entities in the piipeline.
>
> This series was tested with:
>
> SEN_DEV=/dev/v4l-subdev3
> ISP_DEV=/dev/v4l-subdev0
> RSZ_SP_DEV=/dev/v4l-subdev2
> RSZ_MP_DEV=/dev/v4l-subdev1
> CAP_SP_DEV=/dev/video1
> CAP_MP_DEV=/dev/video0
>
> WIDTH=1920
> HEIGHT=1080
> RAW_CODE=SRGGB10_1X10
> YUV_CODE=YUYV8_2X8
>
> v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$RAW_CODE -d $SEN_DEV
>
> v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$RAW_CODE -d $ISP_DEV
> v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $ISP_DEV
>
> v4l2-ctl --set-subdev-selection pad=2,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $ISP_DEV
> v4l2-ctl --set-subdev-fmt pad=2,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $ISP_DEV
>
> v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_SP_DEV
> v4l2-ctl --set-subdev-fmt pad=1,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_SP_DEV
>
> v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $RSZ_SP_DEV
>
> v4l2-ctl --set-subdev-fmt pad=0,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_MP_DEV
> v4l2-ctl --set-subdev-fmt pad=1,width=$WIDTH,height=$HEIGHT,code=$YUV_CODE -d $RSZ_MP_DEV
>
> v4l2-ctl --set-subdev-selection pad=0,target=crop,top=0,left=0,width=$WIDTH,height=$HEIGHT -d $RSZ_MP_DEV
>
> v4l2-ctl -v width=$WIDTH,height=$HEIGHT,pixelformat=NV12 -d $CAP_SP_DEV
> v4l2-ctl -v width=$WIDTH,height=$HEIGHT,pixelformat=NV12 -d $CAP_MP_DEV
>
> sleep 1
>
> v4l2-ctl --stream-mmap --stream-count=100 -d $CAP_SP_DEV --stream-to=/tmp/test_sp.raw &
> v4l2-ctl --stream-mmap --stream-count=100 -d $CAP_MP_DEV --stream-to=/tmp/test_mp.raw &
>
> wait
> echo "Completed"
>
>
>
> Helen Koike (3):
> media: staging: rkisp1: cap: fix return values from pm functions
> media: staging: rkisp1: do not call s_stream if the entity is still in
> use
> media: staging: rkisp1: cap: serialize start/stop stream
>
> drivers/staging/media/rkisp1/rkisp1-capture.c | 25 ++++++++++++++++---
> drivers/staging/media/rkisp1/rkisp1-common.h | 2 ++
> drivers/staging/media/rkisp1/rkisp1-dev.c | 2 ++
> 3 files changed, 25 insertions(+), 4 deletions(-)
>

Please, ignore this version, I rebased with the wrong branch. I'll send v2.

Thanks
Helen