|
@@ -469,8 +469,14 @@ static int vdec_subscribe_event(struct v4l2_fh *fh,
|
|
static int
|
|
static int
|
|
vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
|
|
vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
|
|
{
|
|
{
|
|
- if (cmd->cmd != V4L2_DEC_CMD_STOP)
|
|
|
|
|
|
+ switch (cmd->cmd) {
|
|
|
|
+ case V4L2_DEC_CMD_STOP:
|
|
|
|
+ if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -479,6 +485,7 @@ static int
|
|
vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
|
|
vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
|
|
{
|
|
{
|
|
struct venus_inst *inst = to_inst(file);
|
|
struct venus_inst *inst = to_inst(file);
|
|
|
|
+ struct hfi_frame_data fdata = {0};
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
ret = vdec_try_decoder_cmd(file, fh, cmd);
|
|
ret = vdec_try_decoder_cmd(file, fh, cmd);
|
|
@@ -486,12 +493,23 @@ vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
mutex_lock(&inst->lock);
|
|
mutex_lock(&inst->lock);
|
|
- inst->cmd_stop = true;
|
|
|
|
- mutex_unlock(&inst->lock);
|
|
|
|
|
|
|
|
- hfi_session_flush(inst);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
|
|
|
|
+ * input to signal EOS.
|
|
|
|
+ */
|
|
|
|
+ if (!(inst->streamon_out & inst->streamon_cap))
|
|
|
|
+ goto unlock;
|
|
|
|
+
|
|
|
|
+ fdata.buffer_type = HFI_BUFFER_INPUT;
|
|
|
|
+ fdata.flags |= HFI_BUFFERFLAG_EOS;
|
|
|
|
+ fdata.device_addr = 0xdeadbeef;
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ ret = hfi_session_process_buf(inst, &fdata);
|
|
|
|
+
|
|
|
|
+unlock:
|
|
|
|
+ mutex_unlock(&inst->lock);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
|
|
static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
|
|
@@ -718,7 +736,6 @@ static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
inst->reconfig = false;
|
|
inst->reconfig = false;
|
|
inst->sequence_cap = 0;
|
|
inst->sequence_cap = 0;
|
|
inst->sequence_out = 0;
|
|
inst->sequence_out = 0;
|
|
- inst->cmd_stop = false;
|
|
|
|
|
|
|
|
ret = vdec_init_session(inst);
|
|
ret = vdec_init_session(inst);
|
|
if (ret)
|
|
if (ret)
|
|
@@ -807,11 +824,6 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
|
|
vb->timestamp = timestamp_us * NSEC_PER_USEC;
|
|
vb->timestamp = timestamp_us * NSEC_PER_USEC;
|
|
vbuf->sequence = inst->sequence_cap++;
|
|
vbuf->sequence = inst->sequence_cap++;
|
|
|
|
|
|
- if (inst->cmd_stop) {
|
|
|
|
- vbuf->flags |= V4L2_BUF_FLAG_LAST;
|
|
|
|
- inst->cmd_stop = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
|
|
if (vbuf->flags & V4L2_BUF_FLAG_LAST) {
|
|
const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
|
|
const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
|
|
|
|
|