aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/media
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2022-05-13 22:29:03 +0200
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-05-17 09:58:42 +0200
commit2e2c3d6c0ef88ffac0d6b5079ee88cf8408f5f3b (patch)
treee935576ca7043801ab8bc5aa3ea856720501f0f7 /drivers/media
parentmedia: ov7251: fix mutex lock unbalance (diff)
downloadwireguard-linux-2e2c3d6c0ef88ffac0d6b5079ee88cf8408f5f3b.tar.xz
wireguard-linux-2e2c3d6c0ef88ffac0d6b5079ee88cf8408f5f3b.zip
media: h264: Use v4l2_h264_reference for reflist
In preparation for adding field decoding support, convert the byte arrays for reflist into array of struct v4l2_h264_reference. That struct will allow us to mark which field of the reference picture is being referenced. [hverkuil: top_field_order_cnt -> pic_order_count] Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c21
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h11
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c15
-rw-r--r--drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c27
-rw-r--r--drivers/media/platform/nvidia/tegra-vde/h264.c19
-rw-r--r--drivers/media/v4l2-core/v4l2-h264.c33
6 files changed, 80 insertions, 46 deletions
diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c
index 3c75a7b4e845..ca628321d272 100644
--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c
+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.c
@@ -12,11 +12,24 @@
#define GET_MTK_VDEC_PARAM(param) \
{ dst_param->param = src_param->param; }
-/*
- * The firmware expects unused reflist entries to have the value 0x20.
- */
-void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
+void mtk_vdec_h264_get_ref_list(u8 *ref_list,
+ const struct v4l2_h264_reference *v4l2_ref_list,
+ int num_valid)
{
+ u32 i;
+
+ /*
+ * TODO The firmware does not support field decoding. Future
+ * implementation must use v4l2_ref_list[i].fields to obtain
+ * the reference field parity.
+ */
+
+ for (i = 0; i < num_valid; i++)
+ ref_list[i] = v4l2_ref_list[i].index;
+
+ /*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
memset(&ref_list[num_valid], 0x20, 32 - num_valid);
}
diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h
index 0113f380b491..53d0a7c962a9 100644
--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h
+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_common.h
@@ -164,12 +164,15 @@ struct h264_fb {
};
/**
- * mtk_vdec_h264_fixup_ref_list - fixup unused reference to 0x20.
+ * mtk_vdec_h264_get_ref_list - translate V4L2 reference list
*
- * @ref_list: reference picture list
- * @num_valid: used reference number
+ * @ref_list: Mediatek reference picture list
+ * @v4l2_ref_list: V4L2 reference picture list
+ * @num_valid: used reference number
*/
-void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid);
+void mtk_vdec_h264_get_ref_list(u8 *ref_list,
+ const struct v4l2_h264_reference *v4l2_ref_list,
+ int num_valid);
/**
* mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
index b055ceea481d..4bc05ab5afea 100644
--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_if.c
@@ -102,6 +102,9 @@ static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
struct v4l2_h264_reflist_builder reflist_builder;
+ struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -137,12 +140,14 @@ static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
/* Build the reference lists */
v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
inst->dpb);
- v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
- v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+ v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
+ v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist,
+ v4l2_b1_reflist);
+
/* Adapt the built lists to the firmware's expectations */
- mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);
memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
sizeof(inst->vsi_ctx.h264_slice_params));
diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
index 1d9e753cf894..784d01f8bd50 100644
--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
@@ -222,6 +222,9 @@ static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)
const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
struct vdec_h264_slice_lat_dec_param *slice_param = &inst->h264_slice_param;
struct v4l2_h264_reflist_builder reflist_builder;
+ struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -256,13 +259,14 @@ static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)
/* Build the reference lists */
v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, inst->dpb);
- v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+ v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
+ v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist, v4l2_b1_reflist);
- v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
/* Adapt the built lists to the firmware's expectations */
- mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);
+
memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
sizeof(inst->vsi_ctx.h264_slice_params));
@@ -276,6 +280,9 @@ static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *ins
struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
struct v4l2_h264_reflist_builder reflist_builder;
+ struct v4l2_h264_reference v4l2_p0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b0_reflist[V4L2_H264_REF_LIST_LEN];
+ struct v4l2_h264_reference v4l2_b1_reflist[V4L2_H264_REF_LIST_LEN];
u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
@@ -291,13 +298,13 @@ static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *ins
/* Build the reference lists */
v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
inst->dpb);
- v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
- v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+ v4l2_h264_build_p_ref_list(&reflist_builder, v4l2_p0_reflist);
+ v4l2_h264_build_b_ref_lists(&reflist_builder, v4l2_b0_reflist, v4l2_b1_reflist);
/* Adapt the built lists to the firmware's expectations */
- mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
- mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(p0_reflist, v4l2_p0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b0_reflist, v4l2_b0_reflist, reflist_builder.num_valid);
+ mtk_vdec_h264_get_ref_list(b1_reflist, v4l2_b1_reflist, reflist_builder.num_valid);
}
static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
diff --git a/drivers/media/platform/nvidia/tegra-vde/h264.c b/drivers/media/platform/nvidia/tegra-vde/h264.c
index d8e5534e80c8..4fb0aaad16d6 100644
--- a/drivers/media/platform/nvidia/tegra-vde/h264.c
+++ b/drivers/media/platform/nvidia/tegra-vde/h264.c
@@ -45,9 +45,9 @@ struct tegra_vde_h264_decoder_ctx {
};
struct h264_reflists {
- u8 p[V4L2_H264_NUM_DPB_ENTRIES];
- u8 b0[V4L2_H264_NUM_DPB_ENTRIES];
- u8 b1[V4L2_H264_NUM_DPB_ENTRIES];
+ struct v4l2_h264_reference p[V4L2_H264_NUM_DPB_ENTRIES];
+ struct v4l2_h264_reference b0[V4L2_H264_NUM_DPB_ENTRIES];
+ struct v4l2_h264_reference b1[V4L2_H264_NUM_DPB_ENTRIES];
};
static int tegra_vde_wait_mbe(struct tegra_vde *vde)
@@ -765,10 +765,10 @@ static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
struct tegra_m2m_buffer *tb = vb_to_tegra_buf(&dst->vb2_buf);
struct tegra_ctx_h264 *h = &ctx->h264;
struct v4l2_h264_reflist_builder b;
+ struct v4l2_h264_reference *dpb_id;
struct h264_reflists reflists;
struct vb2_buffer *ref;
unsigned int i;
- u8 *dpb_id;
int err;
/*
@@ -811,14 +811,16 @@ static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
}
for (i = 0; i < b.num_valid; i++) {
- ref = get_ref_buf(ctx, dst, dpb_id[i]);
+ int dpb_idx = dpb_id[i].index;
- err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_id[i],
+ ref = get_ref_buf(ctx, dst, dpb_idx);
+
+ err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_idx,
h264->dpb_frames_nb++);
if (err)
return err;
- if (b.refs[dpb_id[i]].pic_order_count < b.cur_pic_order_count)
+ if (b.refs[dpb_idx].pic_order_count < b.cur_pic_order_count)
h264->dpb_ref_frames_with_earlier_poc_nb++;
}
@@ -880,6 +882,9 @@ static int tegra_vde_h264_setup_context(struct tegra_ctx *ctx,
if (h->pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
return -EOPNOTSUPP;
+ if (h->decode_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC)
+ return -EOPNOTSUPP;
+
if (h->sps->profile_idc == 66)
h264->baseline_profile = 1;
diff --git a/drivers/media/v4l2-core/v4l2-h264.c b/drivers/media/v4l2-core/v4l2-h264.c
index ac47519a9fbe..afbfcf78efe4 100644
--- a/drivers/media/v4l2-core/v4l2-h264.c
+++ b/drivers/media/v4l2-core/v4l2-h264.c
@@ -75,12 +75,12 @@ v4l2_h264_init_reflist_builder(struct v4l2_h264_reflist_builder *b,
pic_order_count = dpb[i].top_field_order_cnt;
b->refs[i].pic_order_count = pic_order_count;
- b->unordered_reflist[b->num_valid] = i;
+ b->unordered_reflist[b->num_valid].index = i;
b->num_valid++;
}
for (i = b->num_valid; i < ARRAY_SIZE(b->unordered_reflist); i++)
- b->unordered_reflist[i] = i;
+ b->unordered_reflist[i].index = i;
}
EXPORT_SYMBOL_GPL(v4l2_h264_init_reflist_builder);
@@ -90,8 +90,8 @@ static int v4l2_h264_p_ref_list_cmp(const void *ptra, const void *ptrb,
const struct v4l2_h264_reflist_builder *builder = data;
u8 idxa, idxb;
- idxa = *((u8 *)ptra);
- idxb = *((u8 *)ptrb);
+ idxa = ((struct v4l2_h264_reference *)ptra)->index;
+ idxb = ((struct v4l2_h264_reference *)ptrb)->index;
if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES ||
idxb >= V4L2_H264_NUM_DPB_ENTRIES))
@@ -125,8 +125,8 @@ static int v4l2_h264_b0_ref_list_cmp(const void *ptra, const void *ptrb,
s32 poca, pocb;
u8 idxa, idxb;
- idxa = *((u8 *)ptra);
- idxb = *((u8 *)ptrb);
+ idxa = ((struct v4l2_h264_reference *)ptra)->index;
+ idxb = ((struct v4l2_h264_reference *)ptrb)->index;
if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES ||
idxb >= V4L2_H264_NUM_DPB_ENTRIES))
@@ -170,8 +170,8 @@ static int v4l2_h264_b1_ref_list_cmp(const void *ptra, const void *ptrb,
s32 poca, pocb;
u8 idxa, idxb;
- idxa = *((u8 *)ptra);
- idxb = *((u8 *)ptrb);
+ idxa = ((struct v4l2_h264_reference *)ptra)->index;
+ idxb = ((struct v4l2_h264_reference *)ptrb)->index;
if (WARN_ON(idxa >= V4L2_H264_NUM_DPB_ENTRIES ||
idxb >= V4L2_H264_NUM_DPB_ENTRIES))
@@ -212,8 +212,8 @@ static int v4l2_h264_b1_ref_list_cmp(const void *ptra, const void *ptrb,
* v4l2_h264_build_p_ref_list() - Build the P reference list
*
* @builder: reference list builder context
- * @reflist: 16-bytes array used to store the P reference list. Each entry
- * is an index in the DPB
+ * @reflist: 16 sized array used to store the P reference list. Each entry
+ * is a v4l2_h264_reference structure
*
* This functions builds the P reference lists. This procedure is describe in
* section '8.2.4 Decoding process for reference picture lists construction'
@@ -222,7 +222,7 @@ static int v4l2_h264_b1_ref_list_cmp(const void *ptra, const void *ptrb,
*/
void
v4l2_h264_build_p_ref_list(const struct v4l2_h264_reflist_builder *builder,
- u8 *reflist)
+ struct v4l2_h264_reference *reflist)
{
memcpy(reflist, builder->unordered_reflist,
sizeof(builder->unordered_reflist[0]) * builder->num_valid);
@@ -235,10 +235,10 @@ EXPORT_SYMBOL_GPL(v4l2_h264_build_p_ref_list);
* v4l2_h264_build_b_ref_lists() - Build the B0/B1 reference lists
*
* @builder: reference list builder context
- * @b0_reflist: 16-bytes array used to store the B0 reference list. Each entry
- * is an index in the DPB
- * @b1_reflist: 16-bytes array used to store the B1 reference list. Each entry
- * is an index in the DPB
+ * @b0_reflist: 16 sized array used to store the B0 reference list. Each entry
+ * is a v4l2_h264_reference structure
+ * @b1_reflist: 16 sized array used to store the B1 reference list. Each entry
+ * is a v4l2_h264_reference structure
*
* This functions builds the B0/B1 reference lists. This procedure is described
* in section '8.2.4 Decoding process for reference picture lists construction'
@@ -247,7 +247,8 @@ EXPORT_SYMBOL_GPL(v4l2_h264_build_p_ref_list);
*/
void
v4l2_h264_build_b_ref_lists(const struct v4l2_h264_reflist_builder *builder,
- u8 *b0_reflist, u8 *b1_reflist)
+ struct v4l2_h264_reference *b0_reflist,
+ struct v4l2_h264_reference *b1_reflist)
{
memcpy(b0_reflist, builder->unordered_reflist,
sizeof(builder->unordered_reflist[0]) * builder->num_valid);