[media] exynos4-is: Add struct exynos_video_entity

This patch introduces common structure for the video entities
to handle all video nodes and media pipelines associated with
them in more generic way.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Sylwester Nawrocki 2013-05-31 11:37:18 -03:00 committed by Mauro Carvalho Chehab
parent 045a1faca8
commit bc7584b0b7
9 changed files with 55 additions and 42 deletions

View File

@ -320,6 +320,7 @@ static void buffer_queue(struct vb2_buffer *vb);
int fimc_capture_resume(struct fimc_dev *fimc) int fimc_capture_resume(struct fimc_dev *fimc)
{ {
struct fimc_vid_cap *vid_cap = &fimc->vid_cap; struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
struct exynos_video_entity *ve = &vid_cap->ve;
struct fimc_vid_buffer *buf; struct fimc_vid_buffer *buf;
int i; int i;
@ -329,7 +330,7 @@ int fimc_capture_resume(struct fimc_dev *fimc)
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
vid_cap->buf_index = 0; vid_cap->buf_index = 0;
fimc_pipeline_call(fimc, open, &fimc->pipeline, fimc_pipeline_call(fimc, open, &fimc->pipeline,
&vid_cap->vfd.entity, false); &ve->vdev.entity, false);
fimc_capture_hw_init(fimc); fimc_capture_hw_init(fimc);
clear_bit(ST_CAPT_SUSPENDED, &fimc->state); clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@ -397,7 +398,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
unsigned long size = ctx->d_frame.payload[i]; unsigned long size = ctx->d_frame.payload[i];
if (vb2_plane_size(vb, i) < size) { if (vb2_plane_size(vb, i) < size) {
v4l2_err(&ctx->fimc_dev->vid_cap.vfd, v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
"User buffer too small (%ld < %ld)\n", "User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size); vb2_plane_size(vb, i), size);
return -EINVAL; return -EINVAL;
@ -415,6 +416,7 @@ static void buffer_queue(struct vb2_buffer *vb)
struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_vid_cap *vid_cap = &fimc->vid_cap; struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
struct exynos_video_entity *ve = &vid_cap->ve;
unsigned long flags; unsigned long flags;
int min_bufs; int min_bufs;
@ -454,7 +456,7 @@ static void buffer_queue(struct vb2_buffer *vb)
ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1); ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
if (ret < 0) if (ret < 0)
v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret); v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
return; return;
} }
spin_unlock_irqrestore(&fimc->slock, flags); spin_unlock_irqrestore(&fimc->slock, flags);
@ -503,11 +505,12 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc);
static int fimc_capture_open(struct file *file) static int fimc_capture_open(struct file *file)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct exynos_video_entity *ve = &fimc->vid_cap.ve;
int ret = -EBUSY; int ret = -EBUSY;
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
fimc_md_graph_lock(fimc); fimc_md_graph_lock(ve);
mutex_lock(&fimc->lock); mutex_lock(&fimc->lock);
if (fimc_m2m_active(fimc)) if (fimc_m2m_active(fimc))
@ -526,7 +529,7 @@ static int fimc_capture_open(struct file *file)
if (v4l2_fh_is_singular_file(file)) { if (v4l2_fh_is_singular_file(file)) {
ret = fimc_pipeline_call(fimc, open, &fimc->pipeline, ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
&fimc->vid_cap.vfd.entity, true); &fimc->vid_cap.ve.vdev.entity, true);
if (!ret && !fimc->vid_cap.user_subdev_api) if (!ret && !fimc->vid_cap.user_subdev_api)
ret = fimc_capture_set_default_format(fimc); ret = fimc_capture_set_default_format(fimc);
@ -544,7 +547,7 @@ static int fimc_capture_open(struct file *file)
} }
unlock: unlock:
mutex_unlock(&fimc->lock); mutex_unlock(&fimc->lock);
fimc_md_graph_unlock(fimc); fimc_md_graph_unlock(ve);
return ret; return ret;
} }
@ -560,7 +563,7 @@ static int fimc_capture_release(struct file *file)
if (v4l2_fh_is_singular_file(file)) { if (v4l2_fh_is_singular_file(file)) {
if (vc->streaming) { if (vc->streaming) {
media_entity_pipeline_stop(&vc->vfd.entity); media_entity_pipeline_stop(&vc->ve.vdev.entity);
vc->streaming = false; vc->streaming = false;
} }
clear_bit(ST_CAPT_BUSY, &fimc->state); clear_bit(ST_CAPT_BUSY, &fimc->state);
@ -935,11 +938,12 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct fimc_ctx *ctx = fimc->vid_cap.ctx; struct fimc_ctx *ctx = fimc->vid_cap.ctx;
struct exynos_video_entity *ve = &fimc->vid_cap.ve;
struct v4l2_mbus_framefmt mf; struct v4l2_mbus_framefmt mf;
struct fimc_fmt *ffmt = NULL; struct fimc_fmt *ffmt = NULL;
int ret = 0; int ret = 0;
fimc_md_graph_lock(fimc); fimc_md_graph_lock(ve);
mutex_lock(&fimc->lock); mutex_lock(&fimc->lock);
if (fimc_jpeg_fourcc(pix->pixelformat)) { if (fimc_jpeg_fourcc(pix->pixelformat)) {
@ -975,7 +979,7 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
pix->plane_fmt, ffmt->memplanes, true); pix->plane_fmt, ffmt->memplanes, true);
unlock: unlock:
mutex_unlock(&fimc->lock); mutex_unlock(&fimc->lock);
fimc_md_graph_unlock(fimc); fimc_md_graph_unlock(ve);
return ret; return ret;
} }
@ -1076,7 +1080,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
int ret; int ret;
fimc_md_graph_lock(fimc); fimc_md_graph_lock(&fimc->vid_cap.ve);
mutex_lock(&fimc->lock); mutex_lock(&fimc->lock);
/* /*
* The graph is walked within __fimc_capture_set_format() to set * The graph is walked within __fimc_capture_set_format() to set
@ -1088,8 +1092,8 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
*/ */
ret = __fimc_capture_set_format(fimc, f); ret = __fimc_capture_set_format(fimc, f);
fimc_md_graph_unlock(&fimc->vid_cap.ve);
mutex_unlock(&fimc->lock); mutex_unlock(&fimc->lock);
fimc_md_graph_unlock(fimc);
return ret; return ret;
} }
@ -1209,7 +1213,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct fimc_pipeline *p = &fimc->pipeline; struct fimc_pipeline *p = &fimc->pipeline;
struct fimc_vid_cap *vc = &fimc->vid_cap; struct fimc_vid_cap *vc = &fimc->vid_cap;
struct media_entity *entity = &vc->vfd.entity; struct media_entity *entity = &vc->ve.vdev.entity;
struct fimc_source_info *si = NULL; struct fimc_source_info *si = NULL;
struct v4l2_subdev *sd; struct v4l2_subdev *sd;
int ret; int ret;
@ -1259,14 +1263,15 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct fimc_vid_cap *vc = &fimc->vid_cap;
int ret; int ret;
ret = vb2_ioctl_streamoff(file, priv, type); ret = vb2_ioctl_streamoff(file, priv, type);
if (ret < 0) if (ret < 0)
return ret; return ret;
media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity); media_entity_pipeline_stop(&vc->ve.vdev.entity);
fimc->vid_cap.streaming = false; vc->streaming = false;
return 0; return 0;
} }
@ -1735,7 +1740,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc)
static int fimc_register_capture_device(struct fimc_dev *fimc, static int fimc_register_capture_device(struct fimc_dev *fimc,
struct v4l2_device *v4l2_dev) struct v4l2_device *v4l2_dev)
{ {
struct video_device *vfd = &fimc->vid_cap.vfd; struct video_device *vfd = &fimc->vid_cap.ve.vdev;
struct vb2_queue *q = &fimc->vid_cap.vbq; struct vb2_queue *q = &fimc->vid_cap.vbq;
struct fimc_ctx *ctx; struct fimc_ctx *ctx;
struct fimc_vid_cap *vid_cap; struct fimc_vid_cap *vid_cap;
@ -1840,15 +1845,17 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
{ {
struct fimc_dev *fimc = v4l2_get_subdevdata(sd); struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
struct video_device *vdev;
if (fimc == NULL) if (fimc == NULL)
return; return;
fimc_unregister_m2m_device(fimc); fimc_unregister_m2m_device(fimc);
vdev = &fimc->vid_cap.ve.vdev;
if (video_is_registered(&fimc->vid_cap.vfd)) { if (video_is_registered(vdev)) {
video_unregister_device(&fimc->vid_cap.vfd); video_unregister_device(vdev);
media_entity_cleanup(&fimc->vid_cap.vfd.entity); media_entity_cleanup(&vdev->entity);
fimc->pipeline_ops = NULL; fimc->pipeline_ops = NULL;
} }
kfree(fimc->vid_cap.ctx); kfree(fimc->vid_cap.ctx);

View File

@ -283,8 +283,8 @@ struct fimc_m2m_device {
/** /**
* struct fimc_vid_cap - camera capture device information * struct fimc_vid_cap - camera capture device information
* @ctx: hardware context data * @ctx: hardware context data
* @vfd: video device node for camera capture mode
* @subdev: subdev exposing the FIMC processing block * @subdev: subdev exposing the FIMC processing block
* @ve: exynos video device entity structure
* @vd_pad: fimc video capture node pad * @vd_pad: fimc video capture node pad
* @sd_pads: fimc video processing block pads * @sd_pads: fimc video processing block pads
* @ci_fmt: image format at the FIMC camera input (and the scaler output) * @ci_fmt: image format at the FIMC camera input (and the scaler output)
@ -305,8 +305,8 @@ struct fimc_m2m_device {
struct fimc_vid_cap { struct fimc_vid_cap {
struct fimc_ctx *ctx; struct fimc_ctx *ctx;
struct vb2_alloc_ctx *alloc_ctx; struct vb2_alloc_ctx *alloc_ctx;
struct video_device vfd;
struct v4l2_subdev subdev; struct v4l2_subdev subdev;
struct exynos_video_entity ve;
struct media_pad vd_pad; struct media_pad vd_pad;
struct media_pad sd_pads[FIMC_SD_PADS_NUM]; struct media_pad sd_pads[FIMC_SD_PADS_NUM];
struct v4l2_mbus_framefmt ci_fmt; struct v4l2_mbus_framefmt ci_fmt;

View File

@ -137,7 +137,7 @@ void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
} }
if (i == 0 && src_pixfmt_map[i][0] != pixelcode) { if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
v4l2_err(&dev->vfd, v4l2_err(&dev->ve.vdev,
"Unsupported pixel code, falling back to %#08x\n", "Unsupported pixel code, falling back to %#08x\n",
src_pixfmt_map[i][0]); src_pixfmt_map[i][0]);
} }

View File

@ -392,7 +392,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
unsigned long size = fimc->payload[i]; unsigned long size = fimc->payload[i];
if (vb2_plane_size(vb, i) < size) { if (vb2_plane_size(vb, i) < size) {
v4l2_err(&fimc->vfd, v4l2_err(&fimc->ve.vdev,
"User buffer too small (%ld < %ld)\n", "User buffer too small (%ld < %ld)\n",
vb2_plane_size(vb, i), size); vb2_plane_size(vb, i), size);
return -EINVAL; return -EINVAL;
@ -458,7 +458,7 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
static int fimc_lite_open(struct file *file) static int fimc_lite_open(struct file *file)
{ {
struct fimc_lite *fimc = video_drvdata(file); struct fimc_lite *fimc = video_drvdata(file);
struct media_entity *me = &fimc->vfd.entity; struct media_entity *me = &fimc->ve.vdev.entity;
int ret; int ret;
mutex_lock(&me->parent->graph_mutex); mutex_lock(&me->parent->graph_mutex);
@ -509,7 +509,7 @@ static int fimc_lite_release(struct file *file)
if (v4l2_fh_is_singular_file(file) && if (v4l2_fh_is_singular_file(file) &&
atomic_read(&fimc->out_path) == FIMC_IO_DMA) { atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
if (fimc->streaming) { if (fimc->streaming) {
media_entity_pipeline_stop(&fimc->vfd.entity); media_entity_pipeline_stop(&fimc->ve.vdev.entity);
fimc->streaming = false; fimc->streaming = false;
} }
clear_bit(ST_FLITE_IN_USE, &fimc->state); clear_bit(ST_FLITE_IN_USE, &fimc->state);
@ -792,7 +792,7 @@ static int fimc_lite_streamon(struct file *file, void *priv,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct fimc_lite *fimc = video_drvdata(file); struct fimc_lite *fimc = video_drvdata(file);
struct media_entity *entity = &fimc->vfd.entity; struct media_entity *entity = &fimc->ve.vdev.entity;
struct fimc_pipeline *p = &fimc->pipeline; struct fimc_pipeline *p = &fimc->pipeline;
int ret; int ret;
@ -830,7 +830,7 @@ static int fimc_lite_streamoff(struct file *file, void *priv,
if (ret < 0) if (ret < 0)
return ret; return ret;
media_entity_pipeline_stop(&fimc->vfd.entity); media_entity_pipeline_stop(&fimc->ve.vdev.entity);
fimc->streaming = false; fimc->streaming = false;
return 0; return 0;
} }
@ -1234,7 +1234,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
{ {
struct fimc_lite *fimc = v4l2_get_subdevdata(sd); struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
struct vb2_queue *q = &fimc->vb_queue; struct vb2_queue *q = &fimc->vb_queue;
struct video_device *vfd = &fimc->vfd; struct video_device *vfd = &fimc->ve.vdev;
int ret; int ret;
memset(vfd, 0, sizeof(*vfd)); memset(vfd, 0, sizeof(*vfd));
@ -1298,9 +1298,9 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
if (fimc == NULL) if (fimc == NULL)
return; return;
if (video_is_registered(&fimc->vfd)) { if (video_is_registered(&fimc->ve.vdev)) {
video_unregister_device(&fimc->vfd); video_unregister_device(&fimc->ve.vdev);
media_entity_cleanup(&fimc->vfd.entity); media_entity_cleanup(&fimc->ve.vdev.entity);
fimc->pipeline_ops = NULL; fimc->pipeline_ops = NULL;
} }
} }
@ -1548,7 +1548,7 @@ static int fimc_lite_resume(struct device *dev)
INIT_LIST_HEAD(&fimc->active_buf_q); INIT_LIST_HEAD(&fimc->active_buf_q);
fimc_pipeline_call(fimc, open, &fimc->pipeline, fimc_pipeline_call(fimc, open, &fimc->pipeline,
&fimc->vfd.entity, false); &fimc->ve.vdev.entity, false);
fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP); fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
clear_bit(ST_FLITE_SUSPENDED, &fimc->state); clear_bit(ST_FLITE_SUSPENDED, &fimc->state);

View File

@ -95,8 +95,8 @@ struct flite_buffer {
* struct fimc_lite - fimc lite structure * struct fimc_lite - fimc lite structure
* @pdev: pointer to FIMC-LITE platform device * @pdev: pointer to FIMC-LITE platform device
* @dd: SoC specific driver data structure * @dd: SoC specific driver data structure
* @ve: exynos video device entity structure
* @v4l2_dev: pointer to top the level v4l2_device * @v4l2_dev: pointer to top the level v4l2_device
* @vfd: video device node
* @fh: v4l2 file handle * @fh: v4l2 file handle
* @alloc_ctx: videobuf2 memory allocator context * @alloc_ctx: videobuf2 memory allocator context
* @subdev: FIMC-LITE subdev * @subdev: FIMC-LITE subdev
@ -130,8 +130,8 @@ struct flite_buffer {
struct fimc_lite { struct fimc_lite {
struct platform_device *pdev; struct platform_device *pdev;
struct flite_drvdata *dd; struct flite_drvdata *dd;
struct exynos_video_entity ve;
struct v4l2_device *v4l2_dev; struct v4l2_device *v4l2_dev;
struct video_device vfd;
struct v4l2_fh fh; struct v4l2_fh fh;
struct vb2_alloc_ctx *alloc_ctx; struct vb2_alloc_ctx *alloc_ctx;
struct v4l2_subdev subdev; struct v4l2_subdev subdev;

View File

@ -618,7 +618,7 @@ int fimc_hw_set_camera_source(struct fimc_dev *fimc,
} }
if (i == ARRAY_SIZE(pix_desc)) { if (i == ARRAY_SIZE(pix_desc)) {
v4l2_err(&vc->vfd, v4l2_err(&vc->ve.vdev,
"Camera color format not supported: %d\n", "Camera color format not supported: %d\n",
vc->ci_fmt.code); vc->ci_fmt.code);
return -EINVAL; return -EINVAL;
@ -698,7 +698,7 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
cfg |= FIMC_REG_CIGCTRL_CAM_JPEG; cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
break; break;
default: default:
v4l2_err(&vid_cap->vfd, v4l2_err(&vid_cap->ve.vdev,
"Not supported camera pixel format: %#x\n", "Not supported camera pixel format: %#x\n",
vid_cap->ci_fmt.code); vid_cap->ci_fmt.code);
return -EINVAL; return -EINVAL;
@ -721,7 +721,8 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
WARN_ONCE(1, "ISP Writeback input is not supported\n"); WARN_ONCE(1, "ISP Writeback input is not supported\n");
break; break;
default: default:
v4l2_err(&vid_cap->vfd, "Invalid FIMC bus type selected: %d\n", v4l2_err(&vid_cap->ve.vdev,
"Invalid FIMC bus type selected: %d\n",
source->fimc_bus_type); source->fimc_bus_type);
return -EINVAL; return -EINVAL;
} }

View File

@ -929,7 +929,7 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
continue; continue;
source = &fimc->subdev.entity; source = &fimc->subdev.entity;
sink = &fimc->vfd.entity; sink = &fimc->ve.vdev.entity;
/* FIMC-LITE's subdev and video node */ /* FIMC-LITE's subdev and video node */
ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA, ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
sink, 0, 0); sink, 0, 0);
@ -1066,7 +1066,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
continue; continue;
source = &fmd->fimc[i]->vid_cap.subdev.entity; source = &fmd->fimc[i]->vid_cap.subdev.entity;
sink = &fmd->fimc[i]->vid_cap.vfd.entity; sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
sink, 0, flags); sink, 0, flags);

View File

@ -127,14 +127,14 @@ static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
container_of(me->parent, struct fimc_md, media_dev); container_of(me->parent, struct fimc_md, media_dev);
} }
static inline void fimc_md_graph_lock(struct fimc_dev *fimc) static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
{ {
mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex); mutex_lock(&ve->vdev.entity.parent->graph_mutex);
} }
static inline void fimc_md_graph_unlock(struct fimc_dev *fimc) static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
{ {
mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex); mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
} }
int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);

View File

@ -13,6 +13,7 @@
#define S5P_FIMC_H_ #define S5P_FIMC_H_
#include <media/media-entity.h> #include <media/media-entity.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-mediabus.h> #include <media/v4l2-mediabus.h>
/* /*
@ -157,6 +158,10 @@ struct fimc_pipeline {
struct media_pipeline *m_pipeline; struct media_pipeline *m_pipeline;
}; };
struct exynos_video_entity {
struct video_device vdev;
};
/* /*
* Media pipeline operations to be called from within the fimc(-lite) * Media pipeline operations to be called from within the fimc(-lite)
* video node when it is the last entity of the pipeline. Implemented * video node when it is the last entity of the pipeline. Implemented