sws: add dither enum
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. Note, improving the logic of the checks is left to subsequent commits, this here only switches from flags to enum. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
60e9b8556a
commit
1e0e193240
@ -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.
|
||||
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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, \
|
||||
|
Loading…
Reference in New Issue
Block a user