Commit 455e5836 authored by Ming Qian's avatar Ming Qian Committed by Mauro Carvalho Chehab

media: amphion: encoder copy timestamp from output to capture

copy the timestamp using the helper function
V4L2_BUF_FLAG_TIMESTAMP_COPY

To implement this, driver will keep the output buffer until it's
encoded, in previous, driver will return the output buffer immediately
after firmware return it
Signed-off-by: default avatarMing Qian <ming.qian@nxp.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent a4dca209
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#define VENC_CAPTURE_ENABLE BIT(1) #define VENC_CAPTURE_ENABLE BIT(1)
#define VENC_ENABLE_MASK (VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE) #define VENC_ENABLE_MASK (VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
#define VENC_MAX_BUF_CNT 8 #define VENC_MAX_BUF_CNT 8
#define VENC_MIN_BUFFER_OUT 6
#define VENC_MIN_BUFFER_CAP 6
struct venc_t { struct venc_t {
struct vpu_encode_params params; struct vpu_encode_params params;
...@@ -423,7 +425,7 @@ static int venc_drain(struct vpu_inst *inst) ...@@ -423,7 +425,7 @@ static int venc_drain(struct vpu_inst *inst)
if (inst->state != VPU_CODEC_STATE_DRAIN) if (inst->state != VPU_CODEC_STATE_DRAIN)
return 0; return 0;
if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx)) if (!vpu_is_source_empty(inst))
return 0; return 0;
if (!venc->input_ready) if (!venc->input_ready)
...@@ -775,10 +777,20 @@ static int venc_get_one_encoded_frame(struct vpu_inst *inst, ...@@ -775,10 +777,20 @@ static int venc_get_one_encoded_frame(struct vpu_inst *inst,
struct vb2_v4l2_buffer *vbuf) struct vb2_v4l2_buffer *vbuf)
{ {
struct venc_t *venc = inst->priv; struct venc_t *venc = inst->priv;
struct vb2_v4l2_buffer *src_buf;
if (!vbuf) if (!vbuf)
return -EAGAIN; return -EAGAIN;
src_buf = vpu_find_buf_by_sequence(inst, inst->out_format.type, frame->info.frame_id);
if (src_buf) {
v4l2_m2m_buf_copy_metadata(src_buf, vbuf, true);
vpu_set_buffer_state(src_buf, VPU_BUF_STATE_IDLE);
v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, src_buf);
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
} else {
vbuf->vb2_buf.timestamp = frame->info.timestamp;
}
if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) { if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
return 0; return 0;
...@@ -800,11 +812,10 @@ static int venc_get_one_encoded_frame(struct vpu_inst *inst, ...@@ -800,11 +812,10 @@ static int venc_get_one_encoded_frame(struct vpu_inst *inst,
} }
vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused); vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
vbuf->sequence = frame->info.frame_id; vbuf->sequence = frame->info.frame_id;
vbuf->vb2_buf.timestamp = frame->info.timestamp;
vbuf->field = inst->cap_format.field; vbuf->field = inst->cap_format.field;
vbuf->flags |= frame->info.pic_type; vbuf->flags |= frame->info.pic_type;
vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE); vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->info.timestamp); dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp);
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
venc->ready_count++; venc->ready_count++;
...@@ -860,33 +871,6 @@ static int venc_frame_encoded(struct vpu_inst *inst, void *arg) ...@@ -860,33 +871,6 @@ static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
return ret; return ret;
} }
static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
{
struct vb2_v4l2_buffer *vbuf;
if (!inst->fh.m2m_ctx)
return;
vpu_inst_lock(inst);
if (!venc_get_enable(inst->priv, frame->type))
goto exit;
vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
if (!vbuf) {
dev_err(inst->dev, "[%d] can't find buf: type %d, sequence %d\n",
inst->id, frame->type, frame->sequence);
goto exit;
}
vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
if (V4L2_TYPE_IS_OUTPUT(frame->type))
v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
else
v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
exit:
vpu_inst_unlock(inst);
}
static void venc_set_last_buffer_dequeued(struct vpu_inst *inst) static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
{ {
struct venc_t *venc = inst->priv; struct venc_t *venc = inst->priv;
...@@ -1252,7 +1236,6 @@ static struct vpu_inst_ops venc_inst_ops = { ...@@ -1252,7 +1236,6 @@ static struct vpu_inst_ops venc_inst_ops = {
.check_ready = venc_check_ready, .check_ready = venc_check_ready,
.input_done = venc_input_done, .input_done = venc_input_done,
.get_one_frame = venc_frame_encoded, .get_one_frame = venc_frame_encoded,
.buf_done = venc_buf_done,
.stop_done = venc_stop_done, .stop_done = venc_stop_done,
.event_notify = venc_event_notify, .event_notify = venc_event_notify,
.release = venc_release, .release = venc_release,
...@@ -1333,6 +1316,8 @@ static int venc_open(struct file *file) ...@@ -1333,6 +1316,8 @@ static int venc_open(struct file *file)
if (ret) if (ret)
return ret; return ret;
inst->min_buffer_out = VENC_MIN_BUFFER_OUT;
inst->min_buffer_cap = VENC_MIN_BUFFER_CAP;
venc_init(file); venc_init(file);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment