summaryrefslogtreecommitdiff
path: root/libavformat/movenchint.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-07-07 16:55:26 +0300
committerMartin Storsjö <martin@martin.st>2013-07-08 12:43:42 +0300
commita87a0acf9b5d27aad032e61eef4973e62a4a6830 (patch)
treeba9f6b0f8f8f16ae89e5e5f5b5672ba0e6629ba3 /libavformat/movenchint.c
parent744a11c996641888d477a3981d609e79eeb69ea9 (diff)
movenc: Make sure the RTP hint tracks have nondecreasing DTS
The RTP timestamps can be decreasing for codecs with B-frames. For these cases, make sure the timestamps in the MP4 file track itself are nondecreasing, and add an offset to the RTP packet hint instead to produce the intended RTP timestamp. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/movenchint.c')
-rw-r--r--libavformat/movenchint.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index b4e4654552..84ba6770a2 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -328,6 +328,7 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
uint32_t packet_len = AV_RB32(data);
uint16_t seq;
uint32_t ts;
+ int32_t ts_diff;
data += 4;
size -= 4;
@@ -350,8 +351,12 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
trk->prev_rtp_ts = ts;
/* Unwrap the 32-bit RTP timestamp that wraps around often
* into a not (as often) wrapping 64-bit timestamp. */
- trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
- trk->prev_rtp_ts = ts;
+ ts_diff = ts - trk->prev_rtp_ts;
+ if (ts_diff > 0) {
+ trk->cur_rtp_ts_unwrapped += ts_diff;
+ trk->prev_rtp_ts = ts;
+ ts_diff = 0;
+ }
if (*pts == AV_NOPTS_VALUE)
*pts = trk->cur_rtp_ts_unwrapped;
@@ -360,9 +365,15 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
avio_wb32(out, 0); /* relative_time */
avio_write(out, data, 2); /* RTP header */
avio_wb16(out, seq); /* RTPsequenceseed */
- avio_wb16(out, 0); /* reserved + flags */
+ avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
entries_pos = avio_tell(out);
avio_wb16(out, 0); /* entry count */
+ if (ts_diff) { /* if extra_flag is set */
+ avio_wb32(out, 16); /* extra_information_length */
+ avio_wb32(out, 12); /* rtpoffsetTLV box */
+ avio_write(out, "rtpo", 4);
+ avio_wb32(out, ts_diff);
+ }
data += 12;
size -= 12;