Adjust the stateless API code to support both encoder and decoder. Signed-off-by: Dafna Hirschfeld <dafna3@xxxxxxxxx> --- drivers/media/platform/vicodec/vicodec-core.c | 106 ++++++++++++------ 1 file changed, 73 insertions(+), 33 deletions(-) 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, ¶ms); + ret = v4l2_ctrl_s_ctrl_ptr(ctx->ctrl_fwht_params, + ¶ms); + 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); -- 2.17.1