Commit a0517f5d authored by Pawel Osciak's avatar Pawel Osciak Committed by Mauro Carvalho Chehab

[media] s5p-mfc: Copy timestamps only when a frame is produced

Timestamps for destination buffers are assigned by copying them from
corresponding source buffers when the decode operation results in a frame
being outputted to a destination buffer. But the decision when to do this, i.e.
whether the decode operation on current source buffer produced a destination
frame, is wrongly based on "display status". Display status reflects the status
of the destination buffer, not source.

This used to work for firmwares version <= 6, because in addition to the above,
we'd check the decoded frame type register, which was set to "skipped" if
a destination frame was not produced, exiting early from
s5p_mfc_handle_frame_new().
Firmware >=7 does not set the frame type register for frames that were not
decoded anymore though, which results in us wrongly overwriting timestamps of
previously decoded buffers (firmware reports the same destination buffer address
as previously decoded one if a frame wasn't decoded during current operation).

To do it properly, we should be basing our decision to copy the timestamp on the
status of the source buffer, i.e. "decode status". The decode status register
values are confusing, because in its case "display" means "a frame has been
outputted to a destination buffer". We should copy if "decode and display"
is returned in it. This also works on <= v6 firmware, which behaves in the same
way with regards to decode status register.
Signed-off-by: default avatarPawel Osciak <posciak@chromium.org>
Signed-off-by: default avatarArun Kumar K <arun.kk@samsung.com>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent d98f1b78
...@@ -309,12 +309,15 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, ...@@ -309,12 +309,15 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
{ {
struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_dev *dev = ctx->dev;
unsigned int dst_frame_status; unsigned int dst_frame_status;
unsigned int dec_frame_status;
struct s5p_mfc_buf *src_buf; struct s5p_mfc_buf *src_buf;
unsigned long flags; unsigned long flags;
unsigned int res_change; unsigned int res_change;
dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) dst_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK; & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
dec_frame_status = s5p_mfc_hw_call(dev->mfc_ops, get_dec_status, dev)
& S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev) res_change = (s5p_mfc_hw_call(dev->mfc_ops, get_dspl_status, dev)
& S5P_FIMV_DEC_STATUS_RESOLUTION_MASK) & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK)
>> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT; >> S5P_FIMV_DEC_STATUS_RESOLUTION_SHIFT;
...@@ -347,8 +350,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, ...@@ -347,8 +350,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
} }
} }
if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY || if (dec_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY)
dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY)
s5p_mfc_handle_frame_copy_time(ctx); s5p_mfc_handle_frame_copy_time(ctx);
/* A frame has been decoded and is in the buffer */ /* A frame has been decoded and is in the buffer */
......
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