diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch b/recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch new file mode 100644 index 0000000000..969162f8ec --- /dev/null +++ b/recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch @@ -0,0 +1,259 @@ +From 4e07e9ada1b3baaec6d4948eccf3c0499e3228df Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Date: Wed, 25 Aug 2010 15:00:41 +0300 +Subject: [PATCH 16/43] media: Pipelines and media streams + +Drivers often need to associate pipeline objects to entities, and to +take stream state into account when configuring entities and links. The +pipeline API helps drivers manage that information. + +When starting streaming, drivers call media_entity_pipeline_start(). The +function marks all entities connected to the given entity through +enabled links, either directly or indirectly, as streaming. Similarly, +when stopping the stream, drivers call media_entity_pipeline_stop(). + +The media_entity_pipeline_start() function takes a pointer to a media +pipeline and stores it in every entity in the graph. Drivers should +embed the media_pipeline structure in higher-level pipeline structures +and can then access the pipeline through the media_entity structure. + +Link configuration will fail with -EBUSY by default if either end of the +link is a streaming entity, unless the link is marked with the +MEDIA_LNK_FL_DYNAMIC flag. + +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +--- + Documentation/DocBook/v4l/media-ioc-enum-links.xml | 5 ++ + Documentation/DocBook/v4l/media-ioc-setup-link.xml | 3 + + Documentation/media-framework.txt | 38 ++++++++++ + drivers/media/media-entity.c | 73 ++++++++++++++++++++ + include/linux/media.h | 1 + + include/media/media-entity.h | 10 +++ + 6 files changed, 130 insertions(+), 0 deletions(-) + +diff --git a/Documentation/DocBook/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/v4l/media-ioc-enum-links.xml +index daf0360..b204bfb 100644 +--- a/Documentation/DocBook/v4l/media-ioc-enum-links.xml ++++ b/Documentation/DocBook/v4l/media-ioc-enum-links.xml +@@ -179,6 +179,11 @@ + <entry>The link enabled state can't be modified at runtime. An + immutable link is always enabled.</entry> + </row> ++ <row> ++ <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry> ++ <entry>The link enabled state can be modified during streaming. This ++ flag is set by drivers and is read-only for applications.</entry> ++ </row> + </tbody> + </tgroup> + </table> +diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml +index 09ab3d2..2331e76 100644 +--- a/Documentation/DocBook/v4l/media-ioc-setup-link.xml ++++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml +@@ -60,6 +60,9 @@ + <para>Link configuration has no side effect on other links. If an enabled + link at the sink pad prevents the link from being enabled, the driver + returns with an &EBUSY;.</para> ++ <para>Only links marked with the <constant>DYNAMIC</constant> link flag can ++ be enabled/disabled while streaming media data. Attempting to enable or ++ disable a streaming non-dynamic link will return an &EBUSY;.</para> + <para>If the specified link can't be found the driver returns with an + &EINVAL;.</para> + </refsect1> +diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt +index 634845e..435d0c4 100644 +--- a/Documentation/media-framework.txt ++++ b/Documentation/media-framework.txt +@@ -313,3 +313,41 @@ Link configuration must not have any side effect on other links. If an enabled + link at a sink pad prevents another link at the same pad from being disabled, + the link_setup operation must return -EBUSY and can't implicitly disable the + first enabled link. ++ ++ ++Pipelines and media streams ++--------------------------- ++ ++When starting streaming, drivers must notify all entities in the pipeline to ++prevent link states from being modified during streaming by calling ++ ++ media_entity_pipeline_start(struct media_entity *entity, ++ struct media_pipeline *pipe); ++ ++The function will mark all entities connected to the given entity through ++enabled links, either directly or indirectly, as streaming. ++ ++The media_pipeline instance pointed to by the pipe argument will be stored in ++every entity in the pipeline. Drivers should embed the media_pipeline structure ++in higher-level pipeline structures and can then access the pipeline through ++the media_entity pipe field. ++ ++Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must ++be identical for all nested calls to the function. ++ ++When stopping the stream, drivers must notify the entities with ++ ++ media_entity_pipeline_stop(struct media_entity *entity); ++ ++If multiple calls to media_entity_pipeline_start() have been made the same ++number of media_entity_pipeline_stop() calls are required to stop streaming. The ++media_entity pipe field is reset to NULL on the last nested stop call. ++ ++Link configuration will fail with -EBUSY by default if either end of the link is ++a streaming entity. Links that can be modified while streaming must be marked ++with the MEDIA_LNK_FL_DYNAMIC flag. ++ ++If other operations need to be disallowed on streaming entities (such as ++changing entities configuration parameters) drivers can explictly check the ++media_entity stream_count field to find out if an entity is streaming. This ++operation must be done with the media_device graph_mutex held. +diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c +index d703ce8..e63e089 100644 +--- a/drivers/media/media-entity.c ++++ b/drivers/media/media-entity.c +@@ -197,6 +197,75 @@ media_entity_graph_walk_next(struct media_entity_graph *graph) + EXPORT_SYMBOL_GPL(media_entity_graph_walk_next); + + /* ----------------------------------------------------------------------------- ++ * Pipeline management ++ */ ++ ++/** ++ * media_entity_pipeline_start - Mark a pipeline as streaming ++ * @entity: Starting entity ++ * @pipe: Media pipeline to be assigned to all entities in the pipeline. ++ * ++ * Mark all entities connected to a given entity through enabled links, either ++ * directly or indirectly, as streaming. The given pipeline object is assigned to ++ * every entity in the pipeline and stored in the media_entity pipe field. ++ * ++ * Calls to this function can be nested, in which case the same number of ++ * media_entity_pipeline_stop() calls will be required to stop streaming. The ++ * pipeline pointer must be identical for all nested calls to ++ * media_entity_pipeline_start(). ++ */ ++void media_entity_pipeline_start(struct media_entity *entity, ++ struct media_pipeline *pipe) ++{ ++ struct media_device *mdev = entity->parent; ++ struct media_entity_graph graph; ++ ++ mutex_lock(&mdev->graph_mutex); ++ ++ media_entity_graph_walk_start(&graph, entity); ++ ++ while ((entity = media_entity_graph_walk_next(&graph))) { ++ entity->stream_count++; ++ WARN_ON(entity->pipe && entity->pipe != pipe); ++ entity->pipe = pipe; ++ } ++ ++ mutex_unlock(&mdev->graph_mutex); ++} ++EXPORT_SYMBOL_GPL(media_entity_pipeline_start); ++ ++/** ++ * media_entity_pipeline_stop - Mark a pipeline as not streaming ++ * @entity: Starting entity ++ * ++ * Mark all entities connected to a given entity through enabled links, either ++ * directly or indirectly, as not streaming. The media_entity pipe field is ++ * reset to NULL. ++ * ++ * If multiple calls to media_entity_pipeline_start() have been made, the same ++ * number of calls to this function are required to mark the pipeline as not ++ * streaming. ++ */ ++void media_entity_pipeline_stop(struct media_entity *entity) ++{ ++ struct media_device *mdev = entity->parent; ++ struct media_entity_graph graph; ++ ++ mutex_lock(&mdev->graph_mutex); ++ ++ media_entity_graph_walk_start(&graph, entity); ++ ++ while ((entity = media_entity_graph_walk_next(&graph))) { ++ entity->stream_count--; ++ if (entity->stream_count == 0) ++ entity->pipe = NULL; ++ } ++ ++ mutex_unlock(&mdev->graph_mutex); ++} ++EXPORT_SYMBOL_GPL(media_entity_pipeline_stop); ++ ++/* ----------------------------------------------------------------------------- + * Module use count + */ + +@@ -364,6 +433,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) + source = link->source->entity; + sink = link->sink->entity; + ++ if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && ++ (source->stream_count || sink->stream_count)) ++ return -EBUSY; ++ + mdev = source->parent; + + if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) { +diff --git a/include/linux/media.h b/include/linux/media.h +index 2f67ed2..29039e8 100644 +--- a/include/linux/media.h ++++ b/include/linux/media.h +@@ -106,6 +106,7 @@ struct media_pad_desc { + + #define MEDIA_LNK_FL_ENABLED (1 << 0) + #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) ++#define MEDIA_LNK_FL_DYNAMIC (1 << 2) + + struct media_link_desc { + struct media_pad_desc source; +diff --git a/include/media/media-entity.h b/include/media/media-entity.h +index 60fc7bd..450ba12 100644 +--- a/include/media/media-entity.h ++++ b/include/media/media-entity.h +@@ -26,6 +26,9 @@ + #include <linux/list.h> + #include <linux/media.h> + ++struct media_pipeline { ++}; ++ + struct media_link { + struct media_pad *source; /* Source pad */ + struct media_pad *sink; /* Sink pad */ +@@ -67,8 +70,11 @@ struct media_entity { + + const struct media_entity_operations *ops; /* Entity operations */ + ++ int stream_count; /* Stream count for the entity. */ + int use_count; /* Use count for the entity. */ + ++ struct media_pipeline *pipe; /* Pipeline this entity belongs to. */ ++ + union { + /* Node specifications */ + struct { +@@ -114,6 +120,7 @@ struct media_entity_graph { + int media_entity_init(struct media_entity *entity, u16 num_pads, + struct media_pad *pads, u16 extra_links); + void media_entity_cleanup(struct media_entity *entity); ++ + int media_entity_create_link(struct media_entity *source, u16 source_pad, + struct media_entity *sink, u16 sink_pad, u32 flags); + int __media_entity_setup_link(struct media_link *link, u32 flags); +@@ -129,6 +136,9 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, + struct media_entity *entity); + struct media_entity * + media_entity_graph_walk_next(struct media_entity_graph *graph); ++void media_entity_pipeline_start(struct media_entity *entity, ++ struct media_pipeline *pipe); ++void media_entity_pipeline_stop(struct media_entity *entity); + + #define media_entity_call(entity, operation, args...) \ + (((entity)->ops && (entity)->ops->operation) ? \ +-- +1.6.6.1 + |