mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
8c399bd5ce
ucNumDeltaPocsOfRefRpsIdx needs to contain the flat value from the SPS RPS, and not the final computed value from the slice header RPS, as this calculation is done internally by the driver again. Sample-Id: http://trailers.divx.com/hevc/Sintel_4k_27qp_24fps_1aud_9subs.mkvi Signed-off-by: Rémi Denis-Courmont <remi@remlab.net>
1376 lines
51 KiB
C
1376 lines
51 KiB
C
/*
|
|
* HEVC Parameter Set decoding
|
|
*
|
|
* Copyright (C) 2012 - 2103 Guillaume Martres
|
|
* Copyright (C) 2012 - 2103 Mickael Raulet
|
|
* Copyright (C) 2012 - 2013 Gildas Cocherel
|
|
* Copyright (C) 2013 Vittorio Giovara
|
|
*
|
|
* This file is part of Libav.
|
|
*
|
|
* Libav is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* Libav 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with Libav; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "libavutil/imgutils.h"
|
|
|
|
#include "golomb.h"
|
|
#include "hevc.h"
|
|
|
|
static const uint8_t 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 uint8_t 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 AVRational 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 },
|
|
};
|
|
|
|
static void remove_pps(HEVCParamSets *s, int id)
|
|
{
|
|
if (s->pps_list[id] && s->pps == (const HEVCPPS*)s->pps_list[id]->data)
|
|
s->pps = NULL;
|
|
av_buffer_unref(&s->pps_list[id]);
|
|
}
|
|
|
|
static void remove_sps(HEVCParamSets *s, int id)
|
|
{
|
|
int i;
|
|
if (s->sps_list[id]) {
|
|
if (s->sps == (const HEVCSPS*)s->sps_list[id]->data)
|
|
s->sps = NULL;
|
|
|
|
/* drop all PPS that depend on this SPS */
|
|
for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
|
|
if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == id)
|
|
remove_pps(s, i);
|
|
}
|
|
av_buffer_unref(&s->sps_list[id]);
|
|
}
|
|
|
|
static void remove_vps(HEVCParamSets *s, int id)
|
|
{
|
|
int i;
|
|
if (s->vps_list[id]) {
|
|
if (s->vps == (const HEVCVPS*)s->vps_list[id]->data)
|
|
s->vps = NULL;
|
|
|
|
for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
|
|
if (s->sps_list[i] && ((HEVCSPS*)s->sps_list[i]->data)->vps_id == id)
|
|
remove_sps(s, i);
|
|
}
|
|
av_buffer_unref(&s->vps_list[id]);
|
|
}
|
|
|
|
int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
|
|
ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header)
|
|
{
|
|
uint8_t rps_predict = 0;
|
|
int delta_poc;
|
|
int k0 = 0;
|
|
int k1 = 0;
|
|
int k = 0;
|
|
int i;
|
|
|
|
if (rps != sps->st_rps && sps->nb_st_rps)
|
|
rps_predict = get_bits1(gb);
|
|
|
|
if (rps_predict) {
|
|
const ShortTermRPS *rps_ridx;
|
|
int delta_rps, abs_delta_rps;
|
|
uint8_t use_delta_flag = 0;
|
|
uint8_t delta_rps_sign;
|
|
|
|
if (is_slice_header) {
|
|
unsigned int delta_idx = get_ue_golomb_long(gb) + 1;
|
|
if (delta_idx > sps->nb_st_rps) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Invalid value of delta_idx in slice header RPS: %d > %d.\n",
|
|
delta_idx, sps->nb_st_rps);
|
|
return AVERROR_INVALIDDATA;
|
|
}
|
|
rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
|
|
rps->rps_idx_num_delta_pocs = rps_ridx->num_delta_pocs;
|
|
} else
|
|
rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
|
|
|
|
delta_rps_sign = get_bits1(gb);
|
|
abs_delta_rps = get_ue_golomb_long(gb) + 1;
|
|
delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
|
|
for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
|
|
int used = rps->used[k] = get_bits1(gb);
|
|
|
|
if (!used)
|
|
use_delta_flag = get_bits1(gb);
|
|
|
|
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) {
|
|
int 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) {
|
|
int used;
|
|
k = rps->num_negative_pics - 1;
|
|
// flip the negative values to largest first
|
|
for (i = 0; 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 {
|
|
unsigned int prev, nb_positive_pics;
|
|
rps->num_negative_pics = get_ue_golomb_long(gb);
|
|
nb_positive_pics = get_ue_golomb_long(gb);
|
|
|
|
if (rps->num_negative_pics >= MAX_REFS ||
|
|
nb_positive_pics >= MAX_REFS) {
|
|
av_log(avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");
|
|
return AVERROR_INVALIDDATA;
|
|
}
|
|
|
|
rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
|
|
if (rps->num_delta_pocs) {
|
|
prev = 0;
|
|
for (i = 0; i < rps->num_negative_pics; i++) {
|
|
delta_poc = get_ue_golomb_long(gb) + 1;
|
|
prev -= delta_poc;
|
|
rps->delta_poc[i] = prev;
|
|
rps->used[i] = get_bits1(gb);
|
|
}
|
|
prev = 0;
|
|
for (i = 0; i < nb_positive_pics; i++) {
|
|
delta_poc = get_ue_golomb_long(gb) + 1;
|
|
prev += delta_poc;
|
|
rps->delta_poc[rps->num_negative_pics + i] = prev;
|
|
rps->used[rps->num_negative_pics + i] = get_bits1(gb);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,
|
|
PTLCommon *ptl)
|
|
{
|
|
int i;
|
|
|
|
ptl->profile_space = get_bits(gb, 2);
|
|
ptl->tier_flag = get_bits1(gb);
|
|
ptl->profile_idc = get_bits(gb, 5);
|
|
if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)
|
|
av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
|
|
else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)
|
|
av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
|
|
else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)
|
|
av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
|
|
else
|
|
av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
|
|
|
|
for (i = 0; i < 32; i++)
|
|
ptl->profile_compatibility_flag[i] = get_bits1(gb);
|
|
ptl->progressive_source_flag = get_bits1(gb);
|
|
ptl->interlaced_source_flag = get_bits1(gb);
|
|
ptl->non_packed_constraint_flag = get_bits1(gb);
|
|
ptl->frame_only_constraint_flag = get_bits1(gb);
|
|
|
|
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]
|
|
}
|
|
|
|
static void parse_ptl(GetBitContext *gb, AVCodecContext *avctx,
|
|
PTL *ptl, int max_num_sub_layers)
|
|
{
|
|
int i;
|
|
decode_profile_tier_level(gb, avctx, &ptl->general_ptl);
|
|
ptl->general_ptl.level_idc = get_bits(gb, 8);
|
|
|
|
for (i = 0; i < max_num_sub_layers - 1; i++) {
|
|
ptl->sub_layer_profile_present_flag[i] = get_bits1(gb);
|
|
ptl->sub_layer_level_present_flag[i] = get_bits1(gb);
|
|
}
|
|
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(gb, avctx, &ptl->sub_layer_ptl[i]);
|
|
if (ptl->sub_layer_level_present_flag[i])
|
|
ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8);
|
|
}
|
|
}
|
|
|
|
static void decode_sublayer_hrd(GetBitContext *gb, unsigned int nb_cpb,
|
|
int subpic_params_present)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < nb_cpb; i++) {
|
|
get_ue_golomb_long(gb); // bit_rate_value_minus1
|
|
get_ue_golomb_long(gb); // cpb_size_value_minus1
|
|
|
|
if (subpic_params_present) {
|
|
get_ue_golomb_long(gb); // cpb_size_du_value_minus1
|
|
get_ue_golomb_long(gb); // bit_rate_du_value_minus1
|
|
}
|
|
skip_bits1(gb); // cbr_flag
|
|
}
|
|
}
|
|
|
|
static void decode_hrd(GetBitContext *gb, int common_inf_present,
|
|
int max_sublayers)
|
|
{
|
|
int nal_params_present = 0, vcl_params_present = 0;
|
|
int subpic_params_present = 0;
|
|
int i;
|
|
|
|
if (common_inf_present) {
|
|
nal_params_present = get_bits1(gb);
|
|
vcl_params_present = get_bits1(gb);
|
|
|
|
if (nal_params_present || vcl_params_present) {
|
|
subpic_params_present = get_bits1(gb);
|
|
|
|
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++) {
|
|
int low_delay = 0;
|
|
unsigned int nb_cpb = 1;
|
|
int fixed_rate = get_bits1(gb);
|
|
|
|
if (!fixed_rate)
|
|
fixed_rate = get_bits1(gb);
|
|
|
|
if (fixed_rate)
|
|
get_ue_golomb_long(gb); // elemental_duration_in_tc_minus1
|
|
else
|
|
low_delay = get_bits1(gb);
|
|
|
|
if (!low_delay)
|
|
nb_cpb = get_ue_golomb_long(gb) + 1;
|
|
|
|
if (nal_params_present)
|
|
decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
|
|
if (vcl_params_present)
|
|
decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
|
|
}
|
|
}
|
|
|
|
int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
|
|
HEVCParamSets *ps)
|
|
{
|
|
int i,j;
|
|
int vps_id = 0;
|
|
HEVCVPS *vps;
|
|
AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));
|
|
|
|
if (!vps_buf)
|
|
return AVERROR(ENOMEM);
|
|
vps = (HEVCVPS*)vps_buf->data;
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Decoding VPS\n");
|
|
|
|
vps_id = get_bits(gb, 4);
|
|
if (vps_id >= MAX_VPS_COUNT) {
|
|
av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);
|
|
goto err;
|
|
}
|
|
|
|
if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
|
|
av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
|
|
goto err;
|
|
}
|
|
|
|
vps->vps_max_layers = get_bits(gb, 6) + 1;
|
|
vps->vps_max_sub_layers = get_bits(gb, 3) + 1;
|
|
vps->vps_temporal_id_nesting_flag = get_bits1(gb);
|
|
|
|
if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits
|
|
av_log(avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");
|
|
goto err;
|
|
}
|
|
|
|
if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
|
|
av_log(avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",
|
|
vps->vps_max_sub_layers);
|
|
goto err;
|
|
}
|
|
|
|
parse_ptl(gb, avctx, &vps->ptl, vps->vps_max_sub_layers);
|
|
|
|
vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
|
|
|
|
i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
|
|
for (; i < vps->vps_max_sub_layers; i++) {
|
|
vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;
|
|
vps->vps_num_reorder_pics[i] = get_ue_golomb_long(gb);
|
|
vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1;
|
|
|
|
if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE) {
|
|
av_log(avctx, AV_LOG_ERROR, "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) {
|
|
av_log(avctx, AV_LOG_WARNING, "vps_max_num_reorder_pics out of range: %d\n",
|
|
vps->vps_num_reorder_pics[i]);
|
|
if (avctx->err_recognition & AV_EF_EXPLODE)
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
vps->vps_max_layer_id = get_bits(gb, 6);
|
|
vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 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]
|
|
|
|
vps->vps_timing_info_present_flag = get_bits1(gb);
|
|
if (vps->vps_timing_info_present_flag) {
|
|
vps->vps_num_units_in_tick = get_bits_long(gb, 32);
|
|
vps->vps_time_scale = get_bits_long(gb, 32);
|
|
vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);
|
|
if (vps->vps_poc_proportional_to_timing_flag)
|
|
vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;
|
|
vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);
|
|
for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
|
|
int common_inf_present = 1;
|
|
|
|
get_ue_golomb_long(gb); // hrd_layer_set_idx
|
|
if (i)
|
|
common_inf_present = get_bits1(gb);
|
|
decode_hrd(gb, common_inf_present, vps->vps_max_sub_layers);
|
|
}
|
|
}
|
|
get_bits1(gb); /* vps_extension_flag */
|
|
|
|
if (ps->vps_list[vps_id] &&
|
|
!memcmp(ps->vps_list[vps_id]->data, vps_buf->data, vps_buf->size)) {
|
|
av_buffer_unref(&vps_buf);
|
|
} else {
|
|
remove_vps(ps, vps_id);
|
|
ps->vps_list[vps_id] = vps_buf;
|
|
}
|
|
|
|
return 0;
|
|
|
|
err:
|
|
av_buffer_unref(&vps_buf);
|
|
return AVERROR_INVALIDDATA;
|
|
}
|
|
|
|
static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
|
|
int apply_defdispwin, HEVCSPS *sps)
|
|
{
|
|
VUI *vui = &sps->vui;
|
|
int sar_present;
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n");
|
|
|
|
sar_present = get_bits1(gb);
|
|
if (sar_present) {
|
|
uint8_t sar_idx = get_bits(gb, 8);
|
|
if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
|
|
vui->sar = vui_sar[sar_idx];
|
|
else if (sar_idx == 255) {
|
|
vui->sar.num = get_bits(gb, 16);
|
|
vui->sar.den = get_bits(gb, 16);
|
|
} else
|
|
av_log(avctx, AV_LOG_WARNING,
|
|
"Unknown SAR index: %u.\n", sar_idx);
|
|
}
|
|
|
|
vui->overscan_info_present_flag = get_bits1(gb);
|
|
if (vui->overscan_info_present_flag)
|
|
vui->overscan_appropriate_flag = get_bits1(gb);
|
|
|
|
vui->video_signal_type_present_flag = get_bits1(gb);
|
|
if (vui->video_signal_type_present_flag) {
|
|
vui->video_format = get_bits(gb, 3);
|
|
vui->video_full_range_flag = get_bits1(gb);
|
|
vui->colour_description_present_flag = get_bits1(gb);
|
|
if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
|
|
sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
|
|
if (vui->colour_description_present_flag) {
|
|
vui->colour_primaries = get_bits(gb, 8);
|
|
vui->transfer_characteristic = get_bits(gb, 8);
|
|
vui->matrix_coeffs = get_bits(gb, 8);
|
|
|
|
// Set invalid values to "unspecified"
|
|
if (vui->colour_primaries >= AVCOL_PRI_NB)
|
|
vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
|
|
if (vui->transfer_characteristic >= AVCOL_TRC_NB)
|
|
vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
|
|
if (vui->matrix_coeffs >= AVCOL_SPC_NB)
|
|
vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
|
|
}
|
|
}
|
|
|
|
vui->chroma_loc_info_present_flag = get_bits1(gb);
|
|
if (vui->chroma_loc_info_present_flag) {
|
|
vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb);
|
|
vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
|
|
}
|
|
|
|
vui->neutra_chroma_indication_flag = get_bits1(gb);
|
|
vui->field_seq_flag = get_bits1(gb);
|
|
vui->frame_field_info_present_flag = get_bits1(gb);
|
|
|
|
vui->default_display_window_flag = get_bits1(gb);
|
|
if (vui->default_display_window_flag) {
|
|
//TODO: * 2 is only valid for 420
|
|
vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * 2;
|
|
vui->def_disp_win.right_offset = get_ue_golomb_long(gb) * 2;
|
|
vui->def_disp_win.top_offset = get_ue_golomb_long(gb) * 2;
|
|
vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * 2;
|
|
|
|
if (apply_defdispwin &&
|
|
avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
|
|
av_log(avctx, AV_LOG_DEBUG,
|
|
"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;
|
|
}
|
|
}
|
|
|
|
vui->vui_timing_info_present_flag = get_bits1(gb);
|
|
if (vui->vui_timing_info_present_flag) {
|
|
vui->vui_num_units_in_tick = get_bits_long(gb, 32);
|
|
vui->vui_time_scale = get_bits_long(gb, 32);
|
|
vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
|
|
if (vui->vui_poc_proportional_to_timing_flag)
|
|
vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
|
|
vui->vui_hrd_parameters_present_flag = get_bits1(gb);
|
|
if (vui->vui_hrd_parameters_present_flag)
|
|
decode_hrd(gb, 1, sps->max_sub_layers);
|
|
}
|
|
|
|
vui->bitstream_restriction_flag = get_bits1(gb);
|
|
if (vui->bitstream_restriction_flag) {
|
|
vui->tiles_fixed_structure_flag = get_bits1(gb);
|
|
vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb);
|
|
vui->restricted_ref_pic_lists_flag = get_bits1(gb);
|
|
vui->min_spatial_segmentation_idc = get_ue_golomb_long(gb);
|
|
vui->max_bytes_per_pic_denom = get_ue_golomb_long(gb);
|
|
vui->max_bits_per_min_cu_denom = get_ue_golomb_long(gb);
|
|
vui->log2_max_mv_length_horizontal = get_ue_golomb_long(gb);
|
|
vui->log2_max_mv_length_vertical = get_ue_golomb_long(gb);
|
|
}
|
|
}
|
|
|
|
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][1], default_scaling_list_inter, 64);
|
|
}
|
|
|
|
static int scaling_list_data(GetBitContext *gb, AVCodecContext *avctx, ScalingList *sl)
|
|
{
|
|
uint8_t scaling_list_pred_mode_flag[4][6];
|
|
int32_t scaling_list_dc_coef[2][6];
|
|
int size_id, matrix_id, i, pos;
|
|
|
|
for (size_id = 0; size_id < 4; size_id++)
|
|
for (matrix_id = 0; matrix_id < (size_id == 3 ? 2 : 6); matrix_id++) {
|
|
scaling_list_pred_mode_flag[size_id][matrix_id] = get_bits1(gb);
|
|
if (!scaling_list_pred_mode_flag[size_id][matrix_id]) {
|
|
unsigned int delta = get_ue_golomb_long(gb);
|
|
/* Only need to handle non-zero delta. Zero means default,
|
|
* which should already be in the arrays. */
|
|
if (delta) {
|
|
// Copy from previous array.
|
|
if (matrix_id < delta) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Invalid delta in scaling list data: %d.\n", delta);
|
|
return AVERROR_INVALIDDATA;
|
|
}
|
|
|
|
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 {
|
|
int next_coef, coef_num;
|
|
int32_t scaling_list_delta_coef;
|
|
|
|
next_coef = 8;
|
|
coef_num = FFMIN(64, 1 << (4 + (size_id << 1)));
|
|
if (size_id > 1) {
|
|
scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 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 * ff_hevc_diag_scan4x4_y[i] +
|
|
ff_hevc_diag_scan4x4_x[i];
|
|
else
|
|
pos = 8 * ff_hevc_diag_scan8x8_y[i] +
|
|
ff_hevc_diag_scan8x8_x[i];
|
|
|
|
scaling_list_delta_coef = get_se_golomb(gb);
|
|
next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
|
|
sl->sl[size_id][matrix_id][pos] = next_coef;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps)
|
|
{
|
|
const AVPixFmtDescriptor *desc;
|
|
if (sps->chroma_format_idc == 1) {
|
|
switch (sps->bit_depth) {
|
|
case 8: sps->pix_fmt = AV_PIX_FMT_YUV420P; break;
|
|
case 9: sps->pix_fmt = AV_PIX_FMT_YUV420P9; break;
|
|
case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;
|
|
default:
|
|
av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
|
|
sps->bit_depth);
|
|
return AVERROR_PATCHWELCOME;
|
|
}
|
|
} else {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"non-4:2:0 support is currently unspecified.\n");
|
|
return AVERROR_PATCHWELCOME;
|
|
}
|
|
|
|
desc = av_pix_fmt_desc_get(sps->pix_fmt);
|
|
if (!desc)
|
|
return AVERROR(EINVAL);
|
|
|
|
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;
|
|
|
|
sps->pixel_shift = sps->bit_depth > 8;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
|
|
int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx)
|
|
{
|
|
int ret = 0;
|
|
int log2_diff_max_min_transform_block_size;
|
|
int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
|
|
int i;
|
|
|
|
// Coded parameters
|
|
|
|
sps->vps_id = get_bits(gb, 4);
|
|
if (sps->vps_id >= MAX_VPS_COUNT) {
|
|
av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
if (vps_list && !vps_list[sps->vps_id]) {
|
|
av_log(avctx, AV_LOG_ERROR, "VPS %d does not exist\n",
|
|
sps->vps_id);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
sps->max_sub_layers = get_bits(gb, 3) + 1;
|
|
if (sps->max_sub_layers > MAX_SUB_LAYERS) {
|
|
av_log(avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
|
|
sps->max_sub_layers);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
skip_bits1(gb); // temporal_id_nesting_flag
|
|
|
|
parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers);
|
|
|
|
*sps_id = get_ue_golomb_long(gb);
|
|
if (*sps_id >= MAX_SPS_COUNT) {
|
|
av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", *sps_id);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
sps->chroma_format_idc = get_ue_golomb_long(gb);
|
|
if (sps->chroma_format_idc != 1) {
|
|
avpriv_report_missing_feature(avctx, "chroma_format_idc %d",
|
|
sps->chroma_format_idc);
|
|
ret = AVERROR_PATCHWELCOME;
|
|
goto err;
|
|
}
|
|
|
|
if (sps->chroma_format_idc == 3)
|
|
sps->separate_colour_plane_flag = get_bits1(gb);
|
|
|
|
sps->width = get_ue_golomb_long(gb);
|
|
sps->height = get_ue_golomb_long(gb);
|
|
if ((ret = av_image_check_size(sps->width,
|
|
sps->height, 0, avctx)) < 0)
|
|
goto err;
|
|
|
|
if (get_bits1(gb)) { // pic_conformance_flag
|
|
//TODO: * 2 is only valid for 420
|
|
sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * 2;
|
|
sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * 2;
|
|
sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * 2;
|
|
sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;
|
|
|
|
if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
|
|
av_log(avctx, AV_LOG_DEBUG,
|
|
"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;
|
|
}
|
|
sps->output_window = sps->pic_conf_win;
|
|
}
|
|
|
|
sps->bit_depth = get_ue_golomb_long(gb) + 8;
|
|
bit_depth_chroma = get_ue_golomb_long(gb) + 8;
|
|
if (bit_depth_chroma != sps->bit_depth) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Luma bit depth (%d) is different from chroma bit depth (%d), "
|
|
"this is unsupported.\n",
|
|
sps->bit_depth, bit_depth_chroma);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
|
|
ret = map_pixel_format(avctx, sps);
|
|
if (ret < 0)
|
|
goto err;
|
|
|
|
sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;
|
|
if (sps->log2_max_poc_lsb > 16) {
|
|
av_log(avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
|
|
sps->log2_max_poc_lsb - 4);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
sublayer_ordering_info = get_bits1(gb);
|
|
start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
|
|
for (i = start; i < sps->max_sub_layers; i++) {
|
|
sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;
|
|
sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb);
|
|
sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1;
|
|
if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
|
|
av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
|
|
sps->temporal_layer[i].max_dec_pic_buffering - 1);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
|
|
av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n",
|
|
sps->temporal_layer[i].num_reorder_pics);
|
|
if (avctx->err_recognition & AV_EF_EXPLODE ||
|
|
sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) {
|
|
ret = AVERROR_INVALIDDATA;
|
|
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;
|
|
}
|
|
}
|
|
|
|
sps->log2_min_cb_size = get_ue_golomb_long(gb) + 3;
|
|
sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);
|
|
sps->log2_min_tb_size = get_ue_golomb_long(gb) + 2;
|
|
log2_diff_max_min_transform_block_size = get_ue_golomb_long(gb);
|
|
sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size +
|
|
sps->log2_min_tb_size;
|
|
|
|
if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
|
|
sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
|
|
|
|
sps->scaling_list_enable_flag = get_bits1(gb);
|
|
if (sps->scaling_list_enable_flag) {
|
|
set_default_scaling_list_data(&sps->scaling_list);
|
|
|
|
if (get_bits1(gb)) {
|
|
ret = scaling_list_data(gb, avctx, &sps->scaling_list);
|
|
if (ret < 0)
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
sps->amp_enabled_flag = get_bits1(gb);
|
|
sps->sao_enabled = get_bits1(gb);
|
|
|
|
sps->pcm_enabled_flag = get_bits1(gb);
|
|
if (sps->pcm_enabled_flag) {
|
|
sps->pcm.bit_depth = get_bits(gb, 4) + 1;
|
|
sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;
|
|
sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;
|
|
sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
|
|
get_ue_golomb_long(gb);
|
|
if (sps->pcm.bit_depth > sps->bit_depth) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"PCM bit depth (%d) is greater than normal bit depth (%d)\n",
|
|
sps->pcm.bit_depth, sps->bit_depth);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
|
|
sps->pcm.loop_filter_disable_flag = get_bits1(gb);
|
|
}
|
|
|
|
sps->nb_st_rps = get_ue_golomb_long(gb);
|
|
if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
|
|
av_log(avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
|
|
sps->nb_st_rps);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
for (i = 0; i < sps->nb_st_rps; i++) {
|
|
if ((ret = ff_hevc_decode_short_term_rps(gb, avctx, &sps->st_rps[i],
|
|
sps, 0)) < 0)
|
|
goto err;
|
|
}
|
|
|
|
sps->long_term_ref_pics_present_flag = get_bits1(gb);
|
|
if (sps->long_term_ref_pics_present_flag) {
|
|
sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
|
|
for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
|
|
sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(gb, sps->log2_max_poc_lsb);
|
|
sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
|
|
}
|
|
}
|
|
|
|
sps->sps_temporal_mvp_enabled_flag = get_bits1(gb);
|
|
sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
|
|
sps->vui.sar = (AVRational){0, 1};
|
|
vui_present = get_bits1(gb);
|
|
if (vui_present)
|
|
decode_vui(gb, avctx, apply_defdispwin, sps);
|
|
skip_bits1(gb); // sps_extension_flag
|
|
|
|
if (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 (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
|
|
!(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
|
|
sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
|
|
av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d "
|
|
"chroma samples to preserve alignment.\n",
|
|
sps->output_window.left_offset);
|
|
}
|
|
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) {
|
|
av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
|
|
sps->output_width, sps->output_height);
|
|
if (avctx->err_recognition & AV_EF_EXPLODE) {
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
av_log(avctx, AV_LOG_WARNING,
|
|
"Displaying the whole video surface.\n");
|
|
sps->output_window.left_offset =
|
|
sps->output_window.right_offset =
|
|
sps->output_window.top_offset =
|
|
sps->output_window.bottom_offset = 0;
|
|
sps->output_width = sps->width;
|
|
sps->output_height = sps->height;
|
|
}
|
|
|
|
// Inferred parameters
|
|
sps->log2_ctb_size = sps->log2_min_cb_size +
|
|
sps->log2_diff_max_min_coding_block_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)) {
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
|
|
goto err;
|
|
}
|
|
|
|
if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
|
|
av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
|
|
goto err;
|
|
}
|
|
if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
|
|
av_log(avctx, AV_LOG_ERROR, "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 > sps->log2_ctb_size - sps->log2_min_tb_size) {
|
|
av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",
|
|
sps->max_transform_hierarchy_depth_intra);
|
|
goto err;
|
|
}
|
|
if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"max transform block size out of range: %d\n",
|
|
sps->log2_max_trafo_size);
|
|
goto err;
|
|
}
|
|
|
|
return 0;
|
|
|
|
err:
|
|
return ret < 0 ? ret : AVERROR_INVALIDDATA;
|
|
}
|
|
|
|
int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx,
|
|
HEVCParamSets *ps, int apply_defdispwin)
|
|
{
|
|
HEVCSPS *sps;
|
|
AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
|
|
unsigned int sps_id;
|
|
int ret;
|
|
|
|
if (!sps_buf)
|
|
return AVERROR(ENOMEM);
|
|
sps = (HEVCSPS*)sps_buf->data;
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Decoding SPS\n");
|
|
|
|
ret = ff_hevc_parse_sps(sps, gb, &sps_id,
|
|
apply_defdispwin,
|
|
ps->vps_list, avctx);
|
|
if (ret < 0) {
|
|
av_buffer_unref(&sps_buf);
|
|
return ret;
|
|
}
|
|
|
|
if (avctx->debug & FF_DEBUG_BITSTREAM) {
|
|
av_log(avctx, AV_LOG_DEBUG,
|
|
"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));
|
|
}
|
|
|
|
/* 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 (ps->sps_list[sps_id] &&
|
|
!memcmp(ps->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
|
|
av_buffer_unref(&sps_buf);
|
|
} else {
|
|
remove_sps(ps, sps_id);
|
|
ps->sps_list[sps_id] = sps_buf;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void hevc_pps_free(void *opaque, uint8_t *data)
|
|
{
|
|
HEVCPPS *pps = (HEVCPPS*)data;
|
|
|
|
av_freep(&pps->column_width);
|
|
av_freep(&pps->row_height);
|
|
av_freep(&pps->col_bd);
|
|
av_freep(&pps->row_bd);
|
|
av_freep(&pps->col_idxX);
|
|
av_freep(&pps->ctb_addr_rs_to_ts);
|
|
av_freep(&pps->ctb_addr_ts_to_rs);
|
|
av_freep(&pps->tile_pos_rs);
|
|
av_freep(&pps->tile_id);
|
|
av_freep(&pps->min_tb_addr_zs);
|
|
|
|
av_freep(&pps);
|
|
}
|
|
|
|
static inline int setup_pps(AVCodecContext *avctx, GetBitContext *gb,
|
|
HEVCPPS *pps, HEVCSPS *sps)
|
|
{
|
|
int log2_diff;
|
|
int pic_area_in_ctbs, pic_area_in_min_tbs;
|
|
int i, j, x, y, ctb_addr_rs, tile_id;
|
|
|
|
// Inferred parameters
|
|
pps->col_bd = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));
|
|
pps->row_bd = av_malloc_array(pps->num_tile_rows + 1, sizeof(*pps->row_bd));
|
|
pps->col_idxX = av_malloc_array(sps->ctb_width, sizeof(*pps->col_idxX));
|
|
if (!pps->col_bd || !pps->row_bd || !pps->col_idxX)
|
|
return AVERROR(ENOMEM);
|
|
|
|
if (pps->uniform_spacing_flag) {
|
|
if (!pps->column_width) {
|
|
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)
|
|
return AVERROR(ENOMEM);
|
|
|
|
for (i = 0; i < pps->num_tile_columns; i++) {
|
|
pps->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++) {
|
|
pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
|
|
(i * sps->ctb_height) / pps->num_tile_rows;
|
|
}
|
|
}
|
|
|
|
pps->col_bd[0] = 0;
|
|
for (i = 0; i < pps->num_tile_columns; i++)
|
|
pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];
|
|
|
|
pps->row_bd[0] = 0;
|
|
for (i = 0; i < pps->num_tile_rows; i++)
|
|
pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];
|
|
|
|
for (i = 0, j = 0; i < sps->ctb_width; i++) {
|
|
if (i > pps->col_bd[j])
|
|
j++;
|
|
pps->col_idxX[i] = j;
|
|
}
|
|
|
|
/**
|
|
* 6.5
|
|
*/
|
|
pic_area_in_ctbs = sps->ctb_width * sps->ctb_height;
|
|
pic_area_in_min_tbs = sps->min_tb_width * sps->min_tb_height;
|
|
|
|
pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_rs_to_ts));
|
|
pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_ts_to_rs));
|
|
pps->tile_id = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->tile_id));
|
|
pps->min_tb_addr_zs = av_malloc_array(pic_area_in_min_tbs, sizeof(*pps->min_tb_addr_zs));
|
|
if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||
|
|
!pps->tile_id || !pps->min_tb_addr_zs) {
|
|
return AVERROR(ENOMEM);
|
|
}
|
|
|
|
for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {
|
|
int tb_x = ctb_addr_rs % sps->ctb_width;
|
|
int tb_y = ctb_addr_rs / sps->ctb_width;
|
|
int tile_x = 0;
|
|
int tile_y = 0;
|
|
int val = 0;
|
|
|
|
for (i = 0; i < pps->num_tile_columns; i++) {
|
|
if (tb_x < pps->col_bd[i + 1]) {
|
|
tile_x = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < pps->num_tile_rows; i++) {
|
|
if (tb_y < pps->row_bd[i + 1]) {
|
|
tile_y = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < tile_x; i++)
|
|
val += pps->row_height[tile_y] * pps->column_width[i];
|
|
for (i = 0; i < tile_y; i++)
|
|
val += sps->ctb_width * pps->row_height[i];
|
|
|
|
val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +
|
|
tb_x - pps->col_bd[tile_x];
|
|
|
|
pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;
|
|
pps->ctb_addr_ts_to_rs[val] = ctb_addr_rs;
|
|
}
|
|
|
|
for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)
|
|
for (i = 0; i < pps->num_tile_columns; i++, tile_id++)
|
|
for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)
|
|
for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)
|
|
pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;
|
|
|
|
pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));
|
|
if (!pps->tile_pos_rs)
|
|
return AVERROR(ENOMEM);
|
|
|
|
for (j = 0; j < pps->num_tile_rows; j++)
|
|
for (i = 0; i < pps->num_tile_columns; i++)
|
|
pps->tile_pos_rs[j * pps->num_tile_columns + i] =
|
|
pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];
|
|
|
|
log2_diff = sps->log2_ctb_size - sps->log2_min_tb_size;
|
|
for (y = 0; y < sps->min_tb_height; y++) {
|
|
for (x = 0; x < sps->min_tb_width; x++) {
|
|
int tb_x = x >> log2_diff;
|
|
int tb_y = y >> log2_diff;
|
|
int rs = sps->ctb_width * tb_y + tb_x;
|
|
int val = pps->ctb_addr_rs_to_ts[rs] << (log2_diff * 2);
|
|
for (i = 0; i < log2_diff; i++) {
|
|
int m = 1 << i;
|
|
val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
|
|
}
|
|
pps->min_tb_addr_zs[y * sps->min_tb_width + x] = val;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
|
|
HEVCParamSets *ps)
|
|
{
|
|
HEVCSPS *sps = NULL;
|
|
int i, ret = 0;
|
|
unsigned int pps_id = 0;
|
|
|
|
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");
|
|
|
|
// 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;
|
|
|
|
// Coded parameters
|
|
pps_id = get_ue_golomb_long(gb);
|
|
if (pps_id >= 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 >= 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);
|
|
|
|
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) {
|
|
pps->beta_offset = get_se_golomb(gb) * 2;
|
|
pps->tc_offset = get_se_golomb(gb) * 2;
|
|
if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {
|
|
av_log(avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",
|
|
pps->beta_offset/2);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {
|
|
av_log(avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",
|
|
pps->tc_offset/2);
|
|
ret = AVERROR_INVALIDDATA;
|
|
goto err;
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
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);
|
|
skip_bits1(gb); // pps_extension_flag
|
|
|
|
ret = setup_pps(avctx, gb, pps, sps);
|
|
if (ret < 0)
|
|
goto err;
|
|
|
|
remove_pps(ps, pps_id);
|
|
ps->pps_list[pps_id] = pps_buf;
|
|
|
|
return 0;
|
|
|
|
err:
|
|
av_buffer_unref(&pps_buf);
|
|
return ret;
|
|
}
|