X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mux.h;h=c6c442100c58b18c481754747693b54c8571bcbc;hb=96cb6414f85e0ef4d660b7bd56267303e80fcd05;hp=d645916d758c1fa9435cbb39e8fc135b9aaad721;hpb=16c71cac0d5c81e84271222d1ed0c501fe723d56;p=nageru diff --git a/mux.h b/mux.h index d645916..c6c4421 100644 --- a/mux.h +++ b/mux.h @@ -6,15 +6,31 @@ extern "C" { #include #include -#include } +#include +#include +#include #include +#include +#include +#include -class KeyFrameSignalReceiver { -public: - // Needs to automatically turn the flag off again after actually receiving data. - virtual void signal_keyframe() = 0; +struct MuxMetrics { + // “written” will usually be equal video + audio + mux overhead, + // except that there could be buffered packets that count in audio or video + // but not yet in written. + std::atomic metric_video_bytes{0}, metric_audio_bytes{0}, metric_written_bytes{0}; + + // Registers in global_metrics. + void init(const std::vector> &labels); + + void reset() + { + metric_video_bytes = 0; + metric_audio_bytes = 0; + metric_written_bytes = 0; + } }; class Mux { @@ -24,16 +40,38 @@ public: CODEC_NV12, // Uncompressed 4:2:0. }; - // Takes ownership of avctx. can be nullptr. - Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const AVCodec *codec_audio, int time_base, int bit_rate, KeyFrameSignalReceiver *keyframe_signal_receiver); + // Takes ownership of avctx. will be called every time + // a write has been made to the video stream (id 0), with the pts of + // the just-written frame. (write_callback can be nullptr.) + // Does not take ownership of ; elements in there, if any, + // will be added to. + Mux(AVFormatContext *avctx, int width, int height, Codec video_codec, const std::string &video_extradata, const AVCodecParameters *audio_codecpar, int time_base, std::function write_callback, const std::vector &metrics); ~Mux(); void add_packet(const AVPacket &pkt, int64_t pts, int64_t dts); + // As long as the mux is plugged, it will not actually write anything to disk, + // just queue the packets. Once it is unplugged, the packets are reordered by pts + // and written. This is primarily useful if you might have two different encoders + // writing to the mux at the same time (because one is shutting down), so that + // pts might otherwise come out-of-order. + // + // You can plug and unplug multiple times; only when the plug count reaches zero, + // something will actually happen. + void plug(); + void unplug(); + private: - std::mutex ctx_mu; - AVFormatContext *avctx; // Protected by . + void write_packet_or_die(const AVPacket &pkt); // Must be called with held. + + std::mutex mu; + AVFormatContext *avctx; // Protected by . + int plug_count = 0; // Protected by . + std::vector plugged_packets; // Protected by . + AVStream *avstream_video, *avstream_audio; - KeyFrameSignalReceiver *keyframe_signal_receiver; + + std::function write_callback; + std::vector metrics; }; #endif // !defined(_MUX_H)