|
35 | 35 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | 36 | */ |
37 | 37 |
|
38 | | -#include <string> |
| 38 | +#include <cassert> // for assert |
39 | 39 | #include <cinttypes> // for PRIu32 |
| 40 | +#include <climits> // for LLONG_MIN |
40 | 41 | #include <condition_variable> |
41 | 42 | #include <memory> |
42 | 43 | #include <mutex> |
| 44 | +#include <string> |
43 | 45 | #include <thread> |
44 | 46 | #include <vector> |
45 | 47 | #include <svt-jpegxs/SvtJpegxs.h> // for SvtJxsErrorType |
@@ -89,6 +91,8 @@ struct state_video_compress_jpegxs { |
89 | 91 | svt_jpeg_xs_frame_pool_t *frame_pool{}; |
90 | 92 | int pool_size = DEFAULT_POOL_SIZE; |
91 | 93 |
|
| 94 | + long long req_bitrate = -1; |
| 95 | + |
92 | 96 | bool configured = 0; |
93 | 97 | bool reconfiguring = 0; |
94 | 98 | bool stop = 0; |
@@ -278,6 +282,23 @@ ColourFormat subsampling_to_jpegxs(int ug_subs) { |
278 | 282 | } |
279 | 283 | } |
280 | 284 |
|
| 285 | +static void |
| 286 | +set_bitrate(svt_jpeg_xs_encoder_api_t *encoder, long long req_bitrate, |
| 287 | + const struct video_desc *desc) |
| 288 | +{ |
| 289 | + long long numerator = req_bitrate; |
| 290 | + long long denominator = desc->width * desc->height * desc->fps; |
| 291 | + // reduce numbers to fit uint32_t if num or den is larger |
| 292 | + while (numerator > UINT32_MAX || denominator > UINT32_MAX) { |
| 293 | + numerator /= 1024; |
| 294 | + denominator /= 1024; |
| 295 | + } |
| 296 | + assert(numerator > 0); |
| 297 | + assert(denominator > 0); |
| 298 | + encoder->bpp_numerator = numerator; |
| 299 | + encoder->bpp_denominator = denominator; |
| 300 | +} |
| 301 | + |
281 | 302 | static bool configure_with(struct state_video_compress_jpegxs *s, struct video_desc desc) |
282 | 303 | { |
283 | 304 | const struct uv_to_jpegxs_conversion *conv = get_uv_to_jpegxs_conversion(desc.color_spec); |
@@ -307,6 +328,10 @@ static bool configure_with(struct state_video_compress_jpegxs *s, struct video_d |
307 | 328 | return false; |
308 | 329 | } |
309 | 330 |
|
| 331 | + if (s->req_bitrate != -1) { |
| 332 | + set_bitrate(&s->encoder, s->req_bitrate, &desc); |
| 333 | + } |
| 334 | + |
310 | 335 | err = svt_jpeg_xs_encoder_init(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &s->encoder); |
311 | 336 | if (err != SvtJxsErrorNone) { |
312 | 337 | log_msg(LOG_LEVEL_ERROR, MOD_NAME "Failed to initialize JPEG XS encoder: %x\n", err); |
@@ -342,7 +367,13 @@ bool state_video_compress_jpegxs::parse_fmt(char *fmt) { |
342 | 367 | while ((tok = strtok_r(fmt, ":", &save_ptr)) != nullptr) { |
343 | 368 | const char *const val = strchr(tok, '=') + 1; |
344 | 369 | const int num = val != nullptr ? atoi(val) : -1; |
345 | | - if (IS_KEY_PREFIX(tok, "bpp")) { |
| 370 | + if (IS_KEY_PREFIX(tok, "bitrate")) { |
| 371 | + req_bitrate = unit_evaluate(val, nullptr); |
| 372 | + if (req_bitrate == LLONG_MIN) { |
| 373 | + MSG(ERROR, "Invalid value for bitrate: %s\n", val); |
| 374 | + return false; |
| 375 | + } |
| 376 | + } else if (IS_KEY_PREFIX(tok, "bpp")) { |
346 | 377 | int num = 0, den = 1; |
347 | 378 | if (sscanf(val, "%d/%d", &num, &den) < 1 || num <= 0 || den <= 0) { |
348 | 379 | MSG(ERROR, "Invalid bpp value '%s' (must be a positive integer or fraction, e.g., 2 or 3/4).\n", val); |
@@ -423,6 +454,9 @@ static const struct { |
423 | 454 | bool is_boolean; |
424 | 455 | const char *placeholder; |
425 | 456 | } usage_opts[] = { |
| 457 | + {"Bit rate", "bitrate", "bitrate", "\t\tbitrate to be used " |
| 458 | + "(eg. 50.5M)\n", ":bitrate=", false, "50.5M" |
| 459 | + }, |
426 | 460 | {"Bits per pixel", "bpp", "bpp", |
427 | 461 | "\t\tTarget bits-per-pixel ratio for the encoder. May be given as an\n" |
428 | 462 | "\t\tinteger (e.g., 2) or as a fraction (e.g., 3/4). Controls the\n" |
@@ -485,7 +519,7 @@ static void *jpegxs_compress_init(struct module *parent, const char *opts) { |
485 | 519 | if (opts && strcmp(opts, "help") == 0) { |
486 | 520 | color_printf(TBOLD("JPEG XS") " compression usage:\n"); |
487 | 521 | color_printf("\t" TBOLD( |
488 | | - TRED("-c jpegxs") "[:bpp=<ratio>][:decomp_v=<0-2>][:decomp_h=<1-5>]" |
| 522 | + TRED("-c jpegxs") "[:bitrate=<br>|:bpp=<ratio>][:decomp_v=<0-2>][:decomp_h=<1-5>]" |
489 | 523 | "[:quantization=<0-1>][:slice_height=<n>][:rc=<mode>]" |
490 | 524 | "[:threads=<num_threads>][:pool_size=<n>][:verbose=<n>]") "\n"); |
491 | 525 | color_printf("\t" TBOLD(TRED("-c jpegxs") ":help") "\n"); |
|
0 commit comments