[FFmpeg-devel] [PATCH 4/5] avfilter/select: use SAD 16x16 when w/h are multiples of 16
Clément Bœsch
u at pkh.me
Thu Aug 14 23:05:14 CEST 2014
Note: this isn't actually faster. pixelutils_sad_a_16x16_sse2() is ~500
decicyles. pixelutils_sad_8x8_mmxext() is ~240 decicyles. Still, the
overall decode is bigger when using the former. I don't get it.
---
libavfilter/f_select.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c
index e1837db..e4bc52a 100644
--- a/libavfilter/f_select.c
+++ b/libavfilter/f_select.c
@@ -144,6 +144,7 @@ typedef struct SelectContext {
av_pixelutils_sad_fn sad; ///< Sum of the absolute difference function (scene detect only)
double prev_mafd; ///< previous MAFD (scene detect only)
AVFrame *prev_picref; ///< previous frame (scene detect only)
+ int block_size; ///< size of the SAD block (scene detect only)
double select;
int select_out; ///< mark the selected output pad index
int nb_outputs;
@@ -235,7 +236,9 @@ static int config_input(AVFilterLink *inlink)
inlink->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
if (select->do_scene_detect) {
- select->sad = av_pixelutils_get_sad_fn(3, 3, 2, select); // 8x8 both sources aligned
+ const int n = 3 + ((inlink->w & 15) == 0 && (inlink->h & 15) == 0);
+ select->block_size = 1 << n;
+ select->sad = av_pixelutils_get_sad_fn(n, n, 2, select); // 8x8 or 16x16 both sources aligned
if (!select->sad)
return AVERROR(EINVAL);
}
@@ -252,11 +255,12 @@ static double get_scene_score(AVFilterContext *ctx, AVFrame *frame)
frame->height == prev_picref->height &&
frame->width == prev_picref->width) {
double mafd, diff;
- const int nb_sad = (frame->height & ~7) * ((frame->width*3) & ~7);
+ const int bsize = select->block_size;
+ const int nb_sad = (frame->height & ~(bsize-1)) * ((frame->width*3) & ~(bsize-1));
const int64_t sad = av_pixelutils_bdiff(
frame->data[0], frame->linesize[0],
prev_picref->data[0], prev_picref->linesize[0],
- select->sad, frame->width*3, frame->height, 8);
+ select->sad, frame->width*3, frame->height, bsize);
emms_c();
mafd = nb_sad ? (double)sad / nb_sad : 0;
diff = fabs(mafd - select->prev_mafd);
--
2.0.4
More information about the ffmpeg-devel
mailing list