diff --git a/src/video_compress/jpegxs.cpp b/src/video_compress/jpegxs.cpp index c6a27f2f0..4603c449a 100644 --- a/src/video_compress/jpegxs.cpp +++ b/src/video_compress/jpegxs.cpp @@ -1,6 +1,7 @@ #include #include "lib_common.h" +#include "video.h" #include "video_compress.h" #include @@ -13,7 +14,10 @@ struct state_video_compress_jpegxs { private: state_video_compress_jpegxs(struct module *parent, const char *opts); public: - svt_jpeg_xs_encoder_api_t m_encoder; + svt_jpeg_xs_encoder_api_t encoder; + unsigned int configured:1; + svt_jpeg_xs_image_buffer_t in_buf; + svt_jpeg_xs_bitstream_buffer_t out_buf; static state_video_compress_jpegxs *create(struct module *parent, const char *opts); void push(std::shared_ptr in_frame); @@ -22,14 +26,6 @@ public: state_video_compress_jpegxs::state_video_compress_jpegxs(struct module *parent, const char *opts) { (void) parent; - - m_encoder.source_width = 1920; - m_encoder.source_height = 1080; - m_encoder.input_bit_depth = 8; - m_encoder.colour_format = COLOUR_FORMAT_PLANAR_YUV422; - m_encoder.bpp_numerator = 3; - - svt_jpeg_xs_encoder_init(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &m_encoder); } state_video_compress_jpegxs *state_video_compress_jpegxs::create(struct module *parent, const char *opts) { @@ -38,11 +34,62 @@ state_video_compress_jpegxs *state_video_compress_jpegxs::create(struct module * return ret; } +static bool configure_with(struct state_video_compress_jpegxs *s, struct video_desc desc) { + svt_jpeg_xs_encoder_api_t enc = {}; + + SvtJxsErrorType_t err = svt_jpeg_xs_encoder_load_default_parameters(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &enc); + if (err != SvtJxsErrorNone) { + return false; + } + + // TODO parameters + enc.source_width = desc.width; + enc.source_height = desc.height; + enc.input_bit_depth = 8; + enc.colour_format = COLOUR_FORMAT_PLANAR_YUV422; + enc.bpp_numerator = 3; + + err = svt_jpeg_xs_encoder_init(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &enc); + if (err != SvtJxsErrorNone) { + return false; + } + + uint32_t pixel_size = enc.input_bit_depth <= 8 ? 1 : 2; + svt_jpeg_xs_image_buffer_t in_buf; + in_buf.stride[0] = enc.source_width; + in_buf.stride[1] = enc.source_width / 2; + in_buf.stride[2] = enc.source_width / 2; + for (uint8_t i = 0; i < 3; ++i) { + in_buf.alloc_size[i] = in_buf.stride[i] * enc.source_height * pixel_size; + in_buf.data_yuv[i] = (uint8_t *) malloc(in_buf.alloc_size[i]); + if (!in_buf.data_yuv[i]) { + return false; + } + } + + svt_jpeg_xs_bitstream_buffer_t out_buf; + uint32_t bitstream_size = (uint32_t)( + ((uint64_t)enc.source_width * enc.source_height * enc.bpp_numerator / enc.bpp_denominator + 7) / +8); + out_buf.allocation_size = bitstream_size; + out_buf.used_size = 0; + out_buf.buffer = (uint8_t *) malloc(out_buf.allocation_size); + if (!out_buf.buffer) { + return false; + } + + s->encoder = enc; + s->in_buf = in_buf; + s->out_buf = out_buf; + s->configured = true; + + return true; +} + void * jpegxs_compress_init(struct module *parent, const char *opts) { struct state_video_compress_jpegxs *s; - if(opts && strcmp(opts, "help") == 0) { + if (opts && strcmp(opts, "help") == 0) { printf("JPEG XS help message\n"); return INIT_NOERR; } @@ -53,7 +100,16 @@ jpegxs_compress_init(struct module *parent, const char *opts) { } shared_ptr jpegxs_compress(void *state, shared_ptr frame) { - // TODO + auto *s = (struct state_video_compress_jpegxs *) state; + + if (!s->configured) { + struct video_desc desc = video_desc_from_frame(frame.get()); + if (!configure_with(s, desc)) { + return NULL; + } + } + + return frame; } // void state_video_compress_jpegxs::push(std::shared_ptr in_frame) @@ -88,7 +144,7 @@ static compress_module_info get_jpegxs_module_info() { const struct video_compress_info jpegxs_info = { jpegxs_compress_init, // jpegxs_compress_init jpegxs_compress_done, // jpegxs_compress_done - NULL, // jpegxs_compress (synchronous) + jpegxs_compress, // jpegxs_compress (synchronous) NULL, NULL, // jpegxs_compress_push (asynchronous) NULL, // jpegxs_compress_pull