av_buffer_unref(&s->sps_list[id]);
}
-static inline int decode_hrd_parameters(GetBitContext *gb, AVCodecContext *avctx,
+static inline int decode_hrd_parameters(GetBitContext *gb, void *logctx,
SPS *sps)
{
int cpb_count, i;
cpb_count = get_ue_golomb_31(gb) + 1;
if (cpb_count > 32U) {
- av_log(avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
+ av_log(logctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
return AVERROR_INVALIDDATA;
}
return 0;
}
-static inline int decode_vui_parameters(GetBitContext *gb, AVCodecContext *avctx,
+static inline int decode_vui_parameters(GetBitContext *gb, void *logctx,
SPS *sps)
{
int aspect_ratio_info_present_flag;
} else if (aspect_ratio_idc < FF_ARRAY_ELEMS(ff_h264_pixel_aspect)) {
sps->sar = ff_h264_pixel_aspect[aspect_ratio_idc];
} else {
- av_log(avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
+ av_log(logctx, AV_LOG_ERROR, "illegal aspect ratio\n");
return AVERROR_INVALIDDATA;
}
} else {
/* chroma_location_info_present_flag */
if (get_bits1(gb)) {
/* chroma_sample_location_type_top_field */
- avctx->chroma_sample_location = get_ue_golomb(gb) + 1;
+ sps->chroma_location = get_ue_golomb(gb) + 1;
get_ue_golomb(gb); /* chroma_sample_location_type_bottom_field */
- }
+ } else
+ sps->chroma_location = AVCHROMA_LOC_LEFT;
if (show_bits1(gb) && get_bits_left(gb) < 10) {
- av_log(avctx, AV_LOG_WARNING, "Truncated VUI\n");
+ av_log(logctx, AV_LOG_WARNING, "Truncated VUI (%d)\n", get_bits_left(gb));
return 0;
}
unsigned num_units_in_tick = get_bits_long(gb, 32);
unsigned time_scale = get_bits_long(gb, 32);
if (!num_units_in_tick || !time_scale) {
- av_log(avctx, AV_LOG_ERROR,
+ av_log(logctx, AV_LOG_ERROR,
"time_scale/num_units_in_tick invalid or unsupported (%u/%u)\n",
time_scale, num_units_in_tick);
sps->timing_info_present_flag = 0;
sps->nal_hrd_parameters_present_flag = get_bits1(gb);
if (sps->nal_hrd_parameters_present_flag)
- if (decode_hrd_parameters(gb, avctx, sps) < 0)
+ if (decode_hrd_parameters(gb, logctx, sps) < 0)
return AVERROR_INVALIDDATA;
sps->vcl_hrd_parameters_present_flag = get_bits1(gb);
if (sps->vcl_hrd_parameters_present_flag)
- if (decode_hrd_parameters(gb, avctx, sps) < 0)
+ if (decode_hrd_parameters(gb, logctx, sps) < 0)
return AVERROR_INVALIDDATA;
if (sps->nal_hrd_parameters_present_flag ||
sps->vcl_hrd_parameters_present_flag)
if (sps->num_reorder_frames > 16U
/* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
- av_log(avctx, AV_LOG_ERROR,
+ av_log(logctx, AV_LOG_ERROR,
"Clipping illegal num_reorder_frames %d\n",
sps->num_reorder_frames);
sps->num_reorder_frames = 16;
for (i = 0; i < MAX_PPS_COUNT; i++)
av_buffer_unref(&ps->pps_list[i]);
- av_buffer_unref(&ps->sps_ref);
av_buffer_unref(&ps->pps_ref);
ps->pps = NULL;
sps->log2_max_poc_lsb = t + 4;
} else if (sps->poc_type == 1) { // FIXME #define
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->offset_for_non_ref_pic = get_se_golomb_long(gb);
+ sps->offset_for_top_to_bottom_field = get_se_golomb_long(gb);
+
+ if ( sps->offset_for_non_ref_pic == INT32_MIN
+ || sps->offset_for_top_to_bottom_field == INT32_MIN
+ ) {
+ av_log(avctx, AV_LOG_ERROR,
+ "offset_for_non_ref_pic or offset_for_top_to_bottom_field is out of range\n");
+ goto fail;
+ }
+
sps->poc_cycle_length = get_ue_golomb(gb);
if ((unsigned)sps->poc_cycle_length >=
goto fail;
}
- for (i = 0; i < sps->poc_cycle_length; i++)
- sps->offset_for_ref_frame[i] = get_se_golomb(gb);
+ for (i = 0; i < sps->poc_cycle_length; i++) {
+ sps->offset_for_ref_frame[i] = get_se_golomb_long(gb);
+ if (sps->offset_for_ref_frame[i] == INT32_MIN) {
+ av_log(avctx, AV_LOG_ERROR,
+ "offset_for_ref_frame is out of range\n");
+ goto fail;
+ }
+ }
} else if (sps->poc_type != 2) {
av_log(avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
goto fail;
}
if (get_bits_left(gb) < 0) {
- av_log(avctx, ignore_truncation ? AV_LOG_WARNING : AV_LOG_ERROR,
+ av_log_once(avctx, ignore_truncation ? AV_LOG_WARNING : AV_LOG_ERROR, AV_LOG_DEBUG,
+ &ps->overread_warning_printed[sps->vui_parameters_present_flag],
"Overread %s by %d bits\n", sps->vui_parameters_present_flag ? "VUI" : "SPS", -get_bits_left(gb));
if (!ignore_truncation)
goto fail;
return 1;
}
+static void pps_free(void *opaque, uint8_t *data)
+{
+ PPS *pps = (PPS*)data;
+
+ av_buffer_unref(&pps->sps_ref);
+
+ av_freep(&data);
+}
+
int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
H264ParamSets *ps, int bit_length)
{
return AVERROR_INVALIDDATA;
}
- pps_buf = av_buffer_allocz(sizeof(*pps));
- if (!pps_buf)
+ pps = av_mallocz(sizeof(*pps));
+ if (!pps)
+ return AVERROR(ENOMEM);
+ pps_buf = av_buffer_create((uint8_t*)pps, sizeof(*pps),
+ pps_free, NULL, 0);
+ if (!pps_buf) {
+ av_freep(&pps);
return AVERROR(ENOMEM);
- pps = (PPS*)pps_buf->data;
+ }
pps->data_size = gb->buffer_end - gb->buffer;
if (pps->data_size > sizeof(pps->data)) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
- sps = (const SPS*)ps->sps_list[pps->sps_id]->data;
+ pps->sps_ref = av_buffer_ref(ps->sps_list[pps->sps_id]);
+ if (!pps->sps_ref) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ pps->sps = (const SPS*)pps->sps_ref->data;
+ sps = pps->sps;
+
if (sps->bit_depth_luma > 14) {
av_log(avctx, AV_LOG_ERROR,
"Invalid luma bit depth=%d\n",
pps->slice_group_count = get_ue_golomb(gb) + 1;
if (pps->slice_group_count > 1) {
pps->mb_slice_group_map_type = get_ue_golomb(gb);
- av_log(avctx, AV_LOG_ERROR, "FMO not supported\n");
+ avpriv_report_missing_feature(avctx, "FMO");
+ ret = AVERROR_PATCHWELCOME;
+ goto fail;
}
pps->ref_count[0] = get_ue_golomb(gb) + 1;
pps->ref_count[1] = get_ue_golomb(gb) + 1;