Ping Wu, Jianhua: > Ping. > > From: Wu, Jianhua <jianhua...@intel.com> > > Sent: Monday, November 22, 2021 4:09 PM > > To: ffmpeg-devel@ffmpeg.org > > Cc: Wu, Jianhua <jianhua...@intel.com> > > Subject: [PATCH v3 1/3] avfilter/x86/vf_exposure: add x86 SIMD > > optimization > > > > Performance data(Less is better): > > exposure_c: 857394 > > exposure_sse: 327589 > > > > Signed-off-by: Wu Jianhua <jianhua...@intel.com> > > --- > > libavfilter/exposure.h | 36 +++++++++++++++++++ > > libavfilter/vf_exposure.c | 36 +++++++++---------- > > libavfilter/x86/Makefile | 2 ++ > > libavfilter/x86/vf_exposure.asm | 55 > > ++++++++++++++++++++++++++++++ > > libavfilter/x86/vf_exposure_init.c | 36 +++++++++++++++++++ > > 5 files changed, 147 insertions(+), 18 deletions(-) create mode > > 100644 libavfilter/exposure.h create mode 100644 > > libavfilter/x86/vf_exposure.asm create mode 100644 > > libavfilter/x86/vf_exposure_init.c > > > > diff --git a/libavfilter/exposure.h b/libavfilter/exposure.h new file > > mode > > 100644 index 0000000000..e76a517826 > > --- /dev/null > > +++ b/libavfilter/exposure.h > > @@ -0,0 +1,36 @@ > > +/* > > + * This file is part of FFmpeg. > > + * > > + * FFmpeg is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2.1 of the License, or (at your option) any later version. > > + * > > + * FFmpeg is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with FFmpeg; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > > +02110-1301 USA */ > > + > > +#ifndef AVFILTER_EXPOSURE_H > > +#define AVFILTER_EXPOSURE_H > > +#include "avfilter.h" > > + > > +typedef struct ExposureContext { > > + const AVClass *class; > > + > > + float exposure; > > + float black; > > + float scale; > > + > > + void (*exposure_func)(float *ptr, int length, float black, float > > +scale); } ExposureContext; > > + > > +void ff_exposure_init(ExposureContext *s); void > > +ff_exposure_init_x86(ExposureContext *s); > > + > > +#endif > > diff --git a/libavfilter/vf_exposure.c b/libavfilter/vf_exposure.c > > index > > 108fba7930..045ae710d3 100644 > > --- a/libavfilter/vf_exposure.c > > +++ b/libavfilter/vf_exposure.c > > @@ -26,23 +26,20 @@ > > #include "formats.h" > > #include "internal.h" > > #include "video.h" > > +#include "exposure.h" > > > > -typedef struct ExposureContext { > > - const AVClass *class; > > - > > - float exposure; > > - float black; > > +static void exposure_c(float *ptr, int length, float black, float > > +scale) { > > + int i; > > > > - float scale; > > - int (*do_slice)(AVFilterContext *s, void *arg, > > - int jobnr, int nb_jobs); > > -} ExposureContext; > > + for (i = 0; i < length; i++) > > + ptr[i] = (ptr[i] - black) * scale; } > > > > static int exposure_slice(AVFilterContext *ctx, void *arg, int jobnr, > > int > > nb_jobs) { > > ExposureContext *s = ctx->priv; > > AVFrame *frame = arg; > > - const int width = frame->width; > > const int height = frame->height; > > const int slice_start = (height * jobnr) / nb_jobs; > > const int slice_end = (height * (jobnr + 1)) / nb_jobs; @@ -52,24 > > +49,27 @@ static int exposure_slice(AVFilterContext *ctx, void *arg, > > int jobnr, int nb_job > > for (int p = 0; p < 3; p++) { > > const int linesize = frame->linesize[p] / 4; > > float *ptr = (float *)frame->data[p] + slice_start * linesize; > > - for (int y = slice_start; y < slice_end; y++) { > > - for (int x = 0; x < width; x++) > > - ptr[x] = (ptr[x] - black) * scale; > > - > > - ptr += linesize; > > - } > > + s->exposure_func(ptr, linesize * (slice_end - slice_start), > > + black, scale); > > } > > > > return 0; > > } > > > > +void ff_exposure_init(ExposureContext *s) { > > + s->exposure_func = exposure_c; > > + > > + if (ARCH_X86) > > + ff_exposure_init_x86(s); > > +} > > + > > static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { > > AVFilterContext *ctx = inlink->dst; > > ExposureContext *s = ctx->priv; > > > > s->scale = 1.f / (exp2f(-s->exposure) - s->black); > > - ff_filter_execute(ctx, s->do_slice, frame, NULL, > > + ff_filter_execute(ctx, exposure_slice, frame, NULL, > > FFMIN(frame->height, > > ff_filter_get_nb_threads(ctx))); > > > > return ff_filter_frame(ctx->outputs[0], frame); @@ -80,7 +80,7 @@ > > static av_cold int config_input(AVFilterLink *inlink) > > AVFilterContext *ctx = inlink->dst; > > ExposureContext *s = ctx->priv; > > > > - s->do_slice = exposure_slice; > > + ff_exposure_init(s); > > > > return 0; > > } > > diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile index > > e87481bd7a..830a1e94cb 100644 > > --- a/libavfilter/x86/Makefile > > +++ b/libavfilter/x86/Makefile > > @@ -8,6 +8,7 @@ OBJS-$(CONFIG_BWDIF_FILTER) += > > x86/vf_bwdif_init.o > > OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp_init.o > > OBJS-$(CONFIG_CONVOLUTION_FILTER) += > x86/vf_convolution_init.o > > OBJS-$(CONFIG_EQ_FILTER) += x86/vf_eq_init.o > > +OBJS-$(CONFIG_EXPOSURE_FILTER) += x86/vf_exposure_init.o > > OBJS-$(CONFIG_FSPP_FILTER) += x86/vf_fspp_init.o > > OBJS-$(CONFIG_GBLUR_FILTER) += x86/vf_gblur_init.o > > OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun_init.o > > @@ -50,6 +51,7 @@ X86ASM-OBJS-$(CONFIG_BWDIF_FILTER) += > > x86/vf_bwdif.o > > X86ASM-OBJS-$(CONFIG_COLORSPACE_FILTER) += x86/colorspacedsp.o > > X86ASM-OBJS-$(CONFIG_CONVOLUTION_FILTER) += > > x86/vf_convolution.o > > X86ASM-OBJS-$(CONFIG_EQ_FILTER) += x86/vf_eq.o > > +X86ASM-OBJS-$(CONFIG_EXPOSURE_FILTER) += x86/vf_exposure.o > > X86ASM-OBJS-$(CONFIG_FRAMERATE_FILTER) += x86/vf_framerate.o > > X86ASM-OBJS-$(CONFIG_FSPP_FILTER) += x86/vf_fspp.o > > X86ASM-OBJS-$(CONFIG_GBLUR_FILTER) += x86/vf_gblur.o > > diff --git a/libavfilter/x86/vf_exposure.asm > > b/libavfilter/x86/vf_exposure.asm new file mode 100644 index > > 0000000000..3351c6fb3b > > --- /dev/null > > +++ b/libavfilter/x86/vf_exposure.asm > > @@ -0,0 +1,55 @@ > > > +;********************************************************* > > ************* > > +******* > > +;* x86-optimized functions for exposure filter > > +;* > > +;* This file is part of FFmpeg. > > +;* > > +;* FFmpeg is free software; you can redistribute it and/or > > +;* modify it under the terms of the GNU Lesser General Public > > +;* License as published by the Free Software Foundation; either > > +;* version 2.1 of the License, or (at your option) any later version. > > +;* > > +;* FFmpeg is distributed in the hope that it will be useful, > > +;* but WITHOUT ANY WARRANTY; without even the implied warranty of > > +;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > GNU > > +;* Lesser General Public License for more details. > > +;* > > +;* You should have received a copy of the GNU Lesser General Public > > +;* License along with FFmpeg; if not, write to the Free Software > > +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > > +02110-1301 USA > > > +;********************************************************* > > ************* > > +******** > > + > > +%include "libavutil/x86/x86util.asm" > > + > > +SECTION .text > > + > > > +;********************************************************* > > ************* > > +********* ; void ff_exposure(float *ptr, int length, float black, > > +float scale); > > > +;********************************************************* > > ************* > > +********* > > +%macro EXPOSURE 0 > > +cglobal exposure, 2, 2, 4, ptr, length, black, scale > > + movsxdifnidn lengthq, lengthd > > +%if WIN64 > > + VBROADCASTSS m0, xmm2 > > + VBROADCASTSS m1, xmm3 > > +%else > > + VBROADCASTSS m0, xmm0 > > + VBROADCASTSS m1, xmm1 > > +%endif > > + > > +.loop: > > + movu m2, [ptrq] > > + subps m2, m2, m0 > > + mulps m2, m2, m1 > > + movu [ptrq], m2 > > + add ptrq, mmsize > > + sub lengthq, mmsize/4 > > + > > + jg .loop > > + > > + RET > > +%endmacro > > + > > +%if ARCH_X86_64 > > +INIT_XMM sse > > +EXPOSURE > > +%endif > > diff --git a/libavfilter/x86/vf_exposure_init.c > > b/libavfilter/x86/vf_exposure_init.c > > new file mode 100644 > > index 0000000000..de1b360f6c > > --- /dev/null > > +++ b/libavfilter/x86/vf_exposure_init.c > > @@ -0,0 +1,36 @@ > > +/* > > + * This file is part of FFmpeg. > > + * > > + * FFmpeg is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2.1 of the License, or (at your option) any later version. > > + * > > + * FFmpeg is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with FFmpeg; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > > +02110-1301 USA */ > > + > > +#include "config.h" > > + > > +#include "libavutil/attributes.h" > > +#include "libavutil/cpu.h" > > +#include "libavutil/x86/cpu.h" > > +#include "libavfilter/exposure.h" > > + > > +void ff_exposure_sse(float *ptr, int length, float black, float > > +scale); > > + > > +av_cold void ff_exposure_init_x86(ExposureContext *s) { > > + int cpu_flags = av_get_cpu_flags(); > > + > > +#if ARCH_X86_64 > > + if (EXTERNAL_SSE(cpu_flags)) > > + s->exposure_func = ff_exposure_sse; #endif } > > -- > > 2.17.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".