Эх сурвалжийг харах

video: driver: add support for VIDIOC_TRY_DECODER/ENCODER_CMD

Decoder needs to support VIDIOC_TRY_DECODER_CMD and
Encoder needs to be support VIDIOC_TRY_ENCODER_CMD.

Partially Fixes: V4l2-complience:
       testDecoder(VIDIOC_(TRY)_DECODER_CMD) for decoder.
       testEncoder(VIDIOC_(TRY)_ENCODER_CMD) for encoder.

Change-Id: Ia68587412ed316f0c871397da83d6c56665cfbb5
Signed-off-by: Dikshita Agarwal <[email protected]>
Dikshita Agarwal 4 жил өмнө
parent
commit
c790532a9b

+ 1 - 0
driver/vidc/inc/msm_vidc.h

@@ -39,6 +39,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type i);
 int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl);
 int msm_vidc_query_menu(void *instance, struct v4l2_querymenu *qmenu);
 int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i);
+int msm_vidc_try_cmd(void *instance, union msm_v4l2_cmd *cmd);
 int msm_vidc_cmd(void *instance, union msm_v4l2_cmd *cmd);
 int msm_vidc_poll(void *instance, struct file *filp,
 		struct poll_table_struct *pt);

+ 4 - 0
driver/vidc/inc/msm_vidc_v4l2.h

@@ -50,8 +50,12 @@ int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
 		const struct v4l2_event_subscription *sub);
 int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
 		const struct v4l2_event_subscription *sub);
+int msm_v4l2_try_decoder_cmd(struct file *file, void *fh,
+		struct v4l2_decoder_cmd *enc);
 int msm_v4l2_decoder_cmd(struct file *file, void *fh,
 		struct v4l2_decoder_cmd *dec);
+int msm_v4l2_try_encoder_cmd(struct file *file, void *fh,
+		struct v4l2_encoder_cmd *enc);
 int msm_v4l2_encoder_cmd(struct file *file, void *fh,
 		struct v4l2_encoder_cmd *enc);
 int msm_v4l2_enum_framesizes(struct file *file, void *fh,

+ 31 - 0
driver/vidc/src/msm_vidc.c

@@ -608,6 +608,37 @@ exit:
 }
 EXPORT_SYMBOL(msm_vidc_streamoff);
 
+int msm_vidc_try_cmd(void *instance, union msm_v4l2_cmd *cmd)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = instance;
+	struct v4l2_decoder_cmd *dec = NULL;
+	struct v4l2_encoder_cmd *enc = NULL;
+
+	if (is_decode_session(inst)) {
+		dec = (struct v4l2_decoder_cmd *)cmd;
+		i_vpr_h(inst, "%s: cmd %d\n", __func__, dec->cmd);
+		if (dec->cmd != V4L2_DEC_CMD_STOP && dec->cmd != V4L2_DEC_CMD_START)
+			return -EINVAL;
+		dec->flags = 0;
+		if (dec->cmd == V4L2_DEC_CMD_STOP) {
+			dec->stop.pts = 0;
+		} else if (dec->cmd == V4L2_DEC_CMD_START) {
+			dec->start.speed = 0;
+			dec->start.format = V4L2_DEC_START_FMT_NONE;
+		}
+	} else if (is_encode_session(inst)) {
+		enc = (struct v4l2_encoder_cmd *)cmd;
+		i_vpr_h(inst, "%s: cmd %d\n", __func__, enc->cmd);
+		if (enc->cmd != V4L2_ENC_CMD_STOP && enc->cmd != V4L2_ENC_CMD_START)
+			return -EINVAL;
+		enc->flags = 0;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(msm_vidc_try_cmd);
+
 int msm_vidc_cmd(void *instance, union msm_v4l2_cmd *cmd)
 {
 	int rc = 0;

+ 2 - 0
driver/vidc/src/msm_vidc_platform.c

@@ -70,6 +70,7 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops_enc = {
 	.vidioc_querymenu               = msm_v4l2_querymenu,
 	.vidioc_subscribe_event         = msm_v4l2_subscribe_event,
 	.vidioc_unsubscribe_event       = msm_v4l2_unsubscribe_event,
+	.vidioc_try_encoder_cmd         = msm_v4l2_try_encoder_cmd,
 	.vidioc_encoder_cmd             = msm_v4l2_encoder_cmd,
 };
 
@@ -108,6 +109,7 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops_dec = {
 	.vidioc_querymenu               = msm_v4l2_querymenu,
 	.vidioc_subscribe_event         = msm_v4l2_subscribe_event,
 	.vidioc_unsubscribe_event       = msm_v4l2_unsubscribe_event,
+	.vidioc_try_decoder_cmd         = msm_v4l2_try_decoder_cmd,
 	.vidioc_decoder_cmd             = msm_v4l2_decoder_cmd,
 };
 

+ 58 - 0
driver/vidc/src/msm_vidc_v4l2.c

@@ -539,6 +539,35 @@ unlock:
 	return rc;
 }
 
+int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh,
+			     struct v4l2_decoder_cmd *dec)
+{
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	if (is_session_error(inst)) {
+		i_vpr_e(inst, "%s: inst in error state\n", __func__);
+		rc = -EBUSY;
+		goto unlock;
+	}
+	rc = msm_vidc_try_cmd(inst, (union msm_v4l2_cmd *)dec);
+	if (rc)
+		goto unlock;
+
+unlock:
+	inst_unlock(inst, __func__);
+	put_inst(inst);
+
+	return rc;
+}
+
 int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
 				struct v4l2_decoder_cmd *dec)
 {
@@ -568,6 +597,35 @@ unlock:
 	return rc;
 }
 
+int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh,
+			     struct v4l2_encoder_cmd *enc)
+{
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	if (is_session_error(inst)) {
+		i_vpr_e(inst, "%s: inst in error state\n", __func__);
+		rc = -EBUSY;
+		goto unlock;
+	}
+	rc = msm_vidc_try_cmd(inst, (union msm_v4l2_cmd *)enc);
+	if (rc)
+		goto unlock;
+
+unlock:
+	inst_unlock(inst, __func__);
+	put_inst(inst);
+
+	return rc;
+}
+
 int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
 				struct v4l2_encoder_cmd *enc)
 {