All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] add support for stateless encoder
@ 2019-03-30 20:42 Dafna Hirschfeld
  2019-03-30 20:42 ` [PATCH 01/14] kernel/sysctl.c: bug fix Dafna Hirschfeld
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:42 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

patches 9-13 are new,

Dafna Hirschfeld (6):
  media: vicodec: don't test if info is NULL
  media: vicodec: add field 'dev_inst' to vicodec_ctx
  media: vicodec: Register another node for stateless encoder
  media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS for
    stateless encoder
  media: vicodec: Add support for stateless encoder
  prints

Hans Verkuil (8):
  kernel/sysctl.c: bug fix
  vicodec: always return a valid format.
  vicodec: pass on enc output format to capture side
  vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT
  videobuf2-v4l2: set last_buffer_dequeued in dqbuf
  vicodec: improve handling of ENC_CMD_STOP/START
  vicodec: restrict decoder format list when src fmt is known
  vicodec: fix vicodec_buf_queue()

 .../media/common/videobuf2/videobuf2-v4l2.c   |  10 +-
 drivers/media/media-request.c                 |   3 +
 drivers/media/platform/vicodec/codec-fwht.c   |  25 +
 drivers/media/platform/vicodec/codec-fwht.h   |   2 +
 .../media/platform/vicodec/codec-v4l2-fwht.c  |  63 ++-
 drivers/media/platform/vicodec/vicodec-core.c | 497 +++++++++++++-----
 drivers/media/v4l2-core/v4l2-ctrls.c          |  57 +-
 kernel/sysctl.c                               |   2 +-
 8 files changed, 507 insertions(+), 152 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/14] kernel/sysctl.c: bug fix
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
@ 2019-03-30 20:42 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 02/14] vicodec: always return a valid format Dafna Hirschfeld
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:42 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 kernel/sysctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e5da394d1ca3..3e959d67d619 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -124,7 +124,7 @@ static int sixty = 60;
 
 static int __maybe_unused neg_one = -1;
 
-static int zero;
+static long zero;
 static int __maybe_unused one = 1;
 static int __maybe_unused two = 2;
 static int __maybe_unused four = 4;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/14] vicodec: always return a valid format.
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
  2019-03-30 20:42 ` [PATCH 01/14] kernel/sysctl.c: bug fix Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 03/14] vicodec: pass on enc output format to capture side Dafna Hirschfeld
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Rather than returning width/height values of 0, just default to
a format. Formats in V4L2 are always supposed to be valid, there
is no concept of an invalid format.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 26 ++++++++++---------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index bd01a9206aa6..a6b35db7203a 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -1771,11 +1771,13 @@ static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
  */
 static int vicodec_open(struct file *file)
 {
+	const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_get_pixfmt(0);
 	struct video_device *vfd = video_devdata(file);
 	struct vicodec_dev *dev = video_drvdata(file);
 	struct vicodec_ctx *ctx = NULL;
 	struct v4l2_ctrl_handler *hdl;
-	unsigned int size;
+	unsigned int raw_size;
+	unsigned int comp_size;
 	int rc = 0;
 
 	if (mutex_lock_interruptible(vfd->lock))
@@ -1814,7 +1816,7 @@ static int vicodec_open(struct file *file)
 	v4l2_ctrl_handler_setup(hdl);
 
 	if (ctx->is_enc)
-		ctx->q_data[V4L2_M2M_SRC].info = v4l2_fwht_get_pixfmt(0);
+		ctx->q_data[V4L2_M2M_SRC].info = info;
 	else if (ctx->is_stateless)
 		ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht;
 	else
@@ -1823,22 +1825,22 @@ static int vicodec_open(struct file *file)
 	ctx->q_data[V4L2_M2M_SRC].coded_height = 720;
 	ctx->q_data[V4L2_M2M_SRC].visible_width = 1280;
 	ctx->q_data[V4L2_M2M_SRC].visible_height = 720;
-	size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult /
-		ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div;
+	raw_size = 1280 * 720 * info->sizeimage_mult / info->sizeimage_div;
+	comp_size = 1280 * 720 * pixfmt_fwht.sizeimage_mult /
+				 pixfmt_fwht.sizeimage_div;
 	if (ctx->is_enc || ctx->is_stateless)
-		ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
+		ctx->q_data[V4L2_M2M_SRC].sizeimage = raw_size;
 	else
 		ctx->q_data[V4L2_M2M_SRC].sizeimage =
-			size + sizeof(struct fwht_cframe_hdr);
+			comp_size + sizeof(struct fwht_cframe_hdr);
+	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
 	if (ctx->is_enc) {
-		ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
 		ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
-		ctx->q_data[V4L2_M2M_DST].sizeimage = 1280 * 720 *
-			ctx->q_data[V4L2_M2M_DST].info->sizeimage_mult /
-			ctx->q_data[V4L2_M2M_DST].info->sizeimage_div +
-			sizeof(struct fwht_cframe_hdr);
+		ctx->q_data[V4L2_M2M_DST].sizeimage =
+			comp_size + sizeof(struct fwht_cframe_hdr);
 	} else {
-		ctx->q_data[V4L2_M2M_DST].info = NULL;
+		ctx->q_data[V4L2_M2M_DST].info = info;
+		ctx->q_data[V4L2_M2M_DST].sizeimage = raw_size;
 	}
 
 	ctx->state.colorspace = V4L2_COLORSPACE_REC709;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/14] vicodec: pass on enc output format to capture side
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
  2019-03-30 20:42 ` [PATCH 01/14] kernel/sysctl.c: bug fix Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 02/14] vicodec: always return a valid format Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 04/14] vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT Dafna Hirschfeld
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Setting the encoder output format to e.g. 1920x1080 will set the
crop rectangle to 1920x1080, the coded resolution to 1920x1088 and
the capture coded resolution and sizeimage to 1920x1088 as well.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 64 ++++++++++++++++---
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index a6b35db7203a..3b5124838f15 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -1032,16 +1032,10 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 	default:
 		return -EINVAL;
 	}
-	if (q_data->visible_width > q_data->coded_width)
-		q_data->visible_width = q_data->coded_width;
-	if (q_data->visible_height > q_data->coded_height)
-		q_data->visible_height = q_data->coded_height;
-
 
 	dprintk(ctx->dev,
-		"Setting format for type %d, coded wxh: %dx%d, visible wxh: %dx%d, fourcc: %08x\n",
+		"Setting format for type %d, coded wxh: %dx%d, fourcc: 0x%08x\n",
 		f->type, q_data->coded_width, q_data->coded_height,
-		q_data->visible_width, q_data->visible_height,
 		q_data->info->id);
 
 	return 0;
@@ -1063,18 +1057,69 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	struct vicodec_ctx *ctx = file2ctx(file);
-	struct v4l2_pix_format_mplane *pix_mp;
+	struct vicodec_q_data *q_data;
+	struct vicodec_q_data *q_data_cap;
 	struct v4l2_pix_format *pix;
+	struct v4l2_pix_format_mplane *pix_mp;
+	u32 coded_w = 0, coded_h = 0;
+	unsigned int size = 0;
+	u32 w, h;
 	int ret;
 
+	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		w = f->fmt.pix.width;
+		h = f->fmt.pix.height;
+	} else {
+		w = f->fmt.pix_mp.width;
+		h = f->fmt.pix_mp.height;
+	}
+	q_data = get_q_data(ctx, f->type);
+	q_data_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
 	ret = vidioc_try_fmt_vid_out(file, priv, f);
 	if (ret)
 		return ret;
 
+	if (ctx->is_enc) {
+		struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+		struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+							   V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
+			&pixfmt_stateless_fwht : &pixfmt_fwht;
+
+		if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+			coded_w = f->fmt.pix.width;
+			coded_h = f->fmt.pix.height;
+		} else {
+			coded_w = f->fmt.pix_mp.width;
+			coded_h = f->fmt.pix_mp.height;
+		}
+		if (vb2_is_busy(vq) && (coded_w != q_data->coded_width ||
+					coded_h != q_data->coded_height))
+			return -EBUSY;
+		size = coded_w * coded_h *
+			info->sizeimage_mult / info->sizeimage_div;
+		if (!ctx->is_stateless)
+			size += sizeof(struct fwht_cframe_hdr);
+
+		if (vb2_is_busy(vq_cap) && size > q_data_cap->sizeimage)
+			return -EBUSY;
+	}
+
 	ret = vidioc_s_fmt(file2ctx(file), f);
 	if (!ret) {
+		if (ctx->is_enc) {
+			q_data->visible_width = w;
+			q_data->visible_height = h;
+			q_data_cap->coded_width = coded_w;
+			q_data_cap->coded_height = coded_h;
+			if (q_data_cap->sizeimage < size)
+				q_data_cap->sizeimage = size;
+			dprintk(ctx->dev,
+				"Setting output crop to %dx%d\n", w, h);
+		}
+
 		switch (f->type) {
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
 			pix = &f->fmt.pix;
 			ctx->state.colorspace = pix->colorspace;
@@ -1082,7 +1127,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
 			ctx->state.ycbcr_enc = pix->ycbcr_enc;
 			ctx->state.quantization = pix->quantization;
 			break;
-		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
 			pix_mp = &f->fmt.pix_mp;
 			ctx->state.colorspace = pix_mp->colorspace;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/14] vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (2 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 03/14] vicodec: pass on enc output format to capture side Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 05/14] videobuf2-v4l2: set last_buffer_dequeued in dqbuf Dafna Hirschfeld
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

The stateful encoder requires the presence of this control.
Since a single buffer is sufficient for vicodec, we just
set this control to 1.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 3b5124838f15..b0c1d7cd1db6 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -1841,13 +1841,16 @@ static int vicodec_open(struct file *file)
 	file->private_data = &ctx->fh;
 	ctx->dev = dev;
 	hdl = &ctx->hdl;
-	v4l2_ctrl_handler_init(hdl, 4);
+	v4l2_ctrl_handler_init(hdl, 5);
 	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
 			  1, 16, 1, 10);
 	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
 			  1, 31, 1, 20);
 	v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
 			  1, 31, 1, 20);
+	if (ctx->is_enc)
+		v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops,
+				  V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 1, 1, 1);
 	if (ctx->is_stateless)
 		v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL);
 	if (hdl->error) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/14] videobuf2-v4l2: set last_buffer_dequeued in dqbuf
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (3 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 04/14] vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 06/14] vicodec: improve handling of ENC_CMD_STOP/START Dafna Hirschfeld
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

last_buffer_dequeued was set to true in __fill_v4l2_buffer, but this
is called for qbuf as well. Move it to vb2_dqbuf.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/common/videobuf2/videobuf2-v4l2.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index b11a779e97b0..379738372651 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -562,11 +562,6 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
 		b->flags |= V4L2_BUF_FLAG_REQUEST_FD;
 		b->request_fd = vbuf->request_fd;
 	}
-
-	if (!q->is_output &&
-		b->flags & V4L2_BUF_FLAG_DONE &&
-		b->flags & V4L2_BUF_FLAG_LAST)
-		q->last_buffer_dequeued = true;
 }
 
 /*
@@ -785,6 +780,11 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
 
 	ret = vb2_core_dqbuf(q, NULL, b, nonblocking);
 
+	if (!q->is_output &&
+	    b->flags & V4L2_BUF_FLAG_DONE &&
+	    b->flags & V4L2_BUF_FLAG_LAST)
+		q->last_buffer_dequeued = true;
+
 	/*
 	 *  After calling the VIDIOC_DQBUF V4L2_BUF_FLAG_DONE must be
 	 *  cleared.
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/14] vicodec: improve handling of ENC_CMD_STOP/START
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (4 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 05/14] videobuf2-v4l2: set last_buffer_dequeued in dqbuf Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 07/14] vicodec: restrict decoder format list when src fmt is known Dafna Hirschfeld
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Correctly handle stopping and restarting the encoder, keeping
track of the stop and drain states.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 121 +++++++++++++++---
 1 file changed, 100 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index b0c1d7cd1db6..980c30cc9d48 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -116,12 +116,14 @@ struct vicodec_ctx {
 	struct vicodec_dev	*dev;
 	bool			is_enc;
 	bool			is_stateless;
+	bool			is_draining;
+	bool			next_is_last;
+	bool			has_stopped;
 	spinlock_t		*lock;
 
 	struct v4l2_ctrl_handler hdl;
 
 	struct vb2_v4l2_buffer *last_src_buf;
-	struct vb2_v4l2_buffer *last_dst_buf;
 
 	/* Source and destination queue data */
 	struct vicodec_q_data   q_data[2];
@@ -138,6 +140,10 @@ struct vicodec_ctx {
 	bool			source_changed;
 };
 
+static const struct v4l2_event vicodec_eos_event = {
+	.type = V4L2_EVENT_EOS
+};
+
 static inline struct vicodec_ctx *file2ctx(struct file *file)
 {
 	return container_of(file->private_data, struct vicodec_ctx, fh);
@@ -397,9 +403,6 @@ static enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx,
 /* device_run() - prepares and starts the device */
 static void device_run(void *priv)
 {
-	static const struct v4l2_event eos_event = {
-		.type = V4L2_EVENT_EOS
-	};
 	struct vicodec_ctx *ctx = priv;
 	struct vicodec_dev *dev = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
@@ -423,12 +426,12 @@ static void device_run(void *priv)
 	dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc);
 
-	ctx->last_dst_buf = dst_buf;
-
 	spin_lock(ctx->lock);
 	if (!ctx->comp_has_next_frame && src_buf == ctx->last_src_buf) {
 		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
-		v4l2_event_queue_fh(&ctx->fh, &eos_event);
+		v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+		ctx->is_draining = false;
+		ctx->has_stopped = true;
 	}
 	if (ctx->is_enc || ctx->is_stateless) {
 		src_buf->sequence = q_src->sequence++;
@@ -579,6 +582,8 @@ static int job_ready(void *priv)
 	unsigned int max_to_copy;
 	unsigned int comp_frame_size;
 
+	if (ctx->has_stopped)
+		return 0;
 	if (ctx->source_changed)
 		return 0;
 	if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)
@@ -1217,25 +1222,45 @@ static int vidioc_s_selection(struct file *file, void *priv,
 	return 0;
 }
 
-static void vicodec_mark_last_buf(struct vicodec_ctx *ctx)
+static int vicodec_mark_last_buf(struct vicodec_ctx *ctx)
 {
-	static const struct v4l2_event eos_event = {
-		.type = V4L2_EVENT_EOS
-	};
+	struct vb2_v4l2_buffer *next_dst_buf;
+	int ret = 0;
 
 	spin_lock(ctx->lock);
+	if (ctx->is_draining) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+	if (ctx->has_stopped)
+		goto unlock;
+
 	ctx->last_src_buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
-	if (!ctx->last_src_buf && ctx->last_dst_buf) {
-		ctx->last_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
-		v4l2_event_queue_fh(&ctx->fh, &eos_event);
+	ctx->is_draining = true;
+	if (ctx->last_src_buf)
+		goto unlock;
+
+	next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+	if (!next_dst_buf) {
+		ctx->next_is_last = true;
+		goto unlock;
 	}
+
+	next_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+	vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE);
+	ctx->is_draining = false;
+	ctx->has_stopped = true;
+	v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+
+unlock:
 	spin_unlock(ctx->lock);
+	return ret;
 }
 
 static int vicodec_try_encoder_cmd(struct file *file, void *fh,
 				struct v4l2_encoder_cmd *ec)
 {
-	if (ec->cmd != V4L2_ENC_CMD_STOP)
+	if (ec->cmd != V4L2_ENC_CMD_STOP && ec->cmd != V4L2_ENC_CMD_START)
 		return -EINVAL;
 
 	if (ec->flags & V4L2_ENC_CMD_STOP_AT_GOP_END)
@@ -1254,8 +1279,22 @@ static int vicodec_encoder_cmd(struct file *file, void *fh,
 	if (ret < 0)
 		return ret;
 
-	vicodec_mark_last_buf(ctx);
-	return 0;
+	if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) ||
+	    !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))
+		return 0;
+
+	if (ec->cmd == V4L2_ENC_CMD_STOP)
+		return vicodec_mark_last_buf(ctx);
+	ret = 0;
+	spin_lock(ctx->lock);
+	if (ctx->is_draining) {
+		ret = -EBUSY;
+	} else if (ctx->has_stopped) {
+		ctx->has_stopped = false;
+		vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q);
+	}
+	spin_unlock(ctx->lock);
+	return ret;
 }
 
 static int vicodec_try_decoder_cmd(struct file *file, void *fh,
@@ -1283,8 +1322,7 @@ static int vicodec_decoder_cmd(struct file *file, void *fh,
 	if (ret < 0)
 		return ret;
 
-	vicodec_mark_last_buf(ctx);
-	return 0;
+	return vicodec_mark_last_buf(ctx);
 }
 
 static int vicodec_enum_framesizes(struct file *file, void *fh,
@@ -1462,6 +1500,23 @@ static void vicodec_buf_queue(struct vb2_buffer *vb)
 		return;
 	}
 
+	if (vb2_is_streaming(vq_cap)) {
+		if (!V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type) &&
+		    ctx->next_is_last) {
+			unsigned int i;
+
+			for (i = 0; i < vb->num_planes; i++)
+				vb->planes[i].bytesused = 0;
+			vbuf->flags |= V4L2_BUF_FLAG_LAST;
+			vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+			ctx->is_draining = false;
+			ctx->has_stopped = true;
+			ctx->next_is_last = false;
+			v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+			return;
+		}
+	}
+
 	/*
 	 * if both queues are streaming, the source change event is
 	 * handled in job_ready
@@ -1571,8 +1626,6 @@ static int vicodec_start_streaming(struct vb2_queue *q,
 
 	if (V4L2_TYPE_IS_OUTPUT(q->type))
 		ctx->last_src_buf = NULL;
-	else
-		ctx->last_dst_buf = NULL;
 
 	state->gop_cnt = 0;
 
@@ -1648,6 +1701,32 @@ static void vicodec_stop_streaming(struct vb2_queue *q)
 
 	vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
 
+	if (ctx->is_enc) {
+		if (V4L2_TYPE_IS_OUTPUT(q->type)) {
+			if (ctx->is_draining) {
+				struct vb2_v4l2_buffer *next_dst_buf;
+
+				spin_lock(ctx->lock);
+				ctx->last_src_buf = NULL;
+				next_dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+				if (!next_dst_buf) {
+					ctx->next_is_last = true;
+				} else {
+					next_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
+					vb2_buffer_done(&next_dst_buf->vb2_buf, VB2_BUF_STATE_DONE);
+					ctx->is_draining = false;
+					ctx->has_stopped = true;
+					v4l2_event_queue_fh(&ctx->fh, &vicodec_eos_event);
+				}
+				spin_unlock(ctx->lock);
+			}
+		} else {
+			ctx->is_draining = false;
+			ctx->has_stopped = false;
+			ctx->next_is_last = false;
+		}
+	}
+
 	if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
 	    (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
 		if (!ctx->is_stateless)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/14] vicodec: restrict decoder format list when src fmt is known
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (5 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 06/14] vicodec: improve handling of ENC_CMD_STOP/START Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 08/14] vicodec: fix vicodec_buf_queue() Dafna Hirschfeld
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Report the full list of supported decoder formats until the
format encoded in the bitstream is known. After that only
report the formats compatible with that initial format.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 980c30cc9d48..7e4ac412cc38 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -671,7 +671,6 @@ static int job_ready(void *priv)
 			v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
 		update_capture_data_from_header(ctx);
-		ctx->first_source_change_sent = true;
 		v4l2_event_queue_fh(&ctx->fh, &rs_event);
 		set_last_buffer(dst_buf, src_buf, ctx);
 		ctx->source_changed = true;
@@ -718,7 +717,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx,
 		const struct v4l2_fwht_pixfmt_info *info =
 					get_q_data(ctx, f->type)->info;
 
-		if (!info || ctx->is_enc)
+		if (!ctx->first_source_change_sent || ctx->is_enc)
 			info = v4l2_fwht_get_pixfmt(f->index);
 		else
 			info = v4l2_fwht_find_nth_fmt(info->width_div,
@@ -1522,6 +1521,7 @@ static void vicodec_buf_queue(struct vb2_buffer *vb)
 	 * handled in job_ready
 	 */
 	if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
+		ctx->first_source_change_sent = true;
 		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 		return;
 	}
@@ -1726,6 +1726,8 @@ static void vicodec_stop_streaming(struct vb2_queue *q)
 			ctx->next_is_last = false;
 		}
 	}
+	if (!ctx->is_enc && V4L2_TYPE_IS_OUTPUT(q->type))
+		ctx->first_source_change_sent = false;
 
 	if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
 	    (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/14] vicodec: fix vicodec_buf_queue()
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (6 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 07/14] vicodec: restrict decoder format list when src fmt is known Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 09/14] media: vicodec: don't test if info is NULL Dafna Hirschfeld
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Hans Verkuil

From: Hans Verkuil <hverkuil-cisco@xs4all.nl>

Only set first_source_change_sent for decoders.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
 drivers/media/platform/vicodec/vicodec-core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 7e4ac412cc38..ba327512e085 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -1521,7 +1521,8 @@ static void vicodec_buf_queue(struct vb2_buffer *vb)
 	 * handled in job_ready
 	 */
 	if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
-		ctx->first_source_change_sent = true;
+		if (!ctx->is_enc)
+			ctx->first_source_change_sent = true;
 		v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 		return;
 	}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/14] media: vicodec: don't test if info is NULL
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (7 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 08/14] vicodec: fix vicodec_buf_queue() Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 10/14] media: vicodec: add field 'dev_inst' to vicodec_ctx Dafna Hirschfeld
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

pixel info of q_data is never set to NULL
so there is no need to test if it is.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 drivers/media/platform/vicodec/vicodec-core.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index ba327512e085..6276a803cc4d 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -659,7 +659,6 @@ static int job_ready(void *priv)
 
 	if (ntohl(ctx->state.header.width) != q_dst->visible_width ||
 	    ntohl(ctx->state.header.height) != q_dst->visible_height ||
-	    !q_dst->info ||
 	    hdr_width_div != q_dst->info->width_div ||
 	    hdr_height_div != q_dst->info->height_div) {
 		static const struct v4l2_event rs_event = {
@@ -768,9 +767,6 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 	q_data = get_q_data(ctx, f->type);
 	info = q_data->info;
 
-	if (!info)
-		info = v4l2_fwht_get_pixfmt(0);
-
 	switch (f->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -992,7 +988,6 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 		pix = &f->fmt.pix;
 		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
 			fmt_changed =
-				!q_data->info ||
 				q_data->info->id != pix->pixelformat ||
 				q_data->coded_width != pix->width ||
 				q_data->coded_height != pix->height;
@@ -1015,7 +1010,6 @@ static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
 		pix_mp = &f->fmt.pix_mp;
 		if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
 			fmt_changed =
-				!q_data->info ||
 				q_data->info->id != pix_mp->pixelformat ||
 				q_data->coded_width != pix_mp->width ||
 				q_data->coded_height != pix_mp->height;
@@ -1593,10 +1587,6 @@ static unsigned int total_frame_size(struct vicodec_q_data *q_data)
 	unsigned int size;
 	unsigned int chroma_div;
 
-	if (!q_data->info) {
-		WARN_ON(1);
-		return 0;
-	}
 	size = q_data->coded_width * q_data->coded_height;
 	chroma_div = q_data->info->width_div * q_data->info->height_div;
 
@@ -1619,9 +1609,6 @@ static int vicodec_start_streaming(struct vb2_queue *q,
 	unsigned int total_planes_size;
 	u8 *new_comp_frame = NULL;
 
-	if (!info)
-		return -EINVAL;
-
 	chroma_div = info->width_div * info->height_div;
 	q_data->sequence = 0;
 
@@ -1820,8 +1807,6 @@ static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
 
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
-		if (!q_dst->info)
-			return -EINVAL;
 		params = ctrl->p_new.p_fwht_params;
 		if (params->width > q_dst->coded_width ||
 		    params->width < MIN_WIDTH ||
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/14] media: vicodec: add field 'dev_inst' to vicodec_ctx
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (8 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 09/14] media: vicodec: don't test if info is NULL Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 11/14] media: vicodec: Register another node for stateless encoder Dafna Hirschfeld
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add the field 'dev_inst' to vicodec_ctx that points to
the 'vicodec_dev_instance'. This saves many if-elses

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 drivers/media/platform/vicodec/vicodec-core.c | 42 ++++++-------------
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 6276a803cc4d..a701afd7cecb 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -121,6 +121,7 @@ struct vicodec_ctx {
 	bool			has_stopped;
 	spinlock_t		*lock;
 
+	struct vicodec_dev_instance *dev_inst;
 	struct v4l2_ctrl_handler hdl;
 
 	struct vb2_v4l2_buffer *last_src_buf;
@@ -404,7 +405,6 @@ static enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx,
 static void device_run(void *priv)
 {
 	struct vicodec_ctx *ctx = priv;
-	struct vicodec_dev *dev = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	struct vicodec_q_data *q_src, *q_dst;
 	u32 state;
@@ -454,13 +454,7 @@ static void device_run(void *priv)
 	ctx->comp_has_frame = false;
 	spin_unlock(ctx->lock);
 
-	if (ctx->is_enc)
-		v4l2_m2m_job_finish(dev->stateful_enc.m2m_dev, ctx->fh.m2m_ctx);
-	else if (ctx->is_stateless)
-		v4l2_m2m_job_finish(dev->stateless_dec.m2m_dev,
-				    ctx->fh.m2m_ctx);
-	else
-		v4l2_m2m_job_finish(dev->stateful_dec.m2m_dev, ctx->fh.m2m_ctx);
+	v4l2_m2m_job_finish(ctx->dev_inst->m2m_dev, ctx->fh.m2m_ctx);
 }
 
 static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
@@ -1771,12 +1765,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->ops = &vicodec_qops;
 	src_vq->mem_ops = &vb2_vmalloc_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	if (ctx->is_enc)
-		src_vq->lock = &ctx->dev->stateful_enc.mutex;
-	else if (ctx->is_stateless)
-		src_vq->lock = &ctx->dev->stateless_dec.mutex;
-	else
-		src_vq->lock = &ctx->dev->stateful_dec.mutex;
+	src_vq->lock = &ctx->dev_inst->mutex;
 	src_vq->supports_requests = ctx->is_stateless;
 	src_vq->requires_requests = ctx->is_stateless;
 	ret = vb2_queue_init(src_vq);
@@ -1899,10 +1888,15 @@ static int vicodec_open(struct file *file)
 		goto open_unlock;
 	}
 
-	if (vfd == &dev->stateful_enc.vfd)
+	if (vfd == &dev->stateful_enc.vfd) {
 		ctx->is_enc = true;
-	else if (vfd == &dev->stateless_dec.vfd)
+		ctx->dev_inst = &dev->stateful_enc;
+	} else if (vfd == &dev->stateless_dec.vfd) {
 		ctx->is_stateless = true;
+		ctx->dev_inst = &dev->stateless_dec;
+	} else {
+		ctx->dev_inst = &dev->stateful_dec;
+	}
 
 	v4l2_fh_init(&ctx->fh, video_devdata(file));
 	file->private_data = &ctx->fh;
@@ -1959,19 +1953,9 @@ static int vicodec_open(struct file *file)
 
 	ctx->state.colorspace = V4L2_COLORSPACE_REC709;
 
-	if (ctx->is_enc) {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateful_enc.lock;
-	} else if (ctx->is_stateless) {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateless_dec.lock;
-	} else {
-		ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev,
-						    ctx, &queue_init);
-		ctx->lock = &dev->stateful_dec.lock;
-	}
+	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(ctx->dev_inst->m2m_dev,
+					    ctx, &queue_init);
+	ctx->lock = &ctx->dev_inst->lock;
 
 	if (IS_ERR(ctx->fh.m2m_ctx)) {
 		rc = PTR_ERR(ctx->fh.m2m_ctx);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 11/14] media: vicodec: Register another node for stateless encoder
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (9 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 10/14] media: vicodec: add field 'dev_inst' to vicodec_ctx Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 12/14] media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS " Dafna Hirschfeld
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add stateless encoder instance field to the dev struct and
register another node for the stateless encoder.
The stateless API for the node will be implemented in further
patches.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 drivers/media/platform/vicodec/vicodec-core.c | 42 +++++++++++++++----
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index a701afd7cecb..6bfcd266ffc4 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -105,6 +105,7 @@ struct vicodec_dev {
 	struct vicodec_dev_instance stateful_enc;
 	struct vicodec_dev_instance stateful_dec;
 	struct vicodec_dev_instance stateless_dec;
+	struct vicodec_dev_instance stateless_enc;
 #ifdef CONFIG_MEDIA_CONTROLLER
 	struct media_device	mdev;
 #endif
@@ -1887,16 +1888,20 @@ static int vicodec_open(struct file *file)
 		rc = -ENOMEM;
 		goto open_unlock;
 	}
+	ctx->is_enc = (vfd == &dev->stateful_enc.vfd ||
+		       vfd == &dev->stateless_enc.vfd);
 
-	if (vfd == &dev->stateful_enc.vfd) {
-		ctx->is_enc = true;
+	ctx->is_stateless = (vfd == &dev->stateless_dec.vfd ||
+			     vfd == &dev->stateless_enc.vfd);
+
+	if (vfd == &dev->stateful_enc.vfd)
 		ctx->dev_inst = &dev->stateful_enc;
-	} else if (vfd == &dev->stateless_dec.vfd) {
-		ctx->is_stateless = true;
-		ctx->dev_inst = &dev->stateless_dec;
-	} else {
+	else if (vfd == &dev->stateful_dec.vfd)
 		ctx->dev_inst = &dev->stateful_dec;
-	}
+	else if (vfd == &dev->stateless_enc.vfd)
+		ctx->dev_inst = &dev->stateless_enc;
+	else
+		ctx->dev_inst = &dev->stateless_dec;
 
 	v4l2_fh_init(&ctx->fh, video_devdata(file));
 	file->private_data = &ctx->fh;
@@ -2150,6 +2155,9 @@ static int vicodec_probe(struct platform_device *pdev)
 			      "stateless-decoder", false))
 		goto unreg_sf_dec;
 
+	if (register_instance(dev, &dev->stateless_enc,
+			      "stateless-encoder", false))
+		goto unreg_sl_dec;
 #ifdef CONFIG_MEDIA_CONTROLLER
 	ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev,
 						 &dev->stateful_enc.vfd,
@@ -2175,15 +2183,26 @@ static int vicodec_probe(struct platform_device *pdev)
 		goto unreg_m2m_sf_dec_mc;
 	}
 
+	ret = v4l2_m2m_register_media_controller(dev->stateless_enc.m2m_dev,
+						 &dev->stateless_enc.vfd,
+						 MEDIA_ENT_F_PROC_VIDEO_ENCODER);
+	if (ret) {
+		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless enc\n");
+		goto unreg_m2m_sl_dec_mc;
+	}
+
+
 	ret = media_device_register(&dev->mdev);
 	if (ret) {
 		v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
-		goto unreg_m2m_sl_dec_mc;
+		goto unreg_m2m_sl_enc_mc;
 	}
 #endif
 	return 0;
 
 #ifdef CONFIG_MEDIA_CONTROLLER
+unreg_m2m_sl_enc_mc:
+	v4l2_m2m_unregister_media_controller(dev->stateless_enc.m2m_dev);
 unreg_m2m_sl_dec_mc:
 	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
 unreg_m2m_sf_dec_mc:
@@ -2191,9 +2210,12 @@ static int vicodec_probe(struct platform_device *pdev)
 unreg_m2m_sf_enc_mc:
 	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
 unreg_m2m:
+	video_unregister_device(&dev->stateless_enc.vfd);
+	v4l2_m2m_release(dev->stateless_enc.m2m_dev);
+#endif
+unreg_sl_dec:
 	video_unregister_device(&dev->stateless_dec.vfd);
 	v4l2_m2m_release(dev->stateless_dec.m2m_dev);
-#endif
 unreg_sf_dec:
 	video_unregister_device(&dev->stateful_dec.vfd);
 	v4l2_m2m_release(dev->stateful_dec.m2m_dev);
@@ -2217,6 +2239,7 @@ static int vicodec_remove(struct platform_device *pdev)
 	v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
 	v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
 	v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
+	v4l2_m2m_unregister_media_controller(dev->stateless_enc.m2m_dev);
 	media_device_cleanup(&dev->mdev);
 #endif
 
@@ -2225,6 +2248,7 @@ static int vicodec_remove(struct platform_device *pdev)
 	video_unregister_device(&dev->stateful_enc.vfd);
 	video_unregister_device(&dev->stateful_dec.vfd);
 	video_unregister_device(&dev->stateless_dec.vfd);
+	video_unregister_device(&dev->stateless_enc.vfd);
 	v4l2_device_unregister(&dev->v4l2_dev);
 
 	return 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 12/14] media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS for stateless encoder
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (10 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 11/14] media: vicodec: Register another node for stateless encoder Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-30 20:43 ` [PATCH 13/14] media: vicodec: Add support " Dafna Hirschfeld
  2019-03-31 10:17 ` [PATCH 00/14] add " Hans Verkuil
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

for stateless encoder, set the capture pixelformat
to V4L2_PIX_FMT_FWHT_STATELESS and the pix info to
pixfmt_stateless_fwht

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 drivers/media/platform/vicodec/vicodec-core.c | 31 ++++++++++++-------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 6bfcd266ffc4..f042c4b618ba 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -895,8 +895,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		if (multiplanar)
 			return -EINVAL;
 		pix = &f->fmt.pix;
-		pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-				   find_fmt(f->fmt.pix.pixelformat)->id;
+		if (!ctx->is_enc)
+			pix->pixelformat = find_fmt(f->fmt.pix.pixelformat)->id;
+		else if (ctx->is_stateless)
+			pix->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
+		else
+			pix->pixelformat = V4L2_PIX_FMT_FWHT;
 		pix->colorspace = ctx->state.colorspace;
 		pix->xfer_func = ctx->state.xfer_func;
 		pix->ycbcr_enc = ctx->state.ycbcr_enc;
@@ -906,8 +910,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		if (!multiplanar)
 			return -EINVAL;
 		pix_mp = &f->fmt.pix_mp;
-		pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
-				      find_fmt(pix_mp->pixelformat)->id;
+		if (!ctx->is_enc)
+			pix_mp->pixelformat = find_fmt(f->fmt.pix_mp.pixelformat)->id;
+		else if (ctx->is_stateless)
+			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
+		else
+			pix_mp->pixelformat = V4L2_PIX_FMT_FWHT;
 		pix_mp->colorspace = ctx->state.colorspace;
 		pix_mp->xfer_func = ctx->state.xfer_func;
 		pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
@@ -1631,22 +1639,22 @@ static int vicodec_start_streaming(struct vb2_queue *q,
 	state->stride = q_data->coded_width *
 				info->bytesperline_mult;
 
-	if (ctx->is_stateless) {
+	if (!ctx->is_enc && ctx->is_stateless) {
 		state->ref_stride = state->stride;
 		return 0;
 	}
 	state->ref_stride = q_data->coded_width * info->luma_alpha_step;
 
 	state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL);
-	state->ref_frame.luma = state->ref_frame.buf;
 	new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
 
-	if (!state->ref_frame.luma || !new_comp_frame) {
-		kvfree(state->ref_frame.luma);
+	if (!state->ref_frame.buf || !new_comp_frame) {
+		kvfree(state->ref_frame.buf);
 		kvfree(new_comp_frame);
 		vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
 		return -ENOMEM;
 	}
+	state->ref_frame.luma = state->ref_frame.buf;
 	/*
 	 * if state->compressed_frame was already allocated then
 	 * it contain data of the first frame of the new resolution
@@ -1948,9 +1956,10 @@ static int vicodec_open(struct file *file)
 			comp_size + sizeof(struct fwht_cframe_hdr);
 	ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
 	if (ctx->is_enc) {
-		ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
-		ctx->q_data[V4L2_M2M_DST].sizeimage =
-			comp_size + sizeof(struct fwht_cframe_hdr);
+		ctx->q_data[V4L2_M2M_DST].info = ctx->is_stateless ?
+			&pixfmt_stateless_fwht : &pixfmt_fwht;
+		ctx->q_data[V4L2_M2M_DST].sizeimage = comp_size +
+			sizeof(struct fwht_cframe_hdr);
 	} else {
 		ctx->q_data[V4L2_M2M_DST].info = info;
 		ctx->q_data[V4L2_M2M_DST].sizeimage = raw_size;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 13/14] media: vicodec: Add support for stateless encoder
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (11 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 12/14] media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS " Dafna Hirschfeld
@ 2019-03-30 20:43 ` Dafna Hirschfeld
  2019-03-31 10:17 ` [PATCH 00/14] add " Hans Verkuil
  13 siblings, 0 replies; 15+ messages in thread
From: Dafna Hirschfeld @ 2019-03-30 20:43 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Adjust the stateless API code to support
both encoder and decoder.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 drivers/media/platform/vicodec/vicodec-core.c | 58 +++++++++++--------
 1 file changed, 33 insertions(+), 25 deletions(-)

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index f042c4b618ba..3808e72b2361 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -280,29 +280,31 @@ static int device_process(struct vicodec_ctx *ctx,
 
 		ctx->state.header.size =
 			htonl(vb2_get_plane_payload(&src_vb->vb2_buf, 0));
-		/*
-		 * set the reference buffer from the reference timestamp
-		 * only if this is a P-frame
-		 */
-		if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) {
-			struct vb2_buffer *ref_vb2_buf;
-			int ref_buf_idx;
-			struct vb2_queue *vq_cap =
+		if (!ctx->is_enc) {
+			/*
+			 * set the reference buffer from the reference timestamp
+			 * only if this is a P-frame
+			*/
+			if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) {
+				struct vb2_buffer *ref_vb2_buf;
+				int ref_buf_idx;
+				struct vb2_queue *vq_cap =
 				v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-						V4L2_BUF_TYPE_VIDEO_CAPTURE);
+				V4L2_BUF_TYPE_VIDEO_CAPTURE);
 
-			ref_buf_idx = vb2_find_timestamp(vq_cap,
-							 ctx->state.ref_frame_ts, 0);
-			if (ref_buf_idx < 0)
-				return -EINVAL;
+				ref_buf_idx = vb2_find_timestamp(vq_cap,
+				ctx->state.ref_frame_ts, 0);
+				if (ref_buf_idx < 0)
+					return -EINVAL;
 
-			ref_vb2_buf = vq_cap->bufs[ref_buf_idx];
-			if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR)
-				ret = -EINVAL;
-			ctx->state.ref_frame.buf =
+				ref_vb2_buf = vq_cap->bufs[ref_buf_idx];
+				if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR)
+					ret = -EINVAL;
+				ctx->state.ref_frame.buf =
 				vb2_plane_vaddr(ref_vb2_buf, 0);
-		} else {
-			ctx->state.ref_frame.buf = NULL;
+			} else {
+				ctx->state.ref_frame.buf = NULL;
+			}
 		}
 	}
 	p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
@@ -1722,7 +1724,7 @@ static void vicodec_stop_streaming(struct vb2_queue *q)
 
 	if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
 	    (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
-		if (!ctx->is_stateless)
+		if (!ctx->is_stateless || ctx->is_enc)
 			kvfree(ctx->state.ref_frame.buf);
 		ctx->state.ref_frame.buf = NULL;
 		ctx->state.ref_frame.luma = NULL;
@@ -1800,20 +1802,26 @@ static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
 	struct vicodec_ctx *ctx = container_of(ctrl->handler,
 			struct vicodec_ctx, hdl);
 	const struct v4l2_ctrl_fwht_params *params;
-	struct vicodec_q_data *q_dst = get_q_data(ctx,
-			V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	struct vicodec_q_data *q_data;
+
+	if (ctx->is_enc)
+		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	else
+		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
 		params = ctrl->p_new.p_fwht_params;
-		if (params->width > q_dst->coded_width ||
+		if (params->width > q_data->coded_width ||
 		    params->width < MIN_WIDTH ||
-		    params->height > q_dst->coded_height ||
+		    params->height > q_data->coded_height ||
 		    params->height < MIN_HEIGHT)
 			return -EINVAL;
+		if (ctx->is_enc)
+			return 0;
 		if (!validate_by_version(params->flags, params->version))
 			return -EINVAL;
-		if (!validate_stateless_params_flags(params, q_dst->info))
+		if (!validate_stateless_params_flags(params, q_data->info))
 			return -EINVAL;
 		return 0;
 	default:
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/14] add support for stateless encoder
  2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
                   ` (12 preceding siblings ...)
  2019-03-30 20:43 ` [PATCH 13/14] media: vicodec: Add support " Dafna Hirschfeld
@ 2019-03-31 10:17 ` Hans Verkuil
  13 siblings, 0 replies; 15+ messages in thread
