Commit 64ed3976 authored by Anton Khirnov's avatar Anton Khirnov

vf_yadif: fix out-of line reads

Some changes in the border pixels, visually indistinguishable.
parent ccd70d9c
...@@ -34,15 +34,15 @@ ...@@ -34,15 +34,15 @@
#define PERM_RWP AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE #define PERM_RWP AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE
#define CHECK(j)\ #define CHECK(j)\
{ int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\ { int score = FFABS(cur[mrefs + off_left + (j)] - cur[prefs + off_left - (j)])\
+ FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\ + FFABS(cur[mrefs +(j)] - cur[prefs -(j)])\
+ FFABS(cur[mrefs+1+(j)] - cur[prefs+1-(j)]);\ + FFABS(cur[mrefs + off_right + (j)] - cur[prefs + off_right - (j)]);\
if (score < spatial_score) {\ if (score < spatial_score) {\
spatial_score= score;\ spatial_score= score;\
spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\ spatial_pred= (cur[mrefs +(j)] + cur[prefs -(j)])>>1;\
#define FILTER \ #define FILTER(start, end) \
for (x = 0; x < w; x++) { \ for (x = start; x < end; x++) { \
int c = cur[mrefs]; \ int c = cur[mrefs]; \
int d = (prev2[0] + next2[0])>>1; \ int d = (prev2[0] + next2[0])>>1; \
int e = cur[prefs]; \ int e = cur[prefs]; \
...@@ -51,11 +51,15 @@ ...@@ -51,11 +51,15 @@
int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \ int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \
int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \ int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
int spatial_pred = (c+e) >> 1; \ int spatial_pred = (c+e) >> 1; \
int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \ int off_right = (x < w - 1) ? 1 : -1;\
+ FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \ int off_left = x ? -1 : 1;\
int spatial_score = FFABS(cur[mrefs + off_left] - cur[prefs + off_left]) + FFABS(c-e) \
+ FFABS(cur[mrefs + off_right] - cur[prefs + off_right]) - 1; \
\ \
if (x > 2 && x < w - 3) {\
CHECK(-1) CHECK(-2) }} }} \ CHECK(-1) CHECK(-2) }} }} \
CHECK( 1) CHECK( 2) }} }} \ CHECK( 1) CHECK( 2) }} }} \
}\
\ \
if (mode < 2) { \ if (mode < 2) { \
int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \ int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \
...@@ -93,9 +97,34 @@ static void filter_line_c(void *dst1, ...@@ -93,9 +97,34 @@ static void filter_line_c(void *dst1,
uint8_t *prev2 = parity ? prev : cur ; uint8_t *prev2 = parity ? prev : cur ;
uint8_t *next2 = parity ? cur : next; uint8_t *next2 = parity ? cur : next;
FILTER FILTER(0, w)
} }
static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1,
int w, int prefs, int mrefs, int parity, int mode,
int l_edge)
{
uint8_t *dst = dst1;
uint8_t *prev = prev1;
uint8_t *cur = cur1;
uint8_t *next = next1;
int x;
uint8_t *prev2 = parity ? prev : cur ;
uint8_t *next2 = parity ? cur : next;
FILTER(0, l_edge)
dst = (uint8_t*)dst1 + w - 3;
prev = (uint8_t*)prev1 + w - 3;
cur = (uint8_t*)cur1 + w - 3;
next = (uint8_t*)next1 + w - 3;
prev2 = (uint8_t*)(parity ? prev : cur);
next2 = (uint8_t*)(parity ? cur : next);
FILTER(w - 3, w)
}
static void filter_line_c_16bit(void *dst1, static void filter_line_c_16bit(void *dst1,
void *prev1, void *cur1, void *next1, void *prev1, void *cur1, void *next1,
int w, int prefs, int mrefs, int parity, int w, int prefs, int mrefs, int parity,
...@@ -111,7 +140,31 @@ static void filter_line_c_16bit(void *dst1, ...@@ -111,7 +140,31 @@ static void filter_line_c_16bit(void *dst1,
mrefs /= 2; mrefs /= 2;
prefs /= 2; prefs /= 2;
FILTER FILTER(0, w)
}
static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1,
int w, int prefs, int mrefs, int parity, int mode,
int l_edge)
{
uint16_t *dst = dst1;
uint16_t *prev = prev1;
uint16_t *cur = cur1;
uint16_t *next = next1;
int x;
uint16_t *prev2 = parity ? prev : cur ;
uint16_t *next2 = parity ? cur : next;
FILTER(0, l_edge)
dst = (uint16_t*)dst1 + w - 3;
prev = (uint16_t*)prev1 + w - 3;
cur = (uint16_t*)cur1 + w - 3;
next = (uint16_t*)next1 + w - 3;
prev2 = (uint16_t*)(parity ? prev : cur);
next2 = (uint16_t*)(parity ? cur : next);
FILTER(w - 3, w)
} }
static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
...@@ -125,6 +178,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, ...@@ -125,6 +178,7 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
int h = dstpic->video->h; int h = dstpic->video->h;
int refs = yadif->cur->linesize[i]; int refs = yadif->cur->linesize[i];
int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8; int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
int l_edge, l_edge_pix;
if (i == 1 || i == 2) { if (i == 1 || i == 2) {
/* Why is this not part of the per-plane description thing? */ /* Why is this not part of the per-plane description thing? */
...@@ -132,6 +186,12 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, ...@@ -132,6 +186,12 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
h >>= yadif->csp->log2_chroma_h; h >>= yadif->csp->log2_chroma_h;
} }
/* filtering reads 3 pixels to the left/right; to avoid invalid reads,
* we need to call the c variant which avoids this for border pixels
*/
l_edge = yadif->req_align;
l_edge_pix = l_edge / df;
for (y = 0; y < h; y++) { for (y = 0; y < h; y++) {
if ((y ^ parity) & 1) { if ((y ^ parity) & 1) {
uint8_t *prev = &yadif->prev->data[i][y * refs]; uint8_t *prev = &yadif->prev->data[i][y * refs];
...@@ -139,10 +199,22 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic, ...@@ -139,10 +199,22 @@ static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
uint8_t *next = &yadif->next->data[i][y * refs]; uint8_t *next = &yadif->next->data[i][y * refs];
uint8_t *dst = &dstpic->data[i][y * dstpic->linesize[i]]; uint8_t *dst = &dstpic->data[i][y * dstpic->linesize[i]];
int mode = y == 1 || y + 2 == h ? 2 : yadif->mode; int mode = y == 1 || y + 2 == h ? 2 : yadif->mode;
yadif->filter_line(dst, prev, cur, next, w, if (yadif->req_align) {
yadif->filter_line(dst + l_edge, prev + l_edge, cur + l_edge,
next + l_edge, w - l_edge_pix - 3,
y + 1 < h ? refs : -refs, y + 1 < h ? refs : -refs,
y ? -refs : refs, y ? -refs : refs,
parity ^ tff, mode); parity ^ tff, mode);
yadif->filter_edges(dst, prev, cur, next, w,
y + 1 < h ? refs : -refs,
y ? -refs : refs,
parity ^ tff, mode, l_edge_pix);
} else {
yadif->filter_line(dst, prev, cur, next + l_edge, w,
y + 1 < h ? refs : -refs,
y ? -refs : refs,
parity ^ tff, mode);
}
} else { } else {
memcpy(&dstpic->data[i][y * dstpic->linesize[i]], memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
&yadif->cur->data[i][y * refs], w * df); &yadif->cur->data[i][y * refs], w * df);
...@@ -392,8 +464,10 @@ static int config_props(AVFilterLink *link) ...@@ -392,8 +464,10 @@ static int config_props(AVFilterLink *link)
s->csp = av_pix_fmt_desc_get(link->format); s->csp = av_pix_fmt_desc_get(link->format);
if (s->csp->comp[0].depth_minus1 / 8 == 1) { if (s->csp->comp[0].depth_minus1 / 8 == 1) {
s->filter_line = filter_line_c_16bit; s->filter_line = filter_line_c_16bit;
s->filter_edges = filter_edges_16bit;
} else { } else {
s->filter_line = filter_line_c; s->filter_line = filter_line_c;
s->filter_edges = filter_edges;
if (ARCH_X86) if (ARCH_X86)
ff_yadif_init_x86(s); ff_yadif_init_x86(s);
......
...@@ -43,12 +43,18 @@ av_cold void ff_yadif_init_x86(YADIFContext *yadif) ...@@ -43,12 +43,18 @@ av_cold void ff_yadif_init_x86(YADIFContext *yadif)
#if HAVE_YASM #if HAVE_YASM
#if ARCH_X86_32 #if ARCH_X86_32
if (EXTERNAL_MMXEXT(cpu_flags)) if (EXTERNAL_MMXEXT(cpu_flags)) {
yadif->filter_line = ff_yadif_filter_line_mmxext; yadif->filter_line = ff_yadif_filter_line_mmxext;
yadif->req_align = 8;
}
#endif /* ARCH_X86_32 */ #endif /* ARCH_X86_32 */
if (EXTERNAL_SSE2(cpu_flags)) if (EXTERNAL_SSE2(cpu_flags)) {
yadif->filter_line = ff_yadif_filter_line_sse2; yadif->filter_line = ff_yadif_filter_line_sse2;
if (EXTERNAL_SSSE3(cpu_flags)) yadif->req_align = 16;
}
if (EXTERNAL_SSSE3(cpu_flags)) {
yadif->filter_line = ff_yadif_filter_line_ssse3; yadif->filter_line = ff_yadif_filter_line_ssse3;
yadif->req_align = 16;
}
#endif /* HAVE_YASM */ #endif /* HAVE_YASM */
} }
...@@ -50,9 +50,17 @@ typedef struct YADIFContext { ...@@ -50,9 +50,17 @@ typedef struct YADIFContext {
AVFilterBufferRef *next; AVFilterBufferRef *next;
AVFilterBufferRef *prev; AVFilterBufferRef *prev;
AVFilterBufferRef *out; AVFilterBufferRef *out;
/**
* Required alignment for filter_line
*/
int req_align;
void (*filter_line)(void *dst, void (*filter_line)(void *dst,
void *prev, void *cur, void *next, void *prev, void *cur, void *next,
int w, int prefs, int mrefs, int parity, int mode); int w, int prefs, int mrefs, int parity, int mode);
void (*filter_edges)(void *dst, void *prev, void *cur, void *next,
int w, int prefs, int mrefs, int parity, int mode,
int l_edge);
const AVPixFmtDescriptor *csp; const AVPixFmtDescriptor *csp;
int eof; int eof;
......
#tb 0: 1/180000 #tb 0: 1/180000
0, 64800, 64800, 0, 622080, 0x4440caef 0, 64800, 64800, 0, 622080, 0x6331caee
0, 72000, 72000, 0, 622080, 0xce67e69d 0, 72000, 72000, 0, 622080, 0xa459e690
0, 79200, 79200, 0, 622080, 0x1dbdc653 0, 79200, 79200, 0, 622080, 0x6429c648
0, 86400, 86400, 0, 622080, 0x82c591d1 0, 86400, 86400, 0, 622080, 0xa49891ca
0, 93600, 93600, 0, 622080, 0x8193740b 0, 93600, 93600, 0, 622080, 0x2a887404
0, 100800, 100800, 0, 622080, 0xcb219711 0, 100800, 100800, 0, 622080, 0xe8d49705
0, 108000, 108000, 0, 622080, 0x1870783b 0, 108000, 108000, 0, 622080, 0x1b627835
0, 115200, 115200, 0, 622080, 0x7080590b 0, 115200, 115200, 0, 622080, 0x686858fd
0, 122400, 122400, 0, 622080, 0x6df4175d 0, 122400, 122400, 0, 622080, 0x2675174f
0, 129600, 129600, 0, 622080, 0x6b530e95 0, 129600, 129600, 0, 622080, 0x78470e7f
0, 136800, 136800, 0, 622080, 0x7f9d66f7 0, 136800, 136800, 0, 622080, 0xffb366ec
0, 144000, 144000, 0, 622080, 0x338cda81 0, 144000, 144000, 0, 622080, 0xd575da72
0, 151200, 151200, 0, 622080, 0xb13797f8 0, 151200, 151200, 0, 622080, 0x5fb297f7
0, 158400, 158400, 0, 622080, 0xb51e7ca4 0, 158400, 158400, 0, 622080, 0xbac77ca0
0, 165600, 165600, 0, 622080, 0x353eed75 0, 165600, 165600, 0, 622080, 0x3276ed72
0, 172800, 172800, 0, 622080, 0xf93e92b0 0, 172800, 172800, 0, 622080, 0x264092b2
0, 180000, 180000, 0, 622080, 0xd0811094 0, 180000, 180000, 0, 622080, 0x20ba1094
0, 187200, 187200, 0, 622080, 0xb04a3141 0, 187200, 187200, 0, 622080, 0x76cc3139
0, 194400, 194400, 0, 622080, 0x4ab84909 0, 194400, 194400, 0, 622080, 0x469a4902
0, 201600, 201600, 0, 622080, 0xa0fcb8fb 0, 201600, 201600, 0, 622080, 0x0ed7b8f5
0, 208800, 208800, 0, 622080, 0x9003aebb 0, 208800, 208800, 0, 622080, 0xdc51aeac
0, 216000, 216000, 0, 622080, 0x153faa3e 0, 216000, 216000, 0, 622080, 0xee06aa36
0, 223200, 223200, 0, 622080, 0xae724063 0, 223200, 223200, 0, 622080, 0x7372405f
0, 230400, 230400, 0, 622080, 0xeb4de77a 0, 230400, 230400, 0, 622080, 0x9e0ee776
0, 237600, 237600, 0, 622080, 0x209ed8c7 0, 237600, 237600, 0, 622080, 0x39e6d8c9
0, 244800, 244800, 0, 622080, 0xe2bbac96 0, 244800, 244800, 0, 622080, 0x51d9ac9a
0, 252000, 252000, 0, 622080, 0xe945441e 0, 252000, 252000, 0, 622080, 0x2b63441d
0, 259200, 259200, 0, 622080, 0x8f8cbd5f 0, 259200, 259200, 0, 622080, 0x58afbd5e
0, 266400, 266400, 0, 622080, 0xbc3cf717 0, 266400, 266400, 0, 622080, 0xb972f716
0, 273600, 273600, 0, 622080, 0x0109f125 0, 273600, 273600, 0, 622080, 0x6a6df129
0, 280800, 280800, 0, 622080, 0x230c373f 0, 280800, 280800, 0, 622080, 0x28b1373d
#tb 0: 1/180000 #tb 0: 1/180000
0, 64800, 64800, 0, 622080, 0x4440caef 0, 64800, 64800, 0, 622080, 0x6331caee
0, 68400, 68400, 0, 622080, 0xa5cea88b 0, 68400, 68400, 0, 622080, 0x625da883
0, 72000, 72000, 0, 622080, 0xce67e69d 0, 72000, 72000, 0, 622080, 0xa459e690
0, 75600, 75600, 0, 622080, 0x9a57891f 0, 75600, 75600, 0, 622080, 0xce5d891e
0, 79200, 79200, 0, 622080, 0x1dbdc653 0, 79200, 79200, 0, 622080, 0x6429c648
0, 82800, 82800, 0, 622080, 0xc171c0c5 0, 82800, 82800, 0, 622080, 0x608cc0ba
0, 86400, 86400, 0, 622080, 0x82c591d1 0, 86400, 86400, 0, 622080, 0xa49891ca
0, 90000, 90000, 0, 622080, 0x20db9890 0, 90000, 90000, 0, 622080, 0x9721987f
0, 93600, 93600, 0, 622080, 0x8193740b 0, 93600, 93600, 0, 622080, 0x2a887404
0, 97200, 97200, 0, 622080, 0xdb181d52 0, 97200, 97200, 0, 622080, 0x60d71d47
0, 100800, 100800, 0, 622080, 0xcb219711 0, 100800, 100800, 0, 622080, 0xe8d49705
0, 104400, 104400, 0, 622080, 0xc2b913d1 0, 104400, 104400, 0, 622080, 0x821e13cb
0, 108000, 108000, 0, 622080, 0x1870783b 0, 108000, 108000, 0, 622080, 0x1b627835
0, 111600, 111600, 0, 622080, 0xf1d9c5fb 0, 111600, 111600, 0, 622080, 0x1806c5f4
0, 115200, 115200, 0, 622080, 0x7080590b 0, 115200, 115200, 0, 622080, 0x686858fd
0, 118800, 118800, 0, 622080, 0x669c5775 0, 118800, 118800, 0, 622080, 0xab865773
0, 122400, 122400, 0, 622080, 0x6df4175d 0, 122400, 122400, 0, 622080, 0x2675174f
0, 126000, 126000, 0, 622080, 0x01921a16 0, 126000, 126000, 0, 622080, 0x43a61a14
0, 129600, 129600, 0, 622080, 0x6b530e95 0, 129600, 129600, 0, 622080, 0x78470e7f
0, 133200, 133200, 0, 622080, 0xd5047bc9 0, 133200, 133200, 0, 622080, 0xeb877bc6
0, 136800, 136800, 0, 622080, 0x7f9d66f7 0, 136800, 136800, 0, 622080, 0xffb366ec
0, 140400, 140400, 0, 622080, 0xa8b006eb 0, 140400, 140400, 0, 622080, 0xda0906e7
0, 144000, 144000, 0, 622080, 0x338cda81 0, 144000, 144000, 0, 622080, 0xd575da72
0, 147600, 147600, 0, 622080, 0xf0e125a7 0, 147600, 147600, 0, 622080, 0x23ae25a4
0, 151200, 151200, 0, 622080, 0xb13797f8 0, 151200, 151200, 0, 622080, 0x5fb297f7
0, 154800, 154800, 0, 622080, 0x4afe2976 0, 154800, 154800, 0, 622080, 0x99b32978
0, 158400, 158400, 0, 622080, 0xb51e7ca4 0, 158400, 158400, 0, 622080, 0xbac77ca0
0, 162000, 162000, 0, 622080, 0x637fcbfe 0, 162000, 162000, 0, 622080, 0xc1cdcbf9
0, 165600, 165600, 0, 622080, 0x353eed75 0, 165600, 165600, 0, 622080, 0x3276ed72
0, 169200, 169200, 0, 622080, 0xd9a8f5ac 0, 169200, 169200, 0, 622080, 0x4061f5ab
0, 172800, 172800, 0, 622080, 0xf93e92b0 0, 172800, 172800, 0, 622080, 0x264092b2
0, 176400, 176400, 0, 622080, 0x4540039f 0, 176400, 176400, 0, 622080, 0xa4e2039e
0, 180000, 180000, 0, 622080, 0xd0811094 0, 180000, 180000, 0, 622080, 0x20ba1094
0, 183600, 183600, 0, 622080, 0x3039906f 0, 183600, 183600, 0, 622080, 0x984e906e
0, 187200, 187200, 0, 622080, 0xb04a3141 0, 187200, 187200, 0, 622080, 0x76cc3139
0, 190800, 190800, 0, 622080, 0x638d2cf5 0, 190800, 190800, 0, 622080, 0xf70e2cf6
0, 194400, 194400, 0, 622080, 0x4ab84909 0, 194400, 194400, 0, 622080, 0x469a4902
0, 198000, 198000, 0, 622080, 0x82de12ee 0, 198000, 198000, 0, 622080, 0x235312e6
0, 201600, 201600, 0, 622080, 0xa0fcb8fb 0, 201600, 201600, 0, 622080, 0x0ed7b8f5
0, 205200, 205200, 0, 622080, 0x7e849cc9 0, 205200, 205200, 0, 622080, 0xd0269cc3
0, 208800, 208800, 0, 622080, 0x9003aebb 0, 208800, 208800, 0, 622080, 0xdc51aeac
0, 212400, 212400, 0, 622080, 0xffe6f770 0, 212400, 212400, 0, 622080, 0x1aa5f76e
0, 216000, 216000, 0, 622080, 0x153faa3e 0, 216000, 216000, 0, 622080, 0xee06aa36
0, 219600, 219600, 0, 622080, 0xbf023231 0, 219600, 219600, 0, 622080, 0xa7103230
0, 223200, 223200, 0, 622080, 0xae724063 0, 223200, 223200, 0, 622080, 0x7372405f
0, 226800, 226800, 0, 622080, 0x15fe44b4 0, 226800, 226800, 0, 622080, 0x8d7a44b5
0, 230400, 230400, 0, 622080, 0xeb4de77a 0, 230400, 230400, 0, 622080, 0x9e0ee776
0, 234000, 234000, 0, 622080, 0x380f8563 0, 234000, 234000, 0, 622080, 0xd41e8560
0, 237600, 237600, 0, 622080, 0x209ed8c7 0, 237600, 237600, 0, 622080, 0x39e6d8c9
0, 241200, 241200, 0, 622080, 0xb964d70f 0, 241200, 241200, 0, 622080, 0x7a23d70c
0, 244800, 244800, 0, 622080, 0xe2bbac96 0, 244800, 244800, 0, 622080, 0x51d9ac9a
0, 248400, 248400, 0, 622080, 0x57e3f7f2 0, 248400, 248400, 0, 622080, 0x8eacf7f2
0, 252000, 252000, 0, 622080, 0xe945441e 0, 252000, 252000, 0, 622080, 0x2b63441d
0, 255600, 255600, 0, 622080, 0xd0afb742 0, 255600, 255600, 0, 622080, 0x9f71b742
0, 259200, 259200, 0, 622080, 0x8f8cbd5f 0, 259200, 259200, 0, 622080, 0x58afbd5e
0, 262800, 262800, 0, 622080, 0xb9a15294 0, 262800, 262800, 0, 622080, 0x4d645292
0, 266400, 266400, 0, 622080, 0xbc3cf717 0, 266400, 266400, 0, 622080, 0xb972f716
0, 270000, 270000, 0, 622080, 0xb70b01a9 0, 270000, 270000, 0, 622080, 0xbb5d01a2
0, 273600, 273600, 0, 622080, 0x0109f125 0, 273600, 273600, 0, 622080, 0x6a6df129
0, 277200, 277200, 0, 622080, 0x5806371c 0, 277200, 277200, 0, 622080, 0x9e45371e
0, 280800, 280800, 0, 622080, 0x230c373f 0, 280800, 280800, 0, 622080, 0x28b1373d
0, 284400, 284400, 0, 622080, 0x82dfb1f2 0, 284400, 284400, 0, 622080, 0xa1cdb1f2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment