PR #24860 opened by Lynne URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24860 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24860.patch
Mixed bag of changes. >From 8af0a63b378326e18f8eb244e36a98f5809ac4b0 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sun, 26 Jul 2026 13:53:42 +0800 Subject: [PATCH 1/3] avutil: add AV_PIX_FMT_XYZP12 Planar 12-bit XYZ, the natural planar layout for DCI JPEG2000 content. Also wire it into the Vulkan format table and shader format helpers. --- doc/APIchanges | 3 +++ libavutil/hwcontext_vulkan.c | 3 +++ libavutil/pixdesc.c | 24 ++++++++++++++++++++++++ libavutil/pixfmt.h | 5 +++++ libavutil/version.h | 2 +- libavutil/vulkan.c | 2 ++ tests/ref/fate/imgutils | 4 ++++ tests/ref/fate/sws-pixdesc-query | 11 +++++++++++ 8 files changed, 53 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 7d83410b6b..c7f3f7a253 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2026-06-23. API changes, most recent first: +2026-10-03 - xxxxxxxxxx - lavu 61.11.100 - pixfmt.h + Add AV_PIX_FMT_XYZP12LE, AV_PIX_FMT_XYZP12BE, and AV_PIX_FMT_XYZP12. + 2026-09-xx - xxxxxxxxxx - lavfi 12.5.100 - avfilter.h buffersrc.h buffersink.h Add AVFilterLink.chroma_location, AVBufferSrcParameters.chroma_location and av_buffersink_get_chroma_location(). diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index fab3532df9..63d2ab5c43 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -514,6 +514,9 @@ static const struct FFVkFormatEntry { { VK_FORMAT_R16_SFLOAT, AV_PIX_FMT_GBRPF16, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT, VK_FORMAT_R16_SFLOAT } }, { VK_FORMAT_R32_SFLOAT, AV_PIX_FMT_GBRPF32, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32_SFLOAT } }, + /* XYZ */ + { VK_FORMAT_R16_UNORM, AV_PIX_FMT_XYZP12, VK_IMAGE_ASPECT_COLOR_BIT, 3, 3, 3, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, + /* Planar RGB + Alpha */ { VK_FORMAT_R8_UNORM, AV_PIX_FMT_GBRAP, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM } }, { VK_FORMAT_R16_UNORM, AV_PIX_FMT_GBRAP10, VK_IMAGE_ASPECT_COLOR_BIT, 4, 4, 4, { VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM } }, diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index f1e80cb31c..c7cbfa8658 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2145,6 +2145,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_BE, }, + [AV_PIX_FMT_XYZP12LE] = { + .name = "xyzp12le", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 4, 12 }, /* X */ + { 1, 2, 0, 4, 12 }, /* Y */ + { 2, 2, 0, 4, 12 }, /* Z */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_XYZ, + }, + [AV_PIX_FMT_XYZP12BE] = { + .name = "xyzp12be", + .nb_components = 3, + .log2_chroma_w = 0, + .log2_chroma_h = 0, + .comp = { + { 0, 2, 0, 4, 12 }, /* X */ + { 1, 2, 0, 4, 12 }, /* Y */ + { 2, 2, 0, 4, 12 }, /* Z */ + }, + .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_BE, + }, #define BAYER8_DESC_COMMON \ .nb_components= 3, \ diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index b08881cc1f..750e05b644 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -505,6 +505,9 @@ enum AVPixelFormat { */ AV_PIX_FMT_CUARRAY, + AV_PIX_FMT_XYZP12LE, ///< planar XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_XYZP12BE, ///< planar XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0 + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; @@ -603,6 +606,8 @@ enum AVPixelFormat { #define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE) #define AV_PIX_FMT_XYZ12 AV_PIX_FMT_NE(XYZ12BE, XYZ12LE) +#define AV_PIX_FMT_XYZP12 AV_PIX_FMT_NE(XYZP12BE, XYZP12LE) + #define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE) #define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE) #define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE) diff --git a/libavutil/version.h b/libavutil/version.h index 1a2406e75e..edc3fa5832 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 61 -#define LIBAVUTIL_VERSION_MINOR 10 +#define LIBAVUTIL_VERSION_MINOR 11 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index fd8f939c55..3987c33080 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -1707,6 +1707,7 @@ int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt) pix_fmt == AV_PIX_FMT_X2RGB10 || pix_fmt == AV_PIX_FMT_X2BGR10 || pix_fmt == AV_PIX_FMT_RGBAF32 || pix_fmt == AV_PIX_FMT_RGBF32 || pix_fmt == AV_PIX_FMT_RGBA128 || pix_fmt == AV_PIX_FMT_RGB96 || + pix_fmt == AV_PIX_FMT_XYZP12 || pix_fmt == AV_PIX_FMT_GBRP || pix_fmt == AV_PIX_FMT_BAYER_RGGB16) return 1; return 0; @@ -1875,6 +1876,7 @@ const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt, case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: case AV_PIX_FMT_GBRPF16: + case AV_PIX_FMT_XYZP12: case AV_PIX_FMT_YUV420P10: case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV420P16: diff --git a/tests/ref/fate/imgutils b/tests/ref/fate/imgutils index ccd1522ef2..1d104b7476 100644 --- a/tests/ref/fate/imgutils +++ b/tests/ref/fate/imgutils @@ -306,6 +306,8 @@ gbrp10msbbe planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 gbrp10msble planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 gbrp12msbbe planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 gbrp12msble planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +xyzp12le planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 +xyzp12be planes: 3, linesizes: 128 128 128 0, plane_sizes: 6144 6144 6144 0, plane_offsets: 6144 6144 0, total_size: 18432 image_fill_black tests yuv420p total_size: 4608, black_unknown_crc: 0xd00f6cc6, black_tv_crc: 0xd00f6cc6, black_pc_crc: 0x234969af @@ -559,3 +561,5 @@ gbrp10msbbe total_size: 18432, black_unknown_crc: 0x00000000, black_tv_cr gbrp10msble total_size: 18432, black_unknown_crc: 0x00000000, black_tv_crc: 0x00000000, black_pc_crc: 0x00000000 gbrp12msbbe total_size: 18432, black_unknown_crc: 0x00000000, black_tv_crc: 0x00000000, black_pc_crc: 0x00000000 gbrp12msble total_size: 18432, black_unknown_crc: 0x00000000, black_tv_crc: 0x00000000, black_pc_crc: 0x00000000 +xyzp12le total_size: 18432, black_unknown_crc: 0x00000000, black_tv_crc: 0x00000000, black_pc_crc: 0x00000000 +xyzp12be total_size: 18432, black_unknown_crc: 0x00000000, black_tv_crc: 0x00000000, black_pc_crc: 0x00000000 diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query index a062088d54..92a2430ca4 100644 --- a/tests/ref/fate/sws-pixdesc-query +++ b/tests/ref/fate/sws-pixdesc-query @@ -105,6 +105,8 @@ isNBPS: xv36le xyz12be xyz12le + xyzp12be + xyzp12le y210be y210le y212be @@ -221,6 +223,7 @@ isBE: xv36be xv48be xyz12be + xyzp12be y210be y212be y216be @@ -303,6 +306,8 @@ isYUV: xv48le xyz12be xyz12le + xyzp12be + xyzp12le y210be y210le y212be @@ -419,6 +424,8 @@ isPlanarYUV: p412le p416be p416le + xyzp12be + xyzp12le yuv410p yuv411p yuv420p @@ -1035,6 +1042,8 @@ Planar: p412le p416be p416le + xyzp12be + xyzp12le yuv410p yuv411p yuv420p @@ -1241,6 +1250,8 @@ DataInHighBits: xv36le xyz12be xyz12le + xyzp12be + xyzp12le y210be y210le y212be -- 2.52.0 >From e382640440b6761a0e5cf457ff69d2bab0186042 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sun, 26 Jul 2026 13:53:52 +0800 Subject: [PATCH 2/3] swscale: treat XYZ formats as colorspace-less in color (de|en)coding XYZ formats carry no colorspace matrix; their transfer and primaries are handled by the color mapping layer, so treat them like RGB when decoding and encoding colors. --- libswscale/format.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index 631719fa8e..5484e8180c 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -1522,8 +1522,10 @@ int ff_sws_decode_colors(SwsContext *ctx, SwsPixelType type, .lin = fmt_decode_range(fmt, incomplete), })); - /* Final step, decode colorspace */ - switch (fmt->csp) { + /* Final step, decode colorspace. XYZ formats carry no colorspace + * matrix; their transfer/primaries are handled by the color mapping + * layer, so treat them like RGB here. */ + switch (fmt->desc->flags & AV_PIX_FMT_FLAG_XYZ ? AVCOL_SPC_RGB : fmt->csp) { case AVCOL_SPC_RGB: return 0; case AVCOL_SPC_UNSPECIFIED: @@ -1595,7 +1597,8 @@ int ff_sws_encode_colors(SwsContext *ctx, SwsPixelType type, if (!pixel_type) return AVERROR(ENOTSUP); - switch (dst->csp) { + /* See ff_sws_decode_colors(): XYZ formats have no colorspace matrix */ + switch (dst->desc->flags & AV_PIX_FMT_FLAG_XYZ ? AVCOL_SPC_RGB : dst->csp) { case AVCOL_SPC_RGB: break; case AVCOL_SPC_UNSPECIFIED: -- 2.52.0 >From c0c3c7298353843497ceec877c74a16054a118f0 Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sun, 26 Jul 2026 13:55:17 +0800 Subject: [PATCH 3/3] jpeg2000dec: convert the decoder to the receive_frame API Convert the decoder to the receive_frame API (one codestream per packet; skipped frames pull the next packet instead of returning empty-handed), finish threading setup before the tile decode, and do not leave a partially initialized frame on the output on error. Move the tag-tree size, exp2fi and band stepsize helpers into the shared header as ff_-prefixed inlines so code outside jpeg2000.c can derive the same geometry and quantization parameters. Co-Authored-By: Claude Fable 5 <[email protected]> --- libavcodec/jpeg2000.c | 89 ++++++++++++++++++---------------------- libavcodec/jpeg2000.h | 36 ++++++++++++++++ libavcodec/jpeg2000dec.c | 40 ++++++++++++++---- 3 files changed, 108 insertions(+), 57 deletions(-) diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 6433e13892..a21f9c2a82 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -39,18 +39,6 @@ /* tag tree routines */ -static int32_t tag_tree_size(int w, int h) -{ - int64_t res = 0; - while (w > 1 || h > 1) { - res += w * (int64_t)h; - av_assert0(res + 1 < INT32_MAX); - w = (w + 1) >> 1; - h = (h + 1) >> 1; - } - return (int32_t)(res + 1); -} - /* allocate the memory for tag tree */ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) { @@ -58,7 +46,7 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) Jpeg2000TgtNode *res, *t, *t2; int32_t tt_size; - tt_size = tag_tree_size(w, h); + tt_size = ff_jpeg2000_tag_tree_size(w, h); t = res = av_calloc(tt_size, sizeof(*t)); if (!res) @@ -85,7 +73,7 @@ static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h) void ff_tag_tree_zero(Jpeg2000TgtNode *t, int w, int h, int val) { - int i, siz = tag_tree_size(w, h); + int i, siz = ff_jpeg2000_tag_tree_size(w, h); for (i = 0; i < siz; i++) { t[i].val = val; @@ -199,33 +187,22 @@ void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1, int x, int y, t1->flags[(y - 1) * t1->stride + x - 1] |= JPEG2000_T1_SIG_SE; } +/* TODO: Implementation of quantization step not finished, see + * ISO/IEC 15444-1:2002 E.1 and A.6.4. */ // static const uint8_t lut_gain[2][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 2 } }; (unused) - -/** - * 2^(x) for integer x in the range -126..128. - * @return correctly rounded float - */ -static av_always_inline float exp2fi(int x) +float ff_jpeg2000_band_stepsize(AVCodecContext *avctx, + Jpeg2000CodingStyle *codsty, + Jpeg2000QuantStyle *qntsty, + int bandno, int gbandno, + int reslevelno, int cbps) { - av_assert2(-126 <= x && x <= 128); - /* Normal range */ - return av_int2float((x+127) << 23); -} + float fss; -static void init_band_stepsize(AVCodecContext *avctx, - Jpeg2000Band *band, - Jpeg2000CodingStyle *codsty, - Jpeg2000QuantStyle *qntsty, - int bandno, int gbandno, int reslevelno, - int cbps) -{ - /* TODO: Implementation of quantization step not finished, - * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */ switch (qntsty->quantsty) { uint8_t gain; case JPEG2000_QSTY_NONE: /* TODO: to verify. No quantization in this case */ - band->f_stepsize = 1; + fss = 1; break; case JPEG2000_QSTY_SI: /*TODO: Compute formula to implement. */ @@ -240,35 +217,47 @@ static void init_band_stepsize(AVCodecContext *avctx, * delta_b = 2 ^ (R_b - expn_b) * (1 + (mant_b / 2 ^ 11)) * R_b = R_I + log2 (gain_b ) * see ISO/IEC 15444-1:2002 E.1.1 eqn. E-3 and E-4 */ - gain = cbps; - band->f_stepsize = exp2fi(gain - qntsty->expn[gbandno]); - band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0; + gain = cbps; + fss = ff_jpeg2000_exp2fi(gain - qntsty->expn[gbandno]); + fss *= qntsty->mant[gbandno] / 2048.0 + 1.0; break; default: - band->f_stepsize = 0; av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n"); - break; + return 0; } if (codsty->transform != FF_DWT53) { int lband = 0; switch (bandno + (reslevelno > 0)) { - case 1: - case 2: - band->f_stepsize *= F_LFTG_X * 2; - lband = 1; - break; - case 3: - band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4; - break; + case 1: + case 2: + fss *= F_LFTG_X * 2; + lband = 1; + break; + case 3: + fss *= F_LFTG_X * F_LFTG_X * 4; + break; } - band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2); + fss *= pow(F_LFTG_K, 2 * (codsty->nreslevels2decode - reslevelno) + + lband - 2); } - if (band->f_stepsize > (INT_MAX >> 15)) { - band->f_stepsize = 0; + if (fss > (INT_MAX >> 15)) { av_log(avctx, AV_LOG_ERROR, "stepsize out of range\n"); + return 0; } + return fss; +} +static void init_band_stepsize(AVCodecContext *avctx, + Jpeg2000Band *band, + Jpeg2000CodingStyle *codsty, + Jpeg2000QuantStyle *qntsty, + int bandno, int gbandno, int reslevelno, + int cbps) +{ + band->f_stepsize = ff_jpeg2000_band_stepsize(avctx, codsty, qntsty, + bandno, gbandno, reslevelno, + cbps); band->i_stepsize = (int)floorf(band->f_stepsize * (1 << 15)); } diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h index 93221d90ca..52c00f4268 100644 --- a/libavcodec/jpeg2000.h +++ b/libavcodec/jpeg2000.h @@ -31,6 +31,9 @@ #include <stdint.h> +#include "libavutil/avassert.h" +#include "libavutil/intfloat.h" + #include "avcodec.h" #include "mqc.h" #include "jpeg2000dwt.h" @@ -289,6 +292,39 @@ static inline int ff_jpeg2000_getsgnctxno(int flag, int *xorbit) return ff_jpeg2000_sgnctxno_lut[flag & 15][(flag >> 8) & 15]; } +/* Node count of the tag-tree pyramid over a (w, h) leaf grid. */ +static inline int32_t ff_jpeg2000_tag_tree_size(int w, int h) +{ + int64_t res = 0; + while (w > 1 || h > 1) { + res += w * (int64_t)h; + av_assert0(res + 1 < INT32_MAX); + w = (w + 1) >> 1; + h = (h + 1) >> 1; + } + return (int32_t)(res + 1); +} + +/** + * 2^(x) for integer x in the range -126..128. + * @return correctly rounded float + */ +static av_always_inline float ff_jpeg2000_exp2fi(int x) +{ + av_assert2(-126 <= x && x <= 128); + /* Normal range */ + return av_int2float((x + 127) << 23); +} + +/* Band dequantization step size (ISO/IEC 15444-1:2002 E.1), shared between + * the software decoder's band setup and the Vulkan hwaccel's inline + * geometry. */ +float ff_jpeg2000_band_stepsize(AVCodecContext *avctx, + Jpeg2000CodingStyle *codsty, + Jpeg2000QuantStyle *qntsty, + int bandno, int gbandno, + int reslevelno, int cbps); + int ff_jpeg2000_init_component(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty, Jpeg2000QuantStyle *qntsty, diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 369377e4fc..870678f0b0 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -39,6 +39,7 @@ #include "bytestream.h" #include "codec_internal.h" #include "decode.h" +#include "internal.h" #include "thread.h" #include "jpeg2000.h" #include "jpeg2000dsp.h" @@ -2855,7 +2856,7 @@ static av_cold int jpeg2000_decode_init(AVCodecContext *avctx) } static int jpeg2000_decode_frame(AVCodecContext *avctx, AVFrame *picture, - int *got_frame, AVPacket *avpkt) + const AVPacket *avpkt) { Jpeg2000DecoderContext *s = avctx->priv_data; int ret; @@ -2902,7 +2903,7 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, AVFrame *picture, if (avctx->skip_frame >= AVDISCARD_ALL) { jpeg2000_dec_cleanup(s); - return avpkt->size; + return 0; } /* get picture buffer */ @@ -2916,22 +2917,47 @@ static int jpeg2000_decode_frame(AVCodecContext *avctx, AVFrame *picture, if (++x == s->ncomponents) picture->flags |= AV_FRAME_FLAG_LOSSLESS; - avctx->execute2(avctx, jpeg2000_decode_tile, picture, NULL, s->numXtiles * s->numYtiles); + ff_thread_finish_setup(avctx); + + avctx->execute2(avctx, jpeg2000_decode_tile, picture, NULL, + s->numXtiles * s->numYtiles); jpeg2000_dec_cleanup(s); - *got_frame = 1; - if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t)); - return bytestream2_tell(&s->g); + return 0; end: + /* Do not leave a partially initialized frame on the output. */ + av_frame_unref(picture); jpeg2000_dec_cleanup(s); return ret; } +static int jpeg2000_receive_frame(AVCodecContext *avctx, AVFrame *frame) +{ + AVPacket *const avpkt = avctx->internal->in_pkt; + int ret; + + /* One codestream per packet. Loop so that skipped frames (produce no + * output) transparently pull the next packet instead of returning to the + * caller empty-handed. */ + do { + ret = ff_decode_get_packet(avctx, avpkt); + if (ret < 0) + return ret; + + ret = jpeg2000_decode_frame(avctx, frame, avpkt); + av_packet_unref(avpkt); + if (ret < 0) + return ret; + } while (!frame->buf[0]); + + return 0; +} + #define OFFSET(x) offsetof(Jpeg2000DecoderContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM @@ -2956,7 +2982,7 @@ const FFCodec ff_jpeg2000_decoder = { .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1, .priv_data_size = sizeof(Jpeg2000DecoderContext), .init = jpeg2000_decode_init, - FF_CODEC_DECODE_CB(jpeg2000_decode_frame), + FF_CODEC_RECEIVE_FRAME_CB(jpeg2000_receive_frame), .p.priv_class = &jpeg2000_class, .p.max_lowres = 5, .p.profiles = NULL_IF_CONFIG_SMALL(ff_jpeg2000_profiles), -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
