mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avfilter/vf_maskedmerge: fix rounding when masking
This commit is contained in:
parent
59520f068d
commit
dae95b3ffd
@ -30,7 +30,7 @@ typedef struct MaskedMergeContext {
|
|||||||
int linesize[4];
|
int linesize[4];
|
||||||
int nb_planes;
|
int nb_planes;
|
||||||
int planes;
|
int planes;
|
||||||
int half, depth;
|
int half, depth, max;
|
||||||
FFFrameSync fs;
|
FFFrameSync fs;
|
||||||
|
|
||||||
void (*maskedmerge)(const uint8_t *bsrc, const uint8_t *osrc,
|
void (*maskedmerge)(const uint8_t *bsrc, const uint8_t *osrc,
|
||||||
|
@ -96,7 +96,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
|
|||||||
base->linesize[p], overlay->linesize[p],
|
base->linesize[p], overlay->linesize[p],
|
||||||
mask->linesize[p], out->linesize[p],
|
mask->linesize[p], out->linesize[p],
|
||||||
s->width[p], slice_end - slice_start,
|
s->width[p], slice_end - slice_start,
|
||||||
s->half, s->depth);
|
s->half, s->max);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -138,13 +138,13 @@ static int process_frame(FFFrameSync *fs)
|
|||||||
return ff_filter_frame(outlink, out);
|
return ff_filter_frame(outlink, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MASKEDMERGE(n, type, half, shift) \
|
#define MASKEDMERGE(n, type, ctype, half, max, div) \
|
||||||
static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \
|
static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \
|
||||||
const uint8_t *mmsrc, uint8_t *ddst, \
|
const uint8_t *mmsrc, uint8_t *ddst, \
|
||||||
ptrdiff_t blinesize, ptrdiff_t olinesize, \
|
ptrdiff_t blinesize, ptrdiff_t olinesize, \
|
||||||
ptrdiff_t mlinesize, ptrdiff_t dlinesize, \
|
ptrdiff_t mlinesize, ptrdiff_t dlinesize, \
|
||||||
int w, int h, \
|
int w, int h, \
|
||||||
int hhalf, int sshift) \
|
int hhalf, int mmax) \
|
||||||
{ \
|
{ \
|
||||||
const type *bsrc = (const type *)bbsrc; \
|
const type *bsrc = (const type *)bbsrc; \
|
||||||
const type *osrc = (const type *)oosrc; \
|
const type *osrc = (const type *)oosrc; \
|
||||||
@ -158,7 +158,10 @@ static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \
|
|||||||
\
|
\
|
||||||
for (int y = 0; y < h; y++) { \
|
for (int y = 0; y < h; y++) { \
|
||||||
for (int x = 0; x < w; x++) { \
|
for (int x = 0; x < w; x++) { \
|
||||||
dst[x] = bsrc[x] + ((msrc[x] * (osrc[x] - bsrc[x]) + half) shift); \
|
const type invm = max - msrc[x]; \
|
||||||
|
const ctype r = ((ctype)(bsrc[x] * invm) + \
|
||||||
|
(ctype)(msrc[x] * osrc[x] + half)) div; \
|
||||||
|
dst[x] = r; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
dst += dlinesize; \
|
dst += dlinesize; \
|
||||||
@ -168,9 +171,9 @@ static void maskedmerge##n(const uint8_t *bbsrc, const uint8_t *oosrc, \
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
MASKEDMERGE(8, uint8_t, 128, >> 8)
|
MASKEDMERGE(8, uint8_t, uint16_t, 127, 255, / 255)
|
||||||
MASKEDMERGE(16, uint16_t, hhalf, >> sshift)
|
MASKEDMERGE(16, uint16_t, uint32_t, hhalf, mmax, / mmax)
|
||||||
MASKEDMERGE(32, float, 0.f, + 0.f)
|
MASKEDMERGE(32, float, float, 0.f, 1.f, + 0.f)
|
||||||
|
|
||||||
static int config_input(AVFilterLink *inlink)
|
static int config_input(AVFilterLink *inlink)
|
||||||
{
|
{
|
||||||
@ -189,7 +192,8 @@ static int config_input(AVFilterLink *inlink)
|
|||||||
s->width[0] = s->width[3] = inlink->w;
|
s->width[0] = s->width[3] = inlink->w;
|
||||||
|
|
||||||
s->depth = desc->comp[0].depth;
|
s->depth = desc->comp[0].depth;
|
||||||
s->half = (1 << s->depth) / 2;
|
s->max = (1 << s->depth) - 1;
|
||||||
|
s->half = s->max / 2;
|
||||||
|
|
||||||
if (s->depth == 8)
|
if (s->depth == 8)
|
||||||
s->maskedmerge = maskedmerge8;
|
s->maskedmerge = maskedmerge8;
|
||||||
|
@ -24,26 +24,28 @@
|
|||||||
|
|
||||||
SECTION_RODATA
|
SECTION_RODATA
|
||||||
|
|
||||||
pw_128: times 8 dw 128
|
pw_127: times 8 dw 127
|
||||||
pw_256: times 8 dw 256
|
pw_255: times 8 dw 255
|
||||||
|
pw_32897: times 8 dw 32897
|
||||||
|
|
||||||
SECTION .text
|
SECTION .text
|
||||||
|
|
||||||
INIT_XMM sse2
|
INIT_XMM sse2
|
||||||
%if ARCH_X86_64
|
%if ARCH_X86_64
|
||||||
cglobal maskedmerge8, 8, 11, 7, bsrc, osrc, msrc, dst, blinesize, olinesize, mlinesize, dlinesize, w, h, x
|
cglobal maskedmerge8, 8, 11, 8, bsrc, osrc, msrc, dst, blinesize, olinesize, mlinesize, dlinesize, w, h, x
|
||||||
mov wd, dword wm
|
mov wd, dword wm
|
||||||
mov hd, dword hm
|
mov hd, dword hm
|
||||||
%else
|
%else
|
||||||
cglobal maskedmerge8, 5, 7, 7, bsrc, osrc, msrc, dst, blinesize, w, x
|
cglobal maskedmerge8, 5, 7, 8, bsrc, osrc, msrc, dst, blinesize, w, x
|
||||||
mov wd, r8m
|
mov wd, r8m
|
||||||
%define olinesizeq r5mp
|
%define olinesizeq r5mp
|
||||||
%define mlinesizeq r6mp
|
%define mlinesizeq r6mp
|
||||||
%define dlinesizeq r7mp
|
%define dlinesizeq r7mp
|
||||||
%define hd r9mp
|
%define hd r9mp
|
||||||
%endif
|
%endif
|
||||||
mova m4, [pw_256]
|
mova m4, [pw_255]
|
||||||
mova m5, [pw_128]
|
mova m5, [pw_127]
|
||||||
|
mova m7, [pw_32897]
|
||||||
pxor m6, m6
|
pxor m6, m6
|
||||||
add bsrcq, wq
|
add bsrcq, wq
|
||||||
add osrcq, wq
|
add osrcq, wq
|
||||||
@ -66,7 +68,8 @@ cglobal maskedmerge8, 5, 7, 7, bsrc, osrc, msrc, dst, blinesize, w, x
|
|||||||
pmullw m1, m3
|
pmullw m1, m3
|
||||||
paddw m1, m2
|
paddw m1, m2
|
||||||
paddw m1, m5
|
paddw m1, m5
|
||||||
psrlw m1, 8
|
pmulhuw m1, m7
|
||||||
|
psrlw m1, 7
|
||||||
packuswb m1, m1
|
packuswb m1, m1
|
||||||
movh [dstq + xq], m1
|
movh [dstq + xq], m1
|
||||||
add xq, mmsize / 2
|
add xq, mmsize / 2
|
||||||
|
Loading…
Reference in New Issue
Block a user