media: rockchip/vpu: Add infra to support MPEG-2 decoding
Only adds structs and helpers to allow supporting MPEG-2 decoding on rockchip SoCs. Support for RK3399 and RK3288 will be added in separate commits Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
6d9a39cffc
commit
7cdedc3f45
|
@ -8,4 +8,5 @@ rockchip-vpu-y += \
|
|||
rk3288_vpu_hw_jpeg_enc.o \
|
||||
rk3399_vpu_hw.o \
|
||||
rk3399_vpu_hw_jpeg_enc.o \
|
||||
rockchip_vpu_jpeg.o
|
||||
rockchip_vpu_jpeg.o \
|
||||
rockchip_vpu_mpeg2.o
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
#define ROCKCHIP_VPU_MAX_CLOCKS 4
|
||||
|
||||
#define MPEG2_MB_DIM 16
|
||||
#define MPEG2_MB_WIDTH(w) DIV_ROUND_UP(w, MPEG2_MB_DIM)
|
||||
#define MPEG2_MB_HEIGHT(h) DIV_ROUND_UP(h, MPEG2_MB_DIM)
|
||||
|
||||
#define JPEG_MB_DIM 16
|
||||
#define JPEG_MB_WIDTH(w) DIV_ROUND_UP(w, JPEG_MB_DIM)
|
||||
#define JPEG_MB_HEIGHT(h) DIV_ROUND_UP(h, JPEG_MB_DIM)
|
||||
|
@ -37,6 +41,7 @@ struct rockchip_vpu_codec_ops;
|
|||
#define RK_VPU_JPEG_ENCODER BIT(0)
|
||||
#define RK_VPU_ENCODERS 0x0000ffff
|
||||
|
||||
#define RK_VPU_MPEG2_DECODER BIT(16)
|
||||
#define RK_VPU_DECODERS 0xffff0000
|
||||
|
||||
/**
|
||||
|
@ -76,10 +81,12 @@ struct rockchip_vpu_variant {
|
|||
* enum rockchip_vpu_codec_mode - codec operating mode.
|
||||
* @RK_VPU_MODE_NONE: No operating mode. Used for RAW video formats.
|
||||
* @RK_VPU_MODE_JPEG_ENC: JPEG encoder.
|
||||
* @RK_VPU_MODE_MPEG2_DEC: MPEG-2 decoder.
|
||||
*/
|
||||
enum rockchip_vpu_codec_mode {
|
||||
RK_VPU_MODE_NONE = -1,
|
||||
RK_VPU_MODE_JPEG_ENC,
|
||||
RK_VPU_MODE_MPEG2_DEC,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -190,6 +197,7 @@ struct rockchip_vpu_dev {
|
|||
* calling v4l2_m2m_job_finish.
|
||||
* @codec_ops: Set of operations related to codec mode.
|
||||
* @jpeg_enc: JPEG-encoding context.
|
||||
* @mpeg2_dec: MPEG-2-decoding context.
|
||||
*/
|
||||
struct rockchip_vpu_ctx {
|
||||
struct rockchip_vpu_dev *dev;
|
||||
|
@ -215,6 +223,7 @@ struct rockchip_vpu_ctx {
|
|||
/* Specific for particular codec modes. */
|
||||
union {
|
||||
struct rockchip_vpu_jpeg_enc_hw_ctx jpeg_enc;
|
||||
struct rockchip_vpu_mpeg2_dec_hw_ctx mpeg2_dec;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -319,4 +328,7 @@ static inline u32 vdpu_read(struct rockchip_vpu_dev *vpu, u32 reg)
|
|||
|
||||
bool rockchip_vpu_is_encoder_ctx(const struct rockchip_vpu_ctx *ctx);
|
||||
|
||||
void *rockchip_vpu_get_ctrl(struct rockchip_vpu_ctx *ctx, u32 id);
|
||||
dma_addr_t rockchip_vpu_get_ref(struct vb2_queue *q, u64 ts);
|
||||
|
||||
#endif /* ROCKCHIP_VPU_H_ */
|
||||
|
|
|
@ -35,6 +35,24 @@ module_param_named(debug, rockchip_vpu_debug, int, 0644);
|
|||
MODULE_PARM_DESC(debug,
|
||||
"Debug level - higher value produces more verbose messages");
|
||||
|
||||
void *rockchip_vpu_get_ctrl(struct rockchip_vpu_ctx *ctx, u32 id)
|
||||
{
|
||||
struct v4l2_ctrl *ctrl;
|
||||
|
||||
ctrl = v4l2_ctrl_find(&ctx->ctrl_handler, id);
|
||||
return ctrl ? ctrl->p_cur.p : NULL;
|
||||
}
|
||||
|
||||
dma_addr_t rockchip_vpu_get_ref(struct vb2_queue *q, u64 ts)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = vb2_find_timestamp(q, ts, 0);
|
||||
if (index >= 0)
|
||||
return vb2_dma_contig_plane_dma_addr(q->bufs[index], 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rockchip_vpu_enc_buf_finish(struct rockchip_vpu_ctx *ctx,
|
||||
struct vb2_buffer *buf,
|
||||
|
@ -255,6 +273,18 @@ static struct rockchip_vpu_ctrl controls[] = {
|
|||
.step = 1,
|
||||
.def = 50,
|
||||
},
|
||||
}, {
|
||||
.id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
|
||||
.codec = RK_VPU_MPEG2_DECODER,
|
||||
.cfg = {
|
||||
.elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params),
|
||||
},
|
||||
}, {
|
||||
.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
|
||||
.codec = RK_VPU_MPEG2_DECODER,
|
||||
.cfg = {
|
||||
.elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/v4l2-controls.h>
|
||||
#include <media/mpeg2-ctrls.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
|
||||
struct rockchip_vpu_dev;
|
||||
|
@ -38,6 +39,14 @@ struct rockchip_vpu_jpeg_enc_hw_ctx {
|
|||
struct rockchip_vpu_aux_buf bounce_buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rockchip_vpu_mpeg2_dec_hw_ctx
|
||||
* @qtable: Quantization table
|
||||
*/
|
||||
struct rockchip_vpu_mpeg2_dec_hw_ctx {
|
||||
struct rockchip_vpu_aux_buf qtable;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rockchip_vpu_codec_ops - codec mode specific operations
|
||||
*
|
||||
|
@ -83,4 +92,9 @@ void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx);
|
|||
int rockchip_vpu_jpeg_enc_init(struct rockchip_vpu_ctx *ctx);
|
||||
void rockchip_vpu_jpeg_enc_exit(struct rockchip_vpu_ctx *ctx);
|
||||
|
||||
void rockchip_vpu_mpeg2_dec_copy_qtable(u8 *qtable,
|
||||
const struct v4l2_ctrl_mpeg2_quantization *ctrl);
|
||||
int rockchip_vpu_mpeg2_dec_init(struct rockchip_vpu_ctx *ctx);
|
||||
void rockchip_vpu_mpeg2_dec_exit(struct rockchip_vpu_ctx *ctx);
|
||||
|
||||
#endif /* ROCKCHIP_VPU_HW_H_ */
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Rockchip VPU codec driver
|
||||
*
|
||||
* Copyright (C) 2018 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include "rockchip_vpu.h"
|
||||
|
||||
static const u8 zigzag[64] = {
|
||||
0, 1, 8, 16, 9, 2, 3, 10,
|
||||
17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34,
|
||||
27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36,
|
||||
29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46,
|
||||
53, 60, 61, 54, 47, 55, 62, 63
|
||||
};
|
||||
|
||||
void rockchip_vpu_mpeg2_dec_copy_qtable(u8 *qtable,
|
||||
const struct v4l2_ctrl_mpeg2_quantization *ctrl)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (!qtable || !ctrl)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(zigzag); i++) {
|
||||
n = zigzag[i];
|
||||
qtable[n + 0] = ctrl->intra_quantiser_matrix[i];
|
||||
qtable[n + 64] = ctrl->non_intra_quantiser_matrix[i];
|
||||
qtable[n + 128] = ctrl->chroma_intra_quantiser_matrix[i];
|
||||
qtable[n + 192] = ctrl->chroma_non_intra_quantiser_matrix[i];
|
||||
}
|
||||
}
|
||||
|
||||
int rockchip_vpu_mpeg2_dec_init(struct rockchip_vpu_ctx *ctx)
|
||||
{
|
||||
struct rockchip_vpu_dev *vpu = ctx->dev;
|
||||
|
||||
ctx->mpeg2_dec.qtable.size = ARRAY_SIZE(zigzag) * 4;
|
||||
ctx->mpeg2_dec.qtable.cpu =
|
||||
dma_alloc_coherent(vpu->dev,
|
||||
ctx->mpeg2_dec.qtable.size,
|
||||
&ctx->mpeg2_dec.qtable.dma,
|
||||
GFP_KERNEL);
|
||||
if (!ctx->mpeg2_dec.qtable.cpu)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rockchip_vpu_mpeg2_dec_exit(struct rockchip_vpu_ctx *ctx)
|
||||
{
|
||||
struct rockchip_vpu_dev *vpu = ctx->dev;
|
||||
|
||||
dma_free_coherent(vpu->dev,
|
||||
ctx->mpeg2_dec.qtable.size,
|
||||
ctx->mpeg2_dec.qtable.cpu,
|
||||
ctx->mpeg2_dec.qtable.dma);
|
||||
}
|
Loading…
Reference in New Issue