linux-omap 2.6.37: sync with OE .dev
[glsdk/meta-ti-glsdk.git] / recipes-bsp / linux / linux-omap / media / 0016-media-Pipelines-and-media-streams.patch
1 From 4e07e9ada1b3baaec6d4948eccf3c0499e3228df Mon Sep 17 00:00:00 2001
2 From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
3 Date: Wed, 25 Aug 2010 15:00:41 +0300
4 Subject: [PATCH 16/43] media: Pipelines and media streams
6 Drivers often need to associate pipeline objects to entities, and to
7 take stream state into account when configuring entities and links. The
8 pipeline API helps drivers manage that information.
10 When starting streaming, drivers call media_entity_pipeline_start(). The
11 function marks all entities connected to the given entity through
12 enabled links, either directly or indirectly, as streaming. Similarly,
13 when stopping the stream, drivers call media_entity_pipeline_stop().
15 The media_entity_pipeline_start() function takes a pointer to a media
16 pipeline and stores it in every entity in the graph. Drivers should
17 embed the media_pipeline structure in higher-level pipeline structures
18 and can then access the pipeline through the media_entity structure.
20 Link configuration will fail with -EBUSY by default if either end of the
21 link is a streaming entity, unless the link is marked with the
22 MEDIA_LNK_FL_DYNAMIC flag.
24 Signed-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(-)
34 diff --git a/Documentation/DocBook/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
35 index 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>
50 diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
51 index 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>
64 diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
65 index 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.
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.
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.
110 diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
111 index 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 + */
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;
141 +       mutex_lock(&mdev->graph_mutex);
143 +       media_entity_graph_walk_start(&graph, entity);
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 +       }
151 +       mutex_unlock(&mdev->graph_mutex);
152 +}
153 +EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
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;
172 +       mutex_lock(&mdev->graph_mutex);
174 +       media_entity_graph_walk_start(&graph, entity);
176 +       while ((entity = media_entity_graph_walk_next(&graph))) {
177 +               entity->stream_count--;
178 +               if (entity->stream_count == 0)
179 +                       entity->pipe = NULL;
180 +       }
182 +       mutex_unlock(&mdev->graph_mutex);
183 +}
184 +EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
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;
198         mdev = source->parent;
199  
200         if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
201 diff --git a/include/linux/media.h b/include/linux/media.h
202 index 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;
213 diff --git a/include/media/media-entity.h b/include/media/media-entity.h
214 index 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 +};
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. */
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);
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 -- 
258 1.6.6.1