summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/APIchanges4
-rw-r--r--libavformat/avformat.h19
-rw-r--r--libavformat/mux.c35
-rw-r--r--libavformat/options_table.h1
-rw-r--r--libavformat/version.h4
5 files changed, 59 insertions, 4 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index e4bd6d8077..6b9efd01c0 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil: 2013-12-xx
API changes, most recent first:
+2014-02-xx - xxxxxxx - lavf 55.11.0 - avformat.h
+ Add AVFormatContext.max_interleave_delta for controlling amount of buffering
+ when interleaving.
+
2014-01-xx - xxxxxxx - lavc 55.32.1 - avcodec.h
Edges are not required anymore on video buffers allocated by get_buffer2()
(i.e. as if the CODEC_FLAG_EMU_EDGE flag was always on). Deprecate
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 00380d7b6c..ab09efd4bb 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1002,6 +1002,25 @@ typedef struct AVFormatContext {
*/
int debug;
#define FF_FDEBUG_TS 0x0001
+
+ /**
+ * Maximum buffering duration for interleaving.
+ *
+ * To ensure all the streams are interleaved correctly,
+ * av_interleaved_write_frame() will wait until it has at least one packet
+ * for each stream before actually writing any packets to the output file.
+ * When some streams are "sparse" (i.e. there are large gaps between
+ * successive packets), this can result in excessive buffering.
+ *
+ * This field specifies the maximum difference between the timestamps of the
+ * first and the last packet in the muxing queue, above which libavformat
+ * will output a packet regardless of whether it has queued a packet for all
+ * the streams.
+ *
+ * Muxing only, set by the caller before avformat_write_header().
+ */
+ int64_t max_interleave_delta;
+
/*****************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 06dacead8f..c16d1c83a5 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -541,8 +541,39 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
ff_interleave_add_packet(s, pkt, interleave_compare_dts);
}
- for (i = 0; i < s->nb_streams; i++)
- stream_count += !!s->streams[i]->last_in_packet_buffer;
+ if (s->max_interleave_delta > 0 && s->packet_buffer && !flush) {
+ AVPacket *top_pkt = &s->packet_buffer->pkt;
+ int64_t delta_dts = INT64_MIN;
+ int64_t top_dts = av_rescale_q(top_pkt->dts,
+ s->streams[top_pkt->stream_index]->time_base,
+ AV_TIME_BASE_Q);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ int64_t last_dts;
+ const AVPacketList *last = s->streams[i]->last_in_packet_buffer;
+
+ if (!last)
+ continue;
+
+ last_dts = av_rescale_q(last->pkt.dts,
+ s->streams[i]->time_base,
+ AV_TIME_BASE_Q);
+ delta_dts = FFMAX(delta_dts, last_dts - top_dts);
+ stream_count++;
+ }
+
+ if (delta_dts > s->max_interleave_delta) {
+ av_log(s, AV_LOG_DEBUG,
+ "Delay between the first packet and last packet in the "
+ "muxing queue is %"PRId64" > %"PRId64": forcing output\n",
+ delta_dts, s->max_interleave_delta);
+ flush = 1;
+ }
+ } else {
+ for (i = 0; i < s->nb_streams; i++)
+ stream_count += !!s->streams[i]->last_in_packet_buffer;
+ }
+
if (stream_count && (s->internal->nb_interleaved_streams == stream_count || flush)) {
pktl = s->packet_buffer;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 54bf25fc27..cc84e1c02f 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -58,6 +58,7 @@ static const AVOption avformat_options[] = {
{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, "err_detect"},
{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, D, "err_detect"},
{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
+{"max_interleave_delta", "maximum buffering duration for interleaving", OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT64_MAX, E },
{NULL},
};
diff --git a/libavformat/version.h b/libavformat/version.h
index dbdccb4cdc..3b96d0a976 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@
#include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 10
-#define LIBAVFORMAT_VERSION_MICRO 3
+#define LIBAVFORMAT_VERSION_MINOR 11
+#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \