summaryrefslogtreecommitdiff
path: root/libavcodec/h264_ps.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-03-22 13:31:21 +0100
committerAnton Khirnov <anton@khirnov.net>2016-04-24 10:06:23 +0200
commit3176217c60ca7828712985092d9102d331ea4f3d (patch)
tree1124709788c4b1b3ec4da9cd8e204cc63039cc8f /libavcodec/h264_ps.c
parent44d16df413878588659dd8901bba016b5a869fd1 (diff)
h264: decouple h264_ps from the h264 decoder
Make the SPS/PPS parsing independent of the H264Context, to allow decoupling the parser from the decoder. The change is modelled after the one done earlier for HEVC. Move the dequant buffers to the PPS to avoid complex checks whether they changed and an expensive copy for frame threads.
Diffstat (limited to 'libavcodec/h264_ps.c')
-rw-r--r--libavcodec/h264_ps.c470
1 files changed, 290 insertions, 180 deletions
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index d77fabf284..99ede76920 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -104,47 +104,71 @@ static const int level_max_dpb_mbs[][2] = {
{ 52, 184320 },
};
-static inline int decode_hrd_parameters(H264Context *h, SPS *sps)
+static void remove_pps(H264ParamSets *s, int id)
+{
+ if (s->pps_list[id] && s->pps == (const PPS*)s->pps_list[id]->data)
+ s->pps = NULL;
+ av_buffer_unref(&s->pps_list[id]);
+}
+
+static void remove_sps(H264ParamSets *s, int id)
+{
+ int i;
+ if (s->sps_list[id]) {
+ if (s->sps == (SPS*)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] && ((PPS*)s->pps_list[i]->data)->sps_id == id)
+ remove_pps(s, i);
+ }
+ av_buffer_unref(&s->sps_list[id]);
+}
+
+static inline int decode_hrd_parameters(GetBitContext *gb, AVCodecContext *avctx,
+ SPS *sps)
{
int cpb_count, i;
- cpb_count = get_ue_golomb_31(&h->gb) + 1;
+ cpb_count = get_ue_golomb_31(gb) + 1;
if (cpb_count > 32U) {
- av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
+ av_log(avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
return AVERROR_INVALIDDATA;
}
- get_bits(&h->gb, 4); /* bit_rate_scale */
- get_bits(&h->gb, 4); /* cpb_size_scale */
+ get_bits(gb, 4); /* bit_rate_scale */
+ get_bits(gb, 4); /* cpb_size_scale */
for (i = 0; i < cpb_count; i++) {
- get_ue_golomb_long(&h->gb); /* bit_rate_value_minus1 */
- get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */
- get_bits1(&h->gb); /* cbr_flag */
- }
- sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
- sps->cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
- sps->dpb_output_delay_length = get_bits(&h->gb, 5) + 1;
- sps->time_offset_length = get_bits(&h->gb, 5);
+ get_ue_golomb_long(gb); /* bit_rate_value_minus1 */
+ get_ue_golomb_long(gb); /* cpb_size_value_minus1 */
+ get_bits1(gb); /* cbr_flag */
+ }
+ sps->initial_cpb_removal_delay_length = get_bits(gb, 5) + 1;
+ sps->cpb_removal_delay_length = get_bits(gb, 5) + 1;
+ sps->dpb_output_delay_length = get_bits(gb, 5) + 1;
+ sps->time_offset_length = get_bits(gb, 5);
sps->cpb_cnt = cpb_count;
return 0;
}
-static inline int decode_vui_parameters(H264Context *h, SPS *sps)
+static inline int decode_vui_parameters(GetBitContext *gb, AVCodecContext *avctx,
+ SPS *sps)
{
int aspect_ratio_info_present_flag;
unsigned int aspect_ratio_idc;
- aspect_ratio_info_present_flag = get_bits1(&h->gb);
+ aspect_ratio_info_present_flag = get_bits1(gb);
if (aspect_ratio_info_present_flag) {
- aspect_ratio_idc = get_bits(&h->gb, 8);
+ aspect_ratio_idc = get_bits(gb, 8);
if (aspect_ratio_idc == EXTENDED_SAR) {
- sps->sar.num = get_bits(&h->gb, 16);
- sps->sar.den = get_bits(&h->gb, 16);
+ sps->sar.num = get_bits(gb, 16);
+ sps->sar.den = get_bits(gb, 16);
} else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) {
sps->sar = pixel_aspect[aspect_ratio_idc];
} else {
- av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
+ av_log(avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
return AVERROR_INVALIDDATA;
}
} else {
@@ -152,19 +176,19 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps)
sps->sar.den = 0;
}
- if (get_bits1(&h->gb)) /* overscan_info_present_flag */
- get_bits1(&h->gb); /* overscan_appropriate_flag */
+ if (get_bits1(gb)) /* overscan_info_present_flag */
+ get_bits1(gb); /* overscan_appropriate_flag */
- sps->video_signal_type_present_flag = get_bits1(&h->gb);
+ sps->video_signal_type_present_flag = get_bits1(gb);
if (sps->video_signal_type_present_flag) {
- get_bits(&h->gb, 3); /* video_format */
- sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */
+ get_bits(gb, 3); /* video_format */
+ sps->full_range = get_bits1(gb); /* video_full_range_flag */
- sps->colour_description_present_flag = get_bits1(&h->gb);
+ sps->colour_description_present_flag = get_bits1(gb);
if (sps->colour_description_present_flag) {
- sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */
- sps->color_trc = get_bits(&h->gb, 8); /* transfer_characteristics */
- sps->colorspace = get_bits(&h->gb, 8); /* matrix_coefficients */
+ sps->color_primaries = get_bits(gb, 8); /* colour_primaries */
+ sps->color_trc = get_bits(gb, 8); /* transfer_characteristics */
+ sps->colorspace = get_bits(gb, 8); /* matrix_coefficients */
if (sps->color_primaries >= AVCOL_PRI_NB)
sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
if (sps->color_trc >= AVCOL_TRC_NB)
@@ -175,83 +199,83 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps)
}
/* chroma_location_info_present_flag */
- if (get_bits1(&h->gb)) {
+ if (get_bits1(gb)) {
/* chroma_sample_location_type_top_field */
- h->avctx->chroma_sample_location = get_ue_golomb(&h->gb) + 1;
- get_ue_golomb(&h->gb); /* chroma_sample_location_type_bottom_field */
+ avctx->chroma_sample_location = get_ue_golomb(gb) + 1;
+ get_ue_golomb(gb); /* chroma_sample_location_type_bottom_field */
}
- sps->timing_info_present_flag = get_bits1(&h->gb);
+ sps->timing_info_present_flag = get_bits1(gb);
if (sps->timing_info_present_flag) {
- sps->num_units_in_tick = get_bits_long(&h->gb, 32);
- sps->time_scale = get_bits_long(&h->gb, 32);
+ sps->num_units_in_tick = get_bits_long(gb, 32);
+ sps->time_scale = get_bits_long(gb, 32);
if (!sps->num_units_in_tick || !sps->time_scale) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"time_scale/num_units_in_tick invalid or unsupported (%"PRIu32"/%"PRIu32")\n",
sps->time_scale, sps->num_units_in_tick);
return AVERROR_INVALIDDATA;
}
- sps->fixed_frame_rate_flag = get_bits1(&h->gb);
+ sps->fixed_frame_rate_flag = get_bits1(gb);
}
- sps->nal_hrd_parameters_present_flag = get_bits1(&h->gb);
+ sps->nal_hrd_parameters_present_flag = get_bits1(gb);
if (sps->nal_hrd_parameters_present_flag)
- if (decode_hrd_parameters(h, sps) < 0)
+ if (decode_hrd_parameters(gb, avctx, sps) < 0)
return AVERROR_INVALIDDATA;
- sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb);
+ sps->vcl_hrd_parameters_present_flag = get_bits1(gb);
if (sps->vcl_hrd_parameters_present_flag)
- if (decode_hrd_parameters(h, sps) < 0)
+ if (decode_hrd_parameters(gb, avctx, sps) < 0)
return AVERROR_INVALIDDATA;
if (sps->nal_hrd_parameters_present_flag ||
sps->vcl_hrd_parameters_present_flag)
- get_bits1(&h->gb); /* low_delay_hrd_flag */
- sps->pic_struct_present_flag = get_bits1(&h->gb);
+ get_bits1(gb); /* low_delay_hrd_flag */
+ sps->pic_struct_present_flag = get_bits1(gb);
- sps->bitstream_restriction_flag = get_bits1(&h->gb);
+ sps->bitstream_restriction_flag = get_bits1(gb);
if (sps->bitstream_restriction_flag) {
- get_bits1(&h->gb); /* motion_vectors_over_pic_boundaries_flag */
- get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
- get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */
- get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */
- get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */
- sps->num_reorder_frames = get_ue_golomb(&h->gb);
- get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/
-
- if (get_bits_left(&h->gb) < 0) {
+ get_bits1(gb); /* motion_vectors_over_pic_boundaries_flag */
+ get_ue_golomb(gb); /* max_bytes_per_pic_denom */
+ get_ue_golomb(gb); /* max_bits_per_mb_denom */
+ get_ue_golomb(gb); /* log2_max_mv_length_horizontal */
+ get_ue_golomb(gb); /* log2_max_mv_length_vertical */
+ sps->num_reorder_frames = get_ue_golomb(gb);
+ get_ue_golomb(gb); /*max_dec_frame_buffering*/
+
+ if (get_bits_left(gb) < 0) {
sps->num_reorder_frames = 0;
sps->bitstream_restriction_flag = 0;
}
if (sps->num_reorder_frames > 16U
/* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"Clipping illegal num_reorder_frames %d\n",
sps->num_reorder_frames);
sps->num_reorder_frames = 16;
return AVERROR_INVALIDDATA;
}
}
- if (get_bits_left(&h->gb) < 0) {
- av_log(h->avctx, AV_LOG_ERROR,
- "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
+ if (get_bits_left(gb) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Overread VUI by %d bits\n", -get_bits_left(gb));
return AVERROR_INVALIDDATA;
}
return 0;
}
-static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
+static void decode_scaling_list(GetBitContext *gb, uint8_t *factors, int size,
const uint8_t *jvt_list,
const uint8_t *fallback_list)
{
int i, last = 8, next = 8;
const uint8_t *scan = size == 16 ? ff_zigzag_scan : ff_zigzag_direct;
- if (!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */
+ if (!get_bits1(gb)) /* matrix not written, we use the predicted one */
memcpy(factors, fallback_list, size * sizeof(uint8_t));
else
for (i = 0; i < size; i++) {
if (next)
- next = (last + get_se_golomb(&h->gb)) & 0xff;
+ next = (last + get_se_golomb(gb)) & 0xff;
if (!i && !next) { /* matrix not written, we use the preset one */
memcpy(factors, jvt_list, size * sizeof(uint8_t));
break;
@@ -260,7 +284,7 @@ static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
}
}
-static void decode_scaling_matrices(H264Context *h, SPS *sps,
+static void decode_scaling_matrices(GetBitContext *gb, SPS *sps,
PPS *pps, int is_sps,
uint8_t(*scaling_matrix4)[16],
uint8_t(*scaling_matrix8)[64])
@@ -272,54 +296,58 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps,
fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
};
- if (get_bits1(&h->gb)) {
+ if (get_bits1(gb)) {
sps->scaling_matrix_present |= is_sps;
- decode_scaling_list(h, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y
- decode_scaling_list(h, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
- decode_scaling_list(h, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
- decode_scaling_list(h, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y
- decode_scaling_list(h, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
- decode_scaling_list(h, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
+ decode_scaling_list(gb, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]); // Intra, Y
+ decode_scaling_list(gb, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
+ decode_scaling_list(gb, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
+ decode_scaling_list(gb, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]); // Inter, Y
+ decode_scaling_list(gb, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
+ decode_scaling_list(gb, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
if (is_sps || pps->transform_8x8_mode) {
- decode_scaling_list(h, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y
+ decode_scaling_list(gb, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y
if (sps->chroma_format_idc == 3) {
- decode_scaling_list(h, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr
- decode_scaling_list(h, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb
+ decode_scaling_list(gb, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr
+ decode_scaling_list(gb, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb
}
- decode_scaling_list(h, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y
+ decode_scaling_list(gb, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y
if (sps->chroma_format_idc == 3) {
- decode_scaling_list(h, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
- decode_scaling_list(h, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
+ decode_scaling_list(gb, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
+ decode_scaling_list(gb, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
}
}
}
}
-int ff_h264_decode_seq_parameter_set(H264Context *h)
+int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
+ H264ParamSets *ps)
{
+ AVBufferRef *sps_buf;
int profile_idc, level_idc, constraint_set_flags = 0;
unsigned int sps_id;
int i, log2_max_frame_num_minus4;
SPS *sps;
- profile_idc = get_bits(&h->gb, 8);
- constraint_set_flags |= get_bits1(&h->gb) << 0; // constraint_set0_flag
- constraint_set_flags |= get_bits1(&h->gb) << 1; // constraint_set1_flag
- constraint_set_flags |= get_bits1(&h->gb) << 2; // constraint_set2_flag
- constraint_set_flags |= get_bits1(&h->gb) << 3; // constraint_set3_flag
- constraint_set_flags |= get_bits1(&h->gb) << 4; // constraint_set4_flag
- constraint_set_flags |= get_bits1(&h->gb) << 5; // constraint_set5_flag
- skip_bits(&h->gb, 2); // reserved_zero_2bits
- level_idc = get_bits(&h->gb, 8);
- sps_id = get_ue_golomb_31(&h->gb);
+ profile_idc = get_bits(gb, 8);
+ constraint_set_flags |= get_bits1(gb) << 0; // constraint_set0_flag
+ constraint_set_flags |= get_bits1(gb) << 1; // constraint_set1_flag
+ constraint_set_flags |= get_bits1(gb) << 2; // constraint_set2_flag
+ constraint_set_flags |= get_bits1(gb) << 3; // constraint_set3_flag
+ constraint_set_flags |= get_bits1(gb) << 4; // constraint_set4_flag
+ constraint_set_flags |= get_bits1(gb) << 5; // constraint_set5_flag
+ skip_bits(gb, 2); // reserved_zero_2bits
+ level_idc = get_bits(gb, 8);
+ sps_id = get_ue_golomb_31(gb);
if (sps_id >= MAX_SPS_COUNT) {
- av_log(h->avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id);
+ av_log(avctx, AV_LOG_ERROR, "sps_id %u out of range\n", sps_id);
return AVERROR_INVALIDDATA;
}
- sps = av_mallocz(sizeof(SPS));
- if (!sps)
+
+ sps_buf = av_buffer_allocz(sizeof(*sps));
+ if (!sps_buf)
return AVERROR(ENOMEM);
+ sps = (SPS*)sps_buf->data;
sps->sps_id = sps_id;
sps->time_offset_length = 24;
@@ -342,23 +370,23 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
sps->profile_idc == 128 || // Multiview High profile (MVC)
sps->profile_idc == 138 || // Multiview Depth High profile (MVCD)
sps->profile_idc == 144) { // old High444 profile
- sps->chroma_format_idc = get_ue_golomb_31(&h->gb);
+ sps->chroma_format_idc = get_ue_golomb_31(gb);
if (sps->chroma_format_idc > 3) {
- avpriv_request_sample(h->avctx, "chroma_format_idc %u",
+ avpriv_request_sample(avctx, "chroma_format_idc %u",
sps->chroma_format_idc);
goto fail;
} else if (sps->chroma_format_idc == 3) {
- sps->residual_color_transform_flag = get_bits1(&h->gb);
+ sps->residual_color_transform_flag = get_bits1(gb);
}
- sps->bit_depth_luma = get_ue_golomb(&h->gb) + 8;
- sps->bit_depth_chroma = get_ue_golomb(&h->gb) + 8;
+ sps->bit_depth_luma = get_ue_golomb(gb) + 8;
+ sps->bit_depth_chroma = get_ue_golomb(gb) + 8;
if (sps->bit_depth_chroma != sps->bit_depth_luma) {
- avpriv_request_sample(h->avctx,
+ avpriv_request_sample(avctx,
"Different chroma and luma bit depth");
goto fail;
}
- sps->transform_bypass = get_bits1(&h->gb);
- decode_scaling_matrices(h, sps, NULL, 1,
+ sps->transform_bypass = get_bits1(gb);
+ decode_scaling_matrices(gb, sps, NULL, 1,
sps->scaling_matrix4, sps->scaling_matrix8);
} else {
sps->chroma_format_idc = 1;
@@ -366,85 +394,85 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
sps->bit_depth_chroma = 8;
}
- log2_max_frame_num_minus4 = get_ue_golomb(&h->gb);
+ log2_max_frame_num_minus4 = get_ue_golomb(gb);
if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"log2_max_frame_num_minus4 out of range (0-12): %d\n",
log2_max_frame_num_minus4);
goto fail;
}
sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
- sps->poc_type = get_ue_golomb_31(&h->gb);
+ sps->poc_type = get_ue_golomb_31(gb);
if (sps->poc_type == 0) { // FIXME #define
- sps->log2_max_poc_lsb = get_ue_golomb(&h->gb) + 4;
+ sps->log2_max_poc_lsb = get_ue_golomb(gb) + 4;
} else if (sps->poc_type == 1) { // FIXME #define
- sps->delta_pic_order_always_zero_flag = get_bits1(&h->gb);
- sps->offset_for_non_ref_pic = get_se_golomb(&h->gb);
- sps->offset_for_top_to_bottom_field = get_se_golomb(&h->gb);
- sps->poc_cycle_length = get_ue_golomb(&h->gb);
+ sps->delta_pic_order_always_zero_flag = get_bits1(gb);
+ sps->offset_for_non_ref_pic = get_se_golomb(gb);
+ sps->offset_for_top_to_bottom_field = get_se_golomb(gb);
+ sps->poc_cycle_length = get_ue_golomb(gb);
if ((unsigned)sps->poc_cycle_length >=
FF_ARRAY_ELEMS(sps->offset_for_ref_frame)) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"poc_cycle_length overflow %d\n", sps->poc_cycle_length);
goto fail;
}
for (i = 0; i < sps->poc_cycle_length; i++)
- sps->offset_for_ref_frame[i] = get_se_golomb(&h->gb);
+ sps->offset_for_ref_frame[i] = get_se_golomb(gb);
} else if (sps->poc_type != 2) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
+ av_log(avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
goto fail;
}
- sps->ref_frame_count = get_ue_golomb_31(&h->gb);
+ sps->ref_frame_count = get_ue_golomb_31(gb);
if (sps->ref_frame_count > H264_MAX_PICTURE_COUNT - 2 ||
sps->ref_frame_count >= 32U) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"too many reference frames %d\n", sps->ref_frame_count);
goto fail;
}
- sps->gaps_in_frame_num_allowed_flag = get_bits1(&h->gb);
- sps->mb_width = get_ue_golomb(&h->gb) + 1;
- sps->mb_height = get_ue_golomb(&h->gb) + 1;
+ sps->gaps_in_frame_num_allowed_flag = get_bits1(gb);
+ sps->mb_width = get_ue_golomb(gb) + 1;
+ sps->mb_height = get_ue_golomb(gb) + 1;
if ((unsigned)sps->mb_width >= INT_MAX / 16 ||
(unsigned)sps->mb_height >= INT_MAX / 16 ||
av_image_check_size(16 * sps->mb_width,
- 16 * sps->mb_height, 0, h->avctx)) {
- av_log(h->avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
+ 16 * sps->mb_height, 0, avctx)) {
+ av_log(avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
goto fail;
}
- sps->frame_mbs_only_flag = get_bits1(&h->gb);
+ sps->frame_mbs_only_flag = get_bits1(gb);
if (!sps->frame_mbs_only_flag)
- sps->mb_aff = get_bits1(&h->gb);
+ sps->mb_aff = get_bits1(gb);
else
sps->mb_aff = 0;
- sps->direct_8x8_inference_flag = get_bits1(&h->gb);
+ sps->direct_8x8_inference_flag = get_bits1(gb);
if (!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"This stream was generated by a broken encoder, invalid 8x8 inference\n");
goto fail;
}
#ifndef ALLOW_INTERLACE
if (sps->mb_aff)
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"MBAFF support not included; enable it at compile-time.\n");
#endif
- sps->crop = get_bits1(&h->gb);
+ sps->crop = get_bits1(gb);
if (sps->crop) {
- unsigned int crop_left = get_ue_golomb(&h->gb);
- unsigned int crop_right = get_ue_golomb(&h->gb);
- unsigned int crop_top = get_ue_golomb(&h->gb);
- unsigned int crop_bottom = get_ue_golomb(&h->gb);
+ unsigned int crop_left = get_ue_golomb(gb);
+ unsigned int crop_right = get_ue_golomb(gb);
+ unsigned int crop_top = get_ue_golomb(gb);
+ unsigned int crop_bottom = get_ue_golomb(gb);
- if (h->avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
- av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
+ if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
+ av_log(avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
"values are l:%d r:%d t:%d b:%d\n",
crop_left, crop_right, crop_top, crop_bottom);
@@ -460,9 +488,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) &&
- !(h->avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
+ !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8));
- av_log(h->avctx, AV_LOG_WARNING,
+ av_log(avctx, AV_LOG_WARNING,
"Reducing left cropping to %d "
"chroma samples to preserve alignment.\n",
crop_left);
@@ -474,8 +502,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
INT_MAX / step_y <= crop_top ||
INT_MAX / step_y - crop_top <= crop_bottom ||
16 * sps->mb_height <= step_y * (crop_top + crop_bottom)) {
- av_log(h->avctx, AV_LOG_WARNING, "Invalid crop parameters\n");
- if (h->avctx->err_recognition & AV_EF_EXPLODE)
+ av_log(avctx, AV_LOG_WARNING, "Invalid crop parameters\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
goto fail;
crop_left = crop_right = crop_top = crop_bottom = 0;
}
@@ -493,10 +521,10 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
sps->crop = 0;
}
- sps->vui_parameters_present_flag = get_bits1(&h->gb);
+ sps->vui_parameters_present_flag = get_bits1(gb);
if (sps->vui_parameters_present_flag) {
- int ret = decode_vui_parameters(h, sps);
- if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
+ int ret = decode_vui_parameters(gb, avctx, sps);
+ if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE)
goto fail;
}
@@ -516,9 +544,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
if (!sps->sar.den)
sps->sar.den = 1;
- if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+ if (avctx->debug & FF_DEBUG_PICT_INFO) {
static const char csp[4][5] = { "Gray", "420", "422", "444" };
- av_log(h->avctx, AV_LOG_DEBUG,
+ av_log(avctx, AV_LOG_DEBUG,
"sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%u/%u/%u/%u %s %s %"PRId32"/%"PRId32"\n",
sps_id, sps->profile_idc, sps->level_idc,
sps->poc_type,
@@ -533,19 +561,95 @@ int ff_h264_decode_seq_parameter_set(H264Context *h)
sps->timing_info_present_flag ? sps->num_units_in_tick : 0,
sps->timing_info_present_flag ? sps->time_scale : 0);
}
- sps->new = 1;
- av_free(h->sps_buffers[sps_id]);
- h->sps_buffers[sps_id] = sps;
- h->sps = *sps;
+ /* 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;
fail:
- av_free(sps);
+ av_buffer_unref(&sps_buf);
return AVERROR_INVALIDDATA;
}
+static void init_dequant8_coeff_table(PPS *pps, const SPS *sps)
+{
+ int i, j, q, x;
+ const int max_qp = 51 + 6 * (sps->bit_depth_luma - 8);
+
+ for (i = 0; i < 6; i++) {
+ pps->dequant8_coeff[i] = pps->dequant8_buffer[i];
+ for (j = 0; j < i; j++)
+ if (!memcmp(pps->scaling_matrix8[j], pps->scaling_matrix8[i],
+ 64 * sizeof(uint8_t))) {
+ pps->dequant8_coeff[i] = pps->dequant8_buffer[j];
+ break;
+ }
+ if (j < i)
+ continue;
+
+ for (q = 0; q < max_qp + 1; q++) {
+ int shift = ff_h264_quant_div6[q];
+ int idx = ff_h264_quant_rem6[q];
+ for (x = 0; x < 64; x++)
+ pps->dequant8_coeff[i][q][(x >> 3) | ((x & 7) << 3)] =
+ ((uint32_t)ff_h264_dequant8_coeff_init[idx][ff_h264_dequant8_coeff_init_scan[((x >> 1) & 12) | (x & 3)]] *
+ pps->scaling_matrix8[i][x]) << shift;
+ }
+ }
+}
+
+static void init_dequant4_coeff_table(PPS *pps, const SPS *sps)
+{
+ int i, j, q, x;
+ const int max_qp = 51 + 6 * (sps->bit_depth_luma - 8);
+ for (i = 0; i < 6; i++) {
+ pps->dequant4_coeff[i] = pps->dequant4_buffer[i];
+ for (j = 0; j < i; j++)
+ if (!memcmp(pps->scaling_matrix4[j], pps->scaling_matrix4[i],
+ 16 * sizeof(uint8_t))) {
+ pps->dequant4_coeff[i] = pps->dequant4_buffer[j];
+ break;
+ }
+ if (j < i)
+ continue;
+
+ for (q = 0; q < max_qp + 1; q++) {
+ int shift = ff_h264_quant_div6[q] + 2;
+ int idx = ff_h264_quant_rem6[q];
+ for (x = 0; x < 16; x++)
+ pps->dequant4_coeff[i][q][(x >> 2) | ((x << 2) & 0xF)] =
+ ((uint32_t)ff_h264_dequant4_coeff_init[idx][(x & 1) + ((x >> 2) & 1)] *
+ pps->scaling_matrix4[i][x]) << shift;
+ }
+ }
+}
+
+static void init_dequant_tables(PPS *pps, const SPS *sps)
+{
+ int i, x;
+ init_dequant4_coeff_table(pps, sps);
+ if (pps->transform_8x8_mode)
+ init_dequant8_coeff_table(pps, sps);
+ if (sps->transform_bypass) {
+ for (i = 0; i < 6; i++)
+ for (x = 0; x < 16; x++)
+ pps->dequant4_coeff[i][0][x] = 1 << 6;
+ if (pps->transform_8x8_mode)
+ for (i = 0; i < 6; i++)
+ for (x = 0; x < 64; x++)
+ pps->dequant8_coeff[i][0][x] = 1 << 6;
+ }
+}
+
static void build_qp_table(PPS *pps, int t, int index, const int depth)
{
int i;
@@ -555,46 +659,50 @@ static void build_qp_table(PPS *pps, int t, int index, const int depth)
ff_h264_chroma_qp[depth - 8][av_clip(i + index, 0, max_qp)];
}
-int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
+int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
+ H264ParamSets *ps, int bit_length)
{
- const SPS *sps;
- unsigned int pps_id = get_ue_golomb(&h->gb);
+ AVBufferRef *pps_buf;
+ SPS *sps;
+ unsigned int pps_id = get_ue_golomb(gb);
PPS *pps;
int qp_bd_offset;
int bits_left;
int ret;
if (pps_id >= MAX_PPS_COUNT) {
- av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
+ av_log(avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);
return AVERROR_INVALIDDATA;
}
- pps = av_mallocz(sizeof(PPS));
- if (!pps)
+ pps_buf = av_buffer_allocz(sizeof(*pps));
+ if (!pps_buf)
return AVERROR(ENOMEM);
- pps->sps_id = get_ue_golomb_31(&h->gb);
+ pps = (PPS*)pps_buf->data;
+
+ pps->sps_id = get_ue_golomb_31(gb);
if ((unsigned)pps->sps_id >= MAX_SPS_COUNT ||
- !h->sps_buffers[pps->sps_id]) {
- av_log(h->avctx, AV_LOG_ERROR, "sps_id %u out of range\n", pps->sps_id);
+ !ps->sps_list[pps->sps_id]) {
+ av_log(avctx, AV_LOG_ERROR, "sps_id %u out of range\n", pps->sps_id);
ret = AVERROR_INVALIDDATA;
goto fail;
}
- sps = h->sps_buffers[pps->sps_id];
+ sps = (SPS*)ps->sps_list[pps->sps_id]->data;
if (sps->bit_depth_luma > 10) {
- av_log(h->avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_ERROR,
"Unimplemented luma bit depth=%d (max=10)\n",
sps->bit_depth_luma);
ret = AVERROR_PATCHWELCOME;
goto fail;
}
- pps->cabac = get_bits1(&h->gb);
- pps->pic_order_present = get_bits1(&h->gb);
- pps->slice_group_count = get_ue_golomb(&h->gb) + 1;
+ pps->cabac = get_bits1(gb);
+ pps->pic_order_present = get_bits1(gb);
+ pps->slice_group_count = get_ue_golomb(gb) + 1;
if (pps->slice_group_count > 1) {
- pps->mb_slice_group_map_type = get_ue_golomb(&h->gb);
- av_log(h->avctx, AV_LOG_ERROR, "FMO not supported\n");
+ pps->mb_slice_group_map_type = get_ue_golomb(gb);
+ av_log(avctx, AV_LOG_ERROR, "FMO not supported\n");
switch (pps->mb_slice_group_map_type) {
case 0:
#if 0
@@ -627,41 +735,39 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
break;
}
}
- pps->ref_count[0] = get_ue_golomb(&h->gb) + 1;
- pps->ref_count[1] = get_ue_golomb(&h->gb) + 1;
+ pps->ref_count[0] = get_ue_golomb(gb) + 1;
+ pps->ref_count[1] = get_ue_golomb(gb) + 1;
if (pps->ref_count[0] - 1 > 32 - 1 || pps->ref_count[1] - 1 > 32 - 1) {
- av_log(h->avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
+ av_log(avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
qp_bd_offset = 6 * (sps->bit_depth_luma - 8);
- pps->weighted_pred = get_bits1(&h->gb);
- pps->weighted_bipred_idc = get_bits(&h->gb, 2);
- pps->init_qp = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
- pps->init_qs = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
- pps->chroma_qp_index_offset[0] = get_se_golomb(&h->gb);
- pps->deblocking_filter_parameters_present = get_bits1(&h->gb);
- pps->constrained_intra_pred = get_bits1(&h->gb);
- pps->redundant_pic_cnt_present = get_bits1(&h->gb);
+ pps->weighted_pred = get_bits1(gb);
+ pps->weighted_bipred_idc = get_bits(gb, 2);
+ pps->init_qp = get_se_golomb(gb) + 26 + qp_bd_offset;
+ pps->init_qs = get_se_golomb(gb) + 26 + qp_bd_offset;
+ pps->chroma_qp_index_offset[0] = get_se_golomb(gb);
+ pps->deblocking_filter_parameters_present = get_bits1(gb);
+ pps->constrained_intra_pred = get_bits1(gb);
+ pps->redundant_pic_cnt_present = get_bits1(gb);
pps->transform_8x8_mode = 0;
- // contents of sps/pps can change even if id doesn't, so reinit
- h->dequant_coeff_pps = -1;
- memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4,
+ memcpy(pps->scaling_matrix4, sps->scaling_matrix4,
sizeof(pps->scaling_matrix4));
- memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8,
+ memcpy(pps->scaling_matrix8, sps->scaling_matrix8,
sizeof(pps->scaling_matrix8));
- bits_left = bit_length - get_bits_count(&h->gb);
+ bits_left = bit_length - get_bits_count(gb);
if (bits_left && (bits_left > 8 ||
- show_bits(&h->gb, bits_left) != 1 << (bits_left - 1))) {
- pps->transform_8x8_mode = get_bits1(&h->gb);
- decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0,
+ show_bits(gb, bits_left) != 1 << (bits_left - 1))) {
+ pps->transform_8x8_mode = get_bits1(gb);
+ decode_scaling_matrices(gb, sps, pps, 0,
pps->scaling_matrix4, pps->scaling_matrix8);
// second_chroma_qp_index_offset
- pps->chroma_qp_index_offset[1] = get_se_golomb(&h->gb);
+ pps->chroma_qp_index_offset[1] = get_se_golomb(gb);
} else {
pps->chroma_qp_index_offset[1] = pps->chroma_qp_index_offset[0];
}
@@ -670,11 +776,14 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
sps->bit_depth_luma);
build_qp_table(pps, 1, pps->chroma_qp_index_offset[1],
sps->bit_depth_luma);
+
+ init_dequant_tables(pps, sps);
+
if (pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
pps->chroma_qp_diff = 1;
- if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(h->avctx, AV_LOG_DEBUG,
+ if (avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(avctx, AV_LOG_DEBUG,
"pps:%u sps:%u %s slice_groups:%d ref:%u/%u %s qp:%d/%d/%d/%d %s %s %s %s\n",
pps_id, pps->sps_id,
pps->cabac ? "CABAC" : "CAVLC",
@@ -688,11 +797,12 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
pps->transform_8x8_mode ? "8x8DCT" : "");
}
- av_free(h->pps_buffers[pps_id]);
- h->pps_buffers[pps_id] = pps;
+ remove_pps(ps, pps_id);
+ ps->pps_list[pps_id] = pps_buf;
+
return 0;
fail:
- av_free(pps);
+ av_buffer_unref(&pps_buf);
return ret;
}