/* * * 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. */ #include #include #include "h264d_scalist.h" static RK_U8 ZZ_SCAN[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; static RK_U8 ZZ_SCAN8[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 RK_S32 Default4x4Intra[H264ScalingList4x4Length] = { 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 }; static RK_S32 Default4x4Inter[H264ScalingList4x4Length] = { 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 }; static RK_S32 Default8x8Intra[H264ScalingList8x8Length] = { 6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29, 13, 16, 18, 23, 25, 27, 29, 31, 16, 18, 23, 25, 27, 29, 31, 33, 18, 23, 25, 27, 29, 31, 33, 36, 23, 25, 27, 29, 31, 33, 36, 38, 25, 27, 29, 31, 33, 36, 38, 40, 27, 29, 31, 33, 36, 38, 40, 42 }; static RK_S32 Default8x8Inter[H264ScalingList8x8Length] = { 9, 13, 15, 17, 19, 21, 22, 24, 13, 13, 17, 19, 21, 22, 24, 25, 15, 17, 19, 21, 22, 24, 25, 27, 17, 19, 21, 22, 24, 25, 27, 28, 19, 21, 22, 24, 25, 27, 28, 30, 21, 22, 24, 25, 27, 28, 30, 32, 22, 24, 25, 27, 28, 30, 32, 33, 24, 25, 27, 28, 30, 32, 33, 35 }; static RK_S32 Default4x4[16] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; static RK_S32 Default8x8[64] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; static void set_sps_scanlist_matrix(H264_SPS_t *sps, H264dVideoCtx_t *p_Vid) { RK_S32 i = 0; for (i = 0; i < 6; ++i) { if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A if (i == 0) { p_Vid->qmatrix[i] = Default4x4Intra; } else if (i == 3) { p_Vid->qmatrix[i] = Default4x4Inter; } else { p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; } } else { if (sps->UseDefaultScalingMatrix4x4Flag[i]) { p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; } else { p_Vid->qmatrix[i] = sps->ScalingList4x4[i]; } } } for (i = 6; i < ((sps->chroma_format_idc != H264_CHROMA_444) ? 8 : 12); ++i) { if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A if (i == 6) { p_Vid->qmatrix[i] = Default8x8Intra; } else if (i == 7) { p_Vid->qmatrix[i] = Default8x8Inter; } else { p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; } } else { if (sps->UseDefaultScalingMatrix8x8Flag[i - 6]) { p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; } else { p_Vid->qmatrix[i] = sps->ScalingList8x8[i - 6]; } } } } static void set_pps_scanlist_matrix(H264_SPS_t *sps, H264_PPS_t *pps, H264dVideoCtx_t *p_Vid) { RK_S32 i = 0; for (i = 0; i < 6; ++i) { if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B if (i == 0) { if (!sps->seq_scaling_matrix_present_flag) { p_Vid->qmatrix[i] = Default4x4Intra; } } else if (i == 3) { if (!sps->seq_scaling_matrix_present_flag) { p_Vid->qmatrix[i] = Default4x4Inter; } } else { p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; } } else { if (pps->UseDefaultScalingMatrix4x4Flag[i]) { p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; } else { p_Vid->qmatrix[i] = pps->ScalingList4x4[i]; } } } for (i = 6; i < ((sps->chroma_format_idc != H264_CHROMA_444) ? 8 : 12); ++i) { if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B if (i == 6) { if (!sps->seq_scaling_matrix_present_flag) { p_Vid->qmatrix[i] = Default8x8Intra; } } else if (i == 7) { if (!sps->seq_scaling_matrix_present_flag) p_Vid->qmatrix[i] = Default8x8Inter; } else p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; } else { if (pps->UseDefaultScalingMatrix8x8Flag[i - 6]) { p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; } else { p_Vid->qmatrix[i] = pps->ScalingList8x8[i - 6]; } } } } /*! *********************************************************************** * \brief * check profile *********************************************************************** */ //extern "C" RK_U32 is_prext_profile(RK_U32 profile_idc) { return (profile_idc >= H264_PROFILE_HIGH || profile_idc == H264_PROFILE_FREXT_CAVLC444) ? 1 : 0; } /*! *********************************************************************** * \brief * parse sps and process sps *********************************************************************** */ //extern "C" MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default) { MPP_RET ret = MPP_ERR_UNKNOW; RK_S32 last_scale = 8; RK_S32 next_scale = 8; RK_S32 delta_scale = 0; RK_S32 j = 0, scanj = 0; RK_U8 *zz_scan = (size > 16) ? ZZ_SCAN8 : ZZ_SCAN; *use_default = 0; for (j = 0; j < size; ++j) { scanj = zz_scan[j]; if (next_scale != 0) { READ_SE(p_bitctx, &delta_scale); next_scale = (last_scale + delta_scale + 256) & 0xff; *use_default = (scanj == 0 && next_scale == 0) ? 1 : 0; } scaling_list[scanj] = (next_scale == 0) ? last_scale : next_scale; last_scale = scaling_list[scanj]; } return ret = MPP_OK; __BITREAD_ERR: ret = p_bitctx->ret; return ret; } /*! *********************************************************************** * \brief * parse sps and process sps *********************************************************************** */ //extern "C" MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps) { RK_S32 size = 0; RK_S32 pic_size = 0; MPP_RET ret = MPP_ERR_UNKNOW; switch (sps->level_idc) { case 9: size = 152064; break; case 10: size = 152064; break; case 11: if (sps->constrained_set3_flag && !is_prext_profile(sps->profile_idc)) { size = 152064; } else { size = 345600; } break; case 12: size = 912384; break; case 13: size = 912384; break; case 20: size = 912384; break; case 21: size = 1824768; break; case 22: size = 3110400; break; case 30: size = 3110400; break; case 31: size = 6912000; break; case 32: size = 7864320; break; case 40: size = 12582912; break; case 41: size = 12582912; break; case 42: size = 13369344; break; case 50: size = 42393600; break; case 51: size = 70778880; break; case 52: size = 70778880; break; case 60: size = 267386880; break; case 61: size = 267386880; break; case 62: size = 267386880; break; default: ASSERT(0); // undefined level return ret = MPP_NOK; } pic_size = (sps->pic_width_in_mbs_minus1 + 1) * (sps->pic_height_in_map_units_minus1 + 1) * (sps->frame_mbs_only_flag ? 1 : 2) * 384; size /= pic_size; size = MPP_MIN(size, 16); sps->max_dec_frame_buffering = size; return ret = MPP_OK; } /*! *********************************************************************** * \brief * parse sps and process sps *********************************************************************** */ //extern "C" MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps) { RK_S32 i = 0; MPP_RET ret = MPP_ERR_UNKNOW; // Parse scaling_list4x4. for (i = 0; i < 6; ++i) { READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[i]); if (sps->seq_scaling_list_present_flag[i]) { FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length, sps->ScalingList4x4[i], &sps->UseDefaultScalingMatrix4x4Flag[i])); } } // Parse scaling_list8x8. for (i = 0; i < ((sps->chroma_format_idc != H264_CHROMA_444) ? 2 : 6); ++i) { READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[6 + i]); if (sps->seq_scaling_list_present_flag[6 + i]) { FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length, sps->ScalingList8x8[i], &sps->UseDefaultScalingMatrix8x8Flag[i])); } } return ret = MPP_OK; __BITREAD_ERR: ret = p_bitctx->ret; __FAILED: return ret; } /*! *********************************************************************** * \brief * prepare scanlist info to register syntax *********************************************************************** */ //extern "C" MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice) { RK_S32 i = 0; H264_SPS_t *sps = currSlice->p_Vid->active_sps; H264_PPS_t *pps = currSlice->p_Vid->active_pps; if (!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag) { for (i = 0; i < 12; i++) { currSlice->p_Vid->qmatrix[i] = (i < 6) ? Default4x4 : Default8x8; } } else { if (sps->seq_scaling_matrix_present_flag) { // check sps first set_sps_scanlist_matrix(sps, currSlice->p_Vid); } if (pps->pic_scaling_matrix_present_flag) { // then check pps set_pps_scanlist_matrix(sps, pps, currSlice->p_Vid); } } return MPP_OK; }