Example #1
0
/* Return a pointer to the ISP video instance at the far end of the pipeline. */
static int isp_video_get_graph_data(struct isp_video *video,
				    struct isp_pipeline *pipe)
{
	struct media_entity_graph graph;
	struct media_entity *entity = &video->video.entity;
	struct media_device *mdev = entity->graph_obj.mdev;
	struct isp_video *far_end = NULL;
	int ret;

	mutex_lock(&mdev->graph_mutex);
	ret = media_entity_graph_walk_init(&graph, entity->graph_obj.mdev);
	if (ret) {
		mutex_unlock(&mdev->graph_mutex);
		return ret;
	}

	media_entity_graph_walk_start(&graph, entity);

	while ((entity = media_entity_graph_walk_next(&graph))) {
		struct isp_video *__video;

		media_entity_enum_set(&pipe->ent_enum, entity);

		if (far_end != NULL)
			continue;

		if (entity == &video->video.entity)
			continue;

		if (!is_media_entity_v4l2_video_device(entity))
			continue;

		__video = to_isp_video(media_entity_to_video_device(entity));
		if (__video->type != video->type)
			far_end = __video;
	}

	mutex_unlock(&mdev->graph_mutex);

	media_entity_graph_walk_cleanup(&graph);

	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
		pipe->input = far_end;
		pipe->output = video;
	} else {
		if (far_end == NULL)
			return -EPIPE;

		pipe->input = video;
		pipe->output = far_end;
	}

	return 0;
}
Example #2
0
/*
 * iss_pipeline_disable - Disable streaming on a pipeline
 * @pipe: ISS pipeline
 * @until: entity at which to stop pipeline walk
 *
 * Walk the entities chain starting at the pipeline output video node and stop
 * all modules in the chain. Wait synchronously for the modules to be stopped if
 * necessary.
 *
 * If the until argument isn't NULL, stop the pipeline walk when reaching the
 * until entity. This is used to disable a partially started pipeline due to a
 * subdev start error.
 */
static int iss_pipeline_disable(struct iss_pipeline *pipe,
				struct media_entity *until)
{
	struct iss_device *iss = pipe->output->iss;
	struct media_entity *entity;
	struct media_pad *pad;
	struct v4l2_subdev *subdev;
	int failure = 0;
	int ret;

	entity = &pipe->output->video.entity;
	while (1) {
		pad = &entity->pads[0];
		if (!(pad->flags & MEDIA_PAD_FL_SINK))
			break;

		pad = media_entity_remote_pad(pad);
		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
			break;

		entity = pad->entity;
		if (entity == until)
			break;

		subdev = media_entity_to_v4l2_subdev(entity);
		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
		if (ret < 0) {
			dev_warn(iss->dev, "%s: module stop timeout.\n",
				 subdev->name);
			/* If the entity failed to stopped, assume it has
			 * crashed. Mark it as such, the ISS will be reset when
			 * applications will release it.
			 */
			media_entity_enum_set(&iss->crashed, &subdev->entity);
			failure = -ETIMEDOUT;
		}
	}

	return failure;
}