diff --git a/LICENSE.md b/LICENSE.md index 613070e1b6..371b0913ce 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 f58936db61..7f7faa0595 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 6c23a38be1..2e69b3c56c 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 a9ec077ef0..679b71f290 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 d980d4e64f..f33531fd84 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 2ac3fd4fb3..c2f6b9de2a 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 7c0d879ec9..0effe4127f 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 740d9ab265..5ea33cdf01 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 9e9903eb97..0000000000 --- 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, 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 ee709fbb2a..c8ae114ab6 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 d78fc0277f..0000000000 --- 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 27381c6aca..0000000000 --- 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 eab2228919..0000000000 --- a/libpostproc/postprocess.c +++ /dev/null @@ -1,992 +0,0 @@ -/* - * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at) - * - * AltiVec optimizations (C) 2004 Romain Dolbeau - * - * 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 - */ - -/** - * @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 -#include -#include - -#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 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 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 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; yQP){ - 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; yQP ? 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; yQP; - 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 force quantizer\n" -"Usage:\n" -"[: