#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
+#include "libavutil/time.h"
#include "libavutil/timestamp.h"
#include "riff.h"
#include "audiointerleave.h"
--st->probe_packets;
if (pkt) {
- pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+ uint8_t *new_buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+ if(!new_buf)
+ goto no_packet;
+ pd->buf = new_buf;
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 {
+no_packet:
st->probe_packets = 0;
}
pkt->pts, pkt->dts, pkt->pos);
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
+ pkt->pos = -1;
/* increment read pointer */
data += len;
size -= len;
out_pkt.dts = st->parser->dts;
out_pkt.pos = st->parser->pos;
+ if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+ out_pkt.pos = st->parser->frame_offset;
+
if (st->parser->key_frame == 1 ||
(st->parser->key_frame == -1 &&
st->parser->pict_type == AV_PICTURE_TYPE_I))
compute_pkt_fields(s, st, st->parser, &out_pkt);
- if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
- out_pkt.flags & AV_PKT_FLAG_KEY) {
- int64_t pos= (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? out_pkt.pos : st->parser->frame_offset;
- ff_reduce_index(s, st->index);
- av_add_index_entry(st, pos, out_pkt.dts,
- 0, 0, AVINDEX_KEYFRAME);
- }
-
if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
out_pkt.destruct = pkt->destruct;
pkt->destruct = NULL;
const int genpts = s->flags & AVFMT_FLAG_GENPTS;
int eof = 0;
int ret;
+ AVStream *st;
if (!genpts) {
ret = s->packet_buffer ? read_from_packet_buffer(&s->packet_buffer,
return_packet:
- if(s->streams[pkt->stream_index]->skip_samples) {
+ st = s->streams[pkt->stream_index];
+ if (st->skip_samples) {
uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
- AV_WL32(p, s->streams[pkt->stream_index]->skip_samples);
- av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", s->streams[pkt->stream_index]->skip_samples);
- s->streams[pkt->stream_index]->skip_samples = 0;
+ AV_WL32(p, st->skip_samples);
+ av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples);
+ st->skip_samples = 0;
+ }
+
+ if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) {
+ ff_reduce_index(s, st->index);
+ av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
}
if (is_relative(pkt->dts))
pkt->dts -= RELATIVE_TS_BASE;
if (is_relative(pkt->pts))
pkt->pts -= RELATIVE_TS_BASE;
+
return ret;
}
if((unsigned)*nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
return -1;
+ if(timestamp == AV_NOPTS_VALUE)
+ return AVERROR(EINVAL);
+
if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known
timestamp -= RELATIVE_TS_BASE;
AVPacket pkt1, *pkt;
int64_t old_offset = avio_tell(ic->pb);
int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those
- int flush_codecs = 1;
+ int flush_codecs = ic->probesize > 0;
if(ic->pb)
av_log(ic, AV_LOG_DEBUG, "File position before avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
}
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;
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 (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_DEBUG, "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;
+ }
if (st->codec_info_nb_frames>1) {
int64_t t=0;
if (st->time_base.den > 0)
}
st->info->codec_info_duration += pkt->duration;
}
+#if FF_API_R_FRAME_RATE
{
int64_t last = st->info->last_dts;
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) {
st->codec->codec_tag= tag;
}
- 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->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration) {
+ 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);
+
+ /* 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);
+ }
+ }
// 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 > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !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= 0.01;
}
}
+ if(ic->probesize)
estimate_timings(ic, old_offset);
compute_chapters_end(ic);
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)