@@ -1,7 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
rk-mpp-service-objs := mpp_service.o
rk-mpp-device-objs := mpp_dev_common.o
-rk-mpp-vdec-objs := mpp_dev_rkvdec.o rkvdec/hevc.o rkvdec/avc.o
+rk-mpp-vdec-objs := mpp_dev_rkvdec.o
+rk-mpp-vdec-objs += rkvdec/avc.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
obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += rk-mpp-service.o
new file mode 100644
@@ -0,0 +1,208 @@
+// 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 "hevc-data.h"
+
+/* 7.3.2.2.1 General sequence parameter set RBSP syntax */
+int rkvdec_hevc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps)
+{
+ /* TODO: sps_video_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* TODO: sps_seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* chroma_format_idc */
+ rbsp_write_bits(rbsp, 2, sps->chroma_format_idc);
+ rbsp_write_bits(rbsp, 13, sps->pic_width_in_luma_samples);
+ rbsp_write_bits(rbsp, 13, sps->pic_height_in_luma_samples);
+ /* bit_depth_luma */
+ rbsp_write_bits(rbsp, 4, sps->bit_depth_luma_minus8 + 8);
+ rbsp_write_bits(rbsp, 4, sps->bit_depth_chroma_minus8 + 8);
+ /* log2_max_pic_order_cnt_lsb */
+ rbsp_write_bits(rbsp, 5, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+ /* FIXME it is 3 bits in document */
+ rbsp_write_bits(rbsp, 2, sps->log2_diff_max_min_luma_coding_block_size);
+ /* log2_min_luma_coding_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_luma_coding_block_size_minus3 + 3);
+ /* log2_min_transform_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_luma_transform_block_size_minus2 + 2);
+ rbsp_write_bits(rbsp, 2,
+ sps->log2_diff_max_min_luma_transform_block_size);
+ rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_inter);
+ rbsp_write_bits(rbsp, 3, sps->max_transform_hierarchy_depth_intra);
+
+ rbsp_write_flag(rbsp, sps->scaling_list_enabled_flag);
+ rbsp_write_flag(rbsp, sps->amp_enabled_flag);
+ rbsp_write_flag(rbsp, sps->sample_adaptive_offset_enabled_flag);
+ rbsp_write_flag(rbsp, sps->pcm_enabled_flag);
+
+ /* pcm_sample_bit_depth_luma */
+ rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_luma_minus1 + 1);
+ /* pcm_sample_bit_depth_chroma */
+ rbsp_write_bits(rbsp, 4, sps->pcm_sample_bit_depth_chroma_minus1 + 1);
+ rbsp_write_flag(rbsp, sps->pcm_loop_filter_disabled_flag);
+
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_diff_max_min_pcm_luma_coding_block_size);
+ /* log2_min_pcm_luma_coding_block_size */
+ rbsp_write_bits(rbsp, 3,
+ sps->log2_min_pcm_luma_coding_block_size_minus3 + 3);
+ rbsp_write_bits(rbsp, 7, sps->num_short_term_ref_pic_sets);
+ rbsp_write_flag(rbsp, sps->long_term_ref_pics_present_flag);
+ rbsp_write_bits(rbsp, 6, sps->num_long_term_ref_pics_sps);
+ rbsp_write_flag(rbsp, sps->sps_temporal_mvp_enabled_flag);
+ rbsp_write_flag(rbsp, sps->strong_intra_smoothing_enabled_flag);
+ /* Above is 100 bits total */
+#if 0
+ /* transform_skip_rotation_enabled_flag to intra_smoothing_disabled_flag */
+ rbsp_write_bits(rbsp, 7, 0);
+ /* sps_max_dec_pic_buffering_minus1 */
+ rbsp_write_bits(rbsp, 4, sps->sps_max_dec_pic_buffering_minus1);
+ rbsp_write_flag(rbsp, sps->separate_colour_plane_flag);
+ /* TODO: high_precision_offsets_enabled */
+ rbsp_write_flag(rbsp, 0);
+ /* TODO: persistent_rice_adaptation_enabled_flag */
+ rbsp_write_flag(rbsp, 0);
+ /* reserved */
+ rbsp_write_bits(rbsp, 14, 0xffffffff);
+#else
+ rbsp_write_bits(rbsp, 7, 0);
+ /* padding */
+ rbsp_write_bits(rbsp, 21, 0xffffffff);
+#endif
+
+ return 0;
+}
+
+int rkvdec_hevc_write_pps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps,
+ const struct v4l2_ctrl_hevc_pps *pps,
+ const struct v4l2_ctrl_hevc_slice_params *slice_params)
+{
+
+ u32 min_cb_log2_size_y, ctb_log2_size_y, log2_min_cu_qp_delta_size;
+ u16 column_width[20] = { 0, };
+ u16 row_height[22] = { 0, };
+ u8 i;
+
+ min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3;
+ ctb_log2_size_y = min_cb_log2_size_y +
+ sps->log2_diff_max_min_luma_coding_block_size;
+
+ log2_min_cu_qp_delta_size = ctb_log2_size_y - pps->diff_cu_qp_delta_depth;
+
+ /* pps_pic_parameter_set_id */
+ rbsp_write_bits(rbsp, 6, 0);
+ /* pps_seq_parameter_set_id */
+ rbsp_write_bits(rbsp, 4, 0);
+ /* dependent_slice_segments_enabled_flag */
+ rbsp_write_flag(rbsp, pps->dependent_slice_segment_flag);
+ rbsp_write_flag(rbsp, pps->output_flag_present_flag);
+ /* FIXME it is 3 bits in document */
+ rbsp_write_bits(rbsp, 13, pps->num_extra_slice_header_bits);
+ /* sign_data_hiding_flag */
+ rbsp_write_flag(rbsp, pps->sign_data_hiding_enabled_flag);
+ rbsp_write_flag(rbsp, pps->cabac_init_present_flag);
+ /* FIXME: from slice params ? */
+ rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l0_active_minus1 + 1);
+ rbsp_write_bits(rbsp, 4, slice_params->num_ref_idx_l1_active_minus1 + 1);
+ /* FIXME it is 6 bits in document init_qp_minus26 */
+ rbsp_write_bits(rbsp, 7, pps->init_qp_minus26);
+ rbsp_write_flag(rbsp, pps->constrained_intra_pred_flag);
+ rbsp_write_flag(rbsp, pps->transform_skip_enabled_flag);
+ rbsp_write_flag(rbsp, pps->cu_qp_delta_enabled_flag);
+ /* Log2MinCuQpDeltaSize */
+ rbsp_write_bits(rbsp, 3, log2_min_cu_qp_delta_size);
+ rbsp_write_bits(rbsp, 5, pps->pps_cb_qp_offset);
+ rbsp_write_bits(rbsp, 5, pps->pps_cr_qp_offset);
+ rbsp_write_flag(rbsp, pps->pps_slice_chroma_qp_offsets_present_flag);
+ rbsp_write_flag(rbsp, pps->weighted_pred_flag);
+ rbsp_write_flag(rbsp, pps->weighted_bipred_flag);
+ rbsp_write_flag(rbsp, pps->transquant_bypass_enabled_flag);
+ rbsp_write_flag(rbsp, pps->tiles_enabled_flag);
+ rbsp_write_flag(rbsp, pps->entropy_coding_sync_enabled_flag);
+ rbsp_write_flag(rbsp, pps->pps_loop_filter_across_slices_enabled_flag);
+ rbsp_write_flag(rbsp, pps->loop_filter_across_tiles_enabled_flag);
+ rbsp_write_flag(rbsp, pps->deblocking_filter_override_enabled_flag);
+ /* pps_deblocking_filter_disabled_flag */
+ rbsp_write_flag(rbsp, pps->pps_disable_deblocking_filter_flag);
+ rbsp_write_bits(rbsp, 4, pps->pps_beta_offset_div2);
+ rbsp_write_bits(rbsp, 4, pps->pps_tc_offset_div2);
+ rbsp_write_flag(rbsp, pps->lists_modification_present_flag);
+ rbsp_write_bits(rbsp, 3, pps->log2_parallel_merge_level_minus2 + 2);
+ rbsp_write_flag(rbsp, pps->slice_segment_header_extension_present_flag);
+ /* reserved, log2_transform_skip_max_size_minus2 */
+ rbsp_write_bits(rbsp, 3, 0);
+ /* num_tile_columns */
+ rbsp_write_bits(rbsp, 5, pps->num_tile_columns_minus1 + 1);
+ /* num_tile_rows */
+ rbsp_write_bits(rbsp, 5, pps->num_tile_rows_minus1 + 1);
+ /* ? */
+ rbsp_write_bits(rbsp, 3, 2);
+ /* align 30 ? */
+ rbsp_write_bits(rbsp, 32, 0xffffffff);
+
+ /* TODO: support tile video */
+ column_width[0] = 0;
+ row_height[0] = 0;
+
+ for (i = 0; i < 20; i++) {
+ if (column_width[i])
+ column_width[i]--;
+ rbsp_write_bits(rbsp, column_width[i], 8);
+ }
+ for (i = 0; i < 22; i++) {
+ if (row_height[i])
+ row_height[i]--;
+ rbsp_write_bits(rbsp, row_height[i], 8);
+ }
+
+ /* TODO: scaleing_address */
+
+ return 0;
+}
+
+int rkvdec_hevc_write_soft_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_slice_params *slice_params)
+{
+ int i;
+
+ for (i = 0; i < 15; i++) {
+ /* FIXME: is long term */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l0[i]);
+ }
+
+ for (i = 0; i < 15; i++) {
+ /* FIXME: is long term */
+ rbsp_write_flag(rbsp, 0);
+ rbsp_write_bits(rbsp, 4, slice_params->ref_idx_l1[i]);
+ }
+ /* TODO: lowdelay_flag */
+ rbsp_write_flag(rbsp, 1);
+
+ /* TODO: Rps_bit_offset_include_lt */
+ rbsp_write_bits(rbsp, 10, 0);
+ rbsp_write_bits(rbsp, 9, 0);
+}
+
+/* 7.3.7 Short-term reference picture set syntax */
+int rkvdec_hevc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_pps *pps)
+{
+
+}
new file mode 100644
@@ -0,0 +1,27 @@
+// 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"
+
+int rkvdec_hevc_write_sps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_sps *sps);
+
+int rkvdec_hevc_write_rps(struct rbsp *rbsp,
+ const struct v4l2_ctrl_hevc_pps *pps);
@@ -25,6 +25,8 @@
#include "hal.h"
#include "regs.h"
+#include "hevc-data.h"
+
static void init_hw_cfg(struct rkvdec_regs *p_regs)
{
p_regs->sw_interrupt.dec_e = 1;