X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=nageru%2Fmjpeg_encoder.h;h=6ba7f0381bad3a1f3f1ec879e07cf44dcaf7260b;hp=8a0d8fadb6b198fc8e6e2104eb8da41da2e17ce1;hb=bcd177e1daf5a63d7bf877bc5d30d8803dfd472c;hpb=0a338eed8f26adaf202e0cadc88b533ce9fa173d diff --git a/nageru/mjpeg_encoder.h b/nageru/mjpeg_encoder.h index 8a0d8fa..6ba7f03 100644 --- a/nageru/mjpeg_encoder.h +++ b/nageru/mjpeg_encoder.h @@ -1,7 +1,9 @@ #ifndef _MJPEG_ENCODER_H #define _MJPEG_ENCODER_H 1 +#include "defs.h" #include "shared/ffmpeg_raii.h" +#include "shared/httpd.h" #include "ref_counted_frame.h" extern "C" { @@ -23,7 +25,6 @@ extern "C" { #include #include -class HTTPD; struct jpeg_compress_struct; struct VADisplayWithCleanup; struct VectorDestinationManager; @@ -42,8 +43,7 @@ public: void upload_frame(int64_t pts, unsigned card_index, RefCountedFrame frame, const bmusb::VideoFormat &video_format, size_t y_offset, size_t cbcr_offset, std::vector audio, const movit::RGBTriplet &white_balance); bool using_vaapi() const { return va_dpy != nullptr; } - // Returns -1 for inactive (ie., don't encode frames for this card right now). - int get_mjpeg_stream_for_card(unsigned card_index); + bool should_encode_mjpeg_for_card(unsigned card_index); private: static constexpr int quality = 90; @@ -117,13 +117,21 @@ private: void va_receiver_thread_func(); void encode_jpeg_va(QueuedFrame &&qf); std::vector encode_jpeg_libjpeg(const QueuedFrame &qf); - void write_mjpeg_packet(int64_t pts, unsigned card_index, const uint8_t *jpeg, size_t jpeg_size); - void write_audio_packet(int64_t pts, unsigned card_index, const std::vector &audio); + void write_mjpeg_packet(AVFormatContext *avctx, int64_t pts, unsigned stream_index, const uint8_t *jpeg, size_t jpeg_size); + void write_audio_packet(AVFormatContext *avctx, int64_t pts, unsigned stream_index, const std::vector &audio); void init_jpeg_422(unsigned width, unsigned height, const movit::RGBTriplet &white_balance, VectorDestinationManager *dest, jpeg_compress_struct *cinfo); std::vector get_jpeg_header(unsigned width, unsigned height, const movit::RGBTriplet &white_balance, jpeg_compress_struct *cinfo); + void add_stream(HTTPD::StreamID stream_id); // Can only be called from the constructor, or the thread owning . + void update_siphon_streams(); // Same. + void create_ffmpeg_context(HTTPD::StreamID stream_id); + struct WritePacket2Context { + MJPEGEncoder *mjpeg_encoder; + HTTPD::StreamID stream_id; + }; + std::map ffmpeg_contexts; // Statically set up, so we never need to worry about dangling pointers. static int write_packet2_thunk(void *opaque, uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time); - int write_packet2(uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time); + int write_packet2(HTTPD::StreamID stream_id, uint8_t *buf, int buf_size, AVIODataMarkerType type, int64_t time); std::thread encoder_thread, va_receiver_thread; @@ -134,9 +142,12 @@ private: std::queue frames_encoding; // Under mu. Used for VA-API only. std::condition_variable any_frames_encoding; - AVFormatContextWithCloser avctx; + struct Stream { + AVFormatContextWithCloser avctx; + std::string mux_header; + }; + std::map streams; // Owned by the VA-API receiver thread if VA-API is active, or the encoder thread if not. HTTPD *httpd; - std::string mux_header; std::atomic should_quit{false}; bool running = false;