[FFmpeg-devel] [PATCH 5/5] avfilter/fieldmatch: use av_pixelutils_bdiff()
Clément Bœsch
u at pkh.me
Thu Aug 14 23:05:15 CEST 2014
Not that much relevant from a performance PoV because not called often.
---
libavfilter/vf_fieldmatch.c | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
index e2aa60b..4935a30 100644
--- a/libavfilter/vf_fieldmatch.c
+++ b/libavfilter/vf_fieldmatch.c
@@ -35,6 +35,7 @@
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
+#include "libavutil/pixelutils.h"
#include "libavutil/timestamp.h"
#include "avfilter.h"
#include "internal.h"
@@ -82,6 +83,8 @@ typedef struct {
uint32_t eof; ///< bitmask for end of stream
int64_t lastscdiff;
int64_t lastn;
+ av_pixelutils_sad_fn sad; ///< Sum of the absolute difference function
+ int block_size; ///< size of the SAD block
/* options */
int order;
@@ -161,24 +164,16 @@ static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane)
return plane ? FF_CEIL_RSHIFT(f->height, fm->vsub) : f->height;
}
-static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
+static inline int64_t luma_abs_diff(const FieldMatchContext *fm,
+ const AVFrame *f1, const AVFrame *f2)
{
- int x, y;
- const uint8_t *srcp1 = f1->data[0];
- const uint8_t *srcp2 = f2->data[0];
- const int src1_linesize = f1->linesize[0];
- const int src2_linesize = f2->linesize[0];
- const int width = f1->width;
- const int height = f1->height;
- int64_t acc = 0;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++)
- acc += abs(srcp1[x] - srcp2[x]);
- srcp1 += src1_linesize;
- srcp2 += src2_linesize;
- }
- return acc;
+ const int64_t sad = av_pixelutils_bdiff(
+ f1->data[0], f1->linesize[0],
+ f2->data[0], f2->linesize[0],
+ fm->sad, f1->width, f1->height,
+ fm->block_size);
+ emms_c();
+ return sad;
}
static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
@@ -740,13 +735,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if (fm->lastn == outlink->frame_count - 1) {
if (fm->lastscdiff > fm->scthresh)
sc = 1;
- } else if (luma_abs_diff(fm->prv, fm->src) > fm->scthresh) {
+ } else if (luma_abs_diff(fm, fm->prv, fm->src) > fm->scthresh) {
sc = 1;
}
if (!sc) {
fm->lastn = outlink->frame_count;
- fm->lastscdiff = luma_abs_diff(fm->src, fm->nxt);
+ fm->lastscdiff = luma_abs_diff(fm, fm->src, fm->nxt);
sc = fm->lastscdiff > fm->scthresh;
}
}
@@ -947,9 +942,10 @@ static av_cold void fieldmatch_uninit(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
- const FieldMatchContext *fm = ctx->priv;
+ FieldMatchContext *fm = ctx->priv;
const AVFilterLink *inlink =
ctx->inputs[fm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN];
+ const int n = 3 + ((outlink->w & 15) == 0 && (outlink->h & 15) == 0);
outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP;
outlink->time_base = inlink->time_base;
@@ -957,6 +953,12 @@ static int config_output(AVFilterLink *outlink)
outlink->frame_rate = inlink->frame_rate;
outlink->w = inlink->w;
outlink->h = inlink->h;
+
+ fm->block_size = 1 << n;
+ fm->sad = av_pixelutils_get_sad_fn(n, n, 2, fm); // 8x8 or 16x16 both sources aligned
+ if (!fm->sad)
+ return AVERROR(EINVAL);
+
return 0;
}
--
2.0.4
More information about the ffmpeg-devel
mailing list