aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2015-03-06 22:30:31 +0200
committerMartin Storsjö <martin@martin.st>2015-03-19 10:27:03 +0200
commit3041183677bda0a431b36e96a2c76617abaa8183 (patch)
treec3903db3f0c2e7e94d156166cd221b6932245e9d
parent2889c5e16711770437f380f1bead5f72c6a0b17a (diff)
downloadffmpeg-3041183677bda0a431b36e96a2c76617abaa8183.tar.gz
dashenc: Heuristically fill in the duration of packets that need it
This avoids that the mp4 muxer does a similar heuristic, adjusting the timestamps in a way that the dash muxer doesn't know the actual timestamps written to the file in the end. By making sure that the mp4 muxer internal heuristic isn't applied, we know the exact timestamps written to file, so that the timestamps in manifest match the files. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/dashenc.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 1d32cdf7ef..94bf1c2bec 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -69,6 +69,7 @@ typedef struct OutputStream {
int nb_segments, segments_size, segment_index;
Segment **segments;
int64_t first_pts, start_pts, max_pts;
+ int64_t last_dts;
int bit_rate;
char bandwidth_str[64];
@@ -648,6 +649,7 @@ static int dash_write_header(AVFormatContext *s)
set_codec_str(s, st->codec, os->codec_str, sizeof(os->codec_str));
os->first_pts = AV_NOPTS_VALUE;
os->max_pts = AV_NOPTS_VALUE;
+ os->last_dts = AV_NOPTS_VALUE;
os->segment_index = 1;
}
@@ -860,6 +862,16 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
if (ret < 0)
return ret;
+ // Fill in a heuristic guess of the packet duration, if none is available.
+ // The mp4 muxer will do something similar (for the last packet in a fragment)
+ // if nothing is set (setting it for the other packets doesn't hurt).
+ // By setting a nonzero duration here, we can be sure that the mp4 muxer won't
+ // invoke its heuristic (this doesn't have to be identical to that algorithm),
+ // so that we know the exact timestamps of fragments.
+ if (!pkt->duration && os->last_dts != AV_NOPTS_VALUE)
+ pkt->duration = pkt->dts - os->last_dts;
+ os->last_dts = pkt->dts;
+
// If forcing the stream to start at 0, the mp4 muxer will set the start
// timestamps to 0. Do the same here, to avoid mismatches in duration/timestamps.
if (os->first_pts == AV_NOPTS_VALUE &&