summaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch')
-rw-r--r--extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch259
1 files changed, 259 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch b/extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch
new file mode 100644
index 00000000..969162f8
--- /dev/null
+++ b/extras/recipes-kernel/linux/linux-omap/media/0016-media-Pipelines-and-media-streams.patch
@@ -0,0 +1,259 @@
1From 4e07e9ada1b3baaec6d4948eccf3c0499e3228df Mon Sep 17 00:00:00 2001
2From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
3Date: Wed, 25 Aug 2010 15:00:41 +0300
4Subject: [PATCH 16/43] media: Pipelines and media streams
5
6Drivers often need to associate pipeline objects to entities, and to
7take stream state into account when configuring entities and links. The
8pipeline API helps drivers manage that information.
9
10When starting streaming, drivers call media_entity_pipeline_start(). The
11function marks all entities connected to the given entity through
12enabled links, either directly or indirectly, as streaming. Similarly,
13when stopping the stream, drivers call media_entity_pipeline_stop().
14
15The media_entity_pipeline_start() function takes a pointer to a media
16pipeline and stores it in every entity in the graph. Drivers should
17embed the media_pipeline structure in higher-level pipeline structures
18and can then access the pipeline through the media_entity structure.
19
20Link configuration will fail with -EBUSY by default if either end of the
21link is a streaming entity, unless the link is marked with the
22MEDIA_LNK_FL_DYNAMIC flag.
23
24Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
25---
26 Documentation/DocBook/v4l/media-ioc-enum-links.xml | 5 ++
27 Documentation/DocBook/v4l/media-ioc-setup-link.xml | 3 +
28 Documentation/media-framework.txt | 38 ++++++++++
29 drivers/media/media-entity.c | 73 ++++++++++++++++++++
30 include/linux/media.h | 1 +
31 include/media/media-entity.h | 10 +++
32 6 files changed, 130 insertions(+), 0 deletions(-)
33
34diff --git a/Documentation/DocBook/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
35index daf0360..b204bfb 100644
36--- a/Documentation/DocBook/v4l/media-ioc-enum-links.xml
37+++ b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
38@@ -179,6 +179,11 @@
39 <entry>The link enabled state can't be modified at runtime. An
40 immutable link is always enabled.</entry>
41 </row>
42+ <row>
43+ <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry>
44+ <entry>The link enabled state can be modified during streaming. This
45+ flag is set by drivers and is read-only for applications.</entry>
46+ </row>
47 </tbody>
48 </tgroup>
49 </table>
50diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
51index 09ab3d2..2331e76 100644
52--- a/Documentation/DocBook/v4l/media-ioc-setup-link.xml
53+++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
54@@ -60,6 +60,9 @@
55 <para>Link configuration has no side effect on other links. If an enabled
56 link at the sink pad prevents the link from being enabled, the driver
57 returns with an &EBUSY;.</para>
58+ <para>Only links marked with the <constant>DYNAMIC</constant> link flag can
59+ be enabled/disabled while streaming media data. Attempting to enable or
60+ disable a streaming non-dynamic link will return an &EBUSY;.</para>
61 <para>If the specified link can't be found the driver returns with an
62 &EINVAL;.</para>
63 </refsect1>
64diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
65index 634845e..435d0c4 100644
66--- a/Documentation/media-framework.txt
67+++ b/Documentation/media-framework.txt
68@@ -313,3 +313,41 @@ Link configuration must not have any side effect on other links. If an enabled
69 link at a sink pad prevents another link at the same pad from being disabled,
70 the link_setup operation must return -EBUSY and can't implicitly disable the
71 first enabled link.
72+
73+
74+Pipelines and media streams
75+---------------------------
76+
77+When starting streaming, drivers must notify all entities in the pipeline to
78+prevent link states from being modified during streaming by calling
79+
80+ media_entity_pipeline_start(struct media_entity *entity,
81+ struct media_pipeline *pipe);
82+
83+The function will mark all entities connected to the given entity through
84+enabled links, either directly or indirectly, as streaming.
85+
86+The media_pipeline instance pointed to by the pipe argument will be stored in
87+every entity in the pipeline. Drivers should embed the media_pipeline structure
88+in higher-level pipeline structures and can then access the pipeline through
89+the media_entity pipe field.
90+
91+Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
92+be identical for all nested calls to the function.
93+
94+When stopping the stream, drivers must notify the entities with
95+
96+ media_entity_pipeline_stop(struct media_entity *entity);
97+
98+If multiple calls to media_entity_pipeline_start() have been made the same
99+number of media_entity_pipeline_stop() calls are required to stop streaming. The
100+media_entity pipe field is reset to NULL on the last nested stop call.
101+
102+Link configuration will fail with -EBUSY by default if either end of the link is
103+a streaming entity. Links that can be modified while streaming must be marked
104+with the MEDIA_LNK_FL_DYNAMIC flag.
105+
106+If other operations need to be disallowed on streaming entities (such as
107+changing entities configuration parameters) drivers can explictly check the
108+media_entity stream_count field to find out if an entity is streaming. This
109+operation must be done with the media_device graph_mutex held.
110diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
111index d703ce8..e63e089 100644
112--- a/drivers/media/media-entity.c
113+++ b/drivers/media/media-entity.c
114@@ -197,6 +197,75 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
115 EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
116
117 /* -----------------------------------------------------------------------------
118+ * Pipeline management
119+ */
120+
121+/**
122+ * media_entity_pipeline_start - Mark a pipeline as streaming
123+ * @entity: Starting entity
124+ * @pipe: Media pipeline to be assigned to all entities in the pipeline.
125+ *
126+ * Mark all entities connected to a given entity through enabled links, either
127+ * directly or indirectly, as streaming. The given pipeline object is assigned to
128+ * every entity in the pipeline and stored in the media_entity pipe field.
129+ *
130+ * Calls to this function can be nested, in which case the same number of
131+ * media_entity_pipeline_stop() calls will be required to stop streaming. The
132+ * pipeline pointer must be identical for all nested calls to
133+ * media_entity_pipeline_start().
134+ */
135+void media_entity_pipeline_start(struct media_entity *entity,
136+ struct media_pipeline *pipe)
137+{
138+ struct media_device *mdev = entity->parent;
139+ struct media_entity_graph graph;
140+
141+ mutex_lock(&mdev->graph_mutex);
142+
143+ media_entity_graph_walk_start(&graph, entity);
144+
145+ while ((entity = media_entity_graph_walk_next(&graph))) {
146+ entity->stream_count++;
147+ WARN_ON(entity->pipe && entity->pipe != pipe);
148+ entity->pipe = pipe;
149+ }
150+
151+ mutex_unlock(&mdev->graph_mutex);
152+}
153+EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
154+
155+/**
156+ * media_entity_pipeline_stop - Mark a pipeline as not streaming
157+ * @entity: Starting entity
158+ *
159+ * Mark all entities connected to a given entity through enabled links, either
160+ * directly or indirectly, as not streaming. The media_entity pipe field is
161+ * reset to NULL.
162+ *
163+ * If multiple calls to media_entity_pipeline_start() have been made, the same
164+ * number of calls to this function are required to mark the pipeline as not
165+ * streaming.
166+ */
167+void media_entity_pipeline_stop(struct media_entity *entity)
168+{
169+ struct media_device *mdev = entity->parent;
170+ struct media_entity_graph graph;
171+
172+ mutex_lock(&mdev->graph_mutex);
173+
174+ media_entity_graph_walk_start(&graph, entity);
175+
176+ while ((entity = media_entity_graph_walk_next(&graph))) {
177+ entity->stream_count--;
178+ if (entity->stream_count == 0)
179+ entity->pipe = NULL;
180+ }
181+
182+ mutex_unlock(&mdev->graph_mutex);
183+}
184+EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
185+
186+/* -----------------------------------------------------------------------------
187 * Module use count
188 */
189
190@@ -364,6 +433,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
191 source = link->source->entity;
192 sink = link->sink->entity;
193
194+ if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
195+ (source->stream_count || sink->stream_count))
196+ return -EBUSY;
197+
198 mdev = source->parent;
199
200 if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
201diff --git a/include/linux/media.h b/include/linux/media.h
202index 2f67ed2..29039e8 100644
203--- a/include/linux/media.h
204+++ b/include/linux/media.h
205@@ -106,6 +106,7 @@ struct media_pad_desc {
206
207 #define MEDIA_LNK_FL_ENABLED (1 << 0)
208 #define MEDIA_LNK_FL_IMMUTABLE (1 << 1)
209+#define MEDIA_LNK_FL_DYNAMIC (1 << 2)
210
211 struct media_link_desc {
212 struct media_pad_desc source;
213diff --git a/include/media/media-entity.h b/include/media/media-entity.h
214index 60fc7bd..450ba12 100644
215--- a/include/media/media-entity.h
216+++ b/include/media/media-entity.h
217@@ -26,6 +26,9 @@
218 #include <linux/list.h>
219 #include <linux/media.h>
220
221+struct media_pipeline {
222+};
223+
224 struct media_link {
225 struct media_pad *source; /* Source pad */
226 struct media_pad *sink; /* Sink pad */
227@@ -67,8 +70,11 @@ struct media_entity {
228
229 const struct media_entity_operations *ops; /* Entity operations */
230
231+ int stream_count; /* Stream count for the entity. */
232 int use_count; /* Use count for the entity. */
233
234+ struct media_pipeline *pipe; /* Pipeline this entity belongs to. */
235+
236 union {
237 /* Node specifications */
238 struct {
239@@ -114,6 +120,7 @@ struct media_entity_graph {
240 int media_entity_init(struct media_entity *entity, u16 num_pads,
241 struct media_pad *pads, u16 extra_links);
242 void media_entity_cleanup(struct media_entity *entity);
243+
244 int media_entity_create_link(struct media_entity *source, u16 source_pad,
245 struct media_entity *sink, u16 sink_pad, u32 flags);
246 int __media_entity_setup_link(struct media_link *link, u32 flags);
247@@ -129,6 +136,9 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
248 struct media_entity *entity);
249 struct media_entity *
250 media_entity_graph_walk_next(struct media_entity_graph *graph);
251+void media_entity_pipeline_start(struct media_entity *entity,
252+ struct media_pipeline *pipe);
253+void media_entity_pipeline_stop(struct media_entity *entity);
254
255 #define media_entity_call(entity, operation, args...) \
256 (((entity)->ops && (entity)->ops->operation) ? \
257--
2581.6.6.1
259