<div dir="ltr"><div dir="ltr">Hi,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, May 18, 2019 at 4:16 AM Niklas Söderlund <<a href="mailto:niklas.soderlund%2Brenesas@ragnatech.se">niklas.soderlund+renesas@ragnatech.se</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">A sensor which is running is already part of a pipeline and trying to<br>
start a new pipeline is not possible. This prevents two capture devices<br>
connected to the same sensor from running at the same time.<br>
<br>
Instead of failing to start the second capture device allow it to join<br>
the already running pipeline by looking it up at the sensor. This allows<br>
two (or more) capture devices to independently be started and stopped<br>
while still being connected to the same sensor.<br>
<br>
Signed-off-by: Niklas Söderlund <<a href="mailto:niklas.soderlund@ragnatech.se" target="_blank">niklas.soderlund@ragnatech.se</a>><br>
---<br>
drivers/media/platform/vimc/vimc-capture.c | 35 +++++++++++++++++++++-<br>
1 file changed, 34 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c<br>
index e7d0fc2228a6f0c1..f9eb1e327e311b4a 100644<br>
--- a/drivers/media/platform/vimc/vimc-capture.c<br>
+++ b/drivers/media/platform/vimc/vimc-capture.c<br>
@@ -264,16 +264,49 @@ static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap,<br>
spin_unlock(&vcap->qlock);<br>
}<br>
<br>
+static struct media_entity *vimc_cap_get_sensor(struct vimc_cap_device *vcap)<br>
+{<br>
+ struct media_entity *entity = &vcap->vdev.entity;<br>
+ struct media_device *mdev = entity->graph_obj.mdev;<br>
+ struct media_graph graph;<br>
+<br>
+ mutex_lock(&mdev->graph_mutex);<br>
+ if (media_graph_walk_init(&graph, mdev)) {<br></blockquote><div>adding error debug?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ mutex_unlock(&mdev->graph_mutex);<br>
+ return NULL;<br>
+ } </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+ media_graph_walk_start(&graph, entity);<br>
+<br>
+ while ((entity = media_graph_walk_next(&graph)))<br>
+ if (entity->function == MEDIA_ENT_F_CAM_SENSOR)<br>
+ break;<br>
+<br>
+ mutex_unlock(&mdev->graph_mutex);<br>
+<br>
+ media_graph_walk_cleanup(&graph);<br>
+<br>
+ return entity;<br>
+}<br>
+<br></blockquote><div>Iterating the pipeline from the capture back to the source is already done int the function vimc_streamer_pipeline_init</div><div>but there it iterates it using the media_entity_remote_pad function and not with the graph_walk api, so better use the same</div><div>form of iteration in both places.</div><div>In addition, the vimc streamer code uses the function vimc_is_source to check that the source is reached instead of MEDIA_ENT_F_CAM_SENSOR</div><div>so better be consistent with that too.</div><div>Last, I think it is enough to iterate back until an entity with non NULL pipe pointer is reached.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)<br>
{<br>
struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);<br>
struct media_entity *entity = &vcap->vdev.entity;<br>
+ struct media_pipeline *pipe = NULL;<br>
+ struct media_entity *sensorent;<br></blockquote><div>better call it sensor_ent, </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
int ret;<br>
<br>
vcap->sequence = 0;<br>
<br>
/* Start the media pipeline */<br>
- ret = media_pipeline_start(entity, &vcap->stream.pipe);<br>
+ sensorent = vimc_cap_get_sensor(vcap);<br>
+ if (sensorent && sensorent->pipe)<br></blockquote><div>if sensorent is null, this must be an error so better change the code to something like</div><div>if (!sensorent) {</div><div> dev_err("err blabla");</div><div> ret -EPIPE;</div><div>} </div><div>if(seneorent->pipe)</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ pipe = sensorent->pipe;<br>
+ else<br>
+ pipe = &vcap->stream.pipe;<br>
+<br></blockquote><div>and with the new code this can be one line with the "? :" operator.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ ret = media_pipeline_start(entity, pipe);<br>
if (ret) {<br>
vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);<br>
return ret;<br>
-- <br></blockquote><div>Thanks,</div><div>Dafna </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
2.21.0<br>
<br>
</blockquote></div></div>