forked from FFmpeg/FFmpeg
Merge commit 'd9ae1031f5edbd25c8526b4cb51aba66d3bee931'
* commit 'd9ae1031f5edbd25c8526b4cb51aba66d3bee931':
lavf: improve handling of sparse streams when muxing
Conflicts:
doc/APIchanges
libavformat/avformat.h
libavformat/mux.c
libavformat/options_table.h
libavformat/version.h
See: 37ed5df5c5
Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
3adb5f8d8b
5 changed files with 52 additions and 19 deletions
|
@ -15,6 +15,10 @@ libavutil: 2012-10-22
|
||||||
|
|
||||||
API changes, most recent first:
|
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-02-02 - xxxxxxx - lavf 55.29.100 - avformat.h
|
2014-02-02 - xxxxxxx - lavf 55.29.100 - avformat.h
|
||||||
Add output_ts_offset muxing option to AVFormatContext.
|
Add output_ts_offset muxing option to AVFormatContext.
|
||||||
|
|
||||||
|
|
|
@ -1182,6 +1182,24 @@ typedef struct AVFormatContext {
|
||||||
int debug;
|
int debug;
|
||||||
#define FF_FDEBUG_TS 0x0001
|
#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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transport stream id.
|
* Transport stream id.
|
||||||
* This will be moved into demuxer private options. Thus no API/ABI compatibility
|
* This will be moved into demuxer private options. Thus no API/ABI compatibility
|
||||||
|
|
|
@ -713,7 +713,6 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
|
||||||
{
|
{
|
||||||
AVPacketList *pktl;
|
AVPacketList *pktl;
|
||||||
int stream_count = 0, noninterleaved_count = 0;
|
int stream_count = 0, noninterleaved_count = 0;
|
||||||
int64_t delta_dts_max = 0;
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
if (pkt) {
|
if (pkt) {
|
||||||
|
@ -730,27 +729,38 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->internal->nb_interleaved_streams == stream_count) {
|
if (s->internal->nb_interleaved_streams == stream_count)
|
||||||
flush = 1;
|
flush = 1;
|
||||||
} else if (!flush) {
|
|
||||||
for (i=0; i < s->nb_streams; i++) {
|
if (s->max_interleave_delta > 0 && s->packet_buffer && !flush) {
|
||||||
if (s->streams[i]->last_in_packet_buffer) {
|
AVPacket *top_pkt = &s->packet_buffer->pkt;
|
||||||
int64_t delta_dts =
|
int64_t delta_dts = INT64_MIN;
|
||||||
av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts,
|
int64_t top_dts = av_rescale_q(top_pkt->dts,
|
||||||
s->streams[i]->time_base,
|
s->streams[top_pkt->stream_index]->time_base,
|
||||||
AV_TIME_BASE_Q) -
|
AV_TIME_BASE_Q);
|
||||||
av_rescale_q(s->packet_buffer->pkt.dts,
|
|
||||||
s->streams[s->packet_buffer->pkt.stream_index]->time_base,
|
for (i = 0; i < s->nb_streams; i++) {
|
||||||
AV_TIME_BASE_Q);
|
int64_t last_dts;
|
||||||
delta_dts_max= FFMAX(delta_dts_max, delta_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);
|
||||||
}
|
}
|
||||||
if (s->internal->nb_interleaved_streams == stream_count+noninterleaved_count &&
|
|
||||||
delta_dts_max > 20*AV_TIME_BASE) {
|
if (delta_dts > s->max_interleave_delta) {
|
||||||
av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count);
|
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;
|
flush = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream_count && flush) {
|
if (stream_count && flush) {
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
pktl = s->packet_buffer;
|
pktl = s->packet_buffer;
|
||||||
|
|
|
@ -79,6 +79,7 @@ static const AVOption avformat_options[] = {
|
||||||
{"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E},
|
{"flush_packets", "enable flushing of the I/O context after each packet", OFFSET(flush_packets), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E},
|
||||||
{"metadata_header_padding", "set number of bytes to be written as padding in a metadata header", OFFSET(metadata_header_padding), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, E},
|
{"metadata_header_padding", "set number of bytes to be written as padding in a metadata header", OFFSET(metadata_header_padding), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, E},
|
||||||
{"output_ts_offset", "set output timestamp offset", OFFSET(output_ts_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E},
|
{"output_ts_offset", "set output timestamp offset", OFFSET(output_ts_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E},
|
||||||
|
{"max_interleave_delta", "maximum buffering duration for interleaving", OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT64_MAX, E },
|
||||||
{NULL},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_MAJOR 55
|
#define LIBAVFORMAT_VERSION_MAJOR 55
|
||||||
#define LIBAVFORMAT_VERSION_MINOR 29
|
#define LIBAVFORMAT_VERSION_MINOR 30
|
||||||
#define LIBAVFORMAT_VERSION_MICRO 101
|
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||||
LIBAVFORMAT_VERSION_MINOR, \
|
LIBAVFORMAT_VERSION_MINOR, \
|
||||||
|
|
Loading…
Add table
Reference in a new issue