/*
|
*
|
* 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.
|
*/
|
|
/*
|
* @file h265d_ps.c
|
* @brief
|
* @author csy(csy@rock-chips.com)
|
|
* @version 1.0.0
|
* @history
|
* 2015.7.15 : Create
|
*/
|
|
#define MODULE_TAG "H265PARSER_PS"
|
|
#include "mpp_mem.h"
|
#include "mpp_bitread.h"
|
#include "h265d_parser.h"
|
|
static const RK_U8 default_scaling_list_intra[] = {
|
16, 16, 16, 16, 17, 18, 21, 24,
|
16, 16, 16, 16, 17, 19, 22, 25,
|
16, 16, 17, 18, 20, 22, 25, 29,
|
16, 16, 18, 21, 24, 27, 31, 36,
|
17, 17, 20, 24, 30, 35, 41, 47,
|
18, 19, 22, 27, 35, 44, 54, 65,
|
21, 22, 25, 31, 41, 54, 70, 88,
|
24, 25, 29, 36, 47, 65, 88, 115
|
};
|
|
static const RK_U8 default_scaling_list_inter[] = {
|
16, 16, 16, 16, 17, 18, 20, 24,
|
16, 16, 16, 17, 18, 20, 24, 25,
|
16, 16, 17, 18, 20, 24, 25, 28,
|
16, 17, 18, 20, 24, 25, 28, 33,
|
17, 18, 20, 24, 25, 28, 33, 41,
|
18, 20, 24, 25, 28, 33, 41, 54,
|
20, 24, 25, 28, 33, 41, 54, 71,
|
24, 25, 28, 33, 41, 54, 71, 91
|
};
|
|
static const MppRational_t vui_sar[] = {
|
{ 0, 1 },
|
{ 1, 1 },
|
{ 12, 11 },
|
{ 10, 11 },
|
{ 16, 11 },
|
{ 40, 33 },
|
{ 24, 11 },
|
{ 20, 11 },
|
{ 32, 11 },
|
{ 80, 33 },
|
{ 18, 11 },
|
{ 15, 11 },
|
{ 64, 33 },
|
{ 160, 99 },
|
{ 4, 3 },
|
{ 3, 2 },
|
{ 2, 1 },
|
};
|
|
const RK_U8 mpp_hevc_diag_scan4x4_x[16] = {
|
0, 0, 1, 0,
|
1, 2, 0, 1,
|
2, 3, 1, 2,
|
3, 2, 3, 3,
|
};
|
|
const RK_U8 mpp_hevc_diag_scan4x4_y[16] = {
|
0, 1, 0, 2,
|
1, 0, 3, 2,
|
1, 0, 3, 2,
|
1, 3, 2, 3,
|
};
|
|
const RK_U8 mpp_hevc_diag_scan8x8_x[64] = {
|
0, 0, 1, 0,
|
1, 2, 0, 1,
|
2, 3, 0, 1,
|
2, 3, 4, 0,
|
1, 2, 3, 4,
|
5, 0, 1, 2,
|
3, 4, 5, 6,
|
0, 1, 2, 3,
|
4, 5, 6, 7,
|
1, 2, 3, 4,
|
5, 6, 7, 2,
|
3, 4, 5, 6,
|
7, 3, 4, 5,
|
6, 7, 4, 5,
|
6, 7, 5, 6,
|
7, 6, 7, 7,
|
};
|
|
const RK_U8 mpp_hevc_diag_scan8x8_y[64] = {
|
0, 1, 0, 2,
|
1, 0, 3, 2,
|
1, 0, 4, 3,
|
2, 1, 0, 5,
|
4, 3, 2, 1,
|
0, 6, 5, 4,
|
3, 2, 1, 0,
|
7, 6, 5, 4,
|
3, 2, 1, 0,
|
7, 6, 5, 4,
|
3, 2, 1, 7,
|
6, 5, 4, 3,
|
2, 7, 6, 5,
|
4, 3, 7, 6,
|
5, 4, 7, 6,
|
5, 7, 6, 7,
|
};
|
|
int mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
|
const HEVCSPS *sps, RK_S32 is_slice_header)
|
{
|
HEVCLocalContext *lc = s->HEVClc;
|
RK_U8 rps_predict = 0;
|
RK_S32 delta_poc;
|
RK_S32 k0 = 0;
|
RK_S32 k1 = 0;
|
RK_S32 k = 0;
|
RK_S32 i;
|
|
BitReadCtx_t *gb = &lc->gb;
|
|
if (rps != sps->st_rps && sps->nb_st_rps)
|
READ_ONEBIT(gb, &rps_predict);
|
|
if (rps_predict) {
|
const ShortTermRPS *rps_ridx;
|
RK_S32 delta_rps, abs_delta_rps;
|
RK_U8 use_delta_flag = 0;
|
RK_U8 delta_rps_sign;
|
|
if (is_slice_header) {
|
RK_U32 delta_idx = 0;
|
READ_UE(gb, &delta_idx);
|
delta_idx = delta_idx + 1;
|
if (delta_idx > sps->nb_st_rps) {
|
mpp_err(
|
"Invalid value of delta_idx in slice header RPS: %d > %d.\n",
|
delta_idx, sps->nb_st_rps);
|
return MPP_ERR_STREAM;
|
}
|
rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
|
} else
|
rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
|
|
READ_BITS(gb, 1, &delta_rps_sign);
|
|
READ_UE(gb, &abs_delta_rps);
|
|
abs_delta_rps = abs_delta_rps + 1;
|
|
delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
|
for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
|
RK_S32 used = 0;
|
READ_ONEBIT(gb, &used);
|
|
rps->used[k] = used;
|
|
if (!used)
|
READ_ONEBIT(gb, &use_delta_flag);
|
|
if (used || use_delta_flag) {
|
if (i < rps_ridx->num_delta_pocs)
|
delta_poc = delta_rps + rps_ridx->delta_poc[i];
|
else
|
delta_poc = delta_rps;
|
rps->delta_poc[k] = delta_poc;
|
if (delta_poc < 0)
|
k0++;
|
else
|
k1++;
|
k++;
|
}
|
}
|
|
rps->num_delta_pocs = k;
|
rps->num_negative_pics = k0;
|
// sort in increasing order (smallest first)
|
if (rps->num_delta_pocs != 0) {
|
RK_S32 used, tmp;
|
for (i = 1; i < rps->num_delta_pocs; i++) {
|
delta_poc = rps->delta_poc[i];
|
used = rps->used[i];
|
for (k = i - 1; k >= 0; k--) {
|
tmp = rps->delta_poc[k];
|
if (delta_poc < tmp) {
|
rps->delta_poc[k + 1] = tmp;
|
rps->used[k + 1] = rps->used[k];
|
rps->delta_poc[k] = delta_poc;
|
rps->used[k] = used;
|
}
|
}
|
}
|
}
|
if ((rps->num_negative_pics >> 1) != 0) {
|
RK_S32 used;
|
k = rps->num_negative_pics - 1;
|
// flip the negative values to largest first
|
for (i = 0; (RK_U32)i < rps->num_negative_pics >> 1; i++) {
|
delta_poc = rps->delta_poc[i];
|
used = rps->used[i];
|
rps->delta_poc[i] = rps->delta_poc[k];
|
rps->used[i] = rps->used[k];
|
rps->delta_poc[k] = delta_poc;
|
rps->used[k] = used;
|
k--;
|
}
|
}
|
} else {
|
RK_U32 prev, nb_positive_pics;
|
|
READ_UE(gb, &rps->num_negative_pics);
|
|
READ_UE(gb, &nb_positive_pics);
|
|
if (rps->num_negative_pics >= MAX_REFS ||
|
nb_positive_pics >= MAX_REFS) {
|
mpp_err( "Too many refs in a short term RPS.\n");
|
return MPP_ERR_STREAM;
|
}
|
|
rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
|
if (rps->num_delta_pocs) {
|
prev = 0;
|
for (i = 0; (RK_U32)i < rps->num_negative_pics; i++) {
|
READ_UE(gb, &delta_poc);
|
delta_poc += 1;
|
prev -= delta_poc;
|
rps->delta_poc[i] = prev;
|
READ_ONEBIT(gb, &rps->used[i]);
|
}
|
prev = 0;
|
for (i = 0; (RK_U32)i < nb_positive_pics; i++) {
|
READ_UE(gb, &delta_poc);
|
delta_poc = delta_poc + 1;
|
prev += delta_poc;
|
rps->delta_poc[rps->num_negative_pics + i] = prev;
|
READ_ONEBIT(gb, &rps->used[rps->num_negative_pics + i]);
|
}
|
}
|
}
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
|
static RK_S32 decode_profile_tier_level(HEVCContext *s, PTLCommon *ptl)
|
{
|
int i;
|
HEVCLocalContext *lc = s->HEVClc;
|
BitReadCtx_t *gb = &lc->gb;
|
|
READ_BITS(gb, 2, &ptl->profile_space);
|
READ_ONEBIT(gb, &ptl->tier_flag);
|
READ_BITS(gb, 5, &ptl->profile_idc);
|
|
if (ptl->profile_idc == MPP_PROFILE_HEVC_MAIN)
|
h265d_dbg(H265D_DBG_GLOBAL, "Main profile bitstream\n");
|
else if (ptl->profile_idc == MPP_PROFILE_HEVC_MAIN_10)
|
h265d_dbg(H265D_DBG_GLOBAL, "Main 10 profile bitstream\n");
|
else if (ptl->profile_idc == MPP_PROFILE_HEVC_MAIN_STILL_PICTURE)
|
h265d_dbg(H265D_DBG_GLOBAL, "Main Still Picture profile bitstream\n");
|
else
|
mpp_log("Unknown HEVC profile: %d\n", ptl->profile_idc);
|
|
for (i = 0; i < 32; i++)
|
READ_ONEBIT(gb, & ptl->profile_compatibility_flag[i]);
|
READ_ONEBIT(gb, &ptl->progressive_source_flag);
|
READ_ONEBIT(gb, &ptl->interlaced_source_flag);
|
READ_ONEBIT(gb, &ptl->non_packed_constraint_flag);
|
READ_ONEBIT(gb, &ptl->frame_only_constraint_flag);
|
|
SKIP_BITS(gb, 16); // XXX_reserved_zero_44bits[0..15]
|
SKIP_BITS(gb, 16); // XXX_reserved_zero_44bits[16..31]
|
SKIP_BITS(gb, 12); // XXX_reserved_zero_44bits[32..43]
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
static RK_S32 parse_ptl(HEVCContext *s, PTL *ptl, int max_num_sub_layers)
|
{
|
RK_S32 i;
|
HEVCLocalContext *lc = s->HEVClc;
|
BitReadCtx_t *gb = &lc->gb;
|
decode_profile_tier_level(s, &ptl->general_ptl);
|
READ_BITS(gb, 8, &ptl->general_ptl.level_idc);
|
|
for (i = 0; i < max_num_sub_layers - 1; i++) {
|
READ_ONEBIT(gb, &ptl->sub_layer_profile_present_flag[i]);
|
READ_ONEBIT(gb, &ptl->sub_layer_level_present_flag[i]);
|
}
|
if (max_num_sub_layers - 1 > 0)
|
for (i = max_num_sub_layers - 1; i < 8; i++)
|
SKIP_BITS(gb, 2); // reserved_zero_2bits[i]
|
for (i = 0; i < max_num_sub_layers - 1; i++) {
|
if (ptl->sub_layer_profile_present_flag[i])
|
decode_profile_tier_level(s, &ptl->sub_layer_ptl[i]);
|
if (ptl->sub_layer_level_present_flag[i])
|
READ_BITS(gb, 8, &ptl->sub_layer_ptl[i].level_idc);
|
}
|
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
static RK_S32 decode_sublayer_hrd(HEVCContext *s, unsigned int nb_cpb,
|
int subpic_params_present)
|
{
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
RK_U32 i, value;
|
|
for (i = 0; i < nb_cpb; i++) {
|
READ_UE(gb, &value); // bit_rate_value_minus1
|
READ_UE(gb, &value); // cpb_size_value_minus1
|
|
if (subpic_params_present) {
|
READ_UE(gb, &value); // cpb_size_du_value_minus1
|
READ_UE(gb, &value); // bit_rate_du_value_minus1
|
}
|
SKIP_BITS(gb, 1); // cbr_flag
|
}
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
static RK_S32 decode_hrd(HEVCContext *s, int common_inf_present,
|
int max_sublayers)
|
{
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
int nal_params_present = 0, vcl_params_present = 0;
|
int subpic_params_present = 0;
|
int i;
|
|
if (common_inf_present) {
|
READ_ONEBIT(gb, &nal_params_present);
|
READ_ONEBIT(gb, &vcl_params_present);
|
|
if (nal_params_present || vcl_params_present) {
|
READ_ONEBIT(gb, &subpic_params_present);
|
|
if (subpic_params_present) {
|
SKIP_BITS(gb, 8); // tick_divisor_minus2
|
SKIP_BITS(gb, 5); // du_cpb_removal_delay_increment_length_minus1
|
SKIP_BITS(gb, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
|
SKIP_BITS(gb, 5); // dpb_output_delay_du_length_minus1
|
}
|
|
SKIP_BITS(gb, 4); // bit_rate_scale
|
SKIP_BITS(gb, 4); // cpb_size_scale
|
|
if (subpic_params_present)
|
SKIP_BITS(gb, 4); // cpb_size_du_scale
|
|
SKIP_BITS(gb, 5); // initial_cpb_removal_delay_length_minus1
|
SKIP_BITS(gb, 5); // au_cpb_removal_delay_length_minus1
|
SKIP_BITS(gb, 5); // dpb_output_delay_length_minus1
|
}
|
}
|
|
for (i = 0; i < max_sublayers; i++) {
|
RK_S32 low_delay = 0;
|
RK_U32 nb_cpb = 1;
|
RK_S32 fixed_rate = 0;
|
RK_S32 value = 0;
|
|
READ_ONEBIT(gb, &fixed_rate);
|
|
if (!fixed_rate)
|
READ_ONEBIT(gb, &fixed_rate);
|
|
if (fixed_rate)
|
READ_UE(gb, &value); // elemental_duration_in_tc_minus1
|
else
|
READ_ONEBIT(gb, &low_delay);
|
|
if (!low_delay) {
|
READ_UE(gb, &nb_cpb);
|
nb_cpb = nb_cpb + 1;
|
}
|
|
if (nal_params_present)
|
decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
|
if (vcl_params_present)
|
decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
|
}
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
|
#ifdef VPS_EXTENSION
|
static RK_S32 parse_vps_extension (HEVCContext *s, HEVCVPS *vps)
|
{
|
RK_S32 i, j;
|
RK_S32 value = 0;
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
#ifdef VPS_EXTN_MASK_AND_DIM_INFO
|
RK_S32 numScalabilityTypes = 0;
|
READ_ONEBIT(gb, &vps->avc_base_layer_flag);
|
READ_ONEBIT(gb, &vps->splitting_flag);
|
|
for (i = 0; i < MAX_VPS_NUM_SCALABILITY_TYPES; i++) {
|
READ_ONEBIT(gb, &vps->scalability_mask[i]);
|
numScalabilityTypes += vps->scalability_mask[i];
|
if ( i != 1 && vps->scalability_mask[i] != 0) {
|
mpp_err( "Multiview and reserved masks are not used in this version of software \n");
|
}
|
}
|
|
vps->m_numScalabilityTypes = numScalabilityTypes;
|
for (i = 0; i < numScalabilityTypes; i++) {
|
READ_BITS(gb, 3, &vps->dimension_id_len[i]);
|
vps->dimension_id_len[i] = vps->dimension_id_len[i] + 1;
|
}
|
|
if (vps->splitting_flag) {
|
int numBits = 0;
|
for (i = 0; i < numScalabilityTypes; i++) {
|
numBits += vps->dimension_id_len[i];
|
}
|
if (numBits > 6)
|
mpp_err( "numBits>6 \n");
|
}
|
|
READ_ONEBIT(gb, &vps->nuh_layer_id_present_flag);
|
vps->layer_id_in_nuh[0] = 0;
|
vps->m_layerIdInVps[0] = 0;
|
|
for (i = 1; i < vps->vps_max_layers; i++) {
|
if (vps->nuh_layer_id_present_flag ) {
|
READ_BITS(gb, 6, vps->layer_id_in_nuh[i]);
|
} else {
|
vps->layer_id_in_nuh[i] = i;
|
}
|
vps->m_layerIdInVps[vps->layer_id_in_nuh[i]] = i;
|
for (j = 0; j < numScalabilityTypes; j++) {
|
READ_BITS(gb, vps->dimension_id_len[j], &vps->dimension_id[i][j]);
|
}
|
}
|
|
#endif
|
#ifdef VPS_MOVE_DIR_DEPENDENCY_FLAG
|
#ifdef VPS_EXTN_DIRECT_REF_LAYERS
|
vps->m_numDirectRefLayers[0] = 0;
|
for ( i = 1; i <= vps->vps_max_layers - 1; i++) {
|
RK_S32 numDirectRefLayers = 0;
|
for ( j = 0; j < i; j++) {
|
READ_ONEBIT(gb, &vps->direct_dependency_flag[i][j]);
|
if (vps->direct_dependency_flag[i][j]) {
|
vps->m_refLayerId[i][numDirectRefLayers] = j;
|
numDirectRefLayers++;
|
}
|
}
|
|
vps->m_numDirectRefLayers[i] = numDirectRefLayers;
|
}
|
#endif
|
#endif
|
#ifdef VPS_EXTN_PROFILE_INFO
|
#ifdef VPS_PROFILE_OUTPUT_LAYERS
|
READ_BITS(gb, 10, value);
|
if ( value != (vps->vps_num_layer_sets - 1)) { //vps_number_layer_sets_minus1
|
mpp_err( "Erro vps_number_layer_sets_minus1 != vps->vps_num_layer_sets-1 \n");
|
}
|
READ_BITS(gb, 6, &vps->vps_num_profile_tier_level);
|
vps->vps_num_profile_tier_level = vps->vps_num_profile_tier_level + 1;
|
vps->PTLExt = mpp_malloc(PTL*, vps->vps_num_profile_tier_level); // TO DO add free
|
|
for (i = 1; i <= vps->vps_num_profile_tier_level - 1; i++)
|
#else
|
vps->PTLExt = mpp_malloc(PTL*, vps->vps_num_layer_sets); // TO DO add free
|
for (i = 1; i <= vps->vps_num_layer_sets - 1; i++)
|
#endif
|
{
|
READ_ONEBIT(gb, &vps->vps_profile_present_flag[i]);
|
if ( !vps->vps_profile_present_flag[i] ) {
|
#ifdef VPS_PROFILE_OUTPUT_LAYERS
|
READ_BITS(gb, 6, &vps->profile_ref[i])
|
|
vps->profile_ref[i] = vps->profile_ref[i] + 1;
|
|
#else
|
READ_UE(gb, &vps->profile_ref[i]);
|
#endif
|
vps->PTLExt[i] = mpp_malloc(PTL, 1); // TO DO add free
|
memcpy(vps->PTLExt[i], vps->PTLExt[vps->profile_ref[i]], sizeof(PTL));
|
}
|
vps->PTLExt[i] = mpp_malloc(PTL, 1); // TO DO add free
|
parse_ptl(s, vps->PTLExt[i], vps->vps_max_sub_layers);
|
}
|
#endif
|
|
#ifdef VPS_PROFILE_OUTPUT_LAYERS
|
READ_ONEBIT(gb, &vps->more_output_layer_sets_than_default_flag );
|
RK_S32 numOutputLayerSets = 0;
|
if (! vps->more_output_layer_sets_than_default_flag ) {
|
numOutputLayerSets = vps->vps_num_layer_sets;
|
} else {
|
READ_BITS(gb, 10, &vps->num_add_output_layer_sets);
|
numOutputLayerSets = vps->vps_num_layer_sets + vps->num_add_output_layer_sets;
|
}
|
if (numOutputLayerSets > 1) {
|
READ_ONEBIT(gb, &vps->default_one_target_output_layer_flag);
|
}
|
vps->m_numOutputLayerSets = numOutputLayerSets;
|
for (i = 1; i < numOutputLayerSets; i++) {
|
if ( i > (vps->vps_num_layer_sets - 1) ) {
|
RK_S32 numBits = 1, lsIdx;
|
while ((1 << numBits) < (vps->vps_num_layer_sets - 1)) {
|
numBits++;
|
}
|
READ_BITS(gb, numBits, &vps->output_layer_set_idx[i]);
|
vps->output_layer_set_idx[i] = vps->output_layer_set_idx[i] + 1;
|
lsIdx = vps->output_layer_set_idx[i];
|
for (j = 0; j < vps->m_numLayerInIdList[lsIdx] - 1; j++) {
|
READ_ONEBIT(gb, &vps->output_layer_flag[i][j]);
|
}
|
} else {
|
int lsIdx = i;
|
if ( vps->default_one_target_output_layer_flag ) {
|
for (j = 0; j < vps->m_numLayerInIdList[lsIdx]; j++) {
|
vps->output_layer_flag[i][j] = (j == (vps->m_numLayerInIdList[lsIdx] - 1));
|
}
|
} else {
|
for (j = 0; j < vps->m_numLayerInIdList[lsIdx]; j++) {
|
vps->output_layer_flag[i][j] = 1;
|
}
|
}
|
}
|
int numBits = 1;
|
while ((1 << numBits) < (vps->vps_num_profile_tier_level)) {
|
numBits++;
|
}
|
READ_BITS(gb, numBits, &vps->profile_level_tier_idx[i]);
|
}
|
#endif
|
#ifdef JCTVC_M0458_INTERLAYER_RPS_SIG
|
READ_ONEBIT(gb, &vps->max_one_active_ref_layer_flag);
|
#endif
|
}
|
#endif
|
static RK_S32 compare_vps(HEVCVPS *openhevc_vps, HEVCVPS *vps)
|
{
|
|
if (openhevc_vps->vps_temporal_id_nesting_flag !=
|
vps->vps_temporal_id_nesting_flag) {
|
mpp_log("vps_temporal_id_nesting_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_vps->vps_max_layers != vps->vps_max_layers) {
|
mpp_log("vps_max_layers diff\n");
|
return -1;
|
}
|
|
if (openhevc_vps->vps_max_sub_layers != vps->vps_max_sub_layers) {
|
mpp_log("vps_max_sub_layers diff\n");
|
return -1;
|
}
|
if (openhevc_vps->vps_sub_layer_ordering_info_present_flag !=
|
vps->vps_sub_layer_ordering_info_present_flag) {
|
mpp_log("vps_sub_layer_ordering_info_present_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_vps->vps_max_layer_id != vps->vps_max_layer_id) {
|
|
mpp_log("vps_max_layer_id diff\n");
|
return -1;
|
}
|
|
if (openhevc_vps->vps_num_layer_sets != vps->vps_num_layer_sets) {
|
|
mpp_log("vps_num_layer_sets diff\n");
|
return -1;
|
}
|
if (openhevc_vps->vps_timing_info_present_flag !=
|
vps->vps_timing_info_present_flag) {
|
|
mpp_log("vps_timing_info_present_flag diff\n");
|
return -1;
|
}
|
if (openhevc_vps->vps_num_units_in_tick !=
|
vps->vps_num_units_in_tick) {
|
mpp_log("vps_num_units_in_tick diff\n");
|
return -1;
|
}
|
|
if ( openhevc_vps->vps_time_scale !=
|
vps->vps_time_scale) {
|
mpp_log("vps_time_scale diff\n");
|
return -1;
|
}
|
if (openhevc_vps->vps_poc_proportional_to_timing_flag !=
|
vps->vps_poc_proportional_to_timing_flag) {
|
mpp_log("vps_poc_proportional_to_timing_flag \n");
|
return -1;
|
}
|
if (openhevc_vps->vps_num_ticks_poc_diff_one !=
|
vps->vps_num_ticks_poc_diff_one) {
|
mpp_log("vps_poc_proportional_to_timing_flag \n");
|
return -1;
|
}
|
|
if (openhevc_vps->vps_num_hrd_parameters
|
!= vps->vps_num_hrd_parameters) {
|
mpp_log("vps_num_hrd_parameters \n");
|
return -1;
|
}
|
return 0;
|
}
|
|
static RK_S32 compare_sps(HEVCSPS *openhevc_sps, HEVCSPS *sps)
|
{
|
if (openhevc_sps->vps_id != sps->vps_id) {
|
mpp_log("vps_id diff\n");
|
return -1;
|
}
|
if (openhevc_sps->sps_id != sps->sps_id) {
|
mpp_log("sps_id diff\n");
|
return -1;
|
}
|
if (openhevc_sps->chroma_format_idc != sps->chroma_format_idc) {
|
mpp_log("chroma_format_idc diff\n");
|
return -1;
|
}
|
if (openhevc_sps->separate_colour_plane_flag
|
!= sps->separate_colour_plane_flag) {
|
mpp_log("separate_colour_plane_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->output_width != sps->output_width) {
|
mpp_log("output_width diff\n");
|
return -1;
|
}
|
if (openhevc_sps->output_height != sps->output_height) {
|
mpp_log("output_height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->bit_depth != sps->bit_depth) {
|
mpp_log("bit_depth diff\n");
|
return -1;
|
}
|
if (openhevc_sps->bit_depth_chroma != sps->bit_depth_chroma) {
|
mpp_log("bit_depth_chroma diff\n");
|
return -1;
|
}
|
if (openhevc_sps->pixel_shift != sps->pixel_shift) {
|
mpp_log("pixel_shift diff\n");
|
return -1;
|
}
|
// openhevc_sps->pix_fmt;
|
|
if (openhevc_sps->log2_max_poc_lsb != sps->log2_max_poc_lsb) {
|
mpp_log("log2_max_poc_lsb diff\n");
|
return -1;
|
}
|
if (openhevc_sps->pcm_enabled_flag != sps->pcm_enabled_flag) {
|
mpp_log("pcm_enabled_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->max_sub_layers != sps->max_sub_layers) {
|
mpp_log("max_sub_layers diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->scaling_list_enable_flag != sps->scaling_list_enable_flag) {
|
mpp_log("scaling_list_enable_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->nb_st_rps != sps->nb_st_rps) {
|
mpp_log("nb_st_rps diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->amp_enabled_flag != sps->amp_enabled_flag) {
|
mpp_log(" amp_enabled_flag diff openhevc %d != %d\n", openhevc_sps->amp_enabled_flag, sps->amp_enabled_flag);
|
return -1;
|
}
|
if (openhevc_sps->sao_enabled != sps->sao_enabled) {
|
mpp_log("sao_enabled diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->long_term_ref_pics_present_flag
|
!= sps->long_term_ref_pics_present_flag) {
|
mpp_log("long_term_ref_pics_present_flag diff\n");
|
return -1;
|
}
|
if (openhevc_sps->num_long_term_ref_pics_sps !=
|
sps->num_long_term_ref_pics_sps) {
|
mpp_log("num_long_term_ref_pics_sps diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->sps_temporal_mvp_enabled_flag !=
|
sps->sps_temporal_mvp_enabled_flag) {
|
mpp_log("sps_temporal_mvp_enabled_flag diff\n");
|
return -1;
|
}
|
if (openhevc_sps->sps_strong_intra_smoothing_enable_flag !=
|
sps->sps_strong_intra_smoothing_enable_flag) {
|
mpp_log("sps_strong_intra_smoothing_enable_flag diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->log2_min_cb_size != sps->log2_min_cb_size) {
|
mpp_log("log2_min_cb_size diff\n");
|
return -1;
|
}
|
if (openhevc_sps->log2_diff_max_min_coding_block_size !=
|
sps->log2_diff_max_min_coding_block_size) {
|
mpp_log("log2_diff_max_min_coding_block_size diff\n");
|
return -1;
|
}
|
if (openhevc_sps->log2_min_tb_size != sps->log2_min_tb_size) {
|
mpp_log("log2_min_tb_size diff\n");
|
return -1;
|
}
|
if (openhevc_sps->log2_max_trafo_size != sps->log2_max_trafo_size) {
|
mpp_log("log2_max_trafo_size diff\n");
|
return -1;
|
}
|
if (openhevc_sps->log2_ctb_size != sps->log2_ctb_size) {
|
mpp_log("log2_ctb_size diff\n");
|
return -1;
|
}
|
if (openhevc_sps->log2_min_pu_size != sps->log2_min_pu_size) {
|
mpp_log("log2_min_pu_size diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->max_transform_hierarchy_depth_inter !=
|
sps->max_transform_hierarchy_depth_inter) {
|
mpp_log("max_transform_hierarchy_depth_inter diff\n");
|
return -1;
|
}
|
if (openhevc_sps->max_transform_hierarchy_depth_intra !=
|
sps->max_transform_hierarchy_depth_intra) {
|
mpp_log("max_transform_hierarchy_depth_intra diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->width != sps->width) {
|
mpp_log("width diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->height != sps->height) {
|
mpp_log("height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->ctb_width != sps->ctb_width) {
|
mpp_log("ctb_width diff\n");
|
return -1;
|
}
|
|
if ( openhevc_sps->ctb_height != sps->ctb_height) {
|
mpp_log("ctb_height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->ctb_size != sps->ctb_size) {
|
mpp_log("ctb_size diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_cb_width != sps->min_cb_width) {
|
mpp_log("min_cb_width diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_cb_height != sps->min_cb_height) {
|
mpp_log("min_cb_height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_tb_width != sps->min_tb_width) {
|
mpp_log("min_tb_width diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_tb_height != sps->min_tb_height) {
|
mpp_log("min_tb_height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_pu_width != sps->min_pu_width) {
|
mpp_log("min_pu_width diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->min_pu_height != sps->min_pu_height) {
|
mpp_log("min_pu_height diff\n");
|
return -1;
|
}
|
|
if (openhevc_sps->qp_bd_offset != sps->qp_bd_offset) {
|
mpp_log("qp_bd_offset diff \n");
|
return -1;
|
}
|
return 0;
|
}
|
|
static RK_S32 compare_pps(HEVCPPS *openhevc_pps, HEVCPPS *pps)
|
{
|
|
if (openhevc_pps->sps_id != pps->sps_id) {
|
mpp_log("sps_id diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->pps_id != pps->pps_id) {
|
mpp_log("pps_id diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->sign_data_hiding_flag != pps->sign_data_hiding_flag) {
|
mpp_log("sign_data_hiding_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->cabac_init_present_flag != pps->cabac_init_present_flag) {
|
mpp_log("cabac_init_present_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->num_ref_idx_l0_default_active != pps->num_ref_idx_l0_default_active) {
|
mpp_log("num_ref_idx_l0_default_active diff \n");
|
return -1;
|
}
|
if (openhevc_pps->num_ref_idx_l1_default_active != pps->num_ref_idx_l1_default_active) {
|
mpp_log("num_ref_idx_l1_default_active diff \n");
|
return -1;
|
}
|
if (openhevc_pps->pic_init_qp_minus26 != pps->pic_init_qp_minus26) {
|
mpp_log("pic_init_qp_minus26 diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->constrained_intra_pred_flag != pps->constrained_intra_pred_flag) {
|
mpp_log("constrained_intra_pred_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->transform_skip_enabled_flag != pps->transform_skip_enabled_flag) {
|
mpp_log("transform_skip_enabled_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->cu_qp_delta_enabled_flag != pps->cu_qp_delta_enabled_flag) {
|
mpp_log("cu_qp_delta_enabled_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->diff_cu_qp_delta_depth != pps->diff_cu_qp_delta_depth) {
|
mpp_log("diff_cu_qp_delta_depth diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->cb_qp_offset != pps->cb_qp_offset) {
|
mpp_log("cb_qp_offset diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->cr_qp_offset != pps->cr_qp_offset) {
|
mpp_log("cr_qp_offset diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->pic_slice_level_chroma_qp_offsets_present_flag !=
|
pps->pic_slice_level_chroma_qp_offsets_present_flag) {
|
mpp_log("pic_slice_level_chroma_qp_offsets_present_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->weighted_pred_flag != pps->weighted_pred_flag) {
|
mpp_log("weighted_pred_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->weighted_bipred_flag != pps->weighted_bipred_flag) {
|
mpp_log("weighted_bipred_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->output_flag_present_flag != pps->output_flag_present_flag) {
|
mpp_log("output_flag_present_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->transquant_bypass_enable_flag !=
|
pps->transquant_bypass_enable_flag) {
|
mpp_log("transquant_bypass_enable_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->dependent_slice_segments_enabled_flag !=
|
pps->dependent_slice_segments_enabled_flag) {
|
mpp_log("dependent_slice_segments_enabled_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->tiles_enabled_flag != pps->tiles_enabled_flag) {
|
mpp_log("tiles_enabled_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->entropy_coding_sync_enabled_flag !=
|
pps->entropy_coding_sync_enabled_flag) {
|
mpp_log("entropy_coding_sync_enabled_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->num_tile_columns != pps->num_tile_columns) {
|
mpp_log("num_tile_columns diff \n");
|
return -1;
|
}
|
if (openhevc_pps->num_tile_rows != pps->num_tile_rows) {
|
mpp_log("num_tile_rows diff \n");
|
return -1;
|
}
|
if (openhevc_pps->uniform_spacing_flag != pps->uniform_spacing_flag) {
|
mpp_log("qp_bd_offset diff \n");
|
return -1;
|
}
|
if (openhevc_pps->loop_filter_across_tiles_enabled_flag !=
|
pps->loop_filter_across_tiles_enabled_flag) {
|
mpp_log("loop_filter_across_tiles_enabled_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->seq_loop_filter_across_slices_enabled_flag !=
|
pps->seq_loop_filter_across_slices_enabled_flag) {
|
mpp_log("seq_loop_filter_across_slices_enabled_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->deblocking_filter_control_present_flag !=
|
pps->deblocking_filter_control_present_flag) {
|
mpp_log("deblocking_filter_control_present_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->deblocking_filter_override_enabled_flag !=
|
pps->deblocking_filter_override_enabled_flag) {
|
mpp_log("deblocking_filter_override_enabled_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->disable_dbf != pps->disable_dbf) {
|
mpp_log("disable_dbf diff \n");
|
return -1;
|
}
|
if (openhevc_pps->beta_offset != pps->beta_offset) {
|
mpp_log("beta_offset diff \n");
|
return -1;
|
}
|
if (openhevc_pps->tc_offset != pps->tc_offset) {
|
mpp_log("tc_offset diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->scaling_list_data_present_flag !=
|
pps->scaling_list_data_present_flag) {
|
mpp_log("scaling_list_data_present_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->lists_modification_present_flag !=
|
pps->lists_modification_present_flag) {
|
mpp_log("lists_modification_present_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->log2_parallel_merge_level != pps->log2_parallel_merge_level) {
|
mpp_log("log2_parallel_merge_level diff \n");
|
return -1;
|
}
|
if (openhevc_pps->num_extra_slice_header_bits !=
|
pps->num_extra_slice_header_bits) {
|
mpp_log("num_extra_slice_header_bits diff \n");
|
return -1;
|
}
|
#if 0
|
if (openhevc_pps->slice_header_extension_present_flag !=
|
pps->slice_header_extension_present_flag) {
|
mpp_log("slice_header_extension_present_flag diff \n");
|
return -1;
|
}
|
|
if (openhevc_pps->pps_extension_flag != pps->pps_extension_flag) {
|
mpp_log("pps_extension_flag diff \n");
|
return -1;
|
}
|
if (openhevc_pps->pps_extension_data_flag != pps->pps_extension_data_flag) {
|
mpp_log("pps_extension_data_flag diff \n");
|
return -1;
|
}
|
#endif
|
return 0;
|
|
}
|
|
|
|
int mpp_hevc_decode_nal_vps(HEVCContext *s)
|
{
|
RK_S32 i, j;
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
RK_S32 vps_id = 0;
|
HEVCVPS *vps = NULL;
|
RK_U8 *vps_buf = mpp_calloc(RK_U8, sizeof(HEVCVPS));
|
RK_S32 value = 0;
|
|
if (!vps_buf)
|
return MPP_ERR_NOMEM;
|
vps = (HEVCVPS*)vps_buf;
|
|
h265d_dbg(H265D_DBG_FUNCTION, "Decoding VPS\n");
|
|
READ_BITS(gb, 4, &vps_id);
|
|
h265d_dbg(H265D_DBG_VPS, "vps_id = 0x%x", vps_id);
|
|
if (vps_id >= MAX_VPS_COUNT) {
|
mpp_err( "VPS id out of range: %d\n", vps_id);
|
goto err;
|
}
|
READ_BITS(gb, 2, &value);
|
if (value != 3) { // vps_reserved_three_2bits
|
mpp_err( "vps_reserved_three_2bits is not three\n");
|
goto err;
|
}
|
|
READ_BITS(gb, 6, &vps->vps_max_layers);
|
vps->vps_max_layers = vps->vps_max_layers + 1;
|
|
READ_BITS(gb, 3, &vps->vps_max_sub_layers);
|
vps->vps_max_sub_layers = vps->vps_max_sub_layers + 1;
|
|
READ_ONEBIT(gb, & vps->vps_temporal_id_nesting_flag);
|
READ_BITS(gb, 16, &value);
|
|
if (value != 0xffff) { // vps_reserved_ffff_16bits
|
mpp_err( "vps_reserved_ffff_16bits is not 0xffff\n");
|
goto err;
|
}
|
|
if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
|
mpp_err( "vps_max_sub_layers out of range: %d\n",
|
vps->vps_max_sub_layers);
|
goto err;
|
}
|
|
parse_ptl(s, &vps->ptl, vps->vps_max_sub_layers);
|
|
READ_ONEBIT(gb, &vps->vps_sub_layer_ordering_info_present_flag);
|
|
i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
|
for (; i < vps->vps_max_sub_layers; i++) {
|
READ_UE(gb, &vps->vps_max_dec_pic_buffering[i]);
|
vps->vps_max_dec_pic_buffering[i] = vps->vps_max_dec_pic_buffering[i] + 1;
|
READ_UE(gb, &vps->vps_num_reorder_pics[i]);
|
READ_UE(gb, &vps->vps_max_latency_increase[i]);
|
vps->vps_max_latency_increase[i] = vps->vps_max_latency_increase[i] - 1;
|
|
if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE) {
|
mpp_err( "vps_max_dec_pic_buffering_minus1 out of range: %d\n",
|
vps->vps_max_dec_pic_buffering[i] - 1);
|
goto err;
|
}
|
if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {
|
mpp_err( "vps_max_num_reorder_pics out of range: %d\n",
|
vps->vps_num_reorder_pics[i]);
|
goto err;
|
}
|
}
|
|
READ_BITS(gb, 6, &vps->vps_max_layer_id);
|
READ_UE(gb, &vps->vps_num_layer_sets);
|
vps->vps_num_layer_sets += 1;
|
for (i = 1; i < vps->vps_num_layer_sets; i++)
|
for (j = 0; j <= vps->vps_max_layer_id; j++)
|
SKIP_BITS(gb, 1); // layer_id_included_flag[i][j]
|
|
READ_ONEBIT(gb, &vps->vps_timing_info_present_flag);
|
if (vps->vps_timing_info_present_flag) {
|
mpp_read_longbits(gb, 32, &vps->vps_num_units_in_tick);
|
mpp_read_longbits(gb, 32, &vps->vps_time_scale);
|
READ_ONEBIT(gb, &vps->vps_poc_proportional_to_timing_flag);
|
if (vps->vps_poc_proportional_to_timing_flag) {
|
READ_UE(gb, &vps->vps_num_ticks_poc_diff_one);
|
vps->vps_num_ticks_poc_diff_one += 1;
|
}
|
READ_UE(gb, &vps->vps_num_hrd_parameters);
|
for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
|
RK_S32 common_inf_present = 1;
|
RK_S32 hrd_layer_set_idx = 0;
|
|
READ_UE(gb, &hrd_layer_set_idx); // hrd_layer_set_idx
|
if (i)
|
READ_ONEBIT(gb, &common_inf_present);
|
decode_hrd(s, common_inf_present, vps->vps_max_sub_layers);
|
}
|
}
|
|
// READ_ONEBIT(gb, &vps->vps_extension_flag);
|
|
#ifdef VPS_EXTENSION
|
if (vps->vps_extension_flag) { // vps_extension_flag
|
parse_vps_extension(s, vps);
|
}
|
#endif
|
if (s->h265dctx->compare_info != NULL) {
|
CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info;
|
HEVCVPS *openhevc_vps = (HEVCVPS*)&info->vps[vps_id];
|
mpp_log("compare_vps in \n");
|
if (compare_vps(openhevc_vps, (HEVCVPS*)vps_buf) < 0) {
|
mpp_err("compare_vps return error \n");
|
mpp_assert(0);
|
return -1;
|
}
|
mpp_log("compare_vps ok \n");
|
}
|
|
if (s->vps_list[vps_id] &&
|
!memcmp(s->vps_list[vps_id], vps_buf, sizeof(HEVCVPS))) {
|
mpp_free(vps_buf);
|
} else {
|
if (s->vps_list[vps_id] != NULL) {
|
mpp_free(s->vps_list[vps_id]);
|
}
|
s->vps_list[vps_id] = vps_buf;
|
s->ps_need_upate = 1;
|
}
|
|
return 0;
|
__BITREAD_ERR:
|
err:
|
mpp_free(vps_buf);
|
return MPP_ERR_STREAM;
|
}
|
|
|
static RK_S32 decode_vui(HEVCContext *s, HEVCSPS *sps)
|
{
|
VUI *vui = &sps->vui;
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
RK_S32 sar_present;
|
|
h265d_dbg(H265D_DBG_FUNCTION, "Decoding VUI\n");
|
|
vui->colour_primaries = MPP_FRAME_PRI_UNSPECIFIED;
|
vui->transfer_characteristic = MPP_FRAME_TRC_UNSPECIFIED;
|
vui->matrix_coeffs = MPP_FRAME_SPC_UNSPECIFIED;
|
|
READ_ONEBIT(gb, &sar_present);
|
if (sar_present) {
|
RK_U8 sar_idx = 0;
|
READ_BITS(gb, 8, &sar_idx);
|
if (sar_idx < MPP_ARRAY_ELEMS(vui_sar))
|
vui->sar = vui_sar[sar_idx];
|
else if (sar_idx == 255) {
|
READ_BITS(gb, 16, &vui->sar.num);
|
READ_BITS(gb, 16, &vui->sar.den);
|
} else
|
mpp_log("Unknown SAR index: %u.\n", sar_idx);
|
}
|
|
READ_ONEBIT(gb, &vui->overscan_info_present_flag);
|
if (vui->overscan_info_present_flag)
|
READ_ONEBIT(gb, &vui->overscan_appropriate_flag);
|
|
READ_ONEBIT(gb, &vui->video_signal_type_present_flag);
|
if (vui->video_signal_type_present_flag) {
|
READ_BITS(gb, 3, & vui->video_format);
|
READ_ONEBIT(gb, &vui->video_full_range_flag);
|
READ_ONEBIT(gb, &vui->colour_description_present_flag);
|
|
if (vui->colour_description_present_flag) {
|
READ_BITS(gb, 8, &vui->colour_primaries);
|
READ_BITS(gb, 8, &vui->transfer_characteristic);
|
READ_BITS(gb, 8, &vui->matrix_coeffs);
|
|
// Set invalid values to "unspecified"
|
// if (vui->colour_primaries >= RKCOL_PRI_NB)
|
// vui->colour_primaries = RKCOL_PRI_UNSPECIFIED;
|
// if (vui->transfer_characteristic >= RKCOL_TRC_NB)
|
// vui->transfer_characteristic = RKCOL_TRC_UNSPECIFIED;
|
if (vui->matrix_coeffs >= MPP_FRAME_SPC_NB)
|
vui->matrix_coeffs = MPP_FRAME_SPC_UNSPECIFIED;
|
}
|
}
|
|
READ_ONEBIT(gb, &vui->chroma_loc_info_present_flag );
|
if (vui->chroma_loc_info_present_flag) {
|
READ_UE(gb, &vui->chroma_sample_loc_type_top_field);
|
READ_UE(gb, &vui->chroma_sample_loc_type_bottom_field);
|
}
|
|
READ_ONEBIT(gb, &vui->neutra_chroma_indication_flag);
|
READ_ONEBIT(gb, &vui->field_seq_flag);
|
READ_ONEBIT(gb, &vui->frame_field_info_present_flag);
|
|
READ_ONEBIT(gb, &vui->default_display_window_flag);
|
if (vui->default_display_window_flag) {
|
//TODO: * 2 is only valid for 420
|
READ_UE(gb, &vui->def_disp_win.left_offset);
|
vui->def_disp_win.left_offset = vui->def_disp_win.left_offset * 2;
|
|
READ_UE(gb, &vui->def_disp_win.right_offset);
|
vui->def_disp_win.right_offset = vui->def_disp_win.right_offset * 2;
|
|
READ_UE(gb, &vui->def_disp_win.right_offset);
|
vui->def_disp_win.top_offset = vui->def_disp_win.top_offset * 2;
|
|
READ_UE(gb, &vui->def_disp_win.right_offset);
|
vui->def_disp_win.bottom_offset = vui->def_disp_win.bottom_offset * 2;
|
|
#if 0
|
if (s->apply_defdispwin &&
|
s->h265dctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
|
h265d_dbg(H265D_DBG_SPS,
|
"discarding vui default display window, "
|
"original values are l:%u r:%u t:%u b:%u\n",
|
vui->def_disp_win.left_offset,
|
vui->def_disp_win.right_offset,
|
vui->def_disp_win.top_offset,
|
vui->def_disp_win.bottom_offset);
|
|
vui->def_disp_win.left_offset =
|
vui->def_disp_win.right_offset =
|
vui->def_disp_win.top_offset =
|
vui->def_disp_win.bottom_offset = 0;
|
}
|
#endif
|
}
|
|
READ_ONEBIT(gb, &vui->vui_timing_info_present_flag);
|
|
if (vui->vui_timing_info_present_flag) {
|
mpp_read_longbits(gb, 32, &vui->vui_num_units_in_tick);
|
mpp_read_longbits(gb, 32, &vui->vui_time_scale);
|
READ_ONEBIT(gb, &vui->vui_poc_proportional_to_timing_flag);
|
if (vui->vui_poc_proportional_to_timing_flag)
|
READ_UE(gb, &vui->vui_num_ticks_poc_diff_one_minus1);
|
READ_ONEBIT(gb, &vui->vui_hrd_parameters_present_flag);
|
if (vui->vui_hrd_parameters_present_flag)
|
decode_hrd(s, 1, sps->max_sub_layers);
|
}
|
|
READ_ONEBIT(gb, &vui->bitstream_restriction_flag);
|
if (vui->bitstream_restriction_flag) {
|
READ_ONEBIT(gb, &vui->tiles_fixed_structure_flag);
|
READ_ONEBIT(gb, &vui->motion_vectors_over_pic_boundaries_flag);
|
READ_ONEBIT(gb, &vui->restricted_ref_pic_lists_flag);
|
READ_UE(gb, &vui->min_spatial_segmentation_idc);
|
READ_UE(gb, &vui->max_bytes_per_pic_denom);
|
READ_UE(gb, &vui->max_bits_per_min_cu_denom);
|
READ_UE(gb, &vui->log2_max_mv_length_horizontal);
|
READ_UE(gb, &vui->log2_max_mv_length_vertical);
|
}
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
static void set_default_scaling_list_data(ScalingList *sl)
|
{
|
int matrixId;
|
|
for (matrixId = 0; matrixId < 6; matrixId++) {
|
// 4x4 default is 16
|
memset(sl->sl[0][matrixId], 16, 16);
|
sl->sl_dc[0][matrixId] = 16; // default for 16x16
|
sl->sl_dc[1][matrixId] = 16; // default for 32x32
|
}
|
memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
|
memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
|
memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
|
memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
|
memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
|
memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
|
memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
|
memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
|
memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
|
memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
|
memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
|
memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
|
memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
|
memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
|
memcpy(sl->sl[3][1], default_scaling_list_intra, 64);
|
memcpy(sl->sl[3][2], default_scaling_list_intra, 64);
|
memcpy(sl->sl[3][3], default_scaling_list_inter, 64);
|
memcpy(sl->sl[3][4], default_scaling_list_inter, 64);
|
memcpy(sl->sl[3][5], default_scaling_list_inter, 64);
|
}
|
|
static int scaling_list_data(HEVCContext *s, ScalingList *sl, HEVCSPS *sps)
|
{
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
RK_U8 scaling_list_pred_mode_flag;
|
RK_S32 scaling_list_dc_coef[2][6];
|
RK_S32 size_id, i, pos;
|
RK_U32 matrix_id;
|
|
for (size_id = 0; size_id < 4; size_id++)
|
for (matrix_id = 0; matrix_id < 6; matrix_id += ((size_id == 3) ? 3 : 1)) {
|
READ_ONEBIT(gb, &scaling_list_pred_mode_flag);
|
if (!scaling_list_pred_mode_flag) {
|
RK_U32 delta = 0;
|
READ_UE(gb, &delta);
|
/* Only need to handle non-zero delta. Zero means default,
|
* which should already be in the arrays. */
|
if (delta) {
|
// Copy from previous array.
|
delta *= (size_id == 3) ? 3 : 1;
|
if (matrix_id < delta) {
|
mpp_err(
|
"Invalid delta in scaling list data: %d.\n", delta);
|
return MPP_ERR_STREAM;
|
}
|
|
memcpy(sl->sl[size_id][matrix_id],
|
sl->sl[size_id][matrix_id - delta],
|
size_id > 0 ? 64 : 16);
|
if (size_id > 1)
|
sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];
|
}
|
} else {
|
RK_S32 next_coef, coef_num;
|
RK_S32 scaling_list_delta_coef;
|
|
next_coef = 8;
|
coef_num = MPP_MIN(64, 1 << (4 + (size_id << 1)));
|
if (size_id > 1) {
|
READ_SE(gb, &scaling_list_dc_coef[size_id - 2][matrix_id]);
|
scaling_list_dc_coef[size_id - 2][matrix_id] = scaling_list_dc_coef[size_id - 2][matrix_id] + 8;
|
next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
|
sl->sl_dc[size_id - 2][matrix_id] = next_coef;
|
}
|
for (i = 0; i < coef_num; i++) {
|
if (size_id == 0)
|
pos = 4 * mpp_hevc_diag_scan4x4_y[i] +
|
mpp_hevc_diag_scan4x4_x[i];
|
else
|
pos = 8 * mpp_hevc_diag_scan8x8_y[i] +
|
mpp_hevc_diag_scan8x8_x[i];
|
|
READ_SE(gb, &scaling_list_delta_coef);
|
next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
|
sl->sl[size_id][matrix_id][pos] = next_coef;
|
}
|
}
|
}
|
if (sps->chroma_format_idc == 3) {
|
for (i = 0; i < 64; i++) {
|
sl->sl[3][1][i] = sl->sl[2][1][i];
|
sl->sl[3][2][i] = sl->sl[2][2][i];
|
sl->sl[3][4][i] = sl->sl[2][4][i];
|
sl->sl[3][5][i] = sl->sl[2][5][i];
|
}
|
sl->sl_dc[1][1] = sl->sl_dc[0][1];
|
sl->sl_dc[1][2] = sl->sl_dc[0][2];
|
sl->sl_dc[1][4] = sl->sl_dc[0][4];
|
sl->sl_dc[1][5] = sl->sl_dc[0][5];
|
}
|
return 0;
|
__BITREAD_ERR:
|
return MPP_ERR_STREAM;
|
}
|
|
RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s)
|
{
|
// const AVPixFmtDescriptor *desc;
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
RK_S32 ret = 0;
|
RK_S32 sps_id = 0;
|
RK_S32 log2_diff_max_min_transform_block_size;
|
RK_S32 bit_depth_chroma, start, vui_present, sublayer_ordering_info;
|
RK_S32 i;
|
RK_S32 value = 0;
|
|
HEVCSPS *sps;
|
RK_U8 *sps_buf = mpp_mem_pool_get(s->sps_pool);
|
|
if (!sps_buf)
|
return MPP_ERR_NOMEM;
|
sps = (HEVCSPS*)sps_buf;
|
|
h265d_dbg(H265D_DBG_FUNCTION, "Decoding SPS\n");
|
|
// Coded parameters
|
|
READ_BITS(gb, 4, &sps->vps_id);
|
if (sps->vps_id >= MAX_VPS_COUNT) {
|
mpp_err( "VPS id out of range: %d\n", sps->vps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
if (!s->vps_list[sps->vps_id]) {
|
mpp_err( "VPS %d does not exist\n",
|
sps->vps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
READ_BITS(gb, 3, &sps->max_sub_layers);
|
sps->max_sub_layers += 1;
|
|
if (sps->max_sub_layers > MAX_SUB_LAYERS) {
|
mpp_err( "sps_max_sub_layers out of range: %d\n",
|
sps->max_sub_layers);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
SKIP_BITS(gb, 1); // temporal_id_nesting_flag
|
|
parse_ptl(s, &sps->ptl, sps->max_sub_layers);
|
|
READ_UE(gb, &sps_id);
|
sps->sps_id = sps_id;
|
if (sps_id >= MAX_SPS_COUNT) {
|
mpp_err( "SPS id out of range: %d\n", sps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
READ_UE(gb, &sps->chroma_format_idc);
|
if (sps->chroma_format_idc != 1) {
|
mpp_err("chroma_format_idc != 1\n");
|
ret = MPP_ERR_PROTOL;
|
goto err;
|
}
|
|
if (sps->chroma_format_idc == 3)
|
READ_ONEBIT(gb, &sps->separate_colour_plane_flag);
|
|
READ_UE(gb, &sps->width);
|
READ_UE(gb, &sps->height);
|
|
READ_ONEBIT(gb, &value);
|
|
if (value) { // pic_conformance_flag
|
//TODO: * 2 is only valid for 420
|
READ_UE(gb, &sps->pic_conf_win.left_offset);
|
sps->pic_conf_win.left_offset = sps->pic_conf_win.left_offset * 2;
|
READ_UE(gb, &sps->pic_conf_win.right_offset);
|
sps->pic_conf_win.right_offset = sps->pic_conf_win.right_offset * 2;
|
READ_UE(gb, &sps->pic_conf_win.top_offset);
|
sps->pic_conf_win.top_offset = sps->pic_conf_win.top_offset * 2;
|
READ_UE(gb, &sps->pic_conf_win.bottom_offset);
|
sps->pic_conf_win.bottom_offset = sps->pic_conf_win.bottom_offset * 2;
|
#if 0
|
if (s->h265dctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
|
h265d_dbg(H265D_DBG_SPS,
|
"discarding sps conformance window, "
|
"original values are l:%u r:%u t:%u b:%u\n",
|
sps->pic_conf_win.left_offset,
|
sps->pic_conf_win.right_offset,
|
sps->pic_conf_win.top_offset,
|
sps->pic_conf_win.bottom_offset);
|
|
sps->pic_conf_win.left_offset =
|
sps->pic_conf_win.right_offset =
|
sps->pic_conf_win.top_offset =
|
sps->pic_conf_win.bottom_offset = 0;
|
}
|
|
#endif
|
sps->output_window = sps->pic_conf_win;
|
}
|
|
READ_UE(gb, &sps->bit_depth);
|
|
sps->bit_depth = sps->bit_depth + 8;
|
READ_UE(gb, &bit_depth_chroma);
|
bit_depth_chroma = bit_depth_chroma + 8;
|
sps->bit_depth_chroma = bit_depth_chroma;
|
if (bit_depth_chroma != sps->bit_depth) {
|
mpp_err(
|
"Luma bit depth (%d) is different from chroma bit depth (%d), "
|
"this is unsupported.\n",
|
sps->bit_depth, bit_depth_chroma);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
if (sps->chroma_format_idc == 1) {
|
switch (sps->bit_depth) {
|
case 8: sps->pix_fmt = MPP_FMT_YUV420SP; break;
|
case 10: sps->pix_fmt = MPP_FMT_YUV420SP_10BIT; break;
|
default:
|
mpp_err( "Unsupported bit depth: %d\n",
|
sps->bit_depth);
|
ret = MPP_ERR_PROTOL;
|
goto err;
|
}
|
} else {
|
mpp_err(
|
"non-4:2:0 support is currently unspecified.\n");
|
return MPP_ERR_PROTOL;
|
}
|
#if 0
|
desc = av_pix_fmt_desc_get(sps->pix_fmt);
|
if (!desc) {
|
goto err;
|
}
|
|
sps->hshift[0] = sps->vshift[0] = 0;
|
sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
|
sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
|
#endif
|
sps->pixel_shift = sps->bit_depth > 8;
|
|
READ_UE(gb, &sps->log2_max_poc_lsb);
|
sps->log2_max_poc_lsb += 4;
|
if (sps->log2_max_poc_lsb > 16) {
|
mpp_err( "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
|
sps->log2_max_poc_lsb - 4);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
READ_ONEBIT(gb, &sublayer_ordering_info);
|
h265d_dbg(H265D_DBG_SPS, "read bit left %d", gb->num_remaining_bits_in_curr_byte_ + gb->bytes_left_ * 8);
|
start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
|
for (i = start; i < sps->max_sub_layers; i++) {
|
READ_UE(gb, &sps->temporal_layer[i].max_dec_pic_buffering) ;
|
sps->temporal_layer[i].max_dec_pic_buffering += 1;
|
READ_UE(gb, &sps->temporal_layer[i].num_reorder_pics);
|
READ_UE(gb, &sps->temporal_layer[i].max_latency_increase );
|
sps->temporal_layer[i].max_latency_increase -= 1;
|
if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
|
mpp_err( "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
|
sps->temporal_layer[i].max_dec_pic_buffering - 1);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
|
mpp_err( "sps_max_num_reorder_pics out of range: %d\n",
|
sps->temporal_layer[i].num_reorder_pics);
|
if (sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) {
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1;
|
}
|
}
|
|
if (!sublayer_ordering_info) {
|
for (i = 0; i < start; i++) {
|
sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;
|
sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics;
|
sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase;
|
}
|
}
|
|
h265d_dbg(H265D_DBG_SPS, "2 read bit left %d", gb->num_remaining_bits_in_curr_byte_ + gb->bytes_left_ * 8);
|
READ_UE(gb, &sps->log2_min_cb_size) ;
|
if (sps->log2_min_cb_size > (LOG2_MAX_CU_SIZE - 3)) {
|
mpp_err( "Invalid value for log2_min_cb_size");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
sps->log2_min_cb_size += 3;
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_min_cb_size %d", sps->log2_min_cb_size);
|
READ_UE(gb, &sps->log2_diff_max_min_coding_block_size);
|
if (sps->log2_diff_max_min_coding_block_size > (LOG2_MAX_CU_SIZE - LOG2_MIN_CU_SIZE)) {
|
mpp_err( "Invalid value for log2_diff_max_min_coding_block_size");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_diff_max_min_coding_block_size %d", sps->log2_diff_max_min_coding_block_size);
|
READ_UE(gb, &sps->log2_min_tb_size);
|
if (sps->log2_min_tb_size > (LOG2_MAX_TU_SIZE - 2)) {
|
mpp_err( "Invalid value for log2_min_tb_size");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
sps->log2_min_tb_size += 2;
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_min_tb_size %d", sps->log2_min_tb_size);
|
READ_UE(gb, &log2_diff_max_min_transform_block_size);
|
if (log2_diff_max_min_transform_block_size > (LOG2_MAX_TU_SIZE - LOG2_MIN_TU_SIZE)) {
|
mpp_err( "Invalid value for log2_diff_max_min_transform_block_size");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_diff_max_min_transform_block_size %d", log2_diff_max_min_transform_block_size);
|
sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size +
|
sps->log2_min_tb_size;
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_max_trafo_size %d", sps->log2_max_trafo_size);
|
|
if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {
|
mpp_err( "Invalid value for log2_min_tb_size");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
READ_UE(gb, &sps->max_transform_hierarchy_depth_inter);
|
READ_UE(gb, &sps->max_transform_hierarchy_depth_intra);
|
|
|
READ_ONEBIT(gb, &sps->scaling_list_enable_flag );
|
|
if (sps->scaling_list_enable_flag) {
|
value = 0;
|
set_default_scaling_list_data(&sps->scaling_list);
|
READ_ONEBIT(gb, &value);
|
if (value) {
|
ret = scaling_list_data(s, &sps->scaling_list, sps);
|
if (ret < 0)
|
goto err;
|
}
|
|
s->scaling_list_listen[sps_id] = 1;
|
}
|
|
READ_ONEBIT(gb, &sps->amp_enabled_flag);
|
READ_ONEBIT(gb, &sps->sao_enabled);
|
READ_ONEBIT(gb, &sps->pcm_enabled_flag);
|
|
h265d_dbg(H265D_DBG_SPS, "sps->amp_enabled_flag = %d", sps->amp_enabled_flag);
|
h265d_dbg(H265D_DBG_SPS, "sps->sao_enabled = %d", sps->sao_enabled);
|
h265d_dbg(H265D_DBG_SPS, "sps->pcm_enabled_flag = %d", sps->pcm_enabled_flag);
|
|
if (sps->pcm_enabled_flag) {
|
READ_BITS(gb, 4, &sps->pcm.bit_depth);
|
sps->pcm.bit_depth += 1;
|
READ_BITS(gb, 4, &sps->pcm.bit_depth_chroma);
|
sps->pcm.bit_depth_chroma += 1;
|
READ_UE(gb, &sps->pcm.log2_min_pcm_cb_size );
|
sps->pcm.log2_min_pcm_cb_size += 3;
|
READ_UE(gb, &value);
|
sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size + value;
|
|
if (sps->pcm.bit_depth > sps->bit_depth) {
|
mpp_err(
|
"PCM bit depth (%d) is greater than normal bit depth (%d)\n",
|
sps->pcm.bit_depth, sps->bit_depth);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
READ_ONEBIT(gb, &sps->pcm.loop_filter_disable_flag);
|
}
|
|
READ_UE(gb, &sps->nb_st_rps);
|
if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
|
mpp_err( "Too many short term RPS: %d.\n",
|
sps->nb_st_rps);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
for (i = 0; (RK_U32)i < sps->nb_st_rps; i++) {
|
if ((ret = mpp_hevc_decode_short_term_rps(s, &sps->st_rps[i],
|
sps, 0)) < 0)
|
goto err;
|
}
|
|
READ_ONEBIT(gb, &sps->long_term_ref_pics_present_flag);
|
if (sps->long_term_ref_pics_present_flag) {
|
READ_UE(gb, &sps->num_long_term_ref_pics_sps);
|
for (i = 0; (RK_U8)i < sps->num_long_term_ref_pics_sps; i++) {
|
READ_BITS(gb, sps->log2_max_poc_lsb, &sps->lt_ref_pic_poc_lsb_sps[i]);
|
READ_ONEBIT(gb, &sps->used_by_curr_pic_lt_sps_flag[i]);
|
}
|
}
|
|
READ_ONEBIT(gb, &sps->sps_temporal_mvp_enabled_flag);
|
|
#ifdef REF_IDX_MFM
|
if (s->nuh_layer_id > 0)
|
READ_ONEBIT(gb, &sps->set_mfm_enabled_flag);
|
#endif
|
READ_ONEBIT(gb, &sps->sps_strong_intra_smoothing_enable_flag);
|
|
sps->vui.sar.num = 0;
|
sps->vui.sar.den = 1;
|
READ_ONEBIT(gb, &vui_present);
|
if (vui_present)
|
decode_vui(s, sps);
|
#ifdef SCALED_REF_LAYER_OFFSETS
|
if ( s->nuh_layer_id > 0 ) {
|
READ_SE(gb, &value);
|
sps->scaled_ref_layer_window.left_offset = (value << 1);
|
READ_SE(gb, &value);
|
sps->scaled_ref_layer_window.top_offset = (value << 1);
|
READ_SE(gb, &value);
|
sps->scaled_ref_layer_window.right_offset = (value << 1);
|
READ_SE(gb, &value);
|
sps->scaled_ref_layer_window.bottom_offset = (value << 1);
|
}
|
#endif
|
|
// SKIP_BITS(gb, 1); // sps_extension_flag
|
|
if (s->apply_defdispwin) {
|
sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
|
sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
|
sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
|
sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
|
}
|
#if 1
|
if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift))) {
|
sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
|
mpp_log("Reducing left output window to %d "
|
"chroma samples to preserve alignment.\n",
|
sps->output_window.left_offset);
|
}
|
#endif
|
sps->output_width = sps->width -
|
(sps->output_window.left_offset + sps->output_window.right_offset);
|
sps->output_height = sps->height -
|
(sps->output_window.top_offset + sps->output_window.bottom_offset);
|
if (sps->output_width <= 0 || sps->output_height <= 0) {
|
mpp_log("Invalid visible frame dimensions: %dx%d.\n",
|
sps->output_width, sps->output_height);
|
#if 0
|
if (s->h265dctx->err_recognition & AV_EF_EXPLODE) {
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
#endif
|
mpp_log("Displaying the whole video surface.\n");
|
sps->pic_conf_win.left_offset = 0;
|
sps->pic_conf_win.right_offset = 0;
|
sps->pic_conf_win.top_offset = 0;
|
sps->pic_conf_win.bottom_offset = 0;
|
sps->output_width = sps->width;
|
sps->output_height = sps->height;
|
}
|
|
// NOTE: only do this for the first time of parsing sps
|
// this is for extra data sps/pps parser
|
if (s->h265dctx->width == 0 && s->h265dctx->height == 0) {
|
s->h265dctx->width = sps->output_width;
|
s->h265dctx->height = sps->output_height;
|
}
|
|
// Inferred parameters
|
sps->log2_ctb_size = sps->log2_min_cb_size + sps->log2_diff_max_min_coding_block_size;
|
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_min_cb_size = %d sps->log2_diff_max_min_coding_block_size = %d", sps->log2_min_cb_size, sps->log2_diff_max_min_coding_block_size);
|
|
h265d_dbg(H265D_DBG_SPS, "plus sps->log2_ctb_size %d", sps->log2_ctb_size);
|
sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
|
|
sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
|
sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
|
sps->ctb_size = sps->ctb_width * sps->ctb_height;
|
|
sps->min_cb_width = sps->width >> sps->log2_min_cb_size;
|
sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
|
sps->min_tb_width = sps->width >> sps->log2_min_tb_size;
|
sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
|
sps->min_pu_width = sps->width >> sps->log2_min_pu_size;
|
sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
|
|
sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
|
|
if (sps->width & ((1 << sps->log2_min_cb_size) - 1) ||
|
sps->height & ((1 << sps->log2_min_cb_size) - 1)) {
|
mpp_err( "Invalid coded frame dimensions.\n");
|
goto err;
|
}
|
|
if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
|
mpp_err( "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
|
goto err;
|
}
|
if (sps->max_transform_hierarchy_depth_inter > (RK_S32)(sps->log2_ctb_size - sps->log2_min_tb_size)) {
|
mpp_err( "max_transform_hierarchy_depth_inter out of range: %d\n",
|
sps->max_transform_hierarchy_depth_inter);
|
goto err;
|
}
|
if (sps->max_transform_hierarchy_depth_intra > (RK_S32)(sps->log2_ctb_size - sps->log2_min_tb_size)) {
|
mpp_err( "max_transform_hierarchy_depth_intra out of range: %d\n",
|
sps->max_transform_hierarchy_depth_intra);
|
goto err;
|
}
|
h265d_dbg(H265D_DBG_SPS, "sps->log2_ctb_size %d", sps->log2_ctb_size);
|
if (sps->log2_max_trafo_size > (RK_U32)MPP_MIN(sps->log2_ctb_size, 5)) {
|
mpp_err(
|
"max transform block size out of range: %d\n",
|
sps->log2_max_trafo_size);
|
goto err;
|
}
|
if (s->h265dctx->compare_info != NULL) {
|
CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info;
|
HEVCSPS *openhevc_sps = (HEVCSPS *)&info->sps[sps_id];
|
mpp_log("compare sps in");
|
if (compare_sps(openhevc_sps, (HEVCSPS *)sps_buf) < 0) {
|
mpp_err("compare sps with openhevc error found");
|
mpp_assert(0);
|
return -1;
|
}
|
mpp_log("compare sps ok");
|
}
|
#if 0
|
if (s->h265dctx->debug & FF_DEBUG_BITSTREAM) {
|
h265d_dbg(H265D_DBG_SPS,
|
"Parsed SPS: id %d; coded wxh: %dx%d; "
|
"cropped wxh: %dx%d; pix_fmt: %s.\n",
|
sps_id, sps->width, sps->height,
|
sps->output_width, sps->output_height,
|
av_get_pix_fmt_name(sps->pix_fmt));
|
}
|
#endif
|
/* check if this is a repeat of an already parsed SPS, then keep the
|
* original one.
|
* otherwise drop all PPSes that depend on it */
|
|
if (s->sps_list[sps_id] &&
|
!memcmp(s->sps_list[sps_id], sps_buf, sizeof(HEVCSPS))) {
|
mpp_mem_pool_put(s->sps_pool, sps_buf);
|
} else {
|
for (i = 0; (RK_U32)i < MPP_ARRAY_ELEMS(s->pps_list); i++) {
|
if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i])->sps_id == sps_id) {
|
mpp_hevc_pps_free(s->pps_list[i]);
|
s->pps_list[i] = NULL;
|
}
|
}
|
if (s->sps_list[sps_id] != NULL)
|
mpp_mem_pool_put(s->sps_pool, s->sps_list[sps_id]);
|
s->sps_list[sps_id] = sps_buf;
|
s->ps_need_upate = 1;
|
}
|
|
if (s->sps_list[sps_id])
|
s->sps_list_of_updated[sps_id] = 1;
|
|
return 0;
|
__BITREAD_ERR:
|
err:
|
mpp_mem_pool_put(s->sps_pool, sps_buf);
|
return ret;
|
}
|
|
void mpp_hevc_pps_free(RK_U8 *data)
|
{
|
HEVCPPS *pps = (HEVCPPS*)data;
|
|
if (pps) {
|
MPP_FREE(pps->bufs.column_width);
|
MPP_FREE(pps->bufs.row_height);
|
MPP_FREE(pps);
|
}
|
}
|
|
int mpp_hevc_decode_nal_pps(HEVCContext *s)
|
{
|
BitReadCtx_t *gb = &s->HEVClc->gb;
|
HEVCSPS *sps = NULL;
|
HEVCPPS *pps = NULL;
|
HevcPpsBufInfo *bufs = NULL;
|
RK_S32 buf_size = 0;
|
RK_S32 new_pps = 0;
|
RK_S32 pps_id = 0;
|
RK_S32 ret = 0;
|
RK_S32 i;
|
|
h265d_dbg(H265D_DBG_FUNCTION, "Decoding PPS\n");
|
|
// Coded parameters
|
READ_UE(gb, &pps_id);
|
if (pps_id >= MAX_PPS_COUNT) {
|
mpp_err( "PPS id out of range: %d\n", pps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
pps = (HEVCPPS *)s->pps_list[pps_id];
|
if (pps) {
|
// NOTE: keep tile buffers at the end
|
memset(pps, 0, sizeof(*pps) - sizeof(pps->bufs));
|
} else {
|
pps = (HEVCPPS *)mpp_calloc(RK_U8, sizeof(*pps));
|
new_pps = 1;
|
}
|
|
if (!pps)
|
return MPP_ERR_NOMEM;
|
|
bufs = &pps->bufs;
|
|
pps->pps_id = pps_id;
|
// Default values
|
pps->loop_filter_across_tiles_enabled_flag = 1;
|
pps->num_tile_columns = 1;
|
pps->num_tile_rows = 1;
|
pps->uniform_spacing_flag = 1;
|
pps->disable_dbf = 0;
|
pps->beta_offset = 0;
|
pps->tc_offset = 0;
|
|
READ_UE(gb, &pps->sps_id);
|
if (pps->sps_id >= MAX_SPS_COUNT) {
|
mpp_err( "SPS id out of range: %d\n", pps->sps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
if (!s->sps_list[pps->sps_id]) {
|
mpp_err( "SPS %u does not exist.\n", pps->sps_id);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
sps = (HEVCSPS *)s->sps_list[pps->sps_id];
|
|
h265d_dbg(H265D_DBG_FUNCTION, "Decoding PPS 1\n");
|
READ_ONEBIT(gb, &pps->dependent_slice_segments_enabled_flag);
|
READ_ONEBIT(gb, &pps->output_flag_present_flag );
|
READ_BITS(gb, 3, &pps->num_extra_slice_header_bits);
|
|
READ_ONEBIT(gb, &pps->sign_data_hiding_flag);
|
|
READ_ONEBIT(gb, &pps->cabac_init_present_flag);
|
|
READ_UE(gb, &pps->num_ref_idx_l0_default_active);
|
pps->num_ref_idx_l0_default_active += 1;
|
READ_UE(gb, &pps->num_ref_idx_l1_default_active);
|
pps->num_ref_idx_l1_default_active += 1;
|
|
READ_SE(gb, &pps->pic_init_qp_minus26);
|
|
READ_ONEBIT(gb, & pps->constrained_intra_pred_flag);
|
READ_ONEBIT(gb, &pps->transform_skip_enabled_flag);
|
|
READ_ONEBIT(gb, &pps->cu_qp_delta_enabled_flag);
|
pps->diff_cu_qp_delta_depth = 0;
|
if (pps->cu_qp_delta_enabled_flag)
|
READ_UE(gb, &pps->diff_cu_qp_delta_depth);
|
|
READ_SE(gb, &pps->cb_qp_offset);
|
if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {
|
mpp_err( "pps_cb_qp_offset out of range: %d\n",
|
pps->cb_qp_offset);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
READ_SE(gb, &pps->cr_qp_offset);
|
if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {
|
mpp_err( "pps_cr_qp_offset out of range: %d\n",
|
pps->cr_qp_offset);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
READ_ONEBIT(gb, &pps->pic_slice_level_chroma_qp_offsets_present_flag);
|
|
READ_ONEBIT(gb, &pps->weighted_pred_flag);
|
|
READ_ONEBIT(gb, &pps->weighted_bipred_flag);
|
|
READ_ONEBIT(gb, &pps->transquant_bypass_enable_flag);
|
READ_ONEBIT(gb, &pps->tiles_enabled_flag);
|
READ_ONEBIT(gb, &pps->entropy_coding_sync_enabled_flag);
|
|
// check support solution
|
{
|
RK_S32 max_supt_width = PIXW_1080P;
|
RK_S32 max_supt_height = pps->tiles_enabled_flag ? PIXH_1080P : PIXW_1080P;
|
const MppDecHwCap *hw_info = s->h265dctx->hw_info;
|
|
if (hw_info && hw_info->cap_8k) {
|
max_supt_width = PIXW_8Kx4K;
|
max_supt_height = pps->tiles_enabled_flag ? PIXH_8Kx4K : PIXW_8Kx4K;
|
} else if (hw_info && hw_info->cap_4k) {
|
max_supt_width = PIXW_4Kx2K;
|
max_supt_height = pps->tiles_enabled_flag ? PIXH_4Kx2K : PIXW_4Kx2K;
|
}
|
|
if (sps->width > max_supt_width || sps->height > max_supt_height) {
|
mpp_err("cannot support %dx%d, max solution %dx%d\n",
|
sps->width, sps->height, max_supt_width, max_supt_height);
|
goto err;
|
}
|
}
|
|
if (pps->tiles_enabled_flag) {
|
READ_UE(gb, &pps->num_tile_columns);
|
pps->num_tile_columns += 1;
|
READ_UE(gb, &pps->num_tile_rows);
|
pps->num_tile_rows += 1;
|
if (pps->num_tile_columns == 0 ||
|
pps->num_tile_columns >= sps->width) {
|
mpp_err( "num_tile_columns_minus1 out of range: %d\n",
|
pps->num_tile_columns - 1);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
if (pps->num_tile_rows == 0 ||
|
pps->num_tile_rows >= sps->height) {
|
mpp_err( "num_tile_rows_minus1 out of range: %d\n",
|
pps->num_tile_rows - 1);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
|
buf_size = pps->num_tile_columns * sizeof(RK_U32);
|
if (bufs->column_width_size < buf_size) {
|
bufs->column_width = mpp_malloc_size(RK_U32, buf_size);
|
bufs->column_width_size = buf_size;
|
}
|
|
buf_size = pps->num_tile_rows * sizeof(RK_U32);
|
if (bufs->row_height_size < buf_size) {
|
bufs->row_height = mpp_malloc_size(RK_U32, buf_size);
|
bufs->row_height_size = buf_size;
|
}
|
|
if (!bufs->column_width || !bufs->row_height) {
|
ret = MPP_ERR_NOMEM;
|
goto err;
|
}
|
|
READ_ONEBIT(gb, &pps->uniform_spacing_flag );
|
if (!pps->uniform_spacing_flag) {
|
RK_S32 sum = 0;
|
for (i = 0; i < pps->num_tile_columns - 1; i++) {
|
READ_UE(gb, &bufs->column_width[i]);
|
bufs->column_width[i] += 1;
|
sum += bufs->column_width[i];
|
}
|
if (sum >= sps->ctb_width) {
|
mpp_err( "Invalid tile widths.\n");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
bufs->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;
|
|
sum = 0;
|
for (i = 0; i < pps->num_tile_rows - 1; i++) {
|
READ_UE(gb, &bufs->row_height[i]);
|
bufs->row_height[i] += 1;
|
sum += bufs->row_height[i];
|
}
|
if (sum >= sps->ctb_height) {
|
mpp_err( "Invalid tile heights.\n");
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
bufs->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;
|
}
|
READ_ONEBIT(gb, &pps->loop_filter_across_tiles_enabled_flag);
|
}
|
|
READ_ONEBIT(gb, &pps->seq_loop_filter_across_slices_enabled_flag);
|
READ_ONEBIT(gb, &pps->deblocking_filter_control_present_flag);
|
if (pps->deblocking_filter_control_present_flag) {
|
READ_ONEBIT(gb, &pps->deblocking_filter_override_enabled_flag);
|
READ_ONEBIT(gb, & pps->disable_dbf);
|
if (!pps->disable_dbf) {
|
READ_SE(gb, &pps->beta_offset);
|
pps->beta_offset = pps->beta_offset * 2;
|
READ_SE(gb, &pps->tc_offset);
|
pps->tc_offset = pps->tc_offset * 2;
|
if (pps->beta_offset / 2 < -6 || pps->beta_offset / 2 > 6) {
|
mpp_err( "pps_beta_offset_div2 out of range: %d\n",
|
pps->beta_offset / 2);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
if (pps->tc_offset / 2 < -6 || pps->tc_offset / 2 > 6) {
|
mpp_err( "pps_tc_offset_div2 out of range: %d\n",
|
pps->tc_offset / 2);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
}
|
}
|
|
READ_ONEBIT(gb, &pps->scaling_list_data_present_flag);
|
if (pps->scaling_list_data_present_flag) {
|
set_default_scaling_list_data(&pps->scaling_list);
|
ret = scaling_list_data(s, &pps->scaling_list, sps);
|
|
if (ret < 0)
|
goto err;
|
s->scaling_list_listen[pps_id + 16] = 1;
|
}
|
|
h265d_dbg(H265D_DBG_PPS, "num bit left %d", gb->num_remaining_bits_in_curr_byte_);
|
READ_ONEBIT(gb, & pps->lists_modification_present_flag);
|
|
|
h265d_dbg(H265D_DBG_PPS, "num bit left %d", gb->num_remaining_bits_in_curr_byte_);
|
READ_UE(gb, &pps->log2_parallel_merge_level);
|
|
h265d_dbg(H265D_DBG_PPS, "num bit left %d", gb->num_remaining_bits_in_curr_byte_);
|
pps->log2_parallel_merge_level += 2;
|
if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {
|
mpp_err( "log2_parallel_merge_level_minus2 out of range: %d\n",
|
pps->log2_parallel_merge_level - 2);
|
ret = MPP_ERR_STREAM;
|
goto err;
|
}
|
READ_ONEBIT(gb, &pps->slice_header_extension_present_flag);
|
READ_ONEBIT(gb, &pps->pps_extension_flag);
|
h265d_dbg(H265D_DBG_PPS, "pps_extension_flag %d", pps->pps_extension_flag);
|
if (pps->pps_extension_flag) {
|
READ_ONEBIT(gb, &pps->pps_range_extensions_flag);
|
SKIP_BITS(gb, 7); // pps_extension_7bits
|
}
|
|
if (s->h265dctx->compare_info != NULL) {
|
CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info;
|
HEVCPPS *openhevc_pps = (HEVCPPS*)&info->pps[pps_id];
|
mpp_log("compare pps in");
|
if (compare_pps(openhevc_pps, (HEVCPPS*)pps) < 0) {
|
mpp_err("compare pps with openhevc error found");
|
mpp_assert(0);
|
return -1;
|
}
|
mpp_log("compare pps ok");
|
}
|
|
// Inferred parameters
|
if (pps->uniform_spacing_flag) {
|
buf_size = pps->num_tile_columns * sizeof(RK_U32);
|
if (bufs->column_width_size < buf_size) {
|
bufs->column_width = mpp_malloc_size(RK_U32, buf_size);
|
bufs->column_width_size = buf_size;
|
}
|
|
buf_size = pps->num_tile_rows * sizeof(RK_U32);
|
if (bufs->row_height_size < buf_size) {
|
bufs->row_height = mpp_malloc_size(RK_U32, buf_size);
|
bufs->row_height_size = buf_size;
|
}
|
if (!bufs->column_width || !bufs->row_height) {
|
ret = MPP_ERR_NOMEM;
|
goto err;
|
}
|
|
for (i = 0; i < pps->num_tile_columns; i++) {
|
bufs->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -
|
(i * sps->ctb_width) / pps->num_tile_columns;
|
}
|
|
for (i = 0; i < pps->num_tile_rows; i++) {
|
bufs->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
|
(i * sps->ctb_height) / pps->num_tile_rows;
|
}
|
}
|
|
s->pps_list[pps_id] = (RK_U8 *)pps;
|
s->ps_need_upate = 1;
|
|
if (s->pps_list[pps_id])
|
s->pps_list_of_updated[pps_id] = 1;
|
|
return 0;
|
__BITREAD_ERR:
|
err:
|
if (new_pps)
|
mpp_hevc_pps_free((RK_U8 *)pps);
|
|
return ret;
|
}
|