Commit a9471e25 authored by Hertz Wong's avatar Hertz Wong Committed by Mauro Carvalho Chehab

media: hantro: Add core bits to support H264 decoding

Add helpers and patch hantro_{drv,v4l2}.c to prepare addition of H264
decoding support.
Signed-off-by: default avatarHertz Wong <hertz.wong@rock-chips.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Tested-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 6c2eb77b
...@@ -10,6 +10,7 @@ hantro-vpu-y += \ ...@@ -10,6 +10,7 @@ hantro-vpu-y += \
rk3399_vpu_hw_mpeg2_dec.o \ rk3399_vpu_hw_mpeg2_dec.o \
rk3399_vpu_hw_vp8_dec.o \ rk3399_vpu_hw_vp8_dec.o \
hantro_jpeg.o \ hantro_jpeg.o \
hantro_h264.o \
hantro_mpeg2.o \ hantro_mpeg2.o \
hantro_vp8.o hantro_vp8.o
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#define VP8_MB_WIDTH(w) DIV_ROUND_UP(w, VP8_MB_DIM) #define VP8_MB_WIDTH(w) DIV_ROUND_UP(w, VP8_MB_DIM)
#define VP8_MB_HEIGHT(h) DIV_ROUND_UP(h, VP8_MB_DIM) #define VP8_MB_HEIGHT(h) DIV_ROUND_UP(h, VP8_MB_DIM)
#define H264_MB_DIM 16
#define H264_MB_WIDTH(w) DIV_ROUND_UP(w, H264_MB_DIM)
#define H264_MB_HEIGHT(h) DIV_ROUND_UP(h, H264_MB_DIM)
#define MPEG2_MB_DIM 16 #define MPEG2_MB_DIM 16
#define MPEG2_MB_WIDTH(w) DIV_ROUND_UP(w, MPEG2_MB_DIM) #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 MPEG2_MB_HEIGHT(h) DIV_ROUND_UP(h, MPEG2_MB_DIM)
...@@ -43,9 +47,9 @@ struct hantro_codec_ops; ...@@ -43,9 +47,9 @@ struct hantro_codec_ops;
#define HANTRO_JPEG_ENCODER BIT(0) #define HANTRO_JPEG_ENCODER BIT(0)
#define HANTRO_ENCODERS 0x0000ffff #define HANTRO_ENCODERS 0x0000ffff
#define HANTRO_MPEG2_DECODER BIT(16) #define HANTRO_MPEG2_DECODER BIT(16)
#define HANTRO_VP8_DECODER BIT(17) #define HANTRO_VP8_DECODER BIT(17)
#define HANTRO_H264_DECODER BIT(18)
#define HANTRO_DECODERS 0xffff0000 #define HANTRO_DECODERS 0xffff0000
/** /**
...@@ -102,12 +106,14 @@ struct hantro_variant { ...@@ -102,12 +106,14 @@ struct hantro_variant {
* enum hantro_codec_mode - codec operating mode. * enum hantro_codec_mode - codec operating mode.
* @HANTRO_MODE_NONE: No operating mode. Used for RAW video formats. * @HANTRO_MODE_NONE: No operating mode. Used for RAW video formats.
* @HANTRO_MODE_JPEG_ENC: JPEG encoder. * @HANTRO_MODE_JPEG_ENC: JPEG encoder.
* @HANTRO_MODE_H264_DEC: H264 decoder.
* @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder. * @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder.
* @HANTRO_MODE_VP8_DEC: VP8 decoder. * @HANTRO_MODE_VP8_DEC: VP8 decoder.
*/ */
enum hantro_codec_mode { enum hantro_codec_mode {
HANTRO_MODE_NONE = -1, HANTRO_MODE_NONE = -1,
HANTRO_MODE_JPEG_ENC, HANTRO_MODE_JPEG_ENC,
HANTRO_MODE_H264_DEC,
HANTRO_MODE_MPEG2_DEC, HANTRO_MODE_MPEG2_DEC,
HANTRO_MODE_VP8_DEC, HANTRO_MODE_VP8_DEC,
}; };
...@@ -246,6 +252,7 @@ struct hantro_ctx { ...@@ -246,6 +252,7 @@ struct hantro_ctx {
/* Specific for particular codec modes. */ /* Specific for particular codec modes. */
union { union {
struct hantro_h264_dec_hw_ctx h264_dec;
struct hantro_jpeg_enc_hw_ctx jpeg_enc; struct hantro_jpeg_enc_hw_ctx jpeg_enc;
struct hantro_mpeg2_dec_hw_ctx mpeg2_dec; struct hantro_mpeg2_dec_hw_ctx mpeg2_dec;
struct hantro_vp8_dec_hw_ctx vp8_dec; struct hantro_vp8_dec_hw_ctx vp8_dec;
......
...@@ -314,6 +314,48 @@ static const struct hantro_ctrl controls[] = { ...@@ -314,6 +314,48 @@ static const struct hantro_ctrl controls[] = {
.cfg = { .cfg = {
.id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER, .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER,
}, },
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_SPS,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_PPS,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE,
.min = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
.def = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
.max = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
},
}, {
.codec = HANTRO_H264_DECODER,
.cfg = {
.id = V4L2_CID_MPEG_VIDEO_H264_START_CODE,
.min = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
.def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
.max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
},
}, {
}, },
}; };
......
This diff is collapsed.
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/v4l2-controls.h> #include <linux/v4l2-controls.h>
#include <media/h264-ctrls.h>
#include <media/mpeg2-ctrls.h> #include <media/mpeg2-ctrls.h>
#include <media/vp8-ctrls.h> #include <media/vp8-ctrls.h>
#include <media/videobuf2-core.h> #include <media/videobuf2-core.h>
...@@ -42,6 +43,54 @@ struct hantro_jpeg_enc_hw_ctx { ...@@ -42,6 +43,54 @@ struct hantro_jpeg_enc_hw_ctx {
struct hantro_aux_buf bounce_buffer; struct hantro_aux_buf bounce_buffer;
}; };
/* Max. number of entries in the DPB (HW limitation). */
#define HANTRO_H264_DPB_SIZE 16
/**
* struct hantro_h264_dec_ctrls
* @decode: Decode params
* @scaling: Scaling info
* @slice: Slice params
* @sps: SPS info
* @pps: PPS info
*/
struct hantro_h264_dec_ctrls {
const struct v4l2_ctrl_h264_decode_params *decode;
const struct v4l2_ctrl_h264_scaling_matrix *scaling;
const struct v4l2_ctrl_h264_slice_params *slices;
const struct v4l2_ctrl_h264_sps *sps;
const struct v4l2_ctrl_h264_pps *pps;
};
/**
* struct hantro_h264_dec_reflists
* @p: P reflist
* @b0: B0 reflist
* @b1: B1 reflist
*/
struct hantro_h264_dec_reflists {
u8 p[HANTRO_H264_DPB_SIZE];
u8 b0[HANTRO_H264_DPB_SIZE];
u8 b1[HANTRO_H264_DPB_SIZE];
};
/**
* struct hantro_h264_dec_hw_ctx
* @priv: Private auxiliary buffer for hardware.
* @dpb: DPB
* @reflists: P/B0/B1 reflists
* @ctrls: V4L2 controls attached to a run
* @pic_size: Size in bytes of decoded picture, this is needed
* to pass the location of motion vectors.
*/
struct hantro_h264_dec_hw_ctx {
struct hantro_aux_buf priv;
struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE];
struct hantro_h264_dec_reflists reflists;
struct hantro_h264_dec_ctrls ctrls;
size_t pic_size;
};
/** /**
* struct hantro_mpeg2_dec_hw_ctx * struct hantro_mpeg2_dec_hw_ctx
* @qtable: Quantization table * @qtable: Quantization table
...@@ -109,6 +158,12 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx); ...@@ -109,6 +158,12 @@ void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx);
int hantro_jpeg_enc_init(struct hantro_ctx *ctx); int hantro_jpeg_enc_init(struct hantro_ctx *ctx);
void hantro_jpeg_enc_exit(struct hantro_ctx *ctx); void hantro_jpeg_enc_exit(struct hantro_ctx *ctx);
struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
unsigned int dpb_idx);
int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx);
int hantro_h264_dec_init(struct hantro_ctx *ctx);
void hantro_h264_dec_exit(struct hantro_ctx *ctx);
void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx); void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx);
void hantro_mpeg2_dec_copy_qtable(u8 *qtable, void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
......
...@@ -239,6 +239,15 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f, ...@@ -239,6 +239,15 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
/* Fill remaining fields */ /* Fill remaining fields */
v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width, v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
pix_mp->height); pix_mp->height);
/*
* The H264 decoder needs extra space on the output buffers
* to store motion vectors. This is needed for reference
* frames.
*/
if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
pix_mp->plane_fmt[0].sizeimage +=
128 * DIV_ROUND_UP(pix_mp->width, 16) *
DIV_ROUND_UP(pix_mp->height, 16);
} else if (!pix_mp->plane_fmt[0].sizeimage) { } else if (!pix_mp->plane_fmt[0].sizeimage) {
/* /*
* For coded formats the application can specify * For coded formats the application can specify
...@@ -345,6 +354,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc) ...@@ -345,6 +354,7 @@ hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
break; break;
case V4L2_PIX_FMT_MPEG2_SLICE: case V4L2_PIX_FMT_MPEG2_SLICE:
case V4L2_PIX_FMT_VP8_FRAME: case V4L2_PIX_FMT_VP8_FRAME:
case V4L2_PIX_FMT_H264_SLICE:
ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true; ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
break; break;
default: default:
......
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