From: Hans Verkuil @ 2019-03-31 10:17 UTC (permalink / raw)
  To: Dafna Hirschfeld, linux-media; +Cc: helen.koike

On 3/30/19 9:42 PM, Dafna Hirschfeld wrote:
> patches 9-13 are new,
> 
> Dafna Hirschfeld (6):
>   media: vicodec: don't test if info is NULL
>   media: vicodec: add field 'dev_inst' to vicodec_ctx
>   media: vicodec: Register another node for stateless encoder
>   media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS for
>     stateless encoder
>   media: vicodec: Add support for stateless encoder
>   prints

It looks like this series just prepares for stateless encoder support but
no actually implements it yet. Is that right?

I also see only 13 patches, not 14, so perhaps something is missing?

Regards,

	Hans

> 
> Hans Verkuil (8):
>   kernel/sysctl.c: bug fix
>   vicodec: always return a valid format.
>   vicodec: pass on enc output format to capture side
>   vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT
>   videobuf2-v4l2: set last_buffer_dequeued in dqbuf
>   vicodec: improve handling of ENC_CMD_STOP/START
>   vicodec: restrict decoder format list when src fmt is known
>   vicodec: fix vicodec_buf_queue()
> 
>  .../media/common/videobuf2/videobuf2-v4l2.c   |  10 +-
>  drivers/media/media-request.c                 |   3 +
>  drivers/media/platform/vicodec/codec-fwht.c   |  25 +
>  drivers/media/platform/vicodec/codec-fwht.h   |   2 +
>  .../media/platform/vicodec/codec-v4l2-fwht.c  |  63 ++-
>  drivers/media/platform/vicodec/vicodec-core.c | 497 +++++++++++++-----
>  drivers/media/v4l2-core/v4l2-ctrls.c          |  57 +-
>  kernel/sysctl.c                               |   2 +-
>  8 files changed, 507 insertions(+), 152 deletions(-)
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-03-31 10:17 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-30 20:42 [PATCH 00/14] add support for stateless encoder Dafna Hirschfeld
2019-03-30 20:42 ` [PATCH 01/14] kernel/sysctl.c: bug fix Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 02/14] vicodec: always return a valid format Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 03/14] vicodec: pass on enc output format to capture side Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 04/14] vicodec: add V4L2_CID_MIN_BUFFERS_FOR_OUTPUT Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 05/14] videobuf2-v4l2: set last_buffer_dequeued in dqbuf Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 06/14] vicodec: improve handling of ENC_CMD_STOP/START Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 07/14] vicodec: restrict decoder format list when src fmt is known Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 08/14] vicodec: fix vicodec_buf_queue() Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 09/14] media: vicodec: don't test if info is NULL Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 10/14] media: vicodec: add field 'dev_inst' to vicodec_ctx Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 11/14] media: vicodec: Register another node for stateless encoder Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 12/14] media: vicodec: set pixelformat V4L2_PIX_FMT_FWHT_STATELESS " Dafna Hirschfeld
2019-03-30 20:43 ` [PATCH 13/14] media: vicodec: Add support " Dafna Hirschfeld
2019-03-31 10:17 ` [PATCH 00/14] add " Hans Verkuil

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.