@@ -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);