From cdadaa9bba830b097543a2e553b37789142115bf Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Wed, 16 Oct 2019 15:44:33 +0800 Subject: [PATCH] [h264e_pps]: Add h264e pps function NOTE: Add scaling list mode flag to rk_venc_cmd.h Change-Id: Idd3b33c577ce5ffd79dabc850f7c98a98c1ac19a Signed-off-by: Herman Chen --- inc/rk_venc_cmd.h | 7 ++ mpp/codec/enc/h264/CMakeLists.txt | 1 + mpp/codec/enc/h264/h264e_pps.c | 196 ++++++++++++++++++++++++++++++ mpp/codec/enc/h264/h264e_pps.h | 37 ++++++ mpp/common/h264_syntax.h | 12 ++ mpp/common/h264e_syntax.h | 3 +- 6 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 mpp/codec/enc/h264/h264e_pps.c create mode 100644 mpp/codec/enc/h264/h264e_pps.h diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index bf11b5a4..f04cd0d0 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -601,6 +601,13 @@ typedef struct MppEncH264Cfg_t { */ RK_S32 constrained_intra_pred_mode; + /* + * 0 : flat scaling list + * 1 : default scaling list for all cases + * 2 : customized scaling list (not supported) + */ + RK_S32 scaling_list_mode; + /* * chroma qp offset (-12 - 12) */ diff --git a/mpp/codec/enc/h264/CMakeLists.txt b/mpp/codec/enc/h264/CMakeLists.txt index 7822cc20..a74f68a6 100644 --- a/mpp/codec/enc/h264/CMakeLists.txt +++ b/mpp/codec/enc/h264/CMakeLists.txt @@ -15,6 +15,7 @@ set(H264E_HDR # h264 encoder sourse set(H264E_SRC h264e_sps.c + h264e_pps.c h264e_api.c ) diff --git a/mpp/codec/enc/h264/h264e_pps.c b/mpp/codec/enc/h264/h264e_pps.c new file mode 100644 index 00000000..3a6db10b --- /dev/null +++ b/mpp/codec/enc/h264/h264e_pps.c @@ -0,0 +1,196 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "h264e_sps" + +#include "mpp_common.h" + +#include "mpp_bitwrite.h" +#include "h264e_pps.h" + +static void write_scaling_list(MppWriteCtx *bit, RK_S32 mode) +{ + switch (mode) { + case 0 : { + // flat scaling matrix + /* scaling_list_present_flag */ + mpp_writer_put_bits(bit, 0, 1); + } break; + case 1 : { + /* scaling_list_present_flag */ + mpp_writer_put_bits(bit, 1, 1); + /* delta_scale */ + mpp_writer_put_se(bit, -8); + } break; + default : { + mpp_err_f("unsupport scaling list mode %d\n", mode); + } break; + } +} + +MPP_RET h264e_pps_update(SynH264ePps *pps, MppEncCfgSet *cfg) +{ + MppEncH264Cfg *codec = &cfg->codec.h264; + + pps->pps_id = 0; + pps->sps_id = 0; + + pps->entropy_coding_mode = codec->entropy_coding_mode; + pps->bottom_field_pic_order_in_frame_present = 0; + pps->num_slice_groups = 1; + + pps->num_ref_idx_l0_default_active = 1; + pps->num_ref_idx_l1_default_active = 1; + + pps->weighted_pred = 0; + pps->weighted_bipred_idc = 0; + + pps->pic_init_qp = 26; + pps->pic_init_qs = pps->pic_init_qp; + + pps->chroma_qp_index_offset = codec->chroma_cb_qp_offset; + pps->deblocking_filter_control = 1; + pps->constrained_intra_pred = codec->constrained_intra_pred_mode; + pps->redundant_pic_cnt = 0; + + // if (more_rbsp_data()) + pps->transform_8x8_mode = codec->transform8x8_mode; + mpp_assert(codec->scaling_list_mode == 0 || codec->scaling_list_mode == 1); + pps->pic_scaling_matrix_present = codec->scaling_list_mode; + if (codec->scaling_list_mode) { + /* NOTE: H.264 current encoder do NOT split detail matrix case */ + pps->use_default_scaling_matrix[H264_INTRA_4x4_Y] = 1; + pps->use_default_scaling_matrix[H264_INTRA_4x4_U] = 1; + pps->use_default_scaling_matrix[H264_INTRA_4x4_V] = 1; + pps->use_default_scaling_matrix[H264_INTER_4x4_Y] = 1; + pps->use_default_scaling_matrix[H264_INTER_4x4_U] = 1; + pps->use_default_scaling_matrix[H264_INTER_4x4_V] = 1; + pps->use_default_scaling_matrix[H264_INTRA_8x8_Y] = 1; + pps->use_default_scaling_matrix[H264_INTER_8x8_Y] = 1; + } + pps->second_chroma_qp_index_offset = codec->chroma_cr_qp_offset; + + if (codec->profile < H264_PROFILE_HIGH) { + if (pps->transform_8x8_mode) { + pps->transform_8x8_mode = 0; + mpp_log_f("warning: for profile %d transform_8x8_mode should be 0\n", + codec->profile); + } + if (pps->second_chroma_qp_index_offset) { + pps->second_chroma_qp_index_offset = 0; + mpp_log_f("warning: for profile %d second_chroma_qp_index_offset should be 0\n", + codec->profile); + } + } + if (codec->profile == H264_PROFILE_BASELINE && pps->entropy_coding_mode) { + mpp_log_f("warning: for baseline profile entropy_coding_mode should be 0\n"); + pps->entropy_coding_mode = 0; + } + + return MPP_OK; +} + +MPP_RET h264e_pps_to_packet(SynH264ePps *pps, MppPacket packet) +{ + void *pos = mpp_packet_get_pos(packet); + void *data = mpp_packet_get_data(packet); + size_t size = mpp_packet_get_size(packet); + size_t length = mpp_packet_get_length(packet); + void *p = pos + length; + RK_S32 buf_size = (data + size) - (pos + length); + MppWriteCtx bit_ctx; + MppWriteCtx *bit = &bit_ctx; + RK_S32 pps_size = 0; + + mpp_writer_init(bit, p, buf_size); + + /* start_code_prefix 00 00 00 01 */ + mpp_writer_put_raw_bits(bit, 0, 24); + mpp_writer_put_raw_bits(bit, 1, 8); + /* forbidden_zero_bit */ + mpp_writer_put_raw_bits(bit, 0, 1); + /* nal_ref_idc */ + mpp_writer_put_raw_bits(bit, H264_NALU_PRIORITY_HIGHEST, 2); + /* nal_unit_type */ + mpp_writer_put_raw_bits(bit, H264_NALU_TYPE_PPS, 5); + + /* pic_parameter_set_id */ + mpp_writer_put_ue(bit, pps->pps_id); + /* seq_parameter_set_id */ + mpp_writer_put_ue(bit, pps->sps_id); + /* entropy_coding_mode_flag */ + mpp_writer_put_bits(bit, pps->entropy_coding_mode, 1); + /* bottom_field_pic_order_in_frame_present */ + mpp_writer_put_bits(bit, pps->bottom_field_pic_order_in_frame_present, 1); + /* num_slice_groups_minus1 */ + mpp_writer_put_ue(bit, pps->num_slice_groups - 1); + /* num_ref_idx_l0_active_minus1 */ + mpp_writer_put_ue(bit, pps->num_ref_idx_l0_default_active - 1); + /* num_ref_idx_l1_active_minus1 */ + mpp_writer_put_ue(bit, pps->num_ref_idx_l1_default_active - 1); + /* weighted_pred_flag */ + mpp_writer_put_bits(bit, pps->weighted_pred, 1); + /* weighted_bipred_idc */ + mpp_writer_put_bits(bit, pps->weighted_bipred_idc, 2); + /* pic_init_qp_minus26 */ + mpp_writer_put_se(bit, pps->pic_init_qp - 26); + /* pic_init_qs_minus26 */ + mpp_writer_put_se(bit, pps->pic_init_qs - 26); + /* chroma_qp_index_offset */ + mpp_writer_put_se(bit, pps->chroma_qp_index_offset); + /* deblocking_filter_control_present_flag */ + mpp_writer_put_bits(bit, pps->deblocking_filter_control, 1); + /* constrained_intra_pred_flag */ + mpp_writer_put_bits(bit, pps->constrained_intra_pred, 1); + /* redundant_pic_cnt_present_flag */ + mpp_writer_put_bits(bit, pps->redundant_pic_cnt, 1); + + if (pps->transform_8x8_mode || + pps->second_chroma_qp_index_offset || + pps->pic_scaling_matrix_present) { + /* transform_8x8_mode_flag */ + mpp_writer_put_bits(bit, pps->transform_8x8_mode, 1); + + /* pic_scaling_matrix_present_flag */ + mpp_writer_put_bits(bit, pps->pic_scaling_matrix_present, 1); + if (pps->pic_scaling_matrix_present) { + /* Only support default scaling list */ + /* pic_scaling_list_present_flag[i] */ + RK_S32 count = pps->transform_8x8_mode ? 8 : 6; + RK_S32 i; + + for (i = 0; i < count; i++) + write_scaling_list(bit, pps->use_default_scaling_matrix[i]); + } + + /* second_chroma_qp_index_offset */ + mpp_writer_put_se(bit, pps->second_chroma_qp_index_offset); + } + + mpp_writer_trailing(bit); + + pps_size = mpp_writer_bytes(bit); + + mpp_packet_set_length(packet, length + pps_size); + + return MPP_OK; +} + +MPP_RET h264e_pps_dump(SynH264ePps *pps) +{ + (void) pps; + return MPP_OK; +} diff --git a/mpp/codec/enc/h264/h264e_pps.h b/mpp/codec/enc/h264/h264e_pps.h new file mode 100644 index 00000000..e22feb0c --- /dev/null +++ b/mpp/codec/enc/h264/h264e_pps.h @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __H264E_PPS_H__ +#define __H264E_PPS_H__ + +#include "mpp_packet.h" +#include "mpp_enc_cfg.h" + +#include "h264e_syntax.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET h264e_pps_update(SynH264ePps *pps, MppEncCfgSet *cfg); +MPP_RET h264e_pps_to_packet(SynH264ePps *pps, MppPacket packet); +MPP_RET h264e_pps_dump(SynH264ePps *pps); + +#ifdef __cplusplus +} +#endif + +#endif /* __H264E_PPS_H__ */ diff --git a/mpp/common/h264_syntax.h b/mpp/common/h264_syntax.h index 761cfe98..cf44a7f0 100644 --- a/mpp/common/h264_syntax.h +++ b/mpp/common/h264_syntax.h @@ -165,4 +165,16 @@ typedef enum H264SeiType_e { H264_SEI_MAX_ELEMENTS //!< number of maximum syntax elements } H264SeiType; +typedef enum H264ScalingListType_e { + H264_INTRA_4x4_Y, + H264_INTRA_4x4_U, + H264_INTRA_4x4_V, + H264_INTER_4x4_Y, + H264_INTER_4x4_U, + H264_INTER_4x4_V, + H264_INTRA_8x8_Y, + H264_INTER_8x8_Y, + H264_SCALING_MATRIX_TYPE_BUTT, +} H264ScalingMatrixType; + #endif /*__H264_SYNTAX_H__*/ diff --git a/mpp/common/h264e_syntax.h b/mpp/common/h264e_syntax.h index 85e8d77a..2505ef75 100644 --- a/mpp/common/h264e_syntax.h +++ b/mpp/common/h264e_syntax.h @@ -285,7 +285,8 @@ typedef struct SynH264ePps_t { RK_S32 transform_8x8_mode; // Only support flat and default scaling list - RK_S32 pic_scaling_list_present; + RK_S32 pic_scaling_matrix_present; + RK_S32 use_default_scaling_matrix[H264_SCALING_MATRIX_TYPE_BUTT]; } SynH264ePps; #endif