media: rkvdec: h264: Fix dpb_valid implementation
[ Upstream commit 7ab889f09dfa70e8097ec1b9186fd228124112cb ]
The ref builder only provided references that are marked as valid in the
dpb. Thus the current implementation of dpb_valid would always set the
flag to 1. This is not representing missing frames (this is called
'non-existing' pictures in the spec). In some context, these non-existing
pictures still need to occupy a slot in the reference list according to
the spec.
Fixes: cd33c83044
("media: rkvdec: Add the rkvdec driver")
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reviewed-by: Sebastian Fricke <sebastian.fricke@collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
82239e30ab
commit
b4805a77d5
@@ -112,6 +112,7 @@ struct rkvdec_h264_run {
|
|||||||
const struct v4l2_ctrl_h264_sps *sps;
|
const struct v4l2_ctrl_h264_sps *sps;
|
||||||
const struct v4l2_ctrl_h264_pps *pps;
|
const struct v4l2_ctrl_h264_pps *pps;
|
||||||
const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
|
const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
|
||||||
|
int ref_buf_idx[V4L2_H264_NUM_DPB_ENTRIES];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rkvdec_h264_ctx {
|
struct rkvdec_h264_ctx {
|
||||||
@@ -725,6 +726,26 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
|
||||||
|
struct rkvdec_h264_run *run)
|
||||||
|
{
|
||||||
|
const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
|
||||||
|
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
|
||||||
|
const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
|
||||||
|
struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
|
||||||
|
int buf_idx = -1;
|
||||||
|
|
||||||
|
if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
||||||
|
buf_idx = vb2_find_timestamp(cap_q,
|
||||||
|
dpb[i].reference_ts, 0);
|
||||||
|
|
||||||
|
run->ref_buf_idx[i] = buf_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
||||||
struct rkvdec_h264_run *run)
|
struct rkvdec_h264_run *run)
|
||||||
{
|
{
|
||||||
@@ -762,7 +783,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
|||||||
|
|
||||||
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
|
||||||
for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
|
for (i = 0; i < h264_ctx->reflists.num_valid; i++) {
|
||||||
u8 dpb_valid = 0;
|
bool dpb_valid = run->ref_buf_idx[i] >= 0;
|
||||||
u8 idx = 0;
|
u8 idx = 0;
|
||||||
|
|
||||||
switch (j) {
|
switch (j) {
|
||||||
@@ -779,8 +800,6 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
|
|||||||
|
|
||||||
if (idx >= ARRAY_SIZE(dec_params->dpb))
|
if (idx >= ARRAY_SIZE(dec_params->dpb))
|
||||||
continue;
|
continue;
|
||||||
dpb_valid = !!(dpb[idx].flags &
|
|
||||||
V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
|
|
||||||
|
|
||||||
set_ps_field(hw_rps, DPB_INFO(i, j),
|
set_ps_field(hw_rps, DPB_INFO(i, j),
|
||||||
idx | dpb_valid << 4);
|
idx | dpb_valid << 4);
|
||||||
@@ -859,13 +878,8 @@ get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run,
|
|||||||
unsigned int dpb_idx)
|
unsigned int dpb_idx)
|
||||||
{
|
{
|
||||||
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
|
struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx;
|
||||||
const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb;
|
|
||||||
struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
|
struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q;
|
||||||
int buf_idx = -1;
|
int buf_idx = run->ref_buf_idx[dpb_idx];
|
||||||
|
|
||||||
if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
|
|
||||||
buf_idx = vb2_find_timestamp(cap_q,
|
|
||||||
dpb[dpb_idx].reference_ts, 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a DPB entry is unused or invalid, address of current destination
|
* If a DPB entry is unused or invalid, address of current destination
|
||||||
@@ -1102,6 +1116,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
|
|||||||
|
|
||||||
assemble_hw_scaling_list(ctx, &run);
|
assemble_hw_scaling_list(ctx, &run);
|
||||||
assemble_hw_pps(ctx, &run);
|
assemble_hw_pps(ctx, &run);
|
||||||
|
lookup_ref_buf_idx(ctx, &run);
|
||||||
assemble_hw_rps(ctx, &run);
|
assemble_hw_rps(ctx, &run);
|
||||||
config_registers(ctx, &run);
|
config_registers(ctx, &run);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user