X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mux.cpp;h=b9860b943c402f08f8263de63ccd40aca3719c3b;hb=ab03e5e6f24b1651b4ca7df95e20aa5786939209;hp=e16943828fcccaa8f9d5e65ad9008cc9bb1456dd;hpb=64f9314bfe9b21fed7304a4d08a35d80e8c73144;p=nageru diff --git a/mux.cpp b/mux.cpp index e169438..b9860b9 100644 --- a/mux.cpp +++ b/mux.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -107,8 +108,10 @@ void Mux::add_packet(const AVPacket &pkt, int64_t pts, int64_t dts) } { - lock_guard lock(ctx_mu); - if (av_interleaved_write_frame(avctx, &pkt_copy) < 0) { + lock_guard lock(mu); + if (plug_count > 0) { + plugged_packets.push_back(av_packet_clone(&pkt_copy)); + } else if (av_interleaved_write_frame(avctx, &pkt_copy) < 0) { fprintf(stderr, "av_interleaved_write_frame() failed\n"); exit(1); } @@ -116,3 +119,37 @@ void Mux::add_packet(const AVPacket &pkt, int64_t pts, int64_t dts) av_packet_unref(&pkt_copy); } + +void Mux::plug() +{ + lock_guard lock(mu); + ++plug_count; +} + +void Mux::unplug() +{ + lock_guard lock(mu); + if (--plug_count > 0) { + return; + } + 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; + } + }); + + for (AVPacket *pkt : plugged_packets) { + if (av_interleaved_write_frame(avctx, pkt) < 0) { + fprintf(stderr, "av_interleaved_write_frame() failed\n"); + exit(1); + } + av_packet_free(&pkt); + } + plugged_packets.clear(); +}