#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
+#include "libavutil/time.h"
#include "riff.h"
#include "audiointerleave.h"
#include "url.h"
-#include <sys/time.h>
-#include <time.h>
#include <stdarg.h>
#if CONFIG_NETWORK
#include "network.h"
}
s->duration = s->start_time = AV_NOPTS_VALUE;
- av_strlcpy(s->filename, filename, sizeof(s->filename));
+ av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
/* allocate private data */
if (s->iformat->priv_data_size > 0) {
av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
--st->probe_packets;
- pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
- memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
- pd->buf_size += pkt->size;
- memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
+ if (pkt) {
+ pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+ memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
+ pd->buf_size += pkt->size;
+ memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
+ } else {
+ st->probe_packets = 0;
+ }
- if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
- //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes
+ if (!st->probe_packets ||
+ av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
if(st->codec->codec_id != CODEC_ID_PROBE){
pd->buf_size=0;
if (pktl) {
*pkt = pktl->pkt;
- if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
- !s->streams[pkt->stream_index]->probe_packets ||
- s->raw_packet_buffer_remaining_size < pkt->size){
- AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data;
+ st = s->streams[pkt->stream_index];
+ if (st->codec->codec_id != CODEC_ID_PROBE || !st->probe_packets ||
+ s->raw_packet_buffer_remaining_size < pkt->size) {
+ AVProbeData *pd;
+ if (st->probe_packets) {
+ probe_codec(s, st, NULL);
+ }
+ pd = &st->probe_data;
av_freep(&pd->buf);
pd->buf_size = 0;
s->raw_packet_buffer = pktl->next;
if (ret < 0) {
if (!pktl || ret == AVERROR(EAGAIN))
return ret;
- for (i = 0; i < s->nb_streams; i++)
- s->streams[i]->probe_packets = 0;
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->probe_packets) {
+ probe_codec(s, st, NULL);
+ }
+ }
continue;
}
*pden = 0;
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- if (st->r_frame_rate.num) {
- *pnum = st->r_frame_rate.den;
- *pden = st->r_frame_rate.num;
+ if (st->avg_frame_rate.num) {
+ *pnum = st->avg_frame_rate.den;
+ *pden = st->avg_frame_rate.num;
} else if(st->time_base.num*1000LL > st->time_base.den) {
*pnum = st->time_base.num;
*pden = st->time_base.den;
}
for (i=0; i<ic->nb_streams; i++) {
+#if FF_API_R_FRAME_RATE
ic->streams[i]->info->last_dts = AV_NOPTS_VALUE;
+#endif
+ ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE;
+ ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE;
}
count = 0;
if (ic->fps_probe_size >= 0)
fps_analyze_framecount = ic->fps_probe_size;
/* variable fps and no guess at the real fps */
- if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
- && st->info->duration_count < fps_analyze_framecount
+ if( tb_unreliable(st->codec) && !st->avg_frame_rate.num
+ && st->codec_info_nb_frames < fps_analyze_framecount
&& st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
break;
if(st->parser && st->parser->parser->split && !st->codec->extradata)
break;
}
- pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
- if ((ret = av_dup_packet(pkt)) < 0)
- goto find_stream_info_err;
+ if (ic->flags & AVFMT_FLAG_NOBUFFER) {
+ pkt = &pkt1;
+ } else {
+ pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1,
+ &ic->packet_buffer_end);
+ if ((ret = av_dup_packet(pkt)) < 0)
+ goto find_stream_info_err;
+ }
read_size += pkt->size;
st = ic->streams[pkt->stream_index];
- if (st->codec_info_nb_frames>1) {
- if (av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
+ if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) {
+ /* check for non-increasing dts */
+ if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
+ st->info->fps_last_dts >= pkt->dts) {
+ av_log(ic, AV_LOG_WARNING, "Non-increasing DTS in stream %d: "
+ "packet %d with DTS %"PRId64", packet %d with DTS "
+ "%"PRId64"\n", st->index, st->info->fps_last_dts_idx,
+ st->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts);
+ st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE;
+ }
+
+ /* update stored dts values */
+ if (st->info->fps_first_dts == AV_NOPTS_VALUE) {
+ st->info->fps_first_dts = pkt->dts;
+ st->info->fps_first_dts_idx = st->codec_info_nb_frames;
+ }
+ st->info->fps_last_dts = pkt->dts;
+ st->info->fps_last_dts_idx = st->codec_info_nb_frames;
+
+ /* check max_analyze_duration */
+ if (av_rescale_q(pkt->dts - st->info->fps_first_dts, st->time_base,
+ AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
break;
}
- st->info->codec_info_duration += pkt->duration;
}
+#if FF_API_R_FRAME_RATE
{
int64_t last = st->info->last_dts;
int64_t duration= pkt->dts - last;
double dur= duration * av_q2d(st->time_base);
-// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
if (st->info->duration_count < 2)
memset(st->info->duration_error, 0, sizeof(st->info->duration_error));
for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
if (last == AV_NOPTS_VALUE || st->info->duration_count <= 1)
st->info->last_dts = pkt->dts;
}
+#endif
if(st->parser && st->parser->parser->split && !st->codec->extradata){
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration)
+ /* estimate average framerate if not set by demuxer */
+ if (!st->avg_frame_rate.num && st->info->fps_last_dts != st->info->fps_first_dts) {
+ int64_t delta_dts = st->info->fps_last_dts - st->info->fps_first_dts;
+ int delta_packets = st->info->fps_last_dts_idx - st->info->fps_first_dts_idx;
+ int best_fps = 0;
+ double best_error = 0.01;
+
av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
- (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
- st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
+ delta_packets*(int64_t)st->time_base.den,
+ delta_dts*(int64_t)st->time_base.num, 60000);
+
+ /* round guessed framerate to a "standard" framerate if it's
+ * within 1% of the original estimate*/
+ for (j = 1; j < MAX_STD_TIMEBASES; j++) {
+ AVRational std_fps = (AVRational){get_std_framerate(j), 12*1001};
+ double error = fabs(av_q2d(st->avg_frame_rate) / av_q2d(std_fps) - 1);
+
+ if (error < best_error) {
+ best_error = error;
+ best_fps = std_fps.num;
+ }
+ }
+ if (best_fps) {
+ av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
+ best_fps, 12*1001, INT_MAX);
+ }
+ }
+#if FF_API_R_FRAME_RATE
// the check for tb_unreliable() is not completely correct, since this is not about handling
// a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
// ipmovie.c produces.
if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
if (st->info->duration_count && !st->r_frame_rate.num
- && tb_unreliable(st->codec) /*&&
- //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
- st->time_base.num*duration_sum[i]/st->info->duration_count*101LL > st->time_base.den*/){
+ && tb_unreliable(st->codec)) {
int num = 0;
double best_error= 2*av_q2d(st->time_base);
best_error = best_error*best_error*st->info->duration_count*1000*12*30;
for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {
double error = st->info->duration_error[j] * get_std_framerate(j);
-// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
if(error < best_error){
best_error= error;
num = get_std_framerate(j);
if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))
av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);
}
+#endif
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if(!st->codec->bits_per_coded_sample)
st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);
if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
if(st->avg_frame_rate.den && st->avg_frame_rate.num)
print_fps(av_q2d(st->avg_frame_rate), "fps");
+#if FF_API_R_FRAME_RATE
if(st->r_frame_rate.den && st->r_frame_rate.num)
print_fps(av_q2d(st->r_frame_rate), "tbr");
+#endif
if(st->time_base.den && st->time_base.num)
print_fps(1/av_q2d(st->time_base), "tbn");
if(st->codec->time_base.den && st->codec->time_base.num)
av_free(printed);
}
-int64_t av_gettime(void)
+#if FF_API_AV_GETTIME && CONFIG_SHARED && HAVE_SYMVER
+FF_SYMVER(int64_t, av_gettime, (void), "LIBAVFORMAT_54")
{
- struct timeval tv;
- gettimeofday(&tv,NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
+ return av_gettime();
}
+#endif
uint64_t ff_ntp_time(void)
{