static inline int decode_vui_parameters(H264Context *h, SPS *sps)
{
int aspect_ratio_info_present_flag;
unsigned int aspect_ratio_idc;
aspect_ratio_info_present_flag = get_bits1(&h->gb);
if (aspect_ratio_info_present_flag) {
aspect_ratio_idc = get_bits(&h->gb, 8);
if (aspect_ratio_idc == EXTENDED_SAR) {
sps->sar.num = get_bits(&h->gb, 16);
sps->sar.den = get_bits(&h->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");
return AVERROR_INVALIDDATA;
}
} else {
sps->sar.num =
sps->sar.den = 0;
}
if (get_bits1(&h->gb)) /* overscan_info_present_flag */
get_bits1(&h->gb); /* overscan_appropriate_flag */
sps->video_signal_type_present_flag = get_bits1(&h->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 */
sps->colour_description_present_flag = get_bits1(&h->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 */
if (sps->color_primaries >= AVCOL_PRI_NB)
sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
if (sps->color_trc >= AVCOL_TRC_NB)
sps->color_trc = AVCOL_TRC_UNSPECIFIED;
if (sps->colorspace >= AVCOL_SPC_NB)
sps->colorspace = AVCOL_SPC_UNSPECIFIED;
}
}
/* chroma_location_info_present_flag */
if (get_bits1(&h->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 */
}
if (show_bits1(&h->gb) && get_bits_left(&h->gb) < 10) {
av_log(h->avctx, AV_LOG_WARNING, "Truncated VUI\n");
return 0;
}
sps->timing_info_present_flag = get_bits1(&h->gb);
if (sps->timing_info_present_flag) {
// sps->num_units_in_tick will be set to time_base.num of AvCodecContext
// sps->time_scale will be set to time_base.den of AvCodecContext
// see h264_slice_header_init function below
sps->num_units_in_tick = get_bits_long(&h->gb, 32);
sps->time_scale = get_bits_long(&h->gb, 32);
if (!sps->num_units_in_tick || !sps->time_scale) {
av_log(h->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->nal_hrd_parameters_present_flag = get_bits1(&h->gb);
if (sps->nal_hrd_parameters_present_flag)
if (decode_hrd_parameters(h, sps) < 0)
return AVERROR_INVALIDDATA;
sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb);
if (sps->vcl_hrd_parameters_present_flag)
if (decode_hrd_parameters(h, 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);
if (!get_bits_left(&h->gb))
return 0;
sps->bitstream_restriction_flag = get_bits1(&h->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) {
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,
"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));
return AVERROR_INVALIDDATA;
}
return 0;
}
{
int nb_slices = (HAVE_THREADS &&
h->avctx->active_thread_type & FF_THREAD_SLICE) ?
h->avctx->thread_count : 1;
int i, ret;
av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
&h->chroma_x_shift, &h->chroma_y_shift);
int64_t den = h->sps.time_scale;
if (h->x264_build < 44U)
den *= 2;
av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
h->sps.num_units_in_tick, den, 1 << 30);
}
ff_h264_free_tables(h, 0);
h->first_field = 0;
h->prev_interlaced_frame = 1;
ret = ff_h264_alloc_tables(h);
if (ret < 0) {
av_log(h->avctx, AV_LOG_ERROR, "Could not allocate memory\n");
return ret;
}
int max_slices;
if (h->mb_height)
max_slices = FFMIN(H264_MAX_THREADS, h->mb_height);
else
max_slices = H264_MAX_THREADS;
av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices %d,"
" reducing to %d\n", nb_slices, max_slices);
nb_slices = max_slices;
}
h->slice_context_count = nb_slices;
ret = ff_h264_context_init(h);
if (ret < 0) {
av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
return ret;
}
} else {
for (i = 1; i < h->slice_context_count; i++) {
H264Context *c;
c = h->thread_context[i] = av_mallocz(sizeof(H264Context));
if (!c)
return AVERROR(ENOMEM);
c->avctx = h->avctx;
if (CONFIG_ERROR_RESILIENCE) {
c->dsp = h->dsp;
}
c->vdsp = h->vdsp;
c->h264dsp = h->h264dsp;
c->h264qpel = h->h264qpel;
c->h264chroma = h->h264chroma;
c->sps = h->sps;
c->pps = h->pps;
c->pixel_shift = h->pixel_shift;
c->cur_chroma_format_idc = h->cur_chroma_format_idc;
c->width = h->width;
c->height = h->height;
c->linesize = h->linesize;
c->uvlinesize = h->uvlinesize;
c->chroma_x_shift = h->chroma_x_shift;
c->chroma_y_shift = h->chroma_y_shift;
c->qscale = h->qscale;
c->droppable = h->droppable;
c->data_partitioning = h->data_partitioning;
c->low_delay = h->low_delay;
c->mb_width = h->mb_width;
c->mb_height = h->mb_height;
c->mb_stride = h->mb_stride;
c->mb_num = h->mb_num;
c->flags = h->flags;
c->workaround_bugs = h->workaround_bugs;
c->pict_type = h->pict_type;
clone_tables(c, h, i);
c->context_initialized = 1;
}
if ((ret = ff_h264_context_init(h->thread_context[i])) < 0) {
av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
return ret;
}
}
}