vcomp/lavc: support JXS

This commit is contained in:
Martin Pulec
2026-02-17 16:02:21 +01:00
parent 58b94505b9
commit 9e5cb700b2
3 changed files with 50 additions and 3 deletions

View File

@@ -4,7 +4,7 @@
* @author Martin Piatka <445597@mail.muni.cz>
*/
/*
* Copyright (c) 2013-2025 CESNET, zájmové sdružení právnických osob
* Copyright (c) 2013-2026 CESNET, zájmové sdružení právnických osob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,7 @@
#include "host.h"
#include "libavcodec/lavc_common.h"
#include <libavutil/channel_layout.h>
#include "types.h"
#include "utils/macros.h"
#include "video.h"
@@ -81,6 +82,7 @@ static const struct {
{ AV_CODEC_ID_PRORES, PRORES_422_PROXY },
{ AV_CODEC_ID_PRORES, PRORES_422_LT },
{ AV_CODEC_ID_APV, APV },
{ AV_CODEC_ID_JPEGXS, JPEG_XS },
};
codec_t get_av_to_ug_codec(enum AVCodecID av_codec)

View File

@@ -3,7 +3,7 @@
* @author Martin Pulec <martin.pulec@cesnet.cz>
*/
/*
* Copyright (c) 2013-2025 CESNET, zájmové sdružení právnických osob
* Copyright (c) 2013-2026 CESNET, zájmové sdružení právnických osob
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -82,6 +82,9 @@ enum {
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(62, 3, 100)
#define AV_CODEC_ID_APV AV_CODEC_ID_NONE
#endif
#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(62, 22, 101)
#define AV_CODEC_ID_JPEGXS AV_CODEC_ID_NONE
#endif
#define Y210_PRESENT LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 42, 100) // FFMPEG commit 1c37cad0
#define X2RGB10LE_PRESENT LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 55, 100) // FFMPEG commit b09fb030

View File

@@ -70,7 +70,7 @@
#include "utils/color_out.h"
#include "utils/debug.h" // for debug_file_dump
#include "utils/macros.h"
#include "utils/misc.h"
#include "utils/misc.h" // for get_framerate_[dn]
#include "utils/string.h" // replace_all
#include "utils/text.h"
#include "video.h"
@@ -185,6 +185,8 @@ static void libavcodec_compress_done(void *state);
static void setparam_default(AVCodecContext *, struct setparam_param *);
static void setparam_h264_h265_av1(AVCodecContext *, struct setparam_param *);
static void setparam_jpeg(AVCodecContext *, struct setparam_param *);
static void setparam_jxs(AVCodecContext *codec_ctx,
struct setparam_param *param);
static void setparam_oapv(AVCodecContext *, struct setparam_param *);
static void setparam_vp8_vp9(AVCodecContext *, struct setparam_param *);
static void set_codec_thread_mode(AVCodecContext *codec_ctx, struct setparam_param *param);
@@ -235,6 +237,8 @@ get_codec_params(codec_t ug_codec)
};
case APV:
return { nullptr, 0, setparam_oapv, gui_dfl_prio };
case JPEG_XS:
return { nullptr, 1, setparam_jxs, gui_dfl_prio };
default:
break;
}
@@ -950,6 +954,8 @@ bool set_codec_ctx_params(struct state_video_compress_libav *s, AVPixelFormat pi
s->codec_ctx->height = desc.height;
/* frames per second */
s->codec_ctx->time_base = (AVRational){1,(int) desc.fps};
s->codec_ctx->framerate = (AVRational) { get_framerate_n(desc.fps),
get_framerate_d(desc.fps) };
s->codec_ctx->gop_size = s->requested_gop;
s->codec_ctx->max_b_frames = 0;
@@ -962,6 +968,7 @@ bool set_codec_ctx_params(struct state_video_compress_libav *s, AVPixelFormat pi
params.slices, s->codec_ctx->codec_id == AV_CODEC_ID_FFV1
? 16
: DEFAULT_SLICE_COUNT);
MSG(VERBOSE, "Setting slices to %d\n", s->codec_ctx->slices);
s->header_inserter = params.header_inserter_req == 1;
// set user supplied parameters
@@ -1806,6 +1813,41 @@ setparam_oapv(AVCodecContext */*codec_ctx*/, struct setparam_param *param)
param->lavc_opts["oapv-params"] = oapv_params;
}
static void
setparam_jxs(AVCodecContext * /* codec_ctx */, struct setparam_param *param)
{
unsigned decomp_v = 0;
if (param->lavc_opts.find("decomp_v") == param->lavc_opts.end()) {
unsigned height = param->desc.height;
while (height % 2 == 0 && decomp_v < 2) {
decomp_v += 1;
height /= 2;
}
char num[2];
snprintf_ch(num, "%u", decomp_v);
param->lavc_opts["decomp_v"] = num;
} else {
decomp_v = stoi(param->lavc_opts.at("decomp_v"));
}
if (param->slices == -1) {
int slice_height = 1 << decomp_v;
param->slices = param->desc.height / slice_height;
}
if (param->lavc_opts.find("decomp_h") == param->lavc_opts.end()) {
unsigned decomp_h = 0;
unsigned width = param->desc.width;
while (width % 2 == 0 && decomp_h < 5) {
decomp_h += 1;
width /= 2;
}
char num[2];
snprintf_ch(num, "%u", decomp_h);
param->lavc_opts["decomp_h"] = num;
}
}
static void configure_amf([[maybe_unused]] AVCodecContext *codec_ctx, [[maybe_unused]] struct setparam_param *param) {
check_av_opt_set(codec_ctx->priv_data, "rc", DEFAULT_AMF_RC);
const char *const usage = codec_ctx->codec->id == AV_CODEC_ID_AV1