lkml.org 
[lkml]   [2020]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 6/8] venus: venc: add handling for VIDIOC_ENCODER_CMD
    Date
    From: Dikshita Agarwal <dikshita@codeaurora.org>

    Add handling for below commands in encoder:
    1. V4L2_ENC_CMD_STOP
    2. V4L2_ENC_CMD_START

    Signed-off-by: Dikshita Agarwal <dikshita@codeaurora.org>
    Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
    ---
    drivers/media/platform/qcom/venus/venc.c | 77 +++++++++++++++++++++++-
    1 file changed, 76 insertions(+), 1 deletion(-)

    diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
    index 99bfabf90bd2..7512e4a16270 100644
    --- a/drivers/media/platform/qcom/venus/venc.c
    +++ b/drivers/media/platform/qcom/venus/venc.c
    @@ -507,6 +507,59 @@ static int venc_enum_frameintervals(struct file *file, void *fh,
    return 0;
    }

    +static int venc_encoder_cmd(struct file *file, void *fh,
    + struct v4l2_encoder_cmd *ec)
    +{
    + struct venus_inst *inst = to_inst(file);
    + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
    + struct hfi_frame_data fdata = {0};
    + int ret = 0;
    +
    + ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
    + if (ret < 0)
    + return ret;
    +
    + mutex_lock(&inst->lock);
    +
    + if (!vb2_is_streaming(&m2m_ctx->cap_q_ctx.q) ||
    + !vb2_is_streaming(&m2m_ctx->out_q_ctx.q))
    + goto unlock;
    +
    + if (m2m_ctx->is_draining) {
    + ret = -EBUSY;
    + goto unlock;
    + }
    +
    + if (ec->cmd == V4L2_ENC_CMD_STOP) {
    + if (v4l2_m2m_has_stopped(m2m_ctx)) {
    + ret = 0;
    + goto unlock;
    + }
    +
    + m2m_ctx->is_draining = true;
    +
    + fdata.buffer_type = HFI_BUFFER_INPUT;
    + fdata.flags |= HFI_BUFFERFLAG_EOS;
    + fdata.device_addr = 0;
    + fdata.clnt_data = (u32)-1;
    +
    + ret = hfi_session_process_buf(inst, &fdata);
    + if (ret)
    + goto unlock;
    + }
    +
    + if (ec->cmd == V4L2_ENC_CMD_START && v4l2_m2m_has_stopped(m2m_ctx)) {
    + vb2_clear_last_buffer_dequeued(&m2m_ctx->cap_q_ctx.q);
    + inst->m2m_ctx->has_stopped = false;
    + venus_helper_process_initial_out_bufs(inst);
    + venus_helper_process_initial_cap_bufs(inst);
    + }
    +
    +unlock:
    + mutex_unlock(&inst->lock);
    + return ret;
    +}
    +
    static const struct v4l2_ioctl_ops venc_ioctl_ops = {
    .vidioc_querycap = venc_querycap,
    .vidioc_enum_fmt_vid_cap = venc_enum_fmt,
    @@ -534,6 +587,8 @@ static const struct v4l2_ioctl_ops venc_ioctl_ops = {
    .vidioc_enum_frameintervals = venc_enum_frameintervals,
    .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
    .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
    + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
    + .vidioc_encoder_cmd = venc_encoder_cmd,
    };

    static int venc_set_properties(struct venus_inst *inst)
    @@ -946,9 +1001,22 @@ static int venc_start_streaming(struct vb2_queue *q, unsigned int count)
    static void venc_vb2_buf_queue(struct vb2_buffer *vb)
    {
    struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
    + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
    + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;

    mutex_lock(&inst->lock);
    - venus_helper_vb2_buf_queue(vb);
    +
    + v4l2_m2m_buf_queue(m2m_ctx, vbuf);
    +
    + if (!(inst->streamon_out && inst->streamon_cap))
    + goto unlock;
    +
    + if (v4l2_m2m_has_stopped(m2m_ctx))
    + goto unlock;
    +
    + venus_helper_process_buf(vb);
    +
    +unlock:
    mutex_unlock(&inst->lock);
    }

    @@ -968,6 +1036,7 @@ static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type,
    struct vb2_v4l2_buffer *vbuf;
    struct vb2_buffer *vb;
    unsigned int type;
    + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;

    if (buf_type == HFI_BUFFER_INPUT)
    type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    @@ -986,6 +1055,12 @@ static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type,
    vb->planes[0].data_offset = data_offset;
    vb->timestamp = timestamp_us * NSEC_PER_USEC;
    vbuf->sequence = inst->sequence_cap++;
    +
    + if ((!bytesused && m2m_ctx->is_draining) ||
    + (vbuf->flags & V4L2_BUF_FLAG_LAST)) {
    + vbuf->flags |= V4L2_BUF_FLAG_LAST;
    + v4l2_m2m_mark_stopped(inst->m2m_ctx);
    + }
    } else {
    vbuf->sequence = inst->sequence_out++;
    }
    --
    2.17.1
    \
     
     \ /
      Last update: 2020-11-11 15:39    [W:4.452 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site