From: Steinar H. Gunderson Date: Wed, 4 May 2016 18:18:27 +0000 (+0200) Subject: Fix packet sorting in Mux. X-Git-Tag: 1.3.0~22 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=dd64578c19aace6c4a946af40a5716c716f20ce9;p=nageru Fix packet sorting in Mux. Packets cannot be compared based on dts/pts alone; they also need to take the timebase into account. (Right now, this is harmless, but we need more precise packet sorting in the next commit.) --- diff --git a/mux.cpp b/mux.cpp index b9860b9..326c73f 100644 --- a/mux.cpp +++ b/mux.cpp @@ -11,6 +11,24 @@ using namespace std; +struct PacketBefore { + PacketBefore(const AVFormatContext *ctx) : ctx(ctx) {} + + bool operator() (const AVPacket *a, const AVPacket *b) const { + int64_t a_dts = (a->dts == AV_NOPTS_VALUE ? a->pts : a->dts); + int64_t b_dts = (b->dts == AV_NOPTS_VALUE ? b->pts : b->dts); + AVRational a_timebase = ctx->streams[a->stream_index]->time_base; + AVRational b_timebase = ctx->streams[b->stream_index]->time_base; + if (av_compare_ts(a_dts, a_timebase, b_dts, b_timebase) != 0) { + return av_compare_ts(a_dts, a_timebase, b_dts, b_timebase) < 0; + } else { + return av_compare_ts(a->pts, a_timebase, b->pts, b_timebase) < 0; + } + } + + const AVFormatContext * const ctx; +}; + Mux::Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const string &video_extradata, const AVCodecContext *audio_ctx, int time_base, KeyFrameSignalReceiver *keyframe_signal_receiver) : avctx(avctx), keyframe_signal_receiver(keyframe_signal_receiver) { @@ -134,15 +152,7 @@ void Mux::unplug() } assert(plug_count >= 0); - sort(plugged_packets.begin(), plugged_packets.end(), [](const AVPacket *a, const AVPacket *b) { - int64_t a_dts = (a->dts == AV_NOPTS_VALUE ? a->pts : a->dts); - int64_t b_dts = (b->dts == AV_NOPTS_VALUE ? b->pts : b->dts); - if (a_dts != b_dts) { - return a_dts < b_dts; - } else { - return a->pts < b->pts; - } - }); + sort(plugged_packets.begin(), plugged_packets.end(), PacketBefore(avctx)); for (AVPacket *pkt : plugged_packets) { if (av_interleaved_write_frame(avctx, pkt) < 0) {