提交 1e0e1932 编写于 作者: M Michael Niedermayer

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: NMichael Niedermayer <michaelni@gmx.at>
上级 60e9b855
......@@ -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, \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册