mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
avcodec/me_cmp: add median SAD compare function
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
dcfd24b10c
commit
4edd74bd7c
@ -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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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){
|
|||||||
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 {
|
|||||||
{ "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[] = {
|
|||||||
#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
|
||||||
|
Loading…
Reference in New Issue
Block a user