@@ -2,7 +2,7 @@
rk-mpp-service-objs := mpp_service.o
rk-mpp-device-objs := mpp_dev_common.o
rk-mpp-vdec-objs := mpp_dev_rkvdec.o
-rk-mpp-vdec-objs += rkvdec/avc.o
+rk-mpp-vdec-objs += rkvdec/avc.o rkvdec/avc-data.o
rk-mpp-vdec-objs += rkvdec/hevc.o rkvdec/hevc-data.o rkvdec/rbsp.o
rk-mpp-vdpu2-objs := mpp_dev_vdpu2.o vdpu2/mpeg2.o
@@ -284,13 +284,15 @@ static int rkvdec_s_fmt_vid_cap_mplane(struct file *filp, void *priv,
pix_mp->plane_fmt[1].bytesperline * ALIGN(pix_mp->height,
8);
#else
- /* TODO: HEVC only request the height is aligned with 8 */
+ /*
+ * TODO: H.264 would use 16 alignment while the resolution is under HD,
+ * HEVC only request the height is aligned with 8
+ */
pix_mp->plane_fmt[0].sizeimage =
pix_mp->plane_fmt[0].bytesperline * ALIGN(pix_mp->height,
- 16);
+ 8);
/* Additional space for motion vector */
pix_mp->plane_fmt[0].sizeimage *= 2;
- pix_mp->plane_fmt[0].sizeimage += SZ_4M;
pix_mp->plane_fmt[1].sizeimage = SZ_2M;
#endif
pix_mp->num_planes = 2;
new file mode 100644
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "avc-data.h"
+
+static const u32 zig_zag_4x4[16] = {
+ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
+};
+
+static const u32 zig_zag_8x8[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
+};
+
+static void fill_is_long_term(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ u16 is_long_term = 0;
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ if (decode_param->dpb[i].
+ flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+ is_long_term |= (1 << i);
+
+ rbsp_write_bits(rbsp, 16, is_long_term);
+}
+
+/* in zig-zag order */
+void rkvdec_avc_update_scaling_list(u8 * buf, const struct
+ v4l2_ctrl_h264_scaling_matrix
+ *scaling)
+{
+ u8 i, j;
+
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 16; j++)
+ buf[zig_zag_4x4[j] + (i << 4)] =
+ scaling->scaling_list_4x4[i][j];
+
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 64; j++)
+ buf[zig_zag_8x8[j] + (i << 6)] =
+ scaling->scaling_list_8x8[i][j];
+}
+
+int rkvdec_avc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps)
+{
+ /* TODO: seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ rbsp_write_bits(rbsp, 8, sps->profile_idc);
+ /* constraint_set3_flag */
+ rbsp_write_flag(rbsp, sps->constraint_set_flags >> 3);
+ rbsp_write_bits(rbsp, 2, sps->chroma_format_idc);
+ /* bit_depth_luma Not used */
+ rbsp_write_bits(rbsp, 3, sps->bit_depth_luma_minus8);
+ /* bit_depth_chroma Not used */
+ rbsp_write_bits(rbsp, 3, sps->bit_depth_chroma_minus8);
+ /* TODO: qpprime_y_zero_transform_bypass_flag */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, sps->log2_max_frame_num_minus4);
+ rbsp_write_bits(rbsp, 5, sps->max_num_ref_frames);
+ rbsp_write_bits(rbsp, 2, sps->pic_order_cnt_type);
+ rbsp_write_bits(rbsp, 4, sps->log2_max_pic_order_cnt_lsb_minus4);
+ /* delta_pic_order_always_zero_flag */
+ rbsp_write_flag(rbsp,
+ sps->flags &
+ V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+ rbsp_write_bits(rbsp, 9, sps->pic_width_in_mbs_minus1 + 1);
+ /* TODO: check whether it work for field coding */
+ rbsp_write_bits(rbsp, 9, sps->pic_height_in_map_units_minus1 + 1);
+ rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+ rbsp_write_flag(rbsp, sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+ rbsp_write_flag(rbsp,
+ sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+
+ /* TODO: mvc */
+ rbsp_write_flag(rbsp, 0);
+ /* num_views_minus1 */
+ rbsp_write_bits(rbsp, 2, 0);
+ /* view_id[0] */
+ rbsp_write_bits(rbsp, 10, 0);
+ /* view_id[1] */
+ rbsp_write_bits(rbsp, 10, 0);
+ /* num_anchor_refs_l0 */
+ rbsp_write_flag(rbsp, 0);
+ /* anchor_ref_l0 */
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ /* num_non_anchor_refs_l0 */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 10, 0);
+ /* Align with 128 bit */
+ rbsp_write_bits(rbsp, 2, 0);
+
+ return 0;
+}
+
+int rkvdec_avc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_pps *pps)
+{
+ /* TODO: pps_pic_parameter_set_id */
+ rbsp_write_bits(rbsp, 8, 0);
+ rbsp_write_bits(rbsp, 5, 0);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+ rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l0_default_active_minus1);
+ rbsp_write_bits(rbsp, 5, pps->num_ref_idx_l1_default_active_minus1);
+ rbsp_write_flag(rbsp, pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+ rbsp_write_bits(rbsp, 2, pps->weighted_bipred_idc);
+ rbsp_write_bits(rbsp, 7, pps->pic_init_qp_minus26);
+ rbsp_write_bits(rbsp, 6, pps->pic_init_qs_minus26);
+ rbsp_write_bits(rbsp, 5, pps->chroma_qp_index_offset);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+ rbsp_write_flag(rbsp,
+ pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+ rbsp_write_bits(rbsp, 5, pps->second_chroma_qp_index_offset);
+ rbsp_write_flag(rbsp,
+ pps->flags &
+ V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT);
+
+ return 0;
+}
+
+int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ /* scaling list buffer */
+ rbsp_write_bits(rbsp, 32, scaling_addr);
+
+ /* DPB */
+ fill_is_long_term(rbsp, decode_param);
+
+ /* TODO: VOIdx, Layer id */
+ rbsp_write_bits(rbsp, 16, 0);
+
+ /* Align with 128 bit */
+ rbsp_write_bits(rbsp, 8, 0);
+
+ return 0;
+}
+
+static inline void fill_rps_list(struct rbsp *rbsp, const struct v4l2_ctrl_h264_decode_param
+ *decode_param, const u8 * list)
+{
+ u8 i;
+
+ for (i = 0; i < 32; i++) {
+ u8 idx, active_flag;
+
+ idx = list[i];
+
+ active_flag = decode_param->dpb[idx].flags &
+ V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+ if (!active_flag) {
+ rbsp_write_bits(rbsp, 7, 0);
+ } else {
+ rbsp_write_bits(rbsp, 5, idx | BIT(5));
+ /* TODO: bottom flag */
+ rbsp_write_flag(rbsp, 0);
+ /* TODO: view id */
+ rbsp_write_flag(rbsp, 0);
+ }
+ }
+}
+
+int rkvdec_avc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_slice_param *slice_param,
+ const struct v4l2_ctrl_h264_decode_param *decode_param)
+{
+ int max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
+ u8 i;
+
+ for (i = 0; i < 16; i++) {
+ u16 frame_num = decode_param->dpb[i].frame_num;
+
+ rbsp_write_bits(rbsp, 16, frame_num > max_frame_num ?
+ frame_num - max_frame_num : frame_num);
+ }
+
+ /* reserved */
+ rbsp_write_bits(rbsp, 16, 0);
+ /* TODO: VoidX */
+ rbsp_write_bits(rbsp, 16, 0);
+
+ switch (slice_param->slice_type) {
+ case V4L2_H264_SLICE_TYPE_P:
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0);
+ for (i = 0; i < 14; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ break;
+ case V4L2_H264_SLICE_TYPE_B:
+ for (i = 0; i < 7; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list0);
+ fill_rps_list(rbsp, decode_param, slice_param->ref_pic_list1);
+ break;
+ case V4L2_H264_SLICE_TYPE_I:
+ /* TODO: SVC */
+ default:
+ for (i = 0; i < 21; i++)
+ rbsp_write_bits(rbsp, 32, 0);
+ break;
+ }
+
+ rbsp_write_bits(rbsp, 32, 0);
+ rbsp_write_bits(rbsp, 32, 0);
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+
+#include "rbsp.h"
+
+void rkvdec_avc_update_scaling_list(u8 * buf, const struct
+ v4l2_ctrl_h264_scaling_matrix
+ *scaling);
+
+int rkvdec_avc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps);
+
+int rkvdec_avc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_pps *pps);
+
+int rkvdec_avc_write_pps_tail(struct rbsp *rbsp, dma_addr_t scaling_addr,
+ const struct v4l2_ctrl_h264_decode_param *decode_param);
+
+int rkvdec_avc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_slice_param *slice_param,
+ const struct v4l2_ctrl_h264_decode_param
+ *decode_param);
@@ -24,6 +24,56 @@
#include "mpp_dev_common.h"
#include "hal.h"
#include "regs.h"
+#include "avc-data.h"
+
+static void generate_input_data(struct rkvdec_regs *p_regs,
+ struct vb2_v4l2_buffer *src_buf,
+ const struct v4l2_ctrl_h264_sps *sps,
+ const struct v4l2_ctrl_h264_pps *pps,
+ const struct v4l2_ctrl_h264_scaling_matrix
+ *scaling, const struct v4l2_ctrl_h264_slice_param
+ *slice_param, const struct v4l2_ctrl_h264_decode_param
+ *decode_param)
+{
+ struct rbsp rbsp = { 0, };
+ size_t r_scaling_offs, r_sps_offs, r_rps_offs;
+ size_t stream_len = 0;
+ dma_addr_t scaling_addr = 0;
+ void *r_data = NULL;
+ int i;
+
+ stream_len = slice_param->size + 64;
+
+ r_data = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
+ r_scaling_offs = ALIGN(stream_len, 16);
+ r_data += r_scaling_offs;
+
+ if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) {
+ rkvdec_avc_update_scaling_list(r_data, scaling);
+ r_sps_offs = r_scaling_offs + 6 * 16 + 2 * 64 + 128;
+ r_sps_offs = ALIGN(r_sps_offs, 16);
+ scaling_addr = p_regs->sw_strm_rlc_base + r_scaling_offs;
+ } else {
+ r_sps_offs = r_scaling_offs;
+ scaling_addr = 0;
+ }
+
+ rbsp_init(&rbsp, r_data + r_sps_offs, SZ_2M - r_sps_offs, 0);
+ rkvdec_avc_write_sps(&rbsp, sps);
+ rkvdec_avc_write_pps(&rbsp, pps);
+ rkvdec_avc_write_pps_tail(&rbsp, scaling_addr, decode_param);
+ p_regs->sw_pps_base = p_regs->sw_strm_rlc_base + r_sps_offs;
+
+ for (i = 1; i < 256; i++)
+ memset(r_data + r_sps_offs + i * 32, 0, 32);
+
+ /* 256 bits */
+ r_rps_offs = r_sps_offs + 32 * 256 + 128;
+ r_rps_offs = ALIGN(r_rps_offs, 16);
+ rbsp_init(&rbsp, r_data + r_rps_offs, SZ_2M - r_rps_offs, 0);
+ rkvdec_avc_write_rps(&rbsp, sps, slice_param, decode_param);
+ p_regs->sw_rps_base = p_regs->sw_strm_rlc_base + r_rps_offs;
+}
static void init_hw_cfg(struct rkvdec_regs *p_regs)
{
@@ -152,18 +202,23 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs,
{
const struct v4l2_ctrl_h264_sps *sps;
const struct v4l2_ctrl_h264_pps *pps;
+ const struct v4l2_ctrl_h264_scaling_matrix *scaling;
const struct v4l2_ctrl_h264_slice_param *slice_param;
const struct v4l2_ctrl_h264_decode_param *decode_param;
struct vb2_v4l2_buffer *dst_buf;
struct rkvdec_regs *p_regs = regs;
- size_t stream_len = 0;
sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS);
pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS);
- slice_param = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
- decode_param = rockchip_mpp_get_cur_ctrl(session,
- V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
+ scaling =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ slice_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ decode_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
if (!sps || !pps || !slice_param || !decode_param)
return -EINVAL;
@@ -178,12 +233,14 @@ int rkvdec_avc_gen_reg(struct mpp_session *session, void *regs,
p_regs->sw_sysctrl.strm_start_bit = slice_param->header_bit_size;
/* hardware wants a zerod memory at the stream end */
- stream_len = slice_param->size + 64;
- p_regs->sw_stream_len = stream_len;
+ p_regs->sw_stream_len = slice_param->size + 64;
dst_buf = v4l2_m2m_next_dst_buf(session->fh.m2m_ctx);
rkvdec_avc_gen_ref(p_regs, dst_buf, decode_param);
+ generate_input_data(p_regs, src_buf, sps, pps, scaling, slice_param,
+ decode_param);
+
return 0;
}
new file mode 100644
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Randy Li, <ayaka@soulik.info>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "mpp_dev_common.h"
+#include "hal.h"
+#include "regs.h"
+
+#define DEC_LITTLE_ENDIAN (1)
+
+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
+};
+
+static const u8 intra_default_q_matrix[64] = {
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+static void init_hw_cfg(struct vdpu2_regs *p_regs)
+{
+ p_regs->sw54.dec_strm_wordsp = 1;
+ p_regs->sw54.dec_strendian_e = DEC_LITTLE_ENDIAN;
+ p_regs->sw54.dec_in_wordsp = 1;
+ p_regs->sw54.dec_out_wordsp = 1;
+ p_regs->sw54.dec_in_endian = DEC_LITTLE_ENDIAN; //change
+ p_regs->sw54.dec_out_endian = DEC_LITTLE_ENDIAN;
+ p_regs->sw57.dec_timeout = 1;
+ p_regs->sw57.dec_timeout_e = 1;
+
+ p_regs->sw57.dec_clk_gate_e = 1;
+ p_regs->sw57.pref_sigchan = 1;
+ p_regs->sw57.bus_pos_sel = 1;
+ p_regs->sw57.intra_dbl3t = 1;
+ p_regs->sw57.inter_dblspeed = 1;
+ p_regs->sw57.intra_dblspeed = 1;
+
+ p_regs->sw50.tiled_mode_msb = 0;
+ p_regs->sw56.dec_max_burst = 16;
+ p_regs->sw50.dec_scmd_dis = 0;
+ p_regs->sw50.dec_adv_pre_dis = 0;
+ p_regs->sw52.apf_threshold = 8;
+
+ p_regs->sw50.dec_latency = 0;
+ p_regs->sw56.dec_data_disc_e = 0;
+
+ p_regs->sw55.dec_irq = 0;
+ p_regs->sw56.dec_axi_rd_id = 0;
+ p_regs->sw56.dec_axi_wr_id = 0;
+
+ p_reg->sw59.pred_bc_tap_0_0 = 1;
+ /* -5 */
+ p_reg->sw59.pred_bc_tap_0_1 = 0x3fb;
+ p_reg->sw59.pred_bc_tap_0_2 = 20;
+
+ p_regs->sw53.dec_mode = RKVDPU2_FMT_H264D;
+}
+
+int rkvdpu_mpeg2_gen_reg(struct mpp_session *session, void *regs,
+ struct vb2_v4l2_buffer *src_buf)
+{
+ const struct v4l2_ctrl_h264_sps *sps;
+ const struct v4l2_ctrl_h264_pps *pps;
+ const struct v4l2_ctrl_h264_scaling_matrix *scaling;
+ const struct v4l2_ctrl_h264_slice_param *slice_param;
+ const struct v4l2_ctrl_h264_decode_param *decode_param;
+ struct vb2_v4l2_buffer *dst_buf;
+ struct rkvdec_regs *p_regs = regs;
+
+ sps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_SPS);
+ pps = rockchip_mpp_get_cur_ctrl(session, V4L2_CID_MPEG_VIDEO_H264_PPS);
+ scaling =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ slice_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+ decode_param =
+ rockchip_mpp_get_cur_ctrl(session,
+ V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
+
+ if (!sps || !pps || !slice_param || !decode_param)
+ return -EINVAL;
+
+ init_hw_cfg(p_regs);
+
+ p_regs->sw120.pic_mb_width = sps->pic_width_in_mbs_minus1 + 1;
+ p_regs->sw120.pic_mb_height_p = sps->pic_height_in_map_units_minus1 + 1;
+
+#if 0
+ /* PICT_FRAME */
+ if (picture->picture_structure == 3) {
+ p_regs->sw57.pic_fieldmode_e = 0;
+ } else {
+ p_regs->sw57.pic_fieldmode_e = 1;
+ /* PICT_TOP_FIEL */
+ if (picture->picture_structure == 1)
+ p_regs->sw57.pic_topfield_e = 1;
+ }
+#endif
+ p_regs->sw51.qp_init = pps->pic_init_qp_minus26 + 26;
+ p_regs->sw114.max_refidx0 = slice_params->num_ref_idx_l0_active_minus1 + 1;
+ p_regs->sw111.max_refnum = sps->num_ref_frames;
+
+ p_regs->sw115.const_intra_en = pps->constrained_intra_pred_flag;
+
+#if 0
+ p_regs->sw112.dblk_ctrl_flag = pp->deblocking_filter_control_present_flag;
+ p_regs->sw112.rpcp_flag = pp->redundant_pic_cnt_present_flag;
+ p_regs->sw113.refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen;
+ p_regs->sw115.idr_pic_flag = p_hal->slice_long[0].idr_flag;
+ p_regs->sw113.idr_pic_id = p_hal->slice_long[0].idr_pic_id;
+ p_regs->sw114.pps_id = p_hal->slice_long[0].active_pps_id;
+ p_regs->sw114.poc_field_len = p_hal->slice_long[0].poc_used_bitlen;
+#endif
+
+ p_regs->sw52.startmb_x = 0;
+ p_regs->sw52.startmb_y = 0;
+ p_regs->sw57.dec_out_dis = 0;
+ p_regs->sw50.filtering_dis = 1;
+
+ p_regs->sw64.rlc_vlc_base =
+ vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+ p_regs->sw122.strm_start_bit = params->data_bit_offset;
+ stream_len = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
+ p_regs->sw51.stream_len = stream_len;
+
+ qtable = vb2_plane_vaddr(&src_buf->vb2_buf, 0) + ALIGN(stream_len, 8);
+ p_regs->sw61.qtable_base = p_regs->sw64.rlc_vlc_base
+ + ALIGN(stream_len, 8);
+
+ return 0;
+}