int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx, HEVCParamSets *ps) { HEVCSPS *sps = NULL; int i, ret = 0; unsigned int pps_id = 0; ptrdiff_t nal_size; AVBufferRef *pps_buf; HEVCPPS *pps = av_mallocz(sizeof(*pps)); if (!pps) return AVERROR(ENOMEM); pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps), hevc_pps_free, NULL, 0); if (!pps_buf) { av_freep(&pps); return AVERROR(ENOMEM); } av_log(avctx, AV_LOG_DEBUG, "Decoding PPS\n"); nal_size = gb->buffer_end - gb->buffer; if (nal_size > sizeof(pps->data)) { av_log(avctx, AV_LOG_WARNING, "Truncating likely oversized PPS " "(%"PTRDIFF_SPECIFIER" > %"SIZE_SPECIFIER")\n", nal_size, sizeof(pps->data)); pps->data_size = sizeof(pps->data); } else { pps->data_size = nal_size; } memcpy(pps->data, gb->buffer, pps->data_size); // 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; pps->log2_max_transform_skip_block_size = 2; // Coded parameters pps_id = get_ue_golomb_long(gb); if (pps_id >= HEVC_MAX_PPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id); ret = AVERROR_INVALIDDATA; goto err; } pps->sps_id = get_ue_golomb_long(gb); if (pps->sps_id >= HEVC_MAX_SPS_COUNT) { av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id); ret = AVERROR_INVALIDDATA; goto err; } if (!ps->sps_list[pps->sps_id]) { av_log(avctx, AV_LOG_ERROR, "SPS %u does not exist.\n", pps->sps_id); ret = AVERROR_INVALIDDATA; goto err; } sps = (HEVCSPS *)ps->sps_list[pps->sps_id]->data; pps->dependent_slice_segments_enabled_flag = get_bits1(gb); pps->output_flag_present_flag = get_bits1(gb); pps->num_extra_slice_header_bits = get_bits(gb, 3); pps->sign_data_hiding_flag = get_bits1(gb); pps->cabac_init_present_flag = get_bits1(gb); pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1; pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1; pps->pic_init_qp_minus26 = get_se_golomb(gb); pps->constrained_intra_pred_flag = get_bits1(gb); pps->transform_skip_enabled_flag = get_bits1(gb); pps->cu_qp_delta_enabled_flag = get_bits1(gb); pps->diff_cu_qp_delta_depth = 0; if (pps->cu_qp_delta_enabled_flag) pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb); if (pps->diff_cu_qp_delta_depth < 0 || pps->diff_cu_qp_delta_depth > sps->log2_diff_max_min_coding_block_size) { av_log(avctx, AV_LOG_ERROR, "diff_cu_qp_delta_depth %d is invalid\n", pps->diff_cu_qp_delta_depth); ret = AVERROR_INVALIDDATA; goto err; } pps->cb_qp_offset = get_se_golomb(gb); if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) { av_log(avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n", pps->cb_qp_offset); ret = AVERROR_INVALIDDATA; goto err; } pps->cr_qp_offset = get_se_golomb(gb); if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) { av_log(avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n", pps->cr_qp_offset); ret = AVERROR_INVALIDDATA; goto err; } pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb); pps->weighted_pred_flag = get_bits1(gb); pps->weighted_bipred_flag = get_bits1(gb); pps->transquant_bypass_enable_flag = get_bits1(gb); pps->tiles_enabled_flag = get_bits1(gb); pps->entropy_coding_sync_enabled_flag = get_bits1(gb); if (pps->tiles_enabled_flag) { pps->num_tile_columns = get_ue_golomb_long(gb) + 1; pps->num_tile_rows = get_ue_golomb_long(gb) + 1; if (pps->num_tile_columns <= 0 || pps->num_tile_columns >= sps->width) { av_log(avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n", pps->num_tile_columns - 1); ret = AVERROR_INVALIDDATA; goto err; } if (pps->num_tile_rows <= 0 || pps->num_tile_rows >= sps->height) { av_log(avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n", pps->num_tile_rows - 1); ret = AVERROR_INVALIDDATA; goto err; } pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width)); pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height)); if (!pps->column_width || !pps->row_height) { ret = AVERROR(ENOMEM); goto err; } pps->uniform_spacing_flag = get_bits1(gb); if (!pps->uniform_spacing_flag) { uint64_t sum = 0; for (i = 0; i < pps->num_tile_columns - 1; i++) { pps->column_width[i] = get_ue_golomb_long(gb) + 1; sum += pps->column_width[i]; } if (sum >= sps->ctb_width) { av_log(avctx, AV_LOG_ERROR, "Invalid tile widths.\n"); ret = AVERROR_INVALIDDATA; goto err; } pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum; sum = 0; for (i = 0; i < pps->num_tile_rows - 1; i++) { pps->row_height[i] = get_ue_golomb_long(gb) + 1; sum += pps->row_height[i]; } if (sum >= sps->ctb_height) { av_log(avctx, AV_LOG_ERROR, "Invalid tile heights.\n"); ret = AVERROR_INVALIDDATA; goto err; } pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum; } pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb); } pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb); pps->deblocking_filter_control_present_flag = get_bits1(gb); if (pps->deblocking_filter_control_present_flag) { pps->deblocking_filter_override_enabled_flag = get_bits1(gb); pps->disable_dbf = get_bits1(gb); if (!pps->disable_dbf) { int beta_offset_div2 = get_se_golomb(gb); int tc_offset_div2 = get_se_golomb(gb) ; if (beta_offset_div2 < -6 || beta_offset_div2 > 6) { av_log(avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n", beta_offset_div2); ret = AVERROR_INVALIDDATA; goto err; } if (tc_offset_div2 < -6 || tc_offset_div2 > 6) { av_log(avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n", tc_offset_div2); ret = AVERROR_INVALIDDATA; goto err; } pps->beta_offset = 2 * beta_offset_div2; pps->tc_offset = 2 * tc_offset_div2; } } pps->scaling_list_data_present_flag = get_bits1(gb); if (pps->scaling_list_data_present_flag) { set_default_scaling_list_data(&pps->scaling_list); ret = scaling_list_data(gb, avctx, &pps->scaling_list, sps); if (ret < 0) goto err; } pps->lists_modification_present_flag = get_bits1(gb); pps->log2_parallel_merge_level = get_ue_golomb_long(gb) + 2; if (pps->log2_parallel_merge_level > sps->log2_ctb_size) { av_log(avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n", pps->log2_parallel_merge_level - 2); ret = AVERROR_INVALIDDATA; goto err; } pps->slice_header_extension_present_flag = get_bits1(gb); if (get_bits1(gb)) { // pps_extension_present_flag int pps_range_extensions_flag = get_bits1(gb); /* int pps_extension_7bits = */ get_bits(gb, 7); if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) { if ((ret = pps_range_extensions(gb, avctx, pps, sps)) < 0) goto err; } } ret = setup_pps(avctx, gb, pps, sps); if (ret < 0) goto err; if (get_bits_left(gb) < 0) { av_log(avctx, AV_LOG_ERROR, "Overread PPS by %d bits\n", -get_bits_left(gb)); goto err; } remove_pps(ps, pps_id); ps->pps_list[pps_id] = pps_buf; return 0; err: av_buffer_unref(&pps_buf); return ret; }