55#include <cmpto_j2k_dec.h>
94using std::unique_lock;
121 unsigned char *src_buffer,
122 unsigned int width,
unsigned int height){
nullptr};
125#define CHECK_OK(cmd, err_msg, action_fail) do { \
126 int j2k_error = cmd; \
127 if (j2k_error != CMPTO_OK) {\
128 LOG(LOG_LEVEL_ERROR) << MOD_NAME << (err_msg) << ": " << cmpto_j2k_dec_get_last_error() << "\n"; \
133#define NOOP ((void) 0)
136 unsigned char *src_buffer,
137 unsigned int width,
unsigned int height)
145 (
const char *) src_buffer, src_pitch,
148 MSG(
DEBUG,
"pixfmt conversion duration: %f ms\n",
154 if (dropped % 10 == 1) {
157 "tile limit to increase the throughput by adding parameter: --param j2k-dec-tile-limit=4\n");
172 struct cmpto_j2k_dec_img *img;
173 int decoded_img_status;
174 CHECK_OK(cmpto_j2k_dec_ctx_get_decoded_img(s->
decoder, 1, &img, &decoded_img_status),
175 "Decode image",
goto next_image);
178 lock_guard<mutex> lk(s->
lock);
186 if (decoded_img_status != CMPTO_J2K_DEC_IMG_OK) {
187 const char * decoding_error =
"";
188 CHECK_OK(cmpto_j2k_dec_img_get_error(img, &decoding_error),
"get error status",
189 decoding_error =
"(failed)");
196 CHECK_OK(cmpto_j2k_dec_img_get_samples(img, &dec_data, &
len),
197 "Error getting samples", cmpto_j2k_dec_img_destroy(img);
goto next_image);
199 char *buffer = (
char *) malloc(
len);
201 s->
convert((
unsigned char*) buffer, (
unsigned char*) dec_data, s->
desc.width, s->
desc.height);
204 memcpy(buffer, dec_data,
len);
207 CHECK_OK(cmpto_j2k_dec_img_destroy(img),
208 "Unable to to return processed image",
NOOP);
209 lock_guard<mutex> lk(s->
lock);
223 " J2K max memory usage in bytes.\n");
225 " number of tiles decoded at moment (less to reduce latency, more to increase performance, 0 unlimited)\n");
229 " max number of frames held by encoder\n");
253 const auto *version = cmpto_j2k_dec_get_version();
254 LOG(
LOG_LEVEL_INFO) <<
MOD_NAME <<
"Using codec version: " << (version ==
nullptr ?
"(unknown)" : version->name) <<
"\n";
261 void *,
void *,
size_t ,
262 int size_x,
int size_y,
struct cmpto_j2k_dec_comp_format *,
263 int comp_count,
size_t *temp_buffer_size,
size_t *output_buffer_size)
265 assert(comp_count == 3);
266 *temp_buffer_size = 0;
281 void (*
convert)(
unsigned char *dst_buffer,
unsigned char *src_buffer,
unsigned int width,
unsigned int height);
286 {
UYVY, CMPTO_422_U8_P1020,
nullptr,
nullptr,
nullptr },
287 {
v210, CMPTO_422_U10_V210,
nullptr,
nullptr,
nullptr },
288 {
RGB, CMPTO_444_U8_P012,
nullptr,
nullptr,
nullptr },
289 {
BGR, CMPTO_444_U8_P210,
nullptr,
nullptr,
nullptr },
290 {
RGBA, CMPTO_444_U8_P012Z,
nullptr,
nullptr,
nullptr },
291 {
R10k, CMPTO_444_U10U10U10_MSB32BE_P210,
nullptr,
nullptr,
nullptr },
292 {
RG48, CMPTO_444_U12_MSB16LE_P012,
nullptr,
nullptr,
nullptr },
297#define CPU_CONV_PARAM "j2k-dec-cpu-conv"
301 " Enforce CPU conversion instead of CUDA (applicable to R12L now)\n");
304 struct cmpto_j2k_dec_ctx_cfg *ctx_cfg,
307 const bool force_cpu_conv =
309 if (
codec->run_callback !=
nullptr && !force_cpu_conv) {
311 CHECK_OK(cmpto_j2k_dec_ctx_cfg_set_postprocessor_cuda(
312 ctx_cfg,
nullptr,
nullptr,
314 "add postprocessor",
return false);
318 "More than 1 CUDA device set, will use CPU conversion...\n");
321 if (s->
convert !=
nullptr &&
codec->run_callback ==
nullptr &&
323 MSG(WARNING,
"Compiled without CUDA, pixfmt conv will "
324 "be processed on CPU...\n");
330 int rshift,
int gshift,
int bshift,
int pitch,
codec_t out_codec)
346 enum cmpto_sample_format_type
cmpto_sf = (cmpto_sample_format_type) 0;
348 struct cmpto_j2k_dec_ctx_cfg *ctx_cfg =
nullptr;
349 CHECK_OK(cmpto_j2k_dec_ctx_cfg_create(&ctx_cfg),
"Error creating dec cfg",
return false);
351 CHECK_OK(cmpto_j2k_dec_ctx_cfg_add_cuda_device(
354 "Error setting CUDA device",
return false);
358 if(
codec.ug_codec != out_codec){
374 "Error initializing context",
return false);
376 CHECK_OK(cmpto_j2k_dec_ctx_cfg_destroy(ctx_cfg),
"Destroy cfg",
NOOP);
379 "Error creating configuration",
return false);
381 if (out_codec !=
RGBA || (rshift == 0 && gshift == 8 && bshift == 16)) {
383 "Error setting sample format type",
return false);
385 if (rshift % 8 != 0 || gshift % 8 != 0 || bshift % 8 != 0) {
387 "byte boundary is not supported.\n";
390 cmpto_j2k_dec_comp_format
fmt[3] = {};
391 const int shifts[3] = { rshift, gshift, bshift };
392 for (
int i = 0; i < 3; ++i) {
393 fmt[i].comp_index = i;
394 fmt[i].data_type = CMPTO_INT8;
395 fmt[i].offset = shifts[i] / 8;
399 fmt[i].bit_shift = 0;
400 fmt[i].is_or_combined = 0;
401 fmt[i].is_signed = 0;
402 fmt[i].sampling_factor_x = 1;
403 fmt[i].sampling_factor_y = 1;
407 "Error setting sample format",
return false);
415 assert(ret == 0 &&
"Unable to create thread");
425 (void)
custom_data; (void) custom_data_size; (void) codestream_size;
426 free(
const_cast<void *
>(codestream));
430 struct cmpto_j2k_dec_img_info info;
431 struct cmpto_j2k_dec_comp_info comp_info[3];
432 if (cmpto_j2k_dec_cstream_get_img_info(buffer,
len, &info) != CMPTO_OK ||
433 cmpto_j2k_dec_cstream_get_comp_info(buffer,
len, 0, &comp_info[0]) != CMPTO_OK) {
438 internal_prop->
depth = comp_info[0].bit_depth;
439 internal_prop->
rgb = in_codec ==
J2KR;
440 if (info.comp_count == 3) {
441 if (cmpto_j2k_dec_cstream_get_comp_info(buffer,
len, 1, &comp_info[1]) != CMPTO_OK ||
442 cmpto_j2k_dec_cstream_get_comp_info(buffer,
len, 2, &comp_info[2]) != CMPTO_OK) {
446 if (comp_info[0].sampling_factor_x == 1 && comp_info[0].sampling_factor_y == 1 &&
447 comp_info[1].sampling_factor_x == comp_info[2].sampling_factor_x &&
448 comp_info[1].sampling_factor_y == comp_info[2].sampling_factor_y) {
449 int a = 4 / comp_info[1].sampling_factor_x;
451 if (comp_info[1].sampling_factor_y == 1) {
473 struct cmpto_j2k_dec_img *img;
474 pair<char *, size_t> decoded;
483 goto return_previous;
487 "Could not create frame",
goto return_previous);
489 tmp = malloc(src_len);
490 memcpy(tmp, buffer, src_len);
492 "Error setting cstream", cmpto_j2k_dec_img_destroy(img);
goto return_previous);
495 cmpto_j2k_dec_img_destroy(img);
goto return_previous);
497 lock_guard<mutex> lk(s->
lock);
502 unique_lock<mutex> lk(s->
lock);
511 size_t frame_size = linesize * s->
desc.height;
512 if ((decoded.second + 3) / 4 * 4 != frame_size) {
516 for (
size_t i = 0; i < s->
desc.height; ++i) {
517 memcpy(dst + i * s->
pitch, decoded.first + i * linesize, min(linesize, decoded.second - min(decoded.second, i * linesize)));
532 if(*
len >=
sizeof(
int)) {
533 *(
int *)
val =
false;
548 cmpto_j2k_dec_ctx_stop(s->
decoder);
553 cmpto_j2k_dec_cfg_destroy(s->
settings);
557 cmpto_j2k_dec_ctx_destroy(s->
decoder);
578 if (compression !=
J2K && compression !=
J2KR) {
584 bool codec_found =
false;
586 if (
codec.ug_codec == ugc) {
594 if (internal.depth == 0) {
int vc_get_linesize(unsigned int width, codec_t codec)
const char * get_codec_name(codec_t codec)
void log_msg(int level, const char *format,...)
void log_msg_once(int level, uint32_t id, const char *msg,...)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_WARNING
less severe errors
#define DECOMPRESS_PROPERTY_ACCEPTS_CORRUPTED_FRAME
@ DECODER_GOT_CODEC
Internal pixel format was determined.
@ VDEC_PRIO_NA
decoder cannot handle the codec in any way
@ VDEC_PRIO_PROBE_HI
decoder can probe
unsigned int cuda_devices_count
const char * get_commandline_param(const char *key)
unsigned int cuda_devices[MAX_CUDA_DEVICES]
#define ADD_TO_PARAM(param, doc)
int postprocess_rg48_to_r12l(void *, void *, size_t, int size_x, int size_y, struct cmpto_j2k_dec_comp_format *, int, void *input_samples, size_t, void *, size_t, void *output_buffer, size_t, void *vstream)
@ LIBRARY_CLASS_VIDEO_DECOMPRESS
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
#define to_fourcc(a, b, c, d)
Creates FourCC word.
double unit_evaluate_dbl(const char *str, bool case_sensitive, const char **endptr)
void parallel_pix_conv(int height, char *out, int out_linesize, const char *in, int in_linesize, decoder_t decode, int threads)
decoder_t get_decoder_from_to(codec_t in, codec_t out)
static void vc_copylineRG48toR12L(unsigned char *__restrict dst, const unsigned char *__restrict src, int dst_len, int rshift, int gshift, int bshift)
Converts RG48 to R12L. Converts 16-bit RGB to 12-bit packed RGB in full range (compatible with SMPTE ...
decoder_func_t * decoder_t
enum cmpto_sample_format_type cmpto_sf
cmpto_j2k_dec_postprocessor_size_callback_cuda size_callback
cmpto_j2k_dec_postprocessor_run_callback_cuda run_callback
void(* convert)(unsigned char *dst_buffer, unsigned char *src_buffer, unsigned int width, unsigned int height)
auxilliary data structure passed with encoded frame
int depth
bit depth; 0 means that whole struct is undefined
int subsampling
in 'JabA' format, eg. '4444'
cmpto_j2k_dec_cfg * settings
unsigned int req_tile_limit
cmpto_j2k_dec_ctx * decoder
long long int req_mem_limit
unsigned int max_queue_size
maximal length of decompressed_frames
void(* convert)(unsigned char *dst_buffer, unsigned char *src_buffer, unsigned int width, unsigned int height)
unsigned long long int dropped
number of dropped frames because queue was full
state_decompress_j2k(unsigned int mqs, unsigned int mif)
queue< pair< char *, size_t > > decompressed_frames
buffer, length
unsigned int in_frames
actual number of decompressed frames
unsigned int max_in_frames
maximal frames that can be "in progress"
unsigned int width
width of every tile (!)
Struct containing callbacks of a video_frame.
static time_ns_t get_time_in_ns()
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
@ RGB
RGB 8-bit (packed into 24-bit word)
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
@ VIDEO_CODEC_NONE
dummy color spec
@ RG48
16-bit RGB little-endian (RlRhGl...)
@ R12L
RGB 12-bit packed, little-endian.
@ RGBA
RGBA 8-bit, big-endian.
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
const char * get_pixdesc_desc(struct pixfmt_desc desc)
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).
double get_bpp(codec_t codec)
size_t vc_get_datalen(unsigned int width, unsigned int height, codec_t codec)
int get_bits_per_component(codec_t codec)
enum cmpto_sample_format_type cmpto_sf
constexpr const int DEFAULT_TILE_LIMIT
static void rg48_to_r12l(unsigned char *dst_buffer, unsigned char *src_buffer, unsigned int width, unsigned int height)
static void * decompress_j2k_worker(void *args)
constexpr const int DEFAULT_MAX_IN_FRAMES
maximal number of concurrently decompressed frames
constexpr const int64_t DEFAULT_MEM_LIMIT
static int j2k_decompress_get_priority(codec_t compression, struct pixfmt_desc internal, codec_t ugc)
static bool set_postprocess_convert(struct state_decompress_j2k *s, struct cmpto_j2k_dec_ctx_cfg *ctx_cfg, const struct conv_props *codec)
static decompress_status j2k_decompress(void *state, unsigned char *dst, unsigned char *buffer, unsigned int src_len, int, struct video_frame_callbacks *, struct pixfmt_desc *internal_prop)
static decompress_status j2k_probe_internal_codec(codec_t in_codec, unsigned char *buffer, size_t len, struct pixfmt_desc *internal_prop)
static int j2k_decompress_get_property(void *state, int property, void *val, size_t *len)
static void release_cstream(void *custom_data, size_t custom_data_size, const void *codestream, size_t codestream_size)
static const struct video_decompress_info j2k_decompress_info
constexpr const int DEFAULT_MAX_QUEUE_SIZE
maximal size of queue for decompressed frames
static void j2k_decompress_done(void *state)
static void r12l_postprocessor_get_sz(void *, void *, size_t, int size_x, int size_y, struct cmpto_j2k_dec_comp_format *, int comp_count, size_t *temp_buffer_size, size_t *output_buffer_size)
static int j2k_decompress_reconfigure(void *state, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
const cmpto_j2k_dec_postprocessor_run_callback_cuda r12l_postprocess_cuda
#define CHECK_OK(cmd, err_msg, action_fail)
static void print_dropped(unsigned long long int dropped)
static void * j2k_decompress_init(void)
static const struct conv_props codecs[]
constexpr const char * MOD_NAME
static void j2k_decompress_cleanup_common(struct state_decompress_j2k *s)
API for video decompress drivers.
#define VIDEO_DECOMPRESS_ABI_VERSION