static int isp_video_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { struct fimc_isp *isp = video_drvdata(file); struct exynos_video_entity *ve = &isp->video_capture.ve; struct media_entity *me = &ve->vdev.entity; int ret; ret = media_pipeline_start(me, &ve->pipe->mp); if (ret < 0) return ret; ret = isp_video_pipeline_validate(isp); if (ret < 0) goto p_stop; ret = vb2_ioctl_streamon(file, priv, type); if (ret < 0) goto p_stop; isp->video_capture.streaming = 1; return 0; p_stop: media_pipeline_stop(me); return ret; }
static void video_stop_streaming(struct vb2_queue *q) { struct camss_video *video = vb2_get_drv_priv(q); struct video_device *vdev = &video->vdev; struct media_entity *entity; struct media_pad *pad; struct v4l2_subdev *subdev; entity = &vdev->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; subdev = media_entity_to_v4l2_subdev(entity); v4l2_subdev_call(subdev, video, s_stream, 0); } media_pipeline_stop(&vdev->entity); video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR); }
static int isp_video_release(struct file *file) { struct fimc_isp *isp = video_drvdata(file); struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; struct media_device *mdev = entity->graph_obj.mdev; mutex_lock(&isp->video_lock); if (v4l2_fh_is_singular_file(file) && ivc->streaming) { media_pipeline_stop(entity); ivc->streaming = 0; } vb2_fop_release(file); if (v4l2_fh_is_singular_file(file)) { fimc_pipeline_call(&ivc->ve, close); mutex_lock(&mdev->graph_mutex); entity->use_count--; mutex_unlock(&mdev->graph_mutex); } pm_runtime_put(&isp->pdev->dev); mutex_unlock(&isp->video_lock); return 0; }
static int isp_video_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { struct fimc_isp *isp = video_drvdata(file); struct fimc_is_video *video = &isp->video_capture; int ret; ret = vb2_ioctl_streamoff(file, priv, type); if (ret < 0) return ret; media_pipeline_stop(&video->ve.vdev.entity); video->streaming = 0; return 0; }
static int video_start_streaming(struct vb2_queue *q, unsigned int count) { struct camss_video *video = vb2_get_drv_priv(q); struct video_device *vdev = &video->vdev; struct media_entity *entity; struct media_pad *pad; struct v4l2_subdev *subdev; int ret; ret = media_pipeline_start(&vdev->entity, &video->pipe); if (ret < 0) return ret; ret = video_check_format(video); if (ret < 0) goto error; entity = &vdev->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; subdev = media_entity_to_v4l2_subdev(entity); ret = v4l2_subdev_call(subdev, video, s_stream, 1); if (ret < 0 && ret != -ENOIOCTLCMD) goto error; } return 0; error: media_pipeline_stop(&vdev->entity); video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED); return ret; }