From patchwork Wed Jul 22 13:43:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kaaira Gupta X-Patchwork-Id: 8925 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B3B21BDB1B for ; Wed, 22 Jul 2020 13:43:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 472A660948; Wed, 22 Jul 2020 15:43:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=es-iitr-ac-in.20150623.gappssmtp.com header.i=@es-iitr-ac-in.20150623.gappssmtp.com header.b="pcu/eiL5"; dkim-atps=neutral Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 798FB6053C for ; Wed, 22 Jul 2020 15:43:11 +0200 (CEST) Received: by mail-pj1-x1041.google.com with SMTP id k1so1498905pjt.5 for ; Wed, 22 Jul 2020 06:43:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=es-iitr-ac-in.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=y4lW4sfL0CUAZ4TNRnAc1oO9jlALN1Z/xI/HJ0V+T2k=; b=pcu/eiL59R65OaYMVLlo3XgkMt01Z4xGSPnox3zmJQSoNCFMgdtDlrEX6M1Xaduz1a O0s1awVw63FYCmJi1eDecN0w+eebAL7G3Zylz0EFlPbdpL1KuUOgj5Nr/fvu+zGz7fX4 RpV+yLINKP9GdB9gUAtfvs22I5Tsax9vGNyG/SOJnRxfCIJ30lE5tI3Bf+Ua/gBmeFzu OKzsJzyCLEpoP0hc2ELzlLxjZBaYm/qIl5IV5b4g1R9b4Ap4Zb4av9R33NAhUWm8blGQ n91w1BUZIloluG91QRsY9MNJnmS2rlNwGjrZuqh5hAJI1G92u19luXJRZtgTg268+lsF U9aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=y4lW4sfL0CUAZ4TNRnAc1oO9jlALN1Z/xI/HJ0V+T2k=; b=ovbM8z/VAb/in6tmjpH7+xwnYYFfV2LKRg042vMrLrT1Gre0KDmkkB/jtkjrAZxJE3 xEy4qSFdBhYc68hDyd6l9O8vbJ23Nm71p0KxPgw3x4PwwAYVSXQu8K3vlgOWKZ+ygG2X WJlAuaQNr8rKZ0jHlCnE9RsKgNEQtNDd80IAETlkbNtzwgCBH1b4g9ppWdRr5XziwrWR IKkNcZhIPiCSRDbu9d/aTpEEom9tHGpiMl8oX6R1XQWHar5D3TxronmhCGcSY6Zx4cFa noaJN/Cy7Yvgs5hyQ3ZIAwIdVLmFcP2YXSafRgoNc+bhZaZgYTlDlGhAFXr8MnF8tmuL BQTw== X-Gm-Message-State: AOAM5310YCQnCBthWvjRhDwQc6HdYvZaymzKqMxB9Zu4rrKpmKKzJtQt G+GbkV/+XCtdRf9u0I4EOkt8dHGDWbg= X-Google-Smtp-Source: ABdhPJyIv3WuXGsTcJSRJFTTjpgiv6zPoJgElpo4dM06/2nW3Hb68xVvGMefxNaf4URT6VC4M3KjwA== X-Received: by 2002:a17:90b:358e:: with SMTP id mm14mr10664764pjb.54.1595425389612; Wed, 22 Jul 2020 06:43:09 -0700 (PDT) Received: from kaaira-HP-Pavilion-Notebook ([103.113.213.178]) by smtp.gmail.com with ESMTPSA id l16sm23941473pff.167.2020.07.22.06.43.08 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 22 Jul 2020 06:43:09 -0700 (PDT) Date: Wed, 22 Jul 2020 19:13:04 +0530 From: Kaaira Gupta To: libcamera-devel@lists.libcamera.org, Kieran Bingham Message-ID: <20200722134303.GA27212@kaaira-HP-Pavilion-Notebook> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) Subject: [libcamera-devel] media: vimc: VIMC multiple streams X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This is a patchset by Niklas (https://patchwork.kernel.org/cover/10948831/) that I have rebased on the current media-tree, I have not added anything to it and it is just a compressed version of his patchset into a single patch, based on the latest master to aid testing multiple stream support in the VIMC pipeline. Signed-off-by: Kaaira Gupta --- .../media/test-drivers/vimc/vimc-capture.c | 35 ++++++++++++++++++- .../media/test-drivers/vimc/vimc-debayer.c | 8 +++++ drivers/media/test-drivers/vimc/vimc-scaler.c | 8 +++++ drivers/media/test-drivers/vimc/vimc-sensor.c | 8 +++++ .../media/test-drivers/vimc/vimc-streamer.c | 22 +++++++----- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/drivers/media/test-drivers/vimc/vimc-capture.c b/drivers/media/test-drivers/vimc/vimc-capture.c index c63496b17b9a..5fc56582af83 100644 --- a/drivers/media/test-drivers/vimc/vimc-capture.c +++ b/drivers/media/test-drivers/vimc/vimc-capture.c @@ -237,16 +237,49 @@ static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap, spin_unlock(&vcap->qlock); } +static struct media_entity *vimc_cap_get_sensor(struct vimc_cap_device *vcap) +{ + struct media_entity *entity = &vcap->vdev.entity; + struct media_device *mdev = entity->graph_obj.mdev; + struct media_graph graph; + + mutex_lock(&mdev->graph_mutex); + if (media_graph_walk_init(&graph, mdev)) { + mutex_unlock(&mdev->graph_mutex); + return NULL; + } + + media_graph_walk_start(&graph, entity); + + while ((entity = media_graph_walk_next(&graph))) + if (entity->function == MEDIA_ENT_F_CAM_SENSOR) + break; + + mutex_unlock(&mdev->graph_mutex); + + media_graph_walk_cleanup(&graph); + + return entity; +} + static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) { struct vimc_cap_device *vcap = vb2_get_drv_priv(vq); struct media_entity *entity = &vcap->vdev.entity; + struct media_pipeline *pipe = NULL; + struct media_entity *sensorent; int ret; vcap->sequence = 0; /* Start the media pipeline */ - ret = media_pipeline_start(entity, &vcap->stream.pipe); + sensorent = vimc_cap_get_sensor(vcap); + if (sensorent && sensorent->pipe) + pipe = sensorent->pipe; + else + pipe = &vcap->stream.pipe; + + ret = media_pipeline_start(entity, pipe); if (ret) { vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED); return ret; diff --git a/drivers/media/test-drivers/vimc/vimc-debayer.c b/drivers/media/test-drivers/vimc/vimc-debayer.c index c3f6fef34f68..93fe19d8d2b4 100644 --- a/drivers/media/test-drivers/vimc/vimc-debayer.c +++ b/drivers/media/test-drivers/vimc/vimc-debayer.c @@ -29,6 +29,7 @@ struct vimc_deb_pix_map { struct vimc_deb_device { struct vimc_ent_device ved; struct v4l2_subdev sd; + atomic_t use_count; /* The active format */ struct v4l2_mbus_framefmt sink_fmt; u32 src_code; @@ -343,6 +344,9 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable) const struct vimc_pix_map *vpix; unsigned int frame_size; + if (atomic_inc_return(&vdeb->use_count) != 1) + return 0; + if (vdeb->src_frame) return 0; @@ -368,6 +372,9 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable) return -ENOMEM; } else { + if (atomic_dec_return(&vdeb->use_count) != 0) + return 0; + if (!vdeb->src_frame) return 0; @@ -595,6 +602,7 @@ static struct vimc_ent_device *vimc_deb_add(struct vimc_device *vimc, vdeb->ved.process_frame = vimc_deb_process_frame; vdeb->ved.dev = vimc->mdev.dev; vdeb->mean_win_size = vimc_deb_ctrl_mean_win_size.def; + atomic_set(&vdeb->use_count, 0); /* Initialize the frame format */ vdeb->sink_fmt = sink_fmt_default; diff --git a/drivers/media/test-drivers/vimc/vimc-scaler.c b/drivers/media/test-drivers/vimc/vimc-scaler.c index 121fa7d62a2e..9b8458dbe57c 100644 --- a/drivers/media/test-drivers/vimc/vimc-scaler.c +++ b/drivers/media/test-drivers/vimc/vimc-scaler.c @@ -25,6 +25,7 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); struct vimc_sca_device { struct vimc_ent_device ved; struct v4l2_subdev sd; + atomic_t use_count; /* NOTE: the source fmt is the same as the sink * with the width and hight multiplied by mult */ @@ -340,6 +341,9 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) const struct vimc_pix_map *vpix; unsigned int frame_size; + if (atomic_inc_return(&vsca->use_count) != 1) + return 0; + if (vsca->src_frame) return 0; @@ -363,6 +367,9 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) return -ENOMEM; } else { + if (atomic_dec_return(&vsca->use_count) != 0) + return 0; + if (!vsca->src_frame) return 0; @@ -506,6 +513,7 @@ static struct vimc_ent_device *vimc_sca_add(struct vimc_device *vimc, vsca->ved.process_frame = vimc_sca_process_frame; vsca->ved.dev = vimc->mdev.dev; + atomic_set(&vsca->use_count, 0); /* Initialize the frame format */ vsca->sink_fmt = sink_fmt_default; diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c index a2f09ac9a360..d68113886290 100644 --- a/drivers/media/test-drivers/vimc/vimc-sensor.c +++ b/drivers/media/test-drivers/vimc/vimc-sensor.c @@ -18,6 +18,7 @@ struct vimc_sen_device { struct vimc_ent_device ved; struct v4l2_subdev sd; struct tpg_data tpg; + atomic_t use_count; u8 *frame; /* The active format */ struct v4l2_mbus_framefmt mbus_format; @@ -201,6 +202,9 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) const struct vimc_pix_map *vpix; unsigned int frame_size; + if (atomic_inc_return(&vsen->use_count) != 1) + return 0; + /* Calculate the frame size */ vpix = vimc_pix_map_by_code(vsen->mbus_format.code); frame_size = vsen->mbus_format.width * vpix->bpp * @@ -219,6 +223,9 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) } else { + if (atomic_dec_return(&vsen->use_count) != 0) + return 0; + vfree(vsen->frame); vsen->frame = NULL; } @@ -359,6 +366,7 @@ static struct vimc_ent_device *vimc_sen_add(struct vimc_device *vimc, vsen->ved.process_frame = vimc_sen_process_frame; vsen->ved.dev = vimc->mdev.dev; + atomic_set(&vsen->use_count, 0); /* Initialize the frame format */ vsen->mbus_format = fmt_default; diff --git a/drivers/media/test-drivers/vimc/vimc-streamer.c b/drivers/media/test-drivers/vimc/vimc-streamer.c index 451a32c0d034..d5b966a99f7b 100644 --- a/drivers/media/test-drivers/vimc/vimc-streamer.c +++ b/drivers/media/test-drivers/vimc/vimc-streamer.c @@ -192,33 +192,35 @@ int vimc_streamer_s_stream(struct vimc_stream *stream, struct vimc_ent_device *ved, int enable) { + static DEFINE_MUTEX(vimc_streamer_lock); int ret; if (!stream || !ved) return -EINVAL; + ret = mutex_lock_interruptible(&vimc_streamer_lock); + if (ret) + return ret; + if (enable) { if (stream->kthread) - return 0; + goto out; ret = vimc_streamer_pipeline_init(stream, ved); if (ret) - return ret; + goto out; stream->kthread = kthread_run(vimc_streamer_thread, stream, "vimc-streamer thread"); if (IS_ERR(stream->kthread)) { ret = PTR_ERR(stream->kthread); - dev_err(ved->dev, "kthread_run failed with %d\n", ret); - vimc_streamer_pipeline_terminate(stream); - stream->kthread = NULL; - return ret; + goto out; } } else { if (!stream->kthread) - return 0; + goto out; ret = kthread_stop(stream->kthread); /* @@ -228,12 +230,14 @@ int vimc_streamer_s_stream(struct vimc_stream *stream, * pipeline. */ if (ret) - dev_dbg(ved->dev, "kthread_stop returned '%d'\n", ret); + goto out; stream->kthread = NULL; vimc_streamer_pipeline_terminate(stream); } +out: + mutex_unlock(&vimc_streamer_lock); - return 0; + return ret; }