* [FFmpeg-devel] [PATCH 1/3] avutil/pixfmt: add YAF16 and YAF32 pixel formats
@ 2025-03-05 20:44 James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 2/3] swscale/input: add support for YAF16 and YAF32 James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats James Almer
0 siblings, 2 replies; 7+ messages in thread
From: James Almer @ 2025-03-05 20:44 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/pixdesc.c | 44 ++++++++++++++++++++++++++++++++
libavutil/pixfmt.h | 9 +++++++
tests/ref/fate/imgutils | 8 ++++++
tests/ref/fate/sws-pixdesc-query | 20 +++++++++++++++
4 files changed, 81 insertions(+)
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 7ffc8f3b2e..1917ae74d8 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -2543,6 +2543,50 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
},
.flags = AV_PIX_FMT_FLAG_FLOAT,
},
+ [AV_PIX_FMT_YAF32BE] = {
+ .name = "yaf32be",
+ .nb_components = 2,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 8, 0, 0, 32 }, /* Y */
+ { 0, 8, 4, 0, 32 }, /* A */
+ },
+ .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_ALPHA,
+ },
+ [AV_PIX_FMT_YAF32LE] = {
+ .name = "yaf32le",
+ .nb_components = 2,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 8, 0, 0, 32 }, /* Y */
+ { 0, 8, 4, 0, 32 }, /* A */
+ },
+ .flags = AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_ALPHA,
+ },
+ [AV_PIX_FMT_YAF16BE] = {
+ .name = "yaf16be",
+ .nb_components = 2,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 4, 0, 0, 16 }, /* Y */
+ { 0, 4, 2, 0, 16 }, /* A */
+ },
+ .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_ALPHA,
+ },
+ [AV_PIX_FMT_YAF16LE] = {
+ .name = "yaf16le",
+ .nb_components = 2,
+ .log2_chroma_w = 0,
+ .log2_chroma_h = 0,
+ .comp = {
+ { 0, 4, 0, 0, 16 }, /* Y */
+ { 0, 4, 2, 0, 16 }, /* A */
+ },
+ .flags = AV_PIX_FMT_FLAG_FLOAT | AV_PIX_FMT_FLAG_ALPHA,
+ },
[AV_PIX_FMT_YUVA422P12BE] = {
.name = "yuva422p12be",
.nb_components = 4,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index ca1b22762b..6f343cb026 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -479,6 +479,12 @@ enum AVPixelFormat {
AV_PIX_FMT_GRAY32BE, ///< Y , 32bpp, big-endian
AV_PIX_FMT_GRAY32LE, ///< Y , 32bpp, little-endian
+ AV_PIX_FMT_YAF32BE, ///< IEEE-754 half precision packed YA, 32 bits gray, 32 bits alpha, 64bpp, big-endian
+ AV_PIX_FMT_YAF32LE, ///< IEEE-754 half precision packed YA, 32 bits gray, 32 bits alpha, 64bpp, little-endian
+
+ AV_PIX_FMT_YAF16BE, ///< IEEE-754 half precision packed YA, 16 bits gray, 16 bits alpha, 32bpp, big-endian
+ AV_PIX_FMT_YAF16LE, ///< IEEE-754 half precision packed YA, 16 bits gray, 16 bits alpha, 32bpp, little-endian
+
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
};
@@ -554,6 +560,9 @@ enum AVPixelFormat {
#define AV_PIX_FMT_GRAYF16 AV_PIX_FMT_NE(GRAYF16BE, GRAYF16LE)
#define AV_PIX_FMT_GRAYF32 AV_PIX_FMT_NE(GRAYF32BE, GRAYF32LE)
+#define AV_PIX_FMT_YAF16 AV_PIX_FMT_NE(YAF16BE, YAF16LE)
+#define AV_PIX_FMT_YAF32 AV_PIX_FMT_NE(YAF32BE, YAF32LE)
+
#define AV_PIX_FMT_YUVA420P9 AV_PIX_FMT_NE(YUVA420P9BE , YUVA420P9LE)
#define AV_PIX_FMT_YUVA422P9 AV_PIX_FMT_NE(YUVA422P9BE , YUVA422P9LE)
#define AV_PIX_FMT_YUVA444P9 AV_PIX_FMT_NE(YUVA444P9BE , YUVA444P9LE)
diff --git a/tests/ref/fate/imgutils b/tests/ref/fate/imgutils
index 0951bab161..79e31e80ac 100644
--- a/tests/ref/fate/imgutils
+++ b/tests/ref/fate/imgutils
@@ -292,6 +292,10 @@ grayf16be planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0
grayf16le planes: 1, linesizes: 128 0 0 0, plane_sizes: 6144 0 0 0, plane_offsets: 0 0 0, total_size: 6144
gray32be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288
gray32le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288
+yaf32be planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576
+yaf32le planes: 1, linesizes: 512 0 0 0, plane_sizes: 24576 0 0 0, plane_offsets: 0 0 0, total_size: 24576
+yaf16be planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288
+yaf16le planes: 1, linesizes: 256 0 0 0, plane_sizes: 12288 0 0 0, plane_offsets: 0 0 0, total_size: 12288
image_fill_black tests
yuv420p total_size: 4608, black_unknown_crc: 0xd00f6cc6, black_tv_crc: 0xd00f6cc6, black_pc_crc: 0x234969af
@@ -531,3 +535,7 @@ grayf16be total_size: 6144, black_unknown_crc: 0x72aa7ce2, black_tv_cr
grayf16le total_size: 6144, black_unknown_crc: 0xad1b67c6, black_tv_crc: 0xad1b67c6, black_pc_crc: 0x00000000
gray32be total_size: 12288, black_unknown_crc: 0x52baa2c6, black_tv_crc: 0x52baa2c6, black_pc_crc: 0x00000000
gray32le total_size: 12288, black_unknown_crc: 0xc72f7e60, black_tv_crc: 0xc72f7e60, black_pc_crc: 0x00000000
+yaf32be total_size: 24576, black_unknown_crc: 0xa3dc1529, black_tv_crc: 0xa3dc1529, black_pc_crc: 0x0bbcb13e
+yaf32le total_size: 24576, black_unknown_crc: 0xfd900236, black_tv_crc: 0xfd900236, black_pc_crc: 0xdcaf0cb1
+yaf16be total_size: 12288, black_unknown_crc: 0x7afe9aae, black_tv_crc: 0x7afe9aae, black_pc_crc: 0x0fc0a5d0
+yaf16le total_size: 12288, black_unknown_crc: 0x94c0068b, black_tv_crc: 0x94c0068b, black_pc_crc: 0xc05ce449
diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query
index 9a1d0d4b52..426794b7f2 100644
--- a/tests/ref/fate/sws-pixdesc-query
+++ b/tests/ref/fate/sws-pixdesc-query
@@ -37,6 +37,8 @@ is16BPS:
y216le
ya16be
ya16le
+ yaf16be
+ yaf16le
yuv420p16be
yuv420p16le
yuv422p16be
@@ -212,6 +214,8 @@ isBE:
y212be
y216be
ya16be
+ yaf16be
+ yaf32be
yuv420p10be
yuv420p12be
yuv420p14be
@@ -295,6 +299,10 @@ isYUV:
ya16be
ya16le
ya8
+ yaf16be
+ yaf16le
+ yaf32be
+ yaf32le
yuv410p
yuv411p
yuv420p
@@ -607,6 +615,10 @@ Gray:
ya16be
ya16le
ya8
+ yaf16be
+ yaf16le
+ yaf32be
+ yaf32le
RGBinInt:
monob
@@ -795,6 +807,10 @@ ALPHA:
ya16be
ya16le
ya8
+ yaf16be
+ yaf16le
+ yaf32be
+ yaf32le
yuva420p
yuva420p10be
yuva420p10le
@@ -917,6 +933,10 @@ Packed:
ya16be
ya16le
ya8
+ yaf16be
+ yaf16le
+ yaf32be
+ yaf32le
yuyv422
yvyu422
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 2/3] swscale/input: add support for YAF16 and YAF32
2025-03-05 20:44 [FFmpeg-devel] [PATCH 1/3] avutil/pixfmt: add YAF16 and YAF32 pixel formats James Almer
@ 2025-03-05 20:44 ` James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats James Almer
1 sibling, 0 replies; 7+ messages in thread
From: James Almer @ 2025-03-05 20:44 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libswscale/input.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
libswscale/utils.c | 4 +++
2 files changed, 93 insertions(+)
diff --git a/libswscale/input.c b/libswscale/input.c
index d6b319f25f..dfa8ed15ab 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -1283,6 +1283,28 @@ static av_always_inline void grayf32ToY16_c(uint8_t *_dst, const uint8_t *_src,
}
}
+static av_always_inline void read_yaf32_gray_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1,
+ const uint8_t *unused2, int width, int is_be, uint32_t *unused)
+{
+ int i;
+ const float *src = (const float *)_src;
+ uint16_t *dst = (uint16_t *)_dst;
+
+ for (i = 0; i < width; ++i)
+ dst[i] = lrintf(av_clipf(65535.0f * rdpx(src + i*2), 0.0f, 65535.0f));
+}
+
+static av_always_inline void read_yaf32_alpha_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1,
+ const uint8_t *unused2, int width, int is_be, uint32_t *unused)
+{
+ int i;
+ const float *src = (const float *)_src;
+ uint16_t *dst = (uint16_t *)_dst;
+
+ for (i = 0; i < width; ++i)
+ dst[i] = lrintf(av_clipf(65535.0f * rdpx(src + i*2 + 1), 0.0f, 65535.0f));
+}
+
#undef rdpx
#define rgb9plus_planar_funcs_endian(nbits, endian_name, endian) \
@@ -1363,6 +1385,18 @@ static void grayf32##endian_name##ToY16_c(uint8_t *dst, const uint8_t *src,
int width, uint32_t *unused, void *opq) \
{ \
grayf32ToY16_c(dst, src, unused1, unused2, width, endian, unused); \
+} \
+static void read_yaf32##endian_name##_gray_c(uint8_t *dst, const uint8_t *src, \
+ const uint8_t *unused1, const uint8_t *unused2, \
+ int width, uint32_t *unused, void *opq) \
+{ \
+ read_yaf32_gray_c(dst, src, unused1, unused2, width, endian, unused); \
+} \
+static void read_yaf32##endian_name##_alpha_c(uint8_t *dst, const uint8_t *src, \
+ const uint8_t *unused1, const uint8_t *unused2, \
+ int width, uint32_t *unused, void *opq) \
+{ \
+ read_yaf32_alpha_c(dst, src, unused1, unused2, width, endian, unused); \
}
rgbf32_funcs_endian(le, 0)
@@ -1421,6 +1455,24 @@ static av_always_inline void grayf16ToY16_c(uint8_t *dst, const uint8_t *src, co
}
}
+static av_always_inline void read_yaf16_gray_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1,
+ const uint8_t *unused2, int width, int is_be, uint32_t *unused, Half2FloatTables *h2f_tbl)
+{
+ int i;
+
+ for (i = 0; i < width; i++)
+ AV_WN16(dst + 2*i, lrintf(av_clipf(65535.0f * rdpx2(src + 4*i), 0.0f, 65535.0f)));
+}
+
+static av_always_inline void read_yaf16_alpha_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1,
+ const uint8_t *unused2, int width, int is_be, uint32_t *unused, Half2FloatTables *h2f_tbl)
+{
+ int i;
+
+ for (i = 0; i < width; i++)
+ AV_WN16(dst + 2*i, lrintf(av_clipf(65535.0f * rdpx2(src + 4*i + 2), 0.0f, 65535.0f)));
+}
+
static av_always_inline void rgbaf16ToUV_half_endian(uint16_t *dstU, uint16_t *dstV, int is_be,
const uint16_t *src, int width,
int32_t *rgb2yuv, Half2FloatTables *h2f_tbl)
@@ -1557,6 +1609,19 @@ static void grayf16##endian_name##ToY16_c(uint8_t *dst, const uint8_t *src,
{ \
grayf16ToY16_c(dst, src, unused1, unused2, width, endian, unused, opq); \
} \
+static void read_yaf16##endian_name##_gray_c(uint8_t *dst, const uint8_t *src, \
+ const uint8_t *unused1, const uint8_t *unused2, \
+ int width, uint32_t *unused, void *opq) \
+{ \
+ read_yaf16_gray_c(dst, src, unused1, unused2, width, endian, unused, opq); \
+} \
+static void read_yaf16##endian_name##_alpha_c(uint8_t *dst, const uint8_t *src, \
+ const uint8_t *unused1, const uint8_t *unused2, \
+ int width, uint32_t *unused, void *opq) \
+{ \
+ read_yaf16_alpha_c(dst, src, unused1, unused2, width, endian, unused, opq); \
+} \
+ \
static void rgbaf16##endian_name##ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused, \
const uint8_t *src1, const uint8_t *src2, \
int width, uint32_t *_rgb2yuv, void *opq) \
@@ -2244,6 +2309,12 @@ av_cold void ff_sws_init_input_funcs(SwsInternal *c,
case AV_PIX_FMT_YA16BE:
*lumToYV12 = read_ya16be_gray_c;
break;
+ case AV_PIX_FMT_YAF16LE:
+ *lumToYV12 = read_yaf16le_gray_c;
+ break;
+ case AV_PIX_FMT_YAF16BE:
+ *lumToYV12 = read_yaf16be_gray_c;
+ break;
case AV_PIX_FMT_VUYA:
case AV_PIX_FMT_VUYX:
*lumToYV12 = read_vuyx_Y_c;
@@ -2400,6 +2471,12 @@ av_cold void ff_sws_init_input_funcs(SwsInternal *c,
case AV_PIX_FMT_GRAYF32BE:
*lumToYV12 = grayf32beToY16_c;
break;
+ case AV_PIX_FMT_YAF32LE:
+ *lumToYV12 = read_yaf32le_gray_c;
+ break;
+ case AV_PIX_FMT_YAF32BE:
+ *lumToYV12 = read_yaf32be_gray_c;
+ break;
case AV_PIX_FMT_GRAYF16LE:
*lumToYV12 = grayf16leToY16_c;
break;
@@ -2473,6 +2550,18 @@ av_cold void ff_sws_init_input_funcs(SwsInternal *c,
case AV_PIX_FMT_YA16BE:
*alpToYV12 = read_ya16be_alpha_c;
break;
+ case AV_PIX_FMT_YAF16LE:
+ *alpToYV12 = read_yaf16le_alpha_c;
+ break;
+ case AV_PIX_FMT_YAF16BE:
+ *alpToYV12 = read_yaf16be_alpha_c;
+ break;
+ case AV_PIX_FMT_YAF32LE:
+ *alpToYV12 = read_yaf32le_alpha_c;
+ break;
+ case AV_PIX_FMT_YAF32BE:
+ *alpToYV12 = read_yaf32be_alpha_c;
+ break;
case AV_PIX_FMT_VUYA:
case AV_PIX_FMT_UYVA:
*alpToYV12 = read_vuya_A_c;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index c2fbaf5515..953bf015e4 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -252,6 +252,10 @@ static const FormatEntry format_entries[] = {
[AV_PIX_FMT_GRAYF32BE] = { 1, 1 },
[AV_PIX_FMT_GRAYF16LE] = { 1, 0 },
[AV_PIX_FMT_GRAYF16BE] = { 1, 0 },
+ [AV_PIX_FMT_YAF32LE] = { 1, 0 },
+ [AV_PIX_FMT_YAF32BE] = { 1, 0 },
+ [AV_PIX_FMT_YAF16LE] = { 1, 0 },
+ [AV_PIX_FMT_YAF16BE] = { 1, 0 },
[AV_PIX_FMT_YUVA422P12BE] = { 1, 1 },
[AV_PIX_FMT_YUVA422P12LE] = { 1, 1 },
[AV_PIX_FMT_YUVA444P12BE] = { 1, 1 },
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats
2025-03-05 20:44 [FFmpeg-devel] [PATCH 1/3] avutil/pixfmt: add YAF16 and YAF32 pixel formats James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 2/3] swscale/input: add support for YAF16 and YAF32 James Almer
@ 2025-03-05 20:44 ` James Almer
2025-03-05 21:33 ` [FFmpeg-devel] [PATCH v2 " James Almer
2025-03-06 13:21 ` [FFmpeg-devel] [PATCH v3 " James Almer
1 sibling, 2 replies; 7+ messages in thread
From: James Almer @ 2025-03-05 20:44 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/exr.c | 71 +++++++-------------
tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 2 +-
2 files changed, 26 insertions(+), 47 deletions(-)
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 3eed4b3c87..312d8fd6e1 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1353,82 +1353,67 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
data_yoffset = FFABS(FFMIN(0, line));
data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
+ if (s->channel_offsets[3] >= 0)
+ channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
if (!s->is_luma) {
channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
rgb_channel_count = 3;
- } else { /* put y data in the first channel_buffer */
+ } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
+ if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
+ channel_buffer[1] = channel_buffer[3];
rgb_channel_count = 1;
}
- if (s->channel_offsets[3] >= 0)
- channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
- if (s->is_luma) {
- channel_buffer[1] = channel_buffer[0];
- channel_buffer[2] = channel_buffer[0];
- }
-
- for (c = 0; c < channel_count; c++) {
+ if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
+ for (c = 0; c < s->desc->nb_components; c++) {
int plane = s->desc->comp[c].plane;
- ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);
+ ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
- const uint8_t *src;
+ const uint8_t *src = channel_buffer[c];
+
+ // Zero out the start if xmin is not 0
+ if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
+ memset(ptr, 0, bxmin);
if (s->pixel_type == EXR_FLOAT ||
s->compression == EXR_DWAA ||
s->compression == EXR_DWAB) {
// 32-bit
- union av_intfloat32 *ptr_x;
-
- src = channel_buffer[c];
- ptr_x = (union av_intfloat32 *)ptr;
-
- // Zero out the start if xmin is not 0
- memset(ptr_x, 0, bxmin);
- ptr_x += window_xoffset;
-
union av_intfloat32 t;
+
if (trc_func && c < 3) {
- for (x = 0; x < xsize; x++) {
+ for (x = window_xoffset; x < xsize + window_xoffset; x++) {
t.i = bytestream_get_le32(&src);
t.f = trc_func(t.f);
- *ptr_x++ = t;
+ AV_WN32(ptr + x * step, t.i);
}
} else if (one_gamma != 1.f) {
- for (x = 0; x < xsize; x++) {
+ for (x = window_xoffset; x < xsize + window_xoffset; x++) {
t.i = bytestream_get_le32(&src);
if (t.f > 0.0f && c < 3) /* avoid negative values */
t.f = powf(t.f, one_gamma);
- *ptr_x++ = t;
+ AV_WN32(ptr + x * step, t.i);
}
} else {
- for (x = 0; x < xsize; x++) {
+ for (x = window_xoffset; x < xsize + window_xoffset; x++) {
t.i = bytestream_get_le32(&src);
- *ptr_x++ = t;
+ AV_WN32(ptr + x * step, t.i);
}
}
- memset(ptr_x, 0, axmax);
} else if (s->pixel_type == EXR_HALF) {
- src = channel_buffer[c];
-
- // Zero out the start if xmin is not 0
- memset(ptr, 0, bxmin);
-
// 16-bit
for (x = window_xoffset; x < xsize + window_xoffset; x++) {
int v = bytestream_get_le16(&src);
- AV_WN16(ptr + x * sizeof(uint16_t), v);
+ AV_WN16(ptr + x * step, v);
}
- memset(ptr + x * sizeof(uint16_t), 0, axmax);
}
// Zero out the end if xmax+1 is not w
+ memset(ptr + x * step, 0, axmax);
channel_buffer[c] += td->channel_line_size;
}
}
@@ -2060,8 +2045,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
+ avctx->pix_fmt = AV_PIX_FMT_YAF16;
}
} else {
if (!s->is_luma) {
@@ -2077,8 +2061,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
+ avctx->pix_fmt = AV_PIX_FMT_YAF32;
}
} else {
if (!s->is_luma) {
@@ -2157,11 +2140,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->desc)
return AVERROR_INVALIDDATA;
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
- planes = s->desc->nb_components;
- } else {
- planes = 1;
- }
+ planes = av_pix_fmt_count_planes(avctx->pix_fmt);
out_line_size = avctx->width * s->desc->comp[0].step;
if (s->is_tile) {
diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
index 97ea715962..6c07f19846 100644
--- a/tests/ref/fate/exr-ya-scanline-zip-half-12x8
+++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 12x8
#sar 0: 1/1
-0, 0, 0, 1, 1536, 0x2b457bd2
+0, 0, 0, 1, 1536, 0xa33f5f69
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH v2 3/3] avcodec/exr: use luma+alpha float pixel formats
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats James Almer
@ 2025-03-05 21:33 ` James Almer
2025-03-05 21:41 ` Andreas Rheinhardt
2025-03-06 13:21 ` [FFmpeg-devel] [PATCH v3 " James Almer
1 sibling, 1 reply; 7+ messages in thread
From: James Almer @ 2025-03-05 21:33 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
Updated for the latest git master changes.
libavcodec/exr.c | 55 ++++++++------------
tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 2 +-
2 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index b25e9ef397..fe5f62c3b5 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1352,33 +1352,32 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
data_yoffset = FFABS(FFMIN(0, line));
data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
+ if (s->channel_offsets[3] >= 0)
+ channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
if (!s->is_luma) {
channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
rgb_channel_count = 3;
- } else { /* put y data in the first channel_buffer */
+ } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
+ if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
+ channel_buffer[1] = channel_buffer[3];
rgb_channel_count = 1;
}
- if (s->channel_offsets[3] >= 0)
- channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
-
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
- if (s->is_luma) {
- channel_buffer[1] = channel_buffer[0];
- channel_buffer[2] = channel_buffer[0];
- }
- for (c = 0; c < channel_count; c++) {
+ if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
+ for (c = 0; c < s->desc->nb_components; c++) {
int plane = s->desc->comp[c].plane;
- ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);
+ ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
const uint8_t *src;
+ // Zero out the start if xmin is not 0
+ if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
+ memset(ptr, 0, bxmin);
+
if (s->pixel_type == EXR_FLOAT ||
s->compression == EXR_DWAA ||
s->compression == EXR_DWAB) {
@@ -1387,42 +1386,36 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
src = channel_buffer[c];
- // Zero out the start if xmin is not 0
- memset(ptr_x, 0, bxmin);
- ptr_x += 4 * window_xoffset;
+ ptr_x += window_xoffset * step;
if (trc_func && c < 3) {
- for (int x = 0; x < xsize; x++, ptr_x += 4) {
+ for (x = 0; x < xsize; x++, ptr_x += step) {
float f = av_int2float(bytestream_get_le32(&src));
AV_WN32A(ptr_x, av_float2int(trc_func(f)));
}
} else if (one_gamma != 1.f) {
- for (int x = 0; x < xsize; x++, ptr_x += 4) {
+ for (x = 0; x < xsize; x++, ptr_x += step) {
float f = av_int2float(bytestream_get_le32(&src));
if (f > 0.0f && c < 3) /* avoid negative values */
f = powf(f, one_gamma);
AV_WN32A(ptr_x, av_float2int(f));
}
} else {
- for (int x = 0; x < xsize; x++, ptr_x += 4)
+ for (x = 0; x < xsize; x++, ptr_x += step)
AV_WN32A(ptr_x, bytestream_get_le32(&src));
}
- memset(ptr_x, 0, axmax);
} else if (s->pixel_type == EXR_HALF) {
src = channel_buffer[c];
- // Zero out the start if xmin is not 0
- memset(ptr, 0, bxmin);
-
// 16-bit
for (x = window_xoffset; x < xsize + window_xoffset; x++) {
int v = bytestream_get_le16(&src);
- AV_WN16(ptr + x * sizeof(uint16_t), v);
+ AV_WN16(ptr + x * step, v);
}
- memset(ptr + x * sizeof(uint16_t), 0, axmax);
}
// Zero out the end if xmax+1 is not w
+ memset(ptr + x * step, 0, axmax);
channel_buffer[c] += td->channel_line_size;
}
}
@@ -2054,8 +2047,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
+ avctx->pix_fmt = AV_PIX_FMT_YAF16;
}
} else {
if (!s->is_luma) {
@@ -2071,8 +2063,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
+ avctx->pix_fmt = AV_PIX_FMT_YAF32;
}
} else {
if (!s->is_luma) {
@@ -2151,11 +2142,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->desc)
return AVERROR_INVALIDDATA;
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
- planes = s->desc->nb_components;
- } else {
- planes = 1;
- }
+ planes = av_pix_fmt_count_planes(avctx->pix_fmt);
out_line_size = avctx->width * s->desc->comp[0].step;
if (s->is_tile) {
diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
index 97ea715962..6c07f19846 100644
--- a/tests/ref/fate/exr-ya-scanline-zip-half-12x8
+++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 12x8
#sar 0: 1/1
-0, 0, 0, 1, 1536, 0x2b457bd2
+0, 0, 0, 1, 1536, 0xa33f5f69
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 3/3] avcodec/exr: use luma+alpha float pixel formats
2025-03-05 21:33 ` [FFmpeg-devel] [PATCH v2 " James Almer
@ 2025-03-05 21:41 ` Andreas Rheinhardt
2025-03-05 22:03 ` James Almer
0 siblings, 1 reply; 7+ messages in thread
From: Andreas Rheinhardt @ 2025-03-05 21:41 UTC (permalink / raw)
To: ffmpeg-devel
James Almer:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> Updated for the latest git master changes.
>
> libavcodec/exr.c | 55 ++++++++------------
> tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 2 +-
> 2 files changed, 22 insertions(+), 35 deletions(-)
>
> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
> index b25e9ef397..fe5f62c3b5 100644
> --- a/libavcodec/exr.c
> +++ b/libavcodec/exr.c
> @@ -1352,33 +1352,32 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
> data_yoffset = FFABS(FFMIN(0, line));
> data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
>
> + if (s->channel_offsets[3] >= 0)
> + channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
> if (!s->is_luma) {
> channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
> channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
> channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
> rgb_channel_count = 3;
> - } else { /* put y data in the first channel_buffer */
> + } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
> channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
> + if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
> + channel_buffer[1] = channel_buffer[3];
> rgb_channel_count = 1;
> }
> - if (s->channel_offsets[3] >= 0)
> - channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
> -
> - if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {
> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
> - int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
> - if (s->is_luma) {
> - channel_buffer[1] = channel_buffer[0];
> - channel_buffer[2] = channel_buffer[0];
> - }
>
> - for (c = 0; c < channel_count; c++) {
> + if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
> + for (c = 0; c < s->desc->nb_components; c++) {
> int plane = s->desc->comp[c].plane;
> - ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);
> + ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
>
> for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
> const uint8_t *src;
>
> + // Zero out the start if xmin is not 0
> + if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
> + memset(ptr, 0, bxmin);
> +
> if (s->pixel_type == EXR_FLOAT ||
> s->compression == EXR_DWAA ||
> s->compression == EXR_DWAB) {
> @@ -1387,42 +1386,36 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
>
> src = channel_buffer[c];
>
> - // Zero out the start if xmin is not 0
> - memset(ptr_x, 0, bxmin);
> - ptr_x += 4 * window_xoffset;
> + ptr_x += window_xoffset * step;
>
> if (trc_func && c < 3) {
> - for (int x = 0; x < xsize; x++, ptr_x += 4) {
> + for (x = 0; x < xsize; x++, ptr_x += step) {
> float f = av_int2float(bytestream_get_le32(&src));
> AV_WN32A(ptr_x, av_float2int(trc_func(f)));
> }
> } else if (one_gamma != 1.f) {
> - for (int x = 0; x < xsize; x++, ptr_x += 4) {
> + for (x = 0; x < xsize; x++, ptr_x += step) {
> float f = av_int2float(bytestream_get_le32(&src));
> if (f > 0.0f && c < 3) /* avoid negative values */
> f = powf(f, one_gamma);
> AV_WN32A(ptr_x, av_float2int(f));
> }
> } else {
> - for (int x = 0; x < xsize; x++, ptr_x += 4)
> + for (x = 0; x < xsize; x++, ptr_x += step)
Don't remove loop-scope for iterators.
> AV_WN32A(ptr_x, bytestream_get_le32(&src));
> }
> - memset(ptr_x, 0, axmax);
> } else if (s->pixel_type == EXR_HALF) {
> src = channel_buffer[c];
>
> - // Zero out the start if xmin is not 0
> - memset(ptr, 0, bxmin);
> -
> // 16-bit
> for (x = window_xoffset; x < xsize + window_xoffset; x++) {
> int v = bytestream_get_le16(&src);
> - AV_WN16(ptr + x * sizeof(uint16_t), v);
> + AV_WN16(ptr + x * step, v);
What values can step have here?
> }
> - memset(ptr + x * sizeof(uint16_t), 0, axmax);
> }
>
> // Zero out the end if xmax+1 is not w
> + memset(ptr + x * step, 0, axmax);
> channel_buffer[c] += td->channel_line_size;
> }
> }
> @@ -2054,8 +2047,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
> if (!s->is_luma) {
> avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
> } else {
> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
> - avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
> + avctx->pix_fmt = AV_PIX_FMT_YAF16;
> }
> } else {
> if (!s->is_luma) {
> @@ -2071,8 +2063,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
> if (!s->is_luma) {
> avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
> } else {
> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
> - avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
> + avctx->pix_fmt = AV_PIX_FMT_YAF32;
> }
> } else {
> if (!s->is_luma) {
> @@ -2151,11 +2142,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
> if (!s->desc)
> return AVERROR_INVALIDDATA;
>
> - if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
> - planes = s->desc->nb_components;
> - } else {
> - planes = 1;
> - }
> + planes = av_pix_fmt_count_planes(avctx->pix_fmt);
> out_line_size = avctx->width * s->desc->comp[0].step;
>
> if (s->is_tile) {
> diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
> index 97ea715962..6c07f19846 100644
> --- a/tests/ref/fate/exr-ya-scanline-zip-half-12x8
> +++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
> @@ -3,4 +3,4 @@
> #codec_id 0: rawvideo
> #dimensions 0: 12x8
> #sar 0: 1/1
> -0, 0, 0, 1, 1536, 0x2b457bd2
> +0, 0, 0, 1, 1536, 0xa33f5f69
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 3/3] avcodec/exr: use luma+alpha float pixel formats
2025-03-05 21:41 ` Andreas Rheinhardt
@ 2025-03-05 22:03 ` James Almer
0 siblings, 0 replies; 7+ messages in thread
From: James Almer @ 2025-03-05 22:03 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 8317 bytes --]
On 3/5/2025 6:41 PM, Andreas Rheinhardt wrote:
> James Almer:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> Updated for the latest git master changes.
>>
>> libavcodec/exr.c | 55 ++++++++------------
>> tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 2 +-
>> 2 files changed, 22 insertions(+), 35 deletions(-)
>>
>> diff --git a/libavcodec/exr.c b/libavcodec/exr.c
>> index b25e9ef397..fe5f62c3b5 100644
>> --- a/libavcodec/exr.c
>> +++ b/libavcodec/exr.c
>> @@ -1352,33 +1352,32 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
>> data_yoffset = FFABS(FFMIN(0, line));
>> data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
>>
>> + if (s->channel_offsets[3] >= 0)
>> + channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
>> if (!s->is_luma) {
>> channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
>> channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
>> channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
>> rgb_channel_count = 3;
>> - } else { /* put y data in the first channel_buffer */
>> + } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
>> channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
>> + if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
>> + channel_buffer[1] = channel_buffer[3];
>> rgb_channel_count = 1;
>> }
>> - if (s->channel_offsets[3] >= 0)
>> - channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
>> -
>> - if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {
>> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
>> - int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
>> - if (s->is_luma) {
>> - channel_buffer[1] = channel_buffer[0];
>> - channel_buffer[2] = channel_buffer[0];
>> - }
>>
>> - for (c = 0; c < channel_count; c++) {
>> + if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
>> + for (c = 0; c < s->desc->nb_components; c++) {
>> int plane = s->desc->comp[c].plane;
>> - ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);
>> + ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
>>
>> for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
>> const uint8_t *src;
>>
>> + // Zero out the start if xmin is not 0
>> + if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
>> + memset(ptr, 0, bxmin);
>> +
>> if (s->pixel_type == EXR_FLOAT ||
>> s->compression == EXR_DWAA ||
>> s->compression == EXR_DWAB) {
>> @@ -1387,42 +1386,36 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
>>
>> src = channel_buffer[c];
>>
>> - // Zero out the start if xmin is not 0
>> - memset(ptr_x, 0, bxmin);
>> - ptr_x += 4 * window_xoffset;
>> + ptr_x += window_xoffset * step;
>>
>> if (trc_func && c < 3) {
>> - for (int x = 0; x < xsize; x++, ptr_x += 4) {
>> + for (x = 0; x < xsize; x++, ptr_x += step) {
>> float f = av_int2float(bytestream_get_le32(&src));
>> AV_WN32A(ptr_x, av_float2int(trc_func(f)));
>> }
>> } else if (one_gamma != 1.f) {
>> - for (int x = 0; x < xsize; x++, ptr_x += 4) {
>> + for (x = 0; x < xsize; x++, ptr_x += step) {
>> float f = av_int2float(bytestream_get_le32(&src));
>> if (f > 0.0f && c < 3) /* avoid negative values */
>> f = powf(f, one_gamma);
>> AV_WN32A(ptr_x, av_float2int(f));
>> }
>> } else {
>> - for (int x = 0; x < xsize; x++, ptr_x += 4)
>> + for (x = 0; x < xsize; x++, ptr_x += step)
>
> Don't remove loop-scope for iterators.
I moved the axmax memset outside the scope of these loops, and it uses x.
>
>> AV_WN32A(ptr_x, bytestream_get_le32(&src));
>> }
>> - memset(ptr_x, 0, axmax);
>> } else if (s->pixel_type == EXR_HALF) {
>> src = channel_buffer[c];
>>
>> - // Zero out the start if xmin is not 0
>> - memset(ptr, 0, bxmin);
>> -
>> // 16-bit
>> for (x = window_xoffset; x < xsize + window_xoffset; x++) {
>> int v = bytestream_get_le16(&src);
>> - AV_WN16(ptr + x * sizeof(uint16_t), v);
>> + AV_WN16(ptr + x * step, v);
>
> What values can step have here?
2 or 4, since it's float pixel formats only.
>
>> }
>> - memset(ptr + x * sizeof(uint16_t), 0, axmax);
>> }
>>
>> // Zero out the end if xmax+1 is not w
>> + memset(ptr + x * step, 0, axmax);
>> channel_buffer[c] += td->channel_line_size;
>> }
>> }
>> @@ -2054,8 +2047,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
>> if (!s->is_luma) {
>> avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
>> } else {
>> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
>> - avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
>> + avctx->pix_fmt = AV_PIX_FMT_YAF16;
>> }
>> } else {
>> if (!s->is_luma) {
>> @@ -2071,8 +2063,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
>> if (!s->is_luma) {
>> avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
>> } else {
>> - /* todo: change this when a floating point pixel format with luma with alpha is implemented */
>> - avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
>> + avctx->pix_fmt = AV_PIX_FMT_YAF32;
>> }
>> } else {
>> if (!s->is_luma) {
>> @@ -2151,11 +2142,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
>> if (!s->desc)
>> return AVERROR_INVALIDDATA;
>>
>> - if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
>> - planes = s->desc->nb_components;
>> - } else {
>> - planes = 1;
>> - }
>> + planes = av_pix_fmt_count_planes(avctx->pix_fmt);
>> out_line_size = avctx->width * s->desc->comp[0].step;
>>
>> if (s->is_tile) {
>> diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
>> index 97ea715962..6c07f19846 100644
>> --- a/tests/ref/fate/exr-ya-scanline-zip-half-12x8
>> +++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
>> @@ -3,4 +3,4 @@
>> #codec_id 0: rawvideo
>> #dimensions 0: 12x8
>> #sar 0: 1/1
>> -0, 0, 0, 1, 1536, 0x2b457bd2
>> +0, 0, 0, 1, 1536, 0xa33f5f69
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH v3 3/3] avcodec/exr: use luma+alpha float pixel formats
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats James Almer
2025-03-05 21:33 ` [FFmpeg-devel] [PATCH v2 " James Almer
@ 2025-03-06 13:21 ` James Almer
1 sibling, 0 replies; 7+ messages in thread
From: James Almer @ 2025-03-06 13:21 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/exr.c | 70 +++++++-------------
tests/ref/fate/exr-ya-scanline-zip-half-12x8 | 2 +-
2 files changed, 25 insertions(+), 47 deletions(-)
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index b25e9ef397..4482f104d0 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1352,77 +1352,61 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
data_yoffset = FFABS(FFMIN(0, line));
data_window_offset = (data_yoffset * td->channel_line_size) + data_xoffset;
+ if (s->channel_offsets[3] >= 0)
+ channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
if (!s->is_luma) {
channel_buffer[0] = src + (td->xsize * s->channel_offsets[0]) + data_window_offset;
channel_buffer[1] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
channel_buffer[2] = src + (td->xsize * s->channel_offsets[2]) + data_window_offset;
rgb_channel_count = 3;
- } else { /* put y data in the first channel_buffer */
+ } else { /* put y data in the first channel_buffer and if needed, alpha in the second */
channel_buffer[0] = src + (td->xsize * s->channel_offsets[1]) + data_window_offset;
+ if (!(s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))
+ channel_buffer[1] = channel_buffer[3];
rgb_channel_count = 1;
}
- if (s->channel_offsets[3] >= 0)
- channel_buffer[3] = src + (td->xsize * s->channel_offsets[3]) + data_window_offset;
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || s->desc->nb_components == 1 ) {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- int channel_count = s->channel_offsets[3] >= 0 ? 4 : rgb_channel_count;
- if (s->is_luma) {
- channel_buffer[1] = channel_buffer[0];
- channel_buffer[2] = channel_buffer[0];
- }
-
- for (c = 0; c < channel_count; c++) {
+ if (s->desc->flags & AV_PIX_FMT_FLAG_FLOAT) {
+ for (c = 0; c < s->desc->nb_components; c++) {
int plane = s->desc->comp[c].plane;
- ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step);
+ ptr = p->data[plane] + window_ymin * p->linesize[plane] + (window_xmin * step) + s->desc->comp[c].offset;
for (i = 0; i < ysize; i++, ptr += p->linesize[plane]) {
- const uint8_t *src;
+ const uint8_t *src = channel_buffer[c];
+ uint8_t *ptr_x = ptr + window_xoffset * step;
+
+ // Zero out the start if xmin is not 0
+ if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR || !c)
+ memset(ptr, 0, bxmin);
if (s->pixel_type == EXR_FLOAT ||
s->compression == EXR_DWAA ||
s->compression == EXR_DWAB) {
// 32-bit
- uint8_t *ptr_x = ptr;
-
- src = channel_buffer[c];
-
- // Zero out the start if xmin is not 0
- memset(ptr_x, 0, bxmin);
- ptr_x += 4 * window_xoffset;
-
- if (trc_func && c < 3) {
- for (int x = 0; x < xsize; x++, ptr_x += 4) {
+ if (trc_func && (!c || (c < 3 && s->desc->flags & AV_PIX_FMT_FLAG_PLANAR))) {
+ for (int x = 0; x < xsize; x++, ptr_x += step) {
float f = av_int2float(bytestream_get_le32(&src));
AV_WN32A(ptr_x, av_float2int(trc_func(f)));
}
} else if (one_gamma != 1.f) {
- for (int x = 0; x < xsize; x++, ptr_x += 4) {
+ for (int x = 0; x < xsize; x++, ptr_x += step) {
float f = av_int2float(bytestream_get_le32(&src));
if (f > 0.0f && c < 3) /* avoid negative values */
f = powf(f, one_gamma);
AV_WN32A(ptr_x, av_float2int(f));
}
} else {
- for (int x = 0; x < xsize; x++, ptr_x += 4)
+ for (int x = 0; x < xsize; x++, ptr_x += step)
AV_WN32A(ptr_x, bytestream_get_le32(&src));
}
- memset(ptr_x, 0, axmax);
} else if (s->pixel_type == EXR_HALF) {
- src = channel_buffer[c];
-
- // Zero out the start if xmin is not 0
- memset(ptr, 0, bxmin);
-
// 16-bit
- for (x = window_xoffset; x < xsize + window_xoffset; x++) {
- int v = bytestream_get_le16(&src);
- AV_WN16(ptr + x * sizeof(uint16_t), v);
- }
- memset(ptr + x * sizeof(uint16_t), 0, axmax);
+ for (int x = 0; x < xsize; x++, ptr_x += step)
+ AV_WN16A(ptr_x, bytestream_get_le16(&src));
}
// Zero out the end if xmax+1 is not w
+ memset(ptr_x, 0, axmax);
channel_buffer[c] += td->channel_line_size;
}
}
@@ -2054,8 +2038,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF16;
+ avctx->pix_fmt = AV_PIX_FMT_YAF16;
}
} else {
if (!s->is_luma) {
@@ -2071,8 +2054,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->is_luma) {
avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
} else {
- /* todo: change this when a floating point pixel format with luma with alpha is implemented */
- avctx->pix_fmt = AV_PIX_FMT_GBRAPF32;
+ avctx->pix_fmt = AV_PIX_FMT_YAF32;
}
} else {
if (!s->is_luma) {
@@ -2151,11 +2133,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
if (!s->desc)
return AVERROR_INVALIDDATA;
- if (s->desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
- planes = s->desc->nb_components;
- } else {
- planes = 1;
- }
+ planes = av_pix_fmt_count_planes(avctx->pix_fmt);
out_line_size = avctx->width * s->desc->comp[0].step;
if (s->is_tile) {
diff --git a/tests/ref/fate/exr-ya-scanline-zip-half-12x8 b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
index 97ea715962..6c07f19846 100644
--- a/tests/ref/fate/exr-ya-scanline-zip-half-12x8
+++ b/tests/ref/fate/exr-ya-scanline-zip-half-12x8
@@ -3,4 +3,4 @@
#codec_id 0: rawvideo
#dimensions 0: 12x8
#sar 0: 1/1
-0, 0, 0, 1, 1536, 0x2b457bd2
+0, 0, 0, 1, 1536, 0xa33f5f69
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-03-06 13:22 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-05 20:44 [FFmpeg-devel] [PATCH 1/3] avutil/pixfmt: add YAF16 and YAF32 pixel formats James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 2/3] swscale/input: add support for YAF16 and YAF32 James Almer
2025-03-05 20:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/exr: use luma+alpha float pixel formats James Almer
2025-03-05 21:33 ` [FFmpeg-devel] [PATCH v2 " James Almer
2025-03-05 21:41 ` Andreas Rheinhardt
2025-03-05 22:03 ` James Almer
2025-03-06 13:21 ` [FFmpeg-devel] [PATCH v3 " James Almer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git