diff mbox series

[v2,16/16] media: vicodec: Add support for stateless encoder

Message ID 20190403221501.32814-17-dafna3@gmail.com (mailing list archive)
State New, archived
Headers show
Series media: vicodec: adding support for stateless encoder | expand

Commit Message

Dafna Hirschfeld April 3, 2019, 10:15 p.m. UTC
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 | 106 ++++++++++++------
 1 file changed, 73 insertions(+), 33 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index c972c175707c..e1bfcc480716 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -140,6 +140,7 @@  struct vicodec_ctx {
 	bool			comp_has_next_frame;
 	bool			first_source_change_sent;
 	bool			source_changed;
+	struct v4l2_ctrl	*ctrl_fwht_params;
 };
 
 static const struct v4l2_event vicodec_eos_event = {
@@ -256,6 +257,21 @@  static void update_state_from_header(struct vicodec_ctx *ctx)
 	ctx->state.quantization = ntohl(p_hdr->quantization);
 }
 
+static void update_stateless_params_from_header(const struct vicodec_ctx *ctx,
+						struct v4l2_ctrl_fwht_params *params)
+{
+	const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
+
+	params->version = ntohl(p_hdr->version);
+	params->width = ntohl(p_hdr->width);
+	params->height = ntohl(p_hdr->height);
+	params->flags =	ntohl(p_hdr->flags);
+	params->colorspace = ntohl(p_hdr->colorspace);
+	params->xfer_func = ntohl(p_hdr->xfer_func);
+	params->ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
+	params->quantization = ntohl(p_hdr->quantization);
+}
+
 static int device_process(struct vicodec_ctx *ctx,
 			  struct vb2_v4l2_buffer *src_vb,
 			  struct vb2_v4l2_buffer *dst_vb)
@@ -276,33 +292,35 @@  static int device_process(struct vicodec_ctx *ctx,
 		ret = v4l2_ctrl_request_setup(src_req, &ctx->hdl);
 		if (ret)
 			return ret;
-		update_state_from_header(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) {
+			update_state_from_header(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 =
 				v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
-						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_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;
+					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_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;
+			}
 		}
 	}
 	p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
@@ -315,18 +333,36 @@  static int device_process(struct vicodec_ctx *ctx,
 	if (ctx->is_enc) {
 		struct vicodec_q_data *q_src;
 		int comp_sz_or_errcode;
-		struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *) p_dst;
-		u8 *comp_buf = p_dst + sizeof(struct fwht_cframe_hdr);
-
+		struct fwht_cframe_hdr *p_hdr;
+		u8 *comp_buf;
 
+		if (ctx->is_stateless) {
+			p_hdr = &ctx->state.header;
+			comp_buf = p_dst;
+		} else {
+			p_hdr = (struct fwht_cframe_hdr *) p_dst;
+			comp_buf = p_dst + sizeof(struct fwht_cframe_hdr);
+		}
 		q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 		state->info = q_src->info;
 		comp_sz_or_errcode = v4l2_fwht_encode(state, p_src, comp_buf,
 						      p_hdr);
 		if (comp_sz_or_errcode < 0)
 			return comp_sz_or_errcode;
-		vb2_set_plane_payload(&dst_vb->vb2_buf, 0,
-				      comp_sz_or_errcode + sizeof(*p_hdr));
+
+		if (!ctx->is_stateless) {
+			comp_sz_or_errcode += sizeof(*p_hdr);
+		} else {
+			int ret;
+			struct v4l2_ctrl_fwht_params params;
+
+			update_stateless_params_from_header(ctx, &params);
+			ret = v4l2_ctrl_s_ctrl_ptr(ctx->ctrl_fwht_params,
+						   &params);
+			if (ret)
+				return ret;
+		}
+		vb2_set_plane_payload(&dst_vb->vb2_buf, 0, comp_sz_or_errcode);
 	} else {
 		struct vicodec_q_data *q_dst;
 		unsigned int comp_frame_size = ntohl(ctx->state.header.size);
@@ -1739,7 +1775,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;
@@ -1819,6 +1855,8 @@  static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
 	const struct v4l2_ctrl_fwht_params *params;
 	struct vicodec_q_data *q_dst = get_q_data(ctx,
 			V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ctx->is_enc)
+		return 0;
 
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
@@ -1943,7 +1981,9 @@  static int vicodec_open(struct file *file)
 		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);
+		ctx->ctrl_fwht_params =
+			v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state,
+					     NULL);
 	if (hdl->error) {
 		rc = hdl->error;
 		v4l2_ctrl_handler_free(hdl);