From patchwork Mon Jan 18 16:17:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacek Anaszewski X-Patchwork-Id: 8056001 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 73045BEEE5 for ; Mon, 18 Jan 2016 16:18:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6AA2E204AF for ; Mon, 18 Jan 2016 16:18:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 46B33204A9 for ; Mon, 18 Jan 2016 16:18:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932114AbcARQSo (ORCPT ); Mon, 18 Jan 2016 11:18:44 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:57478 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755756AbcARQSo (ORCPT ); Mon, 18 Jan 2016 11:18:44 -0500 Received: from epcpsbgm2new.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout4.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O1501N1RPAIDD20@mailout4.samsung.com> for linux-media@vger.kernel.org; Tue, 19 Jan 2016 01:18:43 +0900 (KST) X-AuditID: cbfee61b-f793c6d00000236c-b2-569d1062dc1c Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2new.samsung.com (EPCPMTA) with SMTP id 0B.59.09068.2601D965; Tue, 19 Jan 2016 01:18:42 +0900 (KST) Received: from AMDC2362.DIGITAL.local ([106.120.53.23]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O15003TLP9I9Y00@mmp2.samsung.com>; Tue, 19 Jan 2016 01:18:42 +0900 (KST) From: Jacek Anaszewski To: linux-media@vger.kernel.org Cc: sakari.ailus@linux.intel.com, laurent.pinchart@ideasonboard.com, gjasny@googlemail.com, hdegoede@redhat.com, hverkuil@xs4all.nl, Jacek Anaszewski Subject: [PATCH 08/15] mediactl: Add support for media device pipelines Date: Mon, 18 Jan 2016 17:17:33 +0100 Message-id: <1453133860-21571-9-git-send-email-j.anaszewski@samsung.com> X-Mailer: git-send-email 1.7.9.5 In-reply-to: <1453133860-21571-1-git-send-email-j.anaszewski@samsung.com> References: <1453133860-21571-1-git-send-email-j.anaszewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprPLMWRmVeSWpSXmKPExsVy+t9jQd0kgblhBm9f21hMnzKL0eLN8elM FqcmP2Oy6L36nNGic+ISdoueDVtZLT5t+cbkwO7xdMJkdo/ZHTNZPeadDPR4v+8qm0ffllWM Hp83yXmc+vqZPYA9issmJTUnsyy1SN8ugSvj6cQZTAUPLSquXXvH1MC4XreLkYNDQsBE4kaL UhcjJ5ApJnHh3nq2LkYuDiGBWYwSi3+1s0A4PxklNu95yQJSxSZgKPHzxWsmEFtEQF7iSe8N sA5mgS2MEnfvLGIHSQgLuEvcaz7ACGKzCKhKtE5aCNbMK+AhsfbSJUaIzQoScybZgIQ5BTwl 3tzczwZiCwGVHLi7lXkCI+8CRoZVjBKpBckFxUnpuUZ5qeV6xYm5xaV56XrJ+bmbGMHB9kx6 B+PhXe6HGAU4GJV4eB3Ozg4TYk0sK67MPcQowcGsJMJ7iGNumBBvSmJlVWpRfnxRaU5q8SFG aQ4WJXHefZciw4QE0hNLUrNTUwtSi2CyTBycUg2MLrV5sx32+QaXvy4O3hq55jFPYIu+ku/X sOf5MrImdrGFplwT/ctXtDZ6nv4qdO0vZzUTW9Ddt7WLXF98/W36LOn5VNvbWziEH6hkFyZu qV6w8M2Xvykfnrz4LnvT8uIjyz3/1ZbkGH60rOFRPnDp5tzc8uSi0+zdUxTlmuXcP3gtnpfz YMIxJZbijERDLeai4kQAM7xyMTICAAA= Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add infrastructure for linking media entities and discovering media device pipelines. Signed-off-by: Jacek Anaszewski Acked-by: Kyungmin Park --- utils/media-ctl/libmediactl.c | 117 +++++++++++++++++++++++++++++++++++++++ utils/media-ctl/mediactl-priv.h | 6 ++ utils/media-ctl/mediactl.h | 71 ++++++++++++++++++++++++ 3 files changed, 194 insertions(+) diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c index 3a45ecc..9909c1c 100644 --- a/utils/media-ctl/libmediactl.c +++ b/utils/media-ctl/libmediactl.c @@ -1109,3 +1109,120 @@ int media_parse_setup_links(struct media_device *media, const char *p) return *end ? -EINVAL : 0; } + +/* ----------------------------------------------------------------------------- + * Pipeline operations + */ + +int media_discover_pipeline_by_entity(struct media_device *media, + struct media_entity *entity) +{ + struct media_entity *pipe_head = NULL; + struct media_pad *src_pad; + struct media_link *link = NULL, *backlinks[10]; + int i, num_backlinks, ret; + + if (entity == NULL) + return -EINVAL; + + for (;;) { + /* Make recently discovered entity the pipeline head */ + if (pipe_head == NULL) { + pipe_head = entity; + } else { + entity->next = pipe_head; + pipe_head = entity; + } + + /* Cache a source pad used for linking the entity */ + if (link) + entity->pipe_src_pad = link->source; + + ret = media_get_backlinks_by_entity(entity, + backlinks, + &num_backlinks); + if (ret < 0) + return ret; + + /* check if pipeline source entity has been reached */ + if (num_backlinks > 2) { + media_dbg(media, "Unexpected number of busy sink pads (%d)\n", num_backlinks); + return -EINVAL; + } else if (num_backlinks == 2) { + /* + * Allow two active pads only in case of + * S5C73M3-OIF entity. + */ + if (strcmp(entity->info.name, "S5C73M3-OIF")) { + media_dbg(media, "Ambiguous media device topology: two busy sink pads"); + return -EINVAL; + } + /* + * Two active links are allowed betwen S5C73M3-OIF and + * S5C73M3 entities. In such a case a route through pad + * with id == 0 has to be selected. + */ + for (i = 0; i < num_backlinks; i++) + if (backlinks[i]->sink->index == 0) + link = backlinks[i]; + } else if (num_backlinks == 1) + link = backlinks[0]; + else + break; + + /* Cache a sink pad used for linking the entity */ + entity->pipe_sink_pad = link->sink; + + media_dbg(media, "Discovered sink pad %d for the %s entity\n", + entity->pipe_sink_pad->index, media_entity_get_name(entity)); + + src_pad = media_entity_remote_source(link->sink); + if (!src_pad) + return -EINVAL; + + entity = src_pad->entity; + } + + media->pipeline = pipe_head; + + return 0; +} + +int media_has_pipeline_entity(struct media_entity *pipeline, char *entity_name) +{ + if (pipeline == NULL || entity_name == NULL) + return -EINVAL; + + while (pipeline) { + if (!strncmp(pipeline->info.name, entity_name, + strlen(entity_name))) + return 1; + pipeline = pipeline->next; + } + + return 0; +} + +/* ----------------------------------------------------------------------------- + * Media entity access + */ + +struct media_entity *media_get_pipeline(struct media_device *media) +{ + return media->pipeline; +} + +int media_entity_get_src_pad_index(struct media_entity *entity) +{ + return entity->pipe_src_pad->index; +} + +int media_entity_get_sink_pad_index(struct media_entity *entity) +{ + return entity->pipe_sink_pad->index; +} + +struct media_entity *media_entity_get_next(struct media_entity *entity) +{ + return entity->next; +} diff --git a/utils/media-ctl/mediactl-priv.h b/utils/media-ctl/mediactl-priv.h index f531c52..3378880 100644 --- a/utils/media-ctl/mediactl-priv.h +++ b/utils/media-ctl/mediactl-priv.h @@ -36,9 +36,14 @@ struct media_entity { unsigned int max_links; unsigned int num_links; + struct media_pad *pipe_src_pad; + struct media_pad *pipe_sink_pad; + struct v4l2_subdev *sd; char devname[32]; + + struct media_entity *next; }; struct media_device { @@ -49,6 +54,7 @@ struct media_device { struct media_device_info info; struct media_entity *entities; unsigned int entities_count; + struct media_entity *pipeline; void (*debug_handler)(void *, ...); void *debug_priv; diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h index 1d62191..4570160 100644 --- a/utils/media-ctl/mediactl.h +++ b/utils/media-ctl/mediactl.h @@ -500,4 +500,75 @@ int media_get_backlinks_by_entity(struct media_entity *entity, struct media_link **backlinks, int *num_backlinks); +/** + * @brief Check presence of the entity in the pipeline + * @param pipeline - video pipeline within a media device. + * @param entity_name - name of the entity to search for. + * + * Check if the entity with entity_name belongs to + * the pipeline. + * + * @return 0 on success, or a negative error code on failure. + */ +int media_has_pipeline_entity(struct media_entity *pipeline, char *entity_name); + +/** + * @brief Discover the video pipeline + * @param media - media device. + * @param entity - media entity. + * + * Discover the pipeline of sub-devices, by walking + * upstream starting from the passed sink entity until + * the camera sensor entity is encountered. + * + * @return 0 on success, or a negative error code on failure. + */ +int media_discover_pipeline_by_entity(struct media_device *media, + struct media_entity *entity); + +/** + * @brief Get source pad of the pipeline entity + * @param entity - media entity. + * + * This function returns the source pad of the entity. + * + * @return entity source pad, or NULL if the entity is not linked. + */ +int media_entity_get_src_pad_index(struct media_entity *entity); + +/** + * @brief Get sink pad of the pipeline entity + * @param entity - media entity. + * + * This function returns the sink pad of the entity. + * + * @return entity sink pad, or NULL if the entity is not linked. + */ +int media_entity_get_sink_pad_index(struct media_entity *entity); + +/** + * @brief Get next entity in the pipeline + * @param entity - media entity + * + * This function gets the entity connected to a source pad of this entity. + * + * @return next enetity in the pipeline, + * or NULL if the entity is not linked + */ +struct media_entity *media_entity_get_next(struct media_entity *entity); + +/** + * @brief Get the video pipeline + * @param media - media device + * + * This function gets the pipeline of media entities. The pipeline + * source entity is a camera sensor and the sink one is the entity + * representing opened video device node. The pipeline has to be + * discovered with use of the function media_discover_pipeline_by_entity. + * + * @return first media_entity in the pipeline, + * or NULL if the pipeline hasn't been discovered + */ +struct media_entity *media_get_pipeline(struct media_device *media); + #endif