summaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-omap-2.6.37/media/0016-media-Pipelines-and-media-streams.patch
diff options
context:
space:
mode:
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.patch259
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
+