diff --git a/libavformat/internal.h b/libavformat/internal.h index 6b7f677950..8c2740be2e 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -625,9 +625,11 @@ int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf * The packet is not removed from the interleaving queue, but only * a pointer to it is returned. * + * @param ts_offset the ts difference between packet in the que and the muxer. + * * @return a pointer to the next packet, or NULL if no packet is queued * for this stream. */ -const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream); +const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream, int64_t *ts_offset); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/movenc.c b/libavformat/movenc.c index bf57174850..693851e153 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -4314,13 +4314,15 @@ static int mov_flush_fragment(AVFormatContext *s, int force) for (i = 0; i < s->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; if (!track->end_reliable) { - const AVPacket *next = ff_interleaved_peek(s, i); + int64_t ts_offset; + const AVPacket *next = ff_interleaved_peek(s, i, &ts_offset); if (next) { - track->track_duration = next->dts - track->start_dts; + track->track_duration = next->dts - track->start_dts + ts_offset; if (next->pts != AV_NOPTS_VALUE) track->end_pts = next->pts; else track->end_pts = next->dts; + track->end_pts += ts_offset; } } } diff --git a/libavformat/mux.c b/libavformat/mux.c index 10b2750e3f..105d76240e 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1041,12 +1041,20 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } -const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream) +const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream, int64_t *ts_offset) { AVPacketList *pktl = s->internal->packet_buffer; while (pktl) { - if (pktl->pkt.stream_index == stream) - return &pktl->pkt; + if (pktl->pkt.stream_index == stream) { + AVPacket *pkt = &pktl->pkt; + AVStream *st = s->streams[pkt->stream_index]; + *ts_offset = st->mux_ts_offset; + + if (s->output_ts_offset) + *ts_offset += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); + + return pkt; + } pktl = pktl->next; } return NULL;