Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242013
b: refs/heads/master
c: e02188c
h: refs/heads/master
i:
  242011: bf20aaf
v: v3
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Mar 22, 2011
1 parent a6597a4 commit 8072d28
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 97548ed4c4661502cdfd1aabd5d3876fa4f5cc2e
refs/heads/master: e02188c90f6ef61f0844c42508fe603c5d4fa42b
5 changes: 5 additions & 0 deletions trunk/Documentation/DocBook/v4l/media-ioc-enum-links.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
3 changes: 3 additions & 0 deletions trunk/Documentation/DocBook/v4l/media-ioc-setup-link.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
38 changes: 38 additions & 0 deletions trunk/Documentation/media-framework.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
73 changes: 73 additions & 0 deletions trunk/drivers/media/media-entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,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
*/
Expand Down Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/media.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions trunk/include/media/media-entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -71,8 +74,11 @@ struct media_entity {
* purpose: a simple WARN_ON(<0) check can be used to detect reference
* count bugs that would make them negative.
*/
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 {
Expand Down Expand Up @@ -118,6 +124,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);
Expand All @@ -133,6 +140,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) ? \
Expand Down

0 comments on commit 8072d28

Please sign in to comment.