FFmpeg
Loading...
Searching...
No Matches
libsvtjpegxsenc.c
Go to the documentation of this file.
1/*
2 * Copyright(c) 2024 Intel Corporation
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/*
22* Copyright(c) 2024 Intel Corporation
23* SPDX - License - Identifier: BSD - 2 - Clause - Patent
24*/
25
26#include <SvtJpegxsEnc.h>
27
28#include "libavutil/avassert.h"
29#include "libavutil/common.h"
30#include "libavutil/cpu.h"
31#include "libavutil/imgutils.h"
32#include "libavutil/rational.h"
33
34#include "avcodec.h"
35#include "codec_internal.h"
36#include "encode.h"
37#include "profiles.h"
38
52
54 const AVFrame* frame, int* got_packet)
55{
56 SvtJpegXsEncodeContext* svt_enc = avctx->priv_data;
57
58 svt_jpeg_xs_frame_t enc_input;
59 svt_jpeg_xs_bitstream_buffer_t *const out_buf = &enc_input.bitstream;
60 svt_jpeg_xs_image_buffer_t *const in_buf = &enc_input.image;
61 svt_jpeg_xs_frame_t enc_output;
62
63 SvtJxsErrorType_t err = SvtJxsErrorNone;
64
65 int ret = ff_get_encode_buffer(avctx, pkt, svt_enc->bitstream_frame_size, 0);
66 if (ret < 0)
67 return ret;
68
69 out_buf->buffer = pkt->data;// output bitstream ptr
70 out_buf->allocation_size = pkt->size;// output bitstream size
71 out_buf->used_size = 0;
72
73 unsigned pixel_shift = svt_enc->encoder.input_bit_depth <= 8 ? 0 : 1;
74 for (int comp = 0; comp < 3; comp++) {
75 // svt-jpegxs require stride in pixel's not in bytes, this means that for 10 bit-depth, stride is half the linesize
76 in_buf->stride[comp] = frame->linesize[comp] >> pixel_shift;
77 in_buf->data_yuv[comp] = frame->data[comp];
78 in_buf->alloc_size[comp] = frame->linesize[comp] * svt_enc->encoder.source_height;
79 }
80
81 enc_input.user_prv_ctx_ptr = pkt;
82
83 err = svt_jpeg_xs_encoder_send_picture(&svt_enc->encoder, &enc_input, 1 /*blocking*/);
84 if (err != SvtJxsErrorNone) {
85 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_encoder_send_picture failed\n");
86 return AVERROR_EXTERNAL;
87 }
88
89 err = svt_jpeg_xs_encoder_get_packet(&svt_enc->encoder, &enc_output, 1 /*blocking*/);
90 if (err != SvtJxsErrorNone) {
91 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_encoder_get_packet failed\n");
92 return AVERROR_EXTERNAL;
93 }
94
95 if (enc_output.user_prv_ctx_ptr != pkt) {
96 av_log(avctx, AV_LOG_ERROR, "Returned different user_prv_ctx_ptr than expected\n");
97 return AVERROR_EXTERNAL;
98 }
99
100 pkt->size = enc_output.bitstream.used_size;
101
102 *got_packet = 1;
103
104 return 0;
105}
106
108 SvtJpegXsEncodeContext* svt_enc = avctx->priv_data;
109
110 svt_jpeg_xs_encoder_close(&svt_enc->encoder);
111
112 return 0;
113}
114
115static void set_pix_fmt(AVCodecContext *avctx, svt_jpeg_xs_encoder_api_t *encoder)
116{
117 switch (avctx->pix_fmt) {
119 encoder->input_bit_depth = 8;
120 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV420;
121 return;
123 encoder->input_bit_depth = 8;
124 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV422;
125 return;
127 encoder->input_bit_depth = 8;
128 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV444_OR_RGB;
129 return;
131 encoder->input_bit_depth = 10;
132 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV420;
133 return;
135 encoder->input_bit_depth = 10;
136 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV422;
137 return;
139 encoder->input_bit_depth = 10;
140 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV444_OR_RGB;
141 return;
143 encoder->input_bit_depth = 12;
144 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV420;
145 return;
147 encoder->input_bit_depth = 12;
148 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV422;
149 return;
151 encoder->input_bit_depth = 12;
152 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV444_OR_RGB;
153 return;
155 encoder->input_bit_depth = 14;
156 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV420;
157 return;
159 encoder->input_bit_depth = 14;
160 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV422;
161 return;
163 encoder->input_bit_depth = 14;
164 encoder->colour_format = COLOUR_FORMAT_PLANAR_YUV444_OR_RGB;
165 return;
166 default:
167 av_unreachable("Already checked via CODEC_PIXFMTS_ARRAY");
168 break;
169 }
170}
171
173 SvtJpegXsEncodeContext* svt_enc = avctx->priv_data;
174 AVRational bpp;
175 SvtJxsErrorType_t err;
176
177 err = svt_jpeg_xs_encoder_load_default_parameters(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &(svt_enc->encoder));
178 if (err != SvtJxsErrorNone) {
179 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_encoder_load_default_parameters failed\n");
180 return AVERROR_EXTERNAL;
181 }
182
183 svt_enc->encoder.source_width = avctx->width;
184 svt_enc->encoder.source_height = avctx->height;
185
186 set_pix_fmt(avctx, &svt_enc->encoder);
187
188 int thread_count = avctx->thread_count ? avctx->thread_count : av_cpu_count();
189 svt_enc->encoder.threads_num = FFMIN(thread_count, 64);
190
191 int log_level = av_log_get_level();
192 svt_enc->encoder.verbose = log_level < AV_LOG_DEBUG ? VERBOSE_ERRORS :
193 log_level == AV_LOG_DEBUG ? VERBOSE_SYSTEM_INFO : VERBOSE_WARNINGS;
194
195 if (avctx->framerate.num <= 0 || avctx->framerate.den <= 0) {
196 av_log(avctx, AV_LOG_ERROR, "framerate must be set\n");
197 return AVERROR(EINVAL);
198 }
199 if (avctx->bit_rate == 0) {
201 // default to a 1.5 compression ratio
202 avctx->bit_rate = (int64_t)avctx->width * avctx->height *
203 (av_get_bits_per_pixel(desc) * 2 / 3) * av_q2d(avctx->framerate);
204 av_log(avctx, AV_LOG_WARNING, "No bitrate set, defaulting to %"PRId64"\n", avctx->bit_rate);
205 }
206
207 av_reduce(&bpp.num, &bpp.den, avctx->bit_rate, (int64_t)avctx->width * avctx->height, INT_MAX);
208 bpp = av_div_q(bpp, avctx->framerate);
209 svt_enc->encoder.bpp_numerator = bpp.num;
210 svt_enc->encoder.bpp_denominator = bpp.den;
211
212 if (svt_enc->decomp_v >= 0)
213 svt_enc->encoder.ndecomp_v = svt_enc->decomp_v;
214 if (svt_enc->decomp_h >= 0)
215 svt_enc->encoder.ndecomp_h = svt_enc->decomp_h;
216 if (svt_enc->quant >= 0)
217 svt_enc->encoder.quantization = svt_enc->quant;
218 if (svt_enc->coding_signs_handling >= 0)
219 svt_enc->encoder.coding_signs_handling = svt_enc->coding_signs_handling;
220 if (svt_enc->coding_significance >= 0)
221 svt_enc->encoder.coding_significance = svt_enc->coding_significance;
222 if (svt_enc->coding_vpred >= 0)
223 svt_enc->encoder.coding_vertical_prediction_mode = svt_enc->coding_vpred;
224 if (avctx->slices > 0)
225 svt_enc->encoder.slice_height = avctx->height / avctx->slices;
226
227 err = svt_jpeg_xs_encoder_init(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR, &svt_enc->encoder);
228 if (err != SvtJxsErrorNone) {
229 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_encoder_init failed\n");
230 return AVERROR_EXTERNAL;
231 }
232
233 svt_enc->bitstream_frame_size = (((int64_t)avctx->width * avctx->height *
234 svt_enc->encoder.bpp_numerator / svt_enc->encoder.bpp_denominator + 7) / 8);
235
236 return 0;
237}
238
254
256 { "b", "0" },
257 { NULL },
258};
259
260#define OFFSET(x) offsetof(SvtJpegXsEncodeContext, x)
261#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
263 { "decomp_v", "vertical decomposition level", OFFSET(decomp_v), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, VE },
264 { "decomp_h", "horizontal decomposition level", OFFSET(decomp_h), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 5, VE },
265 { "quantization", "Quantization algorithm", OFFSET(quant), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 1, VE, .unit = "quantization" },
266 { "deadzone", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "quantization" },
267 { "uniform", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, VE, .unit = "quantization" },
268 { "coding-signs", "Enable Signs handling strategy", OFFSET(coding_signs_handling), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, VE, .unit = "coding-signs" },
269 { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "coding-signs" },
270 { "fast", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, VE, .unit = "coding-signs" },
271 { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, INT_MIN, INT_MAX, VE, .unit = "coding-signs" },
272 { "coding-sigf", "Enable Significance coding", OFFSET(coding_significance), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
273 { "coding-vpred", "Enable Vertical Prediction coding", OFFSET(coding_vpred), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, VE, .unit = "coding-vpred" },
274 { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "coding-vpred" },
275 { "no_residuals", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, INT_MIN, INT_MAX, VE, .unit = "coding-vpred" },
276 { "no_coeffs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, INT_MIN, INT_MAX, VE, .unit = "coding-vpred" },
277 { NULL },
278};
279
281 .class_name = "libsvtjpegxs",
282 .item_name = av_default_item_name,
283 .option = svtjpegxs_enc_options,
284 .version = LIBAVUTIL_VERSION_INT,
285};
286
288 .p.name = "libsvtjpegxs",
289 CODEC_LONG_NAME("SVT JPEG XS(Scalable Video Technology for JPEG XS) encoder"),
290 .p.type = AVMEDIA_TYPE_VIDEO,
291 .p.id = AV_CODEC_ID_JPEGXS,
292 .priv_data_size = sizeof(SvtJpegXsEncodeContext),
298 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
301 .p.wrapper_name = "libsvtjpegxs",
302 .p.priv_class = &svtjpegxs_enc_class,
303};
const FFCodec ff_libsvtjpegxs_encoder
#define VE
Definition amfenc_av1.c:30
static const FFCodecDefault defaults[]
Definition amfenc_av1.c:723
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
Libavcodec external API header.
#define CODEC_PIXFMTS_ARRAY(array)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
common internal and external API header
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition eamad.c:79
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition codec.h:112
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
@ AV_CODEC_ID_JPEGXS
Definition codec_id.h:325
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
int av_log_get_level(void)
Get the current log level.
Definition log.c:471
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition rational.c:35
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition rational.c:88
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
misc image utilities
#define av_cold
Definition attributes.h:117
int av_cpu_count(void)
Definition cpu.c:228
static enum AVPixelFormat pix_fmts[]
Definition libkvazaar.c:296
const char * desc
Definition libsvtav1.c:83
static const FFCodecDefault svt_jpegxs_defaults[]
static void set_pix_fmt(AVCodecContext *avctx, svt_jpeg_xs_encoder_api_t *encoder)
static av_cold int svt_jpegxs_enc_init(AVCodecContext *avctx)
static av_cold int svt_jpegxs_enc_free(AVCodecContext *avctx)
static const AVClass svtjpegxs_enc_class
static int svt_jpegxs_enc_encode(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
#define OFFSET(x)
static const AVOption svtjpegxs_enc_options[]
#define FFMIN(a, b)
Definition macros.h:49
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition pixdesc.c:3412
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_YUV420P14LE
planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition pixfmt.h:270
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition pixfmt.h:156
@ AV_PIX_FMT_YUV444P14LE
planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition pixfmt.h:278
@ AV_PIX_FMT_YUV422P12LE
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition pixfmt.h:272
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_YUV420P12LE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition pixfmt.h:268
@ AV_PIX_FMT_YUV422P10LE
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition pixfmt.h:158
@ AV_PIX_FMT_YUV422P14LE
planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition pixfmt.h:274
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition pixfmt.h:162
@ AV_PIX_FMT_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition pixfmt.h:276
Utilities for rational number calculation.
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
AVRational framerate
Definition avcodec.h:563
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
void * priv_data
Definition avcodec.h:470
int slices
Number of slices.
Definition avcodec.h:1037
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
svt_jpeg_xs_encoder_api_t encoder
#define av_log(a,...)
static const uint8_t quant[64]
Definition vmixdec.c:71