summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/APIchanges3
-rw-r--r--libswscale/options.c5
-rw-r--r--libswscale/output.c6
-rw-r--r--libswscale/swscale.c2
-rw-r--r--libswscale/swscale_internal.h10
-rw-r--r--libswscale/swscale_unscaled.c2
-rw-r--r--libswscale/utils.c12
-rw-r--r--libswscale/version.h2
8 files changed, 32 insertions, 10 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 049d142760..1ea2bd6ab3 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil: 2012-10-22
API changes, most recent first:
+2013-08-xx - xxxxxxx - lsws 2.5.100 -
+ Add a sws_dither AVOption, allowing to set the dither algorithm used
+
2013-08-xx - xxxxxxx - lavc 55.27.100 - vdpau.h
Add a render2 alternative to the render callback function.
diff --git a/libswscale/options.c b/libswscale/options.c
index 81d8c28b08..8985e6b5d6 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -69,6 +69,11 @@ 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", "set dithering algorithm", OFFSET(dither), AV_OPT_TYPE_INT, { .i64 = SWS_DITHER_AUTO }, 0, NB_SWS_DITHER, VE, "sws_dither" },
+ { "auto", "leave choice to sws", 0, AV_OPT_TYPE_CONST, { .i64 = SWS_DITHER_AUTO }, 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 54b6ebd461..2d390c706c 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 6721dc3a2d..87b867d2b7 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 18563eed78..bd5628d081 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -61,6 +61,14 @@
struct SwsContext;
+typedef enum SwsDither {
+ SWS_DITHER_NONE = 0,
+ SWS_DITHER_AUTO,
+ SWS_DITHER_BAYER,
+ SWS_DITHER_ED,
+ NB_SWS_DITHER,
+} SwsDither;
+
typedef int (*SwsFunc)(struct SwsContext *context, const uint8_t *src[],
int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *dst[], int dstStride[]);
@@ -593,6 +601,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 8735c62ba3..49338839d4 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 5aacd817b8..f5826c37be 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 1c4520926a..06f119afb3 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, \