diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 13f6524d85..fe3757a309 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -971,6 +971,8 @@ enum AVDurationEstimationMethod { AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate) }; +typedef struct AVFormatInternal AVFormatInternal; + /** * Format I/O context. * New fields can be added to the end with minor version bumps. @@ -1331,6 +1333,12 @@ typedef struct AVFormatContext { */ AVRational offset_timebase; + /** + * An opaque field for libavformat internal usage. + * Must not be accessed in any way by callers. + */ + AVFormatInternal *internal; + /** * IO repositioned flag. * This is set by avformat when the underlaying IO context read pointer diff --git a/libavformat/internal.h b/libavformat/internal.h index 59370565ca..a840f8af05 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -46,6 +46,14 @@ typedef struct CodecMime{ enum AVCodecID id; } CodecMime; +struct AVFormatInternal { + /** + * Number of streams relevant for interleaving. + * Muxing only. + */ + int nb_interleaved_streams; +}; + #ifdef __GNUC__ #define dynarray_add(tab, nb_ptr, elem)\ do {\ diff --git a/libavformat/mux.c b/libavformat/mux.c index aebfe2c8f7..71a099f643 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -320,6 +320,9 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers " "but container format requires global headers\n", i); + + if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT) + s->internal->nb_interleaved_streams++; } if (!s->priv_data && of->priv_data_size > 0) { @@ -727,7 +730,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } - if (s->nb_streams == stream_count) { + if (s->internal->nb_interleaved_streams == stream_count) { flush = 1; } else if (!flush) { for (i=0; i < s->nb_streams; i++) { @@ -742,7 +745,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, delta_dts_max= FFMAX(delta_dts_max, delta_dts); } } - if (s->nb_streams == stream_count+noninterleaved_count && + if (s->internal->nb_interleaved_streams == stream_count+noninterleaved_count && delta_dts_max > 20*AV_TIME_BASE) { av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count); flush = 1; diff --git a/libavformat/options.c b/libavformat/options.c index 5218e5b92a..e0d6df6fbd 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -19,6 +19,7 @@ */ #include "avformat.h" #include "avio_internal.h" +#include "internal.h" #include "libavutil/opt.h" /** @@ -109,6 +110,13 @@ AVFormatContext *avformat_alloc_context(void) ic = av_malloc(sizeof(AVFormatContext)); if (!ic) return ic; avformat_get_context_defaults(ic); + + ic->internal = av_mallocz(sizeof(*ic->internal)); + if (!ic->internal) { + avformat_free_context(ic); + return NULL; + } + return ic; } diff --git a/libavformat/utils.c b/libavformat/utils.c index 56ce38bbcf..2be4279b45 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3480,6 +3480,7 @@ void avformat_free_context(AVFormatContext *s) av_freep(&s->chapters); av_dict_free(&s->metadata); av_freep(&s->streams); + av_freep(&s->internal); av_free(s); }