media: v4l2-dev: Add videodev wrappers for media pipelines

With the upcoming stream related improvements to the pipelines, the
pipelines are moved from media entities to media pads. As the drivers
currently use the pipelines with the entity based model, moving the
pipelines to pads will cause changes to the drivers.

However, most of the uses of media pipelines are related to a video
device (a DMA engine) with a single pad, and thus there's never a need
to support multiple pads in these use cases. We can avoid pushing the
complexities of the pad based model to the drivers by adding video
device wrappers for the pipeline related functions.

This patch adds a number of wrappers to media_pipeline functions, all of
which take a video_device as a parameter (instead of a media_entity),
and verify that there's just one pad.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Tomi Valkeinen 2022-08-31 16:13:32 +02:00 committed by Mauro Carvalho Chehab
parent 72b603357a
commit 340eba477f
2 changed files with 149 additions and 0 deletions

View File

@ -1095,6 +1095,67 @@ void video_unregister_device(struct video_device *vdev)
}
EXPORT_SYMBOL(video_unregister_device);
#if defined(CONFIG_MEDIA_CONTROLLER)
__must_check int video_device_pipeline_start(struct video_device *vdev,
struct media_pipeline *pipe)
{
struct media_entity *entity = &vdev->entity;
if (entity->num_pads != 1)
return -ENODEV;
return media_pipeline_start(entity, pipe);
}
EXPORT_SYMBOL_GPL(video_device_pipeline_start);
__must_check int __video_device_pipeline_start(struct video_device *vdev,
struct media_pipeline *pipe)
{
struct media_entity *entity = &vdev->entity;
if (entity->num_pads != 1)
return -ENODEV;
return __media_pipeline_start(entity, pipe);
}
EXPORT_SYMBOL_GPL(__video_device_pipeline_start);
void video_device_pipeline_stop(struct video_device *vdev)
{
struct media_entity *entity = &vdev->entity;
if (WARN_ON(entity->num_pads != 1))
return;
return media_pipeline_stop(entity);
}
EXPORT_SYMBOL_GPL(video_device_pipeline_stop);
void __video_device_pipeline_stop(struct video_device *vdev)
{
struct media_entity *entity = &vdev->entity;
if (WARN_ON(entity->num_pads != 1))
return;
return __media_pipeline_stop(entity);
}
EXPORT_SYMBOL_GPL(__video_device_pipeline_stop);
struct media_pipeline *video_device_pipeline(struct video_device *vdev)
{
struct media_entity *entity = &vdev->entity;
if (WARN_ON(entity->num_pads != 1))
return NULL;
return media_entity_pipeline(entity);
}
EXPORT_SYMBOL_GPL(video_device_pipeline);
#endif /* CONFIG_MEDIA_CONTROLLER */
/*
* Initialise video for linux
*/

View File

@ -539,4 +539,92 @@ static inline int video_is_registered(struct video_device *vdev)
return test_bit(V4L2_FL_REGISTERED, &vdev->flags);
}
#if defined(CONFIG_MEDIA_CONTROLLER)
/**
* video_device_pipeline_start - Mark a pipeline as streaming
* @vdev: Starting video device
* @pipe: Media pipeline to be assigned to all entities in the pipeline.
*
* Mark all entities connected to a given video device 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
* video_device_pipeline_stop() calls will be required to stop streaming. The
* pipeline pointer must be identical for all nested calls to
* video_device_pipeline_start().
*
* The video device must contain a single pad.
*
* This is a convenience wrapper around media_pipeline_start().
*/
__must_check int video_device_pipeline_start(struct video_device *vdev,
struct media_pipeline *pipe);
/**
* __video_device_pipeline_start - Mark a pipeline as streaming
* @vdev: Starting video device
* @pipe: Media pipeline to be assigned to all entities in the pipeline.
*
* ..note:: This is the non-locking version of video_device_pipeline_start()
*
* The video device must contain a single pad.
*
* This is a convenience wrapper around __media_pipeline_start().
*/
__must_check int __video_device_pipeline_start(struct video_device *vdev,
struct media_pipeline *pipe);
/**
* video_device_pipeline_stop - Mark a pipeline as not streaming
* @vdev: Starting video device
*
* Mark all entities connected to a given video device through enabled links,
* either directly or indirectly, as not streaming. The media_entity pipe field
* is reset to %NULL.
*
* If multiple calls to media_pipeline_start() have been made, the same
* number of calls to this function are required to mark the pipeline as not
* streaming.
*
* The video device must contain a single pad.
*
* This is a convenience wrapper around media_pipeline_stop().
*/
void video_device_pipeline_stop(struct video_device *vdev);
/**
* __video_device_pipeline_stop - Mark a pipeline as not streaming
* @vdev: Starting video device
*
* .. note:: This is the non-locking version of media_pipeline_stop()
*
* The video device must contain a single pad.
*
* This is a convenience wrapper around __media_pipeline_stop().
*/
void __video_device_pipeline_stop(struct video_device *vdev);
/**
* video_device_pipeline - Get the media pipeline a video device is part of
* @vdev: The video device
*
* This function returns the media pipeline that a video device has been
* associated with when constructing the pipeline with
* video_device_pipeline_start(). The pointer remains valid until
* video_device_pipeline_stop() is called.
*
* Return: The media_pipeline the video device is part of, or NULL if the video
* device is not part of any pipeline.
*
* The video device must contain a single pad.
*
* This is a convenience wrapper around media_entity_pipeline().
*/
struct media_pipeline *video_device_pipeline(struct video_device *vdev);
#endif /* CONFIG_MEDIA_CONTROLLER */
#endif /* _V4L2_DEV_H */