diff --git a/libavformat/internal.h b/libavformat/internal.h index da64c641a7..9d614fb12c 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -657,14 +657,13 @@ int ff_bprint_to_codecpar_extradata(AVCodecParameters *par, struct AVBPrint *buf /** * Find the next packet in the interleaving queue for the given stream. - * The packet is not removed from the interleaving queue, but only - * a pointer to it is returned. + * The pkt parameter is filled in with the queued packet, including + * references to the data (which the caller is not allowed to keep or + * modify). * - * @param ts_offset the ts difference between packet in the queue and the muxer. - * - * @return a pointer to the next packet, or NULL if no packet is queued - * for this stream. + * @return 0 if a packet was found, a negative value if no packet was found */ -const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream, int64_t *ts_offset); +int ff_interleaved_peek(AVFormatContext *s, int stream, + AVPacket *pkt, int add_offset); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/movenc.c b/libavformat/movenc.c index efa050ee44..7a726c6bfd 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -4484,15 +4484,13 @@ 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) { - int64_t ts_offset; - const AVPacket *next = ff_interleaved_peek(s, i, &ts_offset); - if (next) { - track->track_duration = next->dts - track->start_dts + ts_offset; - if (next->pts != AV_NOPTS_VALUE) - track->end_pts = next->pts; + AVPacket pkt; + if (!ff_interleaved_peek(s, i, &pkt, 1)) { + track->track_duration = pkt.dts - track->start_dts; + if (pkt.pts != AV_NOPTS_VALUE) + track->end_pts = pkt.pts; else - track->end_pts = next->dts; - track->end_pts += ts_offset; + track->end_pts = pkt.dts; } } } diff --git a/libavformat/mux.c b/libavformat/mux.c index 77823a4e75..4d47ddcbde 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -692,6 +692,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) pts_backup = pkt->pts; dts_backup = pkt->dts; + // If the timestamp offsetting below is adjusted, adjust + // ff_interleaved_peek similarly. if (s->output_ts_offset) { AVStream *st = s->streams[pkt->stream_index]; int64_t offset = av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); @@ -1180,23 +1182,30 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } -const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream, int64_t *ts_offset) +int ff_interleaved_peek(AVFormatContext *s, int stream, + AVPacket *pkt, int add_offset) { AVPacketList *pktl = s->internal->packet_buffer; while (pktl) { 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; + *pkt = pktl->pkt; + if (add_offset) { + AVStream *st = s->streams[pkt->stream_index]; + int64_t offset = st->mux_ts_offset; + + if (s->output_ts_offset) + offset += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); + + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts += offset; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts += offset; + } + return 0; } pktl = pktl->next; } - return NULL; + return AVERROR(ENOENT); } /**