Commit 4edd74bd authored by Stanislav Dolganov's avatar Stanislav Dolganov Committed by Michael Niedermayer

avcodec/me_cmp: add median SAD compare function

Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent dcfd24b1
...@@ -2093,22 +2093,23 @@ typedef struct AVCodecContext { ...@@ -2093,22 +2093,23 @@ typedef struct AVCodecContext {
* - decoding: unused * - decoding: unused
*/ */
int ildct_cmp; int ildct_cmp;
#define FF_CMP_SAD 0 #define FF_CMP_SAD 0
#define FF_CMP_SSE 1 #define FF_CMP_SSE 1
#define FF_CMP_SATD 2 #define FF_CMP_SATD 2
#define FF_CMP_DCT 3 #define FF_CMP_DCT 3
#define FF_CMP_PSNR 4 #define FF_CMP_PSNR 4
#define FF_CMP_BIT 5 #define FF_CMP_BIT 5
#define FF_CMP_RD 6 #define FF_CMP_RD 6
#define FF_CMP_ZERO 7 #define FF_CMP_ZERO 7
#define FF_CMP_VSAD 8 #define FF_CMP_VSAD 8
#define FF_CMP_VSSE 9 #define FF_CMP_VSSE 9
#define FF_CMP_NSSE 10 #define FF_CMP_NSSE 10
#define FF_CMP_W53 11 #define FF_CMP_W53 11
#define FF_CMP_W97 12 #define FF_CMP_W97 12
#define FF_CMP_DCTMAX 13 #define FF_CMP_DCTMAX 13
#define FF_CMP_DCT264 14 #define FF_CMP_DCT264 14
#define FF_CMP_CHROMA 256 #define FF_CMP_MEDIAN_SAD 15
#define FF_CMP_CHROMA 256
/** /**
* ME diamond size & shape * ME diamond size & shape
......
...@@ -139,6 +139,45 @@ static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ...@@ -139,6 +139,45 @@ static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
return s; 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, static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h) ptrdiff_t stride, int h)
{ {
...@@ -247,6 +286,37 @@ static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ...@@ -247,6 +286,37 @@ static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
return s; 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, static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
ptrdiff_t stride, int h) ptrdiff_t stride, int h)
{ {
...@@ -378,6 +448,9 @@ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type) ...@@ -378,6 +448,9 @@ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type)
case FF_CMP_SAD: case FF_CMP_SAD:
cmp[i] = c->sad[i]; cmp[i] = c->sad[i];
break; break;
case FF_CMP_MEDIAN_SAD:
cmp[i] = c->median_sad[i];
break;
case FF_CMP_SATD: case FF_CMP_SATD:
cmp[i] = c->hadamard8_diff[i]; cmp[i] = c->hadamard8_diff[i];
break; break;
...@@ -993,4 +1066,7 @@ av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx) ...@@ -993,4 +1066,7 @@ av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
ff_me_cmp_init_x86(c, avctx); ff_me_cmp_init_x86(c, avctx);
if (ARCH_MIPS) if (ARCH_MIPS)
ff_me_cmp_init_mips(c, avctx); ff_me_cmp_init_mips(c, avctx);
c->median_sad[0] = pix_median_abs16_c;
c->median_sad[1] = pix_median_abs8_c;
} }
...@@ -76,6 +76,7 @@ typedef struct MECmpContext { ...@@ -76,6 +76,7 @@ typedef struct MECmpContext {
me_cmp_func frame_skip_cmp[6]; // only width 8 used me_cmp_func frame_skip_cmp[6]; // only width 8 used
me_cmp_func pix_abs[2][4]; me_cmp_func pix_abs[2][4];
me_cmp_func median_sad[2];
} MECmpContext; } MECmpContext;
void ff_me_cmp_init_static(void); void ff_me_cmp_init_static(void);
......
...@@ -897,6 +897,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){ ...@@ -897,6 +897,7 @@ static inline int get_penalty_factor(int lambda, int lambda2, int type){
case FF_CMP_NSSE: case FF_CMP_NSSE:
return lambda2>>FF_LAMBDA_SHIFT; return lambda2>>FF_LAMBDA_SHIFT;
case FF_CMP_BIT: case FF_CMP_BIT:
case FF_CMP_MEDIAN_SAD:
return 1; return 1;
} }
} }
......
...@@ -594,7 +594,8 @@ enum rc_strategy { ...@@ -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" }, \ { "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" }, \ { "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" }, \ { "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 #ifndef FF_MPV_OFFSET
#define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x) #define FF_MPV_OFFSET(x) offsetof(MpegEncContext, x)
......
...@@ -312,6 +312,7 @@ static const AVOption avcodec_options[] = { ...@@ -312,6 +312,7 @@ static const AVOption avcodec_options[] = {
#endif #endif
{"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"}, {"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"}, {"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}, {"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}, {"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 #if FF_API_AFD
......
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