* @param timestamp the time stamp to wrap
* @return resulting time stamp
*/
-static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)
+static int64_t wrap_timestamp(const AVStream *st, int64_t timestamp)
{
if (st->pts_wrap_behavior != AV_PTS_WRAP_IGNORE &&
st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) {
}
}
-int ff_copy_whiteblacklists(AVFormatContext *dst, AVFormatContext *src)
+int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
{
av_assert0(!dst->codec_whitelist &&
!dst->format_whitelist &&
return 0;
}
-static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
+static const AVCodec *find_decoder(AVFormatContext *s, const AVStream *st, enum AVCodecID codec_id)
{
#if FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
return avcodec_find_decoder(codec_id);
}
+static const AVCodec *find_probe_decoder(AVFormatContext *s, const AVStream *st, enum AVCodecID codec_id)
+{
+ const AVCodec *codec;
+
+#if CONFIG_H264_DECODER
+ /* Other parts of the code assume this decoder to be used for h264,
+ * so force it if possible. */
+ if (codec_id == AV_CODEC_ID_H264)
+ return avcodec_find_decoder_by_name("h264");
+#endif
+
+ codec = find_decoder(s, st, codec_id);
+ if (!codec)
+ return NULL;
+
+ if (codec->capabilities & AV_CODEC_CAP_AVOID_PROBING) {
+ const AVCodec *probe_codec = NULL;
+ while (probe_codec = av_codec_next(probe_codec)) {
+ if (probe_codec->id == codec_id &&
+ av_codec_is_decoder(probe_codec) &&
+ !(probe_codec->capabilities & (AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_EXPERIMENTAL))) {
+ return probe_codec;
+ }
+ }
+ }
+
+ return codec;
+}
+
int av_format_get_probe_score(const AVFormatContext *s)
{
return s->probe_score;
int score;
AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
- if (fmt && st->request_probe <= score) {
+ if (fmt) {
int i;
av_log(s, AV_LOG_DEBUG,
"Probe with size=%d, packets=%d detected %s with score=%d\n",
if (fmt_id_type[i].type != AVMEDIA_TYPE_AUDIO &&
st->codecpar->sample_rate)
continue;
+ if (st->request_probe > score &&
+ st->codecpar->codec_id != fmt_id_type[i].id)
+ continue;
st->codecpar->codec_id = fmt_id_type[i].id;
st->codecpar->codec_type = fmt_id_type[i].type;
st->internal->need_context_update = 1;
if (!st->internal->need_context_update)
continue;
+ /* close parser, because it depends on the codec */
+ if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
+ av_parser_close(st->parser);
+ st->parser = NULL;
+ }
+
/* update internal codec context, for the parser */
ret = avcodec_parameters_to_context(st->internal->avctx, st->codecpar);
if (ret < 0)
if (s->subtitle_codec_id)
st->codecpar->codec_id = s->subtitle_codec_id;
break;
+ case AVMEDIA_TYPE_DATA:
+ if (s->data_codec_id)
+ st->codecpar->codec_id = s->data_codec_id;
+ break;
}
}
return ret;
for (i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
- if (st->probe_packets)
+ if (st->probe_packets || st->request_probe > 0)
if ((err = probe_codec(s, st, NULL)) < 0)
return err;
av_assert0(st->request_probe <= 0);
st->info->found_decoder = 0;
}
+ /* close parser, because it depends on the codec */
+ if (st->parser && st->internal->avctx->codec_id != st->codecpar->codec_id) {
+ av_parser_close(st->parser);
+ st->parser = NULL;
+ }
+
ret = avcodec_parameters_to_context(st->internal->avctx, st->codecpar);
if (ret < 0)
return ret;
while (b - a > 1) {
m = (a + b) >> 1;
+
+ // Search for the next non-discarded packet.
+ while ((entries[m].flags & AVINDEX_DISCARD_FRAME) && m < b) {
+ m++;
+ if (m == b && entries[m].timestamp >= wanted_timestamp) {
+ m = b - 1;
+ break;
+ }
+ }
+
timestamp = entries[m].timestamp;
if (timestamp >= wanted_timestamp)
b = m;
max_ts = av_rescale_rnd(max_ts, time_base.den,
time_base.num * (int64_t)AV_TIME_BASE,
AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+ stream_index = 0;
}
ret = s->iformat->read_seek2(s, stream_index, min_ts,
*/
static void update_stream_timings(AVFormatContext *ic)
{
- int64_t start_time, start_time1, start_time_text, end_time, end_time1;
+ int64_t start_time, start_time1, start_time_text, end_time, end_time1, end_time_text;
int64_t duration, duration1, filesize;
int i;
AVStream *st;
start_time = INT64_MAX;
start_time_text = INT64_MAX;
end_time = INT64_MIN;
+ end_time_text = INT64_MIN;
duration = INT64_MIN;
for (i = 0; i < ic->nb_streams; i++) {
st = ic->streams[i];
end_time1 = av_rescale_q_rnd(st->duration, st->time_base,
AV_TIME_BASE_Q,
AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
- if (end_time1 != AV_NOPTS_VALUE && start_time1 <= INT64_MAX - end_time1) {
+ if (end_time1 != AV_NOPTS_VALUE && (end_time1 > 0 ? start_time1 <= INT64_MAX - end_time1 : start_time1 >= INT64_MIN - end_time1)) {
end_time1 += start_time1;
- end_time = FFMAX(end_time, end_time1);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
+ end_time_text = FFMAX(end_time_text, end_time1);
+ else
+ end_time = FFMAX(end_time, end_time1);
}
for (p = NULL; (p = av_find_program_from_stream(ic, p, i)); ) {
if (p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1)
else if (start_time > start_time_text)
av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE);
+ if (end_time == INT64_MIN || (end_time < end_time_text && end_time_text - end_time < AV_TIME_BASE)) {
+ end_time = end_time_text;
+ } else if (end_time < end_time_text) {
+ av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream endtime %f\n", end_time_text / (float)AV_TIME_BASE);
+ }
+
if (start_time != INT64_MAX) {
ic->start_time = start_time;
if (end_time != INT64_MIN) {
- if (ic->nb_programs) {
+ if (ic->nb_programs > 1) {
for (i = 0; i < ic->nb_programs; i++) {
p = ic->programs[i];
if (p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time)
(st->codecpar->codec_id != -st->info->found_decoder || !st->codecpar->codec_id)) {
AVDictionary *thread_opt = NULL;
- codec = find_decoder(s, st, st->codecpar->codec_id);
+ codec = find_probe_decoder(s, st, st->codecpar->codec_id);
if (!codec) {
st->info->found_decoder = -st->codecpar->codec_id;
return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
case 4:
return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
+ case 8:
+ return be ? AV_CODEC_ID_PCM_S64BE : AV_CODEC_ID_PCM_S64LE;
default:
return AV_CODEC_ID_NONE;
}
int64_t max_subtitle_analyze_duration;
int64_t probesize = ic->probesize;
int eof_reached = 0;
+ int64_t *missing_streams = av_opt_ptr(ic->iformat->priv_class, ic->priv_data, "missing_streams");
flush_codecs = probesize > 0;
if (!avctx->time_base.num)
avctx->time_base = st->time_base;
}
+
+ /* check if the caller has overridden the codec id */
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (st->codec->codec_id != st->internal->orig_codec_id) {
+ st->codecpar->codec_id = st->codec->codec_id;
+ st->codecpar->codec_type = st->codec->codec_type;
+ st->internal->orig_codec_id = st->codec->codec_id;
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
// only for the split stuff
if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) {
st->parser = av_parser_init(st->codecpar->codec_id);
}
}
- /* check if the caller has overridden the codec id */
-#if FF_API_LAVF_AVCTX
-FF_DISABLE_DEPRECATION_WARNINGS
- if (st->codec->codec_id != st->internal->orig_codec_id) {
- st->codecpar->codec_id = st->codec->codec_id;
- st->codecpar->codec_type = st->codec->codec_type;
- st->internal->orig_codec_id = st->codec->codec_id;
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
if (st->codecpar->codec_id != st->internal->orig_codec_id)
st->internal->orig_codec_id = st->codecpar->codec_id;
if (st->request_probe <= 0)
st->internal->avctx_inited = 1;
- codec = find_decoder(ic, st, st->codecpar->codec_id);
+ 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. */
break;
}
analyzed_all_streams = 0;
+ if (!missing_streams || !*missing_streams)
if (i == ic->nb_streams) {
analyzed_all_streams = 1;
/* NOTE: If the format has no header, then we need to read some
st = ic->streams[stream_index];
avctx = st->internal->avctx;
if (!has_codec_parameters(st, NULL)) {
- const AVCodec *codec = find_decoder(ic, st, st->codecpar->codec_id);
+ const AVCodec *codec = find_probe_decoder(ic, st, st->codecpar->codec_id);
if (codec && !avctx->codec) {
if (avcodec_open2(avctx, codec, (options && stream_index < orig_nb_streams) ? &options[stream_index] : NULL) < 0)
av_log(ic, AV_LOG_WARNING,
st->codec->height = st->internal->avctx->height;
}
- if (st->codec->codec_tag != MKTAG('t','m','c','d'))
+ if (st->codec->codec_tag != MKTAG('t','m','c','d')) {
st->codec->time_base = st->internal->avctx->time_base;
+ st->codec->ticks_per_frame = st->internal->avctx->ticks_per_frame;
+ }
st->codec->framerate = st->avg_frame_rate;
if (st->internal->avctx->subtitle_header) {
return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
}
-int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
+int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
{
const char *p;
char *q, buf1[20], c;
case '%':
goto addchar;
case 'd':
- if (percentd_found)
+ if (!(flags & AV_FRAME_FILENAME_FLAGS_MULTIPLE) && percentd_found)
goto fail;
percentd_found = 1;
if (number < 0)
return -1;
}
+int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
+{
+ return av_get_frame_filename2(buf, buf_size, path, number, 0);
+}
+
void av_url_split(char *proto, int proto_size,
char *authorization, int authorization_size,
char *hostname, int hostname_size,
return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
else if (codec_id == ofmt->video_codec ||
codec_id == ofmt->audio_codec ||
- codec_id == ofmt->subtitle_codec)
+ codec_id == ofmt->subtitle_codec ||
+ codec_id == ofmt->data_codec)
return 1;
}
return AVERROR_PATCHWELCOME;
return 0;
}
-uint8_t *av_stream_get_side_data(AVStream *st, enum AVPacketSideDataType type,
- int *size)
+#if FF_API_NOCONST_GET_SIDE_DATA
+uint8_t *av_stream_get_side_data(AVStream *st,
+ enum AVPacketSideDataType type, int *size)
+#else
+uint8_t *av_stream_get_side_data(const AVStream *st,
+ enum AVPacketSideDataType type, int *size)
+#endif
{
int i;
{
int64_t timestamp;
int ret = ff_parse_creation_time_metadata(s, ×tamp, 0);
- if (ret == 1) {
- time_t seconds = timestamp / 1000000;
- struct tm *ptm, tmbuf;
- ptm = gmtime_r(&seconds, &tmbuf);
- if (ptm) {
- char buf[32];
- if (!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", ptm))
- return AVERROR_EXTERNAL;
- av_strlcatf(buf, sizeof(buf), ".%06dZ", (int)(timestamp % 1000000));
- av_dict_set(&s->metadata, "creation_time", buf, 0);
- } else {
- return AVERROR_EXTERNAL;
- }
- }
+ if (ret == 1)
+ return avpriv_dict_set_timestamp(&s->metadata, "creation_time", timestamp);
return ret;
}
par->extradata_size = buf->len;
return 0;
}
+
+int avformat_transfer_internal_stream_timing_info(const AVOutputFormat *ofmt,
+ AVStream *ost, const AVStream *ist,
+ enum AVTimebaseSource copy_tb)
+{
+ //TODO: use [io]st->internal->avctx
+ const AVCodecContext *dec_ctx = ist->codec;
+ AVCodecContext *enc_ctx = ost->codec;
+
+ enc_ctx->time_base = ist->time_base;
+ /*
+ * Avi is a special case here because it supports variable fps but
+ * having the fps and timebase differe significantly adds quite some
+ * overhead
+ */
+ if (!strcmp(ofmt->name, "avi")) {
+#if FF_API_R_FRAME_RATE
+ if (copy_tb == AVFMT_TBCF_AUTO && ist->r_frame_rate.num
+ && av_q2d(ist->r_frame_rate) >= av_q2d(ist->avg_frame_rate)
+ && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(ist->time_base)
+ && 0.5/av_q2d(ist->r_frame_rate) > av_q2d(dec_ctx->time_base)
+ && av_q2d(ist->time_base) < 1.0/500 && av_q2d(dec_ctx->time_base) < 1.0/500
+ || copy_tb == AVFMT_TBCF_R_FRAMERATE) {
+ enc_ctx->time_base.num = ist->r_frame_rate.den;
+ enc_ctx->time_base.den = 2*ist->r_frame_rate.num;
+ enc_ctx->ticks_per_frame = 2;
+ } else
+#endif
+ if (copy_tb == AVFMT_TBCF_AUTO && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > 2*av_q2d(ist->time_base)
+ && av_q2d(ist->time_base) < 1.0/500
+ || copy_tb == AVFMT_TBCF_DECODER) {
+ enc_ctx->time_base = dec_ctx->time_base;
+ enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
+ enc_ctx->time_base.den *= 2;
+ enc_ctx->ticks_per_frame = 2;
+ }
+ } else if (!(ofmt->flags & AVFMT_VARIABLE_FPS)
+ && !av_match_name(ofmt->name, "mov,mp4,3gp,3g2,psp,ipod,ismv,f4v")) {
+ if (copy_tb == AVFMT_TBCF_AUTO && dec_ctx->time_base.den
+ && av_q2d(dec_ctx->time_base)*dec_ctx->ticks_per_frame > av_q2d(ist->time_base)
+ && av_q2d(ist->time_base) < 1.0/500
+ || copy_tb == AVFMT_TBCF_DECODER) {
+ enc_ctx->time_base = dec_ctx->time_base;
+ enc_ctx->time_base.num *= dec_ctx->ticks_per_frame;
+ }
+ }
+
+ if ((enc_ctx->codec_tag == AV_RL32("tmcd") || ost->codecpar->codec_tag == AV_RL32("tmcd"))
+ && dec_ctx->time_base.num < dec_ctx->time_base.den
+ && dec_ctx->time_base.num > 0
+ && 121LL*dec_ctx->time_base.num > dec_ctx->time_base.den) {
+ enc_ctx->time_base = dec_ctx->time_base;
+ }
+
+ if (ost->avg_frame_rate.num)
+ enc_ctx->time_base = av_inv_q(ost->avg_frame_rate);
+
+ av_reduce(&enc_ctx->time_base.num, &enc_ctx->time_base.den,
+ enc_ctx->time_base.num, enc_ctx->time_base.den, INT_MAX);
+
+ return 0;
+}
+
+AVRational av_stream_get_codec_timebase(const AVStream *st)
+{
+ // See avformat_transfer_internal_stream_timing_info() TODO.
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+ return st->codec->time_base;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ return st->internal->avctx->time_base;
+#endif
+}