X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fmjpeg_encoder.h;h=896b63ba4b612a2e0fed0955b09e07b4cef7df6e;hb=a0e57ec99e9dfdd7e79bcf21e8c996dc43b6cb49;hp=eff361ea4e4cb1ebada2236daef46321e690a942;hpb=731424ea25080a11a0b687f5cdb0007ca82c6050;p=nageru diff --git a/nageru/mjpeg_encoder.h b/nageru/mjpeg_encoder.h index eff361e..896b63b 100644 --- a/nageru/mjpeg_encoder.h +++ b/nageru/mjpeg_encoder.h @@ -1,9 +1,9 @@ #ifndef _MJPEG_ENCODER_H #define _MJPEG_ENCODER_H 1 -#include "defs.h" #include "shared/ffmpeg_raii.h" #include "shared/httpd.h" +#include "shared/va_resource_pool.h" #include "ref_counted_frame.h" extern "C" { @@ -15,15 +15,19 @@ extern "C" { #include #include #include -#include +#include +#include #include #include +#include #include #include #include +#include #include #include +#include struct jpeg_compress_struct; struct VADisplayWithCleanup; @@ -44,61 +48,11 @@ public: bool using_vaapi() const { return va_dpy != nullptr; } bool should_encode_mjpeg_for_card(unsigned card_index); + VAResourcePool *get_va_pool() const { return va_pool.get(); } private: static constexpr int quality = 90; - struct VAResources { - unsigned width, height; - VASurfaceID surface; - VAContextID context; - VABufferID data_buffer; - VAImage image; - }; - - // RAII wrapper to release VAResources on return (even on error). - class ReleaseVAResources { - public: - ReleaseVAResources() : committed(true) {} - - ReleaseVAResources(MJPEGEncoder *mjpeg, const VAResources &resources) - : mjpeg(mjpeg), resources(resources) {} - - ReleaseVAResources(ReleaseVAResources &) = delete; - - ReleaseVAResources(ReleaseVAResources &&other) - : mjpeg(other.mjpeg), resources(other.resources), committed(other.committed) { - other.commit(); - } - - ReleaseVAResources &operator= (ReleaseVAResources &) = delete; - - ReleaseVAResources &operator= (ReleaseVAResources &&other) { - if (!committed) { - mjpeg->release_va_resources(resources); - } - mjpeg = other.mjpeg; - resources = std::move(other.resources); - committed = other.committed; - other.commit(); - return *this; - } - - ~ReleaseVAResources() - { - if (!committed) { - mjpeg->release_va_resources(resources); - } - } - - void commit() { committed = true; } - - private: - MJPEGEncoder *mjpeg = nullptr; - VAResources resources; - bool committed = false; - }; - struct QueuedFrame { int64_t pts; unsigned card_index; @@ -109,7 +63,7 @@ private: movit::RGBTriplet white_balance; // Only for frames in the process of being encoded by VA-API. - VAResources resources; + VAResourcePool::VAResources resources; ReleaseVAResources resource_releaser; }; @@ -119,8 +73,8 @@ private: std::vector encode_jpeg_libjpeg(const QueuedFrame &qf); 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 init_jpeg(unsigned width, unsigned height, const movit::RGBTriplet &white_balance, VectorDestinationManager *dest, jpeg_compress_struct *cinfo, int y_h_samp_factor, int y_v_samp_factor); + std::vector get_jpeg_header(unsigned width, unsigned height, const movit::RGBTriplet &white_balance, int y_h_samp_factor, int y_v_samp_factor, 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); @@ -152,8 +106,28 @@ private: bool running = false; std::unique_ptr va_dpy; - VAConfigID config_id; + std::unique_ptr va_pool; + + struct VAKey { + unsigned width, height, y_h_samp_factor, y_v_samp_factor; + movit::RGBTriplet white_balance; + bool operator< (const VAKey &other) const { + if (width != other.width) + return width < other.width; + if (height != other.height) + return height < other.height; + if (y_h_samp_factor != other.y_h_samp_factor) + return y_h_samp_factor < other.y_h_samp_factor; + if (y_v_samp_factor != other.y_v_samp_factor) + return y_v_samp_factor < other.y_v_samp_factor; + if (white_balance.r != other.white_balance.r) + return white_balance.r < other.white_balance.r; + if (white_balance.g != other.white_balance.g) + return white_balance.g < other.white_balance.g; + return white_balance.b < other.white_balance.b; + } + }; struct VAData { std::vector jpeg_header; VAEncPictureParameterBufferJPEG pic_param; @@ -161,15 +135,8 @@ private: VAHuffmanTableBufferJPEGBaseline huff; VAEncSliceParameterBufferJPEG parms; }; - std::map, VAData> va_data_for_resolution; - VAData get_va_data_for_resolution(unsigned width, unsigned height, const movit::RGBTriplet &white_balance); - - std::list va_resources_freelist; - std::mutex va_resources_mutex; - VAResources get_va_resources(unsigned width, unsigned height); - void release_va_resources(VAResources resources); - - static std::unique_ptr try_open_va(const std::string &va_display, std::string *error, VAConfigID *config_id); + std::map va_data_for_parameters; + VAData get_va_data_for_parameters(unsigned width, unsigned height, unsigned y_h_samp_factor, unsigned y_v_samp_factor, const movit::RGBTriplet &white_balance); uint8_t *tmp_y, *tmp_cbcr, *tmp_cb, *tmp_cr; // Private to the encoder thread. Used by the libjpeg backend only.