if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
- return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
+ return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, s->probesize);
else if (s->iformat->flags & AVFMT_NOFILE)
return AVERROR(EINVAL);
return 0;
return ret;
if (s->iformat)
return 0;
- return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
+ return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, s->probesize);
}
static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
return &pktl->pkt;
}
+static void queue_attached_pictures(AVFormatContext *s)
+{
+ int i;
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
+ s->streams[i]->discard < AVDISCARD_ALL) {
+ AVPacket copy = s->streams[i]->attached_pic;
+ copy.destruct = NULL;
+ add_to_pktbuf(&s->raw_packet_buffer, ©, &s->raw_packet_buffer_end);
+ }
+}
+
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
{
AVFormatContext *s = *ps;
- int i, ret = 0;
+ int ret = 0;
AVDictionary *tmp = NULL;
ID3v2ExtraMeta *id3v2_extra_meta = NULL;
goto fail;
ff_id3v2_free_extra_meta(&id3v2_extra_meta);
- /* queue attached pictures */
- for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
- AVPacket copy = s->streams[i]->attached_pic;
- copy.destruct = NULL;
- add_to_pktbuf(&s->raw_packet_buffer, ©, &s->raw_packet_buffer_end);
- }
+ queue_attached_pictures(s);
if (s->pb && !s->data_offset)
s->data_offset = avio_tell(s->pb);
/*******************************************************/
-int av_read_packet(AVFormatContext *s, AVPacket *pkt)
+int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int ret, i;
AVStream *st;
}
}
+#if FF_API_READ_PACKET
+int av_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ return ff_read_packet(s, pkt);
+}
+#endif
+
+
/**********************************************************/
/**
st->start_time = pts;
}
-static void update_initial_durations(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+static void update_initial_durations(AVFormatContext *s, AVStream *st,
+ int stream_index, int duration)
{
AVPacketList *pktl= s->packet_buffer;
int64_t cur_dts= 0;
if(st->first_dts != AV_NOPTS_VALUE){
cur_dts= st->first_dts;
for(; pktl; pktl= pktl->next){
- if(pktl->pkt.stream_index == pkt->stream_index){
+ if(pktl->pkt.stream_index == stream_index){
if(pktl->pkt.pts != pktl->pkt.dts || pktl->pkt.dts != AV_NOPTS_VALUE || pktl->pkt.duration)
break;
- cur_dts -= pkt->duration;
+ cur_dts -= duration;
}
}
pktl= s->packet_buffer;
return;
for(; pktl; pktl= pktl->next){
- if(pktl->pkt.stream_index != pkt->stream_index)
+ if(pktl->pkt.stream_index != stream_index)
continue;
if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE
&& !pktl->pkt.duration){
pktl->pkt.dts= cur_dts;
if(!st->codec->has_b_frames)
pktl->pkt.pts= cur_dts;
- cur_dts += pkt->duration;
- pktl->pkt.duration= pkt->duration;
+ cur_dts += duration;
+ if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+ pktl->pkt.duration = duration;
}else
break;
}
pkt->dts= pkt->pts= AV_NOPTS_VALUE;
}
- if (pkt->duration == 0) {
+ if (pkt->duration == 0 && st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
compute_frame_duration(&num, &den, st, pc, pkt);
if (den && num) {
pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN);
if(pkt->duration != 0 && s->packet_buffer)
- update_initial_durations(s, st, pkt);
+ update_initial_durations(s, st, pkt->stream_index, pkt->duration);
}
}
st->last_IP_pts= pkt->pts;
/* cannot compute PTS if not present (we can compute it only
by knowing the future */
- } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
- if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
- int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts);
+ } else if (pkt->pts != AV_NOPTS_VALUE ||
+ pkt->dts != AV_NOPTS_VALUE ||
+ pkt->duration ||
+ st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ int duration = pkt->duration;
+ if (!duration && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ compute_frame_duration(&num, &den, st, pc, pkt);
+ if (den && num) {
+ duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den,
+ den * (int64_t)st->time_base.num,
+ AV_ROUND_DOWN);
+ if (duration != 0 && s->packet_buffer) {
+ update_initial_durations(s, st, pkt->stream_index,
+ duration);
+ }
+ }
+ }
+
+ if(pkt->pts != AV_NOPTS_VALUE && duration){
+ int64_t old_diff= FFABS(st->cur_dts - duration - pkt->pts);
int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
- if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
- pkt->pts += pkt->duration;
+ if(old_diff < new_diff && old_diff < (duration>>3)){
+ pkt->pts += duration;
// av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
}
}
pkt->pts = st->cur_dts;
pkt->dts = pkt->pts;
if(pkt->pts != AV_NOPTS_VALUE)
- st->cur_dts = pkt->pts + pkt->duration;
+ st->cur_dts = pkt->pts + duration;
}
}
AVPacket cur_pkt;
/* read next packet */
- ret = av_read_packet(s, &cur_pkt);
+ ret = ff_read_packet(s, &cur_pkt);
if (ret < 0) {
if (ret == AVERROR(EAGAIN))
return ret;
cur_pkt.size);
}
if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
+ av_log(s, AV_LOG_DEBUG, "ff_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
cur_pkt.stream_index,
cur_pkt.pts,
cur_pkt.dts,
return -1;
for(i = 0; i < s->nb_streams; i++) {
st = s->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ !(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
return i;
}
if (first_audio_index < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
int64_t pos_min, pos_max;
-#if 0
- AVStream *st;
-
- if (stream_index < 0)
- return -1;
-
- st= s->streams[stream_index];
-#endif
pos_min = s->data_offset;
pos_max = avio_size(s->pb) - 1;
avio_seek(s->pb, pos, SEEK_SET);
-#if 0
- av_update_cur_dts(s, st, ts);
-#endif
return 0;
}
return 0;
}
-int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int seek_frame_internal(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
{
int ret;
AVStream *st;
return -1;
}
+int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+{
+ int ret = seek_frame_internal(s, stream_index, timestamp, flags);
+
+ if (ret >= 0)
+ queue_attached_pictures(s);
+
+ return ret;
+}
+
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
if(min_ts > ts || max_ts < ts)
return -1;
if (s->iformat->read_seek2) {
+ int ret;
ff_read_frame_flush(s);
- return s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
+ ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
+
+ if (ret >= 0)
+ queue_attached_pictures(s);
+ return ret;
}
if(s->iformat->read_timestamp){
break;
do {
- ret = av_read_packet(ic, pkt);
+ ret = ff_read_packet(ic, pkt);
} while(ret == AVERROR(EAGAIN));
if (ret != 0)
break;
}
}
-static int has_codec_parameters(AVCodecContext *avctx)
+static int has_codec_parameters(AVStream *st)
{
+ AVCodecContext *avctx = st->codec;
int val;
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
- val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE;
+ val = avctx->sample_rate && avctx->channels;
+ if (st->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
+ return 0;
break;
case AVMEDIA_TYPE_VIDEO:
- val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE;
+ val = avctx->width;
+ if (st->info->found_decoder >= 0 && avctx->pix_fmt == PIX_FMT_NONE)
+ return 0;
break;
default:
val = 1;
AVFrame picture;
AVPacket pkt = *avpkt;
- if (!avcodec_is_open(st->codec)) {
+ if (!avcodec_is_open(st->codec) && !st->info->found_decoder) {
AVDictionary *thread_opt = NULL;
codec = st->codec->codec ? st->codec->codec :
avcodec_find_decoder(st->codec->codec_id);
- if (!codec)
+ if (!codec) {
+ st->info->found_decoder = -1;
return -1;
+ }
/* force thread count to 1 since the h264 decoder will not extract SPS
* and PPS to extradata during multi-threaded decoding */
ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt);
if (!options)
av_dict_free(&thread_opt);
- if (ret < 0)
+ if (ret < 0) {
+ st->info->found_decoder = -1;
return ret;
- }
+ }
+ st->info->found_decoder = 1;
+ } else if (!st->info->found_decoder)
+ st->info->found_decoder = 1;
+
+ if (st->info->found_decoder < 0)
+ return -1;
while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
ret >= 0 &&
- (!has_codec_parameters(st->codec) ||
+ (!has_codec_parameters(st) ||
!has_decode_delay_been_guessed(st) ||
(!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
got_picture = 0;
: &thread_opt);
//try to just open decoders, in case this is enough to get parameters
- if(!has_codec_parameters(st->codec)){
+ if (!has_codec_parameters(st)) {
if (codec && !st->codec->codec)
avcodec_open2(st->codec, codec, options ? &options[i]
: &thread_opt);
int fps_analyze_framecount = 20;
st = ic->streams[i];
- if (!has_codec_parameters(st->codec))
+ if (!has_codec_parameters(st))
break;
/* if the timebase is coarse (like the usual millisecond precision
of mkv), we need to analyze more frames to reliably arrive at
if (ret < 0) {
/* EOF or error*/
AVPacket empty_pkt = { 0 };
- int err;
+ int err = 0;
av_init_packet(&empty_pkt);
ret = -1; /* we could not have all the codec parameters before EOF */
st = ic->streams[i];
/* flush the decoders */
- do {
- err = try_decode_frame(st, &empty_pkt,
- (options && i < orig_nb_streams) ?
- &options[i] : NULL);
- } while (err > 0 && !has_codec_parameters(st->codec));
+ if (st->info->found_decoder == 1) {
+ do {
+ err = try_decode_frame(st, &empty_pkt,
+ (options && i < orig_nb_streams) ?
+ &options[i] : NULL);
+ } while (err > 0 && !has_codec_parameters(st));
+ }
if (err < 0) {
av_log(ic, AV_LOG_WARNING,
"decoding for stream %d failed\n", st->index);
- } else if (!has_codec_parameters(st->codec)){
+ } else if (!has_codec_parameters(st)) {
char buf[256];
avcodec_string(buf, sizeof(buf), st->codec, 0);
av_log(ic, AV_LOG_WARNING,
st = ic->streams[pkt->stream_index];
if (st->codec_info_nb_frames>1) {
- if (st->time_base.den > 0 && av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
+ if (av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
break;
}
}
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
- if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration)
- 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);
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)
+ 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);
// 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.
compute_chapters_end(ic);
-#if 0
- /* correct DTS for B-frame streams with no timestamps */
- for(i=0;i<ic->nb_streams;i++) {
- st = ic->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if(b-frames){
- ppktl = &ic->packet_buffer;
- while(ppkt1){
- if(ppkt1->stream_index != i)
- continue;
- if(ppkt1->pkt->dts < 0)
- break;
- if(ppkt1->pkt->pts != AV_NOPTS_VALUE)
- break;
- ppkt1->pkt->dts -= delta;
- ppkt1= ppkt1->next;
- }
- if(ppkt1)
- continue;
- st->cur_dts -= delta;
- }
- }
- }
-#endif
-
find_stream_info_err:
for (i=0; i < ic->nb_streams; i++) {
if (ic->streams[i]->codec)
return comp > 0;
}
-int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
+int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
+ AVPacket *pkt, int flush)
+{
AVPacketList *pktl;
int stream_count=0;
int i;
}
}
+#if FF_API_INTERLEAVE_PACKET
+int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
+ AVPacket *pkt, int flush)
+{
+ return ff_interleave_packet_per_dts(s, out, pkt, flush);
+}
+#endif
+
/**
* Interleave an AVPacket correctly so it can be muxed.
* @param out the interleaved packet will be output here
av_free_packet(in);
return ret;
} else
- return av_interleave_packet_per_dts(s, out, in, flush);
+ return ff_interleave_packet_per_dts(s, out, in, flush);
}
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){