вт, 6 мая 2025 г., 02:27 Michael Niedermayer <mich...@niedermayer.cc>:
> This will be available in https://github.com/michaelni/libpostproc > either as a separate library or a ffmpeg source plugin whatever turns > out more convenient to maintain > Congratulations, you broke building cinelerra-gg with ffmpeg.git despite our best efforts :/ Why all this code movement?! For whom it "simple"? > > Sponsored-by: Sovereign Tech Fund > Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > --- > LICENSE.md | 2 - > MAINTAINERS | 2 - > configure | 13 +- > doc/filters.texi | 175 -- > fftools/ffprobe.c | 3 - > fftools/opt_common.c | 3 - > libavfilter/Makefile | 1 - > libavfilter/allfilters.c | 1 - > libavfilter/vf_pp.c | 191 -- > libavutil/avutil.h | 1 - > libpostproc/Makefile | 23 - > libpostproc/libpostproc.v | 7 - > libpostproc/postprocess.c | 992 ------ > libpostproc/postprocess.h | 109 - > libpostproc/postprocess_altivec_template.c | 1214 -------- > libpostproc/postprocess_internal.h | 185 -- > libpostproc/postprocess_template.c | 3293 -------------------- > libpostproc/postprocres.rc | 55 - > libpostproc/tests/.gitignore | 3 - > libpostproc/tests/blocktest.c | 113 - > libpostproc/tests/stripetest.c | 115 - > libpostproc/tests/temptest.c | 106 - > libpostproc/tests/test_utils.c | 38 - > libpostproc/tests/test_utils.h | 27 - > libpostproc/version.c | 45 - > libpostproc/version.h | 48 - > libpostproc/version_major.h | 33 - > tests/Makefile | 1 - > tests/fate/filter-video.mak | 16 - > tests/fate/libpostproc.mak | 14 - > tests/ref/fate/blocktest | 1800 ----------- > tests/ref/fate/filter-pp | 10 - > tests/ref/fate/filter-pp1 | 1 - > tests/ref/fate/filter-pp2 | 1 - > tests/ref/fate/filter-pp3 | 1 - > tests/ref/fate/filter-pp4 | 1 - > tests/ref/fate/filter-pp5 | 1 - > tests/ref/fate/filter-pp6 | 1 - > tests/ref/fate/filter-qp | 1 - > tests/ref/fate/stripetest | 360 --- > tests/ref/fate/temptest | 336 -- > tools/gen-rc | 1 - > 42 files changed, 1 insertion(+), 9342 deletions(-) > delete mode 100644 libavfilter/vf_pp.c > delete mode 100644 libpostproc/Makefile > delete mode 100644 libpostproc/libpostproc.v > delete mode 100644 libpostproc/postprocess.c > delete mode 100644 libpostproc/postprocess.h > delete mode 100644 libpostproc/postprocess_altivec_template.c > delete mode 100644 libpostproc/postprocess_internal.h > delete mode 100644 libpostproc/postprocess_template.c > delete mode 100644 libpostproc/postprocres.rc > delete mode 100644 libpostproc/tests/.gitignore > delete mode 100644 libpostproc/tests/blocktest.c > delete mode 100644 libpostproc/tests/stripetest.c > delete mode 100644 libpostproc/tests/temptest.c > delete mode 100644 libpostproc/tests/test_utils.c > delete mode 100644 libpostproc/tests/test_utils.h > delete mode 100644 libpostproc/version.c > delete mode 100644 libpostproc/version.h > delete mode 100644 libpostproc/version_major.h > delete mode 100644 tests/fate/libpostproc.mak > delete mode 100644 tests/ref/fate/blocktest > delete mode 100644 tests/ref/fate/filter-pp > delete mode 100644 tests/ref/fate/filter-pp1 > delete mode 100644 tests/ref/fate/filter-pp2 > delete mode 100644 tests/ref/fate/filter-pp3 > delete mode 100644 tests/ref/fate/filter-pp4 > delete mode 100644 tests/ref/fate/filter-pp5 > delete mode 100644 tests/ref/fate/filter-pp6 > delete mode 100644 tests/ref/fate/filter-qp > delete mode 100644 tests/ref/fate/stripetest > delete mode 100644 tests/ref/fate/temptest > > diff --git a/LICENSE.md b/LICENSE.md > index 613070e1b63..371b0913ce7 100644 > --- a/LICENSE.md > +++ b/LICENSE.md > @@ -12,7 +12,6 @@ configure to activate them. In this case, FFmpeg's > license changes to GPL v2+. > > Specifically, the GPL parts of FFmpeg are: > > -- libpostproc > - optional x86 optimization in the files > - `libavcodec/x86/flac_dsp_gpl.asm` > - `libavcodec/x86/idct_mmx.c` > @@ -45,7 +44,6 @@ Specifically, the GPL parts of FFmpeg are: > - `vf_owdenoise.c` > - `vf_perspective.c` > - `vf_phase.c` > - - `vf_pp.c` > - `vf_pp7.c` > - `vf_pullup.c` > - `vf_repeatfields.c` > diff --git a/MAINTAINERS b/MAINTAINERS > index f58936db619..7f7faa05959 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -134,8 +134,6 @@ Generic Parts: > ratecontrol.c [2] Michael Niedermayer > simple IDCT: > simple_idct.c, simple_idct.h [2] Michael Niedermayer > - postprocessing: > - libpostproc/* [2] Michael Niedermayer > table generation: > tableprint.c, tableprint.h Reimar Doeffinger > fixed point FFT: > diff --git a/configure b/configure > index 6c23a38be1f..2e69b3c56c3 100755 > --- a/configure > +++ b/configure > @@ -130,7 +130,6 @@ Component options: > --disable-avformat disable libavformat build > --disable-swresample disable libswresample build > --disable-swscale disable libswscale build > - --disable-postproc disable libpostproc build > --disable-avfilter disable libavfilter build > --disable-pthreads disable pthreads [autodetect] > --disable-w32threads disable Win32 threads [autodetect] > @@ -2072,7 +2071,6 @@ LIBRARY_LIST=" > avdevice > avfilter > swscale > - postproc > avformat > avcodec > swresample > @@ -3969,7 +3967,6 @@ pan_filter_deps="swresample" > perspective_filter_deps="gpl" > phase_filter_deps="gpl" > pp7_filter_deps="gpl" > -pp_filter_deps="gpl postproc" > prewitt_opencl_filter_deps="opencl" > procamp_vaapi_filter_deps="vaapi" > program_opencl_filter_deps="opencl" > @@ -4086,8 +4083,6 @@ avfilter_suggest="libm stdatomic spirv_compiler" > avformat_deps="avcodec avutil" > avformat_suggest="libm network zlib stdatomic" > avutil_suggest="clock_gettime ffnvcodec gcrypt libm libdrm libmfx opencl > openssl user32 vaapi vulkan videotoolbox corefoundation corevideo coremedia > bcrypt stdatomic" > -postproc_deps="avutil gpl" > -postproc_suggest="libm stdatomic" > swresample_deps="avutil" > swresample_suggest="libm libsoxr stdatomic" > swscale_deps="avutil" > @@ -7533,7 +7528,7 @@ void (^block)(void); > EOF > > # add some linker flags > -check_ldflags > -Wl,-rpath-link=:libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil > +check_ldflags > -Wl,-rpath-link=:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil > enabled rpath && add_ldexeflags -Wl,-rpath,$libdir && add_ldsoflags > -Wl,-rpath,$libdir > test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic > > @@ -7898,7 +7893,6 @@ enabled fsync_filter && prepend avfilter_deps > "avformat" > enabled mcdeint_filter && prepend avfilter_deps "avcodec" > enabled movie_filter && prepend avfilter_deps "avformat avcodec" > enabled pan_filter && prepend avfilter_deps "swresample" > -enabled pp_filter && prepend avfilter_deps "postproc" > enabled qrencode_filter && prepend avfilter_deps "swscale" > enabled qrencodesrc_filter && prepend avfilter_deps "swscale" > enabled removelogo_filter && prepend avfilter_deps "avformat avcodec > swscale" > @@ -7950,9 +7944,6 @@ expand_deps(){ > reorder_by ${1}_deps LIBRARY_LIST # linking order is expected later > } > > -#we have to remove gpl from the deps here as some code assumes all lib > deps are libs > -postproc_deps="$(filter_out 'gpl' $postproc_deps)" > - > map 'expand_deps $v' $LIBRARY_LIST > > if test "$quiet" != "yes"; then > @@ -8043,7 +8034,6 @@ echo "optimize for size ${small-no}" > echo "optimizations ${optimizations-no}" > echo "static ${static-no}" > echo "shared ${shared-no}" > -echo "postprocessing support ${postproc-no}" > echo "network support ${network-no}" > echo "threading support ${thread_type-no}" > echo "safe bitstream reader ${safe_bitstream_reader-no}" > @@ -8420,7 +8410,6 @@ extralibs_avcodec="$avcodec_extralibs" > extralibs_avformat="$avformat_extralibs" > extralibs_avdevice="$avdevice_extralibs" > extralibs_avfilter="$avfilter_extralibs" > -extralibs_postproc="$postproc_extralibs" > extralibs_swscale="$swscale_extralibs" > extralibs_swresample="$swresample_extralibs" > EOF > diff --git a/doc/filters.texi b/doc/filters.texi > index a9ec077ef04..679b71f2906 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -19387,181 +19387,6 @@ Set window Y position, relative offset on Y axis. > > This filter supports same @ref{commands} as options. > > -@section pp > - > -Enable the specified chain of postprocessing subfilters using > libpostproc. This > -library should be automatically selected with a GPL build > (@code{--enable-gpl}). > -Subfilters must be separated by '/' and can be disabled by prepending a > '-'. > -Each subfilter and some options have a short and a long name that can be > used > -interchangeably, i.e. dr/dering are the same. > - > -The filters accept the following options: > - > -@table @option > -@item subfilters > -Set postprocessing subfilters string. > -@end table > - > -All subfilters share common options to determine their scope: > - > -@table @option > -@item a/autoq > -Honor the quality commands for this subfilter. > - > -@item c/chrom > -Do chrominance filtering, too (default). > - > -@item y/nochrom > -Do luma filtering only (no chrominance). > - > -@item n/noluma > -Do chrominance filtering only (no luma). > -@end table > - > -These options can be appended after the subfilter name, separated by a > '|'. > - > -Available subfilters are: > - > -@table @option > -@item hb/hdeblock[|difference[|flatness]] > -Horizontal deblocking filter > -@table @option > -@item difference > -Difference factor where higher values mean more deblocking (default: > @code{32}). > -@item flatness > -Flatness threshold where lower values mean more deblocking (default: > @code{39}). > -@end table > - > -@item vb/vdeblock[|difference[|flatness]] > -Vertical deblocking filter > -@table @option > -@item difference > -Difference factor where higher values mean more deblocking (default: > @code{32}). > -@item flatness > -Flatness threshold where lower values mean more deblocking (default: > @code{39}). > -@end table > - > -@item ha/hadeblock[|difference[|flatness]] > -Accurate horizontal deblocking filter > -@table @option > -@item difference > -Difference factor where higher values mean more deblocking (default: > @code{32}). > -@item flatness > -Flatness threshold where lower values mean more deblocking (default: > @code{39}). > -@end table > - > -@item va/vadeblock[|difference[|flatness]] > -Accurate vertical deblocking filter > -@table @option > -@item difference > -Difference factor where higher values mean more deblocking (default: > @code{32}). > -@item flatness > -Flatness threshold where lower values mean more deblocking (default: > @code{39}). > -@end table > -@end table > - > -The horizontal and vertical deblocking filters share the difference and > -flatness values so you cannot set different horizontal and vertical > -thresholds. > - > -@table @option > -@item h1/x1hdeblock > -Experimental horizontal deblocking filter > - > -@item v1/x1vdeblock > -Experimental vertical deblocking filter > - > -@item dr/dering > -Deringing filter > - > -@item tn/tmpnoise[|threshold1[|threshold2[|threshold3]]], temporal noise > reducer > -@table @option > -@item threshold1 > -larger -> stronger filtering > -@item threshold2 > -larger -> stronger filtering > -@item threshold3 > -larger -> stronger filtering > -@end table > - > -@item al/autolevels[:f/fullyrange], automatic brightness / contrast > correction > -@table @option > -@item f/fullyrange > -Stretch luma to @code{0-255}. > -@end table > - > -@item lb/linblenddeint > -Linear blend deinterlacing filter that deinterlaces the given block by > -filtering all lines with a @code{(1 2 1)} filter. > - > -@item li/linipoldeint > -Linear interpolating deinterlacing filter that deinterlaces the given > block by > -linearly interpolating every second line. > - > -@item ci/cubicipoldeint > -Cubic interpolating deinterlacing filter deinterlaces the given block by > -cubically interpolating every second line. > - > -@item md/mediandeint > -Median deinterlacing filter that deinterlaces the given block by applying > a > -median filter to every second line. > - > -@item fd/ffmpegdeint > -FFmpeg deinterlacing filter that deinterlaces the given block by > filtering every > -second line with a @code{(-1 4 2 4 -1)} filter. > - > -@item l5/lowpass5 > -Vertically applied FIR lowpass deinterlacing filter that deinterlaces the > given > -block by filtering all lines with a @code{(-1 2 6 2 -1)} filter. > - > -@item fq/forceQuant[|quantizer] > -Overrides the quantizer table from the input with the constant quantizer > you > -specify. > -@table @option > -@item quantizer > -Quantizer to use > -@end table > - > -@item de/default > -Default pp filter combination (@code{hb|a,vb|a,dr|a}) > - > -@item fa/fast > -Fast pp filter combination (@code{h1|a,v1|a,dr|a}) > - > -@item ac > -High quality pp filter combination (@code{ha|a|128|7,va|a,dr|a}) > -@end table > - > -@subsection Examples > - > -@itemize > -@item > -Apply horizontal and vertical deblocking, deringing and automatic > -brightness/contrast: > -@example > -pp=hb/vb/dr/al > -@end example > - > -@item > -Apply default filters without brightness/contrast correction: > -@example > -pp=de/-al > -@end example > - > -@item > -Apply default filters and temporal denoiser: > -@example > -pp=default/tmpnoise|1|2|3 > -@end example > - > -@item > -Apply deblocking on luma only, and switch vertical deblocking on or off > -automatically depending on available CPU time: > -@example > -pp=hb|y/vb|a > -@end example > -@end itemize > - > @section pp7 > Apply Postprocessing filter 7. It is variant of the @ref{spp} filter, > similar to spp = 6 with 7 point DCT, where only the center sample is > diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c > index d980d4e64fe..f33531fd84c 100644 > --- a/fftools/ffprobe.c > +++ b/fftools/ffprobe.c > @@ -62,8 +62,6 @@ > #include "libswscale/version.h" > #include "libswresample/swresample.h" > #include "libswresample/version.h" > -#include "libpostproc/postprocess.h" > -#include "libpostproc/version.h" > #include "libavfilter/version.h" > #include "textformat/avtextformat.h" > #include "cmdutils.h" > @@ -2573,7 +2571,6 @@ static void > ffprobe_show_library_versions(AVTextFormatContext *tfc) > SHOW_LIB_VERSION(avfilter, AVFILTER); > SHOW_LIB_VERSION(swscale, SWSCALE); > SHOW_LIB_VERSION(swresample, SWRESAMPLE); > - SHOW_LIB_VERSION(postproc, POSTPROC); > avtext_print_section_footer(tfc); > } > > diff --git a/fftools/opt_common.c b/fftools/opt_common.c > index 2ac3fd4fb36..c2f6b9de2a7 100644 > --- a/fftools/opt_common.c > +++ b/fftools/opt_common.c > @@ -60,8 +60,6 @@ > #include "libswresample/swresample.h" > #include "libswresample/version.h" > > -#include "libpostproc/postprocess.h" > -#include "libpostproc/version.h" > > enum show_muxdemuxers { > SHOW_DEFAULT, > @@ -191,7 +189,6 @@ static void print_all_libs_info(int flags, int level) > PRINT_LIB_INFO(avfilter, AVFILTER, flags, level); > PRINT_LIB_INFO(swscale, SWSCALE, flags, level); > PRINT_LIB_INFO(swresample, SWRESAMPLE, flags, level); > - PRINT_LIB_INFO(postproc, POSTPROC, flags, level); > } > > static void print_program_info(int flags, int level) > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 7c0d879ec9c..0effe4127ff 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -431,7 +431,6 @@ OBJS-$(CONFIG_PHOTOSENSITIVITY_FILTER) += > vf_photosensitivity.o > OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o > OBJS-$(CONFIG_PIXELIZE_FILTER) += vf_pixelize.o > OBJS-$(CONFIG_PIXSCOPE_FILTER) += vf_datascope.o > -OBJS-$(CONFIG_PP_FILTER) += vf_pp.o qp_table.o > OBJS-$(CONFIG_PP7_FILTER) += vf_pp7.o qp_table.o > OBJS-$(CONFIG_PREMULTIPLY_FILTER) += vf_premultiply.o > framesync.o > OBJS-$(CONFIG_PREWITT_FILTER) += vf_convolution.o > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 740d9ab265c..5ea33cdf01b 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -404,7 +404,6 @@ extern const FFFilter ff_vf_photosensitivity; > extern const FFFilter ff_vf_pixdesctest; > extern const FFFilter ff_vf_pixelize; > extern const FFFilter ff_vf_pixscope; > -extern const FFFilter ff_vf_pp; > extern const FFFilter ff_vf_pp7; > extern const FFFilter ff_vf_premultiply; > extern const FFFilter ff_vf_prewitt; > diff --git a/libavfilter/vf_pp.c b/libavfilter/vf_pp.c > deleted file mode 100644 > index 9e9903eb974..00000000000 > --- a/libavfilter/vf_pp.c > +++ /dev/null > @@ -1,191 +0,0 @@ > -/* > - * Copyright (c) 2002 A'rpi > - * Copyright (C) 2012 Clément Bœsch > - * > - * This file is part of FFmpeg. > - * > - * FFmpeg is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 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 General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License along > - * with FFmpeg; if not, write to the Free Software Foundation, Inc., > - * 51 Franklin Street > <https://www.google.com/maps/search/51+Franklin+Street?entry=gmail&source=g>, > Fifth Floor, Boston, MA 02110-1301 USA. > - */ > - > -/** > - * @file > - * libpostproc filter, ported from MPlayer. > - */ > - > -#include "libavutil/avassert.h" > -#include "libavutil/mem.h" > -#include "libavutil/opt.h" > - > -#include "filters.h" > -#include "qp_table.h" > -#include "video.h" > - > -#include "libpostproc/postprocess.h" > - > -typedef struct PPFilterContext { > - const AVClass *class; > - char *subfilters; > - int mode_id; > - pp_mode *modes[PP_QUALITY_MAX + 1]; > - void *pp_ctx; > -} PPFilterContext; > - > -#define OFFSET(x) offsetof(PPFilterContext, x) > -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > -static const AVOption pp_options[] = { > - { "subfilters", "set postprocess subfilters", OFFSET(subfilters), > AV_OPT_TYPE_STRING, {.str="de"}, .flags = FLAGS }, > - { NULL } > -}; > - > -AVFILTER_DEFINE_CLASS(pp); > - > -static av_cold int pp_init(AVFilterContext *ctx) > -{ > - int i; > - PPFilterContext *pp = ctx->priv; > - > - for (i = 0; i <= PP_QUALITY_MAX; i++) { > - pp->modes[i] = pp_get_mode_by_name_and_quality(pp->subfilters, i); > - if (!pp->modes[i]) > - return AVERROR_EXTERNAL; > - } > - pp->mode_id = PP_QUALITY_MAX; > - return 0; > -} > - > -static int pp_process_command(AVFilterContext *ctx, const char *cmd, > const char *args, > - char *res, int res_len, int flags) > -{ > - PPFilterContext *pp = ctx->priv; > - > - if (!strcmp(cmd, "quality")) { > - pp->mode_id = av_clip(strtol(args, NULL, 10), 0, PP_QUALITY_MAX); > - return 0; > - } > - return AVERROR(ENOSYS); > -} > - > -static const enum AVPixelFormat pix_fmts[] = { > - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, > - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, > - AV_PIX_FMT_YUV411P, > - AV_PIX_FMT_GBRP, > - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, > - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P, > - AV_PIX_FMT_GRAY8, > - AV_PIX_FMT_NONE > -}; > - > -static int pp_config_props(AVFilterLink *inlink) > -{ > - int flags = PP_CPU_CAPS_AUTO; > - PPFilterContext *pp = inlink->dst->priv; > - > - switch (inlink->format) { > - case AV_PIX_FMT_GRAY8: > - case AV_PIX_FMT_YUVJ420P: > - case AV_PIX_FMT_YUV420P: flags |= PP_FORMAT_420; break; > - case AV_PIX_FMT_YUVJ422P: > - case AV_PIX_FMT_YUV422P: flags |= PP_FORMAT_422; break; > - case AV_PIX_FMT_YUV411P: flags |= PP_FORMAT_411; break; > - case AV_PIX_FMT_GBRP: > - case AV_PIX_FMT_YUVJ444P: > - case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; break; > - case AV_PIX_FMT_YUVJ440P: > - case AV_PIX_FMT_YUV440P: flags |= PP_FORMAT_440; break; > - default: av_assert0(0); > - } > - > - pp->pp_ctx = pp_get_context(inlink->w, inlink->h, flags); > - if (!pp->pp_ctx) > - return AVERROR(ENOMEM); > - return 0; > -} > - > -static int pp_filter_frame(AVFilterLink *inlink, AVFrame *inbuf) > -{ > - AVFilterContext *ctx = inlink->dst; > - PPFilterContext *pp = ctx->priv; > - AVFilterLink *outlink = ctx->outputs[0]; > - const int aligned_w = FFALIGN(outlink->w, 8); > - const int aligned_h = FFALIGN(outlink->h, 8); > - AVFrame *outbuf; > - int qstride = 0; > - int8_t *qp_table = NULL; > - int ret; > - > - outbuf = ff_get_video_buffer(outlink, aligned_w, aligned_h); > - if (!outbuf) { > - av_frame_free(&inbuf); > - return AVERROR(ENOMEM); > - } > - av_frame_copy_props(outbuf, inbuf); > - outbuf->width = inbuf->width; > - outbuf->height = inbuf->height; > - > - ret = ff_qp_table_extract(inbuf, &qp_table, &qstride, NULL, NULL); > - if (ret < 0) { > - av_frame_free(&inbuf); > - av_frame_free(&outbuf); > - return ret; > - } > - > - pp_postprocess((const uint8_t **)inbuf->data, inbuf->linesize, > - outbuf->data, outbuf->linesize, > - aligned_w, outlink->h, > - qp_table, > - qstride, > - pp->modes[pp->mode_id], > - pp->pp_ctx, > - outbuf->pict_type | (qp_table ? PP_PICT_TYPE_QP2 : 0)); > - > - av_frame_free(&inbuf); > - av_freep(&qp_table); > - return ff_filter_frame(outlink, outbuf); > -} > - > -static av_cold void pp_uninit(AVFilterContext *ctx) > -{ > - int i; > - PPFilterContext *pp = ctx->priv; > - > - for (i = 0; i <= PP_QUALITY_MAX; i++) > - pp_free_mode(pp->modes[i]); > - if (pp->pp_ctx) > - pp_free_context(pp->pp_ctx); > -} > - > -static const AVFilterPad pp_inputs[] = { > - { > - .name = "default", > - .type = AVMEDIA_TYPE_VIDEO, > - .config_props = pp_config_props, > - .filter_frame = pp_filter_frame, > - }, > -}; > - > -const FFFilter ff_vf_pp = { > - .p.name = "pp", > - .p.description = NULL_IF_CONFIG_SMALL("Filter video using > libpostproc."), > - .p.priv_class = &pp_class, > - .p.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, > - .priv_size = sizeof(PPFilterContext), > - .init = pp_init, > - .uninit = pp_uninit, > - FILTER_INPUTS(pp_inputs), > - FILTER_OUTPUTS(ff_video_default_filterpad), > - FILTER_PIXFMTS_ARRAY(pix_fmts), > - .process_command = pp_process_command, > -}; > diff --git a/libavutil/avutil.h b/libavutil/avutil.h > index ee709fbb2ab..c8ae114ab6f 100644 > --- a/libavutil/avutil.h > +++ b/libavutil/avutil.h > @@ -41,7 +41,6 @@ > * @li @ref lavd "libavdevice" special devices muxing/demuxing library > * @li @ref lavu "libavutil" common utility library > * @li @ref lswr "libswresample" audio resampling, format conversion and > mixing > - * @li @ref lpp "libpostproc" post processing library > * @li @ref libsws "libswscale" color conversion and scaling library > * > * @section ffmpeg_versioning Versioning and compatibility > diff --git a/libpostproc/Makefile b/libpostproc/Makefile > deleted file mode 100644 > index d78fc0277f4..00000000000 > --- a/libpostproc/Makefile > +++ /dev/null > @@ -1,23 +0,0 @@ > -NAME = postproc > -DESC = FFmpeg postprocessing library > -FFLIBS = avutil > - > -HEADERS = postprocess.h \ > - version.h \ > - version_major.h \ > - > -OBJS = postprocess.o \ > - version.o \ > - > -TESTOBJS = tests/test_utils.o \ > - > -# Windows resource file > -SHLIBOBJS-$(HAVE_GNU_WINDRES) += postprocres.o > - > -TESTPROGS = blocktest \ > - stripetest \ > - temptest \ > - > -$(SUBDIR)tests/blocktest$(EXESUF): $(SUBDIR)tests/test_utils.o > -$(SUBDIR)tests/stripetest$(EXESUF): $(SUBDIR)tests/test_utils.o > -$(SUBDIR)tests/temptest$(EXESUF): $(SUBDIR)tests/test_utils.o > diff --git a/libpostproc/libpostproc.v b/libpostproc/libpostproc.v > deleted file mode 100644 > index 27381c6aca3..00000000000 > --- a/libpostproc/libpostproc.v > +++ /dev/null > @@ -1,7 +0,0 @@ > -LIBPOSTPROC_MAJOR { > - global: > - postproc_*; > - pp_*; > - local: > - *; > -}; > diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c > deleted file mode 100644 > index eab22289192..00000000000 > --- a/libpostproc/postprocess.c > +++ /dev/null > @@ -1,992 +0,0 @@ > -/* > - * Copyright (C) 2001-2003 Michael Niedermayer (michae...@gmx.at) > - * > - * AltiVec optimizations (C) 2004 Romain Dolbeau <rom...@dolbeau.org> > - * > - * This file is part of FFmpeg. > - * > - * FFmpeg is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 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 General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with FFmpeg; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street > <https://www.google.com/maps/search/51+Franklin+Street?entry=gmail&source=g>, > Fifth Floor, Boston, MA 02110-1301 USA > - */ > - > -/** > - * @file > - * postprocessing. > - */ > - > -/* > - C MMX MMX2 AltiVec > -isVertDC Ec Ec Ec > -isVertMinMaxOk Ec Ec Ec > -doVertLowPass E e Ec > -doVertDefFilter Ec Ec e Ec > -isHorizDC Ec Ec Ec > -isHorizMinMaxOk a E Ec > -doHorizLowPass E e Ec > -doHorizDefFilter Ec Ec e Ec > -do_a_deblock Ec E Ec > -deRing E e Ecp > -Vertical RKAlgo1 E a > -Horizontal RKAlgo1 a > -Vertical X1# a E > -Horizontal X1# a E > -LinIpolDeinterlace e E > -CubicIpolDeinterlace a e > -LinBlendDeinterlace e E > -MedianDeinterlace# E Ec Ec > -TempDeNoiser# E e Ec > - > -# more or less selfinvented filters so the exactness is not too meaningful > -E = Exact implementation > -e = almost exact implementation (slightly different rounding,...) > -a = alternative / approximate impl > -c = checked against the other implementations (-vo md5) > -p = partially optimized, still some work to do > -*/ > - > -/* > -TODO: > -reduce the time wasted on the mem transfer > -unroll stuff if instructions depend too much on the prior one > -move YScale thing to the end instead of fixing QP > -write a faster and higher quality deblocking filter :) > -make the mainloop more flexible (variable number of blocks at once > - (the if/else stuff per block is slowing things down) > -compare the quality & speed of all filters > -split this huge file > -optimize c versions > -try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks > -... > -*/ > - > -//Changelog: use git log > - > -#include <stddef.h> > -#include <stdlib.h> > -#include <string.h> > - > -#include "config.h" > -#include "libavutil/common.h" > -#include "libavutil/cpu.h" > -#include "libavutil/intreadwrite.h" > -#include "libavutil/mem.h" > -//#undef HAVE_MMXEXT_INLINE > -//#undef HAVE_MMX_INLINE > -//#undef ARCH_X86 > -//#define DEBUG_BRIGHTNESS > -#include "postprocess.h" > -#include "postprocess_internal.h" > -#include "libavutil/avstring.h" > - > -#define GET_MODE_BUFFER_SIZE 500 > -#define OPTIONS_ARRAY_SIZE 10 > -#define BLOCK_SIZE 8 > -#define TEMP_STRIDE 8 > -//#define NUM_BLOCKS_AT_ONCE 16 //not used yet > - > -#define DERING_THRESHOLD 20 > - > -#if ARCH_X86 && HAVE_INLINE_ASM > -DECLARE_ASM_CONST(8, uint64_t, w05)= 0x0005000500050005LL; > -DECLARE_ASM_CONST(8, uint64_t, w04)= 0x0004000400040004LL; > -DECLARE_ASM_CONST(8, uint64_t, w20)= 0x0020002000200020LL; > -DECLARE_ASM_CONST(8, uint64_t, b00)= 0x0000000000000000LL; > -DECLARE_ASM_CONST(8, uint64_t, b01)= 0x0101010101010101LL; > -DECLARE_ASM_CONST(8, uint64_t, b08)= 0x0808080808080808LL; > -DECLARE_ASM_CONST(8, uint64_t, b80)= 0x8080808080808080LL; > -#endif > - > -static const struct PPFilter filters[]= > -{ > - {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK}, > - {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, > -/* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER}, > - {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/ > - {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, > - {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, > - {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK}, > - {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK}, > - {"dr", "dering", 1, 5, 6, DERING}, > - {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, > - {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER}, > - {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER}, > - {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER}, > - {"md", "mediandeint", 1, 1, 4, MEDIAN_DEINT_FILTER}, > - {"fd", "ffmpegdeint", 1, 1, 4, FFMPEG_DEINT_FILTER}, > - {"l5", "lowpass5", 1, 1, 4, LOWPASS5_DEINT_FILTER}, > - {"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER}, > - {"fq", "forcequant", 1, 0, 0, FORCE_QUANT}, > - {"be", "bitexact", 1, 0, 0, BITEXACT}, > - {"vi", "visualize", 1, 0, 0, VISUALIZE}, > - {NULL, NULL,0,0,0,0} //End Marker > -}; > - > -static const char * const replaceTable[]= > -{ > - "default", "hb:a,vb:a,dr:a", > - "de", "hb:a,vb:a,dr:a", > - "fast", "h1:a,v1:a,dr:a", > - "fa", "h1:a,v1:a,dr:a", > - "ac", "ha:a:128:7,va:a,dr:a", > - NULL //End Marker > -}; > - > -/* The horizontal functions exist only in C because the MMX > - * code is faster with vertical filters and transposing. */ > - > -/** > - * Check if the given 8x8 Block is mostly "flat" > - */ > -static inline int isHorizDC_C(const uint8_t src[], int stride, const > PPContext *c) > -{ > - int numEq= 0; > - int y; > - const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; > - const int dcThreshold= dcOffset*2 + 1; > - > - for(y=0; y<BLOCK_SIZE; y++){ > - numEq += ((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold; > - numEq += ((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold; > - src+= stride; > - } > - return numEq > c->ppMode.flatnessThreshold; > -} > - > -/** > - * Check if the middle 8x8 Block in the given 8x16 block is flat > - */ > -static inline int isVertDC_C(const uint8_t src[], int stride, const > PPContext *c) > -{ > - int numEq= 0; > - int y; > - const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; > - const int dcThreshold= dcOffset*2 + 1; > - > - src+= stride*4; // src points to begin of the 8x8 Block > - for(y=0; y<BLOCK_SIZE-1; y++){ > - numEq += ((unsigned)(src[0] - src[0+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[1] - src[1+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[2] - src[2+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[3] - src[3+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[4] - src[4+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[5] - src[5+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[6] - src[6+stride] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[7] - src[7+stride] + dcOffset)) < > dcThreshold; > - src+= stride; > - } > - return numEq > c->ppMode.flatnessThreshold; > -} > - > -static inline int isHorizMinMaxOk_C(const uint8_t src[], int stride, int > QP) > -{ > - int i; > - for(i=0; i<2; i++){ > - if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0; > - src += stride; > - if((unsigned)(src[2] - src[7] + 2*QP) > 4*QP) return 0; > - src += stride; > - if((unsigned)(src[4] - src[1] + 2*QP) > 4*QP) return 0; > - src += stride; > - if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0; > - src += stride; > - } > - return 1; > -} > - > -static inline int isVertMinMaxOk_C(const uint8_t src[], int stride, int > QP) > -{ > - int x; > - src+= stride*4; > - for(x=0; x<BLOCK_SIZE; x+=4){ > - if((unsigned)(src[ x + 0*stride] - src[ x + 5*stride] + 2*QP) > > 4*QP) return 0; > - if((unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > > 4*QP) return 0; > - if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > > 4*QP) return 0; > - if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > > 4*QP) return 0; > - } > - return 1; > -} > - > -static inline int horizClassify_C(const uint8_t src[], int stride, const > PPContext *c) > -{ > - if( isHorizDC_C(src, stride, c) ){ > - return isHorizMinMaxOk_C(src, stride, c->QP); > - }else{ > - return 2; > - } > -} > - > -static inline int vertClassify_C(const uint8_t src[], int stride, const > PPContext *c) > -{ > - if( isVertDC_C(src, stride, c) ){ > - return isVertMinMaxOk_C(src, stride, c->QP); > - }else{ > - return 2; > - } > -} > - > -static inline void doHorizDefFilter_C(uint8_t dst[], int stride, const > PPContext *c) > -{ > - int y; > - for(y=0; y<BLOCK_SIZE; y++){ > - const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]); > - > - if(FFABS(middleEnergy) < 8*c->QP){ > - const int q=(dst[3] - dst[4])/2; > - const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - > dst[3]); > - const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - > dst[7]); > - > - int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), > FFABS(rightEnergy) ); > - d= FFMAX(d, 0); > - > - d= (5*d + 32) >> 6; > - d*= FFSIGN(-middleEnergy); > - > - if(q>0) > - { > - d = FFMAX(d, 0); > - d = FFMIN(d, q); > - } > - else > - { > - d = FFMIN(d, 0); > - d = FFMAX(d, q); > - } > - > - dst[3]-= d; > - dst[4]+= d; > - } > - dst+= stride; > - } > -} > - > -/** > - * Do a horizontal low pass filter on the 10x8 block (dst points to > middle 8x8 Block) > - * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version) > - */ > -static inline void doHorizLowPass_C(uint8_t dst[], int stride, const > PPContext *c) > -{ > - int y; > - for(y=0; y<BLOCK_SIZE; y++){ > - const int first= FFABS(dst[-1] - dst[0]) < c->QP ? dst[-1] : > dst[0]; > - const int last= FFABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7]; > - > - int sums[10]; > - sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4; > - sums[1] = sums[0] - first + dst[3]; > - sums[2] = sums[1] - first + dst[4]; > - sums[3] = sums[2] - first + dst[5]; > - sums[4] = sums[3] - first + dst[6]; > - sums[5] = sums[4] - dst[0] + dst[7]; > - sums[6] = sums[5] - dst[1] + last; > - sums[7] = sums[6] - dst[2] + last; > - sums[8] = sums[7] - dst[3] + last; > - sums[9] = sums[8] - dst[4] + last; > - > - dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4; > - dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4; > - dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4; > - dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4; > - dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4; > - dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4; > - dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4; > - dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4; > - > - dst+= stride; > - } > -} > - > -/** > - * Experimental Filter 1 (Horizontal) > - * will not damage linear gradients > - * Flat blocks should look like they were passed through the > (1,1,2,2,4,2,2,1,1) 9-Tap filter > - * can only smooth blocks at the expected locations (it cannot smooth > them if they did move) > - * MMX2 version does correct clipping C version does not > - * not identical with the vertical one > - */ > -static inline void horizX1Filter(uint8_t *src, int stride, int QP) > -{ > - int y; > - static uint64_t lut[256]; > - if(!lut[255]) > - { > - int i; > - for(i=0; i<256; i++) > - { > - int v= i < 128 ? 2*i : 2*(i-256); > -/* > -//Simulate 112242211 9-Tap filter > - uint64_t a= (v/16) & 0xFF; > - uint64_t b= (v/8) & 0xFF; > - uint64_t c= (v/4) & 0xFF; > - uint64_t d= (3*v/8) & 0xFF; > -*/ > -//Simulate piecewise linear interpolation > - uint64_t a= (v/16) & 0xFF; > - uint64_t b= (v*3/16) & 0xFF; > - uint64_t c= (v*5/16) & 0xFF; > - uint64_t d= (7*v/16) & 0xFF; > - uint64_t A= (0x100 - a)&0xFF; > - uint64_t B= (0x100 - b)&0xFF; > - uint64_t C= (0x100 - c)&0xFF; > - uint64_t D= (0x100 - c)&0xFF; > - > - lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) | > - (D<<24) | (C<<16) | (B<<8) | (A); > - //lut[i] = (v<<32) | (v<<24); > - } > - } > - > - for(y=0; y<BLOCK_SIZE; y++){ > - int a= src[1] - src[2]; > - int b= src[3] - src[4]; > - int c= src[5] - src[6]; > - > - int d= FFMAX(FFABS(b) - (FFABS(a) + FFABS(c))/2, 0); > - > - if(d < QP){ > - int v = d * FFSIGN(-b); > - > - src[1] +=v/8; > - src[2] +=v/4; > - src[3] +=3*v/8; > - src[4] -=3*v/8; > - src[5] -=v/4; > - src[6] -=v/8; > - } > - src+=stride; > - } > -} > - > -/** > - * accurate deblock filter > - */ > -static av_always_inline void do_a_deblock_C(uint8_t *src, int step, > - int stride, const PPContext > *c, int mode) > -{ > - int y; > - const int QP= c->QP; > - const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; > - const int dcThreshold= dcOffset*2 + 1; > - > - src+= step*4; // src points to begin of the 8x8 Block > - for(y=0; y<8; y++){ > - int numEq= 0; > - > - numEq += ((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < > dcThreshold; > - numEq += ((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < > dcThreshold; > - if(numEq > c->ppMode.flatnessThreshold){ > - int min, max, x; > - > - if(src[0] > src[step]){ > - max= src[0]; > - min= src[step]; > - }else{ > - max= src[step]; > - min= src[0]; > - } > - for(x=2; x<8; x+=2){ > - if(src[x*step] > src[(x+1)*step]){ > - if(src[x *step] > max) max= src[ x *step]; > - if(src[(x+1)*step] < min) min= src[(x+1)*step]; > - }else{ > - if(src[(x+1)*step] > max) max= src[(x+1)*step]; > - if(src[ x *step] < min) min= src[ x *step]; > - } > - } > - if(max-min < 2*QP){ > - const int first= FFABS(src[-1*step] - src[0]) < QP ? > src[-1*step] : src[0]; > - const int last= FFABS(src[8*step] - src[7*step]) < QP ? > src[8*step] : src[7*step]; > - > - int sums[10]; > - sums[0] = 4*first + src[0*step] + src[1*step] + > src[2*step] + 4; > - sums[1] = sums[0] - first + src[3*step]; > - sums[2] = sums[1] - first + src[4*step]; > - sums[3] = sums[2] - first + src[5*step]; > - sums[4] = sums[3] - first + src[6*step]; > - sums[5] = sums[4] - src[0*step] + src[7*step]; > - sums[6] = sums[5] - src[1*step] + last; > - sums[7] = sums[6] - src[2*step] + last; > - sums[8] = sums[7] - src[3*step] + last; > - sums[9] = sums[8] - src[4*step] + last; > - > - if (mode & VISUALIZE) { > - src[0*step] = > - src[1*step] = > - src[2*step] = > - src[3*step] = > - src[4*step] = > - src[5*step] = > - src[6*step] = > - src[7*step] = 128; > - } > - src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4; > - src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4; > - src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4; > - src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4; > - src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4; > - src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4; > - src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4; > - src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4; > - } > - }else{ > - const int middleEnergy= 5*(src[4*step] - src[3*step]) + > 2*(src[2*step] - src[5*step]); > - > - if(FFABS(middleEnergy) < 8*QP){ > - const int q=(src[3*step] - src[4*step])/2; > - const int leftEnergy= 5*(src[2*step] - src[1*step]) + > 2*(src[0*step] - src[3*step]); > - const int rightEnergy= 5*(src[6*step] - src[5*step]) + > 2*(src[4*step] - src[7*step]); > - > - int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), > FFABS(rightEnergy) ); > - d= FFMAX(d, 0); > - > - d= (5*d + 32) >> 6; > - d*= FFSIGN(-middleEnergy); > - > - if(q>0){ > - d = FFMAX(d, 0); > - d = FFMIN(d, q); > - }else{ > - d = FFMIN(d, 0); > - d = FFMAX(d, q); > - } > - > - if ((mode & VISUALIZE) && d) { > - d= (d < 0) ? 32 : -32; > - src[3*step]= av_clip_uint8(src[3*step] - d); > - src[4*step]= av_clip_uint8(src[4*step] + d); > - d = 0; > - } > - > - src[3*step]-= d; > - src[4*step]+= d; > - } > - } > - > - src += stride; > - } > -} > - > -//Note: we have C and SSE2 version (which uses MMX(EXT) when advantageous) > -//Plain C versions > -//we always compile C for testing which needs bitexactness > -#define TEMPLATE_PP_C 1 > -#include "postprocess_template.c" > - > -#if HAVE_ALTIVEC > -#include "libavutil/ppc/util_altivec.h" > - > -# define TEMPLATE_PP_ALTIVEC 1 > -# include "postprocess_altivec_template.c" > -# include "postprocess_template.c" > -#endif > - > -#if ARCH_X86 && HAVE_INLINE_ASM > -# if CONFIG_RUNTIME_CPUDETECT > -# define TEMPLATE_PP_SSE2 1 > -# include "postprocess_template.c" > -# else > -# if HAVE_SSE2_INLINE > -# define TEMPLATE_PP_SSE2 1 > -# include "postprocess_template.c" > -# endif > -# endif > -#endif > - > -typedef void (*pp_fn)(const uint8_t src[], int srcStride, uint8_t dst[], > int dstStride, int width, int height, > - const int8_t QPs[], int QPStride, int isColor, > PPContext *c2); > - > -static inline void postProcess(const uint8_t src[], int srcStride, > uint8_t dst[], int dstStride, int width, int height, > - const int8_t QPs[], int QPStride, int isColor, pp_mode *vm, > pp_context *vc) > -{ > - pp_fn pp = postProcess_C; > - PPContext *c= (PPContext *)vc; > - PPMode *ppMode= (PPMode *)vm; > - c->ppMode= *ppMode; //FIXME > - > - if (!(ppMode->lumMode & BITEXACT)) { > -#if CONFIG_RUNTIME_CPUDETECT > -#if ARCH_X86 && HAVE_INLINE_ASM > - // ordered per speed fastest first > - if (c->cpuCaps & AV_CPU_FLAG_SSE2) pp = postProcess_SSE2; > -#elif HAVE_ALTIVEC > - if (c->cpuCaps & AV_CPU_FLAG_ALTIVEC) pp = > postProcess_altivec; > -#endif > -#else /* CONFIG_RUNTIME_CPUDETECT */ > -#if HAVE_SSE2_INLINE > - pp = postProcess_SSE2; > -#elif HAVE_ALTIVEC > - pp = postProcess_altivec; > -#endif > -#endif /* !CONFIG_RUNTIME_CPUDETECT */ > - } > - > - pp(src, srcStride, dst, dstStride, width, height, QPs, QPStride, > isColor, c); > -} > - > -/* -pp Command line Help > -*/ > -const char pp_help[] = > -"Available postprocessing filters:\n" > -"Filters Options\n" > -"short long name short long option Description\n" > -"* * a autoq CPU power dependent > enabler\n" > -" c chrom chrominance filtering > enabled\n" > -" y nochrom chrominance filtering > disabled\n" > -" n noluma luma filtering disabled\n" > -"hb hdeblock (2 threshold) horizontal deblocking > filter\n" > -" 1. difference factor: default=32, higher -> more deblocking\n" > -" 2. flatness threshold: default=39, lower -> more deblocking\n" > -" the h & v deblocking filters share these\n" > -" so you can't set different thresholds for h / v\n" > -"vb vdeblock (2 threshold) vertical deblocking > filter\n" > -"ha hadeblock (2 threshold) horizontal deblocking > filter\n" > -"va vadeblock (2 threshold) vertical deblocking > filter\n" > -"h1 x1hdeblock experimental h deblock > filter 1\n" > -"v1 x1vdeblock experimental v deblock > filter 1\n" > -"dr dering deringing filter\n" > -"al autolevels automatic brightness / > contrast\n" > -" f fullyrange stretch luminance to > (0..255)\n" > -"lb linblenddeint linear blend > deinterlacer\n" > -"li linipoldeint linear interpolating > deinterlace\n" > -"ci cubicipoldeint cubic interpolating > deinterlacer\n" > -"md mediandeint median deinterlacer\n" > -"fd ffmpegdeint ffmpeg deinterlacer\n" > -"l5 lowpass5 FIR lowpass > deinterlacer\n" > -"de default hb:a,vb:a,dr:a\n" > -"fa fast h1:a,v1:a,dr:a\n" > -"ac ha:a:128:7,va:a,dr:a\n" > -"tn tmpnoise (3 threshold) temporal noise reducer\n" > -" 1. <= 2. <= 3. larger -> stronger > filtering\n" > -"fq forceQuant <quantizer> force quantizer\n" > -"Usage:\n" > > -"<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" > -"long form example:\n" > -"vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n" > -"short form example:\n" > -"vb:a/hb:a/lb de,-vb\n" > -"more examples:\n" > -"tn:64:128:256\n" > -"\n" > -; > - > -pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality) > -{ > - char temp[GET_MODE_BUFFER_SIZE]; > - char *p= temp; > - static const char filterDelimiters[] = ",/"; > - static const char optionDelimiters[] = ":|"; > - struct PPMode *ppMode; > - char *filterToken; > - > - if (!name) { > - av_log(NULL, AV_LOG_ERROR, "pp: Missing argument\n"); > - return NULL; > - } > - > - if (!strcmp(name, "help")) { > - const char *p; > - for (p = pp_help; strchr(p, '\n'); p = strchr(p, '\n') + 1) { > - av_strlcpy(temp, p, FFMIN(sizeof(temp), strchr(p, '\n') - p + > 2)); > - av_log(NULL, AV_LOG_INFO, "%s", temp); > - } > - return NULL; > - } > - > - ppMode= av_malloc(sizeof(PPMode)); > - if (!ppMode) > - return NULL; > - > - ppMode->lumMode= 0; > - ppMode->chromMode= 0; > - ppMode->maxTmpNoise[0]= 700; > - ppMode->maxTmpNoise[1]= 1500; > - ppMode->maxTmpNoise[2]= 3000; > - ppMode->maxAllowedY= 234; > - ppMode->minAllowedY= 16; > - ppMode->baseDcDiff= 256/8; > - ppMode->flatnessThreshold= 56-16-1; > - ppMode->maxClippedThreshold= (AVRational){1,100}; > - ppMode->error=0; > - > - memset(temp, 0, GET_MODE_BUFFER_SIZE); > - av_strlcpy(temp, name, GET_MODE_BUFFER_SIZE - 1); > - > - av_log(NULL, AV_LOG_DEBUG, "pp: %s\n", name); > - > - for(;;){ > - const char *filterName; > - int q= 1000000; //PP_QUALITY_MAX; > - int chrom=-1; > - int luma=-1; > - const char *option; > - const char *options[OPTIONS_ARRAY_SIZE]; > - int i; > - int filterNameOk=0; > - int numOfUnknownOptions=0; > - int enable=1; //does the user want us to enabled or disabled the > filter > - char *tokstate; > - > - filterToken= av_strtok(p, filterDelimiters, &tokstate); > - if(!filterToken) break; > - p+= strlen(filterToken) + 1; // p points to next filterToken > - filterName= av_strtok(filterToken, optionDelimiters, &tokstate); > - if (!filterName) { > - ppMode->error++; > - break; > - } > - av_log(NULL, AV_LOG_DEBUG, "pp: %s::%s\n", filterToken, > filterName); > - > - if(*filterName == '-'){ > - enable=0; > - filterName++; > - } > - > - for(;;){ //for all options > - option= av_strtok(NULL, optionDelimiters, &tokstate); > - if(!option) break; > - > - av_log(NULL, AV_LOG_DEBUG, "pp: option: %s\n", option); > - if(!strcmp("autoq", option) || !strcmp("a", option)) q= > quality; > - else if(!strcmp("nochrom", option) || !strcmp("y", option)) > chrom=0; > - else if(!strcmp("chrom", option) || !strcmp("c", option)) > chrom=1; > - else if(!strcmp("noluma", option) || !strcmp("n", option)) > luma=0; > - else{ > - options[numOfUnknownOptions] = option; > - numOfUnknownOptions++; > - } > - if(numOfUnknownOptions >= OPTIONS_ARRAY_SIZE-1) break; > - } > - options[numOfUnknownOptions] = NULL; > - > - /* replace stuff from the replace Table */ > - for(i=0; replaceTable[2*i]; i++){ > - if(!strcmp(replaceTable[2*i], filterName)){ > - size_t newlen = strlen(replaceTable[2*i + 1]); > - int plen; > - int spaceLeft; > - > - p--, *p=','; > - > - plen= strlen(p); > - spaceLeft= p - temp + plen; > - if(spaceLeft + newlen >= GET_MODE_BUFFER_SIZE - 1){ > - ppMode->error++; > - break; > - } > - memmove(p + newlen, p, plen+1); > - memcpy(p, replaceTable[2*i + 1], newlen); > - filterNameOk=1; > - } > - } > - > - for(i=0; filters[i].shortName; i++){ > - if( !strcmp(filters[i].longName, filterName) > - || !strcmp(filters[i].shortName, filterName)){ > - ppMode->lumMode &= ~filters[i].mask; > - ppMode->chromMode &= ~filters[i].mask; > - > - filterNameOk=1; > - if(!enable) break; // user wants to disable it > - > - if(q >= filters[i].minLumQuality && luma) > - ppMode->lumMode|= filters[i].mask; > - if(chrom==1 || (chrom==-1 && filters[i].chromDefault)) > - if(q >= filters[i].minChromQuality) > - ppMode->chromMode|= filters[i].mask; > - > - if(filters[i].mask == LEVEL_FIX){ > - int o; > - ppMode->minAllowedY= 16; > - ppMode->maxAllowedY= 234; > - for(o=0; options[o]; o++){ > - if( !strcmp(options[o],"fullyrange") > - ||!strcmp(options[o],"f")){ > - ppMode->minAllowedY= 0; > - ppMode->maxAllowedY= 255; > - numOfUnknownOptions--; > - } > - } > - } > - else if(filters[i].mask == TEMP_NOISE_FILTER) > - { > - int o; > - int numOfNoises=0; > - > - for(o=0; options[o]; o++){ > - char *tail; > - ppMode->maxTmpNoise[numOfNoises]= > - strtol(options[o], &tail, 0); > - if(tail!=options[o]){ > - numOfNoises++; > - numOfUnknownOptions--; > - if(numOfNoises >= 3) break; > - } > - } > - } > - else if(filters[i].mask == V_DEBLOCK || filters[i].mask > == H_DEBLOCK > - || filters[i].mask == V_A_DEBLOCK || filters[i].mask > == H_A_DEBLOCK){ > - int o; > - > - for(o=0; options[o] && o<2; o++){ > - char *tail; > - int val= strtol(options[o], &tail, 0); > - if(tail==options[o]) break; > - > - numOfUnknownOptions--; > - if(o==0) ppMode->baseDcDiff= val; > - else ppMode->flatnessThreshold= val; > - } > - } > - else if(filters[i].mask == FORCE_QUANT){ > - int o; > - ppMode->forcedQuant= 15; > - > - for(o=0; options[o] && o<1; o++){ > - char *tail; > - int val= strtol(options[o], &tail, 0); > - if(tail==options[o]) break; > - > - numOfUnknownOptions--; > - ppMode->forcedQuant= val; > - } > - } > - } > - } > - if(!filterNameOk) ppMode->error++; > - ppMode->error += numOfUnknownOptions; > - } > - > - av_log(NULL, AV_LOG_DEBUG, "pp: lumMode=%X, chromMode=%X\n", > ppMode->lumMode, ppMode->chromMode); > - if(ppMode->error){ > - av_log(NULL, AV_LOG_ERROR, "%d errors in postprocess string > \"%s\"\n", ppMode->error, name); > - av_free(ppMode); > - return NULL; > - } > - return ppMode; > -} > - > -void pp_free_mode(pp_mode *mode){ > - av_free(mode); > -} > - > -static void reallocAlign(void **p, int size){ > - av_free(*p); > - *p= av_mallocz(size); > -} > - > -static void reallocBuffers(PPContext *c, int width, int height, int > stride, int qpStride){ > - int mbWidth = (width+15)>>4; > - int mbHeight= (height+15)>>4; > - int i; > - > - c->stride= stride; > - c->qpStride= qpStride; > - > - reallocAlign((void **)&c->tempDst, stride*24+32); > - reallocAlign((void **)&c->tempSrc, stride*24); > - reallocAlign((void **)&c->tempBlocks, 2*16*8); > - reallocAlign((void **)&c->yHistogram, 256*sizeof(uint64_t)); > - for(i=0; i<256; i++) > - c->yHistogram[i]= width*height/64*15/256; > - > - for(i=0; i<3; i++){ > - //Note: The +17*1024 is just there so I do not have to worry > about r/w over the end. > - reallocAlign((void **)&c->tempBlurred[i], stride*mbHeight*16 + > 17*1024); > - reallocAlign((void **)&c->tempBlurredPast[i], > 256*((height+7)&(~7))/2 + 17*1024);//FIXME size > - } > - > - reallocAlign((void **)&c->deintTemp, 2*width+32); > - reallocAlign((void **)&c->nonBQPTable, > qpStride*mbHeight*sizeof(int8_t)); > - reallocAlign((void **)&c->stdQPTable, > qpStride*mbHeight*sizeof(int8_t)); > - reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(int8_t)); > -} > - > -static const char * context_to_name(void * ptr) { > - return "postproc"; > -} > - > -static const AVClass av_codec_context_class = { "Postproc", > context_to_name, NULL }; > - > -av_cold pp_context *pp_get_context(int width, int height, int cpuCaps){ > - PPContext *c= av_mallocz(sizeof(PPContext)); > - int stride= FFALIGN(width, 16); //assumed / will realloc if needed > - int qpStride= (width+15)/16 + 2; //assumed / will realloc if needed > - > - if (!c) > - return NULL; > - > - c->av_class = &av_codec_context_class; > - if(cpuCaps&PP_FORMAT){ > - c->hChromaSubSample= cpuCaps&0x3; > - c->vChromaSubSample= (cpuCaps>>4)&0x3; > - }else{ > - c->hChromaSubSample= 1; > - c->vChromaSubSample= 1; > - } > - if (cpuCaps & PP_CPU_CAPS_AUTO) { > - c->cpuCaps = av_get_cpu_flags(); > - } else { > - c->cpuCaps = 0; > - if (cpuCaps & PP_CPU_CAPS_ALTIVEC) c->cpuCaps |= > AV_CPU_FLAG_ALTIVEC; > - } > - > - reallocBuffers(c, width, height, stride, qpStride); > - > - c->frameNum=-1; > - > - return c; > -} > - > -av_cold void pp_free_context(void *vc){ > - PPContext *c = (PPContext*)vc; > - int i; > - > - for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurred); i++) > - av_free(c->tempBlurred[i]); > - for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurredPast); i++) > - av_free(c->tempBlurredPast[i]); > - > - av_free(c->tempBlocks); > - av_free(c->yHistogram); > - av_free(c->tempDst); > - av_free(c->tempSrc); > - av_free(c->deintTemp); > - av_free(c->stdQPTable); > - av_free(c->nonBQPTable); > - av_free(c->forcedQPTable); > - > - memset(c, 0, sizeof(PPContext)); > - > - av_free(c); > -} > - > -void pp_postprocess(const uint8_t * src[3], const int srcStride[3], > - uint8_t * dst[3], const int dstStride[3], > - int width, int height, > - const int8_t *QP_store, int QPStride, > - pp_mode *vm, void *vc, int pict_type) > -{ > - int mbWidth = (width+15)>>4; > - int mbHeight= (height+15)>>4; > - PPMode *mode = vm; > - PPContext *c = vc; > - int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0])); > - int absQPStride = FFABS(QPStride); > - > - if (width < 16 || height < 16) { > - av_log(c, AV_LOG_ERROR, "Postproc is designed to filter 16x16 > macroblock based formats, the minimum size is 1 macroblock\n"); > - return; > - } > - > - // c->stride and c->QPStride are always positive > - if(c->stride < minStride || c->qpStride < absQPStride) > - reallocBuffers(c, width, height, > - FFMAX(minStride, c->stride), > - FFMAX(c->qpStride, absQPStride)); > - > - if(!QP_store || (mode->lumMode & FORCE_QUANT)){ > - int i; > - QP_store= c->forcedQPTable; > - absQPStride = QPStride = 0; > - if(mode->lumMode & FORCE_QUANT) > - for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= > mode->forcedQuant; > - else > - for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= 1; > - } > - > - if(pict_type & PP_PICT_TYPE_QP2){ > - int i; > - const int count= FFMAX(mbHeight * absQPStride, mbWidth); > - for(i=0; i<(count>>2); i++){ > - AV_WN32(c->stdQPTable + (i<<2), AV_RN32(QP_store + (i<<2)) >> > 1 & 0x7F7F7F7F); > - } > - for(i<<=2; i<count; i++){ > - c->stdQPTable[i] = QP_store[i]>>1; > - } > - QP_store= c->stdQPTable; > - QPStride= absQPStride; > - } > - > - if(0){ > - int x,y; > - for(y=0; y<mbHeight; y++){ > - for(x=0; x<mbWidth; x++){ > - av_log(c, AV_LOG_INFO, "%2d ", QP_store[x + y*QPStride]); > - } > - av_log(c, AV_LOG_INFO, "\n"); > - } > - av_log(c, AV_LOG_INFO, "\n"); > - } > - > - if((pict_type&7)!=3){ > - if (QPStride >= 0){ > - int i; > - const int count= FFMAX(mbHeight * QPStride, mbWidth); > - for(i=0; i<(count>>2); i++){ > - AV_WN32(c->nonBQPTable + (i<<2), AV_RN32(QP_store + > (i<<2)) & 0x3F3F3F3F); > - } > - for(i<<=2; i<count; i++){ > - c->nonBQPTable[i] = QP_store[i] & 0x3F; > - } > - } else { > - int i,j; > - for(i=0; i<mbHeight; i++) { > - for(j=0; j<absQPStride; j++) { > - c->nonBQPTable[i*absQPStride+j] = > QP_store[i*QPStride+j] & 0x3F; > - } > - } > - } > - } > - > - av_log(c, AV_LOG_DEBUG, "using npp filters 0x%X/0x%X\n", > - mode->lumMode, mode->chromMode); > - > - postProcess(src[0], srcStride[0], dst[0], dstStride[0], > - width, height, QP_store, QPStride, 0, mode, c); > - > - if (!(src[1] && src[2] && dst[1] && dst[2])) > - return; > - > - width = (width )>>c->hChromaSubSample; > - height = (height)>>c->vChromaSubSample; > - > - if(mode->chromMode){ > - postProcess(src[1], srcStride[1], dst[1], dstStride[1], > - width, height, QP_store, QPStride, 1, mode, c); > - postProcess(src[2], srcStride[2], dst[2], dstStride[2], > - width, height, QP_store, QPStride, 2, mode, c); > - } > - else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){ > - linecpy(dst[1], src[1], height, srcStride[1]); > - linecpy(dst[2], src[2], height, srcStride[2]); > - }else{ > - int y; > - for(y=0; y<height; y++){ > - memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), > width); > - memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), > width); > - } > - } > -} > diff --git a/libpostproc/postprocess.h b/libpostproc/postprocess.h > deleted file mode 100644 > index d2adb6ccad7..00000000000 > --- a/libpostproc/postprocess.h > +++ /dev/null > @@ -1,109 +0,0 @@ > -/* > - * Copyright (C) 2001-2003 Michael Niedermayer (michae...@gmx.at) > - * > - * This file is part of FFmpeg. > - * > - * FFmpeg is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 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 General Public License for more details. > - * > - * You should have received a copy of the GNU General Public License > - * along with FFmpeg; if not, write to the Free Software > - * Foundation, Inc., 51 Franklin Street > <https://www.google.com/maps/search/51+Franklin+Street?entry=gmail&source=g>, > Fifth Floor, Boston, MA 02110-1301 USA > - */ > - > -#ifndef POSTPROC_POSTPROCESS_H > -#define POSTPROC_POSTPROCESS_H > - > -/** > - * @file > - * @ingroup lpp > - * external API header > - */ > - > -/** > - * @defgroup lpp libpostproc > - * Video postprocessing library. > - * > - * @{ > - */ > - > -#include "libpostproc/version_major.h" > -#ifndef HAVE_AV_CONFIG_H > -/* When included as part of the ffmpeg build, only include the major > version > - * to avoid unnecessary rebuilds. When included externally, keep including > - * the full version information. */ > -#include "libpostproc/version.h" > -#endif > - > -/** > - * Return the LIBPOSTPROC_VERSION_INT constant. > - */ > -unsigned postproc_version(void); > - > -/** > - * Return the libpostproc build-time configuration. > - */ > -const char *postproc_configuration(void); > - > -/** > - * Return the libpostproc license. > - */ > -const char *postproc_license(void); > - > -#define PP_QUALITY_MAX 6 > - > -#include <inttypes.h> > - > -typedef void pp_context; > -typedef void pp_mode; > - > -extern const char pp_help[]; ///< a simple help text > - > -void pp_postprocess(const uint8_t * src[3], const int srcStride[3], > - uint8_t * dst[3], const int dstStride[3], > - int horizontalSize, int verticalSize, > - const int8_t *QP_store, int QP_stride, > - pp_mode *mode, pp_context *ppContext, int pict_type); > - > - > -/** > - * Return a pp_mode or NULL if an error occurred. > - * > - * @param name the string after "-pp" on the command line > - * @param quality a number from 0 to PP_QUALITY_MAX > - */ > -pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality); > -void pp_free_mode(pp_mode *mode); > - > -pp_context *pp_get_context(int width, int height, int flags); > -void pp_free_context(pp_context *ppContext); > - > -#define PP_CPU_CAPS_MMX 0x80000000 > -#define PP_CPU_CAPS_MMX2 0x20000000 > -#if FF_API_PP_AMD_3DNOW > -#define PP_CPU_CAPS_3DNOW 0x40000000 > -#endif > -#define PP_CPU_CAPS_ALTIVEC 0x10000000 > -#define PP_CPU_CAPS_AUTO 0x00080000 > - > -#define PP_FORMAT 0x00000008 > -#define PP_FORMAT_420 (0x00000011|PP_FORMAT) > -#define PP_FORMAT_422 (0x00000001|PP_FORMAT) > -#define PP_FORMAT_411 (0x00000002|PP_FORMAT) > -#define PP_FORMAT_444 (0x00000000|PP_FORMAT) > -#define PP_FORMAT_440 (0x00000010|PP_FORMAT) > - > -#define PP_PICT_TYPE_QP2 0x00000010 ///< MPEG2 style QScale > - > -/** > - * @} > - */ > - > -#endif /* POSTPROC_POSTPROCESS_H */ > diff --git a/libpostproc/postprocess_altivec_template.c > b/libpostproc/postprocess_altivec_template.c > deleted file mode 100644 > index feddab50356..00000000000 > --- a/libpostproc/postprocess_altivec_template.c > +++ /dev/null > @@ -1,1214 +0,0 @@ > -/* > - * AltiVec optimizations (C) 2004 Romain Dolbeau <rom...@dolbeau.org> > - * > - * based on code by Copyright (C) 2001-2003 Michael Niedermayer ( > michae...@gmx.at) > - * > - * This file is part of FFmpeg. > - * > - * FFmpeg is free software; you can redistribute it and/or modify > - * it under the terms of the GNU General Public License as published by > - * the Free Software Foundation; either version 2 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 General Public License for more details. > - * > - * You should have received a copy of the GNU 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/avutil.h" > -#include "libavutil/mem_internal.h" > - > -#define > ALTIVEC_TRANSPOSE_8x8_SHORT(src_a,src_b,src_c,src_d,src_e,src_f,src_g,src_h) > \ > - do { \ > - __typeof__(src_a) tempA1, tempB1, tempC1, tempD1; \ > - __typeof__(src_a) tempE1, tempF1, tempG1, tempH1; \ > - __typeof__(src_a) tempA2, tempB2, tempC2, tempD2; \ > - __typeof__(src_a) tempE2, tempF2, tempG2, tempH2; \ > - tempA1 = vec_mergeh (src_a, src_e); \ > - tempB1 = vec_mergel (src_a, src_e); \ > - tempC1 = vec_mergeh (src_b, src_f); \ > - tempD1 = vec_mergel (src_b, src_f); \ > - tempE1 = vec_mergeh (src_c, src_g); \ > - tempF1 = vec_mergel (src_c, src_g); \ > - tempG1 = vec_mergeh (src_d, src_h); \ > - tempH1 = vec_mergel (src_d, src_h); \ > - tempA2 = vec_mergeh (tempA1, tempE1); \ > - tempB2 = vec_mergel (tempA1, tempE1); \ > - tempC2 = vec_mergeh (tempB1, tempF1); \ > - tempD2 = vec_mergel (tempB1, tempF1); \ > - tempE2 = vec_mergeh (tempC1, tempG1); \ > - tempF2 = vec_mergel (tempC1, tempG1); \ > - tempG2 = vec_mergeh (tempD1, tempH1); \ > - tempH2 = vec_mergel (tempD1, tempH1); \ > - src_a = vec_mergeh (tempA2, tempE2); \ > - src_b = vec_mergel (tempA2, tempE2); \ > - src_c = vec_mergeh (tempB2, tempF2); \ > - src_d = vec_mergel (tempB2, tempF2); \ > - src_e = vec_mergeh (tempC2, tempG2); \ > - src_f = vec_mergel (tempC2, tempG2); \ > - src_g = vec_mergeh (tempD2, tempH2); \ > - src_h = vec_mergel (tempD2, tempH2); \ > - } while (0) > - > - > -static inline int vertClassify_altivec(uint8_t src[], int stride, > PPContext *c) { > - /* > - this code makes no assumption on src or stride. > - One could remove the recomputation of the perm > - vector by assuming (stride % 16) == 0, unfortunately > - this is not always true. > - */ > - short data_0 = ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; > - DECLARE_ALIGNED(16, short, data)[8] = > - { > - data_0, > - data_0 * 2 + 1, > - c->QP * 2, > - c->QP * 4 > - }; > - int numEq; > - uint8_t *src2 = src; > - vector signed short v_dcOffset; > - vector signed short v2QP; > - vector unsigned short v4QP; > - vector unsigned short v_dcThreshold; > - const int properStride = (stride % 16); > - const int srcAlign = ((unsigned long)src2 % 16); > - const int two_vectors = ((srcAlign > 8) || properStride) ? 1 : 0; > - const vector signed int zero = vec_splat_s32(0); > - const vector signed short mask = vec_splat_s16(1); > - vector signed int v_numEq = vec_splat_s32(0); > - vector signed short v_data = vec_ld(0, data); > - vector signed short v_srcAss0, v_srcAss1, v_srcAss2, v_srcAss3, > - v_srcAss4, v_srcAss5, v_srcAss6, v_srcAss7; > -//FIXME avoid this mess if possible > - register int j0 = 0, > - j1 = stride, > - j2 = 2 * stride, > - j3 = 3 * stride, > - j4 = 4 * stride, > - j5 = 5 * stride, > - j6 = 6 * stride, > - j7 = 7 * stride; > - vector unsigned char v_srcA0, v_srcA1, v_srcA2, v_srcA3, > - v_srcA4, v_srcA5, v_srcA6, v_srcA7; > - > - v_dcOffset = vec_splat(v_data, 0); > - v_dcThreshold = (vector unsigned short)vec_splat(v_data, 1); > - v2QP = vec_splat(v_data, 2); > - v4QP = (vector unsigned short)vec_splat(v_data, 3); > - > - src2 += stride * 4; > - > -#define LOAD_LINE(i) \ > - { \ > - vector unsigned char perm##i = vec_lvsl(j##i, src2); \ > - vector unsigned char v_srcA2##i; \ > - vector unsigned char v_srcA1##i = vec_ld(j##i, src2); \ > - if (two_vectors) \ > - v_srcA2##i = vec_ld(j##i + 16, src2); \ > - v_srcA##i = \ > - vec_perm(v_srcA1##i, v_srcA2##i, perm##i); \ > - v_srcAss##i = \ > - (vector signed short)vec_mergeh((vector signed char)zero, \ > - (vector signed char)v_srcA##i); } > - > -#define LOAD_LINE_ALIGNED(i) \ > - v_srcA##i = vec_ld(j##i, src2); \ > - v_srcAss##i = \ > - (vector signed short)vec_mergeh((vector signed char)zero, \ > - (vector signed char)v_srcA##i) > - > - /* Special-casing the aligned case is worthwhile, as all calls from > - * the (transposed) horizontable deblocks will be aligned, in addition > - * to the naturally aligned vertical deblocks. */ > - if (properStride && srcAlign) { > - LOAD_LINE_ALIGNED(0); > - LOAD_LINE_ALIGNED(1); > - LOAD_LINE_ALIGNED(2); > - LOAD_LINE_ALIGNED(3); > - LOAD_LINE_ALIGNED(4); > - LOAD_LINE_ALIGNED(5); > - LOAD_LINE_ALIGNED(6); > - LOAD_LINE_ALIGNED(7); > - } else { > - LOAD_LINE(0); > - LOAD_LINE(1); > - LOAD_LINE(2); > - LOAD_LINE(3); > - LOAD_LINE(4); > - LOAD_LINE(5); > - LOAD_LINE(6); > - LOAD_LINE(7); > - } > -#undef LOAD_LINE > -#undef LOAD_LINE_ALIGNED > - > -#define ITER(i, j) \ > - const vector signed short v_diff##i = \ > - vec_sub(v_srcAss##i, v_srcAss##j); \ > - const vector signed short v_sum##i = \ > - vec_add(v_diff##i, v_dcOffset); \ > - const vector signed short v_comp##i = \ > - (vector signed short)vec_cmplt((vector unsigned short)v_sum##i, \ > - v_dcThreshold); \ > - const vector signed short v_part##i = vec_and(mask, v_comp##i); > - > - { > - ITER(0, 1) > - ITER(1, 2) > - ITER(2, 3) > - ITER(3, 4) > - ITER(4, 5) > - ITER(5, 6) > - ITER(6, 7) > - > - v_numEq = vec_sum4s(v_part0, v_numEq); > - v_numEq = vec_sum4s(v_part1, v_numEq); > - v_numEq = vec_sum4s(v_part2, v_numEq); > - v_numEq = vec_sum4s(v_part3, v_numEq); > - v_numEq = vec_sum4s(v_part4, v_numEq); > - v_numEq = vec_sum4s(v_part5, v_numEq); > - v_numEq = vec_sum4s(v_part6, v_numEq); > - } > - > -#undef ITER > - > - v_numEq = vec_sums(v_numEq, zero); > - > - v_numEq = vec_splat(v_numEq, 3); > - vec_ste(v_numEq, 0, &numEq); > - > - if (numEq > c->ppMode.flatnessThreshold){ > - const vector unsigned char mmoP1 = (const vector unsigned char) > - {0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, > - 0x00, 0x01, 0x12, 0x13, 0x08, 0x09, 0x1A, 0x1B}; > - const vector unsigned char mmoP2 = (const vector unsigned char) > - {0x04, 0x05, 0x16, 0x17, 0x0C, 0x0D, 0x1E, 0x1F, > - 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}; > - const vector unsigned char mmoP = (const vector unsigned char) > - vec_lvsl(8, (unsigned char*)0); > - > - vector signed short mmoL1 = vec_perm(v_srcAss0, v_srcAss2, mmoP1); > - vector signed short mmoL2 = vec_perm(v_srcAss4, v_srcAss6, mmoP2); > - vector signed short mmoL = vec_perm(mmoL1, mmoL2, mmoP); > - vector signed short mmoR1 = vec_perm(v_srcAss5, v_srcAss7, mmoP1); > - vector signed short mmoR2 = vec_perm(v_srcAss1, v_srcAss3, mmoP2); > - vector signed short mmoR = vec_perm(mmoR1, mmoR2, mmoP); > - vector signed short mmoDiff = vec_sub(mmoL, mmoR); > - vector unsigned short mmoSum = (vector unsigned > short)vec_add(mmoDiff, v2QP); > - > - if (vec_any_gt(mmoSum, v4QP)) > - return 0; > - else > - return 1; > - } > - else return 2; > -} > - > -static inline void doVertLowPass_altivec(uint8_t *src, int stride, > PPContext *c) { > - /* > - this code makes no assumption on src or stride. > - One could remove the recomputation of the perm > - vector by assuming (stride % 16) == 0, unfortunately > - this is not always true. Quite a lot of load/stores > - can be removed by assuming proper alignment of > - src & stride :-( > - */ > - uint8_t *src2 = src; > - const vector signed int zero = vec_splat_s32(0); > - const int properStride = (stride % 16); > - const int srcAlign = ((unsigned long)src2 % 16); > - DECLARE_ALIGNED(16, short, qp)[8] = {c->QP}; > - vector signed short vqp = vec_ld(0, qp); > - vector signed short vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7, vb8, vb9; > - vector unsigned char vbA0, av_uninit(vbA1), av_uninit(vbA2), > av_uninit(vbA3), av_uninit(vbA4), av_uninit(vbA5), av_uninit(vbA6), > av_uninit(vbA7), av_uninit(vbA8), vbA9; > - vector unsigned char vbB0, av_uninit(vbB1), av_uninit(vbB2), > av_uninit(vbB3), av_uninit(vbB4), av_uninit(vbB5), av_uninit(vbB6), > av_uninit(vbB7), av_uninit(vbB8), vbB9; > - vector unsigned char vbT0, vbT1, vbT2, vbT3, vbT4, vbT5, vbT6, vbT7, > vbT8, vbT9; > - vector unsigned char perml0, perml1, perml2, perml3, perml4, > - perml5, perml6, perml7, perml8, perml9; > - register int j0 = 0, > - j1 = stride, > - j2 = 2 * stride, > - j3 = 3 * stride, > - j4 = 4 * stride, > - j5 = 5 * stride, > - j6 = 6 * stride, > - j7 = 7 * stride, > - j8 = 8 * stride, > - j9 = 9 * stride; > - > - vqp = vec_splat(vqp, 0); > - > - src2 += stride*3; > - > -#define LOAD_LINE(i) \ > - perml##i = vec_lvsl(i * stride, src2); \ > - vbA##i = vec_ld(i * stride, src2); \ > - vbB##i = vec_ld(i * stride + 16, src2); \ > - vbT##i = vec_perm(vbA##i, vbB##i, perml##i); \ > - vb##i = \ > - (vector signed short)vec_mergeh((vector unsigned char)zero, \ > - (vector unsigned char)vbT##i) > - > -#define LOAD_LINE_ALIGNED(i) \ > - vbT##i = vec_ld(j##i, src2); \ > - vb##i = \ > - (vector signed short)vec_mergeh((vector signed char)zero, \ > - (vector signed char)vbT##i) > - > - /* Special-casing the aligned case is worthwhile, as all calls from > - * the (transposed) horizontable deblocks will be aligned, in > addition > - * to the naturally aligned vertical deblocks. */ > - if (properStride && srcAlign) { > - LOAD_LINE_ALIGNED(0); > - LOAD_LINE_ALIGNED(1); > - LOAD_LINE_ALIGNED(2); > - LOAD_LINE_ALIGNED(3); > - LOAD_LINE_ALIGNED(4); > - LOAD_LINE_ALIGNED(5); > - LOAD_LINE_ALIGNED(6); > - LOAD_LINE_ALIGNED(7); > - LOAD_LINE_ALIGNED(8); > - LOAD_LINE_ALIGNED(9); > - } else { > - LOAD_LINE(0); > - LOAD_LINE(1); > - LOAD_LINE(2); > - LOAD_LINE(3); > - LOAD_LINE(4); > - LOAD_LINE(5); > - LOAD_LINE(6); > - LOAD_LINE(7); > - LOAD_LINE(8); > - LOAD_LINE(9); > - } > -#undef LOAD_LINE > -#undef LOAD_LINE_ALIGNED > - { > - const vector unsigned short v_2 = vec_splat_u16(2); > - const vector unsigned short v_4 = vec_splat_u16(4); > - > - const vector signed short v_diff01 = vec_sub(vb0, vb1); > - const vector unsigned short v_cmp01 = > - (const vector unsigned short) vec_cmplt(vec_abs(v_diff01), > vqp); > - const vector signed short v_first = vec_sel(vb1, vb0, v_cmp01); > - const vector signed short v_diff89 = vec_sub(vb8, vb9); > - const vector unsigned short v_cmp89 = > - (const vector unsigned short) vec_cmplt(vec_abs(v_diff89), > vqp); > - const vector signed short v_last = vec_sel(vb8, vb9, v_cmp89); > - > - const vector signed short temp01 = vec_mladd(v_first, (vector > signed short)v_4, vb1); > - const vector signed short temp02 = vec_add(vb2, vb3); > - const vector signed short temp03 = vec_add(temp01, (vector signed > short)v_4); > - const vector signed short v_sumsB0 = vec_add(temp02, temp03); > - > - const vector signed short temp11 = vec_sub(v_sumsB0, v_first); > - const vector signed short v_sumsB1 = vec_add(temp11, vb4); > - > - const vector signed short temp21 = vec_sub(v_sumsB1, v_first); > - const vector signed short v_sumsB2 = vec_add(temp21, vb5); > - > - const vector signed short temp31 = vec_sub(v_sumsB2, v_first); > - const vector signed short v_sumsB3 = vec_add(temp31, vb6); > - > - const vector signed short temp41 = vec_sub(v_sumsB3, v_first); > - const vector signed short v_sumsB4 = vec_add(temp41, vb7); > - > - const vector signed short temp51 = vec_sub(v_sumsB4, vb1); > - const vector signed short v_sumsB5 = vec_add(temp51, vb8); > - > - const vector signed short temp61 = vec_sub(v_sumsB5, vb2); > - const vector signed short v_sumsB6 = vec_add(temp61, v_last); > - > - const vector signed short temp71 = vec_sub(v_sumsB6, vb3); > - const vector signed short v_sumsB7 = vec_add(temp71, v_last); > - > - const vector signed short temp81 = vec_sub(v_sumsB7, vb4); > - const vector signed short v_sumsB8 = vec_add(temp81, v_last); > - > - const vector signed short temp91 = vec_sub(v_sumsB8, vb5); > - const vector signed short v_sumsB9 = vec_add(temp91, v_last); > - > - #define COMPUTE_VR(i, j, k) > \ > - const vector signed short temps1##i = > \ > - vec_add(v_sumsB##i, v_sumsB##k); > \ > - const vector signed short temps2##i = > \ > - vec_mladd(vb##j, (vector signed short)v_2, temps1##i); > \ > - const vector signed short vr##j = vec_sra(temps2##i, v_4) > - > - COMPUTE_VR(0, 1, 2); > - COMPUTE_VR(1, 2, 3); > - COMPUTE_VR(2, 3, 4); > - COMPUTE_VR(3, 4, 5); > - COMPUTE_VR(4, 5, 6); > - COMPUTE_VR(5, 6, 7); > - COMPUTE_VR(6, 7, 8); > - COMPUTE_VR(7, 8, 9); > - > - const vector signed char neg1 = vec_splat_s8(-1); > - const vector unsigned char permHH = (const vector unsigned > char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, > - > 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}; > - > -#define PACK_AND_STORE(i) \ > -{ const vector unsigned char perms##i = \ > - vec_lvsr(i * stride, src2); \ > - const vector unsigned char vf##i = \ > - vec_packsu(vr##i, (vector signed short)zero); \ > - const vector unsigned char vg##i = \ > - vec_perm(vf##i, vbT##i, permHH); \ > - const vector unsigned char mask##i = \ > - vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, > perms##i); \ > - const vector unsigned char vg2##i = \ > - vec_perm(vg##i, vg##i, perms##i); \ > - const vector unsigned char svA##i = \ > - vec_sel(vbA##i, vg2##i, mask##i); \ > - const vector unsigned char svB##i = \ > - vec_sel(vg2##i, vbB##i, mask##i); \ > - vec_st(svA##i, i * stride, src2); \ > - vec_st(svB##i, i * stride + 16, src2);} > - > -#define PACK_AND_STORE_ALIGNED(i) \ > -{ const vector unsigned char vf##i = \ > - vec_packsu(vr##i, (vector signed short)zero); \ > - const vector unsigned char vg##i = \ > - vec_perm(vf##i, vbT##i, permHH); \ > - vec_st(vg##i, i * stride, src2);} > - > - /* Special-casing the aligned case is worthwhile, as all calls > from > - * the (transposed) horizontable deblocks will be aligned, in > addition > - * to the naturally aligned vertical deblocks. */ > - if (properStride && srcAlign) { > - PACK_AND_STORE_ALIGNED(1) > - PACK_AND_STORE_ALIGNED(2) > - PACK_AND_STORE_ALIGNED(3) > - PACK_AND_STORE_ALIGNED(4) > - PACK_AND_STORE_ALIGNED(5) > - PACK_AND_STORE_ALIGNED(6) > - PACK_AND_STORE_ALIGNED(7) > - PACK_AND_STORE_ALIGNED(8) > - } else { > - PACK_AND_STORE(1) > - PACK_AND_STORE(2) > - PACK_AND_STORE(3) > - PACK_AND_STORE(4) > - PACK_AND_STORE(5) > - PACK_AND_STORE(6) > - PACK_AND_STORE(7) > - PACK_AND_STORE(8) > - } > - #undef PACK_AND_STORE > - #undef PACK_AND_STORE_ALIGNED > - } > -} > - > - > - > -static inline void doVertDefFilter_altivec(uint8_t src[], int stride, > PPContext *c) { > - /* > - this code makes no assumption on src or stride. > - One could remove the recomputation of the perm > - vector by assuming (stride % 16) == 0, unfortunately > - this is not always true. Quite a lot of load/stores > - can be removed by assuming proper alignment of > - src & stride :-( > - */ > - uint8_t *src2 = src + stride*3; > - const vector signed int zero = vec_splat_s32(0); > - DECLARE_ALIGNED(16, short, qp)[8] = {8*c->QP}; > - vector signed short vqp = vec_splat( > - (vector signed short)vec_ld(0, qp), 0); > - > -#define LOAD_LINE(i) \ > - const vector unsigned char perm##i = \ > - vec_lvsl(i * stride, src2); \ > - const vector unsigned char vbA##i = \ > - vec_ld(i * stride, src2); \ > - const vector unsigned char vbB##i = \ > - vec_ld(i * stride + 16, src2); \ > - const vector unsigned char vbT##i = \ > - vec_perm(vbA##i, vbB##i, perm##i); \ > - const vector signed short vb##i = \ > - (vector signed short)vec_mergeh((vector unsigned char)zero, \ > - (vector unsigned char)vbT##i) > - > - LOAD_LINE(1); > - LOAD_LINE(2); > - LOAD_LINE(3); > - LOAD_LINE(4); > - LOAD_LINE(5); > - LOAD_LINE(6); > - LOAD_LINE(7); > - LOAD_LINE(8); > -#undef LOAD_LINE > - > - const vector signed short v_1 = vec_splat_s16(1); > - const vector signed short v_2 = vec_splat_s16(2); > - const vector signed short v_5 = vec_splat_s16(5); > - const vector signed short v_32 = vec_sl(v_1, > - (vector unsigned short)v_5); > - /* middle energy */ > - const vector signed short l3minusl6 = vec_sub(vb3, vb6); > - const vector signed short l5minusl4 = vec_sub(vb5, vb4); > - const vector signed short twotimes_l3minusl6 = vec_mladd(v_2, > l3minusl6, (vector signed short)zero); > - const vector signed short mE = vec_mladd(v_5, l5minusl4, > twotimes_l3minusl6); > - const vector signed short absmE = vec_abs(mE); > - /* left & right energy */ > - const vector signed short l1minusl4 = vec_sub(vb1, vb4); > - const vector signed short l3minusl2 = vec_sub(vb3, vb2); > - const vector signed short l5minusl8 = vec_sub(vb5, vb8); > - const vector signed short l7minusl6 = vec_sub(vb7, vb6); > - const vector signed short twotimes_l1minusl4 = vec_mladd(v_2, > l1minusl4, (vector signed short)zero); > - const vector signed short twotimes_l5minusl8 = vec_mladd(v_2, > l5minusl8, (vector signed short)zero); > - const vector signed short lE = vec_mladd(v_5, l3minusl2, > twotimes_l1minusl4); > - const vector signed short rE = vec_mladd(v_5, l7minusl6, > twotimes_l5minusl8); > - /* d */ > - const vector signed short ddiff = vec_sub(absmE, > - vec_min(vec_abs(lE), > - vec_abs(rE))); > - const vector signed short ddiffclamp = vec_max(ddiff, (vector signed > short)zero); > - const vector signed short dtimes64 = vec_mladd(v_5, ddiffclamp, > v_32); > - const vector signed short d = vec_sra(dtimes64, vec_splat_u16(6)); > - const vector signed short minusd = vec_sub((vector signed > short)zero, d); > - const vector signed short finald = vec_sel(minusd, > - d, > - vec_cmpgt(vec_sub((vector > signed short)zero, mE), > - _______________________________________________ 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".