#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" {
#include <movit/effect.h>
#include <va/va.h>
-class HTTPD;
struct jpeg_compress_struct;
struct VADisplayWithCleanup;
struct VectorDestinationManager;
void va_receiver_thread_func();
void encode_jpeg_va(QueuedFrame &&qf);
std::vector<uint8_t> 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<int32_t> &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<int32_t> &audio);
void init_jpeg_422(unsigned width, unsigned height, const movit::RGBTriplet &white_balance, VectorDestinationManager *dest, jpeg_compress_struct *cinfo);
std::vector<uint8_t> 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 <streams>.
+ void update_siphon_streams(); // Same.
+ void create_ffmpeg_context(HTTPD::StreamID stream_id);
+ struct WritePacket2Context {
+ MJPEGEncoder *mjpeg_encoder;
+ HTTPD::StreamID stream_id;
+ };
+ std::map<HTTPD::StreamID, WritePacket2Context> 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;
std::queue<QueuedFrame> 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<HTTPD::StreamID, Stream> 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<bool> should_quit{false};
bool running = false;