[FFmpeg-devel] [PATCH 1/2] avcodec/snow_dwt: Support correct rounding of dwt decomposition of non even sizes
Michael Niedermayer
michael at niedermayer.cc
Sat Mar 25 00:10:24 EET 2023
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
libavcodec/snow_dwt.c | 61 ++++++++++++++++++++++++-------------------
libavcodec/snow_dwt.h | 3 +++
2 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/libavcodec/snow_dwt.c b/libavcodec/snow_dwt.c
index 965f409002..b27b07f58a 100644
--- a/libavcodec/snow_dwt.c
+++ b/libavcodec/snow_dwt.c
@@ -322,15 +322,17 @@ void ff_spatial_dwt(DWTELEM *buffer, DWTELEM *temp, int width, int height,
int level;
for (level = 0; level < decomposition_count; level++) {
- switch (type) {
+ int w = DWT_RSHIFT(width , level);
+ int h = DWT_RSHIFT(height, level);
+ switch (type & 3) {
case DWT_97:
spatial_decompose97i(buffer, temp,
- width >> level, height >> level,
+ w, h,
stride << level);
break;
case DWT_53:
spatial_decompose53i(buffer, temp,
- width >> level, height >> level,
+ w, h,
stride << level);
break;
}
@@ -642,13 +644,14 @@ void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
{
int level;
for (level = decomposition_count - 1; level >= 0; level--) {
- switch (type) {
+ int h = DWT_RSHIFT(height, level);
+ switch (type & 3) {
case DWT_97:
- spatial_compose97i_buffered_init(cs + level, sb, height >> level,
+ spatial_compose97i_buffered_init(cs + level, sb, h,
stride_line << level);
break;
case DWT_53:
- spatial_compose53i_buffered_init(cs + level, sb, height >> level,
+ spatial_compose53i_buffered_init(cs + level, sb, h,
stride_line << level);
break;
}
@@ -660,28 +663,29 @@ void ff_spatial_idwt_buffered_slice(SnowDWTContext *dsp, DWTCompose *cs,
int width, int height, int stride_line,
int type, int decomposition_count, int y)
{
- const int support = type == 1 ? 3 : 5;
+ const int support = (type & 3) == 1 ? 3 : 5;
int level;
- if (type == 2)
+ if ((type & 3) == 2)
return;
- for (level = decomposition_count - 1; level >= 0; level--)
- while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
- switch (type) {
+ for (level = decomposition_count - 1; level >= 0; level--) {
+ int w = DWT_RSHIFT(width , level);
+ int h = DWT_RSHIFT(height, level);
+ while (cs[level].y <= FFMIN((y >> level) + support, h)) {
+ switch (type & 3) {
case DWT_97:
spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
- width >> level,
- height >> level,
+ w, h,
stride_line << level);
break;
case DWT_53:
spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
- width >> level,
- height >> level,
+ w, h,
stride_line << level);
break;
}
}
+ }
}
static void spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width,
@@ -690,13 +694,14 @@ static void spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width,
{
int level;
for (level = decomposition_count - 1; level >= 0; level--) {
- switch (type) {
+ int h = DWT_RSHIFT(height, level);
+ switch (type & 3) {
case DWT_97:
- spatial_compose97i_init(cs + level, buffer, height >> level,
+ spatial_compose97i_init(cs + level, buffer, h,
stride << level);
break;
case DWT_53:
- spatial_compose53i_init(cs + level, buffer, height >> level,
+ spatial_compose53i_init(cs + level, buffer, h,
stride << level);
break;
}
@@ -708,24 +713,25 @@ static void spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer,
int stride, int type,
int decomposition_count, int y)
{
- const int support = type == 1 ? 3 : 5;
+ const int support = (type & 3) == 1 ? 3 : 5;
int level;
- if (type == 2)
+ if ((type & 3) == 2)
return;
- for (level = decomposition_count - 1; level >= 0; level--)
- while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
- switch (type) {
+ for (level = decomposition_count - 1; level >= 0; level--) {
+ int w = DWT_RSHIFT(width , level);
+ int h = DWT_RSHIFT(height, level);
+ while (cs[level].y <= FFMIN((y >> level) + support, h)) {
+ switch (type & 3) {
case DWT_97:
- spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
- height >> level, stride << level);
+ spatial_compose97i_dy(cs + level, buffer, temp, w, h, stride << level);
break;
case DWT_53:
- spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
- height >> level, stride << level);
+ spatial_compose53i_dy(cs + level, buffer, temp, w, h, stride << level);
break;
}
}
+ }
}
void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
@@ -788,6 +794,7 @@ static inline int w_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8
}
ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
+ type &= 3;
s = 0;
av_assert1(w == h);
diff --git a/libavcodec/snow_dwt.h b/libavcodec/snow_dwt.h
index 15b8a3007b..48acfd46c5 100644
--- a/libavcodec/snow_dwt.h
+++ b/libavcodec/snow_dwt.h
@@ -67,6 +67,9 @@ typedef struct SnowDWTContext {
#define DWT_97 0
#define DWT_53 1
+#define DWT_NEW_ROUNDING_FLAG 4
+
+#define DWT_RSHIFT(a, b) (((type) & DWT_NEW_ROUNDING_FLAG) ? -(-(a) >> (b)) : (a) >> (b))
#define liftS lift
#define W_AM 3
--
2.17.1
More information about the ffmpeg-devel
mailing list