Mercurial > mplayer.hg
changeset 15721:eec6ace22741
small change to field-matching metrics which hopefully makes a big
improvement to results. inter-field comparison is now counterbalanced
with intra-field total (vertical) variation. this means that areas of
extreme high frequency content, which become aliased within individual
fields, will not interfere with field matching. examples: white noise
effects, small kanji, very small latin text, ...
may still need tweaking. please report regressions. this change will
likely be made optional in the future (right now it's enclosed in
"if (1)"...
author | rfelker |
---|---|
date | Tue, 14 Jun 2005 05:33:34 +0000 |
parents | e999d58f94fd |
children | b53c4b26dc96 |
files | libmpcodecs/pullup.c libmpcodecs/pullup.h |
diffstat | 2 files changed, 90 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpcodecs/pullup.c Mon Jun 13 20:40:29 2005 +0000 +++ b/libmpcodecs/pullup.c Tue Jun 14 05:33:34 2005 +0000 @@ -147,6 +147,53 @@ ); return ret; } + +static int var_y_mmx(unsigned char *a, unsigned char *b, int s) +{ + int ret; + asm volatile ( + "movl $3, %%ecx \n\t" + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm7, %%mm7 \n\t" + + ".balign 16 \n\t" + "1: \n\t" + + "movq (%%esi), %%mm0 \n\t" + "movq (%%esi), %%mm2 \n\t" + "movq (%%esi,%%eax), %%mm1 \n\t" + "addl %%eax, %%esi \n\t" + "psubusb %%mm1, %%mm2 \n\t" + "psubusb %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm1, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm4 \n\t" + "paddw %%mm1, %%mm4 \n\t" + "paddw %%mm2, %%mm4 \n\t" + "paddw %%mm3, %%mm4 \n\t" + + "decl %%ecx \n\t" + "jnz 1b \n\t" + + "movq %%mm4, %%mm3 \n\t" + "punpcklwd %%mm7, %%mm4 \n\t" + "punpckhwd %%mm7, %%mm3 \n\t" + "paddd %%mm4, %%mm3 \n\t" + "movd %%mm3, %%eax \n\t" + "psrlq $32, %%mm3 \n\t" + "movd %%mm3, %%edx \n\t" + "addl %%edx, %%eax \n\t" + "emms \n\t" + : "=a" (ret) + : "S" (a), "a" (s) + : "%ecx", "%edx" + ); + return 4*ret; +} #endif #endif @@ -195,6 +242,18 @@ } #endif +static int var_y(unsigned char *a, unsigned char *b, int s) +{ + int i, j, var=0; + for (i=3; i; i--) { + for (j=0; j<8; j++) { + var += ABS(a[j]-a[j+s]); + } + a+=s; b+=s; + } + return 4*var; /* match comb scaling */ +} + @@ -307,6 +366,7 @@ { f->diffs = calloc(c->metric_len, sizeof(int)); f->comb = calloc(c->metric_len, sizeof(int)); + f->var = calloc(c->metric_len, sizeof(int)); /* add more metrics here as needed */ } @@ -357,6 +417,7 @@ compute_metric(c, f, parity, f->prev->prev, parity, c->diff, f->diffs); compute_metric(c, parity?f->prev:f, 0, parity?f:f->prev, 1, c->comb, f->comb); + compute_metric(c, f, parity, f, -1, c->var, f->var); /* Advance the circular list */ if (!c->first) c->first = c->head; @@ -463,14 +524,32 @@ f->next->next->flags |= F_HAVE_AFFINITY; return; } - for (i = 0; i < c->metric_len; i++) { - l = f->comb[i] - f->next->comb[i]; - if (l > max_l) max_l = l; - if (-l > max_r) max_r = -l; + if (1) { + for (i = 0; i < c->metric_len; i++) { + int lv = f->prev->var[i]; + int rv = f->next->var[i]; + int v = f->var[i]; + int lc = f->comb[i] - (v+lv) + ABS(v-lv); + int rc = f->next->comb[i] - (v+rv) + ABS(v-rv); + lc = lc>0 ? lc : 0; + rc = rc>0 ? rc : 0; + l = lc - rc; + if (l > max_l) max_l = l; + if (-l > max_r) max_r = -l; + } + if (max_l + max_r < 64) return; + if (max_r > 6*max_l) f->affinity = -1; + else if (max_l > 6*max_r) f->affinity = 1; + } else { + for (i = 0; i < c->metric_len; i++) { + l = f->comb[i] - f->next->comb[i]; + if (l > max_l) max_l = l; + if (-l > max_r) max_r = -l; + } + if (max_l + max_r < 64) return; + if (max_r > 2*max_l) f->affinity = -1; + else if (max_l > 2*max_r) f->affinity = 1; } - if (max_l + max_r < 64) return; - if (max_r > 2*max_l) f->affinity = -1; - else if (max_l > 2*max_r) f->affinity = 1; } static void foo(struct pullup_context *c) @@ -692,11 +771,13 @@ case PULLUP_FMT_Y: c->diff = diff_y; c->comb = licomb_y; + c->var = var_y; #ifdef ARCH_X86 #ifdef HAVE_MMX if (c->cpu & PULLUP_CPU_MMX) { c->diff = diff_y_mmx; c->comb = licomb_y_mmx; + c->var = var_y_mmx; } #endif #endif
--- a/libmpcodecs/pullup.h Mon Jun 13 20:40:29 2005 +0000 +++ b/libmpcodecs/pullup.h Tue Jun 14 05:33:34 2005 +0000 @@ -27,6 +27,7 @@ int affinity; int *diffs; int *comb; + int *var; struct pullup_field *prev, *next; }; @@ -57,6 +58,7 @@ int nbuffers; int (*diff)(unsigned char *, unsigned char *, int); int (*comb)(unsigned char *, unsigned char *, int); + int (*var)(unsigned char *, unsigned char *, int); int metric_w, metric_h, metric_len, metric_offset; struct pullup_frame *frame; };