FFmpeg
Loading...
Searching...
No Matches
libsvtjpegxsdec.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 <SvtJpegxsDec.h>
27
28#include "libavutil/mem.h"
29#include "libavutil/common.h"
30#include "libavutil/cpu.h"
31#include "libavutil/imgutils.h"
32#include "libavutil/avassert.h"
33
34#include "avcodec.h"
35#include "codec_internal.h"
36#include "decode.h"
37#include "profiles.h"
38
39typedef struct SvtJpegXsDecodeContext {
40 svt_jpeg_xs_image_config_t config;
41 svt_jpeg_xs_decoder_api_t decoder;
42 svt_jpeg_xs_frame_t input;
43 svt_jpeg_xs_frame_t output;
45
48
49static int set_pix_fmt(void *logctx, const svt_jpeg_xs_image_config_t *config)
50{
51 int ret = AVERROR_BUG;
52
53 switch (config->format) {
54 case COLOUR_FORMAT_PLANAR_YUV420:
55 if (config->bit_depth == 8)
56 return AV_PIX_FMT_YUV420P;
57 else if (config->bit_depth == 10)
59 else if (config->bit_depth == 12)
61 else
63 break;
64 case COLOUR_FORMAT_PLANAR_YUV422:
65 if (config->bit_depth == 8)
66 return AV_PIX_FMT_YUV422P;
67 else if (config->bit_depth == 10)
69 else if (config->bit_depth == 12)
71 else
73 break;
74 case COLOUR_FORMAT_PLANAR_YUV444_OR_RGB:
75 if (config->bit_depth == 8)
76 return AV_PIX_FMT_YUV444P;
77 else if (config->bit_depth == 10)
79 else if (config->bit_depth == 12)
81 else
83 break;
84 default:
85 av_log(logctx, AV_LOG_ERROR, "Unsupported pixel format.\n");
87 break;
88 }
89
90 return ret;
91}
92
93static int svt_jpegxs_dec_decode(AVCodecContext* avctx, AVFrame* picture, int* got_frame, AVPacket* avpkt)
94{
95 SvtJpegXsDecodeContext* svt_dec = avctx->priv_data;
96 SvtJxsErrorType_t err = SvtJxsErrorNone;
97 uint32_t frame_size;
98 int ret;
99
100 err = svt_jpeg_xs_decoder_get_single_frame_size_with_proxy(
101 avpkt->data, avpkt->size, &svt_dec->config, &frame_size, 1 /*quick search*/, svt_dec->decoder.proxy_mode);
102 if (err) {
103 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_decoder_get_single_frame_size_with_proxy failed, err=%d\n", err);
104 return AVERROR_EXTERNAL;
105 }
106 if (avpkt->size < frame_size) {
107 av_log(avctx, AV_LOG_ERROR, "Not enough data in a packet.\n");
108 return AVERROR(EINVAL);
109 }
110 if (avpkt->size > frame_size) {
111 av_log(avctx, AV_LOG_ERROR, "Single packet have data for more than one frame.\n");
112 return AVERROR(EINVAL);
113 }
114
115 ret = set_pix_fmt(avctx, &svt_dec->config);
116 if (ret < 0)
117 return ret;
118
119 if (!svt_dec->decoder_initialized || ret != avctx->pix_fmt ||
120 avctx->width != svt_dec->config.width || avctx->height != svt_dec->config.height) {
121 if (svt_dec->decoder_initialized)
122 svt_jpeg_xs_decoder_close(&svt_dec->decoder);
123 err = svt_jpeg_xs_decoder_init(SVT_JPEGXS_API_VER_MAJOR, SVT_JPEGXS_API_VER_MINOR,
124 &svt_dec->decoder, avpkt->data, avpkt->size, &svt_dec->config);
125 if (err) {
126 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_decoder_init failed, err=%d\n", err);
127 return AVERROR_EXTERNAL;
128 }
129
130 avctx->pix_fmt = ret;
131
132 ret = ff_set_dimensions(avctx, svt_dec->config.width, svt_dec->config.height);
133 if (ret < 0) {
134 av_log(avctx, AV_LOG_ERROR, "ff_set_dimensions failed, err=%d\n", ret);
135 return ret;
136 }
137
138 svt_dec->decoder_initialized = 1;
139 }
140
141 if (avctx->skip_frame == AVDISCARD_ALL)
142 return 0;
143
144 svt_dec->input.bitstream.buffer = avpkt->data;
145 svt_dec->input.bitstream.allocation_size = avpkt->size;
146 svt_dec->input.bitstream.used_size = avpkt->size;
147 svt_dec->input.user_prv_ctx_ptr = avpkt;
148
149 ret = ff_get_buffer(avctx, picture, 0);
150 if (ret < 0)
151 return ret;
152
153 unsigned pixel_shift = svt_dec->config.bit_depth <= 8 ? 0 : 1;
154 for (int comp = 0; comp < svt_dec->config.components_num; comp++) {
155 svt_dec->input.image.data_yuv[comp] = picture->data[comp];
156 svt_dec->input.image.stride[comp] = picture->linesize[comp] >> pixel_shift;
157 svt_dec->input.image.alloc_size[comp] = picture->linesize[comp] * svt_dec->config.components[comp].height;
158 }
159
160 err = svt_jpeg_xs_decoder_send_frame(&svt_dec->decoder, &svt_dec->input, 1 /*blocking*/);
161 if (err) {
162 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_decoder_send_frame failed, err=%d\n", err);
163 return AVERROR_EXTERNAL;
164 }
165
166 err = svt_jpeg_xs_decoder_get_frame(&svt_dec->decoder, &svt_dec->output, 1 /*blocking*/);
167 if (err) {
168 av_log(avctx, AV_LOG_ERROR, "svt_jpeg_xs_decoder_get_frame failed, err=%d\n", err);
169 return AVERROR_EXTERNAL;
170 }
171
172 if (svt_dec->output.user_prv_ctx_ptr != avpkt) {
173 av_log(avctx, AV_LOG_ERROR, "Returned different user_prv_ctx_ptr than expected\n");
174 return AVERROR_EXTERNAL;
175 }
176
177 *got_frame = 1;
178
179 return avpkt->size;
180}
181
183{
184 SvtJpegXsDecodeContext* svt_dec = avctx->priv_data;
185
186 svt_jpeg_xs_decoder_close(&svt_dec->decoder);
187
188 return 0;
189}
190
192{
193 SvtJpegXsDecodeContext* svt_dec = avctx->priv_data;
194
195 int log_level = av_log_get_level();
196 svt_dec->decoder.verbose = log_level < AV_LOG_DEBUG ? VERBOSE_ERRORS :
197 log_level == AV_LOG_DEBUG ? VERBOSE_SYSTEM_INFO : VERBOSE_WARNINGS;
198
199 if (avctx->lowres == 1)
200 svt_dec->decoder.proxy_mode = proxy_mode_half;
201 else if (avctx->lowres == 2)
202 svt_dec->decoder.proxy_mode = proxy_mode_quarter;
203 else
204 svt_dec->decoder.proxy_mode = proxy_mode_full;
205
206 int thread_count = avctx->thread_count ? avctx->thread_count : av_cpu_count();
207 svt_dec->decoder.threads_num = FFMIN(thread_count, 64);
208 svt_dec->decoder.use_cpu_flags = CPU_FLAGS_ALL;
209
210 return 0;
211}
212
214 .p.name = "libsvtjpegxs",
215 CODEC_LONG_NAME("SVT JPEG XS(Scalable Video Technology for JPEG XS) decoder"),
216 .p.type = AVMEDIA_TYPE_VIDEO,
217 .p.id = AV_CODEC_ID_JPEGXS,
218 .priv_data_size = sizeof(SvtJpegXsDecodeContext),
223 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
226 .p.max_lowres = 2,
227 .p.wrapper_name = "libsvtjpegxs",
228};
const FFCodec ff_libsvtjpegxs_decoder
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().
Libavcodec external API header.
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
The decoder extracts and fills its parameters even if the frame is skipped due to the skip_frame sett...
#define FF_CODEC_DECODE_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
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition decode.c:1777
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
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
static const uint8_t frame_size[4]
Definition g723_1.h:222
#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
@ AVDISCARD_ALL
discard all
Definition defs.h:232
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#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_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_log_get_level(void)
Get the current log level.
Definition log.c:471
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
misc image utilities
#define av_cold
Definition attributes.h:117
int av_cpu_count(void)
Definition cpu.c:228
static av_cold int svt_jpegxs_dec_free(AVCodecContext *avctx)
static int svt_jpegxs_dec_decode(AVCodecContext *avctx, AVFrame *picture, int *got_frame, AVPacket *avpkt)
static int set_pix_fmt(void *logctx, const svt_jpeg_xs_image_config_t *config)
static av_cold int svt_jpegxs_dec_init(AVCodecContext *avctx)
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
@ 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
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
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition avcodec.h:1702
void * priv_data
Definition avcodec.h:470
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition avcodec.h:1667
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
svt_jpeg_xs_frame_t output
svt_jpeg_xs_frame_t input
svt_jpeg_xs_decoder_api_t decoder
svt_jpeg_xs_image_config_t config
#define av_log(a,...)