summaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorJernej Skrabec <jernej.skrabec@siol.net>2020-08-25 05:52:41 +0200
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2020-09-01 14:13:28 +0200
commit46e8893e72b43d10f5cad92355b36a7babe83724 (patch)
treef3649c28288d63d0537adcbbe055ef535f38fcc3 /drivers/staging
parentcfc8c3ed533e650270152f293a3536f3ca0e7053 (diff)
media: cedrus: h264: Fix frame list construction
Current frame list construction algorithm assumes that decoded image will be output into its own buffer. That is true for progressive content but not for interlaced where each field is decoded separately into same buffer. Fix that by checking if capture buffer is listed in DPB. If it is, reuse it. Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/sunxi/cedrus/cedrus_h264.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
index 1e89a8438f36..fe041b444385 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
@@ -101,7 +101,7 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
struct cedrus_dev *dev = ctx->dev;
unsigned long used_dpbs = 0;
unsigned int position;
- unsigned int output = 0;
+ int output = -1;
unsigned int i;
cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
@@ -124,6 +124,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
position = cedrus_buf->codec.h264.position;
used_dpbs |= BIT(position);
+ if (run->dst->vb2_buf.timestamp == dpb->reference_ts) {
+ output = position;
+ continue;
+ }
+
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
continue;
@@ -131,13 +136,11 @@ static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
dpb->top_field_order_cnt,
dpb->bottom_field_order_cnt,
&pic_list[position]);
-
- output = max(position, output);
}
- position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
- output);
- if (position >= CEDRUS_H264_FRAME_NUM)
+ if (output >= 0)
+ position = output;
+ else
position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);