summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorStanislav Dolganov <dolganov@qst.hk>2016-08-18 14:40:09 +0300
committerMichael Niedermayer <michael@niedermayer.cc>2016-08-22 16:41:33 +0200
commit4edd74bd7c0aaef92d3ef81e627ec7660715e9e1 (patch)
tree1bc6bba98681bfd95847c4bddf92d00ba745e500 /libavcodec
parentdcfd24b10c7eaec4b7b1ec2c4abb46808721a71d (diff)
avcodec/me_cmp: add median SAD compare function
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/avcodec.h33
-rw-r--r--libavcodec/me_cmp.c76
-rw-r--r--libavcodec/me_cmp.h1
-rw-r--r--libavcodec/motion_est.c1
-rw-r--r--libavcodec/mpegvideo.h3
-rw-r--r--libavcodec/options_table.h1
6 files changed, 98 insertions, 17 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 6ac66461ac..e2dad5de6b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2093,22 +2093,23 @@ typedef struct AVCodecContext {
* - decoding: unused
*/
int ildct_cmp;
-#define FF_CMP_SAD 0
-#define FF_CMP_SSE 1
-#define FF_CMP_SATD 2
-#define FF_CMP_DCT 3
-#define FF_CMP_PSNR 4
-#define FF_CMP_BIT 5
-#define FF_CMP_RD 6
-#define FF_CMP_ZERO 7
-#define FF_CMP_VSAD 8
-#define FF_CMP_VSSE 9
-#define FF_CMP_NSSE 10
-#define FF_CMP_W53 11
-#define FF_CMP_W97 12
-#define FF_CMP_DCTMAX 13
-#define FF_CMP_DCT264 14
-#define FF_CMP_CHROMA 256
+#define FF_CMP_SAD 0
+#define FF_CMP_SSE 1
+#define FF_CMP_SATD 2
+#define FF_CMP_DCT 3
+#define FF_CMP_PSNR 4
+#define FF_CMP_BIT 5
+#define FF_CMP_RD 6
+#define FF_CMP_ZERO 7
+#define FF_CMP_VSAD 8
+#define FF_CMP_VSSE 9
+#define FF_CMP_NSSE 10
+#define FF_CMP_W53 11
+#define FF_CMP_W97 12
+#define FF_CMP_DCTMAX 13
+#define FF_CMP_DCT264 14
+#define FF_CMP_MEDIAN_SAD 15
+#define FF_CMP_CHROMA 256
/**
* ME diamond size & shape
diff --git a/libavcodec/me_cmp.c b/libavcodec/me_cmp.c
index dc76b07ba2..6639b919ff 100644
--- a/libavcodec/me_cmp.c
+++ b/libavcodec/me_cmp.c
@@ -139,6 +139,45 @@ static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
return s;
}
+static inline int pix_median_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h)
+{
+ int s = 0, i, j;
+
+#define V(x) (pix1[x] - pix2[x])
+
+ s += abs(V(0));
+ s += abs(V(1) - V(0));
+ s += abs(V(2) - V(1));
+ s += abs(V(3) - V(2));
+ s += abs(V(4) - V(3));
+ s += abs(V(5) - V(4));
+ s += abs(V(6) - V(5));
+ s += abs(V(7) - V(6));
+ s += abs(V(8) - V(7));
+ s += abs(V(9) - V(8));
+ s += abs(V(10) - V(9));
+ s += abs(V(11) - V(10));
+ s += abs(V(12) - V(11));
+ s += abs(V(13) - V(12));
+ s += abs(V(14) - V(13));
+ s += abs(V(15) - V(14));
+
+ pix1 += stride;
+ pix2 += stride;
+
+ for (i = 1; i < h; i++) {
+ s += abs(V(0) - V(-stride));
+ for (j = 1; j < 16; j++)
+ s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1)));
+ pix1 += stride;
+ pix2 += stride;
+
+ }
+#undef V
+ return s;
+}
+
static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
@@ -247,6 +286,37 @@ static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
return s;
}
+static inline int pix_median_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+ ptrdiff_t stride, int h)
+{
+ int s = 0, i, j;
+
+#define V(x) (pix1[x] - pix2[x])
+
+ s += abs(V(0));
+ s += abs(V(1) - V(0));
+ s += abs(V(2) - V(1));
+ s += abs(V(3) - V(2));
+ s += abs(V(4) - V(3));
+ s += abs(V(5) - V(4));
+ s += abs(V(6) - V(5));
+ s += abs(V(7) - V(6));
+
+ pix1 += stride;
+ pix2 += stride;
+
+ for (i = 1; i < h; i++) {
+ s += abs(V(0) - V(-stride));
+ for (j = 1; j < 8; j++)
+ s += abs(V(j) - mid_pred(V(j-stride), V(j-1), V(j-stride) + V(j-1) - V(j-stride-1)));
+ pix1 += stride;
+ pix2 += stride;
+
+ }
+#undef V
+ return s;
+}
+
static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h)
{
@@ -378,6 +448,9 @@ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type)
case FF_CMP_SAD:
cmp[i] = c->sad[i];
break;
+ case FF_CMP_MEDIAN_SAD:
+ cmp[i] = c->median_sad[i];
+ break;
case FF_CMP_SATD:
cmp[i] = c->hadamard8_diff[i];
break;
@@ -993,4 +1066,7 @@ av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
ff_me_cmp_init_x86(c, avctx);
if (ARCH_MIPS)
ff_me_cmp_init_mips(c, avctx);
+
+ c->median_sad[0] = pix_median_abs16_c;
+ c->median_sad[1] = pix_median_abs8_c;
}
diff --git a/libavcodec/me_cmp.h b/libavcodec/me_cmp.h
index a3603ec2c1..5666f59ade 100644
--- a/libavcodec/me_cmp.h
+++ b/libavcodec/me_cmp.h
@@ -76,6 +76,7 @@ typedef struct MECmpContext {
me_cmp_func frame_skip_cmp[6]; // only width 8 used
me_cmp_func pix_abs[2][4];
+ me_cmp_func median_sad[2];
} MECmpContext;
void ff_me_cmp_init_static(void);
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 257d00b59e..25b606f819 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -897,6 +897,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
case FF_CMP_NSSE:
return lambda2>>FF_LAMBDA_SHIFT;
case FF_CMP_BIT:
+ case FF_CMP_MEDIAN_SAD:
return 1;
}
}
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index a1f3d4bd9a..c82fa3e1a1 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -594,7 +594,8 @@ enum rc_strategy {
{ "nsse", "Noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "dct264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCT264 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
{ "dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
-{ "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }
+{ "chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }, \
+{ "msad", "Sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS, "cmp_func" }
#ifndef FF_MPV_OFFSET
#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index adfbe72bff..fe354549a8 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -312,6 +312,7 @@ static const AVOption avcodec_options[] = {
#endif
{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
{"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
+{"msad", "sum of absolute differences, median predicted", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_MEDIAN_SAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
{"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"subq", "sub-pel motion estimation quality", OFFSET(me_subpel_quality), AV_OPT_TYPE_INT, {.i64 = 8 }, INT_MIN, INT_MAX, V|E},
#if FF_API_AFD