*/
static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp)
{
- if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE &&
+ if (st->internal->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && st->pts_wrap_bits < 64 &&
st->internal->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) {
if (st->internal->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET &&
timestamp < st->internal->pts_wrap_reference)
int ffio_limit(AVIOContext *s, int size)
{
if (s->maxsize>= 0) {
- int64_t remaining= s->maxsize - avio_tell(s);
+ int64_t pos = avio_tell(s);
+ int64_t remaining= s->maxsize - pos;
if (remaining < size) {
int64_t newsize = avio_size(s);
if (!s->maxsize || s->maxsize<newsize)
s->maxsize = newsize - !newsize;
- remaining= s->maxsize - avio_tell(s);
- remaining= FFMAX(remaining, 0);
+ if (pos > s->maxsize && s->maxsize >= 0)
+ s->maxsize = AVERROR(EIO);
+ if (s->maxsize >= 0)
+ remaining = s->maxsize - pos;
}
- if (s->maxsize>= 0 && remaining+1 < size) {
- av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1);
- size = remaining+1;
+ if (s->maxsize >= 0 && remaining < size && size > 1) {
+ av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG,
+ "Truncating packet of size %d to %"PRId64"\n",
+ size, remaining + !remaining);
+ size = remaining + !remaining;
}
}
return size;
if (fmt_id_type[i].type != AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate)
continue;
- if (st->request_probe > score &&
+ if (st->internal->request_probe > score &&
st->codecpar->codec_id != fmt_id_type[i].id)
continue;
st->codecpar->codec_id = fmt_id_type[i].id;
static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
{
- if (st->request_probe>0) {
- AVProbeData *pd = &st->probe_data;
+ if (st->internal->request_probe>0) {
+ AVProbeData *pd = &st->internal->probe_data;
int end;
av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
--st->probe_packets;
|| end) {
pd->buf_size = 0;
av_freep(&pd->buf);
- st->request_probe = -1;
+ st->internal->request_probe = -1;
if (st->codecpar->codec_id != AV_CODEC_ID_NONE) {
av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
} else
if (s->internal->raw_packet_buffer_remaining_size <= 0)
if ((err = probe_codec(s, st, NULL)) < 0)
return err;
- if (st->request_probe <= 0) {
+ if (st->internal->request_probe <= 0) {
avpriv_packet_list_get(&s->internal->raw_packet_buffer,
&s->internal->raw_packet_buffer_end, pkt);
s->internal->raw_packet_buffer_remaining_size += pkt->size;
return ret;
for (i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
- if (st->probe_packets || st->request_probe > 0)
+ if (st->probe_packets || st->internal->request_probe > 0)
if ((err = probe_codec(s, st, NULL)) < 0)
return err;
- av_assert0(st->request_probe <= 0);
+ av_assert0(st->internal->request_probe <= 0);
}
continue;
}
if (s->use_wallclock_as_timestamps)
pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base);
- if (!pktl && st->request_probe <= 0)
+ if (!pktl && st->internal->request_probe <= 0)
return ret;
err = avpriv_packet_list_put(&s->internal->raw_packet_buffer,
return 1;
#endif
if (st->internal->avctx->has_b_frames<3)
- return st->nb_decoded_frames >= 7;
+ return st->internal->nb_decoded_frames >= 7;
else if (st->internal->avctx->has_b_frames<4)
- return st->nb_decoded_frames >= 18;
+ return st->internal->nb_decoded_frames >= 18;
else
- return st->nb_decoded_frames >= 20;
+ return st->internal->nb_decoded_frames >= 20;
}
static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl)
dts == AV_NOPTS_VALUE ||
st->cur_dts == AV_NOPTS_VALUE ||
st->cur_dts < INT_MIN + RELATIVE_TS_BASE ||
+ dts < INT_MIN + (st->cur_dts - RELATIVE_TS_BASE) ||
is_relative(dts))
return;
if (st->start_time == AV_NOPTS_VALUE && pktl_it->pkt.pts != AV_NOPTS_VALUE) {
st->start_time = pktl_it->pkt.pts;
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate)
- st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base));
+ st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base));
}
}
st->start_time = pts;
}
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate)
- st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base));
+ st->start_time = av_sat_add64(st->start_time, av_rescale_q(st->internal->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base));
}
}
presentation_delayed = 1;
if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
- st->pts_wrap_bits < 63 &&
+ st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << (st->pts_wrap_bits - 1)) &&
pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) {
if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) {
pkt->dts -= 1LL << st->pts_wrap_bits;
}
if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) {
- st->pts_buffer[0] = pkt->pts;
- for (i = 0; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
- FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
+ st->internal->pts_buffer[0] = pkt->pts;
+ for (i = 0; i<delay && st->internal->pts_buffer[i] > st->internal->pts_buffer[i + 1]; i++)
+ FFSWAP(int64_t, st->internal->pts_buffer[i], st->internal->pts_buffer[i + 1]);
if(has_decode_delay_been_guessed(st))
- pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts);
+ pkt->dts = select_from_pts_buffer(st, st->internal->pts_buffer, pkt->dts);
}
// We skipped it above so we try here.
if (!onein_oneout)
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
pkt->pos = -1;
/* increment read pointer */
- data += len;
+ av_assert1(data || !len);
+ data = len ? data + len : data;
size -= len;
got_output = !!out_pkt.size;
av_packet_unref(pkt);
}
if (pkt->flags & AV_PKT_FLAG_KEY)
- st->skip_to_keyframe = 0;
- if (st->skip_to_keyframe) {
+ st->internal->skip_to_keyframe = 0;
+ if (st->internal->skip_to_keyframe) {
av_packet_unref(pkt);
got_packet = 0;
}
if (ret >= 0) {
AVStream *st = s->streams[pkt->stream_index];
int discard_padding = 0;
- if (st->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) {
+ if (st->internal->first_discard_sample && pkt->pts != AV_NOPTS_VALUE) {
int64_t pts = pkt->pts - (is_relative(pkt->pts) ? RELATIVE_TS_BASE : 0);
int64_t sample = ts_to_samples(st, pts);
int duration = ts_to_samples(st, pkt->duration);
int64_t end_sample = sample + duration;
- if (duration > 0 && end_sample >= st->first_discard_sample &&
- sample < st->last_discard_sample)
- discard_padding = FFMIN(end_sample - st->first_discard_sample, duration);
+ if (duration > 0 && end_sample >= st->internal->first_discard_sample &&
+ sample < st->internal->last_discard_sample)
+ discard_padding = FFMIN(end_sample - st->internal->first_discard_sample, duration);
}
- if (st->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE))
- st->skip_samples = st->start_skip_samples;
- if (st->skip_samples || discard_padding) {
+ if (st->internal->start_skip_samples && (pkt->pts == 0 || pkt->pts == RELATIVE_TS_BASE))
+ st->internal->skip_samples = st->internal->start_skip_samples;
+ if (st->internal->skip_samples || discard_padding) {
uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
if (p) {
- AV_WL32(p, st->skip_samples);
+ AV_WL32(p, st->internal->skip_samples);
AV_WL32(p + 4, discard_padding);
- av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->skip_samples, discard_padding);
+ av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->internal->skip_samples, discard_padding);
}
- st->skip_samples = 0;
+ st->internal->skip_samples = 0;
}
if (st->internal->inject_global_side_data) {
st->probe_packets = s->max_probe_packets;
for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
- st->pts_buffer[j] = AV_NOPTS_VALUE;
+ st->internal->pts_buffer[j] = AV_NOPTS_VALUE;
if (s->internal->inject_global_side_data)
st->internal->inject_global_side_data = 1;
- st->skip_samples = 0;
+ st->internal->skip_samples = 0;
}
}
AVStream *st = s->streams[stream_index];
unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry);
- if ((unsigned) st->nb_index_entries >= max_entries) {
+ if ((unsigned) st->internal->nb_index_entries >= max_entries) {
int i;
- for (i = 0; 2 * i < st->nb_index_entries; i++)
- st->index_entries[i] = st->index_entries[2 * i];
- st->nb_index_entries = i;
+ for (i = 0; 2 * i < st->internal->nb_index_entries; i++)
+ st->internal->index_entries[i] = st->internal->index_entries[2 * i];
+ st->internal->nb_index_entries = i;
}
}
int size, int distance, int flags)
{
timestamp = wrap_timestamp(st, timestamp);
- return ff_add_index_entry(&st->index_entries, &st->nb_index_entries,
- &st->index_entries_allocated_size, pos,
+ return ff_add_index_entry(&st->internal->index_entries, &st->internal->nb_index_entries,
+ &st->internal->index_entries_allocated_size, pos,
timestamp, size, distance, flags);
}
if (ist1 == ist2)
continue;
- for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
- AVIndexEntry *e1 = &st1->index_entries[i1];
+ for (i1 = i2 = 0; i1 < st1->internal->nb_index_entries; i1++) {
+ AVIndexEntry *e1 = &st1->internal->index_entries[i1];
int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
skip = FFMAX(skip, e1->size);
- for (; i2 < st2->nb_index_entries; i2++) {
- AVIndexEntry *e2 = &st2->index_entries[i2];
+ for (; i2 < st2->internal->nb_index_entries; i2++) {
+ AVIndexEntry *e2 = &st2->internal->index_entries[i2];
int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
if (e2_pts < e1_pts || e2_pts - (uint64_t)e1_pts < time_tolerance)
continue;
int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
{
- return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
+ return ff_index_search_timestamp(st->internal->index_entries, st->internal->nb_index_entries,
wanted_timestamp, flags);
}
pos_limit = -1; // GCC falsely says it may be uninitialized.
st = s->streams[stream_index];
- if (st->index_entries) {
+ if (st->internal->index_entries) {
AVIndexEntry *e;
/* FIXME: Whole function must be checked for non-keyframe entries in
index = av_index_search_timestamp(st, target_ts,
flags | AVSEEK_FLAG_BACKWARD);
index = FFMAX(index, 0);
- e = &st->index_entries[index];
+ e = &st->internal->index_entries[index];
if (e->timestamp <= target_ts || e->pos == e->min_distance) {
pos_min = e->pos;
index = av_index_search_timestamp(st, target_ts,
flags & ~AVSEEK_FLAG_BACKWARD);
- av_assert0(index < st->nb_index_entries);
+ av_assert0(index < st->internal->nb_index_entries);
if (index >= 0) {
- e = &st->index_entries[index];
+ e = &st->internal->index_entries[index];
av_assert1(e->timestamp >= target_ts);
pos_max = e->pos;
ts_max = e->timestamp;
index = av_index_search_timestamp(st, timestamp, flags);
- if (index < 0 && st->nb_index_entries &&
- timestamp < st->index_entries[0].timestamp)
+ if (index < 0 && st->internal->nb_index_entries &&
+ timestamp < st->internal->index_entries[0].timestamp)
return -1;
- if (index < 0 || index == st->nb_index_entries - 1) {
+ if (index < 0 || index == st->internal->nb_index_entries - 1) {
AVPacket pkt;
int nonkey = 0;
- if (st->nb_index_entries) {
- av_assert0(st->index_entries);
- ie = &st->index_entries[st->nb_index_entries - 1];
+ if (st->internal->nb_index_entries) {
+ av_assert0(st->internal->index_entries);
+ ie = &st->internal->index_entries[st->internal->nb_index_entries - 1];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
ff_update_cur_dts(s, st, ie->timestamp);
if (s->iformat->read_seek)
if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
return 0;
- ie = &st->index_entries[index];
+ ie = &st->internal->index_entries[index];
if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
ff_update_cur_dts(s, st, ie->timestamp);
st->last_IP_pts = AV_NOPTS_VALUE;
st->internal->last_dts_for_order_check = AV_NOPTS_VALUE;
for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
- st->pts_buffer[j] = AV_NOPTS_VALUE;
+ st->internal->pts_buffer[j] = AV_NOPTS_VALUE;
}
}
/* 1:1 map to AVDurationEstimationMethod */
-static const char *duration_name[] = {
+static const char *const duration_name[] = {
[AVFMT_DURATION_FROM_PTS] = "pts",
[AVFMT_DURATION_FROM_STREAM] = "stream",
[AVFMT_DURATION_FROM_BITRATE] = "bit rate",
FAIL("unspecified sample rate");
if (!avctx->channels)
FAIL("unspecified number of channels");
- if (st->internal->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS)
+ if (st->internal->info->found_decoder >= 0 && !st->internal->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS)
FAIL("no decodable DTS frames");
break;
case AVMEDIA_TYPE_VIDEO:
/* Force thread count to 1 since the H.264 decoder will not extract
* SPS and PPS to extradata during multi-threaded decoding. */
av_dict_set(options ? options : &thread_opt, "threads", "1", 0);
+ /* Force lowres to 0. The decoder might reduce the video size by the
+ * lowres factor, and we don't want that propagated to the stream's
+ * codecpar */
+ av_dict_set(options ? options : &thread_opt, "lowres", "0", 0);
if (s->codec_whitelist)
av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
ret = avcodec_open2(avctx, codec, options ? options : &thread_opt);
}
if (ret >= 0) {
if (got_picture)
- st->nb_decoded_frames++;
+ st->internal->nb_decoded_frames++;
ret = got_picture;
}
}
return AV_CODEC_ID_NONE;
}
-static void compute_chapters_end(AVFormatContext *s)
+static int chapter_start_cmp(const void *p1, const void *p2)
{
- unsigned int i, j;
+ AVChapter *ch1 = *(AVChapter**)p1;
+ AVChapter *ch2 = *(AVChapter**)p2;
+ int delta = av_compare_ts(ch1->start, ch1->time_base, ch2->start, ch2->time_base);
+ if (delta)
+ return delta;
+ return (ch1 > ch2) - (ch1 < ch2);
+}
+
+static int compute_chapters_end(AVFormatContext *s)
+{
+ unsigned int i;
int64_t max_time = 0;
+ AVChapter **timetable = av_malloc(s->nb_chapters * sizeof(*timetable));
+
+ if (!timetable)
+ return AVERROR(ENOMEM);
if (s->duration > 0 && s->start_time < INT64_MAX - s->duration)
max_time = s->duration +
((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time);
for (i = 0; i < s->nb_chapters; i++)
- if (s->chapters[i]->end == AV_NOPTS_VALUE) {
- AVChapter *ch = s->chapters[i];
+ timetable[i] = s->chapters[i];
+ qsort(timetable, s->nb_chapters, sizeof(*timetable), chapter_start_cmp);
+
+ for (i = 0; i < s->nb_chapters; i++)
+ if (timetable[i]->end == AV_NOPTS_VALUE) {
+ AVChapter *ch = timetable[i];
int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q,
- ch->time_base)
- : INT64_MAX;
+ ch->time_base)
+ : INT64_MAX;
- for (j = 0; j < s->nb_chapters; j++) {
- AVChapter *ch1 = s->chapters[j];
+ if (i + 1 < s->nb_chapters) {
+ AVChapter *ch1 = timetable[i + 1];
int64_t next_start = av_rescale_q(ch1->start, ch1->time_base,
- ch->time_base);
- if (j != i && next_start > ch->start && next_start < end)
+ ch->time_base);
+ if (next_start > ch->start && next_start < end)
end = next_start;
}
ch->end = (end == INT64_MAX || end < ch->start) ? ch->start : end;
}
+ av_free(timetable);
+ return 0;
}
static int get_std_framerate(int i)
FF_ENABLE_DEPRECATION_WARNINGS
#endif
// only for the split stuff
- if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) {
+ if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->internal->request_probe <= 0) {
st->parser = av_parser_init(st->codecpar->codec_id);
if (st->parser) {
if (st->need_parsing == AVSTREAM_PARSE_HEADERS) {
ret = avcodec_parameters_to_context(avctx, st->codecpar);
if (ret < 0)
goto find_stream_info_err;
- if (st->request_probe <= 0)
+ if (st->internal->request_probe <= 0)
st->internal->avctx_inited = 1;
codec = find_probe_decoder(ic, st, st->codecpar->codec_id);
/* Force thread count to 1 since the H.264 decoder will not extract
* SPS and PPS to extradata during multi-threaded decoding. */
av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0);
+ /* Force lowres to 0. The decoder might reduce the video size by the
+ * lowres factor, and we don't want that propagated to the stream's
+ * codecpar */
+ av_dict_set(options ? &options[i] : &thread_opt, "lowres", "0", 0);
if (ic->codec_whitelist)
av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0);
}
// Try to just open decoders, in case this is enough to get parameters.
- if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) {
+ if (!has_codec_parameters(st, NULL) && st->internal->request_probe <= 0) {
if (codec && !avctx->codec)
if (avcodec_open2(avctx, codec, options ? &options[i] : &thread_opt) < 0)
av_log(ic, AV_LOG_WARNING,
if ( t == 0
&& st->codec_info_nb_frames>30
&& st->internal->info->fps_first_dts != AV_NOPTS_VALUE
- && st->internal->info->fps_last_dts != AV_NOPTS_VALUE)
- t = FFMAX(t, av_rescale_q(st->internal->info->fps_last_dts - st->internal->info->fps_first_dts, st->time_base, AV_TIME_BASE_Q));
+ && st->internal->info->fps_last_dts != AV_NOPTS_VALUE) {
+ int64_t dur = av_sat_sub64(st->internal->info->fps_last_dts, st->internal->info->fps_first_dts);
+ t = FFMAX(t, av_rescale_q(dur, st->time_base, AV_TIME_BASE_Q));
+ }
if (analyzed_all_streams) limit = max_analyze_duration;
else if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
}
}
- compute_chapters_end(ic);
+ ret = compute_chapters_end(ic);
+ if (ret < 0)
+ goto find_stream_info_err;
/* update the stream parameters from the internal codec contexts */
for (i = 0; i < ic->nb_streams; i++) {
st = ic->streams[i];
if (st->internal->avctx_inited) {
- int orig_w = st->codecpar->width;
- int orig_h = st->codecpar->height;
ret = avcodec_parameters_from_context(st->codecpar, st->internal->avctx);
if (ret < 0)
goto find_stream_info_err;
ret = add_coded_side_data(st, st->internal->avctx);
if (ret < 0)
goto find_stream_info_err;
-#if FF_API_LOWRES
- // The decoder might reduce the video size by the lowres factor.
- if (st->internal->avctx->lowres && orig_w) {
- st->codecpar->width = orig_w;
- st->codecpar->height = orig_h;
- }
-#endif
}
#if FF_API_LAVF_AVCTX
avcodec_free_context(&st->internal->avctx);
av_bsf_free(&st->internal->bsfc);
av_freep(&st->internal->priv_pts);
+ av_freep(&st->internal->index_entries);
+ av_freep(&st->internal->probe_data.buf);
+
av_bsf_free(&st->internal->extract_extradata.bsf);
av_packet_free(&st->internal->extract_extradata.pkt);
av_dict_free(&st->metadata);
avcodec_parameters_free(&st->codecpar);
- av_freep(&st->probe_data.buf);
- av_freep(&st->index_entries);
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
avcodec_free_context(&st->codec);
st->last_IP_pts = AV_NOPTS_VALUE;
st->internal->last_dts_for_order_check = AV_NOPTS_VALUE;
for (i = 0; i < MAX_REORDER_DELAY + 1; i++)
- st->pts_buffer[i] = AV_NOPTS_VALUE;
+ st->internal->pts_buffer[i] = AV_NOPTS_VALUE;
st->sample_aspect_ratio = (AVRational) { 0, 1 };
dynarray_add(&ac->programs, &ac->nb_programs, program);
program->discard = AVDISCARD_NONE;
program->pmt_version = -1;
+ program->id = id;
+ program->pts_wrap_reference = AV_NOPTS_VALUE;
+ program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
+ program->start_time =
+ program->end_time = AV_NOPTS_VALUE;
}
- program->id = id;
- program->pts_wrap_reference = AV_NOPTS_VALUE;
- program->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
-
- program->start_time =
- program->end_time = AV_NOPTS_VALUE;
-
return program;
}
return NULL;
}
- for (i = 0; i < s->nb_chapters; i++)
- if (s->chapters[i]->id == id)
- chapter = s->chapters[i];
+ if (!s->nb_chapters) {
+ s->internal->chapter_ids_monotonic = 1;
+ } else if (!s->internal->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) {
+ s->internal->chapter_ids_monotonic = 0;
+ for (i = 0; i < s->nb_chapters; i++)
+ if (s->chapters[i]->id == id)
+ chapter = s->chapters[i];
+ }
if (!chapter) {
chapter = av_mallocz(sizeof(AVChapter));
if (c == '%') {
do {
nd = 0;
- while (av_isdigit(*p))
+ while (av_isdigit(*p)) {
+ if (nd >= INT_MAX / 10 - 255)
+ goto fail;
nd = nd * 10 + *p++ - '0';
+ }
c = *p++;
} while (av_isdigit(c));