[FFmpeg-devel] [PATCH] sws: add dither enum
Michael Niedermayer
michaelni at gmx.at
Wed Aug 14 17:33:53 CEST 2013
This allows specifying more dither algorithms without using up flags and
without ambiguities.
Also initialize the new field based on the flags and use it
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
libswscale/options.c | 6 ++++++
libswscale/output.c | 6 +++---
libswscale/swscale.c | 2 +-
libswscale/swscale_internal.h | 9 +++++++++
libswscale/swscale_unscaled.c | 2 +-
libswscale/utils.c | 12 ++++++++----
libswscale/version.h | 2 +-
7 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/libswscale/options.c b/libswscale/options.c
index 81d8c28..f7edd21 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -69,6 +69,12 @@ static const AVOption swscale_options[] = {
{ "dst_v_chr_pos", "destination vertical chroma position in luma grid/256" , OFFSET(dst_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 512, VE },
{ "dst_h_chr_pos", "destination horizontal chroma position in luma grid/256", OFFSET(dst_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 512, VE },
+ { "sws_dither", "Dither algorithm", OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = SWS_DITHER_AUTO }, 0, 1, VE, "sws_dither" },
+ { "auto", "leave choice to sws", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_AUTO }, INT_MIN, INT_MAX, VE, "sws_dither" },
+ { "off", "no dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_NONE }, INT_MIN, INT_MAX, VE, "sws_dither" },
+ { "bayer", "bayer dither", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_BAYER }, INT_MIN, INT_MAX, VE, "sws_dither" },
+ { "ed", "error diffusion", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_ED }, INT_MIN, INT_MAX, VE, "sws_dither" },
+
{ NULL }
};
diff --git a/libswscale/output.c b/libswscale/output.c
index 54b6ebd..2d390c7 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -349,7 +349,7 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
Y1 = av_clip_uint8(Y1);
Y2 = av_clip_uint8(Y2);
}
- if (c->flags & SWS_ERROR_DIFFUSION) {
+ if (c->dither == SWS_DITHER_ED) {
Y1 += (7*err + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2] + 8 - 256)>>4;
c->dither_error[0][i] = err;
acc = 2*acc + (Y1 >= 128);
@@ -386,7 +386,7 @@ yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
int yalpha1 = 4096 - yalpha;
int i;
- if (c->flags & SWS_ERROR_DIFFUSION) {
+ if (c->dither == SWS_DITHER_ED) {
int err = 0;
int acc = 0;
for (i = 0; i < dstW; i +=2) {
@@ -443,7 +443,7 @@ yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
const uint8_t * const d128 = dither_8x8_220[y & 7];
int i;
- if (c->flags & SWS_ERROR_DIFFUSION) {
+ if (c->dither == SWS_DITHER_ED) {
int err = 0;
int acc = 0;
for (i = 0; i < dstW; i +=2) {
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 6721dc3..87b867d 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -1051,7 +1051,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
src2[0] = base;
}
- if (!srcSliceY && (c->flags & SWS_BITEXACT) && (c->flags & SWS_ERROR_DIFFUSION) && c->dither_error[0])
+ if (!srcSliceY && (c->flags & SWS_BITEXACT) && c->dither == SWS_DITHER_ED && c->dither_error[0])
for (i = 0; i < 4; i++)
memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index e7cc26e..a14cc02 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -61,6 +61,13 @@
struct SwsContext;
+typedef enum SwsDither {
+ SWS_DITHER_NONE = 0,
+ SWS_DITHER_AUTO,
+ SWS_DITHER_BAYER,
+ SWS_DITHER_ED,
+} SwsDither;
+
typedef int (*SwsFunc)(struct SwsContext *context, const uint8_t *src[],
int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *dst[], int dstStride[]);
@@ -593,6 +600,8 @@ typedef struct SwsContext {
void (*chrConvertRange)(int16_t *dst1, int16_t *dst2, int width);
int needs_hcscale; ///< Set if there are chroma planes to be converted.
+
+ SwsDither dither;
} SwsContext;
//FIXME check init (where 0)
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 3b07800..22196bd 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -1180,7 +1180,7 @@ void ff_get_unscaled_swscale(SwsContext *c)
/* yuv2bgr */
if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
- !(flags & (SWS_ACCURATE_RND|SWS_ERROR_DIFFUSION)) && !(dstH & 1)) {
+ !(flags & SWS_ACCURATE_RND) && c->dither != SWS_DITHER_ED && !(dstH & 1)) {
c->swScale = ff_yuv2rgb_get_func_ptr(c);
}
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 5aacd81..f5826c3 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -1196,23 +1196,27 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
}
}
+ if (c->dither == SWS_DITHER_AUTO) {
+ if (flags & SWS_ERROR_DIFFUSION)
+ c->dither = SWS_DITHER_ED;
+ }
+
if(dstFormat == AV_PIX_FMT_BGR4_BYTE ||
dstFormat == AV_PIX_FMT_RGB4_BYTE ||
dstFormat == AV_PIX_FMT_BGR8 ||
dstFormat == AV_PIX_FMT_RGB8) {
- if (flags & SWS_ERROR_DIFFUSION && !(flags & SWS_FULL_CHR_H_INT)) {
+ if (c->dither == SWS_DITHER_ED && !(flags & SWS_FULL_CHR_H_INT)) {
av_log(c, AV_LOG_DEBUG,
"Error diffusion dither is only supported in full chroma interpolation for destination format '%s'\n",
av_get_pix_fmt_name(dstFormat));
flags |= SWS_FULL_CHR_H_INT;
c->flags = flags;
}
- if (!(flags & SWS_ERROR_DIFFUSION) && (flags & SWS_FULL_CHR_H_INT)) {
+ if (c->dither != SWS_DITHER_ED && (flags & SWS_FULL_CHR_H_INT)) {
av_log(c, AV_LOG_DEBUG,
"Ordered dither is not supported in full chroma interpolation for destination format '%s'\n",
av_get_pix_fmt_name(dstFormat));
- flags |= SWS_ERROR_DIFFUSION;
- c->flags = flags;
+ c->dither = SWS_DITHER_ED;
}
}
if (isPlanarRGB(dstFormat)) {
diff --git a/libswscale/version.h b/libswscale/version.h
index 1c45209..06f119a 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -27,7 +27,7 @@
#include "libavutil/avutil.h"
#define LIBSWSCALE_VERSION_MAJOR 2
-#define LIBSWSCALE_VERSION_MINOR 4
+#define LIBSWSCALE_VERSION_MINOR 5
#define LIBSWSCALE_VERSION_MICRO 100
#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
--
1.7.9.5
More information about the ffmpeg-devel
mailing list