diff options
Diffstat (limited to 'ffmpeg/libavfilter')
174 files changed, 0 insertions, 54434 deletions
diff --git a/ffmpeg/libavfilter/Makefile b/ffmpeg/libavfilter/Makefile deleted file mode 100644 index 3d587fe..0000000 --- a/ffmpeg/libavfilter/Makefile +++ /dev/null @@ -1,265 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avfilter -FFLIBS = avutil -FFLIBS-$(CONFIG_ACONVERT_FILTER) += swresample -FFLIBS-$(CONFIG_AMOVIE_FILTER) += avformat avcodec -FFLIBS-$(CONFIG_ARESAMPLE_FILTER) += swresample -FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample -FFLIBS-$(CONFIG_ATEMPO_FILTER) += avcodec -FFLIBS-$(CONFIG_DECIMATE_FILTER) += avcodec -FFLIBS-$(CONFIG_DESHAKE_FILTER) += avcodec -FFLIBS-$(CONFIG_ELBG_FILTER) += avcodec -FFLIBS-$(CONFIG_MCDEINT_FILTER) += avcodec -FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec -FFLIBS-$(CONFIG_MP_FILTER) += avcodec -FFLIBS-$(CONFIG_PAN_FILTER) += swresample -FFLIBS-$(CONFIG_PP_FILTER) += postproc -FFLIBS-$(CONFIG_REMOVELOGO_FILTER) += avformat avcodec swscale -FFLIBS-$(CONFIG_RESAMPLE_FILTER) += avresample -FFLIBS-$(CONFIG_SAB_FILTER) += swscale -FFLIBS-$(CONFIG_SCALE_FILTER) += swscale -FFLIBS-$(CONFIG_SHOWSPECTRUM_FILTER) += avcodec -FFLIBS-$(CONFIG_SMARTBLUR_FILTER) += swscale -FFLIBS-$(CONFIG_SUBTITLES_FILTER) += avformat avcodec - -HEADERS = asrc_abuffer.h \ - avcodec.h \ - avfilter.h \ - avfiltergraph.h \ - buffersink.h \ - buffersrc.h \ - version.h \ - -OBJS = allfilters.o \ - audio.o \ - avfilter.o \ - avfiltergraph.o \ - buffer.o \ - buffersink.o \ - buffersrc.o \ - drawutils.o \ - fifo.o \ - formats.o \ - graphdump.o \ - graphparser.o \ - opencl_allkernels.o \ - transform.o \ - video.o \ - - -OBJS-$(CONFIG_AVCODEC) += avcodec.o - -OBJS-$(CONFIG_ACONVERT_FILTER) += af_aconvert.o -OBJS-$(CONFIG_ADELAY_FILTER) += af_adelay.o -OBJS-$(CONFIG_AECHO_FILTER) += af_aecho.o -OBJS-$(CONFIG_AEVAL_FILTER) += aeval.o -OBJS-$(CONFIG_AFADE_FILTER) += af_afade.o -OBJS-$(CONFIG_AFORMAT_FILTER) += af_aformat.o -OBJS-$(CONFIG_AINTERLEAVE_FILTER) += f_interleave.o -OBJS-$(CONFIG_ALLPASS_FILTER) += af_biquads.o -OBJS-$(CONFIG_AMERGE_FILTER) += af_amerge.o -OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o -OBJS-$(CONFIG_ANULL_FILTER) += af_anull.o -OBJS-$(CONFIG_APAD_FILTER) += af_apad.o -OBJS-$(CONFIG_APERMS_FILTER) += f_perms.o -OBJS-$(CONFIG_APHASER_FILTER) += af_aphaser.o -OBJS-$(CONFIG_ARESAMPLE_FILTER) += af_aresample.o -OBJS-$(CONFIG_ASELECT_FILTER) += f_select.o -OBJS-$(CONFIG_ASENDCMD_FILTER) += f_sendcmd.o -OBJS-$(CONFIG_ASETNSAMPLES_FILTER) += af_asetnsamples.o -OBJS-$(CONFIG_ASETPTS_FILTER) += setpts.o -OBJS-$(CONFIG_ASETRATE_FILTER) += af_asetrate.o -OBJS-$(CONFIG_ASETTB_FILTER) += f_settb.o -OBJS-$(CONFIG_ASHOWINFO_FILTER) += af_ashowinfo.o -OBJS-$(CONFIG_ASPLIT_FILTER) += split.o -OBJS-$(CONFIG_ASTATS_FILTER) += af_astats.o -OBJS-$(CONFIG_ASTREAMSYNC_FILTER) += af_astreamsync.o -OBJS-$(CONFIG_ASYNCTS_FILTER) += af_asyncts.o -OBJS-$(CONFIG_ATEMPO_FILTER) += af_atempo.o -OBJS-$(CONFIG_ATRIM_FILTER) += trim.o -OBJS-$(CONFIG_AZMQ_FILTER) += f_zmq.o -OBJS-$(CONFIG_BANDPASS_FILTER) += af_biquads.o -OBJS-$(CONFIG_BANDREJECT_FILTER) += af_biquads.o -OBJS-$(CONFIG_BASS_FILTER) += af_biquads.o -OBJS-$(CONFIG_BIQUAD_FILTER) += af_biquads.o -OBJS-$(CONFIG_CHANNELMAP_FILTER) += af_channelmap.o -OBJS-$(CONFIG_CHANNELSPLIT_FILTER) += af_channelsplit.o -OBJS-$(CONFIG_COMPAND_FILTER) += af_compand.o -OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o -OBJS-$(CONFIG_EBUR128_FILTER) += f_ebur128.o -OBJS-$(CONFIG_EQUALIZER_FILTER) += af_biquads.o -OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o -OBJS-$(CONFIG_JOIN_FILTER) += af_join.o -OBJS-$(CONFIG_LADSPA_FILTER) += af_ladspa.o -OBJS-$(CONFIG_LOWPASS_FILTER) += af_biquads.o -OBJS-$(CONFIG_PAN_FILTER) += af_pan.o -OBJS-$(CONFIG_REPLAYGAIN_FILTER) += af_replaygain.o -OBJS-$(CONFIG_RESAMPLE_FILTER) += af_resample.o -OBJS-$(CONFIG_SILENCEDETECT_FILTER) += af_silencedetect.o -OBJS-$(CONFIG_TREBLE_FILTER) += af_biquads.o -OBJS-$(CONFIG_VOLUME_FILTER) += af_volume.o -OBJS-$(CONFIG_VOLUMEDETECT_FILTER) += af_volumedetect.o - -OBJS-$(CONFIG_AEVALSRC_FILTER) += aeval.o -OBJS-$(CONFIG_ANULLSRC_FILTER) += asrc_anullsrc.o -OBJS-$(CONFIG_FLITE_FILTER) += asrc_flite.o -OBJS-$(CONFIG_SINE_FILTER) += asrc_sine.o - -OBJS-$(CONFIG_ANULLSINK_FILTER) += asink_anullsink.o - -OBJS-$(CONFIG_ASS_FILTER) += vf_subtitles.o -OBJS-$(CONFIG_ALPHAEXTRACT_FILTER) += vf_extractplanes.o -OBJS-$(CONFIG_ALPHAMERGE_FILTER) += vf_alphamerge.o -OBJS-$(CONFIG_BBOX_FILTER) += bbox.o vf_bbox.o -OBJS-$(CONFIG_BLACKDETECT_FILTER) += vf_blackdetect.o -OBJS-$(CONFIG_BLACKFRAME_FILTER) += vf_blackframe.o -OBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o dualinput.o framesync.o -OBJS-$(CONFIG_BOXBLUR_FILTER) += vf_boxblur.o -OBJS-$(CONFIG_COLORBALANCE_FILTER) += vf_colorbalance.o -OBJS-$(CONFIG_COLORCHANNELMIXER_FILTER) += vf_colorchannelmixer.o -OBJS-$(CONFIG_COLORMATRIX_FILTER) += vf_colormatrix.o -OBJS-$(CONFIG_COPY_FILTER) += vf_copy.o -OBJS-$(CONFIG_CROP_FILTER) += vf_crop.o -OBJS-$(CONFIG_CROPDETECT_FILTER) += vf_cropdetect.o -OBJS-$(CONFIG_CURVES_FILTER) += vf_curves.o -OBJS-$(CONFIG_DCTDNOIZ_FILTER) += vf_dctdnoiz.o -OBJS-$(CONFIG_DECIMATE_FILTER) += vf_decimate.o -OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o -OBJS-$(CONFIG_DESHAKE_FILTER) += vf_deshake.o -OBJS-$(CONFIG_DRAWBOX_FILTER) += vf_drawbox.o -OBJS-$(CONFIG_DRAWGRID_FILTER) += vf_drawbox.o -OBJS-$(CONFIG_DRAWTEXT_FILTER) += vf_drawtext.o -OBJS-$(CONFIG_ELBG_FILTER) += vf_elbg.o -OBJS-$(CONFIG_EDGEDETECT_FILTER) += vf_edgedetect.o -OBJS-$(CONFIG_EXTRACTPLANES_FILTER) += vf_extractplanes.o -OBJS-$(CONFIG_FADE_FILTER) += vf_fade.o -OBJS-$(CONFIG_FIELD_FILTER) += vf_field.o -OBJS-$(CONFIG_FIELDMATCH_FILTER) += vf_fieldmatch.o -OBJS-$(CONFIG_FIELDORDER_FILTER) += vf_fieldorder.o -OBJS-$(CONFIG_FORMAT_FILTER) += vf_format.o -OBJS-$(CONFIG_FRAMESTEP_FILTER) += vf_framestep.o -OBJS-$(CONFIG_FPS_FILTER) += vf_fps.o -OBJS-$(CONFIG_FREI0R_FILTER) += vf_frei0r.o -OBJS-$(CONFIG_GEQ_FILTER) += vf_geq.o -OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o -OBJS-$(CONFIG_HALDCLUT_FILTER) += vf_lut3d.o dualinput.o framesync.o -OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o -OBJS-$(CONFIG_HISTEQ_FILTER) += vf_histeq.o -OBJS-$(CONFIG_HISTOGRAM_FILTER) += vf_histogram.o -OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o -OBJS-$(CONFIG_HUE_FILTER) += vf_hue.o -OBJS-$(CONFIG_IDET_FILTER) += vf_idet.o -OBJS-$(CONFIG_IL_FILTER) += vf_il.o -OBJS-$(CONFIG_INTERLACE_FILTER) += vf_interlace.o -OBJS-$(CONFIG_INTERLEAVE_FILTER) += f_interleave.o -OBJS-$(CONFIG_KERNDEINT_FILTER) += vf_kerndeint.o -OBJS-$(CONFIG_LUT3D_FILTER) += vf_lut3d.o -OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o -OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o -OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o -OBJS-$(CONFIG_MCDEINT_FILTER) += vf_mcdeint.o -OBJS-$(CONFIG_MERGEPLANES_FILTER) += vf_mergeplanes.o framesync.o -OBJS-$(CONFIG_MP_FILTER) += vf_mp.o -OBJS-$(CONFIG_MPDECIMATE_FILTER) += vf_mpdecimate.o -OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o -OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o -OBJS-$(CONFIG_NOISE_FILTER) += vf_noise.o -OBJS-$(CONFIG_NULL_FILTER) += vf_null.o -OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o -OBJS-$(CONFIG_OPENCL) += deshake_opencl.o unsharp_opencl.o -OBJS-$(CONFIG_OVERLAY_FILTER) += vf_overlay.o dualinput.o framesync.o -OBJS-$(CONFIG_OWDENOISE_FILTER) += vf_owdenoise.o -OBJS-$(CONFIG_PAD_FILTER) += vf_pad.o -OBJS-$(CONFIG_PERMS_FILTER) += f_perms.o -OBJS-$(CONFIG_PERSPECTIVE_FILTER) += vf_perspective.o -OBJS-$(CONFIG_PHASE_FILTER) += vf_phase.o -OBJS-$(CONFIG_PIXDESCTEST_FILTER) += vf_pixdesctest.o -OBJS-$(CONFIG_PP_FILTER) += vf_pp.o -OBJS-$(CONFIG_PSNR_FILTER) += vf_psnr.o dualinput.o framesync.o -OBJS-$(CONFIG_PULLUP_FILTER) += vf_pullup.o -OBJS-$(CONFIG_REMOVELOGO_FILTER) += bbox.o lswsutils.o lavfutils.o vf_removelogo.o -OBJS-$(CONFIG_ROTATE_FILTER) += vf_rotate.o -OBJS-$(CONFIG_SEPARATEFIELDS_FILTER) += vf_separatefields.o -OBJS-$(CONFIG_SAB_FILTER) += vf_sab.o -OBJS-$(CONFIG_SCALE_FILTER) += vf_scale.o -OBJS-$(CONFIG_SELECT_FILTER) += f_select.o -OBJS-$(CONFIG_SENDCMD_FILTER) += f_sendcmd.o -OBJS-$(CONFIG_SETDAR_FILTER) += vf_aspect.o -OBJS-$(CONFIG_SETFIELD_FILTER) += vf_setfield.o -OBJS-$(CONFIG_SETPTS_FILTER) += setpts.o -OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o -OBJS-$(CONFIG_SETTB_FILTER) += f_settb.o -OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o -OBJS-$(CONFIG_SMARTBLUR_FILTER) += vf_smartblur.o -OBJS-$(CONFIG_SPLIT_FILTER) += split.o -OBJS-$(CONFIG_SPP_FILTER) += vf_spp.o -OBJS-$(CONFIG_STEREO3D_FILTER) += vf_stereo3d.o -OBJS-$(CONFIG_SUBTITLES_FILTER) += vf_subtitles.o -OBJS-$(CONFIG_SUPER2XSAI_FILTER) += vf_super2xsai.o -OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o -OBJS-$(CONFIG_TELECINE_FILTER) += vf_telecine.o -OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o -OBJS-$(CONFIG_TILE_FILTER) += vf_tile.o -OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o -OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o -OBJS-$(CONFIG_TRIM_FILTER) += trim.o -OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o -OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o -OBJS-$(CONFIG_VIDSTABDETECT_FILTER) += vidstabutils.o vf_vidstabdetect.o -OBJS-$(CONFIG_VIDSTABTRANSFORM_FILTER) += vidstabutils.o vf_vidstabtransform.o -OBJS-$(CONFIG_VIGNETTE_FILTER) += vf_vignette.o -OBJS-$(CONFIG_W3FDIF_FILTER) += vf_w3fdif.o -OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o -OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o - -OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o -OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o -OBJS-$(CONFIG_HALDCLUTSRC_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_LIFE_FILTER) += vsrc_life.o -OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o -OBJS-$(CONFIG_MPTESTSRC_FILTER) += vsrc_mptestsrc.o -OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_RGBTESTSRC_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_SMPTEBARS_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o -OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o - -OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o - -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/mp_image.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/img_format.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq2.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_eq.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fspp.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_ilpack.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_pp7.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_softpulldown.o -OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_uspp.o - -# multimedia filters -OBJS-$(CONFIG_AVECTORSCOPE_FILTER) += avf_avectorscope.o -OBJS-$(CONFIG_CONCAT_FILTER) += avf_concat.o -OBJS-$(CONFIG_SHOWSPECTRUM_FILTER) += avf_showspectrum.o -OBJS-$(CONFIG_SHOWWAVES_FILTER) += avf_showwaves.o - -# multimedia sources -OBJS-$(CONFIG_AMOVIE_FILTER) += src_movie.o -OBJS-$(CONFIG_MOVIE_FILTER) += src_movie.o - -# Windows resource file -SLIBOBJS-$(HAVE_GNU_WINDRES) += avfilterres.o - -SKIPHEADERS-$(CONFIG_LIBVIDSTAB) += vidstabutils.h -SKIPHEADERS-$(CONFIG_OPENCL) += opencl_internal.h deshake_opencl_kernel.h unsharp_opencl_kernel.h - -OBJS-$(HAVE_THREADS) += pthread.o - -TOOLS = graph2dot -TESTPROGS = drawutils filtfmts formats - -TOOLS-$(CONFIG_LIBZMQ) += zmqsend - -clean:: - $(RM) $(CLEANSUFFIXES:%=libavfilter/libmpcodecs/%) diff --git a/ffmpeg/libavfilter/af_aconvert.c b/ffmpeg/libavfilter/af_aconvert.c deleted file mode 100644 index 19095cb..0000000 --- a/ffmpeg/libavfilter/af_aconvert.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu> - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2011 Mina Nagy Zaki - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * sample format and channel layout conversion audio filter - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libswresample/swresample.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - enum AVSampleFormat out_sample_fmt; - int64_t out_chlayout; - struct SwrContext *swr; - char *format_str; - char *channel_layout_str; -} AConvertContext; - -#define OFFSET(x) offsetof(AConvertContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption aconvert_options[] = { - { "sample_fmt", "", OFFSET(format_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { "channel_layout", "", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(aconvert); - -static av_cold int init(AVFilterContext *ctx) -{ - AConvertContext *aconvert = ctx->priv; - int ret = 0; - - av_log(ctx, AV_LOG_WARNING, "This filter is deprecated, use aformat instead\n"); - - aconvert->out_sample_fmt = AV_SAMPLE_FMT_NONE; - aconvert->out_chlayout = 0; - - if (aconvert->format_str && strcmp(aconvert->format_str, "auto") && - (ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0) - return ret; - if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto")) - return ff_parse_channel_layout(&aconvert->out_chlayout, NULL, aconvert->channel_layout_str, ctx); - return ret; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - AConvertContext *aconvert = ctx->priv; - swr_free(&aconvert->swr); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - AConvertContext *aconvert = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - AVFilterChannelLayouts *layouts; - - ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO), - &inlink->out_formats); - if (aconvert->out_sample_fmt != AV_SAMPLE_FMT_NONE) { - formats = NULL; - ff_add_format(&formats, aconvert->out_sample_fmt); - ff_formats_ref(formats, &outlink->in_formats); - } else - ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO), - &outlink->in_formats); - - ff_channel_layouts_ref(ff_all_channel_layouts(), - &inlink->out_channel_layouts); - if (aconvert->out_chlayout != 0) { - layouts = NULL; - ff_add_channel_layout(&layouts, aconvert->out_chlayout); - ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); - } else - ff_channel_layouts_ref(ff_all_channel_layouts(), - &outlink->in_channel_layouts); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - int ret; - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - AConvertContext *aconvert = ctx->priv; - char buf1[64], buf2[64]; - - /* if not specified in args, use the format and layout of the output */ - if (aconvert->out_sample_fmt == AV_SAMPLE_FMT_NONE) - aconvert->out_sample_fmt = outlink->format; - if (aconvert->out_chlayout == 0) - aconvert->out_chlayout = outlink->channel_layout; - - aconvert->swr = swr_alloc_set_opts(aconvert->swr, - aconvert->out_chlayout, aconvert->out_sample_fmt, inlink->sample_rate, - inlink->channel_layout, inlink->format, inlink->sample_rate, - 0, ctx); - if (!aconvert->swr) - return AVERROR(ENOMEM); - ret = swr_init(aconvert->swr); - if (ret < 0) - return ret; - - av_get_channel_layout_string(buf1, sizeof(buf1), - -1, inlink ->channel_layout); - av_get_channel_layout_string(buf2, sizeof(buf2), - -1, outlink->channel_layout); - av_log(ctx, AV_LOG_VERBOSE, - "fmt:%s cl:%s -> fmt:%s cl:%s\n", - av_get_sample_fmt_name(inlink ->format), buf1, - av_get_sample_fmt_name(outlink->format), buf2); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) -{ - AConvertContext *aconvert = inlink->dst->priv; - const int n = insamplesref->nb_samples; - AVFilterLink *const outlink = inlink->dst->outputs[0]; - AVFrame *outsamplesref = ff_get_audio_buffer(outlink, n); - int ret; - - if (!outsamplesref) - return AVERROR(ENOMEM); - swr_convert(aconvert->swr, outsamplesref->extended_data, n, - (void *)insamplesref->extended_data, n); - - av_frame_copy_props(outsamplesref, insamplesref); - av_frame_set_channels(outsamplesref, outlink->channels); - outsamplesref->channel_layout = outlink->channel_layout; - - ret = ff_filter_frame(outlink, outsamplesref); - av_frame_free(&insamplesref); - return ret; -} - -static const AVFilterPad aconvert_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad aconvert_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_af_aconvert = { - .name = "aconvert", - .description = NULL_IF_CONFIG_SMALL("Convert the input audio to sample_fmt:channel_layout."), - .priv_size = sizeof(AConvertContext), - .priv_class = &aconvert_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = aconvert_inputs, - .outputs = aconvert_outputs, -}; diff --git a/ffmpeg/libavfilter/af_afade.c b/ffmpeg/libavfilter/af_afade.c deleted file mode 100644 index fbf9802..0000000 --- a/ffmpeg/libavfilter/af_afade.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2013 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * fade audio filter - */ - -#include "libavutil/opt.h" -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int type; - int curve; - int nb_samples; - int64_t start_sample; - int64_t duration; - int64_t start_time; - - void (*fade_samples)(uint8_t **dst, uint8_t * const *src, - int nb_samples, int channels, int direction, - int64_t start, int range, int curve); -} AudioFadeContext; - -enum CurveType { TRI, QSIN, ESIN, HSIN, LOG, PAR, QUA, CUB, SQU, CBR }; - -#define OFFSET(x) offsetof(AudioFadeContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption afade_options[] = { - { "type", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "type" }, - { "t", "set the fade direction", OFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS, "type" }, - { "in", "fade-in", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "type" }, - { "out", "fade-out", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "type" }, - { "start_sample", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, FLAGS }, - { "ss", "set number of first sample to start fading", OFFSET(start_sample), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, FLAGS }, - { "nb_samples", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX, FLAGS }, - { "ns", "set number of samples for fade duration", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 44100}, 1, INT32_MAX, FLAGS }, - { "start_time", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "st", "set time to start fading", OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "duration", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "d", "set fade duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "curve", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, TRI, CBR, FLAGS, "curve" }, - { "c", "set fade curve type", OFFSET(curve), AV_OPT_TYPE_INT, {.i64 = TRI }, TRI, CBR, FLAGS, "curve" }, - { "tri", "linear slope", 0, AV_OPT_TYPE_CONST, {.i64 = TRI }, 0, 0, FLAGS, "curve" }, - { "qsin", "quarter of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = QSIN }, 0, 0, FLAGS, "curve" }, - { "esin", "exponential sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = ESIN }, 0, 0, FLAGS, "curve" }, - { "hsin", "half of sine wave", 0, AV_OPT_TYPE_CONST, {.i64 = HSIN }, 0, 0, FLAGS, "curve" }, - { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64 = LOG }, 0, 0, FLAGS, "curve" }, - { "par", "inverted parabola", 0, AV_OPT_TYPE_CONST, {.i64 = PAR }, 0, 0, FLAGS, "curve" }, - { "qua", "quadratic", 0, AV_OPT_TYPE_CONST, {.i64 = QUA }, 0, 0, FLAGS, "curve" }, - { "cub", "cubic", 0, AV_OPT_TYPE_CONST, {.i64 = CUB }, 0, 0, FLAGS, "curve" }, - { "squ", "square root", 0, AV_OPT_TYPE_CONST, {.i64 = SQU }, 0, 0, FLAGS, "curve" }, - { "cbr", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64 = CBR }, 0, 0, FLAGS, "curve" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(afade); - -static av_cold int init(AVFilterContext *ctx) -{ - AudioFadeContext *s = ctx->priv; - - if (INT64_MAX - s->nb_samples < s->start_sample) - return AVERROR(EINVAL); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats; - AVFilterChannelLayouts *layouts; - static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32P, - AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, - AV_SAMPLE_FMT_NONE - }; - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_set_common_channel_layouts(ctx, layouts); - - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, formats); - - return 0; -} - -static double fade_gain(int curve, int64_t index, int range) -{ - double gain; - - gain = FFMAX(0.0, FFMIN(1.0, 1.0 * index / range)); - - switch (curve) { - case QSIN: - gain = sin(gain * M_PI / 2.0); - break; - case ESIN: - gain = 1.0 - cos(M_PI / 4.0 * (pow(2.0*gain - 1, 3) + 1)); - break; - case HSIN: - gain = (1.0 - cos(gain * M_PI)) / 2.0; - break; - case LOG: - gain = pow(0.1, (1 - gain) * 5.0); - break; - case PAR: - gain = (1 - (1 - gain) * (1 - gain)); - break; - case QUA: - gain *= gain; - break; - case CUB: - gain = gain * gain * gain; - break; - case SQU: - gain = sqrt(gain); - break; - case CBR: - gain = cbrt(gain); - break; - } - - return gain; -} - -#define FADE_PLANAR(name, type) \ -static void fade_samples_## name ##p(uint8_t **dst, uint8_t * const *src, \ - int nb_samples, int channels, int dir, \ - int64_t start, int range, int curve) \ -{ \ - int i, c; \ - \ - for (i = 0; i < nb_samples; i++) { \ - double gain = fade_gain(curve, start + i * dir, range); \ - for (c = 0; c < channels; c++) { \ - type *d = (type *)dst[c]; \ - const type *s = (type *)src[c]; \ - \ - d[i] = s[i] * gain; \ - } \ - } \ -} - -#define FADE(name, type) \ -static void fade_samples_## name (uint8_t **dst, uint8_t * const *src, \ - int nb_samples, int channels, int dir, \ - int64_t start, int range, int curve) \ -{ \ - type *d = (type *)dst[0]; \ - const type *s = (type *)src[0]; \ - int i, c, k = 0; \ - \ - for (i = 0; i < nb_samples; i++) { \ - double gain = fade_gain(curve, start + i * dir, range); \ - for (c = 0; c < channels; c++, k++) \ - d[k] = s[k] * gain; \ - } \ -} - -FADE_PLANAR(dbl, double) -FADE_PLANAR(flt, float) -FADE_PLANAR(s16, int16_t) -FADE_PLANAR(s32, int32_t) - -FADE(dbl, double) -FADE(flt, float) -FADE(s16, int16_t) -FADE(s32, int32_t) - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - AudioFadeContext *s = ctx->priv; - - switch (inlink->format) { - case AV_SAMPLE_FMT_DBL: s->fade_samples = fade_samples_dbl; break; - case AV_SAMPLE_FMT_DBLP: s->fade_samples = fade_samples_dblp; break; - case AV_SAMPLE_FMT_FLT: s->fade_samples = fade_samples_flt; break; - case AV_SAMPLE_FMT_FLTP: s->fade_samples = fade_samples_fltp; break; - case AV_SAMPLE_FMT_S16: s->fade_samples = fade_samples_s16; break; - case AV_SAMPLE_FMT_S16P: s->fade_samples = fade_samples_s16p; break; - case AV_SAMPLE_FMT_S32: s->fade_samples = fade_samples_s32; break; - case AV_SAMPLE_FMT_S32P: s->fade_samples = fade_samples_s32p; break; - } - - if (s->duration) - s->nb_samples = av_rescale(s->duration, inlink->sample_rate, AV_TIME_BASE); - if (s->start_time) - s->start_sample = av_rescale(s->start_time, inlink->sample_rate, AV_TIME_BASE); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AudioFadeContext *s = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - int nb_samples = buf->nb_samples; - AVFrame *out_buf; - int64_t cur_sample = av_rescale_q(buf->pts, (AVRational){1, outlink->sample_rate}, outlink->time_base); - - if ((!s->type && (s->start_sample + s->nb_samples < cur_sample)) || - ( s->type && (cur_sample + s->nb_samples < s->start_sample))) - return ff_filter_frame(outlink, buf); - - if (av_frame_is_writable(buf)) { - out_buf = buf; - } else { - out_buf = ff_get_audio_buffer(inlink, nb_samples); - if (!out_buf) - return AVERROR(ENOMEM); - av_frame_copy_props(out_buf, buf); - } - - if ((!s->type && (cur_sample + nb_samples < s->start_sample)) || - ( s->type && (s->start_sample + s->nb_samples < cur_sample))) { - av_samples_set_silence(out_buf->extended_data, 0, nb_samples, - av_frame_get_channels(out_buf), out_buf->format); - } else { - int64_t start; - - if (!s->type) - start = cur_sample - s->start_sample; - else - start = s->start_sample + s->nb_samples - cur_sample; - - s->fade_samples(out_buf->extended_data, buf->extended_data, - nb_samples, av_frame_get_channels(buf), - s->type ? -1 : 1, start, - s->nb_samples, s->curve); - } - - if (buf != out_buf) - av_frame_free(&buf); - - return ff_filter_frame(outlink, out_buf); -} - -static const AVFilterPad avfilter_af_afade_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_afade_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_afade = { - .name = "afade", - .description = NULL_IF_CONFIG_SMALL("Fade in/out input audio."), - .query_formats = query_formats, - .priv_size = sizeof(AudioFadeContext), - .init = init, - .inputs = avfilter_af_afade_inputs, - .outputs = avfilter_af_afade_outputs, - .priv_class = &afade_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/af_aformat.c b/ffmpeg/libavfilter/af_aformat.c deleted file mode 100644 index 5fd0308..0000000 --- a/ffmpeg/libavfilter/af_aformat.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2011 Mina Nagy Zaki - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * format audio filter - */ - -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -typedef struct AFormatContext { - const AVClass *class; - - AVFilterFormats *formats; - AVFilterFormats *sample_rates; - AVFilterChannelLayouts *channel_layouts; - - char *formats_str; - char *sample_rates_str; - char *channel_layouts_str; -} AFormatContext; - -#define OFFSET(x) offsetof(AFormatContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption aformat_options[] = { - { "sample_fmts", "A comma-separated list of sample formats.", OFFSET(formats_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { "sample_rates", "A comma-separated list of sample rates.", OFFSET(sample_rates_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { "channel_layouts", "A comma-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(aformat); - -#define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc) \ -do { \ - char *next, *cur = str, sep; \ - \ - if (str && strchr(str, ',')) { \ - av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use '|' to "\ - "separate %s.\n", desc); \ - sep = ','; \ - } else \ - sep = '|'; \ - \ - while (cur) { \ - type fmt; \ - next = strchr(cur, sep); \ - if (next) \ - *next++ = 0; \ - \ - if ((fmt = get_fmt(cur)) == none) { \ - av_log(ctx, AV_LOG_ERROR, "Error parsing " desc ": %s.\n", cur);\ - return AVERROR(EINVAL); \ - } \ - add_to_list(&list, fmt); \ - \ - cur = next; \ - } \ -} while (0) - -static int get_sample_rate(const char *samplerate) -{ - int ret = strtol(samplerate, NULL, 0); - return FFMAX(ret, 0); -} - -static av_cold int init(AVFilterContext *ctx) -{ - AFormatContext *s = ctx->priv; - - PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats, - ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); - PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, - get_sample_rate, 0, "sample rate"); - PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts, - ff_add_channel_layout, av_get_channel_layout, 0, - "channel layout"); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - AFormatContext *s = ctx->priv; - - ff_set_common_formats(ctx, s->formats ? s->formats : - ff_all_formats(AVMEDIA_TYPE_AUDIO)); - ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates : - ff_all_samplerates()); - ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts : - ff_all_channel_counts()); - - return 0; -} - -static const AVFilterPad avfilter_af_aformat_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_aformat_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO - }, - { NULL } -}; - -AVFilter ff_af_aformat = { - .name = "aformat", - .description = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."), - .init = init, - .query_formats = query_formats, - .priv_size = sizeof(AFormatContext), - .priv_class = &aformat_class, - .inputs = avfilter_af_aformat_inputs, - .outputs = avfilter_af_aformat_outputs, -}; diff --git a/ffmpeg/libavfilter/af_amerge.c b/ffmpeg/libavfilter/af_amerge.c deleted file mode 100644 index 82b694b..0000000 --- a/ffmpeg/libavfilter/af_amerge.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Audio merging filter - */ - -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libswresample/swresample.h" // only for SWR_CH_MAX -#include "avfilter.h" -#include "audio.h" -#include "bufferqueue.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int nb_inputs; - int route[SWR_CH_MAX]; /**< channels routing, see copy_samples */ - int bps; - struct amerge_input { - struct FFBufQueue queue; - int nb_ch; /**< number of channels for the input */ - int nb_samples; - int pos; - } *in; -} AMergeContext; - -#define OFFSET(x) offsetof(AMergeContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption amerge_options[] = { - { "inputs", "specify the number of inputs", OFFSET(nb_inputs), - AV_OPT_TYPE_INT, { .i64 = 2 }, 2, SWR_CH_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(amerge); - -static av_cold void uninit(AVFilterContext *ctx) -{ - AMergeContext *am = ctx->priv; - int i; - - for (i = 0; i < am->nb_inputs; i++) { - if (am->in) - ff_bufqueue_discard_all(&am->in[i].queue); - if (ctx->input_pads) - av_freep(&ctx->input_pads[i].name); - } - av_freep(&am->in); -} - -static int query_formats(AVFilterContext *ctx) -{ - AMergeContext *am = ctx->priv; - int64_t inlayout[SWR_CH_MAX], outlayout = 0; - AVFilterFormats *formats; - AVFilterChannelLayouts *layouts; - int i, overlap = 0, nb_ch = 0; - - for (i = 0; i < am->nb_inputs; i++) { - if (!ctx->inputs[i]->in_channel_layouts || - !ctx->inputs[i]->in_channel_layouts->nb_channel_layouts) { - av_log(ctx, AV_LOG_WARNING, - "No channel layout for input %d\n", i + 1); - return AVERROR(EAGAIN); - } - inlayout[i] = ctx->inputs[i]->in_channel_layouts->channel_layouts[0]; - if (ctx->inputs[i]->in_channel_layouts->nb_channel_layouts > 1) { - char buf[256]; - av_get_channel_layout_string(buf, sizeof(buf), 0, inlayout[i]); - av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1); - } - am->in[i].nb_ch = av_get_channel_layout_nb_channels(inlayout[i]); - if (outlayout & inlayout[i]) - overlap++; - outlayout |= inlayout[i]; - nb_ch += am->in[i].nb_ch; - } - if (nb_ch > SWR_CH_MAX) { - av_log(ctx, AV_LOG_ERROR, "Too many channels (max %d)\n", SWR_CH_MAX); - return AVERROR(EINVAL); - } - if (overlap) { - av_log(ctx, AV_LOG_WARNING, - "Input channel layouts overlap: " - "output layout will be determined by the number of distinct input channels\n"); - for (i = 0; i < nb_ch; i++) - am->route[i] = i; - outlayout = av_get_default_channel_layout(nb_ch); - if (!outlayout) - outlayout = ((int64_t)1 << nb_ch) - 1; - } else { - int *route[SWR_CH_MAX]; - int c, out_ch_number = 0; - - route[0] = am->route; - for (i = 1; i < am->nb_inputs; i++) - route[i] = route[i - 1] + am->in[i - 1].nb_ch; - for (c = 0; c < 64; c++) - for (i = 0; i < am->nb_inputs; i++) - if ((inlayout[i] >> c) & 1) - *(route[i]++) = out_ch_number++; - } - formats = ff_make_format_list(ff_packed_sample_fmts_array); - ff_set_common_formats(ctx, formats); - for (i = 0; i < am->nb_inputs; i++) { - layouts = NULL; - ff_add_channel_layout(&layouts, inlayout[i]); - ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts); - } - layouts = NULL; - ff_add_channel_layout(&layouts, outlayout); - ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AMergeContext *am = ctx->priv; - AVBPrint bp; - int i; - - for (i = 1; i < am->nb_inputs; i++) { - if (ctx->inputs[i]->sample_rate != ctx->inputs[0]->sample_rate) { - av_log(ctx, AV_LOG_ERROR, - "Inputs must have the same sample rate " - "%d for in%d vs %d\n", - ctx->inputs[i]->sample_rate, i, ctx->inputs[0]->sample_rate); - return AVERROR(EINVAL); - } - } - am->bps = av_get_bytes_per_sample(ctx->outputs[0]->format); - outlink->sample_rate = ctx->inputs[0]->sample_rate; - outlink->time_base = ctx->inputs[0]->time_base; - - av_bprint_init(&bp, 0, 1); - for (i = 0; i < am->nb_inputs; i++) { - av_bprintf(&bp, "%sin%d:", i ? " + " : "", i); - av_bprint_channel_layout(&bp, -1, ctx->inputs[i]->channel_layout); - } - av_bprintf(&bp, " -> out:"); - av_bprint_channel_layout(&bp, -1, ctx->outputs[0]->channel_layout); - av_log(ctx, AV_LOG_VERBOSE, "%s\n", bp.str); - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AMergeContext *am = ctx->priv; - int i, ret; - - for (i = 0; i < am->nb_inputs; i++) - if (!am->in[i].nb_samples) - if ((ret = ff_request_frame(ctx->inputs[i])) < 0) - return ret; - return 0; -} - -/** - * Copy samples from several input streams to one output stream. - * @param nb_inputs number of inputs - * @param in inputs; used only for the nb_ch field; - * @param route routing values; - * input channel i goes to output channel route[i]; - * i < in[0].nb_ch are the channels from the first output; - * i >= in[0].nb_ch are the channels from the second output - * @param ins pointer to the samples of each inputs, in packed format; - * will be left at the end of the copied samples - * @param outs pointer to the samples of the output, in packet format; - * must point to a buffer big enough; - * will be left at the end of the copied samples - * @param ns number of samples to copy - * @param bps bytes per sample - */ -static inline void copy_samples(int nb_inputs, struct amerge_input in[], - int *route, uint8_t *ins[], - uint8_t **outs, int ns, int bps) -{ - int *route_cur; - int i, c, nb_ch = 0; - - for (i = 0; i < nb_inputs; i++) - nb_ch += in[i].nb_ch; - while (ns--) { - route_cur = route; - for (i = 0; i < nb_inputs; i++) { - for (c = 0; c < in[i].nb_ch; c++) { - memcpy((*outs) + bps * *(route_cur++), ins[i], bps); - ins[i] += bps; - } - } - *outs += nb_ch * bps; - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterContext *ctx = inlink->dst; - AMergeContext *am = ctx->priv; - AVFilterLink *const outlink = ctx->outputs[0]; - int input_number; - int nb_samples, ns, i; - AVFrame *outbuf, *inbuf[SWR_CH_MAX]; - uint8_t *ins[SWR_CH_MAX], *outs; - - for (input_number = 0; input_number < am->nb_inputs; input_number++) - if (inlink == ctx->inputs[input_number]) - break; - av_assert1(input_number < am->nb_inputs); - if (ff_bufqueue_is_full(&am->in[input_number].queue)) { - av_frame_free(&insamples); - return AVERROR(ENOMEM); - } - ff_bufqueue_add(ctx, &am->in[input_number].queue, av_frame_clone(insamples)); - am->in[input_number].nb_samples += insamples->nb_samples; - av_frame_free(&insamples); - nb_samples = am->in[0].nb_samples; - for (i = 1; i < am->nb_inputs; i++) - nb_samples = FFMIN(nb_samples, am->in[i].nb_samples); - if (!nb_samples) - return 0; - - outbuf = ff_get_audio_buffer(ctx->outputs[0], nb_samples); - if (!outbuf) - return AVERROR(ENOMEM); - outs = outbuf->data[0]; - for (i = 0; i < am->nb_inputs; i++) { - inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0); - ins[i] = inbuf[i]->data[0] + - am->in[i].pos * am->in[i].nb_ch * am->bps; - } - av_frame_copy_props(outbuf, inbuf[0]); - outbuf->pts = inbuf[0]->pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE : - inbuf[0]->pts + - av_rescale_q(am->in[0].pos, - (AVRational){ 1, ctx->inputs[0]->sample_rate }, - ctx->outputs[0]->time_base); - - outbuf->nb_samples = nb_samples; - outbuf->channel_layout = outlink->channel_layout; - av_frame_set_channels(outbuf, outlink->channels); - - while (nb_samples) { - ns = nb_samples; - for (i = 0; i < am->nb_inputs; i++) - ns = FFMIN(ns, inbuf[i]->nb_samples - am->in[i].pos); - /* Unroll the most common sample formats: speed +~350% for the loop, - +~13% overall (including two common decoders) */ - switch (am->bps) { - case 1: - copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 1); - break; - case 2: - copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 2); - break; - case 4: - copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 4); - break; - default: - copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, am->bps); - break; - } - - nb_samples -= ns; - for (i = 0; i < am->nb_inputs; i++) { - am->in[i].nb_samples -= ns; - am->in[i].pos += ns; - if (am->in[i].pos == inbuf[i]->nb_samples) { - am->in[i].pos = 0; - av_frame_free(&inbuf[i]); - ff_bufqueue_get(&am->in[i].queue); - inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0); - ins[i] = inbuf[i] ? inbuf[i]->data[0] : NULL; - } - } - } - return ff_filter_frame(ctx->outputs[0], outbuf); -} - -static av_cold int init(AVFilterContext *ctx) -{ - AMergeContext *am = ctx->priv; - int i; - - am->in = av_calloc(am->nb_inputs, sizeof(*am->in)); - if (!am->in) - return AVERROR(ENOMEM); - for (i = 0; i < am->nb_inputs; i++) { - char *name = av_asprintf("in%d", i); - AVFilterPad pad = { - .name = name, - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }; - if (!name) - return AVERROR(ENOMEM); - ff_insert_inpad(ctx, i, &pad); - } - return 0; -} - -static const AVFilterPad amerge_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_af_amerge = { - .name = "amerge", - .description = NULL_IF_CONFIG_SMALL("Merge two or more audio streams into " - "a single multi-channel stream."), - .priv_size = sizeof(AMergeContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = amerge_outputs, - .priv_class = &amerge_class, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, -}; diff --git a/ffmpeg/libavfilter/af_amix.c b/ffmpeg/libavfilter/af_amix.c deleted file mode 100644 index 7140b6c..0000000 --- a/ffmpeg/libavfilter/af_amix.c +++ /dev/null @@ -1,560 +0,0 @@ -/* - * Audio Mix Filter - * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Audio Mix Filter - * - * Mixes audio from multiple sources into a single output. The channel layout, - * sample rate, and sample format will be the same for all inputs and the - * output. - */ - -#include "libavutil/attributes.h" -#include "libavutil/audio_fifo.h" -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/float_dsp.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -#define INPUT_OFF 0 /**< input has reached EOF */ -#define INPUT_ON 1 /**< input is active */ -#define INPUT_INACTIVE 2 /**< input is on, but is currently inactive */ - -#define DURATION_LONGEST 0 -#define DURATION_SHORTEST 1 -#define DURATION_FIRST 2 - - -typedef struct FrameInfo { - int nb_samples; - int64_t pts; - struct FrameInfo *next; -} FrameInfo; - -/** - * Linked list used to store timestamps and frame sizes of all frames in the - * FIFO for the first input. - * - * This is needed to keep timestamps synchronized for the case where multiple - * input frames are pushed to the filter for processing before a frame is - * requested by the output link. - */ -typedef struct FrameList { - int nb_frames; - int nb_samples; - FrameInfo *list; - FrameInfo *end; -} FrameList; - -static void frame_list_clear(FrameList *frame_list) -{ - if (frame_list) { - while (frame_list->list) { - FrameInfo *info = frame_list->list; - frame_list->list = info->next; - av_free(info); - } - frame_list->nb_frames = 0; - frame_list->nb_samples = 0; - frame_list->end = NULL; - } -} - -static int frame_list_next_frame_size(FrameList *frame_list) -{ - if (!frame_list->list) - return 0; - return frame_list->list->nb_samples; -} - -static int64_t frame_list_next_pts(FrameList *frame_list) -{ - if (!frame_list->list) - return AV_NOPTS_VALUE; - return frame_list->list->pts; -} - -static void frame_list_remove_samples(FrameList *frame_list, int nb_samples) -{ - if (nb_samples >= frame_list->nb_samples) { - frame_list_clear(frame_list); - } else { - int samples = nb_samples; - while (samples > 0) { - FrameInfo *info = frame_list->list; - av_assert0(info != NULL); - if (info->nb_samples <= samples) { - samples -= info->nb_samples; - frame_list->list = info->next; - if (!frame_list->list) - frame_list->end = NULL; - frame_list->nb_frames--; - frame_list->nb_samples -= info->nb_samples; - av_free(info); - } else { - info->nb_samples -= samples; - info->pts += samples; - frame_list->nb_samples -= samples; - samples = 0; - } - } - } -} - -static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t pts) -{ - FrameInfo *info = av_malloc(sizeof(*info)); - if (!info) - return AVERROR(ENOMEM); - info->nb_samples = nb_samples; - info->pts = pts; - info->next = NULL; - - if (!frame_list->list) { - frame_list->list = info; - frame_list->end = info; - } else { - av_assert0(frame_list->end != NULL); - frame_list->end->next = info; - frame_list->end = info; - } - frame_list->nb_frames++; - frame_list->nb_samples += nb_samples; - - return 0; -} - - -typedef struct MixContext { - const AVClass *class; /**< class for AVOptions */ - AVFloatDSPContext fdsp; - - int nb_inputs; /**< number of inputs */ - int active_inputs; /**< number of input currently active */ - int duration_mode; /**< mode for determining duration */ - float dropout_transition; /**< transition time when an input drops out */ - - int nb_channels; /**< number of channels */ - int sample_rate; /**< sample rate */ - int planar; - AVAudioFifo **fifos; /**< audio fifo for each input */ - uint8_t *input_state; /**< current state of each input */ - float *input_scale; /**< mixing scale factor for each input */ - float scale_norm; /**< normalization factor for all inputs */ - int64_t next_pts; /**< calculated pts for next output frame */ - FrameList *frame_list; /**< list of frame info for the first input */ -} MixContext; - -#define OFFSET(x) offsetof(MixContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption amix_options[] = { - { "inputs", "Number of inputs.", - OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 32, A|F }, - { "duration", "How to determine the end-of-stream.", - OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0, 2, A|F, "duration" }, - { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST }, INT_MIN, INT_MAX, A|F, "duration" }, - { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, INT_MIN, INT_MAX, A|F, "duration" }, - { "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST }, INT_MIN, INT_MAX, A|F, "duration" }, - { "dropout_transition", "Transition time, in seconds, for volume " - "renormalization when an input stream ends.", - OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(amix); - -/** - * Update the scaling factors to apply to each input during mixing. - * - * This balances the full volume range between active inputs and handles - * volume transitions when EOF is encountered on an input but mixing continues - * with the remaining inputs. - */ -static void calculate_scales(MixContext *s, int nb_samples) -{ - int i; - - if (s->scale_norm > s->active_inputs) { - s->scale_norm -= nb_samples / (s->dropout_transition * s->sample_rate); - s->scale_norm = FFMAX(s->scale_norm, s->active_inputs); - } - - for (i = 0; i < s->nb_inputs; i++) { - if (s->input_state[i] == INPUT_ON) - s->input_scale[i] = 1.0f / s->scale_norm; - else - s->input_scale[i] = 0.0f; - } -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - MixContext *s = ctx->priv; - int i; - char buf[64]; - - s->planar = av_sample_fmt_is_planar(outlink->format); - s->sample_rate = outlink->sample_rate; - outlink->time_base = (AVRational){ 1, outlink->sample_rate }; - s->next_pts = AV_NOPTS_VALUE; - - s->frame_list = av_mallocz(sizeof(*s->frame_list)); - if (!s->frame_list) - return AVERROR(ENOMEM); - - s->fifos = av_mallocz(s->nb_inputs * sizeof(*s->fifos)); - if (!s->fifos) - return AVERROR(ENOMEM); - - s->nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout); - for (i = 0; i < s->nb_inputs; i++) { - s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024); - if (!s->fifos[i]) - return AVERROR(ENOMEM); - } - - s->input_state = av_malloc(s->nb_inputs); - if (!s->input_state) - return AVERROR(ENOMEM); - memset(s->input_state, INPUT_ON, s->nb_inputs); - s->active_inputs = s->nb_inputs; - - s->input_scale = av_mallocz(s->nb_inputs * sizeof(*s->input_scale)); - if (!s->input_scale) - return AVERROR(ENOMEM); - s->scale_norm = s->active_inputs; - calculate_scales(s, 0); - - av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout); - - av_log(ctx, AV_LOG_VERBOSE, - "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs, - av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf); - - return 0; -} - -/** - * Read samples from the input FIFOs, mix, and write to the output link. - */ -static int output_frame(AVFilterLink *outlink, int nb_samples) -{ - AVFilterContext *ctx = outlink->src; - MixContext *s = ctx->priv; - AVFrame *out_buf, *in_buf; - int i; - - calculate_scales(s, nb_samples); - - out_buf = ff_get_audio_buffer(outlink, nb_samples); - if (!out_buf) - return AVERROR(ENOMEM); - - in_buf = ff_get_audio_buffer(outlink, nb_samples); - if (!in_buf) { - av_frame_free(&out_buf); - return AVERROR(ENOMEM); - } - - for (i = 0; i < s->nb_inputs; i++) { - if (s->input_state[i] == INPUT_ON) { - int planes, plane_size, p; - - av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, - nb_samples); - - planes = s->planar ? s->nb_channels : 1; - plane_size = nb_samples * (s->planar ? 1 : s->nb_channels); - plane_size = FFALIGN(plane_size, 16); - - for (p = 0; p < planes; p++) { - s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p], - (float *) in_buf->extended_data[p], - s->input_scale[i], plane_size); - } - } - } - av_frame_free(&in_buf); - - out_buf->pts = s->next_pts; - if (s->next_pts != AV_NOPTS_VALUE) - s->next_pts += nb_samples; - - return ff_filter_frame(outlink, out_buf); -} - -/** - * Returns the smallest number of samples available in the input FIFOs other - * than that of the first input. - */ -static int get_available_samples(MixContext *s) -{ - int i; - int available_samples = INT_MAX; - - av_assert0(s->nb_inputs > 1); - - for (i = 1; i < s->nb_inputs; i++) { - int nb_samples; - if (s->input_state[i] == INPUT_OFF) - continue; - nb_samples = av_audio_fifo_size(s->fifos[i]); - available_samples = FFMIN(available_samples, nb_samples); - } - if (available_samples == INT_MAX) - return 0; - return available_samples; -} - -/** - * Requests a frame, if needed, from each input link other than the first. - */ -static int request_samples(AVFilterContext *ctx, int min_samples) -{ - MixContext *s = ctx->priv; - int i, ret; - - av_assert0(s->nb_inputs > 1); - - for (i = 1; i < s->nb_inputs; i++) { - ret = 0; - if (s->input_state[i] == INPUT_OFF) - continue; - while (!ret && av_audio_fifo_size(s->fifos[i]) < min_samples) - ret = ff_request_frame(ctx->inputs[i]); - if (ret == AVERROR_EOF) { - if (av_audio_fifo_size(s->fifos[i]) == 0) { - s->input_state[i] = INPUT_OFF; - continue; - } - } else if (ret < 0) - return ret; - } - return 0; -} - -/** - * Calculates the number of active inputs and determines EOF based on the - * duration option. - * - * @return 0 if mixing should continue, or AVERROR_EOF if mixing should stop. - */ -static int calc_active_inputs(MixContext *s) -{ - int i; - int active_inputs = 0; - for (i = 0; i < s->nb_inputs; i++) - active_inputs += !!(s->input_state[i] != INPUT_OFF); - s->active_inputs = active_inputs; - - if (!active_inputs || - (s->duration_mode == DURATION_FIRST && s->input_state[0] == INPUT_OFF) || - (s->duration_mode == DURATION_SHORTEST && active_inputs != s->nb_inputs)) - return AVERROR_EOF; - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - MixContext *s = ctx->priv; - int ret; - int wanted_samples, available_samples; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; - - if (s->input_state[0] == INPUT_OFF) { - ret = request_samples(ctx, 1); - if (ret < 0) - return ret; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; - - available_samples = get_available_samples(s); - if (!available_samples) - return AVERROR(EAGAIN); - - return output_frame(outlink, available_samples); - } - - if (s->frame_list->nb_frames == 0) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF) { - s->input_state[0] = INPUT_OFF; - if (s->nb_inputs == 1) - return AVERROR_EOF; - else - return AVERROR(EAGAIN); - } else if (ret < 0) - return ret; - } - av_assert0(s->frame_list->nb_frames > 0); - - wanted_samples = frame_list_next_frame_size(s->frame_list); - - if (s->active_inputs > 1) { - ret = request_samples(ctx, wanted_samples); - if (ret < 0) - return ret; - - ret = calc_active_inputs(s); - if (ret < 0) - return ret; - } - - if (s->active_inputs > 1) { - available_samples = get_available_samples(s); - if (!available_samples) - return AVERROR(EAGAIN); - available_samples = FFMIN(available_samples, wanted_samples); - } else { - available_samples = wanted_samples; - } - - s->next_pts = frame_list_next_pts(s->frame_list); - frame_list_remove_samples(s->frame_list, available_samples); - - return output_frame(outlink, available_samples); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - MixContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int i, ret = 0; - - for (i = 0; i < ctx->nb_inputs; i++) - if (ctx->inputs[i] == inlink) - break; - if (i >= ctx->nb_inputs) { - av_log(ctx, AV_LOG_ERROR, "unknown input link\n"); - ret = AVERROR(EINVAL); - goto fail; - } - - if (i == 0) { - int64_t pts = av_rescale_q(buf->pts, inlink->time_base, - outlink->time_base); - ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts); - if (ret < 0) - goto fail; - } - - ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data, - buf->nb_samples); - -fail: - av_frame_free(&buf); - - return ret; -} - -static av_cold int init(AVFilterContext *ctx) -{ - MixContext *s = ctx->priv; - int i; - - for (i = 0; i < s->nb_inputs; i++) { - char name[32]; - AVFilterPad pad = { 0 }; - - snprintf(name, sizeof(name), "input%d", i); - pad.type = AVMEDIA_TYPE_AUDIO; - pad.name = av_strdup(name); - pad.filter_frame = filter_frame; - - ff_insert_inpad(ctx, i, &pad); - } - - avpriv_float_dsp_init(&s->fdsp, 0); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - int i; - MixContext *s = ctx->priv; - - if (s->fifos) { - for (i = 0; i < s->nb_inputs; i++) - av_audio_fifo_free(s->fifos[i]); - av_freep(&s->fifos); - } - frame_list_clear(s->frame_list); - av_freep(&s->frame_list); - av_freep(&s->input_state); - av_freep(&s->input_scale); - - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - ff_add_format(&formats, AV_SAMPLE_FMT_FLT); - ff_add_format(&formats, AV_SAMPLE_FMT_FLTP); - ff_set_common_formats(ctx, formats); - ff_set_common_channel_layouts(ctx, ff_all_channel_layouts()); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - return 0; -} - -static const AVFilterPad avfilter_af_amix_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - .request_frame = request_frame - }, - { NULL } -}; - -AVFilter ff_af_amix = { - .name = "amix", - .description = NULL_IF_CONFIG_SMALL("Audio mixing."), - .priv_size = sizeof(MixContext), - .priv_class = &amix_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = avfilter_af_amix_outputs, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, -}; diff --git a/ffmpeg/libavfilter/af_anull.c b/ffmpeg/libavfilter/af_anull.c deleted file mode 100644 index fff456e..0000000 --- a/ffmpeg/libavfilter/af_anull.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu> - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * null audio filter - */ - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" -#include "libavutil/internal.h" - -static const AVFilterPad avfilter_af_anull_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_anull_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_anull = { - .name = "anull", - .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."), - .query_formats = ff_query_formats_all, - .inputs = avfilter_af_anull_inputs, - .outputs = avfilter_af_anull_outputs, -}; diff --git a/ffmpeg/libavfilter/af_apad.c b/ffmpeg/libavfilter/af_apad.c deleted file mode 100644 index 88a3a77..0000000 --- a/ffmpeg/libavfilter/af_apad.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2012 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** - * @file - * audio pad filter. - * - * Based on af_aresample.c - */ - -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int64_t next_pts; - - int packet_size; - int64_t pad_len; - int64_t whole_len; -} APadContext; - -#define OFFSET(x) offsetof(APadContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption apad_options[] = { - { "packet_size", "set silence packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, { .i64 = 4096 }, 0, INT_MAX, A }, - { "pad_len", "number of samples of silence to add", OFFSET(pad_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A }, - { "whole_len", "target number of samples in the audio stream", OFFSET(whole_len), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, A }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(apad); - -static av_cold int init(AVFilterContext *ctx) -{ - APadContext *apad = ctx->priv; - - apad->next_pts = AV_NOPTS_VALUE; - if (apad->whole_len && apad->pad_len) { - av_log(ctx, AV_LOG_ERROR, "Both whole and pad length are set, this is not possible\n"); - return AVERROR(EINVAL); - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - APadContext *apad = ctx->priv; - - if (apad->whole_len) - apad->whole_len -= frame->nb_samples; - - apad->next_pts = frame->pts + av_rescale_q(frame->nb_samples, (AVRational){1, inlink->sample_rate}, inlink->time_base); - return ff_filter_frame(ctx->outputs[0], frame); -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - APadContext *apad = ctx->priv; - int ret; - - ret = ff_request_frame(ctx->inputs[0]); - - if (ret == AVERROR_EOF && !ctx->is_disabled) { - int n_out = apad->packet_size; - AVFrame *outsamplesref; - - if (apad->whole_len > 0) { - apad->pad_len = apad->whole_len; - apad->whole_len = 0; - } - if (apad->pad_len > 0) { - n_out = FFMIN(n_out, apad->pad_len); - apad->pad_len -= n_out; - } - - if(!n_out) - return AVERROR_EOF; - - outsamplesref = ff_get_audio_buffer(outlink, n_out); - if (!outsamplesref) - return AVERROR(ENOMEM); - - av_assert0(outsamplesref->sample_rate == outlink->sample_rate); - av_assert0(outsamplesref->nb_samples == n_out); - - av_samples_set_silence(outsamplesref->extended_data, 0, - n_out, - av_frame_get_channels(outsamplesref), - outsamplesref->format); - - outsamplesref->pts = apad->next_pts; - if (apad->next_pts != AV_NOPTS_VALUE) - apad->next_pts += av_rescale_q(n_out, (AVRational){1, outlink->sample_rate}, outlink->time_base); - - return ff_filter_frame(outlink, outsamplesref); - } - return ret; -} - -static const AVFilterPad apad_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad apad_outputs[] = { - { - .name = "default", - .request_frame = request_frame, - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_apad = { - .name = "apad", - .description = NULL_IF_CONFIG_SMALL("Pad audio with silence."), - .init = init, - .priv_size = sizeof(APadContext), - .inputs = apad_inputs, - .outputs = apad_outputs, - .priv_class = &apad_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, -}; diff --git a/ffmpeg/libavfilter/af_aresample.c b/ffmpeg/libavfilter/af_aresample.c deleted file mode 100644 index e05c0a1..0000000 --- a/ffmpeg/libavfilter/af_aresample.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2011 Mina Nagy Zaki - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * resampling audio filter - */ - -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" -#include "libavutil/avassert.h" -#include "libswresample/swresample.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int sample_rate_arg; - double ratio; - struct SwrContext *swr; - int64_t next_pts; - int req_fullfilled; -} AResampleContext; - -static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts) -{ - AResampleContext *aresample = ctx->priv; - int ret = 0; - - aresample->next_pts = AV_NOPTS_VALUE; - aresample->swr = swr_alloc(); - if (!aresample->swr) { - ret = AVERROR(ENOMEM); - goto end; - } - - if (opts) { - AVDictionaryEntry *e = NULL; - - while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { - if ((ret = av_opt_set(aresample->swr, e->key, e->value, 0)) < 0) - goto end; - } - av_dict_free(opts); - } - if (aresample->sample_rate_arg > 0) - av_opt_set_int(aresample->swr, "osr", aresample->sample_rate_arg, 0); -end: - return ret; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - AResampleContext *aresample = ctx->priv; - swr_free(&aresample->swr); -} - -static int query_formats(AVFilterContext *ctx) -{ - AResampleContext *aresample = ctx->priv; - int out_rate = av_get_int(aresample->swr, "osr", NULL); - uint64_t out_layout = av_get_int(aresample->swr, "ocl", NULL); - enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL); - - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - - AVFilterFormats *in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *out_formats; - AVFilterFormats *in_samplerates = ff_all_samplerates(); - AVFilterFormats *out_samplerates; - AVFilterChannelLayouts *in_layouts = ff_all_channel_counts(); - AVFilterChannelLayouts *out_layouts; - - ff_formats_ref (in_formats, &inlink->out_formats); - ff_formats_ref (in_samplerates, &inlink->out_samplerates); - ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); - - if(out_rate > 0) { - out_samplerates = ff_make_format_list((int[]){ out_rate, -1 }); - } else { - out_samplerates = ff_all_samplerates(); - } - ff_formats_ref(out_samplerates, &outlink->in_samplerates); - - if(out_format != AV_SAMPLE_FMT_NONE) { - out_formats = ff_make_format_list((int[]){ out_format, -1 }); - } else - out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - ff_formats_ref(out_formats, &outlink->in_formats); - - if(out_layout) { - out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 }); - } else - out_layouts = ff_all_channel_counts(); - ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); - - return 0; -} - - -static int config_output(AVFilterLink *outlink) -{ - int ret; - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - AResampleContext *aresample = ctx->priv; - int out_rate; - uint64_t out_layout; - enum AVSampleFormat out_format; - char inchl_buf[128], outchl_buf[128]; - - aresample->swr = swr_alloc_set_opts(aresample->swr, - outlink->channel_layout, outlink->format, outlink->sample_rate, - inlink->channel_layout, inlink->format, inlink->sample_rate, - 0, ctx); - if (!aresample->swr) - return AVERROR(ENOMEM); - if (!inlink->channel_layout) - av_opt_set_int(aresample->swr, "ich", inlink->channels, 0); - if (!outlink->channel_layout) - av_opt_set_int(aresample->swr, "och", outlink->channels, 0); - - ret = swr_init(aresample->swr); - if (ret < 0) - return ret; - - out_rate = av_get_int(aresample->swr, "osr", NULL); - out_layout = av_get_int(aresample->swr, "ocl", NULL); - out_format = av_get_int(aresample->swr, "osf", NULL); - outlink->time_base = (AVRational) {1, out_rate}; - - av_assert0(outlink->sample_rate == out_rate); - av_assert0(outlink->channel_layout == out_layout || !outlink->channel_layout); - av_assert0(outlink->format == out_format); - - aresample->ratio = (double)outlink->sample_rate / inlink->sample_rate; - - av_get_channel_layout_string(inchl_buf, sizeof(inchl_buf), inlink ->channels, inlink ->channel_layout); - av_get_channel_layout_string(outchl_buf, sizeof(outchl_buf), outlink->channels, outlink->channel_layout); - - av_log(ctx, AV_LOG_VERBOSE, "ch:%d chl:%s fmt:%s r:%dHz -> ch:%d chl:%s fmt:%s r:%dHz\n", - inlink ->channels, inchl_buf, av_get_sample_fmt_name(inlink->format), inlink->sample_rate, - outlink->channels, outchl_buf, av_get_sample_fmt_name(outlink->format), outlink->sample_rate); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamplesref) -{ - AResampleContext *aresample = inlink->dst->priv; - const int n_in = insamplesref->nb_samples; - int64_t delay; - int n_out = n_in * aresample->ratio + 32; - AVFilterLink *const outlink = inlink->dst->outputs[0]; - AVFrame *outsamplesref; - int ret; - - delay = swr_get_delay(aresample->swr, outlink->sample_rate); - if (delay > 0) - n_out += delay; - - outsamplesref = ff_get_audio_buffer(outlink, n_out); - - if(!outsamplesref) - return AVERROR(ENOMEM); - - av_frame_copy_props(outsamplesref, insamplesref); - outsamplesref->format = outlink->format; - av_frame_set_channels(outsamplesref, outlink->channels); - outsamplesref->channel_layout = outlink->channel_layout; - outsamplesref->sample_rate = outlink->sample_rate; - - if(insamplesref->pts != AV_NOPTS_VALUE) { - int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den); - int64_t outpts= swr_next_pts(aresample->swr, inpts); - aresample->next_pts = - outsamplesref->pts = ROUNDED_DIV(outpts, inlink->sample_rate); - } else { - outsamplesref->pts = AV_NOPTS_VALUE; - } - n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, - (void *)insamplesref->extended_data, n_in); - if (n_out <= 0) { - av_frame_free(&outsamplesref); - av_frame_free(&insamplesref); - return 0; - } - - outsamplesref->nb_samples = n_out; - - ret = ff_filter_frame(outlink, outsamplesref); - aresample->req_fullfilled= 1; - av_frame_free(&insamplesref); - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AResampleContext *aresample = ctx->priv; - AVFilterLink *const inlink = outlink->src->inputs[0]; - int ret; - - aresample->req_fullfilled = 0; - do{ - ret = ff_request_frame(ctx->inputs[0]); - }while(!aresample->req_fullfilled && ret>=0); - - if (ret == AVERROR_EOF) { - AVFrame *outsamplesref; - int n_out = 4096; - int64_t pts; - - outsamplesref = ff_get_audio_buffer(outlink, n_out); - if (!outsamplesref) - return AVERROR(ENOMEM); - - pts = swr_next_pts(aresample->swr, INT64_MIN); - pts = ROUNDED_DIV(pts, inlink->sample_rate); - - n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, 0, 0); - if (n_out <= 0) { - av_frame_free(&outsamplesref); - return (n_out == 0) ? AVERROR_EOF : n_out; - } - - outsamplesref->sample_rate = outlink->sample_rate; - outsamplesref->nb_samples = n_out; - - outsamplesref->pts = pts; - - return ff_filter_frame(outlink, outsamplesref); - } - return ret; -} - -static const AVClass *resample_child_class_next(const AVClass *prev) -{ - return prev ? NULL : swr_get_class(); -} - -static void *resample_child_next(void *obj, void *prev) -{ - AResampleContext *s = obj; - return prev ? NULL : s->swr; -} - -#define OFFSET(x) offsetof(AResampleContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption options[] = { - {"sample_rate", NULL, OFFSET(sample_rate_arg), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS }, - {NULL} -}; - -static const AVClass aresample_class = { - .class_name = "aresample", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .child_class_next = resample_child_class_next, - .child_next = resample_child_next, -}; - -static const AVFilterPad aresample_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad aresample_outputs[] = { - { - .name = "default", - .config_props = config_output, - .request_frame = request_frame, - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_aresample = { - .name = "aresample", - .description = NULL_IF_CONFIG_SMALL("Resample audio data."), - .init_dict = init_dict, - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(AResampleContext), - .priv_class = &aresample_class, - .inputs = aresample_inputs, - .outputs = aresample_outputs, -}; diff --git a/ffmpeg/libavfilter/af_asetnsamples.c b/ffmpeg/libavfilter/af_asetnsamples.c deleted file mode 100644 index fbcf275..0000000 --- a/ffmpeg/libavfilter/af_asetnsamples.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2012 Andrey Utkin - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Filter that changes number of samples on single output operation - */ - -#include "libavutil/audio_fifo.h" -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" -#include "formats.h" - -typedef struct { - const AVClass *class; - int nb_out_samples; ///< how many samples to output - AVAudioFifo *fifo; ///< samples are queued here - int64_t next_out_pts; - int pad; -} ASNSContext; - -#define OFFSET(x) offsetof(ASNSContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption asetnsamples_options[] = { - { "nb_out_samples", "set the number of per-frame output samples", OFFSET(nb_out_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS }, - { "n", "set the number of per-frame output samples", OFFSET(nb_out_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS }, - { "pad", "pad last frame with zeros", OFFSET(pad), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { "p", "pad last frame with zeros", OFFSET(pad), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(asetnsamples); - -static av_cold int init(AVFilterContext *ctx) -{ - ASNSContext *asns = ctx->priv; - - asns->next_out_pts = AV_NOPTS_VALUE; - av_log(ctx, AV_LOG_VERBOSE, "nb_out_samples:%d pad:%d\n", asns->nb_out_samples, asns->pad); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ASNSContext *asns = ctx->priv; - av_audio_fifo_free(asns->fifo); -} - -static int config_props_output(AVFilterLink *outlink) -{ - ASNSContext *asns = outlink->src->priv; - - asns->fifo = av_audio_fifo_alloc(outlink->format, outlink->channels, asns->nb_out_samples); - if (!asns->fifo) - return AVERROR(ENOMEM); - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - - return 0; -} - -static int push_samples(AVFilterLink *outlink) -{ - ASNSContext *asns = outlink->src->priv; - AVFrame *outsamples = NULL; - int ret, nb_out_samples, nb_pad_samples; - - if (asns->pad) { - nb_out_samples = av_audio_fifo_size(asns->fifo) ? asns->nb_out_samples : 0; - nb_pad_samples = nb_out_samples - FFMIN(nb_out_samples, av_audio_fifo_size(asns->fifo)); - } else { - nb_out_samples = FFMIN(asns->nb_out_samples, av_audio_fifo_size(asns->fifo)); - nb_pad_samples = 0; - } - - if (!nb_out_samples) - return 0; - - outsamples = ff_get_audio_buffer(outlink, nb_out_samples); - if (!outsamples) - return AVERROR(ENOMEM); - - av_audio_fifo_read(asns->fifo, - (void **)outsamples->extended_data, nb_out_samples); - - if (nb_pad_samples) - av_samples_set_silence(outsamples->extended_data, nb_out_samples - nb_pad_samples, - nb_pad_samples, outlink->channels, - outlink->format); - outsamples->nb_samples = nb_out_samples; - outsamples->channel_layout = outlink->channel_layout; - outsamples->sample_rate = outlink->sample_rate; - outsamples->pts = asns->next_out_pts; - - if (asns->next_out_pts != AV_NOPTS_VALUE) - asns->next_out_pts += nb_out_samples; - - ret = ff_filter_frame(outlink, outsamples); - if (ret < 0) - return ret; - return nb_out_samples; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterContext *ctx = inlink->dst; - ASNSContext *asns = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int ret; - int nb_samples = insamples->nb_samples; - - if (av_audio_fifo_space(asns->fifo) < nb_samples) { - av_log(ctx, AV_LOG_DEBUG, "No space for %d samples, stretching audio fifo\n", nb_samples); - ret = av_audio_fifo_realloc(asns->fifo, av_audio_fifo_size(asns->fifo) + nb_samples); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, - "Stretching audio fifo failed, discarded %d samples\n", nb_samples); - return -1; - } - } - av_audio_fifo_write(asns->fifo, (void **)insamples->extended_data, nb_samples); - if (asns->next_out_pts == AV_NOPTS_VALUE) - asns->next_out_pts = insamples->pts; - av_frame_free(&insamples); - - while (av_audio_fifo_size(asns->fifo) >= asns->nb_out_samples) - push_samples(outlink); - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterLink *inlink = outlink->src->inputs[0]; - int ret; - - ret = ff_request_frame(inlink); - if (ret == AVERROR_EOF) { - ret = push_samples(outlink); - return ret < 0 ? ret : ret > 0 ? 0 : AVERROR_EOF; - } - - return ret; -} - -static const AVFilterPad asetnsamples_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad asetnsamples_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .request_frame = request_frame, - .config_props = config_props_output, - }, - { NULL } -}; - -AVFilter ff_af_asetnsamples = { - .name = "asetnsamples", - .description = NULL_IF_CONFIG_SMALL("Set the number of samples for each output audio frames."), - .priv_size = sizeof(ASNSContext), - .priv_class = &asetnsamples_class, - .init = init, - .uninit = uninit, - .inputs = asetnsamples_inputs, - .outputs = asetnsamples_outputs, -}; diff --git a/ffmpeg/libavfilter/af_ashowinfo.c b/ffmpeg/libavfilter/af_ashowinfo.c deleted file mode 100644 index 783f9a6..0000000 --- a/ffmpeg/libavfilter/af_ashowinfo.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * filter for showing textual audio frame information - */ - -#include <inttypes.h> -#include <stddef.h> - -#include "libavutil/adler32.h" -#include "libavutil/attributes.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/mem.h" -#include "libavutil/timestamp.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct AShowInfoContext { - /** - * Scratch space for individual plane checksums for planar audio - */ - uint32_t *plane_checksums; -} AShowInfoContext; - -static av_cold void uninit(AVFilterContext *ctx) -{ - AShowInfoContext *s = ctx->priv; - av_freep(&s->plane_checksums); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - AShowInfoContext *s = ctx->priv; - char chlayout_str[128]; - uint32_t checksum = 0; - int channels = inlink->channels; - int planar = av_sample_fmt_is_planar(buf->format); - int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels); - int data_size = buf->nb_samples * block_align; - int planes = planar ? channels : 1; - int i; - void *tmp_ptr = av_realloc(s->plane_checksums, channels * sizeof(*s->plane_checksums)); - - if (!tmp_ptr) - return AVERROR(ENOMEM); - s->plane_checksums = tmp_ptr; - - for (i = 0; i < planes; i++) { - uint8_t *data = buf->extended_data[i]; - - s->plane_checksums[i] = av_adler32_update(0, data, data_size); - checksum = i ? av_adler32_update(checksum, data, data_size) : - s->plane_checksums[0]; - } - - av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1, - buf->channel_layout); - - av_log(ctx, AV_LOG_INFO, - "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" " - "fmt:%s channels:%d chlayout:%s rate:%d nb_samples:%d " - "checksum:%08X ", - inlink->frame_count, - av_ts2str(buf->pts), av_ts2timestr(buf->pts, &inlink->time_base), - av_frame_get_pkt_pos(buf), - av_get_sample_fmt_name(buf->format), av_frame_get_channels(buf), chlayout_str, - buf->sample_rate, buf->nb_samples, - checksum); - - av_log(ctx, AV_LOG_INFO, "plane_checksums: [ "); - for (i = 0; i < planes; i++) - av_log(ctx, AV_LOG_INFO, "%08X ", s->plane_checksums[i]); - av_log(ctx, AV_LOG_INFO, "]\n"); - - return ff_filter_frame(inlink->dst->outputs[0], buf); -} - -static const AVFilterPad inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_ashowinfo = { - .name = "ashowinfo", - .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."), - .priv_size = sizeof(AShowInfoContext), - .uninit = uninit, - .inputs = inputs, - .outputs = outputs, -}; diff --git a/ffmpeg/libavfilter/af_astreamsync.c b/ffmpeg/libavfilter/af_astreamsync.c deleted file mode 100644 index becfe34..0000000 --- a/ffmpeg/libavfilter/af_astreamsync.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Stream (de)synchronization filter - */ - -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" - -#define QUEUE_SIZE 16 - -static const char * const var_names[] = { - "b1", "b2", - "s1", "s2", - "t1", "t2", - NULL -}; - -enum var_name { - VAR_B1, VAR_B2, - VAR_S1, VAR_S2, - VAR_T1, VAR_T2, - VAR_NB -}; - -typedef struct { - const AVClass *class; - AVExpr *expr; - char *expr_str; - double var_values[VAR_NB]; - struct buf_queue { - AVFrame *buf[QUEUE_SIZE]; - unsigned tail, nb; - /* buf[tail] is the oldest, - buf[(tail + nb) % QUEUE_SIZE] is where the next is added */ - } queue[2]; - int req[2]; - int next_out; - int eof; /* bitmask, one bit for each stream */ -} AStreamSyncContext; - -#define OFFSET(x) offsetof(AStreamSyncContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption astreamsync_options[] = { - { "expr", "set stream selection expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "t1-t2" }, .flags = FLAGS }, - { "e", "set stream selection expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "t1-t2" }, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(astreamsync); - -static av_cold int init(AVFilterContext *ctx) -{ - AStreamSyncContext *as = ctx->priv; - int r, i; - - r = av_expr_parse(&as->expr, as->expr_str, var_names, - NULL, NULL, NULL, NULL, 0, ctx); - if (r < 0) { - av_log(ctx, AV_LOG_ERROR, "Error in expression \"%s\"\n", as->expr_str); - return r; - } - for (i = 0; i < 42; i++) - av_expr_eval(as->expr, as->var_values, NULL); /* exercize prng */ - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - int i; - AVFilterFormats *formats, *rates; - AVFilterChannelLayouts *layouts; - - for (i = 0; i < 2; i++) { - formats = ctx->inputs[i]->in_formats; - ff_formats_ref(formats, &ctx->inputs[i]->out_formats); - ff_formats_ref(formats, &ctx->outputs[i]->in_formats); - rates = ff_all_samplerates(); - ff_formats_ref(rates, &ctx->inputs[i]->out_samplerates); - ff_formats_ref(rates, &ctx->outputs[i]->in_samplerates); - layouts = ctx->inputs[i]->in_channel_layouts; - ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts); - ff_channel_layouts_ref(layouts, &ctx->outputs[i]->in_channel_layouts); - } - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - int id = outlink == ctx->outputs[1]; - - outlink->sample_rate = ctx->inputs[id]->sample_rate; - outlink->time_base = ctx->inputs[id]->time_base; - return 0; -} - -static int send_out(AVFilterContext *ctx, int out_id) -{ - AStreamSyncContext *as = ctx->priv; - struct buf_queue *queue = &as->queue[out_id]; - AVFrame *buf = queue->buf[queue->tail]; - int ret; - - queue->buf[queue->tail] = NULL; - as->var_values[VAR_B1 + out_id]++; - as->var_values[VAR_S1 + out_id] += buf->nb_samples; - if (buf->pts != AV_NOPTS_VALUE) - as->var_values[VAR_T1 + out_id] = - av_q2d(ctx->outputs[out_id]->time_base) * buf->pts; - as->var_values[VAR_T1 + out_id] += buf->nb_samples / - (double)ctx->inputs[out_id]->sample_rate; - ret = ff_filter_frame(ctx->outputs[out_id], buf); - queue->nb--; - queue->tail = (queue->tail + 1) % QUEUE_SIZE; - if (as->req[out_id]) - as->req[out_id]--; - return ret; -} - -static void send_next(AVFilterContext *ctx) -{ - AStreamSyncContext *as = ctx->priv; - int i; - - while (1) { - if (!as->queue[as->next_out].nb) - break; - send_out(ctx, as->next_out); - if (!as->eof) - as->next_out = av_expr_eval(as->expr, as->var_values, NULL) >= 0; - } - for (i = 0; i < 2; i++) - if (as->queue[i].nb == QUEUE_SIZE) - send_out(ctx, i); -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AStreamSyncContext *as = ctx->priv; - int id = outlink == ctx->outputs[1]; - - as->req[id]++; - while (as->req[id] && !(as->eof & (1 << id))) { - if (as->queue[as->next_out].nb) { - send_next(ctx); - } else { - as->eof |= 1 << as->next_out; - ff_request_frame(ctx->inputs[as->next_out]); - if (as->eof & (1 << as->next_out)) - as->next_out = !as->next_out; - } - } - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterContext *ctx = inlink->dst; - AStreamSyncContext *as = ctx->priv; - int id = inlink == ctx->inputs[1]; - - as->queue[id].buf[(as->queue[id].tail + as->queue[id].nb++) % QUEUE_SIZE] = - insamples; - as->eof &= ~(1 << id); - send_next(ctx); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - AStreamSyncContext *as = ctx->priv; - - av_expr_free(as->expr); - as->expr = NULL; -} - -static const AVFilterPad astreamsync_inputs[] = { - { - .name = "in1", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - },{ - .name = "in2", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad astreamsync_outputs[] = { - { - .name = "out1", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - .request_frame = request_frame, - },{ - .name = "out2", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_af_astreamsync = { - .name = "astreamsync", - .description = NULL_IF_CONFIG_SMALL("Copy two streams of audio data " - "in a configurable order."), - .priv_size = sizeof(AStreamSyncContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = astreamsync_inputs, - .outputs = astreamsync_outputs, - .priv_class = &astreamsync_class, -}; diff --git a/ffmpeg/libavfilter/af_asyncts.c b/ffmpeg/libavfilter/af_asyncts.c deleted file mode 100644 index 5f8e1f6..0000000 --- a/ffmpeg/libavfilter/af_asyncts.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdint.h> - -#include "libavresample/avresample.h" -#include "libavutil/attributes.h" -#include "libavutil/audio_fifo.h" -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct ASyncContext { - const AVClass *class; - - AVAudioResampleContext *avr; - int64_t pts; ///< timestamp in samples of the first sample in fifo - int min_delta; ///< pad/trim min threshold in samples - int first_frame; ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE - int64_t first_pts; ///< user-specified first expected pts, in samples - int comp; ///< current resample compensation - - /* options */ - int resample; - float min_delta_sec; - int max_comp; - - /* set by filter_frame() to signal an output frame to request_frame() */ - int got_output; -} ASyncContext; - -#define OFFSET(x) offsetof(ASyncContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption asyncts_options[] = { - { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, A|F }, - { "min_delta", "Minimum difference between timestamps and audio data " - "(in seconds) to trigger padding/trimmin the data.", OFFSET(min_delta_sec), AV_OPT_TYPE_FLOAT, { .dbl = 0.1 }, 0, INT_MAX, A|F }, - { "max_comp", "Maximum compensation in samples per second.", OFFSET(max_comp), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, A|F }, - { "first_pts", "Assume the first pts should be this value.", OFFSET(first_pts), AV_OPT_TYPE_INT64, { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(asyncts); - -static av_cold int init(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - s->pts = AV_NOPTS_VALUE; - s->first_frame = 1; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->avr) { - avresample_close(s->avr); - avresample_free(&s->avr); - } -} - -static int config_props(AVFilterLink *link) -{ - ASyncContext *s = link->src->priv; - int ret; - - s->min_delta = s->min_delta_sec * link->sample_rate; - link->time_base = (AVRational){1, link->sample_rate}; - - s->avr = avresample_alloc_context(); - if (!s->avr) - return AVERROR(ENOMEM); - - av_opt_set_int(s->avr, "in_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "out_channel_layout", link->channel_layout, 0); - av_opt_set_int(s->avr, "in_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "out_sample_fmt", link->format, 0); - av_opt_set_int(s->avr, "in_sample_rate", link->sample_rate, 0); - av_opt_set_int(s->avr, "out_sample_rate", link->sample_rate, 0); - - if (s->resample) - av_opt_set_int(s->avr, "force_resampling", 1, 0); - - if ((ret = avresample_open(s->avr)) < 0) - return ret; - - return 0; -} - -/* get amount of data currently buffered, in samples */ -static int64_t get_delay(ASyncContext *s) -{ - return avresample_available(s->avr) + avresample_get_delay(s->avr); -} - -static void handle_trimming(AVFilterContext *ctx) -{ - ASyncContext *s = ctx->priv; - - if (s->pts < s->first_pts) { - int delta = FFMIN(s->first_pts - s->pts, avresample_available(s->avr)); - av_log(ctx, AV_LOG_VERBOSE, "Trimming %d samples from start\n", - delta); - avresample_read(s->avr, NULL, delta); - s->pts += delta; - } else if (s->first_frame) - s->pts = s->first_pts; -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - ASyncContext *s = ctx->priv; - int ret = 0; - int nb_samples; - - s->got_output = 0; - while (ret >= 0 && !s->got_output) - ret = ff_request_frame(ctx->inputs[0]); - - /* flush the fifo */ - if (ret == AVERROR_EOF) { - if (s->first_pts != AV_NOPTS_VALUE) - handle_trimming(ctx); - - if (nb_samples = get_delay(s)) { - AVFrame *buf = ff_get_audio_buffer(link, nb_samples); - if (!buf) - return AVERROR(ENOMEM); - ret = avresample_convert(s->avr, buf->extended_data, - buf->linesize[0], nb_samples, NULL, 0, 0); - if (ret <= 0) { - av_frame_free(&buf); - return (ret < 0) ? ret : AVERROR_EOF; - } - - buf->pts = s->pts; - return ff_filter_frame(link, buf); - } - } - - return ret; -} - -static int write_to_fifo(ASyncContext *s, AVFrame *buf) -{ - int ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - av_frame_free(&buf); - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - ASyncContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int nb_channels = av_get_channel_layout_nb_channels(buf->channel_layout); - int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts : - av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); - int out_size, ret; - int64_t delta; - int64_t new_pts; - - /* buffer data until we get the next timestamp */ - if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) { - if (pts != AV_NOPTS_VALUE) { - s->pts = pts - get_delay(s); - } - return write_to_fifo(s, buf); - } - - if (s->first_pts != AV_NOPTS_VALUE) { - handle_trimming(ctx); - if (!avresample_available(s->avr)) - return write_to_fifo(s, buf); - } - - /* when we have two timestamps, compute how many samples would we have - * to add/remove to get proper sync between data and timestamps */ - delta = pts - s->pts - get_delay(s); - out_size = avresample_available(s->avr); - - if (labs(delta) > s->min_delta || - (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) { - av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); - out_size = av_clipl_int32((int64_t)out_size + delta); - } else { - if (s->resample) { - // adjust the compensation if delta is non-zero - int delay = get_delay(s); - int comp = s->comp + av_clip(delta * inlink->sample_rate / delay, - -s->max_comp, s->max_comp); - if (comp != s->comp) { - av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); - if (avresample_set_compensation(s->avr, comp, inlink->sample_rate) == 0) { - s->comp = comp; - } - } - } - // adjust PTS to avoid monotonicity errors with input PTS jitter - pts -= delta; - delta = 0; - } - - if (out_size > 0) { - AVFrame *buf_out = ff_get_audio_buffer(outlink, out_size); - if (!buf_out) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (s->first_frame && delta > 0) { - int planar = av_sample_fmt_is_planar(buf_out->format); - int planes = planar ? nb_channels : 1; - int block_size = av_get_bytes_per_sample(buf_out->format) * - (planar ? 1 : nb_channels); - - int ch; - - av_samples_set_silence(buf_out->extended_data, 0, delta, - nb_channels, buf->format); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] += delta * block_size; - - avresample_read(s->avr, buf_out->extended_data, out_size); - - for (ch = 0; ch < planes; ch++) - buf_out->extended_data[ch] -= delta * block_size; - } else { - avresample_read(s->avr, buf_out->extended_data, out_size); - - if (delta > 0) { - av_samples_set_silence(buf_out->extended_data, out_size - delta, - delta, nb_channels, buf->format); - } - } - buf_out->pts = s->pts; - ret = ff_filter_frame(outlink, buf_out); - if (ret < 0) - goto fail; - s->got_output = 1; - } else if (avresample_available(s->avr)) { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - } - - /* drain any remaining buffered data */ - avresample_read(s->avr, NULL, avresample_available(s->avr)); - - new_pts = pts - avresample_get_delay(s->avr); - /* check for s->pts monotonicity */ - if (new_pts > s->pts) { - s->pts = new_pts; - ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data, - buf->linesize[0], buf->nb_samples); - } else { - av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " - "whole buffer.\n"); - ret = 0; - } - - s->first_frame = 0; -fail: - av_frame_free(&buf); - - return ret; -} - -static const AVFilterPad avfilter_af_asyncts_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_asyncts_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .request_frame = request_frame - }, - { NULL } -}; - -AVFilter ff_af_asyncts = { - .name = "asyncts", - .description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps"), - .init = init, - .uninit = uninit, - .priv_size = sizeof(ASyncContext), - .priv_class = &asyncts_class, - .inputs = avfilter_af_asyncts_inputs, - .outputs = avfilter_af_asyncts_outputs, -}; diff --git a/ffmpeg/libavfilter/af_atempo.c b/ffmpeg/libavfilter/af_atempo.c deleted file mode 100644 index c474d6a..0000000 --- a/ffmpeg/libavfilter/af_atempo.c +++ /dev/null @@ -1,1196 +0,0 @@ -/* - * Copyright (c) 2012 Pavel Koshevoy <pkoshevoy at gmail dot com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * tempo scaling audio filter -- an implementation of WSOLA algorithm - * - * Based on MIT licensed yaeAudioTempoFilter.h and yaeAudioFragment.h - * from Apprentice Video player by Pavel Koshevoy. - * https://sourceforge.net/projects/apprenticevideo/ - * - * An explanation of SOLA algorithm is available at - * http://www.surina.net/article/time-and-pitch-scaling.html - * - * WSOLA is very similar to SOLA, only one major difference exists between - * these algorithms. SOLA shifts audio fragments along the output stream, - * where as WSOLA shifts audio fragments along the input stream. - * - * The advantage of WSOLA algorithm is that the overlap region size is - * always the same, therefore the blending function is constant and - * can be precomputed. - */ - -#include <float.h> -#include "libavcodec/avfft.h" -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" -#include "avfilter.h" -#include "audio.h" -#include "internal.h" - -/** - * A fragment of audio waveform - */ -typedef struct { - // index of the first sample of this fragment in the overall waveform; - // 0: input sample position - // 1: output sample position - int64_t position[2]; - - // original packed multi-channel samples: - uint8_t *data; - - // number of samples in this fragment: - int nsamples; - - // rDFT transform of the down-mixed mono fragment, used for - // fast waveform alignment via correlation in frequency domain: - FFTSample *xdat; -} AudioFragment; - -/** - * Filter state machine states - */ -typedef enum { - YAE_LOAD_FRAGMENT, - YAE_ADJUST_POSITION, - YAE_RELOAD_FRAGMENT, - YAE_OUTPUT_OVERLAP_ADD, - YAE_FLUSH_OUTPUT, -} FilterState; - -/** - * Filter state machine - */ -typedef struct { - const AVClass *class; - - // ring-buffer of input samples, necessary because some times - // input fragment position may be adjusted backwards: - uint8_t *buffer; - - // ring-buffer maximum capacity, expressed in sample rate time base: - int ring; - - // ring-buffer house keeping: - int size; - int head; - int tail; - - // 0: input sample position corresponding to the ring buffer tail - // 1: output sample position - int64_t position[2]; - - // sample format: - enum AVSampleFormat format; - - // number of channels: - int channels; - - // row of bytes to skip from one sample to next, across multple channels; - // stride = (number-of-channels * bits-per-sample-per-channel) / 8 - int stride; - - // fragment window size, power-of-two integer: - int window; - - // Hann window coefficients, for feathering - // (blending) the overlapping fragment region: - float *hann; - - // tempo scaling factor: - double tempo; - - // a snapshot of previous fragment input and output position values - // captured when the tempo scale factor was set most recently: - int64_t origin[2]; - - // current/previous fragment ring-buffer: - AudioFragment frag[2]; - - // current fragment index: - uint64_t nfrag; - - // current state: - FilterState state; - - // for fast correlation calculation in frequency domain: - RDFTContext *real_to_complex; - RDFTContext *complex_to_real; - FFTSample *correlation; - - // for managing AVFilterPad.request_frame and AVFilterPad.filter_frame - AVFrame *dst_buffer; - uint8_t *dst; - uint8_t *dst_end; - uint64_t nsamples_in; - uint64_t nsamples_out; -} ATempoContext; - -#define OFFSET(x) offsetof(ATempoContext, x) - -static const AVOption atempo_options[] = { - { "tempo", "set tempo scale factor", - OFFSET(tempo), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, 0.5, 2.0, - AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(atempo); - -inline static AudioFragment *yae_curr_frag(ATempoContext *atempo) -{ - return &atempo->frag[atempo->nfrag % 2]; -} - -inline static AudioFragment *yae_prev_frag(ATempoContext *atempo) -{ - return &atempo->frag[(atempo->nfrag + 1) % 2]; -} - -/** - * Reset filter to initial state, do not deallocate existing local buffers. - */ -static void yae_clear(ATempoContext *atempo) -{ - atempo->size = 0; - atempo->head = 0; - atempo->tail = 0; - - atempo->nfrag = 0; - atempo->state = YAE_LOAD_FRAGMENT; - - atempo->position[0] = 0; - atempo->position[1] = 0; - - atempo->origin[0] = 0; - atempo->origin[1] = 0; - - atempo->frag[0].position[0] = 0; - atempo->frag[0].position[1] = 0; - atempo->frag[0].nsamples = 0; - - atempo->frag[1].position[0] = 0; - atempo->frag[1].position[1] = 0; - atempo->frag[1].nsamples = 0; - - // shift left position of 1st fragment by half a window - // so that no re-normalization would be required for - // the left half of the 1st fragment: - atempo->frag[0].position[0] = -(int64_t)(atempo->window / 2); - atempo->frag[0].position[1] = -(int64_t)(atempo->window / 2); - - av_frame_free(&atempo->dst_buffer); - atempo->dst = NULL; - atempo->dst_end = NULL; - - atempo->nsamples_in = 0; - atempo->nsamples_out = 0; -} - -/** - * Reset filter to initial state and deallocate all buffers. - */ -static void yae_release_buffers(ATempoContext *atempo) -{ - yae_clear(atempo); - - av_freep(&atempo->frag[0].data); - av_freep(&atempo->frag[1].data); - av_freep(&atempo->frag[0].xdat); - av_freep(&atempo->frag[1].xdat); - - av_freep(&atempo->buffer); - av_freep(&atempo->hann); - av_freep(&atempo->correlation); - - av_rdft_end(atempo->real_to_complex); - atempo->real_to_complex = NULL; - - av_rdft_end(atempo->complex_to_real); - atempo->complex_to_real = NULL; -} - -/* av_realloc is not aligned enough; fortunately, the data does not need to - * be preserved */ -#define RE_MALLOC_OR_FAIL(field, field_size) \ - do { \ - av_freep(&field); \ - field = av_malloc(field_size); \ - if (!field) { \ - yae_release_buffers(atempo); \ - return AVERROR(ENOMEM); \ - } \ - } while (0) - -/** - * Prepare filter for processing audio data of given format, - * sample rate and number of channels. - */ -static int yae_reset(ATempoContext *atempo, - enum AVSampleFormat format, - int sample_rate, - int channels) -{ - const int sample_size = av_get_bytes_per_sample(format); - uint32_t nlevels = 0; - uint32_t pot; - int i; - - atempo->format = format; - atempo->channels = channels; - atempo->stride = sample_size * channels; - - // pick a segment window size: - atempo->window = sample_rate / 24; - - // adjust window size to be a power-of-two integer: - nlevels = av_log2(atempo->window); - pot = 1 << nlevels; - av_assert0(pot <= atempo->window); - - if (pot < atempo->window) { - atempo->window = pot * 2; - nlevels++; - } - - // initialize audio fragment buffers: - RE_MALLOC_OR_FAIL(atempo->frag[0].data, atempo->window * atempo->stride); - RE_MALLOC_OR_FAIL(atempo->frag[1].data, atempo->window * atempo->stride); - RE_MALLOC_OR_FAIL(atempo->frag[0].xdat, atempo->window * sizeof(FFTComplex)); - RE_MALLOC_OR_FAIL(atempo->frag[1].xdat, atempo->window * sizeof(FFTComplex)); - - // initialize rDFT contexts: - av_rdft_end(atempo->real_to_complex); - atempo->real_to_complex = NULL; - - av_rdft_end(atempo->complex_to_real); - atempo->complex_to_real = NULL; - - atempo->real_to_complex = av_rdft_init(nlevels + 1, DFT_R2C); - if (!atempo->real_to_complex) { - yae_release_buffers(atempo); - return AVERROR(ENOMEM); - } - - atempo->complex_to_real = av_rdft_init(nlevels + 1, IDFT_C2R); - if (!atempo->complex_to_real) { - yae_release_buffers(atempo); - return AVERROR(ENOMEM); - } - - RE_MALLOC_OR_FAIL(atempo->correlation, atempo->window * sizeof(FFTComplex)); - - atempo->ring = atempo->window * 3; - RE_MALLOC_OR_FAIL(atempo->buffer, atempo->ring * atempo->stride); - - // initialize the Hann window function: - RE_MALLOC_OR_FAIL(atempo->hann, atempo->window * sizeof(float)); - - for (i = 0; i < atempo->window; i++) { - double t = (double)i / (double)(atempo->window - 1); - double h = 0.5 * (1.0 - cos(2.0 * M_PI * t)); - atempo->hann[i] = (float)h; - } - - yae_clear(atempo); - return 0; -} - -static int yae_set_tempo(AVFilterContext *ctx, const char *arg_tempo) -{ - const AudioFragment *prev; - ATempoContext *atempo = ctx->priv; - char *tail = NULL; - double tempo = av_strtod(arg_tempo, &tail); - - if (tail && *tail) { - av_log(ctx, AV_LOG_ERROR, "Invalid tempo value '%s'\n", arg_tempo); - return AVERROR(EINVAL); - } - - if (tempo < 0.5 || tempo > 2.0) { - av_log(ctx, AV_LOG_ERROR, "Tempo value %f exceeds [0.5, 2.0] range\n", - tempo); - return AVERROR(EINVAL); - } - - prev = yae_prev_frag(atempo); - atempo->origin[0] = prev->position[0] + atempo->window / 2; - atempo->origin[1] = prev->position[1] + atempo->window / 2; - atempo->tempo = tempo; - return 0; -} - -/** - * A helper macro for initializing complex data buffer with scalar data - * of a given type. - */ -#define yae_init_xdat(scalar_type, scalar_max) \ - do { \ - const uint8_t *src_end = src + \ - frag->nsamples * atempo->channels * sizeof(scalar_type); \ - \ - FFTSample *xdat = frag->xdat; \ - scalar_type tmp; \ - \ - if (atempo->channels == 1) { \ - for (; src < src_end; xdat++) { \ - tmp = *(const scalar_type *)src; \ - src += sizeof(scalar_type); \ - \ - *xdat = (FFTSample)tmp; \ - } \ - } else { \ - FFTSample s, max, ti, si; \ - int i; \ - \ - for (; src < src_end; xdat++) { \ - tmp = *(const scalar_type *)src; \ - src += sizeof(scalar_type); \ - \ - max = (FFTSample)tmp; \ - s = FFMIN((FFTSample)scalar_max, \ - (FFTSample)fabsf(max)); \ - \ - for (i = 1; i < atempo->channels; i++) { \ - tmp = *(const scalar_type *)src; \ - src += sizeof(scalar_type); \ - \ - ti = (FFTSample)tmp; \ - si = FFMIN((FFTSample)scalar_max, \ - (FFTSample)fabsf(ti)); \ - \ - if (s < si) { \ - s = si; \ - max = ti; \ - } \ - } \ - \ - *xdat = max; \ - } \ - } \ - } while (0) - -/** - * Initialize complex data buffer of a given audio fragment - * with down-mixed mono data of appropriate scalar type. - */ -static void yae_downmix(ATempoContext *atempo, AudioFragment *frag) -{ - // shortcuts: - const uint8_t *src = frag->data; - - // init complex data buffer used for FFT and Correlation: - memset(frag->xdat, 0, sizeof(FFTComplex) * atempo->window); - - if (atempo->format == AV_SAMPLE_FMT_U8) { - yae_init_xdat(uint8_t, 127); - } else if (atempo->format == AV_SAMPLE_FMT_S16) { - yae_init_xdat(int16_t, 32767); - } else if (atempo->format == AV_SAMPLE_FMT_S32) { - yae_init_xdat(int, 2147483647); - } else if (atempo->format == AV_SAMPLE_FMT_FLT) { - yae_init_xdat(float, 1); - } else if (atempo->format == AV_SAMPLE_FMT_DBL) { - yae_init_xdat(double, 1); - } -} - -/** - * Populate the internal data buffer on as-needed basis. - * - * @return - * 0 if requested data was already available or was successfully loaded, - * AVERROR(EAGAIN) if more input data is required. - */ -static int yae_load_data(ATempoContext *atempo, - const uint8_t **src_ref, - const uint8_t *src_end, - int64_t stop_here) -{ - // shortcut: - const uint8_t *src = *src_ref; - const int read_size = stop_here - atempo->position[0]; - - if (stop_here <= atempo->position[0]) { - return 0; - } - - // samples are not expected to be skipped: - av_assert0(read_size <= atempo->ring); - - while (atempo->position[0] < stop_here && src < src_end) { - int src_samples = (src_end - src) / atempo->stride; - - // load data piece-wise, in order to avoid complicating the logic: - int nsamples = FFMIN(read_size, src_samples); - int na; - int nb; - - nsamples = FFMIN(nsamples, atempo->ring); - na = FFMIN(nsamples, atempo->ring - atempo->tail); - nb = FFMIN(nsamples - na, atempo->ring); - - if (na) { - uint8_t *a = atempo->buffer + atempo->tail * atempo->stride; - memcpy(a, src, na * atempo->stride); - - src += na * atempo->stride; - atempo->position[0] += na; - - atempo->size = FFMIN(atempo->size + na, atempo->ring); - atempo->tail = (atempo->tail + na) % atempo->ring; - atempo->head = - atempo->size < atempo->ring ? - atempo->tail - atempo->size : - atempo->tail; - } - - if (nb) { - uint8_t *b = atempo->buffer; - memcpy(b, src, nb * atempo->stride); - - src += nb * atempo->stride; - atempo->position[0] += nb; - - atempo->size = FFMIN(atempo->size + nb, atempo->ring); - atempo->tail = (atempo->tail + nb) % atempo->ring; - atempo->head = - atempo->size < atempo->ring ? - atempo->tail - atempo->size : - atempo->tail; - } - } - - // pass back the updated source buffer pointer: - *src_ref = src; - - // sanity check: - av_assert0(atempo->position[0] <= stop_here); - - return atempo->position[0] == stop_here ? 0 : AVERROR(EAGAIN); -} - -/** - * Populate current audio fragment data buffer. - * - * @return - * 0 when the fragment is ready, - * AVERROR(EAGAIN) if more input data is required. - */ -static int yae_load_frag(ATempoContext *atempo, - const uint8_t **src_ref, - const uint8_t *src_end) -{ - // shortcuts: - AudioFragment *frag = yae_curr_frag(atempo); - uint8_t *dst; - int64_t missing, start, zeros; - uint32_t nsamples; - const uint8_t *a, *b; - int i0, i1, n0, n1, na, nb; - - int64_t stop_here = frag->position[0] + atempo->window; - if (src_ref && yae_load_data(atempo, src_ref, src_end, stop_here) != 0) { - return AVERROR(EAGAIN); - } - - // calculate the number of samples we don't have: - missing = - stop_here > atempo->position[0] ? - stop_here - atempo->position[0] : 0; - - nsamples = - missing < (int64_t)atempo->window ? - (uint32_t)(atempo->window - missing) : 0; - - // setup the output buffer: - frag->nsamples = nsamples; - dst = frag->data; - - start = atempo->position[0] - atempo->size; - zeros = 0; - - if (frag->position[0] < start) { - // what we don't have we substitute with zeros: - zeros = FFMIN(start - frag->position[0], (int64_t)nsamples); - av_assert0(zeros != nsamples); - - memset(dst, 0, zeros * atempo->stride); - dst += zeros * atempo->stride; - } - - if (zeros == nsamples) { - return 0; - } - - // get the remaining data from the ring buffer: - na = (atempo->head < atempo->tail ? - atempo->tail - atempo->head : - atempo->ring - atempo->head); - - nb = atempo->head < atempo->tail ? 0 : atempo->tail; - - // sanity check: - av_assert0(nsamples <= zeros + na + nb); - - a = atempo->buffer + atempo->head * atempo->stride; - b = atempo->buffer; - - i0 = frag->position[0] + zeros - start; - i1 = i0 < na ? 0 : i0 - na; - - n0 = i0 < na ? FFMIN(na - i0, (int)(nsamples - zeros)) : 0; - n1 = nsamples - zeros - n0; - - if (n0) { - memcpy(dst, a + i0 * atempo->stride, n0 * atempo->stride); - dst += n0 * atempo->stride; - } - - if (n1) { - memcpy(dst, b + i1 * atempo->stride, n1 * atempo->stride); - } - - return 0; -} - -/** - * Prepare for loading next audio fragment. - */ -static void yae_advance_to_next_frag(ATempoContext *atempo) -{ - const double fragment_step = atempo->tempo * (double)(atempo->window / 2); - - const AudioFragment *prev; - AudioFragment *frag; - - atempo->nfrag++; - prev = yae_prev_frag(atempo); - frag = yae_curr_frag(atempo); - - frag->position[0] = prev->position[0] + (int64_t)fragment_step; - frag->position[1] = prev->position[1] + atempo->window / 2; - frag->nsamples = 0; -} - -/** - * Calculate cross-correlation via rDFT. - * - * Multiply two vectors of complex numbers (result of real_to_complex rDFT) - * and transform back via complex_to_real rDFT. - */ -static void yae_xcorr_via_rdft(FFTSample *xcorr, - RDFTContext *complex_to_real, - const FFTComplex *xa, - const FFTComplex *xb, - const int window) -{ - FFTComplex *xc = (FFTComplex *)xcorr; - int i; - - // NOTE: first element requires special care -- Given Y = rDFT(X), - // Im(Y[0]) and Im(Y[N/2]) are always zero, therefore av_rdft_calc - // stores Re(Y[N/2]) in place of Im(Y[0]). - - xc->re = xa->re * xb->re; - xc->im = xa->im * xb->im; - xa++; - xb++; - xc++; - - for (i = 1; i < window; i++, xa++, xb++, xc++) { - xc->re = (xa->re * xb->re + xa->im * xb->im); - xc->im = (xa->im * xb->re - xa->re * xb->im); - } - - // apply inverse rDFT: - av_rdft_calc(complex_to_real, xcorr); -} - -/** - * Calculate alignment offset for given fragment - * relative to the previous fragment. - * - * @return alignment offset of current fragment relative to previous. - */ -static int yae_align(AudioFragment *frag, - const AudioFragment *prev, - const int window, - const int delta_max, - const int drift, - FFTSample *correlation, - RDFTContext *complex_to_real) -{ - int best_offset = -drift; - FFTSample best_metric = -FLT_MAX; - FFTSample *xcorr; - - int i0; - int i1; - int i; - - yae_xcorr_via_rdft(correlation, - complex_to_real, - (const FFTComplex *)prev->xdat, - (const FFTComplex *)frag->xdat, - window); - - // identify search window boundaries: - i0 = FFMAX(window / 2 - delta_max - drift, 0); - i0 = FFMIN(i0, window); - - i1 = FFMIN(window / 2 + delta_max - drift, window - window / 16); - i1 = FFMAX(i1, 0); - - // identify cross-correlation peaks within search window: - xcorr = correlation + i0; - - for (i = i0; i < i1; i++, xcorr++) { - FFTSample metric = *xcorr; - - // normalize: - FFTSample drifti = (FFTSample)(drift + i); - metric *= drifti * (FFTSample)(i - i0) * (FFTSample)(i1 - i); - - if (metric > best_metric) { - best_metric = metric; - best_offset = i - window / 2; - } - } - - return best_offset; -} - -/** - * Adjust current fragment position for better alignment - * with previous fragment. - * - * @return alignment correction. - */ -static int yae_adjust_position(ATempoContext *atempo) -{ - const AudioFragment *prev = yae_prev_frag(atempo); - AudioFragment *frag = yae_curr_frag(atempo); - - const double prev_output_position = - (double)(prev->position[1] - atempo->origin[1] + atempo->window / 2); - - const double ideal_output_position = - (double)(prev->position[0] - atempo->origin[0] + atempo->window / 2) / - atempo->tempo; - - const int drift = (int)(prev_output_position - ideal_output_position); - - const int delta_max = atempo->window / 2; - const int correction = yae_align(frag, - prev, - atempo->window, - delta_max, - drift, - atempo->correlation, - atempo->complex_to_real); - - if (correction) { - // adjust fragment position: - frag->position[0] -= correction; - - // clear so that the fragment can be reloaded: - frag->nsamples = 0; - } - - return correction; -} - -/** - * A helper macro for blending the overlap region of previous - * and current audio fragment. - */ -#define yae_blend(scalar_type) \ - do { \ - const scalar_type *aaa = (const scalar_type *)a; \ - const scalar_type *bbb = (const scalar_type *)b; \ - \ - scalar_type *out = (scalar_type *)dst; \ - scalar_type *out_end = (scalar_type *)dst_end; \ - int64_t i; \ - \ - for (i = 0; i < overlap && out < out_end; \ - i++, atempo->position[1]++, wa++, wb++) { \ - float w0 = *wa; \ - float w1 = *wb; \ - int j; \ - \ - for (j = 0; j < atempo->channels; \ - j++, aaa++, bbb++, out++) { \ - float t0 = (float)*aaa; \ - float t1 = (float)*bbb; \ - \ - *out = \ - frag->position[0] + i < 0 ? \ - *aaa : \ - (scalar_type)(t0 * w0 + t1 * w1); \ - } \ - } \ - dst = (uint8_t *)out; \ - } while (0) - -/** - * Blend the overlap region of previous and current audio fragment - * and output the results to the given destination buffer. - * - * @return - * 0 if the overlap region was completely stored in the dst buffer, - * AVERROR(EAGAIN) if more destination buffer space is required. - */ -static int yae_overlap_add(ATempoContext *atempo, - uint8_t **dst_ref, - uint8_t *dst_end) -{ - // shortcuts: - const AudioFragment *prev = yae_prev_frag(atempo); - const AudioFragment *frag = yae_curr_frag(atempo); - - const int64_t start_here = FFMAX(atempo->position[1], - frag->position[1]); - - const int64_t stop_here = FFMIN(prev->position[1] + prev->nsamples, - frag->position[1] + frag->nsamples); - - const int64_t overlap = stop_here - start_here; - - const int64_t ia = start_here - prev->position[1]; - const int64_t ib = start_here - frag->position[1]; - - const float *wa = atempo->hann + ia; - const float *wb = atempo->hann + ib; - - const uint8_t *a = prev->data + ia * atempo->stride; - const uint8_t *b = frag->data + ib * atempo->stride; - - uint8_t *dst = *dst_ref; - - av_assert0(start_here <= stop_here && - frag->position[1] <= start_here && - overlap <= frag->nsamples); - - if (atempo->format == AV_SAMPLE_FMT_U8) { - yae_blend(uint8_t); - } else if (atempo->format == AV_SAMPLE_FMT_S16) { - yae_blend(int16_t); - } else if (atempo->format == AV_SAMPLE_FMT_S32) { - yae_blend(int); - } else if (atempo->format == AV_SAMPLE_FMT_FLT) { - yae_blend(float); - } else if (atempo->format == AV_SAMPLE_FMT_DBL) { - yae_blend(double); - } - - // pass-back the updated destination buffer pointer: - *dst_ref = dst; - - return atempo->position[1] == stop_here ? 0 : AVERROR(EAGAIN); -} - -/** - * Feed as much data to the filter as it is able to consume - * and receive as much processed data in the destination buffer - * as it is able to produce or store. - */ -static void -yae_apply(ATempoContext *atempo, - const uint8_t **src_ref, - const uint8_t *src_end, - uint8_t **dst_ref, - uint8_t *dst_end) -{ - while (1) { - if (atempo->state == YAE_LOAD_FRAGMENT) { - // load additional data for the current fragment: - if (yae_load_frag(atempo, src_ref, src_end) != 0) { - break; - } - - // down-mix to mono: - yae_downmix(atempo, yae_curr_frag(atempo)); - - // apply rDFT: - av_rdft_calc(atempo->real_to_complex, yae_curr_frag(atempo)->xdat); - - // must load the second fragment before alignment can start: - if (!atempo->nfrag) { - yae_advance_to_next_frag(atempo); - continue; - } - - atempo->state = YAE_ADJUST_POSITION; - } - - if (atempo->state == YAE_ADJUST_POSITION) { - // adjust position for better alignment: - if (yae_adjust_position(atempo)) { - // reload the fragment at the corrected position, so that the - // Hann window blending would not require normalization: - atempo->state = YAE_RELOAD_FRAGMENT; - } else { - atempo->state = YAE_OUTPUT_OVERLAP_ADD; - } - } - - if (atempo->state == YAE_RELOAD_FRAGMENT) { - // load additional data if necessary due to position adjustment: - if (yae_load_frag(atempo, src_ref, src_end) != 0) { - break; - } - - // down-mix to mono: - yae_downmix(atempo, yae_curr_frag(atempo)); - - // apply rDFT: - av_rdft_calc(atempo->real_to_complex, yae_curr_frag(atempo)->xdat); - - atempo->state = YAE_OUTPUT_OVERLAP_ADD; - } - - if (atempo->state == YAE_OUTPUT_OVERLAP_ADD) { - // overlap-add and output the result: - if (yae_overlap_add(atempo, dst_ref, dst_end) != 0) { - break; - } - - // advance to the next fragment, repeat: - yae_advance_to_next_frag(atempo); - atempo->state = YAE_LOAD_FRAGMENT; - } - } -} - -/** - * Flush any buffered data from the filter. - * - * @return - * 0 if all data was completely stored in the dst buffer, - * AVERROR(EAGAIN) if more destination buffer space is required. - */ -static int yae_flush(ATempoContext *atempo, - uint8_t **dst_ref, - uint8_t *dst_end) -{ - AudioFragment *frag = yae_curr_frag(atempo); - int64_t overlap_end; - int64_t start_here; - int64_t stop_here; - int64_t offset; - - const uint8_t *src; - uint8_t *dst; - - int src_size; - int dst_size; - int nbytes; - - atempo->state = YAE_FLUSH_OUTPUT; - - if (atempo->position[0] == frag->position[0] + frag->nsamples && - atempo->position[1] == frag->position[1] + frag->nsamples) { - // the current fragment is already flushed: - return 0; - } - - if (frag->position[0] + frag->nsamples < atempo->position[0]) { - // finish loading the current (possibly partial) fragment: - yae_load_frag(atempo, NULL, NULL); - - if (atempo->nfrag) { - // down-mix to mono: - yae_downmix(atempo, frag); - - // apply rDFT: - av_rdft_calc(atempo->real_to_complex, frag->xdat); - - // align current fragment to previous fragment: - if (yae_adjust_position(atempo)) { - // reload the current fragment due to adjusted position: - yae_load_frag(atempo, NULL, NULL); - } - } - } - - // flush the overlap region: - overlap_end = frag->position[1] + FFMIN(atempo->window / 2, - frag->nsamples); - - while (atempo->position[1] < overlap_end) { - if (yae_overlap_add(atempo, dst_ref, dst_end) != 0) { - return AVERROR(EAGAIN); - } - } - - // flush the remaininder of the current fragment: - start_here = FFMAX(atempo->position[1], overlap_end); - stop_here = frag->position[1] + frag->nsamples; - offset = start_here - frag->position[1]; - av_assert0(start_here <= stop_here && frag->position[1] <= start_here); - - src = frag->data + offset * atempo->stride; - dst = (uint8_t *)*dst_ref; - - src_size = (int)(stop_here - start_here) * atempo->stride; - dst_size = dst_end - dst; - nbytes = FFMIN(src_size, dst_size); - - memcpy(dst, src, nbytes); - dst += nbytes; - - atempo->position[1] += (nbytes / atempo->stride); - - // pass-back the updated destination buffer pointer: - *dst_ref = (uint8_t *)dst; - - return atempo->position[1] == stop_here ? 0 : AVERROR(EAGAIN); -} - -static av_cold int init(AVFilterContext *ctx) -{ - ATempoContext *atempo = ctx->priv; - atempo->format = AV_SAMPLE_FMT_NONE; - atempo->state = YAE_LOAD_FRAGMENT; - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ATempoContext *atempo = ctx->priv; - yae_release_buffers(atempo); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterChannelLayouts *layouts = NULL; - AVFilterFormats *formats = NULL; - - // WSOLA necessitates an internal sliding window ring buffer - // for incoming audio stream. - // - // Planar sample formats are too cumbersome to store in a ring buffer, - // therefore planar sample formats are not supported. - // - static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_U8, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_DBL, - AV_SAMPLE_FMT_NONE - }; - - layouts = ff_all_channel_layouts(); - if (!layouts) { - return AVERROR(ENOMEM); - } - ff_set_common_channel_layouts(ctx, layouts); - - formats = ff_make_format_list(sample_fmts); - if (!formats) { - return AVERROR(ENOMEM); - } - ff_set_common_formats(ctx, formats); - - formats = ff_all_samplerates(); - if (!formats) { - return AVERROR(ENOMEM); - } - ff_set_common_samplerates(ctx, formats); - - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - ATempoContext *atempo = ctx->priv; - - enum AVSampleFormat format = inlink->format; - int sample_rate = (int)inlink->sample_rate; - int channels = av_get_channel_layout_nb_channels(inlink->channel_layout); - - ctx->outputs[0]->flags |= FF_LINK_FLAG_REQUEST_LOOP; - - return yae_reset(atempo, format, sample_rate, channels); -} - -static int push_samples(ATempoContext *atempo, - AVFilterLink *outlink, - int n_out) -{ - int ret; - - atempo->dst_buffer->sample_rate = outlink->sample_rate; - atempo->dst_buffer->nb_samples = n_out; - - // adjust the PTS: - atempo->dst_buffer->pts = - av_rescale_q(atempo->nsamples_out, - (AVRational){ 1, outlink->sample_rate }, - outlink->time_base); - - ret = ff_filter_frame(outlink, atempo->dst_buffer); - if (ret < 0) - return ret; - atempo->dst_buffer = NULL; - atempo->dst = NULL; - atempo->dst_end = NULL; - - atempo->nsamples_out += n_out; - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *src_buffer) -{ - AVFilterContext *ctx = inlink->dst; - ATempoContext *atempo = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - - int ret = 0; - int n_in = src_buffer->nb_samples; - int n_out = (int)(0.5 + ((double)n_in) / atempo->tempo); - - const uint8_t *src = src_buffer->data[0]; - const uint8_t *src_end = src + n_in * atempo->stride; - - while (src < src_end) { - if (!atempo->dst_buffer) { - atempo->dst_buffer = ff_get_audio_buffer(outlink, n_out); - if (!atempo->dst_buffer) - return AVERROR(ENOMEM); - av_frame_copy_props(atempo->dst_buffer, src_buffer); - - atempo->dst = atempo->dst_buffer->data[0]; - atempo->dst_end = atempo->dst + n_out * atempo->stride; - } - - yae_apply(atempo, &src, src_end, &atempo->dst, atempo->dst_end); - - if (atempo->dst == atempo->dst_end) { - int n_samples = ((atempo->dst - atempo->dst_buffer->data[0]) / - atempo->stride); - ret = push_samples(atempo, outlink, n_samples); - if (ret < 0) - goto end; - } - } - - atempo->nsamples_in += n_in; -end: - av_frame_free(&src_buffer); - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ATempoContext *atempo = ctx->priv; - int ret; - - ret = ff_request_frame(ctx->inputs[0]); - - if (ret == AVERROR_EOF) { - // flush the filter: - int n_max = atempo->ring; - int n_out; - int err = AVERROR(EAGAIN); - - while (err == AVERROR(EAGAIN)) { - if (!atempo->dst_buffer) { - atempo->dst_buffer = ff_get_audio_buffer(outlink, n_max); - if (!atempo->dst_buffer) - return AVERROR(ENOMEM); - - atempo->dst = atempo->dst_buffer->data[0]; - atempo->dst_end = atempo->dst + n_max * atempo->stride; - } - - err = yae_flush(atempo, &atempo->dst, atempo->dst_end); - - n_out = ((atempo->dst - atempo->dst_buffer->data[0]) / - atempo->stride); - - if (n_out) { - ret = push_samples(atempo, outlink, n_out); - } - } - - av_frame_free(&atempo->dst_buffer); - atempo->dst = NULL; - atempo->dst_end = NULL; - - return AVERROR_EOF; - } - - return ret; -} - -static int process_command(AVFilterContext *ctx, - const char *cmd, - const char *arg, - char *res, - int res_len, - int flags) -{ - return !strcmp(cmd, "tempo") ? yae_set_tempo(ctx, arg) : AVERROR(ENOSYS); -} - -static const AVFilterPad atempo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad atempo_outputs[] = { - { - .name = "default", - .request_frame = request_frame, - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_atempo = { - .name = "atempo", - .description = NULL_IF_CONFIG_SMALL("Adjust audio tempo."), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .process_command = process_command, - .priv_size = sizeof(ATempoContext), - .priv_class = &atempo_class, - .inputs = atempo_inputs, - .outputs = atempo_outputs, -}; diff --git a/ffmpeg/libavfilter/af_biquads.c b/ffmpeg/libavfilter/af_biquads.c deleted file mode 100644 index 5bafad1..0000000 --- a/ffmpeg/libavfilter/af_biquads.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright (c) 2013 Paul B Mahol - * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com> - * see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt - * - * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com> - * Algorithms: Recursive single pole low/high pass filter - * Reference: The Scientist and Engineer's Guide to Digital Signal Processing - * - * low-pass: output[N] = input[N] * A + output[N-1] * B - * X = exp(-2.0 * pi * Fc) - * A = 1 - X - * B = X - * Fc = cutoff freq / sample rate - * - * Mimics an RC low-pass filter: - * - * ---/\/\/\/\-----------> - * | - * --- C - * --- - * | - * | - * V - * - * high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1] - * X = exp(-2.0 * pi * Fc) - * A0 = (1 + X) / 2 - * A1 = -(1 + X) / 2 - * B1 = X - * Fc = cutoff freq / sample rate - * - * Mimics an RC high-pass filter: - * - * || C - * ----||---------> - * || | - * < - * > R - * < - * | - * V - */ - -#include "libavutil/avassert.h" -#include "libavutil/opt.h" -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -enum FilterType { - biquad, - equalizer, - bass, - treble, - band, - bandpass, - bandreject, - allpass, - highpass, - lowpass, -}; - -enum WidthType { - NONE, - HERTZ, - OCTAVE, - QFACTOR, - SLOPE, -}; - -typedef struct ChanCache { - double i1, i2; - double o1, o2; -} ChanCache; - -typedef struct { - const AVClass *class; - - enum FilterType filter_type; - enum WidthType width_type; - int poles; - int csg; - - double gain; - double frequency; - double width; - - double a0, a1, a2; - double b0, b1, b2; - - ChanCache *cache; - - void (*filter)(const void *ibuf, void *obuf, int len, - double *i1, double *i2, double *o1, double *o2, - double b0, double b1, double b2, double a1, double a2); -} BiquadsContext; - -static av_cold int init(AVFilterContext *ctx) -{ - BiquadsContext *p = ctx->priv; - - if (p->filter_type != biquad) { - if (p->frequency <= 0 || p->width <= 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n", - p->frequency, p->width); - return AVERROR(EINVAL); - } - } - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats; - AVFilterChannelLayouts *layouts; - static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S32P, - AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_DBLP, - AV_SAMPLE_FMT_NONE - }; - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_set_common_channel_layouts(ctx, layouts); - - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, formats); - - return 0; -} - -#define BIQUAD_FILTER(name, type, min, max) \ -static void biquad_## name (const void *input, void *output, int len, \ - double *in1, double *in2, \ - double *out1, double *out2, \ - double b0, double b1, double b2, \ - double a1, double a2) \ -{ \ - const type *ibuf = input; \ - type *obuf = output; \ - double i1 = *in1; \ - double i2 = *in2; \ - double o1 = *out1; \ - double o2 = *out2; \ - int i; \ - a1 = -a1; \ - a2 = -a2; \ - \ - for (i = 0; i+1 < len; i++) { \ - o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \ - i2 = ibuf[i]; \ - if (o2 < min) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = min; \ - } else if (o2 > max) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = max; \ - } else { \ - obuf[i] = o2; \ - } \ - i++; \ - o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \ - i1 = ibuf[i]; \ - if (o1 < min) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = min; \ - } else if (o1 > max) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = max; \ - } else { \ - obuf[i] = o1; \ - } \ - } \ - if (i < len) { \ - double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \ - i2 = i1; \ - i1 = ibuf[i]; \ - o2 = o1; \ - o1 = o0; \ - if (o0 < min) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = min; \ - } else if (o0 > max) { \ - av_log(NULL, AV_LOG_WARNING, "clipping\n"); \ - obuf[i] = max; \ - } else { \ - obuf[i] = o0; \ - } \ - } \ - *in1 = i1; \ - *in2 = i2; \ - *out1 = o1; \ - *out2 = o2; \ -} - -BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX) -BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX) -BIQUAD_FILTER(flt, float, -1., 1.) -BIQUAD_FILTER(dbl, double, -1., 1.) - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - BiquadsContext *p = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - double A = exp(p->gain / 40 * log(10.)); - double w0 = 2 * M_PI * p->frequency / inlink->sample_rate; - double alpha; - - if (w0 > M_PI) { - av_log(ctx, AV_LOG_ERROR, - "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n", - p->frequency, inlink->sample_rate); - return AVERROR(EINVAL); - } - - switch (p->width_type) { - case NONE: - alpha = 0.0; - break; - case HERTZ: - alpha = sin(w0) / (2 * p->frequency / p->width); - break; - case OCTAVE: - alpha = sin(w0) * sinh(log(2.) / 2 * p->width * w0 / sin(w0)); - break; - case QFACTOR: - alpha = sin(w0) / (2 * p->width); - break; - case SLOPE: - alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / p->width - 1) + 2); - break; - default: - av_assert0(0); - } - - switch (p->filter_type) { - case biquad: - break; - case equalizer: - p->a0 = 1 + alpha / A; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha / A; - p->b0 = 1 + alpha * A; - p->b1 = -2 * cos(w0); - p->b2 = 1 - alpha * A; - break; - case bass: - p->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha; - p->a1 = -2 * ((A - 1) + (A + 1) * cos(w0)); - p->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha; - p->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha); - p->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0)); - p->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha); - break; - case treble: - p->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha; - p->a1 = 2 * ((A - 1) - (A + 1) * cos(w0)); - p->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha; - p->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha); - p->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0)); - p->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha); - break; - case bandpass: - if (p->csg) { - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = sin(w0) / 2; - p->b1 = 0; - p->b2 = -sin(w0) / 2; - } else { - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = alpha; - p->b1 = 0; - p->b2 = -alpha; - } - break; - case bandreject: - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = 1; - p->b1 = -2 * cos(w0); - p->b2 = 1; - break; - case lowpass: - if (p->poles == 1) { - p->a0 = 1; - p->a1 = -exp(-w0); - p->a2 = 0; - p->b0 = 1 + p->a1; - p->b1 = 0; - p->b2 = 0; - } else { - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = (1 - cos(w0)) / 2; - p->b1 = 1 - cos(w0); - p->b2 = (1 - cos(w0)) / 2; - } - break; - case highpass: - if (p->poles == 1) { - p->a0 = 1; - p->a1 = -exp(-w0); - p->a2 = 0; - p->b0 = (1 - p->a1) / 2; - p->b1 = -p->b0; - p->b2 = 0; - } else { - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = (1 + cos(w0)) / 2; - p->b1 = -(1 + cos(w0)); - p->b2 = (1 + cos(w0)) / 2; - } - break; - case allpass: - p->a0 = 1 + alpha; - p->a1 = -2 * cos(w0); - p->a2 = 1 - alpha; - p->b0 = 1 - alpha; - p->b1 = -2 * cos(w0); - p->b2 = 1 + alpha; - break; - default: - av_assert0(0); - } - - p->a1 /= p->a0; - p->a2 /= p->a0; - p->b0 /= p->a0; - p->b1 /= p->a0; - p->b2 /= p->a0; - - p->cache = av_realloc_f(p->cache, sizeof(ChanCache), inlink->channels); - if (!p->cache) - return AVERROR(ENOMEM); - memset(p->cache, 0, sizeof(ChanCache) * inlink->channels); - - switch (inlink->format) { - case AV_SAMPLE_FMT_S16P: p->filter = biquad_s16; break; - case AV_SAMPLE_FMT_S32P: p->filter = biquad_s32; break; - case AV_SAMPLE_FMT_FLTP: p->filter = biquad_flt; break; - case AV_SAMPLE_FMT_DBLP: p->filter = biquad_dbl; break; - default: av_assert0(0); - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - BiquadsContext *p = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out_buf; - int nb_samples = buf->nb_samples; - int ch; - - if (av_frame_is_writable(buf)) { - out_buf = buf; - } else { - out_buf = ff_get_audio_buffer(inlink, nb_samples); - if (!out_buf) - return AVERROR(ENOMEM); - av_frame_copy_props(out_buf, buf); - } - - for (ch = 0; ch < av_frame_get_channels(buf); ch++) - p->filter(buf->extended_data[ch], - out_buf->extended_data[ch], nb_samples, - &p->cache[ch].i1, &p->cache[ch].i2, - &p->cache[ch].o1, &p->cache[ch].o2, - p->b0, p->b1, p->b2, p->a1, p->a2); - - if (buf != out_buf) - av_frame_free(&buf); - - return ff_filter_frame(outlink, out_buf); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - BiquadsContext *p = ctx->priv; - - av_freep(&p->cache); -} - -static const AVFilterPad inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - }, - { NULL } -}; - -#define OFFSET(x) offsetof(BiquadsContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define DEFINE_BIQUAD_FILTER(name_, description_) \ -AVFILTER_DEFINE_CLASS(name_); \ -static av_cold int name_##_init(AVFilterContext *ctx) \ -{ \ - BiquadsContext *p = ctx->priv; \ - p->class = &name_##_class; \ - p->filter_type = name_; \ - return init(ctx); \ -} \ - \ -AVFilter ff_af_##name_ = { \ - .name = #name_, \ - .description = NULL_IF_CONFIG_SMALL(description_), \ - .priv_size = sizeof(BiquadsContext), \ - .init = name_##_init, \ - .uninit = uninit, \ - .query_formats = query_formats, \ - .inputs = inputs, \ - .outputs = outputs, \ - .priv_class = &name_##_class, \ -} - -#if CONFIG_EQUALIZER_FILTER -static const AVOption equalizer_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS}, - {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS}, - {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter."); -#endif /* CONFIG_EQUALIZER_FILTER */ -#if CONFIG_BASS_FILTER -static const AVOption bass_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies."); -#endif /* CONFIG_BASS_FILTER */ -#if CONFIG_TREBLE_FILTER -static const AVOption treble_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, - {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies."); -#endif /* CONFIG_TREBLE_FILTER */ -#if CONFIG_BANDPASS_FILTER -static const AVOption bandpass_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS}, - {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS}, - {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter."); -#endif /* CONFIG_BANDPASS_FILTER */ -#if CONFIG_BANDREJECT_FILTER -static const AVOption bandreject_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS}, - {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter."); -#endif /* CONFIG_BANDREJECT_FILTER */ -#if CONFIG_LOWPASS_FILTER -static const AVOption lowpass_options[] = { - {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS}, - {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS}, - {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS}, - {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, - {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency."); -#endif /* CONFIG_LOWPASS_FILTER */ -#if CONFIG_HIGHPASS_FILTER -static const AVOption highpass_options[] = { - {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS}, - {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS}, - {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, - {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency."); -#endif /* CONFIG_HIGHPASS_FILTER */ -#if CONFIG_ALLPASS_FILTER -static const AVOption allpass_options[] = { - {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, - {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"}, - {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, - {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, - {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, - {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, - {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS}, - {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter."); -#endif /* CONFIG_ALLPASS_FILTER */ -#if CONFIG_BIQUAD_FILTER -static const AVOption biquad_options[] = { - {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS}, - {NULL} -}; - -DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients."); -#endif /* CONFIG_BIQUAD_FILTER */ diff --git a/ffmpeg/libavfilter/af_channelmap.c b/ffmpeg/libavfilter/af_channelmap.c deleted file mode 100644 index e5e8987..0000000 --- a/ffmpeg/libavfilter/af_channelmap.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2012 Google, Inc. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio channel mapping filter - */ - -#include <ctype.h> - -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -struct ChannelMap { - uint64_t in_channel; - uint64_t out_channel; - int in_channel_idx; - int out_channel_idx; -}; - -enum MappingMode { - MAP_NONE, - MAP_ONE_INT, - MAP_ONE_STR, - MAP_PAIR_INT_INT, - MAP_PAIR_INT_STR, - MAP_PAIR_STR_INT, - MAP_PAIR_STR_STR -}; - -#define MAX_CH 64 -typedef struct ChannelMapContext { - const AVClass *class; - AVFilterChannelLayouts *channel_layouts; - char *mapping_str; - char *channel_layout_str; - uint64_t output_layout; - struct ChannelMap map[MAX_CH]; - int nch; - enum MappingMode mode; -} ChannelMapContext; - -#define OFFSET(x) offsetof(ChannelMapContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption channelmap_options[] = { - { "map", "A comma-separated list of input channel numbers in output order.", - OFFSET(mapping_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { "channel_layout", "Output channel layout.", - OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(channelmap); - -static char* split(char *message, char delim) { - char *next = strchr(message, delim); - if (next) - *next++ = '\0'; - return next; -} - -static int get_channel_idx(char **map, int *ch, char delim, int max_ch) -{ - char *next = split(*map, delim); - int len; - int n = 0; - if (!next && delim == '-') - return AVERROR(EINVAL); - len = strlen(*map); - sscanf(*map, "%d%n", ch, &n); - if (n != len) - return AVERROR(EINVAL); - if (*ch < 0 || *ch > max_ch) - return AVERROR(EINVAL); - *map = next; - return 0; -} - -static int get_channel(char **map, uint64_t *ch, char delim) -{ - char *next = split(*map, delim); - if (!next && delim == '-') - return AVERROR(EINVAL); - *ch = av_get_channel_layout(*map); - if (av_get_channel_layout_nb_channels(*ch) != 1) - return AVERROR(EINVAL); - *map = next; - return 0; -} - -static av_cold int channelmap_init(AVFilterContext *ctx) -{ - ChannelMapContext *s = ctx->priv; - char *mapping, separator = '|'; - int map_entries = 0; - char buf[256]; - enum MappingMode mode; - uint64_t out_ch_mask = 0; - int i; - - mapping = s->mapping_str; - - if (!mapping) { - mode = MAP_NONE; - } else { - char *dash = strchr(mapping, '-'); - if (!dash) { // short mapping - if (av_isdigit(*mapping)) - mode = MAP_ONE_INT; - else - mode = MAP_ONE_STR; - } else if (av_isdigit(*mapping)) { - if (av_isdigit(*(dash+1))) - mode = MAP_PAIR_INT_INT; - else - mode = MAP_PAIR_INT_STR; - } else { - if (av_isdigit(*(dash+1))) - mode = MAP_PAIR_STR_INT; - else - mode = MAP_PAIR_STR_STR; - } -#if FF_API_OLD_FILTER_OPTS - if (strchr(mapping, ',')) { - av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use " - "'|' to separate the mappings.\n"); - separator = ','; - } -#endif - } - - if (mode != MAP_NONE) { - char *sep = mapping; - map_entries = 1; - while ((sep = strchr(sep, separator))) { - if (*++sep) // Allow trailing comma - map_entries++; - } - } - - if (map_entries > MAX_CH) { - av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries); - return AVERROR(EINVAL); - } - - for (i = 0; i < map_entries; i++) { - int in_ch_idx = -1, out_ch_idx = -1; - uint64_t in_ch = 0, out_ch = 0; - static const char err[] = "Failed to parse channel map\n"; - switch (mode) { - case MAP_ONE_INT: - if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel_idx = in_ch_idx; - s->map[i].out_channel_idx = i; - break; - case MAP_ONE_STR: - if (!get_channel(&mapping, &in_ch, separator)) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel = in_ch; - s->map[i].out_channel_idx = i; - break; - case MAP_PAIR_INT_INT: - if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 || - get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel_idx = in_ch_idx; - s->map[i].out_channel_idx = out_ch_idx; - break; - case MAP_PAIR_INT_STR: - if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 || - get_channel(&mapping, &out_ch, separator) < 0 || - out_ch & out_ch_mask) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel_idx = in_ch_idx; - s->map[i].out_channel = out_ch; - out_ch_mask |= out_ch; - break; - case MAP_PAIR_STR_INT: - if (get_channel(&mapping, &in_ch, '-') < 0 || - get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel = in_ch; - s->map[i].out_channel_idx = out_ch_idx; - break; - case MAP_PAIR_STR_STR: - if (get_channel(&mapping, &in_ch, '-') < 0 || - get_channel(&mapping, &out_ch, separator) < 0 || - out_ch & out_ch_mask) { - av_log(ctx, AV_LOG_ERROR, err); - return AVERROR(EINVAL); - } - s->map[i].in_channel = in_ch; - s->map[i].out_channel = out_ch; - out_ch_mask |= out_ch; - break; - } - } - s->mode = mode; - s->nch = map_entries; - s->output_layout = out_ch_mask ? out_ch_mask : - av_get_default_channel_layout(map_entries); - - if (s->channel_layout_str) { - uint64_t fmt; - if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) { - av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n", - s->channel_layout_str); - return AVERROR(EINVAL); - } - if (mode == MAP_NONE) { - int i; - s->nch = av_get_channel_layout_nb_channels(fmt); - for (i = 0; i < s->nch; i++) { - s->map[i].in_channel_idx = i; - s->map[i].out_channel_idx = i; - } - } else if (out_ch_mask && out_ch_mask != fmt) { - av_get_channel_layout_string(buf, sizeof(buf), 0, out_ch_mask); - av_log(ctx, AV_LOG_ERROR, - "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n", - s->channel_layout_str, buf); - return AVERROR(EINVAL); - } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) { - av_log(ctx, AV_LOG_ERROR, - "Output channel layout %s does not match the number of channels mapped %d.\n", - s->channel_layout_str, s->nch); - return AVERROR(EINVAL); - } - s->output_layout = fmt; - } - if (!s->output_layout) { - av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and " - "cannot be guessed from the maps.\n"); - return AVERROR(EINVAL); - } - - ff_add_channel_layout(&s->channel_layouts, s->output_layout); - - if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) { - for (i = 0; i < s->nch; i++) { - s->map[i].out_channel_idx = av_get_channel_layout_channel_index( - s->output_layout, s->map[i].out_channel); - } - } - - return 0; -} - -static int channelmap_query_formats(AVFilterContext *ctx) -{ - ChannelMapContext *s = ctx->priv; - - ff_set_common_formats(ctx, ff_planar_sample_fmts()); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts); - ff_channel_layouts_ref(s->channel_layouts, &ctx->outputs[0]->in_channel_layouts); - - return 0; -} - -static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - const ChannelMapContext *s = ctx->priv; - const int nch_in = av_get_channel_layout_nb_channels(inlink->channel_layout); - const int nch_out = s->nch; - int ch; - uint8_t *source_planes[MAX_CH]; - - memcpy(source_planes, buf->extended_data, - nch_in * sizeof(source_planes[0])); - - if (nch_out > nch_in) { - if (nch_out > FF_ARRAY_ELEMS(buf->data)) { - uint8_t **new_extended_data = - av_mallocz(nch_out * sizeof(*buf->extended_data)); - if (!new_extended_data) { - av_frame_free(&buf); - return AVERROR(ENOMEM); - } - if (buf->extended_data == buf->data) { - buf->extended_data = new_extended_data; - } else { - av_free(buf->extended_data); - buf->extended_data = new_extended_data; - } - } else if (buf->extended_data != buf->data) { - av_free(buf->extended_data); - buf->extended_data = buf->data; - } - } - - for (ch = 0; ch < nch_out; ch++) { - buf->extended_data[s->map[ch].out_channel_idx] = - source_planes[s->map[ch].in_channel_idx]; - } - - if (buf->data != buf->extended_data) - memcpy(buf->data, buf->extended_data, - FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0])); - - return ff_filter_frame(outlink, buf); -} - -static int channelmap_config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - ChannelMapContext *s = ctx->priv; - int nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout); - int i, err = 0; - const char *channel_name; - char layout_name[256]; - - for (i = 0; i < s->nch; i++) { - struct ChannelMap *m = &s->map[i]; - - if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) { - m->in_channel_idx = av_get_channel_layout_channel_index( - inlink->channel_layout, m->in_channel); - } - - if (m->in_channel_idx < 0 || m->in_channel_idx >= nb_channels) { - av_get_channel_layout_string(layout_name, sizeof(layout_name), - 0, inlink->channel_layout); - if (m->in_channel) { - channel_name = av_get_channel_name(m->in_channel); - av_log(ctx, AV_LOG_ERROR, - "input channel '%s' not available from input layout '%s'\n", - channel_name, layout_name); - } else { - av_log(ctx, AV_LOG_ERROR, - "input channel #%d not available from input layout '%s'\n", - m->in_channel_idx, layout_name); - } - err = AVERROR(EINVAL); - } - } - - return err; -} - -static const AVFilterPad avfilter_af_channelmap_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = channelmap_filter_frame, - .config_props = channelmap_config_input, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_channelmap_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO - }, - { NULL } -}; - -AVFilter ff_af_channelmap = { - .name = "channelmap", - .description = NULL_IF_CONFIG_SMALL("Remap audio channels."), - .init = channelmap_init, - .query_formats = channelmap_query_formats, - .priv_size = sizeof(ChannelMapContext), - .priv_class = &channelmap_class, - .inputs = avfilter_af_channelmap_inputs, - .outputs = avfilter_af_channelmap_outputs, -}; diff --git a/ffmpeg/libavfilter/af_channelsplit.c b/ffmpeg/libavfilter/af_channelsplit.c deleted file mode 100644 index b3756e2..0000000 --- a/ffmpeg/libavfilter/af_channelsplit.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Channel split filter - * - * Split an audio stream into per-channel streams. - */ - -#include "libavutil/attributes.h" -#include "libavutil/channel_layout.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -typedef struct ChannelSplitContext { - const AVClass *class; - - uint64_t channel_layout; - char *channel_layout_str; -} ChannelSplitContext; - -#define OFFSET(x) offsetof(ChannelSplitContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption channelsplit_options[] = { - { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(channelsplit); - -static av_cold int init(AVFilterContext *ctx) -{ - ChannelSplitContext *s = ctx->priv; - int nb_channels; - int ret = 0, i; - - if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) { - av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", - s->channel_layout_str); - ret = AVERROR(EINVAL); - goto fail; - } - - nb_channels = av_get_channel_layout_nb_channels(s->channel_layout); - for (i = 0; i < nb_channels; i++) { - uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i); - AVFilterPad pad = { 0 }; - - pad.type = AVMEDIA_TYPE_AUDIO; - pad.name = av_get_channel_name(channel); - - ff_insert_outpad(ctx, i, &pad); - } - -fail: - return ret; -} - -static int query_formats(AVFilterContext *ctx) -{ - ChannelSplitContext *s = ctx->priv; - AVFilterChannelLayouts *in_layouts = NULL; - int i; - - ff_set_common_formats (ctx, ff_planar_sample_fmts()); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - - ff_add_channel_layout(&in_layouts, s->channel_layout); - ff_channel_layouts_ref(in_layouts, &ctx->inputs[0]->out_channel_layouts); - - for (i = 0; i < ctx->nb_outputs; i++) { - AVFilterChannelLayouts *out_layouts = NULL; - uint64_t channel = av_channel_layout_extract_channel(s->channel_layout, i); - - ff_add_channel_layout(&out_layouts, channel); - ff_channel_layouts_ref(out_layouts, &ctx->outputs[i]->in_channel_layouts); - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - int i, ret = 0; - - for (i = 0; i < ctx->nb_outputs; i++) { - AVFrame *buf_out = av_frame_clone(buf); - - if (!buf_out) { - ret = AVERROR(ENOMEM); - break; - } - - buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i]; - buf_out->channel_layout = - av_channel_layout_extract_channel(buf->channel_layout, i); - av_frame_set_channels(buf_out, 1); - - ret = ff_filter_frame(ctx->outputs[i], buf_out); - if (ret < 0) - break; - } - av_frame_free(&buf); - return ret; -} - -static const AVFilterPad avfilter_af_channelsplit_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_af_channelsplit = { - .name = "channelsplit", - .description = NULL_IF_CONFIG_SMALL("Split audio into per-channel streams."), - .priv_size = sizeof(ChannelSplitContext), - .priv_class = &channelsplit_class, - .init = init, - .query_formats = query_formats, - .inputs = avfilter_af_channelsplit_inputs, - .outputs = NULL, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; diff --git a/ffmpeg/libavfilter/af_earwax.c b/ffmpeg/libavfilter/af_earwax.c deleted file mode 100644 index c310997..0000000 --- a/ffmpeg/libavfilter/af_earwax.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2011 Mina Nagy Zaki - * Copyright (c) 2000 Edward Beingessner And Sundry Contributors. - * This source code is freely redistributable and may be used for any purpose. - * This copyright notice must be maintained. Edward Beingessner And Sundry - * Contributors are not responsible for the consequences of using this - * software. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Stereo Widening Effect. Adds audio cues to move stereo image in - * front of the listener. Adapted from the libsox earwax effect. - */ - -#include "libavutil/channel_layout.h" -#include "avfilter.h" -#include "audio.h" -#include "formats.h" - -#define NUMTAPS 64 - -static const int8_t filt[NUMTAPS] = { -/* 30° 330° */ - 4, -6, /* 32 tap stereo FIR filter. */ - 4, -11, /* One side filters as if the */ - -1, -5, /* signal was from 30 degrees */ - 3, 3, /* from the ear, the other as */ - -2, 5, /* if 330 degrees. */ - -5, 0, - 9, 1, - 6, 3, /* Input */ - -4, -1, /* Left Right */ - -5, -3, /* __________ __________ */ - -2, -5, /* | | | | */ - -7, 1, /* .---| Hh,0(f) | | Hh,0(f) |---. */ - 6, -7, /* / |__________| |__________| \ */ - 30, -29, /* / \ / \ */ - 12, -3, /* / X \ */ - -11, 4, /* / / \ \ */ - -3, 7, /* ____V_____ __________V V__________ _____V____ */ - -20, 23, /* | | | | | | | | */ - 2, 0, /* | Hh,30(f) | | Hh,330(f)| | Hh,330(f)| | Hh,30(f) | */ - 1, -6, /* |__________| |__________| |__________| |__________| */ - -14, -5, /* \ ___ / \ ___ / */ - 15, -18, /* \ / \ / _____ \ / \ / */ - 6, 7, /* `->| + |<--' / \ `-->| + |<-' */ - 15, -10, /* \___/ _/ \_ \___/ */ - -14, 22, /* \ / \ / \ / */ - -7, -2, /* `--->| | | |<---' */ - -4, 9, /* \_/ \_/ */ - 6, -12, /* */ - 6, -6, /* Headphones */ - 0, -11, - 0, -5, - 4, 0}; - -typedef struct { - int16_t taps[NUMTAPS * 2]; -} EarwaxContext; - -static int query_formats(AVFilterContext *ctx) -{ - static const int sample_rates[] = { 44100, -1 }; - - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layout = NULL; - - ff_add_format(&formats, AV_SAMPLE_FMT_S16); - ff_set_common_formats(ctx, formats); - ff_add_channel_layout(&layout, AV_CH_LAYOUT_STEREO); - ff_set_common_channel_layouts(ctx, layout); - ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates)); - - return 0; -} - -//FIXME: replace with DSPContext.scalarproduct_int16 -static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, int16_t *out) -{ - int32_t sample; - int16_t j; - - while (in < endin) { - sample = 0; - for (j = 0; j < NUMTAPS; j++) - sample += in[j] * filt[j]; - *out = av_clip_int16(sample >> 6); - out++; - in++; - } - - return out; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterLink *outlink = inlink->dst->outputs[0]; - int16_t *taps, *endin, *in, *out; - AVFrame *outsamples = ff_get_audio_buffer(inlink, insamples->nb_samples); - int len; - - if (!outsamples) { - av_frame_free(&insamples); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outsamples, insamples); - - taps = ((EarwaxContext *)inlink->dst->priv)->taps; - out = (int16_t *)outsamples->data[0]; - in = (int16_t *)insamples ->data[0]; - - len = FFMIN(NUMTAPS, 2*insamples->nb_samples); - // copy part of new input and process with saved input - memcpy(taps+NUMTAPS, in, len * sizeof(*taps)); - out = scalarproduct(taps, taps + len, out); - - // process current input - if (2*insamples->nb_samples >= NUMTAPS ){ - endin = in + insamples->nb_samples * 2 - NUMTAPS; - scalarproduct(in, endin, out); - - // save part of input for next round - memcpy(taps, endin, NUMTAPS * sizeof(*taps)); - } else - memmove(taps, taps + 2*insamples->nb_samples, NUMTAPS * sizeof(*taps)); - - av_frame_free(&insamples); - return ff_filter_frame(outlink, outsamples); -} - -static const AVFilterPad earwax_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad earwax_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_earwax = { - .name = "earwax", - .description = NULL_IF_CONFIG_SMALL("Widen the stereo image."), - .query_formats = query_formats, - .priv_size = sizeof(EarwaxContext), - .inputs = earwax_inputs, - .outputs = earwax_outputs, -}; diff --git a/ffmpeg/libavfilter/af_join.c b/ffmpeg/libavfilter/af_join.c deleted file mode 100644 index 3e9ccc8..0000000 --- a/ffmpeg/libavfilter/af_join.c +++ /dev/null @@ -1,516 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Audio join filter - * - * Join multiple audio inputs as different channels in - * a single output - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -typedef struct ChannelMap { - int input; ///< input stream index - int in_channel_idx; ///< index of in_channel in the input stream data - uint64_t in_channel; ///< layout describing the input channel - uint64_t out_channel; ///< layout describing the output channel -} ChannelMap; - -typedef struct JoinContext { - const AVClass *class; - - int inputs; - char *map; - char *channel_layout_str; - uint64_t channel_layout; - - int nb_channels; - ChannelMap *channels; - - /** - * Temporary storage for input frames, until we get one on each input. - */ - AVFrame **input_frames; - - /** - * Temporary storage for buffer references, for assembling the output frame. - */ - AVBufferRef **buffers; -} JoinContext; - -#define OFFSET(x) offsetof(JoinContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption join_options[] = { - { "inputs", "Number of input streams.", OFFSET(inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, A|F }, - { "channel_layout", "Channel layout of the " - "output stream.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A|F }, - { "map", "A comma-separated list of channels maps in the format " - "'input_stream.input_channel-output_channel.", - OFFSET(map), AV_OPT_TYPE_STRING, .flags = A|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(join); - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AVFilterContext *ctx = link->dst; - JoinContext *s = ctx->priv; - int i; - - for (i = 0; i < ctx->nb_inputs; i++) - if (link == ctx->inputs[i]) - break; - av_assert0(i < ctx->nb_inputs); - av_assert0(!s->input_frames[i]); - s->input_frames[i] = frame; - - return 0; -} - -static int parse_maps(AVFilterContext *ctx) -{ - JoinContext *s = ctx->priv; - char separator = '|'; - char *cur = s->map; - -#if FF_API_OLD_FILTER_OPTS - if (cur && strchr(cur, ',')) { - av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use '|' to " - "separate the mappings.\n"); - separator = ','; - } -#endif - - while (cur && *cur) { - char *sep, *next, *p; - uint64_t in_channel = 0, out_channel = 0; - int input_idx, out_ch_idx, in_ch_idx; - - next = strchr(cur, separator); - if (next) - *next++ = 0; - - /* split the map into input and output parts */ - if (!(sep = strchr(cur, '-'))) { - av_log(ctx, AV_LOG_ERROR, "Missing separator '-' in channel " - "map '%s'\n", cur); - return AVERROR(EINVAL); - } - *sep++ = 0; - -#define PARSE_CHANNEL(str, var, inout) \ - if (!(var = av_get_channel_layout(str))) { \ - av_log(ctx, AV_LOG_ERROR, "Invalid " inout " channel: %s.\n", str);\ - return AVERROR(EINVAL); \ - } \ - if (av_get_channel_layout_nb_channels(var) != 1) { \ - av_log(ctx, AV_LOG_ERROR, "Channel map describes more than one " \ - inout " channel.\n"); \ - return AVERROR(EINVAL); \ - } - - /* parse output channel */ - PARSE_CHANNEL(sep, out_channel, "output"); - if (!(out_channel & s->channel_layout)) { - av_log(ctx, AV_LOG_ERROR, "Output channel '%s' is not present in " - "requested channel layout.\n", sep); - return AVERROR(EINVAL); - } - - out_ch_idx = av_get_channel_layout_channel_index(s->channel_layout, - out_channel); - if (s->channels[out_ch_idx].input >= 0) { - av_log(ctx, AV_LOG_ERROR, "Multiple maps for output channel " - "'%s'.\n", sep); - return AVERROR(EINVAL); - } - - /* parse input channel */ - input_idx = strtol(cur, &cur, 0); - if (input_idx < 0 || input_idx >= s->inputs) { - av_log(ctx, AV_LOG_ERROR, "Invalid input stream index: %d.\n", - input_idx); - return AVERROR(EINVAL); - } - - if (*cur) - cur++; - - in_ch_idx = strtol(cur, &p, 0); - if (p == cur) { - /* channel specifier is not a number, - * try to parse as channel name */ - PARSE_CHANNEL(cur, in_channel, "input"); - } - - s->channels[out_ch_idx].input = input_idx; - if (in_channel) - s->channels[out_ch_idx].in_channel = in_channel; - else - s->channels[out_ch_idx].in_channel_idx = in_ch_idx; - - cur = next; - } - return 0; -} - -static av_cold int join_init(AVFilterContext *ctx) -{ - JoinContext *s = ctx->priv; - int ret, i; - - if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) { - av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n", - s->channel_layout_str); - return AVERROR(EINVAL); - } - - s->nb_channels = av_get_channel_layout_nb_channels(s->channel_layout); - s->channels = av_mallocz(sizeof(*s->channels) * s->nb_channels); - s->buffers = av_mallocz(sizeof(*s->buffers) * s->nb_channels); - s->input_frames = av_mallocz(sizeof(*s->input_frames) * s->inputs); - if (!s->channels || !s->buffers|| !s->input_frames) - return AVERROR(ENOMEM); - - for (i = 0; i < s->nb_channels; i++) { - s->channels[i].out_channel = av_channel_layout_extract_channel(s->channel_layout, i); - s->channels[i].input = -1; - } - - if ((ret = parse_maps(ctx)) < 0) - return ret; - - for (i = 0; i < s->inputs; i++) { - char name[32]; - AVFilterPad pad = { 0 }; - - snprintf(name, sizeof(name), "input%d", i); - pad.type = AVMEDIA_TYPE_AUDIO; - pad.name = av_strdup(name); - pad.filter_frame = filter_frame; - - pad.needs_fifo = 1; - - ff_insert_inpad(ctx, i, &pad); - } - - return 0; -} - -static av_cold void join_uninit(AVFilterContext *ctx) -{ - JoinContext *s = ctx->priv; - int i; - - for (i = 0; i < ctx->nb_inputs; i++) { - av_freep(&ctx->input_pads[i].name); - av_frame_free(&s->input_frames[i]); - } - - av_freep(&s->channels); - av_freep(&s->buffers); - av_freep(&s->input_frames); -} - -static int join_query_formats(AVFilterContext *ctx) -{ - JoinContext *s = ctx->priv; - AVFilterChannelLayouts *layouts = NULL; - int i; - - ff_add_channel_layout(&layouts, s->channel_layout); - ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts); - - for (i = 0; i < ctx->nb_inputs; i++) - ff_channel_layouts_ref(ff_all_channel_layouts(), - &ctx->inputs[i]->out_channel_layouts); - - ff_set_common_formats (ctx, ff_planar_sample_fmts()); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - - return 0; -} - -static void guess_map_matching(AVFilterContext *ctx, ChannelMap *ch, - uint64_t *inputs) -{ - int i; - - for (i = 0; i < ctx->nb_inputs; i++) { - AVFilterLink *link = ctx->inputs[i]; - - if (ch->out_channel & link->channel_layout && - !(ch->out_channel & inputs[i])) { - ch->input = i; - ch->in_channel = ch->out_channel; - inputs[i] |= ch->out_channel; - return; - } - } -} - -static void guess_map_any(AVFilterContext *ctx, ChannelMap *ch, - uint64_t *inputs) -{ - int i; - - for (i = 0; i < ctx->nb_inputs; i++) { - AVFilterLink *link = ctx->inputs[i]; - - if ((inputs[i] & link->channel_layout) != link->channel_layout) { - uint64_t unused = link->channel_layout & ~inputs[i]; - - ch->input = i; - ch->in_channel = av_channel_layout_extract_channel(unused, 0); - inputs[i] |= ch->in_channel; - return; - } - } -} - -static int join_config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - JoinContext *s = ctx->priv; - uint64_t *inputs; // nth element tracks which channels are used from nth input - int i, ret = 0; - - /* initialize inputs to user-specified mappings */ - if (!(inputs = av_mallocz(sizeof(*inputs) * ctx->nb_inputs))) - return AVERROR(ENOMEM); - for (i = 0; i < s->nb_channels; i++) { - ChannelMap *ch = &s->channels[i]; - AVFilterLink *inlink; - - if (ch->input < 0) - continue; - - inlink = ctx->inputs[ch->input]; - - if (!ch->in_channel) - ch->in_channel = av_channel_layout_extract_channel(inlink->channel_layout, - ch->in_channel_idx); - - if (!(ch->in_channel & inlink->channel_layout)) { - av_log(ctx, AV_LOG_ERROR, "Requested channel %s is not present in " - "input stream #%d.\n", av_get_channel_name(ch->in_channel), - ch->input); - ret = AVERROR(EINVAL); - goto fail; - } - - inputs[ch->input] |= ch->in_channel; - } - - /* guess channel maps when not explicitly defined */ - /* first try unused matching channels */ - for (i = 0; i < s->nb_channels; i++) { - ChannelMap *ch = &s->channels[i]; - - if (ch->input < 0) - guess_map_matching(ctx, ch, inputs); - } - - /* if the above failed, try to find _any_ unused input channel */ - for (i = 0; i < s->nb_channels; i++) { - ChannelMap *ch = &s->channels[i]; - - if (ch->input < 0) - guess_map_any(ctx, ch, inputs); - - if (ch->input < 0) { - av_log(ctx, AV_LOG_ERROR, "Could not find input channel for " - "output channel '%s'.\n", - av_get_channel_name(ch->out_channel)); - goto fail; - } - - ch->in_channel_idx = av_get_channel_layout_channel_index(ctx->inputs[ch->input]->channel_layout, - ch->in_channel); - } - - /* print mappings */ - av_log(ctx, AV_LOG_VERBOSE, "mappings: "); - for (i = 0; i < s->nb_channels; i++) { - ChannelMap *ch = &s->channels[i]; - av_log(ctx, AV_LOG_VERBOSE, "%d.%s => %s ", ch->input, - av_get_channel_name(ch->in_channel), - av_get_channel_name(ch->out_channel)); - } - av_log(ctx, AV_LOG_VERBOSE, "\n"); - - for (i = 0; i < ctx->nb_inputs; i++) { - if (!inputs[i]) - av_log(ctx, AV_LOG_WARNING, "No channels are used from input " - "stream %d.\n", i); - } - -fail: - av_freep(&inputs); - return ret; -} - -static int join_request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - JoinContext *s = ctx->priv; - AVFrame *frame; - int linesize = INT_MAX; - int nb_samples = 0; - int nb_buffers = 0; - int i, j, ret; - - /* get a frame on each input */ - for (i = 0; i < ctx->nb_inputs; i++) { - AVFilterLink *inlink = ctx->inputs[i]; - - if (!s->input_frames[i] && - (ret = ff_request_frame(inlink)) < 0) - return ret; - - /* request the same number of samples on all inputs */ - if (i == 0) { - nb_samples = s->input_frames[0]->nb_samples; - - for (j = 1; !i && j < ctx->nb_inputs; j++) - ctx->inputs[j]->request_samples = nb_samples; - } - } - - /* setup the output frame */ - frame = av_frame_alloc(); - if (!frame) - return AVERROR(ENOMEM); - if (s->nb_channels > FF_ARRAY_ELEMS(frame->data)) { - frame->extended_data = av_mallocz(s->nb_channels * - sizeof(*frame->extended_data)); - if (!frame->extended_data) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - - /* copy the data pointers */ - for (i = 0; i < s->nb_channels; i++) { - ChannelMap *ch = &s->channels[i]; - AVFrame *cur = s->input_frames[ch->input]; - AVBufferRef *buf; - - frame->extended_data[i] = cur->extended_data[ch->in_channel_idx]; - linesize = FFMIN(linesize, cur->linesize[0]); - - /* add the buffer where this plan is stored to the list if it's - * not already there */ - buf = av_frame_get_plane_buffer(cur, ch->in_channel_idx); - if (!buf) { - ret = AVERROR(EINVAL); - goto fail; - } - for (j = 0; j < nb_buffers; j++) - if (s->buffers[j]->buffer == buf->buffer) - break; - if (j == i) - s->buffers[nb_buffers++] = buf; - } - - /* create references to the buffers we copied to output */ - if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) { - frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf); - frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) * - frame->nb_extended_buf); - if (!frame->extended_buf) { - frame->nb_extended_buf = 0; - ret = AVERROR(ENOMEM); - goto fail; - } - } - for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) { - frame->buf[i] = av_buffer_ref(s->buffers[i]); - if (!frame->buf[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - for (i = 0; i < frame->nb_extended_buf; i++) { - frame->extended_buf[i] = av_buffer_ref(s->buffers[i + - FF_ARRAY_ELEMS(frame->buf)]); - if (!frame->extended_buf[i]) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - - frame->nb_samples = nb_samples; - frame->channel_layout = outlink->channel_layout; - av_frame_set_channels(frame, outlink->channels); - frame->format = outlink->format; - frame->sample_rate = outlink->sample_rate; - frame->pts = s->input_frames[0]->pts; - frame->linesize[0] = linesize; - if (frame->data != frame->extended_data) { - memcpy(frame->data, frame->extended_data, sizeof(*frame->data) * - FFMIN(FF_ARRAY_ELEMS(frame->data), s->nb_channels)); - } - - ret = ff_filter_frame(outlink, frame); - - for (i = 0; i < ctx->nb_inputs; i++) - av_frame_free(&s->input_frames[i]); - - return ret; - -fail: - av_frame_free(&frame); - return ret; -} - -static const AVFilterPad avfilter_af_join_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = join_config_output, - .request_frame = join_request_frame, - }, - { NULL } -}; - -AVFilter ff_af_join = { - .name = "join", - .description = NULL_IF_CONFIG_SMALL("Join multiple audio streams into " - "multi-channel output."), - .priv_size = sizeof(JoinContext), - .priv_class = &join_class, - .init = join_init, - .uninit = join_uninit, - .query_formats = join_query_formats, - .inputs = NULL, - .outputs = avfilter_af_join_outputs, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, -}; diff --git a/ffmpeg/libavfilter/af_pan.c b/ffmpeg/libavfilter/af_pan.c deleted file mode 100644 index d28f382..0000000 --- a/ffmpeg/libavfilter/af_pan.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2002 Anders Johansson <ajh@atri.curtin.edu.au> - * Copyright (c) 2011 Clément BÅ“sch <u pkh me> - * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Audio panning filter (channels mixing) - * Original code written by Anders Johansson for MPlayer, - * reimplemented for FFmpeg. - */ - -#include <stdio.h> -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libswresample/swresample.h" -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -#define MAX_CHANNELS 63 - -typedef struct PanContext { - const AVClass *class; - char *args; - int64_t out_channel_layout; - double gain[MAX_CHANNELS][MAX_CHANNELS]; - int64_t need_renorm; - int need_renumber; - int nb_output_channels; - - int pure_gains; - /* channel mapping specific */ - int channel_map[SWR_CH_MAX]; - struct SwrContext *swr; -} PanContext; - -static void skip_spaces(char **arg) -{ - int len = 0; - - sscanf(*arg, " %n", &len); - *arg += len; -} - -static int parse_channel_name(char **arg, int *rchannel, int *rnamed) -{ - char buf[8]; - int len, i, channel_id = 0; - int64_t layout, layout0; - - skip_spaces(arg); - /* try to parse a channel name, e.g. "FL" */ - if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) { - layout0 = layout = av_get_channel_layout(buf); - /* channel_id <- first set bit in layout */ - for (i = 32; i > 0; i >>= 1) { - if (layout >= (int64_t)1 << i) { - channel_id += i; - layout >>= i; - } - } - /* reject layouts that are not a single channel */ - if (channel_id >= MAX_CHANNELS || layout0 != (int64_t)1 << channel_id) - return AVERROR(EINVAL); - *rchannel = channel_id; - *rnamed = 1; - *arg += len; - return 0; - } - /* try to parse a channel number, e.g. "c2" */ - if (sscanf(*arg, "c%d%n", &channel_id, &len) && - channel_id >= 0 && channel_id < MAX_CHANNELS) { - *rchannel = channel_id; - *rnamed = 0; - *arg += len; - return 0; - } - return AVERROR(EINVAL); -} - -static av_cold int init(AVFilterContext *ctx) -{ - PanContext *const pan = ctx->priv; - char *arg, *arg0, *tokenizer, *args = av_strdup(pan->args); - int out_ch_id, in_ch_id, len, named, ret; - int nb_in_channels[2] = { 0, 0 }; // number of unnamed and named input channels - double gain; - - if (!pan->args) { - av_log(ctx, AV_LOG_ERROR, - "pan filter needs a channel layout and a set " - "of channels definitions as parameter\n"); - return AVERROR(EINVAL); - } - if (!args) - return AVERROR(ENOMEM); - arg = av_strtok(args, "|", &tokenizer); - ret = ff_parse_channel_layout(&pan->out_channel_layout, - &pan->nb_output_channels, arg, ctx); - if (ret < 0) - goto fail; - - /* parse channel specifications */ - while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) { - /* channel name */ - if (parse_channel_name(&arg, &out_ch_id, &named)) { - av_log(ctx, AV_LOG_ERROR, - "Expected out channel name, got \"%.8s\"\n", arg); - ret = AVERROR(EINVAL); - goto fail; - } - if (named) { - if (!((pan->out_channel_layout >> out_ch_id) & 1)) { - av_log(ctx, AV_LOG_ERROR, - "Channel \"%.8s\" does not exist in the chosen layout\n", arg0); - ret = AVERROR(EINVAL); - goto fail; - } - /* get the channel number in the output channel layout: - * out_channel_layout & ((1 << out_ch_id) - 1) are all the - * channels that come before out_ch_id, - * so their count is the index of out_ch_id */ - out_ch_id = av_get_channel_layout_nb_channels(pan->out_channel_layout & (((int64_t)1 << out_ch_id) - 1)); - } - if (out_ch_id < 0 || out_ch_id >= pan->nb_output_channels) { - av_log(ctx, AV_LOG_ERROR, - "Invalid out channel name \"%.8s\"\n", arg0); - ret = AVERROR(EINVAL); - goto fail; - } - skip_spaces(&arg); - if (*arg == '=') { - arg++; - } else if (*arg == '<') { - pan->need_renorm |= (int64_t)1 << out_ch_id; - arg++; - } else { - av_log(ctx, AV_LOG_ERROR, - "Syntax error after channel name in \"%.8s\"\n", arg0); - ret = AVERROR(EINVAL); - goto fail; - } - /* gains */ - while (1) { - gain = 1; - if (sscanf(arg, "%lf%n *%n", &gain, &len, &len)) - arg += len; - if (parse_channel_name(&arg, &in_ch_id, &named)){ - av_log(ctx, AV_LOG_ERROR, - "Expected in channel name, got \"%.8s\"\n", arg); - ret = AVERROR(EINVAL); - goto fail; - } - nb_in_channels[named]++; - if (nb_in_channels[!named]) { - av_log(ctx, AV_LOG_ERROR, - "Can not mix named and numbered channels\n"); - ret = AVERROR(EINVAL); - goto fail; - } - pan->gain[out_ch_id][in_ch_id] = gain; - skip_spaces(&arg); - if (!*arg) - break; - if (*arg != '+') { - av_log(ctx, AV_LOG_ERROR, "Syntax error near \"%.8s\"\n", arg); - ret = AVERROR(EINVAL); - goto fail; - } - arg++; - } - } - pan->need_renumber = !!nb_in_channels[1]; - - ret = 0; -fail: - av_free(args); - return ret; -} - -static int are_gains_pure(const PanContext *pan) -{ - int i, j; - - for (i = 0; i < MAX_CHANNELS; i++) { - int nb_gain = 0; - - for (j = 0; j < MAX_CHANNELS; j++) { - double gain = pan->gain[i][j]; - - /* channel mapping is effective only if 0% or 100% of a channel is - * selected... */ - if (gain != 0. && gain != 1.) - return 0; - /* ...and if the output channel is only composed of one input */ - if (gain && nb_gain++) - return 0; - } - } - return 1; -} - -static int query_formats(AVFilterContext *ctx) -{ - PanContext *pan = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts; - - pan->pure_gains = are_gains_pure(pan); - /* libswr supports any sample and packing formats */ - ff_set_common_formats(ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO)); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, formats); - - // inlink supports any channel layout - layouts = ff_all_channel_counts(); - ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); - - // outlink supports only requested output channel layout - layouts = NULL; - ff_add_channel_layout(&layouts, - pan->out_channel_layout ? pan->out_channel_layout : - FF_COUNT2LAYOUT(pan->nb_output_channels)); - ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); - return 0; -} - -static int config_props(AVFilterLink *link) -{ - AVFilterContext *ctx = link->dst; - PanContext *pan = ctx->priv; - char buf[1024], *cur; - int i, j, k, r; - double t; - - if (pan->need_renumber) { - // input channels were given by their name: renumber them - for (i = j = 0; i < MAX_CHANNELS; i++) { - if ((link->channel_layout >> i) & 1) { - for (k = 0; k < pan->nb_output_channels; k++) - pan->gain[k][j] = pan->gain[k][i]; - j++; - } - } - } - - // sanity check; can't be done in query_formats since the inlink - // channel layout is unknown at that time - if (link->channels > SWR_CH_MAX || - pan->nb_output_channels > SWR_CH_MAX) { - av_log(ctx, AV_LOG_ERROR, - "libswresample support a maximum of %d channels. " - "Feel free to ask for a higher limit.\n", SWR_CH_MAX); - return AVERROR_PATCHWELCOME; - } - - // init libswresample context - pan->swr = swr_alloc_set_opts(pan->swr, - pan->out_channel_layout, link->format, link->sample_rate, - link->channel_layout, link->format, link->sample_rate, - 0, ctx); - if (!pan->swr) - return AVERROR(ENOMEM); - if (!link->channel_layout) - av_opt_set_int(pan->swr, "ich", link->channels, 0); - if (!pan->out_channel_layout) - av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0); - - // gains are pure, init the channel mapping - if (pan->pure_gains) { - - // get channel map from the pure gains - for (i = 0; i < pan->nb_output_channels; i++) { - int ch_id = -1; - for (j = 0; j < link->channels; j++) { - if (pan->gain[i][j]) { - ch_id = j; - break; - } - } - pan->channel_map[i] = ch_id; - } - - av_opt_set_int(pan->swr, "icl", pan->out_channel_layout, 0); - av_opt_set_int(pan->swr, "uch", pan->nb_output_channels, 0); - swr_set_channel_mapping(pan->swr, pan->channel_map); - } else { - // renormalize - for (i = 0; i < pan->nb_output_channels; i++) { - if (!((pan->need_renorm >> i) & 1)) - continue; - t = 0; - for (j = 0; j < link->channels; j++) - t += pan->gain[i][j]; - if (t > -1E-5 && t < 1E-5) { - // t is almost 0 but not exactly, this is probably a mistake - if (t) - av_log(ctx, AV_LOG_WARNING, - "Degenerate coefficients while renormalizing\n"); - continue; - } - for (j = 0; j < link->channels; j++) - pan->gain[i][j] /= t; - } - av_opt_set_int(pan->swr, "icl", link->channel_layout, 0); - av_opt_set_int(pan->swr, "ocl", pan->out_channel_layout, 0); - swr_set_matrix(pan->swr, pan->gain[0], pan->gain[1] - pan->gain[0]); - } - - r = swr_init(pan->swr); - if (r < 0) - return r; - - // summary - for (i = 0; i < pan->nb_output_channels; i++) { - cur = buf; - for (j = 0; j < link->channels; j++) { - r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d", - j ? " + " : "", pan->gain[i][j], j); - cur += FFMIN(buf + sizeof(buf) - cur, r); - } - av_log(ctx, AV_LOG_VERBOSE, "o%d = %s\n", i, buf); - } - // add channel mapping summary if possible - if (pan->pure_gains) { - av_log(ctx, AV_LOG_INFO, "Pure channel mapping detected:"); - for (i = 0; i < pan->nb_output_channels; i++) - if (pan->channel_map[i] < 0) - av_log(ctx, AV_LOG_INFO, " M"); - else - av_log(ctx, AV_LOG_INFO, " %d", pan->channel_map[i]); - av_log(ctx, AV_LOG_INFO, "\n"); - return 0; - } - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - int ret; - int n = insamples->nb_samples; - AVFilterLink *const outlink = inlink->dst->outputs[0]; - AVFrame *outsamples = ff_get_audio_buffer(outlink, n); - PanContext *pan = inlink->dst->priv; - - if (!outsamples) - return AVERROR(ENOMEM); - swr_convert(pan->swr, outsamples->data, n, (void *)insamples->data, n); - av_frame_copy_props(outsamples, insamples); - outsamples->channel_layout = outlink->channel_layout; - av_frame_set_channels(outsamples, outlink->channels); - - ret = ff_filter_frame(outlink, outsamples); - av_frame_free(&insamples); - return ret; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - PanContext *pan = ctx->priv; - swr_free(&pan->swr); -} - -#define OFFSET(x) offsetof(PanContext, x) - -static const AVOption pan_options[] = { - { "args", NULL, OFFSET(args), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(pan); - -static const AVFilterPad pan_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad pan_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_pan = { - .name = "pan", - .description = NULL_IF_CONFIG_SMALL("Remix channels with coefficients (panning)."), - .priv_size = sizeof(PanContext), - .priv_class = &pan_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = pan_inputs, - .outputs = pan_outputs, -}; diff --git a/ffmpeg/libavfilter/af_resample.c b/ffmpeg/libavfilter/af_resample.c deleted file mode 100644 index bf32aa7..0000000 --- a/ffmpeg/libavfilter/af_resample.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * sample format and channel layout conversion audio filter - */ - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" - -#include "libavresample/avresample.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -typedef struct ResampleContext { - const AVClass *class; - AVAudioResampleContext *avr; - AVDictionary *options; - - int64_t next_pts; - - /* set by filter_frame() to signal an output frame to request_frame() */ - int got_output; -} ResampleContext; - -static av_cold int init(AVFilterContext *ctx, AVDictionary **opts) -{ - ResampleContext *s = ctx->priv; - const AVClass *avr_class = avresample_get_class(); - AVDictionaryEntry *e = NULL; - - while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) { - if (av_opt_find(&avr_class, e->key, NULL, 0, - AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN)) - av_dict_set(&s->options, e->key, e->value, 0); - } - - e = NULL; - while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) - av_dict_set(opts, e->key, NULL, 0); - - /* do not allow the user to override basic format options */ - av_dict_set(&s->options, "in_channel_layout", NULL, 0); - av_dict_set(&s->options, "out_channel_layout", NULL, 0); - av_dict_set(&s->options, "in_sample_fmt", NULL, 0); - av_dict_set(&s->options, "out_sample_fmt", NULL, 0); - av_dict_set(&s->options, "in_sample_rate", NULL, 0); - av_dict_set(&s->options, "out_sample_rate", NULL, 0); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ResampleContext *s = ctx->priv; - - if (s->avr) { - avresample_close(s->avr); - avresample_free(&s->avr); - } - av_dict_free(&s->options); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - - AVFilterFormats *in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *in_samplerates = ff_all_samplerates(); - AVFilterFormats *out_samplerates = ff_all_samplerates(); - AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts(); - AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts(); - - ff_formats_ref(in_formats, &inlink->out_formats); - ff_formats_ref(out_formats, &outlink->in_formats); - - ff_formats_ref(in_samplerates, &inlink->out_samplerates); - ff_formats_ref(out_samplerates, &outlink->in_samplerates); - - ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); - ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - ResampleContext *s = ctx->priv; - char buf1[64], buf2[64]; - int ret; - - if (s->avr) { - avresample_close(s->avr); - avresample_free(&s->avr); - } - - if (inlink->channel_layout == outlink->channel_layout && - inlink->sample_rate == outlink->sample_rate && - (inlink->format == outlink->format || - (av_get_channel_layout_nb_channels(inlink->channel_layout) == 1 && - av_get_channel_layout_nb_channels(outlink->channel_layout) == 1 && - av_get_planar_sample_fmt(inlink->format) == - av_get_planar_sample_fmt(outlink->format)))) - return 0; - - if (!(s->avr = avresample_alloc_context())) - return AVERROR(ENOMEM); - - if (s->options) { - AVDictionaryEntry *e = NULL; - while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX))) - av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value); - - av_opt_set_dict(s->avr, &s->options); - } - - av_opt_set_int(s->avr, "in_channel_layout", inlink ->channel_layout, 0); - av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0); - av_opt_set_int(s->avr, "in_sample_fmt", inlink ->format, 0); - av_opt_set_int(s->avr, "out_sample_fmt", outlink->format, 0); - av_opt_set_int(s->avr, "in_sample_rate", inlink ->sample_rate, 0); - av_opt_set_int(s->avr, "out_sample_rate", outlink->sample_rate, 0); - - if ((ret = avresample_open(s->avr)) < 0) - return ret; - - outlink->time_base = (AVRational){ 1, outlink->sample_rate }; - s->next_pts = AV_NOPTS_VALUE; - - av_get_channel_layout_string(buf1, sizeof(buf1), - -1, inlink ->channel_layout); - av_get_channel_layout_string(buf2, sizeof(buf2), - -1, outlink->channel_layout); - av_log(ctx, AV_LOG_VERBOSE, - "fmt:%s srate:%d cl:%s -> fmt:%s srate:%d cl:%s\n", - av_get_sample_fmt_name(inlink ->format), inlink ->sample_rate, buf1, - av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf2); - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ResampleContext *s = ctx->priv; - int ret = 0; - - s->got_output = 0; - while (ret >= 0 && !s->got_output) - ret = ff_request_frame(ctx->inputs[0]); - - /* flush the lavr delay buffer */ - if (ret == AVERROR_EOF && s->avr) { - AVFrame *frame; - int nb_samples = av_rescale_rnd(avresample_get_delay(s->avr), - outlink->sample_rate, - ctx->inputs[0]->sample_rate, - AV_ROUND_UP); - - if (!nb_samples) - return ret; - - frame = ff_get_audio_buffer(outlink, nb_samples); - if (!frame) - return AVERROR(ENOMEM); - - ret = avresample_convert(s->avr, frame->extended_data, - frame->linesize[0], nb_samples, - NULL, 0, 0); - if (ret <= 0) { - av_frame_free(&frame); - return (ret == 0) ? AVERROR_EOF : ret; - } - - frame->pts = s->next_pts; - return ff_filter_frame(outlink, frame); - } - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - ResampleContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int ret; - - if (s->avr) { - AVFrame *out; - int delay, nb_samples; - - /* maximum possible samples lavr can output */ - delay = avresample_get_delay(s->avr); - nb_samples = av_rescale_rnd(in->nb_samples + delay, - outlink->sample_rate, inlink->sample_rate, - AV_ROUND_UP); - - out = ff_get_audio_buffer(outlink, nb_samples); - if (!out) { - ret = AVERROR(ENOMEM); - goto fail; - } - - ret = avresample_convert(s->avr, out->extended_data, out->linesize[0], - nb_samples, in->extended_data, in->linesize[0], - in->nb_samples); - if (ret <= 0) { - av_frame_free(&out); - if (ret < 0) - goto fail; - } - - av_assert0(!avresample_available(s->avr)); - - if (s->next_pts == AV_NOPTS_VALUE) { - if (in->pts == AV_NOPTS_VALUE) { - av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, " - "assuming 0.\n"); - s->next_pts = 0; - } else - s->next_pts = av_rescale_q(in->pts, inlink->time_base, - outlink->time_base); - } - - if (ret > 0) { - out->nb_samples = ret; - if (in->pts != AV_NOPTS_VALUE) { - out->pts = av_rescale_q(in->pts, inlink->time_base, - outlink->time_base) - - av_rescale(delay, outlink->sample_rate, - inlink->sample_rate); - } else - out->pts = s->next_pts; - - s->next_pts = out->pts + out->nb_samples; - - ret = ff_filter_frame(outlink, out); - s->got_output = 1; - } - -fail: - av_frame_free(&in); - } else { - in->format = outlink->format; - ret = ff_filter_frame(outlink, in); - s->got_output = 1; - } - - return ret; -} - -static const AVClass *resample_child_class_next(const AVClass *prev) -{ - return prev ? NULL : avresample_get_class(); -} - -static void *resample_child_next(void *obj, void *prev) -{ - ResampleContext *s = obj; - return prev ? NULL : s->avr; -} - -static const AVClass resample_class = { - .class_name = "resample", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, - .child_class_next = resample_child_class_next, - .child_next = resample_child_next, -}; - -static const AVFilterPad avfilter_af_resample_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_resample_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - .request_frame = request_frame - }, - { NULL } -}; - -AVFilter ff_af_resample = { - .name = "resample", - .description = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."), - .priv_size = sizeof(ResampleContext), - .priv_class = &resample_class, - .init_dict = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_af_resample_inputs, - .outputs = avfilter_af_resample_outputs, -}; diff --git a/ffmpeg/libavfilter/af_silencedetect.c b/ffmpeg/libavfilter/af_silencedetect.c deleted file mode 100644 index 687d2e7..0000000 --- a/ffmpeg/libavfilter/af_silencedetect.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch <u pkh me> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Audio silence detector - */ - -#include <float.h> /* DBL_MAX */ - -#include "libavutil/opt.h" -#include "libavutil/timestamp.h" -#include "audio.h" -#include "formats.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct SilenceDetectContext { - const AVClass *class; - double noise; ///< noise amplitude ratio - double duration; ///< minimum duration of silence until notification - int64_t nb_null_samples; ///< current number of continuous zero samples - int64_t start; ///< if silence is detected, this value contains the time of the first zero sample - int last_sample_rate; ///< last sample rate to check for sample rate changes - - void (*silencedetect)(struct SilenceDetectContext *s, AVFrame *insamples, - int nb_samples, int64_t nb_samples_notify, - AVRational time_base); -} SilenceDetectContext; - -#define OFFSET(x) offsetof(SilenceDetectContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM -static const AVOption silencedetect_options[] = { - { "n", "set noise tolerance", OFFSET(noise), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0, DBL_MAX, FLAGS }, - { "noise", "set noise tolerance", OFFSET(noise), AV_OPT_TYPE_DOUBLE, {.dbl=0.001}, 0, DBL_MAX, FLAGS }, - { "d", "set minimum duration in seconds", OFFSET(duration), AV_OPT_TYPE_DOUBLE, {.dbl=2.}, 0, 24*60*60, FLAGS }, - { "duration", "set minimum duration in seconds", OFFSET(duration), AV_OPT_TYPE_DOUBLE, {.dbl=2.}, 0, 24*60*60, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(silencedetect); - -static char *get_metadata_val(AVFrame *insamples, const char *key) -{ - AVDictionaryEntry *e = av_dict_get(insamples->metadata, key, NULL, 0); - return e && e->value ? e->value : NULL; -} - -static av_always_inline void update(SilenceDetectContext *s, AVFrame *insamples, - int is_silence, int64_t nb_samples_notify, - AVRational time_base) -{ - if (is_silence) { - if (!s->start) { - s->nb_null_samples++; - if (s->nb_null_samples >= nb_samples_notify) { - s->start = insamples->pts - (int64_t)(s->duration / av_q2d(time_base) + .5); - av_dict_set(&insamples->metadata, "lavfi.silence_start", - av_ts2timestr(s->start, &time_base), 0); - av_log(s, AV_LOG_INFO, "silence_start: %s\n", - get_metadata_val(insamples, "lavfi.silence_start")); - } - } - } else { - if (s->start) { - av_dict_set(&insamples->metadata, "lavfi.silence_end", - av_ts2timestr(insamples->pts, &time_base), 0); - av_dict_set(&insamples->metadata, "lavfi.silence_duration", - av_ts2timestr(insamples->pts - s->start, &time_base), 0); - av_log(s, AV_LOG_INFO, - "silence_end: %s | silence_duration: %s\n", - get_metadata_val(insamples, "lavfi.silence_end"), - get_metadata_val(insamples, "lavfi.silence_duration")); - } - s->nb_null_samples = s->start = 0; - } -} - -#define SILENCE_DETECT(name, type) \ -static void silencedetect_##name(SilenceDetectContext *s, AVFrame *insamples, \ - int nb_samples, int64_t nb_samples_notify, \ - AVRational time_base) \ -{ \ - const type *p = (const type *)insamples->data[0]; \ - const type noise = s->noise; \ - int i; \ - \ - for (i = 0; i < nb_samples; i++, p++) \ - update(s, insamples, *p < noise && *p > -noise, \ - nb_samples_notify, time_base); \ -} - -SILENCE_DETECT(dbl, double) -SILENCE_DETECT(flt, float) -SILENCE_DETECT(s32, int32_t) -SILENCE_DETECT(s16, int16_t) - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - SilenceDetectContext *s = ctx->priv; - - switch (inlink->format) { - case AV_SAMPLE_FMT_DBL: s->silencedetect = silencedetect_dbl; break; - case AV_SAMPLE_FMT_FLT: s->silencedetect = silencedetect_flt; break; - case AV_SAMPLE_FMT_S32: - s->noise *= INT32_MAX; - s->silencedetect = silencedetect_s32; - break; - case AV_SAMPLE_FMT_S16: - s->noise *= INT16_MAX; - s->silencedetect = silencedetect_s16; - break; - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - SilenceDetectContext *s = inlink->dst->priv; - const int nb_channels = inlink->channels; - const int srate = inlink->sample_rate; - const int nb_samples = insamples->nb_samples * nb_channels; - const int64_t nb_samples_notify = srate * s->duration * nb_channels; - - // scale number of null samples to the new sample rate - if (s->last_sample_rate && s->last_sample_rate != srate) - s->nb_null_samples = srate * s->nb_null_samples / s->last_sample_rate; - s->last_sample_rate = srate; - - // TODO: document metadata - s->silencedetect(s, insamples, nb_samples, nb_samples_notify, - inlink->time_base); - - return ff_filter_frame(inlink->dst->outputs[0], insamples); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts = NULL; - static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_DBL, - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE - }; - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_set_common_channel_layouts(ctx, layouts); - - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, formats); - - return 0; -} - -static const AVFilterPad silencedetect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad silencedetect_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_silencedetect = { - .name = "silencedetect", - .description = NULL_IF_CONFIG_SMALL("Detect silence."), - .priv_size = sizeof(SilenceDetectContext), - .query_formats = query_formats, - .inputs = silencedetect_inputs, - .outputs = silencedetect_outputs, - .priv_class = &silencedetect_class, -}; diff --git a/ffmpeg/libavfilter/af_volume.c b/ffmpeg/libavfilter/af_volume.c deleted file mode 100644 index 269a2a5..0000000 --- a/ffmpeg/libavfilter/af_volume.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio volume filter - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/float_dsp.h" -#include "libavutil/opt.h" -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "af_volume.h" - -static const char *precision_str[] = { - "fixed", "float", "double" -}; - -static const char *const var_names[] = { - "n", ///< frame number (starting at zero) - "nb_channels", ///< number of channels - "nb_consumed_samples", ///< number of samples consumed by the filter - "nb_samples", ///< number of samples in the current frame - "pos", ///< position in the file of the frame - "pts", ///< frame presentation timestamp - "sample_rate", ///< sample rate - "startpts", ///< PTS at start of stream - "startt", ///< time at start of stream - "t", ///< time in the file of the frame - "tb", ///< timebase - "volume", ///< last set value - NULL -}; - -#define OFFSET(x) offsetof(VolumeContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption volume_options[] = { - { "volume", "set volume adjustment expression", - OFFSET(volume_expr), AV_OPT_TYPE_STRING, { .str = "1.0" }, .flags = A|F }, - { "precision", "select mathematical precision", - OFFSET(precision), AV_OPT_TYPE_INT, { .i64 = PRECISION_FLOAT }, PRECISION_FIXED, PRECISION_DOUBLE, A|F, "precision" }, - { "fixed", "select 8-bit fixed-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FIXED }, INT_MIN, INT_MAX, A|F, "precision" }, - { "float", "select 32-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_FLOAT }, INT_MIN, INT_MAX, A|F, "precision" }, - { "double", "select 64-bit floating-point", 0, AV_OPT_TYPE_CONST, { .i64 = PRECISION_DOUBLE }, INT_MIN, INT_MAX, A|F, "precision" }, - { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_ONCE}, 0, EVAL_MODE_NB-1, .flags = A|F, "eval" }, - { "once", "eval volume expression once", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_ONCE}, .flags = A|F, .unit = "eval" }, - { "frame", "eval volume expression per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = A|F, .unit = "eval" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(volume); - -static int set_expr(AVExpr **pexpr, const char *expr, void *log_ctx) -{ - int ret; - AVExpr *old = NULL; - - if (*pexpr) - old = *pexpr; - ret = av_expr_parse(pexpr, expr, var_names, - NULL, NULL, NULL, NULL, 0, log_ctx); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Error when evaluating the volume expression '%s'\n", expr); - *pexpr = old; - return ret; - } - - av_expr_free(old); - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - VolumeContext *vol = ctx->priv; - return set_expr(&vol->volume_pexpr, vol->volume_expr, ctx); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - VolumeContext *vol = ctx->priv; - av_expr_free(vol->volume_pexpr); - av_opt_free(vol); -} - -static int query_formats(AVFilterContext *ctx) -{ - VolumeContext *vol = ctx->priv; - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts; - static const enum AVSampleFormat sample_fmts[][7] = { - [PRECISION_FIXED] = { - AV_SAMPLE_FMT_U8, - AV_SAMPLE_FMT_U8P, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_S32P, - AV_SAMPLE_FMT_NONE - }, - [PRECISION_FLOAT] = { - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_NONE - }, - [PRECISION_DOUBLE] = { - AV_SAMPLE_FMT_DBL, - AV_SAMPLE_FMT_DBLP, - AV_SAMPLE_FMT_NONE - } - }; - - layouts = ff_all_channel_counts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_set_common_channel_layouts(ctx, layouts); - - formats = ff_make_format_list(sample_fmts[vol->precision]); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, formats); - - return 0; -} - -static inline void scale_samples_u8(uint8_t *dst, const uint8_t *src, - int nb_samples, int volume) -{ - int i; - for (i = 0; i < nb_samples; i++) - dst[i] = av_clip_uint8(((((int64_t)src[i] - 128) * volume + 128) >> 8) + 128); -} - -static inline void scale_samples_u8_small(uint8_t *dst, const uint8_t *src, - int nb_samples, int volume) -{ - int i; - for (i = 0; i < nb_samples; i++) - dst[i] = av_clip_uint8((((src[i] - 128) * volume + 128) >> 8) + 128); -} - -static inline void scale_samples_s16(uint8_t *dst, const uint8_t *src, - int nb_samples, int volume) -{ - int i; - int16_t *smp_dst = (int16_t *)dst; - const int16_t *smp_src = (const int16_t *)src; - for (i = 0; i < nb_samples; i++) - smp_dst[i] = av_clip_int16(((int64_t)smp_src[i] * volume + 128) >> 8); -} - -static inline void scale_samples_s16_small(uint8_t *dst, const uint8_t *src, - int nb_samples, int volume) -{ - int i; - int16_t *smp_dst = (int16_t *)dst; - const int16_t *smp_src = (const int16_t *)src; - for (i = 0; i < nb_samples; i++) - smp_dst[i] = av_clip_int16((smp_src[i] * volume + 128) >> 8); -} - -static inline void scale_samples_s32(uint8_t *dst, const uint8_t *src, - int nb_samples, int volume) -{ - int i; - int32_t *smp_dst = (int32_t *)dst; - const int32_t *smp_src = (const int32_t *)src; - for (i = 0; i < nb_samples; i++) - smp_dst[i] = av_clipl_int32((((int64_t)smp_src[i] * volume + 128) >> 8)); -} - -static av_cold void volume_init(VolumeContext *vol) -{ - vol->samples_align = 1; - - switch (av_get_packed_sample_fmt(vol->sample_fmt)) { - case AV_SAMPLE_FMT_U8: - if (vol->volume_i < 0x1000000) - vol->scale_samples = scale_samples_u8_small; - else - vol->scale_samples = scale_samples_u8; - break; - case AV_SAMPLE_FMT_S16: - if (vol->volume_i < 0x10000) - vol->scale_samples = scale_samples_s16_small; - else - vol->scale_samples = scale_samples_s16; - break; - case AV_SAMPLE_FMT_S32: - vol->scale_samples = scale_samples_s32; - break; - case AV_SAMPLE_FMT_FLT: - avpriv_float_dsp_init(&vol->fdsp, 0); - vol->samples_align = 4; - break; - case AV_SAMPLE_FMT_DBL: - avpriv_float_dsp_init(&vol->fdsp, 0); - vol->samples_align = 8; - break; - } - - if (ARCH_X86) - ff_volume_init_x86(vol); -} - -static int set_volume(AVFilterContext *ctx) -{ - VolumeContext *vol = ctx->priv; - - vol->volume = av_expr_eval(vol->volume_pexpr, vol->var_values, NULL); - if (isnan(vol->volume)) { - if (vol->eval_mode == EVAL_MODE_ONCE) { - av_log(ctx, AV_LOG_ERROR, "Invalid value NaN for volume\n"); - return AVERROR(EINVAL); - } else { - av_log(ctx, AV_LOG_WARNING, "Invalid value NaN for volume, setting to 0\n"); - vol->volume = 0; - } - } - vol->var_values[VAR_VOLUME] = vol->volume; - - av_log(ctx, AV_LOG_VERBOSE, "n:%f t:%f pts:%f precision:%s ", - vol->var_values[VAR_N], vol->var_values[VAR_T], vol->var_values[VAR_PTS], - precision_str[vol->precision]); - - if (vol->precision == PRECISION_FIXED) { - vol->volume_i = (int)(vol->volume * 256 + 0.5); - vol->volume = vol->volume_i / 256.0; - av_log(ctx, AV_LOG_VERBOSE, "volume_i:%d/255 ", vol->volume_i); - } - av_log(ctx, AV_LOG_VERBOSE, "volume:%f volume_dB:%f\n", - vol->volume, 20.0*log(vol->volume)/M_LN10); - - volume_init(vol); - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - VolumeContext *vol = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - vol->sample_fmt = inlink->format; - vol->channels = inlink->channels; - vol->planes = av_sample_fmt_is_planar(inlink->format) ? vol->channels : 1; - - vol->var_values[VAR_N] = - vol->var_values[VAR_NB_CONSUMED_SAMPLES] = - vol->var_values[VAR_NB_SAMPLES] = - vol->var_values[VAR_POS] = - vol->var_values[VAR_PTS] = - vol->var_values[VAR_STARTPTS] = - vol->var_values[VAR_STARTT] = - vol->var_values[VAR_T] = - vol->var_values[VAR_VOLUME] = NAN; - - vol->var_values[VAR_NB_CHANNELS] = inlink->channels; - vol->var_values[VAR_TB] = av_q2d(inlink->time_base); - vol->var_values[VAR_SAMPLE_RATE] = inlink->sample_rate; - - av_log(inlink->src, AV_LOG_VERBOSE, "tb:%f sample_rate:%f nb_channels:%f\n", - vol->var_values[VAR_TB], - vol->var_values[VAR_SAMPLE_RATE], - vol->var_values[VAR_NB_CHANNELS]); - - return set_volume(ctx); -} - -static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, - char *res, int res_len, int flags) -{ - VolumeContext *vol = ctx->priv; - int ret = AVERROR(ENOSYS); - - if (!strcmp(cmd, "volume")) { - if ((ret = set_expr(&vol->volume_pexpr, args, ctx)) < 0) - return ret; - if (vol->eval_mode == EVAL_MODE_ONCE) - set_volume(ctx); - } - - return ret; -} - -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - VolumeContext *vol = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - int nb_samples = buf->nb_samples; - AVFrame *out_buf; - int64_t pos; - - if (isnan(vol->var_values[VAR_STARTPTS])) { - vol->var_values[VAR_STARTPTS] = TS2D(buf->pts); - vol->var_values[VAR_STARTT ] = TS2T(buf->pts, inlink->time_base); - } - vol->var_values[VAR_PTS] = TS2D(buf->pts); - vol->var_values[VAR_T ] = TS2T(buf->pts, inlink->time_base); - vol->var_values[VAR_N ] = inlink->frame_count; - - pos = av_frame_get_pkt_pos(buf); - vol->var_values[VAR_POS] = pos == -1 ? NAN : pos; - if (vol->eval_mode == EVAL_MODE_FRAME) - set_volume(ctx); - - if (vol->volume == 1.0 || vol->volume_i == 256) { - out_buf = buf; - goto end; - } - - /* do volume scaling in-place if input buffer is writable */ - if (av_frame_is_writable(buf)) { - out_buf = buf; - } else { - out_buf = ff_get_audio_buffer(inlink, nb_samples); - if (!out_buf) - return AVERROR(ENOMEM); - av_frame_copy_props(out_buf, buf); - } - - if (vol->precision != PRECISION_FIXED || vol->volume_i > 0) { - int p, plane_samples; - - if (av_sample_fmt_is_planar(buf->format)) - plane_samples = FFALIGN(nb_samples, vol->samples_align); - else - plane_samples = FFALIGN(nb_samples * vol->channels, vol->samples_align); - - if (vol->precision == PRECISION_FIXED) { - for (p = 0; p < vol->planes; p++) { - vol->scale_samples(out_buf->extended_data[p], - buf->extended_data[p], plane_samples, - vol->volume_i); - } - } else if (av_get_packed_sample_fmt(vol->sample_fmt) == AV_SAMPLE_FMT_FLT) { - for (p = 0; p < vol->planes; p++) { - vol->fdsp.vector_fmul_scalar((float *)out_buf->extended_data[p], - (const float *)buf->extended_data[p], - vol->volume, plane_samples); - } - } else { - for (p = 0; p < vol->planes; p++) { - vol->fdsp.vector_dmul_scalar((double *)out_buf->extended_data[p], - (const double *)buf->extended_data[p], - vol->volume, plane_samples); - } - } - } - - if (buf != out_buf) - av_frame_free(&buf); - -end: - vol->var_values[VAR_NB_CONSUMED_SAMPLES] += out_buf->nb_samples; - return ff_filter_frame(outlink, out_buf); -} - -static const AVFilterPad avfilter_af_volume_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_volume_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_af_volume = { - .name = "volume", - .description = NULL_IF_CONFIG_SMALL("Change input volume."), - .query_formats = query_formats, - .priv_size = sizeof(VolumeContext), - .priv_class = &volume_class, - .init = init, - .uninit = uninit, - .inputs = avfilter_af_volume_inputs, - .outputs = avfilter_af_volume_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, - .process_command = process_command, -}; diff --git a/ffmpeg/libavfilter/af_volume.h b/ffmpeg/libavfilter/af_volume.h deleted file mode 100644 index 10ef6fb..0000000 --- a/ffmpeg/libavfilter/af_volume.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio volume filter - */ - -#ifndef AVFILTER_AF_VOLUME_H -#define AVFILTER_AF_VOLUME_H - -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/float_dsp.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" - -enum PrecisionType { - PRECISION_FIXED = 0, - PRECISION_FLOAT, - PRECISION_DOUBLE, -}; - -enum EvalMode { - EVAL_MODE_ONCE, - EVAL_MODE_FRAME, - EVAL_MODE_NB -}; - -enum VolumeVarName { - VAR_N, - VAR_NB_CHANNELS, - VAR_NB_CONSUMED_SAMPLES, - VAR_NB_SAMPLES, - VAR_POS, - VAR_PTS, - VAR_SAMPLE_RATE, - VAR_STARTPTS, - VAR_STARTT, - VAR_T, - VAR_TB, - VAR_VOLUME, - VAR_VARS_NB -}; - -typedef struct VolumeContext { - const AVClass *class; - AVFloatDSPContext fdsp; - enum PrecisionType precision; - enum EvalMode eval_mode; - const char *volume_expr; - AVExpr *volume_pexpr; - double var_values[VAR_VARS_NB]; - - double volume; - int volume_i; - int channels; - int planes; - enum AVSampleFormat sample_fmt; - - void (*scale_samples)(uint8_t *dst, const uint8_t *src, int nb_samples, - int volume); - int samples_align; -} VolumeContext; - -void ff_volume_init_x86(VolumeContext *vol); - -#endif /* AVFILTER_AF_VOLUME_H */ diff --git a/ffmpeg/libavfilter/af_volumedetect.c b/ffmpeg/libavfilter/af_volumedetect.c deleted file mode 100644 index 5de115e..0000000 --- a/ffmpeg/libavfilter/af_volumedetect.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with FFmpeg; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/avassert.h" -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct { - /** - * Number of samples at each PCM value. - * histogram[0x8000 + i] is the number of samples at value i. - * The extra element is there for symmetry. - */ - uint64_t histogram[0x10001]; -} VolDetectContext; - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVSampleFormat sample_fmts[] = { - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_NONE - }; - AVFilterFormats *formats; - - if (!(formats = ff_make_format_list(sample_fmts))) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *samples) -{ - AVFilterContext *ctx = inlink->dst; - VolDetectContext *vd = ctx->priv; - int64_t layout = samples->channel_layout; - int nb_samples = samples->nb_samples; - int nb_channels = av_get_channel_layout_nb_channels(layout); - int nb_planes = nb_channels; - int plane, i; - int16_t *pcm; - - if (!av_sample_fmt_is_planar(samples->format)) { - nb_samples *= nb_channels; - nb_planes = 1; - } - for (plane = 0; plane < nb_planes; plane++) { - pcm = (int16_t *)samples->extended_data[plane]; - for (i = 0; i < nb_samples; i++) - vd->histogram[pcm[i] + 0x8000]++; - } - - return ff_filter_frame(inlink->dst->outputs[0], samples); -} - -#define MAX_DB 91 - -static inline double logdb(uint64_t v) -{ - double d = v / (double)(0x8000 * 0x8000); - if (!v) - return MAX_DB; - return log(d) * -4.3429448190325182765112891891660508229; /* -10/log(10) */ -} - -static void print_stats(AVFilterContext *ctx) -{ - VolDetectContext *vd = ctx->priv; - int i, max_volume, shift; - uint64_t nb_samples = 0, power = 0, nb_samples_shift = 0, sum = 0; - uint64_t histdb[MAX_DB + 1] = { 0 }; - - for (i = 0; i < 0x10000; i++) - nb_samples += vd->histogram[i]; - av_log(ctx, AV_LOG_INFO, "n_samples: %"PRId64"\n", nb_samples); - if (!nb_samples) - return; - - /* If nb_samples > 1<<34, there is a risk of overflow in the - multiplication or the sum: shift all histogram values to avoid that. - The total number of samples must be recomputed to avoid rounding - errors. */ - shift = av_log2(nb_samples >> 33); - for (i = 0; i < 0x10000; i++) { - nb_samples_shift += vd->histogram[i] >> shift; - power += (i - 0x8000) * (i - 0x8000) * (vd->histogram[i] >> shift); - } - if (!nb_samples_shift) - return; - power = (power + nb_samples_shift / 2) / nb_samples_shift; - av_assert0(power <= 0x8000 * 0x8000); - av_log(ctx, AV_LOG_INFO, "mean_volume: %.1f dB\n", -logdb(power)); - - max_volume = 0x8000; - while (max_volume > 0 && !vd->histogram[0x8000 + max_volume] && - !vd->histogram[0x8000 - max_volume]) - max_volume--; - av_log(ctx, AV_LOG_INFO, "max_volume: %.1f dB\n", -logdb(max_volume * max_volume)); - - for (i = 0; i < 0x10000; i++) - histdb[(int)logdb((i - 0x8000) * (i - 0x8000))] += vd->histogram[i]; - for (i = 0; i <= MAX_DB && !histdb[i]; i++); - for (; i <= MAX_DB && sum < nb_samples / 1000; i++) { - av_log(ctx, AV_LOG_INFO, "histogram_%ddb: %"PRId64"\n", i, histdb[i]); - sum += histdb[i]; - } -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - print_stats(ctx); -} - -static const AVFilterPad volumedetect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad volumedetect_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_volumedetect = { - .name = "volumedetect", - .description = NULL_IF_CONFIG_SMALL("Detect audio volume."), - .priv_size = sizeof(VolDetectContext), - .query_formats = query_formats, - .uninit = uninit, - .inputs = volumedetect_inputs, - .outputs = volumedetect_outputs, -}; diff --git a/ffmpeg/libavfilter/all_channel_layouts.inc b/ffmpeg/libavfilter/all_channel_layouts.inc deleted file mode 100644 index 878e1f5..0000000 --- a/ffmpeg/libavfilter/all_channel_layouts.inc +++ /dev/null @@ -1,68 +0,0 @@ -AV_CH_FRONT_CENTER, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY, -AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER, -AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, -AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT, diff --git a/ffmpeg/libavfilter/allfilters.c b/ffmpeg/libavfilter/allfilters.c deleted file mode 100644 index d58e8cc..0000000 --- a/ffmpeg/libavfilter/allfilters.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * filter registration - * Copyright (c) 2008 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avfilter.h" -#include "config.h" -#include "opencl_allkernels.h" - - -#define REGISTER_FILTER(X, x, y) \ - { \ - extern AVFilter ff_##y##_##x; \ - if (CONFIG_##X##_FILTER) \ - avfilter_register(&ff_##y##_##x); \ - } - -#define REGISTER_FILTER_UNCONDITIONAL(x) \ - { \ - extern AVFilter ff_##x; \ - avfilter_register(&ff_##x); \ - } - -void avfilter_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - -#if FF_API_ACONVERT_FILTER - REGISTER_FILTER(ACONVERT, aconvert, af); -#endif - REGISTER_FILTER(ADELAY, adelay, af); - REGISTER_FILTER(AECHO, aecho, af); - REGISTER_FILTER(AEVAL, aeval, af); - REGISTER_FILTER(AFADE, afade, af); - REGISTER_FILTER(AFORMAT, aformat, af); - REGISTER_FILTER(AINTERLEAVE, ainterleave, af); - REGISTER_FILTER(ALLPASS, allpass, af); - REGISTER_FILTER(AMERGE, amerge, af); - REGISTER_FILTER(AMIX, amix, af); - REGISTER_FILTER(ANULL, anull, af); - REGISTER_FILTER(APAD, apad, af); - REGISTER_FILTER(APERMS, aperms, af); - REGISTER_FILTER(APHASER, aphaser, af); - REGISTER_FILTER(ARESAMPLE, aresample, af); - REGISTER_FILTER(ASELECT, aselect, af); - REGISTER_FILTER(ASENDCMD, asendcmd, af); - REGISTER_FILTER(ASETNSAMPLES, asetnsamples, af); - REGISTER_FILTER(ASETPTS, asetpts, af); - REGISTER_FILTER(ASETRATE, asetrate, af); - REGISTER_FILTER(ASETTB, asettb, af); - REGISTER_FILTER(ASHOWINFO, ashowinfo, af); - REGISTER_FILTER(ASPLIT, asplit, af); - REGISTER_FILTER(ASTATS, astats, af); - REGISTER_FILTER(ASTREAMSYNC, astreamsync, af); - REGISTER_FILTER(ASYNCTS, asyncts, af); - REGISTER_FILTER(ATEMPO, atempo, af); - REGISTER_FILTER(ATRIM, atrim, af); - REGISTER_FILTER(AZMQ, azmq, af); - REGISTER_FILTER(BANDPASS, bandpass, af); - REGISTER_FILTER(BANDREJECT, bandreject, af); - REGISTER_FILTER(BASS, bass, af); - REGISTER_FILTER(BIQUAD, biquad, af); - REGISTER_FILTER(CHANNELMAP, channelmap, af); - REGISTER_FILTER(CHANNELSPLIT, channelsplit, af); - REGISTER_FILTER(COMPAND, compand, af); - REGISTER_FILTER(EARWAX, earwax, af); - REGISTER_FILTER(EBUR128, ebur128, af); - REGISTER_FILTER(EQUALIZER, equalizer, af); - REGISTER_FILTER(HIGHPASS, highpass, af); - REGISTER_FILTER(JOIN, join, af); - REGISTER_FILTER(LADSPA, ladspa, af); - REGISTER_FILTER(LOWPASS, lowpass, af); - REGISTER_FILTER(PAN, pan, af); - REGISTER_FILTER(REPLAYGAIN, replaygain, af); - REGISTER_FILTER(RESAMPLE, resample, af); - REGISTER_FILTER(SILENCEDETECT, silencedetect, af); - REGISTER_FILTER(TREBLE, treble, af); - REGISTER_FILTER(VOLUME, volume, af); - REGISTER_FILTER(VOLUMEDETECT, volumedetect, af); - - REGISTER_FILTER(AEVALSRC, aevalsrc, asrc); - REGISTER_FILTER(ANULLSRC, anullsrc, asrc); - REGISTER_FILTER(FLITE, flite, asrc); - REGISTER_FILTER(SINE, sine, asrc); - - REGISTER_FILTER(ANULLSINK, anullsink, asink); - - REGISTER_FILTER(ALPHAEXTRACT, alphaextract, vf); - REGISTER_FILTER(ALPHAMERGE, alphamerge, vf); - REGISTER_FILTER(ASS, ass, vf); - REGISTER_FILTER(BBOX, bbox, vf); - REGISTER_FILTER(BLACKDETECT, blackdetect, vf); - REGISTER_FILTER(BLACKFRAME, blackframe, vf); - REGISTER_FILTER(BLEND, blend, vf); - REGISTER_FILTER(BOXBLUR, boxblur, vf); - REGISTER_FILTER(COLORBALANCE, colorbalance, vf); - REGISTER_FILTER(COLORCHANNELMIXER, colorchannelmixer, vf); - REGISTER_FILTER(COLORMATRIX, colormatrix, vf); - REGISTER_FILTER(COPY, copy, vf); - REGISTER_FILTER(CROP, crop, vf); - REGISTER_FILTER(CROPDETECT, cropdetect, vf); - REGISTER_FILTER(CURVES, curves, vf); - REGISTER_FILTER(DCTDNOIZ, dctdnoiz, vf); - REGISTER_FILTER(DECIMATE, decimate, vf); - REGISTER_FILTER(DELOGO, delogo, vf); - REGISTER_FILTER(DESHAKE, deshake, vf); - REGISTER_FILTER(DRAWBOX, drawbox, vf); - REGISTER_FILTER(DRAWGRID, drawgrid, vf); - REGISTER_FILTER(DRAWTEXT, drawtext, vf); - REGISTER_FILTER(EDGEDETECT, edgedetect, vf); - REGISTER_FILTER(ELBG, elbg, vf); - REGISTER_FILTER(EXTRACTPLANES, extractplanes, vf); - REGISTER_FILTER(FADE, fade, vf); - REGISTER_FILTER(FIELD, field, vf); - REGISTER_FILTER(FIELDMATCH, fieldmatch, vf); - REGISTER_FILTER(FIELDORDER, fieldorder, vf); - REGISTER_FILTER(FORMAT, format, vf); - REGISTER_FILTER(FPS, fps, vf); - REGISTER_FILTER(FRAMESTEP, framestep, vf); - REGISTER_FILTER(FREI0R, frei0r, vf); - REGISTER_FILTER(GEQ, geq, vf); - REGISTER_FILTER(GRADFUN, gradfun, vf); - REGISTER_FILTER(HALDCLUT, haldclut, vf); - REGISTER_FILTER(HFLIP, hflip, vf); - REGISTER_FILTER(HISTEQ, histeq, vf); - REGISTER_FILTER(HISTOGRAM, histogram, vf); - REGISTER_FILTER(HQDN3D, hqdn3d, vf); - REGISTER_FILTER(HUE, hue, vf); - REGISTER_FILTER(IDET, idet, vf); - REGISTER_FILTER(IL, il, vf); - REGISTER_FILTER(INTERLACE, interlace, vf); - REGISTER_FILTER(INTERLEAVE, interleave, vf); - REGISTER_FILTER(KERNDEINT, kerndeint, vf); - REGISTER_FILTER(LUT3D, lut3d, vf); - REGISTER_FILTER(LUT, lut, vf); - REGISTER_FILTER(LUTRGB, lutrgb, vf); - REGISTER_FILTER(LUTYUV, lutyuv, vf); - REGISTER_FILTER(MCDEINT, mcdeint, vf); - REGISTER_FILTER(MERGEPLANES, mergeplanes, vf); - REGISTER_FILTER(MP, mp, vf); - REGISTER_FILTER(MPDECIMATE, mpdecimate, vf); - REGISTER_FILTER(NEGATE, negate, vf); - REGISTER_FILTER(NOFORMAT, noformat, vf); - REGISTER_FILTER(NOISE, noise, vf); - REGISTER_FILTER(NULL, null, vf); - REGISTER_FILTER(OCV, ocv, vf); - REGISTER_FILTER(OVERLAY, overlay, vf); - REGISTER_FILTER(OWDENOISE, owdenoise, vf); - REGISTER_FILTER(PAD, pad, vf); - REGISTER_FILTER(PERMS, perms, vf); - REGISTER_FILTER(PERSPECTIVE, perspective, vf); - REGISTER_FILTER(PHASE, phase, vf); - REGISTER_FILTER(PIXDESCTEST, pixdesctest, vf); - REGISTER_FILTER(PP, pp, vf); - REGISTER_FILTER(PSNR, psnr, vf); - REGISTER_FILTER(PULLUP, pullup, vf); - REGISTER_FILTER(REMOVELOGO, removelogo, vf); - REGISTER_FILTER(ROTATE, rotate, vf); - REGISTER_FILTER(SAB, sab, vf); - REGISTER_FILTER(SCALE, scale, vf); - REGISTER_FILTER(SELECT, select, vf); - REGISTER_FILTER(SENDCMD, sendcmd, vf); - REGISTER_FILTER(SEPARATEFIELDS, separatefields, vf); - REGISTER_FILTER(SETDAR, setdar, vf); - REGISTER_FILTER(SETFIELD, setfield, vf); - REGISTER_FILTER(SETPTS, setpts, vf); - REGISTER_FILTER(SETSAR, setsar, vf); - REGISTER_FILTER(SETTB, settb, vf); - REGISTER_FILTER(SHOWINFO, showinfo, vf); - REGISTER_FILTER(SMARTBLUR, smartblur, vf); - REGISTER_FILTER(SPLIT, split, vf); - REGISTER_FILTER(SPP, spp, vf); - REGISTER_FILTER(STEREO3D, stereo3d, vf); - REGISTER_FILTER(SUBTITLES, subtitles, vf); - REGISTER_FILTER(SUPER2XSAI, super2xsai, vf); - REGISTER_FILTER(SWAPUV, swapuv, vf); - REGISTER_FILTER(TELECINE, telecine, vf); - REGISTER_FILTER(THUMBNAIL, thumbnail, vf); - REGISTER_FILTER(TILE, tile, vf); - REGISTER_FILTER(TINTERLACE, tinterlace, vf); - REGISTER_FILTER(TRANSPOSE, transpose, vf); - REGISTER_FILTER(TRIM, trim, vf); - REGISTER_FILTER(UNSHARP, unsharp, vf); - REGISTER_FILTER(VFLIP, vflip, vf); - REGISTER_FILTER(VIDSTABDETECT, vidstabdetect, vf); - REGISTER_FILTER(VIDSTABTRANSFORM, vidstabtransform, vf); - REGISTER_FILTER(VIGNETTE, vignette, vf); - REGISTER_FILTER(W3FDIF, w3fdif, vf); - REGISTER_FILTER(YADIF, yadif, vf); - REGISTER_FILTER(ZMQ, zmq, vf); - - REGISTER_FILTER(CELLAUTO, cellauto, vsrc); - REGISTER_FILTER(COLOR, color, vsrc); - REGISTER_FILTER(FREI0R, frei0r_src, vsrc); - REGISTER_FILTER(HALDCLUTSRC, haldclutsrc, vsrc); - REGISTER_FILTER(LIFE, life, vsrc); - REGISTER_FILTER(MANDELBROT, mandelbrot, vsrc); - REGISTER_FILTER(MPTESTSRC, mptestsrc, vsrc); - REGISTER_FILTER(NULLSRC, nullsrc, vsrc); - REGISTER_FILTER(RGBTESTSRC, rgbtestsrc, vsrc); - REGISTER_FILTER(SMPTEBARS, smptebars, vsrc); - REGISTER_FILTER(SMPTEHDBARS, smptehdbars, vsrc); - REGISTER_FILTER(TESTSRC, testsrc, vsrc); - - REGISTER_FILTER(NULLSINK, nullsink, vsink); - - /* multimedia filters */ - REGISTER_FILTER(AVECTORSCOPE, avectorscope, avf); - REGISTER_FILTER(CONCAT, concat, avf); - REGISTER_FILTER(SHOWSPECTRUM, showspectrum, avf); - REGISTER_FILTER(SHOWWAVES, showwaves, avf); - - /* multimedia sources */ - REGISTER_FILTER(AMOVIE, amovie, avsrc); - REGISTER_FILTER(MOVIE, movie, avsrc); - -#if FF_API_AVFILTERBUFFER - REGISTER_FILTER_UNCONDITIONAL(vsink_ffbuffersink); - REGISTER_FILTER_UNCONDITIONAL(asink_ffabuffersink); -#endif - - /* those filters are part of public or internal API => registered - * unconditionally */ - REGISTER_FILTER_UNCONDITIONAL(asrc_abuffer); - REGISTER_FILTER_UNCONDITIONAL(vsrc_buffer); - REGISTER_FILTER_UNCONDITIONAL(asink_abuffer); - REGISTER_FILTER_UNCONDITIONAL(vsink_buffer); - REGISTER_FILTER_UNCONDITIONAL(af_afifo); - REGISTER_FILTER_UNCONDITIONAL(vf_fifo); - ff_opencl_register_filter_kernel_code_all(); -} diff --git a/ffmpeg/libavfilter/asink_anullsink.c b/ffmpeg/libavfilter/asink_anullsink.c deleted file mode 100644 index 9b53d3f..0000000 --- a/ffmpeg/libavfilter/asink_anullsink.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/internal.h" -#include "avfilter.h" -#include "internal.h" - -static int null_filter_frame(AVFilterLink *link, AVFrame *frame) -{ - av_frame_free(&frame); - return 0; -} - -static const AVFilterPad avfilter_asink_anullsink_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = null_filter_frame, - }, - { NULL }, -}; - -AVFilter ff_asink_anullsink = { - .name = "anullsink", - .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input audio."), - - .priv_size = 0, - - .inputs = avfilter_asink_anullsink_inputs, - .outputs = NULL, -}; diff --git a/ffmpeg/libavfilter/asrc_abuffer.h b/ffmpeg/libavfilter/asrc_abuffer.h deleted file mode 100644 index aa34461..0000000 --- a/ffmpeg/libavfilter/asrc_abuffer.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_ASRC_ABUFFER_H -#define AVFILTER_ASRC_ABUFFER_H - -#include "avfilter.h" - -/** - * @file - * memory buffer source for audio - * - * @deprecated use buffersrc.h instead. - */ - -/** - * Queue an audio buffer to the audio buffer source. - * - * @param abuffersrc audio source buffer context - * @param data pointers to the samples planes - * @param linesize linesizes of each audio buffer plane - * @param nb_samples number of samples per channel - * @param sample_fmt sample format of the audio data - * @param ch_layout channel layout of the audio data - * @param planar flag to indicate if audio data is planar or packed - * @param pts presentation timestamp of the audio buffer - * @param flags unused - * - * @deprecated use av_buffersrc_add_ref() instead. - */ -attribute_deprecated -int av_asrc_buffer_add_samples(AVFilterContext *abuffersrc, - uint8_t *data[8], int linesize[8], - int nb_samples, int sample_rate, - int sample_fmt, int64_t ch_layout, int planar, - int64_t pts, int av_unused flags); - -/** - * Queue an audio buffer to the audio buffer source. - * - * This is similar to av_asrc_buffer_add_samples(), but the samples - * are stored in a buffer with known size. - * - * @param abuffersrc audio source buffer context - * @param buf pointer to the samples data, packed is assumed - * @param size the size in bytes of the buffer, it must contain an - * integer number of samples - * @param sample_fmt sample format of the audio data - * @param ch_layout channel layout of the audio data - * @param pts presentation timestamp of the audio buffer - * @param flags unused - * - * @deprecated use av_buffersrc_add_ref() instead. - */ -attribute_deprecated -int av_asrc_buffer_add_buffer(AVFilterContext *abuffersrc, - uint8_t *buf, int buf_size, - int sample_rate, - int sample_fmt, int64_t ch_layout, int planar, - int64_t pts, int av_unused flags); - -/** - * Queue an audio buffer to the audio buffer source. - * - * @param abuffersrc audio source buffer context - * @param samplesref buffer ref to queue - * @param flags unused - * - * @deprecated use av_buffersrc_add_ref() instead. - */ -attribute_deprecated -int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *abuffersrc, - AVFilterBufferRef *samplesref, - int av_unused flags); - -#endif /* AVFILTER_ASRC_ABUFFER_H */ diff --git a/ffmpeg/libavfilter/asrc_anullsrc.c b/ffmpeg/libavfilter/asrc_anullsrc.c deleted file mode 100644 index 28d4500..0000000 --- a/ffmpeg/libavfilter/asrc_anullsrc.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2010 S.N. Hemanth Meenakshisundaram <smeenaks ucsd edu> - * Copyright 2010 Stefano Sabatini <stefano.sabatini-lala poste it> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * null audio source - */ - -#include <inttypes.h> -#include <stdio.h> - -#include "libavutil/channel_layout.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - char *channel_layout_str; - uint64_t channel_layout; - char *sample_rate_str; - int sample_rate; - int nb_samples; ///< number of samples per requested frame - int64_t pts; -} ANullContext; - -#define OFFSET(x) offsetof(ANullContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption anullsrc_options[]= { - { "channel_layout", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS }, - { "cl", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS }, - { "sample_rate", "set sample rate", OFFSET(sample_rate_str) , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS }, - { "r", "set sample rate", OFFSET(sample_rate_str) , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS }, - { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS }, - { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(anullsrc); - -static av_cold int init(AVFilterContext *ctx) -{ - ANullContext *null = ctx->priv; - int ret; - - if ((ret = ff_parse_sample_rate(&null->sample_rate, - null->sample_rate_str, ctx)) < 0) - return ret; - - if ((ret = ff_parse_channel_layout(&null->channel_layout, NULL, - null->channel_layout_str, ctx)) < 0) - return ret; - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - ANullContext *null = ctx->priv; - int64_t chlayouts[] = { null->channel_layout, -1 }; - int sample_rates[] = { null->sample_rate, -1 }; - - ff_set_common_formats (ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO)); - ff_set_common_channel_layouts(ctx, avfilter_make_format64_list(chlayouts)); - ff_set_common_samplerates (ctx, ff_make_format_list(sample_rates)); - - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - ANullContext *null = outlink->src->priv; - char buf[128]; - - av_get_channel_layout_string(buf, sizeof(buf), 0, null->channel_layout); - av_log(outlink->src, AV_LOG_VERBOSE, - "sample_rate:%d channel_layout:'%s' nb_samples:%d\n", - null->sample_rate, buf, null->nb_samples); - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - int ret; - ANullContext *null = outlink->src->priv; - AVFrame *samplesref; - - samplesref = ff_get_audio_buffer(outlink, null->nb_samples); - if (!samplesref) - return AVERROR(ENOMEM); - - samplesref->pts = null->pts; - samplesref->channel_layout = null->channel_layout; - samplesref->sample_rate = outlink->sample_rate; - - ret = ff_filter_frame(outlink, av_frame_clone(samplesref)); - av_frame_free(&samplesref); - if (ret < 0) - return ret; - - null->pts += null->nb_samples; - return ret; -} - -static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_asrc_anullsrc = { - .name = "anullsrc", - .description = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."), - .init = init, - .query_formats = query_formats, - .priv_size = sizeof(ANullContext), - .inputs = NULL, - .outputs = avfilter_asrc_anullsrc_outputs, - .priv_class = &anullsrc_class, -}; diff --git a/ffmpeg/libavfilter/asrc_flite.c b/ffmpeg/libavfilter/asrc_flite.c deleted file mode 100644 index 098a1dd..0000000 --- a/ffmpeg/libavfilter/asrc_flite.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * flite voice synth source - */ - -#include <flite/flite.h> -#include "libavutil/channel_layout.h" -#include "libavutil/file.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "audio.h" -#include "formats.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - char *voice_str; - char *textfile; - char *text; - cst_wave *wave; - int16_t *wave_samples; - int wave_nb_samples; - int list_voices; - cst_voice *voice; - struct voice_entry *voice_entry; - int64_t pts; - int frame_nb_samples; ///< number of samples per frame -} FliteContext; - -#define OFFSET(x) offsetof(FliteContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption flite_options[] = { - { "list_voices", "list voices and exit", OFFSET(list_voices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "nb_samples", "set number of samples per frame", OFFSET(frame_nb_samples), AV_OPT_TYPE_INT, {.i64=512}, 0, INT_MAX, FLAGS }, - { "n", "set number of samples per frame", OFFSET(frame_nb_samples), AV_OPT_TYPE_INT, {.i64=512}, 0, INT_MAX, FLAGS }, - { "text", "set text to speak", OFFSET(text), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "textfile", "set filename of the text to speak", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "v", "set voice", OFFSET(voice_str), AV_OPT_TYPE_STRING, {.str="kal"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "voice", "set voice", OFFSET(voice_str), AV_OPT_TYPE_STRING, {.str="kal"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(flite); - -static volatile int flite_inited = 0; - -/* declare functions for all the supported voices */ -#define DECLARE_REGISTER_VOICE_FN(name) \ - cst_voice *register_cmu_us_## name(const char *); \ - void unregister_cmu_us_## name(cst_voice *); -DECLARE_REGISTER_VOICE_FN(awb); -DECLARE_REGISTER_VOICE_FN(kal); -DECLARE_REGISTER_VOICE_FN(kal16); -DECLARE_REGISTER_VOICE_FN(rms); -DECLARE_REGISTER_VOICE_FN(slt); - -struct voice_entry { - const char *name; - cst_voice * (*register_fn)(const char *); - void (*unregister_fn)(cst_voice *); - cst_voice *voice; - unsigned usage_count; -} voice_entry; - -#define MAKE_VOICE_STRUCTURE(voice_name) { \ - .name = #voice_name, \ - .register_fn = register_cmu_us_ ## voice_name, \ - .unregister_fn = unregister_cmu_us_ ## voice_name, \ -} -static struct voice_entry voice_entries[] = { - MAKE_VOICE_STRUCTURE(awb), - MAKE_VOICE_STRUCTURE(kal), - MAKE_VOICE_STRUCTURE(kal16), - MAKE_VOICE_STRUCTURE(rms), - MAKE_VOICE_STRUCTURE(slt), -}; - -static void list_voices(void *log_ctx, const char *sep) -{ - int i, n = FF_ARRAY_ELEMS(voice_entries); - for (i = 0; i < n; i++) - av_log(log_ctx, AV_LOG_INFO, "%s%s", - voice_entries[i].name, i < (n-1) ? sep : "\n"); -} - -static int select_voice(struct voice_entry **entry_ret, const char *voice_name, void *log_ctx) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(voice_entries); i++) { - struct voice_entry *entry = &voice_entries[i]; - if (!strcmp(entry->name, voice_name)) { - if (!entry->voice) - entry->voice = entry->register_fn(NULL); - if (!entry->voice) { - av_log(log_ctx, AV_LOG_ERROR, - "Could not register voice '%s'\n", voice_name); - return AVERROR_UNKNOWN; - } - entry->usage_count++; - *entry_ret = entry; - return 0; - } - } - - av_log(log_ctx, AV_LOG_ERROR, "Could not find voice '%s'\n", voice_name); - av_log(log_ctx, AV_LOG_INFO, "Choose between the voices: "); - list_voices(log_ctx, ", "); - - return AVERROR(EINVAL); -} - -static av_cold int init(AVFilterContext *ctx) -{ - FliteContext *flite = ctx->priv; - int ret = 0; - - if (flite->list_voices) { - list_voices(ctx, "\n"); - return AVERROR_EXIT; - } - - if (!flite_inited) { - if (flite_init() < 0) { - av_log(ctx, AV_LOG_ERROR, "flite initialization failed\n"); - return AVERROR_UNKNOWN; - } - flite_inited++; - } - - if ((ret = select_voice(&flite->voice_entry, flite->voice_str, ctx)) < 0) - return ret; - flite->voice = flite->voice_entry->voice; - - if (flite->textfile && flite->text) { - av_log(ctx, AV_LOG_ERROR, - "Both text and textfile options set: only one must be specified\n"); - return AVERROR(EINVAL); - } - - if (flite->textfile) { - uint8_t *textbuf; - size_t textbuf_size; - - if ((ret = av_file_map(flite->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, - "The text file '%s' could not be read: %s\n", - flite->textfile, av_err2str(ret)); - return ret; - } - - if (!(flite->text = av_malloc(textbuf_size+1))) - return AVERROR(ENOMEM); - memcpy(flite->text, textbuf, textbuf_size); - flite->text[textbuf_size] = 0; - av_file_unmap(textbuf, textbuf_size); - } - - if (!flite->text) { - av_log(ctx, AV_LOG_ERROR, - "No speech text specified, specify the 'text' or 'textfile' option\n"); - return AVERROR(EINVAL); - } - - /* synth all the file data in block */ - flite->wave = flite_text_to_wave(flite->text, flite->voice); - flite->wave_samples = flite->wave->samples; - flite->wave_nb_samples = flite->wave->num_samples; - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - FliteContext *flite = ctx->priv; - - if (!--flite->voice_entry->usage_count) - flite->voice_entry->unregister_fn(flite->voice); - flite->voice = NULL; - flite->voice_entry = NULL; - delete_wave(flite->wave); - flite->wave = NULL; -} - -static int query_formats(AVFilterContext *ctx) -{ - FliteContext *flite = ctx->priv; - - AVFilterChannelLayouts *chlayouts = NULL; - int64_t chlayout = av_get_default_channel_layout(flite->wave->num_channels); - AVFilterFormats *sample_formats = NULL; - AVFilterFormats *sample_rates = NULL; - - ff_add_channel_layout(&chlayouts, chlayout); - ff_set_common_channel_layouts(ctx, chlayouts); - ff_add_format(&sample_formats, AV_SAMPLE_FMT_S16); - ff_set_common_formats(ctx, sample_formats); - ff_add_format(&sample_rates, flite->wave->sample_rate); - ff_set_common_samplerates (ctx, sample_rates); - - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - FliteContext *flite = ctx->priv; - - outlink->sample_rate = flite->wave->sample_rate; - outlink->time_base = (AVRational){1, flite->wave->sample_rate}; - - av_log(ctx, AV_LOG_VERBOSE, "voice:%s fmt:%s sample_rate:%d\n", - flite->voice_str, - av_get_sample_fmt_name(outlink->format), outlink->sample_rate); - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFrame *samplesref; - FliteContext *flite = outlink->src->priv; - int nb_samples = FFMIN(flite->wave_nb_samples, flite->frame_nb_samples); - - if (!nb_samples) - return AVERROR_EOF; - - samplesref = ff_get_audio_buffer(outlink, nb_samples); - if (!samplesref) - return AVERROR(ENOMEM); - - memcpy(samplesref->data[0], flite->wave_samples, - nb_samples * flite->wave->num_channels * 2); - samplesref->pts = flite->pts; - av_frame_set_pkt_pos(samplesref, -1); - av_frame_set_sample_rate(samplesref, flite->wave->sample_rate); - flite->pts += nb_samples; - flite->wave_samples += nb_samples * flite->wave->num_channels; - flite->wave_nb_samples -= nb_samples; - - return ff_filter_frame(outlink, samplesref); -} - -static const AVFilterPad flite_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_props, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_asrc_flite = { - .name = "flite", - .description = NULL_IF_CONFIG_SMALL("Synthesize voice from text using libflite."), - .query_formats = query_formats, - .init = init, - .uninit = uninit, - .priv_size = sizeof(FliteContext), - .inputs = NULL, - .outputs = flite_outputs, - .priv_class = &flite_class, -}; diff --git a/ffmpeg/libavfilter/asrc_sine.c b/ffmpeg/libavfilter/asrc_sine.c deleted file mode 100644 index 68e1398..0000000 --- a/ffmpeg/libavfilter/asrc_sine.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2013 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with FFmpeg; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <float.h> - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - double frequency; - double beep_factor; - int samples_per_frame; - int sample_rate; - int64_t duration; - int16_t *sin; - int64_t pts; - uint32_t phi; ///< current phase of the sine (2pi = 1<<32) - uint32_t dphi; ///< phase increment between two samples - unsigned beep_period; - unsigned beep_index; - unsigned beep_length; - uint32_t phi_beep; ///< current phase of the beep - uint32_t dphi_beep; ///< phase increment of the beep -} SineContext; - -#define CONTEXT SineContext -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define OPT_GENERIC(name, field, def, min, max, descr, type, deffield, ...) \ - { name, descr, offsetof(CONTEXT, field), AV_OPT_TYPE_ ## type, \ - { .deffield = def }, min, max, FLAGS, __VA_ARGS__ } - -#define OPT_INT(name, field, def, min, max, descr, ...) \ - OPT_GENERIC(name, field, def, min, max, descr, INT, i64, __VA_ARGS__) - -#define OPT_DBL(name, field, def, min, max, descr, ...) \ - OPT_GENERIC(name, field, def, min, max, descr, DOUBLE, dbl, __VA_ARGS__) - -#define OPT_DUR(name, field, def, min, max, descr, ...) \ - OPT_GENERIC(name, field, def, min, max, descr, DURATION, str, __VA_ARGS__) - -static const AVOption sine_options[] = { - OPT_DBL("frequency", frequency, 440, 0, DBL_MAX, "set the sine frequency"), - OPT_DBL("f", frequency, 440, 0, DBL_MAX, "set the sine frequency"), - OPT_DBL("beep_factor", beep_factor, 0, 0, DBL_MAX, "set the beep fequency factor"), - OPT_DBL("b", beep_factor, 0, 0, DBL_MAX, "set the beep fequency factor"), - OPT_INT("sample_rate", sample_rate, 44100, 1, INT_MAX, "set the sample rate"), - OPT_INT("r", sample_rate, 44100, 1, INT_MAX, "set the sample rate"), - OPT_DUR("duration", duration, 0, 0, INT64_MAX, "set the audio duration"), - OPT_DUR("d", duration, 0, 0, INT64_MAX, "set the audio duration"), - OPT_INT("samples_per_frame", samples_per_frame, 1024, 0, INT_MAX, "set the number of samples per frame"), - {NULL} -}; - -AVFILTER_DEFINE_CLASS(sine); - -#define LOG_PERIOD 15 -#define AMPLITUDE 4095 -#define AMPLITUDE_SHIFT 3 - -static void make_sin_table(int16_t *sin) -{ - unsigned half_pi = 1 << (LOG_PERIOD - 2); - unsigned ampls = AMPLITUDE << AMPLITUDE_SHIFT; - uint64_t unit2 = (uint64_t)(ampls * ampls) << 32; - unsigned step, i, c, s, k, new_k, n2; - - /* Principle: if u = exp(i*a1) and v = exp(i*a2), then - exp(i*(a1+a2)/2) = (u+v) / length(u+v) */ - sin[0] = 0; - sin[half_pi] = ampls; - for (step = half_pi; step > 1; step /= 2) { - /* k = (1 << 16) * amplitude / length(u+v) - In exact values, k is constant at a given step */ - k = 0x10000; - for (i = 0; i < half_pi / 2; i += step) { - s = sin[i] + sin[i + step]; - c = sin[half_pi - i] + sin[half_pi - i - step]; - n2 = s * s + c * c; - /* Newton's method to solve n² * k² = unit² */ - while (1) { - new_k = (k + unit2 / ((uint64_t)k * n2) + 1) >> 1; - if (k == new_k) - break; - k = new_k; - } - sin[i + step / 2] = (k * s + 0x7FFF) >> 16; - sin[half_pi - i - step / 2] = (k * c + 0x8000) >> 16; - } - } - /* Unshift amplitude */ - for (i = 0; i <= half_pi; i++) - sin[i] = (sin[i] + (1 << (AMPLITUDE_SHIFT - 1))) >> AMPLITUDE_SHIFT; - /* Use symmetries to fill the other three quarters */ - for (i = 0; i < half_pi; i++) - sin[half_pi * 2 - i] = sin[i]; - for (i = 0; i < 2 * half_pi; i++) - sin[i + 2 * half_pi] = -sin[i]; -} - -static av_cold int init(AVFilterContext *ctx) -{ - SineContext *sine = ctx->priv; - - if (!(sine->sin = av_malloc(sizeof(*sine->sin) << LOG_PERIOD))) - return AVERROR(ENOMEM); - sine->dphi = ldexp(sine->frequency, 32) / sine->sample_rate + 0.5; - make_sin_table(sine->sin); - - if (sine->beep_factor) { - sine->beep_period = sine->sample_rate; - sine->beep_length = sine->beep_period / 25; - sine->dphi_beep = ldexp(sine->beep_factor * sine->frequency, 32) / - sine->sample_rate + 0.5; - } - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - SineContext *sine = ctx->priv; - - av_freep(&sine->sin); -} - -static av_cold int query_formats(AVFilterContext *ctx) -{ - SineContext *sine = ctx->priv; - static const int64_t chlayouts[] = { AV_CH_LAYOUT_MONO, -1 }; - int sample_rates[] = { sine->sample_rate, -1 }; - static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }; - - ff_set_common_formats (ctx, ff_make_format_list(sample_fmts)); - ff_set_common_channel_layouts(ctx, avfilter_make_format64_list(chlayouts)); - ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates)); - return 0; -} - -static av_cold int config_props(AVFilterLink *outlink) -{ - SineContext *sine = outlink->src->priv; - sine->duration = av_rescale(sine->duration, sine->sample_rate, AV_TIME_BASE); - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - SineContext *sine = outlink->src->priv; - AVFrame *frame; - int i, nb_samples = sine->samples_per_frame; - int16_t *samples; - - if (sine->duration) { - nb_samples = FFMIN(nb_samples, sine->duration - sine->pts); - av_assert1(nb_samples >= 0); - if (!nb_samples) - return AVERROR_EOF; - } - if (!(frame = ff_get_audio_buffer(outlink, nb_samples))) - return AVERROR(ENOMEM); - samples = (int16_t *)frame->data[0]; - - for (i = 0; i < nb_samples; i++) { - samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; - sine->phi += sine->dphi; - if (sine->beep_index < sine->beep_length) { - samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << 1; - sine->phi_beep += sine->dphi_beep; - } - if (++sine->beep_index == sine->beep_period) - sine->beep_index = 0; - } - - frame->pts = sine->pts; - sine->pts += nb_samples; - return ff_filter_frame(outlink, frame); -} - -static const AVFilterPad sine_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_asrc_sine = { - .name = "sine", - .description = NULL_IF_CONFIG_SMALL("Generate sine wave audio signal."), - .query_formats = query_formats, - .init = init, - .uninit = uninit, - .priv_size = sizeof(SineContext), - .inputs = NULL, - .outputs = sine_outputs, - .priv_class = &sine_class, -}; diff --git a/ffmpeg/libavfilter/audio.c b/ffmpeg/libavfilter/audio.c deleted file mode 100644 index 315c273..0000000 --- a/ffmpeg/libavfilter/audio.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) Stefano Sabatini | stefasab at gmail.com - * Copyright (c) S.N. Hemanth Meenakshisundaram | smeenaks at ucsd.edu - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavcodec/avcodec.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" - -int avfilter_ref_get_channels(AVFilterBufferRef *ref) -{ - return ref->audio ? ref->audio->channels : 0; -} - -AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples) -{ - return ff_get_audio_buffer(link->dst->outputs[0], nb_samples); -} - -AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples) -{ - AVFrame *frame = av_frame_alloc(); - int channels = link->channels; - int ret; - - av_assert0(channels == av_get_channel_layout_nb_channels(link->channel_layout) || !av_get_channel_layout_nb_channels(link->channel_layout)); - - if (!frame) - return NULL; - - frame->nb_samples = nb_samples; - frame->format = link->format; - av_frame_set_channels(frame, link->channels); - frame->channel_layout = link->channel_layout; - frame->sample_rate = link->sample_rate; - ret = av_frame_get_buffer(frame, 0); - if (ret < 0) { - av_frame_free(&frame); - return NULL; - } - - av_samples_set_silence(frame->extended_data, 0, nb_samples, channels, - link->format); - - - return frame; -} - -AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples) -{ - AVFrame *ret = NULL; - - if (link->dstpad->get_audio_buffer) - ret = link->dstpad->get_audio_buffer(link, nb_samples); - - if (!ret) - ret = ff_default_get_audio_buffer(link, nb_samples); - - return ret; -} - -#if FF_API_AVFILTERBUFFER -AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data, - int linesize,int perms, - int nb_samples, - enum AVSampleFormat sample_fmt, - int channels, - uint64_t channel_layout) -{ - int planes; - AVFilterBuffer *samples = av_mallocz(sizeof(*samples)); - AVFilterBufferRef *samplesref = av_mallocz(sizeof(*samplesref)); - - if (!samples || !samplesref) - goto fail; - - av_assert0(channels); - av_assert0(channel_layout == 0 || - channels == av_get_channel_layout_nb_channels(channel_layout)); - - samplesref->buf = samples; - samplesref->buf->free = ff_avfilter_default_free_buffer; - if (!(samplesref->audio = av_mallocz(sizeof(*samplesref->audio)))) - goto fail; - - samplesref->audio->nb_samples = nb_samples; - samplesref->audio->channel_layout = channel_layout; - samplesref->audio->channels = channels; - - planes = av_sample_fmt_is_planar(sample_fmt) ? channels : 1; - - /* make sure the buffer gets read permission or it's useless for output */ - samplesref->perms = perms | AV_PERM_READ; - - samples->refcount = 1; - samplesref->type = AVMEDIA_TYPE_AUDIO; - samplesref->format = sample_fmt; - - memcpy(samples->data, data, - FFMIN(FF_ARRAY_ELEMS(samples->data), planes)*sizeof(samples->data[0])); - memcpy(samplesref->data, samples->data, sizeof(samples->data)); - - samples->linesize[0] = samplesref->linesize[0] = linesize; - - if (planes > FF_ARRAY_ELEMS(samples->data)) { - samples-> extended_data = av_mallocz(sizeof(*samples->extended_data) * - planes); - samplesref->extended_data = av_mallocz(sizeof(*samplesref->extended_data) * - planes); - - if (!samples->extended_data || !samplesref->extended_data) - goto fail; - - memcpy(samples-> extended_data, data, sizeof(*data)*planes); - memcpy(samplesref->extended_data, data, sizeof(*data)*planes); - } else { - samples->extended_data = samples->data; - samplesref->extended_data = samplesref->data; - } - - samplesref->pts = AV_NOPTS_VALUE; - - return samplesref; - -fail: - if (samples && samples->extended_data != samples->data) - av_freep(&samples->extended_data); - if (samplesref) { - av_freep(&samplesref->audio); - if (samplesref->extended_data != samplesref->data) - av_freep(&samplesref->extended_data); - } - av_freep(&samplesref); - av_freep(&samples); - return NULL; -} - -AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data, - int linesize,int perms, - int nb_samples, - enum AVSampleFormat sample_fmt, - uint64_t channel_layout) -{ - int channels = av_get_channel_layout_nb_channels(channel_layout); - return avfilter_get_audio_buffer_ref_from_arrays_channels(data, linesize, perms, - nb_samples, sample_fmt, - channels, channel_layout); -} -#endif diff --git a/ffmpeg/libavfilter/audio.h b/ffmpeg/libavfilter/audio.h deleted file mode 100644 index 3335c96..0000000 --- a/ffmpeg/libavfilter/audio.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) Stefano Sabatini | stefasab at gmail.com - * Copyright (c) S.N. Hemanth Meenakshisundaram | smeenaks at ucsd.edu - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AUDIO_H -#define AVFILTER_AUDIO_H - -#include "avfilter.h" -#include "internal.h" - -static const enum AVSampleFormat ff_packed_sample_fmts_array[] = { - AV_SAMPLE_FMT_U8, - AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_S32, - AV_SAMPLE_FMT_FLT, - AV_SAMPLE_FMT_DBL, - AV_SAMPLE_FMT_NONE -}; - -static const enum AVSampleFormat ff_planar_sample_fmts_array[] = { - AV_SAMPLE_FMT_U8P, - AV_SAMPLE_FMT_S16P, - AV_SAMPLE_FMT_S32P, - AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_DBLP, - AV_SAMPLE_FMT_NONE -}; - -/** default handler for get_audio_buffer() for audio inputs */ -AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples); - -/** get_audio_buffer() handler for filters which simply pass audio along */ -AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples); - -/** - * Request an audio samples buffer with a specific set of permissions. - * - * @param link the output link to the filter from which the buffer will - * be requested - * @param nb_samples the number of samples per channel - * @return A reference to the samples. This must be unreferenced with - * avfilter_unref_buffer when you are finished with it. - */ -AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples); - -/** - * Send a buffer of audio samples to the next filter. - * - * @param link the output link over which the audio samples are being sent - * @param samplesref a reference to the buffer of audio samples being sent. The - * receiving filter will free this reference when it no longer - * needs it or pass it on to the next filter. - * - * @return >= 0 on success, a negative AVERROR on error. The receiving filter - * is responsible for unreferencing samplesref in case of error. - */ -int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref); - -/** - * Send a buffer of audio samples to the next link, without checking - * min_samples. - */ -int ff_filter_samples_framed(AVFilterLink *link, - AVFilterBufferRef *samplesref); - -#endif /* AVFILTER_AUDIO_H */ diff --git a/ffmpeg/libavfilter/avcodec.c b/ffmpeg/libavfilter/avcodec.c deleted file mode 100644 index 605e5d2..0000000 --- a/ffmpeg/libavfilter/avcodec.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2011 Stefano Sabatini | stefasab at gmail.com - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * libavcodec/libavfilter gluing utilities - */ - -#include "avcodec.h" -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" - -#if FF_API_AVFILTERBUFFER -AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame, - int perms) -{ - AVFilterBufferRef *picref = - avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, perms, - frame->width, frame->height, - frame->format); - if (!picref) - return NULL; - if (avfilter_copy_frame_props(picref, frame) < 0) { - picref->buf->data[0] = NULL; - avfilter_unref_bufferp(&picref); - } - return picref; -} - -AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, - int perms) -{ - AVFilterBufferRef *samplesref; - int channels = av_frame_get_channels(frame); - int64_t layout = av_frame_get_channel_layout(frame); - - if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) { - av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); - return NULL; - } - - samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels( - (uint8_t **)frame->extended_data, frame->linesize[0], perms, - frame->nb_samples, frame->format, channels, layout); - if (!samplesref) - return NULL; - if (avfilter_copy_frame_props(samplesref, frame) < 0) { - samplesref->buf->data[0] = NULL; - avfilter_unref_bufferp(&samplesref); - } - return samplesref; -} - -AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type, - const AVFrame *frame, - int perms) -{ - switch (type) { - case AVMEDIA_TYPE_VIDEO: - return avfilter_get_video_buffer_ref_from_frame(frame, perms); - case AVMEDIA_TYPE_AUDIO: - return avfilter_get_audio_buffer_ref_from_frame(frame, perms); - default: - return NULL; - } -} - -int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src) -{ - int planes, nb_channels; - - if (!dst) - return AVERROR(EINVAL); - /* abort in case the src is NULL and dst is not, avoid inconsistent state in dst */ - av_assert0(src); - - memcpy(dst->data, src->data, sizeof(dst->data)); - memcpy(dst->linesize, src->linesize, sizeof(dst->linesize)); - - dst->pts = src->pts; - dst->format = src->format; - av_frame_set_pkt_pos(dst, src->pos); - - switch (src->type) { - case AVMEDIA_TYPE_VIDEO: - av_assert0(src->video); - dst->width = src->video->w; - dst->height = src->video->h; - dst->sample_aspect_ratio = src->video->sample_aspect_ratio; - dst->interlaced_frame = src->video->interlaced; - dst->top_field_first = src->video->top_field_first; - dst->key_frame = src->video->key_frame; - dst->pict_type = src->video->pict_type; - break; - case AVMEDIA_TYPE_AUDIO: - av_assert0(src->audio); - nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout); - planes = av_sample_fmt_is_planar(src->format) ? nb_channels : 1; - - if (planes > FF_ARRAY_ELEMS(dst->data)) { - dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data)); - if (!dst->extended_data) - return AVERROR(ENOMEM); - memcpy(dst->extended_data, src->extended_data, - planes * sizeof(*dst->extended_data)); - } else - dst->extended_data = dst->data; - dst->nb_samples = src->audio->nb_samples; - av_frame_set_sample_rate (dst, src->audio->sample_rate); - av_frame_set_channel_layout(dst, src->audio->channel_layout); - av_frame_set_channels (dst, src->audio->channels); - break; - default: - return AVERROR(EINVAL); - } - - return 0; -} -#endif - -#if FF_API_FILL_FRAME -int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *samplesref) -{ - return avfilter_copy_buf_props(frame, samplesref); -} - -int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *picref) -{ - return avfilter_copy_buf_props(frame, picref); -} - -int avfilter_fill_frame_from_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *ref) -{ - return avfilter_copy_buf_props(frame, ref); -} -#endif diff --git a/ffmpeg/libavfilter/avcodec.h b/ffmpeg/libavfilter/avcodec.h deleted file mode 100644 index 8bbdad2..0000000 --- a/ffmpeg/libavfilter/avcodec.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVCODEC_H -#define AVFILTER_AVCODEC_H - -/** - * @file - * libavcodec/libavfilter gluing utilities - * - * This should be included in an application ONLY if the installed - * libavfilter has been compiled with libavcodec support, otherwise - * symbols defined below will not be available. - */ - -#include "avfilter.h" - -#if FF_API_AVFILTERBUFFER -/** - * Create and return a picref reference from the data and properties - * contained in frame. - * - * @param perms permissions to assign to the new buffer reference - * @deprecated avfilter APIs work natively with AVFrame instead. - */ -attribute_deprecated -AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame, int perms); - - -/** - * Create and return a picref reference from the data and properties - * contained in frame. - * - * @param perms permissions to assign to the new buffer reference - * @deprecated avfilter APIs work natively with AVFrame instead. - */ -attribute_deprecated -AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, - int perms); - -/** - * Create and return a buffer reference from the data and properties - * contained in frame. - * - * @param perms permissions to assign to the new buffer reference - * @deprecated avfilter APIs work natively with AVFrame instead. - */ -attribute_deprecated -AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type, - const AVFrame *frame, - int perms); -#endif - -#if FF_API_FILL_FRAME -/** - * Fill an AVFrame with the information stored in samplesref. - * - * @param frame an already allocated AVFrame - * @param samplesref an audio buffer reference - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure - * @deprecated Use avfilter_copy_buf_props() instead. - */ -attribute_deprecated -int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *samplesref); - -/** - * Fill an AVFrame with the information stored in picref. - * - * @param frame an already allocated AVFrame - * @param picref a video buffer reference - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure - * @deprecated Use avfilter_copy_buf_props() instead. - */ -attribute_deprecated -int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *picref); - -/** - * Fill an AVFrame with information stored in ref. - * - * @param frame an already allocated AVFrame - * @param ref a video or audio buffer reference - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure - * @deprecated Use avfilter_copy_buf_props() instead. - */ -attribute_deprecated -int avfilter_fill_frame_from_buffer_ref(AVFrame *frame, - const AVFilterBufferRef *ref); -#endif - -#endif /* AVFILTER_AVCODEC_H */ diff --git a/ffmpeg/libavfilter/avf_concat.c b/ffmpeg/libavfilter/avf_concat.c deleted file mode 100644 index c211dc4..0000000 --- a/ffmpeg/libavfilter/avf_concat.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with FFmpeg; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * concat audio-video filter - */ - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#define FF_BUFQUEUE_SIZE 256 -#include "bufferqueue.h" -#include "internal.h" -#include "video.h" -#include "audio.h" - -#define TYPE_ALL 2 - -typedef struct { - const AVClass *class; - unsigned nb_streams[TYPE_ALL]; /**< number of out streams of each type */ - unsigned nb_segments; - unsigned cur_idx; /**< index of the first input of current segment */ - int64_t delta_ts; /**< timestamp to add to produce output timestamps */ - unsigned nb_in_active; /**< number of active inputs in current segment */ - unsigned unsafe; - struct concat_in { - int64_t pts; - int64_t nb_frames; - unsigned eof; - struct FFBufQueue queue; - } *in; -} ConcatContext; - -#define OFFSET(x) offsetof(ConcatContext, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -#define V AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption concat_options[] = { - { "n", "specify the number of segments", OFFSET(nb_segments), - AV_OPT_TYPE_INT, { .i64 = 2 }, 2, INT_MAX, V|A|F}, - { "v", "specify the number of video streams", - OFFSET(nb_streams[AVMEDIA_TYPE_VIDEO]), - AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, V|F }, - { "a", "specify the number of audio streams", - OFFSET(nb_streams[AVMEDIA_TYPE_AUDIO]), - AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A|F}, - { "unsafe", "enable unsafe mode", - OFFSET(unsafe), - AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V|A|F}, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(concat); - -static int query_formats(AVFilterContext *ctx) -{ - ConcatContext *cat = ctx->priv; - unsigned type, nb_str, idx0 = 0, idx, str, seg; - AVFilterFormats *formats, *rates = NULL; - AVFilterChannelLayouts *layouts = NULL; - - for (type = 0; type < TYPE_ALL; type++) { - nb_str = cat->nb_streams[type]; - for (str = 0; str < nb_str; str++) { - idx = idx0; - - /* Set the output formats */ - formats = ff_all_formats(type); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &ctx->outputs[idx]->in_formats); - if (type == AVMEDIA_TYPE_AUDIO) { - rates = ff_all_samplerates(); - if (!rates) - return AVERROR(ENOMEM); - ff_formats_ref(rates, &ctx->outputs[idx]->in_samplerates); - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->in_channel_layouts); - } - - /* Set the same formats for each corresponding input */ - for (seg = 0; seg < cat->nb_segments; seg++) { - ff_formats_ref(formats, &ctx->inputs[idx]->out_formats); - if (type == AVMEDIA_TYPE_AUDIO) { - ff_formats_ref(rates, &ctx->inputs[idx]->out_samplerates); - ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->out_channel_layouts); - } - idx += ctx->nb_outputs; - } - - idx0++; - } - } - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ConcatContext *cat = ctx->priv; - unsigned out_no = FF_OUTLINK_IDX(outlink); - unsigned in_no = out_no, seg; - AVFilterLink *inlink = ctx->inputs[in_no]; - - /* enhancement: find a common one */ - outlink->time_base = AV_TIME_BASE_Q; - outlink->w = inlink->w; - outlink->h = inlink->h; - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - outlink->format = inlink->format; - for (seg = 1; seg < cat->nb_segments; seg++) { - inlink = ctx->inputs[in_no += ctx->nb_outputs]; - if (!outlink->sample_aspect_ratio.num) - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - /* possible enhancement: unsafe mode, do not check */ - if (outlink->w != inlink->w || - outlink->h != inlink->h || - outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num && - inlink->sample_aspect_ratio.num || - outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) { - av_log(ctx, AV_LOG_ERROR, "Input link %s parameters " - "(size %dx%d, SAR %d:%d) do not match the corresponding " - "output link %s parameters (%dx%d, SAR %d:%d)\n", - ctx->input_pads[in_no].name, inlink->w, inlink->h, - inlink->sample_aspect_ratio.num, - inlink->sample_aspect_ratio.den, - ctx->input_pads[out_no].name, outlink->w, outlink->h, - outlink->sample_aspect_ratio.num, - outlink->sample_aspect_ratio.den); - if (!cat->unsafe) - return AVERROR(EINVAL); - } - } - - return 0; -} - -static int push_frame(AVFilterContext *ctx, unsigned in_no, AVFrame *buf) -{ - ConcatContext *cat = ctx->priv; - unsigned out_no = in_no % ctx->nb_outputs; - AVFilterLink * inlink = ctx-> inputs[ in_no]; - AVFilterLink *outlink = ctx->outputs[out_no]; - struct concat_in *in = &cat->in[in_no]; - - buf->pts = av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); - in->pts = buf->pts; - in->nb_frames++; - /* add duration to input PTS */ - if (inlink->sample_rate) - /* use number of audio samples */ - in->pts += av_rescale_q(buf->nb_samples, - (AVRational){ 1, inlink->sample_rate }, - outlink->time_base); - else if (in->nb_frames >= 2) - /* use mean duration */ - in->pts = av_rescale(in->pts, in->nb_frames, in->nb_frames - 1); - - buf->pts += cat->delta_ts; - return ff_filter_frame(outlink, buf); -} - -static int process_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - ConcatContext *cat = ctx->priv; - unsigned in_no = FF_INLINK_IDX(inlink); - - if (in_no < cat->cur_idx) { - av_log(ctx, AV_LOG_ERROR, "Frame after EOF on input %s\n", - ctx->input_pads[in_no].name); - av_frame_free(&buf); - } else if (in_no >= cat->cur_idx + ctx->nb_outputs) { - ff_bufqueue_add(ctx, &cat->in[in_no].queue, buf); - } else { - return push_frame(ctx, in_no, buf); - } - return 0; -} - -static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h) -{ - AVFilterContext *ctx = inlink->dst; - unsigned in_no = FF_INLINK_IDX(inlink); - AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs]; - - return ff_get_video_buffer(outlink, w, h); -} - -static AVFrame *get_audio_buffer(AVFilterLink *inlink, int nb_samples) -{ - AVFilterContext *ctx = inlink->dst; - unsigned in_no = FF_INLINK_IDX(inlink); - AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs]; - - return ff_get_audio_buffer(outlink, nb_samples); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - return process_frame(inlink, buf); -} - -static void close_input(AVFilterContext *ctx, unsigned in_no) -{ - ConcatContext *cat = ctx->priv; - - cat->in[in_no].eof = 1; - cat->nb_in_active--; - av_log(ctx, AV_LOG_VERBOSE, "EOF on %s, %d streams left in segment.\n", - ctx->input_pads[in_no].name, cat->nb_in_active); -} - -static void find_next_delta_ts(AVFilterContext *ctx, int64_t *seg_delta) -{ - ConcatContext *cat = ctx->priv; - unsigned i = cat->cur_idx; - unsigned imax = i + ctx->nb_outputs; - int64_t pts; - - pts = cat->in[i++].pts; - for (; i < imax; i++) - pts = FFMAX(pts, cat->in[i].pts); - cat->delta_ts += pts; - *seg_delta = pts; -} - -static int send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no, - int64_t seg_delta) -{ - ConcatContext *cat = ctx->priv; - AVFilterLink *outlink = ctx->outputs[out_no]; - int64_t base_pts = cat->in[in_no].pts + cat->delta_ts - seg_delta; - int64_t nb_samples, sent = 0; - int frame_nb_samples, ret; - AVRational rate_tb = { 1, ctx->inputs[in_no]->sample_rate }; - AVFrame *buf; - int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout); - - if (!rate_tb.den) - return AVERROR_BUG; - nb_samples = av_rescale_q(seg_delta - cat->in[in_no].pts, - outlink->time_base, rate_tb); - frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */ - while (nb_samples) { - frame_nb_samples = FFMIN(frame_nb_samples, nb_samples); - buf = ff_get_audio_buffer(outlink, frame_nb_samples); - if (!buf) - return AVERROR(ENOMEM); - av_samples_set_silence(buf->extended_data, 0, frame_nb_samples, - nb_channels, outlink->format); - buf->pts = base_pts + av_rescale_q(sent, rate_tb, outlink->time_base); - ret = ff_filter_frame(outlink, buf); - if (ret < 0) - return ret; - sent += frame_nb_samples; - nb_samples -= frame_nb_samples; - } - return 0; -} - -static int flush_segment(AVFilterContext *ctx) -{ - int ret; - ConcatContext *cat = ctx->priv; - unsigned str, str_max; - int64_t seg_delta; - - find_next_delta_ts(ctx, &seg_delta); - cat->cur_idx += ctx->nb_outputs; - cat->nb_in_active = ctx->nb_outputs; - av_log(ctx, AV_LOG_VERBOSE, "Segment finished at pts=%"PRId64"\n", - cat->delta_ts); - - if (cat->cur_idx < ctx->nb_inputs) { - /* pad audio streams with silence */ - str = cat->nb_streams[AVMEDIA_TYPE_VIDEO]; - str_max = str + cat->nb_streams[AVMEDIA_TYPE_AUDIO]; - for (; str < str_max; str++) { - ret = send_silence(ctx, cat->cur_idx - ctx->nb_outputs + str, str, - seg_delta); - if (ret < 0) - return ret; - } - /* flush queued buffers */ - /* possible enhancement: flush in PTS order */ - str_max = cat->cur_idx + ctx->nb_outputs; - for (str = cat->cur_idx; str < str_max; str++) { - while (cat->in[str].queue.available) { - ret = push_frame(ctx, str, ff_bufqueue_get(&cat->in[str].queue)); - if (ret < 0) - return ret; - } - } - } - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - ConcatContext *cat = ctx->priv; - unsigned out_no = FF_OUTLINK_IDX(outlink); - unsigned in_no = out_no + cat->cur_idx; - unsigned str, str_max; - int ret; - - while (1) { - if (in_no >= ctx->nb_inputs) - return AVERROR_EOF; - if (!cat->in[in_no].eof) { - ret = ff_request_frame(ctx->inputs[in_no]); - if (ret != AVERROR_EOF) - return ret; - close_input(ctx, in_no); - } - /* cycle on all inputs to finish the segment */ - /* possible enhancement: request in PTS order */ - str_max = cat->cur_idx + ctx->nb_outputs - 1; - for (str = cat->cur_idx; cat->nb_in_active; - str = str == str_max ? cat->cur_idx : str + 1) { - if (cat->in[str].eof) - continue; - ret = ff_request_frame(ctx->inputs[str]); - if (ret == AVERROR_EOF) - close_input(ctx, str); - else if (ret < 0) - return ret; - } - ret = flush_segment(ctx); - if (ret < 0) - return ret; - in_no += ctx->nb_outputs; - } -} - -static av_cold int init(AVFilterContext *ctx) -{ - ConcatContext *cat = ctx->priv; - unsigned seg, type, str; - - /* create input pads */ - for (seg = 0; seg < cat->nb_segments; seg++) { - for (type = 0; type < TYPE_ALL; type++) { - for (str = 0; str < cat->nb_streams[type]; str++) { - AVFilterPad pad = { - .type = type, - .get_video_buffer = get_video_buffer, - .get_audio_buffer = get_audio_buffer, - .filter_frame = filter_frame, - }; - pad.name = av_asprintf("in%d:%c%d", seg, "va"[type], str); - ff_insert_inpad(ctx, ctx->nb_inputs, &pad); - } - } - } - /* create output pads */ - for (type = 0; type < TYPE_ALL; type++) { - for (str = 0; str < cat->nb_streams[type]; str++) { - AVFilterPad pad = { - .type = type, - .config_props = config_output, - .request_frame = request_frame, - }; - pad.name = av_asprintf("out:%c%d", "va"[type], str); - ff_insert_outpad(ctx, ctx->nb_outputs, &pad); - } - } - - cat->in = av_calloc(ctx->nb_inputs, sizeof(*cat->in)); - if (!cat->in) - return AVERROR(ENOMEM); - cat->nb_in_active = ctx->nb_outputs; - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ConcatContext *cat = ctx->priv; - unsigned i; - - for (i = 0; i < ctx->nb_inputs; i++) { - av_freep(&ctx->input_pads[i].name); - ff_bufqueue_discard_all(&cat->in[i].queue); - } - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); - av_free(cat->in); -} - -AVFilter ff_avf_concat = { - .name = "concat", - .description = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(ConcatContext), - .inputs = NULL, - .outputs = NULL, - .priv_class = &concat_class, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS | AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; diff --git a/ffmpeg/libavfilter/avf_showspectrum.c b/ffmpeg/libavfilter/avf_showspectrum.c deleted file mode 100644 index fc32834..0000000 --- a/ffmpeg/libavfilter/avf_showspectrum.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (c) 2012-2013 Clément BÅ“sch - * Copyright (c) 2013 Rudolf Polzer <divverent@xonotic.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio to spectrum (video) transmedia filter, based on ffplay rdft showmode - * (by Michael Niedermayer) and lavfi/avf_showwaves (by Stefano Sabatini). - */ - -#include <math.h> - -#include "libavcodec/avfft.h" -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "internal.h" - -enum DisplayMode { COMBINED, SEPARATE, NB_MODES }; -enum DisplayScale { LINEAR, SQRT, CBRT, LOG, NB_SCALES }; -enum ColorMode { CHANNEL, INTENSITY, NB_CLMODES }; -enum WindowFunc { WFUNC_NONE, WFUNC_HANN, WFUNC_HAMMING, WFUNC_BLACKMAN, NB_WFUNC }; - -typedef struct { - const AVClass *class; - int w, h; - AVFrame *outpicref; - int req_fullfilled; - int nb_display_channels; - int channel_height; - int sliding; ///< 1 if sliding mode, 0 otherwise - enum DisplayMode mode; ///< channel display mode - enum ColorMode color_mode; ///< display color scheme - enum DisplayScale scale; - float saturation; ///< color saturation multiplier - int xpos; ///< x position (current column) - RDFTContext *rdft; ///< Real Discrete Fourier Transform context - int rdft_bits; ///< number of bits (RDFT window size = 1<<rdft_bits) - FFTSample **rdft_data; ///< bins holder for each (displayed) channels - int filled; ///< number of samples (per channel) filled in current rdft_buffer - int consumed; ///< number of samples (per channel) consumed from the input frame - float *window_func_lut; ///< Window function LUT - enum WindowFunc win_func; - float *combine_buffer; ///< color combining buffer (3 * h items) -} ShowSpectrumContext; - -#define OFFSET(x) offsetof(ShowSpectrumContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption showspectrum_options[] = { - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, - { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x512"}, 0, 0, FLAGS }, - { "slide", "set sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS }, - { "mode", "set channel display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=COMBINED}, COMBINED, NB_MODES-1, FLAGS, "mode" }, - { "combined", "combined mode", 0, AV_OPT_TYPE_CONST, {.i64=COMBINED}, 0, 0, FLAGS, "mode" }, - { "separate", "separate mode", 0, AV_OPT_TYPE_CONST, {.i64=SEPARATE}, 0, 0, FLAGS, "mode" }, - { "color", "set channel coloring", OFFSET(color_mode), AV_OPT_TYPE_INT, {.i64=CHANNEL}, CHANNEL, NB_CLMODES-1, FLAGS, "color" }, - { "channel", "separate color for each channel", 0, AV_OPT_TYPE_CONST, {.i64=CHANNEL}, 0, 0, FLAGS, "color" }, - { "intensity", "intensity based coloring", 0, AV_OPT_TYPE_CONST, {.i64=INTENSITY}, 0, 0, FLAGS, "color" }, - { "scale", "set display scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64=SQRT}, LINEAR, NB_SCALES-1, FLAGS, "scale" }, - { "sqrt", "square root", 0, AV_OPT_TYPE_CONST, {.i64=SQRT}, 0, 0, FLAGS, "scale" }, - { "cbrt", "cubic root", 0, AV_OPT_TYPE_CONST, {.i64=CBRT}, 0, 0, FLAGS, "scale" }, - { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG}, 0, 0, FLAGS, "scale" }, - { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "scale" }, - { "saturation", "color saturation multiplier", OFFSET(saturation), AV_OPT_TYPE_FLOAT, {.dbl = 1}, -10, 10, FLAGS }, - { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANN}, 0, NB_WFUNC-1, FLAGS, "win_func" }, - { "hann", "Hann window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HANN}, 0, 0, FLAGS, "win_func" }, - { "hamming", "Hamming window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_HAMMING}, 0, 0, FLAGS, "win_func" }, - { "blackman", "Blackman window", 0, AV_OPT_TYPE_CONST, {.i64 = WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(showspectrum); - -static const struct { - float a, y, u, v; -} intensity_color_table[] = { - { 0, 0, 0, 0 }, - { 0.13, .03587126228984074, .1573300977624594, -.02548747583751842 }, - { 0.30, .18572281794568020, .1772436246393981, .17475554840414750 }, - { 0.60, .28184980583656130, -.1593064119945782, .47132074554608920 }, - { 0.73, .65830621175547810, -.3716070802232764, .24352759331252930 }, - { 0.78, .76318535758242900, -.4307467689263783, .16866496622310430 }, - { 0.91, .95336363636363640, -.2045454545454546, .03313636363636363 }, - { 1, 1, 0, 0 } -}; - -static av_cold void uninit(AVFilterContext *ctx) -{ - ShowSpectrumContext *s = ctx->priv; - int i; - - av_freep(&s->combine_buffer); - av_rdft_end(s->rdft); - for (i = 0; i < s->nb_display_channels; i++) - av_freep(&s->rdft_data[i]); - av_freep(&s->rdft_data); - av_freep(&s->window_func_lut); - av_frame_free(&s->outpicref); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts = NULL; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }; - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_NONE }; - - /* set input audio formats */ - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_formats); - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_samplerates); - - /* set output video format */ - formats = ff_make_format_list(pix_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &outlink->in_formats); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - ShowSpectrumContext *s = ctx->priv; - int i, rdft_bits, win_size, h; - - outlink->w = s->w; - outlink->h = s->h; - - h = (s->mode == COMBINED) ? outlink->h : outlink->h / inlink->channels; - s->channel_height = h; - - /* RDFT window size (precision) according to the requested output frame height */ - for (rdft_bits = 1; 1 << rdft_bits < 2 * h; rdft_bits++); - win_size = 1 << rdft_bits; - - /* (re-)configuration if the video output changed (or first init) */ - if (rdft_bits != s->rdft_bits) { - size_t rdft_size, rdft_listsize; - AVFrame *outpicref; - - av_rdft_end(s->rdft); - s->rdft = av_rdft_init(rdft_bits, DFT_R2C); - s->rdft_bits = rdft_bits; - - /* RDFT buffers: x2 for each (display) channel buffer. - * Note: we use free and malloc instead of a realloc-like function to - * make sure the buffer is aligned in memory for the FFT functions. */ - for (i = 0; i < s->nb_display_channels; i++) - av_freep(&s->rdft_data[i]); - av_freep(&s->rdft_data); - s->nb_display_channels = inlink->channels; - - if (av_size_mult(sizeof(*s->rdft_data), - s->nb_display_channels, &rdft_listsize) < 0) - return AVERROR(EINVAL); - if (av_size_mult(sizeof(**s->rdft_data), - win_size, &rdft_size) < 0) - return AVERROR(EINVAL); - s->rdft_data = av_malloc(rdft_listsize); - if (!s->rdft_data) - return AVERROR(ENOMEM); - for (i = 0; i < s->nb_display_channels; i++) { - s->rdft_data[i] = av_malloc(rdft_size); - if (!s->rdft_data[i]) - return AVERROR(ENOMEM); - } - s->filled = 0; - - /* pre-calc windowing function */ - s->window_func_lut = - av_realloc_f(s->window_func_lut, win_size, - sizeof(*s->window_func_lut)); - if (!s->window_func_lut) - return AVERROR(ENOMEM); - switch (s->win_func) { - case WFUNC_NONE: - for (i = 0; i < win_size; i++) - s->window_func_lut[i] = 1.; - break; - case WFUNC_HANN: - for (i = 0; i < win_size; i++) - s->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1))); - break; - case WFUNC_HAMMING: - for (i = 0; i < win_size; i++) - s->window_func_lut[i] = .54f - .46f * cos(2*M_PI*i / (win_size-1)); - break; - case WFUNC_BLACKMAN: { - for (i = 0; i < win_size; i++) - s->window_func_lut[i] = .42f - .5f*cos(2*M_PI*i / (win_size-1)) + .08f*cos(4*M_PI*i / (win_size-1)); - break; - } - default: - av_assert0(0); - } - - /* prepare the initial picref buffer (black frame) */ - av_frame_free(&s->outpicref); - s->outpicref = outpicref = - ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) - return AVERROR(ENOMEM); - outlink->sample_aspect_ratio = (AVRational){1,1}; - for (i = 0; i < outlink->h; i++) { - memset(outpicref->data[0] + i * outpicref->linesize[0], 0, outlink->w); - memset(outpicref->data[1] + i * outpicref->linesize[1], 128, outlink->w); - memset(outpicref->data[2] + i * outpicref->linesize[2], 128, outlink->w); - } - } - - if (s->xpos >= outlink->w) - s->xpos = 0; - - s->combine_buffer = - av_realloc_f(s->combine_buffer, outlink->h * 3, - sizeof(*s->combine_buffer)); - - av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n", - s->w, s->h, win_size); - return 0; -} - -inline static int push_frame(AVFilterLink *outlink) -{ - ShowSpectrumContext *s = outlink->src->priv; - - s->xpos++; - if (s->xpos >= outlink->w) - s->xpos = 0; - s->filled = 0; - s->req_fullfilled = 1; - - return ff_filter_frame(outlink, av_frame_clone(s->outpicref)); -} - -static int request_frame(AVFilterLink *outlink) -{ - ShowSpectrumContext *s = outlink->src->priv; - AVFilterLink *inlink = outlink->src->inputs[0]; - int ret; - - s->req_fullfilled = 0; - do { - ret = ff_request_frame(inlink); - } while (!s->req_fullfilled && ret >= 0); - - if (ret == AVERROR_EOF && s->outpicref) - push_frame(outlink); - return ret; -} - -static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples, int nb_samples) -{ - int ret; - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - ShowSpectrumContext *s = ctx->priv; - AVFrame *outpicref = s->outpicref; - - /* nb_freq contains the power of two superior or equal to the output image - * height (or half the RDFT window size) */ - const int nb_freq = 1 << (s->rdft_bits - 1); - const int win_size = nb_freq << 1; - const double w = 1. / (sqrt(nb_freq) * 32768.); - - int ch, plane, n, y; - const int start = s->filled; - const int add_samples = FFMIN(win_size - start, nb_samples); - - /* fill RDFT input with the number of samples available */ - for (ch = 0; ch < s->nb_display_channels; ch++) { - const int16_t *p = (int16_t *)insamples->extended_data[ch]; - - p += s->consumed; - for (n = 0; n < add_samples; n++) - s->rdft_data[ch][start + n] = p[n] * s->window_func_lut[start + n]; - } - s->filled += add_samples; - - /* complete RDFT window size? */ - if (s->filled == win_size) { - - /* channel height */ - int h = s->channel_height; - - /* run RDFT on each samples set */ - for (ch = 0; ch < s->nb_display_channels; ch++) - av_rdft_calc(s->rdft, s->rdft_data[ch]); - - /* fill a new spectrum column */ -#define RE(y, ch) s->rdft_data[ch][2 * y + 0] -#define IM(y, ch) s->rdft_data[ch][2 * y + 1] -#define MAGNITUDE(y, ch) hypot(RE(y, ch), IM(y, ch)) - - /* initialize buffer for combining to black */ - for (y = 0; y < outlink->h; y++) { - s->combine_buffer[3 * y ] = 0; - s->combine_buffer[3 * y + 1] = 127.5; - s->combine_buffer[3 * y + 2] = 127.5; - } - - for (ch = 0; ch < s->nb_display_channels; ch++) { - float yf, uf, vf; - - /* decide color range */ - switch (s->mode) { - case COMBINED: - // reduce range by channel count - yf = 256.0f / s->nb_display_channels; - switch (s->color_mode) { - case INTENSITY: - uf = yf; - vf = yf; - break; - case CHANNEL: - /* adjust saturation for mixed UV coloring */ - /* this factor is correct for infinite channels, an approximation otherwise */ - uf = yf * M_PI; - vf = yf * M_PI; - break; - default: - av_assert0(0); - } - break; - case SEPARATE: - // full range - yf = 256.0f; - uf = 256.0f; - vf = 256.0f; - break; - default: - av_assert0(0); - } - - if (s->color_mode == CHANNEL) { - if (s->nb_display_channels > 1) { - uf *= 0.5 * sin((2 * M_PI * ch) / s->nb_display_channels); - vf *= 0.5 * cos((2 * M_PI * ch) / s->nb_display_channels); - } else { - uf = 0.0f; - vf = 0.0f; - } - } - uf *= s->saturation; - vf *= s->saturation; - - /* draw the channel */ - for (y = 0; y < h; y++) { - int row = (s->mode == COMBINED) ? y : ch * h + y; - float *out = &s->combine_buffer[3 * row]; - - /* get magnitude */ - float a = w * MAGNITUDE(y, ch); - - /* apply scale */ - switch (s->scale) { - case LINEAR: - break; - case SQRT: - a = sqrt(a); - break; - case CBRT: - a = cbrt(a); - break; - case LOG: - a = 1 - log(FFMAX(FFMIN(1, a), 1e-6)) / log(1e-6); // zero = -120dBFS - break; - default: - av_assert0(0); - } - - if (s->color_mode == INTENSITY) { - float y, u, v; - int i; - - for (i = 1; i < sizeof(intensity_color_table) / sizeof(*intensity_color_table) - 1; i++) - if (intensity_color_table[i].a >= a) - break; - // i now is the first item >= the color - // now we know to interpolate between item i - 1 and i - if (a <= intensity_color_table[i - 1].a) { - y = intensity_color_table[i - 1].y; - u = intensity_color_table[i - 1].u; - v = intensity_color_table[i - 1].v; - } else if (a >= intensity_color_table[i].a) { - y = intensity_color_table[i].y; - u = intensity_color_table[i].u; - v = intensity_color_table[i].v; - } else { - float start = intensity_color_table[i - 1].a; - float end = intensity_color_table[i].a; - float lerpfrac = (a - start) / (end - start); - y = intensity_color_table[i - 1].y * (1.0f - lerpfrac) - + intensity_color_table[i].y * lerpfrac; - u = intensity_color_table[i - 1].u * (1.0f - lerpfrac) - + intensity_color_table[i].u * lerpfrac; - v = intensity_color_table[i - 1].v * (1.0f - lerpfrac) - + intensity_color_table[i].v * lerpfrac; - } - - out[0] += y * yf; - out[1] += u * uf; - out[2] += v * vf; - } else { - out[0] += a * yf; - out[1] += a * uf; - out[2] += a * vf; - } - } - } - - /* copy to output */ - if (s->sliding) { - for (plane = 0; plane < 3; plane++) { - for (y = 0; y < outlink->h; y++) { - uint8_t *p = outpicref->data[plane] + - y * outpicref->linesize[plane]; - memmove(p, p + 1, outlink->w - 1); - } - } - s->xpos = outlink->w - 1; - } - for (plane = 0; plane < 3; plane++) { - uint8_t *p = outpicref->data[plane] + - (outlink->h - 1) * outpicref->linesize[plane] + - s->xpos; - for (y = 0; y < outlink->h; y++) { - *p = rint(FFMAX(0, FFMIN(s->combine_buffer[3 * y + plane], 255))); - p -= outpicref->linesize[plane]; - } - } - - outpicref->pts = insamples->pts + - av_rescale_q(s->consumed, - (AVRational){ 1, inlink->sample_rate }, - outlink->time_base); - ret = push_frame(outlink); - if (ret < 0) - return ret; - } - - return add_samples; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterContext *ctx = inlink->dst; - ShowSpectrumContext *s = ctx->priv; - int ret = 0, left_samples = insamples->nb_samples; - - s->consumed = 0; - while (left_samples) { - int ret = plot_spectrum_column(inlink, insamples, left_samples); - if (ret < 0) - break; - s->consumed += ret; - left_samples -= ret; - } - - av_frame_free(&insamples); - return ret; -} - -static const AVFilterPad showspectrum_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad showspectrum_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_avf_showspectrum = { - .name = "showspectrum", - .description = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output."), - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(ShowSpectrumContext), - .inputs = showspectrum_inputs, - .outputs = showspectrum_outputs, - .priv_class = &showspectrum_class, -}; diff --git a/ffmpeg/libavfilter/avf_showwaves.c b/ffmpeg/libavfilter/avf_showwaves.c deleted file mode 100644 index 0b45bd0..0000000 --- a/ffmpeg/libavfilter/avf_showwaves.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio to video multimedia filter - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "formats.h" -#include "audio.h" -#include "video.h" -#include "internal.h" - -enum ShowWavesMode { - MODE_POINT, - MODE_LINE, - MODE_NB, -}; - -typedef struct { - const AVClass *class; - int w, h; - AVRational rate; - int buf_idx; - AVFrame *outpicref; - int req_fullfilled; - int n; - int sample_count_mod; - enum ShowWavesMode mode; -} ShowWavesContext; - -#define OFFSET(x) offsetof(ShowWavesContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption showwaves_options[] = { - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS }, - { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "600x240"}, 0, 0, FLAGS }, - { "mode", "select display mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_POINT}, 0, MODE_NB-1, FLAGS, "mode"}, - { "point", "draw a point for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_POINT}, .flags=FLAGS, .unit="mode"}, - { "line", "draw a line for each sample", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LINE}, .flags=FLAGS, .unit="mode"}, - { "n", "set how many samples to show in the same point", OFFSET(n), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, - { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "r", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(showwaves); - -static av_cold void uninit(AVFilterContext *ctx) -{ - ShowWavesContext *showwaves = ctx->priv; - - av_frame_free(&showwaves->outpicref); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts = NULL; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; - - /* set input audio formats */ - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_formats); - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); - - formats = ff_all_samplerates(); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_samplerates); - - /* set output video format */ - formats = ff_make_format_list(pix_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &outlink->in_formats); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - ShowWavesContext *showwaves = ctx->priv; - - if (!showwaves->n) - showwaves->n = FFMAX(1, ((double)inlink->sample_rate / (showwaves->w * av_q2d(showwaves->rate))) + 0.5); - - showwaves->buf_idx = 0; - outlink->w = showwaves->w; - outlink->h = showwaves->h; - outlink->sample_aspect_ratio = (AVRational){1,1}; - - outlink->frame_rate = av_div_q((AVRational){inlink->sample_rate,showwaves->n}, - (AVRational){showwaves->w,1}); - - av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d r:%f n:%d\n", - showwaves->w, showwaves->h, av_q2d(outlink->frame_rate), showwaves->n); - return 0; -} - -inline static int push_frame(AVFilterLink *outlink) -{ - ShowWavesContext *showwaves = outlink->src->priv; - int ret; - - if ((ret = ff_filter_frame(outlink, showwaves->outpicref)) >= 0) - showwaves->req_fullfilled = 1; - showwaves->outpicref = NULL; - showwaves->buf_idx = 0; - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - ShowWavesContext *showwaves = outlink->src->priv; - AVFilterLink *inlink = outlink->src->inputs[0]; - int ret; - - showwaves->req_fullfilled = 0; - do { - ret = ff_request_frame(inlink); - } while (!showwaves->req_fullfilled && ret >= 0); - - if (ret == AVERROR_EOF && showwaves->outpicref) - push_frame(outlink); - return ret; -} - -#define MAX_INT16 ((1<<15) -1) - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - ShowWavesContext *showwaves = ctx->priv; - const int nb_samples = insamples->nb_samples; - AVFrame *outpicref = showwaves->outpicref; - int linesize = outpicref ? outpicref->linesize[0] : 0; - int16_t *p = (int16_t *)insamples->data[0]; - int nb_channels = inlink->channels; - int i, j, k, h, ret = 0; - const int n = showwaves->n; - const int x = 255 / (nb_channels * n); /* multiplication factor, pre-computed to avoid in-loop divisions */ - - /* draw data in the buffer */ - for (i = 0; i < nb_samples; i++) { - if (!showwaves->outpicref) { - showwaves->outpicref = outpicref = - ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) - return AVERROR(ENOMEM); - outpicref->width = outlink->w; - outpicref->height = outlink->h; - outpicref->pts = insamples->pts + - av_rescale_q((p - (int16_t *)insamples->data[0]) / nb_channels, - (AVRational){ 1, inlink->sample_rate }, - outlink->time_base); - linesize = outpicref->linesize[0]; - for (j = 0; j < outlink->h; j++) - memset(outpicref->data[0] + j * linesize, 0, outlink->w); - } - for (j = 0; j < nb_channels; j++) { - h = showwaves->h/2 - av_rescale(*p++, showwaves->h/2, MAX_INT16); - switch (showwaves->mode) { - case MODE_POINT: - if (h >= 0 && h < outlink->h) - *(outpicref->data[0] + showwaves->buf_idx + h * linesize) += x; - break; - - case MODE_LINE: - { - int start = showwaves->h/2, end = av_clip(h, 0, outlink->h-1); - if (start > end) FFSWAP(int16_t, start, end); - for (k = start; k < end; k++) - *(outpicref->data[0] + showwaves->buf_idx + k * linesize) += x; - break; - } - } - } - - showwaves->sample_count_mod++; - if (showwaves->sample_count_mod == n) { - showwaves->sample_count_mod = 0; - showwaves->buf_idx++; - } - if (showwaves->buf_idx == showwaves->w) - if ((ret = push_frame(outlink)) < 0) - break; - outpicref = showwaves->outpicref; - } - - av_frame_free(&insamples); - return ret; -} - -static const AVFilterPad showwaves_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad showwaves_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_avf_showwaves = { - .name = "showwaves", - .description = NULL_IF_CONFIG_SMALL("Convert input audio to a video output."), - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(ShowWavesContext), - .inputs = showwaves_inputs, - .outputs = showwaves_outputs, - .priv_class = &showwaves_class, -}; diff --git a/ffmpeg/libavfilter/avfilter.c b/ffmpeg/libavfilter/avfilter.c deleted file mode 100644 index 2567ce9..0000000 --- a/ffmpeg/libavfilter/avfilter.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* - * filter layer - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/atomic.h" -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/rational.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame); - -void ff_tlog_ref(void *ctx, AVFrame *ref, int end) -{ - av_unused char buf[16]; - ff_tlog(ctx, - "ref[%p buf:%p data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64, - ref, ref->buf, ref->data[0], - ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3], - ref->pts, av_frame_get_pkt_pos(ref)); - - if (ref->width) { - ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c", - ref->sample_aspect_ratio.num, ref->sample_aspect_ratio.den, - ref->width, ref->height, - !ref->interlaced_frame ? 'P' : /* Progressive */ - ref->top_field_first ? 'T' : 'B', /* Top / Bottom */ - ref->key_frame, - av_get_picture_type_char(ref->pict_type)); - } - if (ref->nb_samples) { - ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d", - ref->channel_layout, - ref->nb_samples, - ref->sample_rate); - } - - ff_tlog(ctx, "]%s", end ? "\n" : ""); -} - -unsigned avfilter_version(void) -{ - av_assert0(LIBAVFILTER_VERSION_MICRO >= 100); - return LIBAVFILTER_VERSION_INT; -} - -const char *avfilter_configuration(void) -{ - return FFMPEG_CONFIGURATION; -} - -const char *avfilter_license(void) -{ -#define LICENSE_PREFIX "libavfilter license: " - return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; -} - -void ff_command_queue_pop(AVFilterContext *filter) -{ - AVFilterCommand *c= filter->command_queue; - av_freep(&c->arg); - av_freep(&c->command); - filter->command_queue= c->next; - av_free(c); -} - -int ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad) -{ - AVFilterLink **newlinks; - AVFilterPad *newpads; - unsigned i; - - idx = FFMIN(idx, *count); - - newpads = av_realloc_array(*pads, *count + 1, sizeof(AVFilterPad)); - newlinks = av_realloc_array(*links, *count + 1, sizeof(AVFilterLink*)); - if (newpads) - *pads = newpads; - if (newlinks) - *links = newlinks; - if (!newpads || !newlinks) - return AVERROR(ENOMEM); - - memmove(*pads + idx + 1, *pads + idx, sizeof(AVFilterPad) * (*count - idx)); - memmove(*links + idx + 1, *links + idx, sizeof(AVFilterLink*) * (*count - idx)); - memcpy(*pads + idx, newpad, sizeof(AVFilterPad)); - (*links)[idx] = NULL; - - (*count)++; - for (i = idx + 1; i < *count; i++) - if ((*links)[i]) - (*(unsigned *)((uint8_t *) (*links)[i] + padidx_off))++; - - return 0; -} - -int avfilter_link(AVFilterContext *src, unsigned srcpad, - AVFilterContext *dst, unsigned dstpad) -{ - AVFilterLink *link; - - if (src->nb_outputs <= srcpad || dst->nb_inputs <= dstpad || - src->outputs[srcpad] || dst->inputs[dstpad]) - return -1; - - if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) { - av_log(src, AV_LOG_ERROR, - "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n", - src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"), - dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?")); - return AVERROR(EINVAL); - } - - link = av_mallocz(sizeof(*link)); - if (!link) - return AVERROR(ENOMEM); - - src->outputs[srcpad] = dst->inputs[dstpad] = link; - - link->src = src; - link->dst = dst; - link->srcpad = &src->output_pads[srcpad]; - link->dstpad = &dst->input_pads[dstpad]; - link->type = src->output_pads[srcpad].type; - av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1); - link->format = -1; - - return 0; -} - -void avfilter_link_free(AVFilterLink **link) -{ - if (!*link) - return; - - av_frame_free(&(*link)->partial_buf); - - av_freep(link); -} - -int avfilter_link_get_channels(AVFilterLink *link) -{ - return link->channels; -} - -void avfilter_link_set_closed(AVFilterLink *link, int closed) -{ - link->closed = closed; -} - -int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, - unsigned filt_srcpad_idx, unsigned filt_dstpad_idx) -{ - int ret; - unsigned dstpad_idx = link->dstpad - link->dst->input_pads; - - av_log(link->dst, AV_LOG_VERBOSE, "auto-inserting filter '%s' " - "between the filter '%s' and the filter '%s'\n", - filt->name, link->src->name, link->dst->name); - - link->dst->inputs[dstpad_idx] = NULL; - if ((ret = avfilter_link(filt, filt_dstpad_idx, link->dst, dstpad_idx)) < 0) { - /* failed to link output filter to new filter */ - link->dst->inputs[dstpad_idx] = link; - return ret; - } - - /* re-hookup the link to the new destination filter we inserted */ - link->dst = filt; - link->dstpad = &filt->input_pads[filt_srcpad_idx]; - filt->inputs[filt_srcpad_idx] = link; - - /* if any information on supported media formats already exists on the - * link, we need to preserve that */ - if (link->out_formats) - ff_formats_changeref(&link->out_formats, - &filt->outputs[filt_dstpad_idx]->out_formats); - if (link->out_samplerates) - ff_formats_changeref(&link->out_samplerates, - &filt->outputs[filt_dstpad_idx]->out_samplerates); - if (link->out_channel_layouts) - ff_channel_layouts_changeref(&link->out_channel_layouts, - &filt->outputs[filt_dstpad_idx]->out_channel_layouts); - - return 0; -} - -int avfilter_config_links(AVFilterContext *filter) -{ - int (*config_link)(AVFilterLink *); - unsigned i; - int ret; - - for (i = 0; i < filter->nb_inputs; i ++) { - AVFilterLink *link = filter->inputs[i]; - AVFilterLink *inlink; - - if (!link) continue; - - inlink = link->src->nb_inputs ? link->src->inputs[0] : NULL; - link->current_pts = AV_NOPTS_VALUE; - - switch (link->init_state) { - case AVLINK_INIT: - continue; - case AVLINK_STARTINIT: - av_log(filter, AV_LOG_INFO, "circular filter chain detected\n"); - return 0; - case AVLINK_UNINIT: - link->init_state = AVLINK_STARTINIT; - - if ((ret = avfilter_config_links(link->src)) < 0) - return ret; - - if (!(config_link = link->srcpad->config_props)) { - if (link->src->nb_inputs != 1) { - av_log(link->src, AV_LOG_ERROR, "Source filters and filters " - "with more than one input " - "must set config_props() " - "callbacks on all outputs\n"); - return AVERROR(EINVAL); - } - } else if ((ret = config_link(link)) < 0) { - av_log(link->src, AV_LOG_ERROR, - "Failed to configure output pad on %s\n", - link->src->name); - return ret; - } - - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - if (!link->time_base.num && !link->time_base.den) - link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q; - - if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den) - link->sample_aspect_ratio = inlink ? - inlink->sample_aspect_ratio : (AVRational){1,1}; - - if (inlink && !link->frame_rate.num && !link->frame_rate.den) - link->frame_rate = inlink->frame_rate; - - if (inlink) { - if (!link->w) - link->w = inlink->w; - if (!link->h) - link->h = inlink->h; - } else if (!link->w || !link->h) { - av_log(link->src, AV_LOG_ERROR, - "Video source filters must set their output link's " - "width and height\n"); - return AVERROR(EINVAL); - } - break; - - case AVMEDIA_TYPE_AUDIO: - if (inlink) { - if (!link->time_base.num && !link->time_base.den) - link->time_base = inlink->time_base; - } - - if (!link->time_base.num && !link->time_base.den) - link->time_base = (AVRational) {1, link->sample_rate}; - } - - if ((config_link = link->dstpad->config_props)) - if ((ret = config_link(link)) < 0) { - av_log(link->src, AV_LOG_ERROR, - "Failed to configure input pad on %s\n", - link->dst->name); - return ret; - } - - link->init_state = AVLINK_INIT; - } - } - - return 0; -} - -void ff_tlog_link(void *ctx, AVFilterLink *link, int end) -{ - if (link->type == AVMEDIA_TYPE_VIDEO) { - ff_tlog(ctx, - "link[%p s:%dx%d fmt:%s %s->%s]%s", - link, link->w, link->h, - av_get_pix_fmt_name(link->format), - link->src ? link->src->filter->name : "", - link->dst ? link->dst->filter->name : "", - end ? "\n" : ""); - } else { - char buf[128]; - av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout); - - ff_tlog(ctx, - "link[%p r:%d cl:%s fmt:%s %s->%s]%s", - link, (int)link->sample_rate, buf, - av_get_sample_fmt_name(link->format), - link->src ? link->src->filter->name : "", - link->dst ? link->dst->filter->name : "", - end ? "\n" : ""); - } -} - -int ff_request_frame(AVFilterLink *link) -{ - int ret = -1; - FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1); - - if (link->closed) - return AVERROR_EOF; - av_assert0(!link->frame_requested); - link->frame_requested = 1; - while (link->frame_requested) { - if (link->srcpad->request_frame) - ret = link->srcpad->request_frame(link); - else if (link->src->inputs[0]) - ret = ff_request_frame(link->src->inputs[0]); - if (ret == AVERROR_EOF && link->partial_buf) { - AVFrame *pbuf = link->partial_buf; - link->partial_buf = NULL; - ret = ff_filter_frame_framed(link, pbuf); - } - if (ret < 0) { - link->frame_requested = 0; - if (ret == AVERROR_EOF) - link->closed = 1; - } else { - av_assert0(!link->frame_requested || - link->flags & FF_LINK_FLAG_REQUEST_LOOP); - } - } - return ret; -} - -int ff_poll_frame(AVFilterLink *link) -{ - int i, min = INT_MAX; - - if (link->srcpad->poll_frame) - return link->srcpad->poll_frame(link); - - for (i = 0; i < link->src->nb_inputs; i++) { - int val; - if (!link->src->inputs[i]) - return -1; - val = ff_poll_frame(link->src->inputs[i]); - min = FFMIN(min, val); - } - - return min; -} - -static const char *const var_names[] = { "t", "n", "pos", NULL }; -enum { VAR_T, VAR_N, VAR_POS, VAR_VARS_NB }; - -static int set_enable_expr(AVFilterContext *ctx, const char *expr) -{ - int ret; - char *expr_dup; - AVExpr *old = ctx->enable; - - if (!(ctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE)) { - av_log(ctx, AV_LOG_ERROR, "Timeline ('enable' option) not supported " - "with filter '%s'\n", ctx->filter->name); - return AVERROR_PATCHWELCOME; - } - - expr_dup = av_strdup(expr); - if (!expr_dup) - return AVERROR(ENOMEM); - - if (!ctx->var_values) { - ctx->var_values = av_calloc(VAR_VARS_NB, sizeof(*ctx->var_values)); - if (!ctx->var_values) { - av_free(expr_dup); - return AVERROR(ENOMEM); - } - } - - ret = av_expr_parse((AVExpr**)&ctx->enable, expr_dup, var_names, - NULL, NULL, NULL, NULL, 0, ctx->priv); - if (ret < 0) { - av_log(ctx->priv, AV_LOG_ERROR, - "Error when evaluating the expression '%s' for enable\n", - expr_dup); - av_free(expr_dup); - return ret; - } - - av_expr_free(old); - av_free(ctx->enable_str); - ctx->enable_str = expr_dup; - return 0; -} - -void ff_update_link_current_pts(AVFilterLink *link, int64_t pts) -{ - if (pts == AV_NOPTS_VALUE) - return; - link->current_pts = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q); - /* TODO use duration */ - if (link->graph && link->age_index >= 0) - ff_avfilter_graph_update_heap(link->graph, link); -} - -int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags) -{ - if(!strcmp(cmd, "ping")){ - char local_res[256] = {0}; - - if (!res) { - res = local_res; - res_len = sizeof(local_res); - } - av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name); - if (res == local_res) - av_log(filter, AV_LOG_INFO, "%s", res); - return 0; - }else if(!strcmp(cmd, "enable")) { - return set_enable_expr(filter, arg); - }else if(filter->filter->process_command) { - return filter->filter->process_command(filter, cmd, arg, res, res_len, flags); - } - return AVERROR(ENOSYS); -} - -static AVFilter *first_filter; - -#if !FF_API_NOCONST_GET_NAME -const -#endif -AVFilter *avfilter_get_by_name(const char *name) -{ - const AVFilter *f = NULL; - - if (!name) - return NULL; - - while ((f = avfilter_next(f))) - if (!strcmp(f->name, name)) - return (AVFilter *)f; - - return NULL; -} - -int avfilter_register(AVFilter *filter) -{ - AVFilter **f = &first_filter; - int i; - - /* the filter must select generic or internal exclusively */ - av_assert0((filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE) != AVFILTER_FLAG_SUPPORT_TIMELINE); - - for(i=0; filter->inputs && filter->inputs[i].name; i++) { - const AVFilterPad *input = &filter->inputs[i]; - av_assert0( !input->filter_frame - || (!input->start_frame && !input->end_frame)); - } - - filter->next = NULL; - - while(*f || avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter)) - f = &(*f)->next; - - return 0; -} - -const AVFilter *avfilter_next(const AVFilter *prev) -{ - return prev ? prev->next : first_filter; -} - -#if FF_API_OLD_FILTER_REGISTER -AVFilter **av_filter_next(AVFilter **filter) -{ - return filter ? &(*filter)->next : &first_filter; -} - -void avfilter_uninit(void) -{ -} -#endif - -int avfilter_pad_count(const AVFilterPad *pads) -{ - int count; - - if (!pads) - return 0; - - for (count = 0; pads->name; count++) - pads++; - return count; -} - -static const char *default_filter_name(void *filter_ctx) -{ - AVFilterContext *ctx = filter_ctx; - return ctx->name ? ctx->name : ctx->filter->name; -} - -static void *filter_child_next(void *obj, void *prev) -{ - AVFilterContext *ctx = obj; - if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv) - return ctx->priv; - return NULL; -} - -static const AVClass *filter_child_class_next(const AVClass *prev) -{ - const AVFilter *f = NULL; - - /* find the filter that corresponds to prev */ - while (prev && (f = avfilter_next(f))) - if (f->priv_class == prev) - break; - - /* could not find filter corresponding to prev */ - if (prev && !f) - return NULL; - - /* find next filter with specific options */ - while ((f = avfilter_next(f))) - if (f->priv_class) - return f->priv_class; - - return NULL; -} - -#define OFFSET(x) offsetof(AVFilterContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM -static const AVOption avfilter_options[] = { - { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, - { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" }, - { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .unit = "thread_type" }, - { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { NULL }, -}; - -static const AVClass avfilter_class = { - .class_name = "AVFilter", - .item_name = default_filter_name, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_FILTER, - .child_next = filter_child_next, - .child_class_next = filter_child_class_next, - .option = avfilter_options, -}; - -static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, - int *ret, int nb_jobs) -{ - int i; - - for (i = 0; i < nb_jobs; i++) { - int r = func(ctx, arg, i, nb_jobs); - if (ret) - ret[i] = r; - } - return 0; -} - -AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name) -{ - AVFilterContext *ret; - - if (!filter) - return NULL; - - ret = av_mallocz(sizeof(AVFilterContext)); - if (!ret) - return NULL; - - ret->av_class = &avfilter_class; - ret->filter = filter; - ret->name = inst_name ? av_strdup(inst_name) : NULL; - if (filter->priv_size) { - ret->priv = av_mallocz(filter->priv_size); - if (!ret->priv) - goto err; - } - - av_opt_set_defaults(ret); - if (filter->priv_class) { - *(const AVClass**)ret->priv = filter->priv_class; - av_opt_set_defaults(ret->priv); - } - - ret->internal = av_mallocz(sizeof(*ret->internal)); - if (!ret->internal) - goto err; - ret->internal->execute = default_execute; - - ret->nb_inputs = avfilter_pad_count(filter->inputs); - if (ret->nb_inputs ) { - ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs); - if (!ret->input_pads) - goto err; - memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->nb_inputs); - ret->inputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_inputs); - if (!ret->inputs) - goto err; - } - - ret->nb_outputs = avfilter_pad_count(filter->outputs); - if (ret->nb_outputs) { - ret->output_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs); - if (!ret->output_pads) - goto err; - memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->nb_outputs); - ret->outputs = av_mallocz(sizeof(AVFilterLink*) * ret->nb_outputs); - if (!ret->outputs) - goto err; - } -#if FF_API_FOO_COUNT -FF_DISABLE_DEPRECATION_WARNINGS - ret->output_count = ret->nb_outputs; - ret->input_count = ret->nb_inputs; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - return ret; - -err: - av_freep(&ret->inputs); - av_freep(&ret->input_pads); - ret->nb_inputs = 0; - av_freep(&ret->outputs); - av_freep(&ret->output_pads); - ret->nb_outputs = 0; - av_freep(&ret->priv); - av_freep(&ret->internal); - av_free(ret); - return NULL; -} - -#if FF_API_AVFILTER_OPEN -int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name) -{ - *filter_ctx = ff_filter_alloc(filter, inst_name); - return *filter_ctx ? 0 : AVERROR(ENOMEM); -} -#endif - -static void free_link(AVFilterLink *link) -{ - if (!link) - return; - - if (link->src) - link->src->outputs[link->srcpad - link->src->output_pads] = NULL; - if (link->dst) - link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL; - - ff_formats_unref(&link->in_formats); - ff_formats_unref(&link->out_formats); - ff_formats_unref(&link->in_samplerates); - ff_formats_unref(&link->out_samplerates); - ff_channel_layouts_unref(&link->in_channel_layouts); - ff_channel_layouts_unref(&link->out_channel_layouts); - avfilter_link_free(&link); -} - -void avfilter_free(AVFilterContext *filter) -{ - int i; - - if (!filter) - return; - - if (filter->graph) - ff_filter_graph_remove_filter(filter->graph, filter); - - if (filter->filter->uninit) - filter->filter->uninit(filter); - - for (i = 0; i < filter->nb_inputs; i++) { - free_link(filter->inputs[i]); - } - for (i = 0; i < filter->nb_outputs; i++) { - free_link(filter->outputs[i]); - } - - if (filter->filter->priv_class) - av_opt_free(filter->priv); - - av_freep(&filter->name); - av_freep(&filter->input_pads); - av_freep(&filter->output_pads); - av_freep(&filter->inputs); - av_freep(&filter->outputs); - av_freep(&filter->priv); - while(filter->command_queue){ - ff_command_queue_pop(filter); - } - av_opt_free(filter); - av_expr_free(filter->enable); - filter->enable = NULL; - av_freep(&filter->var_values); - av_freep(&filter->internal); - av_free(filter); -} - -static int process_options(AVFilterContext *ctx, AVDictionary **options, - const char *args) -{ - const AVOption *o = NULL; - int ret, count = 0; - char *av_uninit(parsed_key), *av_uninit(value); - const char *key; - int offset= -1; - - if (!args) - return 0; - - while (*args) { - const char *shorthand = NULL; - - o = av_opt_next(ctx->priv, o); - if (o) { - if (o->type == AV_OPT_TYPE_CONST || o->offset == offset) - continue; - offset = o->offset; - shorthand = o->name; - } - - ret = av_opt_get_key_value(&args, "=", ":", - shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0, - &parsed_key, &value); - if (ret < 0) { - if (ret == AVERROR(EINVAL)) - av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", args); - else - av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args, - av_err2str(ret)); - return ret; - } - if (*args) - args++; - if (parsed_key) { - key = parsed_key; - while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */ - } else { - key = shorthand; - } - - av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value); - - if (av_opt_find(ctx, key, NULL, 0, 0)) { - ret = av_opt_set(ctx, key, value, 0); - if (ret < 0) { - av_free(value); - av_free(parsed_key); - return ret; - } - } else { - av_dict_set(options, key, value, 0); - if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) { - if (!av_opt_find(ctx->priv, key, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) { - if (ret == AVERROR_OPTION_NOT_FOUND) - av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key); - av_free(value); - av_free(parsed_key); - return ret; - } - } - } - - av_free(value); - av_free(parsed_key); - count++; - } - - if (ctx->enable_str) { - ret = set_enable_expr(ctx, ctx->enable_str); - if (ret < 0) - return ret; - } - return count; -} - -#if FF_API_AVFILTER_INIT_FILTER -int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque) -{ - return avfilter_init_str(filter, args); -} -#endif - -int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) -{ - int ret = 0; - - ret = av_opt_set_dict(ctx, options); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n"); - return ret; - } - - if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS && - ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE && - ctx->graph->internal->thread_execute) { - ctx->thread_type = AVFILTER_THREAD_SLICE; - ctx->internal->execute = ctx->graph->internal->thread_execute; - } else { - ctx->thread_type = 0; - } - - if (ctx->filter->priv_class) { - ret = av_opt_set_dict(ctx->priv, options); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Error applying options to the filter.\n"); - return ret; - } - } - - if (ctx->filter->init_opaque) - ret = ctx->filter->init_opaque(ctx, NULL); - else if (ctx->filter->init) - ret = ctx->filter->init(ctx); - else if (ctx->filter->init_dict) - ret = ctx->filter->init_dict(ctx, options); - - return ret; -} - -int avfilter_init_str(AVFilterContext *filter, const char *args) -{ - AVDictionary *options = NULL; - AVDictionaryEntry *e; - int ret = 0; - - if (args && *args) { - if (!filter->filter->priv_class) { - av_log(filter, AV_LOG_ERROR, "This filter does not take any " - "options, but options were provided: %s.\n", args); - return AVERROR(EINVAL); - } - -#if FF_API_OLD_FILTER_OPTS - if ( !strcmp(filter->filter->name, "format") || - !strcmp(filter->filter->name, "noformat") || - !strcmp(filter->filter->name, "frei0r") || - !strcmp(filter->filter->name, "frei0r_src") || - !strcmp(filter->filter->name, "ocv") || - !strcmp(filter->filter->name, "pan") || - !strcmp(filter->filter->name, "pp") || - !strcmp(filter->filter->name, "aevalsrc")) { - /* a hack for compatibility with the old syntax - * replace colons with |s */ - char *copy = av_strdup(args); - char *p = copy; - int nb_leading = 0; // number of leading colons to skip - int deprecated = 0; - - if (!copy) { - ret = AVERROR(ENOMEM); - goto fail; - } - - if (!strcmp(filter->filter->name, "frei0r") || - !strcmp(filter->filter->name, "ocv")) - nb_leading = 1; - else if (!strcmp(filter->filter->name, "frei0r_src")) - nb_leading = 3; - - while (nb_leading--) { - p = strchr(p, ':'); - if (!p) { - p = copy + strlen(copy); - break; - } - p++; - } - - deprecated = strchr(p, ':') != NULL; - - if (!strcmp(filter->filter->name, "aevalsrc")) { - deprecated = 0; - while ((p = strchr(p, ':')) && p[1] != ':') { - const char *epos = strchr(p + 1, '='); - const char *spos = strchr(p + 1, ':'); - const int next_token_is_opt = epos && (!spos || epos < spos); - if (next_token_is_opt) { - p++; - break; - } - /* next token does not contain a '=', assume a channel expression */ - deprecated = 1; - *p++ = '|'; - } - if (p && *p == ':') { // double sep '::' found - deprecated = 1; - memmove(p, p + 1, strlen(p)); - } - } else - while ((p = strchr(p, ':'))) - *p++ = '|'; - - if (deprecated) - av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use " - "'|' to separate the list items.\n"); - - av_log(filter, AV_LOG_DEBUG, "compat: called with args=[%s]\n", copy); - ret = process_options(filter, &options, copy); - av_freep(©); - - if (ret < 0) - goto fail; -#endif - } else { -#if CONFIG_MP_FILTER - if (!strcmp(filter->filter->name, "mp")) { - char *escaped; - - if (!strncmp(args, "filter=", 7)) - args += 7; - ret = av_escape(&escaped, args, ":=", AV_ESCAPE_MODE_BACKSLASH, 0); - if (ret < 0) { - av_log(filter, AV_LOG_ERROR, "Unable to escape MPlayer filters arg '%s'\n", args); - goto fail; - } - ret = process_options(filter, &options, escaped); - av_free(escaped); - } else -#endif - ret = process_options(filter, &options, args); - if (ret < 0) - goto fail; - } - } - - ret = avfilter_init_dict(filter, &options); - if (ret < 0) - goto fail; - - if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) { - av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key); - ret = AVERROR_OPTION_NOT_FOUND; - goto fail; - } - -fail: - av_dict_free(&options); - - return ret; -} - -const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx) -{ - return pads[pad_idx].name; -} - -enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx) -{ - return pads[pad_idx].type; -} - -static int default_filter_frame(AVFilterLink *link, AVFrame *frame) -{ - return ff_filter_frame(link->dst->outputs[0], frame); -} - -static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) -{ - int (*filter_frame)(AVFilterLink *, AVFrame *); - AVFilterContext *dstctx = link->dst; - AVFilterPad *dst = link->dstpad; - AVFrame *out; - int ret; - AVFilterCommand *cmd= link->dst->command_queue; - int64_t pts; - - if (link->closed) { - av_frame_free(&frame); - return AVERROR_EOF; - } - - if (!(filter_frame = dst->filter_frame)) - filter_frame = default_filter_frame; - - /* copy the frame if needed */ - if (dst->needs_writable && !av_frame_is_writable(frame)) { - av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n"); - - /* Maybe use ff_copy_buffer_ref instead? */ - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - out = ff_get_video_buffer(link, link->w, link->h); - break; - case AVMEDIA_TYPE_AUDIO: - out = ff_get_audio_buffer(link, frame->nb_samples); - break; - default: return AVERROR(EINVAL); - } - if (!out) { - av_frame_free(&frame); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, frame); - - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize, - frame->format, frame->width, frame->height); - break; - case AVMEDIA_TYPE_AUDIO: - av_samples_copy(out->extended_data, frame->extended_data, - 0, 0, frame->nb_samples, - av_get_channel_layout_nb_channels(frame->channel_layout), - frame->format); - break; - default: return AVERROR(EINVAL); - } - - av_frame_free(&frame); - } else - out = frame; - - while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){ - av_log(link->dst, AV_LOG_DEBUG, - "Processing command time:%f command:%s arg:%s\n", - cmd->time, cmd->command, cmd->arg); - avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags); - ff_command_queue_pop(link->dst); - cmd= link->dst->command_queue; - } - - pts = out->pts; - if (dstctx->enable_str) { - int64_t pos = av_frame_get_pkt_pos(out); - dstctx->var_values[VAR_N] = link->frame_count; - dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base); - dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos; - - dstctx->is_disabled = fabs(av_expr_eval(dstctx->enable, dstctx->var_values, NULL)) < 0.5; - if (dstctx->is_disabled && - (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC)) - filter_frame = default_filter_frame; - } - ret = filter_frame(link, out); - link->frame_count++; - link->frame_requested = 0; - ff_update_link_current_pts(link, pts); - return ret; -} - -static int ff_filter_frame_needs_framing(AVFilterLink *link, AVFrame *frame) -{ - int insamples = frame->nb_samples, inpos = 0, nb_samples; - AVFrame *pbuf = link->partial_buf; - int nb_channels = av_frame_get_channels(frame); - int ret = 0; - - link->flags |= FF_LINK_FLAG_REQUEST_LOOP; - /* Handle framing (min_samples, max_samples) */ - while (insamples) { - if (!pbuf) { - AVRational samples_tb = { 1, link->sample_rate }; - pbuf = ff_get_audio_buffer(link, link->partial_buf_size); - if (!pbuf) { - av_log(link->dst, AV_LOG_WARNING, - "Samples dropped due to memory allocation failure.\n"); - return 0; - } - av_frame_copy_props(pbuf, frame); - pbuf->pts = frame->pts; - if (pbuf->pts != AV_NOPTS_VALUE) - pbuf->pts += av_rescale_q(inpos, samples_tb, link->time_base); - pbuf->nb_samples = 0; - } - nb_samples = FFMIN(insamples, - link->partial_buf_size - pbuf->nb_samples); - av_samples_copy(pbuf->extended_data, frame->extended_data, - pbuf->nb_samples, inpos, - nb_samples, nb_channels, link->format); - inpos += nb_samples; - insamples -= nb_samples; - pbuf->nb_samples += nb_samples; - if (pbuf->nb_samples >= link->min_samples) { - ret = ff_filter_frame_framed(link, pbuf); - pbuf = NULL; - } - } - av_frame_free(&frame); - link->partial_buf = pbuf; - return ret; -} - -int ff_filter_frame(AVFilterLink *link, AVFrame *frame) -{ - FF_TPRINTF_START(NULL, filter_frame); ff_tlog_link(NULL, link, 1); ff_tlog(NULL, " "); ff_tlog_ref(NULL, frame, 1); - - /* Consistency checks */ - if (link->type == AVMEDIA_TYPE_VIDEO) { - if (strcmp(link->dst->filter->name, "scale")) { - av_assert1(frame->format == link->format); - av_assert1(frame->width == link->w); - av_assert1(frame->height == link->h); - } - } else { - av_assert1(frame->format == link->format); - av_assert1(av_frame_get_channels(frame) == link->channels); - av_assert1(frame->channel_layout == link->channel_layout); - av_assert1(frame->sample_rate == link->sample_rate); - } - - /* Go directly to actual filtering if possible */ - if (link->type == AVMEDIA_TYPE_AUDIO && - link->min_samples && - (link->partial_buf || - frame->nb_samples < link->min_samples || - frame->nb_samples > link->max_samples)) { - return ff_filter_frame_needs_framing(link, frame); - } else { - return ff_filter_frame_framed(link, frame); - } -} - -const AVClass *avfilter_get_class(void) -{ - return &avfilter_class; -} diff --git a/ffmpeg/libavfilter/avfilter.h b/ffmpeg/libavfilter/avfilter.h deleted file mode 100644 index 3518ad8..0000000 --- a/ffmpeg/libavfilter/avfilter.h +++ /dev/null @@ -1,1523 +0,0 @@ -/* - * filter layer - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVFILTER_H -#define AVFILTER_AVFILTER_H - -/** - * @file - * @ingroup lavfi - * Main libavfilter public API header - */ - -/** - * @defgroup lavfi Libavfilter - graph-based frame editing library - * @{ - */ - -#include <stddef.h> - -#include "libavutil/attributes.h" -#include "libavutil/avutil.h" -#include "libavutil/dict.h" -#include "libavutil/frame.h" -#include "libavutil/log.h" -#include "libavutil/samplefmt.h" -#include "libavutil/pixfmt.h" -#include "libavutil/rational.h" - -#include "libavfilter/version.h" - -/** - * Return the LIBAVFILTER_VERSION_INT constant. - */ -unsigned avfilter_version(void); - -/** - * Return the libavfilter build-time configuration. - */ -const char *avfilter_configuration(void); - -/** - * Return the libavfilter license. - */ -const char *avfilter_license(void); - -typedef struct AVFilterContext AVFilterContext; -typedef struct AVFilterLink AVFilterLink; -typedef struct AVFilterPad AVFilterPad; -typedef struct AVFilterFormats AVFilterFormats; - -#if FF_API_AVFILTERBUFFER -/** - * A reference-counted buffer data type used by the filter system. Filters - * should not store pointers to this structure directly, but instead use the - * AVFilterBufferRef structure below. - */ -typedef struct AVFilterBuffer { - uint8_t *data[8]; ///< buffer data for each plane/channel - - /** - * pointers to the data planes/channels. - * - * For video, this should simply point to data[]. - * - * For planar audio, each channel has a separate data pointer, and - * linesize[0] contains the size of each channel buffer. - * For packed audio, there is just one data pointer, and linesize[0] - * contains the total size of the buffer for all channels. - * - * Note: Both data and extended_data will always be set, but for planar - * audio with more channels that can fit in data, extended_data must be used - * in order to access all channels. - */ - uint8_t **extended_data; - int linesize[8]; ///< number of bytes per line - - /** private data to be used by a custom free function */ - void *priv; - /** - * A pointer to the function to deallocate this buffer if the default - * function is not sufficient. This could, for example, add the memory - * back into a memory pool to be reused later without the overhead of - * reallocating it from scratch. - */ - void (*free)(struct AVFilterBuffer *buf); - - int format; ///< media format - int w, h; ///< width and height of the allocated buffer - unsigned refcount; ///< number of references to this buffer -} AVFilterBuffer; - -#define AV_PERM_READ 0x01 ///< can read from the buffer -#define AV_PERM_WRITE 0x02 ///< can write to the buffer -#define AV_PERM_PRESERVE 0x04 ///< nobody else can overwrite the buffer -#define AV_PERM_REUSE 0x08 ///< can output the buffer multiple times, with the same contents each time -#define AV_PERM_REUSE2 0x10 ///< can output the buffer multiple times, modified each time -#define AV_PERM_NEG_LINESIZES 0x20 ///< the buffer requested can have negative linesizes -#define AV_PERM_ALIGN 0x40 ///< the buffer must be aligned - -#define AVFILTER_ALIGN 16 //not part of ABI - -/** - * Audio specific properties in a reference to an AVFilterBuffer. Since - * AVFilterBufferRef is common to different media formats, audio specific - * per reference properties must be separated out. - */ -typedef struct AVFilterBufferRefAudioProps { - uint64_t channel_layout; ///< channel layout of audio buffer - int nb_samples; ///< number of audio samples per channel - int sample_rate; ///< audio buffer sample rate - int channels; ///< number of channels (do not access directly) -} AVFilterBufferRefAudioProps; - -/** - * Video specific properties in a reference to an AVFilterBuffer. Since - * AVFilterBufferRef is common to different media formats, video specific - * per reference properties must be separated out. - */ -typedef struct AVFilterBufferRefVideoProps { - int w; ///< image width - int h; ///< image height - AVRational sample_aspect_ratio; ///< sample aspect ratio - int interlaced; ///< is frame interlaced - int top_field_first; ///< field order - enum AVPictureType pict_type; ///< picture type of the frame - int key_frame; ///< 1 -> keyframe, 0-> not - int qp_table_linesize; ///< qp_table stride - int qp_table_size; ///< qp_table size - int8_t *qp_table; ///< array of Quantization Parameters -} AVFilterBufferRefVideoProps; - -/** - * A reference to an AVFilterBuffer. Since filters can manipulate the origin of - * a buffer to, for example, crop image without any memcpy, the buffer origin - * and dimensions are per-reference properties. Linesize is also useful for - * image flipping, frame to field filters, etc, and so is also per-reference. - * - * TODO: add anything necessary for frame reordering - */ -typedef struct AVFilterBufferRef { - AVFilterBuffer *buf; ///< the buffer that this is a reference to - uint8_t *data[8]; ///< picture/audio data for each plane - /** - * pointers to the data planes/channels. - * - * For video, this should simply point to data[]. - * - * For planar audio, each channel has a separate data pointer, and - * linesize[0] contains the size of each channel buffer. - * For packed audio, there is just one data pointer, and linesize[0] - * contains the total size of the buffer for all channels. - * - * Note: Both data and extended_data will always be set, but for planar - * audio with more channels that can fit in data, extended_data must be used - * in order to access all channels. - */ - uint8_t **extended_data; - int linesize[8]; ///< number of bytes per line - - AVFilterBufferRefVideoProps *video; ///< video buffer specific properties - AVFilterBufferRefAudioProps *audio; ///< audio buffer specific properties - - /** - * presentation timestamp. The time unit may change during - * filtering, as it is specified in the link and the filter code - * may need to rescale the PTS accordingly. - */ - int64_t pts; - int64_t pos; ///< byte position in stream, -1 if unknown - - int format; ///< media format - - int perms; ///< permissions, see the AV_PERM_* flags - - enum AVMediaType type; ///< media type of buffer data - - AVDictionary *metadata; ///< dictionary containing metadata key=value tags -} AVFilterBufferRef; - -/** - * Copy properties of src to dst, without copying the actual data - */ -attribute_deprecated -void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src); - -/** - * Add a new reference to a buffer. - * - * @param ref an existing reference to the buffer - * @param pmask a bitmask containing the allowable permissions in the new - * reference - * @return a new reference to the buffer with the same properties as the - * old, excluding any permissions denied by pmask - */ -attribute_deprecated -AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask); - -/** - * Remove a reference to a buffer. If this is the last reference to the - * buffer, the buffer itself is also automatically freed. - * - * @param ref reference to the buffer, may be NULL - * - * @note it is recommended to use avfilter_unref_bufferp() instead of this - * function - */ -attribute_deprecated -void avfilter_unref_buffer(AVFilterBufferRef *ref); - -/** - * Remove a reference to a buffer and set the pointer to NULL. - * If this is the last reference to the buffer, the buffer itself - * is also automatically freed. - * - * @param ref pointer to the buffer reference - */ -attribute_deprecated -void avfilter_unref_bufferp(AVFilterBufferRef **ref); -#endif - -/** - * Get the number of channels of a buffer reference. - */ -attribute_deprecated -int avfilter_ref_get_channels(AVFilterBufferRef *ref); - -#if FF_API_AVFILTERPAD_PUBLIC -/** - * A filter pad used for either input or output. - * - * See doc/filter_design.txt for details on how to implement the methods. - * - * @warning this struct might be removed from public API. - * users should call avfilter_pad_get_name() and avfilter_pad_get_type() - * to access the name and type fields; there should be no need to access - * any other fields from outside of libavfilter. - */ -struct AVFilterPad { - /** - * Pad name. The name is unique among inputs and among outputs, but an - * input may have the same name as an output. This may be NULL if this - * pad has no need to ever be referenced by name. - */ - const char *name; - - /** - * AVFilterPad type. - */ - enum AVMediaType type; - - /** - * Input pads: - * Minimum required permissions on incoming buffers. Any buffer with - * insufficient permissions will be automatically copied by the filter - * system to a new buffer which provides the needed access permissions. - * - * Output pads: - * Guaranteed permissions on outgoing buffers. Any buffer pushed on the - * link must have at least these permissions; this fact is checked by - * asserts. It can be used to optimize buffer allocation. - */ - attribute_deprecated int min_perms; - - /** - * Input pads: - * Permissions which are not accepted on incoming buffers. Any buffer - * which has any of these permissions set will be automatically copied - * by the filter system to a new buffer which does not have those - * permissions. This can be used to easily disallow buffers with - * AV_PERM_REUSE. - * - * Output pads: - * Permissions which are automatically removed on outgoing buffers. It - * can be used to optimize buffer allocation. - */ - attribute_deprecated int rej_perms; - - /** - * @deprecated unused - */ - int (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); - - /** - * Callback function to get a video buffer. If NULL, the filter system will - * use ff_default_get_video_buffer(). - * - * Input video pads only. - */ - AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h); - - /** - * Callback function to get an audio buffer. If NULL, the filter system will - * use ff_default_get_audio_buffer(). - * - * Input audio pads only. - */ - AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples); - - /** - * @deprecated unused - */ - int (*end_frame)(AVFilterLink *link); - - /** - * @deprecated unused - */ - int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); - - /** - * Filtering callback. This is where a filter receives a frame with - * audio/video data and should do its processing. - * - * Input pads only. - * - * @return >= 0 on success, a negative AVERROR on error. This function - * must ensure that frame is properly unreferenced on error if it - * hasn't been passed on to another filter. - */ - int (*filter_frame)(AVFilterLink *link, AVFrame *frame); - - /** - * Frame poll callback. This returns the number of immediately available - * samples. It should return a positive value if the next request_frame() - * is guaranteed to return one frame (with no delay). - * - * Defaults to just calling the source poll_frame() method. - * - * Output pads only. - */ - int (*poll_frame)(AVFilterLink *link); - - /** - * Frame request callback. A call to this should result in at least one - * frame being output over the given link. This should return zero on - * success, and another value on error. - * See ff_request_frame() for the error codes with a specific - * meaning. - * - * Output pads only. - */ - int (*request_frame)(AVFilterLink *link); - - /** - * Link configuration callback. - * - * For output pads, this should set the following link properties: - * video: width, height, sample_aspect_ratio, time_base - * audio: sample_rate. - * - * This should NOT set properties such as format, channel_layout, etc which - * are negotiated between filters by the filter system using the - * query_formats() callback before this function is called. - * - * For input pads, this should check the properties of the link, and update - * the filter's internal state as necessary. - * - * For both input and output pads, this should return zero on success, - * and another value on error. - */ - int (*config_props)(AVFilterLink *link); - - /** - * The filter expects a fifo to be inserted on its input link, - * typically because it has a delay. - * - * input pads only. - */ - int needs_fifo; - - int needs_writable; -}; -#endif - -/** - * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g. - * AVFilter.inputs/outputs). - */ -int avfilter_pad_count(const AVFilterPad *pads); - -/** - * Get the name of an AVFilterPad. - * - * @param pads an array of AVFilterPads - * @param pad_idx index of the pad in the array it; is the caller's - * responsibility to ensure the index is valid - * - * @return name of the pad_idx'th pad in pads - */ -const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx); - -/** - * Get the type of an AVFilterPad. - * - * @param pads an array of AVFilterPads - * @param pad_idx index of the pad in the array; it is the caller's - * responsibility to ensure the index is valid - * - * @return type of the pad_idx'th pad in pads - */ -enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx); - -/** - * The number of the filter inputs is not determined just by AVFilter.inputs. - * The filter might add additional inputs during initialization depending on the - * options supplied to it. - */ -#define AVFILTER_FLAG_DYNAMIC_INPUTS (1 << 0) -/** - * The number of the filter outputs is not determined just by AVFilter.outputs. - * The filter might add additional outputs during initialization depending on - * the options supplied to it. - */ -#define AVFILTER_FLAG_DYNAMIC_OUTPUTS (1 << 1) -/** - * The filter supports multithreading by splitting frames into multiple parts - * and processing them concurrently. - */ -#define AVFILTER_FLAG_SLICE_THREADS (1 << 2) -/** - * Some filters support a generic "enable" expression option that can be used - * to enable or disable a filter in the timeline. Filters supporting this - * option have this flag set. When the enable expression is false, the default - * no-op filter_frame() function is called in place of the filter_frame() - * callback defined on each input pad, thus the frame is passed unchanged to - * the next filters. - */ -#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC (1 << 16) -/** - * Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will - * have its filter_frame() callback(s) called as usual even when the enable - * expression is false. The filter will disable filtering within the - * filter_frame() callback(s) itself, for example executing code depending on - * the AVFilterContext->is_disabled value. - */ -#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL (1 << 17) -/** - * Handy mask to test whether the filter supports or no the timeline feature - * (internally or generically). - */ -#define AVFILTER_FLAG_SUPPORT_TIMELINE (AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL) - -/** - * Filter definition. This defines the pads a filter contains, and all the - * callback functions used to interact with the filter. - */ -typedef struct AVFilter { - /** - * Filter name. Must be non-NULL and unique among filters. - */ - const char *name; - - /** - * A description of the filter. May be NULL. - * - * You should use the NULL_IF_CONFIG_SMALL() macro to define it. - */ - const char *description; - - /** - * List of inputs, terminated by a zeroed element. - * - * NULL if there are no (static) inputs. Instances of filters with - * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in - * this list. - */ - const AVFilterPad *inputs; - /** - * List of outputs, terminated by a zeroed element. - * - * NULL if there are no (static) outputs. Instances of filters with - * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in - * this list. - */ - const AVFilterPad *outputs; - - /** - * A class for the private data, used to declare filter private AVOptions. - * This field is NULL for filters that do not declare any options. - * - * If this field is non-NULL, the first member of the filter private data - * must be a pointer to AVClass, which will be set by libavfilter generic - * code to this class. - */ - const AVClass *priv_class; - - /** - * A combination of AVFILTER_FLAG_* - */ - int flags; - - /***************************************************************** - * All fields below this line are not part of the public API. They - * may not be used outside of libavfilter and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - - /** - * Filter initialization function. - * - * This callback will be called only once during the filter lifetime, after - * all the options have been set, but before links between filters are - * established and format negotiation is done. - * - * Basic filter initialization should be done here. Filters with dynamic - * inputs and/or outputs should create those inputs/outputs here based on - * provided options. No more changes to this filter's inputs/outputs can be - * done after this callback. - * - * This callback must not assume that the filter links exist or frame - * parameters are known. - * - * @ref AVFilter.uninit "uninit" is guaranteed to be called even if - * initialization fails, so this callback does not have to clean up on - * failure. - * - * @return 0 on success, a negative AVERROR on failure - */ - int (*init)(AVFilterContext *ctx); - - /** - * Should be set instead of @ref AVFilter.init "init" by the filters that - * want to pass a dictionary of AVOptions to nested contexts that are - * allocated during init. - * - * On return, the options dict should be freed and replaced with one that - * contains all the options which could not be processed by this filter (or - * with NULL if all the options were processed). - * - * Otherwise the semantics is the same as for @ref AVFilter.init "init". - */ - int (*init_dict)(AVFilterContext *ctx, AVDictionary **options); - - /** - * Filter uninitialization function. - * - * Called only once right before the filter is freed. Should deallocate any - * memory held by the filter, release any buffer references, etc. It does - * not need to deallocate the AVFilterContext.priv memory itself. - * - * This callback may be called even if @ref AVFilter.init "init" was not - * called or failed, so it must be prepared to handle such a situation. - */ - void (*uninit)(AVFilterContext *ctx); - - /** - * Query formats supported by the filter on its inputs and outputs. - * - * This callback is called after the filter is initialized (so the inputs - * and outputs are fixed), shortly before the format negotiation. This - * callback may be called more than once. - * - * This callback must set AVFilterLink.out_formats on every input link and - * AVFilterLink.in_formats on every output link to a list of pixel/sample - * formats that the filter supports on that link. For audio links, this - * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" / - * @ref AVFilterLink.out_samplerates "out_samplerates" and - * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" / - * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously. - * - * This callback may be NULL for filters with one input, in which case - * libavfilter assumes that it supports all input formats and preserves - * them on output. - * - * @return zero on success, a negative value corresponding to an - * AVERROR code otherwise - */ - int (*query_formats)(AVFilterContext *); - - int priv_size; ///< size of private data to allocate for the filter - - /** - * Used by the filter registration system. Must not be touched by any other - * code. - */ - struct AVFilter *next; - - /** - * Make the filter instance process a command. - * - * @param cmd the command to process, for handling simplicity all commands must be alphanumeric only - * @param arg the argument for the command - * @param res a buffer with size res_size where the filter(s) can return a response. This must not change when the command is not supported. - * @param flags if AVFILTER_CMD_FLAG_FAST is set and the command would be - * time consuming then a filter should treat it like an unsupported command - * - * @returns >=0 on success otherwise an error code. - * AVERROR(ENOSYS) on unsupported commands - */ - int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags); - - /** - * Filter initialization function, alternative to the init() - * callback. Args contains the user-supplied parameters, opaque is - * used for providing binary data. - */ - int (*init_opaque)(AVFilterContext *ctx, void *opaque); -} AVFilter; - -/** - * Process multiple parts of the frame concurrently. - */ -#define AVFILTER_THREAD_SLICE (1 << 0) - -typedef struct AVFilterInternal AVFilterInternal; - -/** An instance of a filter */ -struct AVFilterContext { - const AVClass *av_class; ///< needed for av_log() and filters common options - - const AVFilter *filter; ///< the AVFilter of which this is an instance - - char *name; ///< name of this filter instance - - AVFilterPad *input_pads; ///< array of input pads - AVFilterLink **inputs; ///< array of pointers to input links -#if FF_API_FOO_COUNT - attribute_deprecated unsigned input_count; ///< @deprecated use nb_inputs -#endif - unsigned nb_inputs; ///< number of input pads - - AVFilterPad *output_pads; ///< array of output pads - AVFilterLink **outputs; ///< array of pointers to output links -#if FF_API_FOO_COUNT - attribute_deprecated unsigned output_count; ///< @deprecated use nb_outputs -#endif - unsigned nb_outputs; ///< number of output pads - - void *priv; ///< private data for use by the filter - - struct AVFilterGraph *graph; ///< filtergraph this filter belongs to - - /** - * Type of multithreading being allowed/used. A combination of - * AVFILTER_THREAD_* flags. - * - * May be set by the caller before initializing the filter to forbid some - * or all kinds of multithreading for this filter. The default is allowing - * everything. - * - * When the filter is initialized, this field is combined using bit AND with - * AVFilterGraph.thread_type to get the final mask used for determining - * allowed threading types. I.e. a threading type needs to be set in both - * to be allowed. - * - * After the filter is initialzed, libavfilter sets this field to the - * threading type that is actually used (0 for no multithreading). - */ - int thread_type; - - /** - * An opaque struct for libavfilter internal use. - */ - AVFilterInternal *internal; - - struct AVFilterCommand *command_queue; - - char *enable_str; ///< enable expression string - void *enable; ///< parsed expression (AVExpr*) - double *var_values; ///< variable values for the enable expression - int is_disabled; ///< the enabled state from the last expression evaluation -}; - -/** - * A link between two filters. This contains pointers to the source and - * destination filters between which this link exists, and the indexes of - * the pads involved. In addition, this link also contains the parameters - * which have been negotiated and agreed upon between the filter, such as - * image dimensions, format, etc. - */ -struct AVFilterLink { - AVFilterContext *src; ///< source filter - AVFilterPad *srcpad; ///< output pad on the source filter - - AVFilterContext *dst; ///< dest filter - AVFilterPad *dstpad; ///< input pad on the dest filter - - enum AVMediaType type; ///< filter media type - - /* These parameters apply only to video */ - int w; ///< agreed upon image width - int h; ///< agreed upon image height - AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio - /* These parameters apply only to audio */ - uint64_t channel_layout; ///< channel layout of current buffer (see libavutil/channel_layout.h) - int sample_rate; ///< samples per second - - int format; ///< agreed upon media format - - /** - * Define the time base used by the PTS of the frames/samples - * which will pass through this link. - * During the configuration stage, each filter is supposed to - * change only the output timebase, while the timebase of the - * input link is assumed to be an unchangeable property. - */ - AVRational time_base; - - /***************************************************************** - * All fields below this line are not part of the public API. They - * may not be used outside of libavfilter and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - /** - * Lists of formats and channel layouts supported by the input and output - * filters respectively. These lists are used for negotiating the format - * to actually be used, which will be loaded into the format and - * channel_layout members, above, when chosen. - * - */ - AVFilterFormats *in_formats; - AVFilterFormats *out_formats; - - /** - * Lists of channel layouts and sample rates used for automatic - * negotiation. - */ - AVFilterFormats *in_samplerates; - AVFilterFormats *out_samplerates; - struct AVFilterChannelLayouts *in_channel_layouts; - struct AVFilterChannelLayouts *out_channel_layouts; - - /** - * Audio only, the destination filter sets this to a non-zero value to - * request that buffers with the given number of samples should be sent to - * it. AVFilterPad.needs_fifo must also be set on the corresponding input - * pad. - * Last buffer before EOF will be padded with silence. - */ - int request_samples; - - /** stage of the initialization of the link properties (dimensions, etc) */ - enum { - AVLINK_UNINIT = 0, ///< not started - AVLINK_STARTINIT, ///< started, but incomplete - AVLINK_INIT ///< complete - } init_state; - - struct AVFilterPool *pool; - - /** - * Graph the filter belongs to. - */ - struct AVFilterGraph *graph; - - /** - * Current timestamp of the link, as defined by the most recent - * frame(s), in AV_TIME_BASE units. - */ - int64_t current_pts; - - /** - * Index in the age array. - */ - int age_index; - - /** - * Frame rate of the stream on the link, or 1/0 if unknown; - * if left to 0/0, will be automatically be copied from the first input - * of the source filter if it exists. - * - * Sources should set it to the best estimation of the real frame rate. - * Filters should update it if necessary depending on their function. - * Sinks can use it to set a default output frame rate. - * It is similar to the r_frame_rate field in AVStream. - */ - AVRational frame_rate; - - /** - * Buffer partially filled with samples to achieve a fixed/minimum size. - */ - AVFrame *partial_buf; - - /** - * Size of the partial buffer to allocate. - * Must be between min_samples and max_samples. - */ - int partial_buf_size; - - /** - * Minimum number of samples to filter at once. If filter_frame() is - * called with fewer samples, it will accumulate them in partial_buf. - * This field and the related ones must not be changed after filtering - * has started. - * If 0, all related fields are ignored. - */ - int min_samples; - - /** - * Maximum number of samples to filter at once. If filter_frame() is - * called with more samples, it will split them. - */ - int max_samples; - - /** - * The buffer reference currently being received across the link by the - * destination filter. This is used internally by the filter system to - * allow automatic copying of buffers which do not have sufficient - * permissions for the destination. This should not be accessed directly - * by the filters. - */ - AVFilterBufferRef *cur_buf_copy; - - /** - * True if the link is closed. - * If set, all attemps of start_frame, filter_frame or request_frame - * will fail with AVERROR_EOF, and if necessary the reference will be - * destroyed. - * If request_frame returns AVERROR_EOF, this flag is set on the - * corresponding link. - * It can be set also be set by either the source or the destination - * filter. - */ - int closed; - - /** - * Number of channels. - */ - int channels; - - /** - * True if a frame is being requested on the link. - * Used internally by the framework. - */ - unsigned frame_requested; - - /** - * Link processing flags. - */ - unsigned flags; - - /** - * Number of past frames sent through the link. - */ - int64_t frame_count; -}; - -/** - * Link two filters together. - * - * @param src the source filter - * @param srcpad index of the output pad on the source filter - * @param dst the destination filter - * @param dstpad index of the input pad on the destination filter - * @return zero on success - */ -int avfilter_link(AVFilterContext *src, unsigned srcpad, - AVFilterContext *dst, unsigned dstpad); - -/** - * Free the link in *link, and set its pointer to NULL. - */ -void avfilter_link_free(AVFilterLink **link); - -/** - * Get the number of channels of a link. - */ -int avfilter_link_get_channels(AVFilterLink *link); - -/** - * Set the closed field of a link. - */ -void avfilter_link_set_closed(AVFilterLink *link, int closed); - -/** - * Negotiate the media format, dimensions, etc of all inputs to a filter. - * - * @param filter the filter to negotiate the properties for its inputs - * @return zero on successful negotiation - */ -int avfilter_config_links(AVFilterContext *filter); - -#if FF_API_AVFILTERBUFFER -/** - * Create a buffer reference wrapped around an already allocated image - * buffer. - * - * @param data pointers to the planes of the image to reference - * @param linesize linesizes for the planes of the image to reference - * @param perms the required access permissions - * @param w the width of the image specified by the data and linesize arrays - * @param h the height of the image specified by the data and linesize arrays - * @param format the pixel format of the image specified by the data and linesize arrays - */ -attribute_deprecated -AVFilterBufferRef * -avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms, - int w, int h, enum AVPixelFormat format); - -/** - * Create an audio buffer reference wrapped around an already - * allocated samples buffer. - * - * See avfilter_get_audio_buffer_ref_from_arrays_channels() for a version - * that can handle unknown channel layouts. - * - * @param data pointers to the samples plane buffers - * @param linesize linesize for the samples plane buffers - * @param perms the required access permissions - * @param nb_samples number of samples per channel - * @param sample_fmt the format of each sample in the buffer to allocate - * @param channel_layout the channel layout of the buffer - */ -attribute_deprecated -AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data, - int linesize, - int perms, - int nb_samples, - enum AVSampleFormat sample_fmt, - uint64_t channel_layout); -/** - * Create an audio buffer reference wrapped around an already - * allocated samples buffer. - * - * @param data pointers to the samples plane buffers - * @param linesize linesize for the samples plane buffers - * @param perms the required access permissions - * @param nb_samples number of samples per channel - * @param sample_fmt the format of each sample in the buffer to allocate - * @param channels the number of channels of the buffer - * @param channel_layout the channel layout of the buffer, - * must be either 0 or consistent with channels - */ -attribute_deprecated -AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays_channels(uint8_t **data, - int linesize, - int perms, - int nb_samples, - enum AVSampleFormat sample_fmt, - int channels, - uint64_t channel_layout); - -#endif - - -#define AVFILTER_CMD_FLAG_ONE 1 ///< Stop once a filter understood the command (for target=all for example), fast filters are favored automatically -#define AVFILTER_CMD_FLAG_FAST 2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw) - -/** - * Make the filter instance process a command. - * It is recommended to use avfilter_graph_send_command(). - */ -int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags); - -/** Initialize the filter system. Register all builtin filters. */ -void avfilter_register_all(void); - -#if FF_API_OLD_FILTER_REGISTER -/** Uninitialize the filter system. Unregister all filters. */ -attribute_deprecated -void avfilter_uninit(void); -#endif - -/** - * Register a filter. This is only needed if you plan to use - * avfilter_get_by_name later to lookup the AVFilter structure by name. A - * filter can still by instantiated with avfilter_graph_alloc_filter even if it - * is not registered. - * - * @param filter the filter to register - * @return 0 if the registration was successful, a negative value - * otherwise - */ -int avfilter_register(AVFilter *filter); - -/** - * Get a filter definition matching the given name. - * - * @param name the filter name to find - * @return the filter definition, if any matching one is registered. - * NULL if none found. - */ -#if !FF_API_NOCONST_GET_NAME -const -#endif -AVFilter *avfilter_get_by_name(const char *name); - -/** - * Iterate over all registered filters. - * @return If prev is non-NULL, next registered filter after prev or NULL if - * prev is the last filter. If prev is NULL, return the first registered filter. - */ -const AVFilter *avfilter_next(const AVFilter *prev); - -#if FF_API_OLD_FILTER_REGISTER -/** - * If filter is NULL, returns a pointer to the first registered filter pointer, - * if filter is non-NULL, returns the next pointer after filter. - * If the returned pointer points to NULL, the last registered filter - * was already reached. - * @deprecated use avfilter_next() - */ -attribute_deprecated -AVFilter **av_filter_next(AVFilter **filter); -#endif - -#if FF_API_AVFILTER_OPEN -/** - * Create a filter instance. - * - * @param filter_ctx put here a pointer to the created filter context - * on success, NULL on failure - * @param filter the filter to create an instance of - * @param inst_name Name to give to the new instance. Can be NULL for none. - * @return >= 0 in case of success, a negative error code otherwise - * @deprecated use avfilter_graph_alloc_filter() instead - */ -attribute_deprecated -int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name); -#endif - - -#if FF_API_AVFILTER_INIT_FILTER -/** - * Initialize a filter. - * - * @param filter the filter to initialize - * @param args A string of parameters to use when initializing the filter. - * The format and meaning of this string varies by filter. - * @param opaque Any extra non-string data needed by the filter. The meaning - * of this parameter varies by filter. - * @return zero on success - */ -attribute_deprecated -int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque); -#endif - -/** - * Initialize a filter with the supplied parameters. - * - * @param ctx uninitialized filter context to initialize - * @param args Options to initialize the filter with. This must be a - * ':'-separated list of options in the 'key=value' form. - * May be NULL if the options have been set directly using the - * AVOptions API or there are no options that need to be set. - * @return 0 on success, a negative AVERROR on failure - */ -int avfilter_init_str(AVFilterContext *ctx, const char *args); - -/** - * Initialize a filter with the supplied dictionary of options. - * - * @param ctx uninitialized filter context to initialize - * @param options An AVDictionary filled with options for this filter. On - * return this parameter will be destroyed and replaced with - * a dict containing options that were not found. This dictionary - * must be freed by the caller. - * May be NULL, then this function is equivalent to - * avfilter_init_str() with the second parameter set to NULL. - * @return 0 on success, a negative AVERROR on failure - * - * @note This function and avfilter_init_str() do essentially the same thing, - * the difference is in manner in which the options are passed. It is up to the - * calling code to choose whichever is more preferable. The two functions also - * behave differently when some of the provided options are not declared as - * supported by the filter. In such a case, avfilter_init_str() will fail, but - * this function will leave those extra options in the options AVDictionary and - * continue as usual. - */ -int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options); - -/** - * Free a filter context. This will also remove the filter from its - * filtergraph's list of filters. - * - * @param filter the filter to free - */ -void avfilter_free(AVFilterContext *filter); - -/** - * Insert a filter in the middle of an existing link. - * - * @param link the link into which the filter should be inserted - * @param filt the filter to be inserted - * @param filt_srcpad_idx the input pad on the filter to connect - * @param filt_dstpad_idx the output pad on the filter to connect - * @return zero on success - */ -int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, - unsigned filt_srcpad_idx, unsigned filt_dstpad_idx); - -#if FF_API_AVFILTERBUFFER -/** - * Copy the frame properties of src to dst, without copying the actual - * image data. - * - * @return 0 on success, a negative number on error. - */ -attribute_deprecated -int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src); - -/** - * Copy the frame properties and data pointers of src to dst, without copying - * the actual data. - * - * @return 0 on success, a negative number on error. - */ -attribute_deprecated -int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src); -#endif - -/** - * @return AVClass for AVFilterContext. - * - * @see av_opt_find(). - */ -const AVClass *avfilter_get_class(void); - -typedef struct AVFilterGraphInternal AVFilterGraphInternal; - -/** - * A function pointer passed to the @ref AVFilterGraph.execute callback to be - * executed multiple times, possibly in parallel. - * - * @param ctx the filter context the job belongs to - * @param arg an opaque parameter passed through from @ref - * AVFilterGraph.execute - * @param jobnr the index of the job being executed - * @param nb_jobs the total number of jobs - * - * @return 0 on success, a negative AVERROR on error - */ -typedef int (avfilter_action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); - -/** - * A function executing multiple jobs, possibly in parallel. - * - * @param ctx the filter context to which the jobs belong - * @param func the function to be called multiple times - * @param arg the argument to be passed to func - * @param ret a nb_jobs-sized array to be filled with return values from each - * invocation of func - * @param nb_jobs the number of jobs to execute - * - * @return 0 on success, a negative AVERROR on error - */ -typedef int (avfilter_execute_func)(AVFilterContext *ctx, avfilter_action_func *func, - void *arg, int *ret, int nb_jobs); - -typedef struct AVFilterGraph { - const AVClass *av_class; -#if FF_API_FOO_COUNT - attribute_deprecated - unsigned filter_count_unused; -#endif - AVFilterContext **filters; -#if !FF_API_FOO_COUNT - unsigned nb_filters; -#endif - - char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters - char *resample_lavr_opts; ///< libavresample options to use for the auto-inserted resample filters -#if FF_API_FOO_COUNT - unsigned nb_filters; -#endif - - /** - * Type of multithreading allowed for filters in this graph. A combination - * of AVFILTER_THREAD_* flags. - * - * May be set by the caller at any point, the setting will apply to all - * filters initialized after that. The default is allowing everything. - * - * When a filter in this graph is initialized, this field is combined using - * bit AND with AVFilterContext.thread_type to get the final mask used for - * determining allowed threading types. I.e. a threading type needs to be - * set in both to be allowed. - */ - int thread_type; - - /** - * Maximum number of threads used by filters in this graph. May be set by - * the caller before adding any filters to the filtergraph. Zero (the - * default) means that the number of threads is determined automatically. - */ - int nb_threads; - - /** - * Opaque object for libavfilter internal use. - */ - AVFilterGraphInternal *internal; - - /** - * Opaque user data. May be set by the caller to an arbitrary value, e.g. to - * be used from callbacks like @ref AVFilterGraph.execute. - * Libavfilter will not touch this field in any way. - */ - void *opaque; - - /** - * This callback may be set by the caller immediately after allocating the - * graph and before adding any filters to it, to provide a custom - * multithreading implementation. - * - * If set, filters with slice threading capability will call this callback - * to execute multiple jobs in parallel. - * - * If this field is left unset, libavfilter will use its internal - * implementation, which may or may not be multithreaded depending on the - * platform and build options. - */ - avfilter_execute_func *execute; - - char *aresample_swr_opts; ///< swr options to use for the auto-inserted aresample filters, Access ONLY through AVOptions - - /** - * Private fields - * - * The following fields are for internal use only. - * Their type, offset, number and semantic can change without notice. - */ - - AVFilterLink **sink_links; - int sink_links_count; - - unsigned disable_auto_convert; -} AVFilterGraph; - -/** - * Allocate a filter graph. - */ -AVFilterGraph *avfilter_graph_alloc(void); - -/** - * Create a new filter instance in a filter graph. - * - * @param graph graph in which the new filter will be used - * @param filter the filter to create an instance of - * @param name Name to give to the new instance (will be copied to - * AVFilterContext.name). This may be used by the caller to identify - * different filters, libavfilter itself assigns no semantics to - * this parameter. May be NULL. - * - * @return the context of the newly created filter instance (note that it is - * also retrievable directly through AVFilterGraph.filters or with - * avfilter_graph_get_filter()) on success or NULL or failure. - */ -AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, - const AVFilter *filter, - const char *name); - -/** - * Get a filter instance with name name from graph. - * - * @return the pointer to the found filter instance or NULL if it - * cannot be found. - */ -AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name); - -#if FF_API_AVFILTER_OPEN -/** - * Add an existing filter instance to a filter graph. - * - * @param graphctx the filter graph - * @param filter the filter to be added - * - * @deprecated use avfilter_graph_alloc_filter() to allocate a filter in a - * filter graph - */ -attribute_deprecated -int avfilter_graph_add_filter(AVFilterGraph *graphctx, AVFilterContext *filter); -#endif - -/** - * Create and add a filter instance into an existing graph. - * The filter instance is created from the filter filt and inited - * with the parameters args and opaque. - * - * In case of success put in *filt_ctx the pointer to the created - * filter instance, otherwise set *filt_ctx to NULL. - * - * @param name the instance name to give to the created filter instance - * @param graph_ctx the filter graph - * @return a negative AVERROR error code in case of failure, a non - * negative value otherwise - */ -int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, - const char *name, const char *args, void *opaque, - AVFilterGraph *graph_ctx); - -/** - * Enable or disable automatic format conversion inside the graph. - * - * Note that format conversion can still happen inside explicitly inserted - * scale and aresample filters. - * - * @param flags any of the AVFILTER_AUTO_CONVERT_* constants - */ -void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags); - -enum { - AVFILTER_AUTO_CONVERT_ALL = 0, /**< all automatic conversions enabled */ - AVFILTER_AUTO_CONVERT_NONE = -1, /**< all automatic conversions disabled */ -}; - -/** - * Check validity and configure all the links and formats in the graph. - * - * @param graphctx the filter graph - * @param log_ctx context used for logging - * @return >= 0 in case of success, a negative AVERROR code otherwise - */ -int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx); - -/** - * Free a graph, destroy its links, and set *graph to NULL. - * If *graph is NULL, do nothing. - */ -void avfilter_graph_free(AVFilterGraph **graph); - -/** - * A linked-list of the inputs/outputs of the filter chain. - * - * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(), - * where it is used to communicate open (unlinked) inputs and outputs from and - * to the caller. - * This struct specifies, per each not connected pad contained in the graph, the - * filter context and the pad index required for establishing a link. - */ -typedef struct AVFilterInOut { - /** unique name for this input/output in the list */ - char *name; - - /** filter context associated to this input/output */ - AVFilterContext *filter_ctx; - - /** index of the filt_ctx pad to use for linking */ - int pad_idx; - - /** next input/input in the list, NULL if this is the last */ - struct AVFilterInOut *next; -} AVFilterInOut; - -/** - * Allocate a single AVFilterInOut entry. - * Must be freed with avfilter_inout_free(). - * @return allocated AVFilterInOut on success, NULL on failure. - */ -AVFilterInOut *avfilter_inout_alloc(void); - -/** - * Free the supplied list of AVFilterInOut and set *inout to NULL. - * If *inout is NULL, do nothing. - */ -void avfilter_inout_free(AVFilterInOut **inout); - -#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI || !FF_API_OLD_GRAPH_PARSE -/** - * Add a graph described by a string to a graph. - * - * @note The caller must provide the lists of inputs and outputs, - * which therefore must be known before calling the function. - * - * @note The inputs parameter describes inputs of the already existing - * part of the graph; i.e. from the point of view of the newly created - * part, they are outputs. Similarly the outputs parameter describes - * outputs of the already existing filters, which are provided as - * inputs to the parsed filters. - * - * @param graph the filter graph where to link the parsed grap context - * @param filters string to be parsed - * @param inputs linked list to the inputs of the graph - * @param outputs linked list to the outputs of the graph - * @return zero on success, a negative AVERROR code on error - */ -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut *inputs, AVFilterInOut *outputs, - void *log_ctx); -#else -/** - * Add a graph described by a string to a graph. - * - * @param graph the filter graph where to link the parsed graph context - * @param filters string to be parsed - * @param inputs pointer to a linked list to the inputs of the graph, may be NULL. - * If non-NULL, *inputs is updated to contain the list of open inputs - * after the parsing, should be freed with avfilter_inout_free(). - * @param outputs pointer to a linked list to the outputs of the graph, may be NULL. - * If non-NULL, *outputs is updated to contain the list of open outputs - * after the parsing, should be freed with avfilter_inout_free(). - * @return non negative on success, a negative AVERROR code on error - * @deprecated Use avfilter_graph_parse_ptr() instead. - */ -attribute_deprecated -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut **inputs, AVFilterInOut **outputs, - void *log_ctx); -#endif - -/** - * Add a graph described by a string to a graph. - * - * @param graph the filter graph where to link the parsed graph context - * @param filters string to be parsed - * @param inputs pointer to a linked list to the inputs of the graph, may be NULL. - * If non-NULL, *inputs is updated to contain the list of open inputs - * after the parsing, should be freed with avfilter_inout_free(). - * @param outputs pointer to a linked list to the outputs of the graph, may be NULL. - * If non-NULL, *outputs is updated to contain the list of open outputs - * after the parsing, should be freed with avfilter_inout_free(). - * @return non negative on success, a negative AVERROR code on error - */ -int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, - AVFilterInOut **inputs, AVFilterInOut **outputs, - void *log_ctx); - -/** - * Add a graph described by a string to a graph. - * - * @param[in] graph the filter graph where to link the parsed graph context - * @param[in] filters string to be parsed - * @param[out] inputs a linked list of all free (unlinked) inputs of the - * parsed graph will be returned here. It is to be freed - * by the caller using avfilter_inout_free(). - * @param[out] outputs a linked list of all free (unlinked) outputs of the - * parsed graph will be returned here. It is to be freed by the - * caller using avfilter_inout_free(). - * @return zero on success, a negative AVERROR code on error - * - * @note This function returns the inputs and outputs that are left - * unlinked after parsing the graph and the caller then deals with - * them. - * @note This function makes no reference whatsoever to already - * existing parts of the graph and the inputs parameter will on return - * contain inputs of the newly parsed part of the graph. Analogously - * the outputs parameter will contain outputs of the newly created - * filters. - */ -int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, - AVFilterInOut **inputs, - AVFilterInOut **outputs); - -/** - * Send a command to one or more filter instances. - * - * @param graph the filter graph - * @param target the filter(s) to which the command should be sent - * "all" sends to all filters - * otherwise it can be a filter or filter instance name - * which will send the command to all matching filters. - * @param cmd the command to send, for handling simplicity all commands must be alphanumeric only - * @param arg the argument for the command - * @param res a buffer with size res_size where the filter(s) can return a response. - * - * @returns >=0 on success otherwise an error code. - * AVERROR(ENOSYS) on unsupported commands - */ -int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags); - -/** - * Queue a command for one or more filter instances. - * - * @param graph the filter graph - * @param target the filter(s) to which the command should be sent - * "all" sends to all filters - * otherwise it can be a filter or filter instance name - * which will send the command to all matching filters. - * @param cmd the command to sent, for handling simplicity all commands must be alphanummeric only - * @param arg the argument for the command - * @param ts time at which the command should be sent to the filter - * - * @note As this executes commands after this function returns, no return code - * from the filter is provided, also AVFILTER_CMD_FLAG_ONE is not supported. - */ -int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts); - - -/** - * Dump a graph into a human-readable string representation. - * - * @param graph the graph to dump - * @param options formatting options; currently ignored - * @return a string, or NULL in case of memory allocation failure; - * the string must be freed using av_free - */ -char *avfilter_graph_dump(AVFilterGraph *graph, const char *options); - -/** - * Request a frame on the oldest sink link. - * - * If the request returns AVERROR_EOF, try the next. - * - * Note that this function is not meant to be the sole scheduling mechanism - * of a filtergraph, only a convenience function to help drain a filtergraph - * in a balanced way under normal circumstances. - * - * Also note that AVERROR_EOF does not mean that frames did not arrive on - * some of the sinks during the process. - * When there are multiple sink links, in case the requested link - * returns an EOF, this may cause a filter to flush pending frames - * which are sent to another sink link, although unrequested. - * - * @return the return value of ff_request_frame(), - * or AVERROR_EOF if all links returned AVERROR_EOF - */ -int avfilter_graph_request_oldest(AVFilterGraph *graph); - -/** - * @} - */ - -#endif /* AVFILTER_AVFILTER_H */ diff --git a/ffmpeg/libavfilter/avfiltergraph.c b/ffmpeg/libavfilter/avfiltergraph.c deleted file mode 100644 index 1fb83c4..0000000 --- a/ffmpeg/libavfilter/avfiltergraph.c +++ /dev/null @@ -1,1326 +0,0 @@ -/* - * filter graphs - * Copyright (c) 2008 Vitor Sessak - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" - -#include <string.h> - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/channel_layout.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2() - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "thread.h" - -#define OFFSET(x) offsetof(AVFilterGraph, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption filtergraph_options[] = { - { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, - { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" }, - { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" }, - { "threads", "Maximum number of threads", OFFSET(nb_threads), - AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, - {"scale_sws_opts" , "default scale filter options" , OFFSET(scale_sws_opts) , - AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - {"aresample_swr_opts" , "default aresample filter options" , OFFSET(aresample_swr_opts) , - AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { NULL }, -}; - -static const AVClass filtergraph_class = { - .class_name = "AVFilterGraph", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, - .option = filtergraph_options, - .category = AV_CLASS_CATEGORY_FILTER, -}; - -#if !HAVE_THREADS -void ff_graph_thread_free(AVFilterGraph *graph) -{ -} - -int ff_graph_thread_init(AVFilterGraph *graph) -{ - graph->thread_type = 0; - graph->nb_threads = 1; - return 0; -} -#endif - -AVFilterGraph *avfilter_graph_alloc(void) -{ - AVFilterGraph *ret = av_mallocz(sizeof(*ret)); - if (!ret) - return NULL; - - ret->internal = av_mallocz(sizeof(*ret->internal)); - if (!ret->internal) { - av_freep(&ret); - return NULL; - } - - ret->av_class = &filtergraph_class; - av_opt_set_defaults(ret); - - return ret; -} - -void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter) -{ - int i; - for (i = 0; i < graph->nb_filters; i++) { - if (graph->filters[i] == filter) { - FFSWAP(AVFilterContext*, graph->filters[i], - graph->filters[graph->nb_filters - 1]); - graph->nb_filters--; - return; - } - } -} - -void avfilter_graph_free(AVFilterGraph **graph) -{ - if (!*graph) - return; - - while ((*graph)->nb_filters) - avfilter_free((*graph)->filters[0]); - - ff_graph_thread_free(*graph); - - av_freep(&(*graph)->sink_links); - - av_freep(&(*graph)->scale_sws_opts); - av_freep(&(*graph)->aresample_swr_opts); - av_freep(&(*graph)->resample_lavr_opts); - av_freep(&(*graph)->filters); - av_freep(&(*graph)->internal); - av_freep(graph); -} - -#if FF_API_AVFILTER_OPEN -int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter) -{ - AVFilterContext **filters = av_realloc(graph->filters, - sizeof(*filters) * (graph->nb_filters + 1)); - if (!filters) - return AVERROR(ENOMEM); - - graph->filters = filters; - graph->filters[graph->nb_filters++] = filter; - -#if FF_API_FOO_COUNT -FF_DISABLE_DEPRECATION_WARNINGS - graph->filter_count_unused = graph->nb_filters; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - filter->graph = graph; - - return 0; -} -#endif - -int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt, - const char *name, const char *args, void *opaque, - AVFilterGraph *graph_ctx) -{ - int ret; - - *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name); - if (!*filt_ctx) - return AVERROR(ENOMEM); - - ret = avfilter_init_str(*filt_ctx, args); - if (ret < 0) - goto fail; - - return 0; - -fail: - if (*filt_ctx) - avfilter_free(*filt_ctx); - *filt_ctx = NULL; - return ret; -} - -void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags) -{ - graph->disable_auto_convert = flags; -} - -AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph, - const AVFilter *filter, - const char *name) -{ - AVFilterContext **filters, *s; - - if (graph->thread_type && !graph->internal->thread_execute) { - if (graph->execute) { - graph->internal->thread_execute = graph->execute; - } else { - int ret = ff_graph_thread_init(graph); - if (ret < 0) { - av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n"); - return NULL; - } - } - } - - s = ff_filter_alloc(filter, name); - if (!s) - return NULL; - - filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1)); - if (!filters) { - avfilter_free(s); - return NULL; - } - - graph->filters = filters; - graph->filters[graph->nb_filters++] = s; - -#if FF_API_FOO_COUNT -FF_DISABLE_DEPRECATION_WARNINGS - graph->filter_count_unused = graph->nb_filters; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - - s->graph = graph; - - return s; -} - -/** - * Check for the validity of graph. - * - * A graph is considered valid if all its input and output pads are - * connected. - * - * @return >= 0 in case of success, a negative value otherwise - */ -static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *filt; - int i, j; - - for (i = 0; i < graph->nb_filters; i++) { - const AVFilterPad *pad; - filt = graph->filters[i]; - - for (j = 0; j < filt->nb_inputs; j++) { - if (!filt->inputs[j] || !filt->inputs[j]->src) { - pad = &filt->input_pads[j]; - av_log(log_ctx, AV_LOG_ERROR, - "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n", - pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name); - return AVERROR(EINVAL); - } - } - - for (j = 0; j < filt->nb_outputs; j++) { - if (!filt->outputs[j] || !filt->outputs[j]->dst) { - pad = &filt->output_pads[j]; - av_log(log_ctx, AV_LOG_ERROR, - "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n", - pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name); - return AVERROR(EINVAL); - } - } - } - - return 0; -} - -/** - * Configure all the links of graphctx. - * - * @return >= 0 in case of success, a negative value otherwise - */ -static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *filt; - int i, ret; - - for (i = 0; i < graph->nb_filters; i++) { - filt = graph->filters[i]; - - if (!filt->nb_outputs) { - if ((ret = avfilter_config_links(filt))) - return ret; - } - } - - return 0; -} - -AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) -{ - int i; - - for (i = 0; i < graph->nb_filters; i++) - if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name)) - return graph->filters[i]; - - return NULL; -} - -static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l) -{ - if (!l) - return; - if (l->nb_channel_layouts) { - if (l->all_layouts || l->all_counts) - av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n"); - l->all_layouts = l->all_counts = 0; - } else { - if (l->all_counts && !l->all_layouts) - av_log(log, AV_LOG_WARNING, "All counts without all layouts\n"); - l->all_layouts = 1; - } -} - -static int filter_query_formats(AVFilterContext *ctx) -{ - int ret, i; - AVFilterFormats *formats; - AVFilterChannelLayouts *chlayouts; - AVFilterFormats *samplerates; - enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : - ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : - AVMEDIA_TYPE_VIDEO; - - if ((ret = ctx->filter->query_formats(ctx)) < 0) { - if (ret != AVERROR(EAGAIN)) - av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n", - ctx->name, av_err2str(ret)); - return ret; - } - - for (i = 0; i < ctx->nb_inputs; i++) - sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts); - for (i = 0; i < ctx->nb_outputs; i++) - sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts); - - formats = ff_all_formats(type); - if (!formats) - return AVERROR(ENOMEM); - ff_set_common_formats(ctx, formats); - if (type == AVMEDIA_TYPE_AUDIO) { - samplerates = ff_all_samplerates(); - if (!samplerates) - return AVERROR(ENOMEM); - ff_set_common_samplerates(ctx, samplerates); - chlayouts = ff_all_channel_layouts(); - if (!chlayouts) - return AVERROR(ENOMEM); - ff_set_common_channel_layouts(ctx, chlayouts); - } - return 0; -} - -static int formats_declared(AVFilterContext *f) -{ - int i; - - for (i = 0; i < f->nb_inputs; i++) { - if (!f->inputs[i]->out_formats) - return 0; - if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO && - !(f->inputs[i]->out_samplerates && - f->inputs[i]->out_channel_layouts)) - return 0; - } - for (i = 0; i < f->nb_outputs; i++) { - if (!f->outputs[i]->in_formats) - return 0; - if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO && - !(f->outputs[i]->in_samplerates && - f->outputs[i]->in_channel_layouts)) - return 0; - } - return 1; -} - -static AVFilterFormats *clone_filter_formats(AVFilterFormats *arg) -{ - AVFilterFormats *a = av_memdup(arg, sizeof(*arg)); - if (a) { - a->refcount = 0; - a->refs = NULL; - a->formats = av_memdup(a->formats, sizeof(*a->formats) * a->nb_formats); - if (!a->formats && arg->formats) - av_freep(&a); - } - return a; -} - -static int can_merge_formats(AVFilterFormats *a_arg, - AVFilterFormats *b_arg, - enum AVMediaType type, - int is_sample_rate) -{ - AVFilterFormats *a, *b, *ret; - if (a_arg == b_arg) - return 1; - a = clone_filter_formats(a_arg); - b = clone_filter_formats(b_arg); - - if (!a || !b) { - if (a) - av_freep(&a->formats); - if (b) - av_freep(&b->formats); - - av_freep(&a); - av_freep(&b); - - return 0; - } - - if (is_sample_rate) { - ret = ff_merge_samplerates(a, b); - } else { - ret = ff_merge_formats(a, b, type); - } - if (ret) { - av_freep(&ret->formats); - av_freep(&ret->refs); - av_freep(&ret); - return 1; - } else { - av_freep(&a->formats); - av_freep(&b->formats); - av_freep(&a); - av_freep(&b); - return 0; - } -} - -/** - * Perform one round of query_formats() and merging formats lists on the - * filter graph. - * @return >=0 if all links formats lists could be queried and merged; - * AVERROR(EAGAIN) some progress was made in the queries or merging - * and a later call may succeed; - * AVERROR(EIO) (may be changed) plus a log message if no progress - * was made and the negotiation is stuck; - * a negative error code if some other error happened - */ -static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) -{ - int i, j, ret; - int scaler_count = 0, resampler_count = 0; - int count_queried = 0; /* successful calls to query_formats() */ - int count_merged = 0; /* successful merge of formats lists */ - int count_already_merged = 0; /* lists already merged */ - int count_delayed = 0; /* lists that need to be merged later */ - - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *f = graph->filters[i]; - if (formats_declared(f)) - continue; - if (f->filter->query_formats) - ret = filter_query_formats(f); - else - ret = ff_default_query_formats(f); - if (ret < 0 && ret != AVERROR(EAGAIN)) - return ret; - /* note: EAGAIN could indicate a partial success, not counted yet */ - count_queried += ret >= 0; - } - - /* go through and merge as many format lists as possible */ - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - - for (j = 0; j < filter->nb_inputs; j++) { - AVFilterLink *link = filter->inputs[j]; - int convert_needed = 0; - - if (!link) - continue; - - if (link->in_formats != link->out_formats - && link->in_formats && link->out_formats) - if (!can_merge_formats(link->in_formats, link->out_formats, - link->type, 0)) - convert_needed = 1; - if (link->type == AVMEDIA_TYPE_AUDIO) { - if (link->in_samplerates != link->out_samplerates - && link->in_samplerates && link->out_samplerates) - if (!can_merge_formats(link->in_samplerates, - link->out_samplerates, - 0, 1)) - convert_needed = 1; - } - -#define MERGE_DISPATCH(field, statement) \ - if (!(link->in_ ## field && link->out_ ## field)) { \ - count_delayed++; \ - } else if (link->in_ ## field == link->out_ ## field) { \ - count_already_merged++; \ - } else if (!convert_needed) { \ - count_merged++; \ - statement \ - } - - if (link->type == AVMEDIA_TYPE_AUDIO) { - MERGE_DISPATCH(channel_layouts, - if (!ff_merge_channel_layouts(link->in_channel_layouts, - link->out_channel_layouts)) - convert_needed = 1; - ) - MERGE_DISPATCH(samplerates, - if (!ff_merge_samplerates(link->in_samplerates, - link->out_samplerates)) - convert_needed = 1; - ) - } - MERGE_DISPATCH(formats, - if (!ff_merge_formats(link->in_formats, link->out_formats, - link->type)) - convert_needed = 1; - ) -#undef MERGE_DISPATCH - - if (convert_needed) { - AVFilterContext *convert; - AVFilter *filter; - AVFilterLink *inlink, *outlink; - char scale_args[256]; - char inst_name[30]; - - /* couldn't merge format lists. auto-insert conversion filter */ - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - if (!(filter = avfilter_get_by_name("scale"))) { - av_log(log_ctx, AV_LOG_ERROR, "'scale' filter " - "not present, cannot convert pixel formats.\n"); - return AVERROR(EINVAL); - } - - snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d", - scaler_count++); - - if ((ret = avfilter_graph_create_filter(&convert, filter, - inst_name, graph->scale_sws_opts, NULL, - graph)) < 0) - return ret; - break; - case AVMEDIA_TYPE_AUDIO: - if (!(filter = avfilter_get_by_name("aresample"))) { - av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter " - "not present, cannot convert audio formats.\n"); - return AVERROR(EINVAL); - } - - snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d", - resampler_count++); - scale_args[0] = '\0'; - if (graph->aresample_swr_opts) - snprintf(scale_args, sizeof(scale_args), "%s", - graph->aresample_swr_opts); - if ((ret = avfilter_graph_create_filter(&convert, filter, - inst_name, graph->aresample_swr_opts, - NULL, graph)) < 0) - return ret; - break; - default: - return AVERROR(EINVAL); - } - - if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0) - return ret; - - filter_query_formats(convert); - inlink = convert->inputs[0]; - outlink = convert->outputs[0]; - if (!ff_merge_formats( inlink->in_formats, inlink->out_formats, inlink->type) || - !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type)) - ret |= AVERROR(ENOSYS); - if (inlink->type == AVMEDIA_TYPE_AUDIO && - (!ff_merge_samplerates(inlink->in_samplerates, - inlink->out_samplerates) || - !ff_merge_channel_layouts(inlink->in_channel_layouts, - inlink->out_channel_layouts))) - ret |= AVERROR(ENOSYS); - if (outlink->type == AVMEDIA_TYPE_AUDIO && - (!ff_merge_samplerates(outlink->in_samplerates, - outlink->out_samplerates) || - !ff_merge_channel_layouts(outlink->in_channel_layouts, - outlink->out_channel_layouts))) - ret |= AVERROR(ENOSYS); - - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Impossible to convert between the formats supported by the filter " - "'%s' and the filter '%s'\n", link->src->name, link->dst->name); - return ret; - } - } - } - } - - av_log(graph, AV_LOG_DEBUG, "query_formats: " - "%d queried, %d merged, %d already done, %d delayed\n", - count_queried, count_merged, count_already_merged, count_delayed); - if (count_delayed) { - AVBPrint bp; - - /* if count_queried > 0, one filter at least did set its formats, - that will give additional information to its neighbour; - if count_merged > 0, one pair of formats lists at least was merged, - that will give additional information to all connected filters; - in both cases, progress was made and a new round must be done */ - if (count_queried || count_merged) - return AVERROR(EAGAIN); - av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); - for (i = 0; i < graph->nb_filters; i++) - if (!formats_declared(graph->filters[i])) - av_bprintf(&bp, "%s%s", bp.len ? ", " : "", - graph->filters[i]->name); - av_log(graph, AV_LOG_ERROR, - "The following filters could not choose their formats: %s\n" - "Consider inserting the (a)format filter near their input or " - "output.\n", bp.str); - return AVERROR(EIO); - } - return 0; -} - -static int pick_format(AVFilterLink *link, AVFilterLink *ref) -{ - if (!link || !link->in_formats) - return 0; - - if (link->type == AVMEDIA_TYPE_VIDEO) { - if(ref && ref->type == AVMEDIA_TYPE_VIDEO){ - int has_alpha= av_pix_fmt_desc_get(ref->format)->nb_components % 2 == 0; - enum AVPixelFormat best= AV_PIX_FMT_NONE; - int i; - for (i=0; i<link->in_formats->nb_formats; i++) { - enum AVPixelFormat p = link->in_formats->formats[i]; - best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL); - } - av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n", - av_get_pix_fmt_name(best), link->in_formats->nb_formats, - av_get_pix_fmt_name(ref->format), has_alpha); - link->in_formats->formats[0] = best; - } - } - - link->in_formats->nb_formats = 1; - link->format = link->in_formats->formats[0]; - - if (link->type == AVMEDIA_TYPE_AUDIO) { - if (!link->in_samplerates->nb_formats) { - av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for" - " the link between filters %s and %s.\n", link->src->name, - link->dst->name); - return AVERROR(EINVAL); - } - link->in_samplerates->nb_formats = 1; - link->sample_rate = link->in_samplerates->formats[0]; - - if (link->in_channel_layouts->all_layouts) { - av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" - " the link between filters %s and %s.\n", link->src->name, - link->dst->name); - if (!link->in_channel_layouts->all_counts) - av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not " - "supported, try specifying a channel layout using " - "'aformat=channel_layouts=something'.\n"); - return AVERROR(EINVAL); - } - link->in_channel_layouts->nb_channel_layouts = 1; - link->channel_layout = link->in_channel_layouts->channel_layouts[0]; - if ((link->channels = FF_LAYOUT2COUNT(link->channel_layout))) - link->channel_layout = 0; - else - link->channels = av_get_channel_layout_nb_channels(link->channel_layout); - } - - ff_formats_unref(&link->in_formats); - ff_formats_unref(&link->out_formats); - ff_formats_unref(&link->in_samplerates); - ff_formats_unref(&link->out_samplerates); - ff_channel_layouts_unref(&link->in_channel_layouts); - ff_channel_layouts_unref(&link->out_channel_layouts); - - return 0; -} - -#define REDUCE_FORMATS(fmt_type, list_type, list, var, nb, add_format) \ -do { \ - for (i = 0; i < filter->nb_inputs; i++) { \ - AVFilterLink *link = filter->inputs[i]; \ - fmt_type fmt; \ - \ - if (!link->out_ ## list || link->out_ ## list->nb != 1) \ - continue; \ - fmt = link->out_ ## list->var[0]; \ - \ - for (j = 0; j < filter->nb_outputs; j++) { \ - AVFilterLink *out_link = filter->outputs[j]; \ - list_type *fmts; \ - \ - if (link->type != out_link->type || \ - out_link->in_ ## list->nb == 1) \ - continue; \ - fmts = out_link->in_ ## list; \ - \ - if (!out_link->in_ ## list->nb) { \ - add_format(&out_link->in_ ##list, fmt); \ - ret = 1; \ - break; \ - } \ - \ - for (k = 0; k < out_link->in_ ## list->nb; k++) \ - if (fmts->var[k] == fmt) { \ - fmts->var[0] = fmt; \ - fmts->nb = 1; \ - ret = 1; \ - break; \ - } \ - } \ - } \ -} while (0) - -static int reduce_formats_on_filter(AVFilterContext *filter) -{ - int i, j, k, ret = 0; - - REDUCE_FORMATS(int, AVFilterFormats, formats, formats, - nb_formats, ff_add_format); - REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, - nb_formats, ff_add_format); - - /* reduce channel layouts */ - for (i = 0; i < filter->nb_inputs; i++) { - AVFilterLink *inlink = filter->inputs[i]; - uint64_t fmt; - - if (!inlink->out_channel_layouts || - inlink->out_channel_layouts->nb_channel_layouts != 1) - continue; - fmt = inlink->out_channel_layouts->channel_layouts[0]; - - for (j = 0; j < filter->nb_outputs; j++) { - AVFilterLink *outlink = filter->outputs[j]; - AVFilterChannelLayouts *fmts; - - fmts = outlink->in_channel_layouts; - if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1) - continue; - - if (fmts->all_layouts && - (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) { - /* Turn the infinite list into a singleton */ - fmts->all_layouts = fmts->all_counts = 0; - ff_add_channel_layout(&outlink->in_channel_layouts, fmt); - break; - } - - for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) { - if (fmts->channel_layouts[k] == fmt) { - fmts->channel_layouts[0] = fmt; - fmts->nb_channel_layouts = 1; - ret = 1; - break; - } - } - } - } - - return ret; -} - -static void reduce_formats(AVFilterGraph *graph) -{ - int i, reduced; - - do { - reduced = 0; - - for (i = 0; i < graph->nb_filters; i++) - reduced |= reduce_formats_on_filter(graph->filters[i]); - } while (reduced); -} - -static void swap_samplerates_on_filter(AVFilterContext *filter) -{ - AVFilterLink *link = NULL; - int sample_rate; - int i, j; - - for (i = 0; i < filter->nb_inputs; i++) { - link = filter->inputs[i]; - - if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_samplerates->nb_formats== 1) - break; - } - if (i == filter->nb_inputs) - return; - - sample_rate = link->out_samplerates->formats[0]; - - for (i = 0; i < filter->nb_outputs; i++) { - AVFilterLink *outlink = filter->outputs[i]; - int best_idx, best_diff = INT_MAX; - - if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_samplerates->nb_formats < 2) - continue; - - for (j = 0; j < outlink->in_samplerates->nb_formats; j++) { - int diff = abs(sample_rate - outlink->in_samplerates->formats[j]); - - if (diff < best_diff) { - best_diff = diff; - best_idx = j; - } - } - FFSWAP(int, outlink->in_samplerates->formats[0], - outlink->in_samplerates->formats[best_idx]); - } -} - -static void swap_samplerates(AVFilterGraph *graph) -{ - int i; - - for (i = 0; i < graph->nb_filters; i++) - swap_samplerates_on_filter(graph->filters[i]); -} - -#define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER) -#define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT) -#define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT) -#define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT) -#define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT) -#define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT) -#define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT) - -/* allowable substitutions for channel pairs when comparing layouts, - * ordered by priority for both values */ -static const uint64_t ch_subst[][2] = { - { CH_FRONT_PAIR, CH_CENTER_PAIR }, - { CH_FRONT_PAIR, CH_WIDE_PAIR }, - { CH_FRONT_PAIR, AV_CH_FRONT_CENTER }, - { CH_CENTER_PAIR, CH_FRONT_PAIR }, - { CH_CENTER_PAIR, CH_WIDE_PAIR }, - { CH_CENTER_PAIR, AV_CH_FRONT_CENTER }, - { CH_WIDE_PAIR, CH_FRONT_PAIR }, - { CH_WIDE_PAIR, CH_CENTER_PAIR }, - { CH_WIDE_PAIR, AV_CH_FRONT_CENTER }, - { AV_CH_FRONT_CENTER, CH_FRONT_PAIR }, - { AV_CH_FRONT_CENTER, CH_CENTER_PAIR }, - { AV_CH_FRONT_CENTER, CH_WIDE_PAIR }, - { CH_SIDE_PAIR, CH_DIRECT_PAIR }, - { CH_SIDE_PAIR, CH_BACK_PAIR }, - { CH_SIDE_PAIR, AV_CH_BACK_CENTER }, - { CH_BACK_PAIR, CH_DIRECT_PAIR }, - { CH_BACK_PAIR, CH_SIDE_PAIR }, - { CH_BACK_PAIR, AV_CH_BACK_CENTER }, - { AV_CH_BACK_CENTER, CH_BACK_PAIR }, - { AV_CH_BACK_CENTER, CH_DIRECT_PAIR }, - { AV_CH_BACK_CENTER, CH_SIDE_PAIR }, -}; - -static void swap_channel_layouts_on_filter(AVFilterContext *filter) -{ - AVFilterLink *link = NULL; - int i, j, k; - - for (i = 0; i < filter->nb_inputs; i++) { - link = filter->inputs[i]; - - if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_channel_layouts->nb_channel_layouts == 1) - break; - } - if (i == filter->nb_inputs) - return; - - for (i = 0; i < filter->nb_outputs; i++) { - AVFilterLink *outlink = filter->outputs[i]; - int best_idx = -1, best_score = INT_MIN, best_count_diff = INT_MAX; - - if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_channel_layouts->nb_channel_layouts < 2) - continue; - - for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) { - uint64_t in_chlayout = link->out_channel_layouts->channel_layouts[0]; - uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j]; - int in_channels = av_get_channel_layout_nb_channels(in_chlayout); - int out_channels = av_get_channel_layout_nb_channels(out_chlayout); - int count_diff = out_channels - in_channels; - int matched_channels, extra_channels; - int score = 100000; - - if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) { - /* Compute score in case the input or output layout encodes - a channel count; in this case the score is not altered by - the computation afterwards, as in_chlayout and - out_chlayout have both been set to 0 */ - if (FF_LAYOUT2COUNT(in_chlayout)) - in_channels = FF_LAYOUT2COUNT(in_chlayout); - if (FF_LAYOUT2COUNT(out_chlayout)) - out_channels = FF_LAYOUT2COUNT(out_chlayout); - score -= 10000 + FFABS(out_channels - in_channels) + - (in_channels > out_channels ? 10000 : 0); - in_chlayout = out_chlayout = 0; - /* Let the remaining computation run, even if the score - value is not altered */ - } - - /* channel substitution */ - for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) { - uint64_t cmp0 = ch_subst[k][0]; - uint64_t cmp1 = ch_subst[k][1]; - if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) && - (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) { - in_chlayout &= ~cmp0; - out_chlayout &= ~cmp1; - /* add score for channel match, minus a deduction for - having to do the substitution */ - score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2; - } - } - - /* no penalty for LFE channel mismatch */ - if ( (in_chlayout & AV_CH_LOW_FREQUENCY) && - (out_chlayout & AV_CH_LOW_FREQUENCY)) - score += 10; - in_chlayout &= ~AV_CH_LOW_FREQUENCY; - out_chlayout &= ~AV_CH_LOW_FREQUENCY; - - matched_channels = av_get_channel_layout_nb_channels(in_chlayout & - out_chlayout); - extra_channels = av_get_channel_layout_nb_channels(out_chlayout & - (~in_chlayout)); - score += 10 * matched_channels - 5 * extra_channels; - - if (score > best_score || - (count_diff < best_count_diff && score == best_score)) { - best_score = score; - best_idx = j; - best_count_diff = count_diff; - } - } - av_assert0(best_idx >= 0); - FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0], - outlink->in_channel_layouts->channel_layouts[best_idx]); - } - -} - -static void swap_channel_layouts(AVFilterGraph *graph) -{ - int i; - - for (i = 0; i < graph->nb_filters; i++) - swap_channel_layouts_on_filter(graph->filters[i]); -} - -static void swap_sample_fmts_on_filter(AVFilterContext *filter) -{ - AVFilterLink *link = NULL; - int format, bps; - int i, j; - - for (i = 0; i < filter->nb_inputs; i++) { - link = filter->inputs[i]; - - if (link->type == AVMEDIA_TYPE_AUDIO && - link->out_formats->nb_formats == 1) - break; - } - if (i == filter->nb_inputs) - return; - - format = link->out_formats->formats[0]; - bps = av_get_bytes_per_sample(format); - - for (i = 0; i < filter->nb_outputs; i++) { - AVFilterLink *outlink = filter->outputs[i]; - int best_idx = -1, best_score = INT_MIN; - - if (outlink->type != AVMEDIA_TYPE_AUDIO || - outlink->in_formats->nb_formats < 2) - continue; - - for (j = 0; j < outlink->in_formats->nb_formats; j++) { - int out_format = outlink->in_formats->formats[j]; - int out_bps = av_get_bytes_per_sample(out_format); - int score; - - if (av_get_packed_sample_fmt(out_format) == format || - av_get_planar_sample_fmt(out_format) == format) { - best_idx = j; - break; - } - - /* for s32 and float prefer double to prevent loss of information */ - if (bps == 4 && out_bps == 8) { - best_idx = j; - break; - } - - /* prefer closest higher or equal bps */ - score = -abs(out_bps - bps); - if (out_bps >= bps) - score += INT_MAX/2; - - if (score > best_score) { - best_score = score; - best_idx = j; - } - } - av_assert0(best_idx >= 0); - FFSWAP(int, outlink->in_formats->formats[0], - outlink->in_formats->formats[best_idx]); - } -} - -static void swap_sample_fmts(AVFilterGraph *graph) -{ - int i; - - for (i = 0; i < graph->nb_filters; i++) - swap_sample_fmts_on_filter(graph->filters[i]); - -} - -static int pick_formats(AVFilterGraph *graph) -{ - int i, j, ret; - int change; - - do{ - change = 0; - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - if (filter->nb_inputs){ - for (j = 0; j < filter->nb_inputs; j++){ - if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->nb_formats == 1) { - if ((ret = pick_format(filter->inputs[j], NULL)) < 0) - return ret; - change = 1; - } - } - } - if (filter->nb_outputs){ - for (j = 0; j < filter->nb_outputs; j++){ - if(filter->outputs[j]->in_formats && filter->outputs[j]->in_formats->nb_formats == 1) { - if ((ret = pick_format(filter->outputs[j], NULL)) < 0) - return ret; - change = 1; - } - } - } - if (filter->nb_inputs && filter->nb_outputs && filter->inputs[0]->format>=0) { - for (j = 0; j < filter->nb_outputs; j++) { - if(filter->outputs[j]->format<0) { - if ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0) - return ret; - change = 1; - } - } - } - } - }while(change); - - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - - for (j = 0; j < filter->nb_inputs; j++) - if ((ret = pick_format(filter->inputs[j], NULL)) < 0) - return ret; - for (j = 0; j < filter->nb_outputs; j++) - if ((ret = pick_format(filter->outputs[j], NULL)) < 0) - return ret; - } - return 0; -} - -/** - * Configure the formats of all the links in the graph. - */ -static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx) -{ - int ret; - - /* find supported formats from sub-filters, and merge along links */ - while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN)) - av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n"); - if (ret < 0) - return ret; - - /* Once everything is merged, it's possible that we'll still have - * multiple valid media format choices. We try to minimize the amount - * of format conversion inside filters */ - reduce_formats(graph); - - /* for audio filters, ensure the best format, sample rate and channel layout - * is selected */ - swap_sample_fmts(graph); - swap_samplerates(graph); - swap_channel_layouts(graph); - - if ((ret = pick_formats(graph)) < 0) - return ret; - - return 0; -} - -static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph, - AVClass *log_ctx) -{ - unsigned i, j; - int sink_links_count = 0, n = 0; - AVFilterContext *f; - AVFilterLink **sinks; - - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - for (j = 0; j < f->nb_inputs; j++) { - f->inputs[j]->graph = graph; - f->inputs[j]->age_index = -1; - } - for (j = 0; j < f->nb_outputs; j++) { - f->outputs[j]->graph = graph; - f->outputs[j]->age_index= -1; - } - if (!f->nb_outputs) { - if (f->nb_inputs > INT_MAX - sink_links_count) - return AVERROR(EINVAL); - sink_links_count += f->nb_inputs; - } - } - sinks = av_calloc(sink_links_count, sizeof(*sinks)); - if (!sinks) - return AVERROR(ENOMEM); - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - if (!f->nb_outputs) { - for (j = 0; j < f->nb_inputs; j++) { - sinks[n] = f->inputs[j]; - f->inputs[j]->age_index = n++; - } - } - } - av_assert0(n == sink_links_count); - graph->sink_links = sinks; - graph->sink_links_count = sink_links_count; - return 0; -} - -static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx) -{ - AVFilterContext *f; - int i, j, ret; - int fifo_count = 0; - - for (i = 0; i < graph->nb_filters; i++) { - f = graph->filters[i]; - - for (j = 0; j < f->nb_inputs; j++) { - AVFilterLink *link = f->inputs[j]; - AVFilterContext *fifo_ctx; - AVFilter *fifo; - char name[32]; - - if (!link->dstpad->needs_fifo) - continue; - - fifo = f->inputs[j]->type == AVMEDIA_TYPE_VIDEO ? - avfilter_get_by_name("fifo") : - avfilter_get_by_name("afifo"); - - snprintf(name, sizeof(name), "auto-inserted fifo %d", fifo_count++); - - ret = avfilter_graph_create_filter(&fifo_ctx, fifo, name, NULL, - NULL, graph); - if (ret < 0) - return ret; - - ret = avfilter_insert_filter(link, fifo_ctx, 0, 0); - if (ret < 0) - return ret; - } - } - - return 0; -} - -int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx) -{ - int ret; - - if ((ret = graph_check_validity(graphctx, log_ctx))) - return ret; - if ((ret = graph_insert_fifos(graphctx, log_ctx)) < 0) - return ret; - if ((ret = graph_config_formats(graphctx, log_ctx))) - return ret; - if ((ret = graph_config_links(graphctx, log_ctx))) - return ret; - if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx))) - return ret; - - return 0; -} - -int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags) -{ - int i, r = AVERROR(ENOSYS); - - if (!graph) - return r; - - if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) { - r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST); - if (r != AVERROR(ENOSYS)) - return r; - } - - if (res_len && res) - res[0] = 0; - - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) { - r = avfilter_process_command(filter, cmd, arg, res, res_len, flags); - if (r != AVERROR(ENOSYS)) { - if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0) - return r; - } - } - } - - return r; -} - -int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts) -{ - int i; - - if(!graph) - return 0; - - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){ - AVFilterCommand **queue = &filter->command_queue, *next; - while (*queue && (*queue)->time <= ts) - queue = &(*queue)->next; - next = *queue; - *queue = av_mallocz(sizeof(AVFilterCommand)); - (*queue)->command = av_strdup(command); - (*queue)->arg = av_strdup(arg); - (*queue)->time = ts; - (*queue)->flags = flags; - (*queue)->next = next; - if(flags & AVFILTER_CMD_FLAG_ONE) - return 0; - } - } - - return 0; -} - -static void heap_bubble_up(AVFilterGraph *graph, - AVFilterLink *link, int index) -{ - AVFilterLink **links = graph->sink_links; - - while (index) { - int parent = (index - 1) >> 1; - if (links[parent]->current_pts >= link->current_pts) - break; - links[index] = links[parent]; - links[index]->age_index = index; - index = parent; - } - links[index] = link; - link->age_index = index; -} - -static void heap_bubble_down(AVFilterGraph *graph, - AVFilterLink *link, int index) -{ - AVFilterLink **links = graph->sink_links; - - while (1) { - int child = 2 * index + 1; - if (child >= graph->sink_links_count) - break; - if (child + 1 < graph->sink_links_count && - links[child + 1]->current_pts < links[child]->current_pts) - child++; - if (link->current_pts < links[child]->current_pts) - break; - links[index] = links[child]; - links[index]->age_index = index; - index = child; - } - links[index] = link; - link->age_index = index; -} - -void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link) -{ - heap_bubble_up (graph, link, link->age_index); - heap_bubble_down(graph, link, link->age_index); -} - - -int avfilter_graph_request_oldest(AVFilterGraph *graph) -{ - while (graph->sink_links_count) { - AVFilterLink *oldest = graph->sink_links[0]; - int r = ff_request_frame(oldest); - if (r != AVERROR_EOF) - return r; - av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n", - oldest->dst ? oldest->dst->name : "unknown", - oldest->dstpad ? oldest->dstpad->name : "unknown"); - /* EOF: remove the link from the heap */ - if (oldest->age_index < --graph->sink_links_count) - heap_bubble_down(graph, graph->sink_links[graph->sink_links_count], - oldest->age_index); - oldest->age_index = -1; - } - return AVERROR_EOF; -} diff --git a/ffmpeg/libavfilter/avfiltergraph.h b/ffmpeg/libavfilter/avfiltergraph.h deleted file mode 100644 index b31d581..0000000 --- a/ffmpeg/libavfilter/avfiltergraph.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Filter graphs - * copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_AVFILTERGRAPH_H -#define AVFILTER_AVFILTERGRAPH_H - -#include "avfilter.h" -#include "libavutil/log.h" - -#endif /* AVFILTER_AVFILTERGRAPH_H */ diff --git a/ffmpeg/libavfilter/bbox.c b/ffmpeg/libavfilter/bbox.c deleted file mode 100644 index be9b2e6..0000000 --- a/ffmpeg/libavfilter/bbox.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "bbox.h" - -int ff_calculate_bounding_box(FFBoundingBox *bbox, - const uint8_t *data, int linesize, int w, int h, - int min_val) -{ - int x, y; - int start_x; - int start_y; - int end_x; - int end_y; - const uint8_t *line; - - /* left bound */ - for (start_x = 0; start_x < w; start_x++) - for (y = 0; y < h; y++) - if ((data[y * linesize + start_x] > min_val)) - goto outl; -outl: - if (start_x == w) /* no points found */ - return 0; - - /* right bound */ - for (end_x = w - 1; end_x >= start_x; end_x--) - for (y = 0; y < h; y++) - if ((data[y * linesize + end_x] > min_val)) - goto outr; -outr: - - /* top bound */ - line = data; - for (start_y = 0; start_y < h; start_y++) { - for (x = 0; x < w; x++) - if (line[x] > min_val) - goto outt; - line += linesize; - } -outt: - - /* bottom bound */ - line = data + (h-1)*linesize; - for (end_y = h - 1; end_y >= start_y; end_y--) { - for (x = 0; x < w; x++) - if (line[x] > min_val) - goto outb; - line -= linesize; - } -outb: - - bbox->x1 = start_x; - bbox->y1 = start_y; - bbox->x2 = end_x; - bbox->y2 = end_y; - return 1; -} diff --git a/ffmpeg/libavfilter/bbox.h b/ffmpeg/libavfilter/bbox.h deleted file mode 100644 index eb73154..0000000 --- a/ffmpeg/libavfilter/bbox.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_BBOX_H -#define AVFILTER_BBOX_H - -#include <stdint.h> - -typedef struct { - int x1, x2, y1, y2; -} FFBoundingBox; - -/** - * Calculate the smallest rectangle that will encompass the - * region with values > min_val. - * - * @param bbox bounding box structure which is updated with the found values. - * If no pixels could be found with value > min_val, the - * structure is not modified. - * @return 1 in case at least one pixel with value > min_val was found, - * 0 otherwise - */ -int ff_calculate_bounding_box(FFBoundingBox *bbox, - const uint8_t *data, int linesize, - int w, int h, int min_val); - -#endif /* AVFILTER_BBOX_H */ diff --git a/ffmpeg/libavfilter/buffer.c b/ffmpeg/libavfilter/buffer.c deleted file mode 100644 index a626184..0000000 --- a/ffmpeg/libavfilter/buffer.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright Stefano Sabatini <stefasab gmail com> - * Copyright Anton Khirnov <anton khirnov net> - * Copyright Michael Niedermayer <michaelni 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/avassert.h" -#include "libavutil/common.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavcodec/avcodec.h" - -#include "avfilter.h" -#include "internal.h" -#include "audio.h" -#include "avcodec.h" -#include "version.h" - -#if FF_API_AVFILTERBUFFER -void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr) -{ - if (ptr->extended_data != ptr->data) - av_freep(&ptr->extended_data); - av_free(ptr->data[0]); - av_free(ptr); -} - -static void copy_video_props(AVFilterBufferRefVideoProps *dst, AVFilterBufferRefVideoProps *src) { - *dst = *src; - if (src->qp_table) { - int qsize = src->qp_table_size; - dst->qp_table = av_malloc(qsize); - memcpy(dst->qp_table, src->qp_table, qsize); - } -} - -AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask) -{ - AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef)); - if (!ret) - return NULL; - *ret = *ref; - - ret->metadata = NULL; - av_dict_copy(&ret->metadata, ref->metadata, 0); - - if (ref->type == AVMEDIA_TYPE_VIDEO) { - ret->video = av_malloc(sizeof(AVFilterBufferRefVideoProps)); - if (!ret->video) { - av_free(ret); - return NULL; - } - copy_video_props(ret->video, ref->video); - ret->extended_data = ret->data; - } else if (ref->type == AVMEDIA_TYPE_AUDIO) { - ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps)); - if (!ret->audio) { - av_free(ret); - return NULL; - } - *ret->audio = *ref->audio; - - if (ref->extended_data && ref->extended_data != ref->data) { - int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout); - if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) * - nb_channels))) { - av_freep(&ret->audio); - av_freep(&ret); - return NULL; - } - memcpy(ret->extended_data, ref->extended_data, - sizeof(*ret->extended_data) * nb_channels); - } else - ret->extended_data = ret->data; - } - ret->perms &= pmask; - ret->buf->refcount ++; - return ret; -} - -void avfilter_unref_buffer(AVFilterBufferRef *ref) -{ - if (!ref) - return; - av_assert0(ref->buf->refcount > 0); - if (!(--ref->buf->refcount)) - ref->buf->free(ref->buf); - if (ref->extended_data != ref->data) - av_freep(&ref->extended_data); - if (ref->video) - av_freep(&ref->video->qp_table); - av_freep(&ref->video); - av_freep(&ref->audio); - av_dict_free(&ref->metadata); - av_free(ref); -} - -void avfilter_unref_bufferp(AVFilterBufferRef **ref) -{ -FF_DISABLE_DEPRECATION_WARNINGS - avfilter_unref_buffer(*ref); -FF_ENABLE_DEPRECATION_WARNINGS - *ref = NULL; -} - -int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src) -{ - dst->pts = src->pts; - dst->pos = av_frame_get_pkt_pos(src); - dst->format = src->format; - - av_dict_free(&dst->metadata); - av_dict_copy(&dst->metadata, av_frame_get_metadata(src), 0); - - switch (dst->type) { - case AVMEDIA_TYPE_VIDEO: - dst->video->w = src->width; - dst->video->h = src->height; - dst->video->sample_aspect_ratio = src->sample_aspect_ratio; - dst->video->interlaced = src->interlaced_frame; - dst->video->top_field_first = src->top_field_first; - dst->video->key_frame = src->key_frame; - dst->video->pict_type = src->pict_type; - break; - case AVMEDIA_TYPE_AUDIO: - dst->audio->sample_rate = src->sample_rate; - dst->audio->channel_layout = src->channel_layout; - break; - default: - return AVERROR(EINVAL); - } - - return 0; -} - -void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src) -{ - // copy common properties - dst->pts = src->pts; - dst->pos = src->pos; - - switch (src->type) { - case AVMEDIA_TYPE_VIDEO: { - if (dst->video->qp_table) - av_freep(&dst->video->qp_table); - copy_video_props(dst->video, src->video); - break; - } - case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break; - default: break; - } - - av_dict_free(&dst->metadata); - av_dict_copy(&dst->metadata, src->metadata, 0); -} -#endif /* FF_API_AVFILTERBUFFER */ diff --git a/ffmpeg/libavfilter/bufferqueue.h b/ffmpeg/libavfilter/bufferqueue.h deleted file mode 100644 index adbc0fd..0000000 --- a/ffmpeg/libavfilter/bufferqueue.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Generic buffer queue - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_BUFFERQUEUE_H -#define AVFILTER_BUFFERQUEUE_H - -/** - * FFBufQueue: simple AVFrame queue API - * - * Note: this API is not thread-safe. Concurrent access to the same queue - * must be protected by a mutex or any synchronization mechanism. - */ - -/** - * Maximum size of the queue. - * - * This value can be overridden by definying it before including this - * header. - * Powers of 2 are recommended. - */ -#ifndef FF_BUFQUEUE_SIZE -#define FF_BUFQUEUE_SIZE 32 -#endif - -#include "avfilter.h" -#include "libavutil/avassert.h" - -/** - * Structure holding the queue - */ -struct FFBufQueue { - AVFrame *queue[FF_BUFQUEUE_SIZE]; - unsigned short head; - unsigned short available; /**< number of available buffers */ -}; - -#define BUCKET(i) queue->queue[(queue->head + (i)) % FF_BUFQUEUE_SIZE] - -/** - * Test if a buffer queue is full. - */ -static inline int ff_bufqueue_is_full(struct FFBufQueue *queue) -{ - return queue->available == FF_BUFQUEUE_SIZE; -} - -/** - * Add a buffer to the queue. - * - * If the queue is already full, then the current last buffer is dropped - * (and unrefed) with a warning before adding the new buffer. - */ -static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue, - AVFrame *buf) -{ - if (ff_bufqueue_is_full(queue)) { - av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n"); - av_frame_free(&BUCKET(--queue->available)); - } - BUCKET(queue->available++) = buf; -} - -/** - * Get a buffer from the queue without altering it. - * - * Buffer with index 0 is the first buffer in the queue. - * Return NULL if the queue has not enough buffers. - */ -static inline AVFrame *ff_bufqueue_peek(struct FFBufQueue *queue, - unsigned index) -{ - return index < queue->available ? BUCKET(index) : NULL; -} - -/** - * Get the first buffer from the queue and remove it. - * - * Do not use on an empty queue. - */ -static inline AVFrame *ff_bufqueue_get(struct FFBufQueue *queue) -{ - AVFrame *ret = queue->queue[queue->head]; - av_assert0(queue->available); - queue->available--; - queue->queue[queue->head] = NULL; - queue->head = (queue->head + 1) % FF_BUFQUEUE_SIZE; - return ret; -} - -/** - * Unref and remove all buffers from the queue. - */ -static inline void ff_bufqueue_discard_all(struct FFBufQueue *queue) -{ - while (queue->available) { - AVFrame *buf = ff_bufqueue_get(queue); - av_frame_free(&buf); - } -} - -#undef BUCKET - -#endif /* AVFILTER_BUFFERQUEUE_H */ diff --git a/ffmpeg/libavfilter/buffersink.c b/ffmpeg/libavfilter/buffersink.c deleted file mode 100644 index a6b24ad..0000000 --- a/ffmpeg/libavfilter/buffersink.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * buffer sink - */ - -#include "libavutil/audio_fifo.h" -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" - -#include "audio.h" -#include "avfilter.h" -#include "buffersink.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - AVFifoBuffer *fifo; ///< FIFO buffer of video frame references - unsigned warning_limit; - - /* only used for video */ - enum AVPixelFormat *pixel_fmts; ///< list of accepted pixel formats, must be terminated with -1 - int pixel_fmts_size; - - /* only used for audio */ - enum AVSampleFormat *sample_fmts; ///< list of accepted sample formats, terminated by AV_SAMPLE_FMT_NONE - int sample_fmts_size; - int64_t *channel_layouts; ///< list of accepted channel layouts, terminated by -1 - int channel_layouts_size; - int *channel_counts; ///< list of accepted channel counts, terminated by -1 - int channel_counts_size; - int all_channel_counts; - int *sample_rates; ///< list of accepted sample rates, terminated by -1 - int sample_rates_size; - - /* only used for compat API */ - AVAudioFifo *audio_fifo; ///< FIFO for audio samples - int64_t next_pts; ///< interpolating audio pts -} BufferSinkContext; - -#define NB_ITEMS(list) (list ## _size / sizeof(*list)) - -static av_cold void uninit(AVFilterContext *ctx) -{ - BufferSinkContext *sink = ctx->priv; - AVFrame *frame; - - if (sink->audio_fifo) - av_audio_fifo_free(sink->audio_fifo); - - if (sink->fifo) { - while (av_fifo_size(sink->fifo) >= sizeof(AVFilterBufferRef *)) { - av_fifo_generic_read(sink->fifo, &frame, sizeof(frame), NULL); - av_frame_free(&frame); - } - av_fifo_free(sink->fifo); - sink->fifo = NULL; - } -} - -static int add_buffer_ref(AVFilterContext *ctx, AVFrame *ref) -{ - BufferSinkContext *buf = ctx->priv; - - if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) { - /* realloc fifo size */ - if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) { - av_log(ctx, AV_LOG_ERROR, - "Cannot buffer more frames. Consume some available frames " - "before adding new ones.\n"); - return AVERROR(ENOMEM); - } - } - - /* cache frame */ - av_fifo_generic_write(buf->fifo, &ref, sizeof(AVFilterBufferRef *), NULL); - return 0; -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AVFilterContext *ctx = link->dst; - BufferSinkContext *buf = link->dst->priv; - int ret; - - if ((ret = add_buffer_ref(ctx, frame)) < 0) - return ret; - if (buf->warning_limit && - av_fifo_size(buf->fifo) / sizeof(AVFilterBufferRef *) >= buf->warning_limit) { - av_log(ctx, AV_LOG_WARNING, - "%d buffers queued in %s, something may be wrong.\n", - buf->warning_limit, - (char *)av_x_if_null(ctx->name, ctx->filter->name)); - buf->warning_limit *= 10; - } - return 0; -} - -int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) -{ - return av_buffersink_get_frame_flags(ctx, frame, 0); -} - -int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) -{ - BufferSinkContext *buf = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - int ret; - AVFrame *cur_frame; - - /* no picref available, fetch it from the filterchain */ - if (!av_fifo_size(buf->fifo)) { - if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) - return AVERROR(EAGAIN); - if ((ret = ff_request_frame(inlink)) < 0) - return ret; - } - - if (!av_fifo_size(buf->fifo)) - return AVERROR(EINVAL); - - if (flags & AV_BUFFERSINK_FLAG_PEEK) { - cur_frame = *((AVFrame **)av_fifo_peek2(buf->fifo, 0)); - if ((ret = av_frame_ref(frame, cur_frame)) < 0) - return ret; - } else { - av_fifo_generic_read(buf->fifo, &cur_frame, sizeof(cur_frame), NULL); - av_frame_move_ref(frame, cur_frame); - av_frame_free(&cur_frame); - } - - return 0; -} - -static int read_from_fifo(AVFilterContext *ctx, AVFrame *frame, - int nb_samples) -{ - BufferSinkContext *s = ctx->priv; - AVFilterLink *link = ctx->inputs[0]; - AVFrame *tmp; - - if (!(tmp = ff_get_audio_buffer(link, nb_samples))) - return AVERROR(ENOMEM); - av_audio_fifo_read(s->audio_fifo, (void**)tmp->extended_data, nb_samples); - - tmp->pts = s->next_pts; - if (s->next_pts != AV_NOPTS_VALUE) - s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate}, - link->time_base); - - av_frame_move_ref(frame, tmp); - av_frame_free(&tmp); - - return 0; -} - -int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx, - AVFrame *frame, int nb_samples) -{ - BufferSinkContext *s = ctx->priv; - AVFilterLink *link = ctx->inputs[0]; - AVFrame *cur_frame; - int ret = 0; - - if (!s->audio_fifo) { - int nb_channels = link->channels; - if (!(s->audio_fifo = av_audio_fifo_alloc(link->format, nb_channels, nb_samples))) - return AVERROR(ENOMEM); - } - - while (ret >= 0) { - if (av_audio_fifo_size(s->audio_fifo) >= nb_samples) - return read_from_fifo(ctx, frame, nb_samples); - - if (!(cur_frame = av_frame_alloc())) - return AVERROR(ENOMEM); - ret = av_buffersink_get_frame_flags(ctx, cur_frame, 0); - if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo)) { - av_frame_free(&cur_frame); - return read_from_fifo(ctx, frame, av_audio_fifo_size(s->audio_fifo)); - } else if (ret < 0) { - av_frame_free(&cur_frame); - return ret; - } - - if (cur_frame->pts != AV_NOPTS_VALUE) { - s->next_pts = cur_frame->pts - - av_rescale_q(av_audio_fifo_size(s->audio_fifo), - (AVRational){ 1, link->sample_rate }, - link->time_base); - } - - ret = av_audio_fifo_write(s->audio_fifo, (void**)cur_frame->extended_data, - cur_frame->nb_samples); - av_frame_free(&cur_frame); - } - - return ret; -} - -AVBufferSinkParams *av_buffersink_params_alloc(void) -{ - static const int pixel_fmts[] = { AV_PIX_FMT_NONE }; - AVBufferSinkParams *params = av_malloc(sizeof(AVBufferSinkParams)); - if (!params) - return NULL; - - params->pixel_fmts = pixel_fmts; - return params; -} - -AVABufferSinkParams *av_abuffersink_params_alloc(void) -{ - AVABufferSinkParams *params = av_mallocz(sizeof(AVABufferSinkParams)); - - if (!params) - return NULL; - return params; -} - -#define FIFO_INIT_SIZE 8 - -static av_cold int common_init(AVFilterContext *ctx) -{ - BufferSinkContext *buf = ctx->priv; - - buf->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef *)); - if (!buf->fifo) { - av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n"); - return AVERROR(ENOMEM); - } - buf->warning_limit = 100; - buf->next_pts = AV_NOPTS_VALUE; - return 0; -} - -void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size) -{ - AVFilterLink *inlink = ctx->inputs[0]; - - inlink->min_samples = inlink->max_samples = - inlink->partial_buf_size = frame_size; -} - -#if FF_API_AVFILTERBUFFER -FF_DISABLE_DEPRECATION_WARNINGS -static void compat_free_buffer(AVFilterBuffer *buf) -{ - AVFrame *frame = buf->priv; - av_frame_free(&frame); - av_free(buf); -} - -static int compat_read(AVFilterContext *ctx, - AVFilterBufferRef **pbuf, int nb_samples, int flags) -{ - AVFilterBufferRef *buf; - AVFrame *frame; - int ret; - - if (!pbuf) - return ff_poll_frame(ctx->inputs[0]); - - frame = av_frame_alloc(); - if (!frame) - return AVERROR(ENOMEM); - - if (!nb_samples) - ret = av_buffersink_get_frame_flags(ctx, frame, flags); - else - ret = av_buffersink_get_samples(ctx, frame, nb_samples); - - if (ret < 0) - goto fail; - - AV_NOWARN_DEPRECATED( - if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) { - buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, - AV_PERM_READ, - frame->width, frame->height, - frame->format); - } else { - buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data, - frame->linesize[0], AV_PERM_READ, - frame->nb_samples, - frame->format, - frame->channel_layout); - } - if (!buf) { - ret = AVERROR(ENOMEM); - goto fail; - } - - avfilter_copy_frame_props(buf, frame); - ) - - buf->buf->priv = frame; - buf->buf->free = compat_free_buffer; - - *pbuf = buf; - - return 0; -fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) -{ - return compat_read(ctx, buf, 0, 0); -} - -int attribute_align_arg av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf, - int nb_samples) -{ - return compat_read(ctx, buf, nb_samples, 0); -} - -int attribute_align_arg av_buffersink_get_buffer_ref(AVFilterContext *ctx, - AVFilterBufferRef **bufref, int flags) -{ - *bufref = NULL; - - av_assert0( !strcmp(ctx->filter->name, "buffersink") - || !strcmp(ctx->filter->name, "abuffersink") - || !strcmp(ctx->filter->name, "ffbuffersink") - || !strcmp(ctx->filter->name, "ffabuffersink")); - - return compat_read(ctx, bufref, 0, flags); -} -FF_ENABLE_DEPRECATION_WARNINGS -#endif - -AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx) -{ - av_assert0( !strcmp(ctx->filter->name, "buffersink") - || !strcmp(ctx->filter->name, "ffbuffersink")); - - return ctx->inputs[0]->frame_rate; -} - -int attribute_align_arg av_buffersink_poll_frame(AVFilterContext *ctx) -{ - BufferSinkContext *buf = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - av_assert0( !strcmp(ctx->filter->name, "buffersink") - || !strcmp(ctx->filter->name, "abuffersink") - || !strcmp(ctx->filter->name, "ffbuffersink") - || !strcmp(ctx->filter->name, "ffabuffersink")); - - return av_fifo_size(buf->fifo)/sizeof(AVFilterBufferRef *) + ff_poll_frame(inlink); -} - -static av_cold int vsink_init(AVFilterContext *ctx, void *opaque) -{ - BufferSinkContext *buf = ctx->priv; - AVBufferSinkParams *params = opaque; - int ret; - - if (params) { - if ((ret = av_opt_set_int_list(buf, "pix_fmts", params->pixel_fmts, AV_PIX_FMT_NONE, 0)) < 0) - return ret; - } - - return common_init(ctx); -} - -#define CHECK_LIST_SIZE(field) \ - if (buf->field ## _size % sizeof(*buf->field)) { \ - av_log(ctx, AV_LOG_ERROR, "Invalid size for " #field ": %d, " \ - "should be multiple of %d\n", \ - buf->field ## _size, (int)sizeof(*buf->field)); \ - return AVERROR(EINVAL); \ - } -static int vsink_query_formats(AVFilterContext *ctx) -{ - BufferSinkContext *buf = ctx->priv; - AVFilterFormats *formats = NULL; - unsigned i; - int ret; - - CHECK_LIST_SIZE(pixel_fmts) - if (buf->pixel_fmts_size) { - for (i = 0; i < NB_ITEMS(buf->pixel_fmts); i++) - if ((ret = ff_add_format(&formats, buf->pixel_fmts[i])) < 0) { - ff_formats_unref(&formats); - return ret; - } - ff_set_common_formats(ctx, formats); - } else { - ff_default_query_formats(ctx); - } - - return 0; -} - -static av_cold int asink_init(AVFilterContext *ctx, void *opaque) -{ - BufferSinkContext *buf = ctx->priv; - AVABufferSinkParams *params = opaque; - int ret; - - if (params) { - if ((ret = av_opt_set_int_list(buf, "sample_fmts", params->sample_fmts, AV_SAMPLE_FMT_NONE, 0)) < 0 || - (ret = av_opt_set_int_list(buf, "sample_rates", params->sample_rates, -1, 0)) < 0 || - (ret = av_opt_set_int_list(buf, "channel_layouts", params->channel_layouts, -1, 0)) < 0 || - (ret = av_opt_set_int_list(buf, "channel_counts", params->channel_counts, -1, 0)) < 0 || - (ret = av_opt_set_int(buf, "all_channel_counts", params->all_channel_counts, 0)) < 0) - return ret; - } - return common_init(ctx); -} - -static int asink_query_formats(AVFilterContext *ctx) -{ - BufferSinkContext *buf = ctx->priv; - AVFilterFormats *formats = NULL; - AVFilterChannelLayouts *layouts = NULL; - unsigned i; - int ret; - - CHECK_LIST_SIZE(sample_fmts) - CHECK_LIST_SIZE(sample_rates) - CHECK_LIST_SIZE(channel_layouts) - CHECK_LIST_SIZE(channel_counts) - - if (buf->sample_fmts_size) { - for (i = 0; i < NB_ITEMS(buf->sample_fmts); i++) - if ((ret = ff_add_format(&formats, buf->sample_fmts[i])) < 0) { - ff_formats_unref(&formats); - return ret; - } - ff_set_common_formats(ctx, formats); - } - - if (buf->channel_layouts_size || buf->channel_counts_size || - buf->all_channel_counts) { - for (i = 0; i < NB_ITEMS(buf->channel_layouts); i++) - if ((ret = ff_add_channel_layout(&layouts, buf->channel_layouts[i])) < 0) { - ff_channel_layouts_unref(&layouts); - return ret; - } - for (i = 0; i < NB_ITEMS(buf->channel_counts); i++) - if ((ret = ff_add_channel_layout(&layouts, FF_COUNT2LAYOUT(buf->channel_counts[i]))) < 0) { - ff_channel_layouts_unref(&layouts); - return ret; - } - if (buf->all_channel_counts) { - if (layouts) - av_log(ctx, AV_LOG_WARNING, - "Conflicting all_channel_counts and list in options\n"); - else if (!(layouts = ff_all_channel_counts())) - return AVERROR(ENOMEM); - } - ff_set_common_channel_layouts(ctx, layouts); - } - - if (buf->sample_rates_size) { - formats = NULL; - for (i = 0; i < NB_ITEMS(buf->sample_rates); i++) - if ((ret = ff_add_format(&formats, buf->sample_rates[i])) < 0) { - ff_formats_unref(&formats); - return ret; - } - ff_set_common_samplerates(ctx, formats); - } - - return 0; -} - -#define OFFSET(x) offsetof(BufferSinkContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption buffersink_options[] = { - { "pix_fmts", "set the supported pixel formats", OFFSET(pixel_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { NULL }, -}; -#undef FLAGS -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption abuffersink_options[] = { - { "sample_fmts", "set the supported sample formats", OFFSET(sample_fmts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { "sample_rates", "set the supported sample rates", OFFSET(sample_rates), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { "channel_layouts", "set the supported channel layouts", OFFSET(channel_layouts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { "channel_counts", "set the supported channel counts", OFFSET(channel_counts), AV_OPT_TYPE_BINARY, .flags = FLAGS }, - { "all_channel_counts", "accept all channel counts", OFFSET(all_channel_counts), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS }, - { NULL }, -}; -#undef FLAGS - -AVFILTER_DEFINE_CLASS(buffersink); -AVFILTER_DEFINE_CLASS(abuffersink); - -#if FF_API_AVFILTERBUFFER - -#define ffbuffersink_options buffersink_options -#define ffabuffersink_options abuffersink_options -AVFILTER_DEFINE_CLASS(ffbuffersink); -AVFILTER_DEFINE_CLASS(ffabuffersink); - -static const AVFilterPad ffbuffersink_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL }, -}; - -AVFilter ff_vsink_ffbuffersink = { - .name = "ffbuffersink", - .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."), - .priv_size = sizeof(BufferSinkContext), - .priv_class = &ffbuffersink_class, - .init_opaque = vsink_init, - .uninit = uninit, - - .query_formats = vsink_query_formats, - .inputs = ffbuffersink_inputs, - .outputs = NULL, -}; - -static const AVFilterPad ffabuffersink_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL }, -}; - -AVFilter ff_asink_ffabuffersink = { - .name = "ffabuffersink", - .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."), - .init_opaque = asink_init, - .uninit = uninit, - .priv_size = sizeof(BufferSinkContext), - .priv_class = &ffabuffersink_class, - .query_formats = asink_query_formats, - .inputs = ffabuffersink_inputs, - .outputs = NULL, -}; -#endif /* FF_API_AVFILTERBUFFER */ - -static const AVFilterPad avfilter_vsink_buffer_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_vsink_buffer = { - .name = "buffersink", - .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."), - .priv_size = sizeof(BufferSinkContext), - .priv_class = &buffersink_class, - .init_opaque = vsink_init, - .uninit = uninit, - - .query_formats = vsink_query_formats, - .inputs = avfilter_vsink_buffer_inputs, - .outputs = NULL, -}; - -static const AVFilterPad avfilter_asink_abuffer_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_asink_abuffer = { - .name = "abuffersink", - .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."), - .priv_class = &abuffersink_class, - .priv_size = sizeof(BufferSinkContext), - .init_opaque = asink_init, - .uninit = uninit, - - .query_formats = asink_query_formats, - .inputs = avfilter_asink_abuffer_inputs, - .outputs = NULL, -}; diff --git a/ffmpeg/libavfilter/buffersink.h b/ffmpeg/libavfilter/buffersink.h deleted file mode 100644 index ce96d08..0000000 --- a/ffmpeg/libavfilter/buffersink.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_BUFFERSINK_H -#define AVFILTER_BUFFERSINK_H - -/** - * @file - * memory buffer sink API for audio and video - */ - -#include "avfilter.h" - -#if FF_API_AVFILTERBUFFER -/** - * Get an audio/video buffer data from buffer_sink and put it in bufref. - * - * This function works with both audio and video buffer sinks. - * - * @param buffer_sink pointer to a buffersink or abuffersink context - * @param flags a combination of AV_BUFFERSINK_FLAG_* flags - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure - */ -attribute_deprecated -int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, - AVFilterBufferRef **bufref, int flags); - -/** - * Get the number of immediately available frames. - */ -attribute_deprecated -int av_buffersink_poll_frame(AVFilterContext *ctx); - -/** - * Get a buffer with filtered data from sink and put it in buf. - * - * @param ctx pointer to a context of a buffersink or abuffersink AVFilter. - * @param buf pointer to the buffer will be written here if buf is non-NULL. buf - * must be freed by the caller using avfilter_unref_buffer(). - * Buf may also be NULL to query whether a buffer is ready to be - * output. - * - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure. - */ -attribute_deprecated -int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf); - -/** - * Same as av_buffersink_read, but with the ability to specify the number of - * samples read. This function is less efficient than av_buffersink_read(), - * because it copies the data around. - * - * @param ctx pointer to a context of the abuffersink AVFilter. - * @param buf pointer to the buffer will be written here if buf is non-NULL. buf - * must be freed by the caller using avfilter_unref_buffer(). buf - * will contain exactly nb_samples audio samples, except at the end - * of stream, when it can contain less than nb_samples. - * Buf may also be NULL to query whether a buffer is ready to be - * output. - * - * @warning do not mix this function with av_buffersink_read(). Use only one or - * the other with a single sink, not both. - */ -attribute_deprecated -int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf, - int nb_samples); -#endif - -/** - * Get a frame with filtered data from sink and put it in frame. - * - * @param ctx pointer to a buffersink or abuffersink filter context. - * @param frame pointer to an allocated frame that will be filled with data. - * The data must be freed using av_frame_unref() / av_frame_free() - * @param flags a combination of AV_BUFFERSINK_FLAG_* flags - * - * @return >= 0 in for success, a negative AVERROR code for failure. - */ -int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags); - -/** - * Tell av_buffersink_get_buffer_ref() to read video/samples buffer - * reference, but not remove it from the buffer. This is useful if you - * need only to read a video/samples buffer, without to fetch it. - */ -#define AV_BUFFERSINK_FLAG_PEEK 1 - -/** - * Tell av_buffersink_get_buffer_ref() not to request a frame from its input. - * If a frame is already buffered, it is read (and removed from the buffer), - * but if no frame is present, return AVERROR(EAGAIN). - */ -#define AV_BUFFERSINK_FLAG_NO_REQUEST 2 - -/** - * Struct to use for initializing a buffersink context. - */ -typedef struct { - const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE -} AVBufferSinkParams; - -/** - * Create an AVBufferSinkParams structure. - * - * Must be freed with av_free(). - */ -AVBufferSinkParams *av_buffersink_params_alloc(void); - -/** - * Struct to use for initializing an abuffersink context. - */ -typedef struct { - const enum AVSampleFormat *sample_fmts; ///< list of allowed sample formats, terminated by AV_SAMPLE_FMT_NONE - const int64_t *channel_layouts; ///< list of allowed channel layouts, terminated by -1 - const int *channel_counts; ///< list of allowed channel counts, terminated by -1 - int all_channel_counts; ///< if not 0, accept any channel count or layout - int *sample_rates; ///< list of allowed sample rates, terminated by -1 -} AVABufferSinkParams; - -/** - * Create an AVABufferSinkParams structure. - * - * Must be freed with av_free(). - */ -AVABufferSinkParams *av_abuffersink_params_alloc(void); - -/** - * Set the frame size for an audio buffer sink. - * - * All calls to av_buffersink_get_buffer_ref will return a buffer with - * exactly the specified number of samples, or AVERROR(EAGAIN) if there is - * not enough. The last buffer at EOF will be padded with 0. - */ -void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size); - -/** - * Get the frame rate of the input. - */ -AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx); - -/** - * Get a frame with filtered data from sink and put it in frame. - * - * @param ctx pointer to a context of a buffersink or abuffersink AVFilter. - * @param frame pointer to an allocated frame that will be filled with data. - * The data must be freed using av_frame_unref() / av_frame_free() - * - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure. - */ -int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame); - -/** - * Same as av_buffersink_get_frame(), but with the ability to specify the number - * of samples read. This function is less efficient than - * av_buffersink_get_frame(), because it copies the data around. - * - * @param ctx pointer to a context of the abuffersink AVFilter. - * @param frame pointer to an allocated frame that will be filled with data. - * The data must be freed using av_frame_unref() / av_frame_free() - * frame will contain exactly nb_samples audio samples, except at - * the end of stream, when it can contain less than nb_samples. - * - * @warning do not mix this function with av_buffersink_get_frame(). Use only one or - * the other with a single sink, not both. - */ -int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples); - -#endif /* AVFILTER_BUFFERSINK_H */ diff --git a/ffmpeg/libavfilter/buffersrc.c b/ffmpeg/libavfilter/buffersrc.c deleted file mode 100644 index fb42c8e..0000000 --- a/ffmpeg/libavfilter/buffersrc.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (c) 2008 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * memory buffer source filter - */ - -#include <float.h> - -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/fifo.h" -#include "libavutil/frame.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "libavutil/samplefmt.h" -#include "audio.h" -#include "avfilter.h" -#include "buffersrc.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "avcodec.h" - -typedef struct { - const AVClass *class; - AVFifoBuffer *fifo; - AVRational time_base; ///< time_base to set in the output link - AVRational frame_rate; ///< frame_rate to set in the output link - unsigned nb_failed_requests; - unsigned warning_limit; - - /* video only */ - int w, h; - enum AVPixelFormat pix_fmt; - AVRational pixel_aspect; - char *sws_param; - - /* audio only */ - int sample_rate; - enum AVSampleFormat sample_fmt; - int channels; - uint64_t channel_layout; - char *channel_layout_str; - - int eof; -} BufferSourceContext; - -#define CHECK_VIDEO_PARAM_CHANGE(s, c, width, height, format)\ - if (c->w != width || c->h != height || c->pix_fmt != format) {\ - av_log(s, AV_LOG_INFO, "Changing frame properties on the fly is not supported by all filters.\n");\ - } - -#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, ch_count, format)\ - if (c->sample_fmt != format || c->sample_rate != srate ||\ - c->channel_layout != ch_layout || c->channels != ch_count) {\ - av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not supported.\n");\ - return AVERROR(EINVAL);\ - } - -int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame) -{ - return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame, - AV_BUFFERSRC_FLAG_KEEP_REF); -} - -int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) -{ - return av_buffersrc_add_frame_flags(ctx, frame, 0); -} - -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags); - -int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) -{ - AVFrame *copy = NULL; - int ret = 0; - - if (frame && frame->channel_layout && - av_get_channel_layout_nb_channels(frame->channel_layout) != av_frame_get_channels(frame)) { - av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); - return AVERROR(EINVAL); - } - - if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame) - return av_buffersrc_add_frame_internal(ctx, frame, flags); - - if (!(copy = av_frame_alloc())) - return AVERROR(ENOMEM); - ret = av_frame_ref(copy, frame); - if (ret >= 0) - ret = av_buffersrc_add_frame_internal(ctx, copy, flags); - - av_frame_free(©); - return ret; -} - -static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, - AVFrame *frame, int flags) -{ - BufferSourceContext *s = ctx->priv; - AVFrame *copy; - int ret; - - s->nb_failed_requests = 0; - - if (!frame) { - s->eof = 1; - return 0; - } else if (s->eof) - return AVERROR(EINVAL); - - if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { - - switch (ctx->outputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, - frame->format); - break; - case AVMEDIA_TYPE_AUDIO: - /* For layouts unknown on input but known on link after negotiation. */ - if (!frame->channel_layout) - frame->channel_layout = s->channel_layout; - CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, - av_frame_get_channels(frame), frame->format); - break; - default: - return AVERROR(EINVAL); - } - - } - - if (!av_fifo_space(s->fifo) && - (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) + - sizeof(copy))) < 0) - return ret; - - if (!(copy = av_frame_alloc())) - return AVERROR(ENOMEM); - av_frame_move_ref(copy, frame); - - if ((ret = av_fifo_generic_write(s->fifo, ©, sizeof(copy), NULL)) < 0) { - av_frame_move_ref(frame, copy); - av_frame_free(©); - return ret; - } - - if ((flags & AV_BUFFERSRC_FLAG_PUSH)) - if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0) - return ret; - - return 0; -} - -#if FF_API_AVFILTERBUFFER -FF_DISABLE_DEPRECATION_WARNINGS -static void compat_free_buffer(void *opaque, uint8_t *data) -{ - AVFilterBufferRef *buf = opaque; - AV_NOWARN_DEPRECATED( - avfilter_unref_buffer(buf); - ) -} - -static void compat_unref_buffer(void *opaque, uint8_t *data) -{ - AVBufferRef *buf = opaque; - AV_NOWARN_DEPRECATED( - av_buffer_unref(&buf); - ) -} - -int av_buffersrc_add_ref(AVFilterContext *ctx, AVFilterBufferRef *buf, - int flags) -{ - BufferSourceContext *s = ctx->priv; - AVFrame *frame = NULL; - AVBufferRef *dummy_buf = NULL; - int ret = 0, planes, i; - - if (!buf) { - s->eof = 1; - return 0; - } else if (s->eof) - return AVERROR(EINVAL); - - frame = av_frame_alloc(); - if (!frame) - return AVERROR(ENOMEM); - - dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, buf, - (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY); - if (!dummy_buf) { - ret = AVERROR(ENOMEM); - goto fail; - } - - AV_NOWARN_DEPRECATED( - if ((ret = avfilter_copy_buf_props(frame, buf)) < 0) - goto fail; - ) - -#define WRAP_PLANE(ref_out, data, data_size) \ -do { \ - AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf); \ - if (!dummy_ref) { \ - ret = AVERROR(ENOMEM); \ - goto fail; \ - } \ - ref_out = av_buffer_create(data, data_size, compat_unref_buffer, \ - dummy_ref, (buf->perms & AV_PERM_WRITE) ? 0 : AV_BUFFER_FLAG_READONLY); \ - if (!ref_out) { \ - av_frame_unref(frame); \ - ret = AVERROR(ENOMEM); \ - goto fail; \ - } \ -} while (0) - - if (ctx->outputs[0]->type == AVMEDIA_TYPE_VIDEO) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - - planes = av_pix_fmt_count_planes(frame->format); - if (!desc || planes <= 0) { - ret = AVERROR(EINVAL); - goto fail; - } - - for (i = 0; i < planes; i++) { - int v_shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; - int plane_size = (frame->height >> v_shift) * frame->linesize[i]; - - WRAP_PLANE(frame->buf[i], frame->data[i], plane_size); - } - } else { - int planar = av_sample_fmt_is_planar(frame->format); - int channels = av_get_channel_layout_nb_channels(frame->channel_layout); - - planes = planar ? channels : 1; - - if (planes > FF_ARRAY_ELEMS(frame->buf)) { - frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf); - frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) * - frame->nb_extended_buf); - if (!frame->extended_buf) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - - for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++) - WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]); - - for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++) - WRAP_PLANE(frame->extended_buf[i], - frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)], - frame->linesize[0]); - } - - ret = av_buffersrc_add_frame_flags(ctx, frame, flags); - -fail: - av_buffer_unref(&dummy_buf); - av_frame_free(&frame); - - return ret; -} -FF_ENABLE_DEPRECATION_WARNINGS - -int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf) -{ - return av_buffersrc_add_ref(ctx, buf, 0); -} -#endif - -static av_cold int init_video(AVFilterContext *ctx) -{ - BufferSourceContext *c = ctx->priv; - - if (c->pix_fmt == AV_PIX_FMT_NONE || !c->w || !c->h || av_q2d(c->time_base) <= 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n"); - return AVERROR(EINVAL); - } - - if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*)))) - return AVERROR(ENOMEM); - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n", - c->w, c->h, av_get_pix_fmt_name(c->pix_fmt), - c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den, - c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, "")); - c->warning_limit = 100; - return 0; -} - -unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src) -{ - return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests; -} - -#define OFFSET(x) offsetof(BufferSourceContext, x) -#define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM -#define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption buffer_options[] = { - { "width", NULL, OFFSET(w), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, - { "video_size", NULL, OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, .flags = V }, - { "height", NULL, OFFSET(h), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, - { "pix_fmt", NULL, OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, { .i64 = AV_PIX_FMT_NONE }, .min = AV_PIX_FMT_NONE, .max = INT_MAX, .flags = V }, -#if FF_API_OLD_FILTER_OPTS - /* those 4 are for compatibility with the old option passing system where each filter - * did its own parsing */ - { "time_base_num", "deprecated, do not use", OFFSET(time_base.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, - { "time_base_den", "deprecated, do not use", OFFSET(time_base.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, - { "sar_num", "deprecated, do not use", OFFSET(pixel_aspect.num), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, - { "sar_den", "deprecated, do not use", OFFSET(pixel_aspect.den), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, V }, -#endif - { "sar", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V }, - { "pixel_aspect", "sample aspect ratio", OFFSET(pixel_aspect), AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V }, - { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, - { "frame_rate", NULL, OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V }, - { "sws_param", NULL, OFFSET(sws_param), AV_OPT_TYPE_STRING, .flags = V }, - { NULL }, -}; - -AVFILTER_DEFINE_CLASS(buffer); - -static const AVOption abuffer_options[] = { - { "time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A }, - { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A }, - { "sample_fmt", NULL, OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, { .i64 = AV_SAMPLE_FMT_NONE }, .min = AV_SAMPLE_FMT_NONE, .max = INT_MAX, .flags = A }, - { "channel_layout", NULL, OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A }, - { "channels", NULL, OFFSET(channels), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A }, - { NULL }, -}; - -AVFILTER_DEFINE_CLASS(abuffer); - -static av_cold int init_audio(AVFilterContext *ctx) -{ - BufferSourceContext *s = ctx->priv; - int ret = 0; - - if (s->sample_fmt == AV_SAMPLE_FMT_NONE) { - av_log(ctx, AV_LOG_ERROR, "Sample format was not set or was invalid\n"); - return AVERROR(EINVAL); - } - - if (s->channel_layout_str) { - int n; - /* TODO reindent */ - s->channel_layout = av_get_channel_layout(s->channel_layout_str); - if (!s->channel_layout) { - av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n", - s->channel_layout_str); - return AVERROR(EINVAL); - } - n = av_get_channel_layout_nb_channels(s->channel_layout); - if (s->channels) { - if (n != s->channels) { - av_log(ctx, AV_LOG_ERROR, - "Mismatching channel count %d and layout '%s' " - "(%d channels)\n", - s->channels, s->channel_layout_str, n); - return AVERROR(EINVAL); - } - } - s->channels = n; - } else if (!s->channels) { - av_log(ctx, AV_LOG_ERROR, "Neither number of channels nor " - "channel layout specified\n"); - return AVERROR(EINVAL); - } - - if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) - return AVERROR(ENOMEM); - - if (!s->time_base.num) - s->time_base = (AVRational){1, s->sample_rate}; - - av_log(ctx, AV_LOG_VERBOSE, - "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n", - s->time_base.num, s->time_base.den, av_get_sample_fmt_name(s->sample_fmt), - s->sample_rate, s->channel_layout_str); - s->warning_limit = 100; - - return ret; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - BufferSourceContext *s = ctx->priv; - while (s->fifo && av_fifo_size(s->fifo)) { - AVFrame *frame; - av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL); - av_frame_free(&frame); - } - av_fifo_free(s->fifo); - s->fifo = NULL; -} - -static int query_formats(AVFilterContext *ctx) -{ - BufferSourceContext *c = ctx->priv; - AVFilterChannelLayouts *channel_layouts = NULL; - AVFilterFormats *formats = NULL; - AVFilterFormats *samplerates = NULL; - - switch (ctx->outputs[0]->type) { - case AVMEDIA_TYPE_VIDEO: - ff_add_format(&formats, c->pix_fmt); - ff_set_common_formats(ctx, formats); - break; - case AVMEDIA_TYPE_AUDIO: - ff_add_format(&formats, c->sample_fmt); - ff_set_common_formats(ctx, formats); - - ff_add_format(&samplerates, c->sample_rate); - ff_set_common_samplerates(ctx, samplerates); - - ff_add_channel_layout(&channel_layouts, - c->channel_layout ? c->channel_layout : - FF_COUNT2LAYOUT(c->channels)); - ff_set_common_channel_layouts(ctx, channel_layouts); - break; - default: - return AVERROR(EINVAL); - } - - return 0; -} - -static int config_props(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - link->w = c->w; - link->h = c->h; - link->sample_aspect_ratio = c->pixel_aspect; - break; - case AVMEDIA_TYPE_AUDIO: - if (!c->channel_layout) - c->channel_layout = link->channel_layout; - break; - default: - return AVERROR(EINVAL); - } - - link->time_base = c->time_base; - link->frame_rate = c->frame_rate; - return 0; -} - -static int request_frame(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - AVFrame *frame; - - if (!av_fifo_size(c->fifo)) { - if (c->eof) - return AVERROR_EOF; - c->nb_failed_requests++; - return AVERROR(EAGAIN); - } - av_fifo_generic_read(c->fifo, &frame, sizeof(frame), NULL); - - return ff_filter_frame(link, frame); -} - -static int poll_frame(AVFilterLink *link) -{ - BufferSourceContext *c = link->src->priv; - int size = av_fifo_size(c->fifo); - if (!size && c->eof) - return AVERROR_EOF; - return size/sizeof(AVFrame*); -} - -static const AVFilterPad avfilter_vsrc_buffer_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .poll_frame = poll_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_buffer = { - .name = "buffer", - .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."), - .priv_size = sizeof(BufferSourceContext), - .query_formats = query_formats, - - .init = init_video, - .uninit = uninit, - - .inputs = NULL, - .outputs = avfilter_vsrc_buffer_outputs, - .priv_class = &buffer_class, -}; - -static const AVFilterPad avfilter_asrc_abuffer_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .request_frame = request_frame, - .poll_frame = poll_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_asrc_abuffer = { - .name = "abuffer", - .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."), - .priv_size = sizeof(BufferSourceContext), - .query_formats = query_formats, - - .init = init_audio, - .uninit = uninit, - - .inputs = NULL, - .outputs = avfilter_asrc_abuffer_outputs, - .priv_class = &abuffer_class, -}; diff --git a/ffmpeg/libavfilter/buffersrc.h b/ffmpeg/libavfilter/buffersrc.h deleted file mode 100644 index 89613e1..0000000 --- a/ffmpeg/libavfilter/buffersrc.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_BUFFERSRC_H -#define AVFILTER_BUFFERSRC_H - -/** - * @file - * Memory buffer source API. - */ - -#include "libavcodec/avcodec.h" -#include "avfilter.h" - -enum { - - /** - * Do not check for format changes. - */ - AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT = 1, - -#if FF_API_AVFILTERBUFFER - /** - * Ignored - */ - AV_BUFFERSRC_FLAG_NO_COPY = 2, -#endif - - /** - * Immediately push the frame to the output. - */ - AV_BUFFERSRC_FLAG_PUSH = 4, - - /** - * Keep a reference to the frame. - * If the frame if reference-counted, create a new reference; otherwise - * copy the frame data. - */ - AV_BUFFERSRC_FLAG_KEEP_REF = 8, - -}; - -/** - * Add buffer data in picref to buffer_src. - * - * @param buffer_src pointer to a buffer source context - * @param picref a buffer reference, or NULL to mark EOF - * @param flags a combination of AV_BUFFERSRC_FLAG_* - * @return >= 0 in case of success, a negative AVERROR code - * in case of failure - */ -int av_buffersrc_add_ref(AVFilterContext *buffer_src, - AVFilterBufferRef *picref, int flags); - -/** - * Get the number of failed requests. - * - * A failed request is when the request_frame method is called while no - * frame is present in the buffer. - * The number is reset when a frame is added. - */ -unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src); - -#if FF_API_AVFILTERBUFFER -/** - * Add a buffer to the filtergraph s. - * - * @param buf buffer containing frame data to be passed down the filtergraph. - * This function will take ownership of buf, the user must not free it. - * A NULL buf signals EOF -- i.e. no more frames will be sent to this filter. - * - * @deprecated use av_buffersrc_write_frame() or av_buffersrc_add_frame() - */ -attribute_deprecated -int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf); -#endif - -/** - * Add a frame to the buffer source. - * - * @param s an instance of the buffersrc filter. - * @param frame frame to be added. If the frame is reference counted, this - * function will make a new reference to it. Otherwise the frame data will be - * copied. - * - * @return 0 on success, a negative AVERROR on error - * - * This function is equivalent to av_buffersrc_add_frame_flags() with the - * AV_BUFFERSRC_FLAG_KEEP_REF flag. - */ -int av_buffersrc_write_frame(AVFilterContext *s, const AVFrame *frame); - -/** - * Add a frame to the buffer source. - * - * @param s an instance of the buffersrc filter. - * @param frame frame to be added. If the frame is reference counted, this - * function will take ownership of the reference(s) and reset the frame. - * Otherwise the frame data will be copied. If this function returns an error, - * the input frame is not touched. - * - * @return 0 on success, a negative AVERROR on error. - * - * @note the difference between this function and av_buffersrc_write_frame() is - * that av_buffersrc_write_frame() creates a new reference to the input frame, - * while this function takes ownership of the reference passed to it. - * - * This function is equivalent to av_buffersrc_add_frame_flags() without the - * AV_BUFFERSRC_FLAG_KEEP_REF flag. - */ -int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame); - -/** - * Add a frame to the buffer source. - * - * By default, if the frame is reference-counted, this function will take - * ownership of the reference(s) and reset the frame. This can be controled - * using the flags. - * - * If this function returns an error, the input frame is not touched. - * - * @param buffer_src pointer to a buffer source context - * @param frame a frame, or NULL to mark EOF - * @param flags a combination of AV_BUFFERSRC_FLAG_* - * @return >= 0 in case of success, a negative AVERROR code - * in case of failure - */ -int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src, - AVFrame *frame, int flags); - - -#endif /* AVFILTER_BUFFERSRC_H */ diff --git a/ffmpeg/libavfilter/drawutils.c b/ffmpeg/libavfilter/drawutils.c deleted file mode 100644 index a5064f8..0000000 --- a/ffmpeg/libavfilter/drawutils.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright 2011 Stefano Sabatini <stefano.sabatini-lala poste it> - * Copyright 2012 Nicolas George <nicolas.george normalesup 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> - -#include "libavutil/avutil.h" -#include "libavutil/colorspace.h" -#include "libavutil/mem.h" -#include "libavutil/pixdesc.h" -#include "drawutils.h" -#include "formats.h" - -enum { RED = 0, GREEN, BLUE, ALPHA }; - -int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) -{ - switch (pix_fmt) { - case AV_PIX_FMT_0RGB: - case AV_PIX_FMT_ARGB: rgba_map[ALPHA] = 0; rgba_map[RED ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break; - case AV_PIX_FMT_0BGR: - case AV_PIX_FMT_ABGR: rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED ] = 3; break; - case AV_PIX_FMT_RGB48LE: - case AV_PIX_FMT_RGB48BE: - case AV_PIX_FMT_RGBA64BE: - case AV_PIX_FMT_RGBA64LE: - case AV_PIX_FMT_RGB0: - case AV_PIX_FMT_RGBA: - case AV_PIX_FMT_RGB24: rgba_map[RED ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break; - case AV_PIX_FMT_BGR48LE: - case AV_PIX_FMT_BGR48BE: - case AV_PIX_FMT_BGRA64BE: - case AV_PIX_FMT_BGRA64LE: - case AV_PIX_FMT_BGRA: - case AV_PIX_FMT_BGR0: - case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break; - case AV_PIX_FMT_GBRAP: - case AV_PIX_FMT_GBRP: rgba_map[GREEN] = 0; rgba_map[BLUE ] = 1; rgba_map[RED ] = 2; rgba_map[ALPHA] = 3; break; - default: /* unsupported */ - return AVERROR(EINVAL); - } - return 0; -} - -int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4], - enum AVPixelFormat pix_fmt, uint8_t rgba_color[4], - int *is_packed_rgba, uint8_t rgba_map_ptr[4]) -{ - uint8_t rgba_map[4] = {0}; - int i; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt); - int hsub = pix_desc->log2_chroma_w; - - *is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0; - - if (*is_packed_rgba) { - pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3; - for (i = 0; i < 4; i++) - dst_color[rgba_map[i]] = rgba_color[i]; - - line[0] = av_malloc(w * pixel_step[0]); - for (i = 0; i < w; i++) - memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]); - if (rgba_map_ptr) - memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4); - } else { - int plane; - - dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]); - dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - dst_color[3] = rgba_color[3]; - - for (plane = 0; plane < 4; plane++) { - int line_size; - int hsub1 = (plane == 1 || plane == 2) ? hsub : 0; - - pixel_step[plane] = 1; - line_size = FF_CEIL_RSHIFT(w, hsub1) * pixel_step[plane]; - line[plane] = av_malloc(line_size); - memset(line[plane], dst_color[plane], line_size); - } - } - - return 0; -} - -void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int w, int h) -{ - int i, plane; - uint8_t *p; - - for (plane = 0; plane < 4 && dst[plane]; plane++) { - int hsub1 = plane == 1 || plane == 2 ? hsub : 0; - int vsub1 = plane == 1 || plane == 2 ? vsub : 0; - int width = FF_CEIL_RSHIFT(w, hsub1); - int height = FF_CEIL_RSHIFT(h, vsub1); - - p = dst[plane] + (y >> vsub1) * dst_linesize[plane]; - for (i = 0; i < height; i++) { - memcpy(p + (x >> hsub1) * pixelstep[plane], - src[plane], width * pixelstep[plane]); - p += dst_linesize[plane]; - } - } -} - -void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int src_linesize[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int y2, int w, int h) -{ - int i, plane; - uint8_t *p; - - for (plane = 0; plane < 4 && dst[plane]; plane++) { - int hsub1 = plane == 1 || plane == 2 ? hsub : 0; - int vsub1 = plane == 1 || plane == 2 ? vsub : 0; - int width = FF_CEIL_RSHIFT(w, hsub1); - int height = FF_CEIL_RSHIFT(h, vsub1); - - p = dst[plane] + (y >> vsub1) * dst_linesize[plane]; - for (i = 0; i < height; i++) { - memcpy(p + (x >> hsub1) * pixelstep[plane], - src[plane] + src_linesize[plane]*(i+(y2>>vsub1)), width * pixelstep[plane]); - p += dst_linesize[plane]; - } - } -} - -int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); - const AVComponentDescriptor *c; - unsigned i, nb_planes = 0; - int pixelstep[MAX_PLANES] = { 0 }; - - if (!desc->name) - return AVERROR(EINVAL); - if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL | AV_PIX_FMT_FLAG_ALPHA)) - return AVERROR(ENOSYS); - for (i = 0; i < desc->nb_components; i++) { - c = &desc->comp[i]; - /* for now, only 8-bits formats */ - if (c->depth_minus1 != 8 - 1) - return AVERROR(ENOSYS); - if (c->plane >= MAX_PLANES) - return AVERROR(ENOSYS); - /* strange interleaving */ - if (pixelstep[c->plane] != 0 && - pixelstep[c->plane] != c->step_minus1 + 1) - return AVERROR(ENOSYS); - pixelstep[c->plane] = c->step_minus1 + 1; - if (pixelstep[c->plane] >= 8) - return AVERROR(ENOSYS); - nb_planes = FFMAX(nb_planes, c->plane + 1); - } - if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3) - return AVERROR(ENOSYS); /* exclude NV12 and NV21 */ - memset(draw, 0, sizeof(*draw)); - draw->desc = desc; - draw->format = format; - draw->nb_planes = nb_planes; - memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep)); - draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w; - draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h; - for (i = 0; i < ((desc->nb_components - 1) | 1); i++) - draw->comp_mask[desc->comp[i].plane] |= - 1 << (desc->comp[i].offset_plus1 - 1); - return 0; -} - -void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]) -{ - unsigned i; - uint8_t rgba_map[4]; - - if (rgba != color->rgba) - memcpy(color->rgba, rgba, sizeof(color->rgba)); - if ((draw->desc->flags & AV_PIX_FMT_FLAG_RGB) && - ff_fill_rgba_map(rgba_map, draw->format) >= 0) { - if (draw->nb_planes == 1) { - for (i = 0; i < 4; i++) - color->comp[0].u8[rgba_map[i]] = rgba[i]; - } else { - for (i = 0; i < 4; i++) - color->comp[rgba_map[i]].u8[0] = rgba[i]; - } - } else if (draw->nb_planes == 3 || draw->nb_planes == 4) { - /* assume YUV */ - color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); - color->comp[1].u8[0] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0); - color->comp[2].u8[0] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0); - color->comp[3].u8[0] = rgba[3]; - } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) { - color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]); - color->comp[1].u8[0] = rgba[3]; - } else { - av_log(NULL, AV_LOG_WARNING, - "Color conversion not implemented for %s\n", draw->desc->name); - memset(color, 128, sizeof(*color)); - } -} - -static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[], - int plane, int x, int y) -{ - return data[plane] + - (y >> draw->vsub[plane]) * linesize[plane] + - (x >> draw->hsub[plane]) * draw->pixelstep[plane]; -} - -void ff_copy_rectangle2(FFDrawContext *draw, - uint8_t *dst[], int dst_linesize[], - uint8_t *src[], int src_linesize[], - int dst_x, int dst_y, int src_x, int src_y, - int w, int h) -{ - int plane, y, wp, hp; - uint8_t *p, *q; - - for (plane = 0; plane < draw->nb_planes; plane++) { - p = pointer_at(draw, src, src_linesize, plane, src_x, src_y); - q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); - wp = FF_CEIL_RSHIFT(w, draw->hsub[plane]) * draw->pixelstep[plane]; - hp = FF_CEIL_RSHIFT(h, draw->vsub[plane]); - for (y = 0; y < hp; y++) { - memcpy(q, p, wp); - p += src_linesize[plane]; - q += dst_linesize[plane]; - } - } -} - -void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], - int dst_x, int dst_y, int w, int h) -{ - int plane, x, y, wp, hp; - uint8_t *p0, *p; - - for (plane = 0; plane < draw->nb_planes; plane++) { - p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y); - wp = FF_CEIL_RSHIFT(w, draw->hsub[plane]); - hp = FF_CEIL_RSHIFT(h, draw->vsub[plane]); - if (!hp) - return; - p = p0; - /* copy first line from color */ - for (x = 0; x < wp; x++) { - memcpy(p, color->comp[plane].u8, draw->pixelstep[plane]); - p += draw->pixelstep[plane]; - } - wp *= draw->pixelstep[plane]; - /* copy next lines from first line */ - p = p0 + dst_linesize[plane]; - for (y = 1; y < hp; y++) { - memcpy(p, p0, wp); - p += dst_linesize[plane]; - } - } -} - -/** - * Clip interval [x; x+w[ within [0; wmax[. - * The resulting w may be negative if the final interval is empty. - * dx, if not null, return the difference between in and out value of x. - */ -static void clip_interval(int wmax, int *x, int *w, int *dx) -{ - if (dx) - *dx = 0; - if (*x < 0) { - if (dx) - *dx = -*x; - *w += *x; - *x = 0; - } - if (*x + *w > wmax) - *w = wmax - *x; -} - -/** - * Decompose w pixels starting at x - * into start + (w starting at x) + end - * with x and w aligned on multiples of 1<<sub. - */ -static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end) -{ - int mask = (1 << sub) - 1; - - *start = (-*x) & mask; - *x += *start; - *start = FFMIN(*start, *w); - *w -= *start; - *end = *w & mask; - *w >>= sub; -} - -static int component_used(FFDrawContext *draw, int plane, int comp) -{ - return (draw->comp_mask[plane] >> comp) & 1; -} - -/* If alpha is in the [ 0 ; 0x1010101 ] range, - then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range, - and >> 24 gives a correct rounding. */ -static void blend_line(uint8_t *dst, unsigned src, unsigned alpha, - int dx, int w, unsigned hsub, int left, int right) -{ - unsigned asrc = alpha * src; - unsigned tau = 0x1010101 - alpha; - int x; - - if (left) { - unsigned suba = (left * alpha) >> hsub; - *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; - dst += dx; - } - for (x = 0; x < w; x++) { - *dst = (*dst * tau + asrc) >> 24; - dst += dx; - } - if (right) { - unsigned suba = (right * alpha) >> hsub; - *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24; - } -} - -void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], - int dst_w, int dst_h, - int x0, int y0, int w, int h) -{ - unsigned alpha, nb_planes, nb_comp, plane, comp; - int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; - uint8_t *p0, *p; - - /* TODO optimize if alpha = 0xFF */ - clip_interval(dst_w, &x0, &w, NULL); - clip_interval(dst_h, &y0, &h, NULL); - if (w <= 0 || h <= 0 || !color->rgba[3]) - return; - /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */ - alpha = 0x10203 * color->rgba[3] + 0x2; - nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */ - for (plane = 0; plane < nb_planes; plane++) { - nb_comp = draw->pixelstep[plane]; - p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); - w_sub = w; - h_sub = h; - x_sub = x0; - y_sub = y0; - subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); - subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); - for (comp = 0; comp < nb_comp; comp++) { - if (!component_used(draw, plane, comp)) - continue; - p = p0 + comp; - if (top) { - blend_line(p, color->comp[plane].u8[comp], alpha >> 1, - draw->pixelstep[plane], w_sub, - draw->hsub[plane], left, right); - p += dst_linesize[plane]; - } - for (y = 0; y < h_sub; y++) { - blend_line(p, color->comp[plane].u8[comp], alpha, - draw->pixelstep[plane], w_sub, - draw->hsub[plane], left, right); - p += dst_linesize[plane]; - } - if (bottom) - blend_line(p, color->comp[plane].u8[comp], alpha >> 1, - draw->pixelstep[plane], w_sub, - draw->hsub[plane], left, right); - } - } -} - -static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha, - uint8_t *mask, int mask_linesize, int l2depth, - unsigned w, unsigned h, unsigned shift, unsigned xm0) -{ - unsigned xm, x, y, t = 0; - unsigned xmshf = 3 - l2depth; - unsigned xmmod = 7 >> l2depth; - unsigned mbits = (1 << (1 << l2depth)) - 1; - unsigned mmult = 255 / mbits; - - for (y = 0; y < h; y++) { - xm = xm0; - for (x = 0; x < w; x++) { - t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits) - * mmult; - xm++; - } - mask += mask_linesize; - } - alpha = (t >> shift) * alpha; - *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24; -} - -static void blend_line_hv(uint8_t *dst, int dst_delta, - unsigned src, unsigned alpha, - uint8_t *mask, int mask_linesize, int l2depth, int w, - unsigned hsub, unsigned vsub, - int xm, int left, int right, int hband) -{ - int x; - - if (left) { - blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, - left, hband, hsub + vsub, xm); - dst += dst_delta; - xm += left; - } - for (x = 0; x < w; x++) { - blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, - 1 << hsub, hband, hsub + vsub, xm); - dst += dst_delta; - xm += 1 << hsub; - } - if (right) - blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth, - right, hband, hsub + vsub, xm); -} - -void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, - uint8_t *mask, int mask_linesize, int mask_w, int mask_h, - int l2depth, unsigned endianness, int x0, int y0) -{ - unsigned alpha, nb_planes, nb_comp, plane, comp; - int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y; - uint8_t *p0, *p, *m; - - clip_interval(dst_w, &x0, &mask_w, &xm0); - clip_interval(dst_h, &y0, &mask_h, &ym0); - mask += ym0 * mask_linesize; - if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3]) - return; - /* alpha is in the [ 0 ; 0x10203 ] range, - alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */ - alpha = (0x10307 * color->rgba[3] + 0x3) >> 8; - nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */ - for (plane = 0; plane < nb_planes; plane++) { - nb_comp = draw->pixelstep[plane]; - p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0); - w_sub = mask_w; - h_sub = mask_h; - x_sub = x0; - y_sub = y0; - subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right); - subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom); - for (comp = 0; comp < nb_comp; comp++) { - if (!component_used(draw, plane, comp)) - continue; - p = p0 + comp; - m = mask; - if (top) { - blend_line_hv(p, draw->pixelstep[plane], - color->comp[plane].u8[comp], alpha, - m, mask_linesize, l2depth, w_sub, - draw->hsub[plane], draw->vsub[plane], - xm0, left, right, top); - p += dst_linesize[plane]; - m += top * mask_linesize; - } - for (y = 0; y < h_sub; y++) { - blend_line_hv(p, draw->pixelstep[plane], - color->comp[plane].u8[comp], alpha, - m, mask_linesize, l2depth, w_sub, - draw->hsub[plane], draw->vsub[plane], - xm0, left, right, 1 << draw->vsub[plane]); - p += dst_linesize[plane]; - m += mask_linesize << draw->vsub[plane]; - } - if (bottom) - blend_line_hv(p, draw->pixelstep[plane], - color->comp[plane].u8[comp], alpha, - m, mask_linesize, l2depth, w_sub, - draw->hsub[plane], draw->vsub[plane], - xm0, left, right, bottom); - } - } -} - -int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, - int value) -{ - unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max; - - if (!shift) - return value; - if (round_dir >= 0) - value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1); - return (value >> shift) << shift; -} - -AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags) -{ - enum AVPixelFormat i, pix_fmts[AV_PIX_FMT_NB + 1]; - unsigned n = 0; - FFDrawContext draw; - - for (i = 0; i < AV_PIX_FMT_NB; i++) - if (ff_draw_init(&draw, i, flags) >= 0) - pix_fmts[n++] = i; - pix_fmts[n++] = AV_PIX_FMT_NONE; - return ff_make_format_list(pix_fmts); -} - -#ifdef TEST - -#undef printf - -int main(void) -{ - enum AVPixelFormat f; - const AVPixFmtDescriptor *desc; - FFDrawContext draw; - FFDrawColor color; - int r, i; - - for (f = 0; f < AV_PIX_FMT_NB; f++) { - desc = av_pix_fmt_desc_get(f); - if (!desc->name) - continue; - printf("Testing %s...%*s", desc->name, - (int)(16 - strlen(desc->name)), ""); - r = ff_draw_init(&draw, f, 0); - if (r < 0) { - char buf[128]; - av_strerror(r, buf, sizeof(buf)); - printf("no: %s\n", buf); - continue; - } - ff_draw_color(&draw, &color, (uint8_t[]) { 1, 0, 0, 1 }); - for (i = 0; i < sizeof(color); i++) - if (((uint8_t *)&color)[i] != 128) - break; - if (i == sizeof(color)) { - printf("fallback color\n"); - continue; - } - printf("ok\n"); - } - return 0; -} - -#endif diff --git a/ffmpeg/libavfilter/drawutils.h b/ffmpeg/libavfilter/drawutils.h deleted file mode 100644 index 5ffffe7..0000000 --- a/ffmpeg/libavfilter/drawutils.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_DRAWUTILS_H -#define AVFILTER_DRAWUTILS_H - -/** - * @file - * misc drawing utilities - */ - -#include <stdint.h> -#include "avfilter.h" -#include "libavutil/pixfmt.h" - -int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt); - -int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, - uint8_t dst_color[4], - enum AVPixelFormat pix_fmt, uint8_t rgba_color[4], - int *is_packed_rgba, uint8_t rgba_map[4]); - -void ff_draw_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int w, int h); - -void ff_copy_rectangle(uint8_t *dst[4], int dst_linesize[4], - uint8_t *src[4], int src_linesize[4], int pixelstep[4], - int hsub, int vsub, int x, int y, int y2, int w, int h); - -#define MAX_PLANES 4 - -typedef struct FFDrawContext { - const struct AVPixFmtDescriptor *desc; - enum AVPixelFormat format; - unsigned nb_planes; - int pixelstep[MAX_PLANES]; /*< offset between pixels */ - uint8_t comp_mask[MAX_PLANES]; /*< bitmask of used non-alpha components */ - uint8_t hsub[MAX_PLANES]; /*< horizontal subsampling */ - uint8_t vsub[MAX_PLANES]; /*< vertical subsampling */ - uint8_t hsub_max; - uint8_t vsub_max; -} FFDrawContext; - -typedef struct FFDrawColor { - uint8_t rgba[4]; - union { - uint32_t u32; - uint16_t u16; - uint8_t u8[4]; - } comp[MAX_PLANES]; -} FFDrawColor; - -/** - * Init a draw context. - * - * Only a limited number of pixel formats are supported, if format is not - * supported the function will return an error. - * No flags currently defined. - * @return 0 for success, < 0 for error - */ -int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags); - -/** - * Prepare a color. - */ -void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]); - -/** - * Copy a rectangle from an image to another. - * - * The coordinates must be as even as the subsampling requires. - */ -void ff_copy_rectangle2(FFDrawContext *draw, - uint8_t *dst[], int dst_linesize[], - uint8_t *src[], int src_linesize[], - int dst_x, int dst_y, int src_x, int src_y, - int w, int h); - -/** - * Fill a rectangle with an uniform color. - * - * The coordinates must be as even as the subsampling requires. - * The color needs to be inited with ff_draw_color. - */ -void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], - int dst_x, int dst_y, int w, int h); - -/** - * Blend a rectangle with an uniform color. - */ -void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], - int dst_w, int dst_h, - int x0, int y0, int w, int h); - -/** - * Blend an alpha mask with an uniform color. - * - * @param draw draw context - * @param color color for the overlay; - * @param dst destination image - * @param dst_linesize line stride of the destination - * @param dst_w width of the destination image - * @param dst_h height of the destination image - * @param mask mask - * @param mask_linesize line stride of the mask - * @param mask_w width of the mask - * @param mask_h height of the mask - * @param l2depth log2 of depth of the mask (0 for 1bpp, 3 for 8bpp) - * @param endianness bit order of the mask (0: MSB to the left) - * @param x0 horizontal position of the overlay - * @param y0 vertical position of the overlay - */ -void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color, - uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h, - uint8_t *mask, int mask_linesize, int mask_w, int mask_h, - int l2depth, unsigned endianness, int x0, int y0); - -/** - * Round a dimension according to subsampling. - * - * @param draw draw context - * @param sub_dir 0 for horizontal, 1 for vertical - * @param round_dir 0 nearest, -1 round down, +1 round up - * @param value value to round - * @return the rounded value - */ -int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir, - int value); - -/** - * Return the list of pixel formats supported by the draw functions. - * - * The flags are the same as ff_draw_init, i.e., none currently. - */ -AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags); - -#endif /* AVFILTER_DRAWUTILS_H */ diff --git a/ffmpeg/libavfilter/f_ebur128.c b/ffmpeg/libavfilter/f_ebur128.c deleted file mode 100644 index a2c6160..0000000 --- a/ffmpeg/libavfilter/f_ebur128.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * 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 - * EBU R.128 implementation - * @see http://tech.ebu.ch/loudness - * @see https://www.youtube.com/watch?v=iuEtQqC-Sqo "EBU R128 Introduction - Florian Camerer" - * @todo True Peak - * @todo implement start/stop/reset through filter command injection - * @todo support other frequencies to avoid resampling - */ - -#include <math.h> - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/dict.h" -#include "libavutil/xga_font_data.h" -#include "libavutil/opt.h" -#include "libavutil/timestamp.h" -#include "audio.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -#define MAX_CHANNELS 63 - -/* pre-filter coefficients */ -#define PRE_B0 1.53512485958697 -#define PRE_B1 -2.69169618940638 -#define PRE_B2 1.19839281085285 -#define PRE_A1 -1.69065929318241 -#define PRE_A2 0.73248077421585 - -/* RLB-filter coefficients */ -#define RLB_B0 1.0 -#define RLB_B1 -2.0 -#define RLB_B2 1.0 -#define RLB_A1 -1.99004745483398 -#define RLB_A2 0.99007225036621 - -#define ABS_THRES -70 ///< silence gate: we discard anything below this absolute (LUFS) threshold -#define ABS_UP_THRES 10 ///< upper loud limit to consider (ABS_THRES being the minimum) -#define HIST_GRAIN 100 ///< defines histogram precision -#define HIST_SIZE ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1) - -/** - * A histogram is an array of HIST_SIZE hist_entry storing all the energies - * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES - * (at 0) to ABS_UP_THRES (at HIST_SIZE-1). - * This fixed-size system avoids the need of a list of energies growing - * infinitely over the time and is thus more scalable. - */ -struct hist_entry { - int count; ///< how many times the corresponding value occurred - double energy; ///< E = 10^((L + 0.691) / 10) - double loudness; ///< L = -0.691 + 10 * log10(E) -}; - -struct integrator { - double *cache[MAX_CHANNELS]; ///< window of filtered samples (N ms) - int cache_pos; ///< focus on the last added bin in the cache array - double sum[MAX_CHANNELS]; ///< sum of the last N ms filtered samples (cache content) - int filled; ///< 1 if the cache is completely filled, 0 otherwise - double rel_threshold; ///< relative threshold - double sum_kept_powers; ///< sum of the powers (weighted sums) above absolute threshold - int nb_kept_powers; ///< number of sum above absolute threshold - struct hist_entry *histogram; ///< histogram of the powers, used to compute LRA and I -}; - -struct rect { int x, y, w, h; }; - -typedef struct { - const AVClass *class; ///< AVClass context for log and options purpose - - /* video */ - int do_video; ///< 1 if video output enabled, 0 otherwise - int w, h; ///< size of the video output - struct rect text; ///< rectangle for the LU legend on the left - struct rect graph; ///< rectangle for the main graph in the center - struct rect gauge; ///< rectangle for the gauge on the right - AVFrame *outpicref; ///< output picture reference, updated regularly - int meter; ///< select a EBU mode between +9 and +18 - int scale_range; ///< the range of LU values according to the meter - int y_zero_lu; ///< the y value (pixel position) for 0 LU - int *y_line_ref; ///< y reference values for drawing the LU lines in the graph and the gauge - - /* audio */ - int nb_channels; ///< number of channels in the input - double *ch_weighting; ///< channel weighting mapping - int sample_count; ///< sample count used for refresh frequency, reset at refresh - - /* Filter caches. - * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */ - double x[MAX_CHANNELS * 3]; ///< 3 input samples cache for each channel - double y[MAX_CHANNELS * 3]; ///< 3 pre-filter samples cache for each channel - double z[MAX_CHANNELS * 3]; ///< 3 RLB-filter samples cache for each channel - -#define I400_BINS (48000 * 4 / 10) -#define I3000_BINS (48000 * 3) - struct integrator i400; ///< 400ms integrator, used for Momentary loudness (M), and Integrated loudness (I) - struct integrator i3000; ///< 3s integrator, used for Short term loudness (S), and Loudness Range (LRA) - - /* I and LRA specific */ - double integrated_loudness; ///< integrated loudness in LUFS (I) - double loudness_range; ///< loudness range in LU (LRA) - double lra_low, lra_high; ///< low and high LRA values - - /* misc */ - int loglevel; ///< log level for frame logging - int metadata; ///< whether or not to inject loudness results in frames -} EBUR128Context; - -#define OFFSET(x) offsetof(EBUR128Context, x) -#define A AV_OPT_FLAG_AUDIO_PARAM -#define V AV_OPT_FLAG_VIDEO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption ebur128_options[] = { - { "video", "set video output", OFFSET(do_video), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, V|F }, - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, V|F }, - { "meter", "set scale meter (+9 to +18)", OFFSET(meter), AV_OPT_TYPE_INT, {.i64 = 9}, 9, 18, V|F }, - { "framelog", "force frame logging level", OFFSET(loglevel), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, A|V|F, "level" }, - { "info", "information logging level", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_INFO}, INT_MIN, INT_MAX, A|V|F, "level" }, - { "verbose", "verbose logging level", 0, AV_OPT_TYPE_CONST, {.i64 = AV_LOG_VERBOSE}, INT_MIN, INT_MAX, A|V|F, "level" }, - { "metadata", "inject metadata in the filtergraph", OFFSET(metadata), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|F }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(ebur128); - -static const uint8_t graph_colors[] = { - 0xdd, 0x66, 0x66, // value above 0LU non reached - 0x66, 0x66, 0xdd, // value below 0LU non reached - 0x96, 0x33, 0x33, // value above 0LU reached - 0x33, 0x33, 0x96, // value below 0LU reached - 0xdd, 0x96, 0x96, // value above 0LU line non reached - 0x96, 0x96, 0xdd, // value below 0LU line non reached - 0xdd, 0x33, 0x33, // value above 0LU line reached - 0x33, 0x33, 0xdd, // value below 0LU line reached -}; - -static const uint8_t *get_graph_color(const EBUR128Context *ebur128, int v, int y) -{ - const int below0 = y > ebur128->y_zero_lu; - const int reached = y >= v; - const int line = ebur128->y_line_ref[y] || y == ebur128->y_zero_lu; - const int colorid = 4*line + 2*reached + below0; - return graph_colors + 3*colorid; -} - -static inline int lu_to_y(const EBUR128Context *ebur128, double v) -{ - v += 2 * ebur128->meter; // make it in range [0;...] - v = av_clipf(v, 0, ebur128->scale_range); // make sure it's in the graph scale - v = ebur128->scale_range - v; // invert value (y=0 is on top) - return v * ebur128->graph.h / ebur128->scale_range; // rescale from scale range to px height -} - -#define FONT8 0 -#define FONT16 1 - -static const uint8_t font_colors[] = { - 0xdd, 0xdd, 0x00, - 0x00, 0x96, 0x96, -}; - -static void drawtext(AVFrame *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt, ...) -{ - int i; - char buf[128] = {0}; - const uint8_t *font; - int font_height; - va_list vl; - - if (ftid == FONT16) font = avpriv_vga16_font, font_height = 16; - else if (ftid == FONT8) font = avpriv_cga_font, font_height = 8; - else return; - - va_start(vl, fmt); - vsnprintf(buf, sizeof(buf), fmt, vl); - va_end(vl); - - for (i = 0; buf[i]; i++) { - int char_y, mask; - uint8_t *p = pic->data[0] + y*pic->linesize[0] + (x + i*8)*3; - - for (char_y = 0; char_y < font_height; char_y++) { - for (mask = 0x80; mask; mask >>= 1) { - if (font[buf[i] * font_height + char_y] & mask) - memcpy(p, color, 3); - else - memcpy(p, "\x00\x00\x00", 3); - p += 3; - } - p += pic->linesize[0] - 8*3; - } - } -} - -static void drawline(AVFrame *pic, int x, int y, int len, int step) -{ - int i; - uint8_t *p = pic->data[0] + y*pic->linesize[0] + x*3; - - for (i = 0; i < len; i++) { - memcpy(p, "\x00\xff\x00", 3); - p += step; - } -} - -static int config_video_output(AVFilterLink *outlink) -{ - int i, x, y; - uint8_t *p; - AVFilterContext *ctx = outlink->src; - EBUR128Context *ebur128 = ctx->priv; - AVFrame *outpicref; - - /* check if there is enough space to represent everything decently */ - if (ebur128->w < 640 || ebur128->h < 480) { - av_log(ctx, AV_LOG_ERROR, "Video size %dx%d is too small, " - "minimum size is 640x480\n", ebur128->w, ebur128->h); - return AVERROR(EINVAL); - } - outlink->w = ebur128->w; - outlink->h = ebur128->h; - -#define PAD 8 - - /* configure text area position and size */ - ebur128->text.x = PAD; - ebur128->text.y = 40; - ebur128->text.w = 3 * 8; // 3 characters - ebur128->text.h = ebur128->h - PAD - ebur128->text.y; - - /* configure gauge position and size */ - ebur128->gauge.w = 20; - ebur128->gauge.h = ebur128->text.h; - ebur128->gauge.x = ebur128->w - PAD - ebur128->gauge.w; - ebur128->gauge.y = ebur128->text.y; - - /* configure graph position and size */ - ebur128->graph.x = ebur128->text.x + ebur128->text.w + PAD; - ebur128->graph.y = ebur128->gauge.y; - ebur128->graph.w = ebur128->gauge.x - ebur128->graph.x - PAD; - ebur128->graph.h = ebur128->gauge.h; - - /* graph and gauge share the LU-to-pixel code */ - av_assert0(ebur128->graph.h == ebur128->gauge.h); - - /* prepare the initial picref buffer */ - av_frame_free(&ebur128->outpicref); - ebur128->outpicref = outpicref = - ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) - return AVERROR(ENOMEM); - outlink->sample_aspect_ratio = (AVRational){1,1}; - - /* init y references values (to draw LU lines) */ - ebur128->y_line_ref = av_calloc(ebur128->graph.h + 1, sizeof(*ebur128->y_line_ref)); - if (!ebur128->y_line_ref) - return AVERROR(ENOMEM); - - /* black background */ - memset(outpicref->data[0], 0, ebur128->h * outpicref->linesize[0]); - - /* draw LU legends */ - drawtext(outpicref, PAD, PAD+16, FONT8, font_colors+3, " LU"); - for (i = ebur128->meter; i >= -ebur128->meter * 2; i--) { - y = lu_to_y(ebur128, i); - x = PAD + (i < 10 && i > -10) * 8; - ebur128->y_line_ref[y] = i; - y -= 4; // -4 to center vertically - drawtext(outpicref, x, y + ebur128->graph.y, FONT8, font_colors+3, - "%c%d", i < 0 ? '-' : i > 0 ? '+' : ' ', FFABS(i)); - } - - /* draw graph */ - ebur128->y_zero_lu = lu_to_y(ebur128, 0); - p = outpicref->data[0] + ebur128->graph.y * outpicref->linesize[0] - + ebur128->graph.x * 3; - for (y = 0; y < ebur128->graph.h; y++) { - const uint8_t *c = get_graph_color(ebur128, INT_MAX, y); - - for (x = 0; x < ebur128->graph.w; x++) - memcpy(p + x*3, c, 3); - p += outpicref->linesize[0]; - } - - /* draw fancy rectangles around the graph and the gauge */ -#define DRAW_RECT(r) do { \ - drawline(outpicref, r.x, r.y - 1, r.w, 3); \ - drawline(outpicref, r.x, r.y + r.h, r.w, 3); \ - drawline(outpicref, r.x - 1, r.y, r.h, outpicref->linesize[0]); \ - drawline(outpicref, r.x + r.w, r.y, r.h, outpicref->linesize[0]); \ -} while (0) - DRAW_RECT(ebur128->graph); - DRAW_RECT(ebur128->gauge); - - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - - return 0; -} - -static int config_audio_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - EBUR128Context *ebur128 = ctx->priv; - - /* force 100ms framing in case of metadata injection: the frames must have - * a granularity of the window overlap to be accurately exploited */ - if (ebur128->metadata) - inlink->min_samples = - inlink->max_samples = - inlink->partial_buf_size = inlink->sample_rate / 10; - return 0; -} - -static int config_audio_output(AVFilterLink *outlink) -{ - int i; - int idx_bitposn = 0; - AVFilterContext *ctx = outlink->src; - EBUR128Context *ebur128 = ctx->priv; - const int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout); - -#define BACK_MASK (AV_CH_BACK_LEFT |AV_CH_BACK_CENTER |AV_CH_BACK_RIGHT| \ - AV_CH_TOP_BACK_LEFT|AV_CH_TOP_BACK_CENTER|AV_CH_TOP_BACK_RIGHT| \ - AV_CH_SIDE_LEFT |AV_CH_SIDE_RIGHT| \ - AV_CH_SURROUND_DIRECT_LEFT |AV_CH_SURROUND_DIRECT_RIGHT) - - ebur128->nb_channels = nb_channels; - ebur128->ch_weighting = av_calloc(nb_channels, sizeof(*ebur128->ch_weighting)); - if (!ebur128->ch_weighting) - return AVERROR(ENOMEM); - - for (i = 0; i < nb_channels; i++) { - - /* find the next bit that is set starting from the right */ - while ((outlink->channel_layout & 1ULL<<idx_bitposn) == 0 && idx_bitposn < 63) - idx_bitposn++; - - /* channel weighting */ - if ((1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY) || - (1ULL<<idx_bitposn & AV_CH_LOW_FREQUENCY_2)) { - ebur128->ch_weighting[i] = 0; - } else if (1ULL<<idx_bitposn & BACK_MASK) { - ebur128->ch_weighting[i] = 1.41; - } else { - ebur128->ch_weighting[i] = 1.0; - } - - idx_bitposn++; - - if (!ebur128->ch_weighting[i]) - continue; - - /* bins buffer for the two integration window (400ms and 3s) */ - ebur128->i400.cache[i] = av_calloc(I400_BINS, sizeof(*ebur128->i400.cache[0])); - ebur128->i3000.cache[i] = av_calloc(I3000_BINS, sizeof(*ebur128->i3000.cache[0])); - if (!ebur128->i400.cache[i] || !ebur128->i3000.cache[i]) - return AVERROR(ENOMEM); - } - - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - - return 0; -} - -#define ENERGY(loudness) (pow(10, ((loudness) + 0.691) / 10.)) -#define LOUDNESS(energy) (-0.691 + 10 * log10(energy)) - -static struct hist_entry *get_histogram(void) -{ - int i; - struct hist_entry *h = av_calloc(HIST_SIZE, sizeof(*h)); - - if (!h) - return NULL; - for (i = 0; i < HIST_SIZE; i++) { - h[i].loudness = i / (double)HIST_GRAIN + ABS_THRES; - h[i].energy = ENERGY(h[i].loudness); - } - return h; -} - -static av_cold int init(AVFilterContext *ctx) -{ - EBUR128Context *ebur128 = ctx->priv; - AVFilterPad pad; - - if (ebur128->loglevel != AV_LOG_INFO && - ebur128->loglevel != AV_LOG_VERBOSE) { - if (ebur128->do_video || ebur128->metadata) - ebur128->loglevel = AV_LOG_VERBOSE; - else - ebur128->loglevel = AV_LOG_INFO; - } - - // if meter is +9 scale, scale range is from -18 LU to +9 LU (or 3*9) - // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18) - ebur128->scale_range = 3 * ebur128->meter; - - ebur128->i400.histogram = get_histogram(); - ebur128->i3000.histogram = get_histogram(); - if (!ebur128->i400.histogram || !ebur128->i3000.histogram) - return AVERROR(ENOMEM); - - ebur128->integrated_loudness = ABS_THRES; - ebur128->loudness_range = 0; - - /* insert output pads */ - if (ebur128->do_video) { - pad = (AVFilterPad){ - .name = av_strdup("out0"), - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_video_output, - }; - if (!pad.name) - return AVERROR(ENOMEM); - ff_insert_outpad(ctx, 0, &pad); - } - pad = (AVFilterPad){ - .name = av_asprintf("out%d", ebur128->do_video), - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_audio_output, - }; - if (!pad.name) - return AVERROR(ENOMEM); - ff_insert_outpad(ctx, ebur128->do_video, &pad); - - /* summary */ - av_log(ctx, AV_LOG_VERBOSE, "EBU +%d scale\n", ebur128->meter); - - return 0; -} - -#define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN) - -/* loudness and power should be set such as loudness = -0.691 + - * 10*log10(power), we just avoid doing that calculus two times */ -static int gate_update(struct integrator *integ, double power, - double loudness, int gate_thres) -{ - int ipower; - double relative_threshold; - int gate_hist_pos; - - /* update powers histograms by incrementing current power count */ - ipower = av_clip(HIST_POS(loudness), 0, HIST_SIZE - 1); - integ->histogram[ipower].count++; - - /* compute relative threshold and get its position in the histogram */ - integ->sum_kept_powers += power; - integ->nb_kept_powers++; - relative_threshold = integ->sum_kept_powers / integ->nb_kept_powers; - if (!relative_threshold) - relative_threshold = 1e-12; - integ->rel_threshold = LOUDNESS(relative_threshold) + gate_thres; - gate_hist_pos = av_clip(HIST_POS(integ->rel_threshold), 0, HIST_SIZE - 1); - - return gate_hist_pos; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *insamples) -{ - int i, ch, idx_insample; - AVFilterContext *ctx = inlink->dst; - EBUR128Context *ebur128 = ctx->priv; - const int nb_channels = ebur128->nb_channels; - const int nb_samples = insamples->nb_samples; - const double *samples = (double *)insamples->data[0]; - AVFrame *pic = ebur128->outpicref; - - for (idx_insample = 0; idx_insample < nb_samples; idx_insample++) { - const int bin_id_400 = ebur128->i400.cache_pos; - const int bin_id_3000 = ebur128->i3000.cache_pos; - -#define MOVE_TO_NEXT_CACHED_ENTRY(time) do { \ - ebur128->i##time.cache_pos++; \ - if (ebur128->i##time.cache_pos == I##time##_BINS) { \ - ebur128->i##time.filled = 1; \ - ebur128->i##time.cache_pos = 0; \ - } \ -} while (0) - - MOVE_TO_NEXT_CACHED_ENTRY(400); - MOVE_TO_NEXT_CACHED_ENTRY(3000); - - for (ch = 0; ch < nb_channels; ch++) { - double bin; - - ebur128->x[ch * 3] = *samples++; // set X[i] - - if (!ebur128->ch_weighting[ch]) - continue; - - /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */ -#define FILTER(Y, X, name) do { \ - double *dst = ebur128->Y + ch*3; \ - double *src = ebur128->X + ch*3; \ - dst[2] = dst[1]; \ - dst[1] = dst[0]; \ - dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2 \ - - dst[1]*name##_A1 - dst[2]*name##_A2; \ -} while (0) - - // TODO: merge both filters in one? - FILTER(y, x, PRE); // apply pre-filter - ebur128->x[ch * 3 + 2] = ebur128->x[ch * 3 + 1]; - ebur128->x[ch * 3 + 1] = ebur128->x[ch * 3 ]; - FILTER(z, y, RLB); // apply RLB-filter - - bin = ebur128->z[ch * 3] * ebur128->z[ch * 3]; - - /* add the new value, and limit the sum to the cache size (400ms or 3s) - * by removing the oldest one */ - ebur128->i400.sum [ch] = ebur128->i400.sum [ch] + bin - ebur128->i400.cache [ch][bin_id_400]; - ebur128->i3000.sum[ch] = ebur128->i3000.sum[ch] + bin - ebur128->i3000.cache[ch][bin_id_3000]; - - /* override old cache entry with the new value */ - ebur128->i400.cache [ch][bin_id_400 ] = bin; - ebur128->i3000.cache[ch][bin_id_3000] = bin; - } - - /* For integrated loudness, gating blocks are 400ms long with 75% - * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms - * (4800 samples at 48kHz). */ - if (++ebur128->sample_count == 4800) { - double loudness_400, loudness_3000; - double power_400 = 1e-12, power_3000 = 1e-12; - AVFilterLink *outlink = ctx->outputs[0]; - const int64_t pts = insamples->pts + - av_rescale_q(idx_insample, (AVRational){ 1, inlink->sample_rate }, - outlink->time_base); - - ebur128->sample_count = 0; - -#define COMPUTE_LOUDNESS(m, time) do { \ - if (ebur128->i##time.filled) { \ - /* weighting sum of the last <time> ms */ \ - for (ch = 0; ch < nb_channels; ch++) \ - power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch]; \ - power_##time /= I##time##_BINS; \ - } \ - loudness_##time = LOUDNESS(power_##time); \ -} while (0) - - COMPUTE_LOUDNESS(M, 400); - COMPUTE_LOUDNESS(S, 3000); - - /* Integrated loudness */ -#define I_GATE_THRES -10 // initially defined to -8 LU in the first EBU standard - - if (loudness_400 >= ABS_THRES) { - double integrated_sum = 0; - int nb_integrated = 0; - int gate_hist_pos = gate_update(&ebur128->i400, power_400, - loudness_400, I_GATE_THRES); - - /* compute integrated loudness by summing the histogram values - * above the relative threshold */ - for (i = gate_hist_pos; i < HIST_SIZE; i++) { - const int nb_v = ebur128->i400.histogram[i].count; - nb_integrated += nb_v; - integrated_sum += nb_v * ebur128->i400.histogram[i].energy; - } - if (nb_integrated) - ebur128->integrated_loudness = LOUDNESS(integrated_sum / nb_integrated); - } - - /* LRA */ -#define LRA_GATE_THRES -20 -#define LRA_LOWER_PRC 10 -#define LRA_HIGHER_PRC 95 - - /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770 - * specs is ">" */ - if (loudness_3000 >= ABS_THRES) { - int nb_powers = 0; - int gate_hist_pos = gate_update(&ebur128->i3000, power_3000, - loudness_3000, LRA_GATE_THRES); - - for (i = gate_hist_pos; i < HIST_SIZE; i++) - nb_powers += ebur128->i3000.histogram[i].count; - if (nb_powers) { - int n, nb_pow; - - /* get lower loudness to consider */ - n = 0; - nb_pow = LRA_LOWER_PRC * nb_powers / 100. + 0.5; - for (i = gate_hist_pos; i < HIST_SIZE; i++) { - n += ebur128->i3000.histogram[i].count; - if (n >= nb_pow) { - ebur128->lra_low = ebur128->i3000.histogram[i].loudness; - break; - } - } - - /* get higher loudness to consider */ - n = nb_powers; - nb_pow = LRA_HIGHER_PRC * nb_powers / 100. + 0.5; - for (i = HIST_SIZE - 1; i >= 0; i--) { - n -= ebur128->i3000.histogram[i].count; - if (n < nb_pow) { - ebur128->lra_high = ebur128->i3000.histogram[i].loudness; - break; - } - } - - // XXX: show low & high on the graph? - ebur128->loudness_range = ebur128->lra_high - ebur128->lra_low; - } - } - -#define LOG_FMT "M:%6.1f S:%6.1f I:%6.1f LUFS LRA:%6.1f LU" - - /* push one video frame */ - if (ebur128->do_video) { - int x, y, ret; - uint8_t *p; - - const int y_loudness_lu_graph = lu_to_y(ebur128, loudness_3000 + 23); - const int y_loudness_lu_gauge = lu_to_y(ebur128, loudness_400 + 23); - - /* draw the graph using the short-term loudness */ - p = pic->data[0] + ebur128->graph.y*pic->linesize[0] + ebur128->graph.x*3; - for (y = 0; y < ebur128->graph.h; y++) { - const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_graph, y); - - memmove(p, p + 3, (ebur128->graph.w - 1) * 3); - memcpy(p + (ebur128->graph.w - 1) * 3, c, 3); - p += pic->linesize[0]; - } - - /* draw the gauge using the momentary loudness */ - p = pic->data[0] + ebur128->gauge.y*pic->linesize[0] + ebur128->gauge.x*3; - for (y = 0; y < ebur128->gauge.h; y++) { - const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_gauge, y); - - for (x = 0; x < ebur128->gauge.w; x++) - memcpy(p + x*3, c, 3); - p += pic->linesize[0]; - } - - /* draw textual info */ - drawtext(pic, PAD, PAD - PAD/2, FONT16, font_colors, - LOG_FMT " ", // padding to erase trailing characters - loudness_400, loudness_3000, - ebur128->integrated_loudness, ebur128->loudness_range); - - /* set pts and push frame */ - pic->pts = pts; - ret = ff_filter_frame(outlink, av_frame_clone(pic)); - if (ret < 0) - return ret; - } - - if (ebur128->metadata) { /* happens only once per filter_frame call */ - char metabuf[128]; -#define SET_META(name, var) do { \ - snprintf(metabuf, sizeof(metabuf), "%.3f", var); \ - av_dict_set(&insamples->metadata, "lavfi.r128." name, metabuf, 0); \ -} while (0) - SET_META("M", loudness_400); - SET_META("S", loudness_3000); - SET_META("I", ebur128->integrated_loudness); - SET_META("LRA", ebur128->loudness_range); - SET_META("LRA.low", ebur128->lra_low); - SET_META("LRA.high", ebur128->lra_high); - } - - av_log(ctx, ebur128->loglevel, "t: %-10s " LOG_FMT "\n", - av_ts2timestr(pts, &outlink->time_base), - loudness_400, loudness_3000, - ebur128->integrated_loudness, ebur128->loudness_range); - } - } - - return ff_filter_frame(ctx->outputs[ebur128->do_video], insamples); -} - -static int query_formats(AVFilterContext *ctx) -{ - EBUR128Context *ebur128 = ctx->priv; - AVFilterFormats *formats; - AVFilterChannelLayouts *layouts; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - - static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_NONE }; - static const int input_srate[] = {48000, -1}; // ITU-R BS.1770 provides coeff only for 48kHz - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE }; - - /* set optional output video format */ - if (ebur128->do_video) { - formats = ff_make_format_list(pix_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &outlink->in_formats); - outlink = ctx->outputs[1]; - } - - /* set input and output audio formats - * Note: ff_set_common_* functions are not used because they affect all the - * links, and thus break the video format negotiation */ - formats = ff_make_format_list(sample_fmts); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_formats); - ff_formats_ref(formats, &outlink->in_formats); - - layouts = ff_all_channel_layouts(); - if (!layouts) - return AVERROR(ENOMEM); - ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); - ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); - - formats = ff_make_format_list(input_srate); - if (!formats) - return AVERROR(ENOMEM); - ff_formats_ref(formats, &inlink->out_samplerates); - ff_formats_ref(formats, &outlink->in_samplerates); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - int i; - EBUR128Context *ebur128 = ctx->priv; - - av_log(ctx, AV_LOG_INFO, "Summary:\n\n" - " Integrated loudness:\n" - " I: %5.1f LUFS\n" - " Threshold: %5.1f LUFS\n\n" - " Loudness range:\n" - " LRA: %5.1f LU\n" - " Threshold: %5.1f LUFS\n" - " LRA low: %5.1f LUFS\n" - " LRA high: %5.1f LUFS\n", - ebur128->integrated_loudness, ebur128->i400.rel_threshold, - ebur128->loudness_range, ebur128->i3000.rel_threshold, - ebur128->lra_low, ebur128->lra_high); - - av_freep(&ebur128->y_line_ref); - av_freep(&ebur128->ch_weighting); - av_freep(&ebur128->i400.histogram); - av_freep(&ebur128->i3000.histogram); - for (i = 0; i < ebur128->nb_channels; i++) { - av_freep(&ebur128->i400.cache[i]); - av_freep(&ebur128->i3000.cache[i]); - } - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); - av_frame_free(&ebur128->outpicref); -} - -static const AVFilterPad ebur128_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - .config_props = config_audio_input, - }, - { NULL } -}; - -AVFilter ff_af_ebur128 = { - .name = "ebur128", - .description = NULL_IF_CONFIG_SMALL("EBU R128 scanner."), - .priv_size = sizeof(EBUR128Context), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = ebur128_inputs, - .outputs = NULL, - .priv_class = &ebur128_class, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; diff --git a/ffmpeg/libavfilter/f_perms.c b/ffmpeg/libavfilter/f_perms.c deleted file mode 100644 index 2c53e8c..0000000 --- a/ffmpeg/libavfilter/f_perms.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2013 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/lfg.h" -#include "libavutil/opt.h" -#include "libavutil/random_seed.h" -#include "audio.h" -#include "video.h" - -enum mode { - MODE_NONE, - MODE_RO, - MODE_RW, - MODE_TOGGLE, - MODE_RANDOM, - NB_MODES -}; - -typedef struct { - const AVClass *class; - AVLFG lfg; - int64_t random_seed; - enum mode mode; -} PermsContext; - -#define OFFSET(x) offsetof(PermsContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption options[] = { - { "mode", "select permissions mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_NONE}, MODE_NONE, NB_MODES-1, FLAGS, "mode" }, - { "none", "do nothing", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_NONE}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "ro", "set all output frames read-only", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RO}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "rw", "set all output frames writable", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RW}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "toggle", "switch permissions", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_TOGGLE}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "random", "set permissions randomly", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_RANDOM}, INT_MIN, INT_MAX, FLAGS, "mode" }, - { "seed", "set the seed for the random mode", OFFSET(random_seed), AV_OPT_TYPE_INT64, {.i64 = -1}, -1, UINT32_MAX, FLAGS }, - { NULL } -}; - -static av_cold int init(AVFilterContext *ctx) -{ - PermsContext *perms = ctx->priv; - - if (perms->mode == MODE_RANDOM) { - uint32_t seed; - - if (perms->random_seed == -1) - perms->random_seed = av_get_random_seed(); - seed = perms->random_seed; - av_log(ctx, AV_LOG_INFO, "random seed: 0x%08x\n", seed); - av_lfg_init(&perms->lfg, seed); - } - - return 0; -} - -enum perm { RO, RW }; -static const char *perm_str[2] = { "RO", "RW" }; - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - int ret; - AVFilterContext *ctx = inlink->dst; - PermsContext *perms = ctx->priv; - AVFrame *out = frame; - enum perm in_perm = av_frame_is_writable(frame) ? RW : RO; - enum perm out_perm; - - switch (perms->mode) { - case MODE_TOGGLE: out_perm = in_perm == RO ? RW : RO; break; - case MODE_RANDOM: out_perm = av_lfg_get(&perms->lfg) & 1 ? RW : RO; break; - case MODE_RO: out_perm = RO; break; - case MODE_RW: out_perm = RW; break; - default: out_perm = in_perm; break; - } - - av_log(ctx, AV_LOG_VERBOSE, "%s -> %s%s\n", - perm_str[in_perm], perm_str[out_perm], - in_perm == out_perm ? " (no-op)" : ""); - - if (in_perm == RO && out_perm == RW) { - if ((ret = av_frame_make_writable(frame)) < 0) - return ret; - } else if (in_perm == RW && out_perm == RO) { - out = av_frame_clone(frame); - if (!out) - return AVERROR(ENOMEM); - } - - ret = ff_filter_frame(ctx->outputs[0], out); - - if (in_perm == RW && out_perm == RO) - av_frame_free(&frame); - return ret; -} - -#if CONFIG_APERMS_FILTER - -#define aperms_options options -AVFILTER_DEFINE_CLASS(aperms); - -static const AVFilterPad aperms_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad aperms_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_aperms = { - .name = "aperms", - .description = NULL_IF_CONFIG_SMALL("Set permissions for the output audio frame."), - .init = init, - .priv_size = sizeof(PermsContext), - .inputs = aperms_inputs, - .outputs = aperms_outputs, - .priv_class = &aperms_class, -}; -#endif /* CONFIG_APERMS_FILTER */ - -#if CONFIG_PERMS_FILTER - -#define perms_options options -AVFILTER_DEFINE_CLASS(perms); - -static const AVFilterPad perms_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad perms_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_perms = { - .name = "perms", - .description = NULL_IF_CONFIG_SMALL("Set permissions for the output video frame."), - .init = init, - .priv_size = sizeof(PermsContext), - .inputs = perms_inputs, - .outputs = perms_outputs, - .priv_class = &perms_class, -}; -#endif /* CONFIG_PERMS_FILTER */ diff --git a/ffmpeg/libavfilter/f_select.c b/ffmpeg/libavfilter/f_select.c deleted file mode 100644 index ec84da8..0000000 --- a/ffmpeg/libavfilter/f_select.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * filter for selecting which frame passes in the filterchain - */ - -#include "libavutil/avstring.h" -#include "libavutil/eval.h" -#include "libavutil/fifo.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "audio.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#if CONFIG_AVCODEC -#include "libavcodec/dsputil.h" -#endif - -static const char *const var_names[] = { - "TB", ///< timebase - - "pts", ///< original pts in the file of the frame - "start_pts", ///< first PTS in the stream, expressed in TB units - "prev_pts", ///< previous frame PTS - "prev_selected_pts", ///< previous selected frame PTS - - "t", ///< first PTS in seconds - "start_t", ///< first PTS in the stream, expressed in seconds - "prev_t", ///< previous frame time - "prev_selected_t", ///< previously selected time - - "pict_type", ///< the type of picture in the movie - "I", - "P", - "B", - "S", - "SI", - "SP", - "BI", - "PICT_TYPE_I", - "PICT_TYPE_P", - "PICT_TYPE_B", - "PICT_TYPE_S", - "PICT_TYPE_SI", - "PICT_TYPE_SP", - "PICT_TYPE_BI", - - "interlace_type", ///< the frame interlace type - "PROGRESSIVE", - "TOPFIRST", - "BOTTOMFIRST", - - "consumed_samples_n",///< number of samples consumed by the filter (only audio) - "samples_n", ///< number of samples in the current frame (only audio) - "sample_rate", ///< sample rate (only audio) - - "n", ///< frame number (starting from zero) - "selected_n", ///< selected frame number (starting from zero) - "prev_selected_n", ///< number of the last selected frame - - "key", ///< tell if the frame is a key frame - "pos", ///< original position in the file of the frame - - "scene", - - NULL -}; - -enum var_name { - VAR_TB, - - VAR_PTS, - VAR_START_PTS, - VAR_PREV_PTS, - VAR_PREV_SELECTED_PTS, - - VAR_T, - VAR_START_T, - VAR_PREV_T, - VAR_PREV_SELECTED_T, - - VAR_PICT_TYPE, - VAR_I, - VAR_P, - VAR_B, - VAR_S, - VAR_SI, - VAR_SP, - VAR_BI, - VAR_PICT_TYPE_I, - VAR_PICT_TYPE_P, - VAR_PICT_TYPE_B, - VAR_PICT_TYPE_S, - VAR_PICT_TYPE_SI, - VAR_PICT_TYPE_SP, - VAR_PICT_TYPE_BI, - - VAR_INTERLACE_TYPE, - VAR_INTERLACE_TYPE_P, - VAR_INTERLACE_TYPE_T, - VAR_INTERLACE_TYPE_B, - - VAR_CONSUMED_SAMPLES_N, - VAR_SAMPLES_N, - VAR_SAMPLE_RATE, - - VAR_N, - VAR_SELECTED_N, - VAR_PREV_SELECTED_N, - - VAR_KEY, - VAR_POS, - - VAR_SCENE, - - VAR_VARS_NB -}; - -typedef struct { - const AVClass *class; - char *expr_str; - AVExpr *expr; - double var_values[VAR_VARS_NB]; - int do_scene_detect; ///< 1 if the expression requires scene detection variables, 0 otherwise -#if CONFIG_AVCODEC - AVCodecContext *avctx; ///< codec context required for the DSPContext (scene detect only) - DSPContext c; ///< context providing optimized SAD methods (scene detect only) - double prev_mafd; ///< previous MAFD (scene detect only) -#endif - AVFrame *prev_picref; ///< previous frame (scene detect only) - double select; - int select_out; ///< mark the selected output pad index - int nb_outputs; -} SelectContext; - -#define OFFSET(x) offsetof(SelectContext, x) -#define DEFINE_OPTIONS(filt_name, FLAGS) \ -static const AVOption filt_name##_options[] = { \ - { "expr", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \ - { "e", "set an expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags=FLAGS }, \ - { "outputs", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \ - { "n", "set the number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, .flags=FLAGS }, \ - { NULL } \ -} - -static int request_frame(AVFilterLink *outlink); - -static av_cold int init(AVFilterContext *ctx) -{ - SelectContext *select = ctx->priv; - int i, ret; - - if ((ret = av_expr_parse(&select->expr, select->expr_str, - var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", - select->expr_str); - return ret; - } - select->do_scene_detect = !!strstr(select->expr_str, "scene"); - - for (i = 0; i < select->nb_outputs; i++) { - AVFilterPad pad = { 0 }; - - pad.name = av_asprintf("output%d", i); - if (!pad.name) - return AVERROR(ENOMEM); - pad.type = ctx->filter->inputs[0].type; - pad.request_frame = request_frame; - ff_insert_outpad(ctx, i, &pad); - } - - return 0; -} - -#define INTERLACE_TYPE_P 0 -#define INTERLACE_TYPE_T 1 -#define INTERLACE_TYPE_B 2 - -static int config_input(AVFilterLink *inlink) -{ - SelectContext *select = inlink->dst->priv; - - select->var_values[VAR_N] = 0.0; - select->var_values[VAR_SELECTED_N] = 0.0; - - select->var_values[VAR_TB] = av_q2d(inlink->time_base); - - select->var_values[VAR_PREV_PTS] = NAN; - select->var_values[VAR_PREV_SELECTED_PTS] = NAN; - select->var_values[VAR_PREV_SELECTED_T] = NAN; - select->var_values[VAR_PREV_T] = NAN; - select->var_values[VAR_START_PTS] = NAN; - select->var_values[VAR_START_T] = NAN; - - select->var_values[VAR_I] = AV_PICTURE_TYPE_I; - select->var_values[VAR_P] = AV_PICTURE_TYPE_P; - select->var_values[VAR_B] = AV_PICTURE_TYPE_B; - select->var_values[VAR_SI] = AV_PICTURE_TYPE_SI; - select->var_values[VAR_SP] = AV_PICTURE_TYPE_SP; - select->var_values[VAR_BI] = AV_PICTURE_TYPE_BI; - select->var_values[VAR_PICT_TYPE_I] = AV_PICTURE_TYPE_I; - select->var_values[VAR_PICT_TYPE_P] = AV_PICTURE_TYPE_P; - select->var_values[VAR_PICT_TYPE_B] = AV_PICTURE_TYPE_B; - select->var_values[VAR_PICT_TYPE_SI] = AV_PICTURE_TYPE_SI; - select->var_values[VAR_PICT_TYPE_SP] = AV_PICTURE_TYPE_SP; - select->var_values[VAR_PICT_TYPE_BI] = AV_PICTURE_TYPE_BI; - - select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P; - select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T; - select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B; - - select->var_values[VAR_PICT_TYPE] = NAN; - select->var_values[VAR_INTERLACE_TYPE] = NAN; - select->var_values[VAR_SCENE] = NAN; - select->var_values[VAR_CONSUMED_SAMPLES_N] = NAN; - select->var_values[VAR_SAMPLES_N] = NAN; - - select->var_values[VAR_SAMPLE_RATE] = - inlink->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN; - -#if CONFIG_AVCODEC - if (select->do_scene_detect) { - select->avctx = avcodec_alloc_context3(NULL); - if (!select->avctx) - return AVERROR(ENOMEM); - avpriv_dsputil_init(&select->c, select->avctx); - } -#endif - return 0; -} - -#if CONFIG_AVCODEC -static double get_scene_score(AVFilterContext *ctx, AVFrame *frame) -{ - double ret = 0; - SelectContext *select = ctx->priv; - AVFrame *prev_picref = select->prev_picref; - - if (prev_picref && - frame->height == prev_picref->height && - frame->width == prev_picref->width && - frame->linesize[0] == prev_picref->linesize[0]) { - int x, y, nb_sad = 0; - int64_t sad = 0; - double mafd, diff; - uint8_t *p1 = frame->data[0]; - uint8_t *p2 = prev_picref->data[0]; - const int linesize = frame->linesize[0]; - - for (y = 0; y < frame->height - 8; y += 8) { - for (x = 0; x < frame->width*3 - 8; x += 8) { - sad += select->c.sad[1](select, p1 + x, p2 + x, - linesize, 8); - nb_sad += 8 * 8; - } - p1 += 8 * linesize; - p2 += 8 * linesize; - } - emms_c(); - mafd = nb_sad ? sad / nb_sad : 0; - diff = fabs(mafd - select->prev_mafd); - ret = av_clipf(FFMIN(mafd, diff) / 100., 0, 1); - select->prev_mafd = mafd; - av_frame_free(&prev_picref); - } - select->prev_picref = av_frame_clone(frame); - return ret; -} -#endif - -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) - -static void select_frame(AVFilterContext *ctx, AVFrame *frame) -{ - SelectContext *select = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - double res; - - if (isnan(select->var_values[VAR_START_PTS])) - select->var_values[VAR_START_PTS] = TS2D(frame->pts); - if (isnan(select->var_values[VAR_START_T])) - select->var_values[VAR_START_T] = TS2D(frame->pts) * av_q2d(inlink->time_base); - - select->var_values[VAR_N ] = inlink->frame_count; - select->var_values[VAR_PTS] = TS2D(frame->pts); - select->var_values[VAR_T ] = TS2D(frame->pts) * av_q2d(inlink->time_base); - select->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? NAN : av_frame_get_pkt_pos(frame); - - switch (inlink->type) { - case AVMEDIA_TYPE_AUDIO: - select->var_values[VAR_SAMPLES_N] = frame->nb_samples; - break; - - case AVMEDIA_TYPE_VIDEO: - select->var_values[VAR_INTERLACE_TYPE] = - !frame->interlaced_frame ? INTERLACE_TYPE_P : - frame->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B; - select->var_values[VAR_PICT_TYPE] = frame->pict_type; -#if CONFIG_AVCODEC - if (select->do_scene_detect) { - char buf[32]; - select->var_values[VAR_SCENE] = get_scene_score(ctx, frame); - // TODO: document metadata - snprintf(buf, sizeof(buf), "%f", select->var_values[VAR_SCENE]); - av_dict_set(avpriv_frame_get_metadatap(frame), "lavfi.scene_score", buf, 0); - } -#endif - break; - } - - select->select = res = av_expr_eval(select->expr, select->var_values, NULL); - av_log(inlink->dst, AV_LOG_DEBUG, - "n:%f pts:%f t:%f key:%d", - select->var_values[VAR_N], - select->var_values[VAR_PTS], - select->var_values[VAR_T], - (int)select->var_values[VAR_KEY]); - - switch (inlink->type) { - case AVMEDIA_TYPE_VIDEO: - av_log(inlink->dst, AV_LOG_DEBUG, " interlace_type:%c pict_type:%c scene:%f", - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' : - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' : - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?', - av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]), - select->var_values[VAR_SCENE]); - break; - case AVMEDIA_TYPE_AUDIO: - av_log(inlink->dst, AV_LOG_DEBUG, " samples_n:%d consumed_samples_n:%d", - (int)select->var_values[VAR_SAMPLES_N], - (int)select->var_values[VAR_CONSUMED_SAMPLES_N]); - break; - } - - if (res == 0) { - select->select_out = -1; /* drop */ - } else if (isnan(res) || res < 0) { - select->select_out = 0; /* first output */ - } else { - select->select_out = FFMIN(ceilf(res)-1, select->nb_outputs-1); /* other outputs */ - } - - av_log(inlink->dst, AV_LOG_DEBUG, " -> select:%f select_out:%d\n", res, select->select_out); - - if (res) { - select->var_values[VAR_PREV_SELECTED_N] = select->var_values[VAR_N]; - select->var_values[VAR_PREV_SELECTED_PTS] = select->var_values[VAR_PTS]; - select->var_values[VAR_PREV_SELECTED_T] = select->var_values[VAR_T]; - select->var_values[VAR_SELECTED_N] += 1.0; - if (inlink->type == AVMEDIA_TYPE_AUDIO) - select->var_values[VAR_CONSUMED_SAMPLES_N] += frame->nb_samples; - } - - select->var_values[VAR_PREV_PTS] = select->var_values[VAR_PTS]; - select->var_values[VAR_PREV_T] = select->var_values[VAR_T]; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - SelectContext *select = ctx->priv; - - select_frame(ctx, frame); - if (select->select) - return ff_filter_frame(ctx->outputs[select->select_out], frame); - - av_frame_free(&frame); - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - SelectContext *select = ctx->priv; - AVFilterLink *inlink = outlink->src->inputs[0]; - int out_no = FF_OUTLINK_IDX(outlink); - - do { - int ret = ff_request_frame(inlink); - if (ret < 0) - return ret; - } while (select->select_out != out_no); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - SelectContext *select = ctx->priv; - int i; - - av_expr_free(select->expr); - select->expr = NULL; - - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); - -#if CONFIG_AVCODEC - if (select->do_scene_detect) { - av_frame_free(&select->prev_picref); - if (select->avctx) { - avcodec_close(select->avctx); - av_freep(&select->avctx); - } - } -#endif -} - -static int query_formats(AVFilterContext *ctx) -{ - SelectContext *select = ctx->priv; - - if (!select->do_scene_detect) { - return ff_default_query_formats(ctx); - } else { - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - } - return 0; -} - -#if CONFIG_ASELECT_FILTER - -DEFINE_OPTIONS(aselect, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM); -AVFILTER_DEFINE_CLASS(aselect); - -static av_cold int aselect_init(AVFilterContext *ctx) -{ - SelectContext *select = ctx->priv; - int ret; - - if ((ret = init(ctx)) < 0) - return ret; - - if (select->do_scene_detect) { - av_log(ctx, AV_LOG_ERROR, "Scene detection is ignored in aselect filter\n"); - return AVERROR(EINVAL); - } - - return 0; -} - -static const AVFilterPad avfilter_af_aselect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_af_aselect = { - .name = "aselect", - .description = NULL_IF_CONFIG_SMALL("Select audio frames to pass in output."), - .init = aselect_init, - .uninit = uninit, - .priv_size = sizeof(SelectContext), - .inputs = avfilter_af_aselect_inputs, - .priv_class = &aselect_class, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; -#endif /* CONFIG_ASELECT_FILTER */ - -#if CONFIG_SELECT_FILTER - -DEFINE_OPTIONS(select, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM); -AVFILTER_DEFINE_CLASS(select); - -static av_cold int select_init(AVFilterContext *ctx) -{ - SelectContext *select = ctx->priv; - int ret; - - if ((ret = init(ctx)) < 0) - return ret; - - if (select->do_scene_detect && !CONFIG_AVCODEC) { - av_log(ctx, AV_LOG_ERROR, "Scene detection is not available without libavcodec.\n"); - return AVERROR(EINVAL); - } - - return 0; -} - -static const AVFilterPad avfilter_vf_select_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_vf_select = { - .name = "select", - .description = NULL_IF_CONFIG_SMALL("Select video frames to pass in output."), - .init = select_init, - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(SelectContext), - .priv_class = &select_class, - .inputs = avfilter_vf_select_inputs, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; -#endif /* CONFIG_SELECT_FILTER */ diff --git a/ffmpeg/libavfilter/f_sendcmd.c b/ffmpeg/libavfilter/f_sendcmd.c deleted file mode 100644 index c30f49f..0000000 --- a/ffmpeg/libavfilter/f_sendcmd.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * send commands filter - */ - -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/file.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "internal.h" -#include "avfiltergraph.h" -#include "audio.h" -#include "video.h" - -#define COMMAND_FLAG_ENTER 1 -#define COMMAND_FLAG_LEAVE 2 - -static inline char *make_command_flags_str(AVBPrint *pbuf, int flags) -{ - static const char * const flag_strings[] = { "enter", "leave" }; - int i, is_first = 1; - - av_bprint_init(pbuf, 0, AV_BPRINT_SIZE_AUTOMATIC); - for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) { - if (flags & 1<<i) { - if (!is_first) - av_bprint_chars(pbuf, '+', 1); - av_bprintf(pbuf, "%s", flag_strings[i]); - is_first = 0; - } - } - - return pbuf->str; -} - -typedef struct { - int flags; - char *target, *command, *arg; - int index; -} Command; - -typedef struct { - int64_t start_ts; ///< start timestamp expressed as microseconds units - int64_t end_ts; ///< end timestamp expressed as microseconds units - int index; ///< unique index for these interval commands - Command *commands; - int nb_commands; - int enabled; ///< current time detected inside this interval -} Interval; - -typedef struct { - const AVClass *class; - Interval *intervals; - int nb_intervals; - - char *commands_filename; - char *commands_str; -} SendCmdContext; - -#define OFFSET(x) offsetof(SendCmdContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM -static const AVOption options[] = { - { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "c", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "filename", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "f", "set commands file", OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { NULL } -}; - -#define SPACES " \f\t\n\r" - -static void skip_comments(const char **buf) -{ - while (**buf) { - /* skip leading spaces */ - *buf += strspn(*buf, SPACES); - if (**buf != '#') - break; - - (*buf)++; - - /* skip comment until the end of line */ - *buf += strcspn(*buf, "\n"); - if (**buf) - (*buf)++; - } -} - -#define COMMAND_DELIMS " \f\t\n\r,;" - -static int parse_command(Command *cmd, int cmd_count, int interval_count, - const char **buf, void *log_ctx) -{ - int ret; - - memset(cmd, 0, sizeof(Command)); - cmd->index = cmd_count; - - /* format: [FLAGS] target command arg */ - *buf += strspn(*buf, SPACES); - - /* parse flags */ - if (**buf == '[') { - (*buf)++; /* skip "[" */ - - while (**buf) { - int len = strcspn(*buf, "|+]"); - - if (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER; - else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE; - else { - char flag_buf[64]; - av_strlcpy(flag_buf, *buf, sizeof(flag_buf)); - av_log(log_ctx, AV_LOG_ERROR, - "Unknown flag '%s' in interval #%d, command #%d\n", - flag_buf, interval_count, cmd_count); - return AVERROR(EINVAL); - } - *buf += len; - if (**buf == ']') - break; - if (!strspn(*buf, "+|")) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid flags char '%c' in interval #%d, command #%d\n", - **buf, interval_count, cmd_count); - return AVERROR(EINVAL); - } - if (**buf) - (*buf)++; - } - - if (**buf != ']') { - av_log(log_ctx, AV_LOG_ERROR, - "Missing flag terminator or extraneous data found at the end of flags " - "in interval #%d, command #%d\n", interval_count, cmd_count); - return AVERROR(EINVAL); - } - (*buf)++; /* skip "]" */ - } else { - cmd->flags = COMMAND_FLAG_ENTER; - } - - *buf += strspn(*buf, SPACES); - cmd->target = av_get_token(buf, COMMAND_DELIMS); - if (!cmd->target || !cmd->target[0]) { - av_log(log_ctx, AV_LOG_ERROR, - "No target specified in interval #%d, command #%d\n", - interval_count, cmd_count); - ret = AVERROR(EINVAL); - goto fail; - } - - *buf += strspn(*buf, SPACES); - cmd->command = av_get_token(buf, COMMAND_DELIMS); - if (!cmd->command || !cmd->command[0]) { - av_log(log_ctx, AV_LOG_ERROR, - "No command specified in interval #%d, command #%d\n", - interval_count, cmd_count); - ret = AVERROR(EINVAL); - goto fail; - } - - *buf += strspn(*buf, SPACES); - cmd->arg = av_get_token(buf, COMMAND_DELIMS); - - return 1; - -fail: - av_freep(&cmd->target); - av_freep(&cmd->command); - av_freep(&cmd->arg); - return ret; -} - -static int parse_commands(Command **cmds, int *nb_cmds, int interval_count, - const char **buf, void *log_ctx) -{ - int cmd_count = 0; - int ret, n = 0; - AVBPrint pbuf; - - *cmds = NULL; - *nb_cmds = 0; - - while (**buf) { - Command cmd; - - if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0) - return ret; - cmd_count++; - - /* (re)allocate commands array if required */ - if (*nb_cmds == n) { - n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */ - *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command)); - if (!*cmds) { - av_log(log_ctx, AV_LOG_ERROR, - "Could not (re)allocate command array\n"); - return AVERROR(ENOMEM); - } - } - - (*cmds)[(*nb_cmds)++] = cmd; - - *buf += strspn(*buf, SPACES); - if (**buf && **buf != ';' && **buf != ',') { - av_log(log_ctx, AV_LOG_ERROR, - "Missing separator or extraneous data found at the end of " - "interval #%d, in command #%d\n", - interval_count, cmd_count); - av_log(log_ctx, AV_LOG_ERROR, - "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n", - make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg); - return AVERROR(EINVAL); - } - if (**buf == ';') - break; - if (**buf == ',') - (*buf)++; - } - - return 0; -} - -#define DELIMS " \f\t\n\r,;" - -static int parse_interval(Interval *interval, int interval_count, - const char **buf, void *log_ctx) -{ - char *intervalstr; - int ret; - - *buf += strspn(*buf, SPACES); - if (!**buf) - return 0; - - /* reset data */ - memset(interval, 0, sizeof(Interval)); - interval->index = interval_count; - - /* format: INTERVAL COMMANDS */ - - /* parse interval */ - intervalstr = av_get_token(buf, DELIMS); - if (intervalstr && intervalstr[0]) { - char *start, *end; - - start = av_strtok(intervalstr, "-", &end); - if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid start time specification '%s' in interval #%d\n", - start, interval_count); - goto end; - } - - if (end) { - if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid end time specification '%s' in interval #%d\n", - end, interval_count); - goto end; - } - } else { - interval->end_ts = INT64_MAX; - } - if (interval->end_ts < interval->start_ts) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid end time '%s' in interval #%d: " - "cannot be lesser than start time '%s'\n", - end, interval_count, start); - ret = AVERROR(EINVAL); - goto end; - } - } else { - av_log(log_ctx, AV_LOG_ERROR, - "No interval specified for interval #%d\n", interval_count); - ret = AVERROR(EINVAL); - goto end; - } - - /* parse commands */ - ret = parse_commands(&interval->commands, &interval->nb_commands, - interval_count, buf, log_ctx); - -end: - av_free(intervalstr); - return ret; -} - -static int parse_intervals(Interval **intervals, int *nb_intervals, - const char *buf, void *log_ctx) -{ - int interval_count = 0; - int ret, n = 0; - - *intervals = NULL; - *nb_intervals = 0; - - while (1) { - Interval interval; - - skip_comments(&buf); - if (!(*buf)) - break; - - if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0) - return ret; - - buf += strspn(buf, SPACES); - if (*buf) { - if (*buf != ';') { - av_log(log_ctx, AV_LOG_ERROR, - "Missing terminator or extraneous data found at the end of interval #%d\n", - interval_count); - return AVERROR(EINVAL); - } - buf++; /* skip ';' */ - } - interval_count++; - - /* (re)allocate commands array if required */ - if (*nb_intervals == n) { - n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */ - *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval)); - if (!*intervals) { - av_log(log_ctx, AV_LOG_ERROR, - "Could not (re)allocate intervals array\n"); - return AVERROR(ENOMEM); - } - } - - (*intervals)[(*nb_intervals)++] = interval; - } - - return 0; -} - -static int cmp_intervals(const void *a, const void *b) -{ - const Interval *i1 = a; - const Interval *i2 = b; - int64_t ts_diff = i1->start_ts - i2->start_ts; - int ret; - - ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0; - return ret == 0 ? i1->index - i2->index : ret; -} - -static av_cold int init(AVFilterContext *ctx) -{ - SendCmdContext *sendcmd = ctx->priv; - int ret, i, j; - - if (sendcmd->commands_filename && sendcmd->commands_str) { - av_log(ctx, AV_LOG_ERROR, - "Only one of the filename or commands options must be specified\n"); - return AVERROR(EINVAL); - } - - if (sendcmd->commands_filename) { - uint8_t *file_buf, *buf; - size_t file_bufsize; - ret = av_file_map(sendcmd->commands_filename, - &file_buf, &file_bufsize, 0, ctx); - if (ret < 0) - return ret; - - /* create a 0-terminated string based on the read file */ - buf = av_malloc(file_bufsize + 1); - if (!buf) { - av_file_unmap(file_buf, file_bufsize); - return AVERROR(ENOMEM); - } - memcpy(buf, file_buf, file_bufsize); - buf[file_bufsize] = 0; - av_file_unmap(file_buf, file_bufsize); - sendcmd->commands_str = buf; - } - - if ((ret = parse_intervals(&sendcmd->intervals, &sendcmd->nb_intervals, - sendcmd->commands_str, ctx)) < 0) - return ret; - - qsort(sendcmd->intervals, sendcmd->nb_intervals, sizeof(Interval), cmp_intervals); - - av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n"); - for (i = 0; i < sendcmd->nb_intervals; i++) { - AVBPrint pbuf; - Interval *interval = &sendcmd->intervals[i]; - av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n", - (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index); - for (j = 0; j < interval->nb_commands; j++) { - Command *cmd = &interval->commands[j]; - av_log(ctx, AV_LOG_VERBOSE, - " [%s] target:%s command:%s arg:%s index:%d\n", - make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index); - } - } - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - SendCmdContext *sendcmd = ctx->priv; - int i, j; - - for (i = 0; i < sendcmd->nb_intervals; i++) { - Interval *interval = &sendcmd->intervals[i]; - for (j = 0; j < interval->nb_commands; j++) { - Command *cmd = &interval->commands[j]; - av_free(cmd->target); - av_free(cmd->command); - av_free(cmd->arg); - } - av_free(interval->commands); - } - av_freep(&sendcmd->intervals); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *ref) -{ - AVFilterContext *ctx = inlink->dst; - SendCmdContext *sendcmd = ctx->priv; - int64_t ts; - int i, j, ret; - - if (ref->pts == AV_NOPTS_VALUE) - goto end; - - ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q); - -#define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts)) - - for (i = 0; i < sendcmd->nb_intervals; i++) { - Interval *interval = &sendcmd->intervals[i]; - int flags = 0; - - if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) { - flags += COMMAND_FLAG_ENTER; - interval->enabled = 1; - } - if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) { - flags += COMMAND_FLAG_LEAVE; - interval->enabled = 0; - } - - if (flags) { - AVBPrint pbuf; - av_log(ctx, AV_LOG_VERBOSE, - "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n", - make_command_flags_str(&pbuf, flags), interval->index, - (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, - (double)ts/1000000); - - for (j = 0; flags && j < interval->nb_commands; j++) { - Command *cmd = &interval->commands[j]; - char buf[1024]; - - if (cmd->flags & flags) { - av_log(ctx, AV_LOG_VERBOSE, - "Processing command #%d target:%s command:%s arg:%s\n", - cmd->index, cmd->target, cmd->command, cmd->arg); - ret = avfilter_graph_send_command(inlink->graph, - cmd->target, cmd->command, cmd->arg, - buf, sizeof(buf), - AVFILTER_CMD_FLAG_ONE); - av_log(ctx, AV_LOG_VERBOSE, - "Command reply for command #%d: ret:%s res:%s\n", - cmd->index, av_err2str(ret), buf); - } - } - } - } - -end: - switch (inlink->type) { - case AVMEDIA_TYPE_VIDEO: - case AVMEDIA_TYPE_AUDIO: - return ff_filter_frame(inlink->dst->outputs[0], ref); - } - - return AVERROR(ENOSYS); -} - -#if CONFIG_SENDCMD_FILTER - -#define sendcmd_options options -AVFILTER_DEFINE_CLASS(sendcmd); - -static const AVFilterPad sendcmd_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad sendcmd_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_sendcmd = { - .name = "sendcmd", - .description = NULL_IF_CONFIG_SMALL("Send commands to filters."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(SendCmdContext), - .inputs = sendcmd_inputs, - .outputs = sendcmd_outputs, - .priv_class = &sendcmd_class, -}; - -#endif - -#if CONFIG_ASENDCMD_FILTER - -#define asendcmd_options options -AVFILTER_DEFINE_CLASS(asendcmd); - -static const AVFilterPad asendcmd_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad asendcmd_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - }, - { NULL } -}; - -AVFilter ff_af_asendcmd = { - .name = "asendcmd", - .description = NULL_IF_CONFIG_SMALL("Send commands to filters."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(SendCmdContext), - .inputs = asendcmd_inputs, - .outputs = asendcmd_outputs, - .priv_class = &asendcmd_class, -}; - -#endif diff --git a/ffmpeg/libavfilter/f_settb.c b/ffmpeg/libavfilter/f_settb.c deleted file mode 100644 index d511c14..0000000 --- a/ffmpeg/libavfilter/f_settb.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Set timebase for the output link. - */ - -#include <inttypes.h> -#include <stdio.h> - -#include "libavutil/avstring.h" -#include "libavutil/eval.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/rational.h" -#include "avfilter.h" -#include "internal.h" -#include "audio.h" -#include "video.h" - -static const char *const var_names[] = { - "AVTB", /* default timebase 1/AV_TIME_BASE */ - "intb", /* input timebase */ - "sr", /* sample rate */ - NULL -}; - -enum var_name { - VAR_AVTB, - VAR_INTB, - VAR_SR, - VAR_VARS_NB -}; - -typedef struct { - const AVClass *class; - char *tb_expr; - double var_values[VAR_VARS_NB]; -} SetTBContext; - -#define OFFSET(x) offsetof(SetTBContext, x) -#define DEFINE_OPTIONS(filt_name, filt_type) \ -static const AVOption filt_name##_options[] = { \ - { "expr", "set expression determining the output timebase", OFFSET(tb_expr), AV_OPT_TYPE_STRING, {.str="intb"}, \ - .flags=AV_OPT_FLAG_##filt_type##_PARAM|AV_OPT_FLAG_FILTERING_PARAM }, \ - { "tb", "set expression determining the output timebase", OFFSET(tb_expr), AV_OPT_TYPE_STRING, {.str="intb"}, \ - .flags=AV_OPT_FLAG_##filt_type##_PARAM|AV_OPT_FLAG_FILTERING_PARAM }, \ - { NULL } \ -} - -static int config_output_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - SetTBContext *settb = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - AVRational time_base; - int ret; - double res; - - settb->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q); - settb->var_values[VAR_INTB] = av_q2d(inlink->time_base); - settb->var_values[VAR_SR] = inlink->sample_rate; - - outlink->w = inlink->w; - outlink->h = inlink->h; - - if ((ret = av_expr_parse_and_eval(&res, settb->tb_expr, var_names, settb->var_values, - NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", settb->tb_expr); - return ret; - } - time_base = av_d2q(res, INT_MAX); - if (time_base.num <= 0 || time_base.den <= 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid non-positive values for the timebase num:%d or den:%d.\n", - time_base.num, time_base.den); - return AVERROR(EINVAL); - } - - outlink->time_base = time_base; - av_log(outlink->src, AV_LOG_VERBOSE, "tb:%d/%d -> tb:%d/%d\n", - inlink ->time_base.num, inlink ->time_base.den, - outlink->time_base.num, outlink->time_base.den); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - - if (av_cmp_q(inlink->time_base, outlink->time_base)) { - int64_t orig_pts = frame->pts; - frame->pts = av_rescale_q(frame->pts, inlink->time_base, outlink->time_base); - av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n", - inlink ->time_base.num, inlink ->time_base.den, orig_pts, - outlink->time_base.num, outlink->time_base.den, frame->pts); - } - - return ff_filter_frame(outlink, frame); -} - -#if CONFIG_SETTB_FILTER - -DEFINE_OPTIONS(settb, VIDEO); -AVFILTER_DEFINE_CLASS(settb); - -static const AVFilterPad avfilter_vf_settb_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_settb_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output_props, - }, - { NULL } -}; - -AVFilter ff_vf_settb = { - .name = "settb", - .description = NULL_IF_CONFIG_SMALL("Set timebase for the video output link."), - .priv_size = sizeof(SetTBContext), - .priv_class = &settb_class, - .inputs = avfilter_vf_settb_inputs, - .outputs = avfilter_vf_settb_outputs, -}; -#endif - -#if CONFIG_ASETTB_FILTER - -DEFINE_OPTIONS(asettb, AUDIO); -AVFILTER_DEFINE_CLASS(asettb); - -static const AVFilterPad avfilter_af_asettb_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_asettb_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .config_props = config_output_props, - }, - { NULL } -}; - -AVFilter ff_af_asettb = { - .name = "asettb", - .description = NULL_IF_CONFIG_SMALL("Set timebase for the audio output link."), - .priv_size = sizeof(SetTBContext), - .inputs = avfilter_af_asettb_inputs, - .outputs = avfilter_af_asettb_outputs, - .priv_class = &asettb_class, -}; -#endif diff --git a/ffmpeg/libavfilter/fifo.c b/ffmpeg/libavfilter/fifo.c deleted file mode 100644 index 5310af2..0000000 --- a/ffmpeg/libavfilter/fifo.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * FIFO buffering filter - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/mathematics.h" -#include "libavutil/samplefmt.h" - -#include "audio.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -typedef struct Buf { - AVFrame *frame; - struct Buf *next; -} Buf; - -typedef struct { - Buf root; - Buf *last; ///< last buffered frame - - /** - * When a specific number of output samples is requested, the partial - * buffer is stored here - */ - AVFrame *out; - int allocated_samples; ///< number of samples out was allocated for -} FifoContext; - -static av_cold int init(AVFilterContext *ctx) -{ - FifoContext *fifo = ctx->priv; - fifo->last = &fifo->root; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - FifoContext *fifo = ctx->priv; - Buf *buf, *tmp; - - for (buf = fifo->root.next; buf; buf = tmp) { - tmp = buf->next; - av_frame_free(&buf->frame); - av_free(buf); - } - - av_frame_free(&fifo->out); -} - -static int add_to_queue(AVFilterLink *inlink, AVFrame *frame) -{ - FifoContext *fifo = inlink->dst->priv; - - fifo->last->next = av_mallocz(sizeof(Buf)); - if (!fifo->last->next) { - av_frame_free(&frame); - return AVERROR(ENOMEM); - } - - fifo->last = fifo->last->next; - fifo->last->frame = frame; - - return 0; -} - -static void queue_pop(FifoContext *s) -{ - Buf *tmp = s->root.next->next; - if (s->last == s->root.next) - s->last = &s->root; - av_freep(&s->root.next); - s->root.next = tmp; -} - -/** - * Move data pointers and pts offset samples forward. - */ -static void buffer_offset(AVFilterLink *link, AVFrame *frame, - int offset) -{ - int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); - int planar = av_sample_fmt_is_planar(link->format); - int planes = planar ? nb_channels : 1; - int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels); - int i; - - av_assert0(frame->nb_samples > offset); - - for (i = 0; i < planes; i++) - frame->extended_data[i] += block_align * offset; - if (frame->data != frame->extended_data) - memcpy(frame->data, frame->extended_data, - FFMIN(planes, FF_ARRAY_ELEMS(frame->data)) * sizeof(*frame->data)); - frame->linesize[0] -= block_align*offset; - frame->nb_samples -= offset; - - if (frame->pts != AV_NOPTS_VALUE) { - frame->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate}, - link->time_base); - } -} - -static int calc_ptr_alignment(AVFrame *frame) -{ - int planes = av_sample_fmt_is_planar(frame->format) ? - av_get_channel_layout_nb_channels(frame->channel_layout) : 1; - int min_align = 128; - int p; - - for (p = 0; p < planes; p++) { - int cur_align = 128; - while ((intptr_t)frame->extended_data[p] % cur_align) - cur_align >>= 1; - if (cur_align < min_align) - min_align = cur_align; - } - return min_align; -} - -static int return_audio_frame(AVFilterContext *ctx) -{ - AVFilterLink *link = ctx->outputs[0]; - FifoContext *s = ctx->priv; - AVFrame *head = s->root.next ? s->root.next->frame : NULL; - AVFrame *out; - int ret; - - /* if head is NULL then we're flushing the remaining samples in out */ - if (!head && !s->out) - return AVERROR_EOF; - - if (!s->out && - head->nb_samples >= link->request_samples && - calc_ptr_alignment(head) >= 32) { - if (head->nb_samples == link->request_samples) { - out = head; - queue_pop(s); - } else { - out = av_frame_clone(head); - if (!out) - return AVERROR(ENOMEM); - - out->nb_samples = link->request_samples; - buffer_offset(link, head, link->request_samples); - } - } else { - int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); - - if (!s->out) { - s->out = ff_get_audio_buffer(link, link->request_samples); - if (!s->out) - return AVERROR(ENOMEM); - - s->out->nb_samples = 0; - s->out->pts = head->pts; - s->allocated_samples = link->request_samples; - } else if (link->request_samples != s->allocated_samples) { - av_log(ctx, AV_LOG_ERROR, "request_samples changed before the " - "buffer was returned.\n"); - return AVERROR(EINVAL); - } - - while (s->out->nb_samples < s->allocated_samples) { - int len; - - if (!s->root.next) { - ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF) { - av_samples_set_silence(s->out->extended_data, - s->out->nb_samples, - s->allocated_samples - - s->out->nb_samples, - nb_channels, link->format); - s->out->nb_samples = s->allocated_samples; - break; - } else if (ret < 0) - return ret; - av_assert0(s->root.next); // If ff_request_frame() succeeded then we should have a frame - } - head = s->root.next->frame; - - len = FFMIN(s->allocated_samples - s->out->nb_samples, - head->nb_samples); - - av_samples_copy(s->out->extended_data, head->extended_data, - s->out->nb_samples, 0, len, nb_channels, - link->format); - s->out->nb_samples += len; - - if (len == head->nb_samples) { - av_frame_free(&head); - queue_pop(s); - } else { - buffer_offset(link, head, len); - } - } - out = s->out; - s->out = NULL; - } - return ff_filter_frame(link, out); -} - -static int request_frame(AVFilterLink *outlink) -{ - FifoContext *fifo = outlink->src->priv; - int ret = 0; - - if (!fifo->root.next) { - if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) { - if (ret == AVERROR_EOF && outlink->request_samples) - return return_audio_frame(outlink->src); - return ret; - } - av_assert0(fifo->root.next); - } - - if (outlink->request_samples) { - return return_audio_frame(outlink->src); - } else { - ret = ff_filter_frame(outlink, fifo->root.next->frame); - queue_pop(fifo); - } - - return ret; -} - -static const AVFilterPad avfilter_vf_fifo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = add_to_queue, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_fifo_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_fifo = { - .name = "fifo", - .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."), - - .init = init, - .uninit = uninit, - - .priv_size = sizeof(FifoContext), - - .inputs = avfilter_vf_fifo_inputs, - .outputs = avfilter_vf_fifo_outputs, -}; - -static const AVFilterPad avfilter_af_afifo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = add_to_queue, - }, - { NULL } -}; - -static const AVFilterPad avfilter_af_afifo_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_af_afifo = { - .name = "afifo", - .description = NULL_IF_CONFIG_SMALL("Buffer input frames and send them when they are requested."), - - .init = init, - .uninit = uninit, - - .priv_size = sizeof(FifoContext), - - .inputs = avfilter_af_afifo_inputs, - .outputs = avfilter_af_afifo_outputs, -}; diff --git a/ffmpeg/libavfilter/filtfmts.c b/ffmpeg/libavfilter/filtfmts.c deleted file mode 100644 index e6c9b03..0000000 --- a/ffmpeg/libavfilter/filtfmts.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2009 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> - -#include "libavformat/avformat.h" -#include "libavutil/pixdesc.h" -#include "libavutil/samplefmt.h" -#include "libavfilter/avfilter.h" -#include "libavfilter/formats.h" - -static void print_formats(AVFilterContext *filter_ctx) -{ - int i, j; - -#define PRINT_FMTS(inout, outin, INOUT) \ - for (i = 0; i < filter_ctx->nb_##inout##puts; i++) { \ - if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) { \ - AVFilterFormats *fmts = \ - filter_ctx->inout##puts[i]->outin##_formats; \ - for (j = 0; j < fmts->nb_formats; j++) \ - if(av_get_pix_fmt_name(fmts->formats[j])) \ - printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ - av_get_pix_fmt_name(fmts->formats[j])); \ - } else if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_AUDIO) { \ - AVFilterFormats *fmts; \ - AVFilterChannelLayouts *layouts; \ - \ - fmts = filter_ctx->inout##puts[i]->outin##_formats; \ - for (j = 0; j < fmts->nb_formats; j++) \ - printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ - av_get_sample_fmt_name(fmts->formats[j])); \ - \ - layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \ - for (j = 0; j < layouts->nb_channel_layouts; j++) { \ - char buf[256]; \ - av_get_channel_layout_string(buf, sizeof(buf), -1, \ - layouts->channel_layouts[j]); \ - printf(#INOUT "PUT[%d] %s: chlayout:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, buf); \ - } \ - } \ - } \ - - PRINT_FMTS(in, out, IN); - PRINT_FMTS(out, in, OUT); -} - -int main(int argc, char **argv) -{ - AVFilter *filter; - AVFilterContext *filter_ctx; - AVFilterGraph *graph_ctx; - const char *filter_name; - const char *filter_args = NULL; - int i; - - av_log_set_level(AV_LOG_DEBUG); - - if (argc < 2) { - fprintf(stderr, "Missing filter name as argument\n"); - return 1; - } - - filter_name = argv[1]; - if (argc > 2) - filter_args = argv[2]; - - /* allocate graph */ - graph_ctx = avfilter_graph_alloc(); - if (!graph_ctx) - return 1; - - avfilter_register_all(); - - /* get a corresponding filter and open it */ - if (!(filter = avfilter_get_by_name(filter_name))) { - fprintf(stderr, "Unrecognized filter with name '%s'\n", filter_name); - return 1; - } - - /* open filter and add it to the graph */ - if (!(filter_ctx = avfilter_graph_alloc_filter(graph_ctx, filter, filter_name))) { - fprintf(stderr, "Impossible to open filter with name '%s'\n", - filter_name); - return 1; - } - if (avfilter_init_str(filter_ctx, filter_args) < 0) { - fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n", - filter_name, filter_args); - return 1; - } - - /* create a link for each of the input pads */ - for (i = 0; i < filter_ctx->nb_inputs; i++) { - AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->inputs[i].type; - filter_ctx->inputs[i] = link; - } - for (i = 0; i < filter_ctx->nb_outputs; i++) { - AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->outputs[i].type; - filter_ctx->outputs[i] = link; - } - - if (filter->query_formats) - filter->query_formats(filter_ctx); - else - ff_default_query_formats(filter_ctx); - - print_formats(filter_ctx); - - avfilter_free(filter_ctx); - avfilter_graph_free(&graph_ctx); - fflush(stdout); - return 0; -} diff --git a/ffmpeg/libavfilter/formats.c b/ffmpeg/libavfilter/formats.c deleted file mode 100644 index 5816032..0000000 --- a/ffmpeg/libavfilter/formats.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Filter layer - format negotiation - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/pixdesc.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "internal.h" -#include "formats.h" - -#define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */ - -/** - * Add all refs from a to ret and destroy a. - */ -#define MERGE_REF(ret, a, fmts, type, fail) \ -do { \ - type ***tmp; \ - int i; \ - \ - if (!(tmp = av_realloc(ret->refs, \ - sizeof(*tmp) * (ret->refcount + a->refcount)))) \ - goto fail; \ - ret->refs = tmp; \ - \ - for (i = 0; i < a->refcount; i ++) { \ - ret->refs[ret->refcount] = a->refs[i]; \ - *ret->refs[ret->refcount++] = ret; \ - } \ - \ - av_freep(&a->refs); \ - av_freep(&a->fmts); \ - av_freep(&a); \ -} while (0) - -/** - * Add all formats common for a and b to ret, copy the refs and destroy - * a and b. - */ -#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \ -do { \ - int i, j, k = 0, count = FFMIN(a->nb, b->nb); \ - \ - if (!(ret = av_mallocz(sizeof(*ret)))) \ - goto fail; \ - \ - if (count) { \ - if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \ - goto fail; \ - for (i = 0; i < a->nb; i++) \ - for (j = 0; j < b->nb; j++) \ - if (a->fmts[i] == b->fmts[j]) { \ - if(k >= FFMIN(a->nb, b->nb)){ \ - av_log(NULL, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \ - av_free(ret->fmts); \ - av_free(ret); \ - return NULL; \ - } \ - ret->fmts[k++] = a->fmts[i]; \ - } \ - } \ - ret->nb = k; \ - /* check that there was at least one common format */ \ - if (!ret->nb) \ - goto fail; \ - \ - MERGE_REF(ret, a, fmts, type, fail); \ - MERGE_REF(ret, b, fmts, type, fail); \ -} while (0) - -AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type) -{ - AVFilterFormats *ret = NULL; - int i, j; - int alpha1=0, alpha2=0; - int chroma1=0, chroma2=0; - - if (a == b) - return a; - - /* Do not lose chroma or alpha in merging. - It happens if both lists have formats with chroma (resp. alpha), but - the only formats in common do not have it (e.g. YUV+gray vs. - RGB+gray): in that case, the merging would select the gray format, - possibly causing a lossy conversion elsewhere in the graph. - To avoid that, pretend that there are no common formats to force the - insertion of a conversion filter. */ - if (type == AVMEDIA_TYPE_VIDEO) - for (i = 0; i < a->nb_formats; i++) - for (j = 0; j < b->nb_formats; j++) { - const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]); - const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]); - alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA; - chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1; - if (a->formats[i] == b->formats[j]) { - alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA; - chroma1|= adesc->nb_components > 1; - } - } - - // If chroma or alpha can be lost through merging then do not merge - if (alpha2 > alpha1 || chroma2 > chroma1) - return NULL; - - MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); - - return ret; -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->formats); - } - av_freep(&ret); - return NULL; -} - -AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a, - AVFilterFormats *b) -{ - AVFilterFormats *ret = NULL; - - if (a == b) return a; - - if (a->nb_formats && b->nb_formats) { - MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail); - } else if (a->nb_formats) { - MERGE_REF(a, b, formats, AVFilterFormats, fail); - ret = a; - } else { - MERGE_REF(b, a, formats, AVFilterFormats, fail); - ret = b; - } - - return ret; -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->formats); - } - av_freep(&ret); - return NULL; -} - -AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b) -{ - AVFilterChannelLayouts *ret = NULL; - unsigned a_all = a->all_layouts + a->all_counts; - unsigned b_all = b->all_layouts + b->all_counts; - int ret_max, ret_nb = 0, i, j, round; - - if (a == b) return a; - - /* Put the most generic set in a, to avoid doing everything twice */ - if (a_all < b_all) { - FFSWAP(AVFilterChannelLayouts *, a, b); - FFSWAP(unsigned, a_all, b_all); - } - if (a_all) { - if (a_all == 1 && !b_all) { - /* keep only known layouts in b; works also for b_all = 1 */ - for (i = j = 0; i < b->nb_channel_layouts; i++) - if (KNOWN(b->channel_layouts[i])) - b->channel_layouts[j++] = b->channel_layouts[i]; - /* Not optimal: the unknown layouts of b may become known after - another merge. */ - if (!j) - return NULL; - b->nb_channel_layouts = j; - } - MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail); - return b; - } - - ret_max = a->nb_channel_layouts + b->nb_channel_layouts; - if (!(ret = av_mallocz(sizeof(*ret))) || - !(ret->channel_layouts = av_malloc(sizeof(*ret->channel_layouts) * - ret_max))) - goto fail; - - /* a[known] intersect b[known] */ - for (i = 0; i < a->nb_channel_layouts; i++) { - if (!KNOWN(a->channel_layouts[i])) - continue; - for (j = 0; j < b->nb_channel_layouts; j++) { - if (a->channel_layouts[i] == b->channel_layouts[j]) { - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; - a->channel_layouts[i] = b->channel_layouts[j] = 0; - } - } - } - /* 1st round: a[known] intersect b[generic] - 2nd round: a[generic] intersect b[known] */ - for (round = 0; round < 2; round++) { - for (i = 0; i < a->nb_channel_layouts; i++) { - uint64_t fmt = a->channel_layouts[i], bfmt; - if (!fmt || !KNOWN(fmt)) - continue; - bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt)); - for (j = 0; j < b->nb_channel_layouts; j++) - if (b->channel_layouts[j] == bfmt) - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; - } - /* 1st round: swap to prepare 2nd round; 2nd round: put it back */ - FFSWAP(AVFilterChannelLayouts *, a, b); - } - /* a[generic] intersect b[generic] */ - for (i = 0; i < a->nb_channel_layouts; i++) { - if (KNOWN(a->channel_layouts[i])) - continue; - for (j = 0; j < b->nb_channel_layouts; j++) - if (a->channel_layouts[i] == b->channel_layouts[j]) - ret->channel_layouts[ret_nb++] = a->channel_layouts[i]; - } - - ret->nb_channel_layouts = ret_nb; - if (!ret->nb_channel_layouts) - goto fail; - MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail); - MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail); - return ret; - -fail: - if (ret) { - av_freep(&ret->refs); - av_freep(&ret->channel_layouts); - } - av_freep(&ret); - return NULL; -} - -int ff_fmt_is_in(int fmt, const int *fmts) -{ - const int *p; - - for (p = fmts; *p != -1; p++) { - if (fmt == *p) - return 1; - } - return 0; -} - -#define COPY_INT_LIST(list_copy, list, type) { \ - int count = 0; \ - if (list) \ - for (count = 0; list[count] != -1; count++) \ - ; \ - list_copy = av_calloc(count+1, sizeof(type)); \ - if (list_copy) { \ - memcpy(list_copy, list, sizeof(type) * count); \ - list_copy[count] = -1; \ - } \ -} - -#define MAKE_FORMAT_LIST(type, field, count_field) \ - type *formats; \ - int count = 0; \ - if (fmts) \ - for (count = 0; fmts[count] != -1; count++) \ - ; \ - formats = av_mallocz(sizeof(*formats)); \ - if (!formats) return NULL; \ - formats->count_field = count; \ - if (count) { \ - formats->field = av_malloc(sizeof(*formats->field)*count); \ - if (!formats->field) { \ - av_free(formats); \ - return NULL; \ - } \ - } - -AVFilterFormats *ff_make_format_list(const int *fmts) -{ - MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats); - while (count--) - formats->formats[count] = fmts[count]; - - return formats; -} - -AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts) -{ - MAKE_FORMAT_LIST(AVFilterChannelLayouts, - channel_layouts, nb_channel_layouts); - if (count) - memcpy(formats->channel_layouts, fmts, - sizeof(*formats->channel_layouts) * count); - - return formats; -} - -#define ADD_FORMAT(f, fmt, type, list, nb) \ -do { \ - type *fmts; \ - \ - if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \ - return AVERROR(ENOMEM); \ - \ - fmts = av_realloc((*f)->list, \ - sizeof(*(*f)->list) * ((*f)->nb + 1));\ - if (!fmts) \ - return AVERROR(ENOMEM); \ - \ - (*f)->list = fmts; \ - (*f)->list[(*f)->nb++] = fmt; \ -} while (0) - -int ff_add_format(AVFilterFormats **avff, int64_t fmt) -{ - ADD_FORMAT(avff, fmt, int, formats, nb_formats); - return 0; -} - -int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) -{ - av_assert1(!(*l && (*l)->all_layouts)); - ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts); - return 0; -} - -AVFilterFormats *ff_all_formats(enum AVMediaType type) -{ - AVFilterFormats *ret = NULL; - int fmt; - int num_formats = type == AVMEDIA_TYPE_VIDEO ? AV_PIX_FMT_NB : - type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0; - - for (fmt = 0; fmt < num_formats; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if ((type != AVMEDIA_TYPE_VIDEO) || - (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))) - ff_add_format(&ret, fmt); - } - - return ret; -} - -const int64_t avfilter_all_channel_layouts[] = { -#include "all_channel_layouts.inc" - -1 -}; - -// AVFilterFormats *avfilter_make_all_channel_layouts(void) -// { -// return avfilter_make_format64_list(avfilter_all_channel_layouts); -// } - -AVFilterFormats *ff_planar_sample_fmts(void) -{ - AVFilterFormats *ret = NULL; - int fmt; - - for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++) - if (av_sample_fmt_is_planar(fmt)) - ff_add_format(&ret, fmt); - - return ret; -} - -AVFilterFormats *ff_all_samplerates(void) -{ - AVFilterFormats *ret = av_mallocz(sizeof(*ret)); - return ret; -} - -AVFilterChannelLayouts *ff_all_channel_layouts(void) -{ - AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); - if (!ret) - return NULL; - ret->all_layouts = 1; - return ret; -} - -AVFilterChannelLayouts *ff_all_channel_counts(void) -{ - AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); - if (!ret) - return NULL; - ret->all_layouts = ret->all_counts = 1; - return ret; -} - -#define FORMATS_REF(f, ref) \ -do { \ - *ref = f; \ - f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \ - f->refs[f->refcount-1] = ref; \ -} while (0) - -void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref) -{ - FORMATS_REF(f, ref); -} - -void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) -{ - FORMATS_REF(f, ref); -} - -#define FIND_REF_INDEX(ref, idx) \ -do { \ - int i; \ - for (i = 0; i < (*ref)->refcount; i ++) \ - if((*ref)->refs[i] == ref) { \ - idx = i; \ - break; \ - } \ -} while (0) - -#define FORMATS_UNREF(ref, list) \ -do { \ - int idx = -1; \ - \ - if (!*ref) \ - return; \ - \ - FIND_REF_INDEX(ref, idx); \ - \ - if (idx >= 0) \ - memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \ - sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \ - \ - if(!--(*ref)->refcount) { \ - av_free((*ref)->list); \ - av_free((*ref)->refs); \ - av_free(*ref); \ - } \ - *ref = NULL; \ -} while (0) - -void ff_formats_unref(AVFilterFormats **ref) -{ - FORMATS_UNREF(ref, formats); -} - -void ff_channel_layouts_unref(AVFilterChannelLayouts **ref) -{ - FORMATS_UNREF(ref, channel_layouts); -} - -#define FORMATS_CHANGEREF(oldref, newref) \ -do { \ - int idx = -1; \ - \ - FIND_REF_INDEX(oldref, idx); \ - \ - if (idx >= 0) { \ - (*oldref)->refs[idx] = newref; \ - *newref = *oldref; \ - *oldref = NULL; \ - } \ -} while (0) - -void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, - AVFilterChannelLayouts **newref) -{ - FORMATS_CHANGEREF(oldref, newref); -} - -void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) -{ - FORMATS_CHANGEREF(oldref, newref); -} - -#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \ -{ \ - int count = 0, i; \ - \ - for (i = 0; i < ctx->nb_inputs; i++) { \ - if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) { \ - ref(fmts, &ctx->inputs[i]->out_fmts); \ - count++; \ - } \ - } \ - for (i = 0; i < ctx->nb_outputs; i++) { \ - if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) { \ - ref(fmts, &ctx->outputs[i]->in_fmts); \ - count++; \ - } \ - } \ - \ - if (!count) { \ - av_freep(&fmts->list); \ - av_freep(&fmts->refs); \ - av_freep(&fmts); \ - } \ -} - -void ff_set_common_channel_layouts(AVFilterContext *ctx, - AVFilterChannelLayouts *layouts) -{ - SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts, - ff_channel_layouts_ref, channel_layouts); -} - -void ff_set_common_samplerates(AVFilterContext *ctx, - AVFilterFormats *samplerates) -{ - SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates, - ff_formats_ref, formats); -} - -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - */ -void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) -{ - SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats, - ff_formats_ref, formats); -} - -static int default_query_formats_common(AVFilterContext *ctx, - AVFilterChannelLayouts *(layouts)(void)) -{ - enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : - ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : - AVMEDIA_TYPE_VIDEO; - - ff_set_common_formats(ctx, ff_all_formats(type)); - if (type == AVMEDIA_TYPE_AUDIO) { - ff_set_common_channel_layouts(ctx, layouts()); - ff_set_common_samplerates(ctx, ff_all_samplerates()); - } - - return 0; -} - -int ff_default_query_formats(AVFilterContext *ctx) -{ - return default_query_formats_common(ctx, ff_all_channel_layouts); -} - -int ff_query_formats_all(AVFilterContext *ctx) -{ - return default_query_formats_common(ctx, ff_all_channel_counts); -} - -/* internal functions for parsing audio format arguments */ - -int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx) -{ - char *tail; - int pix_fmt = av_get_pix_fmt(arg); - if (pix_fmt == AV_PIX_FMT_NONE) { - pix_fmt = strtol(arg, &tail, 0); - if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg); - return AVERROR(EINVAL); - } - } - *ret = pix_fmt; - return 0; -} - -int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx) -{ - char *tail; - int sfmt = av_get_sample_fmt(arg); - if (sfmt == AV_SAMPLE_FMT_NONE) { - sfmt = strtol(arg, &tail, 0); - if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); - return AVERROR(EINVAL); - } - } - *ret = sfmt; - return 0; -} - -int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx) -{ - AVRational r; - if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg); - return AVERROR(EINVAL); - } - *ret = r; - return 0; -} - -int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx) -{ - char *tail; - double srate = av_strtod(arg, &tail); - if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg); - return AVERROR(EINVAL); - } - *ret = srate; - return 0; -} - -int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, - void *log_ctx) -{ - char *tail; - int64_t chlayout, count; - - if (nret) { - count = strtol(arg, &tail, 10); - if (*tail == 'c' && !tail[1] && count > 0 && count < 63) { - *nret = count; - *ret = 0; - return 0; - } - } - chlayout = av_get_channel_layout(arg); - if (chlayout == 0) { - chlayout = strtol(arg, &tail, 10); - if (*tail || chlayout == 0) { - av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg); - return AVERROR(EINVAL); - } - } - *ret = chlayout; - if (nret) - *nret = av_get_channel_layout_nb_channels(chlayout); - return 0; -} - -#ifdef TEST - -#undef printf - -int main(void) -{ - const int64_t *cl; - char buf[512]; - - for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) { - av_get_channel_layout_string(buf, sizeof(buf), -1, *cl); - printf("%s\n", buf); - } - - return 0; -} - -#endif - diff --git a/ffmpeg/libavfilter/formats.h b/ffmpeg/libavfilter/formats.h deleted file mode 100644 index 468eac8..0000000 --- a/ffmpeg/libavfilter/formats.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_FORMATS_H -#define AVFILTER_FORMATS_H - -#include "avfilter.h" - -/** - * A list of supported formats for one end of a filter link. This is used - * during the format negotiation process to try to pick the best format to - * use to minimize the number of necessary conversions. Each filter gives a - * list of the formats supported by each input and output pad. The list - * given for each pad need not be distinct - they may be references to the - * same list of formats, as is often the case when a filter supports multiple - * formats, but will always output the same format as it is given in input. - * - * In this way, a list of possible input formats and a list of possible - * output formats are associated with each link. When a set of formats is - * negotiated over a link, the input and output lists are merged to form a - * new list containing only the common elements of each list. In the case - * that there were no common elements, a format conversion is necessary. - * Otherwise, the lists are merged, and all other links which reference - * either of the format lists involved in the merge are also affected. - * - * For example, consider the filter chain: - * filter (a) --> (b) filter (b) --> (c) filter - * - * where the letters in parenthesis indicate a list of formats supported on - * the input or output of the link. Suppose the lists are as follows: - * (a) = {A, B} - * (b) = {A, B, C} - * (c) = {B, C} - * - * First, the first link's lists are merged, yielding: - * filter (a) --> (a) filter (a) --> (c) filter - * - * Notice that format list (b) now refers to the same list as filter list (a). - * Next, the lists for the second link are merged, yielding: - * filter (a) --> (a) filter (a) --> (a) filter - * - * where (a) = {B}. - * - * Unfortunately, when the format lists at the two ends of a link are merged, - * we must ensure that all links which reference either pre-merge format list - * get updated as well. Therefore, we have the format list structure store a - * pointer to each of the pointers to itself. - */ -struct AVFilterFormats { - unsigned nb_formats; ///< number of formats - int *formats; ///< list of media formats - - unsigned refcount; ///< number of references to this list - struct AVFilterFormats ***refs; ///< references to this list -}; - -/** - * A list of supported channel layouts. - * - * The list works the same as AVFilterFormats, except for the following - * differences: - * - A list with all_layouts = 1 means all channel layouts with a known - * disposition; nb_channel_layouts must then be 0. - * - A list with all_counts = 1 means all channel counts, with a known or - * unknown disposition; nb_channel_layouts must then be 0 and all_layouts 1. - * - The list must not contain a layout with a known disposition and a - * channel count with unknown disposition with the same number of channels - * (e.g. AV_CH_LAYOUT_STEREO and FF_COUNT2LAYOUT(2). - */ -typedef struct AVFilterChannelLayouts { - uint64_t *channel_layouts; ///< list of channel layouts - int nb_channel_layouts; ///< number of channel layouts - char all_layouts; ///< accept any known channel layout - char all_counts; ///< accept any channel layout or count - - unsigned refcount; ///< number of references to this list - struct AVFilterChannelLayouts ***refs; ///< references to this list -} AVFilterChannelLayouts; - -/** - * Encode a channel count as a channel layout. - * FF_COUNT2LAYOUT(c) means any channel layout with c channels, with a known - * or unknown disposition. - * The result is only valid inside AVFilterChannelLayouts and immediately - * related functions. - */ -#define FF_COUNT2LAYOUT(c) (0x8000000000000000ULL | (c)) - -/** - * Decode a channel count encoded as a channel layout. - * Return 0 if the channel layout was a real one. - */ -#define FF_LAYOUT2COUNT(l) (((l) & 0x8000000000000000ULL) ? \ - (int)((l) & 0x7FFFFFFF) : 0) - -/** - * Return a channel layouts/samplerates list which contains the intersection of - * the layouts/samplerates of a and b. Also, all the references of a, all the - * references of b, and a and b themselves will be deallocated. - * - * If a and b do not share any common elements, neither is modified, and NULL - * is returned. - */ -AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a, - AVFilterChannelLayouts *b); -AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a, - AVFilterFormats *b); - -/** - * Construct an empty AVFilterChannelLayouts/AVFilterFormats struct -- - * representing any channel layout (with known disposition)/sample rate. - */ -AVFilterChannelLayouts *ff_all_channel_layouts(void); -AVFilterFormats *ff_all_samplerates(void); - -/** - * Construct an AVFilterChannelLayouts coding for any channel layout, with - * known or unknown disposition. - */ -AVFilterChannelLayouts *ff_all_channel_counts(void); - -AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts); - - -/** - * A helper for query_formats() which sets all links to the same list of channel - * layouts/sample rates. If there are no links hooked to this filter, the list - * is freed. - */ -void ff_set_common_channel_layouts(AVFilterContext *ctx, - AVFilterChannelLayouts *layouts); -void ff_set_common_samplerates(AVFilterContext *ctx, - AVFilterFormats *samplerates); - -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - */ -void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); - -int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout); - -/** - * Add *ref as a new reference to f. - */ -void ff_channel_layouts_ref(AVFilterChannelLayouts *f, - AVFilterChannelLayouts **ref); - -/** - * Remove a reference to a channel layouts list. - */ -void ff_channel_layouts_unref(AVFilterChannelLayouts **ref); - -void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, - AVFilterChannelLayouts **newref); - -int ff_default_query_formats(AVFilterContext *ctx); - -/** - * Set the formats list to all existing formats. - * This function behaves like ff_default_query_formats(), except it also - * accepts channel layouts with unknown disposition. It should only be used - * with audio filters. - */ -int ff_query_formats_all(AVFilterContext *ctx); - - -/** - * Create a list of supported formats. This is intended for use in - * AVFilter->query_formats(). - * - * @param fmts list of media formats, terminated by -1 - * @return the format list, with no existing references - */ -AVFilterFormats *ff_make_format_list(const int *fmts); - -/** - * Add fmt to the list of media formats contained in *avff. - * If *avff is NULL the function allocates the filter formats struct - * and puts its pointer in *avff. - * - * @return a non negative value in case of success, or a negative - * value corresponding to an AVERROR code in case of error - */ -int ff_add_format(AVFilterFormats **avff, int64_t fmt); - -/** - * Return a list of all formats supported by FFmpeg for the given media type. - */ -AVFilterFormats *ff_all_formats(enum AVMediaType type); - -/** - * Construct a formats list containing all planar sample formats. - */ -AVFilterFormats *ff_planar_sample_fmts(void); - -/** - * Return a format list which contains the intersection of the formats of - * a and b. Also, all the references of a, all the references of b, and - * a and b themselves will be deallocated. - * - * If a and b do not share any common formats, neither is modified, and NULL - * is returned. - */ -AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b, - enum AVMediaType type); - -/** - * Add *ref as a new reference to formats. - * That is the pointers will point like in the ascii art below: - * ________ - * |formats |<--------. - * | ____ | ____|___________________ - * | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| - * | |____| | | |____| - * |________| |________________________ - */ -void ff_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref); - -/** - * If *ref is non-NULL, remove *ref as a reference to the format list - * it currently points to, deallocates that list if this was the last - * reference, and sets *ref to NULL. - * - * Before After - * ________ ________ NULL - * |formats |<--------. |formats | ^ - * | ____ | ____|________________ | ____ | ____|________________ - * | |refs| | | __|_ | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| | |* | | | |*ref| - * | |____| | | |____| | |____| | | |____| - * |________| |_____________________ |________| |_____________________ - */ -void ff_formats_unref(AVFilterFormats **ref); - -/** - * - * Before After - * ________ ________ - * |formats |<---------. |formats |<---------. - * | ____ | ___|___ | ____ | ___|___ - * | |refs| | | | | | |refs| | | | | NULL - * | |* *--------->|*oldref| | |* *--------->|*newref| ^ - * | |* * | | |_______| | |* * | | |_______| ___|___ - * | |____| | | |____| | | | | - * |________| |________| |*oldref| - * |_______| - */ -void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref); - -#endif /* AVFILTER_FORMATS_H */ diff --git a/ffmpeg/libavfilter/gradfun.h b/ffmpeg/libavfilter/gradfun.h deleted file mode 100644 index eb1f1eb..0000000 --- a/ffmpeg/libavfilter/gradfun.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010 Nolan Lum <nol888@gmail.com> - * Copyright (c) 2009 Loren Merritt <lorenm@u.washington.edu> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_GRADFUN_H -#define AVFILTER_GRADFUN_H - -#include "avfilter.h" - -/// Holds instance-specific information for gradfun. -typedef struct GradFunContext { - const AVClass *class; - float strength; - int thresh; ///< threshold for gradient algorithm - int radius; ///< blur radius - int chroma_w; ///< width of the chroma planes - int chroma_h; ///< weight of the chroma planes - int chroma_r; ///< blur radius for the chroma planes - uint16_t *buf; ///< holds image data for blur algorithm passed into filter. - /// DSP functions. - void (*filter_line) (uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers); - void (*blur_line) (uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width); -} GradFunContext; - -void ff_gradfun_init_x86(GradFunContext *gf); - -void ff_gradfun_filter_line_c(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers); -void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width); - -#endif /* AVFILTER_GRADFUN_H */ diff --git a/ffmpeg/libavfilter/graphdump.c b/ffmpeg/libavfilter/graphdump.c deleted file mode 100644 index 1b59321..0000000 --- a/ffmpeg/libavfilter/graphdump.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Filter graphs to bad ASCII-art - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> - -#include "libavutil/channel_layout.h" -#include "libavutil/bprint.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "avfiltergraph.h" - -static int print_link_prop(AVBPrint *buf, AVFilterLink *link) -{ - char *format; - char layout[64]; - - if (!buf) - buf = &(AVBPrint){ 0 }; /* dummy buffer */ - switch (link->type) { - case AVMEDIA_TYPE_VIDEO: - format = av_x_if_null(av_get_pix_fmt_name(link->format), "?"); - av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h, - link->sample_aspect_ratio.num, - link->sample_aspect_ratio.den, - format); - break; - - case AVMEDIA_TYPE_AUDIO: - av_get_channel_layout_string(layout, sizeof(layout), - link->channels, link->channel_layout); - format = av_x_if_null(av_get_sample_fmt_name(link->format), "?"); - av_bprintf(buf, "[%dHz %s:%s]", - (int)link->sample_rate, format, layout); - break; - - default: - av_bprintf(buf, "?"); - break; - } - return buf->len; -} - -static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph) -{ - unsigned i, j, x, e; - - for (i = 0; i < graph->nb_filters; i++) { - AVFilterContext *filter = graph->filters[i]; - unsigned max_src_name = 0, max_dst_name = 0; - unsigned max_in_name = 0, max_out_name = 0; - unsigned max_in_fmt = 0, max_out_fmt = 0; - unsigned width, height, in_indent; - unsigned lname = strlen(filter->name); - unsigned ltype = strlen(filter->filter->name); - - for (j = 0; j < filter->nb_inputs; j++) { - AVFilterLink *l = filter->inputs[j]; - unsigned ln = strlen(l->src->name) + 1 + strlen(l->srcpad->name); - max_src_name = FFMAX(max_src_name, ln); - max_in_name = FFMAX(max_in_name, strlen(l->dstpad->name)); - max_in_fmt = FFMAX(max_in_fmt, print_link_prop(NULL, l)); - } - for (j = 0; j < filter->nb_outputs; j++) { - AVFilterLink *l = filter->outputs[j]; - unsigned ln = strlen(l->dst->name) + 1 + strlen(l->dstpad->name); - max_dst_name = FFMAX(max_dst_name, ln); - max_out_name = FFMAX(max_out_name, strlen(l->srcpad->name)); - max_out_fmt = FFMAX(max_out_fmt, print_link_prop(NULL, l)); - } - in_indent = max_src_name + max_in_name + max_in_fmt; - in_indent += in_indent ? 4 : 0; - width = FFMAX(lname + 2, ltype + 4); - height = FFMAX3(2, filter->nb_inputs, filter->nb_outputs); - av_bprint_chars(buf, ' ', in_indent); - av_bprintf(buf, "+"); - av_bprint_chars(buf, '-', width); - av_bprintf(buf, "+\n"); - for (j = 0; j < height; j++) { - unsigned in_no = j - (height - filter->nb_inputs ) / 2; - unsigned out_no = j - (height - filter->nb_outputs) / 2; - - /* Input link */ - if (in_no < filter->nb_inputs) { - AVFilterLink *l = filter->inputs[in_no]; - e = buf->len + max_src_name + 2; - av_bprintf(buf, "%s:%s", l->src->name, l->srcpad->name); - av_bprint_chars(buf, '-', e - buf->len); - e = buf->len + max_in_fmt + 2 + - max_in_name - strlen(l->dstpad->name); - print_link_prop(buf, l); - av_bprint_chars(buf, '-', e - buf->len); - av_bprintf(buf, "%s", l->dstpad->name); - } else { - av_bprint_chars(buf, ' ', in_indent); - } - - /* Filter */ - av_bprintf(buf, "|"); - if (j == (height - 2) / 2) { - x = (width - lname) / 2; - av_bprintf(buf, "%*s%-*s", x, "", width - x, filter->name); - } else if (j == (height - 2) / 2 + 1) { - x = (width - ltype - 2) / 2; - av_bprintf(buf, "%*s(%s)%*s", x, "", filter->filter->name, - width - ltype - 2 - x, ""); - } else { - av_bprint_chars(buf, ' ', width); - } - av_bprintf(buf, "|"); - - /* Output link */ - if (out_no < filter->nb_outputs) { - AVFilterLink *l = filter->outputs[out_no]; - unsigned ln = strlen(l->dst->name) + 1 + - strlen(l->dstpad->name); - e = buf->len + max_out_name + 2; - av_bprintf(buf, "%s", l->srcpad->name); - av_bprint_chars(buf, '-', e - buf->len); - e = buf->len + max_out_fmt + 2 + - max_dst_name - ln; - print_link_prop(buf, l); - av_bprint_chars(buf, '-', e - buf->len); - av_bprintf(buf, "%s:%s", l->dst->name, l->dstpad->name); - } - av_bprintf(buf, "\n"); - } - av_bprint_chars(buf, ' ', in_indent); - av_bprintf(buf, "+"); - av_bprint_chars(buf, '-', width); - av_bprintf(buf, "+\n"); - av_bprintf(buf, "\n"); - } -} - -char *avfilter_graph_dump(AVFilterGraph *graph, const char *options) -{ - AVBPrint buf; - char *dump; - - av_bprint_init(&buf, 0, 0); - avfilter_graph_dump_to_buf(&buf, graph); - av_bprint_init(&buf, buf.len + 1, buf.len + 1); - avfilter_graph_dump_to_buf(&buf, graph); - av_bprint_finalize(&buf, &dump); - return dump; -} diff --git a/ffmpeg/libavfilter/graphparser.c b/ffmpeg/libavfilter/graphparser.c deleted file mode 100644 index 7e25282..0000000 --- a/ffmpeg/libavfilter/graphparser.c +++ /dev/null @@ -1,607 +0,0 @@ -/* - * filter graph parser - * Copyright (c) 2008 Vitor Sessak - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> -#include <stdio.h> - -#include "libavutil/avstring.h" -#include "libavutil/mem.h" -#include "avfilter.h" - -#define WHITESPACES " \n\t" - -/** - * Link two filters together. - * - * @see avfilter_link() - */ -static int link_filter(AVFilterContext *src, int srcpad, - AVFilterContext *dst, int dstpad, - void *log_ctx) -{ - int ret; - if ((ret = avfilter_link(src, srcpad, dst, dstpad))) { - av_log(log_ctx, AV_LOG_ERROR, - "Cannot create the link %s:%d -> %s:%d\n", - src->filter->name, srcpad, dst->filter->name, dstpad); - return ret; - } - - return 0; -} - -/** - * Parse the name of a link, which has the format "[linkname]". - * - * @return a pointer (that need to be freed after use) to the name - * between parenthesis - */ -static char *parse_link_name(const char **buf, void *log_ctx) -{ - const char *start = *buf; - char *name; - (*buf)++; - - name = av_get_token(buf, "]"); - - if (!name[0]) { - av_log(log_ctx, AV_LOG_ERROR, - "Bad (empty?) label found in the following: \"%s\".\n", start); - goto fail; - } - - if (*(*buf)++ != ']') { - av_log(log_ctx, AV_LOG_ERROR, - "Mismatched '[' found in the following: \"%s\".\n", start); - fail: - av_freep(&name); - } - - return name; -} - -/** - * Create an instance of a filter, initialize and insert it in the - * filtergraph in *ctx. - * - * @param filt_ctx put here a filter context in case of successful creation and configuration, NULL otherwise. - * @param ctx the filtergraph context - * @param index an index which is supposed to be unique for each filter instance added to the filtergraph - * @param filt_name the name of the filter to create - * @param args the arguments provided to the filter during its initialization - * @param log_ctx the log context to use - * @return >= 0 in case of success, a negative AVERROR code otherwise - */ -static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int index, - const char *filt_name, const char *args, void *log_ctx) -{ - AVFilter *filt; - char inst_name[30]; - char *tmp_args = NULL; - int ret; - - snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index); - - filt = avfilter_get_by_name(filt_name); - - if (!filt) { - av_log(log_ctx, AV_LOG_ERROR, - "No such filter: '%s'\n", filt_name); - return AVERROR(EINVAL); - } - - *filt_ctx = avfilter_graph_alloc_filter(ctx, filt, inst_name); - if (!*filt_ctx) { - av_log(log_ctx, AV_LOG_ERROR, - "Error creating filter '%s'\n", filt_name); - return AVERROR(ENOMEM); - } - - if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") && - ctx->scale_sws_opts) { - tmp_args = av_asprintf("%s:%s", - args, ctx->scale_sws_opts); - if (!tmp_args) - return AVERROR(ENOMEM); - args = tmp_args; - } - - ret = avfilter_init_str(*filt_ctx, args); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Error initializing filter '%s'", filt_name); - if (args) - av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args); - av_log(log_ctx, AV_LOG_ERROR, "\n"); - avfilter_free(*filt_ctx); - *filt_ctx = NULL; - } - - av_free(tmp_args); - return ret; -} - -/** - * Parse a string of the form FILTER_NAME[=PARAMS], and create a - * corresponding filter instance which is added to graph with - * create_filter(). - * - * @param filt_ctx Pointer that is set to the created and configured filter - * context on success, set to NULL on failure. - * @param filt_ctx put here a pointer to the created filter context on - * success, NULL otherwise - * @param buf pointer to the buffer to parse, *buf will be updated to - * point to the char next after the parsed string - * @param index an index which is assigned to the created filter - * instance, and which is supposed to be unique for each filter - * instance added to the filtergraph - * @return >= 0 in case of success, a negative AVERROR code otherwise - */ -static int parse_filter(AVFilterContext **filt_ctx, const char **buf, AVFilterGraph *graph, - int index, void *log_ctx) -{ - char *opts = NULL; - char *name = av_get_token(buf, "=,;[\n"); - int ret; - - if (**buf == '=') { - (*buf)++; - opts = av_get_token(buf, "[],;\n"); - } - - ret = create_filter(filt_ctx, graph, index, name, opts, log_ctx); - av_free(name); - av_free(opts); - return ret; -} - -AVFilterInOut *avfilter_inout_alloc(void) -{ - return av_mallocz(sizeof(AVFilterInOut)); -} - -void avfilter_inout_free(AVFilterInOut **inout) -{ - while (*inout) { - AVFilterInOut *next = (*inout)->next; - av_freep(&(*inout)->name); - av_freep(inout); - *inout = next; - } -} - -static AVFilterInOut *extract_inout(const char *label, AVFilterInOut **links) -{ - AVFilterInOut *ret; - - while (*links && (!(*links)->name || strcmp((*links)->name, label))) - links = &((*links)->next); - - ret = *links; - - if (ret) { - *links = ret->next; - ret->next = NULL; - } - - return ret; -} - -static void insert_inout(AVFilterInOut **inouts, AVFilterInOut *element) -{ - element->next = *inouts; - *inouts = element; -} - -static void append_inout(AVFilterInOut **inouts, AVFilterInOut **element) -{ - while (*inouts && (*inouts)->next) - inouts = &((*inouts)->next); - - if (!*inouts) - *inouts = *element; - else - (*inouts)->next = *element; - *element = NULL; -} - -static int link_filter_inouts(AVFilterContext *filt_ctx, - AVFilterInOut **curr_inputs, - AVFilterInOut **open_inputs, void *log_ctx) -{ - int pad, ret; - - for (pad = 0; pad < filt_ctx->nb_inputs; pad++) { - AVFilterInOut *p = *curr_inputs; - - if (p) { - *curr_inputs = (*curr_inputs)->next; - p->next = NULL; - } else if (!(p = av_mallocz(sizeof(*p)))) - return AVERROR(ENOMEM); - - if (p->filter_ctx) { - ret = link_filter(p->filter_ctx, p->pad_idx, filt_ctx, pad, log_ctx); - av_free(p->name); - av_free(p); - if (ret < 0) - return ret; - } else { - p->filter_ctx = filt_ctx; - p->pad_idx = pad; - append_inout(open_inputs, &p); - } - } - - if (*curr_inputs) { - av_log(log_ctx, AV_LOG_ERROR, - "Too many inputs specified for the \"%s\" filter.\n", - filt_ctx->filter->name); - return AVERROR(EINVAL); - } - - pad = filt_ctx->nb_outputs; - while (pad--) { - AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut)); - if (!currlinkn) - return AVERROR(ENOMEM); - currlinkn->filter_ctx = filt_ctx; - currlinkn->pad_idx = pad; - insert_inout(curr_inputs, currlinkn); - } - - return 0; -} - -static int parse_inputs(const char **buf, AVFilterInOut **curr_inputs, - AVFilterInOut **open_outputs, void *log_ctx) -{ - AVFilterInOut *parsed_inputs = NULL; - int pad = 0; - - while (**buf == '[') { - char *name = parse_link_name(buf, log_ctx); - AVFilterInOut *match; - - if (!name) - return AVERROR(EINVAL); - - /* First check if the label is not in the open_outputs list */ - match = extract_inout(name, open_outputs); - - if (match) { - av_free(name); - } else { - /* Not in the list, so add it as an input */ - if (!(match = av_mallocz(sizeof(AVFilterInOut)))) { - av_free(name); - return AVERROR(ENOMEM); - } - match->name = name; - match->pad_idx = pad; - } - - append_inout(&parsed_inputs, &match); - - *buf += strspn(*buf, WHITESPACES); - pad++; - } - - append_inout(&parsed_inputs, curr_inputs); - *curr_inputs = parsed_inputs; - - return pad; -} - -static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, - AVFilterInOut **open_inputs, - AVFilterInOut **open_outputs, void *log_ctx) -{ - int ret, pad = 0; - - while (**buf == '[') { - char *name = parse_link_name(buf, log_ctx); - AVFilterInOut *match; - - AVFilterInOut *input = *curr_inputs; - - if (!name) - return AVERROR(EINVAL); - - if (!input) { - av_log(log_ctx, AV_LOG_ERROR, - "No output pad can be associated to link label '%s'.\n", name); - av_free(name); - return AVERROR(EINVAL); - } - *curr_inputs = (*curr_inputs)->next; - - /* First check if the label is not in the open_inputs list */ - match = extract_inout(name, open_inputs); - - if (match) { - if ((ret = link_filter(input->filter_ctx, input->pad_idx, - match->filter_ctx, match->pad_idx, log_ctx)) < 0) { - av_free(name); - return ret; - } - av_free(match->name); - av_free(name); - av_free(match); - av_free(input); - } else { - /* Not in the list, so add the first input as a open_output */ - input->name = name; - insert_inout(open_outputs, input); - } - *buf += strspn(*buf, WHITESPACES); - pad++; - } - - return pad; -} - -static int parse_sws_flags(const char **buf, AVFilterGraph *graph) -{ - char *p = strchr(*buf, ';'); - - if (strncmp(*buf, "sws_flags=", 10)) - return 0; - - if (!p) { - av_log(graph, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n"); - return AVERROR(EINVAL); - } - - *buf += 4; // keep the 'flags=' part - - av_freep(&graph->scale_sws_opts); - if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1))) - return AVERROR(ENOMEM); - av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1); - - *buf = p + 1; - return 0; -} - -int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, - AVFilterInOut **inputs, - AVFilterInOut **outputs) -{ - int index = 0, ret = 0; - char chr = 0; - - AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL; - - filters += strspn(filters, WHITESPACES); - - if ((ret = parse_sws_flags(&filters, graph)) < 0) - goto fail; - - do { - AVFilterContext *filter; - filters += strspn(filters, WHITESPACES); - - if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0) - goto end; - if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0) - goto end; - - - if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0) - goto end; - - if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, - graph)) < 0) - goto end; - - filters += strspn(filters, WHITESPACES); - chr = *filters++; - - if (chr == ';' && curr_inputs) - append_inout(&open_outputs, &curr_inputs); - index++; - } while (chr == ',' || chr == ';'); - - if (chr) { - av_log(graph, AV_LOG_ERROR, - "Unable to parse graph description substring: \"%s\"\n", - filters - 1); - ret = AVERROR(EINVAL); - goto end; - } - - append_inout(&open_outputs, &curr_inputs); - - - *inputs = open_inputs; - *outputs = open_outputs; - return 0; - - fail:end: - while (graph->nb_filters) - avfilter_free(graph->filters[0]); - av_freep(&graph->filters); - avfilter_inout_free(&open_inputs); - avfilter_inout_free(&open_outputs); - avfilter_inout_free(&curr_inputs); - - *inputs = NULL; - *outputs = NULL; - - return ret; -} - -#if HAVE_INCOMPATIBLE_LIBAV_ABI || !FF_API_OLD_GRAPH_PARSE -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut *open_inputs, - AVFilterInOut *open_outputs, void *log_ctx) -{ - int ret; - AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL; - - if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0) - goto fail; - - /* First input can be omitted if it is "[in]" */ - if (inputs && !inputs->name) - inputs->name = av_strdup("in"); - for (cur = inputs; cur; cur = cur->next) { - if (!cur->name) { - av_log(log_ctx, AV_LOG_ERROR, - "Not enough inputs specified for the \"%s\" filter.\n", - cur->filter_ctx->filter->name); - ret = AVERROR(EINVAL); - goto fail; - } - if (!(match = extract_inout(cur->name, &open_outputs))) - continue; - ret = avfilter_link(match->filter_ctx, match->pad_idx, - cur->filter_ctx, cur->pad_idx); - avfilter_inout_free(&match); - if (ret < 0) - goto fail; - } - - /* Last output can be omitted if it is "[out]" */ - if (outputs && !outputs->name) - outputs->name = av_strdup("out"); - for (cur = outputs; cur; cur = cur->next) { - if (!cur->name) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid filterchain containing an unlabelled output pad: \"%s\"\n", - filters); - ret = AVERROR(EINVAL); - goto fail; - } - if (!(match = extract_inout(cur->name, &open_inputs))) - continue; - ret = avfilter_link(cur->filter_ctx, cur->pad_idx, - match->filter_ctx, match->pad_idx); - avfilter_inout_free(&match); - if (ret < 0) - goto fail; - } - - fail: - if (ret < 0) { - while (graph->nb_filters) - avfilter_free(graph->filters[0]); - av_freep(&graph->filters); - } - avfilter_inout_free(&inputs); - avfilter_inout_free(&outputs); - avfilter_inout_free(&open_inputs); - avfilter_inout_free(&open_outputs); - return ret; -#else -int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, - AVFilterInOut **inputs, AVFilterInOut **outputs, - void *log_ctx) -{ - return avfilter_graph_parse_ptr(graph, filters, inputs, outputs, log_ctx); -#endif -} - -int avfilter_graph_parse_ptr(AVFilterGraph *graph, const char *filters, - AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr, - void *log_ctx) -{ - int index = 0, ret = 0; - char chr = 0; - - AVFilterInOut *curr_inputs = NULL; - AVFilterInOut *open_inputs = open_inputs_ptr ? *open_inputs_ptr : NULL; - AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL; - - if ((ret = parse_sws_flags(&filters, graph)) < 0) - goto end; - - do { - AVFilterContext *filter; - const char *filterchain = filters; - filters += strspn(filters, WHITESPACES); - - if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0) - goto end; - - if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0) - goto end; - - if (filter->nb_inputs == 1 && !curr_inputs && !index) { - /* First input pad, assume it is "[in]" if not specified */ - const char *tmp = "[in]"; - if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0) - goto end; - } - - if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0) - goto end; - - if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs, - log_ctx)) < 0) - goto end; - - filters += strspn(filters, WHITESPACES); - chr = *filters++; - - if (chr == ';' && curr_inputs) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid filterchain containing an unlabelled output pad: \"%s\"\n", - filterchain); - ret = AVERROR(EINVAL); - goto end; - } - index++; - } while (chr == ',' || chr == ';'); - - if (chr) { - av_log(log_ctx, AV_LOG_ERROR, - "Unable to parse graph description substring: \"%s\"\n", - filters - 1); - ret = AVERROR(EINVAL); - goto end; - } - - if (curr_inputs) { - /* Last output pad, assume it is "[out]" if not specified */ - const char *tmp = "[out]"; - if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs, - log_ctx)) < 0) - goto end; - } - -end: - /* clear open_in/outputs only if not passed as parameters */ - if (open_inputs_ptr) *open_inputs_ptr = open_inputs; - else avfilter_inout_free(&open_inputs); - if (open_outputs_ptr) *open_outputs_ptr = open_outputs; - else avfilter_inout_free(&open_outputs); - avfilter_inout_free(&curr_inputs); - - if (ret < 0) { - while (graph->nb_filters) - avfilter_free(graph->filters[0]); - av_freep(&graph->filters); - } - return ret; -} diff --git a/ffmpeg/libavfilter/internal.h b/ffmpeg/libavfilter/internal.h deleted file mode 100644 index 5e19698..0000000 --- a/ffmpeg/libavfilter/internal.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_INTERNAL_H -#define AVFILTER_INTERNAL_H - -/** - * @file - * internal API functions - */ - -#include "libavutil/internal.h" -#include "avfilter.h" -#include "avfiltergraph.h" -#include "formats.h" -#include "thread.h" -#include "version.h" -#include "video.h" - -#define POOL_SIZE 32 -typedef struct AVFilterPool { - AVFilterBufferRef *pic[POOL_SIZE]; - int count; - int refcount; - int draining; -} AVFilterPool; - -typedef struct AVFilterCommand { - double time; ///< time expressed in seconds - char *command; ///< command - char *arg; ///< optional argument for the command - int flags; - struct AVFilterCommand *next; -} AVFilterCommand; - -/** - * Update the position of a link in the age heap. - */ -void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link); - -#if !FF_API_AVFILTERPAD_PUBLIC -/** - * A filter pad used for either input or output. - */ -struct AVFilterPad { - /** - * Pad name. The name is unique among inputs and among outputs, but an - * input may have the same name as an output. This may be NULL if this - * pad has no need to ever be referenced by name. - */ - const char *name; - - /** - * AVFilterPad type. - */ - enum AVMediaType type; - - /** - * Callback function to get a video buffer. If NULL, the filter system will - * use ff_default_get_video_buffer(). - * - * Input video pads only. - */ - AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h); - - /** - * Callback function to get an audio buffer. If NULL, the filter system will - * use ff_default_get_audio_buffer(). - * - * Input audio pads only. - */ - AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples); - - /** - * Filtering callback. This is where a filter receives a frame with - * audio/video data and should do its processing. - * - * Input pads only. - * - * @return >= 0 on success, a negative AVERROR on error. This function - * must ensure that samplesref is properly unreferenced on error if it - * hasn't been passed on to another filter. - */ - int (*filter_frame)(AVFilterLink *link, AVFrame *frame); - - /** - * Frame poll callback. This returns the number of immediately available - * samples. It should return a positive value if the next request_frame() - * is guaranteed to return one frame (with no delay). - * - * Defaults to just calling the source poll_frame() method. - * - * Output pads only. - */ - int (*poll_frame)(AVFilterLink *link); - - /** - * Frame request callback. A call to this should result in at least one - * frame being output over the given link. This should return zero on - * success, and another value on error. - * - * Output pads only. - */ - int (*request_frame)(AVFilterLink *link); - - /** - * Link configuration callback. - * - * For output pads, this should set the link properties such as - * width/height. This should NOT set the format property - that is - * negotiated between filters by the filter system using the - * query_formats() callback before this function is called. - * - * For input pads, this should check the properties of the link, and update - * the filter's internal state as necessary. - * - * For both input and output filters, this should return zero on success, - * and another value on error. - */ - int (*config_props)(AVFilterLink *link); - - /** - * The filter expects a fifo to be inserted on its input link, - * typically because it has a delay. - * - * input pads only. - */ - int needs_fifo; -}; -#endif - -struct AVFilterGraphInternal { - void *thread; - avfilter_execute_func *thread_execute; -}; - -struct AVFilterInternal { - avfilter_execute_func *execute; -}; - -#if FF_API_AVFILTERBUFFER -/** default handler for freeing audio/video buffer when there are no references left */ -void ff_avfilter_default_free_buffer(AVFilterBuffer *buf); -#endif - -/** Tell is a format is contained in the provided list terminated by -1. */ -int ff_fmt_is_in(int fmt, const int *fmts); - -/* Functions to parse audio format arguments */ - -/** - * Parse a pixel format. - * - * @param ret pixel format pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx); - -/** - * Parse a sample rate. - * - * @param ret unsigned integer pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx); - -/** - * Parse a time base. - * - * @param ret unsigned AVRational pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx); - -/** - * Parse a sample format name or a corresponding integer representation. - * - * @param ret integer pointer to where the value should be written - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx); - -/** - * Parse a channel layout or a corresponding integer representation. - * - * @param ret 64bit integer pointer to where the value should be written. - * @param nret integer pointer to the number of channels; - * if not NULL, then unknown channel layouts are accepted - * @param arg string to parse - * @param log_ctx log context - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, - void *log_ctx); - -void ff_update_link_current_pts(AVFilterLink *link, int64_t pts); - -void ff_command_queue_pop(AVFilterContext *filter); - -/* misc trace functions */ - -/* #define FF_AVFILTER_TRACE */ - -#ifdef FF_AVFILTER_TRACE -# define ff_tlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__) -#else -# define ff_tlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0) -#endif - -#define FF_TPRINTF_START(ctx, func) ff_tlog(NULL, "%-16s: ", #func) - -char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms); - -void ff_tlog_ref(void *ctx, AVFrame *ref, int end); - -void ff_tlog_link(void *ctx, AVFilterLink *link, int end); - -/** - * Insert a new pad. - * - * @param idx Insertion point. Pad is inserted at the end if this point - * is beyond the end of the list of pads. - * @param count Pointer to the number of pads in the list - * @param padidx_off Offset within an AVFilterLink structure to the element - * to increment when inserting a new pad causes link - * numbering to change - * @param pads Pointer to the pointer to the beginning of the list of pads - * @param links Pointer to the pointer to the beginning of the list of links - * @param newpad The new pad to add. A copy is made when adding. - * @return >= 0 in case of success, a negative AVERROR code on error - */ -int ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad); - -/** Insert a new input pad for the filter. */ -static inline int ff_insert_inpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - int ret = ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad), - &f->input_pads, &f->inputs, p); -#if FF_API_FOO_COUNT -FF_DISABLE_DEPRECATION_WARNINGS - f->input_count = f->nb_inputs; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - return ret; -} - -/** Insert a new output pad for the filter. */ -static inline int ff_insert_outpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - int ret = ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad), - &f->output_pads, &f->outputs, p); -#if FF_API_FOO_COUNT -FF_DISABLE_DEPRECATION_WARNINGS - f->output_count = f->nb_outputs; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - return ret; -} - -/** - * Poll a frame from the filter chain. - * - * @param link the input link - * @return the number of immediately available frames, a negative - * number in case of error - */ -int ff_poll_frame(AVFilterLink *link); - -/** - * Request an input frame from the filter at the other end of the link. - * - * @param link the input link - * @return zero on success - */ -int ff_request_frame(AVFilterLink *link); - -#define AVFILTER_DEFINE_CLASS(fname) \ - static const AVClass fname##_class = { \ - .class_name = #fname, \ - .item_name = av_default_item_name, \ - .option = fname##_options, \ - .version = LIBAVUTIL_VERSION_INT, \ - .category = AV_CLASS_CATEGORY_FILTER, \ - } - -AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink, - AVFilterBufferRef *ref); - -/** - * Find the index of a link. - * - * I.e. find i such that link == ctx->(in|out)puts[i] - */ -#define FF_INLINK_IDX(link) ((int)((link)->dstpad - (link)->dst->input_pads)) -#define FF_OUTLINK_IDX(link) ((int)((link)->srcpad - (link)->src->output_pads)) - -int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf); -int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf, - int nb_samples); -/** - * Send a frame of data to the next filter. - * - * @param link the output link over which the data is being sent - * @param frame a reference to the buffer of data being sent. The - * receiving filter will free this reference when it no longer - * needs it or pass it on to the next filter. - * - * @return >= 0 on success, a negative AVERROR on error. The receiving filter - * is responsible for unreferencing frame in case of error. - */ -int ff_filter_frame(AVFilterLink *link, AVFrame *frame); - -/** - * Flags for AVFilterLink.flags. - */ -enum { - - /** - * Frame requests may need to loop in order to be fulfilled. - * A filter must set this flags on an output link if it may return 0 in - * request_frame() without filtering a frame. - */ - FF_LINK_FLAG_REQUEST_LOOP = 1, - -}; - -/** - * Allocate a new filter context and return it. - * - * @param filter what filter to create an instance of - * @param inst_name name to give to the new filter context - * - * @return newly created filter context or NULL on failure - */ -AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name); - -/** - * Remove a filter from a graph; - */ -void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter); - -#endif /* AVFILTER_INTERNAL_H */ diff --git a/ffmpeg/libavfilter/lavfutils.c b/ffmpeg/libavfilter/lavfutils.c deleted file mode 100644 index 58d98cf..0000000 --- a/ffmpeg/libavfilter/lavfutils.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012 Stefano Sabatini <stefasab gmail com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/imgutils.h" -#include "lavfutils.h" - -int ff_load_image(uint8_t *data[4], int linesize[4], - int *w, int *h, enum AVPixelFormat *pix_fmt, - const char *filename, void *log_ctx) -{ - AVInputFormat *iformat = NULL; - AVFormatContext *format_ctx = NULL; - AVCodec *codec; - AVCodecContext *codec_ctx; - AVFrame *frame; - int frame_decoded, ret = 0; - AVPacket pkt; - - av_init_packet(&pkt); - - av_register_all(); - - iformat = av_find_input_format("image2"); - if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL)) < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Failed to open input file '%s'\n", filename); - return ret; - } - - codec_ctx = format_ctx->streams[0]->codec; - codec = avcodec_find_decoder(codec_ctx->codec_id); - if (!codec) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to find codec\n"); - ret = AVERROR(EINVAL); - goto end; - } - - if ((ret = avcodec_open2(codec_ctx, codec, NULL)) < 0) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n"); - goto end; - } - - if (!(frame = av_frame_alloc()) ) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n"); - ret = AVERROR(ENOMEM); - goto end; - } - - ret = av_read_frame(format_ctx, &pkt); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n"); - goto end; - } - - ret = avcodec_decode_video2(codec_ctx, frame, &frame_decoded, &pkt); - if (ret < 0 || !frame_decoded) { - av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n"); - goto end; - } - ret = 0; - - *w = frame->width; - *h = frame->height; - *pix_fmt = frame->format; - - if ((ret = av_image_alloc(data, linesize, *w, *h, *pix_fmt, 16)) < 0) - goto end; - ret = 0; - - av_image_copy(data, linesize, (const uint8_t **)frame->data, frame->linesize, *pix_fmt, *w, *h); - -end: - av_free_packet(&pkt); - avcodec_close(codec_ctx); - avformat_close_input(&format_ctx); - av_freep(&frame); - - if (ret < 0) - av_log(log_ctx, AV_LOG_ERROR, "Error loading image file '%s'\n", filename); - return ret; -} diff --git a/ffmpeg/libavfilter/lavfutils.h b/ffmpeg/libavfilter/lavfutils.h deleted file mode 100644 index 2d5308f..0000000 --- a/ffmpeg/libavfilter/lavfutils.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Miscellaneous utilities which make use of the libavformat library - */ - -#ifndef AVFILTER_LAVFUTILS_H -#define AVFILTER_LAVFUTILS_H - -#include "libavformat/avformat.h" - -/** - * Load image from filename and put the resulting image in data. - * - * @param w pointer to the width of the loaded image - * @param h pointer to the height of the loaded image - * @param pix_fmt pointer to the pixel format of the loaded image - * @param filename the name of the image file to load - * @param log_ctx log context - * @return >= 0 in case of success, a negative error code otherwise. - */ -int ff_load_image(uint8_t *data[4], int linesize[4], - int *w, int *h, enum AVPixelFormat *pix_fmt, - const char *filename, void *log_ctx); - -#endif /* AVFILTER_LAVFUTILS_H */ diff --git a/ffmpeg/libavfilter/libavfilter.pc b/ffmpeg/libavfilter/libavfilter.pc deleted file mode 100644 index 2e82266..0000000 --- a/ffmpeg/libavfilter/libavfilter.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavfilter -Description: FFmpeg audio/video filtering library -Version: 4.0.103 -Requires: -Requires.private: libpostproc = 52.3.100, libswresample = 0.17.104, libswscale = 2.5.101, libavformat = 55.22.100, libavcodec = 55.46.100, libavutil = 52.59.100 -Conflicts: -Libs: -L${libdir} -lavfilter -Libs.private: -lXfixes -lXext -lX11 -lx264 -lmp3lame -lm -lz -pthread -Cflags: -I${includedir} diff --git a/ffmpeg/libavfilter/libavfilter.v b/ffmpeg/libavfilter/libavfilter.v deleted file mode 100644 index a3d33a3..0000000 --- a/ffmpeg/libavfilter/libavfilter.v +++ /dev/null @@ -1,5 +0,0 @@ -LIBAVFILTER_$MAJOR { - global: avfilter_*; av_*; - ff_default_query_formats; - local: *; -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/av_helpers.h b/ffmpeg/libavfilter/libmpcodecs/av_helpers.h deleted file mode 100644 index 90b67d5..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/av_helpers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generic libav* helpers - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_AV_HELPERS_H -#define MPLAYER_AV_HELPERS_H - -void ff_init_avcodec(void); -void ff_init_avformat(void); - -#endif /* MPLAYER_AV_HELPERS_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/cpudetect.h b/ffmpeg/libavfilter/libmpcodecs/cpudetect.h deleted file mode 100644 index 710f6e6..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/cpudetect.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_CPUDETECT_H -#define MPLAYER_CPUDETECT_H - -#define CPUTYPE_I386 3 -#define CPUTYPE_I486 4 -#define CPUTYPE_I586 5 -#define CPUTYPE_I686 6 - -#include "libavutil/x86_cpu.h" - -typedef struct cpucaps_s { - int cpuType; - int cpuModel; - int cpuStepping; - int hasMMX; - int hasMMX2; - int has3DNow; - int has3DNowExt; - int hasSSE; - int hasSSE2; - int hasSSE3; - int hasSSSE3; - int hasSSE4; - int hasSSE42; - int hasSSE4a; - int hasAVX; - int isX86; - unsigned cl_size; /* size of cache line */ - int hasAltiVec; - int hasTSC; -} CpuCaps; - -extern CpuCaps ff_gCpuCaps; - -void ff_do_cpuid(unsigned int ax, unsigned int *p); - -void ff_GetCpuCaps(CpuCaps *caps); - -/* returned value is malloc()'ed so free() it after use */ -char *ff_GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]); - -#endif /* MPLAYER_CPUDETECT_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/img_format.c b/ffmpeg/libavfilter/libmpcodecs/img_format.c deleted file mode 100644 index 61bf898..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/img_format.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" -#include "img_format.h" -#include "stdio.h" -#include "libavutil/bswap.h" - -const char *ff_vo_format_name(int format) -{ - static char unknown_format[20]; - switch(format) - { - case IMGFMT_RGB1: return "RGB 1-bit"; - case IMGFMT_RGB4: return "RGB 4-bit"; - case IMGFMT_RG4B: return "RGB 4-bit per byte"; - case IMGFMT_RGB8: return "RGB 8-bit"; - case IMGFMT_RGB12: return "RGB 12-bit"; - case IMGFMT_RGB15: return "RGB 15-bit"; - case IMGFMT_RGB16: return "RGB 16-bit"; - case IMGFMT_RGB24: return "RGB 24-bit"; -// case IMGFMT_RGB32: return "RGB 32-bit"; - case IMGFMT_RGB48LE: return "RGB 48-bit LE"; - case IMGFMT_RGB48BE: return "RGB 48-bit BE"; - case IMGFMT_RGB64LE: return "RGB 64-bit LE"; - case IMGFMT_RGB64BE: return "RGB 64-bit BE"; - case IMGFMT_BGR1: return "BGR 1-bit"; - case IMGFMT_BGR4: return "BGR 4-bit"; - case IMGFMT_BG4B: return "BGR 4-bit per byte"; - case IMGFMT_BGR8: return "BGR 8-bit"; - case IMGFMT_BGR12: return "BGR 12-bit"; - case IMGFMT_BGR15: return "BGR 15-bit"; - case IMGFMT_BGR16: return "BGR 16-bit"; - case IMGFMT_BGR24: return "BGR 24-bit"; -// case IMGFMT_BGR32: return "BGR 32-bit"; - case IMGFMT_ABGR: return "ABGR"; - case IMGFMT_BGRA: return "BGRA"; - case IMGFMT_ARGB: return "ARGB"; - case IMGFMT_RGBA: return "RGBA"; - case IMGFMT_GBR24P: return "Planar GBR 24-bit"; - case IMGFMT_GBR12P: return "Planar GBR 36-bit"; - case IMGFMT_GBR14P: return "Planar GBR 42-bit"; - case IMGFMT_YVU9: return "Planar YVU9"; - case IMGFMT_IF09: return "Planar IF09"; - case IMGFMT_YV12: return "Planar YV12"; - case IMGFMT_I420: return "Planar I420"; - case IMGFMT_IYUV: return "Planar IYUV"; - case IMGFMT_CLPL: return "Planar CLPL"; - case IMGFMT_Y800: return "Planar Y800"; - case IMGFMT_Y8: return "Planar Y8"; - case IMGFMT_Y8A: return "Planar Y8 with alpha"; - case IMGFMT_Y16_LE: return "Planar Y16 little-endian"; - case IMGFMT_Y16_BE: return "Planar Y16 big-endian"; - case IMGFMT_420P16_LE: return "Planar 420P 16-bit little-endian"; - case IMGFMT_420P16_BE: return "Planar 420P 16-bit big-endian"; - case IMGFMT_420P14_LE: return "Planar 420P 14-bit little-endian"; - case IMGFMT_420P14_BE: return "Planar 420P 14-bit big-endian"; - case IMGFMT_420P12_LE: return "Planar 420P 12-bit little-endian"; - case IMGFMT_420P12_BE: return "Planar 420P 12-bit big-endian"; - case IMGFMT_420P10_LE: return "Planar 420P 10-bit little-endian"; - case IMGFMT_420P10_BE: return "Planar 420P 10-bit big-endian"; - case IMGFMT_420P9_LE: return "Planar 420P 9-bit little-endian"; - case IMGFMT_420P9_BE: return "Planar 420P 9-bit big-endian"; - case IMGFMT_422P16_LE: return "Planar 422P 16-bit little-endian"; - case IMGFMT_422P16_BE: return "Planar 422P 16-bit big-endian"; - case IMGFMT_422P14_LE: return "Planar 422P 14-bit little-endian"; - case IMGFMT_422P14_BE: return "Planar 422P 14-bit big-endian"; - case IMGFMT_422P12_LE: return "Planar 422P 12-bit little-endian"; - case IMGFMT_422P12_BE: return "Planar 422P 12-bit big-endian"; - case IMGFMT_422P10_LE: return "Planar 422P 10-bit little-endian"; - case IMGFMT_422P10_BE: return "Planar 422P 10-bit big-endian"; - case IMGFMT_422P9_LE: return "Planar 422P 9-bit little-endian"; - case IMGFMT_422P9_BE: return "Planar 422P 9-bit big-endian"; - case IMGFMT_444P16_LE: return "Planar 444P 16-bit little-endian"; - case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian"; - case IMGFMT_444P14_LE: return "Planar 444P 14-bit little-endian"; - case IMGFMT_444P14_BE: return "Planar 444P 14-bit big-endian"; - case IMGFMT_444P12_LE: return "Planar 444P 12-bit little-endian"; - case IMGFMT_444P12_BE: return "Planar 444P 12-bit big-endian"; - case IMGFMT_444P10_LE: return "Planar 444P 10-bit little-endian"; - case IMGFMT_444P10_BE: return "Planar 444P 10-bit big-endian"; - case IMGFMT_444P9_LE: return "Planar 444P 9-bit little-endian"; - case IMGFMT_444P9_BE: return "Planar 444P 9-bit big-endian"; - case IMGFMT_420A: return "Planar 420P with alpha"; - case IMGFMT_444P: return "Planar 444P"; - case IMGFMT_444A: return "Planar 444P with alpha"; - case IMGFMT_422P: return "Planar 422P"; - case IMGFMT_422A: return "Planar 422P with alpha"; - case IMGFMT_411P: return "Planar 411P"; - case IMGFMT_NV12: return "Planar NV12"; - case IMGFMT_NV21: return "Planar NV21"; - case IMGFMT_HM12: return "Planar NV12 Macroblock"; - case IMGFMT_IUYV: return "Packed IUYV"; - case IMGFMT_IY41: return "Packed IY41"; - case IMGFMT_IYU1: return "Packed IYU1"; - case IMGFMT_IYU2: return "Packed IYU2"; - case IMGFMT_UYVY: return "Packed UYVY"; - case IMGFMT_UYNV: return "Packed UYNV"; - case IMGFMT_cyuv: return "Packed CYUV"; - case IMGFMT_Y422: return "Packed Y422"; - case IMGFMT_YUY2: return "Packed YUY2"; - case IMGFMT_YUNV: return "Packed YUNV"; - case IMGFMT_YVYU: return "Packed YVYU"; - case IMGFMT_Y41P: return "Packed Y41P"; - case IMGFMT_Y211: return "Packed Y211"; - case IMGFMT_Y41T: return "Packed Y41T"; - case IMGFMT_Y42T: return "Packed Y42T"; - case IMGFMT_V422: return "Packed V422"; - case IMGFMT_V655: return "Packed V655"; - case IMGFMT_CLJR: return "Packed CLJR"; - case IMGFMT_YUVP: return "Packed YUVP"; - case IMGFMT_UYVP: return "Packed UYVP"; - case IMGFMT_MPEGPES: return "Mpeg PES"; - case IMGFMT_ZRMJPEGNI: return "Zoran MJPEG non-interlaced"; - case IMGFMT_ZRMJPEGIT: return "Zoran MJPEG top field first"; - case IMGFMT_ZRMJPEGIB: return "Zoran MJPEG bottom field first"; - case IMGFMT_XVMC_MOCO_MPEG2: return "MPEG1/2 Motion Compensation"; - case IMGFMT_XVMC_IDCT_MPEG2: return "MPEG1/2 Motion Compensation and IDCT"; - case IMGFMT_VDPAU_MPEG1: return "MPEG1 VDPAU acceleration"; - case IMGFMT_VDPAU_MPEG2: return "MPEG2 VDPAU acceleration"; - case IMGFMT_VDPAU_H264: return "H.264 VDPAU acceleration"; - case IMGFMT_VDPAU_MPEG4: return "MPEG-4 Part 2 VDPAU acceleration"; - case IMGFMT_VDPAU_WMV3: return "WMV3 VDPAU acceleration"; - case IMGFMT_VDPAU_VC1: return "VC1 VDPAU acceleration"; - } - snprintf(unknown_format,20,"Unknown 0x%04x",format); - return unknown_format; -} - -int ff_mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits) -{ - int xs = 0, ys = 0; - int bpp; - int err = 0; - int bits = 8; - if ((format & 0xff0000f0) == 0x34000050) - format = av_bswap32(format); - if ((format & 0xf00000ff) == 0x50000034) { - switch (format >> 24) { - case 0x50: - break; - case 0x51: - bits = 16; - break; - case 0x52: - bits = 10; - break; - case 0x53: - bits = 9; - break; - default: - err = 1; - break; - } - switch (format & 0x00ffffff) { - case 0x00343434: // 444 - xs = 0; - ys = 0; - break; - case 0x00323234: // 422 - xs = 1; - ys = 0; - break; - case 0x00303234: // 420 - xs = 1; - ys = 1; - break; - case 0x00313134: // 411 - xs = 2; - ys = 0; - break; - case 0x00303434: // 440 - xs = 0; - ys = 1; - break; - default: - err = 1; - break; - } - } else switch (format) { - case IMGFMT_444A: - xs = 0; - ys = 0; - break; - case IMGFMT_422A: - xs = 1; - ys = 0; - break; - case IMGFMT_420A: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_YV12: - xs = 1; - ys = 1; - break; - case IMGFMT_IF09: - case IMGFMT_YVU9: - xs = 2; - ys = 2; - break; - case IMGFMT_Y8: - case IMGFMT_Y800: - xs = 31; - ys = 31; - break; - default: - err = 1; - break; - } - if (x_shift) *x_shift = xs; - if (y_shift) *y_shift = ys; - if (component_bits) *component_bits = bits; - bpp = 8 + ((16 >> xs) >> ys); - if (format == IMGFMT_420A || format == IMGFMT_422A || format == IMGFMT_444A) - bpp += 8; - bpp *= (bits + 7) >> 3; - return err ? 0 : bpp; -} diff --git a/ffmpeg/libavfilter/libmpcodecs/img_format.h b/ffmpeg/libavfilter/libmpcodecs/img_format.h deleted file mode 100644 index d4d64d8..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/img_format.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_IMG_FORMAT_H -#define MPLAYER_IMG_FORMAT_H - -#include "config.h" - -/* RGB/BGR Formats */ - -#define IMGFMT_RGB_MASK 0xFFFFFF00 -#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) -#define IMGFMT_RGB1 (IMGFMT_RGB|1) -#define IMGFMT_RGB4 (IMGFMT_RGB|4) -#define IMGFMT_RGB4_CHAR (IMGFMT_RGB|4|128) // RGB4 with 1 pixel per byte -#define IMGFMT_RGB8 (IMGFMT_RGB|8) -#define IMGFMT_RGB12 (IMGFMT_RGB|12) -#define IMGFMT_RGB15 (IMGFMT_RGB|15) -#define IMGFMT_RGB16 (IMGFMT_RGB|16) -#define IMGFMT_RGB24 (IMGFMT_RGB|24) -#define IMGFMT_RGB32 (IMGFMT_RGB|32) -#define IMGFMT_RGB48LE (IMGFMT_RGB|48) -#define IMGFMT_RGB48BE (IMGFMT_RGB|48|128) -#define IMGFMT_RGB64LE (IMGFMT_RGB|64) -#define IMGFMT_RGB64BE (IMGFMT_RGB|64|128) - -#define IMGFMT_BGR_MASK 0xFFFFFF00 -#define IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8)) -#define IMGFMT_BGR1 (IMGFMT_BGR|1) -#define IMGFMT_BGR4 (IMGFMT_BGR|4) -#define IMGFMT_BGR4_CHAR (IMGFMT_BGR|4|128) // BGR4 with 1 pixel per byte -#define IMGFMT_BGR8 (IMGFMT_BGR|8) -#define IMGFMT_BGR12 (IMGFMT_BGR|12) -#define IMGFMT_BGR15 (IMGFMT_BGR|15) -#define IMGFMT_BGR16 (IMGFMT_BGR|16) -#define IMGFMT_BGR24 (IMGFMT_BGR|24) -#define IMGFMT_BGR32 (IMGFMT_BGR|32) - -#define IMGFMT_GBR24P (('G'<<24)|('B'<<16)|('R'<<8)|24) -#define IMGFMT_GBR12PLE (('G'<<24)|('B'<<16)|('R'<<8)|36) -#define IMGFMT_GBR12PBE (('G'<<24)|('B'<<16)|('R'<<8)|36|128) -#define IMGFMT_GBR14PLE (('G'<<24)|('B'<<16)|('R'<<8)|42) -#define IMGFMT_GBR14PBE (('G'<<24)|('B'<<16)|('R'<<8)|42|128) - -#if HAVE_BIGENDIAN -#define IMGFMT_ABGR IMGFMT_RGB32 -#define IMGFMT_BGRA (IMGFMT_RGB32|128) -#define IMGFMT_ARGB IMGFMT_BGR32 -#define IMGFMT_RGBA (IMGFMT_BGR32|128) -#define IMGFMT_RGB64NE IMGFMT_RGB64BE -#define IMGFMT_RGB48NE IMGFMT_RGB48BE -#define IMGFMT_RGB12BE IMGFMT_RGB12 -#define IMGFMT_RGB12LE (IMGFMT_RGB12|128) -#define IMGFMT_RGB15BE IMGFMT_RGB15 -#define IMGFMT_RGB15LE (IMGFMT_RGB15|128) -#define IMGFMT_RGB16BE IMGFMT_RGB16 -#define IMGFMT_RGB16LE (IMGFMT_RGB16|128) -#define IMGFMT_BGR12BE IMGFMT_BGR12 -#define IMGFMT_BGR12LE (IMGFMT_BGR12|128) -#define IMGFMT_BGR15BE IMGFMT_BGR15 -#define IMGFMT_BGR15LE (IMGFMT_BGR15|128) -#define IMGFMT_BGR16BE IMGFMT_BGR16 -#define IMGFMT_BGR16LE (IMGFMT_BGR16|128) -#define IMGFMT_GBR12P IMGFMT_GBR12PBE -#define IMGFMT_GBR14P IMGFMT_GBR14PBE -#else -#define IMGFMT_ABGR (IMGFMT_BGR32|128) -#define IMGFMT_BGRA IMGFMT_BGR32 -#define IMGFMT_ARGB (IMGFMT_RGB32|128) -#define IMGFMT_RGBA IMGFMT_RGB32 -#define IMGFMT_RGB64NE IMGFMT_RGB64LE -#define IMGFMT_RGB48NE IMGFMT_RGB48LE -#define IMGFMT_RGB12BE (IMGFMT_RGB12|128) -#define IMGFMT_RGB12LE IMGFMT_RGB12 -#define IMGFMT_RGB15BE (IMGFMT_RGB15|128) -#define IMGFMT_RGB15LE IMGFMT_RGB15 -#define IMGFMT_RGB16BE (IMGFMT_RGB16|128) -#define IMGFMT_RGB16LE IMGFMT_RGB16 -#define IMGFMT_BGR12BE (IMGFMT_BGR12|128) -#define IMGFMT_BGR12LE IMGFMT_BGR12 -#define IMGFMT_BGR15BE (IMGFMT_BGR15|128) -#define IMGFMT_BGR15LE IMGFMT_BGR15 -#define IMGFMT_BGR16BE (IMGFMT_BGR16|128) -#define IMGFMT_BGR16LE IMGFMT_BGR16 -#define IMGFMT_GBR12P IMGFMT_GBR12PLE -#define IMGFMT_GBR14P IMGFMT_GBR14PLE -#endif - -/* old names for compatibility */ -#define IMGFMT_RG4B IMGFMT_RGB4_CHAR -#define IMGFMT_BG4B IMGFMT_BGR4_CHAR - -#define IMGFMT_IS_RGB(fmt) (((fmt)&IMGFMT_RGB_MASK)==IMGFMT_RGB) -#define IMGFMT_IS_BGR(fmt) (((fmt)&IMGFMT_BGR_MASK)==IMGFMT_BGR) - -#define IMGFMT_RGB_DEPTH(fmt) ((fmt)&0x7F) -#define IMGFMT_BGR_DEPTH(fmt) ((fmt)&0x7F) - - -/* Planar YUV Formats */ - -#define IMGFMT_YVU9 0x39555659 -#define IMGFMT_IF09 0x39304649 -#define IMGFMT_YV12 0x32315659 -#define IMGFMT_I420 0x30323449 -#define IMGFMT_IYUV 0x56555949 -#define IMGFMT_CLPL 0x4C504C43 -#define IMGFMT_Y800 0x30303859 -#define IMGFMT_Y8 0x20203859 -#define IMGFMT_NV12 0x3231564E -#define IMGFMT_NV21 0x3132564E -#define IMGFMT_Y16_LE 0x20363159 - -/* unofficial Planar Formats, FIXME if official 4CC exists */ -#define IMGFMT_444P 0x50343434 -#define IMGFMT_422P 0x50323234 -#define IMGFMT_411P 0x50313134 -#define IMGFMT_440P 0x50303434 -#define IMGFMT_HM12 0x32314D48 -#define IMGFMT_Y16_BE 0x59313620 - -// Gray with alpha -#define IMGFMT_Y8A 0x59320008 -// 4:2:0 planar with alpha -#define IMGFMT_420A 0x41303234 -// 4:2:2 planar with alpha -#define IMGFMT_422A 0x41323234 -// 4:4:4 planar with alpha -#define IMGFMT_444A 0x41343434 - -#define IMGFMT_444P16_LE 0x51343434 -#define IMGFMT_444P16_BE 0x34343451 -#define IMGFMT_444P14_LE 0x54343434 -#define IMGFMT_444P14_BE 0x34343454 -#define IMGFMT_444P12_LE 0x55343434 -#define IMGFMT_444P12_BE 0x34343455 -#define IMGFMT_444P10_LE 0x52343434 -#define IMGFMT_444P10_BE 0x34343452 -#define IMGFMT_444P9_LE 0x53343434 -#define IMGFMT_444P9_BE 0x34343453 -#define IMGFMT_422P16_LE 0x51323234 -#define IMGFMT_422P16_BE 0x34323251 -#define IMGFMT_422P14_LE 0x54323234 -#define IMGFMT_422P14_BE 0x34323254 -#define IMGFMT_422P12_LE 0x55323234 -#define IMGFMT_422P12_BE 0x34323255 -#define IMGFMT_422P10_LE 0x52323234 -#define IMGFMT_422P10_BE 0x34323252 -#define IMGFMT_422P9_LE 0x53323234 -#define IMGFMT_422P9_BE 0x34323253 -#define IMGFMT_420P16_LE 0x51303234 -#define IMGFMT_420P16_BE 0x34323051 -#define IMGFMT_420P14_LE 0x54303234 -#define IMGFMT_420P14_BE 0x34323054 -#define IMGFMT_420P12_LE 0x55303234 -#define IMGFMT_420P12_BE 0x34323055 -#define IMGFMT_420P10_LE 0x52303234 -#define IMGFMT_420P10_BE 0x34323052 -#define IMGFMT_420P9_LE 0x53303234 -#define IMGFMT_420P9_BE 0x34323053 -#if HAVE_BIGENDIAN -#define IMGFMT_444P16 IMGFMT_444P16_BE -#define IMGFMT_444P14 IMGFMT_444P14_BE -#define IMGFMT_444P12 IMGFMT_444P12_BE -#define IMGFMT_444P10 IMGFMT_444P10_BE -#define IMGFMT_444P9 IMGFMT_444P9_BE -#define IMGFMT_422P16 IMGFMT_422P16_BE -#define IMGFMT_422P14 IMGFMT_422P14_BE -#define IMGFMT_422P12 IMGFMT_422P12_BE -#define IMGFMT_422P10 IMGFMT_422P10_BE -#define IMGFMT_422P9 IMGFMT_422P9_BE -#define IMGFMT_420P16 IMGFMT_420P16_BE -#define IMGFMT_420P14 IMGFMT_420P14_BE -#define IMGFMT_420P12 IMGFMT_420P12_BE -#define IMGFMT_420P10 IMGFMT_420P10_BE -#define IMGFMT_420P9 IMGFMT_420P9_BE -#define IMGFMT_Y16 IMGFMT_Y16_BE -#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_BE(fmt) -#else -#define IMGFMT_444P16 IMGFMT_444P16_LE -#define IMGFMT_444P14 IMGFMT_444P14_LE -#define IMGFMT_444P12 IMGFMT_444P12_LE -#define IMGFMT_444P10 IMGFMT_444P10_LE -#define IMGFMT_444P9 IMGFMT_444P9_LE -#define IMGFMT_422P16 IMGFMT_422P16_LE -#define IMGFMT_422P14 IMGFMT_422P14_LE -#define IMGFMT_422P12 IMGFMT_422P12_LE -#define IMGFMT_422P10 IMGFMT_422P10_LE -#define IMGFMT_422P9 IMGFMT_422P9_LE -#define IMGFMT_420P16 IMGFMT_420P16_LE -#define IMGFMT_420P14 IMGFMT_420P14_LE -#define IMGFMT_420P12 IMGFMT_420P12_LE -#define IMGFMT_420P10 IMGFMT_420P10_LE -#define IMGFMT_420P9 IMGFMT_420P9_LE -#define IMGFMT_Y16 IMGFMT_Y16_LE -#define IMGFMT_IS_YUVP16_NE(fmt) IMGFMT_IS_YUVP16_LE(fmt) -#endif - -#define IMGFMT_IS_YUVP16_LE(fmt) (((fmt - 0x51000034) & 0xfc0000ff) == 0) -#define IMGFMT_IS_YUVP16_BE(fmt) (((fmt - 0x34000051) & 0xff0000fc) == 0) -#define IMGFMT_IS_YUVP16(fmt) (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt)) - -/** - * \brief Find the corresponding full 16 bit format, i.e. IMGFMT_420P10_LE -> IMGFMT_420P16_LE - * \return normalized format ID or 0 if none exists. - */ -static inline int normalize_yuvp16(int fmt) { - if (IMGFMT_IS_YUVP16_LE(fmt)) - return (fmt & 0x00ffffff) | 0x51000000; - if (IMGFMT_IS_YUVP16_BE(fmt)) - return (fmt & 0xffffff00) | 0x00000051; - return 0; -} - -/* Packed YUV Formats */ - -#define IMGFMT_IUYV 0x56595549 // Interlaced UYVY -#define IMGFMT_IY41 0x31435949 // Interlaced Y41P -#define IMGFMT_IYU1 0x31555949 -#define IMGFMT_IYU2 0x32555949 -#define IMGFMT_UYVY 0x59565955 -#define IMGFMT_UYNV 0x564E5955 // Exactly same as UYVY -#define IMGFMT_cyuv 0x76757963 // upside-down UYVY -#define IMGFMT_Y422 0x32323459 // Exactly same as UYVY -#define IMGFMT_YUY2 0x32595559 -#define IMGFMT_YUNV 0x564E5559 // Exactly same as YUY2 -#define IMGFMT_YVYU 0x55595659 -#define IMGFMT_Y41P 0x50313459 -#define IMGFMT_Y211 0x31313259 -#define IMGFMT_Y41T 0x54313459 // Y41P, Y lsb = transparency -#define IMGFMT_Y42T 0x54323459 // UYVY, Y lsb = transparency -#define IMGFMT_V422 0x32323456 // upside-down UYVY? -#define IMGFMT_V655 0x35353656 -#define IMGFMT_CLJR 0x524A4C43 -#define IMGFMT_YUVP 0x50565559 // 10-bit YUYV -#define IMGFMT_UYVP 0x50565955 // 10-bit UYVY - -/* Compressed Formats */ -#define IMGFMT_MPEGPES (('M'<<24)|('P'<<16)|('E'<<8)|('S')) -#define IMGFMT_MJPEG (('M')|('J'<<8)|('P'<<16)|('G'<<24)) -/* Formats that are understood by zoran chips, we include - * non-interlaced, interlaced top-first, interlaced bottom-first */ -#define IMGFMT_ZRMJPEGNI (('Z'<<24)|('R'<<16)|('N'<<8)|('I')) -#define IMGFMT_ZRMJPEGIT (('Z'<<24)|('R'<<16)|('I'<<8)|('T')) -#define IMGFMT_ZRMJPEGIB (('Z'<<24)|('R'<<16)|('I'<<8)|('B')) - -// I think that this code could not be used by any other codec/format -#define IMGFMT_XVMC 0x1DC70000 -#define IMGFMT_XVMC_MASK 0xFFFF0000 -#define IMGFMT_IS_XVMC(fmt) (((fmt)&IMGFMT_XVMC_MASK)==IMGFMT_XVMC) -//these are chroma420 -#define IMGFMT_XVMC_MOCO_MPEG2 (IMGFMT_XVMC|0x02) -#define IMGFMT_XVMC_IDCT_MPEG2 (IMGFMT_XVMC|0x82) - -// VDPAU specific format. -#define IMGFMT_VDPAU 0x1DC80000 -#define IMGFMT_VDPAU_MASK 0xFFFF0000 -#define IMGFMT_IS_VDPAU(fmt) (((fmt)&IMGFMT_VDPAU_MASK)==IMGFMT_VDPAU) -#define IMGFMT_VDPAU_MPEG1 (IMGFMT_VDPAU|0x01) -#define IMGFMT_VDPAU_MPEG2 (IMGFMT_VDPAU|0x02) -#define IMGFMT_VDPAU_H264 (IMGFMT_VDPAU|0x03) -#define IMGFMT_VDPAU_WMV3 (IMGFMT_VDPAU|0x04) -#define IMGFMT_VDPAU_VC1 (IMGFMT_VDPAU|0x05) -#define IMGFMT_VDPAU_MPEG4 (IMGFMT_VDPAU|0x06) - -#define IMGFMT_IS_HWACCEL(fmt) (IMGFMT_IS_VDPAU(fmt) || IMGFMT_IS_XVMC(fmt)) - -typedef struct { - void* data; - int size; - int id; // stream id. usually 0x1E0 - int timestamp; // pts, 90000 Hz counter based -} vo_mpegpes_t; - -const char *ff_vo_format_name(int format); - -/** - * Calculates the scale shifts for the chroma planes for planar YUV - * - * \param component_bits bits per component - * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise - */ -int ff_mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits); - -#endif /* MPLAYER_IMG_FORMAT_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/libvo/fastmemcpy.h b/ffmpeg/libavfilter/libmpcodecs/libvo/fastmemcpy.h deleted file mode 100644 index 5a17d01..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/libvo/fastmemcpy.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with MPlayer; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MPLAYER_FASTMEMCPY_H -#define MPLAYER_FASTMEMCPY_H - -#include <inttypes.h> -#include <string.h> -#include <stddef.h> - -void * fast_memcpy(void * to, const void * from, size_t len); -void * mem2agpcpy(void * to, const void * from, size_t len); - -#if ! defined(CONFIG_FASTMEMCPY) || ! (HAVE_MMX || HAVE_MMX2 || HAVE_AMD3DNOW /* || HAVE_SSE || HAVE_SSE2 */) -#define mem2agpcpy(a,b,c) memcpy(a,b,c) -#define fast_memcpy(a,b,c) memcpy(a,b,c) -#endif - -static inline void * mem2agpcpy_pic(void * dst, const void * src, int bytesPerLine, int height, int dstStride, int srcStride) -{ - int i; - void *retval=dst; - - if(dstStride == srcStride) - { - if (srcStride < 0) { - src = (const uint8_t*)src + (height-1)*srcStride; - dst = (uint8_t*)dst + (height-1)*dstStride; - srcStride = -srcStride; - } - - mem2agpcpy(dst, src, srcStride*height); - } - else - { - for(i=0; i<height; i++) - { - mem2agpcpy(dst, src, bytesPerLine); - src = (const uint8_t*)src + srcStride; - dst = (uint8_t*)dst + dstStride; - } - } - - return retval; -} - -#define memcpy_pic(d, s, b, h, ds, ss) memcpy_pic2(d, s, b, h, ds, ss, 0) -#define my_memcpy_pic(d, s, b, h, ds, ss) memcpy_pic2(d, s, b, h, ds, ss, 1) - -/** - * \param limit2width always skip data between end of line and start of next - * instead of copying the full block when strides are the same - */ -static inline void * memcpy_pic2(void * dst, const void * src, - int bytesPerLine, int height, - int dstStride, int srcStride, int limit2width) -{ - int i; - void *retval=dst; - - if(!limit2width && dstStride == srcStride) - { - if (srcStride < 0) { - src = (const uint8_t*)src + (height-1)*srcStride; - dst = (uint8_t*)dst + (height-1)*dstStride; - srcStride = -srcStride; - } - - fast_memcpy(dst, src, srcStride*height); - } - else - { - for(i=0; i<height; i++) - { - fast_memcpy(dst, src, bytesPerLine); - src = (const uint8_t*)src + srcStride; - dst = (uint8_t*)dst + dstStride; - } - } - - return retval; -} - -#endif /* MPLAYER_FASTMEMCPY_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/libvo/video_out.h b/ffmpeg/libavfilter/libmpcodecs/libvo/video_out.h deleted file mode 100644 index 2a3a0fa..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/libvo/video_out.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (C) Aaron Holtzman - Aug 1999 - * Strongly modified, most parts rewritten: A'rpi/ESP-team - 2000-2001 - * (C) MPlayer developers - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_VIDEO_OUT_H -#define MPLAYER_VIDEO_OUT_H - -#include <inttypes.h> -#include <stdarg.h> - -//#include "sub/font_load.h" -#include "../img_format.h" -//#include "vidix/vidix.h" - -#define VO_EVENT_EXPOSE 1 -#define VO_EVENT_RESIZE 2 -#define VO_EVENT_KEYPRESS 4 -#define VO_EVENT_REINIT 8 -#define VO_EVENT_MOVE 16 - -/* Obsolete: VOCTRL_QUERY_VAA 1 */ -/* does the device support the required format */ -#define VOCTRL_QUERY_FORMAT 2 -/* signal a device reset seek */ -#define VOCTRL_RESET 3 -/* true if vo driver can use GUI created windows */ -#define VOCTRL_GUISUPPORT 4 -#define VOCTRL_GUI_NOWINDOW 19 -/* used to switch to fullscreen */ -#define VOCTRL_FULLSCREEN 5 -/* signal a device pause */ -#define VOCTRL_PAUSE 7 -/* start/resume playback */ -#define VOCTRL_RESUME 8 -/* libmpcodecs direct rendering: */ -#define VOCTRL_GET_IMAGE 9 -#define VOCTRL_DRAW_IMAGE 13 -#define VOCTRL_SET_SPU_PALETTE 14 -/* decoding ahead: */ -#define VOCTRL_GET_NUM_FRAMES 10 -#define VOCTRL_GET_FRAME_NUM 11 -#define VOCTRL_SET_FRAME_NUM 12 -#define VOCTRL_GET_PANSCAN 15 -#define VOCTRL_SET_PANSCAN 16 -/* equalizer controls */ -#define VOCTRL_SET_EQUALIZER 17 -#define VOCTRL_GET_EQUALIZER 18 -//#define VOCTRL_GUI_NOWINDOW 19 -/* Frame duplication */ -#define VOCTRL_DUPLICATE_FRAME 20 -// ... 21 -#define VOCTRL_START_SLICE 21 - -#define VOCTRL_ONTOP 25 -#define VOCTRL_ROOTWIN 26 -#define VOCTRL_BORDER 27 -#define VOCTRL_DRAW_EOSD 28 -#define VOCTRL_GET_EOSD_RES 29 - -#define VOCTRL_SET_DEINTERLACE 30 -#define VOCTRL_GET_DEINTERLACE 31 - -#define VOCTRL_UPDATE_SCREENINFO 32 - -// Vo can be used by xover -#define VOCTRL_XOVERLAY_SUPPORT 22 - -#define VOCTRL_XOVERLAY_SET_COLORKEY 24 -typedef struct { - uint32_t x11; // The raw x11 color - uint16_t r,g,b; -} mp_colorkey_t; - -#define VOCTRL_XOVERLAY_SET_WIN 23 -typedef struct { - int x,y; - int w,h; -} mp_win_t; - -#define VO_TRUE 1 -#define VO_FALSE 0 -#define VO_ERROR -1 -#define VO_NOTAVAIL -2 -#define VO_NOTIMPL -3 - -#define VOFLAG_FULLSCREEN 0x01 -#define VOFLAG_MODESWITCHING 0x02 -#define VOFLAG_SWSCALE 0x04 -#define VOFLAG_FLIPPING 0x08 -#define VOFLAG_HIDDEN 0x10 //< Use to create a hidden window -#define VOFLAG_STEREO 0x20 //< Use to create a stereo-capable window -#define VOFLAG_XOVERLAY_SUB_VO 0x10000 - -typedef struct vo_info_s -{ - /* driver name ("Matrox Millennium G200/G400" */ - const char *name; - /* short name (for config strings) ("mga") */ - const char *short_name; - /* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ - const char *author; - /* any additional comments */ - const char *comment; -} vo_info_t; - -typedef struct vo_functions_s -{ - const vo_info_t *info; - /* - * Preinitializes driver (real INITIALIZATION) - * arg - currently it's vo_subdevice - * returns: zero on successful initialization, non-zero on error. - */ - int (*preinit)(const char *arg); - /* - * Initialize (means CONFIGURE) the display driver. - * params: - * width,height: image source size - * d_width,d_height: size of the requested window size, just a hint - * fullscreen: flag, 0=windowd 1=fullscreen, just a hint - * title: window title, if available - * format: fourcc of pixel format - * returns : zero on successful initialization, non-zero on error. - */ - int (*config)(uint32_t width, uint32_t height, uint32_t d_width, - uint32_t d_height, uint32_t fullscreen, char *title, - uint32_t format); - - /* - * Control interface - */ - int (*control)(uint32_t request, void *data, ...); - - /* - * Display a new RGB/BGR frame of the video to the screen. - * params: - * src[0] - pointer to the image - */ - int (*draw_frame)(uint8_t *src[]); - - /* - * Draw a planar YUV slice to the buffer: - * params: - * src[3] = source image planes (Y,U,V) - * stride[3] = source image planes line widths (in bytes) - * w,h = width*height of area to be copied (in Y pixels) - * x,y = position at the destination image (in Y pixels) - */ - int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y); - - /* - * Draws OSD to the screen buffer - */ - void (*draw_osd)(void); - - /* - * Blit/Flip buffer to the screen. Must be called after each frame! - */ - void (*flip_page)(void); - - /* - * This func is called after every frames to handle keyboard and - * other events. It's called in PAUSE mode too! - */ - void (*check_events)(void); - - /* - * Closes driver. Should restore the original state of the system. - */ - void (*uninit)(void); -} vo_functions_t; - -const vo_functions_t* init_best_video_out(char** vo_list); -int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height, - uint32_t d_width, uint32_t d_height, uint32_t flags, - char *title, uint32_t format); -void list_video_out(void); - -// NULL terminated array of all drivers -extern const vo_functions_t* const video_out_drivers[]; - -extern int vo_flags; - -extern int vo_config_count; - -extern int xinerama_screen; -extern int xinerama_x; -extern int xinerama_y; - -// correct resolution/bpp on screen: (should be autodetected by vo_init()) -extern int vo_depthonscreen; -extern int vo_screenwidth; -extern int vo_screenheight; - -// requested resolution/bpp: (-x -y -bpp options) -extern int vo_dx; -extern int vo_dy; -extern int vo_dwidth; -extern int vo_dheight; -extern int vo_dbpp; - -extern int vo_grabpointer; -extern int vo_doublebuffering; -extern int vo_directrendering; -extern int vo_vsync; -extern int vo_fsmode; -extern float vo_panscan; -extern int vo_adapter_num; -extern int vo_refresh_rate; -extern int vo_keepaspect; -extern int vo_rootwin; -extern int vo_ontop; -extern int vo_border; - -extern int vo_gamma_gamma; -extern int vo_gamma_brightness; -extern int vo_gamma_saturation; -extern int vo_gamma_contrast; -extern int vo_gamma_hue; -extern int vo_gamma_red_intensity; -extern int vo_gamma_green_intensity; -extern int vo_gamma_blue_intensity; - -extern int vo_nomouse_input; -extern int enable_mouse_movements; - -extern int vo_pts; -extern float vo_fps; - -extern char *vo_subdevice; - -extern int vo_colorkey; - -extern char *vo_winname; -extern char *vo_wintitle; - -extern int64_t WinID; - -typedef struct { - float min; - float max; - } range_t; - -float range_max(range_t *r); -int in_range(range_t *r, float f); -range_t *str2range(char *s); -extern char *monitor_hfreq_str; -extern char *monitor_vfreq_str; -extern char *monitor_dotclock_str; - -struct mp_keymap { - int from; - int to; -}; -int lookup_keymap_table(const struct mp_keymap *map, int key); -struct vo_rect { - int left, right, top, bottom, width, height; -}; -void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst, - struct vo_rect *borders, const struct vo_rect *crop); -void vo_mouse_movement(int posx, int posy); - -#endif /* MPLAYER_VIDEO_OUT_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/mp_image.c b/ffmpeg/libavfilter/libmpcodecs/mp_image.c deleted file mode 100644 index 100ace9..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/mp_image.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#if HAVE_MALLOC_H -#include <malloc.h> -#endif - -#include "img_format.h" -#include "mp_image.h" - -#include "libvo/fastmemcpy.h" -//#include "libavutil/mem.h" -#include "libavutil/imgutils.h" - -void ff_mp_image_alloc_planes(mp_image_t *mpi) { - uint32_t temp[256]; - if (avpriv_set_systematic_pal2(temp, ff_mp2ff_pix_fmt(mpi->imgfmt)) >= 0) - mpi->flags |= MP_IMGFLAG_RGB_PALETTE; - - // IF09 - allocate space for 4. plane delta info - unused - if (mpi->imgfmt == IMGFMT_IF09) { - mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+ - mpi->chroma_width*mpi->chroma_height); - } else - mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8); - if (mpi->flags&MP_IMGFLAG_PLANAR) { - int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; - // YV12/I420/YVU9/IF09. feel free to add other planar formats here... - mpi->stride[0]=mpi->stride[3]=bpp*mpi->width; - if(mpi->num_planes > 2){ - mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width; - if(mpi->flags&MP_IMGFLAG_SWAPPED){ - // I420/IYUV (Y,U,V) - mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; - mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; - if (mpi->num_planes > 3) - mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height; - } else { - // YV12,YVU9,IF09 (Y,V,U) - mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; - mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; - if (mpi->num_planes > 3) - mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; - } - } else { - // NV12/NV21 - mpi->stride[1]=mpi->chroma_width; - mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; - } - } else { - mpi->stride[0]=mpi->width*mpi->bpp/8; - if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) { - mpi->planes[1] = av_malloc(1024); - memcpy(mpi->planes[1], temp, 1024); - } - } - mpi->flags|=MP_IMGFLAG_ALLOCATED; -} - -mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt) { - mp_image_t* mpi = ff_new_mp_image(w,h); - - ff_mp_image_setfmt(mpi,fmt); - ff_mp_image_alloc_planes(mpi); - - return mpi; -} - -void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) { - if(mpi->flags&MP_IMGFLAG_PLANAR){ - memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h, - dmpi->stride[0],mpi->stride[0]); - memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height, - dmpi->stride[1],mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, - dmpi->stride[2],mpi->stride[2]); - } else { - memcpy_pic(dmpi->planes[0],mpi->planes[0], - mpi->w*(dmpi->bpp/8), mpi->h, - dmpi->stride[0],mpi->stride[0]); - } -} - -void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ - mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED); - mpi->imgfmt=out_fmt; - // compressed formats - if(out_fmt == IMGFMT_MPEGPES || - out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB || - IMGFMT_IS_HWACCEL(out_fmt)){ - mpi->bpp=0; - return; - } - mpi->num_planes=1; - if (IMGFMT_IS_RGB(out_fmt)) { - if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128)) - mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt); - else - mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7); - return; - } - if (IMGFMT_IS_BGR(out_fmt)) { - if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128)) - mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt); - else - mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7); - mpi->flags|=MP_IMGFLAG_SWAPPED; - return; - } - mpi->num_planes=3; - if (out_fmt == IMGFMT_GBR24P) { - mpi->bpp=24; - mpi->flags|=MP_IMGFLAG_PLANAR; - return; - } else if (out_fmt == IMGFMT_GBR12P) { - mpi->bpp=36; - mpi->flags|=MP_IMGFLAG_PLANAR; - return; - } else if (out_fmt == IMGFMT_GBR14P) { - mpi->bpp=42; - mpi->flags|=MP_IMGFLAG_PLANAR; - return; - } - mpi->flags|=MP_IMGFLAG_YUV; - if (ff_mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) { - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp = ff_mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL); - mpi->chroma_width = mpi->width >> mpi->chroma_x_shift; - mpi->chroma_height = mpi->height >> mpi->chroma_y_shift; - } - switch(out_fmt){ - case IMGFMT_I420: - case IMGFMT_IYUV: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_YV12: - return; - case IMGFMT_420A: - case IMGFMT_422A: - case IMGFMT_444A: - case IMGFMT_IF09: - mpi->num_planes=4; - case IMGFMT_YVU9: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - case IMGFMT_440P: - case IMGFMT_444P16_LE: - case IMGFMT_444P16_BE: - case IMGFMT_444P14_LE: - case IMGFMT_444P14_BE: - case IMGFMT_444P12_LE: - case IMGFMT_444P12_BE: - case IMGFMT_444P10_LE: - case IMGFMT_444P10_BE: - case IMGFMT_444P9_LE: - case IMGFMT_444P9_BE: - case IMGFMT_422P16_LE: - case IMGFMT_422P16_BE: - case IMGFMT_422P14_LE: - case IMGFMT_422P14_BE: - case IMGFMT_422P12_LE: - case IMGFMT_422P12_BE: - case IMGFMT_422P10_LE: - case IMGFMT_422P10_BE: - case IMGFMT_422P9_LE: - case IMGFMT_422P9_BE: - case IMGFMT_420P16_LE: - case IMGFMT_420P16_BE: - case IMGFMT_420P14_LE: - case IMGFMT_420P14_BE: - case IMGFMT_420P12_LE: - case IMGFMT_420P12_BE: - case IMGFMT_420P10_LE: - case IMGFMT_420P10_BE: - case IMGFMT_420P9_LE: - case IMGFMT_420P9_BE: - return; - case IMGFMT_Y16_LE: - case IMGFMT_Y16_BE: - mpi->bpp=16; - case IMGFMT_Y800: - case IMGFMT_Y8: - /* they're planar ones, but for easier handling use them as packed */ - mpi->flags&=~MP_IMGFLAG_PLANAR; - mpi->num_planes=1; - return; - case IMGFMT_Y8A: - mpi->num_planes=2; - return; - case IMGFMT_UYVY: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_YUY2: - mpi->chroma_x_shift = 1; - mpi->bpp=16; - mpi->num_planes=1; - return; - case IMGFMT_NV12: - mpi->flags|=MP_IMGFLAG_SWAPPED; - case IMGFMT_NV21: - mpi->flags|=MP_IMGFLAG_PLANAR; - mpi->bpp=12; - mpi->num_planes=2; - mpi->chroma_width=(mpi->width>>0); - mpi->chroma_height=(mpi->height>>1); - mpi->chroma_x_shift=0; - mpi->chroma_y_shift=1; - return; - } - ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt); - mpi->bpp=0; -} - -mp_image_t* ff_new_mp_image(int w,int h){ - mp_image_t* mpi = malloc(sizeof(mp_image_t)); - if(!mpi) return NULL; // error! - memset(mpi,0,sizeof(mp_image_t)); - mpi->width=mpi->w=w; - mpi->height=mpi->h=h; - return mpi; -} - -void ff_free_mp_image(mp_image_t* mpi){ - if(!mpi) return; - if(mpi->flags&MP_IMGFLAG_ALLOCATED){ - /* becouse we allocate the whole image in once */ - av_free(mpi->planes[0]); - if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) - av_free(mpi->planes[1]); - } - free(mpi); -} - diff --git a/ffmpeg/libavfilter/libmpcodecs/mp_image.h b/ffmpeg/libavfilter/libmpcodecs/mp_image.h deleted file mode 100644 index aedf451..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/mp_image.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_MP_IMAGE_H -#define MPLAYER_MP_IMAGE_H - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#undef printf //FIXME -#undef fprintf //FIXME -#include "mp_msg.h" -#include "libavutil/avutil.h" -#include "libavutil/avassert.h" -#undef realloc -#undef malloc -#undef free -#undef rand -#undef srand -#undef printf -#undef strncpy -#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t" -#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). - -enum AVPixelFormat ff_mp2ff_pix_fmt(int mp); - -//--------- codec's requirements (filled by the codec/vf) --------- - -//--- buffer content restrictions: -// set if buffer content shouldn't be modified: -#define MP_IMGFLAG_PRESERVE 0x01 -// set if buffer content will be READ. -// This can be e.g. for next frame's MC: (I/P mpeg frames) - -// then in combination with MP_IMGFLAG_PRESERVE - or it -// can be because a video filter or codec will read a significant -// amount of data while processing that frame (e.g. blending something -// onto the frame, MV based intra prediction). -// A frame marked like this should not be placed in to uncachable -// video RAM for example. -#define MP_IMGFLAG_READABLE 0x02 - -//--- buffer width/stride/plane restrictions: (used for direct rendering) -// stride _have_to_ be aligned to MB boundary: [for DR restrictions] -#define MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE 0x4 -// stride should be aligned to MB boundary: [for buffer allocation] -#define MP_IMGFLAG_PREFER_ALIGNED_STRIDE 0x8 -// codec accept any stride (>=width): -#define MP_IMGFLAG_ACCEPT_STRIDE 0x10 -// codec accept any width (width*bpp=stride -> stride%bpp==0) (>=width): -#define MP_IMGFLAG_ACCEPT_WIDTH 0x20 -//--- for planar formats only: -// uses only stride[0], and stride[1]=stride[2]=stride[0]>>mpi->chroma_x_shift -#define MP_IMGFLAG_COMMON_STRIDE 0x40 -// uses only planes[0], and calculates planes[1,2] from width,height,imgfmt -#define MP_IMGFLAG_COMMON_PLANE 0x80 - -#define MP_IMGFLAGMASK_RESTRICTIONS 0xFF - -//--------- color info (filled by ff_mp_image_setfmt() ) ----------- -// set if number of planes > 1 -#define MP_IMGFLAG_PLANAR 0x100 -// set if it's YUV colorspace -#define MP_IMGFLAG_YUV 0x200 -// set if it's swapped (BGR or YVU) plane/byteorder -#define MP_IMGFLAG_SWAPPED 0x400 -// set if you want memory for palette allocated and managed by ff_vf_get_image etc. -#define MP_IMGFLAG_RGB_PALETTE 0x800 - -#define MP_IMGFLAGMASK_COLORS 0xF00 - -// codec uses drawing/rendering callbacks (draw_slice()-like thing, DR method 2) -// [the codec will set this flag if it supports callbacks, and the vo _may_ -// clear it in get_image() if draw_slice() not implemented] -#define MP_IMGFLAG_DRAW_CALLBACK 0x1000 -// set if it's in video buffer/memory: [set by vo/vf's get_image() !!!] -#define MP_IMGFLAG_DIRECT 0x2000 -// set if buffer is allocated (used in destination images): -#define MP_IMGFLAG_ALLOCATED 0x4000 - -// buffer type was printed (do NOT set this flag - it's for INTERNAL USE!!!) -#define MP_IMGFLAG_TYPE_DISPLAYED 0x8000 - -// codec doesn't support any form of direct rendering - it has own buffer -// allocation. so we just export its buffer pointers: -#define MP_IMGTYPE_EXPORT 0 -// codec requires a static WO buffer, but it does only partial updates later: -#define MP_IMGTYPE_STATIC 1 -// codec just needs some WO memory, where it writes/copies the whole frame to: -#define MP_IMGTYPE_TEMP 2 -// I+P type, requires 2+ independent static R/W buffers -#define MP_IMGTYPE_IP 3 -// I+P+B type, requires 2+ independent static R/W and 1+ temp WO buffers -#define MP_IMGTYPE_IPB 4 -// Upper 16 bits give desired buffer number, -1 means get next available -#define MP_IMGTYPE_NUMBERED 5 -// Doesn't need any buffer, incomplete image (probably a first field only) -// we need this type to be able to differentiate between half frames and -// all other cases -#define MP_IMGTYPE_INCOMPLETE 6 - -#define MP_MAX_PLANES 4 - -#define MP_IMGFIELD_ORDERED 0x01 -#define MP_IMGFIELD_TOP_FIRST 0x02 -#define MP_IMGFIELD_REPEAT_FIRST 0x04 -#define MP_IMGFIELD_TOP 0x08 -#define MP_IMGFIELD_BOTTOM 0x10 -#define MP_IMGFIELD_INTERLACED 0x20 - -typedef struct mp_image { - unsigned int flags; - unsigned char type; - int number; - unsigned char bpp; // bits/pixel. NOT depth! for RGB it will be n*8 - unsigned int imgfmt; - int width,height; // stored dimensions - int x,y,w,h; // visible dimensions - unsigned char* planes[MP_MAX_PLANES]; - int stride[MP_MAX_PLANES]; - char * qscale; - int qstride; - int pict_type; // 0->unknown, 1->I, 2->P, 3->B - int fields; - int qscale_type; // 0->mpeg1/4/h263, 1->mpeg2 - int num_planes; - /* these are only used by planar formats Y,U(Cb),V(Cr) */ - int chroma_width; - int chroma_height; - int chroma_x_shift; // horizontal - int chroma_y_shift; // vertical - int usage_count; - /* for private use by filter or vo driver (to store buffer id or dmpi) */ - void* priv; -} mp_image_t; - -void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt); -mp_image_t* ff_new_mp_image(int w,int h); -void ff_free_mp_image(mp_image_t* mpi); - -mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt); -void ff_mp_image_alloc_planes(mp_image_t *mpi); -void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi); - -#endif /* MPLAYER_MP_IMAGE_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/mp_msg.h b/ffmpeg/libavfilter/libmpcodecs/mp_msg.h deleted file mode 100644 index 51cdff3..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/mp_msg.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_MP_MSG_H -#define MPLAYER_MP_MSG_H - -#include <stdarg.h> - -// defined in mplayer.c and mencoder.c -extern int verbose; - -// verbosity elevel: - -/* Only messages level MSGL_FATAL-MSGL_STATUS should be translated, - * messages level MSGL_V and above should not be translated. */ - -#define MSGL_FATAL 0 // will exit/abort -#define MSGL_ERR 1 // continues -#define MSGL_WARN 2 // only warning -#define MSGL_HINT 3 // short help message -#define MSGL_INFO 4 // -quiet -#define MSGL_STATUS 5 // v=0 -#define MSGL_V 6 // v=1 -#define MSGL_DBG2 7 // v=2 -#define MSGL_DBG3 8 // v=3 -#define MSGL_DBG4 9 // v=4 -#define MSGL_DBG5 10 // v=5 - -#define MSGL_FIXME 1 // for conversions from printf where the appropriate MSGL is not known; set equal to ERR for obtrusiveness -#define MSGT_FIXME 0 // for conversions from printf where the appropriate MSGT is not known; set equal to GLOBAL for obtrusiveness - -// code/module: - -#define MSGT_GLOBAL 0 // common player stuff errors -#define MSGT_CPLAYER 1 // console player (mplayer.c) -#define MSGT_GPLAYER 2 // gui player - -#define MSGT_VO 3 // libvo -#define MSGT_AO 4 // libao - -#define MSGT_DEMUXER 5 // demuxer.c (general stuff) -#define MSGT_DS 6 // demux stream (add/read packet etc) -#define MSGT_DEMUX 7 // fileformat-specific stuff (demux_*.c) -#define MSGT_HEADER 8 // fileformat-specific header (*header.c) - -#define MSGT_AVSYNC 9 // mplayer.c timer stuff -#define MSGT_AUTOQ 10 // mplayer.c auto-quality stuff - -#define MSGT_CFGPARSER 11 // cfgparser.c - -#define MSGT_DECAUDIO 12 // av decoder -#define MSGT_DECVIDEO 13 - -#define MSGT_SEEK 14 // seeking code -#define MSGT_WIN32 15 // win32 dll stuff -#define MSGT_OPEN 16 // open.c (stream opening) -#define MSGT_DVD 17 // open.c (DVD init/read/seek) - -#define MSGT_PARSEES 18 // parse_es.c (mpeg stream parser) -#define MSGT_LIRC 19 // lirc_mp.c and input lirc driver - -#define MSGT_STREAM 20 // stream.c -#define MSGT_CACHE 21 // cache2.c - -#define MSGT_MENCODER 22 - -#define MSGT_XACODEC 23 // XAnim codecs - -#define MSGT_TV 24 // TV input subsystem - -#define MSGT_OSDEP 25 // OS-dependent parts - -#define MSGT_SPUDEC 26 // spudec.c - -#define MSGT_PLAYTREE 27 // Playtree handeling (playtree.c, playtreeparser.c) - -#define MSGT_INPUT 28 - -#define MSGT_VFILTER 29 - -#define MSGT_OSD 30 - -#define MSGT_NETWORK 31 - -#define MSGT_CPUDETECT 32 - -#define MSGT_CODECCFG 33 - -#define MSGT_SWS 34 - -#define MSGT_VOBSUB 35 -#define MSGT_SUBREADER 36 - -#define MSGT_AFILTER 37 // Audio filter messages - -#define MSGT_NETST 38 // Netstream - -#define MSGT_MUXER 39 // muxer layer - -#define MSGT_OSD_MENU 40 - -#define MSGT_IDENTIFY 41 // -identify output - -#define MSGT_RADIO 42 - -#define MSGT_ASS 43 // libass messages - -#define MSGT_LOADER 44 // dll loader messages - -#define MSGT_STATUSLINE 45 // playback/encoding status line - -#define MSGT_TELETEXT 46 // Teletext decoder - -#define MSGT_MAX 64 - - -extern char *ff_mp_msg_charset; -extern int ff_mp_msg_color; -extern int ff_mp_msg_module; - -extern int ff_mp_msg_levels[MSGT_MAX]; -extern int ff_mp_msg_level_all; - - -void ff_mp_msg_init(void); -int ff_mp_msg_test(int mod, int lev); - -#include "config.h" - -void ff_mp_msg_va(int mod, int lev, const char *format, va_list va); -#ifdef __GNUC__ -void ff_mp_msg(int mod, int lev, const char *format, ... ) __attribute__ ((format (printf, 3, 4))); -# ifdef MP_DEBUG -# define mp_dbg(mod,lev, args... ) ff_mp_msg(mod, lev, ## args ) -# else - // only useful for developers, disable but check syntax -# define mp_dbg(mod,lev, args... ) do { if (0) ff_mp_msg(mod, lev, ## args ); } while (0) -# endif -#else // not GNU C -void ff_mp_msg(int mod, int lev, const char *format, ... ); -# ifdef MP_DEBUG -# define mp_dbg(mod,lev, ... ) ff_mp_msg(mod, lev, __VA_ARGS__) -# else - // only useful for developers, disable but check syntax -# define mp_dbg(mod,lev, ... ) do { if (0) ff_mp_msg(mod, lev, __VA_ARGS__); } while (0) -# endif -#endif /* __GNUC__ */ - -const char* ff_filename_recode(const char* filename); - -#endif /* MPLAYER_MP_MSG_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/mpc_info.h b/ffmpeg/libavfilter/libmpcodecs/mpc_info.h deleted file mode 100644 index 8554699..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/mpc_info.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_MPC_INFO_H -#define MPLAYER_MPC_INFO_H - -typedef struct mp_codec_info_s -{ - /* codec long name ("Autodesk FLI/FLC Animation decoder" */ - const char *name; - /* short name (same as driver name in codecs.conf) ("dshow") */ - const char *short_name; - /* interface author/maintainer */ - const char *maintainer; - /* codec author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */ - const char *author; - /* any additional comments */ - const char *comment; -} mp_codec_info_t; - -#define CONTROL_OK 1 -#define CONTROL_TRUE 1 -#define CONTROL_FALSE 0 -#define CONTROL_UNKNOWN -1 -#define CONTROL_ERROR -2 -#define CONTROL_NA -3 - -#endif /* MPLAYER_MPC_INFO_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/vf.h b/ffmpeg/libavfilter/libmpcodecs/vf.h deleted file mode 100644 index 0d26296..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_VF_H -#define MPLAYER_VF_H - -//#include "m_option.h" -#include "mp_image.h" - -//extern m_obj_settings_t* vf_settings; -//extern const m_obj_list_t vf_obj_list; - -struct vf_instance; -struct vf_priv_s; - -typedef struct vf_info_s { - const char *info; - const char *name; - const char *author; - const char *comment; - int (*vf_open)(struct vf_instance *vf,char* args); - // Ptr to a struct dscribing the options - const void* opts; -} vf_info_t; - -#define NUM_NUMBERED_MPI 50 - -typedef struct vf_image_context_s { - mp_image_t* static_images[2]; - mp_image_t* temp_images[1]; - mp_image_t* export_images[1]; - mp_image_t* numbered_images[NUM_NUMBERED_MPI]; - int static_idx; -} vf_image_context_t; - -typedef struct vf_format_context_t { - int have_configured; - int orig_width, orig_height, orig_fmt; -} vf_format_context_t; - -typedef struct vf_instance { - const vf_info_t* info; - // funcs: - int (*config)(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt); - int (*control)(struct vf_instance *vf, - int request, void* data); - int (*query_format)(struct vf_instance *vf, - unsigned int fmt); - void (*get_image)(struct vf_instance *vf, - mp_image_t *mpi); - int (*put_image)(struct vf_instance *vf, - mp_image_t *mpi, double pts); - void (*start_slice)(struct vf_instance *vf, - mp_image_t *mpi); - void (*draw_slice)(struct vf_instance *vf, - unsigned char** src, int* stride, int w,int h, int x, int y); - void (*uninit)(struct vf_instance *vf); - - int (*continue_buffered_image)(struct vf_instance *vf); - // caps: - unsigned int default_caps; // used by default query_format() - unsigned int default_reqs; // used by default config() - // data: - int w, h; - vf_image_context_t imgctx; - vf_format_context_t fmt; - struct vf_instance *next; - mp_image_t *dmpi; - struct vf_priv_s* priv; -} vf_instance_t; - -// control codes: -#include "mpc_info.h" - -typedef struct vf_seteq_s -{ - const char *item; - int value; -} vf_equalizer_t; - -#define VFCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */ -#define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */ -#define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */ -#define VFCTRL_GET_EQUALIZER 8 /* gset color options (brightness,contrast etc) */ -#define VFCTRL_DRAW_OSD 7 -#define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */ -#define VFCTRL_FLIP_PAGE 10 /* Tell the vo to flip pages */ -#define VFCTRL_DUPLICATE_FRAME 11 /* For encoding - encode zero-change frame */ -#define VFCTRL_SKIP_NEXT_FRAME 12 /* For encoding - drop the next frame that passes thru */ -#define VFCTRL_FLUSH_FRAMES 13 /* For encoding - flush delayed frames */ -#define VFCTRL_SCREENSHOT 14 /* Make a screenshot */ -#define VFCTRL_INIT_EOSD 15 /* Select EOSD renderer */ -#define VFCTRL_DRAW_EOSD 16 /* Render EOSD */ -#define VFCTRL_GET_PTS 17 /* Return last pts value that reached vf_vo*/ -#define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */ -#define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */ - -#include "vfcap.h" - -//FIXME this should be in a common header, but i dunno which -#define MP_NOPTS_VALUE (-1LL<<63) //both int64_t and double should be able to represent this exactly - - -// functions: -void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h); -mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h); - -vf_instance_t* vf_open_plugin(const vf_info_t* const* filter_list, vf_instance_t* next, const char *name, char **args); -vf_instance_t* vf_open_filter(vf_instance_t* next, const char *name, char **args); -vf_instance_t* ff_vf_add_before_vo(vf_instance_t **vf, char *name, char **args); -vf_instance_t* vf_open_encoder(vf_instance_t* next, const char *name, char *args); - -unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred); -void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src); -void ff_vf_queue_frame(vf_instance_t *vf, int (*)(vf_instance_t *)); -int ff_vf_output_queued_frame(vf_instance_t *vf); - -// default wrappers: -int ff_vf_next_config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt); -int ff_vf_next_control(struct vf_instance *vf, int request, void* data); -void ff_vf_extra_flip(struct vf_instance *vf); -int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt); -int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts); -void ff_vf_next_draw_slice (struct vf_instance *vf, unsigned char** src, int* stride, int w,int h, int x, int y); - -vf_instance_t* ff_append_filters(vf_instance_t* last); - -void ff_vf_uninit_filter(vf_instance_t* vf); -void ff_vf_uninit_filter_chain(vf_instance_t* vf); - -int ff_vf_config_wrapper(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt); - -static inline int norm_qscale(int qscale, int type) -{ - switch (type) { - case 0: // MPEG-1 - return qscale; - case 1: // MPEG-2 - return qscale >> 1; - case 2: // H264 - return qscale >> 2; - case 3: // VP56 - return (63 - qscale + 2) >> 2; - } - return qscale; -} - -#endif /* MPLAYER_VF_H */ diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_eq.c b/ffmpeg/libavfilter/libmpcodecs/vf_eq.c deleted file mode 100644 index c926c51..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_eq.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/video_out.h" - -struct vf_priv_s { - unsigned char *buf; - int brightness; - int contrast; -}; - -#if HAVE_MMX -static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast) -{ - int i; - int pel; - int dstep = dstride-w; - int sstep = sstride-w; - short brvec[4]; - short contvec[4]; - - contrast = ((contrast+100)*256*16)/100; - brightness = ((brightness+100)*511)/200-128 - contrast/32; - - brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness; - contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast; - - while (h--) { - __asm__ volatile ( - "movq (%5), %%mm3 \n\t" - "movq (%6), %%mm4 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "movl %4, %%eax\n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "punpcklbw %%mm0, %%mm1 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" - "psllw $4, %%mm1 \n\t" - "psllw $4, %%mm2 \n\t" - "pmulhw %%mm4, %%mm1 \n\t" - "pmulhw %%mm4, %%mm2 \n\t" - "paddw %%mm3, %%mm1 \n\t" - "paddw %%mm3, %%mm2 \n\t" - "packuswb %%mm2, %%mm1 \n\t" - "add $8, %0 \n\t" - "movq %%mm1, (%1) \n\t" - "add $8, %1 \n\t" - "decl %%eax \n\t" - "jnz 1b \n\t" - : "=r" (src), "=r" (dest) - : "0" (src), "1" (dest), "r" (w>>3), "r" (brvec), "r" (contvec) - : "%eax" - ); - - for (i = w&7; i; i--) - { - pel = ((*src++* contrast)>>12) + brightness; - if(pel&768) pel = (-pel)>>31; - *dest++ = pel; - } - - src += sstep; - dest += dstep; - } - __asm__ volatile ( "emms \n\t" ::: "memory" ); -} -#endif - -static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast) -{ - int i; - int pel; - int dstep = dstride-w; - int sstep = sstride-w; - - contrast = ((contrast+100)*256*256)/100; - brightness = ((brightness+100)*511)/200-128 - contrast/512; - - while (h--) { - for (i = w; i; i--) - { - pel = ((*src++* contrast)>>16) + brightness; - if(pel&768) pel = (-pel)>>31; - *dest++ = pel; - } - src += sstep; - dest += dstep; - } -} - -static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride, - int w, int h, int brightness, int contrast); - -/* FIXME: add packed yuv version of process */ - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - dmpi=ff_vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_EXPORT, 0, - mpi->w, mpi->h); - - dmpi->stride[0] = mpi->stride[0]; - dmpi->planes[1] = mpi->planes[1]; - dmpi->planes[2] = mpi->planes[2]; - dmpi->stride[1] = mpi->stride[1]; - dmpi->stride[2] = mpi->stride[2]; - - if (!vf->priv->buf) vf->priv->buf = malloc(mpi->stride[0]*mpi->h); - - if ((vf->priv->brightness == 0) && (vf->priv->contrast == 0)) - dmpi->planes[0] = mpi->planes[0]; - else { - dmpi->planes[0] = vf->priv->buf; - process(dmpi->planes[0], dmpi->stride[0], - mpi->planes[0], mpi->stride[0], - mpi->w, mpi->h, vf->priv->brightness, - vf->priv->contrast); - } - - return ff_vf_next_put_image(vf,dmpi, pts); -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - vf_equalizer_t *eq; - - switch (request) { - case VFCTRL_SET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"brightness")) { - vf->priv->brightness = eq->value; - return CONTROL_TRUE; - } - else if (!strcmp(eq->item,"contrast")) { - vf->priv->contrast = eq->value; - return CONTROL_TRUE; - } - break; - case VFCTRL_GET_EQUALIZER: - eq = data; - if (!strcmp(eq->item,"brightness")) { - eq->value = vf->priv->brightness; - return CONTROL_TRUE; - } - else if (!strcmp(eq->item,"contrast")) { - eq->value = vf->priv->contrast; - return CONTROL_TRUE; - } - break; - } - return ff_vf_next_control(vf, request, data); -} - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch (fmt) { - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_NV12: - case IMGFMT_NV21: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return ff_vf_next_query_format(vf, fmt); - } - return 0; -} - -static void uninit(struct vf_instance *vf) -{ - free(vf->priv->buf); - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->control=control; - vf->query_format=query_format; - vf->put_image=put_image; - vf->uninit=uninit; - - vf->priv = malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - if (args) sscanf(args, "%d:%d", &vf->priv->brightness, &vf->priv->contrast); - - process = process_C; -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX) process = process_MMX; -#endif - - return 1; -} - -const vf_info_t ff_vf_info_eq = { - "soft video equalizer", - "eq", - "Richard Felker", - "", - vf_open, -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c b/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c deleted file mode 100644 index 7a3ef31..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_eq2.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Software equalizer (brightness, contrast, gamma, saturation) - * - * Hampa Hug <hampa@hampa.ch> (original LUT gamma/contrast/brightness filter) - * Daniel Moreno <comac@comac.darktech.org> (saturation, R/G/B gamma support) - * Richard Felker (original MMX contrast/brightness code (vf_eq.c)) - * Michael Niedermayer <michalni@gmx.at> (LUT16) - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <inttypes.h> - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#define LUT16 - -/* Per channel parameters */ -typedef struct eq2_param_t { - unsigned char lut[256]; -#ifdef LUT16 - uint16_t lut16[256*256]; -#endif - int lut_clean; - - void (*adjust) (struct eq2_param_t *par, unsigned char *dst, unsigned char *src, - unsigned w, unsigned h, unsigned dstride, unsigned sstride); - - double c; - double b; - double g; - double w; -} eq2_param_t; - -typedef struct vf_priv_s { - eq2_param_t param[3]; - - double contrast; - double brightness; - double saturation; - - double gamma; - double gamma_weight; - double rgamma; - double ggamma; - double bgamma; - - unsigned buf_w[3]; - unsigned buf_h[3]; - unsigned char *buf[3]; -} vf_eq2_t; - - -static -void create_lut (eq2_param_t *par) -{ - unsigned i; - double g, v; - double lw, gw; - - g = par->g; - gw = par->w; - lw = 1.0 - gw; - - if ((g < 0.001) || (g > 1000.0)) { - g = 1.0; - } - - g = 1.0 / g; - - for (i = 0; i < 256; i++) { - v = (double) i / 255.0; - v = par->c * (v - 0.5) + 0.5 + par->b; - - if (v <= 0.0) { - par->lut[i] = 0; - } - else { - v = v*lw + pow(v, g)*gw; - - if (v >= 1.0) { - par->lut[i] = 255; - } - else { - par->lut[i] = (unsigned char) (256.0 * v); - } - } - } - -#ifdef LUT16 - for(i=0; i<256*256; i++){ - par->lut16[i]= par->lut[i&0xFF] + (par->lut[i>>8]<<8); - } -#endif - - par->lut_clean = 1; -} - -#if HAVE_MMX -static -void affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src, - unsigned w, unsigned h, unsigned dstride, unsigned sstride) -{ - unsigned i; - int contrast, brightness; - unsigned dstep, sstep; - int pel; - short brvec[4]; - short contvec[4]; - -// printf("\nmmx: src=%p dst=%p w=%d h=%d ds=%d ss=%d\n",src,dst,w,h,dstride,sstride); - - contrast = (int) (par->c * 256 * 16); - brightness = ((int) (100.0 * par->b + 100.0) * 511) / 200 - 128 - contrast / 32; - - brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness; - contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast; - - sstep = sstride - w; - dstep = dstride - w; - - while (h-- > 0) { - __asm__ volatile ( - "movq (%5), %%mm3 \n\t" - "movq (%6), %%mm4 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "movl %4, %%eax\n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "punpcklbw %%mm0, %%mm1 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" - "psllw $4, %%mm1 \n\t" - "psllw $4, %%mm2 \n\t" - "pmulhw %%mm4, %%mm1 \n\t" - "pmulhw %%mm4, %%mm2 \n\t" - "paddw %%mm3, %%mm1 \n\t" - "paddw %%mm3, %%mm2 \n\t" - "packuswb %%mm2, %%mm1 \n\t" - "add $8, %0 \n\t" - "movq %%mm1, (%1) \n\t" - "add $8, %1 \n\t" - "decl %%eax \n\t" - "jnz 1b \n\t" - : "=r" (src), "=r" (dst) - : "0" (src), "1" (dst), "r" (w >> 3), "r" (brvec), "r" (contvec) - : "%eax" - ); - - for (i = w & 7; i > 0; i--) { - pel = ((*src++ * contrast) >> 12) + brightness; - if (pel & 768) { - pel = (-pel) >> 31; - } - *dst++ = pel; - } - - src += sstep; - dst += dstep; - } - - __asm__ volatile ( "emms \n\t" ::: "memory" ); -} -#endif - -static -void apply_lut (eq2_param_t *par, unsigned char *dst, unsigned char *src, - unsigned w, unsigned h, unsigned dstride, unsigned sstride) -{ - unsigned i, j, w2; - unsigned char *lut; - uint16_t *lut16; - - if (!par->lut_clean) { - create_lut (par); - } - - lut = par->lut; -#ifdef LUT16 - lut16 = par->lut16; - w2= (w>>3)<<2; - for (j = 0; j < h; j++) { - uint16_t *src16= (uint16_t*)src; - uint16_t *dst16= (uint16_t*)dst; - for (i = 0; i < w2; i+=4) { - dst16[i+0] = lut16[src16[i+0]]; - dst16[i+1] = lut16[src16[i+1]]; - dst16[i+2] = lut16[src16[i+2]]; - dst16[i+3] = lut16[src16[i+3]]; - } - i <<= 1; -#else - w2= (w>>3)<<3; - for (j = 0; j < h; j++) { - for (i = 0; i < w2; i+=8) { - dst[i+0] = lut[src[i+0]]; - dst[i+1] = lut[src[i+1]]; - dst[i+2] = lut[src[i+2]]; - dst[i+3] = lut[src[i+3]]; - dst[i+4] = lut[src[i+4]]; - dst[i+5] = lut[src[i+5]]; - dst[i+6] = lut[src[i+6]]; - dst[i+7] = lut[src[i+7]]; - } -#endif - for (; i < w; i++) { - dst[i] = lut[src[i]]; - } - - src += sstride; - dst += dstride; - } -} - -static -int put_image (vf_instance_t *vf, mp_image_t *src, double pts) -{ - unsigned i; - vf_eq2_t *eq2; - mp_image_t *dst; - unsigned long img_n,img_c; - - eq2 = vf->priv; - - if ((eq2->buf_w[0] != src->w) || (eq2->buf_h[0] != src->h)) { - eq2->buf_w[0] = src->w; - eq2->buf_h[0] = src->h; - eq2->buf_w[1] = eq2->buf_w[2] = src->w >> src->chroma_x_shift; - eq2->buf_h[1] = eq2->buf_h[2] = src->h >> src->chroma_y_shift; - img_n = eq2->buf_w[0]*eq2->buf_h[0]; - if(src->num_planes>1){ - img_c = eq2->buf_w[1]*eq2->buf_h[1]; - eq2->buf[0] = realloc (eq2->buf[0], img_n + 2*img_c); - eq2->buf[1] = eq2->buf[0] + img_n; - eq2->buf[2] = eq2->buf[1] + img_c; - } else - eq2->buf[0] = realloc (eq2->buf[0], img_n); - } - - dst = ff_vf_get_image (vf->next, src->imgfmt, MP_IMGTYPE_EXPORT, 0, src->w, src->h); - - for (i = 0; i < ((src->num_planes>1)?3:1); i++) { - if (eq2->param[i].adjust != NULL) { - dst->planes[i] = eq2->buf[i]; - dst->stride[i] = eq2->buf_w[i]; - - eq2->param[i].adjust (&eq2->param[i], dst->planes[i], src->planes[i], - eq2->buf_w[i], eq2->buf_h[i], dst->stride[i], src->stride[i]); - } - else { - dst->planes[i] = src->planes[i]; - dst->stride[i] = src->stride[i]; - } - } - - return ff_vf_next_put_image (vf, dst, pts); -} - -static -void check_values (eq2_param_t *par) -{ - /* yuck! floating point comparisons... */ - - if ((par->c == 1.0) && (par->b == 0.0) && (par->g == 1.0)) { - par->adjust = NULL; - } -#if HAVE_MMX - else if (par->g == 1.0 && ff_gCpuCaps.hasMMX) { - par->adjust = &affine_1d_MMX; - } -#endif - else { - par->adjust = &apply_lut; - } -} - -static -void print_values (vf_eq2_t *eq2) -{ - ff_mp_msg (MSGT_VFILTER, MSGL_V, "vf_eq2: c=%.2f b=%.2f g=%.4f s=%.2f \n", - eq2->contrast, eq2->brightness, eq2->gamma, eq2->saturation - ); -} - -static -void set_contrast (vf_eq2_t *eq2, double c) -{ - eq2->contrast = c; - eq2->param[0].c = c; - eq2->param[0].lut_clean = 0; - check_values (&eq2->param[0]); - print_values (eq2); -} - -static -void set_brightness (vf_eq2_t *eq2, double b) -{ - eq2->brightness = b; - eq2->param[0].b = b; - eq2->param[0].lut_clean = 0; - check_values (&eq2->param[0]); - print_values (eq2); -} - -static -void set_gamma (vf_eq2_t *eq2, double g) -{ - eq2->gamma = g; - - eq2->param[0].g = eq2->gamma * eq2->ggamma; - eq2->param[1].g = sqrt (eq2->bgamma / eq2->ggamma); - eq2->param[2].g = sqrt (eq2->rgamma / eq2->ggamma); - eq2->param[0].w = eq2->param[1].w = eq2->param[2].w = eq2->gamma_weight; - - eq2->param[0].lut_clean = 0; - eq2->param[1].lut_clean = 0; - eq2->param[2].lut_clean = 0; - - check_values (&eq2->param[0]); - check_values (&eq2->param[1]); - check_values (&eq2->param[2]); - - print_values (eq2); -} - -static -void set_saturation (vf_eq2_t *eq2, double s) -{ - eq2->saturation = s; - - eq2->param[1].c = s; - eq2->param[2].c = s; - - eq2->param[1].lut_clean = 0; - eq2->param[2].lut_clean = 0; - - check_values (&eq2->param[1]); - check_values (&eq2->param[2]); - - print_values (eq2); -} - -static -int control (vf_instance_t *vf, int request, void *data) -{ - vf_equalizer_t *eq; - - switch (request) { - case VFCTRL_SET_EQUALIZER: - eq = (vf_equalizer_t *) data; - - if (strcmp (eq->item, "gamma") == 0) { - set_gamma (vf->priv, exp (log (8.0) * eq->value / 100.0)); - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "contrast") == 0) { - set_contrast (vf->priv, (1.0 / 100.0) * (eq->value + 100)); - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "brightness") == 0) { - set_brightness (vf->priv, (1.0 / 100.0) * eq->value); - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "saturation") == 0) { - set_saturation (vf->priv, (double) (eq->value + 100) / 100.0); - return CONTROL_TRUE; - } - break; - - case VFCTRL_GET_EQUALIZER: - eq = (vf_equalizer_t *) data; - if (strcmp (eq->item, "gamma") == 0) { - eq->value = (int) (100.0 * log (vf->priv->gamma) / log (8.0)); - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "contrast") == 0) { - eq->value = (int) (100.0 * vf->priv->contrast) - 100; - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "brightness") == 0) { - eq->value = (int) (100.0 * vf->priv->brightness); - return CONTROL_TRUE; - } - else if (strcmp (eq->item, "saturation") == 0) { - eq->value = (int) (100.0 * vf->priv->saturation) - 100; - return CONTROL_TRUE; - } - break; - } - - return ff_vf_next_control (vf, request, data); -} - -static -int query_format (vf_instance_t *vf, unsigned fmt) -{ - switch (fmt) { - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return ff_vf_next_query_format (vf, fmt); - } - - return 0; -} - -static -void uninit (vf_instance_t *vf) -{ - if (vf->priv != NULL) { - free (vf->priv->buf[0]); - free (vf->priv); - } -} - -static -int vf_open(vf_instance_t *vf, char *args) -{ - unsigned i; - vf_eq2_t *eq2; - double par[8]; - - vf->control = control; - vf->query_format = query_format; - vf->put_image = put_image; - vf->uninit = uninit; - - vf->priv = malloc (sizeof (vf_eq2_t)); - eq2 = vf->priv; - - for (i = 0; i < 3; i++) { - eq2->buf[i] = NULL; - eq2->buf_w[i] = 0; - eq2->buf_h[i] = 0; - - eq2->param[i].adjust = NULL; - eq2->param[i].c = 1.0; - eq2->param[i].b = 0.0; - eq2->param[i].g = 1.0; - eq2->param[i].lut_clean = 0; - } - - eq2->contrast = 1.0; - eq2->brightness = 0.0; - eq2->saturation = 1.0; - - eq2->gamma = 1.0; - eq2->gamma_weight = 1.0; - eq2->rgamma = 1.0; - eq2->ggamma = 1.0; - eq2->bgamma = 1.0; - - if (args != NULL) { - par[0] = 1.0; - par[1] = 1.0; - par[2] = 0.0; - par[3] = 1.0; - par[4] = 1.0; - par[5] = 1.0; - par[6] = 1.0; - par[7] = 1.0; - sscanf (args, "%lf:%lf:%lf:%lf:%lf:%lf:%lf:%lf", - par, par + 1, par + 2, par + 3, par + 4, par + 5, par + 6, par + 7 - ); - - eq2->rgamma = par[4]; - eq2->ggamma = par[5]; - eq2->bgamma = par[6]; - eq2->gamma_weight = par[7]; - - set_gamma (eq2, par[0]); - set_contrast (eq2, par[1]); - set_brightness (eq2, par[2]); - set_saturation (eq2, par[3]); - } - - return 1; -} - -const vf_info_t ff_vf_info_eq2 = { - "Software equalizer", - "eq2", - "Hampa Hug, Daniel Moreno, Richard Felker", - "", - &vf_open, - NULL -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c b/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c deleted file mode 100644 index a8a33e2..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_fspp.c +++ /dev/null @@ -1,2118 +0,0 @@ -/* - * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at> - * Copyright (C) 2005 Nikolaj Poroshin <porosh3@psu.ru> - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * This implementation is based on an algorithm described in - * "Aria Nosratinia Embedded Post-Processing for - * Enhancement of Compressed Images (1999)" - * (http://citeseer.nj.nec.com/nosratinia99embedded.html) - * Futher, with splitting (i)dct into hor/ver passes, one of them can be - * performed once per block, not pixel. This allows for much better speed. - */ - -/* - Heavily optimized version of SPP filter by Nikolaj - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <math.h> - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "av_helpers.h" -#include "libvo/fastmemcpy.h" - -#include "libavutil/internal.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/mem.h" -#include "libavutil/x86/asm.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/dsputil.h" - -#undef free -#undef malloc - -//===========================================================================// -#define BLOCKSZ 12 - -static const short custom_threshold[64]= -// values (296) can't be too high -// -it causes too big quant dependence -// or maybe overflow(check), which results in some flashing -{ 71, 296, 295, 237, 71, 40, 38, 19, - 245, 193, 185, 121, 102, 73, 53, 27, - 158, 129, 141, 107, 97, 73, 50, 26, - 102, 116, 109, 98, 82, 66, 45, 23, - 71, 94, 95, 81, 70, 56, 38, 20, - 56, 77, 74, 66, 56, 44, 30, 15, - 38, 53, 50, 45, 38, 30, 21, 11, - 20, 27, 26, 23, 20, 15, 11, 5 -}; - -static const uint8_t __attribute__((aligned(32))) dither[8][8]={ - { 0, 48, 12, 60, 3, 51, 15, 63, }, - { 32, 16, 44, 28, 35, 19, 47, 31, }, - { 8, 56, 4, 52, 11, 59, 7, 55, }, - { 40, 24, 36, 20, 43, 27, 39, 23, }, - { 2, 50, 14, 62, 1, 49, 13, 61, }, - { 34, 18, 46, 30, 33, 17, 45, 29, }, - { 10, 58, 6, 54, 9, 57, 5, 53, }, - { 42, 26, 38, 22, 41, 25, 37, 21, }, -}; - -struct vf_priv_s { //align 16 ! - uint64_t threshold_mtx_noq[8*2]; - uint64_t threshold_mtx[8*2];//used in both C & MMX (& later SSE2) versions - - int log2_count; - int temp_stride; - int qp; - int mpeg2; - int prev_q; - uint8_t *src; - int16_t *temp; - int bframes; - char *non_b_qp; -}; - - -#if !HAVE_MMX - -//This func reads from 1 slice, 1 and clears 0 & 1 -static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale) -{int y, x; -#define STORE(pos) \ - temp= (src[x + pos] + (d[pos]>>log2_scale))>>(6-log2_scale); \ - src[x + pos]=src[x + pos - 8*src_stride]=0; \ - if(temp & 0x100) temp= ~(temp>>31); \ - dst[x + pos]= temp; - - for(y=0; y<height; y++){ - const uint8_t *d= dither[y]; - for(x=0; x<width; x+=8){ - int temp; - STORE(0); - STORE(1); - STORE(2); - STORE(3); - STORE(4); - STORE(5); - STORE(6); - STORE(7); - } - src+=src_stride; - dst+=dst_stride; - } -} - -//This func reads from 2 slices, 0 & 2 and clears 2-nd -static void store_slice2_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale) -{int y, x; -#define STORE2(pos) \ - temp= (src[x + pos] + src[x + pos + 16*src_stride] + (d[pos]>>log2_scale))>>(6-log2_scale); \ - src[x + pos + 16*src_stride]=0; \ - if(temp & 0x100) temp= ~(temp>>31); \ - dst[x + pos]= temp; - - for(y=0; y<height; y++){ - const uint8_t *d= dither[y]; - for(x=0; x<width; x+=8){ - int temp; - STORE2(0); - STORE2(1); - STORE2(2); - STORE2(3); - STORE2(4); - STORE2(5); - STORE2(6); - STORE2(7); - } - src+=src_stride; - dst+=dst_stride; - } -} - -static void mul_thrmat_c(struct vf_priv_s *p,int q) -{ - int a; - for(a=0;a<64;a++) - ((short*)p->threshold_mtx)[a]=q * ((short*)p->threshold_mtx_noq)[a];//ints faster in C -} - -static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt); -static void row_idct_c(int16_t* workspace, - int16_t* output_adr, int output_stride, int cnt); -static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int cnt); - -//this is rather ugly, but there is no need for function pointers -#define store_slice_s store_slice_c -#define store_slice2_s store_slice2_c -#define mul_thrmat_s mul_thrmat_c -#define column_fidct_s column_fidct_c -#define row_idct_s row_idct_c -#define row_fdct_s row_fdct_c - -#else /* HAVE_MMX */ - -//This func reads from 1 slice, 1 and clears 0 & 1 -static void store_slice_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale) -{ - const uint8_t *od=&dither[0][0]; - const uint8_t *end=&dither[height][0]; - width = (width+7)&~7; - dst_stride-=width; - //src_stride=(src_stride-width)*2; - __asm__ volatile( - "mov %5, %%"REG_d" \n\t" - "mov %6, %%"REG_S" \n\t" - "mov %7, %%"REG_D" \n\t" - "mov %1, %%"REG_a" \n\t" - "movd %%"REG_d", %%mm5 \n\t" - "xor $-1, %%"REG_d" \n\t" - "mov %%"REG_a", %%"REG_c" \n\t" - "add $7, %%"REG_d" \n\t" - "neg %%"REG_a" \n\t" - "sub %0, %%"REG_c" \n\t" - "add %%"REG_c", %%"REG_c" \n\t" - "movd %%"REG_d", %%mm2 \n\t" - "mov %%"REG_c", %1 \n\t" - "mov %2, %%"REG_d" \n\t" - "shl $4, %%"REG_a" \n\t" - - "2: \n\t" - "movq (%%"REG_d"), %%mm3 \n\t" - "movq %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "mov %0, %%"REG_c" \n\t" - "psraw %%mm5, %%mm3 \n\t" - "psraw %%mm5, %%mm4 \n\t" - "1: \n\t" - "movq %%mm7, (%%"REG_S",%%"REG_a",) \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq 8(%%"REG_S"), %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S",%%"REG_a",) \n\t" - "paddw %%mm3, %%mm0 \n\t" - "paddw %%mm4, %%mm1 \n\t" - - "movq %%mm7, (%%"REG_S") \n\t" - "psraw %%mm2, %%mm0 \n\t" - "psraw %%mm2, %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S") \n\t" - "packuswb %%mm1, %%mm0 \n\t" - "add $16, %%"REG_S" \n\t" - - "movq %%mm0, (%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "sub $8, %%"REG_c" \n\t" - "jg 1b \n\t" - "add %1, %%"REG_S" \n\t" - "add $8, %%"REG_d" \n\t" - "add %3, %%"REG_D" \n\t" - "cmp %4, %%"REG_d" \n\t" - "jl 2b \n\t" - - : - : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end), - "m" (log2_scale), "m" (src), "m" (dst) //input - : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D - ); -} - -//This func reads from 2 slices, 0 & 2 and clears 2-nd -static void store_slice2_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale) -{ - const uint8_t *od=&dither[0][0]; - const uint8_t *end=&dither[height][0]; - width = (width+7)&~7; - dst_stride-=width; - //src_stride=(src_stride-width)*2; - __asm__ volatile( - "mov %5, %%"REG_d" \n\t" - "mov %6, %%"REG_S" \n\t" - "mov %7, %%"REG_D" \n\t" - "mov %1, %%"REG_a" \n\t" - "movd %%"REG_d", %%mm5 \n\t" - "xor $-1, %%"REG_d" \n\t" - "mov %%"REG_a", %%"REG_c" \n\t" - "add $7, %%"REG_d" \n\t" - "sub %0, %%"REG_c" \n\t" - "add %%"REG_c", %%"REG_c" \n\t" - "movd %%"REG_d", %%mm2 \n\t" - "mov %%"REG_c", %1 \n\t" - "mov %2, %%"REG_d" \n\t" - "shl $5, %%"REG_a" \n\t" - - "2: \n\t" - "movq (%%"REG_d"), %%mm3 \n\t" - "movq %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - "punpcklbw %%mm7, %%mm3 \n\t" - "punpckhbw %%mm7, %%mm4 \n\t" - "mov %0, %%"REG_c" \n\t" - "psraw %%mm5, %%mm3 \n\t" - "psraw %%mm5, %%mm4 \n\t" - "1: \n\t" - "movq (%%"REG_S"), %%mm0 \n\t" - "movq 8(%%"REG_S"), %%mm1 \n\t" - "paddw %%mm3, %%mm0 \n\t" - - "paddw (%%"REG_S",%%"REG_a",), %%mm0 \n\t" - "paddw %%mm4, %%mm1 \n\t" - "movq 8(%%"REG_S",%%"REG_a",), %%mm6 \n\t" - - "movq %%mm7, (%%"REG_S",%%"REG_a",) \n\t" - "psraw %%mm2, %%mm0 \n\t" - "paddw %%mm6, %%mm1 \n\t" - - "movq %%mm7, 8(%%"REG_S",%%"REG_a",) \n\t" - "psraw %%mm2, %%mm1 \n\t" - "packuswb %%mm1, %%mm0 \n\t" - - "movq %%mm0, (%%"REG_D") \n\t" - "add $16, %%"REG_S" \n\t" - "add $8, %%"REG_D" \n\t" - "sub $8, %%"REG_c" \n\t" - "jg 1b \n\t" - "add %1, %%"REG_S" \n\t" - "add $8, %%"REG_d" \n\t" - "add %3, %%"REG_D" \n\t" - "cmp %4, %%"REG_d" \n\t" - "jl 2b \n\t" - - : - : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end), - "m" (log2_scale), "m" (src), "m" (dst) //input - : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_D, "%"REG_S - ); -} - -static void mul_thrmat_mmx(struct vf_priv_s *p, int q) -{ - uint64_t *adr=&p->threshold_mtx_noq[0]; - __asm__ volatile( - "movd %0, %%mm7 \n\t" - "add $8*8*2, %%"REG_D" \n\t" - "movq 0*8(%%"REG_S"), %%mm0 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "movq 1*8(%%"REG_S"), %%mm1 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq 2*8(%%"REG_S"), %%mm2 \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq 3*8(%%"REG_S"), %%mm3 \n\t" - "pmullw %%mm7, %%mm2 \n\t" - - "movq %%mm0, 0*8(%%"REG_D") \n\t" - "movq 4*8(%%"REG_S"), %%mm4 \n\t" - "pmullw %%mm7, %%mm3 \n\t" - - "movq %%mm1, 1*8(%%"REG_D") \n\t" - "movq 5*8(%%"REG_S"), %%mm5 \n\t" - "pmullw %%mm7, %%mm4 \n\t" - - "movq %%mm2, 2*8(%%"REG_D") \n\t" - "movq 6*8(%%"REG_S"), %%mm6 \n\t" - "pmullw %%mm7, %%mm5 \n\t" - - "movq %%mm3, 3*8(%%"REG_D") \n\t" - "movq 7*8+0*8(%%"REG_S"), %%mm0 \n\t" - "pmullw %%mm7, %%mm6 \n\t" - - "movq %%mm4, 4*8(%%"REG_D") \n\t" - "movq 7*8+1*8(%%"REG_S"), %%mm1 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq %%mm5, 5*8(%%"REG_D") \n\t" - "movq 7*8+2*8(%%"REG_S"), %%mm2 \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq %%mm6, 6*8(%%"REG_D") \n\t" - "movq 7*8+3*8(%%"REG_S"), %%mm3 \n\t" - "pmullw %%mm7, %%mm2 \n\t" - - "movq %%mm0, 7*8+0*8(%%"REG_D") \n\t" - "movq 7*8+4*8(%%"REG_S"), %%mm4 \n\t" - "pmullw %%mm7, %%mm3 \n\t" - - "movq %%mm1, 7*8+1*8(%%"REG_D") \n\t" - "movq 7*8+5*8(%%"REG_S"), %%mm5 \n\t" - "pmullw %%mm7, %%mm4 \n\t" - - "movq %%mm2, 7*8+2*8(%%"REG_D") \n\t" - "movq 7*8+6*8(%%"REG_S"), %%mm6 \n\t" - "pmullw %%mm7, %%mm5 \n\t" - - "movq %%mm3, 7*8+3*8(%%"REG_D") \n\t" - "movq 14*8+0*8(%%"REG_S"), %%mm0 \n\t" - "pmullw %%mm7, %%mm6 \n\t" - - "movq %%mm4, 7*8+4*8(%%"REG_D") \n\t" - "movq 14*8+1*8(%%"REG_S"), %%mm1 \n\t" - "pmullw %%mm7, %%mm0 \n\t" - - "movq %%mm5, 7*8+5*8(%%"REG_D") \n\t" - "pmullw %%mm7, %%mm1 \n\t" - - "movq %%mm6, 7*8+6*8(%%"REG_D") \n\t" - "movq %%mm0, 14*8+0*8(%%"REG_D") \n\t" - "movq %%mm1, 14*8+1*8(%%"REG_D") \n\t" - - : "+g" (q), "+S" (adr), "+D" (adr) - : - ); -} - -static void column_fidct_mmx(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt); -static void row_idct_mmx(int16_t* workspace, - int16_t* output_adr, int output_stride, int cnt); -static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, int cnt); - -#define store_slice_s store_slice_mmx -#define store_slice2_s store_slice2_mmx -#define mul_thrmat_s mul_thrmat_mmx -#define column_fidct_s column_fidct_mmx -#define row_idct_s row_idct_mmx -#define row_fdct_s row_fdct_mmx -#endif // HAVE_MMX - -static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, - int dst_stride, int src_stride, - int width, int height, - uint8_t *qp_store, int qp_stride, int is_luma) -{ - int x, x0, y, es, qy, t; - const int stride= is_luma ? p->temp_stride : (width+16);//((width+16+15)&(~15)) - const int step=6-p->log2_count; - const int qps= 3 + is_luma; - int32_t __attribute__((aligned(32))) block_align[4*8*BLOCKSZ+ 4*8*BLOCKSZ]; - int16_t *block= (int16_t *)block_align; - int16_t *block3=(int16_t *)(block_align+4*8*BLOCKSZ); - - memset(block3, 0, 4*8*BLOCKSZ); - - //p->src=src-src_stride*8-8;//! - if (!src || !dst) return; // HACK avoid crash for Y8 colourspace - for(y=0; y<height; y++){ - int index= 8 + 8*stride + y*stride; - fast_memcpy(p->src + index, src + y*src_stride, width);//this line can be avoided by using DR & user fr.buffers - for(x=0; x<8; x++){ - p->src[index - x - 1]= p->src[index + x ]; - p->src[index + width + x ]= p->src[index + width - x - 1]; - } - } - for(y=0; y<8; y++){ - fast_memcpy(p->src + ( 7-y)*stride, p->src + ( y+8)*stride, stride); - fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride); - } - //FIXME (try edge emu) - - for(y=8; y<24; y++) - memset(p->temp+ 8 +y*stride, 0,width*sizeof(int16_t)); - - for(y=step; y<height+8; y+=step){ //step= 1,2 - qy=y-4; - if (qy>height-1) qy=height-1; - if (qy<0) qy=0; - qy=(qy>>qps)*qp_stride; - row_fdct_s(block, p->src + y*stride +2-(y&1), stride, 2); - for(x0=0; x0<width+8-8*(BLOCKSZ-1); x0+=8*(BLOCKSZ-1)){ - row_fdct_s(block+8*8, p->src + y*stride+8+x0 +2-(y&1), stride, 2*(BLOCKSZ-1)); - if(p->qp) - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+0*8, block3+0*8, 8*(BLOCKSZ-1)); //yes, this is a HOTSPOT - else - for (x=0; x<8*(BLOCKSZ-1); x+=8) { - t=x+x0-2; //correct t=x+x0-2-(y&1), but its the same - if (t<0) t=0;//t always < width-2 - t=qp_store[qy+(t>>qps)]; - t=norm_qscale(t, p->mpeg2); - if (t!=p->prev_q) p->prev_q=t, mul_thrmat_s(p, t); - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+x*8, block3+x*8, 8); //yes, this is a HOTSPOT - } - row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, 2*(BLOCKSZ-1)); - memmove(block, block+(BLOCKSZ-1)*64, 8*8*sizeof(int16_t)); //cycling - memmove(block3, block3+(BLOCKSZ-1)*64, 6*8*sizeof(int16_t)); - } - // - es=width+8-x0; // 8, ... - if (es>8) - row_fdct_s(block+8*8, p->src + y*stride+8+x0 +2-(y&1), stride, (es-4)>>2); - column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block, block3, es&(~1)); - row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, es>>2); - {const int y1=y-8+step;//l5-7 l4-6 - if (!(y1&7) && y1) { - if (y1&8) store_slice_s(dst + (y1-8)*dst_stride, p->temp+ 8 +8*stride, - dst_stride, stride, width, 8, 5-p->log2_count); - else store_slice2_s(dst + (y1-8)*dst_stride, p->temp+ 8 +0*stride, - dst_stride, stride, width, 8, 5-p->log2_count); - } } - } - - if (y&7) { // == height & 7 - if (y&8) store_slice_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +8*stride, - dst_stride, stride, width, y&7, 5-p->log2_count); - else store_slice2_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +0*stride, - dst_stride, stride, width, y&7, 5-p->log2_count); - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - int h= (height+16+15)&(~15); - - vf->priv->temp_stride= (width+16+15)&(~15); - vf->priv->temp= (int16_t*)av_mallocz(vf->priv->temp_stride*3*8*sizeof(int16_t)); - //this can also be avoided, see above - vf->priv->src = (uint8_t*)av_malloc(vf->priv->temp_stride*h*sizeof(uint8_t)); - - return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi) -{ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - ff_vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - vf->priv->mpeg2= mpi->qscale_type; - if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){ - int w = mpi->qstride; - int h = (mpi->h + 15) >> 4; - if (!w) { - w = (mpi->w + 15) >> 4; - h = 1; - } - if(!vf->priv->non_b_qp) - vf->priv->non_b_qp= malloc(w*h); - fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h); - } - if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){ - char *qp_tab= vf->priv->non_b_qp; - if(vf->priv->bframes || !qp_tab) - qp_tab= mpi->qscale; - - if(qp_tab || vf->priv->qp){ - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], - mpi->w, mpi->h, qp_tab, mpi->qstride, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], - mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], - mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - return ff_vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf) -{ - if(!vf->priv) return; - - av_free(vf->priv->temp); - vf->priv->temp= NULL; - av_free(vf->priv->src); - vf->priv->src= NULL; - //free(vf->priv->avctx); - //vf->priv->avctx= NULL; - free(vf->priv->non_b_qp); - vf->priv->non_b_qp= NULL; - - av_free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return ff_vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data) -{ - switch(request){ - case VFCTRL_QUERY_MAX_PP_LEVEL: - return 5; - case VFCTRL_SET_PP_LEVEL: - vf->priv->log2_count= *((unsigned int*)data); - if (vf->priv->log2_count < 4) vf->priv->log2_count=4; - return CONTROL_TRUE; - } - return ff_vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - int i=0, bias; - int custom_threshold_m[64]; - int log2c=-1; - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=av_mallocz(sizeof(struct vf_priv_s));//assumes align 16 ! - - ff_init_avcodec(); - - //vf->priv->avctx= avcodec_alloc_context(); - //dsputil_init(&vf->priv->dsp, vf->priv->avctx); - - vf->priv->log2_count= 4; - vf->priv->bframes = 0; - - if (args) sscanf(args, "%d:%d:%d:%d", &log2c, &vf->priv->qp, &i, &vf->priv->bframes); - - if( log2c >=4 && log2c <=5 ) - vf->priv->log2_count = log2c; - else if( log2c >= 6 ) - vf->priv->log2_count = 5; - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - - if (i < -15) i = -15; - if (i > 32) i = 32; - - bias= (1<<4)+i; //regulable - vf->priv->prev_q=0; - // - for(i=0;i<64;i++) //FIXME: tune custom_threshold[] and remove this ! - custom_threshold_m[i]=(int)(custom_threshold[i]*(bias/71.)+ 0.5); - for(i=0;i<8;i++){ - vf->priv->threshold_mtx_noq[2*i]=(uint64_t)custom_threshold_m[i*8+2] - |(((uint64_t)custom_threshold_m[i*8+6])<<16) - |(((uint64_t)custom_threshold_m[i*8+0])<<32) - |(((uint64_t)custom_threshold_m[i*8+4])<<48); - vf->priv->threshold_mtx_noq[2*i+1]=(uint64_t)custom_threshold_m[i*8+5] - |(((uint64_t)custom_threshold_m[i*8+3])<<16) - |(((uint64_t)custom_threshold_m[i*8+1])<<32) - |(((uint64_t)custom_threshold_m[i*8+7])<<48); - } - - if (vf->priv->qp) vf->priv->prev_q=vf->priv->qp, mul_thrmat_s(vf->priv, vf->priv->qp); - - return 1; -} - -const vf_info_t ff_vf_info_fspp = { - "fast simple postprocess", - "fspp", - "Michael Niedermayer, Nikolaj Poroshin", - "", - vf_open, - NULL -}; - -//==================================================================== -//Specific spp's dct, idct and threshold functions -//I'd prefer to have them in the separate file. - -//#define MANGLE(a) #a - -//typedef int16_t int16_t; //! only int16_t - -#define DCTSIZE 8 -#define DCTSIZE_S "8" - -#define FIX(x,s) ((int) ((x) * (1<<s) + 0.5)&0xffff) -#define C64(x) ((uint64_t)((x)|(x)<<16))<<32 | (uint64_t)(x) | (uint64_t)(x)<<16 -#define FIX64(x,s) C64(FIX(x,s)) - -#define MULTIPLY16H(x,k) (((x)*(k))>>16) -#define THRESHOLD(r,x,t) if(((unsigned)((x)+t))>t*2) r=(x);else r=0; -#define DESCALE(x,n) (((x) + (1 << ((n)-1))) >> n) - -#if HAVE_MMX - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_382683433)=FIX64(0.382683433, 14); -DECLARE_ALIGNED(8, uint64_t, ff_MM_FIX_0_541196100)=FIX64(0.541196100, 14); -DECLARE_ALIGNED(8, uint64_t, ff_MM_FIX_0_707106781)=FIX64(0.707106781, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_306562965)=FIX64(1.306562965, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562_A)=FIX64(1.414213562, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_847759065)=FIX64(1.847759065, 13); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_2_613125930)=FIX64(-2.613125930, 13); //- -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562)=FIX64(1.414213562, 13); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_082392200)=FIX64(1.082392200, 13); -//for t3,t5,t7 == 0 shortcut -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_847759065)=FIX64(0.847759065, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_566454497)=FIX64(0.566454497, 14); -DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_198912367)=FIX64(0.198912367, 14); - -DECLARE_ASM_CONST(8, uint64_t, MM_DESCALE_RND)=C64(4); -DECLARE_ASM_CONST(8, uint64_t, MM_2)=C64(2); - -#else /* !HAVE_MMX */ - -typedef int32_t int_simd16_t; -static const int16_t FIX_0_382683433=FIX(0.382683433, 14); -static const int16_t FIX_0_541196100=FIX(0.541196100, 14); -static const int16_t FIX_0_707106781=FIX(0.707106781, 14); -static const int16_t FIX_1_306562965=FIX(1.306562965, 14); -static const int16_t FIX_1_414213562_A=FIX(1.414213562, 14); -static const int16_t FIX_1_847759065=FIX(1.847759065, 13); -static const int16_t FIX_2_613125930=FIX(-2.613125930, 13); //- -static const int16_t FIX_1_414213562=FIX(1.414213562, 13); -static const int16_t FIX_1_082392200=FIX(1.082392200, 13); - -#endif - -#if !HAVE_MMX - -static void column_fidct_c(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z1,z2,z3,z4,z5, z10, z11, z12, z13; - int_simd16_t d0, d1, d2, d3, d4, d5, d6, d7; - - int16_t* dataptr; - int16_t* wsptr; - int16_t *threshold; - int ctr; - - dataptr = data; - wsptr = output; - - for (; cnt > 0; cnt-=2) { //start positions - threshold=(int16_t*)thr_adr;//threshold_mtx - for (ctr = DCTSIZE; ctr > 0; ctr--) { - // Process columns from input, add to output. - tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; - tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; - - tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; - tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; - - tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; - tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; - - tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; - tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; - - // Even part of FDCT - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - - d0 = tmp10 + tmp11; - d4 = tmp10 - tmp11; - - z1 = MULTIPLY16H((tmp12 + tmp13) <<2, FIX_0_707106781); - d2 = tmp13 + z1; - d6 = tmp13 - z1; - - // Even part of IDCT - - THRESHOLD(tmp0, d0, threshold[0*8]); - THRESHOLD(tmp1, d2, threshold[2*8]); - THRESHOLD(tmp2, d4, threshold[4*8]); - THRESHOLD(tmp3, d6, threshold[6*8]); - tmp0+=2; - tmp10 = (tmp0 + tmp2)>>2; - tmp11 = (tmp0 - tmp2)>>2; - - tmp13 = (tmp1 + tmp3)>>2; //+2 ! (psnr decides) - tmp12 = MULTIPLY16H((tmp1 - tmp3), FIX_1_414213562_A) - tmp13; //<<2 - - tmp0 = tmp10 + tmp13; //->temps - tmp3 = tmp10 - tmp13; //->temps - tmp1 = tmp11 + tmp12; //->temps - tmp2 = tmp11 - tmp12; //->temps - - // Odd part of FDCT - - tmp10 = tmp4 + tmp5; - tmp11 = tmp5 + tmp6; - tmp12 = tmp6 + tmp7; - - z5 = MULTIPLY16H((tmp10 - tmp12)<<2, FIX_0_382683433); - z2 = MULTIPLY16H(tmp10 <<2, FIX_0_541196100) + z5; - z4 = MULTIPLY16H(tmp12 <<2, FIX_1_306562965) + z5; - z3 = MULTIPLY16H(tmp11 <<2, FIX_0_707106781); - - z11 = tmp7 + z3; - z13 = tmp7 - z3; - - d5 = z13 + z2; - d3 = z13 - z2; - d1 = z11 + z4; - d7 = z11 - z4; - - // Odd part of IDCT - - THRESHOLD(tmp4, d1, threshold[1*8]); - THRESHOLD(tmp5, d3, threshold[3*8]); - THRESHOLD(tmp6, d5, threshold[5*8]); - THRESHOLD(tmp7, d7, threshold[7*8]); - - //Simd version uses here a shortcut for the tmp5,tmp6,tmp7 == 0 - z13 = tmp6 + tmp5; - z10 = (tmp6 - tmp5)<<1; - z11 = tmp4 + tmp7; - z12 = (tmp4 - tmp7)<<1; - - tmp7 = (z11 + z13)>>2; //+2 ! - tmp11 = MULTIPLY16H((z11 - z13)<<1, FIX_1_414213562); - z5 = MULTIPLY16H(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - !! - - tmp6 = tmp12 - tmp7; - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 + tmp5; - - wsptr[DCTSIZE*0]+= (tmp0 + tmp7); - wsptr[DCTSIZE*1]+= (tmp1 + tmp6); - wsptr[DCTSIZE*2]+= (tmp2 + tmp5); - wsptr[DCTSIZE*3]+= (tmp3 - tmp4); - wsptr[DCTSIZE*4]+= (tmp3 + tmp4); - wsptr[DCTSIZE*5]+= (tmp2 - tmp5); - wsptr[DCTSIZE*6]= (tmp1 - tmp6); - wsptr[DCTSIZE*7]= (tmp0 - tmp7); - // - dataptr++; //next column - wsptr++; - threshold++; - } - dataptr+=8; //skip each second start pos - wsptr +=8; - } -} - -#else /* HAVE_MMX */ - -static void column_fidct_mmx(int16_t* thr_adr, int16_t *data, int16_t *output, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - ASMALIGN(4) - "1: \n\t" - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t" - // - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t" - "movq %%mm1, %%mm0 \n\t" - - "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0 - "movq %%mm7, %%mm3 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3 - "movq %%mm1, %%mm5 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t" - "psubw %%mm7, %%mm1 \n\t" //t13 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "movq %%mm6, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1 - "paddw %%mm7, %%mm5 \n\t" //t10 - - "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2 - "movq %%mm6, %%mm7 \n\t" - - "paddw %%mm2, %%mm6 \n\t" //t11 - "psubw %%mm2, %%mm7 \n\t" //t12 - - "movq %%mm5, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //d0 - // i0 t13 t12 i3 i1 d0 - d4 - "psubw %%mm6, %%mm2 \n\t" //d4 - "paddw %%mm1, %%mm7 \n\t" - - "movq 4*16(%%"REG_d"), %%mm6 \n\t" - "psllw $2, %%mm7 \n\t" - - "psubw 0*16(%%"REG_d"), %%mm5 \n\t" - "psubw %%mm6, %%mm2 \n\t" - - "paddusw 0*16(%%"REG_d"), %%mm5 \n\t" - "paddusw %%mm6, %%mm2 \n\t" - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm7 \n\t" - // - "paddw 0*16(%%"REG_d"), %%mm5 \n\t" - "paddw %%mm6, %%mm2 \n\t" - - "psubusw 0*16(%%"REG_d"), %%mm5 \n\t" - "psubusw %%mm6, %%mm2 \n\t" - -//This func is totally compute-bound, operates at huge speed. So, DC shortcut -// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3). -//However, typical numbers: nondc - 29%%, dc - 46%%, zero - 25%%. All <> 0 case is very rare. - "paddw "MANGLE(MM_2)", %%mm5 \n\t" - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm5, %%mm2 \n\t" - "psubw %%mm6, %%mm5 \n\t" - - "movq %%mm1, %%mm6 \n\t" - "paddw %%mm7, %%mm1 \n\t" //d2 - - "psubw 2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" //d6 - - "movq 6*16(%%"REG_d"), %%mm7 \n\t" - "psraw $2, %%mm5 \n\t" - - "paddusw 2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" - // t7 d2 /t11 t4 t6 - d6 /t10 - - "paddw 2*16(%%"REG_d"), %%mm1 \n\t" - "paddusw %%mm7, %%mm6 \n\t" - - "psubusw 2*16(%%"REG_d"), %%mm1 \n\t" - "paddw %%mm7, %%mm6 \n\t" - - "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t" - "psubusw %%mm7, %%mm6 \n\t" - - //movq [edi+"DCTSIZE_S"*2*2], mm1 - //movq [edi+"DCTSIZE_S"*6*2], mm6 - "movq %%mm1, %%mm7 \n\t" - "psraw $2, %%mm2 \n\t" - - "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t" - "psubw %%mm6, %%mm1 \n\t" - - "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t" - "paddw %%mm7, %%mm6 \n\t" //'t13 - - "psraw $2, %%mm6 \n\t" //paddw mm6, MM_2 !! --- - "movq %%mm2, %%mm7 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t" - "paddw %%mm6, %%mm2 \n\t" //'t0 - - "movq %%mm2, 0*8+%3 \n\t" //! - "psubw %%mm6, %%mm7 \n\t" //'t3 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm6, %%mm1 \n\t" //'t12 - - "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5 - "movq %%mm5, %%mm6 \n\t" - - "movq %%mm7, 3*8+%3 \n\t" - "paddw %%mm2, %%mm3 \n\t" //t10 - - "paddw %%mm4, %%mm2 \n\t" //t11 - "paddw %%mm0, %%mm4 \n\t" //t12 - - "movq %%mm3, %%mm7 \n\t" - "psubw %%mm4, %%mm3 \n\t" - - "psllw $2, %%mm3 \n\t" - "psllw $2, %%mm7 \n\t" //opt for P6 - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" - "psllw $2, %%mm4 \n\t" - - "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm7 \n\t" - "psllw $2, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" //'t1 - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm2 \n\t" - "psubw %%mm1, %%mm6 \n\t" //'t2 - // t7 't12 't11 t4 t6 - 't13 't10 --- - - "paddw %%mm3, %%mm7 \n\t" //z2 - - "movq %%mm5, 1*8+%3 \n\t" - "paddw %%mm3, %%mm4 \n\t" //z4 - - "movq 3*16(%%"REG_d"), %%mm3 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "movq %%mm6, 2*8+%3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //z13 - -//=== - "paddw %%mm2, %%mm0 \n\t" //z11 - "movq %%mm1, %%mm5 \n\t" - - "movq 5*16(%%"REG_d"), %%mm2 \n\t" - "psubw %%mm7, %%mm1 \n\t" //d3 - - "paddw %%mm7, %%mm5 \n\t" //d5 - "psubw %%mm3, %%mm1 \n\t" - - "movq 1*16(%%"REG_d"), %%mm7 \n\t" - "psubw %%mm2, %%mm5 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "paddw %%mm4, %%mm0 \n\t" //d1 - - "paddusw %%mm3, %%mm1 \n\t" - "psubw %%mm4, %%mm6 \n\t" //d7 - - // d1 d3 - - - d5 d7 - - "movq 7*16(%%"REG_d"), %%mm4 \n\t" - "psubw %%mm7, %%mm0 \n\t" - - "psubw %%mm4, %%mm6 \n\t" - "paddusw %%mm2, %%mm5 \n\t" - - "paddusw %%mm4, %%mm6 \n\t" - "paddw %%mm3, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "paddw %%mm4, %%mm6 \n\t" - - "psubusw %%mm3, %%mm1 \n\t" - "psubusw %%mm2, %%mm5 \n\t" - - "psubusw %%mm4, %%mm6 \n\t" - "movq %%mm1, %%mm4 \n\t" - - "por %%mm5, %%mm4 \n\t" - "paddusw %%mm7, %%mm0 \n\t" - - "por %%mm6, %%mm4 \n\t" - "paddw %%mm7, %%mm0 \n\t" - - "packssdw %%mm4, %%mm4 \n\t" - "psubusw %%mm7, %%mm0 \n\t" - - "movd %%mm4, %%"REG_a" \n\t" - "or %%"REG_a", %%"REG_a" \n\t" - "jnz 2f \n\t" - //movq [edi+"DCTSIZE_S"*3*2], mm1 - //movq [edi+"DCTSIZE_S"*5*2], mm5 - //movq [edi+"DCTSIZE_S"*1*2], mm0 - //movq [edi+"DCTSIZE_S"*7*2], mm6 - // t4 t5 - - - t6 t7 - - //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0 -//Typical numbers: nondc - 19%%, dc - 26%%, zero - 55%%. zero case alone isn't worthwhile - "movq 0*8+%3, %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6 - "movq %%mm1, %%mm2 \n\t" - - "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t" - "movq %%mm2, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5 - "paddw %%mm4, %%mm5 \n\t" - - "movq 1*8+%3, %%mm6 \n\t" - //paddw mm3, MM_2 - "psraw $2, %%mm3 \n\t" //tmp7 - - "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4 - "psubw %%mm3, %%mm4 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm6, %%mm7 \n\t" - - "movq 2*8+%3, %%mm3 \n\t" - "psubw %%mm0, %%mm6 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "paddw %%mm3, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq 3*8+%3, %%mm0 \n\t" - "add $8, %%"REG_S" \n\t" - - "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "psubw %%mm2, %%mm0 \n\t" - - "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - - "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - "jmp 4f \n\t" - - "2: \n\t" - //--- non DC2 - //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1 (actually thr1, thr1, thr1-1) - //psraw mm5, 2 - //psraw mm0, 2 - //psraw mm6, 2 - "movq %%mm5, %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psllw $1, %%mm5 \n\t" //'z10 - "paddw %%mm1, %%mm3 \n\t" //'z13 - - "movq %%mm0, %%mm2 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "movq %%mm5, %%mm1 \n\t" - "psllw $1, %%mm0 \n\t" //'z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //- - "paddw %%mm0, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5 - "paddw %%mm6, %%mm2 \n\t" //'z11 - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t" - "movq %%mm2, %%mm7 \n\t" - - //--- - "movq 0*8+%3, %%mm4 \n\t" - "psubw %%mm3, %%mm2 \n\t" - - "psllw $1, %%mm2 \n\t" - "paddw %%mm3, %%mm7 \n\t" //'t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11 - "movq %%mm4, %%mm6 \n\t" - //paddw mm7, MM_2 - "psraw $2, %%mm7 \n\t" - - "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t" - "psubw %%mm7, %%mm6 \n\t" - - "movq 1*8+%3, %%mm3 \n\t" - "paddw %%mm7, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm5, %%mm1 \n\t" //'t12 - - "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "psubw %%mm7, %%mm1 \n\t" //'t6 - - "movq 2*8+%3, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //'t10 - - "movq 3*8+%3, %%mm6 \n\t" - "movq %%mm3, %%mm5 \n\t" - - "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psubw %%mm1, %%mm2 \n\t" //'t5 - "paddw %%mm1, %%mm3 \n\t" - - "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "movq %%mm7, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t" - "psubw %%mm2, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm2, %%mm7 \n\t" - - "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm2, %%mm0 \n\t" //'t4 - - // 't4 't6 't5 - - - - 't7 - "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "movq %%mm6, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t" - "psubw %%mm0, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "add $8, %%"REG_S" \n\t" - - "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - - "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "add $8, %%"REG_D" \n\t" - - "4: \n\t" -//=part 2 (the same)=========================================================== - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t" - // - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t" - "movq %%mm1, %%mm0 \n\t" - - "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0 - "movq %%mm7, %%mm3 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3 - "movq %%mm1, %%mm5 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t" - "psubw %%mm7, %%mm1 \n\t" //t13 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "movq %%mm6, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1 - "paddw %%mm7, %%mm5 \n\t" //t10 - - "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2 - "movq %%mm6, %%mm7 \n\t" - - "paddw %%mm2, %%mm6 \n\t" //t11 - "psubw %%mm2, %%mm7 \n\t" //t12 - - "movq %%mm5, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //d0 - // i0 t13 t12 i3 i1 d0 - d4 - "psubw %%mm6, %%mm2 \n\t" //d4 - "paddw %%mm1, %%mm7 \n\t" - - "movq 1*8+4*16(%%"REG_d"), %%mm6 \n\t" - "psllw $2, %%mm7 \n\t" - - "psubw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "psubw %%mm6, %%mm2 \n\t" - - "paddusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "paddusw %%mm6, %%mm2 \n\t" - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm7 \n\t" - // - "paddw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "paddw %%mm6, %%mm2 \n\t" - - "psubusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t" - "psubusw %%mm6, %%mm2 \n\t" - -//This func is totally compute-bound, operates at huge speed. So, DC shortcut -// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3). -//However, typical numbers: nondc - 29%%, dc - 46%%, zero - 25%%. All <> 0 case is very rare. - "paddw "MANGLE(MM_2)", %%mm5 \n\t" - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm5, %%mm2 \n\t" - "psubw %%mm6, %%mm5 \n\t" - - "movq %%mm1, %%mm6 \n\t" - "paddw %%mm7, %%mm1 \n\t" //d2 - - "psubw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" //d6 - - "movq 1*8+6*16(%%"REG_d"), %%mm7 \n\t" - "psraw $2, %%mm5 \n\t" - - "paddusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "psubw %%mm7, %%mm6 \n\t" - // t7 d2 /t11 t4 t6 - d6 /t10 - - "paddw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "paddusw %%mm7, %%mm6 \n\t" - - "psubusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t" - "paddw %%mm7, %%mm6 \n\t" - - "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t" - "psubusw %%mm7, %%mm6 \n\t" - - //movq [edi+"DCTSIZE_S"*2*2], mm1 - //movq [edi+"DCTSIZE_S"*6*2], mm6 - "movq %%mm1, %%mm7 \n\t" - "psraw $2, %%mm2 \n\t" - - "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t" - "psubw %%mm6, %%mm1 \n\t" - - "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t" - "paddw %%mm7, %%mm6 \n\t" //'t13 - - "psraw $2, %%mm6 \n\t" //paddw mm6, MM_2 !! --- - "movq %%mm2, %%mm7 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t" - "paddw %%mm6, %%mm2 \n\t" //'t0 - - "movq %%mm2, 0*8+%3 \n\t" //! - "psubw %%mm6, %%mm7 \n\t" //'t3 - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm6, %%mm1 \n\t" //'t12 - - "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5 - "movq %%mm5, %%mm6 \n\t" - - "movq %%mm7, 3*8+%3 \n\t" - "paddw %%mm2, %%mm3 \n\t" //t10 - - "paddw %%mm4, %%mm2 \n\t" //t11 - "paddw %%mm0, %%mm4 \n\t" //t12 - - "movq %%mm3, %%mm7 \n\t" - "psubw %%mm4, %%mm3 \n\t" - - "psllw $2, %%mm3 \n\t" - "psllw $2, %%mm7 \n\t" //opt for P6 - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" - "psllw $2, %%mm4 \n\t" - - "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm7 \n\t" - "psllw $2, %%mm2 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t" - "paddw %%mm1, %%mm5 \n\t" //'t1 - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm2 \n\t" - "psubw %%mm1, %%mm6 \n\t" //'t2 - // t7 't12 't11 t4 t6 - 't13 't10 --- - - "paddw %%mm3, %%mm7 \n\t" //z2 - - "movq %%mm5, 1*8+%3 \n\t" - "paddw %%mm3, %%mm4 \n\t" //z4 - - "movq 1*8+3*16(%%"REG_d"), %%mm3 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "movq %%mm6, 2*8+%3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //z13 - -//=== - "paddw %%mm2, %%mm0 \n\t" //z11 - "movq %%mm1, %%mm5 \n\t" - - "movq 1*8+5*16(%%"REG_d"), %%mm2 \n\t" - "psubw %%mm7, %%mm1 \n\t" //d3 - - "paddw %%mm7, %%mm5 \n\t" //d5 - "psubw %%mm3, %%mm1 \n\t" - - "movq 1*8+1*16(%%"REG_d"), %%mm7 \n\t" - "psubw %%mm2, %%mm5 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "paddw %%mm4, %%mm0 \n\t" //d1 - - "paddusw %%mm3, %%mm1 \n\t" - "psubw %%mm4, %%mm6 \n\t" //d7 - - // d1 d3 - - - d5 d7 - - "movq 1*8+7*16(%%"REG_d"), %%mm4 \n\t" - "psubw %%mm7, %%mm0 \n\t" - - "psubw %%mm4, %%mm6 \n\t" - "paddusw %%mm2, %%mm5 \n\t" - - "paddusw %%mm4, %%mm6 \n\t" - "paddw %%mm3, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "paddw %%mm4, %%mm6 \n\t" - - "psubusw %%mm3, %%mm1 \n\t" - "psubusw %%mm2, %%mm5 \n\t" - - "psubusw %%mm4, %%mm6 \n\t" - "movq %%mm1, %%mm4 \n\t" - - "por %%mm5, %%mm4 \n\t" - "paddusw %%mm7, %%mm0 \n\t" - - "por %%mm6, %%mm4 \n\t" - "paddw %%mm7, %%mm0 \n\t" - - "packssdw %%mm4, %%mm4 \n\t" - "psubusw %%mm7, %%mm0 \n\t" - - "movd %%mm4, %%"REG_a" \n\t" - "or %%"REG_a", %%"REG_a" \n\t" - "jnz 3f \n\t" - //movq [edi+"DCTSIZE_S"*3*2], mm1 - //movq [edi+"DCTSIZE_S"*5*2], mm5 - //movq [edi+"DCTSIZE_S"*1*2], mm0 - //movq [edi+"DCTSIZE_S"*7*2], mm6 - // t4 t5 - - - t6 t7 - - //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0 -//Typical numbers: nondc - 19%%, dc - 26%%, zero - 55%%. zero case alone isn't worthwhile - "movq 0*8+%3, %%mm4 \n\t" - "movq %%mm0, %%mm1 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6 - "movq %%mm1, %%mm2 \n\t" - - "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t" - "movq %%mm2, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5 - "paddw %%mm4, %%mm5 \n\t" - - "movq 1*8+%3, %%mm6 \n\t" - //paddw mm3, MM_2 - "psraw $2, %%mm3 \n\t" //tmp7 - - "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4 - "psubw %%mm3, %%mm4 \n\t" - - "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm6, %%mm7 \n\t" - - "movq 2*8+%3, %%mm3 \n\t" - "psubw %%mm0, %%mm6 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "paddw %%mm3, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t" - "paddw %%mm3, %%mm5 \n\t" - - "movq 3*8+%3, %%mm0 \n\t" - "add $24, %%"REG_S" \n\t" - - "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "psubw %%mm2, %%mm0 \n\t" - - "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "paddw %%mm0, %%mm7 \n\t" - - "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - - "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - "add $24, %%"REG_D" \n\t" - "sub $2, %%"REG_c" \n\t" - "jnz 1b \n\t" - "jmp 5f \n\t" - - "3: \n\t" - //--- non DC2 - //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1 (actually thr1, thr1, thr1-1) - //psraw mm5, 2 - //psraw mm0, 2 - //psraw mm6, 2 - "movq %%mm5, %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psllw $1, %%mm5 \n\t" //'z10 - "paddw %%mm1, %%mm3 \n\t" //'z13 - - "movq %%mm0, %%mm2 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "movq %%mm5, %%mm1 \n\t" - "psllw $1, %%mm0 \n\t" //'z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //- - "paddw %%mm0, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5 - "paddw %%mm6, %%mm2 \n\t" //'z11 - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t" - "movq %%mm2, %%mm7 \n\t" - - //--- - "movq 0*8+%3, %%mm4 \n\t" - "psubw %%mm3, %%mm2 \n\t" - - "psllw $1, %%mm2 \n\t" - "paddw %%mm3, %%mm7 \n\t" //'t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11 - "movq %%mm4, %%mm6 \n\t" - //paddw mm7, MM_2 - "psraw $2, %%mm7 \n\t" - - "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t" - "psubw %%mm7, %%mm6 \n\t" - - "movq 1*8+%3, %%mm3 \n\t" - "paddw %%mm7, %%mm4 \n\t" - - "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t" - "paddw %%mm5, %%mm1 \n\t" //'t12 - - "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "psubw %%mm7, %%mm1 \n\t" //'t6 - - "movq 2*8+%3, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //'t10 - - "movq 3*8+%3, %%mm6 \n\t" - "movq %%mm3, %%mm5 \n\t" - - "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t" - "psubw %%mm1, %%mm5 \n\t" - - "psubw %%mm1, %%mm2 \n\t" //'t5 - "paddw %%mm1, %%mm3 \n\t" - - "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t" - "movq %%mm7, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t" - "psubw %%mm2, %%mm4 \n\t" - - "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t" - "paddw %%mm2, %%mm7 \n\t" - - "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "paddw %%mm2, %%mm0 \n\t" //'t4 - - // 't4 't6 't5 - - - - 't7 - "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "movq %%mm6, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t" - "psubw %%mm0, %%mm1 \n\t" - - "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t" - "paddw %%mm0, %%mm6 \n\t" - - "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t" - "add $24, %%"REG_S" \n\t" - - "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t" - - "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "add $24, %%"REG_D" \n\t" - "sub $2, %%"REG_c" \n\t" - "jnz 1b \n\t" - "5: \n\t" - - : "+S"(data), "+D"(output), "+c"(cnt), "=o"(temps) - : "d"(thr_adr) - : "%"REG_a - ); -} - -#endif // HAVE_MMX - -#if !HAVE_MMX - -static void row_idct_c(int16_t* workspace, - int16_t* output_adr, int output_stride, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z5, z10, z11, z12, z13; - int16_t* outptr; - int16_t* wsptr; - - cnt*=4; - wsptr = workspace; - outptr = output_adr; - for (; cnt > 0; cnt--) { - // Even part - //Simd version reads 4x4 block and transposes it - tmp10 = ( wsptr[2] + wsptr[3]); - tmp11 = ( wsptr[2] - wsptr[3]); - - tmp13 = ( wsptr[0] + wsptr[1]); - tmp12 = (MULTIPLY16H( wsptr[0] - wsptr[1], FIX_1_414213562_A)<<2) - tmp13;//this shift order to avoid overflow - - tmp0 = tmp10 + tmp13; //->temps - tmp3 = tmp10 - tmp13; //->temps - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - // Odd part - //Also transpose, with previous: - // ---- ---- |||| - // ---- ---- idct |||| - // ---- ---- ---> |||| - // ---- ---- |||| - z13 = wsptr[4] + wsptr[5]; - z10 = wsptr[4] - wsptr[5]; - z11 = wsptr[6] + wsptr[7]; - z12 = wsptr[6] - wsptr[7]; - - tmp7 = z11 + z13; - tmp11 = MULTIPLY16H(z11 - z13, FIX_1_414213562); - - z5 = MULTIPLY16H(z10 + z12, FIX_1_847759065); - tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5; - tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - FIX_ - - tmp6 = (tmp12<<3) - tmp7; - tmp5 = (tmp11<<3) - tmp6; - tmp4 = (tmp10<<3) + tmp5; - - // Final output stage: descale and write column - outptr[0*output_stride]+= DESCALE(tmp0 + tmp7, 3); - outptr[1*output_stride]+= DESCALE(tmp1 + tmp6, 3); - outptr[2*output_stride]+= DESCALE(tmp2 + tmp5, 3); - outptr[3*output_stride]+= DESCALE(tmp3 - tmp4, 3); - outptr[4*output_stride]+= DESCALE(tmp3 + tmp4, 3); - outptr[5*output_stride]+= DESCALE(tmp2 - tmp5, 3); - outptr[6*output_stride]+= DESCALE(tmp1 - tmp6, 3); //no += ? - outptr[7*output_stride]+= DESCALE(tmp0 - tmp7, 3); //no += ? - outptr++; - - wsptr += DCTSIZE; // advance pointer to next row - } -} - -#else /* HAVE_MMX */ - -static void row_idct_mmx (int16_t* workspace, - int16_t* output_adr, int output_stride, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - "lea (%%"REG_a",%%"REG_a",2), %%"REG_d" \n\t" - "1: \n\t" - "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm0 \n\t" - // - - "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm1 \n\t" - "movq %%mm0, %%mm4 \n\t" - - "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t" - "punpcklwd %%mm1, %%mm0 \n\t" - - "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm3 \n\t" - "punpckhwd %%mm1, %%mm4 \n\t" - - //transpose 4x4 - "movq %%mm2, %%mm7 \n\t" - "punpcklwd %%mm3, %%mm2 \n\t" - - "movq %%mm0, %%mm6 \n\t" - "punpckldq %%mm2, %%mm0 \n\t" //0 - - "punpckhdq %%mm2, %%mm6 \n\t" //1 - "movq %%mm0, %%mm5 \n\t" - - "punpckhwd %%mm3, %%mm7 \n\t" - "psubw %%mm6, %%mm0 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm0 \n\t" - "movq %%mm4, %%mm2 \n\t" - - "punpckldq %%mm7, %%mm4 \n\t" //2 - "paddw %%mm6, %%mm5 \n\t" - - "punpckhdq %%mm7, %%mm2 \n\t" //3 - "movq %%mm4, %%mm1 \n\t" - - "psllw $2, %%mm0 \n\t" - "paddw %%mm2, %%mm4 \n\t" //t10 - - "movq "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_S"), %%mm3 \n\t" - "psubw %%mm2, %%mm1 \n\t" //t11 - - "movq "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_S"), %%mm2 \n\t" - "psubw %%mm5, %%mm0 \n\t" - - "movq %%mm4, %%mm6 \n\t" - "paddw %%mm5, %%mm4 \n\t" //t0 - - "psubw %%mm5, %%mm6 \n\t" //t3 - "movq %%mm1, %%mm7 \n\t" - - "movq "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_S"), %%mm5 \n\t" - "paddw %%mm0, %%mm1 \n\t" //t1 - - "movq %%mm4, 0*8+%3 \n\t" //t0 - "movq %%mm3, %%mm4 \n\t" - - "movq %%mm6, 1*8+%3 \n\t" //t3 - "punpcklwd %%mm2, %%mm3 \n\t" - - //transpose 4x4 - "movq "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_S"), %%mm6 \n\t" - "punpckhwd %%mm2, %%mm4 \n\t" - - "movq %%mm5, %%mm2 \n\t" - "punpcklwd %%mm6, %%mm5 \n\t" - - "psubw %%mm0, %%mm7 \n\t" //t2 - "punpckhwd %%mm6, %%mm2 \n\t" - - "movq %%mm3, %%mm0 \n\t" - "punpckldq %%mm5, %%mm3 \n\t" //4 - - "punpckhdq %%mm5, %%mm0 \n\t" //5 - "movq %%mm4, %%mm5 \n\t" - - // - "movq %%mm3, %%mm6 \n\t" - "punpckldq %%mm2, %%mm4 \n\t" //6 - - "psubw %%mm0, %%mm3 \n\t" //z10 - "punpckhdq %%mm2, %%mm5 \n\t" //7 - - "paddw %%mm0, %%mm6 \n\t" //z13 - "movq %%mm4, %%mm2 \n\t" - - "movq %%mm3, %%mm0 \n\t" - "psubw %%mm5, %%mm4 \n\t" //z12 - - "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm0 \n\t" //- - "paddw %%mm4, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm3 \n\t" //z5 - "paddw %%mm5, %%mm2 \n\t" //z11 > - - "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm4 \n\t" - "movq %%mm2, %%mm5 \n\t" - - "psubw %%mm6, %%mm2 \n\t" - "paddw %%mm6, %%mm5 \n\t" //t7 - - "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //t11 - "paddw %%mm3, %%mm0 \n\t" //t12 - - "psllw $3, %%mm0 \n\t" - "psubw %%mm3, %%mm4 \n\t" //t10 - - "movq 0*8+%3, %%mm6 \n\t" - "movq %%mm1, %%mm3 \n\t" - - "psllw $3, %%mm4 \n\t" - "psubw %%mm5, %%mm0 \n\t" //t6 - - "psllw $3, %%mm2 \n\t" - "paddw %%mm0, %%mm1 \n\t" //d1 - - "psubw %%mm0, %%mm2 \n\t" //t5 - "psubw %%mm0, %%mm3 \n\t" //d6 - - "paddw %%mm2, %%mm4 \n\t" //t4 - "movq %%mm7, %%mm0 \n\t" - - "paddw %%mm2, %%mm7 \n\t" //d2 - "psubw %%mm2, %%mm0 \n\t" //d5 - - "movq "MANGLE(MM_DESCALE_RND)", %%mm2 \n\t" //4 - "psubw %%mm5, %%mm6 \n\t" //d7 - - "paddw 0*8+%3, %%mm5 \n\t" //d0 - "paddw %%mm2, %%mm1 \n\t" - - "paddw %%mm2, %%mm5 \n\t" - "psraw $3, %%mm1 \n\t" - - "paddw %%mm2, %%mm7 \n\t" - "psraw $3, %%mm5 \n\t" - - "paddw (%%"REG_D"), %%mm5 \n\t" - "psraw $3, %%mm7 \n\t" - - "paddw (%%"REG_D",%%"REG_a",), %%mm1 \n\t" - "paddw %%mm2, %%mm0 \n\t" - - "paddw (%%"REG_D",%%"REG_a",2), %%mm7 \n\t" - "paddw %%mm2, %%mm3 \n\t" - - "movq %%mm5, (%%"REG_D") \n\t" - "paddw %%mm2, %%mm6 \n\t" - - "movq %%mm1, (%%"REG_D",%%"REG_a",) \n\t" - "psraw $3, %%mm0 \n\t" - - "movq %%mm7, (%%"REG_D",%%"REG_a",2) \n\t" - "add %%"REG_d", %%"REG_D" \n\t" //3*ls - - "movq 1*8+%3, %%mm5 \n\t" //t3 - "psraw $3, %%mm3 \n\t" - - "paddw (%%"REG_D",%%"REG_a",2), %%mm0 \n\t" - "psubw %%mm4, %%mm5 \n\t" //d3 - - "paddw (%%"REG_D",%%"REG_d",), %%mm3 \n\t" - "psraw $3, %%mm6 \n\t" - - "paddw 1*8+%3, %%mm4 \n\t" //d4 - "paddw %%mm2, %%mm5 \n\t" - - "paddw (%%"REG_D",%%"REG_a",4), %%mm6 \n\t" - "paddw %%mm2, %%mm4 \n\t" - - "movq %%mm0, (%%"REG_D",%%"REG_a",2) \n\t" - "psraw $3, %%mm5 \n\t" - - "paddw (%%"REG_D"), %%mm5 \n\t" - "psraw $3, %%mm4 \n\t" - - "paddw (%%"REG_D",%%"REG_a",), %%mm4 \n\t" - "add $"DCTSIZE_S"*2*4, %%"REG_S" \n\t" //4 rows - - "movq %%mm3, (%%"REG_D",%%"REG_d",) \n\t" - "movq %%mm6, (%%"REG_D",%%"REG_a",4) \n\t" - "movq %%mm5, (%%"REG_D") \n\t" - "movq %%mm4, (%%"REG_D",%%"REG_a",) \n\t" - - "sub %%"REG_d", %%"REG_D" \n\t" - "add $8, %%"REG_D" \n\t" - "dec %%"REG_c" \n\t" - "jnz 1b \n\t" - - : "+S"(workspace), "+D"(output_adr), "+c"(cnt), "=o"(temps) - : "a"(output_stride*sizeof(short)) - : "%"REG_d - ); -} - -#endif // HAVE_MMX - -#if !HAVE_MMX - -static void row_fdct_c(int16_t *data, const uint8_t *pixels, int line_size, int cnt) -{ - int_simd16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - int_simd16_t tmp10, tmp11, tmp12, tmp13; - int_simd16_t z1, z2, z3, z4, z5, z11, z13; - int16_t *dataptr; - - cnt*=4; - // Pass 1: process rows. - - dataptr = data; - for (; cnt > 0; cnt--) { - tmp0 = pixels[line_size*0] + pixels[line_size*7]; - tmp7 = pixels[line_size*0] - pixels[line_size*7]; - tmp1 = pixels[line_size*1] + pixels[line_size*6]; - tmp6 = pixels[line_size*1] - pixels[line_size*6]; - tmp2 = pixels[line_size*2] + pixels[line_size*5]; - tmp5 = pixels[line_size*2] - pixels[line_size*5]; - tmp3 = pixels[line_size*3] + pixels[line_size*4]; - tmp4 = pixels[line_size*3] - pixels[line_size*4]; - - // Even part - - tmp10 = tmp0 + tmp3; - tmp13 = tmp0 - tmp3; - tmp11 = tmp1 + tmp2; - tmp12 = tmp1 - tmp2; - //Even columns are written first, this leads to different order of columns - //in column_fidct(), but they are processed independently, so all ok. - //Later in the row_idct() columns readed at the same order. - dataptr[2] = tmp10 + tmp11; - dataptr[3] = tmp10 - tmp11; - - z1 = MULTIPLY16H((tmp12 + tmp13)<<2, FIX_0_707106781); - dataptr[0] = tmp13 + z1; - dataptr[1] = tmp13 - z1; - - // Odd part - - tmp10 = (tmp4 + tmp5) <<2; - tmp11 = (tmp5 + tmp6) <<2; - tmp12 = (tmp6 + tmp7) <<2; - - z5 = MULTIPLY16H(tmp10 - tmp12, FIX_0_382683433); - z2 = MULTIPLY16H(tmp10, FIX_0_541196100) + z5; - z4 = MULTIPLY16H(tmp12, FIX_1_306562965) + z5; - z3 = MULTIPLY16H(tmp11, FIX_0_707106781); - - z11 = tmp7 + z3; - z13 = tmp7 - z3; - - dataptr[4] = z13 + z2; - dataptr[5] = z13 - z2; - dataptr[6] = z11 + z4; - dataptr[7] = z11 - z4; - - pixels++; // advance pointer to next column - dataptr += DCTSIZE; - } -} - -#else /* HAVE_MMX */ - -static void row_fdct_mmx(int16_t *data, const uint8_t *pixels, int line_size, int cnt) -{ - uint64_t __attribute__((aligned(8))) temps[4]; - __asm__ volatile( - "lea (%%"REG_a",%%"REG_a",2), %%"REG_d" \n\t" - "6: \n\t" - "movd (%%"REG_S"), %%mm0 \n\t" - "pxor %%mm7, %%mm7 \n\t" - - "movd (%%"REG_S",%%"REG_a",), %%mm1 \n\t" - "punpcklbw %%mm7, %%mm0 \n\t" - - "movd (%%"REG_S",%%"REG_a",2), %%mm2 \n\t" - "punpcklbw %%mm7, %%mm1 \n\t" - - "punpcklbw %%mm7, %%mm2 \n\t" - "add %%"REG_d", %%"REG_S" \n\t" - - "movq %%mm0, %%mm5 \n\t" - // - - "movd (%%"REG_S",%%"REG_a",4), %%mm3 \n\t" //7 ;prefetch! - "movq %%mm1, %%mm6 \n\t" - - "movd (%%"REG_S",%%"REG_d",), %%mm4 \n\t" //6 - "punpcklbw %%mm7, %%mm3 \n\t" - - "psubw %%mm3, %%mm5 \n\t" - "punpcklbw %%mm7, %%mm4 \n\t" - - "paddw %%mm3, %%mm0 \n\t" - "psubw %%mm4, %%mm6 \n\t" - - "movd (%%"REG_S",%%"REG_a",2), %%mm3 \n\t" //5 - "paddw %%mm4, %%mm1 \n\t" - - "movq %%mm5, 0*8+%3 \n\t" //t7 - "punpcklbw %%mm7, %%mm3 \n\t" - - "movq %%mm6, 1*8+%3 \n\t" //t6 - "movq %%mm2, %%mm4 \n\t" - - "movd (%%"REG_S"), %%mm5 \n\t" //3 - "paddw %%mm3, %%mm2 \n\t" - - "movd (%%"REG_S",%%"REG_a",), %%mm6 \n\t" //4 - "punpcklbw %%mm7, %%mm5 \n\t" - - "psubw %%mm3, %%mm4 \n\t" - "punpcklbw %%mm7, %%mm6 \n\t" - - "movq %%mm5, %%mm3 \n\t" - "paddw %%mm6, %%mm5 \n\t" //t3 - - "psubw %%mm6, %%mm3 \n\t" //t4 ; t0 t1 t2 t4 t5 t3 - - - "movq %%mm0, %%mm6 \n\t" - - "movq %%mm1, %%mm7 \n\t" - "psubw %%mm5, %%mm0 \n\t" //t13 - - "psubw %%mm2, %%mm1 \n\t" - "paddw %%mm2, %%mm7 \n\t" //t11 - - "paddw %%mm0, %%mm1 \n\t" - "movq %%mm7, %%mm2 \n\t" - - "psllw $2, %%mm1 \n\t" - "paddw %%mm5, %%mm6 \n\t" //t10 - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm1 \n\t" - "paddw %%mm6, %%mm7 \n\t" //d2 - - "psubw %%mm2, %%mm6 \n\t" //d3 - "movq %%mm0, %%mm5 \n\t" - - //transpose 4x4 - "movq %%mm7, %%mm2 \n\t" - "punpcklwd %%mm6, %%mm7 \n\t" - - "paddw %%mm1, %%mm0 \n\t" //d0 - "punpckhwd %%mm6, %%mm2 \n\t" - - "psubw %%mm1, %%mm5 \n\t" //d1 - "movq %%mm0, %%mm6 \n\t" - - "movq 1*8+%3, %%mm1 \n\t" - "punpcklwd %%mm5, %%mm0 \n\t" - - "punpckhwd %%mm5, %%mm6 \n\t" - "movq %%mm0, %%mm5 \n\t" - - "punpckldq %%mm7, %%mm0 \n\t" //0 - "paddw %%mm4, %%mm3 \n\t" - - "punpckhdq %%mm7, %%mm5 \n\t" //1 - "movq %%mm6, %%mm7 \n\t" - - "movq %%mm0, "DCTSIZE_S"*0*2(%%"REG_D") \n\t" - "punpckldq %%mm2, %%mm6 \n\t" //2 - - "movq %%mm5, "DCTSIZE_S"*1*2(%%"REG_D") \n\t" - "punpckhdq %%mm2, %%mm7 \n\t" //3 - - "movq %%mm6, "DCTSIZE_S"*2*2(%%"REG_D") \n\t" - "paddw %%mm1, %%mm4 \n\t" - - "movq %%mm7, "DCTSIZE_S"*3*2(%%"REG_D") \n\t" - "psllw $2, %%mm3 \n\t" //t10 - - "movq 0*8+%3, %%mm2 \n\t" - "psllw $2, %%mm4 \n\t" //t11 - - "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm4 \n\t" //z3 - "paddw %%mm2, %%mm1 \n\t" - - "psllw $2, %%mm1 \n\t" //t12 - "movq %%mm3, %%mm0 \n\t" - - "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm0 \n\t" - "psubw %%mm1, %%mm3 \n\t" - - "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" //z5 - "movq %%mm2, %%mm5 \n\t" - - "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm1 \n\t" - "psubw %%mm4, %%mm2 \n\t" //z13 - - "paddw %%mm4, %%mm5 \n\t" //z11 - "movq %%mm2, %%mm6 \n\t" - - "paddw %%mm3, %%mm0 \n\t" //z2 - "movq %%mm5, %%mm7 \n\t" - - "paddw %%mm0, %%mm2 \n\t" //d4 - "psubw %%mm0, %%mm6 \n\t" //d5 - - "movq %%mm2, %%mm4 \n\t" - "paddw %%mm3, %%mm1 \n\t" //z4 - - //transpose 4x4 - "punpcklwd %%mm6, %%mm2 \n\t" - "paddw %%mm1, %%mm5 \n\t" //d6 - - "punpckhwd %%mm6, %%mm4 \n\t" - "psubw %%mm1, %%mm7 \n\t" //d7 - - "movq %%mm5, %%mm6 \n\t" - "punpcklwd %%mm7, %%mm5 \n\t" - - "punpckhwd %%mm7, %%mm6 \n\t" - "movq %%mm2, %%mm7 \n\t" - - "punpckldq %%mm5, %%mm2 \n\t" //4 - "sub %%"REG_d", %%"REG_S" \n\t" - - "punpckhdq %%mm5, %%mm7 \n\t" //5 - "movq %%mm4, %%mm5 \n\t" - - "movq %%mm2, "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "punpckldq %%mm6, %%mm4 \n\t" //6 - - "movq %%mm7, "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "punpckhdq %%mm6, %%mm5 \n\t" //7 - - "movq %%mm4, "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "add $4, %%"REG_S" \n\t" - - "movq %%mm5, "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_D") \n\t" - "add $"DCTSIZE_S"*2*4, %%"REG_D" \n\t" //4 rows - "dec %%"REG_c" \n\t" - "jnz 6b \n\t" - - : "+S"(pixels), "+D"(data), "+c"(cnt), "=o"(temps) - : "a"(line_size) - : "%"REG_d); -} - -#endif // HAVE_MMX diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c b/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c deleted file mode 100644 index 4db6c0a..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_ilpack.c +++ /dev/null @@ -1,458 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include "config.h" -#include "mp_msg.h" -#include "cpudetect.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libavutil/attributes.h" -#include "libavutil/x86/asm.h" - -typedef void (pack_func_t)(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, int us, int vs); - -struct vf_priv_s { - int mode; - pack_func_t *pack[2]; -}; - -static void pack_nn_C(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, - int av_unused us, int av_unused vs) -{ - int j; - for (j = w/2; j; j--) { - *dst++ = *y++; - *dst++ = *u++; - *dst++ = *y++; - *dst++ = *v++; - } -} - -static void pack_li_0_C(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, int us, int vs) -{ - int j; - for (j = w/2; j; j--) { - *dst++ = *y++; - *dst++ = (u[us+us] + 7*u[0])>>3; - *dst++ = *y++; - *dst++ = (v[vs+vs] + 7*v[0])>>3; - u++; v++; - } -} - -static void pack_li_1_C(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, int us, int vs) -{ - int j; - for (j = w/2; j; j--) { - *dst++ = *y++; - *dst++ = (3*u[us+us] + 5*u[0])>>3; - *dst++ = *y++; - *dst++ = (3*v[vs+vs] + 5*v[0])>>3; - u++; v++; - } -} - -#if HAVE_MMX -static void pack_nn_MMX(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, - int av_unused us, int av_unused vs) -{ - __asm__ volatile ("" - ASMALIGN(4) - "1: \n\t" - "movq (%0), %%mm1 \n\t" - "movq (%0), %%mm2 \n\t" - "movq (%1), %%mm4 \n\t" - "movq (%2), %%mm6 \n\t" - "punpcklbw %%mm6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm1 \n\t" - "punpckhbw %%mm4, %%mm2 \n\t" - - "add $8, %0 \n\t" - "add $4, %1 \n\t" - "add $4, %2 \n\t" - "movq %%mm1, (%3) \n\t" - "movq %%mm2, 8(%3) \n\t" - "add $16, %3 \n\t" - "decl %4 \n\t" - "jnz 1b \n\t" - "emms \n\t" - : - : "r" (y), "r" (u), "r" (v), "r" (dst), "r" (w/8) - : "memory" - ); - pack_nn_C(dst, y, u, v, (w&7), 0, 0); -} - -#if HAVE_EBX_AVAILABLE -static void pack_li_0_MMX(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, int us, int vs) -{ - __asm__ volatile ("" - "push %%"REG_BP" \n\t" -#if ARCH_X86_64 - "mov %6, %%"REG_BP" \n\t" -#else - "movl 4(%%"REG_d"), %%"REG_BP" \n\t" - "movl (%%"REG_d"), %%"REG_d" \n\t" -#endif - "pxor %%mm0, %%mm0 \n\t" - - ASMALIGN(4) - ".Lli0: \n\t" - "movq (%%"REG_S"), %%mm1 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - - "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t" - "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t" - "punpcklbw %%mm0, %%mm4 \n\t" - "punpcklbw %%mm0, %%mm6 \n\t" - "movq (%%"REG_a"), %%mm3 \n\t" - "movq (%%"REG_b"), %%mm5 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - "punpcklbw %%mm0, %%mm5 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "psrlw $3, %%mm4 \n\t" - "psrlw $3, %%mm6 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "packuswb %%mm6, %%mm6 \n\t" - "punpcklbw %%mm6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm1 \n\t" - "punpckhbw %%mm4, %%mm2 \n\t" - - "movq %%mm1, (%%"REG_D") \n\t" - "movq %%mm2, 8(%%"REG_D") \n\t" - - "movq 8(%%"REG_S"), %%mm1 \n\t" - "movq 8(%%"REG_S"), %%mm2 \n\t" - - "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t" - "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t" - "punpckhbw %%mm0, %%mm4 \n\t" - "punpckhbw %%mm0, %%mm6 \n\t" - "movq (%%"REG_a"), %%mm3 \n\t" - "movq (%%"REG_b"), %%mm5 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" - "punpckhbw %%mm0, %%mm5 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "psrlw $3, %%mm4 \n\t" - "psrlw $3, %%mm6 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "packuswb %%mm6, %%mm6 \n\t" - "punpcklbw %%mm6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm1 \n\t" - "punpckhbw %%mm4, %%mm2 \n\t" - - "add $16, %%"REG_S" \n\t" - "add $8, %%"REG_a" \n\t" - "add $8, %%"REG_b" \n\t" - - "movq %%mm1, 16(%%"REG_D") \n\t" - "movq %%mm2, 24(%%"REG_D") \n\t" - "add $32, %%"REG_D" \n\t" - - "decl %%ecx \n\t" - "jnz .Lli0 \n\t" - "emms \n\t" - "pop %%"REG_BP" \n\t" - : - : "S" (y), "D" (dst), "a" (u), "b" (v), "c" (w/16), -#if ARCH_X86_64 - "d" ((x86_reg)us), "r" ((x86_reg)vs) -#else - "d" (&us) -#endif - : "memory" - ); - pack_li_0_C(dst, y, u, v, (w&15), us, vs); -} - -static void pack_li_1_MMX(unsigned char *dst, unsigned char *y, - unsigned char *u, unsigned char *v, int w, int us, int vs) -{ - __asm__ volatile ("" - "push %%"REG_BP" \n\t" -#if ARCH_X86_64 - "mov %6, %%"REG_BP" \n\t" -#else - "movl 4(%%"REG_d"), %%"REG_BP" \n\t" - "movl (%%"REG_d"), %%"REG_d" \n\t" -#endif - "pxor %%mm0, %%mm0 \n\t" - - ASMALIGN(4) - ".Lli1: \n\t" - "movq (%%"REG_S"), %%mm1 \n\t" - "movq (%%"REG_S"), %%mm2 \n\t" - - "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t" - "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t" - "punpcklbw %%mm0, %%mm4 \n\t" - "punpcklbw %%mm0, %%mm6 \n\t" - "movq (%%"REG_a"), %%mm3 \n\t" - "movq (%%"REG_b"), %%mm5 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" - "punpcklbw %%mm0, %%mm5 \n\t" - "movq %%mm4, %%mm7 \n\t" - "paddw %%mm4, %%mm4 \n\t" - "paddw %%mm7, %%mm4 \n\t" - "movq %%mm6, %%mm7 \n\t" - "paddw %%mm6, %%mm6 \n\t" - "paddw %%mm7, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "psrlw $3, %%mm4 \n\t" - "psrlw $3, %%mm6 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "packuswb %%mm6, %%mm6 \n\t" - "punpcklbw %%mm6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm1 \n\t" - "punpckhbw %%mm4, %%mm2 \n\t" - - "movq %%mm1, (%%"REG_D") \n\t" - "movq %%mm2, 8(%%"REG_D") \n\t" - - "movq 8(%%"REG_S"), %%mm1 \n\t" - "movq 8(%%"REG_S"), %%mm2 \n\t" - - "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t" - "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t" - "punpckhbw %%mm0, %%mm4 \n\t" - "punpckhbw %%mm0, %%mm6 \n\t" - "movq (%%"REG_a"), %%mm3 \n\t" - "movq (%%"REG_b"), %%mm5 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" - "punpckhbw %%mm0, %%mm5 \n\t" - "movq %%mm4, %%mm7 \n\t" - "paddw %%mm4, %%mm4 \n\t" - "paddw %%mm7, %%mm4 \n\t" - "movq %%mm6, %%mm7 \n\t" - "paddw %%mm6, %%mm6 \n\t" - "paddw %%mm7, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "paddw %%mm3, %%mm4 \n\t" - "paddw %%mm5, %%mm6 \n\t" - "psrlw $3, %%mm4 \n\t" - "psrlw $3, %%mm6 \n\t" - "packuswb %%mm4, %%mm4 \n\t" - "packuswb %%mm6, %%mm6 \n\t" - "punpcklbw %%mm6, %%mm4 \n\t" - "punpcklbw %%mm4, %%mm1 \n\t" - "punpckhbw %%mm4, %%mm2 \n\t" - - "add $16, %%"REG_S" \n\t" - "add $8, %%"REG_a" \n\t" - "add $8, %%"REG_b" \n\t" - - "movq %%mm1, 16(%%"REG_D") \n\t" - "movq %%mm2, 24(%%"REG_D") \n\t" - "add $32, %%"REG_D" \n\t" - - "decl %%ecx \n\t" - "jnz .Lli1 \n\t" - "emms \n\t" - "pop %%"REG_BP" \n\t" - : - : "S" (y), "D" (dst), "a" (u), "b" (v), "c" (w/16), -#if ARCH_X86_64 - "d" ((x86_reg)us), "r" ((x86_reg)vs) -#else - "d" (&us) -#endif - : "memory" - ); - pack_li_1_C(dst, y, u, v, (w&15), us, vs); -} -#endif /* HAVE_EBX_AVAILABLE */ -#endif - -static pack_func_t *pack_nn; -static pack_func_t *pack_li_0; -static pack_func_t *pack_li_1; - -static void ilpack(unsigned char *dst, unsigned char *src[3], - int dststride, int srcstride[3], int w, int h, pack_func_t *pack[2]) -{ - int i; - unsigned char *y, *u, *v; - int ys = srcstride[0], us = srcstride[1], vs = srcstride[2]; - int a, b; - - y = src[0]; - u = src[1]; - v = src[2]; - - pack_nn(dst, y, u, v, w, 0, 0); - y += ys; dst += dststride; - pack_nn(dst, y, u+us, v+vs, w, 0, 0); - y += ys; dst += dststride; - for (i=2; i<h-2; i++) { - a = (i&2) ? 1 : -1; - b = (i&1) ^ ((i&2)>>1); - pack[b](dst, y, u, v, w, us*a, vs*a); - y += ys; - if ((i&3) == 1) { - u -= us; - v -= vs; - } else { - u += us; - v += vs; - } - dst += dststride; - } - pack_nn(dst, y, u, v, w, 0, 0); - y += ys; dst += dststride; u += us; v += vs; - pack_nn(dst, y, u, v, w, 0, 0); -} - - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - - // hope we'll get DR buffer: - dmpi=ff_vf_get_image(vf->next, IMGFMT_YUY2, - MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, - mpi->w, mpi->h); - - ilpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], mpi->stride, mpi->w, mpi->h, vf->priv->pack); - - return ff_vf_next_put_image(vf,dmpi, pts); -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - /* FIXME - also support UYVY output? */ - return ff_vf_next_config(vf, width, height, d_width, d_height, flags, IMGFMT_YUY2); -} - - -static int query_format(struct vf_instance *vf, unsigned int fmt) -{ - /* FIXME - really any YUV 4:2:0 input format should work */ - switch (fmt) { - case IMGFMT_YV12: - case IMGFMT_IYUV: - case IMGFMT_I420: - return ff_vf_next_query_format(vf,IMGFMT_YUY2); - } - return 0; -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->config=config; - vf->query_format=query_format; - vf->put_image=put_image; - vf->priv = calloc(1, sizeof(struct vf_priv_s)); - vf->priv->mode = 1; - if (args) sscanf(args, "%d", &vf->priv->mode); - - pack_nn = pack_nn_C; - pack_li_0 = pack_li_0_C; - pack_li_1 = pack_li_1_C; -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX) { - pack_nn = pack_nn_MMX; -#if HAVE_EBX_AVAILABLE - pack_li_0 = pack_li_0_MMX; - pack_li_1 = pack_li_1_MMX; -#endif - } -#endif - - switch(vf->priv->mode) { - case 0: - vf->priv->pack[0] = vf->priv->pack[1] = pack_nn; - break; - default: - ff_mp_msg(MSGT_VFILTER, MSGL_WARN, - "ilpack: unknown mode %d (fallback to linear)\n", - vf->priv->mode); - /* Fallthrough */ - case 1: - vf->priv->pack[0] = pack_li_0; - vf->priv->pack[1] = pack_li_1; - break; - } - - return 1; -} - -const vf_info_t ff_vf_info_ilpack = { - "4:2:0 planar -> 4:2:2 packed reinterlacer", - "ilpack", - "Richard Felker", - "", - vf_open, - NULL -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c b/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c deleted file mode 100644 index 30f9530..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_pp7.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2005 Michael Niedermayer <michaelni@gmx.at> - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <math.h> - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#if HAVE_MALLOC_H -#include <malloc.h> -#endif - -#include "libavutil/mem.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "libvo/fastmemcpy.h" - -#define XMIN(a,b) ((a) < (b) ? (a) : (b)) -#define XMAX(a,b) ((a) > (b) ? (a) : (b)) - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0, 48, 12, 60, 3, 51, 15, 63, }, -{ 32, 16, 44, 28, 35, 19, 47, 31, }, -{ 8, 56, 4, 52, 11, 59, 7, 55, }, -{ 40, 24, 36, 20, 43, 27, 39, 23, }, -{ 2, 50, 14, 62, 1, 49, 13, 61, }, -{ 34, 18, 46, 30, 33, 17, 45, 29, }, -{ 10, 58, 6, 54, 9, 57, 5, 53, }, -{ 42, 26, 38, 22, 41, 25, 37, 21, }, -}; - -struct vf_priv_s { - int qp; - int mode; - int mpeg2; - int temp_stride; - uint8_t *src; -}; -#if 0 -static inline void dct7_c(int16_t *dst, int s0, int s1, int s2, int s3, int step){ - int s, d; - int dst2[64]; -//#define S0 (1024/0.37796447300922719759) -#define C0 ((int)(1024*0.37796447300922719759+0.5)) //sqrt(1/7) -#define C1 ((int)(1024*0.53452248382484879308/6+0.5)) //sqrt(2/7)/6 - -#define C2 ((int)(1024*0.45221175985034745004/2+0.5)) -#define C3 ((int)(1024*0.36264567479870879474/2+0.5)) - -//0.1962505182412941918 0.0149276808419397944-0.2111781990832339584 -#define C4 ((int)(1024*0.1962505182412941918+0.5)) -#define C5 ((int)(1024*0.0149276808419397944+0.5)) -//#define C6 ((int)(1024*0.2111781990832339584+0.5)) -#if 0 - s= s0 + s1 + s2; - dst[0*step] = ((s + s3)*C0 + 512) >> 10; - s= (s - 6*s3)*C1 + 512; - d= (s0-s2)*C4 + (s1-s2)*C5; - dst[1*step] = (s + 2*d)>>10; - s -= d; - d= (s1-s0)*C2 + (s1-s2)*C3; - dst[2*step] = (s + d)>>10; - dst[3*step] = (s - d)>>10; -#elif 1 - s = s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0*step]= s0 + s; - dst[2*step]= s0 - s; - dst[1*step]= 2*s3 + s2; - dst[3*step]= s3 - 2*s2; -#else - int i,j,n=7; - for(i=0; i<7; i+=2){ - dst2[i*step/2]= 0; - for(j=0; j<4; j++) - dst2[i*step/2] += src[j*step] * cos(i*M_PI/n*(j+0.5)) * sqrt((i?2.0:1.0)/n); - if(fabs(dst2[i*step/2] - dst[i*step/2]) > 20) - printf("%d %d %d (%d %d %d %d) -> (%d %d %d %d)\n", i,dst2[i*step/2], dst[i*step/2],src[0*step], src[1*step], src[2*step], src[3*step], dst[0*step], dst[1*step],dst[2*step],dst[3*step]); - } -#endif -} -#endif - -static inline void dctA_c(int16_t *dst, uint8_t *src, int stride){ - int i; - - for(i=0; i<4; i++){ - int s0= src[0*stride] + src[6*stride]; - int s1= src[1*stride] + src[5*stride]; - int s2= src[2*stride] + src[4*stride]; - int s3= src[3*stride]; - int s= s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0]= s0 + s; - dst[2]= s0 - s; - dst[1]= 2*s3 + s2; - dst[3]= s3 - 2*s2; - src++; - dst+=4; - } -} - -static void dctB_c(int16_t *dst, int16_t *src){ - int i; - - for(i=0; i<4; i++){ - int s0= src[0*4] + src[6*4]; - int s1= src[1*4] + src[5*4]; - int s2= src[2*4] + src[4*4]; - int s3= src[3*4]; - int s= s3+s3; - s3= s-s0; - s0= s+s0; - s = s2+s1; - s2= s2-s1; - dst[0*4]= s0 + s; - dst[2*4]= s0 - s; - dst[1*4]= 2*s3 + s2; - dst[3*4]= s3 - 2*s2; - src++; - dst++; - } -} - -#if HAVE_MMX -static void dctB_mmx(int16_t *dst, int16_t *src){ - __asm__ volatile ( - "movq (%0), %%mm0 \n\t" - "movq 1*4*2(%0), %%mm1 \n\t" - "paddw 6*4*2(%0), %%mm0 \n\t" - "paddw 5*4*2(%0), %%mm1 \n\t" - "movq 2*4*2(%0), %%mm2 \n\t" - "movq 3*4*2(%0), %%mm3 \n\t" - "paddw 4*4*2(%0), %%mm2 \n\t" - "paddw %%mm3, %%mm3 \n\t" //s - "movq %%mm3, %%mm4 \n\t" //s - "psubw %%mm0, %%mm3 \n\t" //s-s0 - "paddw %%mm0, %%mm4 \n\t" //s+s0 - "movq %%mm2, %%mm0 \n\t" //s2 - "psubw %%mm1, %%mm2 \n\t" //s2-s1 - "paddw %%mm1, %%mm0 \n\t" //s2+s1 - "movq %%mm4, %%mm1 \n\t" //s0' - "psubw %%mm0, %%mm4 \n\t" //s0'-s' - "paddw %%mm0, %%mm1 \n\t" //s0'+s' - "movq %%mm3, %%mm0 \n\t" //s3' - "psubw %%mm2, %%mm3 \n\t" - "psubw %%mm2, %%mm3 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "paddw %%mm0, %%mm2 \n\t" - "movq %%mm1, (%1) \n\t" - "movq %%mm4, 2*4*2(%1) \n\t" - "movq %%mm2, 1*4*2(%1) \n\t" - "movq %%mm3, 3*4*2(%1) \n\t" - :: "r" (src), "r"(dst) - ); -} -#endif - -static void (*dctB)(int16_t *dst, int16_t *src)= dctB_c; - -#define N0 4 -#define N1 5 -#define N2 10 -#define SN0 2 -#define SN1 2.2360679775 -#define SN2 3.16227766017 -#define N (1<<16) - -static const int factor[16]={ - N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2), - N/(N1*N0), N/(N1*N1), N/(N1*N0),N/(N1*N2), - N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2), - N/(N2*N0), N/(N2*N1), N/(N2*N0),N/(N2*N2), -}; - -static const int thres[16]={ - N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2), - N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2), - N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2), - N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2), -}; - -static int thres2[99][16]; - -static void init_thres2(void){ - int qp, i; - int bias= 0; //FIXME - - for(qp=0; qp<99; qp++){ - for(i=0; i<16; i++){ - thres2[qp][i]= ((i&1)?SN2:SN0) * ((i&4)?SN2:SN0) * XMAX(1,qp) * (1<<2) - 1 - bias; - } - } -} - -static int hardthresh_c(int16_t *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - a += level * factor[i]; - } - } - return (a + (1<<11))>>12; -} - -static int mediumthresh_c(int16_t *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - if(((unsigned)(level+2*threshold1))>2*threshold2){ - a += level * factor[i]; - }else{ - if(level>0) a+= 2*(level - (int)threshold1)*factor[i]; - else a+= 2*(level + (int)threshold1)*factor[i]; - } - } - } - return (a + (1<<11))>>12; -} - -static int softthresh_c(int16_t *src, int qp){ - int i; - int a; - - a= src[0] * factor[0]; - for(i=1; i<16; i++){ - unsigned int threshold1= thres2[qp][i]; - unsigned int threshold2= (threshold1<<1); - int level= src[i]; - if(((unsigned)(level+threshold1))>threshold2){ - if(level>0) a+= (level - (int)threshold1)*factor[i]; - else a+= (level + (int)threshold1)*factor[i]; - } - } - return (a + (1<<11))>>12; -} - -static int (*requantize)(int16_t *src, int qp)= hardthresh_c; - -static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, uint8_t *qp_store, int qp_stride, int is_luma){ - int x, y; - const int stride= is_luma ? p->temp_stride : ((width+16+15)&(~15)); - uint8_t *p_src= p->src + 8*stride; - int16_t *block= (int16_t *)p->src; - int16_t *temp= (int16_t *)(p->src + 32); - - if (!src || !dst) return; // HACK avoid crash for Y8 colourspace - for(y=0; y<height; y++){ - int index= 8 + 8*stride + y*stride; - fast_memcpy(p_src + index, src + y*src_stride, width); - for(x=0; x<8; x++){ - p_src[index - x - 1]= p_src[index + x ]; - p_src[index + width + x ]= p_src[index + width - x - 1]; - } - } - for(y=0; y<8; y++){ - fast_memcpy(p_src + ( 7-y)*stride, p_src + ( y+8)*stride, stride); - fast_memcpy(p_src + (height+8+y)*stride, p_src + (height-y+7)*stride, stride); - } - //FIXME (try edge emu) - - for(y=0; y<height; y++){ - for(x=-8; x<0; x+=4){ - const int index= x + y*stride + (8-3)*(1+stride) + 8; //FIXME silly offset - uint8_t *src = p_src + index; - int16_t *tp= temp+4*x; - - dctA_c(tp+4*8, src, stride); - } - for(x=0; x<width; ){ - const int qps= 3 + is_luma; - int qp; - int end= XMIN(x+8, width); - - if(p->qp) - qp= p->qp; - else{ - qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride]; - qp=norm_qscale(qp, p->mpeg2); - } - for(; x<end; x++){ - const int index= x + y*stride + (8-3)*(1+stride) + 8; //FIXME silly offset - uint8_t *src = p_src + index; - int16_t *tp= temp+4*x; - int v; - - if((x&3)==0) - dctA_c(tp+4*8, src, stride); - - dctB(block, tp); - - v= requantize(block, qp); - v= (v + dither[y&7][x&7])>>6; - if((unsigned)v > 255) - v= (-v)>>31; - dst[x + y*dst_stride]= v; - } - } - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int h= (height+16+15)&(~15); - - vf->priv->temp_stride= (width+16+15)&(~15); - vf->priv->src = av_malloc(vf->priv->temp_stride*(h+8)*sizeof(uint8_t)); - - return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(mpi->flags&MP_IMGFLAG_DIRECT){ - dmpi=vf->dmpi; - }else{ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - ff_vf_clone_mpi_attributes(dmpi, mpi); - } - - vf->priv->mpeg2= mpi->qscale_type; - if(mpi->qscale || vf->priv->qp){ - filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, mpi->qscale, mpi->qstride, 1); - filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0); - filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - - return ff_vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - if(!vf->priv) return; - - av_free(vf->priv->src); - vf->priv->src= NULL; - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YVU9: - case IMGFMT_IF09: - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_CLPL: - case IMGFMT_Y800: - case IMGFMT_Y8: - case IMGFMT_444P: - case IMGFMT_422P: - case IMGFMT_411P: - return ff_vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data){ - return ff_vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - if (args) sscanf(args, "%d:%d", &vf->priv->qp, &vf->priv->mode); - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - - init_thres2(); - - switch(vf->priv->mode){ - case 0: requantize= hardthresh_c; break; - case 1: requantize= softthresh_c; break; - default: - case 2: requantize= mediumthresh_c; break; - } - -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX){ - dctB= dctB_mmx; - } -#endif -#if 0 - if(ff_gCpuCaps.hasMMX){ - switch(vf->priv->mode){ - case 0: requantize= hardthresh_mmx; break; - case 1: requantize= softthresh_mmx; break; - } - } -#endif - - return 1; -} - -const vf_info_t ff_vf_info_pp7 = { - "postprocess 7", - "pp7", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_softpulldown.c b/ffmpeg/libavfilter/libmpcodecs/vf_softpulldown.c deleted file mode 100644 index 556374e..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_softpulldown.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" -#include "mp_msg.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" - -#include "libvo/fastmemcpy.h" - -struct vf_priv_s { - int state; - long long in; - long long out; -}; - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts) -{ - mp_image_t *dmpi; - int ret = 0; - int flags = mpi->fields; - int state = vf->priv->state; - - dmpi = ff_vf_get_image(vf->next, mpi->imgfmt, - MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE | - MP_IMGFLAG_PRESERVE, mpi->width, mpi->height); - - vf->priv->in++; - - if ((state == 0 && - !(flags & MP_IMGFIELD_TOP_FIRST)) || - (state == 1 && - flags & MP_IMGFIELD_TOP_FIRST)) { - ff_mp_msg(MSGT_VFILTER, MSGL_WARN, - "softpulldown: Unexpected field flags: state=%d top_field_first=%d repeat_first_field=%d\n", - state, - (flags & MP_IMGFIELD_TOP_FIRST) != 0, - (flags & MP_IMGFIELD_REPEAT_FIRST) != 0); - state ^= 1; - } - - if (state == 0) { - ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); - vf->priv->out++; - if (flags & MP_IMGFIELD_REPEAT_FIRST) { - my_memcpy_pic(dmpi->planes[0], - mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], - mpi->planes[1], - mpi->chroma_width, - mpi->chroma_height/2, - dmpi->stride[1]*2, - mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], - mpi->planes[2], - mpi->chroma_width, - mpi->chroma_height/2, - dmpi->stride[2]*2, - mpi->stride[2]*2); - } - state=1; - } - } else { - my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0], - mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1], - mpi->planes[1]+mpi->stride[1], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[1]*2, mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2], - mpi->planes[2]+mpi->stride[2], - mpi->chroma_width, mpi->chroma_height/2, - dmpi->stride[2]*2, mpi->stride[2]*2); - } - ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE); - vf->priv->out++; - if (flags & MP_IMGFIELD_REPEAT_FIRST) { - ret |= ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE); - vf->priv->out++; - state=0; - } else { - my_memcpy_pic(dmpi->planes[0], - mpi->planes[0], mpi->w, mpi->h/2, - dmpi->stride[0]*2, mpi->stride[0]*2); - if (mpi->flags & MP_IMGFLAG_PLANAR) { - my_memcpy_pic(dmpi->planes[1], - mpi->planes[1], - mpi->chroma_width, - mpi->chroma_height/2, - dmpi->stride[1]*2, - mpi->stride[1]*2); - my_memcpy_pic(dmpi->planes[2], - mpi->planes[2], - mpi->chroma_width, - mpi->chroma_height/2, - dmpi->stride[2]*2, - mpi->stride[2]*2); - } - } - } - - vf->priv->state = state; - - return ret; -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt) -{ - return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void uninit(struct vf_instance *vf) -{ - ff_mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out); - free(vf->priv); -} - -static int vf_open(vf_instance_t *vf, char *args) -{ - vf->config = config; - vf->put_image = put_image; - vf->uninit = uninit; - vf->default_reqs = VFCAP_ACCEPT_STRIDE; - vf->priv = calloc(1, sizeof(struct vf_priv_s)); - vf->priv->state = 0; - return 1; -} - -const vf_info_t ff_vf_info_softpulldown = { - "mpeg2 soft 3:2 pulldown", - "softpulldown", - "Tobias Diedrich <ranma+mplayer@tdiedrich.de>", - "", - vf_open, - NULL -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c b/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c deleted file mode 100644 index 1fb2523..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vf_uspp.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (C) 2005 Michael Niedermayer <michaelni@gmx.at> - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <math.h> -#include <assert.h> - -#include "config.h" - -#include "mp_msg.h" -#include "cpudetect.h" - -#include "libavutil/mem.h" -#include "libavcodec/avcodec.h" - -#include "img_format.h" -#include "mp_image.h" -#include "vf.h" -#include "av_helpers.h" -#include "libvo/fastmemcpy.h" - -#define XMIN(a,b) ((a) < (b) ? (a) : (b)) - -#define BLOCK 16 - -//===========================================================================// -static const uint8_t __attribute__((aligned(8))) dither[8][8]={ -{ 0*4, 48*4, 12*4, 60*4, 3*4, 51*4, 15*4, 63*4, }, -{ 32*4, 16*4, 44*4, 28*4, 35*4, 19*4, 47*4, 31*4, }, -{ 8*4, 56*4, 4*4, 52*4, 11*4, 59*4, 7*4, 55*4, }, -{ 40*4, 24*4, 36*4, 20*4, 43*4, 27*4, 39*4, 23*4, }, -{ 2*4, 50*4, 14*4, 62*4, 1*4, 49*4, 13*4, 61*4, }, -{ 34*4, 18*4, 46*4, 30*4, 33*4, 17*4, 45*4, 29*4, }, -{ 10*4, 58*4, 6*4, 54*4, 9*4, 57*4, 5*4, 53*4, }, -{ 42*4, 26*4, 38*4, 22*4, 41*4, 25*4, 37*4, 21*4, }, -}; - -static const uint8_t offset[511][2]= { -{ 0, 0}, -{ 0, 0}, { 8, 8}, -{ 0, 0}, { 4, 4}, {12, 8}, { 8,12}, -{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, - -{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, -{ 5, 1}, {15, 3}, { 9, 5}, { 3, 7}, {13, 9}, { 7,11}, { 1,13}, {11,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, -{ 2, 2}, {10, 2}, { 2,10}, {10,10}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, -{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, -{ 6, 6}, {14, 6}, { 6,14}, {14,14}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, -{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, -{ 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, -{ 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, -{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, -{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, -{ 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, -{ 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, -{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, -{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, -{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, -{ 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, -{ 2, 4}, {10, 4}, { 2,12}, {10,12}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, -{ 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, -{ 3, 5}, {11, 5}, { 3,13}, {11,13}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, -{ 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, -{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, -{ 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, -{ 5, 5}, {13, 5}, { 5,13}, {13,13}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, -{ 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, -{ 6, 4}, {14, 4}, { 6,12}, {14,12}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, -{ 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, -{ 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, - -{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10}, { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, { 3, 1}, {11, 1} -, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13}, { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9}, { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11}, { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15}, { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11}, { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13}, { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9}, { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12}, { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8}, { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14}, { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10}, { 1, 2}, { 9, 2}, { 1,10}, { 9, -10}, { 5, 6}, {13, 6}, { 5,14}, {13,14}, { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10}, { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12}, { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8}, -}; - -struct vf_priv_s { - int log2_count; - int qp; - int mode; - int mpeg2; - int temp_stride[3]; - uint8_t *src[3]; - int16_t *temp[3]; - int outbuf_size; - uint8_t *outbuf; - AVCodecContext *avctx_enc[BLOCK*BLOCK]; - AVFrame *frame; - AVFrame *frame_dec; -}; - -static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){ - int y, x; - -#define STORE(pos) \ - temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>8;\ - if(temp & 0x100) temp= ~(temp>>31);\ - dst[x + y*dst_stride + pos]= temp; - - for(y=0; y<height; y++){ - const uint8_t *d= dither[y&7]; - for(x=0; x<width; x+=8){ - int temp; - STORE(0); - STORE(1); - STORE(2); - STORE(3); - STORE(4); - STORE(5); - STORE(6); - STORE(7); - } - } -} - -static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height, uint8_t *qp_store, int qp_stride){ - int x, y, i, j; - const int count= 1<<p->log2_count; - - for(i=0; i<3; i++){ - int is_chroma= !!i; - int w= width >>is_chroma; - int h= height>>is_chroma; - int stride= p->temp_stride[i]; - int block= BLOCK>>is_chroma; - - if (!src[i] || !dst[i]) - continue; // HACK avoid crash for Y8 colourspace - for(y=0; y<h; y++){ - int index= block + block*stride + y*stride; - fast_memcpy(p->src[i] + index, src[i] + y*src_stride[i], w); - for(x=0; x<block; x++){ - p->src[i][index - x - 1]= p->src[i][index + x ]; - p->src[i][index + w + x ]= p->src[i][index + w - x - 1]; - } - } - for(y=0; y<block; y++){ - fast_memcpy(p->src[i] + ( block-1-y)*stride, p->src[i] + ( y+block )*stride, stride); - fast_memcpy(p->src[i] + (h+block +y)*stride, p->src[i] + (h-y+block-1)*stride, stride); - } - - p->frame->linesize[i]= stride; - memset(p->temp[i], 0, (h+2*block)*stride*sizeof(int16_t)); - } - - if(p->qp) - p->frame->quality= p->qp * FF_QP2LAMBDA; - else - p->frame->quality= norm_qscale(qp_store[0], p->mpeg2) * FF_QP2LAMBDA; -// init per MB qscale stuff FIXME - - for(i=0; i<count; i++){ - const int x1= offset[i+count-1][0]; - const int y1= offset[i+count-1][1]; - int offset; - p->frame->data[0]= p->src[0] + x1 + y1 * p->frame->linesize[0]; - p->frame->data[1]= p->src[1] + x1/2 + y1/2 * p->frame->linesize[1]; - p->frame->data[2]= p->src[2] + x1/2 + y1/2 * p->frame->linesize[2]; - - avcodec_encode_video(p->avctx_enc[i], p->outbuf, p->outbuf_size, p->frame); - p->frame_dec = p->avctx_enc[i]->coded_frame; - - offset= (BLOCK-x1) + (BLOCK-y1)*p->frame_dec->linesize[0]; - //FIXME optimize - for(y=0; y<height; y++){ - for(x=0; x<width; x++){ - p->temp[0][ x + y*p->temp_stride[0] ] += p->frame_dec->data[0][ x + y*p->frame_dec->linesize[0] + offset ]; - } - } - offset= (BLOCK/2-x1/2) + (BLOCK/2-y1/2)*p->frame_dec->linesize[1]; - for(y=0; y<height/2; y++){ - for(x=0; x<width/2; x++){ - p->temp[1][ x + y*p->temp_stride[1] ] += p->frame_dec->data[1][ x + y*p->frame_dec->linesize[1] + offset ]; - p->temp[2][ x + y*p->temp_stride[2] ] += p->frame_dec->data[2][ x + y*p->frame_dec->linesize[2] + offset ]; - } - } - } - - for(j=0; j<3; j++){ - int is_chroma= !!j; - if (!dst[j]) - continue; // HACK avoid crash for Y8 colourspace - store_slice_c(dst[j], p->temp[j], dst_stride[j], p->temp_stride[j], width>>is_chroma, height>>is_chroma, 8-p->log2_count); - } -} - -static int config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int flags, unsigned int outfmt){ - int i; - AVCodec *enc= avcodec_find_encoder(AV_CODEC_ID_SNOW); - - for(i=0; i<3; i++){ - int is_chroma= !!i; - int w= ((width + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma; - int h= ((height + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma; - - vf->priv->temp_stride[i]= w; - vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t)); - vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t)); - } - for(i=0; i< (1<<vf->priv->log2_count); i++){ - AVCodecContext *avctx_enc; - AVDictionary *opts = NULL; - - avctx_enc= - vf->priv->avctx_enc[i]= avcodec_alloc_context3(NULL); - avctx_enc->width = width + BLOCK; - avctx_enc->height = height + BLOCK; - avctx_enc->time_base= (AVRational){1,25}; // meaningless - avctx_enc->gop_size = 300; - avctx_enc->max_b_frames= 0; - avctx_enc->pix_fmt = AV_PIX_FMT_YUV420P; - avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY; - avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - avctx_enc->global_quality= 123; - av_dict_set(&opts, "no_bitstream", "1", 0); - avcodec_open2(avctx_enc, enc, &opts); - av_dict_free(&opts); - assert(avctx_enc->codec); - } - vf->priv->frame= av_frame_alloc(); - vf->priv->frame_dec= av_frame_alloc(); - - vf->priv->outbuf_size= (width + BLOCK)*(height + BLOCK)*10; - vf->priv->outbuf= malloc(vf->priv->outbuf_size); - - return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); -} - -static void get_image(struct vf_instance *vf, mp_image_t *mpi){ - if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change - // ok, we can do pp in-place (or pp disabled): - vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height); - mpi->planes[0]=vf->dmpi->planes[0]; - mpi->stride[0]=vf->dmpi->stride[0]; - mpi->width=vf->dmpi->width; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - mpi->planes[1]=vf->dmpi->planes[1]; - mpi->planes[2]=vf->dmpi->planes[2]; - mpi->stride[1]=vf->dmpi->stride[1]; - mpi->stride[2]=vf->dmpi->stride[2]; - } - mpi->flags|=MP_IMGFLAG_DIRECT; -} - -static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ - mp_image_t *dmpi; - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // no DR, so get a new image! hope we'll get DR buffer: - dmpi=ff_vf_get_image(vf->next,mpi->imgfmt, - MP_IMGTYPE_TEMP, - MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, - mpi->width,mpi->height); - ff_vf_clone_mpi_attributes(dmpi, mpi); - }else{ - dmpi=vf->dmpi; - } - - vf->priv->mpeg2= mpi->qscale_type; - if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){ - if(mpi->qscale || vf->priv->qp){ - filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h, mpi->qscale, mpi->qstride); - }else{ - memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]); - memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]); - memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]); - } - } - -#if HAVE_MMX - if(ff_gCpuCaps.hasMMX) __asm__ volatile ("emms\n\t"); -#endif -#if HAVE_MMX2 - if(ff_gCpuCaps.hasMMX2) __asm__ volatile ("sfence\n\t"); -#endif - - return ff_vf_next_put_image(vf,dmpi, pts); -} - -static void uninit(struct vf_instance *vf){ - int i; - if(!vf->priv) return; - - for(i=0; i<3; i++){ - free(vf->priv->temp[i]); - vf->priv->temp[i]= NULL; - free(vf->priv->src[i]); - vf->priv->src[i]= NULL; - } - for(i=0; i<BLOCK*BLOCK; i++){ - av_freep(&vf->priv->avctx_enc[i]); - } - - free(vf->priv); - vf->priv=NULL; -} - -//===========================================================================// -static int query_format(struct vf_instance *vf, unsigned int fmt){ - switch(fmt){ - case IMGFMT_YV12: - case IMGFMT_I420: - case IMGFMT_IYUV: - case IMGFMT_Y800: - case IMGFMT_Y8: - return ff_vf_next_query_format(vf,fmt); - } - return 0; -} - -static int control(struct vf_instance *vf, int request, void* data){ - switch(request){ - case VFCTRL_QUERY_MAX_PP_LEVEL: - return 8; - case VFCTRL_SET_PP_LEVEL: - vf->priv->log2_count= *((unsigned int*)data); - //FIXME we have to realloc a few things here - return CONTROL_TRUE; - } - return ff_vf_next_control(vf,request,data); -} - -static int vf_open(vf_instance_t *vf, char *args){ - - int log2c=-1; - - vf->config=config; - vf->put_image=put_image; - vf->get_image=get_image; - vf->query_format=query_format; - vf->uninit=uninit; - vf->control= control; - vf->priv=malloc(sizeof(struct vf_priv_s)); - memset(vf->priv, 0, sizeof(struct vf_priv_s)); - - ff_init_avcodec(); - - vf->priv->log2_count= 4; - - if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode); - - if( log2c >=0 && log2c <=8 ) - vf->priv->log2_count = log2c; - - if(vf->priv->qp < 0) - vf->priv->qp = 0; - -// #if HAVE_MMX -// if(ff_gCpuCaps.hasMMX){ -// store_slice= store_slice_mmx; -// } -// #endif - - return 1; -} - -const vf_info_t ff_vf_info_uspp = { - "ultra simple/slow postprocess", - "uspp", - "Michael Niedermayer", - "", - vf_open, - NULL -}; diff --git a/ffmpeg/libavfilter/libmpcodecs/vfcap.h b/ffmpeg/libavfilter/libmpcodecs/vfcap.h deleted file mode 100644 index 611d642..0000000 --- a/ffmpeg/libavfilter/libmpcodecs/vfcap.h +++ /dev/null @@ -1,56 +0,0 @@ -/* VFCAP_* values: they are flags, returned by query_format(): - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_VFCAP_H -#define MPLAYER_VFCAP_H - -// set, if the given colorspace is supported (with or without conversion) -#define VFCAP_CSP_SUPPORTED 0x1 -// set, if the given colorspace is supported _without_ conversion -#define VFCAP_CSP_SUPPORTED_BY_HW 0x2 -// set if the driver/filter can draw OSD -#define VFCAP_OSD 0x4 -// set if the driver/filter can handle compressed SPU stream -#define VFCAP_SPU 0x8 -// scaling up/down by hardware, or software: -#define VFCAP_HWSCALE_UP 0x10 -#define VFCAP_HWSCALE_DOWN 0x20 -#define VFCAP_SWSCALE 0x40 -// driver/filter can do vertical flip (upside-down) -#define VFCAP_FLIP 0x80 - -// driver/hardware handles timing (blocking) -#define VFCAP_TIMER 0x100 -// driver _always_ flip image upside-down (for ve_vfw) -#define VFCAP_FLIPPED 0x200 -// vf filter: accepts stride (put_image) -// vo driver: has draw_slice() support for the given csp -#define VFCAP_ACCEPT_STRIDE 0x400 -// filter does postprocessing (so you shouldn't scale/filter image before it) -#define VFCAP_POSTPROC 0x800 -// filter cannot be reconfigured to different size & format -#define VFCAP_CONSTANT 0x1000 -// filter can draw EOSD -#define VFCAP_EOSD 0x2000 -// filter will draw EOSD at screen resolution (without scaling) -#define VFCAP_EOSD_UNSCALED 0x4000 -// used by libvo and vf_vo, indicates the VO does not support draw_slice for this format -#define VOCAP_NOSLICES 0x8000 - -#endif /* MPLAYER_VFCAP_H */ diff --git a/ffmpeg/libavfilter/lswsutils.c b/ffmpeg/libavfilter/lswsutils.c deleted file mode 100644 index ebb4f93..0000000 --- a/ffmpeg/libavfilter/lswsutils.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/imgutils.h" -#include "lswsutils.h" - -int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], - int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, - uint8_t * const src_data[4], int src_linesize[4], - int src_w, int src_h, enum AVPixelFormat src_pix_fmt, - void *log_ctx) -{ - int ret; - struct SwsContext *sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt, - dst_w, dst_h, dst_pix_fmt, - 0, NULL, NULL, NULL); - if (!sws_ctx) { - av_log(log_ctx, AV_LOG_ERROR, - "Impossible to create scale context for the conversion " - "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n", - av_get_pix_fmt_name(src_pix_fmt), src_w, src_h, - av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h); - ret = AVERROR(EINVAL); - goto end; - } - - if ((ret = av_image_alloc(dst_data, dst_linesize, dst_w, dst_h, dst_pix_fmt, 16)) < 0) - goto end; - ret = 0; - sws_scale(sws_ctx, (const uint8_t * const*)src_data, src_linesize, 0, src_h, dst_data, dst_linesize); - -end: - sws_freeContext(sws_ctx); - return ret; -} diff --git a/ffmpeg/libavfilter/lswsutils.h b/ffmpeg/libavfilter/lswsutils.h deleted file mode 100644 index f5f5320..0000000 --- a/ffmpeg/libavfilter/lswsutils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Miscellaneous utilities which make use of the libswscale library - */ - -#ifndef AVFILTER_LSWSUTILS_H -#define AVFILTER_LSWSUTILS_H - -#include "libswscale/swscale.h" - -/** - * Scale image using libswscale. - */ -int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4], - int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt, - uint8_t *const src_data[4], int src_linesize[4], - int src_w, int src_h, enum AVPixelFormat src_pix_fmt, - void *log_ctx); - -#endif /* AVFILTER_LSWSUTILS_H */ diff --git a/ffmpeg/libavfilter/split.c b/ffmpeg/libavfilter/split.c deleted file mode 100644 index 6abd5ee..0000000 --- a/ffmpeg/libavfilter/split.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * audio and video splitter - */ - -#include <stdio.h> - -#include "libavutil/attributes.h" -#include "libavutil/internal.h" -#include "libavutil/mem.h" -#include "libavutil/opt.h" - -#include "avfilter.h" -#include "audio.h" -#include "internal.h" -#include "video.h" - -typedef struct SplitContext { - const AVClass *class; - int nb_outputs; -} SplitContext; - -static av_cold int split_init(AVFilterContext *ctx) -{ - SplitContext *s = ctx->priv; - int i; - - for (i = 0; i < s->nb_outputs; i++) { - char name[32]; - AVFilterPad pad = { 0 }; - - snprintf(name, sizeof(name), "output%d", i); - pad.type = ctx->filter->inputs[0].type; - pad.name = av_strdup(name); - - ff_insert_outpad(ctx, i, &pad); - } - - return 0; -} - -static av_cold void split_uninit(AVFilterContext *ctx) -{ - int i; - - for (i = 0; i < ctx->nb_outputs; i++) - av_freep(&ctx->output_pads[i].name); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - int i, ret = AVERROR_EOF; - - for (i = 0; i < ctx->nb_outputs; i++) { - AVFrame *buf_out; - - if (ctx->outputs[i]->closed) - continue; - buf_out = av_frame_clone(frame); - if (!buf_out) { - ret = AVERROR(ENOMEM); - break; - } - - ret = ff_filter_frame(ctx->outputs[i], buf_out); - if (ret < 0) - break; - } - av_frame_free(&frame); - return ret; -} - -#define OFFSET(x) offsetof(SplitContext, x) -#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM -static const AVOption options[] = { - { "outputs", "set number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, FLAGS }, - { NULL } -}; - -#define split_options options -AVFILTER_DEFINE_CLASS(split); - -#define asplit_options options -AVFILTER_DEFINE_CLASS(asplit); - -static const AVFilterPad avfilter_vf_split_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_vf_split = { - .name = "split", - .description = NULL_IF_CONFIG_SMALL("Pass on the input to N video outputs."), - .priv_size = sizeof(SplitContext), - .priv_class = &split_class, - .init = split_init, - .uninit = split_uninit, - .inputs = avfilter_vf_split_inputs, - .outputs = NULL, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; - -static const AVFilterPad avfilter_af_asplit_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -AVFilter ff_af_asplit = { - .name = "asplit", - .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."), - .priv_size = sizeof(SplitContext), - .priv_class = &asplit_class, - .init = split_init, - .uninit = split_uninit, - .inputs = avfilter_af_asplit_inputs, - .outputs = NULL, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; diff --git a/ffmpeg/libavfilter/src_movie.c b/ffmpeg/libavfilter/src_movie.c deleted file mode 100644 index d1289e2..0000000 --- a/ffmpeg/libavfilter/src_movie.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * Copyright (c) 2008 Victor Paesa - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * movie video source - * - * @todo use direct rendering (no allocation of a new frame) - * @todo support a PTS correction mechanism - */ - -#include <float.h> -#include <stdint.h> - -#include "libavutil/attributes.h" -#include "libavutil/avstring.h" -#include "libavutil/avassert.h" -#include "libavutil/opt.h" -#include "libavutil/imgutils.h" -#include "libavutil/timestamp.h" -#include "libavformat/avformat.h" -#include "audio.h" -#include "avcodec.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - AVStream *st; - int done; -} MovieStream; - -typedef struct { - /* common A/V fields */ - const AVClass *class; - int64_t seek_point; ///< seekpoint in microseconds - double seek_point_d; - char *format_name; - char *file_name; - char *stream_specs; /**< user-provided list of streams, separated by + */ - int stream_index; /**< for compatibility */ - int loop_count; - - AVFormatContext *format_ctx; - int eof; - AVPacket pkt, pkt0; - AVFrame *frame; ///< video frame to store the decoded images in - - int max_stream_index; /**< max stream # actually used for output */ - MovieStream *st; /**< array of all streams, one per output */ - int *out_index; /**< stream number -> output number map, or -1 */ -} MovieContext; - -#define OFFSET(x) offsetof(MovieContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption movie_options[]= { - { "filename", NULL, OFFSET(file_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "format_name", "set format name", OFFSET(format_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "f", "set format name", OFFSET(format_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "stream_index", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "si", "set stream index", OFFSET(stream_index), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "seek_point", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, (INT64_MAX-1) / 1000000, FLAGS }, - { "sp", "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, 0, (INT64_MAX-1) / 1000000, FLAGS }, - { "streams", "set streams", OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str = 0}, CHAR_MAX, CHAR_MAX, FLAGS }, - { "s", "set streams", OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str = 0}, CHAR_MAX, CHAR_MAX, FLAGS }, - { "loop", "set loop count", OFFSET(loop_count), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, FLAGS }, - { NULL }, -}; - -static int movie_config_output_props(AVFilterLink *outlink); -static int movie_request_frame(AVFilterLink *outlink); - -static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec) -{ - int i, ret, already = 0, stream_id = -1; - char type_char[2], dummy; - AVStream *found = NULL; - enum AVMediaType type; - - ret = sscanf(spec, "d%1[av]%d%c", type_char, &stream_id, &dummy); - if (ret >= 1 && ret <= 2) { - type = type_char[0] == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO; - ret = av_find_best_stream(avf, type, stream_id, -1, NULL, 0); - if (ret < 0) { - av_log(log, AV_LOG_ERROR, "No %s stream with index '%d' found\n", - av_get_media_type_string(type), stream_id); - return NULL; - } - return avf->streams[ret]; - } - for (i = 0; i < avf->nb_streams; i++) { - ret = avformat_match_stream_specifier(avf, avf->streams[i], spec); - if (ret < 0) { - av_log(log, AV_LOG_ERROR, - "Invalid stream specifier \"%s\"\n", spec); - return NULL; - } - if (!ret) - continue; - if (avf->streams[i]->discard != AVDISCARD_ALL) { - already++; - continue; - } - if (found) { - av_log(log, AV_LOG_WARNING, - "Ambiguous stream specifier \"%s\", using #%d\n", spec, i); - break; - } - found = avf->streams[i]; - } - if (!found) { - av_log(log, AV_LOG_WARNING, "Stream specifier \"%s\" %s\n", spec, - already ? "matched only already used streams" : - "did not match any stream"); - return NULL; - } - if (found->codec->codec_type != AVMEDIA_TYPE_VIDEO && - found->codec->codec_type != AVMEDIA_TYPE_AUDIO) { - av_log(log, AV_LOG_ERROR, "Stream specifier \"%s\" matched a %s stream," - "currently unsupported by libavfilter\n", spec, - av_get_media_type_string(found->codec->codec_type)); - return NULL; - } - return found; -} - -static int open_stream(void *log, MovieStream *st) -{ - AVCodec *codec; - int ret; - - codec = avcodec_find_decoder(st->st->codec->codec_id); - if (!codec) { - av_log(log, AV_LOG_ERROR, "Failed to find any codec\n"); - return AVERROR(EINVAL); - } - - st->st->codec->refcounted_frames = 1; - - if ((ret = avcodec_open2(st->st->codec, codec, NULL)) < 0) { - av_log(log, AV_LOG_ERROR, "Failed to open codec\n"); - return ret; - } - - return 0; -} - -static int guess_channel_layout(MovieStream *st, int st_index, void *log_ctx) -{ - AVCodecContext *dec_ctx = st->st->codec; - char buf[256]; - int64_t chl = av_get_default_channel_layout(dec_ctx->channels); - - if (!chl) { - av_log(log_ctx, AV_LOG_ERROR, - "Channel layout is not set in stream %d, and could not " - "be guessed from the number of channels (%d)\n", - st_index, dec_ctx->channels); - return AVERROR(EINVAL); - } - - av_get_channel_layout_string(buf, sizeof(buf), dec_ctx->channels, chl); - av_log(log_ctx, AV_LOG_WARNING, - "Channel layout is not set in output stream %d, " - "guessed channel layout is '%s'\n", - st_index, buf); - dec_ctx->channel_layout = chl; - return 0; -} - -static av_cold int movie_common_init(AVFilterContext *ctx) -{ - MovieContext *movie = ctx->priv; - AVInputFormat *iformat = NULL; - int64_t timestamp; - int nb_streams, ret, i; - char default_streams[16], *stream_specs, *spec, *cursor; - char name[16]; - AVStream *st; - - if (!movie->file_name) { - av_log(ctx, AV_LOG_ERROR, "No filename provided!\n"); - return AVERROR(EINVAL); - } - - movie->seek_point = movie->seek_point_d * 1000000 + 0.5; - - stream_specs = movie->stream_specs; - if (!stream_specs) { - snprintf(default_streams, sizeof(default_streams), "d%c%d", - !strcmp(ctx->filter->name, "amovie") ? 'a' : 'v', - movie->stream_index); - stream_specs = default_streams; - } - for (cursor = stream_specs, nb_streams = 1; *cursor; cursor++) - if (*cursor == '+') - nb_streams++; - - if (movie->loop_count != 1 && nb_streams != 1) { - av_log(ctx, AV_LOG_ERROR, - "Loop with several streams is currently unsupported\n"); - return AVERROR_PATCHWELCOME; - } - - av_register_all(); - - // Try to find the movie format (container) - iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL; - - movie->format_ctx = NULL; - if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) { - av_log(ctx, AV_LOG_ERROR, - "Failed to avformat_open_input '%s'\n", movie->file_name); - return ret; - } - if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0) - av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n"); - - // if seeking requested, we execute it - if (movie->seek_point > 0) { - timestamp = movie->seek_point; - // add the stream start time, should it exist - if (movie->format_ctx->start_time != AV_NOPTS_VALUE) { - if (timestamp > INT64_MAX - movie->format_ctx->start_time) { - av_log(ctx, AV_LOG_ERROR, - "%s: seek value overflow with start_time:%"PRId64" seek_point:%"PRId64"\n", - movie->file_name, movie->format_ctx->start_time, movie->seek_point); - return AVERROR(EINVAL); - } - timestamp += movie->format_ctx->start_time; - } - if ((ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD)) < 0) { - av_log(ctx, AV_LOG_ERROR, "%s: could not seek to position %"PRId64"\n", - movie->file_name, timestamp); - return ret; - } - } - - for (i = 0; i < movie->format_ctx->nb_streams; i++) - movie->format_ctx->streams[i]->discard = AVDISCARD_ALL; - - movie->st = av_calloc(nb_streams, sizeof(*movie->st)); - if (!movie->st) - return AVERROR(ENOMEM); - - for (i = 0; i < nb_streams; i++) { - spec = av_strtok(stream_specs, "+", &cursor); - if (!spec) - return AVERROR_BUG; - stream_specs = NULL; /* for next strtok */ - st = find_stream(ctx, movie->format_ctx, spec); - if (!st) - return AVERROR(EINVAL); - st->discard = AVDISCARD_DEFAULT; - movie->st[i].st = st; - movie->max_stream_index = FFMAX(movie->max_stream_index, st->index); - } - if (av_strtok(NULL, "+", &cursor)) - return AVERROR_BUG; - - movie->out_index = av_calloc(movie->max_stream_index + 1, - sizeof(*movie->out_index)); - if (!movie->out_index) - return AVERROR(ENOMEM); - for (i = 0; i <= movie->max_stream_index; i++) - movie->out_index[i] = -1; - for (i = 0; i < nb_streams; i++) - movie->out_index[movie->st[i].st->index] = i; - - for (i = 0; i < nb_streams; i++) { - AVFilterPad pad = { 0 }; - snprintf(name, sizeof(name), "out%d", i); - pad.type = movie->st[i].st->codec->codec_type; - pad.name = av_strdup(name); - pad.config_props = movie_config_output_props; - pad.request_frame = movie_request_frame; - ff_insert_outpad(ctx, i, &pad); - ret = open_stream(ctx, &movie->st[i]); - if (ret < 0) - return ret; - if ( movie->st[i].st->codec->codec->type == AVMEDIA_TYPE_AUDIO && - !movie->st[i].st->codec->channel_layout) { - ret = guess_channel_layout(&movie->st[i], i, ctx); - if (ret < 0) - return ret; - } - } - - av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n", - movie->seek_point, movie->format_name, movie->file_name, - movie->stream_index); - - return 0; -} - -static av_cold void movie_uninit(AVFilterContext *ctx) -{ - MovieContext *movie = ctx->priv; - int i; - - for (i = 0; i < ctx->nb_outputs; i++) { - av_freep(&ctx->output_pads[i].name); - if (movie->st[i].st) - avcodec_close(movie->st[i].st->codec); - } - av_freep(&movie->st); - av_freep(&movie->out_index); - av_frame_free(&movie->frame); - if (movie->format_ctx) - avformat_close_input(&movie->format_ctx); -} - -static int movie_query_formats(AVFilterContext *ctx) -{ - MovieContext *movie = ctx->priv; - int list[] = { 0, -1 }; - int64_t list64[] = { 0, -1 }; - int i; - - for (i = 0; i < ctx->nb_outputs; i++) { - MovieStream *st = &movie->st[i]; - AVCodecContext *c = st->st->codec; - AVFilterLink *outlink = ctx->outputs[i]; - - switch (c->codec_type) { - case AVMEDIA_TYPE_VIDEO: - list[0] = c->pix_fmt; - ff_formats_ref(ff_make_format_list(list), &outlink->in_formats); - break; - case AVMEDIA_TYPE_AUDIO: - list[0] = c->sample_fmt; - ff_formats_ref(ff_make_format_list(list), &outlink->in_formats); - list[0] = c->sample_rate; - ff_formats_ref(ff_make_format_list(list), &outlink->in_samplerates); - list64[0] = c->channel_layout; - ff_channel_layouts_ref(avfilter_make_format64_list(list64), - &outlink->in_channel_layouts); - break; - } - } - - return 0; -} - -static int movie_config_output_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - MovieContext *movie = ctx->priv; - unsigned out_id = FF_OUTLINK_IDX(outlink); - MovieStream *st = &movie->st[out_id]; - AVCodecContext *c = st->st->codec; - - outlink->time_base = st->st->time_base; - - switch (c->codec_type) { - case AVMEDIA_TYPE_VIDEO: - outlink->w = c->width; - outlink->h = c->height; - outlink->frame_rate = st->st->r_frame_rate; - break; - case AVMEDIA_TYPE_AUDIO: - break; - } - - return 0; -} - -static char *describe_frame_to_str(char *dst, size_t dst_size, - AVFrame *frame, - AVFilterLink *link) -{ - switch (frame->type) { - case AVMEDIA_TYPE_VIDEO: - snprintf(dst, dst_size, - "video pts:%s time:%s size:%dx%d aspect:%d/%d", - av_ts2str(frame->pts), av_ts2timestr(frame->pts, &link->time_base), - frame->width, frame->height, - frame->sample_aspect_ratio.num, - frame->sample_aspect_ratio.den); - break; - case AVMEDIA_TYPE_AUDIO: - snprintf(dst, dst_size, - "audio pts:%s time:%s samples:%d", - av_ts2str(frame->pts), av_ts2timestr(frame->pts, &link->time_base), - frame->nb_samples); - break; - default: - snprintf(dst, dst_size, "%s BUG", av_get_media_type_string(frame->type)); - break; - } - return dst; -} - -#define describe_frameref(f, link) \ - describe_frame_to_str((char[1024]){0}, 1024, f, link) - -static int rewind_file(AVFilterContext *ctx) -{ - MovieContext *movie = ctx->priv; - int64_t timestamp = movie->seek_point; - int ret, i; - - if (movie->format_ctx->start_time != AV_NOPTS_VALUE) - timestamp += movie->format_ctx->start_time; - ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Unable to loop: %s\n", av_err2str(ret)); - movie->loop_count = 1; /* do not try again */ - return ret; - } - - for (i = 0; i < ctx->nb_outputs; i++) { - avcodec_flush_buffers(movie->st[i].st->codec); - movie->st[i].done = 0; - } - movie->eof = 0; - return 0; -} - -/** - * Try to push a frame to the requested output. - * - * @param ctx filter context - * @param out_id number of output where a frame is wanted; - * if the frame is read from file, used to set the return value; - * if the codec is being flushed, flush the corresponding stream - * @return 1 if a frame was pushed on the requested output, - * 0 if another attempt is possible, - * <0 AVERROR code - */ -static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) -{ - MovieContext *movie = ctx->priv; - AVPacket *pkt = &movie->pkt; - MovieStream *st; - int ret, got_frame = 0, pkt_out_id; - AVFilterLink *outlink; - - if (!pkt->size) { - if (movie->eof) { - if (movie->st[out_id].done) { - if (movie->loop_count != 1) { - ret = rewind_file(ctx); - if (ret < 0) - return ret; - movie->loop_count -= movie->loop_count > 1; - av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n"); - return 0; /* retry */ - } - return AVERROR_EOF; - } - pkt->stream_index = movie->st[out_id].st->index; - /* packet is already ready for flushing */ - } else { - ret = av_read_frame(movie->format_ctx, &movie->pkt0); - if (ret < 0) { - av_init_packet(&movie->pkt0); /* ready for flushing */ - *pkt = movie->pkt0; - if (ret == AVERROR_EOF) { - movie->eof = 1; - return 0; /* start flushing */ - } - return ret; - } - *pkt = movie->pkt0; - } - } - - pkt_out_id = pkt->stream_index > movie->max_stream_index ? -1 : - movie->out_index[pkt->stream_index]; - if (pkt_out_id < 0) { - av_free_packet(&movie->pkt0); - pkt->size = 0; /* ready for next run */ - pkt->data = NULL; - return 0; - } - st = &movie->st[pkt_out_id]; - outlink = ctx->outputs[pkt_out_id]; - - movie->frame = av_frame_alloc(); - if (!movie->frame) - return AVERROR(ENOMEM); - - switch (st->st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_decode_video2(st->st->codec, movie->frame, &got_frame, pkt); - break; - case AVMEDIA_TYPE_AUDIO: - ret = avcodec_decode_audio4(st->st->codec, movie->frame, &got_frame, pkt); - break; - default: - ret = AVERROR(ENOSYS); - break; - } - if (ret < 0) { - av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret)); - av_frame_free(&movie->frame); - av_free_packet(&movie->pkt0); - movie->pkt.size = 0; - movie->pkt.data = NULL; - return 0; - } - if (!ret || st->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - ret = pkt->size; - - pkt->data += ret; - pkt->size -= ret; - if (pkt->size <= 0) { - av_free_packet(&movie->pkt0); - pkt->size = 0; /* ready for next run */ - pkt->data = NULL; - } - if (!got_frame) { - if (!ret) - st->done = 1; - av_frame_free(&movie->frame); - return 0; - } - - av_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name, - describe_frameref(movie->frame, outlink)); - - movie->frame->pts = av_frame_get_best_effort_timestamp(movie->frame); - ret = ff_filter_frame(outlink, movie->frame); - movie->frame = NULL; - - if (ret < 0) - return ret; - return pkt_out_id == out_id; -} - -static int movie_request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - unsigned out_id = FF_OUTLINK_IDX(outlink); - int ret; - - while (1) { - ret = movie_push_frame(ctx, out_id); - if (ret) - return FFMIN(ret, 0); - } -} - -#if CONFIG_MOVIE_FILTER - -AVFILTER_DEFINE_CLASS(movie); - -AVFilter ff_avsrc_movie = { - .name = "movie", - .description = NULL_IF_CONFIG_SMALL("Read from a movie source."), - .priv_size = sizeof(MovieContext), - .priv_class = &movie_class, - .init = movie_common_init, - .uninit = movie_uninit, - .query_formats = movie_query_formats, - - .inputs = NULL, - .outputs = NULL, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; - -#endif /* CONFIG_MOVIE_FILTER */ - -#if CONFIG_AMOVIE_FILTER - -#define amovie_options movie_options -AVFILTER_DEFINE_CLASS(amovie); - -AVFilter ff_avsrc_amovie = { - .name = "amovie", - .description = NULL_IF_CONFIG_SMALL("Read audio from a movie source."), - .priv_size = sizeof(MovieContext), - .init = movie_common_init, - .uninit = movie_uninit, - .query_formats = movie_query_formats, - - .inputs = NULL, - .outputs = NULL, - .priv_class = &amovie_class, - .flags = AVFILTER_FLAG_DYNAMIC_OUTPUTS, -}; - -#endif /* CONFIG_AMOVIE_FILTER */ diff --git a/ffmpeg/libavfilter/transform.c b/ffmpeg/libavfilter/transform.c deleted file mode 100644 index 3fc547e..0000000 --- a/ffmpeg/libavfilter/transform.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2010 Georg Martius <georg.martius@web.de> - * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * transform input video - */ - -#include "libavutil/common.h" -#include "libavutil/avassert.h" - -#include "transform.h" - -#define INTERPOLATE_METHOD(name) \ - static uint8_t name(float x, float y, const uint8_t *src, \ - int width, int height, int stride, uint8_t def) - -#define PIXEL(img, x, y, w, h, stride, def) \ - ((x) < 0 || (y) < 0) ? (def) : \ - (((x) >= (w) || (y) >= (h)) ? (def) : \ - img[(x) + (y) * (stride)]) - -/** - * Nearest neighbor interpolation - */ -INTERPOLATE_METHOD(interpolate_nearest) -{ - return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def); -} - -/** - * Bilinear interpolation - */ -INTERPOLATE_METHOD(interpolate_bilinear) -{ - int x_c, x_f, y_c, y_f; - int v1, v2, v3, v4; - - if (x < -1 || x > width || y < -1 || y > height) { - return def; - } else { - x_f = (int)x; - x_c = x_f + 1; - - y_f = (int)y; - y_c = y_f + 1; - - v1 = PIXEL(src, x_c, y_c, width, height, stride, def); - v2 = PIXEL(src, x_c, y_f, width, height, stride, def); - v3 = PIXEL(src, x_f, y_c, width, height, stride, def); - v4 = PIXEL(src, x_f, y_f, width, height, stride, def); - - return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) + - v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y))); - } -} - -/** - * Biquadratic interpolation - */ -INTERPOLATE_METHOD(interpolate_biquadratic) -{ - int x_c, x_f, y_c, y_f; - uint8_t v1, v2, v3, v4; - float f1, f2, f3, f4; - - if (x < - 1 || x > width || y < -1 || y > height) - return def; - else { - x_f = (int)x; - x_c = x_f + 1; - y_f = (int)y; - y_c = y_f + 1; - - v1 = PIXEL(src, x_c, y_c, width, height, stride, def); - v2 = PIXEL(src, x_c, y_f, width, height, stride, def); - v3 = PIXEL(src, x_f, y_c, width, height, stride, def); - v4 = PIXEL(src, x_f, y_f, width, height, stride, def); - - f1 = 1 - sqrt((x_c - x) * (y_c - y)); - f2 = 1 - sqrt((x_c - x) * (y - y_f)); - f3 = 1 - sqrt((x - x_f) * (y_c - y)); - f4 = 1 - sqrt((x - x_f) * (y - y_f)); - return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4); - } -} - -void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix) { - matrix[0] = zoom * cos(angle); - matrix[1] = -sin(angle); - matrix[2] = x_shift; - matrix[3] = -matrix[1]; - matrix[4] = matrix[0]; - matrix[5] = y_shift; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 1; -} - -void avfilter_add_matrix(const float *m1, const float *m2, float *result) -{ - int i; - for (i = 0; i < 9; i++) - result[i] = m1[i] + m2[i]; -} - -void avfilter_sub_matrix(const float *m1, const float *m2, float *result) -{ - int i; - for (i = 0; i < 9; i++) - result[i] = m1[i] - m2[i]; -} - -void avfilter_mul_matrix(const float *m1, float scalar, float *result) -{ - int i; - for (i = 0; i < 9; i++) - result[i] = m1[i] * scalar; -} - -static inline int mirror(int v, int m) -{ - while ((unsigned)v > (unsigned)m) { - v = -v; - if (v < 0) - v += 2 * m; - } - return v; -} - -int avfilter_transform(const uint8_t *src, uint8_t *dst, - int src_stride, int dst_stride, - int width, int height, const float *matrix, - enum InterpolateMethod interpolate, - enum FillMethod fill) -{ - int x, y; - float x_s, y_s; - uint8_t def = 0; - uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL; - - switch(interpolate) { - case INTERPOLATE_NEAREST: - func = interpolate_nearest; - break; - case INTERPOLATE_BILINEAR: - func = interpolate_bilinear; - break; - case INTERPOLATE_BIQUADRATIC: - func = interpolate_biquadratic; - break; - default: - return AVERROR(EINVAL); - } - - for (y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - x_s = x * matrix[0] + y * matrix[1] + matrix[2]; - y_s = x * matrix[3] + y * matrix[4] + matrix[5]; - - switch(fill) { - case FILL_ORIGINAL: - def = src[y * src_stride + x]; - break; - case FILL_CLAMP: - y_s = av_clipf(y_s, 0, height - 1); - x_s = av_clipf(x_s, 0, width - 1); - def = src[(int)y_s * src_stride + (int)x_s]; - break; - case FILL_MIRROR: - x_s = mirror(x_s, width-1); - y_s = mirror(y_s, height-1); - - av_assert2(x_s >= 0 && y_s >= 0); - av_assert2(x_s < width && y_s < height); - def = src[(int)y_s * src_stride + (int)x_s]; - } - - dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def); - } - } - return 0; -} diff --git a/ffmpeg/libavfilter/transform.h b/ffmpeg/libavfilter/transform.h deleted file mode 100644 index 07436bf..0000000 --- a/ffmpeg/libavfilter/transform.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2010 Georg Martius <georg.martius@web.de> - * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_TRANSFORM_H -#define AVFILTER_TRANSFORM_H - -#include <stdint.h> - -/** - * @file - * transform input video - * - * All matrices are defined as a single 9-item block of contiguous memory. For - * example, the identity matrix would be: - * - * float *matrix = {1, 0, 0, - * 0, 1, 0, - * 0, 0, 1}; - */ - -enum InterpolateMethod { - INTERPOLATE_NEAREST, //< Nearest-neighbor (fast) - INTERPOLATE_BILINEAR, //< Bilinear - INTERPOLATE_BIQUADRATIC, //< Biquadratic (best) - INTERPOLATE_COUNT, //< Number of interpolation methods -}; - -// Shortcuts for the fastest and best interpolation methods -#define INTERPOLATE_DEFAULT INTERPOLATE_BILINEAR -#define INTERPOLATE_FAST INTERPOLATE_NEAREST -#define INTERPOLATE_BEST INTERPOLATE_BIQUADRATIC - -enum FillMethod { - FILL_BLANK, //< Fill zeroes at blank locations - FILL_ORIGINAL, //< Original image at blank locations - FILL_CLAMP, //< Extruded edge value at blank locations - FILL_MIRROR, //< Mirrored edge at blank locations - FILL_COUNT, //< Number of edge fill methods -}; - -// Shortcuts for fill methods -#define FILL_DEFAULT FILL_ORIGINAL - -/** - * Get an affine transformation matrix from a given translation, rotation, and - * zoom factor. The matrix will look like: - * - * [ zoom * cos(angle), -sin(angle), x_shift, - * sin(angle), zoom * cos(angle), y_shift, - * 0, 0, 1 ] - * - * @param x_shift horizontal translation - * @param y_shift vertical translation - * @param angle rotation in radians - * @param zoom scale percent (1.0 = 100%) - * @param matrix 9-item affine transformation matrix - */ -void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix); - -/** - * Add two matrices together. result = m1 + m2. - * - * @param m1 9-item transformation matrix - * @param m2 9-item transformation matrix - * @param result 9-item transformation matrix - */ -void avfilter_add_matrix(const float *m1, const float *m2, float *result); - -/** - * Subtract one matrix from another. result = m1 - m2. - * - * @param m1 9-item transformation matrix - * @param m2 9-item transformation matrix - * @param result 9-item transformation matrix - */ -void avfilter_sub_matrix(const float *m1, const float *m2, float *result); - -/** - * Multiply a matrix by a scalar value. result = m1 * scalar. - * - * @param m1 9-item transformation matrix - * @param scalar a number - * @param result 9-item transformation matrix - */ -void avfilter_mul_matrix(const float *m1, float scalar, float *result); - -/** - * Do an affine transformation with the given interpolation method. This - * multiplies each vector [x,y,1] by the matrix and then interpolates to - * get the final value. - * - * @param src source image - * @param dst destination image - * @param src_stride source image line size in bytes - * @param dst_stride destination image line size in bytes - * @param width image width in pixels - * @param height image height in pixels - * @param matrix 9-item affine transformation matrix - * @param interpolate pixel interpolation method - * @param fill edge fill method - * @return negative on error - */ -int avfilter_transform(const uint8_t *src, uint8_t *dst, - int src_stride, int dst_stride, - int width, int height, const float *matrix, - enum InterpolateMethod interpolate, - enum FillMethod fill); - -#endif /* AVFILTER_TRANSFORM_H */ diff --git a/ffmpeg/libavfilter/version.h b/ffmpeg/libavfilter/version.h deleted file mode 100644 index ff5b604..0000000 --- a/ffmpeg/libavfilter/version.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Version macros. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_VERSION_H -#define AVFILTER_VERSION_H - -/** - * @file - * @ingroup lavfi - * Libavfilter version macros - */ - -#include "libavutil/version.h" - -#define LIBAVFILTER_VERSION_MAJOR 4 -#define LIBAVFILTER_VERSION_MINOR 0 -#define LIBAVFILTER_VERSION_MICRO 103 - -#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_VERSION AV_VERSION(LIBAVFILTER_VERSION_MAJOR, \ - LIBAVFILTER_VERSION_MINOR, \ - LIBAVFILTER_VERSION_MICRO) -#define LIBAVFILTER_BUILD LIBAVFILTER_VERSION_INT - -#define LIBAVFILTER_IDENT "Lavfi" AV_STRINGIFY(LIBAVFILTER_VERSION) - -/** - * FF_API_* defines may be placed below to indicate public API that will be - * dropped at a future version bump. The defines themselves are not part of - * the public API and may change, break or disappear at any time. - */ - -#ifndef FF_API_AVFILTERPAD_PUBLIC -#define FF_API_AVFILTERPAD_PUBLIC (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_FOO_COUNT -#define FF_API_FOO_COUNT (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_FILL_FRAME -#define FF_API_FILL_FRAME (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_BUFFERSRC_BUFFER -#define FF_API_BUFFERSRC_BUFFER (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_AVFILTERBUFFER -#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_OLD_FILTER_OPTS -#define FF_API_OLD_FILTER_OPTS (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_ACONVERT_FILTER -#define FF_API_ACONVERT_FILTER (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_AVFILTER_OPEN -#define FF_API_AVFILTER_OPEN (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_AVFILTER_INIT_FILTER -#define FF_API_AVFILTER_INIT_FILTER (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_OLD_FILTER_REGISTER -#define FF_API_OLD_FILTER_REGISTER (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_OLD_GRAPH_PARSE -#define FF_API_OLD_GRAPH_PARSE (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_DRAWTEXT_OLD_TIMELINE -#define FF_API_DRAWTEXT_OLD_TIMELINE (LIBAVFILTER_VERSION_MAJOR < 5) -#endif -#ifndef FF_API_NOCONST_GET_NAME -#define FF_API_NOCONST_GET_NAME (LIBAVFILTER_VERSION_MAJOR < 5) -#endif - -#endif /* AVFILTER_VERSION_H */ diff --git a/ffmpeg/libavfilter/vf_alphamerge.c b/ffmpeg/libavfilter/vf_alphamerge.c deleted file mode 100644 index 5f0da35..0000000 --- a/ffmpeg/libavfilter/vf_alphamerge.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2012 Steven Robertson - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * copy an alpha component from another video's luma - */ - -#include <string.h> - -#include "libavutil/pixfmt.h" -#include "avfilter.h" -#include "bufferqueue.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -enum { Y, U, V, A }; - -typedef struct { - int frame_requested; - int is_packed_rgb; - uint8_t rgba_map[4]; - struct FFBufQueue queue_main; - struct FFBufQueue queue_alpha; -} AlphaMergeContext; - -static av_cold void uninit(AVFilterContext *ctx) -{ - AlphaMergeContext *merge = ctx->priv; - ff_bufqueue_discard_all(&merge->queue_main); - ff_bufqueue_discard_all(&merge->queue_alpha); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat main_fmts[] = { - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat alpha_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; - AVFilterFormats *main_formats = ff_make_format_list(main_fmts); - AVFilterFormats *alpha_formats = ff_make_format_list(alpha_fmts); - ff_formats_ref(main_formats, &ctx->inputs[0]->out_formats); - ff_formats_ref(alpha_formats, &ctx->inputs[1]->out_formats); - ff_formats_ref(main_formats, &ctx->outputs[0]->in_formats); - return 0; -} - -static int config_input_main(AVFilterLink *inlink) -{ - AlphaMergeContext *merge = inlink->dst->priv; - merge->is_packed_rgb = - ff_fill_rgba_map(merge->rgba_map, inlink->format) >= 0; - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *mainlink = ctx->inputs[0]; - AVFilterLink *alphalink = ctx->inputs[1]; - if (mainlink->w != alphalink->w || mainlink->h != alphalink->h) { - av_log(ctx, AV_LOG_ERROR, - "Input frame sizes do not match (%dx%d vs %dx%d).\n", - mainlink->w, mainlink->h, - alphalink->w, alphalink->h); - return AVERROR(EINVAL); - } - - outlink->w = mainlink->w; - outlink->h = mainlink->h; - outlink->time_base = mainlink->time_base; - outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio; - outlink->frame_rate = mainlink->frame_rate; - return 0; -} - -static void draw_frame(AVFilterContext *ctx, - AVFrame *main_buf, - AVFrame *alpha_buf) -{ - AlphaMergeContext *merge = ctx->priv; - int h = main_buf->height; - - if (merge->is_packed_rgb) { - int x, y; - uint8_t *pin, *pout; - for (y = 0; y < h; y++) { - pin = alpha_buf->data[0] + y * alpha_buf->linesize[0]; - pout = main_buf->data[0] + y * main_buf->linesize[0] + merge->rgba_map[A]; - for (x = 0; x < main_buf->width; x++) { - *pout = *pin; - pin += 1; - pout += 4; - } - } - } else { - int y; - const int main_linesize = main_buf->linesize[A]; - const int alpha_linesize = alpha_buf->linesize[Y]; - for (y = 0; y < h && y < alpha_buf->height; y++) { - memcpy(main_buf->data[A] + y * main_linesize, - alpha_buf->data[Y] + y * alpha_linesize, - FFMIN(main_linesize, alpha_linesize)); - } - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - AlphaMergeContext *merge = ctx->priv; - - int ret = 0; - int is_alpha = (inlink == ctx->inputs[1]); - struct FFBufQueue *queue = - (is_alpha ? &merge->queue_alpha : &merge->queue_main); - ff_bufqueue_add(ctx, queue, buf); - - do { - AVFrame *main_buf, *alpha_buf; - - if (!ff_bufqueue_peek(&merge->queue_main, 0) || - !ff_bufqueue_peek(&merge->queue_alpha, 0)) break; - - main_buf = ff_bufqueue_get(&merge->queue_main); - alpha_buf = ff_bufqueue_get(&merge->queue_alpha); - - merge->frame_requested = 0; - draw_frame(ctx, main_buf, alpha_buf); - ret = ff_filter_frame(ctx->outputs[0], main_buf); - av_frame_free(&alpha_buf); - } while (ret >= 0); - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AlphaMergeContext *merge = ctx->priv; - int in, ret; - - merge->frame_requested = 1; - while (merge->frame_requested) { - in = ff_bufqueue_peek(&merge->queue_main, 0) ? 1 : 0; - ret = ff_request_frame(ctx->inputs[in]); - if (ret < 0) - return ret; - } - return 0; -} - -static const AVFilterPad alphamerge_inputs[] = { - { - .name = "main", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input_main, - .filter_frame = filter_frame, - .needs_writable = 1, - },{ - .name = "alpha", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad alphamerge_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_alphamerge = { - .name = "alphamerge", - .description = NULL_IF_CONFIG_SMALL("Copy the luma value of the second " - "input into the alpha channel of the first input."), - .uninit = uninit, - .priv_size = sizeof(AlphaMergeContext), - .query_formats = query_formats, - .inputs = alphamerge_inputs, - .outputs = alphamerge_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_aspect.c b/ffmpeg/libavfilter/vf_aspect.c deleted file mode 100644 index 97fb216..0000000 --- a/ffmpeg/libavfilter/vf_aspect.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2010 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * aspect ratio modification video filters - */ - -#include <float.h> - -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" - -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { - "w", - "h", - "a", "dar", - "sar", - "hsub", - "vsub", - NULL -}; - -enum var_name { - VAR_W, - VAR_H, - VAR_A, VAR_DAR, - VAR_SAR, - VAR_HSUB, - VAR_VSUB, - VARS_NB -}; - -typedef struct { - const AVClass *class; - AVRational dar; - AVRational sar; - int max; -#if FF_API_OLD_FILTER_OPTS - float aspect_den; -#endif - char *ratio_expr; -} AspectContext; - -static av_cold int init(AVFilterContext *ctx) -{ - AspectContext *s = ctx->priv; - int ret; - -#if FF_API_OLD_FILTER_OPTS - if (s->ratio_expr && s->aspect_den > 0) { - double num; - av_log(ctx, AV_LOG_WARNING, - "num:den syntax is deprecated, please use num/den or named options instead\n"); - ret = av_expr_parse_and_eval(&num, s->ratio_expr, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Unable to parse ratio numerator \"%s\"\n", s->ratio_expr); - return AVERROR(EINVAL); - } - s->sar = s->dar = av_d2q(num / s->aspect_den, s->max); - } -#endif - - return 0; -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AspectContext *s = link->dst->priv; - - frame->sample_aspect_ratio = s->sar; - return ff_filter_frame(link->dst->outputs[0], frame); -} - -#define OFFSET(x) offsetof(AspectContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static inline void compute_dar(AVRational *dar, AVRational sar, int w, int h) -{ - if (sar.num && sar.den) { - av_reduce(&dar->num, &dar->den, sar.num * w, sar.den * h, INT_MAX); - } else { - av_reduce(&dar->num, &dar->den, w, h, INT_MAX); - } -} - -static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio) -{ - AVFilterContext *ctx = inlink->dst; - AspectContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - double var_values[VARS_NB], res; - int ret; - - var_values[VAR_W] = inlink->w; - var_values[VAR_H] = inlink->h; - var_values[VAR_A] = (double) inlink->w / inlink->h; - var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; - var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; - var_values[VAR_HSUB] = 1 << desc->log2_chroma_w; - var_values[VAR_VSUB] = 1 << desc->log2_chroma_h; - - /* evaluate new aspect ratio*/ - ret = av_expr_parse_and_eval(&res, s->ratio_expr, - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) { - ret = av_parse_ratio(aspect_ratio, s->ratio_expr, s->max, 0, ctx); - } else - *aspect_ratio = av_d2q(res, s->max); - - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s'\n", s->ratio_expr); - return ret; - } - if (aspect_ratio->num < 0 || aspect_ratio->den <= 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid string '%s' for aspect ratio\n", s->ratio_expr); - return AVERROR(EINVAL); - } - return 0; -} - -#if CONFIG_SETDAR_FILTER - -static int setdar_config_props(AVFilterLink *inlink) -{ - AspectContext *s = inlink->dst->priv; - AVRational dar; - AVRational old_dar; - AVRational old_sar = inlink->sample_aspect_ratio; - int ret; - -#if FF_API_OLD_FILTER_OPTS - if (!(s->ratio_expr && s->aspect_den > 0)) { -#endif - if ((ret = get_aspect_ratio(inlink, &s->dar))) - return ret; -#if FF_API_OLD_FILTER_OPTS - } -#endif - - if (s->dar.num && s->dar.den) { - av_reduce(&s->sar.num, &s->sar.den, - s->dar.num * inlink->h, - s->dar.den * inlink->w, INT_MAX); - inlink->sample_aspect_ratio = s->sar; - dar = s->dar; - } else { - inlink->sample_aspect_ratio = (AVRational){ 1, 1 }; - dar = (AVRational){ inlink->w, inlink->h }; - } - - compute_dar(&old_dar, old_sar, inlink->w, inlink->h); - av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d dar:%d/%d sar:%d/%d -> dar:%d/%d sar:%d/%d\n", - inlink->w, inlink->h, old_dar.num, old_dar.den, old_sar.num, old_sar.den, - dar.num, dar.den, inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den); - - return 0; -} - -static const AVOption setdar_options[] = { - { "dar", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, - { "ratio", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, - { "r", "set display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, -#if FF_API_OLD_FILTER_OPTS - { "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, -#endif - { "max", "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(setdar); - -static const AVFilterPad avfilter_vf_setdar_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = setdar_config_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_setdar_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_setdar = { - .name = "setdar", - .description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."), - .init = init, - .priv_size = sizeof(AspectContext), - .priv_class = &setdar_class, - .inputs = avfilter_vf_setdar_inputs, - .outputs = avfilter_vf_setdar_outputs, -}; - -#endif /* CONFIG_SETDAR_FILTER */ - -#if CONFIG_SETSAR_FILTER - -static int setsar_config_props(AVFilterLink *inlink) -{ - AspectContext *s = inlink->dst->priv; - AVRational old_sar = inlink->sample_aspect_ratio; - AVRational old_dar, dar; - int ret; - -#if FF_API_OLD_FILTER_OPTS - if (!(s->ratio_expr && s->aspect_den > 0)) { -#endif - if ((ret = get_aspect_ratio(inlink, &s->sar))) - return ret; -#if FF_API_OLD_FILTER_OPTS - } -#endif - - inlink->sample_aspect_ratio = s->sar; - - compute_dar(&old_dar, old_sar, inlink->w, inlink->h); - compute_dar(&dar, s->sar, inlink->w, inlink->h); - av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d dar:%d/%d -> sar:%d/%d dar:%d/%d\n", - inlink->w, inlink->h, old_sar.num, old_sar.den, old_dar.num, old_dar.den, - inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, dar.num, dar.den); - - return 0; -} - -static const AVOption setsar_options[] = { - { "sar", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, - { "ratio", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, - { "r", "set sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS }, -#if FF_API_OLD_FILTER_OPTS - { "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS }, -#endif - { "max", "set max value for nominator or denominator in the ratio", OFFSET(max), AV_OPT_TYPE_INT, {.i64=100}, 1, INT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(setsar); - -static const AVFilterPad avfilter_vf_setsar_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = setsar_config_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_setsar_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_setsar = { - .name = "setsar", - .description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."), - .init = init, - .priv_size = sizeof(AspectContext), - .priv_class = &setsar_class, - .inputs = avfilter_vf_setsar_inputs, - .outputs = avfilter_vf_setsar_outputs, -}; - -#endif /* CONFIG_SETSAR_FILTER */ diff --git a/ffmpeg/libavfilter/vf_bbox.c b/ffmpeg/libavfilter/vf_bbox.c deleted file mode 100644 index 6c6aab1..0000000 --- a/ffmpeg/libavfilter/vf_bbox.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bounding box detection filter - */ - -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/timestamp.h" -#include "avfilter.h" -#include "bbox.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int min_val; -} BBoxContext; - -#define OFFSET(x) offsetof(BBoxContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption bbox_options[] = { - { "min_val", "set minimum luminance value for bounding box", OFFSET(min_val), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 254, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(bbox); - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_NONE, - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -#define SET_META(key, value) \ - snprintf(buf, sizeof(buf), "%d", value); \ - av_dict_set(metadata, key, buf, 0); - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - BBoxContext *bbox = ctx->priv; - FFBoundingBox box; - int has_bbox, w, h; - char buf[32]; - - has_bbox = - ff_calculate_bounding_box(&box, - frame->data[0], frame->linesize[0], - inlink->w, inlink->h, bbox->min_val); - w = box.x2 - box.x1 + 1; - h = box.y2 - box.y1 + 1; - - av_log(ctx, AV_LOG_INFO, - "n:%"PRId64" pts:%s pts_time:%s", inlink->frame_count, - av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base)); - - if (has_bbox) { - AVDictionary **metadata = avpriv_frame_get_metadatap(frame); - - SET_META("lavfi.bbox.x1", box.x1) - SET_META("lavfi.bbox.x2", box.x2) - SET_META("lavfi.bbox.y1", box.y1) - SET_META("lavfi.bbox.y2", box.y2) - SET_META("lavfi.bbox.w", w) - SET_META("lavfi.bbox.h", h) - - av_log(ctx, AV_LOG_INFO, - " x1:%d x2:%d y1:%d y2:%d w:%d h:%d" - " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d", - box.x1, box.x2, box.y1, box.y2, w, h, - w, h, box.x1, box.y1, /* crop params */ - box.x1, box.y1, w, h); /* drawbox params */ - } - av_log(ctx, AV_LOG_INFO, "\n"); - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -static const AVFilterPad bbox_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad bbox_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_bbox = { - .name = "bbox", - .description = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."), - .priv_size = sizeof(BBoxContext), - .priv_class = &bbox_class, - .query_formats = query_formats, - .inputs = bbox_inputs, - .outputs = bbox_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_blackdetect.c b/ffmpeg/libavfilter/vf_blackdetect.c deleted file mode 100644 index 90a28a9..0000000 --- a/ffmpeg/libavfilter/vf_blackdetect.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Video black detector, loosely based on blackframe with extended - * syntax and features - */ - -#include <float.h> -#include "libavutil/opt.h" -#include "libavutil/timestamp.h" -#include "avfilter.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - double black_min_duration_time; ///< minimum duration of detected black, in seconds - int64_t black_min_duration; ///< minimum duration of detected black, expressed in timebase units - int64_t black_start; ///< pts start time of the first black picture - int64_t black_end; ///< pts end time of the last black picture - int64_t last_picref_pts; ///< pts of the last input picture - int black_started; - - double picture_black_ratio_th; - double pixel_black_th; - unsigned int pixel_black_th_i; - - unsigned int nb_black_pixels; ///< number of black pixels counted so far -} BlackDetectContext; - -#define OFFSET(x) offsetof(BlackDetectContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption blackdetect_options[] = { - { "d", "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS }, - { "black_min_duration", "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS }, - { "picture_black_ratio_th", "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS }, - { "pic_th", "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS }, - { "pixel_black_th", "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS }, - { "pix_th", "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(blackdetect); - -#define YUVJ_FORMATS \ - AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P - -static enum AVPixelFormat yuvj_formats[] = { - YUVJ_FORMATS, AV_PIX_FMT_NONE -}; - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, - YUVJ_FORMATS, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - BlackDetectContext *blackdetect = ctx->priv; - - blackdetect->black_min_duration = - blackdetect->black_min_duration_time / av_q2d(inlink->time_base); - - blackdetect->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ? - // luminance_minimum_value + pixel_black_th * luminance_range_size - blackdetect->pixel_black_th * 255 : - 16 + blackdetect->pixel_black_th * (235 - 16); - - av_log(blackdetect, AV_LOG_VERBOSE, - "black_min_duration:%s pixel_black_th:%f pixel_black_th_i:%d picture_black_ratio_th:%f\n", - av_ts2timestr(blackdetect->black_min_duration, &inlink->time_base), - blackdetect->pixel_black_th, blackdetect->pixel_black_th_i, - blackdetect->picture_black_ratio_th); - return 0; -} - -static void check_black_end(AVFilterContext *ctx) -{ - BlackDetectContext *blackdetect = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - if ((blackdetect->black_end - blackdetect->black_start) >= blackdetect->black_min_duration) { - av_log(blackdetect, AV_LOG_INFO, - "black_start:%s black_end:%s black_duration:%s\n", - av_ts2timestr(blackdetect->black_start, &inlink->time_base), - av_ts2timestr(blackdetect->black_end, &inlink->time_base), - av_ts2timestr(blackdetect->black_end - blackdetect->black_start, &inlink->time_base)); - } -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - BlackDetectContext *blackdetect = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - int ret = ff_request_frame(inlink); - - if (ret == AVERROR_EOF && blackdetect->black_started) { - // FIXME: black_end should be set to last_picref_pts + last_picref_duration - blackdetect->black_end = blackdetect->last_picref_pts; - check_black_end(ctx); - } - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *picref) -{ - AVFilterContext *ctx = inlink->dst; - BlackDetectContext *blackdetect = ctx->priv; - double picture_black_ratio = 0; - const uint8_t *p = picref->data[0]; - int x, i; - - for (i = 0; i < inlink->h; i++) { - for (x = 0; x < inlink->w; x++) - blackdetect->nb_black_pixels += p[x] <= blackdetect->pixel_black_th_i; - p += picref->linesize[0]; - } - - picture_black_ratio = (double)blackdetect->nb_black_pixels / (inlink->w * inlink->h); - - av_log(ctx, AV_LOG_DEBUG, - "frame:%"PRId64" picture_black_ratio:%f pts:%s t:%s type:%c\n", - inlink->frame_count, picture_black_ratio, - av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base), - av_get_picture_type_char(picref->pict_type)); - - if (picture_black_ratio >= blackdetect->picture_black_ratio_th) { - if (!blackdetect->black_started) { - /* black starts here */ - blackdetect->black_started = 1; - blackdetect->black_start = picref->pts; - } - } else if (blackdetect->black_started) { - /* black ends here */ - blackdetect->black_started = 0; - blackdetect->black_end = picref->pts; - check_black_end(ctx); - } - - blackdetect->last_picref_pts = picref->pts; - blackdetect->nb_black_pixels = 0; - return ff_filter_frame(inlink->dst->outputs[0], picref); -} - -static const AVFilterPad blackdetect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad blackdetect_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_blackdetect = { - .name = "blackdetect", - .description = NULL_IF_CONFIG_SMALL("Detect video intervals that are (almost) black."), - .priv_size = sizeof(BlackDetectContext), - .query_formats = query_formats, - .inputs = blackdetect_inputs, - .outputs = blackdetect_outputs, - .priv_class = &blackdetect_class, -}; diff --git a/ffmpeg/libavfilter/vf_blackframe.c b/ffmpeg/libavfilter/vf_blackframe.c deleted file mode 100644 index 9b0c973..0000000 --- a/ffmpeg/libavfilter/vf_blackframe.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * Copyright (c) 2006 Ivo van Poorten - * Copyright (c) 2006 Julian Hall - * Copyright (c) 2002-2003 Brian J. Murrell - * - * 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 - * Search for black frames to detect scene transitions. - * Ported from MPlayer libmpcodecs/vf_blackframe.c. - */ - -#include <stdio.h> -#include <inttypes.h> - -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int bamount; ///< black amount - int bthresh; ///< black threshold - unsigned int frame; ///< frame number - unsigned int nblack; ///< number of black pixels counted so far - unsigned int last_keyframe; ///< frame number of the last received key-frame -} BlackFrameContext; - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12, - AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - BlackFrameContext *s = ctx->priv; - int x, i; - int pblack = 0; - uint8_t *p = frame->data[0]; - - for (i = 0; i < frame->height; i++) { - for (x = 0; x < inlink->w; x++) - s->nblack += p[x] < s->bthresh; - p += frame->linesize[0]; - } - - if (frame->key_frame) - s->last_keyframe = s->frame; - - pblack = s->nblack * 100 / (inlink->w * inlink->h); - if (pblack >= s->bamount) - av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pts:%"PRId64" t:%f " - "type:%c last_keyframe:%d\n", - s->frame, pblack, frame->pts, - frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base), - av_get_picture_type_char(frame->pict_type), s->last_keyframe); - - s->frame++; - s->nblack = 0; - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -#define OFFSET(x) offsetof(BlackFrameContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption blackframe_options[] = { - { "amount", "Percentage of the pixels that have to be below the threshold " - "for the frame to be considered black.", OFFSET(bamount), AV_OPT_TYPE_INT, { .i64 = 98 }, 0, 100, FLAGS }, - { "threshold", "threshold below which a pixel value is considered black", - OFFSET(bthresh), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 255, FLAGS }, - { "thresh", "threshold below which a pixel value is considered black", - OFFSET(bthresh), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 255, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(blackframe); - -static const AVFilterPad avfilter_vf_blackframe_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_blackframe_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_blackframe = { - .name = "blackframe", - .description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."), - .priv_size = sizeof(BlackFrameContext), - .priv_class = &blackframe_class, - .query_formats = query_formats, - .inputs = avfilter_vf_blackframe_inputs, - .outputs = avfilter_vf_blackframe_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_blend.c b/ffmpeg/libavfilter/vf_blend.c deleted file mode 100644 index d422a9c..0000000 --- a/ffmpeg/libavfilter/vf_blend.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2013 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/imgutils.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/pixfmt.h" -#include "avfilter.h" -#include "bufferqueue.h" -#include "formats.h" -#include "internal.h" -#include "dualinput.h" -#include "video.h" - -#define TOP 0 -#define BOTTOM 1 - -enum BlendMode { - BLEND_UNSET = -1, - BLEND_NORMAL, - BLEND_ADDITION, - BLEND_AND, - BLEND_AVERAGE, - BLEND_BURN, - BLEND_DARKEN, - BLEND_DIFFERENCE, - BLEND_DIVIDE, - BLEND_DODGE, - BLEND_EXCLUSION, - BLEND_HARDLIGHT, - BLEND_LIGHTEN, - BLEND_MULTIPLY, - BLEND_NEGATION, - BLEND_OR, - BLEND_OVERLAY, - BLEND_PHOENIX, - BLEND_PINLIGHT, - BLEND_REFLECT, - BLEND_SCREEN, - BLEND_SOFTLIGHT, - BLEND_SUBTRACT, - BLEND_VIVIDLIGHT, - BLEND_XOR, - BLEND_NB -}; - -static const char *const var_names[] = { "X", "Y", "W", "H", "SW", "SH", "T", "N", "A", "B", "TOP", "BOTTOM", NULL }; -enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_SW, VAR_SH, VAR_T, VAR_N, VAR_A, VAR_B, VAR_TOP, VAR_BOTTOM, VAR_VARS_NB }; - -typedef struct FilterParams { - enum BlendMode mode; - double opacity; - AVExpr *e; - char *expr_str; - void (*blend)(const uint8_t *top, int top_linesize, - const uint8_t *bottom, int bottom_linesize, - uint8_t *dst, int dst_linesize, - int width, int start, int end, - struct FilterParams *param, double *values); -} FilterParams; - -typedef struct ThreadData { - const AVFrame *top, *bottom; - AVFrame *dst; - AVFilterLink *inlink; - int plane; - int w, h; - FilterParams *param; -} ThreadData; - -typedef struct { - const AVClass *class; - FFDualInputContext dinput; - int hsub, vsub; ///< chroma subsampling values - int nb_planes; - char *all_expr; - enum BlendMode all_mode; - double all_opacity; - - FilterParams params[4]; -} BlendContext; - -#define OFFSET(x) offsetof(BlendContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption blend_options[] = { - { "c0_mode", "set component #0 blend mode", OFFSET(params[0].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"}, - { "c1_mode", "set component #1 blend mode", OFFSET(params[1].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"}, - { "c2_mode", "set component #2 blend mode", OFFSET(params[2].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"}, - { "c3_mode", "set component #3 blend mode", OFFSET(params[3].mode), AV_OPT_TYPE_INT, {.i64=0}, 0, BLEND_NB-1, FLAGS, "mode"}, - { "all_mode", "set blend mode for all components", OFFSET(all_mode), AV_OPT_TYPE_INT, {.i64=-1},-1, BLEND_NB-1, FLAGS, "mode"}, - { "addition", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_ADDITION}, 0, 0, FLAGS, "mode" }, - { "and", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AND}, 0, 0, FLAGS, "mode" }, - { "average", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_AVERAGE}, 0, 0, FLAGS, "mode" }, - { "burn", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_BURN}, 0, 0, FLAGS, "mode" }, - { "darken", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DARKEN}, 0, 0, FLAGS, "mode" }, - { "difference", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIFFERENCE}, 0, 0, FLAGS, "mode" }, - { "divide", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DIVIDE}, 0, 0, FLAGS, "mode" }, - { "dodge", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_DODGE}, 0, 0, FLAGS, "mode" }, - { "exclusion", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_EXCLUSION}, 0, 0, FLAGS, "mode" }, - { "hardlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_HARDLIGHT}, 0, 0, FLAGS, "mode" }, - { "lighten", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_LIGHTEN}, 0, 0, FLAGS, "mode" }, - { "multiply", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_MULTIPLY}, 0, 0, FLAGS, "mode" }, - { "negation", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NEGATION}, 0, 0, FLAGS, "mode" }, - { "normal", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_NORMAL}, 0, 0, FLAGS, "mode" }, - { "or", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OR}, 0, 0, FLAGS, "mode" }, - { "overlay", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_OVERLAY}, 0, 0, FLAGS, "mode" }, - { "phoenix", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PHOENIX}, 0, 0, FLAGS, "mode" }, - { "pinlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_PINLIGHT}, 0, 0, FLAGS, "mode" }, - { "reflect", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_REFLECT}, 0, 0, FLAGS, "mode" }, - { "screen", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SCREEN}, 0, 0, FLAGS, "mode" }, - { "softlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SOFTLIGHT}, 0, 0, FLAGS, "mode" }, - { "subtract", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_SUBTRACT}, 0, 0, FLAGS, "mode" }, - { "vividlight", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_VIVIDLIGHT}, 0, 0, FLAGS, "mode" }, - { "xor", "", 0, AV_OPT_TYPE_CONST, {.i64=BLEND_XOR}, 0, 0, FLAGS, "mode" }, - { "c0_expr", "set color component #0 expression", OFFSET(params[0].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c1_expr", "set color component #1 expression", OFFSET(params[1].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c2_expr", "set color component #2 expression", OFFSET(params[2].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c3_expr", "set color component #3 expression", OFFSET(params[3].expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "all_expr", "set expression for all color components", OFFSET(all_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c0_opacity", "set color component #0 opacity", OFFSET(params[0].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, - { "c1_opacity", "set color component #1 opacity", OFFSET(params[1].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, - { "c2_opacity", "set color component #2 opacity", OFFSET(params[2].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, - { "c3_opacity", "set color component #3 opacity", OFFSET(params[3].opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS }, - { "all_opacity", "set opacity for all color components", OFFSET(all_opacity), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS}, - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "repeatlast", "repeat last bottom frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(blend); - -static void blend_normal(const uint8_t *top, int top_linesize, - const uint8_t *bottom, int bottom_linesize, - uint8_t *dst, int dst_linesize, - int width, int start, int end, - FilterParams *param, double *values) -{ - av_image_copy_plane(dst, dst_linesize, top, top_linesize, width, end - start); -} - -#define DEFINE_BLEND(name, expr) \ -static void blend_## name(const uint8_t *top, int top_linesize, \ - const uint8_t *bottom, int bottom_linesize, \ - uint8_t *dst, int dst_linesize, \ - int width, int start, int end, \ - FilterParams *param, double *values) \ -{ \ - double opacity = param->opacity; \ - int i, j; \ - \ - for (i = start; i < end; i++) { \ - for (j = 0; j < width; j++) { \ - dst[j] = top[j] + ((expr) - top[j]) * opacity; \ - } \ - dst += dst_linesize; \ - top += top_linesize; \ - bottom += bottom_linesize; \ - } \ -} - -#define A top[j] -#define B bottom[j] - -#define MULTIPLY(x, a, b) (x * ((a * b) / 255)) -#define SCREEN(x, a, b) (255 - x * ((255 - a) * (255 - b) / 255)) -#define BURN(a, b) ((a == 0) ? a : FFMAX(0, 255 - ((255 - b) << 8) / a)) -#define DODGE(a, b) ((a == 255) ? a : FFMIN(255, ((b << 8) / (255 - a)))) - -DEFINE_BLEND(addition, FFMIN(255, A + B)) -DEFINE_BLEND(average, (A + B) / 2) -DEFINE_BLEND(subtract, FFMAX(0, A - B)) -DEFINE_BLEND(multiply, MULTIPLY(1, A, B)) -DEFINE_BLEND(negation, 255 - FFABS(255 - A - B)) -DEFINE_BLEND(difference, FFABS(A - B)) -DEFINE_BLEND(screen, SCREEN(1, A, B)) -DEFINE_BLEND(overlay, (A < 128) ? MULTIPLY(2, A, B) : SCREEN(2, A, B)) -DEFINE_BLEND(hardlight, (B < 128) ? MULTIPLY(2, B, A) : SCREEN(2, B, A)) -DEFINE_BLEND(darken, FFMIN(A, B)) -DEFINE_BLEND(lighten, FFMAX(A, B)) -DEFINE_BLEND(divide, ((float)A / ((float)B) * 255)) -DEFINE_BLEND(dodge, DODGE(A, B)) -DEFINE_BLEND(burn, BURN(A, B)) -DEFINE_BLEND(softlight, (A > 127) ? B + (255 - B) * (A - 127.5) / 127.5 * (0.5 - FFABS(B - 127.5) / 255): B - B * ((127.5 - A) / 127.5) * (0.5 - FFABS(B - 127.5)/255)) -DEFINE_BLEND(exclusion, A + B - 2 * A * B / 255) -DEFINE_BLEND(pinlight, (B < 128) ? FFMIN(A, 2 * B) : FFMAX(A, 2 * (B - 128))) -DEFINE_BLEND(phoenix, FFMIN(A, B) - FFMAX(A, B) + 255) -DEFINE_BLEND(reflect, (B == 255) ? B : FFMIN(255, (A * A / (255 - B)))) -DEFINE_BLEND(and, A & B) -DEFINE_BLEND(or, A | B) -DEFINE_BLEND(xor, A ^ B) -DEFINE_BLEND(vividlight, (B < 128) ? BURN(A, 2 * B) : DODGE(A, 2 * (B - 128))) - -static void blend_expr(const uint8_t *top, int top_linesize, - const uint8_t *bottom, int bottom_linesize, - uint8_t *dst, int dst_linesize, - int width, int start, int end, - FilterParams *param, double *values) -{ - AVExpr *e = param->e; - int y, x; - - for (y = start; y < end; y++) { - values[VAR_Y] = y; - for (x = 0; x < width; x++) { - values[VAR_X] = x; - values[VAR_TOP] = values[VAR_A] = top[x]; - values[VAR_BOTTOM] = values[VAR_B] = bottom[x]; - dst[x] = av_expr_eval(e, values, NULL); - } - dst += dst_linesize; - top += top_linesize; - bottom += bottom_linesize; - } -} - -static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ThreadData *td = arg; - int slice_start = (td->h * jobnr ) / nb_jobs; - int slice_end = (td->h * (jobnr+1)) / nb_jobs; - const uint8_t *top = td->top->data[td->plane]; - const uint8_t *bottom = td->bottom->data[td->plane]; - uint8_t *dst = td->dst->data[td->plane]; - double values[VAR_VARS_NB]; - - values[VAR_N] = td->inlink->frame_count; - values[VAR_T] = td->dst->pts == AV_NOPTS_VALUE ? NAN : td->dst->pts * av_q2d(td->inlink->time_base); - values[VAR_W] = td->w; - values[VAR_H] = td->h; - values[VAR_SW] = td->w / (double)td->dst->width; - values[VAR_SH] = td->h / (double)td->dst->height; - - td->param->blend(top + slice_start * td->top->linesize[td->plane], - td->top->linesize[td->plane], - bottom + slice_start * td->bottom->linesize[td->plane], - td->bottom->linesize[td->plane], - dst + slice_start * td->dst->linesize[td->plane], - td->dst->linesize[td->plane], - td->w, slice_start, slice_end, td->param, &values[0]); - return 0; -} - -static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf, - const AVFrame *bottom_buf) -{ - BlendContext *b = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *dst_buf; - int plane; - - dst_buf = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!dst_buf) - return top_buf; - av_frame_copy_props(dst_buf, top_buf); - - for (plane = 0; plane < b->nb_planes; plane++) { - int hsub = plane == 1 || plane == 2 ? b->hsub : 0; - int vsub = plane == 1 || plane == 2 ? b->vsub : 0; - int outw = FF_CEIL_RSHIFT(dst_buf->width, hsub); - int outh = FF_CEIL_RSHIFT(dst_buf->height, vsub); - FilterParams *param = &b->params[plane]; - ThreadData td = { .top = top_buf, .bottom = bottom_buf, .dst = dst_buf, - .w = outw, .h = outh, .param = param, .plane = plane, - .inlink = inlink }; - - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outh, ctx->graph->nb_threads)); - } - - av_frame_free(&top_buf); - - return dst_buf; -} - -static av_cold int init(AVFilterContext *ctx) -{ - BlendContext *b = ctx->priv; - int ret, plane; - - for (plane = 0; plane < FF_ARRAY_ELEMS(b->params); plane++) { - FilterParams *param = &b->params[plane]; - - if (b->all_mode >= 0) - param->mode = b->all_mode; - if (b->all_opacity < 1) - param->opacity = b->all_opacity; - - switch (param->mode) { - case BLEND_ADDITION: param->blend = blend_addition; break; - case BLEND_AND: param->blend = blend_and; break; - case BLEND_AVERAGE: param->blend = blend_average; break; - case BLEND_BURN: param->blend = blend_burn; break; - case BLEND_DARKEN: param->blend = blend_darken; break; - case BLEND_DIFFERENCE: param->blend = blend_difference; break; - case BLEND_DIVIDE: param->blend = blend_divide; break; - case BLEND_DODGE: param->blend = blend_dodge; break; - case BLEND_EXCLUSION: param->blend = blend_exclusion; break; - case BLEND_HARDLIGHT: param->blend = blend_hardlight; break; - case BLEND_LIGHTEN: param->blend = blend_lighten; break; - case BLEND_MULTIPLY: param->blend = blend_multiply; break; - case BLEND_NEGATION: param->blend = blend_negation; break; - case BLEND_NORMAL: param->blend = blend_normal; break; - case BLEND_OR: param->blend = blend_or; break; - case BLEND_OVERLAY: param->blend = blend_overlay; break; - case BLEND_PHOENIX: param->blend = blend_phoenix; break; - case BLEND_PINLIGHT: param->blend = blend_pinlight; break; - case BLEND_REFLECT: param->blend = blend_reflect; break; - case BLEND_SCREEN: param->blend = blend_screen; break; - case BLEND_SOFTLIGHT: param->blend = blend_softlight; break; - case BLEND_SUBTRACT: param->blend = blend_subtract; break; - case BLEND_VIVIDLIGHT: param->blend = blend_vividlight; break; - case BLEND_XOR: param->blend = blend_xor; break; - } - - if (b->all_expr && !param->expr_str) { - param->expr_str = av_strdup(b->all_expr); - if (!param->expr_str) - return AVERROR(ENOMEM); - } - if (param->expr_str) { - ret = av_expr_parse(¶m->e, param->expr_str, var_names, - NULL, NULL, NULL, NULL, 0, ctx); - if (ret < 0) - return ret; - param->blend = blend_expr; - } - } - - b->dinput.process = blend_frame; - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P,AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *toplink = ctx->inputs[TOP]; - AVFilterLink *bottomlink = ctx->inputs[BOTTOM]; - BlendContext *b = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(toplink->format); - int ret; - - if (toplink->format != bottomlink->format) { - av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n"); - return AVERROR(EINVAL); - } - if (toplink->w != bottomlink->w || - toplink->h != bottomlink->h || - toplink->sample_aspect_ratio.num != bottomlink->sample_aspect_ratio.num || - toplink->sample_aspect_ratio.den != bottomlink->sample_aspect_ratio.den) { - av_log(ctx, AV_LOG_ERROR, "First input link %s parameters " - "(size %dx%d, SAR %d:%d) do not match the corresponding " - "second input link %s parameters (%dx%d, SAR %d:%d)\n", - ctx->input_pads[TOP].name, toplink->w, toplink->h, - toplink->sample_aspect_ratio.num, - toplink->sample_aspect_ratio.den, - ctx->input_pads[BOTTOM].name, bottomlink->w, bottomlink->h, - bottomlink->sample_aspect_ratio.num, - bottomlink->sample_aspect_ratio.den); - return AVERROR(EINVAL); - } - - outlink->w = toplink->w; - outlink->h = toplink->h; - outlink->time_base = toplink->time_base; - outlink->sample_aspect_ratio = toplink->sample_aspect_ratio; - outlink->frame_rate = toplink->frame_rate; - - b->hsub = pix_desc->log2_chroma_w; - b->vsub = pix_desc->log2_chroma_h; - b->nb_planes = av_pix_fmt_count_planes(toplink->format); - - if ((ret = ff_dualinput_init(ctx, &b->dinput)) < 0) - return ret; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - BlendContext *b = ctx->priv; - int i; - - ff_dualinput_uninit(&b->dinput); - for (i = 0; i < FF_ARRAY_ELEMS(b->params); i++) - av_expr_free(b->params[i].e); -} - -static int request_frame(AVFilterLink *outlink) -{ - BlendContext *b = outlink->src->priv; - return ff_dualinput_request_frame(&b->dinput, outlink); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - BlendContext *b = inlink->dst->priv; - return ff_dualinput_filter_frame(&b->dinput, inlink, buf); -} - -static const AVFilterPad blend_inputs[] = { - { - .name = "top", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - },{ - .name = "bottom", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad blend_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_blend = { - .name = "blend", - .description = NULL_IF_CONFIG_SMALL("Blend two video frames into each other."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(BlendContext), - .query_formats = query_formats, - .inputs = blend_inputs, - .outputs = blend_outputs, - .priv_class = &blend_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/vf_boxblur.c b/ffmpeg/libavfilter/vf_boxblur.c deleted file mode 100644 index 3183f43..0000000 --- a/ffmpeg/libavfilter/vf_boxblur.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2011 Stefano Sabatini - * - * 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 - * Apply a boxblur filter to the input video. - * Ported from MPlayer libmpcodecs/vf_boxblur.c. - */ - -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { - "w", - "h", - "cw", - "ch", - "hsub", - "vsub", - NULL -}; - -enum var_name { - VAR_W, - VAR_H, - VAR_CW, - VAR_CH, - VAR_HSUB, - VAR_VSUB, - VARS_NB -}; - -typedef struct { - int radius; - int power; - char *radius_expr; -} FilterParam; - -typedef struct { - const AVClass *class; - FilterParam luma_param; - FilterParam chroma_param; - FilterParam alpha_param; - - int hsub, vsub; - int radius[4]; - int power[4]; - uint8_t *temp[2]; ///< temporary buffer used in blur_power() -} BoxBlurContext; - -#define Y 0 -#define U 1 -#define V 2 -#define A 3 - -static av_cold int init(AVFilterContext *ctx) -{ - BoxBlurContext *s = ctx->priv; - - if (!s->luma_param.radius_expr) { - av_log(ctx, AV_LOG_ERROR, "Luma radius expression is not set.\n"); - return AVERROR(EINVAL); - } - - /* fill missing params */ - if (!s->chroma_param.radius_expr) { - s->chroma_param.radius_expr = av_strdup(s->luma_param.radius_expr); - if (!s->chroma_param.radius_expr) - return AVERROR(ENOMEM); - } - if (s->chroma_param.power < 0) - s->chroma_param.power = s->luma_param.power; - - if (!s->alpha_param.radius_expr) { - s->alpha_param.radius_expr = av_strdup(s->luma_param.radius_expr); - if (!s->alpha_param.radius_expr) - return AVERROR(ENOMEM); - } - if (s->alpha_param.power < 0) - s->alpha_param.power = s->luma_param.power; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - BoxBlurContext *s = ctx->priv; - - av_freep(&s->temp[0]); - av_freep(&s->temp[1]); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - AVFilterContext *ctx = inlink->dst; - BoxBlurContext *s = ctx->priv; - int w = inlink->w, h = inlink->h; - int cw, ch; - double var_values[VARS_NB], res; - char *expr; - int ret; - - if (!(s->temp[0] = av_malloc(FFMAX(w, h))) || - !(s->temp[1] = av_malloc(FFMAX(w, h)))) - return AVERROR(ENOMEM); - - s->hsub = desc->log2_chroma_w; - s->vsub = desc->log2_chroma_h; - - var_values[VAR_W] = inlink->w; - var_values[VAR_H] = inlink->h; - var_values[VAR_CW] = cw = w>>s->hsub; - var_values[VAR_CH] = ch = h>>s->vsub; - var_values[VAR_HSUB] = 1<<s->hsub; - var_values[VAR_VSUB] = 1<<s->vsub; - -#define EVAL_RADIUS_EXPR(comp) \ - expr = s->comp##_param.radius_expr; \ - ret = av_expr_parse_and_eval(&res, expr, var_names, var_values, \ - NULL, NULL, NULL, NULL, NULL, 0, ctx); \ - s->comp##_param.radius = res; \ - if (ret < 0) { \ - av_log(NULL, AV_LOG_ERROR, \ - "Error when evaluating " #comp " radius expression '%s'\n", expr); \ - return ret; \ - } - EVAL_RADIUS_EXPR(luma); - EVAL_RADIUS_EXPR(chroma); - EVAL_RADIUS_EXPR(alpha); - - av_log(ctx, AV_LOG_VERBOSE, - "luma_radius:%d luma_power:%d " - "chroma_radius:%d chroma_power:%d " - "alpha_radius:%d alpha_power:%d " - "w:%d chroma_w:%d h:%d chroma_h:%d\n", - s->luma_param .radius, s->luma_param .power, - s->chroma_param.radius, s->chroma_param.power, - s->alpha_param .radius, s->alpha_param .power, - w, cw, h, ch); - -#define CHECK_RADIUS_VAL(w_, h_, comp) \ - if (s->comp##_param.radius < 0 || \ - 2*s->comp##_param.radius > FFMIN(w_, h_)) { \ - av_log(ctx, AV_LOG_ERROR, \ - "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \ - s->comp##_param.radius, FFMIN(w_, h_)/2); \ - return AVERROR(EINVAL); \ - } - CHECK_RADIUS_VAL(w, h, luma); - CHECK_RADIUS_VAL(cw, ch, chroma); - CHECK_RADIUS_VAL(w, h, alpha); - - s->radius[Y] = s->luma_param.radius; - s->radius[U] = s->radius[V] = s->chroma_param.radius; - s->radius[A] = s->alpha_param.radius; - - s->power[Y] = s->luma_param.power; - s->power[U] = s->power[V] = s->chroma_param.power; - s->power[A] = s->alpha_param.power; - - return 0; -} - -static inline void blur(uint8_t *dst, int dst_step, const uint8_t *src, int src_step, - int len, int radius) -{ - /* Naive boxblur would sum source pixels from x-radius .. x+radius - * for destination pixel x. That would be O(radius*width). - * If you now look at what source pixels represent 2 consecutive - * output pixels, then you see they are almost identical and only - * differ by 2 pixels, like: - * src0 111111111 - * dst0 1 - * src1 111111111 - * dst1 1 - * src0-src1 1 -1 - * so when you know one output pixel you can find the next by just adding - * and subtracting 1 input pixel. - * The following code adopts this faster variant. - */ - const int length = radius*2 + 1; - const int inv = ((1<<16) + length/2)/length; - int x, sum = 0; - - for (x = 0; x < radius; x++) - sum += src[x*src_step]<<1; - sum += src[radius*src_step]; - - for (x = 0; x <= radius; x++) { - sum += src[(radius+x)*src_step] - src[(radius-x)*src_step]; - dst[x*dst_step] = (sum*inv + (1<<15))>>16; - } - - for (; x < len-radius; x++) { - sum += src[(radius+x)*src_step] - src[(x-radius-1)*src_step]; - dst[x*dst_step] = (sum*inv + (1<<15))>>16; - } - - for (; x < len; x++) { - sum += src[(2*len-radius-x-1)*src_step] - src[(x-radius-1)*src_step]; - dst[x*dst_step] = (sum*inv + (1<<15))>>16; - } -} - -static inline void blur_power(uint8_t *dst, int dst_step, const uint8_t *src, int src_step, - int len, int radius, int power, uint8_t *temp[2]) -{ - uint8_t *a = temp[0], *b = temp[1]; - - if (radius && power) { - blur(a, 1, src, src_step, len, radius); - for (; power > 2; power--) { - uint8_t *c; - blur(b, 1, a, 1, len, radius); - c = a; a = b; b = c; - } - if (power > 1) { - blur(dst, dst_step, a, 1, len, radius); - } else { - int i; - for (i = 0; i < len; i++) - dst[i*dst_step] = a[i]; - } - } else { - int i; - for (i = 0; i < len; i++) - dst[i*dst_step] = src[i*src_step]; - } -} - -static void hblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, - int w, int h, int radius, int power, uint8_t *temp[2]) -{ - int y; - - if (radius == 0 && dst == src) - return; - - for (y = 0; y < h; y++) - blur_power(dst + y*dst_linesize, 1, src + y*src_linesize, 1, - w, radius, power, temp); -} - -static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, - int w, int h, int radius, int power, uint8_t *temp[2]) -{ - int x; - - if (radius == 0 && dst == src) - return; - - for (x = 0; x < w; x++) - blur_power(dst + x, dst_linesize, src + x, src_linesize, - h, radius, power, temp); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - BoxBlurContext *s = ctx->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - int plane; - int cw = FF_CEIL_RSHIFT(inlink->w, s->hsub), ch = FF_CEIL_RSHIFT(in->height, s->vsub); - int w[4] = { inlink->w, cw, cw, inlink->w }; - int h[4] = { in->height, ch, ch, in->height }; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) - hblur(out->data[plane], out->linesize[plane], - in ->data[plane], in ->linesize[plane], - w[plane], h[plane], s->radius[plane], s->power[plane], - s->temp); - - for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) - vblur(out->data[plane], out->linesize[plane], - out->data[plane], out->linesize[plane], - w[plane], h[plane], s->radius[plane], s->power[plane], - s->temp); - - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(BoxBlurContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption boxblur_options[] = { - { "luma_radius", "Radius of the luma blurring box", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS }, - { "lr", "Radius of the luma blurring box", OFFSET(luma_param.radius_expr), AV_OPT_TYPE_STRING, {.str="2"}, .flags = FLAGS }, - { "luma_power", "How many times should the boxblur be applied to luma", OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS }, - { "lp", "How many times should the boxblur be applied to luma", OFFSET(luma_param.power), AV_OPT_TYPE_INT, {.i64=2}, 0, INT_MAX, .flags = FLAGS }, - - { "chroma_radius", "Radius of the chroma blurring box", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "cr", "Radius of the chroma blurring box", OFFSET(chroma_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "chroma_power", "How many times should the boxblur be applied to chroma", OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "cp", "How many times should the boxblur be applied to chroma", OFFSET(chroma_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - - { "alpha_radius", "Radius of the alpha blurring box", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "ar", "Radius of the alpha blurring box", OFFSET(alpha_param.radius_expr), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "alpha_power", "How many times should the boxblur be applied to alpha", OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "ap", "How many times should the boxblur be applied to alpha", OFFSET(alpha_param.power), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - - { NULL } -}; - -AVFILTER_DEFINE_CLASS(boxblur); - -static const AVFilterPad avfilter_vf_boxblur_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_boxblur_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_boxblur = { - .name = "boxblur", - .description = NULL_IF_CONFIG_SMALL("Blur the input."), - .priv_size = sizeof(BoxBlurContext), - .priv_class = &boxblur_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_vf_boxblur_inputs, - .outputs = avfilter_vf_boxblur_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_colormatrix.c b/ffmpeg/libavfilter/vf_colormatrix.c deleted file mode 100644 index e1b48fa..0000000 --- a/ffmpeg/libavfilter/vf_colormatrix.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * ColorMatrix v2.2 for Avisynth 2.5.x - * - * Copyright (C) 2006-2007 Kevin Stone - * - * ColorMatrix 1.x is Copyright (C) Wilbert Dijkhof - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * OUT 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 this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/** - * @file - * ColorMatrix 2.0 is based on the original ColorMatrix filter by Wilbert - * Dijkhof. It adds the ability to convert between any of: Rec.709, FCC, - * Rec.601, and SMPTE 240M. It also makes pre and post clipping optional, - * adds an option to use scaled or non-scaled coefficients, and more... - */ - -#include <float.h> -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/avstring.h" - -#define NS(n) n < 0 ? (int)(n*65536.0-0.5+DBL_EPSILON) : (int)(n*65536.0+0.5) -#define CB(n) av_clip_uint8(n) - -static const double yuv_coeff[4][3][3] = { - { { +0.7152, +0.0722, +0.2126 }, // Rec.709 (0) - { -0.3850, +0.5000, -0.1150 }, - { -0.4540, -0.0460, +0.5000 } }, - { { +0.5900, +0.1100, +0.3000 }, // FCC (1) - { -0.3310, +0.5000, -0.1690 }, - { -0.4210, -0.0790, +0.5000 } }, - { { +0.5870, +0.1140, +0.2990 }, // Rec.601 (ITU-R BT.470-2/SMPTE 170M) (2) - { -0.3313, +0.5000, -0.1687 }, - { -0.4187, -0.0813, +0.5000 } }, - { { +0.7010, +0.0870, +0.2120 }, // SMPTE 240M (3) - { -0.3840, +0.5000, -0.1160 }, - { -0.4450, -0.0550, +0.5000 } }, -}; - -enum ColorMode { - COLOR_MODE_NONE = -1, - COLOR_MODE_BT709, - COLOR_MODE_FCC, - COLOR_MODE_BT601, - COLOR_MODE_SMPTE240M, - COLOR_MODE_COUNT -}; - -typedef struct { - const AVClass *class; - int yuv_convert[16][3][3]; - int interlaced; - enum ColorMode source, dest; - int mode; - int hsub, vsub; -} ColorMatrixContext; - -#define OFFSET(x) offsetof(ColorMatrixContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption colormatrix_options[] = { - { "src", "set source color matrix", OFFSET(source), AV_OPT_TYPE_INT, {.i64=COLOR_MODE_NONE}, COLOR_MODE_NONE, COLOR_MODE_COUNT-1, .flags=FLAGS, .unit="color_mode" }, - { "dst", "set destination color matrix", OFFSET(dest), AV_OPT_TYPE_INT, {.i64=COLOR_MODE_NONE}, COLOR_MODE_NONE, COLOR_MODE_COUNT-1, .flags=FLAGS, .unit="color_mode" }, - { "bt709", "set BT.709 colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_BT709}, .flags=FLAGS, .unit="color_mode" }, - { "fcc", "set FCC colorspace ", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_FCC}, .flags=FLAGS, .unit="color_mode" }, - { "bt601", "set BT.601 colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_BT601}, .flags=FLAGS, .unit="color_mode" }, - { "smpte240m", "set SMPTE-240M colorspace", 0, AV_OPT_TYPE_CONST, {.i64=COLOR_MODE_SMPTE240M}, .flags=FLAGS, .unit="color_mode" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(colormatrix); - -#define ma m[0][0] -#define mb m[0][1] -#define mc m[0][2] -#define md m[1][0] -#define me m[1][1] -#define mf m[1][2] -#define mg m[2][0] -#define mh m[2][1] -#define mi m[2][2] - -#define ima im[0][0] -#define imb im[0][1] -#define imc im[0][2] -#define imd im[1][0] -#define ime im[1][1] -#define imf im[1][2] -#define img im[2][0] -#define imh im[2][1] -#define imi im[2][2] - -static void inverse3x3(double im[3][3], const double m[3][3]) -{ - double det = ma * (me * mi - mf * mh) - mb * (md * mi - mf * mg) + mc * (md * mh - me * mg); - det = 1.0 / det; - ima = det * (me * mi - mf * mh); - imb = det * (mc * mh - mb * mi); - imc = det * (mb * mf - mc * me); - imd = det * (mf * mg - md * mi); - ime = det * (ma * mi - mc * mg); - imf = det * (mc * md - ma * mf); - img = det * (md * mh - me * mg); - imh = det * (mb * mg - ma * mh); - imi = det * (ma * me - mb * md); -} - -static void solve_coefficients(double cm[3][3], double rgb[3][3], const double yuv[3][3]) -{ - int i, j; - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - cm[i][j] = yuv[i][0] * rgb[0][j] + yuv[i][1] * rgb[1][j] + yuv[i][2] * rgb[2][j]; -} - -static void calc_coefficients(AVFilterContext *ctx) -{ - ColorMatrixContext *color = ctx->priv; - double rgb_coeffd[4][3][3]; - double yuv_convertd[16][3][3]; - int v = 0; - int i, j, k; - - for (i = 0; i < 4; i++) - inverse3x3(rgb_coeffd[i], yuv_coeff[i]); - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - solve_coefficients(yuv_convertd[v], rgb_coeffd[i], yuv_coeff[j]); - for (k = 0; k < 3; k++) { - color->yuv_convert[v][k][0] = NS(yuv_convertd[v][k][0]); - color->yuv_convert[v][k][1] = NS(yuv_convertd[v][k][1]); - color->yuv_convert[v][k][2] = NS(yuv_convertd[v][k][2]); - } - if (color->yuv_convert[v][0][0] != 65536 || color->yuv_convert[v][1][0] != 0 || - color->yuv_convert[v][2][0] != 0) { - av_log(ctx, AV_LOG_ERROR, "error calculating conversion coefficients\n"); - } - v++; - } - } -} - -static const char *color_modes[] = {"bt709", "fcc", "bt601", "smpte240m"}; - -static av_cold int init(AVFilterContext *ctx) -{ - ColorMatrixContext *color = ctx->priv; - - if (color->source == COLOR_MODE_NONE || color->dest == COLOR_MODE_NONE) { - av_log(ctx, AV_LOG_ERROR, "Unspecified source or destination color space\n"); - return AVERROR(EINVAL); - } - - if (color->source == color->dest) { - av_log(ctx, AV_LOG_ERROR, "Source and destination color space must not be identical\n"); - return AVERROR(EINVAL); - } - - color->mode = color->source * 4 + color->dest; - - calc_coefficients(ctx); - - return 0; -} - -static void process_frame_uyvy422(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) -{ - const unsigned char *srcp = src->data[0]; - const int src_pitch = src->linesize[0]; - const int height = src->height; - const int width = src->width*2; - unsigned char *dstp = dst->data[0]; - const int dst_pitch = dst->linesize[0]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x += 4) { - const int u = srcp[x + 0] - 128; - const int v = srcp[x + 2] - 128; - const int uvval = c2 * u + c3 * v + 1081344; - dstp[x + 0] = CB((c4 * u + c5 * v + 8421376) >> 16); - dstp[x + 1] = CB((65536 * (srcp[x + 1] - 16) + uvval) >> 16); - dstp[x + 2] = CB((c6 * u + c7 * v + 8421376) >> 16); - dstp[x + 3] = CB((65536 * (srcp[x + 3] - 16) + uvval) >> 16); - } - srcp += src_pitch; - dstp += dst_pitch; - } -} - -static void process_frame_yuv422p(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) -{ - const unsigned char *srcpU = src->data[1]; - const unsigned char *srcpV = src->data[2]; - const unsigned char *srcpY = src->data[0]; - const int src_pitchY = src->linesize[0]; - const int src_pitchUV = src->linesize[1]; - const int height = src->height; - const int width = src->width; - unsigned char *dstpU = dst->data[1]; - unsigned char *dstpV = dst->data[2]; - unsigned char *dstpY = dst->data[0]; - const int dst_pitchY = dst->linesize[0]; - const int dst_pitchUV = dst->linesize[1]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; - int x, y; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x += 2) { - const int u = srcpU[x >> 1] - 128; - const int v = srcpV[x >> 1] - 128; - const int uvval = c2 * u + c3 * v + 1081344; - dstpY[x + 0] = CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16); - dstpY[x + 1] = CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16); - dstpU[x >> 1] = CB((c4 * u + c5 * v + 8421376) >> 16); - dstpV[x >> 1] = CB((c6 * u + c7 * v + 8421376) >> 16); - } - srcpY += src_pitchY; - dstpY += dst_pitchY; - srcpU += src_pitchUV; - srcpV += src_pitchUV; - dstpU += dst_pitchUV; - dstpV += dst_pitchUV; - } -} - -static void process_frame_yuv420p(ColorMatrixContext *color, - AVFrame *dst, AVFrame *src) -{ - const unsigned char *srcpU = src->data[1]; - const unsigned char *srcpV = src->data[2]; - const unsigned char *srcpY = src->data[0]; - const unsigned char *srcpN = src->data[0] + src->linesize[0]; - const int src_pitchY = src->linesize[0]; - const int src_pitchUV = src->linesize[1]; - const int height = src->height; - const int width = src->width; - unsigned char *dstpU = dst->data[1]; - unsigned char *dstpV = dst->data[2]; - unsigned char *dstpY = dst->data[0]; - unsigned char *dstpN = dst->data[0] + dst->linesize[0]; - const int dst_pitchY = dst->linesize[0]; - const int dst_pitchUV = dst->linesize[1]; - const int c2 = color->yuv_convert[color->mode][0][1]; - const int c3 = color->yuv_convert[color->mode][0][2]; - const int c4 = color->yuv_convert[color->mode][1][1]; - const int c5 = color->yuv_convert[color->mode][1][2]; - const int c6 = color->yuv_convert[color->mode][2][1]; - const int c7 = color->yuv_convert[color->mode][2][2]; - int x, y; - - for (y = 0; y < height; y += 2) { - for (x = 0; x < width; x += 2) { - const int u = srcpU[x >> 1] - 128; - const int v = srcpV[x >> 1] - 128; - const int uvval = c2 * u + c3 * v + 1081344; - dstpY[x + 0] = CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16); - dstpY[x + 1] = CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16); - dstpN[x + 0] = CB((65536 * (srcpN[x + 0] - 16) + uvval) >> 16); - dstpN[x + 1] = CB((65536 * (srcpN[x + 1] - 16) + uvval) >> 16); - dstpU[x >> 1] = CB((c4 * u + c5 * v + 8421376) >> 16); - dstpV[x >> 1] = CB((c6 * u + c7 * v + 8421376) >> 16); - } - srcpY += src_pitchY << 1; - dstpY += dst_pitchY << 1; - srcpN += src_pitchY << 1; - dstpN += dst_pitchY << 1; - srcpU += src_pitchUV; - srcpV += src_pitchUV; - dstpU += dst_pitchUV; - dstpV += dst_pitchUV; - } -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - ColorMatrixContext *color = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - - color->hsub = pix_desc->log2_chroma_w; - color->vsub = pix_desc->log2_chroma_h; - - av_log(ctx, AV_LOG_VERBOSE, "%s -> %s\n", - color_modes[color->source], color_modes[color->dest]); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_UYVY422, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int filter_frame(AVFilterLink *link, AVFrame *in) -{ - AVFilterContext *ctx = link->dst; - ColorMatrixContext *color = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - if (in->format == AV_PIX_FMT_YUV422P) - process_frame_yuv422p(color, out, in); - else if (in->format == AV_PIX_FMT_YUV420P) - process_frame_yuv420p(color, out, in); - else - process_frame_uyvy422(color, out, in); - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad colormatrix_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad colormatrix_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_colormatrix = { - .name = "colormatrix", - .description = NULL_IF_CONFIG_SMALL("Convert color matrix."), - .priv_size = sizeof(ColorMatrixContext), - .init = init, - .query_formats = query_formats, - .inputs = colormatrix_inputs, - .outputs = colormatrix_outputs, - .priv_class = &colormatrix_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_copy.c b/ffmpeg/libavfilter/vf_copy.c deleted file mode 100644 index fcc85c5..0000000 --- a/ffmpeg/libavfilter/vf_copy.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * copy video filter - */ - -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height); - - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - av_image_copy(out->data, out->linesize, (const uint8_t**) in->data, in->linesize, - in->format, in->width, in->height); - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad avfilter_vf_copy_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_copy_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_copy = { - .name = "copy", - .description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."), - .inputs = avfilter_vf_copy_inputs, - .outputs = avfilter_vf_copy_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_crop.c b/ffmpeg/libavfilter/vf_crop.c deleted file mode 100644 index 261db33..0000000 --- a/ffmpeg/libavfilter/vf_crop.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video crop filter - */ - -#include <stdio.h> - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/eval.h" -#include "libavutil/avstring.h" -#include "libavutil/internal.h" -#include "libavutil/libm.h" -#include "libavutil/imgutils.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" - -static const char *const var_names[] = { - "in_w", "iw", ///< width of the input video - "in_h", "ih", ///< height of the input video - "out_w", "ow", ///< width of the cropped video - "out_h", "oh", ///< height of the cropped video - "a", - "sar", - "dar", - "hsub", - "vsub", - "x", - "y", - "n", ///< number of frame - "pos", ///< position in the file - "t", ///< timestamp expressed in seconds - NULL -}; - -enum var_name { - VAR_IN_W, VAR_IW, - VAR_IN_H, VAR_IH, - VAR_OUT_W, VAR_OW, - VAR_OUT_H, VAR_OH, - VAR_A, - VAR_SAR, - VAR_DAR, - VAR_HSUB, - VAR_VSUB, - VAR_X, - VAR_Y, - VAR_N, - VAR_POS, - VAR_T, - VAR_VARS_NB -}; - -typedef struct { - const AVClass *class; - int x; ///< x offset of the non-cropped area with respect to the input area - int y; ///< y offset of the non-cropped area with respect to the input area - int w; ///< width of the cropped area - int h; ///< height of the cropped area - - AVRational out_sar; ///< output sample aspect ratio - int keep_aspect; ///< keep display aspect ratio when cropping - - int max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes - int hsub, vsub; ///< chroma subsampling - char *x_expr, *y_expr, *w_expr, *h_expr; - AVExpr *x_pexpr, *y_pexpr; /* parsed expressions for x and y */ - double var_values[VAR_VARS_NB]; -} CropContext; - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM)) && - !((desc->log2_chroma_w || desc->log2_chroma_h) && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR))) - ff_add_format(&formats, fmt); - } - - ff_set_common_formats(ctx, formats); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - CropContext *s = ctx->priv; - - av_expr_free(s->x_pexpr); - s->x_pexpr = NULL; - av_expr_free(s->y_pexpr); - s->y_pexpr = NULL; -} - -static inline int normalize_double(int *n, double d) -{ - int ret = 0; - - if (isnan(d)) { - ret = AVERROR(EINVAL); - } else if (d > INT_MAX || d < INT_MIN) { - *n = d > INT_MAX ? INT_MAX : INT_MIN; - ret = AVERROR(EINVAL); - } else - *n = round(d); - - return ret; -} - -static int config_input(AVFilterLink *link) -{ - AVFilterContext *ctx = link->dst; - CropContext *s = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(link->format); - int ret; - const char *expr; - double res; - - s->var_values[VAR_IN_W] = s->var_values[VAR_IW] = ctx->inputs[0]->w; - s->var_values[VAR_IN_H] = s->var_values[VAR_IH] = ctx->inputs[0]->h; - s->var_values[VAR_A] = (float) link->w / link->h; - s->var_values[VAR_SAR] = link->sample_aspect_ratio.num ? av_q2d(link->sample_aspect_ratio) : 1; - s->var_values[VAR_DAR] = s->var_values[VAR_A] * s->var_values[VAR_SAR]; - s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w; - s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h; - s->var_values[VAR_X] = NAN; - s->var_values[VAR_Y] = NAN; - s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = NAN; - s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = NAN; - s->var_values[VAR_N] = 0; - s->var_values[VAR_T] = NAN; - s->var_values[VAR_POS] = NAN; - - av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc); - s->hsub = pix_desc->log2_chroma_w; - s->vsub = pix_desc->log2_chroma_h; - - if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), - var_names, s->var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto fail_expr; - s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res; - if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr), - var_names, s->var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto fail_expr; - s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = res; - /* evaluate again ow as it may depend on oh */ - if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), - var_names, s->var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto fail_expr; - - s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res; - if (normalize_double(&s->w, s->var_values[VAR_OUT_W]) < 0 || - normalize_double(&s->h, s->var_values[VAR_OUT_H]) < 0) { - av_log(ctx, AV_LOG_ERROR, - "Too big value or invalid expression for out_w/ow or out_h/oh. " - "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", - s->w_expr, s->h_expr); - return AVERROR(EINVAL); - } - s->w &= ~((1 << s->hsub) - 1); - s->h &= ~((1 << s->vsub) - 1); - - av_expr_free(s->x_pexpr); - av_expr_free(s->y_pexpr); - s->x_pexpr = s->y_pexpr = NULL; - if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names, - NULL, NULL, NULL, NULL, 0, ctx)) < 0 || - (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names, - NULL, NULL, NULL, NULL, 0, ctx)) < 0) - return AVERROR(EINVAL); - - if (s->keep_aspect) { - AVRational dar = av_mul_q(link->sample_aspect_ratio, - (AVRational){ link->w, link->h }); - av_reduce(&s->out_sar.num, &s->out_sar.den, - dar.num * s->h, dar.den * s->w, INT_MAX); - } else - s->out_sar = link->sample_aspect_ratio; - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d -> w:%d h:%d sar:%d/%d\n", - link->w, link->h, link->sample_aspect_ratio.num, link->sample_aspect_ratio.den, - s->w, s->h, s->out_sar.num, s->out_sar.den); - - if (s->w <= 0 || s->h <= 0 || - s->w > link->w || s->h > link->h) { - av_log(ctx, AV_LOG_ERROR, - "Invalid too big or non positive size for width '%d' or height '%d'\n", - s->w, s->h); - return AVERROR(EINVAL); - } - - /* set default, required in the case the first computed value for x/y is NAN */ - s->x = (link->w - s->w) / 2; - s->y = (link->h - s->h) / 2; - s->x &= ~((1 << s->hsub) - 1); - s->y &= ~((1 << s->vsub) - 1); - return 0; - -fail_expr: - av_log(NULL, AV_LOG_ERROR, "Error when evaluating the expression '%s'\n", expr); - return ret; -} - -static int config_output(AVFilterLink *link) -{ - CropContext *s = link->src->priv; - - link->w = s->w; - link->h = s->h; - link->sample_aspect_ratio = s->out_sar; - - return 0; -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AVFilterContext *ctx = link->dst; - CropContext *s = ctx->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - int i; - - frame->width = s->w; - frame->height = s->h; - - s->var_values[VAR_N] = link->frame_count; - s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ? - NAN : frame->pts * av_q2d(link->time_base); - s->var_values[VAR_POS] = av_frame_get_pkt_pos(frame) == -1 ? - NAN : av_frame_get_pkt_pos(frame); - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); - s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL); - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); - - normalize_double(&s->x, s->var_values[VAR_X]); - normalize_double(&s->y, s->var_values[VAR_Y]); - - if (s->x < 0) - s->x = 0; - if (s->y < 0) - s->y = 0; - if ((unsigned)s->x + (unsigned)s->w > link->w) - s->x = link->w - s->w; - if ((unsigned)s->y + (unsigned)s->h > link->h) - s->y = link->h - s->h; - s->x &= ~((1 << s->hsub) - 1); - s->y &= ~((1 << s->vsub) - 1); - - av_dlog(ctx, "n:%d t:%f pos:%f x:%d y:%d x+w:%d y+h:%d\n", - (int)s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS], - s->x, s->y, s->x+s->w, s->y+s->h); - - frame->data[0] += s->y * frame->linesize[0]; - frame->data[0] += s->x * s->max_step[0]; - - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) { - for (i = 1; i < 3; i ++) { - if (frame->data[i]) { - frame->data[i] += (s->y >> s->vsub) * frame->linesize[i]; - frame->data[i] += (s->x * s->max_step[i]) >> s->hsub; - } - } - } - - /* alpha plane */ - if (frame->data[3]) { - frame->data[3] += s->y * frame->linesize[3]; - frame->data[3] += s->x * s->max_step[3]; - } - - return ff_filter_frame(link->dst->outputs[0], frame); -} - -#define OFFSET(x) offsetof(CropContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption crop_options[] = { - { "out_w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set the width crop area expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "out_h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set the height crop area expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "x", "set the x crop area expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "(in_w-out_w)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set the y crop area expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "(in_h-out_h)/2"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "keep_aspect", "keep aspect ratio", OFFSET(keep_aspect), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(crop); - -static const AVFilterPad avfilter_vf_crop_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_crop_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_crop = { - .name = "crop", - .description = NULL_IF_CONFIG_SMALL("Crop the input video."), - .priv_size = sizeof(CropContext), - .priv_class = &crop_class, - .query_formats = query_formats, - .uninit = uninit, - .inputs = avfilter_vf_crop_inputs, - .outputs = avfilter_vf_crop_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_cropdetect.c b/ffmpeg/libavfilter/vf_cropdetect.c deleted file mode 100644 index 4a6b658..0000000 --- a/ffmpeg/libavfilter/vf_cropdetect.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2002 A'rpi - * 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 - * border detection filter - * Ported from MPlayer libmpcodecs/vf_cropdetect.c. - */ - -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int x1, y1, x2, y2; - int limit; - int round; - int reset_count; - int frame_nb; - int max_pixsteps[4]; -} CropDetectContext; - -static int query_formats(AVFilterContext *ctx) -{ - 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_YUV444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_GRAY8, - AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int checkline(void *ctx, const unsigned char *src, int stride, int len, int bpp) -{ - int total = 0; - int div = len; - - switch (bpp) { - case 1: - while (--len >= 0) { - total += src[0]; - src += stride; - } - break; - case 3: - case 4: - while (--len >= 0) { - total += src[0] + src[1] + src[2]; - src += stride; - } - div *= 3; - break; - } - total /= div; - - av_log(ctx, AV_LOG_DEBUG, "total:%d\n", total); - return total; -} - -static av_cold int init(AVFilterContext *ctx) -{ - CropDetectContext *s = ctx->priv; - - s->frame_nb = -2; - - av_log(ctx, AV_LOG_VERBOSE, "limit:%d round:%d reset_count:%d\n", - s->limit, s->round, s->reset_count); - - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - CropDetectContext *s = ctx->priv; - - av_image_fill_max_pixsteps(s->max_pixsteps, NULL, - av_pix_fmt_desc_get(inlink->format)); - - s->x1 = inlink->w - 1; - s->y1 = inlink->h - 1; - s->x2 = 0; - s->y2 = 0; - - return 0; -} - -#define SET_META(key, value) \ - snprintf(buf, sizeof(buf), "%d", value); \ - av_dict_set(metadata, key, buf, 0) - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - CropDetectContext *s = ctx->priv; - int bpp = s->max_pixsteps[0]; - int w, h, x, y, shrink_by; - AVDictionary **metadata; - char buf[32]; - - // ignore first 2 frames - they may be empty - if (++s->frame_nb > 0) { - metadata = avpriv_frame_get_metadatap(frame); - - // Reset the crop area every reset_count frames, if reset_count is > 0 - if (s->reset_count > 0 && s->frame_nb > s->reset_count) { - s->x1 = frame->width - 1; - s->y1 = frame->height - 1; - s->x2 = 0; - s->y2 = 0; - s->frame_nb = 1; - } - - for (y = 0; y < s->y1; y++) { - if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) { - s->y1 = y; - break; - } - } - - for (y = frame->height - 1; y > s->y2; y--) { - if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) { - s->y2 = y; - break; - } - } - - for (y = 0; y < s->x1; y++) { - if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) { - s->x1 = y; - break; - } - } - - for (y = frame->width - 1; y > s->x2; y--) { - if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) { - s->x2 = y; - break; - } - } - - // round x and y (up), important for yuv colorspaces - // make sure they stay rounded! - x = (s->x1+1) & ~1; - y = (s->y1+1) & ~1; - - w = s->x2 - x + 1; - h = s->y2 - y + 1; - - // w and h must be divisible by 2 as well because of yuv - // colorspace problems. - if (s->round <= 1) - s->round = 16; - if (s->round % 2) - s->round *= 2; - - shrink_by = w % s->round; - w -= shrink_by; - x += (shrink_by/2 + 1) & ~1; - - shrink_by = h % s->round; - h -= shrink_by; - y += (shrink_by/2 + 1) & ~1; - - SET_META("lavfi.cropdetect.x1", s->x1); - SET_META("lavfi.cropdetect.x2", s->x2); - SET_META("lavfi.cropdetect.y1", s->y1); - SET_META("lavfi.cropdetect.y2", s->y2); - SET_META("lavfi.cropdetect.w", w); - SET_META("lavfi.cropdetect.h", h); - SET_META("lavfi.cropdetect.x", x); - SET_META("lavfi.cropdetect.y", y); - - av_log(ctx, AV_LOG_INFO, - "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n", - s->x1, s->x2, s->y1, s->y2, w, h, x, y, frame->pts, - frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base), - w, h, x, y); - } - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -#define OFFSET(x) offsetof(CropDetectContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption cropdetect_options[] = { - { "limit", "Threshold below which the pixel is considered black", OFFSET(limit), AV_OPT_TYPE_INT, { .i64 = 24 }, 0, 255, FLAGS }, - { "round", "Value by which the width/height should be divisible", OFFSET(round), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, FLAGS }, - { "reset", "Recalculate the crop area after this many frames", OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, - { "reset_count", "Recalculate the crop area after this many frames",OFFSET(reset_count),AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(cropdetect); - -static const AVFilterPad avfilter_vf_cropdetect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_cropdetect_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_cropdetect = { - .name = "cropdetect", - .description = NULL_IF_CONFIG_SMALL("Auto-detect crop size."), - .priv_size = sizeof(CropDetectContext), - .priv_class = &cropdetect_class, - .init = init, - .query_formats = query_formats, - .inputs = avfilter_vf_cropdetect_inputs, - .outputs = avfilter_vf_cropdetect_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_curves.c b/ffmpeg/libavfilter/vf_curves.c deleted file mode 100644 index 5123430..0000000 --- a/ffmpeg/libavfilter/vf_curves.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2013 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/opt.h" -#include "libavutil/bprint.h" -#include "libavutil/eval.h" -#include "libavutil/file.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/avassert.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -struct keypoint { - double x, y; - struct keypoint *next; -}; - -#define NB_COMP 3 - -enum preset { - PRESET_NONE, - PRESET_COLOR_NEGATIVE, - PRESET_CROSS_PROCESS, - PRESET_DARKER, - PRESET_INCREASE_CONTRAST, - PRESET_LIGHTER, - PRESET_LINEAR_CONTRAST, - PRESET_MEDIUM_CONTRAST, - PRESET_NEGATIVE, - PRESET_STRONG_CONTRAST, - PRESET_VINTAGE, - NB_PRESETS, -}; - -typedef struct { - const AVClass *class; - enum preset preset; - char *comp_points_str[NB_COMP + 1]; - char *comp_points_str_all; - uint8_t graph[NB_COMP + 1][256]; - char *psfile; - uint8_t rgba_map[4]; - int step; -} CurvesContext; - -#define OFFSET(x) offsetof(CurvesContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption curves_options[] = { - { "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=PRESET_NONE}, PRESET_NONE, NB_PRESETS-1, FLAGS, "preset_name" }, - { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NONE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "color_negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_COLOR_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "cross_process", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CROSS_PROCESS}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "darker", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_DARKER}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "increase_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INCREASE_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "lighter", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LIGHTER}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "linear_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LINEAR_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "medium_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MEDIUM_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "strong_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_STRONG_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "vintage", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VINTAGE}, INT_MIN, INT_MAX, FLAGS, "preset_name" }, - { "master","set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "m", "set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "red", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "r", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "green", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "g", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "all", "set points coordinates for all components", OFFSET(comp_points_str_all), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "psfile", "set Photoshop curves file name", OFFSET(psfile), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(curves); - -static const struct { - const char *r; - const char *g; - const char *b; - const char *master; -} curves_presets[] = { - [PRESET_COLOR_NEGATIVE] = { - "0/1 0.129/1 0.466/0.498 0.725/0 1/0", - "0/1 0.109/1 0.301/0.498 0.517/0 1/0", - "0/1 0.098/1 0.235/0.498 0.423/0 1/0", - }, - [PRESET_CROSS_PROCESS] = { - "0.25/0.156 0.501/0.501 0.686/0.745", - "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815", - "0.231/0.094 0.709/0.874", - }, - [PRESET_DARKER] = { .master = "0.5/0.4" }, - [PRESET_INCREASE_CONTRAST] = { .master = "0.149/0.066 0.831/0.905 0.905/0.98" }, - [PRESET_LIGHTER] = { .master = "0.4/0.5" }, - [PRESET_LINEAR_CONTRAST] = { .master = "0.305/0.286 0.694/0.713" }, - [PRESET_MEDIUM_CONTRAST] = { .master = "0.286/0.219 0.639/0.643" }, - [PRESET_NEGATIVE] = { .master = "0/1 1/0" }, - [PRESET_STRONG_CONTRAST] = { .master = "0.301/0.196 0.592/0.6 0.686/0.737" }, - [PRESET_VINTAGE] = { - "0/0.11 0.42/0.51 1/0.95", - "0.50/0.48", - "0/0.22 0.49/0.44 1/0.8", - } -}; - -static struct keypoint *make_point(double x, double y, struct keypoint *next) -{ - struct keypoint *point = av_mallocz(sizeof(*point)); - - if (!point) - return NULL; - point->x = x; - point->y = y; - point->next = next; - return point; -} - -static int parse_points_str(AVFilterContext *ctx, struct keypoint **points, const char *s) -{ - char *p = (char *)s; // strtod won't alter the string - struct keypoint *last = NULL; - - /* construct a linked list based on the key points string */ - while (p && *p) { - struct keypoint *point = make_point(0, 0, NULL); - if (!point) - return AVERROR(ENOMEM); - point->x = av_strtod(p, &p); if (p && *p) p++; - point->y = av_strtod(p, &p); if (p && *p) p++; - if (point->x < 0 || point->x > 1 || point->y < 0 || point->y > 1) { - av_log(ctx, AV_LOG_ERROR, "Invalid key point coordinates (%f;%f), " - "x and y must be in the [0;1] range.\n", point->x, point->y); - return AVERROR(EINVAL); - } - if (!*points) - *points = point; - if (last) { - if ((int)(last->x * 255) >= (int)(point->x * 255)) { - av_log(ctx, AV_LOG_ERROR, "Key point coordinates (%f;%f) " - "and (%f;%f) are too close from each other or not " - "strictly increasing on the x-axis\n", - last->x, last->y, point->x, point->y); - return AVERROR(EINVAL); - } - last->next = point; - } - last = point; - } - - /* auto insert first key point if missing at x=0 */ - if (!*points) { - last = make_point(0, 0, NULL); - if (!last) - return AVERROR(ENOMEM); - last->x = last->y = 0; - *points = last; - } else if ((*points)->x != 0.) { - struct keypoint *newfirst = make_point(0, 0, *points); - if (!newfirst) - return AVERROR(ENOMEM); - *points = newfirst; - } - - av_assert0(last); - - /* auto insert last key point if missing at x=1 */ - if (last->x != 1.) { - struct keypoint *point = make_point(1, 1, NULL); - if (!point) - return AVERROR(ENOMEM); - last->next = point; - } - - return 0; -} - -static int get_nb_points(const struct keypoint *d) -{ - int n = 0; - while (d) { - n++; - d = d->next; - } - return n; -} - -/** - * Natural cubic spline interpolation - * Finding curves using Cubic Splines notes by Steven Rauch and John Stockie. - * @see http://people.math.sfu.ca/~stockie/teaching/macm316/notes/splines.pdf - */ -static int interpolate(AVFilterContext *ctx, uint8_t *y, const struct keypoint *points) -{ - int i, ret = 0; - const struct keypoint *point; - double xprev = 0; - - int n = get_nb_points(points); // number of splines - - double (*matrix)[3] = av_calloc(n, sizeof(*matrix)); - double *h = av_malloc((n - 1) * sizeof(*h)); - double *r = av_calloc(n, sizeof(*r)); - - if (!matrix || !h || !r) { - ret = AVERROR(ENOMEM); - goto end; - } - - /* h(i) = x(i+1) - x(i) */ - i = -1; - for (point = points; point; point = point->next) { - if (i != -1) - h[i] = point->x - xprev; - xprev = point->x; - i++; - } - - /* right-side of the polynomials, will be modified to contains the solution */ - point = points; - for (i = 1; i < n - 1; i++) { - double yp = point->y, - yc = point->next->y, - yn = point->next->next->y; - r[i] = 6 * ((yn-yc)/h[i] - (yc-yp)/h[i-1]); - point = point->next; - } - -#define BD 0 /* sub diagonal (below main) */ -#define MD 1 /* main diagonal (center) */ -#define AD 2 /* sup diagonal (above main) */ - - /* left side of the polynomials into a tridiagonal matrix. */ - matrix[0][MD] = matrix[n - 1][MD] = 1; - for (i = 1; i < n - 1; i++) { - matrix[i][BD] = h[i-1]; - matrix[i][MD] = 2 * (h[i-1] + h[i]); - matrix[i][AD] = h[i]; - } - - /* tridiagonal solving of the linear system */ - for (i = 1; i < n; i++) { - double den = matrix[i][MD] - matrix[i][BD] * matrix[i-1][AD]; - double k = den ? 1./den : 1.; - matrix[i][AD] *= k; - r[i] = (r[i] - matrix[i][BD] * r[i - 1]) * k; - } - for (i = n - 2; i >= 0; i--) - r[i] = r[i] - matrix[i][AD] * r[i + 1]; - - /* compute the graph with x=[0..255] */ - i = 0; - point = points; - av_assert0(point->next); // always at least 2 key points - while (point->next) { - double yc = point->y; - double yn = point->next->y; - - double a = yc; - double b = (yn-yc)/h[i] - h[i]*r[i]/2. - h[i]*(r[i+1]-r[i])/6.; - double c = r[i] / 2.; - double d = (r[i+1] - r[i]) / (6.*h[i]); - - int x; - int x_start = point->x * 255; - int x_end = point->next->x * 255; - - av_assert0(x_start >= 0 && x_start <= 255 && - x_end >= 0 && x_end <= 255); - - for (x = x_start; x <= x_end; x++) { - double xx = (x - x_start) * 1/255.; - double yy = a + b*xx + c*xx*xx + d*xx*xx*xx; - y[x] = av_clipf(yy, 0, 1) * 255; - av_log(ctx, AV_LOG_DEBUG, "f(%f)=%f -> y[%d]=%d\n", xx, yy, x, y[x]); - } - - point = point->next; - i++; - } - -end: - av_free(matrix); - av_free(h); - av_free(r); - return ret; -} - -static int parse_psfile(AVFilterContext *ctx, const char *fname) -{ - CurvesContext *curves = ctx->priv; - uint8_t *buf; - size_t size; - int i, ret, av_unused(version), nb_curves; - AVBPrint ptstr; - static const int comp_ids[] = {3, 0, 1, 2}; - - av_bprint_init(&ptstr, 0, AV_BPRINT_SIZE_AUTOMATIC); - - ret = av_file_map(fname, &buf, &size, 0, NULL); - if (ret < 0) - return ret; - -#define READ16(dst) do { \ - if (size < 2) \ - return AVERROR_INVALIDDATA; \ - dst = AV_RB16(buf); \ - buf += 2; \ - size -= 2; \ -} while (0) - - READ16(version); - READ16(nb_curves); - for (i = 0; i < FFMIN(nb_curves, FF_ARRAY_ELEMS(comp_ids)); i++) { - int nb_points, n; - av_bprint_clear(&ptstr); - READ16(nb_points); - for (n = 0; n < nb_points; n++) { - int y, x; - READ16(y); - READ16(x); - av_bprintf(&ptstr, "%f/%f ", x / 255., y / 255.); - } - if (*ptstr.str) { - char **pts = &curves->comp_points_str[comp_ids[i]]; - if (!*pts) { - *pts = av_strdup(ptstr.str); - av_log(ctx, AV_LOG_DEBUG, "curves %d (intid=%d) [%d points]: [%s]\n", - i, comp_ids[i], nb_points, *pts); - if (!*pts) { - ret = AVERROR(ENOMEM); - goto end; - } - } - } - } -end: - av_bprint_finalize(&ptstr, NULL); - av_file_unmap(buf, size); - return ret; -} - -static av_cold int init(AVFilterContext *ctx) -{ - int i, j, ret; - CurvesContext *curves = ctx->priv; - struct keypoint *comp_points[NB_COMP + 1] = {0}; - char **pts = curves->comp_points_str; - const char *allp = curves->comp_points_str_all; - - //if (!allp && curves->preset != PRESET_NONE && curves_presets[curves->preset].all) - // allp = curves_presets[curves->preset].all; - - if (allp) { - for (i = 0; i < NB_COMP; i++) { - if (!pts[i]) - pts[i] = av_strdup(allp); - if (!pts[i]) - return AVERROR(ENOMEM); - } - } - - if (curves->psfile) { - ret = parse_psfile(ctx, curves->psfile); - if (ret < 0) - return ret; - } - - if (curves->preset != PRESET_NONE) { -#define SET_COMP_IF_NOT_SET(n, name) do { \ - if (!pts[n] && curves_presets[curves->preset].name) { \ - pts[n] = av_strdup(curves_presets[curves->preset].name); \ - if (!pts[n]) \ - return AVERROR(ENOMEM); \ - } \ -} while (0) - SET_COMP_IF_NOT_SET(0, r); - SET_COMP_IF_NOT_SET(1, g); - SET_COMP_IF_NOT_SET(2, b); - SET_COMP_IF_NOT_SET(3, master); - } - - for (i = 0; i < NB_COMP + 1; i++) { - ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]); - if (ret < 0) - return ret; - ret = interpolate(ctx, curves->graph[i], comp_points[i]); - if (ret < 0) - return ret; - } - - if (pts[NB_COMP]) { - for (i = 0; i < NB_COMP; i++) - for (j = 0; j < 256; j++) - curves->graph[i][j] = curves->graph[NB_COMP][curves->graph[i][j]]; - } - - if (av_log_get_level() >= AV_LOG_VERBOSE) { - for (i = 0; i < NB_COMP; i++) { - struct keypoint *point = comp_points[i]; - av_log(ctx, AV_LOG_VERBOSE, "#%d points:", i); - while (point) { - av_log(ctx, AV_LOG_VERBOSE, " (%f;%f)", point->x, point->y); - point = point->next; - } - av_log(ctx, AV_LOG_VERBOSE, "\n"); - av_log(ctx, AV_LOG_VERBOSE, "#%d values:", i); - for (j = 0; j < 256; j++) - av_log(ctx, AV_LOG_VERBOSE, " %02X", curves->graph[i][j]); - av_log(ctx, AV_LOG_VERBOSE, "\n"); - } - } - - for (i = 0; i < NB_COMP + 1; i++) { - struct keypoint *point = comp_points[i]; - while (point) { - struct keypoint *next = point->next; - av_free(point); - point = next; - } - } - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, - AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - CurvesContext *curves = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - - ff_fill_rgba_map(curves->rgba_map, inlink->format); - curves->step = av_get_padded_bits_per_pixel(desc) >> 3; - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - int x, y, direct = 0; - AVFilterContext *ctx = inlink->dst; - CurvesContext *curves = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out; - uint8_t *dst; - const uint8_t *src; - const int step = curves->step; - const uint8_t r = curves->rgba_map[R]; - const uint8_t g = curves->rgba_map[G]; - const uint8_t b = curves->rgba_map[B]; - const uint8_t a = curves->rgba_map[A]; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - } - - dst = out->data[0]; - src = in ->data[0]; - - for (y = 0; y < inlink->h; y++) { - for (x = 0; x < inlink->w * step; x += step) { - dst[x + r] = curves->graph[R][src[x + r]]; - dst[x + g] = curves->graph[G][src[x + g]]; - dst[x + b] = curves->graph[B][src[x + b]]; - if (!direct && step == 4) - dst[x + a] = src[x + a]; - } - dst += out->linesize[0]; - src += in ->linesize[0]; - } - - if (!direct) - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad curves_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad curves_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_curves = { - .name = "curves", - .description = NULL_IF_CONFIG_SMALL("Adjust components curves."), - .priv_size = sizeof(CurvesContext), - .init = init, - .query_formats = query_formats, - .inputs = curves_inputs, - .outputs = curves_outputs, - .priv_class = &curves_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_decimate.c b/ffmpeg/libavfilter/vf_decimate.c deleted file mode 100644 index 5efafe9..0000000 --- a/ffmpeg/libavfilter/vf_decimate.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2012 Fredrik Mellbin - * Copyright (c) 2013 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/timestamp.h" -#include "avfilter.h" -#include "internal.h" - -#define INPUT_MAIN 0 -#define INPUT_CLEANSRC 1 - -struct qitem { - AVFrame *frame; - int64_t maxbdiff; - int64_t totdiff; -}; - -typedef struct { - const AVClass *class; - struct qitem *queue; ///< window of cycle frames and the associated data diff - int fid; ///< current frame id in the queue - int filled; ///< 1 if the queue is filled, 0 otherwise - AVFrame *last; ///< last frame from the previous queue - AVFrame **clean_src; ///< frame queue for the clean source - int got_frame[2]; ///< frame request flag for each input stream - double ts_unit; ///< timestamp units for the output frames - int64_t start_pts; ///< base for output timestamps - uint32_t eof; ///< bitmask for end of stream - int hsub, vsub; ///< chroma subsampling values - int depth; - int nxblocks, nyblocks; - int bdiffsize; - int64_t *bdiffs; - - /* options */ - int cycle; - double dupthresh_flt; - double scthresh_flt; - int64_t dupthresh; - int64_t scthresh; - int blockx, blocky; - int ppsrc; - int chroma; -} DecimateContext; - -#define OFFSET(x) offsetof(DecimateContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption decimate_options[] = { - { "cycle", "set the number of frame from which one will be dropped", OFFSET(cycle), AV_OPT_TYPE_INT, {.i64 = 5}, 2, 25, FLAGS }, - { "dupthresh", "set duplicate threshold", OFFSET(dupthresh_flt), AV_OPT_TYPE_DOUBLE, {.dbl = 1.1}, 0, 100, FLAGS }, - { "scthresh", "set scene change threshold", OFFSET(scthresh_flt), AV_OPT_TYPE_DOUBLE, {.dbl = 15.0}, 0, 100, FLAGS }, - { "blockx", "set the size of the x-axis blocks used during metric calculations", OFFSET(blockx), AV_OPT_TYPE_INT, {.i64 = 32}, 4, 1<<9, FLAGS }, - { "blocky", "set the size of the y-axis blocks used during metric calculations", OFFSET(blocky), AV_OPT_TYPE_INT, {.i64 = 32}, 4, 1<<9, FLAGS }, - { "ppsrc", "mark main input as a pre-processed input and activate clean source input stream", OFFSET(ppsrc), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "chroma", "set whether or not chroma is considered in the metric calculations", OFFSET(chroma), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(decimate); - -static void calc_diffs(const DecimateContext *dm, struct qitem *q, - const AVFrame *f1, const AVFrame *f2) -{ - int64_t maxdiff = -1; - int64_t *bdiffs = dm->bdiffs; - int plane, i, j; - - memset(bdiffs, 0, dm->bdiffsize * sizeof(*bdiffs)); - - for (plane = 0; plane < (dm->chroma && f1->data[2] ? 3 : 1); plane++) { - int x, y, xl; - const int linesize1 = f1->linesize[plane]; - const int linesize2 = f2->linesize[plane]; - const uint8_t *f1p = f1->data[plane]; - const uint8_t *f2p = f2->data[plane]; - int width = plane ? FF_CEIL_RSHIFT(f1->width, dm->hsub) : f1->width; - int height = plane ? FF_CEIL_RSHIFT(f1->height, dm->vsub) : f1->height; - int hblockx = dm->blockx / 2; - int hblocky = dm->blocky / 2; - - if (plane) { - hblockx >>= dm->hsub; - hblocky >>= dm->vsub; - } - - for (y = 0; y < height; y++) { - int ydest = y / hblocky; - int xdest = 0; - -#define CALC_DIFF(nbits) do { \ - for (x = 0; x < width; x += hblockx) { \ - int64_t acc = 0; \ - int m = FFMIN(width, x + hblockx); \ - for (xl = x; xl < m; xl++) \ - acc += abs(((const uint##nbits##_t *)f1p)[xl] - \ - ((const uint##nbits##_t *)f2p)[xl]); \ - bdiffs[ydest * dm->nxblocks + xdest] += acc; \ - xdest++; \ - } \ -} while (0) - if (dm->depth == 8) CALC_DIFF(8); - else CALC_DIFF(16); - - f1p += linesize1; - f2p += linesize2; - } - } - - for (i = 0; i < dm->nyblocks - 1; i++) { - for (j = 0; j < dm->nxblocks - 1; j++) { - int64_t tmp = bdiffs[ i * dm->nxblocks + j ] - + bdiffs[ i * dm->nxblocks + j + 1] - + bdiffs[(i + 1) * dm->nxblocks + j ] - + bdiffs[(i + 1) * dm->nxblocks + j + 1]; - if (tmp > maxdiff) - maxdiff = tmp; - } - } - - q->totdiff = 0; - for (i = 0; i < dm->bdiffsize; i++) - q->totdiff += bdiffs[i]; - q->maxbdiff = maxdiff; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - int scpos = -1, duppos = -1; - int drop = INT_MIN, i, lowest = 0, ret; - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - DecimateContext *dm = ctx->priv; - AVFrame *prv; - - /* update frames queue(s) */ - if (FF_INLINK_IDX(inlink) == INPUT_MAIN) { - dm->queue[dm->fid].frame = in; - dm->got_frame[INPUT_MAIN] = 1; - } else { - dm->clean_src[dm->fid] = in; - dm->got_frame[INPUT_CLEANSRC] = 1; - } - if (!dm->got_frame[INPUT_MAIN] || (dm->ppsrc && !dm->got_frame[INPUT_CLEANSRC])) - return 0; - dm->got_frame[INPUT_MAIN] = dm->got_frame[INPUT_CLEANSRC] = 0; - - if (in) { - /* update frame metrics */ - prv = dm->fid ? dm->queue[dm->fid - 1].frame : dm->last; - if (!prv) - prv = in; - calc_diffs(dm, &dm->queue[dm->fid], prv, in); - if (++dm->fid != dm->cycle) - return 0; - av_frame_free(&dm->last); - dm->last = av_frame_clone(in); - dm->fid = 0; - - /* we have a complete cycle, select the frame to drop */ - lowest = 0; - for (i = 0; i < dm->cycle; i++) { - if (dm->queue[i].totdiff > dm->scthresh) - scpos = i; - if (dm->queue[i].maxbdiff < dm->queue[lowest].maxbdiff) - lowest = i; - } - if (dm->queue[lowest].maxbdiff < dm->dupthresh) - duppos = lowest; - drop = scpos >= 0 && duppos < 0 ? scpos : lowest; - } - - /* metrics debug */ - if (av_log_get_level() >= AV_LOG_DEBUG) { - av_log(ctx, AV_LOG_DEBUG, "1/%d frame drop:\n", dm->cycle); - for (i = 0; i < dm->cycle && dm->queue[i].frame; i++) { - av_log(ctx, AV_LOG_DEBUG," #%d: totdiff=%08"PRIx64" maxbdiff=%08"PRIx64"%s%s%s%s\n", - i + 1, dm->queue[i].totdiff, dm->queue[i].maxbdiff, - i == scpos ? " sc" : "", - i == duppos ? " dup" : "", - i == lowest ? " lowest" : "", - i == drop ? " [DROP]" : ""); - } - } - - /* push all frames except the drop */ - ret = 0; - for (i = 0; i < dm->cycle && dm->queue[i].frame; i++) { - if (i == drop) { - if (dm->ppsrc) - av_frame_free(&dm->clean_src[i]); - av_frame_free(&dm->queue[i].frame); - } else { - AVFrame *frame = dm->queue[i].frame; - if (frame->pts != AV_NOPTS_VALUE && dm->start_pts == AV_NOPTS_VALUE) - dm->start_pts = frame->pts; - if (dm->ppsrc) { - av_frame_free(&frame); - frame = dm->clean_src[i]; - } - frame->pts = outlink->frame_count * dm->ts_unit + - (dm->start_pts == AV_NOPTS_VALUE ? 0 : dm->start_pts); - ret = ff_filter_frame(outlink, frame); - if (ret < 0) - break; - } - } - - return ret; -} - -static int config_input(AVFilterLink *inlink) -{ - int max_value; - AVFilterContext *ctx = inlink->dst; - DecimateContext *dm = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - const int w = inlink->w; - const int h = inlink->h; - - dm->hsub = pix_desc->log2_chroma_w; - dm->vsub = pix_desc->log2_chroma_h; - dm->depth = pix_desc->comp[0].depth_minus1 + 1; - max_value = (1 << dm->depth) - 1; - dm->scthresh = (int64_t)(((int64_t)max_value * w * h * dm->scthresh_flt) / 100); - dm->dupthresh = (int64_t)(((int64_t)max_value * dm->blockx * dm->blocky * dm->dupthresh_flt) / 100); - dm->nxblocks = (w + dm->blockx/2 - 1) / (dm->blockx/2); - dm->nyblocks = (h + dm->blocky/2 - 1) / (dm->blocky/2); - dm->bdiffsize = dm->nxblocks * dm->nyblocks; - dm->bdiffs = av_malloc(dm->bdiffsize * sizeof(*dm->bdiffs)); - dm->queue = av_calloc(dm->cycle, sizeof(*dm->queue)); - - if (!dm->bdiffs || !dm->queue) - return AVERROR(ENOMEM); - - if (dm->ppsrc) { - dm->clean_src = av_calloc(dm->cycle, sizeof(*dm->clean_src)); - if (!dm->clean_src) - return AVERROR(ENOMEM); - } - - return 0; -} - -static av_cold int decimate_init(AVFilterContext *ctx) -{ - DecimateContext *dm = ctx->priv; - AVFilterPad pad = { - .name = av_strdup("main"), - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }; - - if (!pad.name) - return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_MAIN, &pad); - - if (dm->ppsrc) { - pad.name = av_strdup("clean_src"); - pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad); - } - - if ((dm->blockx & (dm->blockx - 1)) || - (dm->blocky & (dm->blocky - 1))) { - av_log(ctx, AV_LOG_ERROR, "blockx and blocky settings must be power of two\n"); - return AVERROR(EINVAL); - } - - dm->start_pts = AV_NOPTS_VALUE; - - return 0; -} - -static av_cold void decimate_uninit(AVFilterContext *ctx) -{ - int i; - DecimateContext *dm = ctx->priv; - - av_frame_free(&dm->last); - av_freep(&dm->bdiffs); - av_freep(&dm->queue); - av_freep(&dm->clean_src); - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); -} - -static int request_inlink(AVFilterContext *ctx, int lid) -{ - int ret = 0; - DecimateContext *dm = ctx->priv; - - if (!dm->got_frame[lid]) { - AVFilterLink *inlink = ctx->inputs[lid]; - ret = ff_request_frame(inlink); - if (ret == AVERROR_EOF) { // flushing - dm->eof |= 1 << lid; - ret = filter_frame(inlink, NULL); - } - } - return ret; -} - -static int request_frame(AVFilterLink *outlink) -{ - int ret; - AVFilterContext *ctx = outlink->src; - DecimateContext *dm = ctx->priv; - const uint32_t eof_mask = 1<<INPUT_MAIN | dm->ppsrc<<INPUT_CLEANSRC; - - if ((dm->eof & eof_mask) == eof_mask) // flush done? - return AVERROR_EOF; - if ((ret = request_inlink(ctx, INPUT_MAIN)) < 0) - return ret; - if (dm->ppsrc && (ret = request_inlink(ctx, INPUT_CLEANSRC)) < 0) - return ret; - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { -#define PF_NOALPHA(suf) AV_PIX_FMT_YUV420##suf, AV_PIX_FMT_YUV422##suf, AV_PIX_FMT_YUV444##suf -#define PF_ALPHA(suf) AV_PIX_FMT_YUVA420##suf, AV_PIX_FMT_YUVA422##suf, AV_PIX_FMT_YUVA444##suf -#define PF(suf) PF_NOALPHA(suf), PF_ALPHA(suf) - PF(P), PF(P9), PF(P10), PF_NOALPHA(P12), PF_NOALPHA(P14), PF(P16), - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - DecimateContext *dm = ctx->priv; - const AVFilterLink *inlink = - ctx->inputs[dm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN]; - AVRational fps = inlink->frame_rate; - - if (!fps.num || !fps.den) { - av_log(ctx, AV_LOG_ERROR, "The input needs a constant frame rate; " - "current rate of %d/%d is invalid\n", fps.num, fps.den); - return AVERROR(EINVAL); - } - fps = av_mul_q(fps, (AVRational){dm->cycle - 1, dm->cycle}); - av_log(ctx, AV_LOG_VERBOSE, "FPS: %d/%d -> %d/%d\n", - inlink->frame_rate.num, inlink->frame_rate.den, fps.num, fps.den); - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - outlink->time_base = inlink->time_base; - outlink->frame_rate = fps; - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - outlink->w = inlink->w; - outlink->h = inlink->h; - dm->ts_unit = av_q2d(av_inv_q(av_mul_q(fps, outlink->time_base))); - return 0; -} - -static const AVFilterPad decimate_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_decimate = { - .name = "decimate", - .description = NULL_IF_CONFIG_SMALL("Decimate frames (post field matching filter)."), - .init = decimate_init, - .uninit = decimate_uninit, - .priv_size = sizeof(DecimateContext), - .query_formats = query_formats, - .outputs = decimate_outputs, - .priv_class = &decimate_class, - .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, -}; diff --git a/ffmpeg/libavfilter/vf_delogo.c b/ffmpeg/libavfilter/vf_delogo.c deleted file mode 100644 index fbc8983..0000000 --- a/ffmpeg/libavfilter/vf_delogo.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (c) 2002 Jindrich Makovicka <makovick@gmail.com> - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2013 Jean Delvare <khali@linux-fr.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, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/** - * @file - * A very simple tv station logo remover - * Originally imported from MPlayer libmpcodecs/vf_delogo.c, - * the algorithm was later improved. - */ - -#include "libavutil/common.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -/** - * Apply a simple delogo algorithm to the image in src and put the - * result in dst. - * - * The algorithm is only applied to the region specified by the logo - * parameters. - * - * @param w width of the input image - * @param h height of the input image - * @param logo_x x coordinate of the top left corner of the logo region - * @param logo_y y coordinate of the top left corner of the logo region - * @param logo_w width of the logo - * @param logo_h height of the logo - * @param band the size of the band around the processed area - * @param show show a rectangle around the processed area, useful for - * parameters tweaking - * @param direct if non-zero perform in-place processing - */ -static void apply_delogo(uint8_t *dst, int dst_linesize, - uint8_t *src, int src_linesize, - int w, int h, AVRational sar, - int logo_x, int logo_y, int logo_w, int logo_h, - unsigned int band, int show, int direct) -{ - int x, y; - uint64_t interp, weightl, weightr, weightt, weightb; - uint8_t *xdst, *xsrc; - - uint8_t *topleft, *botleft, *topright; - unsigned int left_sample, right_sample; - int xclipl, xclipr, yclipt, yclipb; - int logo_x1, logo_x2, logo_y1, logo_y2; - - xclipl = FFMAX(-logo_x, 0); - xclipr = FFMAX(logo_x+logo_w-w, 0); - yclipt = FFMAX(-logo_y, 0); - yclipb = FFMAX(logo_y+logo_h-h, 0); - - logo_x1 = logo_x + xclipl; - logo_x2 = logo_x + logo_w - xclipr; - logo_y1 = logo_y + yclipt; - logo_y2 = logo_y + logo_h - yclipb; - - topleft = src+logo_y1 * src_linesize+logo_x1; - topright = src+logo_y1 * src_linesize+logo_x2-1; - botleft = src+(logo_y2-1) * src_linesize+logo_x1; - - if (!direct) - av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h); - - dst += (logo_y1 + 1) * dst_linesize; - src += (logo_y1 + 1) * src_linesize; - - for (y = logo_y1+1; y < logo_y2-1; y++) { - left_sample = topleft[src_linesize*(y-logo_y1)] + - topleft[src_linesize*(y-logo_y1-1)] + - topleft[src_linesize*(y-logo_y1+1)]; - right_sample = topright[src_linesize*(y-logo_y1)] + - topright[src_linesize*(y-logo_y1-1)] + - topright[src_linesize*(y-logo_y1+1)]; - - for (x = logo_x1+1, - xdst = dst+logo_x1+1, - xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) { - - /* Weighted interpolation based on relative distances, taking SAR into account */ - weightl = (uint64_t) (logo_x2-1-x) * (y-logo_y1) * (logo_y2-1-y) * sar.den; - weightr = (uint64_t)(x-logo_x1) * (y-logo_y1) * (logo_y2-1-y) * sar.den; - weightt = (uint64_t)(x-logo_x1) * (logo_x2-1-x) * (logo_y2-1-y) * sar.num; - weightb = (uint64_t)(x-logo_x1) * (logo_x2-1-x) * (y-logo_y1) * sar.num; - - interp = - left_sample * weightl - + - right_sample * weightr - + - (topleft[x-logo_x1] + - topleft[x-logo_x1-1] + - topleft[x-logo_x1+1]) * weightt - + - (botleft[x-logo_x1] + - botleft[x-logo_x1-1] + - botleft[x-logo_x1+1]) * weightb; - interp /= (weightl + weightr + weightt + weightb) * 3U; - - if (y >= logo_y+band && y < logo_y+logo_h-band && - x >= logo_x+band && x < logo_x+logo_w-band) { - *xdst = interp; - } else { - unsigned dist = 0; - - if (x < logo_x+band) - dist = FFMAX(dist, logo_x-x+band); - else if (x >= logo_x+logo_w-band) - dist = FFMAX(dist, x-(logo_x+logo_w-1-band)); - - if (y < logo_y+band) - dist = FFMAX(dist, logo_y-y+band); - else if (y >= logo_y+logo_h-band) - dist = FFMAX(dist, y-(logo_y+logo_h-1-band)); - - *xdst = (*xsrc*dist + interp*(band-dist))/band; - if (show && (dist == band-1)) - *xdst = 0; - } - } - - dst += dst_linesize; - src += src_linesize; - } -} - -typedef struct { - const AVClass *class; - int x, y, w, h, band, show; -} DelogoContext; - -#define OFFSET(x) offsetof(DelogoContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption delogo_options[]= { - { "x", "set logo x position", OFFSET(x), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "y", "set logo y position", OFFSET(y), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "w", "set logo width", OFFSET(w), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "h", "set logo height", OFFSET(h), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, - { "band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 = 4 }, 1, INT_MAX, FLAGS }, - { "t", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, { .i64 = 4 }, 1, INT_MAX, FLAGS }, - { "show", "show delogo area", OFFSET(show), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(delogo); - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_GRAY8, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - DelogoContext *s = ctx->priv; - -#define CHECK_UNSET_OPT(opt) \ - if (s->opt == -1) { \ - av_log(s, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \ - return AVERROR(EINVAL); \ - } - CHECK_UNSET_OPT(x); - CHECK_UNSET_OPT(y); - CHECK_UNSET_OPT(w); - CHECK_UNSET_OPT(h); - - av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d, w:%d h:%d band:%d show:%d\n", - s->x, s->y, s->w, s->h, s->band, s->show); - - s->w += s->band*2; - s->h += s->band*2; - s->x -= s->band; - s->y -= s->band; - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - DelogoContext *s = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - AVFrame *out; - int hsub0 = desc->log2_chroma_w; - int vsub0 = desc->log2_chroma_h; - int direct = 0; - int plane; - AVRational sar; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - av_frame_copy_props(out, in); - } - - sar = in->sample_aspect_ratio; - /* Assume square pixels if SAR is unknown */ - if (!sar.num) - sar.num = sar.den = 1; - - for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { - int hsub = plane == 1 || plane == 2 ? hsub0 : 0; - int vsub = plane == 1 || plane == 2 ? vsub0 : 0; - - apply_delogo(out->data[plane], out->linesize[plane], - in ->data[plane], in ->linesize[plane], - FF_CEIL_RSHIFT(inlink->w, hsub), - FF_CEIL_RSHIFT(inlink->h, vsub), - sar, s->x>>hsub, s->y>>vsub, - /* Up and left borders were rounded down, inject lost bits - * into width and height to avoid error accumulation */ - FF_CEIL_RSHIFT(s->w + (s->x & ((1<<hsub)-1)), hsub), - FF_CEIL_RSHIFT(s->h + (s->y & ((1<<vsub)-1)), vsub), - s->band>>FFMIN(hsub, vsub), - s->show, direct); - } - - if (!direct) - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad avfilter_vf_delogo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_delogo_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_delogo = { - .name = "delogo", - .description = NULL_IF_CONFIG_SMALL("Remove logo from input video."), - .priv_size = sizeof(DelogoContext), - .priv_class = &delogo_class, - .init = init, - .query_formats = query_formats, - .inputs = avfilter_vf_delogo_inputs, - .outputs = avfilter_vf_delogo_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_deshake.c b/ffmpeg/libavfilter/vf_deshake.c deleted file mode 100644 index 1d62c44..0000000 --- a/ffmpeg/libavfilter/vf_deshake.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Copyright (C) 2010 Georg Martius <georg.martius@web.de> - * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * fast deshake / depan video filter - * - * SAD block-matching motion compensation to fix small changes in - * horizontal and/or vertical shift. This filter helps remove camera shake - * from hand-holding a camera, bumping a tripod, moving on a vehicle, etc. - * - * Algorithm: - * - For each frame with one previous reference frame - * - For each block in the frame - * - If contrast > threshold then find likely motion vector - * - For all found motion vectors - * - Find most common, store as global motion vector - * - Find most likely rotation angle - * - Transform image along global motion - * - * TODO: - * - Fill frame edges based on previous/next reference frames - * - Fill frame edges by stretching image near the edges? - * - Can this be done quickly and look decent? - * - * Dark Shikari links to http://wiki.videolan.org/SoC_x264_2010#GPU_Motion_Estimation_2 - * for an algorithm similar to what could be used here to get the gmv - * It requires only a couple diamond searches + fast downscaling - * - * Special thanks to Jason Kotenko for his help with the algorithm and my - * inability to see simple errors in C code. - */ - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/common.h" -#include "libavutil/mem.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavcodec/dsputil.h" - -#include "deshake.h" -#include "deshake_opencl.h" - -#define CHROMA_WIDTH(link) -((-link->w) >> av_pix_fmt_desc_get(link->format)->log2_chroma_w) -#define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_desc_get(link->format)->log2_chroma_h) - -#define OFFSET(x) offsetof(DeshakeContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define MAX_R 64 - -static const AVOption deshake_options[] = { - { "x", "set x for the rectangular search area", OFFSET(cx), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "y", "set y for the rectangular search area", OFFSET(cy), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "w", "set width for the rectangular search area", OFFSET(cw), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "h", "set height for the rectangular search area", OFFSET(ch), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, .flags = FLAGS }, - { "rx", "set x for the rectangular search area", OFFSET(rx), AV_OPT_TYPE_INT, {.i64=16}, 0, MAX_R, .flags = FLAGS }, - { "ry", "set y for the rectangular search area", OFFSET(ry), AV_OPT_TYPE_INT, {.i64=16}, 0, MAX_R, .flags = FLAGS }, - { "edge", "set edge mode", OFFSET(edge), AV_OPT_TYPE_INT, {.i64=FILL_MIRROR}, FILL_BLANK, FILL_COUNT-1, FLAGS, "edge"}, - { "blank", "fill zeroes at blank locations", 0, AV_OPT_TYPE_CONST, {.i64=FILL_BLANK}, INT_MIN, INT_MAX, FLAGS, "edge" }, - { "original", "original image at blank locations", 0, AV_OPT_TYPE_CONST, {.i64=FILL_ORIGINAL}, INT_MIN, INT_MAX, FLAGS, "edge" }, - { "clamp", "extruded edge value at blank locations", 0, AV_OPT_TYPE_CONST, {.i64=FILL_CLAMP}, INT_MIN, INT_MAX, FLAGS, "edge" }, - { "mirror", "mirrored edge at blank locations", 0, AV_OPT_TYPE_CONST, {.i64=FILL_MIRROR}, INT_MIN, INT_MAX, FLAGS, "edge" }, - { "blocksize", "set motion search blocksize", OFFSET(blocksize), AV_OPT_TYPE_INT, {.i64=8}, 4, 128, .flags = FLAGS }, - { "contrast", "set contrast threshold for blocks", OFFSET(contrast), AV_OPT_TYPE_INT, {.i64=125}, 1, 255, .flags = FLAGS }, - { "search", "set search strategy", OFFSET(search), AV_OPT_TYPE_INT, {.i64=EXHAUSTIVE}, EXHAUSTIVE, SEARCH_COUNT-1, FLAGS, "smode" }, - { "exhaustive", "exhaustive search", 0, AV_OPT_TYPE_CONST, {.i64=EXHAUSTIVE}, INT_MIN, INT_MAX, FLAGS, "smode" }, - { "less", "less exhaustive search", 0, AV_OPT_TYPE_CONST, {.i64=SMART_EXHAUSTIVE}, INT_MIN, INT_MAX, FLAGS, "smode" }, - { "filename", "set motion search detailed log file name", OFFSET(filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "opencl", "use OpenCL filtering capabilities", OFFSET(opencl), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(deshake); - -static int cmp(const double *a, const double *b) -{ - return *a < *b ? -1 : ( *a > *b ? 1 : 0 ); -} - -/** - * Cleaned mean (cuts off 20% of values to remove outliers and then averages) - */ -static double clean_mean(double *values, int count) -{ - double mean = 0; - int cut = count / 5; - int x; - - qsort(values, count, sizeof(double), (void*)cmp); - - for (x = cut; x < count - cut; x++) { - mean += values[x]; - } - - return mean / (count - cut * 2); -} - -/** - * Find the most likely shift in motion between two frames for a given - * macroblock. Test each block against several shifts given by the rx - * and ry attributes. Searches using a simple matrix of those shifts and - * chooses the most likely shift by the smallest difference in blocks. - */ -static void find_block_motion(DeshakeContext *deshake, uint8_t *src1, - uint8_t *src2, int cx, int cy, int stride, - IntMotionVector *mv) -{ - int x, y; - int diff; - int smallest = INT_MAX; - int tmp, tmp2; - - #define CMP(i, j) deshake->c.sad[0](deshake, src1 + cy * stride + cx, \ - src2 + (j) * stride + (i), stride, \ - deshake->blocksize) - - if (deshake->search == EXHAUSTIVE) { - // Compare every possible position - this is sloooow! - for (y = -deshake->ry; y <= deshake->ry; y++) { - for (x = -deshake->rx; x <= deshake->rx; x++) { - diff = CMP(cx - x, cy - y); - if (diff < smallest) { - smallest = diff; - mv->x = x; - mv->y = y; - } - } - } - } else if (deshake->search == SMART_EXHAUSTIVE) { - // Compare every other possible position and find the best match - for (y = -deshake->ry + 1; y < deshake->ry; y += 2) { - for (x = -deshake->rx + 1; x < deshake->rx; x += 2) { - diff = CMP(cx - x, cy - y); - if (diff < smallest) { - smallest = diff; - mv->x = x; - mv->y = y; - } - } - } - - // Hone in on the specific best match around the match we found above - tmp = mv->x; - tmp2 = mv->y; - - for (y = tmp2 - 1; y <= tmp2 + 1; y++) { - for (x = tmp - 1; x <= tmp + 1; x++) { - if (x == tmp && y == tmp2) - continue; - - diff = CMP(cx - x, cy - y); - if (diff < smallest) { - smallest = diff; - mv->x = x; - mv->y = y; - } - } - } - } - - if (smallest > 512) { - mv->x = -1; - mv->y = -1; - } - emms_c(); - //av_log(NULL, AV_LOG_ERROR, "%d\n", smallest); - //av_log(NULL, AV_LOG_ERROR, "Final: (%d, %d) = %d x %d\n", cx, cy, mv->x, mv->y); -} - -/** - * Find the contrast of a given block. When searching for global motion we - * really only care about the high contrast blocks, so using this method we - * can actually skip blocks we don't care much about. - */ -static int block_contrast(uint8_t *src, int x, int y, int stride, int blocksize) -{ - int highest = 0; - int lowest = 255; - int i, j, pos; - - for (i = 0; i <= blocksize * 2; i++) { - // We use a width of 16 here to match the libavcodec sad functions - for (j = 0; j <= 15; j++) { - pos = (y - i) * stride + (x - j); - if (src[pos] < lowest) - lowest = src[pos]; - else if (src[pos] > highest) { - highest = src[pos]; - } - } - } - - return highest - lowest; -} - -/** - * Find the rotation for a given block. - */ -static double block_angle(int x, int y, int cx, int cy, IntMotionVector *shift) -{ - double a1, a2, diff; - - a1 = atan2(y - cy, x - cx); - a2 = atan2(y - cy + shift->y, x - cx + shift->x); - - diff = a2 - a1; - - return (diff > M_PI) ? diff - 2 * M_PI : - (diff < -M_PI) ? diff + 2 * M_PI : - diff; -} - -/** - * Find the estimated global motion for a scene given the most likely shift - * for each block in the frame. The global motion is estimated to be the - * same as the motion from most blocks in the frame, so if most blocks - * move one pixel to the right and two pixels down, this would yield a - * motion vector (1, -2). - */ -static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, - int width, int height, int stride, Transform *t) -{ - int x, y; - IntMotionVector mv = {0, 0}; - int counts[2*MAX_R+1][2*MAX_R+1]; - int count_max_value = 0; - int contrast; - - int pos; - double *angles = av_malloc(sizeof(*angles) * width * height / (16 * deshake->blocksize)); - int center_x = 0, center_y = 0; - double p_x, p_y; - - // Reset counts to zero - for (x = 0; x < deshake->rx * 2 + 1; x++) { - for (y = 0; y < deshake->ry * 2 + 1; y++) { - counts[x][y] = 0; - } - } - - pos = 0; - // Find motion for every block and store the motion vector in the counts - for (y = deshake->ry; y < height - deshake->ry - (deshake->blocksize * 2); y += deshake->blocksize * 2) { - // We use a width of 16 here to match the libavcodec sad functions - for (x = deshake->rx; x < width - deshake->rx - 16; x += 16) { - // If the contrast is too low, just skip this block as it probably - // won't be very useful to us. - contrast = block_contrast(src2, x, y, stride, deshake->blocksize); - if (contrast > deshake->contrast) { - //av_log(NULL, AV_LOG_ERROR, "%d\n", contrast); - find_block_motion(deshake, src1, src2, x, y, stride, &mv); - if (mv.x != -1 && mv.y != -1) { - counts[mv.x + deshake->rx][mv.y + deshake->ry] += 1; - if (x > deshake->rx && y > deshake->ry) - angles[pos++] = block_angle(x, y, 0, 0, &mv); - - center_x += mv.x; - center_y += mv.y; - } - } - } - } - - if (pos) { - center_x /= pos; - center_y /= pos; - t->angle = clean_mean(angles, pos); - if (t->angle < 0.001) - t->angle = 0; - } else { - t->angle = 0; - } - - // Find the most common motion vector in the frame and use it as the gmv - for (y = deshake->ry * 2; y >= 0; y--) { - for (x = 0; x < deshake->rx * 2 + 1; x++) { - //av_log(NULL, AV_LOG_ERROR, "%5d ", counts[x][y]); - if (counts[x][y] > count_max_value) { - t->vector.x = x - deshake->rx; - t->vector.y = y - deshake->ry; - count_max_value = counts[x][y]; - } - } - //av_log(NULL, AV_LOG_ERROR, "\n"); - } - - p_x = (center_x - width / 2); - p_y = (center_y - height / 2); - t->vector.x += (cos(t->angle)-1)*p_x - sin(t->angle)*p_y; - t->vector.y += sin(t->angle)*p_x + (cos(t->angle)-1)*p_y; - - // Clamp max shift & rotation? - t->vector.x = av_clipf(t->vector.x, -deshake->rx * 2, deshake->rx * 2); - t->vector.y = av_clipf(t->vector.y, -deshake->ry * 2, deshake->ry * 2); - t->angle = av_clipf(t->angle, -0.1, 0.1); - - //av_log(NULL, AV_LOG_ERROR, "%d x %d\n", avg->x, avg->y); - av_free(angles); -} - -static int deshake_transform_c(AVFilterContext *ctx, - int width, int height, int cw, int ch, - const float *matrix_y, const float *matrix_uv, - enum InterpolateMethod interpolate, - enum FillMethod fill, AVFrame *in, AVFrame *out) -{ - int i = 0, ret = 0; - const float *matrixs[3]; - int plane_w[3], plane_h[3]; - matrixs[0] = matrix_y; - matrixs[1] = matrixs[2] = matrix_uv; - plane_w[0] = width; - plane_w[1] = plane_w[2] = cw; - plane_h[0] = height; - plane_h[1] = plane_h[2] = ch; - - for (i = 0; i < 3; i++) { - // Transform the luma and chroma planes - ret = avfilter_transform(in->data[i], out->data[i], in->linesize[i], out->linesize[i], - plane_w[i], plane_h[i], matrixs[i], interpolate, fill); - if (ret < 0) - return ret; - } - return ret; -} - -static av_cold int init(AVFilterContext *ctx) -{ - int ret; - DeshakeContext *deshake = ctx->priv; - - deshake->refcount = 20; // XXX: add to options? - deshake->blocksize /= 2; - deshake->blocksize = av_clip(deshake->blocksize, 4, 128); - - if (deshake->rx % 16) { - av_log(ctx, AV_LOG_ERROR, "rx must be a multiple of 16\n"); - return AVERROR_PATCHWELCOME; - } - - if (deshake->filename) - deshake->fp = fopen(deshake->filename, "w"); - if (deshake->fp) - fwrite("Ori x, Avg x, Fin x, Ori y, Avg y, Fin y, Ori angle, Avg angle, Fin angle, Ori zoom, Avg zoom, Fin zoom\n", sizeof(char), 104, deshake->fp); - - // Quadword align left edge of box for MMX code, adjust width if necessary - // to keep right margin - if (deshake->cx > 0) { - deshake->cw += deshake->cx - (deshake->cx & ~15); - deshake->cx &= ~15; - } - deshake->transform = deshake_transform_c; - if (!CONFIG_OPENCL && deshake->opencl) { - av_log(ctx, AV_LOG_ERROR, "OpenCL support was not enabled in this build, cannot be selected\n"); - return AVERROR(EINVAL); - } - - if (CONFIG_OPENCL && deshake->opencl) { - deshake->transform = ff_opencl_transform; - ret = ff_opencl_deshake_init(ctx); - if (ret < 0) - return ret; - } - av_log(ctx, AV_LOG_VERBOSE, "cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n", - deshake->cx, deshake->cy, deshake->cw, deshake->ch, - deshake->rx, deshake->ry, deshake->edge, deshake->blocksize * 2, deshake->contrast, deshake->search); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_props(AVFilterLink *link) -{ - DeshakeContext *deshake = link->dst->priv; - - deshake->ref = NULL; - deshake->last.vector.x = 0; - deshake->last.vector.y = 0; - deshake->last.angle = 0; - deshake->last.zoom = 0; - - deshake->avctx = avcodec_alloc_context3(NULL); - avpriv_dsputil_init(&deshake->c, deshake->avctx); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - DeshakeContext *deshake = ctx->priv; - if (CONFIG_OPENCL && deshake->opencl) { - ff_opencl_deshake_uninit(ctx); - } - av_frame_free(&deshake->ref); - if (deshake->fp) - fclose(deshake->fp); - if (deshake->avctx) - avcodec_close(deshake->avctx); - av_freep(&deshake->avctx); -} - -static int filter_frame(AVFilterLink *link, AVFrame *in) -{ - DeshakeContext *deshake = link->dst->priv; - AVFilterLink *outlink = link->dst->outputs[0]; - AVFrame *out; - Transform t = {{0},0}, orig = {{0},0}; - float matrix_y[9], matrix_uv[9]; - float alpha = 2.0 / deshake->refcount; - char tmp[256]; - int ret = 0; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - if (CONFIG_OPENCL && deshake->opencl) { - ret = ff_opencl_deshake_process_inout_buf(link->dst,in, out); - if (ret < 0) - return ret; - } - - if (deshake->cx < 0 || deshake->cy < 0 || deshake->cw < 0 || deshake->ch < 0) { - // Find the most likely global motion for the current frame - find_motion(deshake, (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0], in->data[0], link->w, link->h, in->linesize[0], &t); - } else { - uint8_t *src1 = (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0]; - uint8_t *src2 = in->data[0]; - - deshake->cx = FFMIN(deshake->cx, link->w); - deshake->cy = FFMIN(deshake->cy, link->h); - - if ((unsigned)deshake->cx + (unsigned)deshake->cw > link->w) deshake->cw = link->w - deshake->cx; - if ((unsigned)deshake->cy + (unsigned)deshake->ch > link->h) deshake->ch = link->h - deshake->cy; - - // Quadword align right margin - deshake->cw &= ~15; - - src1 += deshake->cy * in->linesize[0] + deshake->cx; - src2 += deshake->cy * in->linesize[0] + deshake->cx; - - find_motion(deshake, src1, src2, deshake->cw, deshake->ch, in->linesize[0], &t); - } - - - // Copy transform so we can output it later to compare to the smoothed value - orig.vector.x = t.vector.x; - orig.vector.y = t.vector.y; - orig.angle = t.angle; - orig.zoom = t.zoom; - - // Generate a one-sided moving exponential average - deshake->avg.vector.x = alpha * t.vector.x + (1.0 - alpha) * deshake->avg.vector.x; - deshake->avg.vector.y = alpha * t.vector.y + (1.0 - alpha) * deshake->avg.vector.y; - deshake->avg.angle = alpha * t.angle + (1.0 - alpha) * deshake->avg.angle; - deshake->avg.zoom = alpha * t.zoom + (1.0 - alpha) * deshake->avg.zoom; - - // Remove the average from the current motion to detect the motion that - // is not on purpose, just as jitter from bumping the camera - t.vector.x -= deshake->avg.vector.x; - t.vector.y -= deshake->avg.vector.y; - t.angle -= deshake->avg.angle; - t.zoom -= deshake->avg.zoom; - - // Invert the motion to undo it - t.vector.x *= -1; - t.vector.y *= -1; - t.angle *= -1; - - // Write statistics to file - if (deshake->fp) { - snprintf(tmp, 256, "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", orig.vector.x, deshake->avg.vector.x, t.vector.x, orig.vector.y, deshake->avg.vector.y, t.vector.y, orig.angle, deshake->avg.angle, t.angle, orig.zoom, deshake->avg.zoom, t.zoom); - fwrite(tmp, sizeof(char), strlen(tmp), deshake->fp); - } - - // Turn relative current frame motion into absolute by adding it to the - // last absolute motion - t.vector.x += deshake->last.vector.x; - t.vector.y += deshake->last.vector.y; - t.angle += deshake->last.angle; - t.zoom += deshake->last.zoom; - - // Shrink motion by 10% to keep things centered in the camera frame - t.vector.x *= 0.9; - t.vector.y *= 0.9; - t.angle *= 0.9; - - // Store the last absolute motion information - deshake->last.vector.x = t.vector.x; - deshake->last.vector.y = t.vector.y; - deshake->last.angle = t.angle; - deshake->last.zoom = t.zoom; - - // Generate a luma transformation matrix - avfilter_get_matrix(t.vector.x, t.vector.y, t.angle, 1.0 + t.zoom / 100.0, matrix_y); - // Generate a chroma transformation matrix - avfilter_get_matrix(t.vector.x / (link->w / CHROMA_WIDTH(link)), t.vector.y / (link->h / CHROMA_HEIGHT(link)), t.angle, 1.0 + t.zoom / 100.0, matrix_uv); - // Transform the luma and chroma planes - ret = deshake->transform(link->dst, link->w, link->h, CHROMA_WIDTH(link), CHROMA_HEIGHT(link), - matrix_y, matrix_uv, INTERPOLATE_BILINEAR, deshake->edge, in, out); - - // Cleanup the old reference frame - av_frame_free(&deshake->ref); - - if (ret < 0) - return ret; - - // Store the current frame as the reference frame for calculating the - // motion of the next frame - deshake->ref = in; - - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad deshake_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad deshake_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_deshake = { - .name = "deshake", - .description = NULL_IF_CONFIG_SMALL("Stabilize shaky video."), - .priv_size = sizeof(DeshakeContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = deshake_inputs, - .outputs = deshake_outputs, - .priv_class = &deshake_class, -}; diff --git a/ffmpeg/libavfilter/vf_drawbox.c b/ffmpeg/libavfilter/vf_drawbox.c deleted file mode 100644 index dd884a7..0000000 --- a/ffmpeg/libavfilter/vf_drawbox.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Copyright (c) 2008 Affine Systems, Inc (Michael Sullivan, Bobby Impollonia) - * Copyright (c) 2013 Andrey Utkin <andrey.krieger.utkin gmail com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Box and grid drawing filters. Also a nice template for a filter - * that needs to write in the input frame. - */ - -#include "libavutil/colorspace.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" -#include "libavutil/eval.h" -#include "libavutil/pixdesc.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { - "dar", - "hsub", "vsub", - "in_h", "ih", ///< height of the input video - "in_w", "iw", ///< width of the input video - "sar", - "x", - "y", - "h", ///< height of the rendered box - "w", ///< width of the rendered box - "t", - NULL -}; - -enum { Y, U, V, A }; - -enum var_name { - VAR_DAR, - VAR_HSUB, VAR_VSUB, - VAR_IN_H, VAR_IH, - VAR_IN_W, VAR_IW, - VAR_SAR, - VAR_X, - VAR_Y, - VAR_H, - VAR_W, - VAR_T, - VARS_NB -}; - -typedef struct { - const AVClass *class; - int x, y, w, h; - int thickness; - char *color_str; - unsigned char yuv_color[4]; - int invert_color; ///< invert luma color - int vsub, hsub; ///< chroma subsampling - char *x_expr, *y_expr; ///< expression for x and y - char *w_expr, *h_expr; ///< expression for width and height - char *t_expr; ///< expression for thickness -} DrawBoxContext; - -static const int NUM_EXPR_EVALS = 5; - -static av_cold int init(AVFilterContext *ctx) -{ - DrawBoxContext *s = ctx->priv; - uint8_t rgba_color[4]; - - if (!strcmp(s->color_str, "invert")) - s->invert_color = 1; - else if (av_parse_color(rgba_color, s->color_str, -1, ctx) < 0) - return AVERROR(EINVAL); - - if (!s->invert_color) { - s->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]); - s->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - s->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0); - s->yuv_color[A] = rgba_color[3]; - } - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - DrawBoxContext *s = ctx->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - double var_values[VARS_NB], res; - char *expr; - int ret; - int i; - - s->hsub = desc->log2_chroma_w; - s->vsub = desc->log2_chroma_h; - - var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; - var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; - var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1; - var_values[VAR_DAR] = (double)inlink->w / inlink->h * var_values[VAR_SAR]; - var_values[VAR_HSUB] = s->hsub; - var_values[VAR_VSUB] = s->vsub; - var_values[VAR_X] = NAN; - var_values[VAR_Y] = NAN; - var_values[VAR_H] = NAN; - var_values[VAR_W] = NAN; - var_values[VAR_T] = NAN; - - for (i = 0; i <= NUM_EXPR_EVALS; i++) { - /* evaluate expressions, fail on last iteration */ - if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS) - goto fail; - s->x = var_values[VAR_X] = res; - - if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS) - goto fail; - s->y = var_values[VAR_Y] = res; - - if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS) - goto fail; - s->w = var_values[VAR_W] = res; - - if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS) - goto fail; - s->h = var_values[VAR_H] = res; - - if ((ret = av_expr_parse_and_eval(&res, (expr = s->t_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0 && i == NUM_EXPR_EVALS) - goto fail; - s->thickness = var_values[VAR_T] = res; - } - - /* if w or h are zero, use the input w/h */ - s->w = (s->w > 0) ? s->w : inlink->w; - s->h = (s->h > 0) ? s->h : inlink->h; - - /* sanity check width and height */ - if (s->w < 0 || s->h < 0) { - av_log(ctx, AV_LOG_ERROR, "Size values less than 0 are not acceptable.\n"); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n", - s->x, s->y, s->w, s->h, - s->yuv_color[Y], s->yuv_color[U], s->yuv_color[V], s->yuv_color[A]); - - return 0; - -fail: - av_log(ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s'.\n", - expr); - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - DrawBoxContext *s = inlink->dst->priv; - int plane, x, y, xb = s->x, yb = s->y; - unsigned char *row[4]; - - for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) { - row[0] = frame->data[0] + y * frame->linesize[0]; - - for (plane = 1; plane < 3; plane++) - row[plane] = frame->data[plane] + - frame->linesize[plane] * (y >> s->vsub); - - if (s->invert_color) { - for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) - row[0][x] = 0xff - row[0][x]; - } else { - for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) { - double alpha = (double)s->yuv_color[A] / 255; - - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) { - row[0][x ] = (1 - alpha) * row[0][x ] + alpha * s->yuv_color[Y]; - row[1][x >> s->hsub] = (1 - alpha) * row[1][x >> s->hsub] + alpha * s->yuv_color[U]; - row[2][x >> s->hsub] = (1 - alpha) * row[2][x >> s->hsub] + alpha * s->yuv_color[V]; - } - } - } - } - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -#define OFFSET(x) offsetof(DrawBoxContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#if CONFIG_DRAWBOX_FILTER - -static const AVOption drawbox_options[] = { - { "x", "set horizontal position of the left box edge", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set vertical position of the top box edge", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "width", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "height", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "color", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "thickness", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "t", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(drawbox); - -static const AVFilterPad drawbox_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad drawbox_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_drawbox = { - .name = "drawbox", - .description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."), - .priv_size = sizeof(DrawBoxContext), - .priv_class = &drawbox_class, - .init = init, - .query_formats = query_formats, - .inputs = drawbox_inputs, - .outputs = drawbox_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; -#endif /* CONFIG_DRAWBOX_FILTER */ - -#if CONFIG_DRAWGRID_FILTER -static av_pure av_always_inline int pixel_belongs_to_grid(DrawBoxContext *drawgrid, int x, int y) -{ - // x is horizontal (width) coord, - // y is vertical (height) coord - int x_modulo; - int y_modulo; - - // Abstract from the offset - x -= drawgrid->x; - y -= drawgrid->y; - - x_modulo = x % drawgrid->w; - y_modulo = y % drawgrid->h; - - // If x or y got negative, fix values to preserve logics - if (x_modulo < 0) - x_modulo += drawgrid->w; - if (y_modulo < 0) - y_modulo += drawgrid->h; - - return x_modulo < drawgrid->thickness // Belongs to vertical line - || y_modulo < drawgrid->thickness; // Belongs to horizontal line -} - -static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - DrawBoxContext *drawgrid = inlink->dst->priv; - int plane, x, y; - uint8_t *row[4]; - - for (y = 0; y < frame->height; y++) { - row[0] = frame->data[0] + y * frame->linesize[0]; - - for (plane = 1; plane < 3; plane++) - row[plane] = frame->data[plane] + - frame->linesize[plane] * (y >> drawgrid->vsub); - - if (drawgrid->invert_color) { - for (x = 0; x < frame->width; x++) - if (pixel_belongs_to_grid(drawgrid, x, y)) - row[0][x] = 0xff - row[0][x]; - } else { - for (x = 0; x < frame->width; x++) { - double alpha = (double)drawgrid->yuv_color[A] / 255; - - if (pixel_belongs_to_grid(drawgrid, x, y)) { - row[0][x ] = (1 - alpha) * row[0][x ] + alpha * drawgrid->yuv_color[Y]; - row[1][x >> drawgrid->hsub] = (1 - alpha) * row[1][x >> drawgrid->hsub] + alpha * drawgrid->yuv_color[U]; - row[2][x >> drawgrid->hsub] = (1 - alpha) * row[2][x >> drawgrid->hsub] + alpha * drawgrid->yuv_color[V]; - } - } - } - } - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -static const AVOption drawgrid_options[] = { - { "x", "set horizontal offset", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set vertical offset", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "width", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "height", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "color", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "thickness", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "t", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(drawgrid); - -static const AVFilterPad drawgrid_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = drawgrid_filter_frame, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad drawgrid_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_drawgrid = { - .name = "drawgrid", - .description = NULL_IF_CONFIG_SMALL("Draw a colored grid on the input video."), - .priv_size = sizeof(DrawBoxContext), - .priv_class = &drawgrid_class, - .init = init, - .query_formats = query_formats, - .inputs = drawgrid_inputs, - .outputs = drawgrid_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; - -#endif /* CONFIG_DRAWGRID_FILTER */ diff --git a/ffmpeg/libavfilter/vf_drawtext.c b/ffmpeg/libavfilter/vf_drawtext.c deleted file mode 100644 index 91b8218..0000000 --- a/ffmpeg/libavfilter/vf_drawtext.c +++ /dev/null @@ -1,1074 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram - * Copyright (c) 2003 Gustavo Sverzut Barbieri <gsbarbieri@yahoo.com.br> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * drawtext filter, based on the original vhook/drawtext.c - * filter by Gustavo Sverzut Barbieri - */ - -#include <sys/time.h> -#include <time.h> - -#include "config.h" -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/common.h" -#include "libavutil/file.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/random_seed.h" -#include "libavutil/parseutils.h" -#include "libavutil/timecode.h" -#include "libavutil/tree.h" -#include "libavutil/lfg.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_GLYPH_H -#if CONFIG_FONTCONFIG -#include <fontconfig/fontconfig.h> -#endif - -static const char *const var_names[] = { - "dar", - "hsub", "vsub", - "line_h", "lh", ///< line height, same as max_glyph_h - "main_h", "h", "H", ///< height of the input video - "main_w", "w", "W", ///< width of the input video - "max_glyph_a", "ascent", ///< max glyph ascent - "max_glyph_d", "descent", ///< min glyph descent - "max_glyph_h", ///< max glyph height - "max_glyph_w", ///< max glyph width - "n", ///< number of frame - "sar", - "t", ///< timestamp expressed in seconds - "text_h", "th", ///< height of the rendered text - "text_w", "tw", ///< width of the rendered text - "x", - "y", - "pict_type", - NULL -}; - -static const char *const fun2_names[] = { - "rand" -}; - -static double drand(void *opaque, double min, double max) -{ - return min + (max-min) / UINT_MAX * av_lfg_get(opaque); -} - -typedef double (*eval_func2)(void *, double a, double b); - -static const eval_func2 fun2[] = { - drand, - NULL -}; - -enum var_name { - VAR_DAR, - VAR_HSUB, VAR_VSUB, - VAR_LINE_H, VAR_LH, - VAR_MAIN_H, VAR_h, VAR_H, - VAR_MAIN_W, VAR_w, VAR_W, - VAR_MAX_GLYPH_A, VAR_ASCENT, - VAR_MAX_GLYPH_D, VAR_DESCENT, - VAR_MAX_GLYPH_H, - VAR_MAX_GLYPH_W, - VAR_N, - VAR_SAR, - VAR_T, - VAR_TEXT_H, VAR_TH, - VAR_TEXT_W, VAR_TW, - VAR_X, - VAR_Y, - VAR_PICT_TYPE, - VAR_VARS_NB -}; - -enum expansion_mode { - EXP_NONE, - EXP_NORMAL, - EXP_STRFTIME, -}; - -typedef struct { - const AVClass *class; - enum expansion_mode exp_mode; ///< expansion mode to use for the text - int reinit; ///< tells if the filter is being reinited - uint8_t *fontfile; ///< font to be used - uint8_t *text; ///< text to be drawn - AVBPrint expanded_text; ///< used to contain the expanded text - int ft_load_flags; ///< flags used for loading fonts, see FT_LOAD_* - FT_Vector *positions; ///< positions for each element in the text - size_t nb_positions; ///< number of elements of positions array - char *textfile; ///< file with text to be drawn - int x; ///< x position to start drawing text - int y; ///< y position to start drawing text - int max_glyph_w; ///< max glyph width - int max_glyph_h; ///< max glyph height - int shadowx, shadowy; - unsigned int fontsize; ///< font size to use - - short int draw_box; ///< draw box around text - true or false - int use_kerning; ///< font kerning is used - true/false - int tabsize; ///< tab size - int fix_bounds; ///< do we let it go out of frame bounds - t/f - - FFDrawContext dc; - FFDrawColor fontcolor; ///< foreground color - FFDrawColor shadowcolor; ///< shadow color - FFDrawColor boxcolor; ///< background color - - FT_Library library; ///< freetype font library handle - FT_Face face; ///< freetype font face handle - struct AVTreeNode *glyphs; ///< rendered glyphs, stored using the UTF-32 char code - char *x_expr; ///< expression for x position - char *y_expr; ///< expression for y position - AVExpr *x_pexpr, *y_pexpr; ///< parsed expressions for x and y - int64_t basetime; ///< base pts time in the real world for display - double var_values[VAR_VARS_NB]; -#if FF_API_DRAWTEXT_OLD_TIMELINE - char *draw_expr; ///< expression for draw - AVExpr *draw_pexpr; ///< parsed expression for draw - int draw; ///< set to zero to prevent drawing -#endif - AVLFG prng; ///< random - char *tc_opt_string; ///< specified timecode option string - AVRational tc_rate; ///< frame rate for timecode - AVTimecode tc; ///< timecode context - int tc24hmax; ///< 1 if timecode is wrapped to 24 hours, 0 otherwise - int reload; ///< reload text file for each frame - int start_number; ///< starting frame number for n/frame_num var - AVDictionary *metadata; -} DrawTextContext; - -#define OFFSET(x) offsetof(DrawTextContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption drawtext_options[]= { - {"fontfile", "set font file", OFFSET(fontfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"text", "set text", OFFSET(text), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"textfile", "set text file", OFFSET(textfile), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"fontcolor", "set foreground color", OFFSET(fontcolor.rgba), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"boxcolor", "set box color", OFFSET(boxcolor.rgba), AV_OPT_TYPE_COLOR, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"shadowcolor", "set shadow color", OFFSET(shadowcolor.rgba), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"box", "set box", OFFSET(draw_box), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 , FLAGS}, - {"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX , FLAGS}, - {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"shadowx", "set x", OFFSET(shadowx), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX , FLAGS}, - {"shadowy", "set y", OFFSET(shadowy), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX , FLAGS}, - {"tabsize", "set tab size", OFFSET(tabsize), AV_OPT_TYPE_INT, {.i64=4}, 0, INT_MAX , FLAGS}, - {"basetime", "set base time", OFFSET(basetime), AV_OPT_TYPE_INT64, {.i64=AV_NOPTS_VALUE}, INT64_MIN, INT64_MAX , FLAGS}, -#if FF_API_DRAWTEXT_OLD_TIMELINE - {"draw", "if false do not draw (deprecated)", OFFSET(draw_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, -#endif - - {"expansion", "set the expansion mode", OFFSET(exp_mode), AV_OPT_TYPE_INT, {.i64=EXP_NORMAL}, 0, 2, FLAGS, "expansion"}, - {"none", "set no expansion", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_NONE}, 0, 0, FLAGS, "expansion"}, - {"normal", "set normal expansion", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_NORMAL}, 0, 0, FLAGS, "expansion"}, - {"strftime", "set strftime expansion (deprecated)", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_STRFTIME}, 0, 0, FLAGS, "expansion"}, - - {"timecode", "set initial timecode", OFFSET(tc_opt_string), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, - {"tc24hmax", "set 24 hours max (timecode only)", OFFSET(tc24hmax), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"timecode_rate", "set rate (timecode only)", OFFSET(tc_rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX, FLAGS}, - {"r", "set rate (timecode only)", OFFSET(tc_rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX, FLAGS}, - {"rate", "set rate (timecode only)", OFFSET(tc_rate), AV_OPT_TYPE_RATIONAL, {.dbl=0}, 0, INT_MAX, FLAGS}, - {"reload", "reload text file for each frame", OFFSET(reload), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"fix_bounds", "if true, check and fix text coords to avoid clipping", OFFSET(fix_bounds), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS}, - {"start_number", "start frame number for n/frame_num variable", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS}, - - /* FT_LOAD_* flags */ - { "ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), AV_OPT_TYPE_FLAGS, { .i64 = FT_LOAD_DEFAULT | FT_LOAD_RENDER}, 0, INT_MAX, FLAGS, "ft_load_flags" }, - { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_DEFAULT }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "no_scale", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_SCALE }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "no_hinting", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_HINTING }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "render", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_RENDER }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "no_bitmap", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_BITMAP }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "vertical_layout", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_VERTICAL_LAYOUT }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "force_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_FORCE_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "crop_bitmap", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_CROP_BITMAP }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "pedantic", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_PEDANTIC }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "ignore_global_advance_width", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "no_recurse", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_RECURSE }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "ignore_transform", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_TRANSFORM }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "monochrome", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "linear_design", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN }, .flags = FLAGS, .unit = "ft_load_flags" }, - { "no_autohint", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT }, .flags = FLAGS, .unit = "ft_load_flags" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(drawtext); - -#undef __FTERRORS_H__ -#define FT_ERROR_START_LIST { -#define FT_ERRORDEF(e, v, s) { (e), (s) }, -#define FT_ERROR_END_LIST { 0, NULL } }; - -struct ft_error -{ - int err; - const char *err_msg; -} static ft_errors[] = -#include FT_ERRORS_H - -#define FT_ERRMSG(e) ft_errors[e].err_msg - -typedef struct { - FT_Glyph *glyph; - uint32_t code; - FT_Bitmap bitmap; ///< array holding bitmaps of font - FT_BBox bbox; - int advance; - int bitmap_left; - int bitmap_top; -} Glyph; - -static int glyph_cmp(void *key, const void *b) -{ - const Glyph *a = key, *bb = b; - int64_t diff = (int64_t)a->code - (int64_t)bb->code; - return diff > 0 ? 1 : diff < 0 ? -1 : 0; -} - -/** - * Load glyphs corresponding to the UTF-32 codepoint code. - */ -static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code) -{ - DrawTextContext *s = ctx->priv; - Glyph *glyph; - struct AVTreeNode *node = NULL; - int ret; - - /* load glyph into s->face->glyph */ - if (FT_Load_Char(s->face, code, s->ft_load_flags)) - return AVERROR(EINVAL); - - /* save glyph */ - if (!(glyph = av_mallocz(sizeof(*glyph))) || - !(glyph->glyph = av_mallocz(sizeof(*glyph->glyph)))) { - ret = AVERROR(ENOMEM); - goto error; - } - glyph->code = code; - - if (FT_Get_Glyph(s->face->glyph, glyph->glyph)) { - ret = AVERROR(EINVAL); - goto error; - } - - glyph->bitmap = s->face->glyph->bitmap; - glyph->bitmap_left = s->face->glyph->bitmap_left; - glyph->bitmap_top = s->face->glyph->bitmap_top; - glyph->advance = s->face->glyph->advance.x >> 6; - - /* measure text height to calculate text_height (or the maximum text height) */ - FT_Glyph_Get_CBox(*glyph->glyph, ft_glyph_bbox_pixels, &glyph->bbox); - - /* cache the newly created glyph */ - if (!(node = av_tree_node_alloc())) { - ret = AVERROR(ENOMEM); - goto error; - } - av_tree_insert(&s->glyphs, glyph, glyph_cmp, &node); - - if (glyph_ptr) - *glyph_ptr = glyph; - return 0; - -error: - if (glyph) - av_freep(&glyph->glyph); - av_freep(&glyph); - av_freep(&node); - return ret; -} - -static int load_font_file(AVFilterContext *ctx, const char *path, int index, - const char **error) -{ - DrawTextContext *s = ctx->priv; - int err; - - err = FT_New_Face(s->library, path, index, &s->face); - if (err) { - *error = FT_ERRMSG(err); - return AVERROR(EINVAL); - } - return 0; -} - -#if CONFIG_FONTCONFIG -static int load_font_fontconfig(AVFilterContext *ctx, const char **error) -{ - DrawTextContext *s = ctx->priv; - FcConfig *fontconfig; - FcPattern *pattern, *fpat; - FcResult result = FcResultMatch; - FcChar8 *filename; - int err, index; - double size; - - fontconfig = FcInitLoadConfigAndFonts(); - if (!fontconfig) { - *error = "impossible to init fontconfig\n"; - return AVERROR(EINVAL); - } - pattern = FcNameParse(s->fontfile ? s->fontfile : - (uint8_t *)(intptr_t)"default"); - if (!pattern) { - *error = "could not parse fontconfig pattern"; - return AVERROR(EINVAL); - } - if (!FcConfigSubstitute(fontconfig, pattern, FcMatchPattern)) { - *error = "could not substitue fontconfig options"; /* very unlikely */ - return AVERROR(EINVAL); - } - FcDefaultSubstitute(pattern); - fpat = FcFontMatch(fontconfig, pattern, &result); - if (!fpat || result != FcResultMatch) { - *error = "impossible to find a matching font"; - return AVERROR(EINVAL); - } - if (FcPatternGetString (fpat, FC_FILE, 0, &filename) != FcResultMatch || - FcPatternGetInteger(fpat, FC_INDEX, 0, &index ) != FcResultMatch || - FcPatternGetDouble (fpat, FC_SIZE, 0, &size ) != FcResultMatch) { - *error = "impossible to find font information"; - return AVERROR(EINVAL); - } - av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename); - if (!s->fontsize) - s->fontsize = size + 0.5; - err = load_font_file(ctx, filename, index, error); - if (err) - return err; - FcPatternDestroy(fpat); - FcPatternDestroy(pattern); - FcConfigDestroy(fontconfig); - return 0; -} -#endif - -static int load_font(AVFilterContext *ctx) -{ - DrawTextContext *s = ctx->priv; - int err; - const char *error = "unknown error\n"; - - /* load the face, and set up the encoding, which is by default UTF-8 */ - err = load_font_file(ctx, s->fontfile, 0, &error); - if (!err) - return 0; -#if CONFIG_FONTCONFIG - err = load_font_fontconfig(ctx, &error); - if (!err) - return 0; -#endif - av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n", - s->fontfile, error); - return err; -} - -static int load_textfile(AVFilterContext *ctx) -{ - DrawTextContext *s = ctx->priv; - int err; - uint8_t *textbuf; - size_t textbuf_size; - - if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) { - av_log(ctx, AV_LOG_ERROR, - "The text file '%s' could not be read or is empty\n", - s->textfile); - return err; - } - - if (!(s->text = av_realloc(s->text, textbuf_size + 1))) - return AVERROR(ENOMEM); - memcpy(s->text, textbuf, textbuf_size); - s->text[textbuf_size] = 0; - av_file_unmap(textbuf, textbuf_size); - - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - int err; - DrawTextContext *s = ctx->priv; - Glyph *glyph; - -#if FF_API_DRAWTEXT_OLD_TIMELINE - if (s->draw_expr) - av_log(ctx, AV_LOG_WARNING, "'draw' option is deprecated and will be removed soon, " - "you are encouraged to use the generic timeline support through the 'enable' option\n"); -#endif - - if (!s->fontfile && !CONFIG_FONTCONFIG) { - av_log(ctx, AV_LOG_ERROR, "No font filename provided\n"); - return AVERROR(EINVAL); - } - - if (s->textfile) { - if (s->text) { - av_log(ctx, AV_LOG_ERROR, - "Both text and text file provided. Please provide only one\n"); - return AVERROR(EINVAL); - } - if ((err = load_textfile(ctx)) < 0) - return err; - } - - if (s->reload && !s->textfile) - av_log(ctx, AV_LOG_WARNING, "No file to reload\n"); - - if (s->tc_opt_string) { - int ret = av_timecode_init_from_string(&s->tc, s->tc_rate, - s->tc_opt_string, ctx); - if (ret < 0) - return ret; - if (s->tc24hmax) - s->tc.flags |= AV_TIMECODE_FLAG_24HOURSMAX; - if (!s->text) - s->text = av_strdup(""); - } - - if (!s->text) { - av_log(ctx, AV_LOG_ERROR, - "Either text, a valid file or a timecode must be provided\n"); - return AVERROR(EINVAL); - } - - if ((err = FT_Init_FreeType(&(s->library)))) { - av_log(ctx, AV_LOG_ERROR, - "Could not load FreeType: %s\n", FT_ERRMSG(err)); - return AVERROR(EINVAL); - } - - err = load_font(ctx); - if (err) - return err; - if (!s->fontsize) - s->fontsize = 16; - if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) { - av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n", - s->fontsize, FT_ERRMSG(err)); - return AVERROR(EINVAL); - } - - s->use_kerning = FT_HAS_KERNING(s->face); - - /* load the fallback glyph with code 0 */ - load_glyph(ctx, NULL, 0); - - /* set the tabsize in pixels */ - if ((err = load_glyph(ctx, &glyph, ' ')) < 0) { - av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n"); - return err; - } - s->tabsize *= glyph->advance; - - if (s->exp_mode == EXP_STRFTIME && - (strchr(s->text, '%') || strchr(s->text, '\\'))) - av_log(ctx, AV_LOG_WARNING, "expansion=strftime is deprecated.\n"); - - av_bprint_init(&s->expanded_text, 0, AV_BPRINT_SIZE_UNLIMITED); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -static int glyph_enu_free(void *opaque, void *elem) -{ - Glyph *glyph = elem; - - FT_Done_Glyph(*glyph->glyph); - av_freep(&glyph->glyph); - av_free(elem); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - DrawTextContext *s = ctx->priv; - - av_expr_free(s->x_pexpr); - av_expr_free(s->y_pexpr); -#if FF_API_DRAWTEXT_OLD_TIMELINE - av_expr_free(s->draw_pexpr); - s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL; -#endif - av_freep(&s->positions); - s->nb_positions = 0; - - - av_tree_enumerate(s->glyphs, NULL, NULL, glyph_enu_free); - av_tree_destroy(s->glyphs); - s->glyphs = NULL; - - FT_Done_Face(s->face); - FT_Done_FreeType(s->library); - - av_bprint_finalize(&s->expanded_text, NULL); -} - -static inline int is_newline(uint32_t c) -{ - return c == '\n' || c == '\r' || c == '\f' || c == '\v'; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - DrawTextContext *s = ctx->priv; - int ret; - - ff_draw_init(&s->dc, inlink->format, 0); - ff_draw_color(&s->dc, &s->fontcolor, s->fontcolor.rgba); - ff_draw_color(&s->dc, &s->shadowcolor, s->shadowcolor.rgba); - ff_draw_color(&s->dc, &s->boxcolor, s->boxcolor.rgba); - - s->var_values[VAR_w] = s->var_values[VAR_W] = s->var_values[VAR_MAIN_W] = inlink->w; - s->var_values[VAR_h] = s->var_values[VAR_H] = s->var_values[VAR_MAIN_H] = inlink->h; - s->var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1; - s->var_values[VAR_DAR] = (double)inlink->w / inlink->h * s->var_values[VAR_SAR]; - s->var_values[VAR_HSUB] = 1 << s->dc.hsub_max; - s->var_values[VAR_VSUB] = 1 << s->dc.vsub_max; - s->var_values[VAR_X] = NAN; - s->var_values[VAR_Y] = NAN; - s->var_values[VAR_T] = NAN; - - av_lfg_init(&s->prng, av_get_random_seed()); - - av_expr_free(s->x_pexpr); - av_expr_free(s->y_pexpr); -#if FF_API_DRAWTEXT_OLD_TIMELINE - av_expr_free(s->draw_pexpr); - s->x_pexpr = s->y_pexpr = s->draw_pexpr = NULL; -#else - s->x_pexpr = s->y_pexpr = NULL; -#endif - - if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names, - NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 || - (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names, - NULL, NULL, fun2_names, fun2, 0, ctx)) < 0) - - return AVERROR(EINVAL); -#if FF_API_DRAWTEXT_OLD_TIMELINE - if (s->draw_expr && - (ret = av_expr_parse(&s->draw_pexpr, s->draw_expr, var_names, - NULL, NULL, fun2_names, fun2, 0, ctx)) < 0) - return ret; -#endif - - return 0; -} - -static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags) -{ - DrawTextContext *s = ctx->priv; - - if (!strcmp(cmd, "reinit")) { - int ret; - uninit(ctx); - s->reinit = 1; - if ((ret = init(ctx)) < 0) - return ret; - return config_input(ctx->inputs[0]); - } - - return AVERROR(ENOSYS); -} - -static int func_pict_type(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - DrawTextContext *s = ctx->priv; - - av_bprintf(bp, "%c", av_get_picture_type_char(s->var_values[VAR_PICT_TYPE])); - return 0; -} - -static int func_pts(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - DrawTextContext *s = ctx->priv; - - av_bprintf(bp, "%.6f", s->var_values[VAR_T]); - return 0; -} - -static int func_frame_num(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - DrawTextContext *s = ctx->priv; - - av_bprintf(bp, "%d", (int)s->var_values[VAR_N]); - return 0; -} - -static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - DrawTextContext *s = ctx->priv; - AVDictionaryEntry *e = av_dict_get(s->metadata, argv[0], NULL, 0); - - if (e && e->value) - av_bprintf(bp, "%s", e->value); - return 0; -} - -#if !HAVE_LOCALTIME_R -static void localtime_r(const time_t *t, struct tm *tm) -{ - *tm = *localtime(t); -} -#endif - -static int func_strftime(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - const char *fmt = argc ? argv[0] : "%Y-%m-%d %H:%M:%S"; - time_t now; - struct tm tm; - - time(&now); - if (tag == 'L') - localtime_r(&now, &tm); - else - tm = *gmtime(&now); - av_bprint_strftime(bp, fmt, &tm); - return 0; -} - -static int func_eval_expr(AVFilterContext *ctx, AVBPrint *bp, - char *fct, unsigned argc, char **argv, int tag) -{ - DrawTextContext *s = ctx->priv; - double res; - int ret; - - ret = av_expr_parse_and_eval(&res, argv[0], var_names, s->var_values, - NULL, NULL, fun2_names, fun2, - &s->prng, 0, ctx); - if (ret < 0) - av_log(ctx, AV_LOG_ERROR, - "Expression '%s' for the expr text expansion function is not valid\n", - argv[0]); - else - av_bprintf(bp, "%f", res); - - return ret; -} - -static const struct drawtext_function { - const char *name; - unsigned argc_min, argc_max; - int tag; /**< opaque argument to func */ - int (*func)(AVFilterContext *, AVBPrint *, char *, unsigned, char **, int); -} functions[] = { - { "expr", 1, 1, 0, func_eval_expr }, - { "e", 1, 1, 0, func_eval_expr }, - { "pict_type", 0, 0, 0, func_pict_type }, - { "pts", 0, 0, 0, func_pts }, - { "gmtime", 0, 1, 'G', func_strftime }, - { "localtime", 0, 1, 'L', func_strftime }, - { "frame_num", 0, 0, 0, func_frame_num }, - { "n", 0, 0, 0, func_frame_num }, - { "metadata", 1, 1, 0, func_metadata }, -}; - -static int eval_function(AVFilterContext *ctx, AVBPrint *bp, char *fct, - unsigned argc, char **argv) -{ - unsigned i; - - for (i = 0; i < FF_ARRAY_ELEMS(functions); i++) { - if (strcmp(fct, functions[i].name)) - continue; - if (argc < functions[i].argc_min) { - av_log(ctx, AV_LOG_ERROR, "%%{%s} requires at least %d arguments\n", - fct, functions[i].argc_min); - return AVERROR(EINVAL); - } - if (argc > functions[i].argc_max) { - av_log(ctx, AV_LOG_ERROR, "%%{%s} requires at most %d arguments\n", - fct, functions[i].argc_max); - return AVERROR(EINVAL); - } - break; - } - if (i >= FF_ARRAY_ELEMS(functions)) { - av_log(ctx, AV_LOG_ERROR, "%%{%s} is not known\n", fct); - return AVERROR(EINVAL); - } - return functions[i].func(ctx, bp, fct, argc, argv, functions[i].tag); -} - -static int expand_function(AVFilterContext *ctx, AVBPrint *bp, char **rtext) -{ - const char *text = *rtext; - char *argv[16] = { NULL }; - unsigned argc = 0, i; - int ret; - - if (*text != '{') { - av_log(ctx, AV_LOG_ERROR, "Stray %% near '%s'\n", text); - return AVERROR(EINVAL); - } - text++; - while (1) { - if (!(argv[argc++] = av_get_token(&text, ":}"))) { - ret = AVERROR(ENOMEM); - goto end; - } - if (!*text) { - av_log(ctx, AV_LOG_ERROR, "Unterminated %%{} near '%s'\n", *rtext); - ret = AVERROR(EINVAL); - goto end; - } - if (argc == FF_ARRAY_ELEMS(argv)) - av_freep(&argv[--argc]); /* error will be caught later */ - if (*text == '}') - break; - text++; - } - - if ((ret = eval_function(ctx, bp, argv[0], argc - 1, argv + 1)) < 0) - goto end; - ret = 0; - *rtext = (char *)text + 1; - -end: - for (i = 0; i < argc; i++) - av_freep(&argv[i]); - return ret; -} - -static int expand_text(AVFilterContext *ctx) -{ - DrawTextContext *s = ctx->priv; - char *text = s->text; - AVBPrint *bp = &s->expanded_text; - int ret; - - av_bprint_clear(bp); - while (*text) { - if (*text == '\\' && text[1]) { - av_bprint_chars(bp, text[1], 1); - text += 2; - } else if (*text == '%') { - text++; - if ((ret = expand_function(ctx, bp, &text)) < 0) - return ret; - } else { - av_bprint_chars(bp, *text, 1); - text++; - } - } - if (!av_bprint_is_complete(bp)) - return AVERROR(ENOMEM); - return 0; -} - -static int draw_glyphs(DrawTextContext *s, AVFrame *frame, - int width, int height, const uint8_t rgbcolor[4], FFDrawColor *color, int x, int y) -{ - char *text = s->expanded_text.str; - uint32_t code = 0; - int i, x1, y1; - uint8_t *p; - Glyph *glyph = NULL; - - for (i = 0, p = text; *p; i++) { - Glyph dummy = { 0 }; - GET_UTF8(code, *p++, continue;); - - /* skip new line chars, just go to new line */ - if (code == '\n' || code == '\r' || code == '\t') - continue; - - dummy.code = code; - glyph = av_tree_find(s->glyphs, &dummy, (void *)glyph_cmp, NULL); - - if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO && - glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY) - return AVERROR(EINVAL); - - x1 = s->positions[i].x+s->x+x; - y1 = s->positions[i].y+s->y+y; - - ff_blend_mask(&s->dc, color, - frame->data, frame->linesize, width, height, - glyph->bitmap.buffer, glyph->bitmap.pitch, - glyph->bitmap.width, glyph->bitmap.rows, - glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 0 : 3, - 0, x1, y1); - } - - return 0; -} - -static int draw_text(AVFilterContext *ctx, AVFrame *frame, - int width, int height) -{ - DrawTextContext *s = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - uint32_t code = 0, prev_code = 0; - int x = 0, y = 0, i = 0, ret; - int max_text_line_w = 0, len; - int box_w, box_h; - char *text; - uint8_t *p; - int y_min = 32000, y_max = -32000; - int x_min = 32000, x_max = -32000; - FT_Vector delta; - Glyph *glyph = NULL, *prev_glyph = NULL; - Glyph dummy = { 0 }; - - time_t now = time(0); - struct tm ltime; - AVBPrint *bp = &s->expanded_text; - - av_bprint_clear(bp); - - if(s->basetime != AV_NOPTS_VALUE) - now= frame->pts*av_q2d(ctx->inputs[0]->time_base) + s->basetime/1000000; - - switch (s->exp_mode) { - case EXP_NONE: - av_bprintf(bp, "%s", s->text); - break; - case EXP_NORMAL: - if ((ret = expand_text(ctx)) < 0) - return ret; - break; - case EXP_STRFTIME: - localtime_r(&now, <ime); - av_bprint_strftime(bp, s->text, <ime); - break; - } - - if (s->tc_opt_string) { - char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count); - av_bprint_clear(bp); - av_bprintf(bp, "%s%s", s->text, tcbuf); - } - - if (!av_bprint_is_complete(bp)) - return AVERROR(ENOMEM); - text = s->expanded_text.str; - if ((len = s->expanded_text.len) > s->nb_positions) { - if (!(s->positions = - av_realloc(s->positions, len*sizeof(*s->positions)))) - return AVERROR(ENOMEM); - s->nb_positions = len; - } - - x = 0; - y = 0; - - /* load and cache glyphs */ - for (i = 0, p = text; *p; i++) { - GET_UTF8(code, *p++, continue;); - - /* get glyph */ - dummy.code = code; - glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL); - if (!glyph) { - load_glyph(ctx, &glyph, code); - } - - y_min = FFMIN(glyph->bbox.yMin, y_min); - y_max = FFMAX(glyph->bbox.yMax, y_max); - x_min = FFMIN(glyph->bbox.xMin, x_min); - x_max = FFMAX(glyph->bbox.xMax, x_max); - } - s->max_glyph_h = y_max - y_min; - s->max_glyph_w = x_max - x_min; - - /* compute and save position for each glyph */ - glyph = NULL; - for (i = 0, p = text; *p; i++) { - GET_UTF8(code, *p++, continue;); - - /* skip the \n in the sequence \r\n */ - if (prev_code == '\r' && code == '\n') - continue; - - prev_code = code; - if (is_newline(code)) { - - max_text_line_w = FFMAX(max_text_line_w, x); - y += s->max_glyph_h; - x = 0; - continue; - } - - /* get glyph */ - prev_glyph = glyph; - dummy.code = code; - glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL); - - /* kerning */ - if (s->use_kerning && prev_glyph && glyph->code) { - FT_Get_Kerning(s->face, prev_glyph->code, glyph->code, - ft_kerning_default, &delta); - x += delta.x >> 6; - } - - /* save position */ - s->positions[i].x = x + glyph->bitmap_left; - s->positions[i].y = y - glyph->bitmap_top + y_max; - if (code == '\t') x = (x / s->tabsize + 1)*s->tabsize; - else x += glyph->advance; - } - - max_text_line_w = FFMAX(x, max_text_line_w); - - s->var_values[VAR_TW] = s->var_values[VAR_TEXT_W] = max_text_line_w; - s->var_values[VAR_TH] = s->var_values[VAR_TEXT_H] = y + s->max_glyph_h; - - s->var_values[VAR_MAX_GLYPH_W] = s->max_glyph_w; - s->var_values[VAR_MAX_GLYPH_H] = s->max_glyph_h; - s->var_values[VAR_MAX_GLYPH_A] = s->var_values[VAR_ASCENT ] = y_max; - s->var_values[VAR_MAX_GLYPH_D] = s->var_values[VAR_DESCENT] = y_min; - - s->var_values[VAR_LINE_H] = s->var_values[VAR_LH] = s->max_glyph_h; - - s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng); - s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng); - s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng); -#if FF_API_DRAWTEXT_OLD_TIMELINE - if (s->draw_pexpr){ - s->draw = av_expr_eval(s->draw_pexpr, s->var_values, &s->prng); - - if(!s->draw) - return 0; - } - if (ctx->is_disabled) - return 0; -#endif - - box_w = FFMIN(width - 1 , max_text_line_w); - box_h = FFMIN(height - 1, y + s->max_glyph_h); - - /* draw box */ - if (s->draw_box) - ff_blend_rectangle(&s->dc, &s->boxcolor, - frame->data, frame->linesize, width, height, - s->x, s->y, box_w, box_h); - - if (s->shadowx || s->shadowy) { - if ((ret = draw_glyphs(s, frame, width, height, s->shadowcolor.rgba, - &s->shadowcolor, s->shadowx, s->shadowy)) < 0) - return ret; - } - - if ((ret = draw_glyphs(s, frame, width, height, s->fontcolor.rgba, - &s->fontcolor, 0, 0)) < 0) - return ret; - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - DrawTextContext *s = ctx->priv; - int ret; - - if (s->reload) - if ((ret = load_textfile(ctx)) < 0) - return ret; - - s->var_values[VAR_N] = inlink->frame_count+s->start_number; - s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ? - NAN : frame->pts * av_q2d(inlink->time_base); - - s->var_values[VAR_PICT_TYPE] = frame->pict_type; - s->metadata = av_frame_get_metadata(frame); - - draw_text(ctx, frame, frame->width, frame->height); - - av_log(ctx, AV_LOG_DEBUG, "n:%d t:%f text_w:%d text_h:%d x:%d y:%d\n", - (int)s->var_values[VAR_N], s->var_values[VAR_T], - (int)s->var_values[VAR_TEXT_W], (int)s->var_values[VAR_TEXT_H], - s->x, s->y); - - return ff_filter_frame(outlink, frame); -} - -static const AVFilterPad avfilter_vf_drawtext_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_drawtext_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_drawtext = { - .name = "drawtext", - .description = NULL_IF_CONFIG_SMALL("Draw text on top of video frames using libfreetype library."), - .priv_size = sizeof(DrawTextContext), - .priv_class = &drawtext_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_vf_drawtext_inputs, - .outputs = avfilter_vf_drawtext_outputs, - .process_command = command, -#if FF_API_DRAWTEXT_OLD_TIMELINE - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, -#else - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -#endif -}; diff --git a/ffmpeg/libavfilter/vf_edgedetect.c b/ffmpeg/libavfilter/vf_edgedetect.c deleted file mode 100644 index c8ec734..0000000 --- a/ffmpeg/libavfilter/vf_edgedetect.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Edge detection filter - * - * @see https://en.wikipedia.org/wiki/Canny_edge_detector - */ - -#include "libavutil/opt.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - uint8_t *tmpbuf; - uint16_t *gradients; - char *directions; - double low, high; - uint8_t low_u8, high_u8; -} EdgeDetectContext; - -#define OFFSET(x) offsetof(EdgeDetectContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption edgedetect_options[] = { - { "high", "set high threshold", OFFSET(high), AV_OPT_TYPE_DOUBLE, {.dbl=50/255.}, 0, 1, FLAGS }, - { "low", "set low threshold", OFFSET(low), AV_OPT_TYPE_DOUBLE, {.dbl=20/255.}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(edgedetect); - -static av_cold int init(AVFilterContext *ctx) -{ - EdgeDetectContext *edgedetect = ctx->priv; - - edgedetect->low_u8 = edgedetect->low * 255. + .5; - edgedetect->high_u8 = edgedetect->high * 255. + .5; - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE}; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - EdgeDetectContext *edgedetect = ctx->priv; - - edgedetect->tmpbuf = av_malloc(inlink->w * inlink->h); - edgedetect->gradients = av_calloc(inlink->w * inlink->h, sizeof(*edgedetect->gradients)); - edgedetect->directions = av_malloc(inlink->w * inlink->h); - if (!edgedetect->tmpbuf || !edgedetect->gradients || !edgedetect->directions) - return AVERROR(ENOMEM); - return 0; -} - -static void gaussian_blur(AVFilterContext *ctx, int w, int h, - uint8_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize) -{ - int i, j; - - memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; - memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; - for (j = 2; j < h - 2; j++) { - dst[0] = src[0]; - dst[1] = src[1]; - for (i = 2; i < w - 2; i++) { - /* Gaussian mask of size 5x5 with sigma = 1.4 */ - dst[i] = ((src[-2*src_linesize + i-2] + src[2*src_linesize + i-2]) * 2 - + (src[-2*src_linesize + i-1] + src[2*src_linesize + i-1]) * 4 - + (src[-2*src_linesize + i ] + src[2*src_linesize + i ]) * 5 - + (src[-2*src_linesize + i+1] + src[2*src_linesize + i+1]) * 4 - + (src[-2*src_linesize + i+2] + src[2*src_linesize + i+2]) * 2 - - + (src[ -src_linesize + i-2] + src[ src_linesize + i-2]) * 4 - + (src[ -src_linesize + i-1] + src[ src_linesize + i-1]) * 9 - + (src[ -src_linesize + i ] + src[ src_linesize + i ]) * 12 - + (src[ -src_linesize + i+1] + src[ src_linesize + i+1]) * 9 - + (src[ -src_linesize + i+2] + src[ src_linesize + i+2]) * 4 - - + src[i-2] * 5 - + src[i-1] * 12 - + src[i ] * 15 - + src[i+1] * 12 - + src[i+2] * 5) / 159; - } - dst[i ] = src[i ]; - dst[i + 1] = src[i + 1]; - - dst += dst_linesize; - src += src_linesize; - } - memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; - memcpy(dst, src, w); -} - -enum { - DIRECTION_45UP, - DIRECTION_45DOWN, - DIRECTION_HORIZONTAL, - DIRECTION_VERTICAL, -}; - -static int get_rounded_direction(int gx, int gy) -{ - /* reference angles: - * tan( pi/8) = sqrt(2)-1 - * tan(3pi/8) = sqrt(2)+1 - * Gy/Gx is the tangent of the angle (theta), so Gy/Gx is compared against - * <ref-angle>, or more simply Gy against <ref-angle>*Gx - * - * Gx and Gy bounds = [-1020;1020], using 16-bit arithmetic: - * round((sqrt(2)-1) * (1<<16)) = 27146 - * round((sqrt(2)+1) * (1<<16)) = 158218 - */ - if (gx) { - int tanpi8gx, tan3pi8gx; - - if (gx < 0) - gx = -gx, gy = -gy; - gy <<= 16; - tanpi8gx = 27146 * gx; - tan3pi8gx = 158218 * gx; - if (gy > -tan3pi8gx && gy < -tanpi8gx) return DIRECTION_45UP; - if (gy > -tanpi8gx && gy < tanpi8gx) return DIRECTION_HORIZONTAL; - if (gy > tanpi8gx && gy < tan3pi8gx) return DIRECTION_45DOWN; - } - return DIRECTION_VERTICAL; -} - -static void sobel(AVFilterContext *ctx, int w, int h, - uint16_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize) -{ - int i, j; - EdgeDetectContext *edgedetect = ctx->priv; - - for (j = 1; j < h - 1; j++) { - dst += dst_linesize; - src += src_linesize; - for (i = 1; i < w - 1; i++) { - const int gx = - -1*src[-src_linesize + i-1] + 1*src[-src_linesize + i+1] - -2*src[ i-1] + 2*src[ i+1] - -1*src[ src_linesize + i-1] + 1*src[ src_linesize + i+1]; - const int gy = - -1*src[-src_linesize + i-1] + 1*src[ src_linesize + i-1] - -2*src[-src_linesize + i ] + 2*src[ src_linesize + i ] - -1*src[-src_linesize + i+1] + 1*src[ src_linesize + i+1]; - - dst[i] = FFABS(gx) + FFABS(gy); - edgedetect->directions[j*w + i] = get_rounded_direction(gx, gy); - } - } -} - -static void non_maximum_suppression(AVFilterContext *ctx, int w, int h, - uint8_t *dst, int dst_linesize, - const uint16_t *src, int src_linesize) -{ - int i, j; - EdgeDetectContext *edgedetect = ctx->priv; - -#define COPY_MAXIMA(ay, ax, by, bx) do { \ - if (src[i] > src[(ay)*src_linesize + i+(ax)] && \ - src[i] > src[(by)*src_linesize + i+(bx)]) \ - dst[i] = av_clip_uint8(src[i]); \ -} while (0) - - for (j = 1; j < h - 1; j++) { - dst += dst_linesize; - src += src_linesize; - for (i = 1; i < w - 1; i++) { - switch (edgedetect->directions[j*w + i]) { - case DIRECTION_45UP: COPY_MAXIMA( 1, -1, -1, 1); break; - case DIRECTION_45DOWN: COPY_MAXIMA(-1, -1, 1, 1); break; - case DIRECTION_HORIZONTAL: COPY_MAXIMA( 0, -1, 0, 1); break; - case DIRECTION_VERTICAL: COPY_MAXIMA(-1, 0, 1, 0); break; - } - } - } -} - -static void double_threshold(AVFilterContext *ctx, int w, int h, - uint8_t *dst, int dst_linesize, - const uint8_t *src, int src_linesize) -{ - int i, j; - EdgeDetectContext *edgedetect = ctx->priv; - const int low = edgedetect->low_u8; - const int high = edgedetect->high_u8; - - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - if (src[i] > high) { - dst[i] = src[i]; - continue; - } - - if ((!i || i == w - 1 || !j || j == h - 1) && - src[i] > low && - (src[-src_linesize + i-1] > high || - src[-src_linesize + i ] > high || - src[-src_linesize + i+1] > high || - src[ i-1] > high || - src[ i+1] > high || - src[ src_linesize + i-1] > high || - src[ src_linesize + i ] > high || - src[ src_linesize + i+1] > high)) - dst[i] = src[i]; - else - dst[i] = 0; - } - dst += dst_linesize; - src += src_linesize; - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - EdgeDetectContext *edgedetect = ctx->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - uint8_t *tmpbuf = edgedetect->tmpbuf; - uint16_t *gradients = edgedetect->gradients; - int direct = 0; - AVFrame *out; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - } - - /* gaussian filter to reduce noise */ - gaussian_blur(ctx, inlink->w, inlink->h, - tmpbuf, inlink->w, - in->data[0], in->linesize[0]); - - /* compute the 16-bits gradients and directions for the next step */ - sobel(ctx, inlink->w, inlink->h, - gradients, inlink->w, - tmpbuf, inlink->w); - - /* non_maximum_suppression() will actually keep & clip what's necessary and - * ignore the rest, so we need a clean output buffer */ - memset(tmpbuf, 0, inlink->w * inlink->h); - non_maximum_suppression(ctx, inlink->w, inlink->h, - tmpbuf, inlink->w, - gradients, inlink->w); - - /* keep high values, or low values surrounded by high values */ - double_threshold(ctx, inlink->w, inlink->h, - out->data[0], out->linesize[0], - tmpbuf, inlink->w); - - if (!direct) - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - EdgeDetectContext *edgedetect = ctx->priv; - av_freep(&edgedetect->tmpbuf); - av_freep(&edgedetect->gradients); - av_freep(&edgedetect->directions); -} - -static const AVFilterPad edgedetect_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad edgedetect_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_edgedetect = { - .name = "edgedetect", - .description = NULL_IF_CONFIG_SMALL("Detect and draw edge."), - .priv_size = sizeof(EdgeDetectContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = edgedetect_inputs, - .outputs = edgedetect_outputs, - .priv_class = &edgedetect_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_fade.c b/ffmpeg/libavfilter/vf_fade.c deleted file mode 100644 index cc10b12..0000000 --- a/ffmpeg/libavfilter/vf_fade.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2010 Brandon Mintern - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video fade filter - * based heavily on vf_negate.c by Bobby Bingham - */ - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -#define Y 0 -#define U 1 -#define V 2 - -#define FADE_IN 0 -#define FADE_OUT 1 - -typedef struct { - const AVClass *class; - int type; - int factor, fade_per_frame; - int start_frame, nb_frames; - int hsub, vsub, bpp; - unsigned int black_level, black_level_scaled; - uint8_t is_packed_rgb; - uint8_t rgba_map[4]; - int alpha; - uint64_t start_time, duration; - enum {VF_FADE_WAITING=0, VF_FADE_FADING, VF_FADE_DONE} fade_state; - uint8_t color_rgba[4]; ///< fade color - int black_fade; ///< if color_rgba is black -} FadeContext; - -static av_cold int init(AVFilterContext *ctx) -{ - FadeContext *s = ctx->priv; - - s->fade_per_frame = (1 << 16) / s->nb_frames; - s->fade_state = VF_FADE_WAITING; - - if (s->duration != 0) { - // If duration (seconds) is non-zero, assume that we are not fading based on frames - s->nb_frames = 0; // Mostly to clean up logging - } - - // Choose what to log. If both time-based and frame-based options, both lines will be in the log - if (s->start_frame || s->nb_frames) { - av_log(ctx, AV_LOG_VERBOSE, - "type:%s start_frame:%d nb_frames:%d alpha:%d\n", - s->type == FADE_IN ? "in" : "out", s->start_frame, - s->nb_frames,s->alpha); - } - if (s->start_time || s->duration) { - av_log(ctx, AV_LOG_VERBOSE, - "type:%s start_time:%f duration:%f alpha:%d\n", - s->type == FADE_IN ? "in" : "out", (s->start_time / (double)AV_TIME_BASE), - (s->duration / (double)AV_TIME_BASE),s->alpha); - } - - s->black_fade = !memcmp(s->color_rgba, "\x00\x00\x00\xff", 4); - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - const FadeContext *s = ctx->priv; - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, - AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat pix_fmts_rgb[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, - AV_PIX_FMT_NONE - }; - - if (s->black_fade) - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - else - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts_rgb)); - return 0; -} - -const static enum AVPixelFormat studio_level_pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_NONE -}; - -static int config_props(AVFilterLink *inlink) -{ - FadeContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format); - - s->hsub = pixdesc->log2_chroma_w; - s->vsub = pixdesc->log2_chroma_h; - - s->bpp = av_get_bits_per_pixel(pixdesc) >> 3; - s->alpha &= !!(pixdesc->flags & AV_PIX_FMT_FLAG_ALPHA); - s->is_packed_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0; - - /* use CCIR601/709 black level for studio-level pixel non-alpha components */ - s->black_level = - ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !s->alpha ? 16 : 0; - /* 32768 = 1 << 15, it is an integer representation - * of 0.5 and is for rounding. */ - s->black_level_scaled = (s->black_level << 16) + 32768; - return 0; -} - -static av_always_inline void filter_rgb(FadeContext *s, const AVFrame *frame, - int slice_start, int slice_end, - int do_alpha, int step) -{ - int i, j; - const uint8_t r_idx = s->rgba_map[R]; - const uint8_t g_idx = s->rgba_map[G]; - const uint8_t b_idx = s->rgba_map[B]; - const uint8_t a_idx = s->rgba_map[A]; - const uint8_t *c = s->color_rgba; - - for (i = slice_start; i < slice_end; i++) { - uint8_t *p = frame->data[0] + i * frame->linesize[0]; - for (j = 0; j < frame->width; j++) { -#define INTERP(c_name, c_idx) av_clip_uint8(((c[c_idx]<<16) + ((int)p[c_name] - (int)c[c_idx]) * s->factor + (1<<15)) >> 16) - p[r_idx] = INTERP(r_idx, 0); - p[g_idx] = INTERP(g_idx, 1); - p[b_idx] = INTERP(b_idx, 2); - if (do_alpha) - p[a_idx] = INTERP(a_idx, 3); - p += step; - } - } -} - -static int filter_slice_rgb(AVFilterContext *ctx, void *arg, int jobnr, - int nb_jobs) -{ - FadeContext *s = ctx->priv; - AVFrame *frame = arg; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; - - if (s->alpha) filter_rgb(s, frame, slice_start, slice_end, 1, 4); - else if (s->bpp == 3) filter_rgb(s, frame, slice_start, slice_end, 0, 3); - else if (s->bpp == 4) filter_rgb(s, frame, slice_start, slice_end, 0, 4); - else av_assert0(0); - - return 0; -} - -static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr, - int nb_jobs) -{ - FadeContext *s = ctx->priv; - AVFrame *frame = arg; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; - int i, j; - - for (i = slice_start; i < slice_end; i++) { - uint8_t *p = frame->data[0] + i * frame->linesize[0]; - for (j = 0; j < frame->width * s->bpp; j++) { - /* s->factor is using 16 lower-order bits for decimal - * places. 32768 = 1 << 15, it is an integer representation - * of 0.5 and is for rounding. */ - *p = ((*p - s->black_level) * s->factor + s->black_level_scaled) >> 16; - p++; - } - } - - return 0; -} - -static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr, - int nb_jobs) -{ - FadeContext *s = ctx->priv; - AVFrame *frame = arg; - int i, j, plane; - const int width = FF_CEIL_RSHIFT(frame->width, s->hsub); - const int height= FF_CEIL_RSHIFT(frame->height, s->vsub); - int slice_start = (height * jobnr ) / nb_jobs; - int slice_end = (height * (jobnr+1)) / nb_jobs; - - for (plane = 1; plane < 3; plane++) { - for (i = slice_start; i < slice_end; i++) { - uint8_t *p = frame->data[plane] + i * frame->linesize[plane]; - for (j = 0; j < width; j++) { - /* 8421367 = ((128 << 1) + 1) << 15. It is an integer - * representation of 128.5. The .5 is for rounding - * purposes. */ - *p = ((*p - 128) * s->factor + 8421367) >> 16; - p++; - } - } - } - - return 0; -} - -static int filter_slice_alpha(AVFilterContext *ctx, void *arg, int jobnr, - int nb_jobs) -{ - FadeContext *s = ctx->priv; - AVFrame *frame = arg; - int plane = s->is_packed_rgb ? 0 : A; - int slice_start = (frame->height * jobnr ) / nb_jobs; - int slice_end = (frame->height * (jobnr+1)) / nb_jobs; - int i, j; - - for (i = slice_start; i < slice_end; i++) { - uint8_t *p = frame->data[plane] + i * frame->linesize[plane] + s->is_packed_rgb*s->rgba_map[A]; - int step = s->is_packed_rgb ? 4 : 1; - for (j = 0; j < frame->width; j++) { - /* s->factor is using 16 lower-order bits for decimal - * places. 32768 = 1 << 15, it is an integer representation - * of 0.5 and is for rounding. */ - *p = ((*p - s->black_level) * s->factor + s->black_level_scaled) >> 16; - p += step; - } - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - FadeContext *s = ctx->priv; - double frame_timestamp = frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base); - - // Calculate Fade assuming this is a Fade In - if (s->fade_state == VF_FADE_WAITING) { - s->factor=0; - if (frame_timestamp >= s->start_time/(double)AV_TIME_BASE - && inlink->frame_count >= s->start_frame) { - // Time to start fading - s->fade_state = VF_FADE_FADING; - - // Save start time in case we are starting based on frames and fading based on time - if (s->start_time == 0 && s->start_frame != 0) { - s->start_time = frame_timestamp*(double)AV_TIME_BASE; - } - - // Save start frame in case we are starting based on time and fading based on frames - if (s->start_time != 0 && s->start_frame == 0) { - s->start_frame = inlink->frame_count; - } - } - } - if (s->fade_state == VF_FADE_FADING) { - if (s->duration == 0) { - // Fading based on frame count - s->factor = (inlink->frame_count - s->start_frame) * s->fade_per_frame; - if (inlink->frame_count > s->start_frame + s->nb_frames) { - s->fade_state = VF_FADE_DONE; - } - - } else { - // Fading based on duration - s->factor = (frame_timestamp - s->start_time/(double)AV_TIME_BASE) - * (float) UINT16_MAX / (s->duration/(double)AV_TIME_BASE); - if (frame_timestamp > s->start_time/(double)AV_TIME_BASE - + s->duration/(double)AV_TIME_BASE) { - s->fade_state = VF_FADE_DONE; - } - } - } - if (s->fade_state == VF_FADE_DONE) { - s->factor=UINT16_MAX; - } - - s->factor = av_clip_uint16(s->factor); - - // Invert fade_factor if Fading Out - if (s->type == FADE_OUT) { - s->factor=UINT16_MAX-s->factor; - } - - if (s->factor < UINT16_MAX) { - if (s->alpha) { - ctx->internal->execute(ctx, filter_slice_alpha, frame, NULL, - FFMIN(frame->height, ctx->graph->nb_threads)); - } else if (s->is_packed_rgb && !s->black_fade) { - ctx->internal->execute(ctx, filter_slice_rgb, frame, NULL, - FFMIN(frame->height, ctx->graph->nb_threads)); - } else { - /* luma, or rgb plane in case of black */ - ctx->internal->execute(ctx, filter_slice_luma, frame, NULL, - FFMIN(frame->height, ctx->graph->nb_threads)); - - if (frame->data[1] && frame->data[2]) { - /* chroma planes */ - ctx->internal->execute(ctx, filter_slice_chroma, frame, NULL, - FFMIN(frame->height, ctx->graph->nb_threads)); - } - } - } - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - - -#define OFFSET(x) offsetof(FadeContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption fade_options[] = { - { "type", "'in' or 'out' for fade-in/fade-out", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = FADE_IN }, FADE_IN, FADE_OUT, FLAGS, "type" }, - { "t", "'in' or 'out' for fade-in/fade-out", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = FADE_IN }, FADE_IN, FADE_OUT, FLAGS, "type" }, - { "in", "fade-in", 0, AV_OPT_TYPE_CONST, { .i64 = FADE_IN }, .unit = "type" }, - { "out", "fade-out", 0, AV_OPT_TYPE_CONST, { .i64 = FADE_OUT }, .unit = "type" }, - { "start_frame", "Number of the first frame to which to apply the effect.", - OFFSET(start_frame), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, - { "s", "Number of the first frame to which to apply the effect.", - OFFSET(start_frame), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, - { "nb_frames", "Number of frames to which the effect should be applied.", - OFFSET(nb_frames), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX, FLAGS }, - { "n", "Number of frames to which the effect should be applied.", - OFFSET(nb_frames), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX, FLAGS }, - { "alpha", "fade alpha if it is available on the input", OFFSET(alpha), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, FLAGS }, - { "start_time", "Number of seconds of the beginning of the effect.", - OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "st", "Number of seconds of the beginning of the effect.", - OFFSET(start_time), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "duration", "Duration of the effect in seconds.", - OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "d", "Duration of the effect in seconds.", - OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0. }, 0, INT32_MAX, FLAGS }, - { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(fade); - -static const AVFilterPad avfilter_vf_fade_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - .filter_frame = filter_frame, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_fade_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_fade = { - .name = "fade", - .description = NULL_IF_CONFIG_SMALL("Fade in/out input video."), - .init = init, - .priv_size = sizeof(FadeContext), - .priv_class = &fade_class, - .query_formats = query_formats, - .inputs = avfilter_vf_fade_inputs, - .outputs = avfilter_vf_fade_outputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/vf_field.c b/ffmpeg/libavfilter/vf_field.c deleted file mode 100644 index ed12379..0000000 --- a/ffmpeg/libavfilter/vf_field.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2003 Rich Felker - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * field filter, based on libmpcodecs/vf_field.c by Rich Felker - */ - -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" - -enum FieldType { FIELD_TYPE_TOP = 0, FIELD_TYPE_BOTTOM }; - -typedef struct { - const AVClass *class; - enum FieldType type; - int nb_planes; ///< number of planes of the current format -} FieldContext; - -#define OFFSET(x) offsetof(FieldContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption field_options[] = { - {"type", "set field type (top or bottom)", OFFSET(type), AV_OPT_TYPE_INT, {.i64=FIELD_TYPE_TOP}, 0, 1, FLAGS, "field_type" }, - {"top", "select top field", 0, AV_OPT_TYPE_CONST, {.i64=FIELD_TYPE_TOP}, INT_MIN, INT_MAX, FLAGS, "field_type"}, - {"bottom", "select bottom field", 0, AV_OPT_TYPE_CONST, {.i64=FIELD_TYPE_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "field_type"}, - {NULL} -}; - -AVFILTER_DEFINE_CLASS(field); - -static int config_props_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - FieldContext *field = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - field->nb_planes = av_pix_fmt_count_planes(outlink->format); - - outlink->w = inlink->w; - outlink->h = (inlink->h + (field->type == FIELD_TYPE_TOP)) / 2; - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d type:%s -> w:%d h:%d\n", - inlink->w, inlink->h, field->type == FIELD_TYPE_BOTTOM ? "bottom" : "top", - outlink->w, outlink->h); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - FieldContext *field = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - int i; - - inpicref->height = outlink->h; - inpicref->interlaced_frame = 0; - - for (i = 0; i < field->nb_planes; i++) { - if (field->type == FIELD_TYPE_BOTTOM) - inpicref->data[i] = inpicref->data[i] + inpicref->linesize[i]; - inpicref->linesize[i] = 2 * inpicref->linesize[i]; - } - return ff_filter_frame(outlink, inpicref); -} - -static const AVFilterPad field_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad field_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props_output, - }, - { NULL } -}; - -AVFilter ff_vf_field = { - .name = "field", - .description = NULL_IF_CONFIG_SMALL("Extract a field from the input video."), - .priv_size = sizeof(FieldContext), - .inputs = field_inputs, - .outputs = field_outputs, - .priv_class = &field_class, -}; diff --git a/ffmpeg/libavfilter/vf_fieldorder.c b/ffmpeg/libavfilter/vf_fieldorder.c deleted file mode 100644 index 84088a0..0000000 --- a/ffmpeg/libavfilter/vf_fieldorder.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2011 Mark Himsley - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video field order filter, heavily influenced by vf_pad.c - */ - -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int dst_tff; ///< output bff/tff - int line_size[4]; ///< bytes of pixel data per line for each plane -} FieldOrderContext; - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats; - enum AVPixelFormat pix_fmt; - int ret; - - /** accept any input pixel format that is not hardware accelerated, not - * a bitstream format, and does not have vertically sub-sampled chroma */ - if (ctx->inputs[0]) { - formats = NULL; - for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - desc->nb_components && !desc->log2_chroma_h && - (ret = ff_add_format(&formats, pix_fmt)) < 0) { - ff_formats_unref(&formats); - return ret; - } - } - ff_formats_ref(formats, &ctx->inputs[0]->out_formats); - ff_formats_ref(formats, &ctx->outputs[0]->in_formats); - } - - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - FieldOrderContext *s = ctx->priv; - - return av_image_fill_linesizes(s->line_size, inlink->format, inlink->w); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - FieldOrderContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int h, plane, src_line_step, dst_line_step, line_size, line; - uint8_t *dst, *src; - AVFrame *out; - - if (!frame->interlaced_frame || - frame->top_field_first == s->dst_tff) { - av_log(ctx, AV_LOG_VERBOSE, - "Skipping %s.\n", - frame->interlaced_frame ? - "frame with same field order" : "progressive frame"); - return ff_filter_frame(outlink, frame); - } - - if (av_frame_is_writable(frame)) { - out = frame; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&frame); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, frame); - } - - av_dlog(ctx, - "picture will move %s one line\n", - s->dst_tff ? "up" : "down"); - h = frame->height; - for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) { - dst_line_step = out->linesize[plane]; - src_line_step = frame->linesize[plane]; - line_size = s->line_size[plane]; - dst = out->data[plane]; - src = frame->data[plane]; - if (s->dst_tff) { - /** Move every line up one line, working from - * the top to the bottom of the frame. - * The original top line is lost. - * The new last line is created as a copy of the - * penultimate line from that field. */ - for (line = 0; line < h; line++) { - if (1 + line < frame->height) { - memcpy(dst, src + src_line_step, line_size); - } else { - memcpy(dst, src - 2 * src_line_step, line_size); - } - dst += dst_line_step; - src += src_line_step; - } - } else { - /** Move every line down one line, working from - * the bottom to the top of the frame. - * The original bottom line is lost. - * The new first line is created as a copy of the - * second line from that field. */ - dst += (h - 1) * dst_line_step; - src += (h - 1) * src_line_step; - for (line = h - 1; line >= 0 ; line--) { - if (line > 0) { - memcpy(dst, src - src_line_step, line_size); - } else { - memcpy(dst, src + 2 * src_line_step, line_size); - } - dst -= dst_line_step; - src -= src_line_step; - } - } - } - out->top_field_first = s->dst_tff; - - if (frame != out) - av_frame_free(&frame); - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(FieldOrderContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption fieldorder_options[] = { - { "order", "output field order", OFFSET(dst_tff), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "order" }, - { "bff", "bottom field first", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags=FLAGS, .unit = "order" }, - { "tff", "top field first", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags=FLAGS, .unit = "order" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(fieldorder); - -static const AVFilterPad avfilter_vf_fieldorder_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_fieldorder_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_fieldorder = { - .name = "fieldorder", - .description = NULL_IF_CONFIG_SMALL("Set the field order."), - .priv_size = sizeof(FieldOrderContext), - .priv_class = &fieldorder_class, - .query_formats = query_formats, - .inputs = avfilter_vf_fieldorder_inputs, - .outputs = avfilter_vf_fieldorder_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_format.c b/ffmpeg/libavfilter/vf_format.c deleted file mode 100644 index 2e9ff27..0000000 --- a/ffmpeg/libavfilter/vf_format.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * format and noformat video filters - */ - -#include <string.h> - -#include "libavutil/internal.h" -#include "libavutil/mem.h" -#include "libavutil/pixdesc.h" -#include "libavutil/opt.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - char *pix_fmts; - /** - * List of flags telling if a given image format has been listed - * as argument to the filter. - */ - int listed_pix_fmt_flags[AV_PIX_FMT_NB]; -} FormatContext; - -#define AV_PIX_FMT_NAME_MAXSIZE 32 - -static av_cold int init(AVFilterContext *ctx) -{ - FormatContext *s = ctx->priv; - const char *cur, *sep; - char pix_fmt_name[AV_PIX_FMT_NAME_MAXSIZE]; - int pix_fmt_name_len, ret; - enum AVPixelFormat pix_fmt; - - /* parse the list of formats */ - for (cur = s->pix_fmts; cur; cur = sep ? sep + 1 : NULL) { - if (!(sep = strchr(cur, '|'))) - pix_fmt_name_len = strlen(cur); - else - pix_fmt_name_len = sep - cur; - if (pix_fmt_name_len >= AV_PIX_FMT_NAME_MAXSIZE) { - av_log(ctx, AV_LOG_ERROR, "Format name too long\n"); - return -1; - } - - memcpy(pix_fmt_name, cur, pix_fmt_name_len); - pix_fmt_name[pix_fmt_name_len] = 0; - - if ((ret = ff_parse_pixel_format(&pix_fmt, pix_fmt_name, ctx)) < 0) - return ret; - - s->listed_pix_fmt_flags[pix_fmt] = 1; - } - - return 0; -} - -static AVFilterFormats *make_format_list(FormatContext *s, int flag) -{ - AVFilterFormats *formats = NULL; - enum AVPixelFormat pix_fmt; - - for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) - if (s->listed_pix_fmt_flags[pix_fmt] == flag) { - int ret = ff_add_format(&formats, pix_fmt); - if (ret < 0) { - ff_formats_unref(&formats); - return NULL; - } - } - - return formats; -} - -#define OFFSET(x) offsetof(FormatContext, x) -static const AVOption options[] = { - { "pix_fmts", "A '|'-separated list of pixel formats", OFFSET(pix_fmts), AV_OPT_TYPE_STRING, .flags = AV_OPT_FLAG_VIDEO_PARAM }, - { NULL } -}; - -#if CONFIG_FORMAT_FILTER -static int query_formats_format(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, make_format_list(ctx->priv, 1)); - return 0; -} - -#define format_options options -AVFILTER_DEFINE_CLASS(format); - -static const AVFilterPad avfilter_vf_format_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = ff_null_get_video_buffer, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_format_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_format = { - .name = "format", - .description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."), - .init = init, - .query_formats = query_formats_format, - .priv_size = sizeof(FormatContext), - .priv_class = &format_class, - .inputs = avfilter_vf_format_inputs, - .outputs = avfilter_vf_format_outputs, -}; -#endif /* CONFIG_FORMAT_FILTER */ - -#if CONFIG_NOFORMAT_FILTER -static int query_formats_noformat(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, make_format_list(ctx->priv, 0)); - return 0; -} - -#define noformat_options options -AVFILTER_DEFINE_CLASS(noformat); - -static const AVFilterPad avfilter_vf_noformat_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = ff_null_get_video_buffer, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_noformat_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_noformat = { - .name = "noformat", - .description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."), - .init = init, - .query_formats = query_formats_noformat, - .priv_size = sizeof(FormatContext), - .priv_class = &noformat_class, - .inputs = avfilter_vf_noformat_inputs, - .outputs = avfilter_vf_noformat_outputs, -}; -#endif /* CONFIG_NOFORMAT_FILTER */ diff --git a/ffmpeg/libavfilter/vf_fps.c b/ffmpeg/libavfilter/vf_fps.c deleted file mode 100644 index e6266cc..0000000 --- a/ffmpeg/libavfilter/vf_fps.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2007 Bobby Bingham - * Copyright 2012 Robert Nagy <ronag89 gmail com> - * Copyright 2012 Anton Khirnov <anton khirnov net> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * a filter enforcing given constant framerate - */ - -#include <float.h> -#include <stdint.h> - -#include "libavutil/common.h" -#include "libavutil/fifo.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" - -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -typedef struct FPSContext { - const AVClass *class; - - AVFifoBuffer *fifo; ///< store frames until we get two successive timestamps - - /* timestamps in input timebase */ - int64_t first_pts; ///< pts of the first frame that arrived on this filter - int64_t pts; ///< pts of the first frame currently in the fifo - - double start_time; ///< pts, in seconds, of the expected first frame - - AVRational framerate; ///< target framerate - int rounding; ///< AVRounding method for timestamps - - /* statistics */ - int frames_in; ///< number of frames on input - int frames_out; ///< number of frames on output - int dup; ///< number of frames duplicated - int drop; ///< number of framed dropped -} FPSContext; - -#define OFFSET(x) offsetof(FPSContext, x) -#define V AV_OPT_FLAG_VIDEO_PARAM -#define F AV_OPT_FLAG_FILTERING_PARAM -static const AVOption fps_options[] = { - { "fps", "A string describing desired output framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, .flags = V|F }, - { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX}, -DBL_MAX, DBL_MAX, V }, - { "round", "set rounding method for timestamps", OFFSET(rounding), AV_OPT_TYPE_INT, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" }, - { "zero", "round towards 0", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_ZERO }, 0, 5, V|F, "round" }, - { "inf", "round away from 0", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_INF }, 0, 5, V|F, "round" }, - { "down", "round towards -infty", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_DOWN }, 0, 5, V|F, "round" }, - { "up", "round towards +infty", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_UP }, 0, 5, V|F, "round" }, - { "near", "round to nearest", OFFSET(rounding), AV_OPT_TYPE_CONST, { .i64 = AV_ROUND_NEAR_INF }, 0, 5, V|F, "round" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(fps); - -static av_cold int init(AVFilterContext *ctx) -{ - FPSContext *s = ctx->priv; - - if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*)))) - return AVERROR(ENOMEM); - - s->pts = AV_NOPTS_VALUE; - s->first_pts = AV_NOPTS_VALUE; - - av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den); - return 0; -} - -static void flush_fifo(AVFifoBuffer *fifo) -{ - while (av_fifo_size(fifo)) { - AVFrame *tmp; - av_fifo_generic_read(fifo, &tmp, sizeof(tmp), NULL); - av_frame_free(&tmp); - } -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - FPSContext *s = ctx->priv; - if (s->fifo) { - s->drop += av_fifo_size(s->fifo) / sizeof(AVFrame*); - flush_fifo(s->fifo); - av_fifo_free(s->fifo); - } - - av_log(ctx, AV_LOG_VERBOSE, "%d frames in, %d frames out; %d frames dropped, " - "%d frames duplicated.\n", s->frames_in, s->frames_out, s->drop, s->dup); -} - -static int config_props(AVFilterLink* link) -{ - FPSContext *s = link->src->priv; - - link->time_base = av_inv_q(s->framerate); - link->frame_rate= s->framerate; - link->w = link->src->inputs[0]->w; - link->h = link->src->inputs[0]->h; - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - FPSContext *s = ctx->priv; - int frames_out = s->frames_out; - int ret = 0; - - while (ret >= 0 && s->frames_out == frames_out) - ret = ff_request_frame(ctx->inputs[0]); - - /* flush the fifo */ - if (ret == AVERROR_EOF && av_fifo_size(s->fifo)) { - int i; - for (i = 0; av_fifo_size(s->fifo); i++) { - AVFrame *buf; - - av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL); - buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, - outlink->time_base) + s->frames_out; - - if ((ret = ff_filter_frame(outlink, buf)) < 0) - return ret; - - s->frames_out++; - } - return 0; - } - - return ret; -} - -static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf) -{ - int ret; - - if (!av_fifo_space(fifo) && - (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) { - av_frame_free(&buf); - return ret; - } - - av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *buf) -{ - AVFilterContext *ctx = inlink->dst; - FPSContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int64_t delta; - int i, ret; - - s->frames_in++; - /* discard frames until we get the first timestamp */ - if (s->pts == AV_NOPTS_VALUE) { - if (buf->pts != AV_NOPTS_VALUE) { - ret = write_to_fifo(s->fifo, buf); - if (ret < 0) - return ret; - - if (s->start_time != DBL_MAX && s->start_time != AV_NOPTS_VALUE) { - double first_pts = s->start_time * AV_TIME_BASE; - first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX); - s->first_pts = s->pts = av_rescale_q(first_pts, AV_TIME_BASE_Q, - inlink->time_base); - av_log(ctx, AV_LOG_VERBOSE, "Set first pts to (in:%"PRId64" out:%"PRId64")\n", - s->first_pts, av_rescale_q(first_pts, AV_TIME_BASE_Q, - outlink->time_base)); - } else { - s->first_pts = s->pts = buf->pts; - } - } else { - av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no " - "timestamp.\n"); - av_frame_free(&buf); - s->drop++; - } - return 0; - } - - /* now wait for the next timestamp */ - if (buf->pts == AV_NOPTS_VALUE || av_fifo_size(s->fifo) <= 0) { - return write_to_fifo(s->fifo, buf); - } - - /* number of output frames */ - delta = av_rescale_q_rnd(buf->pts - s->pts, inlink->time_base, - outlink->time_base, s->rounding); - - if (delta < 1) { - /* drop the frame and everything buffered except the first */ - AVFrame *tmp; - int drop = av_fifo_size(s->fifo)/sizeof(AVFrame*); - - av_log(ctx, AV_LOG_DEBUG, "Dropping %d frame(s).\n", drop); - s->drop += drop; - - av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL); - flush_fifo(s->fifo); - ret = write_to_fifo(s->fifo, tmp); - - av_frame_free(&buf); - return ret; - } - - /* can output >= 1 frames */ - for (i = 0; i < delta; i++) { - AVFrame *buf_out; - av_fifo_generic_read(s->fifo, &buf_out, sizeof(buf_out), NULL); - - /* duplicate the frame if needed */ - if (!av_fifo_size(s->fifo) && i < delta - 1) { - AVFrame *dup = av_frame_clone(buf_out); - - av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); - if (dup) - ret = write_to_fifo(s->fifo, dup); - else - ret = AVERROR(ENOMEM); - - if (ret < 0) { - av_frame_free(&buf_out); - av_frame_free(&buf); - return ret; - } - - s->dup++; - } - - buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base, - outlink->time_base) + s->frames_out; - - if ((ret = ff_filter_frame(outlink, buf_out)) < 0) { - av_frame_free(&buf); - return ret; - } - - s->frames_out++; - } - flush_fifo(s->fifo); - - ret = write_to_fifo(s->fifo, buf); - s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base); - - return ret; -} - -static const AVFilterPad avfilter_vf_fps_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_fps_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props - }, - { NULL } -}; - -AVFilter ff_vf_fps = { - .name = "fps", - .description = NULL_IF_CONFIG_SMALL("Force constant framerate."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(FPSContext), - .priv_class = &fps_class, - .inputs = avfilter_vf_fps_inputs, - .outputs = avfilter_vf_fps_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_framestep.c b/ffmpeg/libavfilter/vf_framestep.c deleted file mode 100644 index 9087f46..0000000 --- a/ffmpeg/libavfilter/vf_framestep.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file framestep filter, inspired on libmpcodecs/vf_framestep.c by - * Daniele Fornighieri <guru AT digitalfantasy it>. - */ - -#include "libavutil/opt.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int frame_step; -} FrameStepContext; - -#define OFFSET(x) offsetof(FrameStepContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption framestep_options[] = { - { "step", "set frame step", OFFSET(frame_step), AV_OPT_TYPE_INT, {.i64=1}, 1, INT_MAX, FLAGS}, - { NULL }, -}; - -AVFILTER_DEFINE_CLASS(framestep); - -static int config_output_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - FrameStepContext *framestep = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - outlink->frame_rate = - av_div_q(inlink->frame_rate, (AVRational){framestep->frame_step, 1}); - - av_log(ctx, AV_LOG_VERBOSE, "step:%d frame_rate:%d/%d(%f) -> frame_rate:%d/%d(%f)\n", - framestep->frame_step, - inlink->frame_rate.num, inlink->frame_rate.den, av_q2d(inlink->frame_rate), - outlink->frame_rate.num, outlink->frame_rate.den, av_q2d(outlink->frame_rate)); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *ref) -{ - FrameStepContext *framestep = inlink->dst->priv; - - if (!(inlink->frame_count % framestep->frame_step)) { - return ff_filter_frame(inlink->dst->outputs[0], ref); - } else { - av_frame_free(&ref); - return 0; - } -} - -static const AVFilterPad framestep_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad framestep_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output_props, - }, - { NULL } -}; - -AVFilter ff_vf_framestep = { - .name = "framestep", - .description = NULL_IF_CONFIG_SMALL("Select one frame every N frames."), - .priv_size = sizeof(FrameStepContext), - .priv_class = &framestep_class, - .inputs = framestep_inputs, - .outputs = framestep_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_frei0r.c b/ffmpeg/libavfilter/vf_frei0r.c deleted file mode 100644 index a070eb4..0000000 --- a/ffmpeg/libavfilter/vf_frei0r.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * frei0r wrapper - */ - -#include <dlfcn.h> -#include <frei0r.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "config.h" -#include "libavutil/avstring.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/mem.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height); -typedef void (*f0r_destruct_f)(f0r_instance_t instance); -typedef void (*f0r_deinit_f)(void); -typedef int (*f0r_init_f)(void); -typedef void (*f0r_get_plugin_info_f)(f0r_plugin_info_t *info); -typedef void (*f0r_get_param_info_f)(f0r_param_info_t *info, int param_index); -typedef void (*f0r_update_f)(f0r_instance_t instance, double time, const uint32_t *inframe, uint32_t *outframe); -typedef void (*f0r_update2_f)(f0r_instance_t instance, double time, const uint32_t *inframe1, const uint32_t *inframe2, const uint32_t *inframe3, uint32_t *outframe); -typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); -typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); - -typedef struct Frei0rContext { - const AVClass *class; - f0r_update_f update; - void *dl_handle; /* dynamic library handle */ - f0r_instance_t instance; - f0r_plugin_info_t plugin_info; - - f0r_get_param_info_f get_param_info; - f0r_get_param_value_f get_param_value; - f0r_set_param_value_f set_param_value; - f0r_construct_f construct; - f0r_destruct_f destruct; - f0r_deinit_f deinit; - - char *dl_name; - char *params; - AVRational framerate; - - /* only used by the source */ - int w, h; - AVRational time_base; - uint64_t pts; -} Frei0rContext; - -static void *load_sym(AVFilterContext *ctx, const char *sym_name) -{ - Frei0rContext *s = ctx->priv; - void *sym = dlsym(s->dl_handle, sym_name); - if (!sym) - av_log(ctx, AV_LOG_ERROR, "Could not find symbol '%s' in loaded module\n", sym_name); - return sym; -} - -static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param) -{ - Frei0rContext *s = ctx->priv; - union { - double d; - f0r_param_color_t col; - f0r_param_position_t pos; - } val; - char *tail; - uint8_t rgba[4]; - - switch (info.type) { - case F0R_PARAM_BOOL: - if (!strcmp(param, "y")) val.d = 1.0; - else if (!strcmp(param, "n")) val.d = 0.0; - else goto fail; - break; - - case F0R_PARAM_DOUBLE: - val.d = strtod(param, &tail); - if (*tail || val.d == HUGE_VAL) - goto fail; - break; - - case F0R_PARAM_COLOR: - if (sscanf(param, "%f/%f/%f", &val.col.r, &val.col.g, &val.col.b) != 3) { - if (av_parse_color(rgba, param, -1, ctx) < 0) - goto fail; - val.col.r = rgba[0] / 255.0; - val.col.g = rgba[1] / 255.0; - val.col.b = rgba[2] / 255.0; - } - break; - - case F0R_PARAM_POSITION: - if (sscanf(param, "%lf/%lf", &val.pos.x, &val.pos.y) != 2) - goto fail; - break; - } - - s->set_param_value(s->instance, &val, index); - return 0; - -fail: - av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for parameter '%s'\n", - param, info.name); - return AVERROR(EINVAL); -} - -static int set_params(AVFilterContext *ctx, const char *params) -{ - Frei0rContext *s = ctx->priv; - int i; - - if (!params) - return 0; - - for (i = 0; i < s->plugin_info.num_params; i++) { - f0r_param_info_t info; - char *param; - int ret; - - s->get_param_info(&info, i); - - if (*params) { - if (!(param = av_get_token(¶ms, "|"))) - return AVERROR(ENOMEM); - if (*params) - params++; /* skip ':' */ - ret = set_param(ctx, info, i, param); - av_free(param); - if (ret < 0) - return ret; - } - - av_log(ctx, AV_LOG_VERBOSE, - "idx:%d name:'%s' type:%s explanation:'%s' ", - i, info.name, - info.type == F0R_PARAM_BOOL ? "bool" : - info.type == F0R_PARAM_DOUBLE ? "double" : - info.type == F0R_PARAM_COLOR ? "color" : - info.type == F0R_PARAM_POSITION ? "position" : - info.type == F0R_PARAM_STRING ? "string" : "unknown", - info.explanation); - -#ifdef DEBUG - av_log(ctx, AV_LOG_DEBUG, "value:"); - switch (info.type) { - void *v; - double d; - char s[128]; - f0r_param_color_t col; - f0r_param_position_t pos; - - case F0R_PARAM_BOOL: - v = &d; - s->get_param_value(s->instance, v, i); - av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n"); - break; - case F0R_PARAM_DOUBLE: - v = &d; - s->get_param_value(s->instance, v, i); - av_log(ctx, AV_LOG_DEBUG, "%f", d); - break; - case F0R_PARAM_COLOR: - v = &col; - s->get_param_value(s->instance, v, i); - av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b); - break; - case F0R_PARAM_POSITION: - v = &pos; - s->get_param_value(s->instance, v, i); - av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y); - break; - default: /* F0R_PARAM_STRING */ - v = s; - s->get_param_value(s->instance, v, i); - av_log(ctx, AV_LOG_DEBUG, "'%s'\n", s); - break; - } -#endif - av_log(ctx, AV_LOG_VERBOSE, "\n"); - } - - return 0; -} - -static int load_path(AVFilterContext *ctx, void **handle_ptr, const char *prefix, const char *name) -{ - char *path = av_asprintf("%s%s%s", prefix, name, SLIBSUF); - if (!path) - return AVERROR(ENOMEM); - av_log(ctx, AV_LOG_DEBUG, "Looking for frei0r effect in '%s'\n", path); - *handle_ptr = dlopen(path, RTLD_NOW|RTLD_LOCAL); - av_free(path); - return 0; -} - -static av_cold int frei0r_init(AVFilterContext *ctx, - const char *dl_name, int type) -{ - Frei0rContext *s = ctx->priv; - f0r_init_f f0r_init; - f0r_get_plugin_info_f f0r_get_plugin_info; - f0r_plugin_info_t *pi; - char *path; - int ret = 0; - - if (!dl_name) { - av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n"); - return AVERROR(EINVAL); - } - - /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */ - if ((path = av_strdup(getenv("FREI0R_PATH")))) { -#ifdef _WIN32 - const char *separator = ";"; -#else - const char *separator = ":"; -#endif - char *p, *ptr = NULL; - for (p = path; p = av_strtok(p, separator, &ptr); p = NULL) { - /* add additional trailing slash in case it is missing */ - char *p1 = av_asprintf("%s/", p); - if (!p1) { - ret = AVERROR(ENOMEM); - goto check_path_end; - } - ret = load_path(ctx, &s->dl_handle, p1, dl_name); - av_free(p1); - if (ret < 0) - goto check_path_end; - if (s->dl_handle) - break; - } - - check_path_end: - av_free(path); - if (ret < 0) - return ret; - } - if (!s->dl_handle && (path = getenv("HOME"))) { - char *prefix = av_asprintf("%s/.frei0r-1/lib/", path); - if (!prefix) - return AVERROR(ENOMEM); - ret = load_path(ctx, &s->dl_handle, prefix, dl_name); - av_free(prefix); - if (ret < 0) - return ret; - } - if (!s->dl_handle) { - ret = load_path(ctx, &s->dl_handle, "/usr/local/lib/frei0r-1/", dl_name); - if (ret < 0) - return ret; - } - if (!s->dl_handle) { - ret = load_path(ctx, &s->dl_handle, "/usr/lib/frei0r-1/", dl_name); - if (ret < 0) - return ret; - } - if (!s->dl_handle) { - av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name); - return AVERROR(EINVAL); - } - - if (!(f0r_init = load_sym(ctx, "f0r_init" )) || - !(f0r_get_plugin_info = load_sym(ctx, "f0r_get_plugin_info")) || - !(s->get_param_info = load_sym(ctx, "f0r_get_param_info" )) || - !(s->get_param_value = load_sym(ctx, "f0r_get_param_value")) || - !(s->set_param_value = load_sym(ctx, "f0r_set_param_value")) || - !(s->update = load_sym(ctx, "f0r_update" )) || - !(s->construct = load_sym(ctx, "f0r_construct" )) || - !(s->destruct = load_sym(ctx, "f0r_destruct" )) || - !(s->deinit = load_sym(ctx, "f0r_deinit" ))) - return AVERROR(EINVAL); - - if (f0r_init() < 0) { - av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module\n"); - return AVERROR(EINVAL); - } - - f0r_get_plugin_info(&s->plugin_info); - pi = &s->plugin_info; - if (pi->plugin_type != type) { - av_log(ctx, AV_LOG_ERROR, - "Invalid type '%s' for the plugin\n", - pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" : - pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" : - pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" : - pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown"); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_VERBOSE, - "name:%s author:'%s' explanation:'%s' color_model:%s " - "frei0r_version:%d version:%d.%d num_params:%d\n", - pi->name, pi->author, pi->explanation, - pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" : - pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" : - pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown", - pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params); - - return 0; -} - -static av_cold int filter_init(AVFilterContext *ctx) -{ - Frei0rContext *s = ctx->priv; - - return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_FILTER); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - Frei0rContext *s = ctx->priv; - - if (s->destruct && s->instance) - s->destruct(s->instance); - if (s->deinit) - s->deinit(); - if (s->dl_handle) - dlclose(s->dl_handle); -} - -static int config_input_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - Frei0rContext *s = ctx->priv; - - if (s->destruct && s->instance) - s->destruct(s->instance); - if (!(s->instance = s->construct(inlink->w, inlink->h))) { - av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n"); - return AVERROR(EINVAL); - } - - return set_params(ctx, s->params); -} - -static int query_formats(AVFilterContext *ctx) -{ - Frei0rContext *s = ctx->priv; - AVFilterFormats *formats = NULL; - - if (s->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) { - ff_add_format(&formats, AV_PIX_FMT_BGRA); - } else if (s->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) { - ff_add_format(&formats, AV_PIX_FMT_RGBA); - } else { /* F0R_COLOR_MODEL_PACKED32 */ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_ARGB, AV_PIX_FMT_NONE - }; - formats = ff_make_format_list(pix_fmts); - } - - if (!formats) - return AVERROR(ENOMEM); - - ff_set_common_formats(ctx, formats); - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - Frei0rContext *s = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - s->update(s->instance, in->pts * av_q2d(inlink->time_base) * 1000, - (const uint32_t *)in->data[0], - (uint32_t *)out->data[0]); - - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(Frei0rContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption frei0r_options[] = { - { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(frei0r); - -static const AVFilterPad avfilter_vf_frei0r_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_frei0r_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_frei0r = { - .name = "frei0r", - .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."), - .query_formats = query_formats, - .init = filter_init, - .uninit = uninit, - .priv_size = sizeof(Frei0rContext), - .priv_class = &frei0r_class, - .inputs = avfilter_vf_frei0r_inputs, - .outputs = avfilter_vf_frei0r_outputs, -}; - -static av_cold int source_init(AVFilterContext *ctx) -{ - Frei0rContext *s = ctx->priv; - - s->time_base.num = s->framerate.den; - s->time_base.den = s->framerate.num; - - return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_SOURCE); -} - -static int source_config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - Frei0rContext *s = ctx->priv; - - if (av_image_check_size(s->w, s->h, 0, ctx) < 0) - return AVERROR(EINVAL); - outlink->w = s->w; - outlink->h = s->h; - outlink->time_base = s->time_base; - outlink->sample_aspect_ratio = (AVRational){1,1}; - - if (s->destruct && s->instance) - s->destruct(s->instance); - if (!(s->instance = s->construct(outlink->w, outlink->h))) { - av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n"); - return AVERROR(EINVAL); - } - - return set_params(ctx, s->params); -} - -static int source_request_frame(AVFilterLink *outlink) -{ - Frei0rContext *s = outlink->src->priv; - AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h); - - if (!frame) - return AVERROR(ENOMEM); - - frame->sample_aspect_ratio = (AVRational) {1, 1}; - frame->pts = s->pts++; - - s->update(s->instance, av_rescale_q(frame->pts, s->time_base, (AVRational){1,1000}), - NULL, (uint32_t *)frame->data[0]); - - return ff_filter_frame(outlink, frame); -} - -static const AVOption frei0r_src_options[] = { - { "size", "Dimensions of the generated video.", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, { .str = "320x240" }, .flags = FLAGS }, - { "framerate", NULL, OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, { .str = "25" }, .flags = FLAGS }, - { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { NULL }, -}; - -AVFILTER_DEFINE_CLASS(frei0r_src); - -static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = source_request_frame, - .config_props = source_config_props - }, - { NULL } -}; - -AVFilter ff_vsrc_frei0r_src = { - .name = "frei0r_src", - .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."), - .priv_size = sizeof(Frei0rContext), - .priv_class = &frei0r_src_class, - .init = source_init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = avfilter_vsrc_frei0r_src_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_geq.c b/ffmpeg/libavfilter/vf_geq.c deleted file mode 100644 index 49a3e62..0000000 --- a/ffmpeg/libavfilter/vf_geq.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at> - * Copyright (C) 2012 Clément BÅ“sch <u pkh me> - * - * 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 - * Generic equation change filter - * Originally written by Michael Niedermayer for the MPlayer project, and - * ported by Clément BÅ“sch for FFmpeg. - */ - -#include "libavutil/avstring.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - AVExpr *e[4]; ///< expressions for each plane - char *expr_str[4+3]; ///< expression strings for each plane - AVFrame *picref; ///< current input buffer - int hsub, vsub; ///< chroma subsampling - int planes; ///< number of planes - int is_rgb; -} GEQContext; - -enum { Y = 0, U, V, A, G, B, R }; - -#define OFFSET(x) offsetof(GEQContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption geq_options[] = { - { "lum_expr", "set luminance expression", OFFSET(expr_str[Y]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "lum", "set luminance expression", OFFSET(expr_str[Y]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "cb_expr", "set chroma blue expression", OFFSET(expr_str[U]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "cb", "set chroma blue expression", OFFSET(expr_str[U]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "cr_expr", "set chroma red expression", OFFSET(expr_str[V]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "cr", "set chroma red expression", OFFSET(expr_str[V]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "alpha_expr", "set alpha expression", OFFSET(expr_str[A]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "a", "set alpha expression", OFFSET(expr_str[A]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "red_expr", "set red expression", OFFSET(expr_str[R]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "r", "set red expression", OFFSET(expr_str[R]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "green_expr", "set green expression", OFFSET(expr_str[G]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "g", "set green expression", OFFSET(expr_str[G]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "blue_expr", "set blue expression", OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "b", "set blue expression", OFFSET(expr_str[B]), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, - {NULL}, -}; - -AVFILTER_DEFINE_CLASS(geq); - -static inline double getpix(void *priv, double x, double y, int plane) -{ - int xi, yi; - GEQContext *geq = priv; - AVFrame *picref = geq->picref; - const uint8_t *src = picref->data[plane]; - const int linesize = picref->linesize[plane]; - const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->width, geq->hsub) : picref->width; - const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->height, geq->vsub) : picref->height; - - if (!src) - return 0; - - xi = x = av_clipf(x, 0, w - 2); - yi = y = av_clipf(y, 0, h - 2); - - x -= xi; - y -= yi; - - return (1-y)*((1-x)*src[xi + yi * linesize] + x*src[xi + 1 + yi * linesize]) - + y *((1-x)*src[xi + (yi+1) * linesize] + x*src[xi + 1 + (yi+1) * linesize]); -} - -//TODO: cubic interpolate -//TODO: keep the last few frames -static double lum(void *priv, double x, double y) { return getpix(priv, x, y, 0); } -static double cb(void *priv, double x, double y) { return getpix(priv, x, y, 1); } -static double cr(void *priv, double x, double y) { return getpix(priv, x, y, 2); } -static double alpha(void *priv, double x, double y) { return getpix(priv, x, y, 3); } - -static const char *const var_names[] = { "X", "Y", "W", "H", "N", "SW", "SH", "T", NULL }; -enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_SW, VAR_SH, VAR_T, VAR_VARS_NB }; - -static av_cold int geq_init(AVFilterContext *ctx) -{ - GEQContext *geq = ctx->priv; - int plane, ret = 0; - - if (!geq->expr_str[Y] && !geq->expr_str[G] && !geq->expr_str[B] && !geq->expr_str[R]) { - av_log(ctx, AV_LOG_ERROR, "A luminance or RGB expression is mandatory\n"); - ret = AVERROR(EINVAL); - goto end; - } - geq->is_rgb = !geq->expr_str[Y]; - - if ((geq->expr_str[Y] || geq->expr_str[U] || geq->expr_str[V]) && (geq->expr_str[G] || geq->expr_str[B] || geq->expr_str[R])) { - av_log(ctx, AV_LOG_ERROR, "Either YCbCr or RGB but not both must be specified\n"); - ret = AVERROR(EINVAL); - goto end; - } - - if (!geq->expr_str[U] && !geq->expr_str[V]) { - /* No chroma at all: fallback on luma */ - geq->expr_str[U] = av_strdup(geq->expr_str[Y]); - geq->expr_str[V] = av_strdup(geq->expr_str[Y]); - } else { - /* One chroma unspecified, fallback on the other */ - if (!geq->expr_str[U]) geq->expr_str[U] = av_strdup(geq->expr_str[V]); - if (!geq->expr_str[V]) geq->expr_str[V] = av_strdup(geq->expr_str[U]); - } - - if (!geq->expr_str[A]) - geq->expr_str[A] = av_strdup("255"); - if (!geq->expr_str[G]) - geq->expr_str[G] = av_strdup("g(X,Y)"); - if (!geq->expr_str[B]) - geq->expr_str[B] = av_strdup("b(X,Y)"); - if (!geq->expr_str[R]) - geq->expr_str[R] = av_strdup("r(X,Y)"); - - if (geq->is_rgb ? - (!geq->expr_str[G] || !geq->expr_str[B] || !geq->expr_str[R]) - : - (!geq->expr_str[U] || !geq->expr_str[V] || !geq->expr_str[A])) { - ret = AVERROR(ENOMEM); - goto end; - } - - for (plane = 0; plane < 4; plane++) { - static double (*p[])(void *, double, double) = { lum, cb, cr, alpha }; - static const char *const func2_yuv_names[] = { "lum", "cb", "cr", "alpha", "p", NULL }; - static const char *const func2_rgb_names[] = { "g", "b", "r", "alpha", "p", NULL }; - const char *const *func2_names = geq->is_rgb ? func2_rgb_names : func2_yuv_names; - double (*func2[])(void *, double, double) = { lum, cb, cr, alpha, p[plane], NULL }; - - ret = av_expr_parse(&geq->e[plane], geq->expr_str[plane < 3 && geq->is_rgb ? plane+4 : plane], var_names, - NULL, NULL, func2_names, func2, 0, ctx); - if (ret < 0) - break; - } - -end: - return ret; -} - -static int geq_query_formats(AVFilterContext *ctx) -{ - GEQContext *geq = ctx->priv; - static const enum PixelFormat yuv_pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_NONE - }; - static const enum PixelFormat rgb_pix_fmts[] = { - AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, - AV_PIX_FMT_NONE - }; - if (geq->is_rgb) { - ff_set_common_formats(ctx, ff_make_format_list(rgb_pix_fmts)); - } else - ff_set_common_formats(ctx, ff_make_format_list(yuv_pix_fmts)); - return 0; -} - -static int geq_config_props(AVFilterLink *inlink) -{ - GEQContext *geq = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - - geq->hsub = desc->log2_chroma_w; - geq->vsub = desc->log2_chroma_h; - geq->planes = desc->nb_components; - return 0; -} - -static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - int plane; - GEQContext *geq = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - double values[VAR_VARS_NB] = { - [VAR_N] = inlink->frame_count, - [VAR_T] = in->pts == AV_NOPTS_VALUE ? NAN : in->pts * av_q2d(inlink->time_base), - }; - - geq->picref = in; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - for (plane = 0; plane < geq->planes && out->data[plane]; plane++) { - int x, y; - uint8_t *dst = out->data[plane]; - const int linesize = out->linesize[plane]; - const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, geq->hsub) : inlink->w; - const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, geq->vsub) : inlink->h; - - values[VAR_W] = w; - values[VAR_H] = h; - values[VAR_SW] = w / (double)inlink->w; - values[VAR_SH] = h / (double)inlink->h; - - for (y = 0; y < h; y++) { - values[VAR_Y] = y; - for (x = 0; x < w; x++) { - values[VAR_X] = x; - dst[x] = av_expr_eval(geq->e[plane], values, geq); - } - dst += linesize; - } - } - - av_frame_free(&geq->picref); - return ff_filter_frame(outlink, out); -} - -static av_cold void geq_uninit(AVFilterContext *ctx) -{ - int i; - GEQContext *geq = ctx->priv; - - for (i = 0; i < FF_ARRAY_ELEMS(geq->e); i++) - av_expr_free(geq->e[i]); -} - -static const AVFilterPad geq_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = geq_config_props, - .filter_frame = geq_filter_frame, - }, - { NULL } -}; - -static const AVFilterPad geq_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_geq = { - .name = "geq", - .description = NULL_IF_CONFIG_SMALL("Apply generic equation to each pixel."), - .priv_size = sizeof(GEQContext), - .init = geq_init, - .uninit = geq_uninit, - .query_formats = geq_query_formats, - .inputs = geq_inputs, - .outputs = geq_outputs, - .priv_class = &geq_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_gradfun.c b/ffmpeg/libavfilter/vf_gradfun.c deleted file mode 100644 index 0da9e0b..0000000 --- a/ffmpeg/libavfilter/vf_gradfun.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2010 Nolan Lum <nol888@gmail.com> - * Copyright (c) 2009 Loren Merritt <lorenm@u.washington.edu> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * gradfun debanding filter, ported from MPlayer - * libmpcodecs/vf_gradfun.c - * - * Apply a boxblur debanding algorithm (based on the gradfun2db - * AviSynth filter by prunedtree). - * Foreach pixel, if it's within threshold of the blurred value, make it closer. - * So now we have a smoothed and higher bitdepth version of all the shallow - * gradients, while leaving detailed areas untouched. - * Dither it back to 8bit. - */ - -#include "libavutil/imgutils.h" -#include "libavutil/common.h" -#include "libavutil/cpu.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "gradfun.h" -#include "internal.h" -#include "video.h" - -DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = { - {0x00,0x60,0x18,0x78,0x06,0x66,0x1E,0x7E}, - {0x40,0x20,0x58,0x38,0x46,0x26,0x5E,0x3E}, - {0x10,0x70,0x08,0x68,0x16,0x76,0x0E,0x6E}, - {0x50,0x30,0x48,0x28,0x56,0x36,0x4E,0x2E}, - {0x04,0x64,0x1C,0x7C,0x02,0x62,0x1A,0x7A}, - {0x44,0x24,0x5C,0x3C,0x42,0x22,0x5A,0x3A}, - {0x14,0x74,0x0C,0x6C,0x12,0x72,0x0A,0x6A}, - {0x54,0x34,0x4C,0x2C,0x52,0x32,0x4A,0x2A}, -}; - -void ff_gradfun_filter_line_c(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers) -{ - int x; - for (x = 0; x < width; dc += x & 1, x++) { - int pix = src[x] << 7; - int delta = dc[0] - pix; - int m = abs(delta) * thresh >> 16; - m = FFMAX(0, 127 - m); - m = m * m * delta >> 14; - pix += m + dithers[x & 7]; - dst[x] = av_clip_uint8(pix >> 7); - } -} - -void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width) -{ - int x, v, old; - for (x = 0; x < width; x++) { - v = buf1[x] + src[2 * x] + src[2 * x + 1] + src[2 * x + src_linesize] + src[2 * x + 1 + src_linesize]; - old = buf[x]; - buf[x] = v; - dc[x] = v - old; - } -} - -static void filter(GradFunContext *ctx, uint8_t *dst, const uint8_t *src, int width, int height, int dst_linesize, int src_linesize, int r) -{ - int bstride = FFALIGN(width, 16) / 2; - int y; - uint32_t dc_factor = (1 << 21) / (r * r); - uint16_t *dc = ctx->buf + 16; - uint16_t *buf = ctx->buf + bstride + 32; - int thresh = ctx->thresh; - - memset(dc, 0, (bstride + 16) * sizeof(*buf)); - for (y = 0; y < r; y++) - ctx->blur_line(dc, buf + y * bstride, buf + (y - 1) * bstride, src + 2 * y * src_linesize, src_linesize, width / 2); - for (;;) { - if (y < height - r) { - int mod = ((y + r) / 2) % r; - uint16_t *buf0 = buf + mod * bstride; - uint16_t *buf1 = buf + (mod ? mod - 1 : r - 1) * bstride; - int x, v; - ctx->blur_line(dc, buf0, buf1, src + (y + r) * src_linesize, src_linesize, width / 2); - for (x = v = 0; x < r; x++) - v += dc[x]; - for (; x < width / 2; x++) { - v += dc[x] - dc[x-r]; - dc[x-r] = v * dc_factor >> 16; - } - for (; x < (width + r + 1) / 2; x++) - dc[x-r] = v * dc_factor >> 16; - for (x = -r / 2; x < 0; x++) - dc[x] = dc[0]; - } - if (y == r) { - for (y = 0; y < r; y++) - ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]); - } - ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]); - if (++y >= height) break; - ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]); - if (++y >= height) break; - } - emms_c(); -} - -static av_cold int init(AVFilterContext *ctx) -{ - GradFunContext *s = ctx->priv; - - s->thresh = (1 << 15) / s->strength; - s->radius = av_clip((s->radius + 1) & ~1, 4, 32); - - s->blur_line = ff_gradfun_blur_line_c; - s->filter_line = ff_gradfun_filter_line_c; - - if (ARCH_X86) - ff_gradfun_init_x86(s); - - av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", s->strength, s->radius); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - GradFunContext *s = ctx->priv; - av_freep(&s->buf); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_GBRP, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - GradFunContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int hsub = desc->log2_chroma_w; - int vsub = desc->log2_chroma_h; - - av_freep(&s->buf); - s->buf = av_calloc((FFALIGN(inlink->w, 16) * (s->radius + 1) / 2 + 32), sizeof(*s->buf)); - if (!s->buf) - return AVERROR(ENOMEM); - - s->chroma_w = FF_CEIL_RSHIFT(inlink->w, hsub); - s->chroma_h = FF_CEIL_RSHIFT(inlink->h, vsub); - s->chroma_r = av_clip(((((s->radius >> hsub) + (s->radius >> vsub)) / 2 ) + 1) & ~1, 4, 32); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - GradFunContext *s = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - int p, direct; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - direct = 0; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - } - - for (p = 0; p < 4 && in->data[p] && in->linesize[p]; p++) { - int w = inlink->w; - int h = inlink->h; - int r = s->radius; - if (p) { - w = s->chroma_w; - h = s->chroma_h; - r = s->chroma_r; - } - - if (FFMIN(w, h) > 2 * r) - filter(s, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r); - else if (out->data[p] != in->data[p]) - av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], w, h); - } - - if (!direct) - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(GradFunContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption gradfun_options[] = { - { "strength", "The maximum amount by which the filter will change any one pixel.", OFFSET(strength), AV_OPT_TYPE_FLOAT, { .dbl = 1.2 }, 0.51, 64, FLAGS }, - { "radius", "The neighborhood to fit the gradient to.", OFFSET(radius), AV_OPT_TYPE_INT, { .i64 = 16 }, 4, 32, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(gradfun); - -static const AVFilterPad avfilter_vf_gradfun_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_gradfun_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_gradfun = { - .name = "gradfun", - .description = NULL_IF_CONFIG_SMALL("Debands video quickly using gradients."), - .priv_size = sizeof(GradFunContext), - .priv_class = &gradfun_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_vf_gradfun_inputs, - .outputs = avfilter_vf_gradfun_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_hflip.c b/ffmpeg/libavfilter/vf_hflip.c deleted file mode 100644 index 19b6606..0000000 --- a/ffmpeg/libavfilter/vf_hflip.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2007 Benoit Fouet - * Copyright (c) 2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * horizontal flip filter - */ - -#include <string.h> - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/pixdesc.h" -#include "libavutil/internal.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/imgutils.h" - -typedef struct { - int max_step[4]; ///< max pixel step for each plane, expressed as a number of bytes - int planewidth[4]; ///< width of each plane - int planeheight[4]; ///< height of each plane -} FlipContext; - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *pix_fmts = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM || - (desc->log2_chroma_w != desc->log2_chroma_h && - desc->comp[0].plane == desc->comp[1].plane))) - ff_add_format(&pix_fmts, fmt); - } - - ff_set_common_formats(ctx, pix_fmts); - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - FlipContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - const int hsub = pix_desc->log2_chroma_w; - const int vsub = pix_desc->log2_chroma_h; - - av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc); - s->planewidth[0] = s->planewidth[3] = inlink->w; - s->planewidth[1] = s->planewidth[2] = FF_CEIL_RSHIFT(inlink->w, hsub); - s->planeheight[0] = s->planeheight[3] = inlink->h; - s->planeheight[1] = s->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, vsub); - - return 0; -} - -typedef struct ThreadData { - AVFrame *in, *out; -} ThreadData; - -static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) -{ - FlipContext *s = ctx->priv; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - uint8_t *inrow, *outrow; - int i, j, plane, step; - - for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { - const int width = s->planewidth[plane]; - const int height = s->planeheight[plane]; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; - - step = s->max_step[plane]; - - outrow = out->data[plane] + start * out->linesize[plane]; - inrow = in ->data[plane] + start * in->linesize[plane] + (width - 1) * step; - for (i = start; i < end; i++) { - switch (step) { - case 1: - for (j = 0; j < width; j++) - outrow[j] = inrow[-j]; - break; - - case 2: - { - uint16_t *outrow16 = (uint16_t *)outrow; - uint16_t * inrow16 = (uint16_t *) inrow; - for (j = 0; j < width; j++) - outrow16[j] = inrow16[-j]; - } - break; - - case 3: - { - uint8_t *in = inrow; - uint8_t *out = outrow; - for (j = 0; j < width; j++, out += 3, in -= 3) { - int32_t v = AV_RB24(in); - AV_WB24(out, v); - } - } - break; - - case 4: - { - uint32_t *outrow32 = (uint32_t *)outrow; - uint32_t * inrow32 = (uint32_t *) inrow; - for (j = 0; j < width; j++) - outrow32[j] = inrow32[-j]; - } - break; - - default: - for (j = 0; j < width; j++) - memcpy(outrow + j*step, inrow - j*step, step); - } - - inrow += in ->linesize[plane]; - outrow += out->linesize[plane]; - } - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - ThreadData td; - AVFrame *out; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - /* copy palette if required */ - if (av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_PAL) - memcpy(out->data[1], in->data[1], AVPALETTE_SIZE); - - td.in = in, td.out = out; - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads)); - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad avfilter_vf_hflip_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_hflip_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_hflip = { - .name = "hflip", - .description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."), - .priv_size = sizeof(FlipContext), - .query_formats = query_formats, - .inputs = avfilter_vf_hflip_inputs, - .outputs = avfilter_vf_hflip_outputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/vf_histeq.c b/ffmpeg/libavfilter/vf_histeq.c deleted file mode 100644 index 6fdb7be..0000000 --- a/ffmpeg/libavfilter/vf_histeq.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2012 Jeremy Tran - * Copyright (c) 2001 Donald A. Graft - * - * 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 - * Histogram equalization filter, based on the VirtualDub filter by - * Donald A. Graft <neuron2 AT home DOT com>. - * Implements global automatic contrast adjustment by means of - * histogram equalization. - */ - -#include "libavutil/common.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" - -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -// #define DEBUG - -// Linear Congruential Generator, see "Numerical Recipes" -#define LCG_A 4096 -#define LCG_C 150889 -#define LCG_M 714025 -#define LCG(x) (((x) * LCG_A + LCG_C) % LCG_M) -#define LCG_SEED 739187 - -enum HisteqAntibanding { - HISTEQ_ANTIBANDING_NONE = 0, - HISTEQ_ANTIBANDING_WEAK = 1, - HISTEQ_ANTIBANDING_STRONG = 2, - HISTEQ_ANTIBANDING_NB, -}; - -typedef struct { - const AVClass *class; - float strength; - float intensity; - enum HisteqAntibanding antibanding; - int in_histogram [256]; ///< input histogram - int out_histogram[256]; ///< output histogram - int LUT[256]; ///< lookup table derived from histogram[] - uint8_t rgba_map[4]; ///< components position - int bpp; ///< bytes per pixel -} HisteqContext; - -#define OFFSET(x) offsetof(HisteqContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit } - -static const AVOption histeq_options[] = { - { "strength", "set the strength", OFFSET(strength), AV_OPT_TYPE_FLOAT, {.dbl=0.2}, 0, 1, FLAGS }, - { "intensity", "set the intensity", OFFSET(intensity), AV_OPT_TYPE_FLOAT, {.dbl=0.21}, 0, 1, FLAGS }, - { "antibanding", "set the antibanding level", OFFSET(antibanding), AV_OPT_TYPE_INT, {.i64=HISTEQ_ANTIBANDING_NONE}, 0, HISTEQ_ANTIBANDING_NB-1, FLAGS, "antibanding" }, - CONST("none", "apply no antibanding", HISTEQ_ANTIBANDING_NONE, "antibanding"), - CONST("weak", "apply weak antibanding", HISTEQ_ANTIBANDING_WEAK, "antibanding"), - CONST("strong", "apply strong antibanding", HISTEQ_ANTIBANDING_STRONG, "antibanding"), - { NULL } -}; - -AVFILTER_DEFINE_CLASS(histeq); - -static av_cold int init(AVFilterContext *ctx) -{ - HisteqContext *histeq = ctx->priv; - - av_log(ctx, AV_LOG_VERBOSE, - "strength:%0.3f intensity:%0.3f antibanding:%d\n", - histeq->strength, histeq->intensity, histeq->antibanding); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum PixelFormat pix_fmts[] = { - AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - HisteqContext *histeq = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - - histeq->bpp = av_get_bits_per_pixel(pix_desc) / 8; - ff_fill_rgba_map(histeq->rgba_map, inlink->format); - - return 0; -} - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -#define GET_RGB_VALUES(r, g, b, src, map) do { \ - r = src[x + map[R]]; \ - g = src[x + map[G]]; \ - b = src[x + map[B]]; \ -} while (0) - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) -{ - AVFilterContext *ctx = inlink->dst; - HisteqContext *histeq = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int strength = histeq->strength * 1000; - int intensity = histeq->intensity * 1000; - int x, y, i, luthi, lutlo, lut, luma, oluma, m; - AVFrame *outpic; - unsigned int r, g, b, jran; - uint8_t *src, *dst; - - outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpic) { - av_frame_free(&inpic); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpic, inpic); - - /* Seed random generator for antibanding. */ - jran = LCG_SEED; - - /* Calculate and store the luminance and calculate the global histogram - based on the luminance. */ - memset(histeq->in_histogram, 0, sizeof(histeq->in_histogram)); - src = inpic->data[0]; - dst = outpic->data[0]; - for (y = 0; y < inlink->h; y++) { - for (x = 0; x < inlink->w * histeq->bpp; x += histeq->bpp) { - GET_RGB_VALUES(r, g, b, src, histeq->rgba_map); - luma = (55 * r + 182 * g + 19 * b) >> 8; - dst[x + histeq->rgba_map[A]] = luma; - histeq->in_histogram[luma]++; - } - src += inpic->linesize[0]; - dst += outpic->linesize[0]; - } - -#ifdef DEBUG - for (x = 0; x < 256; x++) - av_dlog(ctx, "in[%d]: %u\n", x, histeq->in_histogram[x]); -#endif - - /* Calculate the lookup table. */ - histeq->LUT[0] = histeq->in_histogram[0]; - /* Accumulate */ - for (x = 1; x < 256; x++) - histeq->LUT[x] = histeq->LUT[x-1] + histeq->in_histogram[x]; - - /* Normalize */ - for (x = 0; x < 256; x++) - histeq->LUT[x] = (histeq->LUT[x] * intensity) / (inlink->h * inlink->w); - - /* Adjust the LUT based on the selected strength. This is an alpha - mix of the calculated LUT and a linear LUT with gain 1. */ - for (x = 0; x < 256; x++) - histeq->LUT[x] = (strength * histeq->LUT[x]) / 255 + - ((255 - strength) * x) / 255; - - /* Output the equalized frame. */ - memset(histeq->out_histogram, 0, sizeof(histeq->out_histogram)); - - src = inpic->data[0]; - dst = outpic->data[0]; - for (y = 0; y < inlink->h; y++) { - for (x = 0; x < inlink->w * histeq->bpp; x += histeq->bpp) { - luma = dst[x + histeq->rgba_map[A]]; - if (luma == 0) { - for (i = 0; i < histeq->bpp; ++i) - dst[x + i] = 0; - histeq->out_histogram[0]++; - } else { - lut = histeq->LUT[luma]; - if (histeq->antibanding != HISTEQ_ANTIBANDING_NONE) { - if (luma > 0) { - lutlo = histeq->antibanding == HISTEQ_ANTIBANDING_WEAK ? - (histeq->LUT[luma] + histeq->LUT[luma - 1]) / 2 : - histeq->LUT[luma - 1]; - } else - lutlo = lut; - - if (luma < 255) { - luthi = (histeq->antibanding == HISTEQ_ANTIBANDING_WEAK) ? - (histeq->LUT[luma] + histeq->LUT[luma + 1]) / 2 : - histeq->LUT[luma + 1]; - } else - luthi = lut; - - if (lutlo != luthi) { - jran = LCG(jran); - lut = lutlo + ((luthi - lutlo + 1) * jran) / LCG_M; - } - } - - GET_RGB_VALUES(r, g, b, src, histeq->rgba_map); - if (((m = FFMAX3(r, g, b)) * lut) / luma > 255) { - r = (r * 255) / m; - g = (g * 255) / m; - b = (b * 255) / m; - } else { - r = (r * lut) / luma; - g = (g * lut) / luma; - b = (b * lut) / luma; - } - dst[x + histeq->rgba_map[R]] = r; - dst[x + histeq->rgba_map[G]] = g; - dst[x + histeq->rgba_map[B]] = b; - oluma = av_clip_uint8((55 * r + 182 * g + 19 * b) >> 8); - histeq->out_histogram[oluma]++; - } - } - src += inpic->linesize[0]; - dst += outpic->linesize[0]; - } -#ifdef DEBUG - for (x = 0; x < 256; x++) - av_dlog(ctx, "out[%d]: %u\n", x, histeq->out_histogram[x]); -#endif - - av_frame_free(&inpic); - return ff_filter_frame(outlink, outpic); -} - -static const AVFilterPad histeq_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad histeq_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_histeq = { - .name = "histeq", - .description = NULL_IF_CONFIG_SMALL("Apply global color histogram equalization."), - .priv_size = sizeof(HisteqContext), - .init = init, - .query_formats = query_formats, - .inputs = histeq_inputs, - .outputs = histeq_outputs, - .priv_class = &histeq_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_histogram.c b/ffmpeg/libavfilter/vf_histogram.c deleted file mode 100644 index 34656b5..0000000 --- a/ffmpeg/libavfilter/vf_histogram.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2012-2013 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avassert.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -enum HistogramMode { - MODE_LEVELS, - MODE_WAVEFORM, - MODE_COLOR, - MODE_COLOR2, - MODE_NB -}; - -typedef struct HistogramContext { - const AVClass *class; ///< AVClass context for log and options purpose - enum HistogramMode mode; - unsigned histogram[256]; - int ncomp; - const uint8_t *bg_color; - const uint8_t *fg_color; - int level_height; - int scale_height; - int step; - int waveform_mode; - int waveform_mirror; - int display_mode; - int levels_mode; - const AVPixFmtDescriptor *desc; -} HistogramContext; - -#define OFFSET(x) offsetof(HistogramContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption histogram_options[] = { - { "mode", "set histogram mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_LEVELS}, 0, MODE_NB-1, FLAGS, "mode"}, - { "levels", "standard histogram", 0, AV_OPT_TYPE_CONST, {.i64=MODE_LEVELS}, 0, 0, FLAGS, "mode" }, - { "waveform", "per row/column luminance graph", 0, AV_OPT_TYPE_CONST, {.i64=MODE_WAVEFORM}, 0, 0, FLAGS, "mode" }, - { "color", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR}, 0, 0, FLAGS, "mode" }, - { "color2", "chroma values in vectorscope", 0, AV_OPT_TYPE_CONST, {.i64=MODE_COLOR2}, 0, 0, FLAGS, "mode" }, - { "level_height", "set level height", OFFSET(level_height), AV_OPT_TYPE_INT, {.i64=200}, 50, 2048, FLAGS}, - { "scale_height", "set scale height", OFFSET(scale_height), AV_OPT_TYPE_INT, {.i64=12}, 0, 40, FLAGS}, - { "step", "set waveform step value", OFFSET(step), AV_OPT_TYPE_INT, {.i64=10}, 1, 255, FLAGS}, - { "waveform_mode", "set waveform mode", OFFSET(waveform_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "waveform_mode"}, - { "row", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "waveform_mode" }, - { "column", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "waveform_mode" }, - { "waveform_mirror", "set waveform mirroring", OFFSET(waveform_mirror), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "waveform_mirror"}, - { "display_mode", "set display mode", OFFSET(display_mode), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, "display_mode"}, - { "parade", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "display_mode" }, - { "overlay", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "display_mode" }, - { "levels_mode", "set levels mode", OFFSET(levels_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "levels_mode"}, - { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "levels_mode" }, - { "logarithmic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "levels_mode" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(histogram); - -static const enum AVPixelFormat color_pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_NONE -}; - -static const enum AVPixelFormat levels_pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE -}; - -static const enum AVPixelFormat waveform_pix_fmts[] = { - AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP, - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_NONE -}; - -static int query_formats(AVFilterContext *ctx) -{ - HistogramContext *h = ctx->priv; - const enum AVPixelFormat *pix_fmts; - - switch (h->mode) { - case MODE_WAVEFORM: - pix_fmts = waveform_pix_fmts; - break; - case MODE_LEVELS: - pix_fmts = levels_pix_fmts; - break; - case MODE_COLOR: - case MODE_COLOR2: - pix_fmts = color_pix_fmts; - break; - default: - av_assert0(0); - } - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static const uint8_t black_yuva_color[4] = { 0, 127, 127, 255 }; -static const uint8_t black_gbrp_color[4] = { 0, 0, 0, 255 }; -static const uint8_t white_yuva_color[4] = { 255, 127, 127, 255 }; -static const uint8_t white_gbrp_color[4] = { 255, 255, 255, 255 }; - -static int config_input(AVFilterLink *inlink) -{ - HistogramContext *h = inlink->dst->priv; - - h->desc = av_pix_fmt_desc_get(inlink->format); - h->ncomp = h->desc->nb_components; - - switch (inlink->format) { - case AV_PIX_FMT_GBRAP: - case AV_PIX_FMT_GBRP: - h->bg_color = black_gbrp_color; - h->fg_color = white_gbrp_color; - break; - default: - h->bg_color = black_yuva_color; - h->fg_color = white_yuva_color; - } - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - HistogramContext *h = ctx->priv; - - switch (h->mode) { - case MODE_LEVELS: - outlink->w = 256; - outlink->h = (h->level_height + h->scale_height) * FFMAX(h->ncomp * h->display_mode, 1); - break; - case MODE_WAVEFORM: - if (h->waveform_mode) - outlink->h = 256 * FFMAX(h->ncomp * h->display_mode, 1); - else - outlink->w = 256 * FFMAX(h->ncomp * h->display_mode, 1); - break; - case MODE_COLOR: - case MODE_COLOR2: - outlink->h = outlink->w = 256; - break; - default: - av_assert0(0); - } - - outlink->sample_aspect_ratio = (AVRational){1,1}; - - return 0; -} - -static void gen_waveform(HistogramContext *h, AVFrame *inpicref, AVFrame *outpicref, - int component, int intensity, int offset, int col_mode) -{ - const int plane = h->desc->comp[component].plane; - const int mirror = h->waveform_mirror; - const int is_chroma = (component == 1 || component == 2); - const int shift_w = (is_chroma ? h->desc->log2_chroma_w : 0); - const int shift_h = (is_chroma ? h->desc->log2_chroma_h : 0); - const int src_linesize = inpicref->linesize[plane]; - const int dst_linesize = outpicref->linesize[plane]; - const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1); - uint8_t *src_data = inpicref->data[plane]; - uint8_t *dst_data = outpicref->data[plane] + (col_mode ? (offset >> shift_h) * dst_linesize : offset >> shift_w); - uint8_t * const dst_bottom_line = dst_data + dst_linesize * ((256 >> shift_h) - 1); - uint8_t * const dst_line = (mirror ? dst_bottom_line : dst_data); - const uint8_t max = 255 - intensity; - const int src_h = FF_CEIL_RSHIFT(inpicref->height, shift_h); - const int src_w = FF_CEIL_RSHIFT(inpicref->width, shift_w); - uint8_t *dst, *p; - int y; - - if (!col_mode && mirror) - dst_data += 256 >> shift_w; - for (y = 0; y < src_h; y++) { - const uint8_t *src_data_end = src_data + src_w; - dst = dst_line; - for (p = src_data; p < src_data_end; p++) { - uint8_t *target; - if (col_mode) { - target = dst++ + dst_signed_linesize * (*p >> shift_h); - } else { - if (mirror) - target = dst_data - (*p >> shift_w); - else - target = dst_data + (*p >> shift_w); - } - if (*target <= max) - *target += intensity; - else - *target = 255; - } - src_data += src_linesize; - dst_data += dst_linesize; - } -} - - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - HistogramContext *h = inlink->dst->priv; - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out; - const uint8_t *src; - uint8_t *dst; - int i, j, k, l; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - out->pts = in->pts; - - for (k = 0; k < h->ncomp; k++) { - const int is_chroma = (k == 1 || k == 2); - const int dst_h = FF_CEIL_RSHIFT(outlink->h, (is_chroma ? h->desc->log2_chroma_h : 0)); - const int dst_w = FF_CEIL_RSHIFT(outlink->w, (is_chroma ? h->desc->log2_chroma_w : 0)); - for (i = 0; i < dst_h ; i++) - memset(out->data[h->desc->comp[k].plane] + - i * out->linesize[h->desc->comp[k].plane], - h->bg_color[k], dst_w); - } - - switch (h->mode) { - case MODE_LEVELS: - for (k = 0; k < h->ncomp; k++) { - const int p = h->desc->comp[k].plane; - const int start = k * (h->level_height + h->scale_height) * h->display_mode; - double max_hval_log; - unsigned max_hval = 0; - - for (i = 0; i < in->height; i++) { - src = in->data[p] + i * in->linesize[p]; - for (j = 0; j < in->width; j++) - h->histogram[src[j]]++; - } - - for (i = 0; i < 256; i++) - max_hval = FFMAX(max_hval, h->histogram[i]); - max_hval_log = log2(max_hval + 1); - - for (i = 0; i < outlink->w; i++) { - int col_height; - - if (h->levels_mode) - col_height = round(h->level_height * (1. - (log2(h->histogram[i] + 1) / max_hval_log))); - else - col_height = h->level_height - (h->histogram[i] * (int64_t)h->level_height + max_hval - 1) / max_hval; - - for (j = h->level_height - 1; j >= col_height; j--) { - if (h->display_mode) { - for (l = 0; l < h->ncomp; l++) - out->data[l][(j + start) * out->linesize[l] + i] = h->fg_color[l]; - } else { - out->data[p][(j + start) * out->linesize[p] + i] = 255; - } - } - for (j = h->level_height + h->scale_height - 1; j >= h->level_height; j--) - out->data[p][(j + start) * out->linesize[p] + i] = i; - } - - memset(h->histogram, 0, 256 * sizeof(unsigned)); - } - break; - case MODE_WAVEFORM: - for (k = 0; k < h->ncomp; k++) { - const int offset = k * 256 * h->display_mode; - gen_waveform(h, in, out, k, h->step, offset, h->waveform_mode); - } - break; - case MODE_COLOR: - for (i = 0; i < inlink->h; i++) { - const int iw1 = i * in->linesize[1]; - const int iw2 = i * in->linesize[2]; - for (j = 0; j < inlink->w; j++) { - const int pos = in->data[1][iw1 + j] * out->linesize[0] + in->data[2][iw2 + j]; - if (out->data[0][pos] < 255) - out->data[0][pos]++; - } - } - for (i = 0; i < 256; i++) { - dst = out->data[0] + i * out->linesize[0]; - for (j = 0; j < 256; j++) { - if (!dst[j]) { - out->data[1][i * out->linesize[0] + j] = i; - out->data[2][i * out->linesize[0] + j] = j; - } - } - } - break; - case MODE_COLOR2: - for (i = 0; i < inlink->h; i++) { - const int iw1 = i * in->linesize[1]; - const int iw2 = i * in->linesize[2]; - for (j = 0; j < inlink->w; j++) { - const int u = in->data[1][iw1 + j]; - const int v = in->data[2][iw2 + j]; - const int pos = u * out->linesize[0] + v; - if (!out->data[0][pos]) - out->data[0][pos] = FFABS(128 - u) + FFABS(128 - v); - out->data[1][pos] = u; - out->data[2][pos] = v; - } - } - break; - default: - av_assert0(0); - } - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_histogram = { - .name = "histogram", - .description = NULL_IF_CONFIG_SMALL("Compute and draw a histogram."), - .priv_size = sizeof(HistogramContext), - .query_formats = query_formats, - .inputs = inputs, - .outputs = outputs, - .priv_class = &histogram_class, -}; diff --git a/ffmpeg/libavfilter/vf_hqdn3d.c b/ffmpeg/libavfilter/vf_hqdn3d.c deleted file mode 100644 index 518a23d..0000000 --- a/ffmpeg/libavfilter/vf_hqdn3d.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org> - * Copyright (c) 2010 Baptiste Coudurier - * Copyright (c) 2012 Loren Merritt - * - * This file is part of FFmpeg, ported from MPlayer. - * - * 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 - * high quality 3d video denoiser, ported from MPlayer - * libmpcodecs/vf_hqdn3d.c. - */ - -#include <float.h> - -#include "config.h" -#include "libavutil/attributes.h" -#include "libavutil/common.h" -#include "libavutil/pixdesc.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "vf_hqdn3d.h" - -#define LUT_BITS (depth==16 ? 8 : 4) -#define LOAD(x) (((depth == 8 ? src[x] : AV_RN16A(src + (x) * 2)) << (16 - depth))\ - + (((1 << (16 - depth)) - 1) >> 1)) -#define STORE(x,val) (depth == 8 ? dst[x] = (val) >> (16 - depth) : \ - AV_WN16A(dst + (x) * 2, (val) >> (16 - depth))) - -av_always_inline -static uint32_t lowpass(int prev, int cur, int16_t *coef, int depth) -{ - int d = (prev - cur) >> (8 - LUT_BITS); - return cur + coef[d]; -} - -av_always_inline -static void denoise_temporal(uint8_t *src, uint8_t *dst, - uint16_t *frame_ant, - int w, int h, int sstride, int dstride, - int16_t *temporal, int depth) -{ - long x, y; - uint32_t tmp; - - temporal += 256 << LUT_BITS; - - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - frame_ant[x] = tmp = lowpass(frame_ant[x], LOAD(x), temporal, depth); - STORE(x, tmp); - } - src += sstride; - dst += dstride; - frame_ant += w; - } -} - -av_always_inline -static void denoise_spatial(HQDN3DContext *s, - uint8_t *src, uint8_t *dst, - uint16_t *line_ant, uint16_t *frame_ant, - int w, int h, int sstride, int dstride, - int16_t *spatial, int16_t *temporal, int depth) -{ - long x, y; - uint32_t pixel_ant; - uint32_t tmp; - - spatial += 256 << LUT_BITS; - temporal += 256 << LUT_BITS; - - /* First line has no top neighbor. Only left one for each tmp and - * last frame */ - pixel_ant = LOAD(0); - for (x = 0; x < w; x++) { - line_ant[x] = tmp = pixel_ant = lowpass(pixel_ant, LOAD(x), spatial, depth); - frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth); - STORE(x, tmp); - } - - for (y = 1; y < h; y++) { - src += sstride; - dst += dstride; - frame_ant += w; - if (s->denoise_row[depth]) { - s->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal); - continue; - } - pixel_ant = LOAD(0); - for (x = 0; x < w-1; x++) { - line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial, depth); - pixel_ant = lowpass(pixel_ant, LOAD(x+1), spatial, depth); - frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth); - STORE(x, tmp); - } - line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial, depth); - frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth); - STORE(x, tmp); - } -} - -av_always_inline -static void denoise_depth(HQDN3DContext *s, - uint8_t *src, uint8_t *dst, - uint16_t *line_ant, uint16_t **frame_ant_ptr, - int w, int h, int sstride, int dstride, - int16_t *spatial, int16_t *temporal, int depth) -{ - // FIXME: For 16bit depth, frame_ant could be a pointer to the previous - // filtered frame rather than a separate buffer. - long x, y; - uint16_t *frame_ant = *frame_ant_ptr; - if (!frame_ant) { - uint8_t *frame_src = src; - *frame_ant_ptr = frame_ant = av_malloc(w*h*sizeof(uint16_t)); - for (y = 0; y < h; y++, src += sstride, frame_ant += w) - for (x = 0; x < w; x++) - frame_ant[x] = LOAD(x); - src = frame_src; - frame_ant = *frame_ant_ptr; - } - - if (spatial[0]) - denoise_spatial(s, src, dst, line_ant, frame_ant, - w, h, sstride, dstride, spatial, temporal, depth); - else - denoise_temporal(src, dst, frame_ant, - w, h, sstride, dstride, temporal, depth); -} - -#define denoise(...) \ - switch (s->depth) {\ - case 8: denoise_depth(__VA_ARGS__, 8); break;\ - case 9: denoise_depth(__VA_ARGS__, 9); break;\ - case 10: denoise_depth(__VA_ARGS__, 10); break;\ - case 16: denoise_depth(__VA_ARGS__, 16); break;\ - } - -static int16_t *precalc_coefs(double dist25, int depth) -{ - int i; - double gamma, simil, C; - int16_t *ct = av_malloc((512<<LUT_BITS)*sizeof(int16_t)); - if (!ct) - return NULL; - - gamma = log(0.25) / log(1.0 - FFMIN(dist25,252.0)/255.0 - 0.00001); - - for (i = -255<<LUT_BITS; i <= 255<<LUT_BITS; i++) { - double f = ((i<<(9-LUT_BITS)) + (1<<(8-LUT_BITS)) - 1) / 512.0; // midpoint of the bin - simil = 1.0 - FFABS(f) / 255.0; - C = pow(simil, gamma) * 256.0 * f; - ct[(256<<LUT_BITS)+i] = lrint(C); - } - - ct[0] = !!dist25; - return ct; -} - -#define PARAM1_DEFAULT 4.0 -#define PARAM2_DEFAULT 3.0 -#define PARAM3_DEFAULT 6.0 - -static av_cold int init(AVFilterContext *ctx) -{ - HQDN3DContext *s = ctx->priv; - - if (!s->strength[LUMA_SPATIAL]) - s->strength[LUMA_SPATIAL] = PARAM1_DEFAULT; - if (!s->strength[CHROMA_SPATIAL]) - s->strength[CHROMA_SPATIAL] = PARAM2_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT; - if (!s->strength[LUMA_TMP]) - s->strength[LUMA_TMP] = PARAM3_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT; - if (!s->strength[CHROMA_TMP]) - s->strength[CHROMA_TMP] = s->strength[LUMA_TMP] * s->strength[CHROMA_SPATIAL] / s->strength[LUMA_SPATIAL]; - - av_log(ctx, AV_LOG_VERBOSE, "ls:%f cs:%f lt:%f ct:%f\n", - s->strength[LUMA_SPATIAL], s->strength[CHROMA_SPATIAL], - s->strength[LUMA_TMP], s->strength[CHROMA_TMP]); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - HQDN3DContext *s = ctx->priv; - - av_freep(&s->coefs[0]); - av_freep(&s->coefs[1]); - av_freep(&s->coefs[2]); - av_freep(&s->coefs[3]); - av_freep(&s->line); - av_freep(&s->frame_prev[0]); - av_freep(&s->frame_prev[1]); - av_freep(&s->frame_prev[2]); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUV420P9, - AV_PIX_FMT_YUV422P9, - AV_PIX_FMT_YUV444P9, - AV_PIX_FMT_YUV420P10, - AV_PIX_FMT_YUV422P10, - AV_PIX_FMT_YUV444P10, - AV_PIX_FMT_YUV420P16, - AV_PIX_FMT_YUV422P16, - AV_PIX_FMT_YUV444P16, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - HQDN3DContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int i; - - uninit(inlink->dst); - - s->hsub = desc->log2_chroma_w; - s->vsub = desc->log2_chroma_h; - s->depth = desc->comp[0].depth_minus1+1; - - s->line = av_malloc(inlink->w * sizeof(*s->line)); - if (!s->line) - return AVERROR(ENOMEM); - - for (i = 0; i < 4; i++) { - s->coefs[i] = precalc_coefs(s->strength[i], s->depth); - if (!s->coefs[i]) - return AVERROR(ENOMEM); - } - - if (ARCH_X86) - ff_hqdn3d_init_x86(s); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - HQDN3DContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - - AVFrame *out; - int direct, c; - - if (av_frame_is_writable(in) && !ctx->is_disabled) { - direct = 1; - out = in; - } else { - direct = 0; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - av_frame_copy_props(out, in); - } - - for (c = 0; c < 3; c++) { - denoise(s, in->data[c], out->data[c], - s->line, &s->frame_prev[c], - FF_CEIL_RSHIFT(in->width, (!!c * s->hsub)), - FF_CEIL_RSHIFT(in->height, (!!c * s->vsub)), - in->linesize[c], out->linesize[c], - s->coefs[c ? CHROMA_SPATIAL : LUMA_SPATIAL], - s->coefs[c ? CHROMA_TMP : LUMA_TMP]); - } - - if (ctx->is_disabled) { - av_frame_free(&out); - return ff_filter_frame(outlink, in); - } - - if (!direct) - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(HQDN3DContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption hqdn3d_options[] = { - { "luma_spatial", "spatial luma strength", OFFSET(strength[LUMA_SPATIAL]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS }, - { "chroma_spatial", "spatial chroma strength", OFFSET(strength[CHROMA_SPATIAL]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS }, - { "luma_tmp", "temporal luma strength", OFFSET(strength[LUMA_TMP]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS }, - { "chroma_tmp", "temporal chroma strength", OFFSET(strength[CHROMA_TMP]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(hqdn3d); - -static const AVFilterPad avfilter_vf_hqdn3d_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - - -static const AVFilterPad avfilter_vf_hqdn3d_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_hqdn3d = { - .name = "hqdn3d", - .description = NULL_IF_CONFIG_SMALL("Apply a High Quality 3D Denoiser."), - .priv_size = sizeof(HQDN3DContext), - .priv_class = &hqdn3d_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_vf_hqdn3d_inputs, - .outputs = avfilter_vf_hqdn3d_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, -}; diff --git a/ffmpeg/libavfilter/vf_hqdn3d.h b/ffmpeg/libavfilter/vf_hqdn3d.h deleted file mode 100644 index 268ac9a..0000000 --- a/ffmpeg/libavfilter/vf_hqdn3d.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2003 Daniel Moreno <comac AT comac DOT darktech DOT org> - * Copyright (c) 2010 Baptiste Coudurier - * Copyright (c) 2012 Loren Merritt - * - * This file is part of FFmpeg, ported from MPlayer. - * - * 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. - */ - -#ifndef AVFILTER_VF_HQDN3D_H -#define AVFILTER_VF_HQDN3D_H - -#include <stddef.h> -#include <stdint.h> - -#include "libavutil/opt.h" - -typedef struct { - const AVClass *class; - int16_t *coefs[4]; - uint16_t *line; - uint16_t *frame_prev[3]; - double strength[4]; - int hsub, vsub; - int depth; - void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal); -} HQDN3DContext; - -#define LUMA_SPATIAL 0 -#define LUMA_TMP 1 -#define CHROMA_SPATIAL 2 -#define CHROMA_TMP 3 - -void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d); - -#endif /* AVFILTER_VF_HQDN3D_H */ diff --git a/ffmpeg/libavfilter/vf_hue.c b/ffmpeg/libavfilter/vf_hue.c deleted file mode 100644 index 7843673..0000000 --- a/ffmpeg/libavfilter/vf_hue.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright (c) 2003 Michael Niedermayer - * Copyright (c) 2012 Jeremy Tran - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Apply a hue/saturation filter to the input video - * Ported from MPlayer libmpcodecs/vf_hue.c. - */ - -#include <float.h> -#include "libavutil/eval.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#define SAT_MIN_VAL -10 -#define SAT_MAX_VAL 10 - -static const char *const var_names[] = { - "n", // frame count - "pts", // presentation timestamp expressed in AV_TIME_BASE units - "r", // frame rate - "t", // timestamp expressed in seconds - "tb", // timebase - NULL -}; - -enum var_name { - VAR_N, - VAR_PTS, - VAR_R, - VAR_T, - VAR_TB, - VAR_NB -}; - -typedef struct { - const AVClass *class; - float hue_deg; /* hue expressed in degrees */ - float hue; /* hue expressed in radians */ - char *hue_deg_expr; - char *hue_expr; - AVExpr *hue_deg_pexpr; - AVExpr *hue_pexpr; - float saturation; - char *saturation_expr; - AVExpr *saturation_pexpr; - float brightness; - char *brightness_expr; - AVExpr *brightness_pexpr; - int hsub; - int vsub; - int is_first; - int32_t hue_sin; - int32_t hue_cos; - double var_values[VAR_NB]; - uint8_t lut_l[256]; - uint8_t lut_u[256][256]; - uint8_t lut_v[256][256]; -} HueContext; - -#define OFFSET(x) offsetof(HueContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption hue_options[] = { - { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING, - { .str = NULL }, .flags = FLAGS }, - { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING, - { .str = "1" }, .flags = FLAGS }, - { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING, - { .str = NULL }, .flags = FLAGS }, - { "b", "set the brightness expression", OFFSET(brightness_expr), AV_OPT_TYPE_STRING, - { .str = "0" }, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(hue); - -static inline void compute_sin_and_cos(HueContext *hue) -{ - /* - * Scale the value to the norm of the resulting (U,V) vector, that is - * the saturation. - * This will be useful in the apply_lut function. - */ - hue->hue_sin = rint(sin(hue->hue) * (1 << 16) * hue->saturation); - hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation); -} - -static inline void create_luma_lut(HueContext *h) -{ - const float b = h->brightness; - int i; - - for (i = 0; i < 256; i++) { - h->lut_l[i] = av_clip_uint8(i + b * 25.5); - } -} - -static inline void create_chrominance_lut(HueContext *h, const int32_t c, - const int32_t s) -{ - int32_t i, j, u, v, new_u, new_v; - - /* - * If we consider U and V as the components of a 2D vector then its angle - * is the hue and the norm is the saturation - */ - for (i = 0; i < 256; i++) { - for (j = 0; j < 256; j++) { - /* Normalize the components from range [16;140] to [-112;112] */ - u = i - 128; - v = j - 128; - /* - * Apply the rotation of the vector : (c * u) - (s * v) - * (s * u) + (c * v) - * De-normalize the components (without forgetting to scale 128 - * by << 16) - * Finally scale back the result by >> 16 - */ - new_u = ((c * u) - (s * v) + (1 << 15) + (128 << 16)) >> 16; - new_v = ((s * u) + (c * v) + (1 << 15) + (128 << 16)) >> 16; - - /* Prevent a potential overflow */ - h->lut_u[i][j] = av_clip_uint8(new_u); - h->lut_v[i][j] = av_clip_uint8(new_v); - } - } -} - -static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr, - const char *expr, const char *option, void *log_ctx) -{ - int ret; - AVExpr *new_pexpr; - char *new_expr; - - new_expr = av_strdup(expr); - if (!new_expr) - return AVERROR(ENOMEM); - ret = av_expr_parse(&new_pexpr, expr, var_names, - NULL, NULL, NULL, NULL, 0, log_ctx); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s' for %s\n", - expr, option); - av_free(new_expr); - return ret; - } - - if (*pexpr_ptr) - av_expr_free(*pexpr_ptr); - *pexpr_ptr = new_pexpr; - av_freep(expr_ptr); - *expr_ptr = new_expr; - - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - HueContext *hue = ctx->priv; - int ret; - - if (hue->hue_expr && hue->hue_deg_expr) { - av_log(ctx, AV_LOG_ERROR, - "H and h options are incompatible and cannot be specified " - "at the same time\n"); - return AVERROR(EINVAL); - } - -#define SET_EXPR(expr, option) \ - if (hue->expr##_expr) do { \ - ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \ - hue->expr##_expr, option, ctx); \ - if (ret < 0) \ - return ret; \ - } while (0) - SET_EXPR(brightness, "b"); - SET_EXPR(saturation, "s"); - SET_EXPR(hue_deg, "h"); - SET_EXPR(hue, "H"); -#undef SET_EXPR - - av_log(ctx, AV_LOG_VERBOSE, - "H_expr:%s h_deg_expr:%s s_expr:%s b_expr:%s\n", - hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr, hue->brightness_expr); - compute_sin_and_cos(hue); - hue->is_first = 1; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - HueContext *hue = ctx->priv; - - av_expr_free(hue->brightness_pexpr); - av_expr_free(hue->hue_deg_pexpr); - av_expr_free(hue->hue_pexpr); - av_expr_free(hue->saturation_pexpr); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, - AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - HueContext *hue = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - - hue->hsub = desc->log2_chroma_w; - hue->vsub = desc->log2_chroma_h; - - hue->var_values[VAR_N] = 0; - hue->var_values[VAR_TB] = av_q2d(inlink->time_base); - hue->var_values[VAR_R] = inlink->frame_rate.num == 0 || inlink->frame_rate.den == 0 ? - NAN : av_q2d(inlink->frame_rate); - - return 0; -} - -static void apply_luma_lut(HueContext *s, - uint8_t *ldst, const int dst_linesize, - uint8_t *lsrc, const int src_linesize, - int w, int h) -{ - int i; - - while (h--) { - for (i = 0; i < w; i++) - ldst[i] = s->lut_l[lsrc[i]]; - - lsrc += src_linesize; - ldst += dst_linesize; - } -} - -static void apply_lut(HueContext *s, - uint8_t *udst, uint8_t *vdst, const int dst_linesize, - uint8_t *usrc, uint8_t *vsrc, const int src_linesize, - int w, int h) -{ - int i; - - while (h--) { - for (i = 0; i < w; i++) { - const int u = usrc[i]; - const int v = vsrc[i]; - - udst[i] = s->lut_u[u][v]; - vdst[i] = s->lut_v[u][v]; - } - - usrc += src_linesize; - vsrc += src_linesize; - udst += dst_linesize; - vdst += dst_linesize; - } -} - -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) -{ - HueContext *hue = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpic; - const int32_t old_hue_sin = hue->hue_sin, old_hue_cos = hue->hue_cos; - const float old_brightness = hue->brightness; - int direct = 0; - - if (av_frame_is_writable(inpic)) { - direct = 1; - outpic = inpic; - } else { - outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpic) { - av_frame_free(&inpic); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpic, inpic); - } - - hue->var_values[VAR_N] = inlink->frame_count; - hue->var_values[VAR_T] = TS2T(inpic->pts, inlink->time_base); - hue->var_values[VAR_PTS] = TS2D(inpic->pts); - - if (hue->saturation_expr) { - hue->saturation = av_expr_eval(hue->saturation_pexpr, hue->var_values, NULL); - - if (hue->saturation < SAT_MIN_VAL || hue->saturation > SAT_MAX_VAL) { - hue->saturation = av_clip(hue->saturation, SAT_MIN_VAL, SAT_MAX_VAL); - av_log(inlink->dst, AV_LOG_WARNING, - "Saturation value not in range [%d,%d]: clipping value to %0.1f\n", - SAT_MIN_VAL, SAT_MAX_VAL, hue->saturation); - } - } - - if (hue->brightness_expr) { - hue->brightness = av_expr_eval(hue->brightness_pexpr, hue->var_values, NULL); - - if (hue->brightness < -10 || hue->brightness > 10) { - hue->brightness = av_clipf(hue->brightness, -10, 10); - av_log(inlink->dst, AV_LOG_WARNING, - "Brightness value not in range [%d,%d]: clipping value to %0.1f\n", - -10, 10, hue->brightness); - } - } - - if (hue->hue_deg_expr) { - hue->hue_deg = av_expr_eval(hue->hue_deg_pexpr, hue->var_values, NULL); - hue->hue = hue->hue_deg * M_PI / 180; - } else if (hue->hue_expr) { - hue->hue = av_expr_eval(hue->hue_pexpr, hue->var_values, NULL); - hue->hue_deg = hue->hue * 180 / M_PI; - } - - av_log(inlink->dst, AV_LOG_DEBUG, - "H:%0.1f*PI h:%0.1f s:%0.1f b:%0.f t:%0.1f n:%d\n", - hue->hue/M_PI, hue->hue_deg, hue->saturation, hue->brightness, - hue->var_values[VAR_T], (int)hue->var_values[VAR_N]); - - compute_sin_and_cos(hue); - if (hue->is_first || (old_hue_sin != hue->hue_sin || old_hue_cos != hue->hue_cos)) - create_chrominance_lut(hue, hue->hue_cos, hue->hue_sin); - - if (hue->is_first || (old_brightness != hue->brightness && hue->brightness)) - create_luma_lut(hue); - - if (!direct) { - if (!hue->brightness) - av_image_copy_plane(outpic->data[0], outpic->linesize[0], - inpic->data[0], inpic->linesize[0], - inlink->w, inlink->h); - if (inpic->data[3]) - av_image_copy_plane(outpic->data[3], outpic->linesize[3], - inpic->data[3], inpic->linesize[3], - inlink->w, inlink->h); - } - - apply_lut(hue, outpic->data[1], outpic->data[2], outpic->linesize[1], - inpic->data[1], inpic->data[2], inpic->linesize[1], - FF_CEIL_RSHIFT(inlink->w, hue->hsub), - FF_CEIL_RSHIFT(inlink->h, hue->vsub)); - if (hue->brightness) - apply_luma_lut(hue, outpic->data[0], outpic->linesize[0], - inpic->data[0], inpic->linesize[0], inlink->w, inlink->h); - - if (!direct) - av_frame_free(&inpic); - - hue->is_first = 0; - return ff_filter_frame(outlink, outpic); -} - -static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, - char *res, int res_len, int flags) -{ - HueContext *hue = ctx->priv; - int ret; - -#define SET_EXPR(expr, option) \ - do { \ - ret = set_expr(&hue->expr##_pexpr, &hue->expr##_expr, \ - args, option, ctx); \ - if (ret < 0) \ - return ret; \ - } while (0) - - if (!strcmp(cmd, "h")) { - SET_EXPR(hue_deg, "h"); - av_freep(&hue->hue_expr); - } else if (!strcmp(cmd, "H")) { - SET_EXPR(hue, "H"); - av_freep(&hue->hue_deg_expr); - } else if (!strcmp(cmd, "s")) { - SET_EXPR(saturation, "s"); - } else if (!strcmp(cmd, "b")) { - SET_EXPR(brightness, "b"); - } else - return AVERROR(ENOSYS); - - return 0; -} - -static const AVFilterPad hue_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad hue_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_hue = { - .name = "hue", - .description = NULL_IF_CONFIG_SMALL("Adjust the hue and saturation of the input video."), - .priv_size = sizeof(HueContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .process_command = process_command, - .inputs = hue_inputs, - .outputs = hue_outputs, - .priv_class = &hue_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_idet.c b/ffmpeg/libavfilter/vf_idet.c deleted file mode 100644 index d441a5f..0000000 --- a/ffmpeg/libavfilter/vf_idet.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (C) 2012 Michael Niedermayer <michaelni@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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <float.h> /* FLT_MAX */ - -#include "libavutil/cpu.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" - -#define HIST_SIZE 4 - -typedef enum { - TFF, - BFF, - PROGRSSIVE, - UNDETERMINED, -} Type; - -typedef struct { - const AVClass *class; - float interlace_threshold; - float progressive_threshold; - - Type last_type; - int prestat[4]; - int poststat[4]; - - uint8_t history[HIST_SIZE]; - - AVFrame *cur; - AVFrame *next; - AVFrame *prev; - int (*filter_line)(const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w); - - const AVPixFmtDescriptor *csp; -} IDETContext; - -#define OFFSET(x) offsetof(IDETContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption idet_options[] = { - { "intl_thres", "set interlacing threshold", OFFSET(interlace_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.04}, -1, FLT_MAX, FLAGS }, - { "prog_thres", "set progressive threshold", OFFSET(progressive_threshold), AV_OPT_TYPE_FLOAT, {.dbl = 1.5}, -1, FLT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(idet); - -static const char *type2str(Type type) -{ - switch(type) { - case TFF : return "Top Field First "; - case BFF : return "Bottom Field First"; - case PROGRSSIVE : return "Progressive "; - case UNDETERMINED: return "Undetermined "; - } - return NULL; -} - -static int filter_line_c(const uint8_t *a, const uint8_t *b, const uint8_t *c, int w) -{ - int x; - int ret=0; - - for(x=0; x<w; x++){ - int v = (*a++ + *c++) - 2 * *b++; - ret += FFABS(v); - } - - return ret; -} - -static int filter_line_c_16bit(const uint16_t *a, const uint16_t *b, const uint16_t *c, int w) -{ - int x; - int ret=0; - - for(x=0; x<w; x++){ - int v = (*a++ + *c++) - 2 * *b++; - ret += FFABS(v); - } - - return ret; -} - -static void filter(AVFilterContext *ctx) -{ - IDETContext *idet = ctx->priv; - int y, i; - int64_t alpha[2]={0}; - int64_t delta=0; - Type type, best_type; - int match = 0; - - for (i = 0; i < idet->csp->nb_components; i++) { - int w = idet->cur->width; - int h = idet->cur->height; - int refs = idet->cur->linesize[i]; - - if (i && i<3) { - w = FF_CEIL_RSHIFT(w, idet->csp->log2_chroma_w); - h = FF_CEIL_RSHIFT(h, idet->csp->log2_chroma_h); - } - - for (y = 2; y < h - 2; y++) { - uint8_t *prev = &idet->prev->data[i][y*refs]; - uint8_t *cur = &idet->cur ->data[i][y*refs]; - uint8_t *next = &idet->next->data[i][y*refs]; - alpha[ y &1] += idet->filter_line(cur-refs, prev, cur+refs, w); - alpha[(y^1)&1] += idet->filter_line(cur-refs, next, cur+refs, w); - delta += idet->filter_line(cur-refs, cur, cur+refs, w); - } - } - - if (alpha[0] > idet->interlace_threshold * alpha[1]){ - type = TFF; - }else if(alpha[1] > idet->interlace_threshold * alpha[0]){ - type = BFF; - }else if(alpha[1] > idet->progressive_threshold * delta){ - type = PROGRSSIVE; - }else{ - type = UNDETERMINED; - } - - memmove(idet->history+1, idet->history, HIST_SIZE-1); - idet->history[0] = type; - best_type = UNDETERMINED; - for(i=0; i<HIST_SIZE; i++){ - if(idet->history[i] != UNDETERMINED){ - if(best_type == UNDETERMINED) - best_type = idet->history[i]; - - if(idet->history[i] == best_type) { - match++; - }else{ - match=0; - break; - } - } - } - if(idet->last_type == UNDETERMINED){ - if(match ) idet->last_type = best_type; - }else{ - if(match>2) idet->last_type = best_type; - } - - if (idet->last_type == TFF){ - idet->cur->top_field_first = 1; - idet->cur->interlaced_frame = 1; - }else if(idet->last_type == BFF){ - idet->cur->top_field_first = 0; - idet->cur->interlaced_frame = 1; - }else if(idet->last_type == PROGRSSIVE){ - idet->cur->interlaced_frame = 0; - } - - idet->prestat [ type] ++; - idet->poststat[idet->last_type] ++; - av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type)); -} - -static int filter_frame(AVFilterLink *link, AVFrame *picref) -{ - AVFilterContext *ctx = link->dst; - IDETContext *idet = ctx->priv; - - if (idet->prev) - av_frame_free(&idet->prev); - idet->prev = idet->cur; - idet->cur = idet->next; - idet->next = picref; - - if (!idet->cur) - return 0; - - if (!idet->prev) - idet->prev = av_frame_clone(idet->cur); - - if (!idet->csp) - idet->csp = av_pix_fmt_desc_get(link->format); - if (idet->csp->comp[0].depth_minus1 / 8 == 1) - idet->filter_line = (void*)filter_line_c_16bit; - - filter(ctx); - - return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - IDETContext *idet = ctx->priv; - - av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n", - idet->prestat[TFF], - idet->prestat[BFF], - idet->prestat[PROGRSSIVE], - idet->prestat[UNDETERMINED] - ); - av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n", - idet->poststat[TFF], - idet->poststat[BFF], - idet->poststat[PROGRSSIVE], - idet->poststat[UNDETERMINED] - ); - - av_frame_free(&idet->prev); - av_frame_free(&idet->cur ); - av_frame_free(&idet->next); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_GRAY16, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUV420P10, - AV_PIX_FMT_YUV422P10, - AV_PIX_FMT_YUV444P10, - AV_PIX_FMT_YUV420P16, - AV_PIX_FMT_YUV422P16, - AV_PIX_FMT_YUV444P16, - AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - IDETContext *idet = ctx->priv; - - idet->last_type = UNDETERMINED; - memset(idet->history, UNDETERMINED, HIST_SIZE); - - idet->filter_line = filter_line_c; - - return 0; -} - - -static const AVFilterPad idet_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad idet_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_idet = { - .name = "idet", - .description = NULL_IF_CONFIG_SMALL("Interlace detect Filter."), - .priv_size = sizeof(IDETContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = idet_inputs, - .outputs = idet_outputs, - .priv_class = &idet_class, -}; diff --git a/ffmpeg/libavfilter/vf_il.c b/ffmpeg/libavfilter/vf_il.c deleted file mode 100644 index e755caa..0000000 --- a/ffmpeg/libavfilter/vf_il.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2013 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * (de)interleave fields filter - */ - -#include "libavutil/opt.h" -#include "libavutil/imgutils.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" - -enum FilterMode { - MODE_NONE, - MODE_INTERLEAVE, - MODE_DEINTERLEAVE -}; - -typedef struct { - const AVClass *class; - enum FilterMode luma_mode, chroma_mode, alpha_mode; - int luma_swap, chroma_swap, alpha_swap; - int nb_planes; - int linesize[4], chroma_height; - int has_alpha; -} IlContext; - -#define OFFSET(x) offsetof(IlContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption il_options[] = { - {"luma_mode", "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"}, - {"l", "select luma mode", OFFSET(luma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "luma_mode"}, - {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "luma_mode"}, - {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "luma_mode"}, - {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "luma_mode"}, - {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"}, - {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "luma_mode"}, - {"chroma_mode", "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"}, - {"c", "select chroma mode", OFFSET(chroma_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "chroma_mode"}, - {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "chroma_mode"}, - {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "chroma_mode"}, - {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "chroma_mode"}, - {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"}, - {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "chroma_mode"}, - {"alpha_mode", "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"}, - {"a", "select alpha mode", OFFSET(alpha_mode), AV_OPT_TYPE_INT, {.i64=MODE_NONE}, MODE_NONE, MODE_DEINTERLEAVE, FLAGS, "alpha_mode"}, - {"none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_NONE}, 0, 0, FLAGS, "alpha_mode"}, - {"interleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "alpha_mode"}, - {"i", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE}, 0, 0, FLAGS, "alpha_mode"}, - {"deinterleave", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"}, - {"d", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_DEINTERLEAVE}, 0, 0, FLAGS, "alpha_mode"}, - {"luma_swap", "swap luma fields", OFFSET(luma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"ls", "swap luma fields", OFFSET(luma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"chroma_swap", "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"cs", "swap chroma fields", OFFSET(chroma_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"alpha_swap", "swap alpha fields", OFFSET(alpha_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {"as", "swap alpha fields", OFFSET(alpha_swap), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS}, - {NULL} -}; - -AVFILTER_DEFINE_CLASS(il); - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL) && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) - ff_add_format(&formats, fmt); - } - - ff_set_common_formats(ctx, formats); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - IlContext *il = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret; - - il->nb_planes = av_pix_fmt_count_planes(inlink->format); - - il->has_alpha = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA); - if ((ret = av_image_fill_linesizes(il->linesize, inlink->format, inlink->w)) < 0) - return ret; - - il->chroma_height = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); - - return 0; -} - -static void interleave(uint8_t *dst, uint8_t *src, int w, int h, - int dst_linesize, int src_linesize, - enum FilterMode mode, int swap) -{ - const int a = swap; - const int b = 1 - a; - const int m = h >> 1; - int y; - - switch (mode) { - case MODE_DEINTERLEAVE: - for (y = 0; y < m; y++) { - memcpy(dst + dst_linesize * y , src + src_linesize * (y * 2 + a), w); - memcpy(dst + dst_linesize * (y + m), src + src_linesize * (y * 2 + b), w); - } - break; - case MODE_NONE: - for (y = 0; y < m; y++) { - memcpy(dst + dst_linesize * y * 2 , src + src_linesize * (y * 2 + a), w); - memcpy(dst + dst_linesize * (y * 2 + 1), src + src_linesize * (y * 2 + b), w); - } - break; - case MODE_INTERLEAVE: - for (y = 0; y < m; y++) { - memcpy(dst + dst_linesize * (y * 2 + a), src + src_linesize * y , w); - memcpy(dst + dst_linesize * (y * 2 + b), src + src_linesize * (y + m), w); - } - break; - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - IlContext *il = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - int comp; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, inpicref); - - interleave(out->data[0], inpicref->data[0], - il->linesize[0], inlink->h, - out->linesize[0], inpicref->linesize[0], - il->luma_mode, il->luma_swap); - - for (comp = 1; comp < (il->nb_planes - il->has_alpha); comp++) { - interleave(out->data[comp], inpicref->data[comp], - il->linesize[comp], il->chroma_height, - out->linesize[comp], inpicref->linesize[comp], - il->chroma_mode, il->chroma_swap); - } - - if (il->has_alpha) { - comp = il->nb_planes - 1; - interleave(out->data[comp], inpicref->data[comp], - il->linesize[comp], inlink->h, - out->linesize[comp], inpicref->linesize[comp], - il->alpha_mode, il->alpha_swap); - } - - av_frame_free(&inpicref); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_il = { - .name = "il", - .description = NULL_IF_CONFIG_SMALL("Deinterleave or interleave fields."), - .priv_size = sizeof(IlContext), - .query_formats = query_formats, - .inputs = inputs, - .outputs = outputs, - .priv_class = &il_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_kerndeint.c b/ffmpeg/libavfilter/vf_kerndeint.c deleted file mode 100644 index 1f8e091..0000000 --- a/ffmpeg/libavfilter/vf_kerndeint.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2012 Jeremy Tran - * Copyright (c) 2004 Tobias Diedrich - * Copyright (c) 2003 Donald A. Graft - * - * 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 - * Kernel Deinterlacer - * Ported from MPlayer libmpcodecs/vf_kerndeint.c. - */ - -#include "libavutil/imgutils.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - int frame; ///< frame count, starting from 0 - int thresh, map, order, sharp, twoway; - int vsub; - int is_packed_rgb; - uint8_t *tmp_data [4]; ///< temporary plane data buffer - int tmp_linesize[4]; ///< temporary plane byte linesize - int tmp_bwidth [4]; ///< temporary plane byte width -} KerndeintContext; - -#define OFFSET(x) offsetof(KerndeintContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM -static const AVOption kerndeint_options[] = { - { "thresh", "set the threshold", OFFSET(thresh), AV_OPT_TYPE_INT, {.i64=10}, 0, 255, FLAGS }, - { "map", "set the map", OFFSET(map), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "order", "set the order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "sharp", "enable sharpening", OFFSET(sharp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "twoway", "enable twoway", OFFSET(twoway), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(kerndeint); - -static av_cold void uninit(AVFilterContext *ctx) -{ - KerndeintContext *kerndeint = ctx->priv; - - av_free(kerndeint->tmp_data[0]); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum PixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUYV422, - AV_PIX_FMT_ARGB, AV_PIX_FMT_0RGB, - AV_PIX_FMT_ABGR, AV_PIX_FMT_0BGR, - AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB0, - AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - KerndeintContext *kerndeint = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret; - - kerndeint->is_packed_rgb = av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_RGB; - kerndeint->vsub = desc->log2_chroma_h; - - ret = av_image_alloc(kerndeint->tmp_data, kerndeint->tmp_linesize, - inlink->w, inlink->h, inlink->format, 16); - if (ret < 0) - return ret; - memset(kerndeint->tmp_data[0], 0, ret); - - if ((ret = av_image_fill_linesizes(kerndeint->tmp_bwidth, inlink->format, inlink->w)) < 0) - return ret; - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) -{ - KerndeintContext *kerndeint = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpic; - const uint8_t *prvp; ///< Previous field's pixel line number n - const uint8_t *prvpp; ///< Previous field's pixel line number (n - 1) - const uint8_t *prvpn; ///< Previous field's pixel line number (n + 1) - const uint8_t *prvppp; ///< Previous field's pixel line number (n - 2) - const uint8_t *prvpnn; ///< Previous field's pixel line number (n + 2) - const uint8_t *prvp4p; ///< Previous field's pixel line number (n - 4) - const uint8_t *prvp4n; ///< Previous field's pixel line number (n + 4) - - const uint8_t *srcp; ///< Current field's pixel line number n - const uint8_t *srcpp; ///< Current field's pixel line number (n - 1) - const uint8_t *srcpn; ///< Current field's pixel line number (n + 1) - const uint8_t *srcppp; ///< Current field's pixel line number (n - 2) - const uint8_t *srcpnn; ///< Current field's pixel line number (n + 2) - const uint8_t *srcp3p; ///< Current field's pixel line number (n - 3) - const uint8_t *srcp3n; ///< Current field's pixel line number (n + 3) - const uint8_t *srcp4p; ///< Current field's pixel line number (n - 4) - const uint8_t *srcp4n; ///< Current field's pixel line number (n + 4) - - uint8_t *dstp, *dstp_saved; - const uint8_t *srcp_saved; - - int src_linesize, psrc_linesize, dst_linesize, bwidth; - int x, y, plane, val, hi, lo, g, h, n = kerndeint->frame++; - double valf; - - const int thresh = kerndeint->thresh; - const int order = kerndeint->order; - const int map = kerndeint->map; - const int sharp = kerndeint->sharp; - const int twoway = kerndeint->twoway; - - const int is_packed_rgb = kerndeint->is_packed_rgb; - - outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpic) { - av_frame_free(&inpic); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpic, inpic); - outpic->interlaced_frame = 0; - - for (plane = 0; plane < 4 && inpic->data[plane] && inpic->linesize[plane]; plane++) { - h = plane == 0 ? inlink->h : FF_CEIL_RSHIFT(inlink->h, kerndeint->vsub); - bwidth = kerndeint->tmp_bwidth[plane]; - - srcp = srcp_saved = inpic->data[plane]; - src_linesize = inpic->linesize[plane]; - psrc_linesize = kerndeint->tmp_linesize[plane]; - dstp = dstp_saved = outpic->data[plane]; - dst_linesize = outpic->linesize[plane]; - srcp = srcp_saved + (1 - order) * src_linesize; - dstp = dstp_saved + (1 - order) * dst_linesize; - - for (y = 0; y < h; y += 2) { - memcpy(dstp, srcp, bwidth); - srcp += 2 * src_linesize; - dstp += 2 * dst_linesize; - } - - // Copy through the lines that will be missed below. - memcpy(dstp_saved + order * dst_linesize, srcp_saved + (1 - order) * src_linesize, bwidth); - memcpy(dstp_saved + (2 + order ) * dst_linesize, srcp_saved + (3 - order) * src_linesize, bwidth); - memcpy(dstp_saved + (h - 2 + order) * dst_linesize, srcp_saved + (h - 1 - order) * src_linesize, bwidth); - memcpy(dstp_saved + (h - 4 + order) * dst_linesize, srcp_saved + (h - 3 - order) * src_linesize, bwidth); - - /* For the other field choose adaptively between using the previous field - or the interpolant from the current field. */ - prvp = kerndeint->tmp_data[plane] + 5 * psrc_linesize - (1 - order) * psrc_linesize; - prvpp = prvp - psrc_linesize; - prvppp = prvp - 2 * psrc_linesize; - prvp4p = prvp - 4 * psrc_linesize; - prvpn = prvp + psrc_linesize; - prvpnn = prvp + 2 * psrc_linesize; - prvp4n = prvp + 4 * psrc_linesize; - - srcp = srcp_saved + 5 * src_linesize - (1 - order) * src_linesize; - srcpp = srcp - src_linesize; - srcppp = srcp - 2 * src_linesize; - srcp3p = srcp - 3 * src_linesize; - srcp4p = srcp - 4 * src_linesize; - - srcpn = srcp + src_linesize; - srcpnn = srcp + 2 * src_linesize; - srcp3n = srcp + 3 * src_linesize; - srcp4n = srcp + 4 * src_linesize; - - dstp = dstp_saved + 5 * dst_linesize - (1 - order) * dst_linesize; - - for (y = 5 - (1 - order); y <= h - 5 - (1 - order); y += 2) { - for (x = 0; x < bwidth; x++) { - if (thresh == 0 || n == 0 || - (abs((int)prvp[x] - (int)srcp[x]) > thresh) || - (abs((int)prvpp[x] - (int)srcpp[x]) > thresh) || - (abs((int)prvpn[x] - (int)srcpn[x]) > thresh)) { - if (map) { - g = x & ~3; - - if (is_packed_rgb) { - AV_WB32(dstp + g, 0xffffffff); - x = g + 3; - } else if (inlink->format == AV_PIX_FMT_YUYV422) { - // y <- 235, u <- 128, y <- 235, v <- 128 - AV_WB32(dstp + g, 0xeb80eb80); - x = g + 3; - } else { - dstp[x] = plane == 0 ? 235 : 128; - } - } else { - if (is_packed_rgb) { - hi = 255; - lo = 0; - } else if (inlink->format == AV_PIX_FMT_YUYV422) { - hi = x & 1 ? 240 : 235; - lo = 16; - } else { - hi = plane == 0 ? 235 : 240; - lo = 16; - } - - if (sharp) { - if (twoway) { - valf = + 0.526 * ((int)srcpp[x] + (int)srcpn[x]) - + 0.170 * ((int)srcp[x] + (int)prvp[x]) - - 0.116 * ((int)srcppp[x] + (int)srcpnn[x] + (int)prvppp[x] + (int)prvpnn[x]) - - 0.026 * ((int)srcp3p[x] + (int)srcp3n[x]) - + 0.031 * ((int)srcp4p[x] + (int)srcp4n[x] + (int)prvp4p[x] + (int)prvp4n[x]); - } else { - valf = + 0.526 * ((int)srcpp[x] + (int)srcpn[x]) - + 0.170 * ((int)prvp[x]) - - 0.116 * ((int)prvppp[x] + (int)prvpnn[x]) - - 0.026 * ((int)srcp3p[x] + (int)srcp3n[x]) - + 0.031 * ((int)prvp4p[x] + (int)prvp4p[x]); - } - dstp[x] = av_clip(valf, lo, hi); - } else { - if (twoway) { - val = (8 * ((int)srcpp[x] + (int)srcpn[x]) + 2 * ((int)srcp[x] + (int)prvp[x]) - - (int)(srcppp[x]) - (int)(srcpnn[x]) - - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; - } else { - val = (8 * ((int)srcpp[x] + (int)srcpn[x]) + 2 * ((int)prvp[x]) - - (int)(prvppp[x]) - (int)(prvpnn[x])) >> 4; - } - dstp[x] = av_clip(val, lo, hi); - } - } - } else { - dstp[x] = srcp[x]; - } - } - prvp += 2 * psrc_linesize; - prvpp += 2 * psrc_linesize; - prvppp += 2 * psrc_linesize; - prvpn += 2 * psrc_linesize; - prvpnn += 2 * psrc_linesize; - prvp4p += 2 * psrc_linesize; - prvp4n += 2 * psrc_linesize; - srcp += 2 * src_linesize; - srcpp += 2 * src_linesize; - srcppp += 2 * src_linesize; - srcp3p += 2 * src_linesize; - srcp4p += 2 * src_linesize; - srcpn += 2 * src_linesize; - srcpnn += 2 * src_linesize; - srcp3n += 2 * src_linesize; - srcp4n += 2 * src_linesize; - dstp += 2 * dst_linesize; - } - - srcp = inpic->data[plane]; - dstp = kerndeint->tmp_data[plane]; - av_image_copy_plane(dstp, psrc_linesize, srcp, src_linesize, bwidth, h); - } - - av_frame_free(&inpic); - return ff_filter_frame(outlink, outpic); -} - -static const AVFilterPad kerndeint_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad kerndeint_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - - -AVFilter ff_vf_kerndeint = { - .name = "kerndeint", - .description = NULL_IF_CONFIG_SMALL("Apply kernel deinterlacing to the input."), - .priv_size = sizeof(KerndeintContext), - .priv_class = &kerndeint_class, - .uninit = uninit, - .query_formats = query_formats, - .inputs = kerndeint_inputs, - .outputs = kerndeint_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_libopencv.c b/ffmpeg/libavfilter/vf_libopencv.c deleted file mode 100644 index 2306b09..0000000 --- a/ffmpeg/libavfilter/vf_libopencv.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * libopencv wrapper functions - */ - -#include <opencv/cv.h> -#include <opencv/cxcore.h> -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/file.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static void fill_iplimage_from_frame(IplImage *img, const AVFrame *frame, enum AVPixelFormat pixfmt) -{ - IplImage *tmpimg; - int depth, channels_nb; - - if (pixfmt == AV_PIX_FMT_GRAY8) { depth = IPL_DEPTH_8U; channels_nb = 1; } - else if (pixfmt == AV_PIX_FMT_BGRA) { depth = IPL_DEPTH_8U; channels_nb = 4; } - else if (pixfmt == AV_PIX_FMT_BGR24) { depth = IPL_DEPTH_8U; channels_nb = 3; } - else return; - - tmpimg = cvCreateImageHeader((CvSize){frame->width, frame->height}, depth, channels_nb); - *img = *tmpimg; - img->imageData = img->imageDataOrigin = frame->data[0]; - img->dataOrder = IPL_DATA_ORDER_PIXEL; - img->origin = IPL_ORIGIN_TL; - img->widthStep = frame->linesize[0]; -} - -static void fill_frame_from_iplimage(AVFrame *frame, const IplImage *img, enum AVPixelFormat pixfmt) -{ - frame->linesize[0] = img->widthStep; - frame->data[0] = img->imageData; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -typedef struct { - const AVClass *class; - char *name; - char *params; - int (*init)(AVFilterContext *ctx, const char *args); - void (*uninit)(AVFilterContext *ctx); - void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg); - void *priv; -} OCVContext; - -typedef struct { - int type; - int param1, param2; - double param3, param4; -} SmoothContext; - -static av_cold int smooth_init(AVFilterContext *ctx, const char *args) -{ - OCVContext *s = ctx->priv; - SmoothContext *smooth = s->priv; - char type_str[128] = "gaussian"; - - smooth->param1 = 3; - smooth->param2 = 0; - smooth->param3 = 0.0; - smooth->param4 = 0.0; - - if (args) - sscanf(args, "%127[^|]|%d|%d|%lf|%lf", type_str, &smooth->param1, &smooth->param2, &smooth->param3, &smooth->param4); - - if (!strcmp(type_str, "blur" )) smooth->type = CV_BLUR; - else if (!strcmp(type_str, "blur_no_scale")) smooth->type = CV_BLUR_NO_SCALE; - else if (!strcmp(type_str, "median" )) smooth->type = CV_MEDIAN; - else if (!strcmp(type_str, "gaussian" )) smooth->type = CV_GAUSSIAN; - else if (!strcmp(type_str, "bilateral" )) smooth->type = CV_BILATERAL; - else { - av_log(ctx, AV_LOG_ERROR, "Smoothing type '%s' unknown.\n", type_str); - return AVERROR(EINVAL); - } - - if (smooth->param1 < 0 || !(smooth->param1%2)) { - av_log(ctx, AV_LOG_ERROR, - "Invalid value '%d' for param1, it has to be a positive odd number\n", - smooth->param1); - return AVERROR(EINVAL); - } - if ((smooth->type == CV_BLUR || smooth->type == CV_BLUR_NO_SCALE || smooth->type == CV_GAUSSIAN) && - (smooth->param2 < 0 || (smooth->param2 && !(smooth->param2%2)))) { - av_log(ctx, AV_LOG_ERROR, - "Invalid value '%d' for param2, it has to be zero or a positive odd number\n", - smooth->param2); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_VERBOSE, "type:%s param1:%d param2:%d param3:%f param4:%f\n", - type_str, smooth->param1, smooth->param2, smooth->param3, smooth->param4); - return 0; -} - -static void smooth_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg) -{ - OCVContext *s = ctx->priv; - SmoothContext *smooth = s->priv; - cvSmooth(inimg, outimg, smooth->type, smooth->param1, smooth->param2, smooth->param3, smooth->param4); -} - -static int read_shape_from_file(int *cols, int *rows, int **values, const char *filename, - void *log_ctx) -{ - uint8_t *buf, *p, *pend; - size_t size; - int ret, i, j, w; - - if ((ret = av_file_map(filename, &buf, &size, 0, log_ctx)) < 0) - return ret; - - /* prescan file to get the number of lines and the maximum width */ - w = 0; - for (i = 0; i < size; i++) { - if (buf[i] == '\n') { - if (*rows == INT_MAX) { - av_log(log_ctx, AV_LOG_ERROR, "Overflow on the number of rows in the file\n"); - return AVERROR_INVALIDDATA; - } - ++(*rows); - *cols = FFMAX(*cols, w); - w = 0; - } else if (w == INT_MAX) { - av_log(log_ctx, AV_LOG_ERROR, "Overflow on the number of columns in the file\n"); - return AVERROR_INVALIDDATA; - } - w++; - } - if (*rows > (SIZE_MAX / sizeof(int) / *cols)) { - av_log(log_ctx, AV_LOG_ERROR, "File with size %dx%d is too big\n", - *rows, *cols); - return AVERROR_INVALIDDATA; - } - if (!(*values = av_mallocz(sizeof(int) * *rows * *cols))) - return AVERROR(ENOMEM); - - /* fill *values */ - p = buf; - pend = buf + size-1; - for (i = 0; i < *rows; i++) { - for (j = 0;; j++) { - if (p > pend || *p == '\n') { - p++; - break; - } else - (*values)[*cols*i + j] = !!av_isgraph(*(p++)); - } - } - av_file_unmap(buf, size); - -#ifdef DEBUG - { - char *line; - if (!(line = av_malloc(*cols + 1))) - return AVERROR(ENOMEM); - for (i = 0; i < *rows; i++) { - for (j = 0; j < *cols; j++) - line[j] = (*values)[i * *cols + j] ? '@' : ' '; - line[j] = 0; - av_log(log_ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line); - } - av_free(line); - } -#endif - - return 0; -} - -static int parse_iplconvkernel(IplConvKernel **kernel, char *buf, void *log_ctx) -{ - char shape_filename[128] = "", shape_str[32] = "rect"; - int cols = 0, rows = 0, anchor_x = 0, anchor_y = 0, shape = CV_SHAPE_RECT; - int *values = NULL, ret; - - sscanf(buf, "%dx%d+%dx%d/%32[^=]=%127s", &cols, &rows, &anchor_x, &anchor_y, shape_str, shape_filename); - - if (!strcmp(shape_str, "rect" )) shape = CV_SHAPE_RECT; - else if (!strcmp(shape_str, "cross" )) shape = CV_SHAPE_CROSS; - else if (!strcmp(shape_str, "ellipse")) shape = CV_SHAPE_ELLIPSE; - else if (!strcmp(shape_str, "custom" )) { - shape = CV_SHAPE_CUSTOM; - if ((ret = read_shape_from_file(&cols, &rows, &values, shape_filename, log_ctx)) < 0) - return ret; - } else { - av_log(log_ctx, AV_LOG_ERROR, - "Shape unspecified or type '%s' unknown.\n", shape_str); - return AVERROR(EINVAL); - } - - if (rows <= 0 || cols <= 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Invalid non-positive values for shape size %dx%d\n", cols, rows); - return AVERROR(EINVAL); - } - - if (anchor_x < 0 || anchor_y < 0 || anchor_x >= cols || anchor_y >= rows) { - av_log(log_ctx, AV_LOG_ERROR, - "Shape anchor %dx%d is not inside the rectangle with size %dx%d.\n", - anchor_x, anchor_y, cols, rows); - return AVERROR(EINVAL); - } - - *kernel = cvCreateStructuringElementEx(cols, rows, anchor_x, anchor_y, shape, values); - av_freep(&values); - if (!*kernel) - return AVERROR(ENOMEM); - - av_log(log_ctx, AV_LOG_VERBOSE, "Structuring element: w:%d h:%d x:%d y:%d shape:%s\n", - rows, cols, anchor_x, anchor_y, shape_str); - return 0; -} - -typedef struct { - int nb_iterations; - IplConvKernel *kernel; -} DilateContext; - -static av_cold int dilate_init(AVFilterContext *ctx, const char *args) -{ - OCVContext *s = ctx->priv; - DilateContext *dilate = s->priv; - char default_kernel_str[] = "3x3+0x0/rect"; - char *kernel_str; - const char *buf = args; - int ret; - - if (args) - kernel_str = av_get_token(&buf, "|"); - else - kernel_str = av_strdup(default_kernel_str); - if (!kernel_str) - return AVERROR(ENOMEM); - if ((ret = parse_iplconvkernel(&dilate->kernel, kernel_str, ctx)) < 0) - return ret; - av_free(kernel_str); - - if (!buf || sscanf(buf, "|%d", &dilate->nb_iterations) != 1) - dilate->nb_iterations = 1; - av_log(ctx, AV_LOG_VERBOSE, "iterations_nb:%d\n", dilate->nb_iterations); - if (dilate->nb_iterations <= 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid non-positive value '%d' for nb_iterations\n", - dilate->nb_iterations); - return AVERROR(EINVAL); - } - return 0; -} - -static av_cold void dilate_uninit(AVFilterContext *ctx) -{ - OCVContext *s = ctx->priv; - DilateContext *dilate = s->priv; - - cvReleaseStructuringElement(&dilate->kernel); -} - -static void dilate_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg) -{ - OCVContext *s = ctx->priv; - DilateContext *dilate = s->priv; - cvDilate(inimg, outimg, dilate->kernel, dilate->nb_iterations); -} - -static void erode_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg) -{ - OCVContext *s = ctx->priv; - DilateContext *dilate = s->priv; - cvErode(inimg, outimg, dilate->kernel, dilate->nb_iterations); -} - -typedef struct { - const char *name; - size_t priv_size; - int (*init)(AVFilterContext *ctx, const char *args); - void (*uninit)(AVFilterContext *ctx); - void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg); -} OCVFilterEntry; - -static OCVFilterEntry ocv_filter_entries[] = { - { "dilate", sizeof(DilateContext), dilate_init, dilate_uninit, dilate_end_frame_filter }, - { "erode", sizeof(DilateContext), dilate_init, dilate_uninit, erode_end_frame_filter }, - { "smooth", sizeof(SmoothContext), smooth_init, NULL, smooth_end_frame_filter }, -}; - -static av_cold int init(AVFilterContext *ctx) -{ - OCVContext *s = ctx->priv; - int i; - - if (!s->name) { - av_log(ctx, AV_LOG_ERROR, "No libopencv filter name specified\n"); - return AVERROR(EINVAL); - } - for (i = 0; i < FF_ARRAY_ELEMS(ocv_filter_entries); i++) { - OCVFilterEntry *entry = &ocv_filter_entries[i]; - if (!strcmp(s->name, entry->name)) { - s->init = entry->init; - s->uninit = entry->uninit; - s->end_frame_filter = entry->end_frame_filter; - - if (!(s->priv = av_mallocz(entry->priv_size))) - return AVERROR(ENOMEM); - return s->init(ctx, s->params); - } - } - - av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", s->name); - return AVERROR(EINVAL); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - OCVContext *s = ctx->priv; - - if (s->uninit) - s->uninit(ctx); - av_free(s->priv); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - OCVContext *s = ctx->priv; - AVFilterLink *outlink= inlink->dst->outputs[0]; - AVFrame *out; - IplImage inimg, outimg; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - fill_iplimage_from_frame(&inimg , in , inlink->format); - fill_iplimage_from_frame(&outimg, out, inlink->format); - s->end_frame_filter(ctx, &inimg, &outimg); - fill_frame_from_iplimage(out, &outimg, inlink->format); - - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(OCVContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM -static const AVOption ocv_options[] = { - { "filter_name", NULL, OFFSET(name), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(ocv); - -static const AVFilterPad avfilter_vf_ocv_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_ocv_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_ocv = { - .name = "ocv", - .description = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."), - .priv_size = sizeof(OCVContext), - .priv_class = &ocv_class, - .query_formats = query_formats, - .init = init, - .uninit = uninit, - .inputs = avfilter_vf_ocv_inputs, - .outputs = avfilter_vf_ocv_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_lut.c b/ffmpeg/libavfilter/vf_lut.c deleted file mode 100644 index 9f30ae0..0000000 --- a/ffmpeg/libavfilter/vf_lut.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Compute a look-up table for binding the input value to the output - * value, and apply it to input video. - */ - -#include "libavutil/attributes.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static const char *const var_names[] = { - "w", ///< width of the input video - "h", ///< height of the input video - "val", ///< input value for the pixel - "maxval", ///< max value for the pixel - "minval", ///< min value for the pixel - "negval", ///< negated value - "clipval", - NULL -}; - -enum var_name { - VAR_W, - VAR_H, - VAR_VAL, - VAR_MAXVAL, - VAR_MINVAL, - VAR_NEGVAL, - VAR_CLIPVAL, - VAR_VARS_NB -}; - -typedef struct { - const AVClass *class; - uint8_t lut[4][256]; ///< lookup table for each component - char *comp_expr_str[4]; - AVExpr *comp_expr[4]; - int hsub, vsub; - double var_values[VAR_VARS_NB]; - int is_rgb, is_yuv; - int step; - int negate_alpha; /* only used by negate */ -} LutContext; - -#define Y 0 -#define U 1 -#define V 2 -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -#define OFFSET(x) offsetof(LutContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption options[] = { - { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "y", "set Y expression", OFFSET(comp_expr_str[Y]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "u", "set U expression", OFFSET(comp_expr_str[U]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "v", "set V expression", OFFSET(comp_expr_str[V]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "r", "set R expression", OFFSET(comp_expr_str[R]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "g", "set G expression", OFFSET(comp_expr_str[G]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "b", "set B expression", OFFSET(comp_expr_str[B]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { "a", "set A expression", OFFSET(comp_expr_str[A]), AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS }, - { NULL } -}; - -static av_cold void uninit(AVFilterContext *ctx) -{ - LutContext *s = ctx->priv; - int i; - - for (i = 0; i < 4; i++) { - av_expr_free(s->comp_expr[i]); - s->comp_expr[i] = NULL; - av_freep(&s->comp_expr_str[i]); - } -} - -#define YUV_FORMATS \ - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, \ - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, \ - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, \ - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, \ - AV_PIX_FMT_YUVJ440P - -#define RGB_FORMATS \ - AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, \ - AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, \ - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24 - -static const enum AVPixelFormat yuv_pix_fmts[] = { YUV_FORMATS, AV_PIX_FMT_NONE }; -static const enum AVPixelFormat rgb_pix_fmts[] = { RGB_FORMATS, AV_PIX_FMT_NONE }; -static const enum AVPixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, AV_PIX_FMT_NONE }; - -static int query_formats(AVFilterContext *ctx) -{ - LutContext *s = ctx->priv; - - const enum AVPixelFormat *pix_fmts = s->is_rgb ? rgb_pix_fmts : - s->is_yuv ? yuv_pix_fmts : - all_pix_fmts; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -/** - * Clip value val in the minval - maxval range. - */ -static double clip(void *opaque, double val) -{ - LutContext *s = opaque; - double minval = s->var_values[VAR_MINVAL]; - double maxval = s->var_values[VAR_MAXVAL]; - - return av_clip(val, minval, maxval); -} - -/** - * Compute gamma correction for value val, assuming the minval-maxval - * range, val is clipped to a value contained in the same interval. - */ -static double compute_gammaval(void *opaque, double gamma) -{ - LutContext *s = opaque; - double val = s->var_values[VAR_CLIPVAL]; - double minval = s->var_values[VAR_MINVAL]; - double maxval = s->var_values[VAR_MAXVAL]; - - return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval; -} - -static double (* const funcs1[])(void *, double) = { - (void *)clip, - (void *)compute_gammaval, - NULL -}; - -static const char * const funcs1_names[] = { - "clip", - "gammaval", - NULL -}; - -static int config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - LutContext *s = ctx->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - uint8_t rgba_map[4]; /* component index -> RGBA color index map */ - int min[4], max[4]; - int val, color, ret; - - s->hsub = desc->log2_chroma_w; - s->vsub = desc->log2_chroma_h; - - s->var_values[VAR_W] = inlink->w; - s->var_values[VAR_H] = inlink->h; - - switch (inlink->format) { - case AV_PIX_FMT_YUV410P: - case AV_PIX_FMT_YUV411P: - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_YUV440P: - case AV_PIX_FMT_YUV444P: - case AV_PIX_FMT_YUVA420P: - case AV_PIX_FMT_YUVA422P: - case AV_PIX_FMT_YUVA444P: - min[Y] = min[U] = min[V] = 16; - max[Y] = 235; - max[U] = max[V] = 240; - min[A] = 0; max[A] = 255; - break; - default: - min[0] = min[1] = min[2] = min[3] = 0; - max[0] = max[1] = max[2] = max[3] = 255; - } - - s->is_yuv = s->is_rgb = 0; - if (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) s->is_yuv = 1; - else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) s->is_rgb = 1; - - if (s->is_rgb) { - ff_fill_rgba_map(rgba_map, inlink->format); - s->step = av_get_bits_per_pixel(desc) >> 3; - } - - for (color = 0; color < desc->nb_components; color++) { - double res; - int comp = s->is_rgb ? rgba_map[color] : color; - - /* create the parsed expression */ - av_expr_free(s->comp_expr[color]); - s->comp_expr[color] = NULL; - ret = av_expr_parse(&s->comp_expr[color], s->comp_expr_str[color], - var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, - "Error when parsing the expression '%s' for the component %d and color %d.\n", - s->comp_expr_str[comp], comp, color); - return AVERROR(EINVAL); - } - - /* compute the lut */ - s->var_values[VAR_MAXVAL] = max[color]; - s->var_values[VAR_MINVAL] = min[color]; - - for (val = 0; val < 256; val++) { - s->var_values[VAR_VAL] = val; - s->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]); - s->var_values[VAR_NEGVAL] = - av_clip(min[color] + max[color] - s->var_values[VAR_VAL], - min[color], max[color]); - - res = av_expr_eval(s->comp_expr[color], s->var_values, s); - if (isnan(res)) { - av_log(ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s' for the value %d for the component %d.\n", - s->comp_expr_str[color], val, comp); - return AVERROR(EINVAL); - } - s->lut[comp][val] = av_clip((int)res, min[color], max[color]); - av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, s->lut[comp][val]); - } - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - LutContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out; - uint8_t *inrow, *outrow, *inrow0, *outrow0; - int i, j, plane, direct = 0; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - } - - if (s->is_rgb) { - /* packed */ - inrow0 = in ->data[0]; - outrow0 = out->data[0]; - - for (i = 0; i < in->height; i ++) { - int w = inlink->w; - const uint8_t (*tab)[256] = (const uint8_t (*)[256])s->lut; - inrow = inrow0; - outrow = outrow0; - for (j = 0; j < w; j++) { - switch (s->step) { - case 4: outrow[3] = tab[3][inrow[3]]; // Fall-through - case 3: outrow[2] = tab[2][inrow[2]]; // Fall-through - case 2: outrow[1] = tab[1][inrow[1]]; // Fall-through - default: outrow[0] = tab[0][inrow[0]]; - } - outrow += s->step; - inrow += s->step; - } - inrow0 += in ->linesize[0]; - outrow0 += out->linesize[0]; - } - } else { - /* planar */ - for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { - int vsub = plane == 1 || plane == 2 ? s->vsub : 0; - int hsub = plane == 1 || plane == 2 ? s->hsub : 0; - int h = FF_CEIL_RSHIFT(inlink->h, vsub); - int w = FF_CEIL_RSHIFT(inlink->w, hsub); - - inrow = in ->data[plane]; - outrow = out->data[plane]; - - for (i = 0; i < h; i++) { - const uint8_t *tab = s->lut[plane]; - for (j = 0; j < w; j++) - outrow[j] = tab[inrow[j]]; - inrow += in ->linesize[plane]; - outrow += out->linesize[plane]; - } - } - } - - if (!direct) - av_frame_free(&in); - - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad inputs[] = { - { .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; -static const AVFilterPad outputs[] = { - { .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -#define DEFINE_LUT_FILTER(name_, description_) \ - AVFilter ff_vf_##name_ = { \ - .name = #name_, \ - .description = NULL_IF_CONFIG_SMALL(description_), \ - .priv_size = sizeof(LutContext), \ - .priv_class = &name_ ## _class, \ - .init = name_##_init, \ - .uninit = uninit, \ - .query_formats = query_formats, \ - .inputs = inputs, \ - .outputs = outputs, \ - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, \ - } - -#if CONFIG_LUT_FILTER - -#define lut_options options -AVFILTER_DEFINE_CLASS(lut); - -static int lut_init(AVFilterContext *ctx) -{ - return 0; -} - -DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video."); -#endif - -#if CONFIG_LUTYUV_FILTER - -#define lutyuv_options options -AVFILTER_DEFINE_CLASS(lutyuv); - -static av_cold int lutyuv_init(AVFilterContext *ctx) -{ - LutContext *s = ctx->priv; - - s->is_yuv = 1; - - return 0; -} - -DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video."); -#endif - -#if CONFIG_LUTRGB_FILTER - -#define lutrgb_options options -AVFILTER_DEFINE_CLASS(lutrgb); - -static av_cold int lutrgb_init(AVFilterContext *ctx) -{ - LutContext *s = ctx->priv; - - s->is_rgb = 1; - - return 0; -} - -DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video."); -#endif - -#if CONFIG_NEGATE_FILTER - -static const AVOption negate_options[] = { - { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(negate); - -static av_cold int negate_init(AVFilterContext *ctx) -{ - LutContext *s = ctx->priv; - int i; - - av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", s->negate_alpha); - - for (i = 0; i < 4; i++) { - s->comp_expr_str[i] = av_strdup((i == 3 && !s->negate_alpha) ? - "val" : "negval"); - if (!s->comp_expr_str[i]) { - uninit(ctx); - return AVERROR(ENOMEM); - } - } - - return 0; -} - -DEFINE_LUT_FILTER(negate, "Negate input video."); - -#endif diff --git a/ffmpeg/libavfilter/vf_mp.c b/ffmpeg/libavfilter/vf_mp.c deleted file mode 100644 index 2c145ab..0000000 --- a/ffmpeg/libavfilter/vf_mp.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * Copyright (c) 2011 Michael Niedermayer - * - * 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 - * - * Parts of this file have been stolen from mplayer - */ - -/** - * @file - */ - -#include "avfilter.h" -#include "video.h" -#include "formats.h" -#include "internal.h" -#include "libavutil/avassert.h" -#include "libavutil/pixdesc.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" - -#include "libmpcodecs/vf.h" -#include "libmpcodecs/img_format.h" -#include "libmpcodecs/cpudetect.h" -#include "libmpcodecs/av_helpers.h" -#include "libmpcodecs/libvo/fastmemcpy.h" - -#include "libswscale/swscale.h" - - -//FIXME maybe link the orig in -//XXX: identical pix_fmt must be following with each others -static const struct { - int fmt; - enum AVPixelFormat pix_fmt; -} conversion_map[] = { - {IMGFMT_ARGB, AV_PIX_FMT_ARGB}, - {IMGFMT_BGRA, AV_PIX_FMT_BGRA}, - {IMGFMT_BGR24, AV_PIX_FMT_BGR24}, - {IMGFMT_BGR16BE, AV_PIX_FMT_RGB565BE}, - {IMGFMT_BGR16LE, AV_PIX_FMT_RGB565LE}, - {IMGFMT_BGR15BE, AV_PIX_FMT_RGB555BE}, - {IMGFMT_BGR15LE, AV_PIX_FMT_RGB555LE}, - {IMGFMT_BGR12BE, AV_PIX_FMT_RGB444BE}, - {IMGFMT_BGR12LE, AV_PIX_FMT_RGB444LE}, - {IMGFMT_BGR8, AV_PIX_FMT_RGB8}, - {IMGFMT_BGR4, AV_PIX_FMT_RGB4}, - {IMGFMT_BGR1, AV_PIX_FMT_MONOBLACK}, - {IMGFMT_RGB1, AV_PIX_FMT_MONOBLACK}, - {IMGFMT_RG4B, AV_PIX_FMT_BGR4_BYTE}, - {IMGFMT_BG4B, AV_PIX_FMT_RGB4_BYTE}, - {IMGFMT_RGB48LE, AV_PIX_FMT_RGB48LE}, - {IMGFMT_RGB48BE, AV_PIX_FMT_RGB48BE}, - {IMGFMT_ABGR, AV_PIX_FMT_ABGR}, - {IMGFMT_RGBA, AV_PIX_FMT_RGBA}, - {IMGFMT_RGB24, AV_PIX_FMT_RGB24}, - {IMGFMT_RGB16BE, AV_PIX_FMT_BGR565BE}, - {IMGFMT_RGB16LE, AV_PIX_FMT_BGR565LE}, - {IMGFMT_RGB15BE, AV_PIX_FMT_BGR555BE}, - {IMGFMT_RGB15LE, AV_PIX_FMT_BGR555LE}, - {IMGFMT_RGB12BE, AV_PIX_FMT_BGR444BE}, - {IMGFMT_RGB12LE, AV_PIX_FMT_BGR444LE}, - {IMGFMT_RGB8, AV_PIX_FMT_BGR8}, - {IMGFMT_RGB4, AV_PIX_FMT_BGR4}, - {IMGFMT_BGR8, AV_PIX_FMT_PAL8}, - {IMGFMT_YUY2, AV_PIX_FMT_YUYV422}, - {IMGFMT_UYVY, AV_PIX_FMT_UYVY422}, - {IMGFMT_NV12, AV_PIX_FMT_NV12}, - {IMGFMT_NV21, AV_PIX_FMT_NV21}, - {IMGFMT_Y800, AV_PIX_FMT_GRAY8}, - {IMGFMT_Y8, AV_PIX_FMT_GRAY8}, - {IMGFMT_YVU9, AV_PIX_FMT_YUV410P}, - {IMGFMT_IF09, AV_PIX_FMT_YUV410P}, - {IMGFMT_YV12, AV_PIX_FMT_YUV420P}, - {IMGFMT_I420, AV_PIX_FMT_YUV420P}, - {IMGFMT_IYUV, AV_PIX_FMT_YUV420P}, - {IMGFMT_411P, AV_PIX_FMT_YUV411P}, - {IMGFMT_422P, AV_PIX_FMT_YUV422P}, - {IMGFMT_444P, AV_PIX_FMT_YUV444P}, - {IMGFMT_440P, AV_PIX_FMT_YUV440P}, - - {IMGFMT_420A, AV_PIX_FMT_YUVA420P}, - - {IMGFMT_420P16_LE, AV_PIX_FMT_YUV420P16LE}, - {IMGFMT_420P16_BE, AV_PIX_FMT_YUV420P16BE}, - {IMGFMT_422P16_LE, AV_PIX_FMT_YUV422P16LE}, - {IMGFMT_422P16_BE, AV_PIX_FMT_YUV422P16BE}, - {IMGFMT_444P16_LE, AV_PIX_FMT_YUV444P16LE}, - {IMGFMT_444P16_BE, AV_PIX_FMT_YUV444P16BE}, - - // YUVJ are YUV formats that use the full Y range and not just - // 16 - 235 (see colorspaces.txt). - // Currently they are all treated the same way. - {IMGFMT_YV12, AV_PIX_FMT_YUVJ420P}, - {IMGFMT_422P, AV_PIX_FMT_YUVJ422P}, - {IMGFMT_444P, AV_PIX_FMT_YUVJ444P}, - {IMGFMT_440P, AV_PIX_FMT_YUVJ440P}, - -#if FF_API_XVMC - {IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC}, - {IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT}, -#endif /* FF_API_XVMC */ - - {IMGFMT_VDPAU_MPEG1, AV_PIX_FMT_VDPAU_MPEG1}, - {IMGFMT_VDPAU_MPEG2, AV_PIX_FMT_VDPAU_MPEG2}, - {IMGFMT_VDPAU_H264, AV_PIX_FMT_VDPAU_H264}, - {IMGFMT_VDPAU_WMV3, AV_PIX_FMT_VDPAU_WMV3}, - {IMGFMT_VDPAU_VC1, AV_PIX_FMT_VDPAU_VC1}, - {IMGFMT_VDPAU_MPEG4, AV_PIX_FMT_VDPAU_MPEG4}, - {0, AV_PIX_FMT_NONE} -}; - -extern const vf_info_t ff_vf_info_eq2; -extern const vf_info_t ff_vf_info_eq; -extern const vf_info_t ff_vf_info_fspp; -extern const vf_info_t ff_vf_info_ilpack; -extern const vf_info_t ff_vf_info_pp7; -extern const vf_info_t ff_vf_info_softpulldown; -extern const vf_info_t ff_vf_info_uspp; - - -static const vf_info_t* const filters[]={ - &ff_vf_info_eq2, - &ff_vf_info_eq, - &ff_vf_info_fspp, - &ff_vf_info_ilpack, - &ff_vf_info_pp7, - &ff_vf_info_softpulldown, - &ff_vf_info_uspp, - - NULL -}; - -/* -Unsupported filters -1bpp -ass -bmovl -crop -dvbscale -flip -expand -format -halfpack -lavc -lavcdeint -noformat -pp -scale -tfields -vo -yadif -zrmjpeg -*/ - -CpuCaps ff_gCpuCaps; //FIXME initialize this so optims work - -enum AVPixelFormat ff_mp2ff_pix_fmt(int mp){ - int i; - for(i=0; conversion_map[i].fmt && mp != conversion_map[i].fmt; i++) - ; - return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE; -} - -typedef struct { - const AVClass *class; - vf_instance_t vf; - vf_instance_t next_vf; - AVFilterContext *avfctx; - int frame_returned; - char *filter; - enum AVPixelFormat in_pix_fmt; -} MPContext; - -#define OFFSET(x) offsetof(MPContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption mp_options[] = { - { "filter", "set MPlayer filter name and parameters", OFFSET(filter), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(mp); - -void ff_mp_msg(int mod, int lev, const char *format, ... ){ - va_list va; - va_start(va, format); - //FIXME convert lev/mod - av_vlog(NULL, AV_LOG_DEBUG, format, va); - va_end(va); -} - -int ff_mp_msg_test(int mod, int lev){ - return 123; -} - -void ff_init_avcodec(void) -{ - //we maybe should init but its kinda 1. unneeded 2. a bit inpolite from here -} - -//Exact copy of vf.c -void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){ - dst->pict_type= src->pict_type; - dst->fields = src->fields; - dst->qscale_type= src->qscale_type; - if(dst->width == src->width && dst->height == src->height){ - dst->qstride= src->qstride; - dst->qscale= src->qscale; - } -} - -//Exact copy of vf.c -void ff_vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){ - if (vf->next->draw_slice) { - vf->next->draw_slice(vf->next,src,stride,w,h,x,y); - return; - } - if (!vf->dmpi) { - ff_mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name); - return; - } - if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) { - memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x, - src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride[0]); - return; - } - memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0], - w, h, vf->dmpi->stride[0], stride[0]); - memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift), - src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]); - memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift), - src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]); -} - -//Exact copy of vf.c -void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){ - int y; - if(mpi->flags&MP_IMGFLAG_PLANAR){ - y0&=~1;h+=h&1; - if(x0==0 && w==mpi->width){ - // full width clear: - memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h); - memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift)); - memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift)); - } else - for(y=y0;y<y0+h;y+=2){ - memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w); - memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w); - memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift)); - memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift)); - } - return; - } - // packed: - for(y=y0;y<y0+h;y++){ - unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0; - if(mpi->flags&MP_IMGFLAG_YUV){ - unsigned int* p=(unsigned int*) dst; - int size=(mpi->bpp>>3)*w/4; - int i; -#if HAVE_BIGENDIAN -#define CLEAR_PACKEDYUV_PATTERN 0x00800080 -#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000 -#else -#define CLEAR_PACKEDYUV_PATTERN 0x80008000 -#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080 -#endif - if(mpi->flags&MP_IMGFLAG_SWAPPED){ - for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED; - for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED; - } else { - for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN; - for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN; - } - } else - memset(dst,0,(mpi->bpp>>3)*w); - } -} - -int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt){ - return 1; -} - -//used by delogo -unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){ - return preferred; -} - -mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){ - MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf)); - mp_image_t* mpi=NULL; - int w2; - int number = mp_imgtype >> 16; - - av_assert0(vf->next == NULL); // all existing filters call this just on next - - //vf_dint needs these as it calls ff_vf_get_image() before configuring the output - if(vf->w==0 && w>0) vf->w=w; - if(vf->h==0 && h>0) vf->h=h; - - av_assert0(w == -1 || w >= vf->w); - av_assert0(h == -1 || h >= vf->h); - av_assert0(vf->w > 0); - av_assert0(vf->h > 0); - - av_log(m->avfctx, AV_LOG_DEBUG, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h); - - if (w == -1) w = vf->w; - if (h == -1) h = vf->h; - - w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w; - - // Note: we should call libvo first to check if it supports direct rendering - // and if not, then fallback to software buffers: - switch(mp_imgtype & 0xff){ - case MP_IMGTYPE_EXPORT: - if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=ff_new_mp_image(w2,h); - mpi=vf->imgctx.export_images[0]; - break; - case MP_IMGTYPE_STATIC: - if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=ff_new_mp_image(w2,h); - mpi=vf->imgctx.static_images[0]; - break; - case MP_IMGTYPE_TEMP: - if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h); - mpi=vf->imgctx.temp_images[0]; - break; - case MP_IMGTYPE_IPB: - if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame: - if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h); - mpi=vf->imgctx.temp_images[0]; - break; - } - case MP_IMGTYPE_IP: - if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=ff_new_mp_image(w2,h); - mpi=vf->imgctx.static_images[vf->imgctx.static_idx]; - vf->imgctx.static_idx^=1; - break; - case MP_IMGTYPE_NUMBERED: - if (number == -1) { - int i; - for (i = 0; i < NUM_NUMBERED_MPI; i++) - if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count) - break; - number = i; - } - if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL; - if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = ff_new_mp_image(w2,h); - mpi = vf->imgctx.numbered_images[number]; - mpi->number = number; - break; - } - if(mpi){ - mpi->type=mp_imgtype; - mpi->w=vf->w; mpi->h=vf->h; - // keep buffer allocation status & color flags only: -// mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT); - mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS; - // accept restrictions, draw_slice and palette flags only: - mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE); - if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK; - if(mpi->width!=w2 || mpi->height!=h){ -// printf("vf.c: MPI parameters changed! %dx%d -> %dx%d \n", mpi->width,mpi->height,w2,h); - if(mpi->flags&MP_IMGFLAG_ALLOCATED){ - if(mpi->width<w2 || mpi->height<h){ - // need to re-allocate buffer memory: - av_free(mpi->planes[0]); - mpi->flags&=~MP_IMGFLAG_ALLOCATED; - ff_mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n"); - } -// } else { - } { - mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift; - mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift; - } - } - if(!mpi->bpp) ff_mp_image_setfmt(mpi,outfmt); - if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){ - - av_assert0(!vf->get_image); - // check libvo first! - if(vf->get_image) vf->get_image(vf,mpi); - - if(!(mpi->flags&MP_IMGFLAG_DIRECT)){ - // non-direct and not yet allocated image. allocate it! - if (!mpi->bpp) { // no way we can allocate this - ff_mp_msg(MSGT_DECVIDEO, MSGL_FATAL, - "ff_vf_get_image: Tried to allocate a format that can not be allocated!\n"); - return NULL; - } - - // check if codec prefer aligned stride: - if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){ - int align=(mpi->flags&MP_IMGFLAG_PLANAR && - mpi->flags&MP_IMGFLAG_YUV) ? - (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME - w2=((w+align)&(~align)); - if(mpi->width!=w2){ -#if 0 - // we have to change width... check if we CAN co it: - int flags=vf->query_format(vf,outfmt); // should not fail - if(!(flags&3)) ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? ff_vf_get_image{vf->query_format(outfmt)} failed!\n"); -// printf("query -> 0x%X \n",flags); - if(flags&VFCAP_ACCEPT_STRIDE){ -#endif - mpi->width=w2; - mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift; -// } - } - } - - ff_mp_image_alloc_planes(mpi); -// printf("clearing img!\n"); - ff_vf_mpi_clear(mpi,0,0,mpi->width,mpi->height); - } - } - av_assert0(!vf->start_slice); - if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK) - if(vf->start_slice) vf->start_slice(vf,mpi); - if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){ - ff_mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n", - "NULL"/*vf->info->name*/, - (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting": - ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"), - (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"", - mpi->width,mpi->height,mpi->bpp, - (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"), - (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed", - mpi->bpp*mpi->width*mpi->height/8); - ff_mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n", - mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2], - mpi->stride[0], mpi->stride[1], mpi->stride[2], - mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift); - mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED; - } - - mpi->qscale = NULL; - mpi->usage_count++; - } -// printf("\rVF_MPI: %p %p %p %d %d %d \n", -// mpi->planes[0],mpi->planes[1],mpi->planes[2], -// mpi->stride[0],mpi->stride[1],mpi->stride[2]); - return mpi; -} - -int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){ - MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf)); - AVFilterLink *outlink = m->avfctx->outputs[0]; - AVFrame *picref = av_frame_alloc(); - int i; - - av_assert0(vf->next); - - av_log(m->avfctx, AV_LOG_DEBUG, "ff_vf_next_put_image\n"); - - if (!picref) - goto fail; - - picref->width = mpi->w; - picref->height = mpi->h; - - picref->type = AVMEDIA_TYPE_VIDEO; - - for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++); - picref->format = conversion_map[i].pix_fmt; - - for(i=0; conversion_map[i].fmt && m->in_pix_fmt != conversion_map[i].pix_fmt; i++); - if (mpi->imgfmt == conversion_map[i].fmt) - picref->format = conversion_map[i].pix_fmt; - - memcpy(picref->linesize, mpi->stride, FFMIN(sizeof(picref->linesize), sizeof(mpi->stride))); - - for(i=0; i<4 && mpi->stride[i]; i++){ - picref->data[i] = mpi->planes[i]; - } - - if(pts != MP_NOPTS_VALUE) - picref->pts= pts * av_q2d(outlink->time_base); - - if(1) { // mp buffers are currently unsupported in libavfilter, we thus must copy - AVFrame *tofree = picref; - picref = av_frame_clone(picref); - av_frame_free(&tofree); - } - - ff_filter_frame(outlink, picref); - m->frame_returned++; - - return 1; -fail: - av_frame_free(&picref); - return 0; -} - -int ff_vf_next_config(struct vf_instance *vf, - int width, int height, int d_width, int d_height, - unsigned int voflags, unsigned int outfmt){ - - av_assert0(width>0 && height>0); - vf->next->w = width; vf->next->h = height; - - return 1; -#if 0 - int flags=vf->next->query_format(vf->next,outfmt); - if(!flags){ - // hmm. colorspace mismatch!!! - //this is fatal for us ATM - return 0; - } - ff_mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X req=0x%X \n",flags,vf->default_reqs); - miss=vf->default_reqs - (flags&vf->default_reqs); - if(miss&VFCAP_ACCEPT_STRIDE){ - // vf requires stride support but vf->next doesn't support it! - // let's insert the 'expand' filter, it does the job for us: - vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL); - if(!vf2) return 0; // shouldn't happen! - vf->next=vf2; - } - vf->next->w = width; vf->next->h = height; - return 1; -#endif -} - -int ff_vf_next_control(struct vf_instance *vf, int request, void* data){ - MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf)); - av_log(m->avfctx, AV_LOG_DEBUG, "Received control %d\n", request); - return 0; -} - -static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){ - MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf)); - int i; - av_log(m->avfctx, AV_LOG_DEBUG, "query %X\n", fmt); - - for(i=0; conversion_map[i].fmt; i++){ - if(fmt==conversion_map[i].fmt) - return 1; //we suport all - } - return 0; -} - - -static av_cold int init(AVFilterContext *ctx) -{ - MPContext *m = ctx->priv; - int cpu_flags = av_get_cpu_flags(); - char name[256]; - const char *args; - int i; - - ff_gCpuCaps.hasMMX = cpu_flags & AV_CPU_FLAG_MMX; - ff_gCpuCaps.hasMMX2 = cpu_flags & AV_CPU_FLAG_MMX2; - ff_gCpuCaps.hasSSE = cpu_flags & AV_CPU_FLAG_SSE; - ff_gCpuCaps.hasSSE2 = cpu_flags & AV_CPU_FLAG_SSE2; - ff_gCpuCaps.hasSSE3 = cpu_flags & AV_CPU_FLAG_SSE3; - ff_gCpuCaps.hasSSSE3 = cpu_flags & AV_CPU_FLAG_SSSE3; - ff_gCpuCaps.hasSSE4 = cpu_flags & AV_CPU_FLAG_SSE4; - ff_gCpuCaps.hasSSE42 = cpu_flags & AV_CPU_FLAG_SSE42; - ff_gCpuCaps.hasAVX = cpu_flags & AV_CPU_FLAG_AVX; - ff_gCpuCaps.has3DNow = cpu_flags & AV_CPU_FLAG_3DNOW; - ff_gCpuCaps.has3DNowExt = cpu_flags & AV_CPU_FLAG_3DNOWEXT; - - m->avfctx= ctx; - - args = m->filter; - if(!args || 1!=sscanf(args, "%255[^:=]", name)){ - av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n"); - return AVERROR(EINVAL); - } - args += strlen(name); - if (args[0] == '=') - args++; - - for(i=0; ;i++){ - if(!filters[i] || !strcmp(name, filters[i]->name)) - break; - } - - if(!filters[i]){ - av_log(ctx, AV_LOG_ERROR, "Unknown filter %s\n", name); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_WARNING, - "'%s' is a wrapped MPlayer filter (libmpcodecs). This filter may be removed\n" - "once it has been ported to a native libavfilter.\n", name); - - memset(&m->vf,0,sizeof(m->vf)); - m->vf.info= filters[i]; - - m->vf.next = &m->next_vf; - m->vf.put_image = ff_vf_next_put_image; - m->vf.config = ff_vf_next_config; - m->vf.query_format= vf_default_query_format; - m->vf.control = ff_vf_next_control; - m->vf.default_caps=VFCAP_ACCEPT_STRIDE; - m->vf.default_reqs=0; - if(m->vf.info->opts) - av_log(ctx, AV_LOG_ERROR, "opts / m_struct_set is unsupported\n"); -#if 0 - if(vf->info->opts) { // vf_vo get some special argument - const m_struct_t* st = vf->info->opts; - void* vf_priv = m_struct_alloc(st); - int n; - for(n = 0 ; args && args[2*n] ; n++) - m_struct_set(st,vf_priv,args[2*n],args[2*n+1]); - vf->priv = vf_priv; - args = NULL; - } else // Otherwise we should have the '_oldargs_' - if(args && !strcmp(args[0],"_oldargs_")) - args = (char**)args[1]; - else - args = NULL; -#endif - if(m->vf.info->vf_open(&m->vf, (char*)args)<=0){ - av_log(ctx, AV_LOG_ERROR, "vf_open() of %s with arg=%s failed\n", name, args); - return -1; - } - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - MPContext *m = ctx->priv; - vf_instance_t *vf = &m->vf; - - while(vf){ - vf_instance_t *next = vf->next; - if(vf->uninit) - vf->uninit(vf); - ff_free_mp_image(vf->imgctx.static_images[0]); - ff_free_mp_image(vf->imgctx.static_images[1]); - ff_free_mp_image(vf->imgctx.temp_images[0]); - ff_free_mp_image(vf->imgctx.export_images[0]); - vf = next; - } -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *avfmts=NULL; - MPContext *m = ctx->priv; - enum AVPixelFormat lastpixfmt = AV_PIX_FMT_NONE; - int i; - - for(i=0; conversion_map[i].fmt; i++){ - av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt); - if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){ - av_log(ctx, AV_LOG_DEBUG, "supported,adding\n"); - if (conversion_map[i].pix_fmt != lastpixfmt) { - ff_add_format(&avfmts, conversion_map[i].pix_fmt); - lastpixfmt = conversion_map[i].pix_fmt; - } - } - } - - if (!avfmts) - return -1; - - //We assume all allowed input formats are also allowed output formats - ff_set_common_formats(ctx, avfmts); - return 0; -} - -static int config_inprops(AVFilterLink *inlink) -{ - MPContext *m = inlink->dst->priv; - int i; - for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++); - - av_assert0(conversion_map[i].fmt && inlink->w && inlink->h); - - m->vf.fmt.have_configured = 1; - m->vf.fmt.orig_height = inlink->h; - m->vf.fmt.orig_width = inlink->w; - m->vf.fmt.orig_fmt = conversion_map[i].fmt; - - if(m->vf.config(&m->vf, inlink->w, inlink->h, inlink->w, inlink->h, 0, conversion_map[i].fmt)<=0) - return -1; - - return 0; -} - -static int config_outprops(AVFilterLink *outlink) -{ - MPContext *m = outlink->src->priv; - - outlink->w = m->next_vf.w; - outlink->h = m->next_vf.h; - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - MPContext *m = outlink->src->priv; - int ret; - - av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n"); - - for(m->frame_returned=0; !m->frame_returned;){ - ret=ff_request_frame(outlink->src->inputs[0]); - if(ret<0) - break; - } - - av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame ret=%d\n", ret); - return ret; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) -{ - MPContext *m = inlink->dst->priv; - int i; - double pts= MP_NOPTS_VALUE; - mp_image_t* mpi = ff_new_mp_image(inpic->width, inpic->height); - - if(inpic->pts != AV_NOPTS_VALUE) - pts= inpic->pts / av_q2d(inlink->time_base); - - for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++); - ff_mp_image_setfmt(mpi,conversion_map[i].fmt); - m->in_pix_fmt = inlink->format; - - memcpy(mpi->planes, inpic->data, FFMIN(sizeof(inpic->data) , sizeof(mpi->planes))); - memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride))); - - if (inpic->interlaced_frame) - mpi->fields |= MP_IMGFIELD_INTERLACED; - if (inpic->top_field_first) - mpi->fields |= MP_IMGFIELD_TOP_FIRST; - if (inpic->repeat_pict) - mpi->fields |= MP_IMGFIELD_REPEAT_FIRST; - - // mpi->flags|=MP_IMGFLAG_ALLOCATED; ? - mpi->flags |= MP_IMGFLAG_READABLE; - if(!av_frame_is_writable(inpic)) - mpi->flags |= MP_IMGFLAG_PRESERVE; - if(m->vf.put_image(&m->vf, mpi, pts) == 0){ - av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n"); - }else{ - av_frame_free(&inpic); - } - ff_free_mp_image(mpi); - return 0; -} - -static const AVFilterPad mp_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_inprops, - }, - { NULL } -}; - -static const AVFilterPad mp_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_outprops, - }, - { NULL } -}; - -AVFilter ff_vf_mp = { - .name = "mp", - .description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(MPContext), - .query_formats = query_formats, - .inputs = mp_inputs, - .outputs = mp_outputs, - .priv_class = &mp_class, -}; diff --git a/ffmpeg/libavfilter/vf_noise.c b/ffmpeg/libavfilter/vf_noise.c deleted file mode 100644 index c29afa2..0000000 --- a/ffmpeg/libavfilter/vf_noise.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2013 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * noise generator - */ - -#include "libavutil/opt.h" -#include "libavutil/imgutils.h" -#include "libavutil/lfg.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "libavutil/x86/asm.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -#define MAX_NOISE 5120 -#define MAX_SHIFT 1024 -#define MAX_RES (MAX_NOISE-MAX_SHIFT) - -#define NOISE_UNIFORM 1 -#define NOISE_TEMPORAL 2 -#define NOISE_AVERAGED 8 -#define NOISE_PATTERN 16 - -typedef struct { - int strength; - unsigned flags; - AVLFG lfg; - int seed; - int8_t *noise; - int8_t *prev_shift[MAX_RES][3]; -} FilterParams; - -typedef struct { - const AVClass *class; - int nb_planes; - int bytewidth[4]; - int height[4]; - FilterParams all; - FilterParams param[4]; - int rand_shift[MAX_RES]; - int rand_shift_init; - void (*line_noise)(uint8_t *dst, const uint8_t *src, int8_t *noise, int len, int shift); - void (*line_noise_avg)(uint8_t *dst, const uint8_t *src, int len, int8_t **shift); -} NoiseContext; - -typedef struct ThreadData { - AVFrame *in, *out; -} ThreadData; - -#define OFFSET(x) offsetof(NoiseContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -#define NOISE_PARAMS(name, x, param) \ - {#name"_seed", "set component #"#x" noise seed", OFFSET(param.seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, INT_MAX, FLAGS}, \ - {#name"_strength", "set component #"#x" strength", OFFSET(param.strength), AV_OPT_TYPE_INT, {.i64=0}, 0, 100, FLAGS}, \ - {#name"s", "set component #"#x" strength", OFFSET(param.strength), AV_OPT_TYPE_INT, {.i64=0}, 0, 100, FLAGS}, \ - {#name"_flags", "set component #"#x" flags", OFFSET(param.flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 31, FLAGS, #name"_flags"}, \ - {#name"f", "set component #"#x" flags", OFFSET(param.flags), AV_OPT_TYPE_FLAGS, {.i64=0}, 0, 31, FLAGS, #name"_flags"}, \ - {"a", "averaged noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_AVERAGED}, 0, 0, FLAGS, #name"_flags"}, \ - {"p", "(semi)regular pattern", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_PATTERN}, 0, 0, FLAGS, #name"_flags"}, \ - {"t", "temporal noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_TEMPORAL}, 0, 0, FLAGS, #name"_flags"}, \ - {"u", "uniform noise", 0, AV_OPT_TYPE_CONST, {.i64=NOISE_UNIFORM}, 0, 0, FLAGS, #name"_flags"}, - -static const AVOption noise_options[] = { - NOISE_PARAMS(all, 0, all) - NOISE_PARAMS(c0, 0, param[0]) - NOISE_PARAMS(c1, 1, param[1]) - NOISE_PARAMS(c2, 2, param[2]) - NOISE_PARAMS(c3, 3, param[3]) - {NULL} -}; - -AVFILTER_DEFINE_CLASS(noise); - -static const int8_t patt[4] = { -1, 0, 1, 0 }; - -#define RAND_N(range) ((int) ((double) range * av_lfg_get(lfg) / (UINT_MAX + 1.0))) -static av_cold int init_noise(NoiseContext *n, int comp) -{ - int8_t *noise = av_malloc(MAX_NOISE * sizeof(int8_t)); - FilterParams *fp = &n->param[comp]; - AVLFG *lfg = &n->param[comp].lfg; - int strength = fp->strength; - int flags = fp->flags; - int i, j; - - if (!noise) - return AVERROR(ENOMEM); - - av_lfg_init(&fp->lfg, fp->seed); - - for (i = 0, j = 0; i < MAX_NOISE; i++, j++) { - if (flags & NOISE_UNIFORM) { - if (flags & NOISE_AVERAGED) { - if (flags & NOISE_PATTERN) { - noise[i] = (RAND_N(strength) - strength / 2) / 6 - + patt[j % 4] * strength * 0.25 / 3; - } else { - noise[i] = (RAND_N(strength) - strength / 2) / 3; - } - } else { - if (flags & NOISE_PATTERN) { - noise[i] = (RAND_N(strength) - strength / 2) / 2 - + patt[j % 4] * strength * 0.25; - } else { - noise[i] = RAND_N(strength) - strength / 2; - } - } - } else { - double x1, x2, w, y1; - do { - x1 = 2.0 * av_lfg_get(lfg) / (float)UINT_MAX - 1.0; - x2 = 2.0 * av_lfg_get(lfg) / (float)UINT_MAX - 1.0; - w = x1 * x1 + x2 * x2; - } while (w >= 1.0); - - w = sqrt((-2.0 * log(w)) / w); - y1 = x1 * w; - y1 *= strength / sqrt(3.0); - if (flags & NOISE_PATTERN) { - y1 /= 2; - y1 += patt[j % 4] * strength * 0.35; - } - y1 = av_clipf(y1, -128, 127); - if (flags & NOISE_AVERAGED) - y1 /= 3.0; - noise[i] = (int)y1; - } - if (RAND_N(6) == 0) - j--; - } - - for (i = 0; i < MAX_RES; i++) - for (j = 0; j < 3; j++) - fp->prev_shift[i][j] = noise + (av_lfg_get(lfg) & (MAX_SHIFT - 1)); - - if (!n->rand_shift_init) { - for (i = 0; i < MAX_RES; i++) - n->rand_shift[i] = av_lfg_get(lfg) & (MAX_SHIFT - 1); - n->rand_shift_init = 1; - } - - fp->noise = noise; - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (desc->flags & AV_PIX_FMT_FLAG_PLANAR && !((desc->comp[0].depth_minus1 + 1) & 7)) - ff_add_format(&formats, fmt); - } - - ff_set_common_formats(ctx, formats); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - NoiseContext *n = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret; - - n->nb_planes = av_pix_fmt_count_planes(inlink->format); - - if ((ret = av_image_fill_linesizes(n->bytewidth, inlink->format, inlink->w)) < 0) - return ret; - - n->height[1] = n->height[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); - n->height[0] = n->height[3] = inlink->h; - - return 0; -} - -static inline void line_noise_c(uint8_t *dst, const uint8_t *src, int8_t *noise, - int len, int shift) -{ - int i; - - noise += shift; - for (i = 0; i < len; i++) { - int v = src[i] + noise[i]; - - dst[i] = av_clip_uint8(v); - } -} - -#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t" - -static void line_noise_mmx(uint8_t *dst, const uint8_t *src, - int8_t *noise, int len, int shift) -{ -#if HAVE_MMX_INLINE - x86_reg mmx_len= len&(~7); - noise+=shift; - - __asm__ volatile( - "mov %3, %%"REG_a" \n\t" - "pcmpeqb %%mm7, %%mm7 \n\t" - "psllw $15, %%mm7 \n\t" - "packsswb %%mm7, %%mm7 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0, %%"REG_a"), %%mm0 \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "pxor %%mm7, %%mm0 \n\t" - "paddsb %%mm1, %%mm0 \n\t" - "pxor %%mm7, %%mm0 \n\t" - "movq %%mm0, (%2, %%"REG_a") \n\t" - "add $8, %%"REG_a" \n\t" - " js 1b \n\t" - :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len) - : "%"REG_a - ); - if (mmx_len!=len) - line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0); -#endif -} - -static void line_noise_mmxext(uint8_t *dst, const uint8_t *src, - int8_t *noise, int len, int shift) -{ -#if HAVE_MMXEXT_INLINE - x86_reg mmx_len= len&(~7); - noise+=shift; - - __asm__ volatile( - "mov %3, %%"REG_a" \n\t" - "pcmpeqb %%mm7, %%mm7 \n\t" - "psllw $15, %%mm7 \n\t" - "packsswb %%mm7, %%mm7 \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%0, %%"REG_a"), %%mm0 \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "pxor %%mm7, %%mm0 \n\t" - "paddsb %%mm1, %%mm0 \n\t" - "pxor %%mm7, %%mm0 \n\t" - "movntq %%mm0, (%2, %%"REG_a") \n\t" - "add $8, %%"REG_a" \n\t" - " js 1b \n\t" - :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len) - : "%"REG_a - ); - if (mmx_len != len) - line_noise_c(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0); -#endif -} - -static inline void line_noise_avg_c(uint8_t *dst, const uint8_t *src, - int len, int8_t **shift) -{ - int i; - int8_t *src2 = (int8_t*)src; - - for (i = 0; i < len; i++) { - const int n = shift[0][i] + shift[1][i] + shift[2][i]; - dst[i] = src2[i] + ((n * src2[i]) >> 7); - } -} - -static inline void line_noise_avg_mmx(uint8_t *dst, const uint8_t *src, - int len, int8_t **shift) -{ -#if HAVE_MMX_INLINE - x86_reg mmx_len= len&(~7); - - __asm__ volatile( - "mov %5, %%"REG_a" \n\t" - ASMALIGN(4) - "1: \n\t" - "movq (%1, %%"REG_a"), %%mm1 \n\t" - "movq (%0, %%"REG_a"), %%mm0 \n\t" - "paddb (%2, %%"REG_a"), %%mm1 \n\t" - "paddb (%3, %%"REG_a"), %%mm1 \n\t" - "movq %%mm0, %%mm2 \n\t" - "movq %%mm1, %%mm3 \n\t" - "punpcklbw %%mm0, %%mm0 \n\t" - "punpckhbw %%mm2, %%mm2 \n\t" - "punpcklbw %%mm1, %%mm1 \n\t" - "punpckhbw %%mm3, %%mm3 \n\t" - "pmulhw %%mm0, %%mm1 \n\t" - "pmulhw %%mm2, %%mm3 \n\t" - "paddw %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm3 \n\t" - "paddw %%mm0, %%mm1 \n\t" - "paddw %%mm2, %%mm3 \n\t" - "psrlw $8, %%mm1 \n\t" - "psrlw $8, %%mm3 \n\t" - "packuswb %%mm3, %%mm1 \n\t" - "movq %%mm1, (%4, %%"REG_a") \n\t" - "add $8, %%"REG_a" \n\t" - " js 1b \n\t" - :: "r" (src+mmx_len), "r" (shift[0]+mmx_len), "r" (shift[1]+mmx_len), "r" (shift[2]+mmx_len), - "r" (dst+mmx_len), "g" (-mmx_len) - : "%"REG_a - ); - - if (mmx_len != len){ - int8_t *shift2[3]={shift[0]+mmx_len, shift[1]+mmx_len, shift[2]+mmx_len}; - line_noise_avg_c(dst+mmx_len, src+mmx_len, len-mmx_len, shift2); - } -#endif -} - -static void noise(uint8_t *dst, const uint8_t *src, - int dst_linesize, int src_linesize, - int width, int start, int end, NoiseContext *n, int comp) -{ - FilterParams *p = &n->param[comp]; - int8_t *noise = p->noise; - const int flags = p->flags; - AVLFG *lfg = &p->lfg; - int shift, y; - - if (!noise) { - if (dst != src) - av_image_copy_plane(dst, dst_linesize, src, src_linesize, width, end - start); - return; - } - - for (y = start; y < end; y++) { - const int ix = y & (MAX_RES - 1); - if (flags & NOISE_TEMPORAL) - shift = av_lfg_get(lfg) & (MAX_SHIFT - 1); - else - shift = n->rand_shift[ix]; - - if (flags & NOISE_AVERAGED) { - n->line_noise_avg(dst, src, width, p->prev_shift[ix]); - p->prev_shift[ix][shift & 3] = noise + shift; - } else { - n->line_noise(dst, src, noise, width, shift); - } - dst += dst_linesize; - src += src_linesize; - } -} - -static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - NoiseContext *s = ctx->priv; - ThreadData *td = arg; - int plane; - - for (plane = 0; plane < s->nb_planes; plane++) { - const int height = s->height[plane]; - const int start = (height * jobnr ) / nb_jobs; - const int end = (height * (jobnr+1)) / nb_jobs; - noise(td->out->data[plane] + start * td->out->linesize[plane], - td->in->data[plane] + start * td->in->linesize[plane], - td->out->linesize[plane], td->in->linesize[plane], - s->bytewidth[plane], start, end, s, plane); - } - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - NoiseContext *n = ctx->priv; - ThreadData td; - AVFrame *out; - - if (av_frame_is_writable(inpicref)) { - out = inpicref; - } else { - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, inpicref); - } - - td.in = inpicref; td.out = out; - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(n->height[0], ctx->graph->nb_threads)); - emms_c(); - - if (inpicref != out) - av_frame_free(&inpicref); - return ff_filter_frame(outlink, out); -} - -static av_cold int init(AVFilterContext *ctx) -{ - NoiseContext *n = ctx->priv; - int ret, i; - int cpu_flags = av_get_cpu_flags(); - - for (i = 0; i < 4; i++) { - if (n->all.seed >= 0) - n->param[i].seed = n->all.seed; - else - n->param[i].seed = 123457; - if (n->all.strength) - n->param[i].strength = n->all.strength; - if (n->all.flags) - n->param[i].flags = n->all.flags; - } - - for (i = 0; i < 4; i++) { - if (n->param[i].strength && ((ret = init_noise(n, i)) < 0)) - return ret; - } - - n->line_noise = line_noise_c; - n->line_noise_avg = line_noise_avg_c; - - if (HAVE_MMX_INLINE && - cpu_flags & AV_CPU_FLAG_MMX) { - n->line_noise = line_noise_mmx; - n->line_noise_avg = line_noise_avg_mmx; - } - if (HAVE_MMXEXT_INLINE && - cpu_flags & AV_CPU_FLAG_MMXEXT) - n->line_noise = line_noise_mmxext; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - NoiseContext *n = ctx->priv; - int i; - - for (i = 0; i < 4; i++) - av_freep(&n->param[i].noise); -} - -static const AVFilterPad noise_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad noise_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_noise = { - .name = "noise", - .description = NULL_IF_CONFIG_SMALL("Add noise."), - .priv_size = sizeof(NoiseContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = noise_inputs, - .outputs = noise_outputs, - .priv_class = &noise_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/vf_null.c b/ffmpeg/libavfilter/vf_null.c deleted file mode 100644 index 2355615..0000000 --- a/ffmpeg/libavfilter/vf_null.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * null video filter - */ - -#include "libavutil/internal.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -static const AVFilterPad avfilter_vf_null_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_null_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_null = { - .name = "null", - .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."), - .inputs = avfilter_vf_null_inputs, - .outputs = avfilter_vf_null_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_overlay.c b/ffmpeg/libavfilter/vf_overlay.c deleted file mode 100644 index 9047dee..0000000 --- a/ffmpeg/libavfilter/vf_overlay.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * Copyright (c) 2010 Baptiste Coudurier - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * overlay one video on top of another - */ - -#include "avfilter.h" -#include "formats.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/avstring.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "internal.h" -#include "dualinput.h" -#include "drawutils.h" -#include "video.h" - -static const char *const var_names[] = { - "main_w", "W", ///< width of the main video - "main_h", "H", ///< height of the main video - "overlay_w", "w", ///< width of the overlay video - "overlay_h", "h", ///< height of the overlay video - "hsub", - "vsub", - "x", - "y", - "n", ///< number of frame - "pos", ///< position in the file - "t", ///< timestamp expressed in seconds - NULL -}; - -enum var_name { - VAR_MAIN_W, VAR_MW, - VAR_MAIN_H, VAR_MH, - VAR_OVERLAY_W, VAR_OW, - VAR_OVERLAY_H, VAR_OH, - VAR_HSUB, - VAR_VSUB, - VAR_X, - VAR_Y, - VAR_N, - VAR_POS, - VAR_T, - VAR_VARS_NB -}; - -#define MAIN 0 -#define OVERLAY 1 - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -#define Y 0 -#define U 1 -#define V 2 - -typedef struct { - const AVClass *class; - int x, y; ///< position of overlayed picture - - int allow_packed_rgb; - uint8_t main_is_packed_rgb; - uint8_t main_rgba_map[4]; - uint8_t main_has_alpha; - uint8_t overlay_is_packed_rgb; - uint8_t overlay_rgba_map[4]; - uint8_t overlay_has_alpha; - enum OverlayFormat { OVERLAY_FORMAT_YUV420, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_NB} format; - enum EvalMode { EVAL_MODE_INIT, EVAL_MODE_FRAME, EVAL_MODE_NB } eval_mode; - - FFDualInputContext dinput; - - int main_pix_step[4]; ///< steps per pixel for each plane of the main output - int overlay_pix_step[4]; ///< steps per pixel for each plane of the overlay - int hsub, vsub; ///< chroma subsampling values - - double var_values[VAR_VARS_NB]; - char *x_expr, *y_expr; - AVExpr *x_pexpr, *y_pexpr; -} OverlayContext; - -static av_cold void uninit(AVFilterContext *ctx) -{ - OverlayContext *s = ctx->priv; - - ff_dualinput_uninit(&s->dinput); - av_expr_free(s->x_pexpr); s->x_pexpr = NULL; - av_expr_free(s->y_pexpr); s->y_pexpr = NULL; -} - -static inline int normalize_xy(double d, int chroma_sub) -{ - if (isnan(d)) - return INT_MAX; - return (int)d & ~((1 << chroma_sub) - 1); -} - -static void eval_expr(AVFilterContext *ctx) -{ - OverlayContext *s = ctx->priv; - - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); - s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL); - s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL); - s->x = normalize_xy(s->var_values[VAR_X], s->hsub); - s->y = normalize_xy(s->var_values[VAR_Y], s->vsub); -} - -static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) -{ - int ret; - AVExpr *old = NULL; - - if (*pexpr) - old = *pexpr; - ret = av_expr_parse(pexpr, expr, var_names, - NULL, NULL, NULL, NULL, 0, log_ctx); - if (ret < 0) { - av_log(log_ctx, AV_LOG_ERROR, - "Error when evaluating the expression '%s' for %s\n", - expr, option); - *pexpr = old; - return ret; - } - - av_expr_free(old); - return 0; -} - -static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, - char *res, int res_len, int flags) -{ - OverlayContext *s = ctx->priv; - int ret; - - if (!strcmp(cmd, "x")) - ret = set_expr(&s->x_pexpr, args, cmd, ctx); - else if (!strcmp(cmd, "y")) - ret = set_expr(&s->y_pexpr, args, cmd, ctx); - else - ret = AVERROR(ENOSYS); - - if (ret < 0) - return ret; - - if (s->eval_mode == EVAL_MODE_INIT) { - eval_expr(ctx); - av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n", - s->var_values[VAR_X], s->x, - s->var_values[VAR_Y], s->y); - } - return ret; -} - -static int query_formats(AVFilterContext *ctx) -{ - OverlayContext *s = ctx->priv; - - /* overlay formats contains alpha, for avoiding conversion with alpha information loss */ - static const enum AVPixelFormat main_pix_fmts_yuv420[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat overlay_pix_fmts_yuv420[] = { - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE - }; - - static const enum AVPixelFormat main_pix_fmts_yuv444[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat overlay_pix_fmts_yuv444[] = { - AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE - }; - - static const enum AVPixelFormat main_pix_fmts_rgb[] = { - AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, - AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_NONE - }; - static const enum AVPixelFormat overlay_pix_fmts_rgb[] = { - AV_PIX_FMT_ARGB, AV_PIX_FMT_RGBA, - AV_PIX_FMT_ABGR, AV_PIX_FMT_BGRA, - AV_PIX_FMT_NONE - }; - - AVFilterFormats *main_formats; - AVFilterFormats *overlay_formats; - - switch (s->format) { - case OVERLAY_FORMAT_YUV420: - main_formats = ff_make_format_list(main_pix_fmts_yuv420); - overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420); - break; - case OVERLAY_FORMAT_YUV444: - main_formats = ff_make_format_list(main_pix_fmts_yuv444); - overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444); - break; - case OVERLAY_FORMAT_RGB: - main_formats = ff_make_format_list(main_pix_fmts_rgb); - overlay_formats = ff_make_format_list(overlay_pix_fmts_rgb); - break; - default: - av_assert0(0); - } - - ff_formats_ref(main_formats, &ctx->inputs [MAIN ]->out_formats); - ff_formats_ref(overlay_formats, &ctx->inputs [OVERLAY]->out_formats); - ff_formats_ref(main_formats, &ctx->outputs[MAIN ]->in_formats ); - - return 0; -} - -static const enum AVPixelFormat alpha_pix_fmts[] = { - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA, - AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE -}; - -static int config_input_main(AVFilterLink *inlink) -{ - OverlayContext *s = inlink->dst->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - - av_image_fill_max_pixsteps(s->main_pix_step, NULL, pix_desc); - - s->hsub = pix_desc->log2_chroma_w; - s->vsub = pix_desc->log2_chroma_h; - - s->main_is_packed_rgb = - ff_fill_rgba_map(s->main_rgba_map, inlink->format) >= 0; - s->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts); - return 0; -} - -static int config_input_overlay(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - OverlayContext *s = inlink->dst->priv; - int ret; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format); - - av_image_fill_max_pixsteps(s->overlay_pix_step, NULL, pix_desc); - - /* Finish the configuration by evaluating the expressions - now when both inputs are configured. */ - s->var_values[VAR_MAIN_W ] = s->var_values[VAR_MW] = ctx->inputs[MAIN ]->w; - s->var_values[VAR_MAIN_H ] = s->var_values[VAR_MH] = ctx->inputs[MAIN ]->h; - s->var_values[VAR_OVERLAY_W] = s->var_values[VAR_OW] = ctx->inputs[OVERLAY]->w; - s->var_values[VAR_OVERLAY_H] = s->var_values[VAR_OH] = ctx->inputs[OVERLAY]->h; - s->var_values[VAR_HSUB] = 1<<pix_desc->log2_chroma_w; - s->var_values[VAR_VSUB] = 1<<pix_desc->log2_chroma_h; - s->var_values[VAR_X] = NAN; - s->var_values[VAR_Y] = NAN; - s->var_values[VAR_N] = 0; - s->var_values[VAR_T] = NAN; - s->var_values[VAR_POS] = NAN; - - if ((ret = set_expr(&s->x_pexpr, s->x_expr, "x", ctx)) < 0 || - (ret = set_expr(&s->y_pexpr, s->y_expr, "y", ctx)) < 0) - return ret; - - s->overlay_is_packed_rgb = - ff_fill_rgba_map(s->overlay_rgba_map, inlink->format) >= 0; - s->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts); - - if (s->eval_mode == EVAL_MODE_INIT) { - eval_expr(ctx); - av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n", - s->var_values[VAR_X], s->x, - s->var_values[VAR_Y], s->y); - } - - av_log(ctx, AV_LOG_VERBOSE, - "main w:%d h:%d fmt:%s overlay w:%d h:%d fmt:%s\n", - ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h, - av_get_pix_fmt_name(ctx->inputs[MAIN]->format), - ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h, - av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format)); - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - OverlayContext *s = ctx->priv; - int ret; - - if ((ret = ff_dualinput_init(ctx, &s->dinput)) < 0) - return ret; - - outlink->w = ctx->inputs[MAIN]->w; - outlink->h = ctx->inputs[MAIN]->h; - outlink->time_base = ctx->inputs[MAIN]->time_base; - - return 0; -} - -// divide by 255 and round to nearest -// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16 -#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16) - -// calculate the unpremultiplied alpha, applying the general equation: -// alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) ) -// (((x) << 16) - ((x) << 9) + (x)) is a faster version of: 255 * 255 * x -// ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)) is a faster version of: 255 * (x + y) -#define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x))) - -/** - * Blend image in src to destination buffer dst at position (x, y). - */ -static void blend_image(AVFilterContext *ctx, - AVFrame *dst, const AVFrame *src, - int x, int y) -{ - OverlayContext *s = ctx->priv; - int i, imax, j, jmax, k, kmax; - const int src_w = src->width; - const int src_h = src->height; - const int dst_w = dst->width; - const int dst_h = dst->height; - - if (x >= dst_w || x+src_w < 0 || - y >= dst_h || y+src_h < 0) - return; /* no intersection */ - - if (s->main_is_packed_rgb) { - uint8_t alpha; ///< the amount of overlay to blend on to main - const int dr = s->main_rgba_map[R]; - const int dg = s->main_rgba_map[G]; - const int db = s->main_rgba_map[B]; - const int da = s->main_rgba_map[A]; - const int dstep = s->main_pix_step[0]; - const int sr = s->overlay_rgba_map[R]; - const int sg = s->overlay_rgba_map[G]; - const int sb = s->overlay_rgba_map[B]; - const int sa = s->overlay_rgba_map[A]; - const int sstep = s->overlay_pix_step[0]; - const int main_has_alpha = s->main_has_alpha; - uint8_t *s, *sp, *d, *dp; - - i = FFMAX(-y, 0); - sp = src->data[0] + i * src->linesize[0]; - dp = dst->data[0] + (y+i) * dst->linesize[0]; - - for (imax = FFMIN(-y + dst_h, src_h); i < imax; i++) { - j = FFMAX(-x, 0); - s = sp + j * sstep; - d = dp + (x+j) * dstep; - - for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { - alpha = s[sa]; - - // if the main channel has an alpha channel, alpha has to be calculated - // to create an un-premultiplied (straight) alpha value - if (main_has_alpha && alpha != 0 && alpha != 255) { - uint8_t alpha_d = d[da]; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - - switch (alpha) { - case 0: - break; - case 255: - d[dr] = s[sr]; - d[dg] = s[sg]; - d[db] = s[sb]; - break; - default: - // main_value = main_value * (1 - alpha) + overlay_value * alpha - // since alpha is in the range 0-255, the result must divided by 255 - d[dr] = FAST_DIV255(d[dr] * (255 - alpha) + s[sr] * alpha); - d[dg] = FAST_DIV255(d[dg] * (255 - alpha) + s[sg] * alpha); - d[db] = FAST_DIV255(d[db] * (255 - alpha) + s[sb] * alpha); - } - if (main_has_alpha) { - switch (alpha) { - case 0: - break; - case 255: - d[da] = s[sa]; - break; - default: - // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha - d[da] += FAST_DIV255((255 - d[da]) * s[sa]); - } - } - d += dstep; - s += sstep; - } - dp += dst->linesize[0]; - sp += src->linesize[0]; - } - } else { - const int main_has_alpha = s->main_has_alpha; - if (main_has_alpha) { - uint8_t alpha; ///< the amount of overlay to blend on to main - uint8_t *s, *sa, *d, *da; - - i = FFMAX(-y, 0); - sa = src->data[3] + i * src->linesize[3]; - da = dst->data[3] + (y+i) * dst->linesize[3]; - - for (imax = FFMIN(-y + dst_h, src_h); i < imax; i++) { - j = FFMAX(-x, 0); - s = sa + j; - d = da + x+j; - - for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { - alpha = *s; - if (alpha != 0 && alpha != 255) { - uint8_t alpha_d = *d; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - switch (alpha) { - case 0: - break; - case 255: - *d = *s; - break; - default: - // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha - *d += FAST_DIV255((255 - *d) * *s); - } - d += 1; - s += 1; - } - da += dst->linesize[3]; - sa += src->linesize[3]; - } - } - for (i = 0; i < 3; i++) { - int hsub = i ? s->hsub : 0; - int vsub = i ? s->vsub : 0; - int src_wp = FF_CEIL_RSHIFT(src_w, hsub); - int src_hp = FF_CEIL_RSHIFT(src_h, vsub); - int dst_wp = FF_CEIL_RSHIFT(dst_w, hsub); - int dst_hp = FF_CEIL_RSHIFT(dst_h, vsub); - int yp = y>>vsub; - int xp = x>>hsub; - uint8_t *s, *sp, *d, *dp, *a, *ap; - - j = FFMAX(-yp, 0); - sp = src->data[i] + j * src->linesize[i]; - dp = dst->data[i] + (yp+j) * dst->linesize[i]; - ap = src->data[3] + (j<<vsub) * src->linesize[3]; - - for (jmax = FFMIN(-yp + dst_hp, src_hp); j < jmax; j++) { - k = FFMAX(-xp, 0); - d = dp + xp+k; - s = sp + k; - a = ap + (k<<hsub); - - for (kmax = FFMIN(-xp + dst_wp, src_wp); k < kmax; k++) { - int alpha_v, alpha_h, alpha; - - // average alpha for color components, improve quality - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha = (a[0] + a[src->linesize[3]] + - a[1] + a[src->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (a[0] + a[1]) >> 1 : a[0]; - alpha_v = vsub && j+1 < src_hp ? - (a[0] + a[src->linesize[3]]) >> 1 : a[0]; - alpha = (alpha_v + alpha_h) >> 1; - } else - alpha = a[0]; - // if the main channel has an alpha channel, alpha has to be calculated - // to create an un-premultiplied (straight) alpha value - if (main_has_alpha && alpha != 0 && alpha != 255) { - // average alpha for color components, improve quality - uint8_t alpha_d; - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha_d = (d[0] + d[src->linesize[3]] + - d[1] + d[src->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (d[0] + d[1]) >> 1 : d[0]; - alpha_v = vsub && j+1 < src_hp ? - (d[0] + d[src->linesize[3]]) >> 1 : d[0]; - alpha_d = (alpha_v + alpha_h) >> 1; - } else - alpha_d = d[0]; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); - s++; - d++; - a += 1 << hsub; - } - dp += dst->linesize[i]; - sp += src->linesize[i]; - ap += (1 << vsub) * src->linesize[3]; - } - } - } -} - -static AVFrame *do_blend(AVFilterContext *ctx, AVFrame *mainpic, - const AVFrame *second) -{ - OverlayContext *s = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - - /* TODO: reindent */ - if (s->eval_mode == EVAL_MODE_FRAME) { - int64_t pos = av_frame_get_pkt_pos(mainpic); - - s->var_values[VAR_N] = inlink->frame_count; - s->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ? - NAN : mainpic->pts * av_q2d(inlink->time_base); - s->var_values[VAR_POS] = pos == -1 ? NAN : pos; - - eval_expr(ctx); - av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n", - s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS], - s->var_values[VAR_X], s->x, - s->var_values[VAR_Y], s->y); - } - - blend_image(ctx, mainpic, second, s->x, s->y); - return mainpic; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - OverlayContext *s = inlink->dst->priv; - return ff_dualinput_filter_frame(&s->dinput, inlink, inpicref); -} - -static int request_frame(AVFilterLink *outlink) -{ - OverlayContext *s = outlink->src->priv; - return ff_dualinput_request_frame(&s->dinput, outlink); -} - -static av_cold int init(AVFilterContext *ctx) -{ - OverlayContext *s = ctx->priv; - - if (s->allow_packed_rgb) { - av_log(ctx, AV_LOG_WARNING, - "The rgb option is deprecated and is overriding the format option, use format instead\n"); - s->format = OVERLAY_FORMAT_RGB; - } - s->dinput.process = do_blend; - return 0; -} - -#define OFFSET(x) offsetof(OverlayContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption overlay_options[] = { - { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, - { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, - { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, - { "rgb", "force packed RGB in input and output (deprecated)", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, - { "shortest", "force termination when the shortest input terminates", OFFSET(dinput.shortest), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, - { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, - { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, - { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" }, - { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, - { "repeatlast", "repeat overlay of the last overlay frame", OFFSET(dinput.repeatlast), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(overlay); - -static const AVFilterPad avfilter_vf_overlay_inputs[] = { - { - .name = "main", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input_main, - .filter_frame = filter_frame, - .needs_writable = 1, - }, - { - .name = "overlay", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input_overlay, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_overlay_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_overlay = { - .name = "overlay", - .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."), - .init = init, - .uninit = uninit, - .priv_size = sizeof(OverlayContext), - .priv_class = &overlay_class, - .query_formats = query_formats, - .process_command = process_command, - .inputs = avfilter_vf_overlay_inputs, - .outputs = avfilter_vf_overlay_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, -}; diff --git a/ffmpeg/libavfilter/vf_pad.c b/ffmpeg/libavfilter/vf_pad.c deleted file mode 100644 index 2962e20..0000000 --- a/ffmpeg/libavfilter/vf_pad.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2008 vmrsss - * Copyright (c) 2009 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video padding filter - */ - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include "libavutil/eval.h" -#include "libavutil/pixdesc.h" -#include "libavutil/colorspace.h" -#include "libavutil/avassert.h" -#include "libavutil/imgutils.h" -#include "libavutil/parseutils.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" - -#include "drawutils.h" - -static const char *const var_names[] = { - "in_w", "iw", - "in_h", "ih", - "out_w", "ow", - "out_h", "oh", - "x", - "y", - "a", - "sar", - "dar", - "hsub", - "vsub", - NULL -}; - -enum var_name { - VAR_IN_W, VAR_IW, - VAR_IN_H, VAR_IH, - VAR_OUT_W, VAR_OW, - VAR_OUT_H, VAR_OH, - VAR_X, - VAR_Y, - VAR_A, - VAR_SAR, - VAR_DAR, - VAR_HSUB, - VAR_VSUB, - VARS_NB -}; - -static int query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -typedef struct { - const AVClass *class; - int w, h; ///< output dimensions, a value of 0 will result in the input size - int x, y; ///< offsets of the input area with respect to the padded area - int in_w, in_h; ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues - - char *w_expr; ///< width expression string - char *h_expr; ///< height expression string - char *x_expr; ///< width expression string - char *y_expr; ///< height expression string - uint8_t rgba_color[4]; ///< color for the padding area - FFDrawContext draw; - FFDrawColor color; -} PadContext; - -static int config_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - PadContext *s = ctx->priv; - int ret; - double var_values[VARS_NB], res; - char *expr; - - ff_draw_init(&s->draw, inlink->format, 0); - ff_draw_color(&s->draw, &s->color, s->rgba_color); - - var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; - var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; - var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; - var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; - var_values[VAR_A] = (double) inlink->w / inlink->h; - var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; - var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; - var_values[VAR_HSUB] = 1 << s->draw.hsub_max; - var_values[VAR_VSUB] = 1 << s->draw.vsub_max; - - /* evaluate width and height */ - av_expr_parse_and_eval(&res, (expr = s->w_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx); - s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; - if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto eval_fail; - s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; - /* evaluate the width again, as it may depend on the evaluated output height */ - if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto eval_fail; - s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; - - /* evaluate x and y */ - av_expr_parse_and_eval(&res, (expr = s->x_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx); - s->x = var_values[VAR_X] = res; - if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto eval_fail; - s->y = var_values[VAR_Y] = res; - /* evaluate x again, as it may depend on the evaluated y value */ - if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto eval_fail; - s->x = var_values[VAR_X] = res; - - /* sanity check params */ - if (s->w < 0 || s->h < 0 || s->x < 0 || s->y < 0) { - av_log(ctx, AV_LOG_ERROR, "Negative values are not acceptable.\n"); - return AVERROR(EINVAL); - } - - if (!s->w) - s->w = inlink->w; - if (!s->h) - s->h = inlink->h; - - s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w); - s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h); - s->x = ff_draw_round_to_sub(&s->draw, 0, -1, s->x); - s->y = ff_draw_round_to_sub(&s->draw, 1, -1, s->y); - s->in_w = ff_draw_round_to_sub(&s->draw, 0, -1, inlink->w); - s->in_h = ff_draw_round_to_sub(&s->draw, 1, -1, inlink->h); - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n", - inlink->w, inlink->h, s->w, s->h, s->x, s->y, - s->rgba_color[0], s->rgba_color[1], s->rgba_color[2], s->rgba_color[3]); - - if (s->x < 0 || s->y < 0 || - s->w <= 0 || s->h <= 0 || - (unsigned)s->x + (unsigned)inlink->w > s->w || - (unsigned)s->y + (unsigned)inlink->h > s->h) { - av_log(ctx, AV_LOG_ERROR, - "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n", - s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h); - return AVERROR(EINVAL); - } - - return 0; - -eval_fail: - av_log(NULL, AV_LOG_ERROR, - "Error when evaluating the expression '%s'\n", expr); - return ret; - -} - -static int config_output(AVFilterLink *outlink) -{ - PadContext *s = outlink->src->priv; - - outlink->w = s->w; - outlink->h = s->h; - return 0; -} - -static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h) -{ - PadContext *s = inlink->dst->priv; - - AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0], - w + (s->w - s->in_w), - h + (s->h - s->in_h)); - int plane; - - if (!frame) - return NULL; - - frame->width = w; - frame->height = h; - - for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) { - int hsub = s->draw.hsub[plane]; - int vsub = s->draw.vsub[plane]; - frame->data[plane] += (s->x >> hsub) * s->draw.pixelstep[plane] + - (s->y >> vsub) * frame->linesize[plane]; - } - - return frame; -} - -/* check whether each plane in this buffer can be padded without copying */ -static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf) -{ - int planes[4] = { -1, -1, -1, -1}, *p = planes; - int i, j; - - /* get all planes in this buffer */ - for (i = 0; i < FF_ARRAY_ELEMS(planes) && frame->data[i]; i++) { - if (av_frame_get_plane_buffer(frame, i) == buf) - *p++ = i; - } - - /* for each plane in this buffer, check that it can be padded without - * going over buffer bounds or other planes */ - for (i = 0; i < FF_ARRAY_ELEMS(planes) && planes[i] >= 0; i++) { - int hsub = s->draw.hsub[planes[i]]; - int vsub = s->draw.vsub[planes[i]]; - - uint8_t *start = frame->data[planes[i]]; - uint8_t *end = start + (frame->height >> vsub) * - frame->linesize[planes[i]]; - - /* amount of free space needed before the start and after the end - * of the plane */ - ptrdiff_t req_start = (s->x >> hsub) * s->draw.pixelstep[planes[i]] + - (s->y >> vsub) * frame->linesize[planes[i]]; - ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) * - s->draw.pixelstep[planes[i]] + - ((s->h - s->y - frame->height) >> vsub) * frame->linesize[planes[i]]; - - if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]]) - return 1; - if (start - buf->data < req_start || - (buf->data + buf->size) - end < req_end) - return 1; - - for (j = 0; j < FF_ARRAY_ELEMS(planes) && planes[j] >= 0; j++) { - int vsub1 = s->draw.vsub[planes[j]]; - uint8_t *start1 = frame->data[planes[j]]; - uint8_t *end1 = start1 + (frame->height >> vsub1) * - frame->linesize[planes[j]]; - if (i == j) - continue; - - if (FFSIGN(start - end1) != FFSIGN(start - end1 - req_start) || - FFSIGN(end - start1) != FFSIGN(end - start1 + req_end)) - return 1; - } - } - - return 0; -} - -static int frame_needs_copy(PadContext *s, AVFrame *frame) -{ - int i; - - if (!av_frame_is_writable(frame)) - return 1; - - for (i = 0; i < 4 && frame->buf[i]; i++) - if (buffer_needs_copy(s, frame, frame->buf[i])) - return 1; - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - PadContext *s = inlink->dst->priv; - AVFrame *out; - int needs_copy = frame_needs_copy(s, in); - - if (needs_copy) { - av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n"); - out = ff_get_video_buffer(inlink->dst->outputs[0], - FFMAX(inlink->w, s->w), - FFMAX(inlink->h, s->h)); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - av_frame_copy_props(out, in); - } else { - int i; - - out = in; - for (i = 0; i < 4 && out->data[i] && out->linesize[i]; i++) { - int hsub = s->draw.hsub[i]; - int vsub = s->draw.vsub[i]; - out->data[i] -= (s->x >> hsub) * s->draw.pixelstep[i] + - (s->y >> vsub) * out->linesize[i]; - } - } - - /* top bar */ - if (s->y) { - ff_fill_rectangle(&s->draw, &s->color, - out->data, out->linesize, - 0, 0, s->w, s->y); - } - - /* bottom bar */ - if (s->h > s->y + s->in_h) { - ff_fill_rectangle(&s->draw, &s->color, - out->data, out->linesize, - 0, s->y + s->in_h, s->w, s->h - s->y - s->in_h); - } - - /* left border */ - ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize, - 0, s->y, s->x, in->height); - - if (needs_copy) { - ff_copy_rectangle2(&s->draw, - out->data, out->linesize, in->data, in->linesize, - s->x, s->y, 0, 0, in->width, in->height); - } - - /* right border */ - ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize, - s->x + s->in_w, s->y, s->w - s->x - s->in_w, - in->height); - - out->width = s->w; - out->height = s->h; - - if (in != out) - av_frame_free(&in); - return ff_filter_frame(inlink->dst->outputs[0], out); -} - -#define OFFSET(x) offsetof(PadContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption pad_options[] = { - { "width", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set the pad area width expression", OFFSET(w_expr), AV_OPT_TYPE_STRING, {.str = "iw"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "height", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set the pad area height expression", OFFSET(h_expr), AV_OPT_TYPE_STRING, {.str = "ih"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "x", "set the x offset expression for the input image position", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set the y offset expression for the input image position", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "color", "set the color of the padded area border", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(pad); - -static const AVFilterPad avfilter_vf_pad_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .get_video_buffer = get_video_buffer, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_pad_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_pad = { - .name = "pad", - .description = NULL_IF_CONFIG_SMALL("Pad the input video."), - .priv_size = sizeof(PadContext), - .priv_class = &pad_class, - .query_formats = query_formats, - .inputs = avfilter_vf_pad_inputs, - .outputs = avfilter_vf_pad_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_pixdesctest.c b/ffmpeg/libavfilter/vf_pixdesctest.c deleted file mode 100644 index 54ddf89..0000000 --- a/ffmpeg/libavfilter/vf_pixdesctest.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2009 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * pixdesc test filter - */ - -#include "libavutil/common.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVPixFmtDescriptor *pix_desc; - uint16_t *line; -} PixdescTestContext; - -static av_cold void uninit(AVFilterContext *ctx) -{ - PixdescTestContext *priv = ctx->priv; - av_freep(&priv->line); -} - -static int config_props(AVFilterLink *inlink) -{ - PixdescTestContext *priv = inlink->dst->priv; - - priv->pix_desc = av_pix_fmt_desc_get(inlink->format); - - av_freep(&priv->line); - if (!(priv->line = av_malloc(sizeof(*priv->line) * inlink->w))) - return AVERROR(ENOMEM); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - PixdescTestContext *priv = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; - int i, c, w = inlink->w, h = inlink->h; - const int cw = FF_CEIL_RSHIFT(w, priv->pix_desc->log2_chroma_w); - const int ch = FF_CEIL_RSHIFT(h, priv->pix_desc->log2_chroma_h); - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - av_frame_copy_props(out, in); - - for (i = 0; i < 4; i++) { - const int h1 = i == 1 || i == 2 ? ch : h; - if (out->data[i]) { - uint8_t *data = out->data[i] + - (out->linesize[i] > 0 ? 0 : out->linesize[i] * (h1-1)); - memset(data, 0, FFABS(out->linesize[i]) * h1); - } - } - - /* copy palette */ - if (priv->pix_desc->flags & AV_PIX_FMT_FLAG_PAL || - priv->pix_desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) - memcpy(out->data[1], in->data[1], AVPALETTE_SIZE); - - for (c = 0; c < priv->pix_desc->nb_components; c++) { - const int w1 = c == 1 || c == 2 ? cw : w; - const int h1 = c == 1 || c == 2 ? ch : h; - - for (i = 0; i < h1; i++) { - av_read_image_line(priv->line, - (void*)in->data, - in->linesize, - priv->pix_desc, - 0, i, c, w1, 0); - - av_write_image_line(priv->line, - out->data, - out->linesize, - priv->pix_desc, - 0, i, c, w1); - } - } - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVFilterPad avfilter_vf_pixdesctest_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_pixdesctest_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_pixdesctest = { - .name = "pixdesctest", - .description = NULL_IF_CONFIG_SMALL("Test pixel format definitions."), - .priv_size = sizeof(PixdescTestContext), - .uninit = uninit, - .inputs = avfilter_vf_pixdesctest_inputs, - .outputs = avfilter_vf_pixdesctest_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_pp.c b/ffmpeg/libavfilter/vf_pp.c deleted file mode 100644 index c72fdc6..0000000 --- a/ffmpeg/libavfilter/vf_pp.c +++ /dev/null @@ -1,186 +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/opt.h" -#include "internal.h" - -#include "libpostproc/postprocess.h" - -typedef struct { - 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 int pp_query_formats(AVFilterContext *ctx) -{ - static const enum PixelFormat 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_YUV444P, AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -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_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_YUVJ444P: - case AV_PIX_FMT_YUV444P: flags |= PP_FORMAT_444; 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, qp_type; - int8_t *qp_table ; - - 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; - qp_table = av_frame_get_qp_table(inbuf, &qstride, &qp_type); - - 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_type ? PP_PICT_TYPE_QP2 : 0)); - - av_frame_free(&inbuf); - 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, - }, - { NULL } -}; - -static const AVFilterPad pp_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_pp = { - .name = "pp", - .description = NULL_IF_CONFIG_SMALL("Filter video using libpostproc."), - .priv_size = sizeof(PPFilterContext), - .init = pp_init, - .uninit = pp_uninit, - .query_formats = pp_query_formats, - .inputs = pp_inputs, - .outputs = pp_outputs, - .process_command = pp_process_command, - .priv_class = &pp_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_removelogo.c b/ffmpeg/libavfilter/vf_removelogo.c deleted file mode 100644 index 01a585c..0000000 --- a/ffmpeg/libavfilter/vf_removelogo.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net> - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Advanced blur-based logo removing filter - * - * This filter loads an image mask file showing where a logo is and - * uses a blur transform to remove the logo. - * - * Based on the libmpcodecs remove-logo filter by Robert Edele. - */ - -/** - * This code implements a filter to remove annoying TV logos and other annoying - * images placed onto a video stream. It works by filling in the pixels that - * comprise the logo with neighboring pixels. The transform is very loosely - * based on a gaussian blur, but it is different enough to merit its own - * paragraph later on. It is a major improvement on the old delogo filter as it - * both uses a better blurring algorithm and uses a bitmap to use an arbitrary - * and generally much tighter fitting shape than a rectangle. - * - * The logo removal algorithm has two key points. The first is that it - * distinguishes between pixels in the logo and those not in the logo by using - * the passed-in bitmap. Pixels not in the logo are copied over directly without - * being modified and they also serve as source pixels for the logo - * fill-in. Pixels inside the logo have the mask applied. - * - * At init-time the bitmap is reprocessed internally, and the distance to the - * nearest edge of the logo (Manhattan distance), along with a little extra to - * remove rough edges, is stored in each pixel. This is done using an in-place - * erosion algorithm, and incrementing each pixel that survives any given - * erosion. Once every pixel is eroded, the maximum value is recorded, and a - * set of masks from size 0 to this size are generaged. The masks are circular - * binary masks, where each pixel within a radius N (where N is the size of the - * mask) is a 1, and all other pixels are a 0. Although a gaussian mask would be - * more mathematically accurate, a binary mask works better in practice because - * we generally do not use the central pixels in the mask (because they are in - * the logo region), and thus a gaussian mask will cause too little blur and - * thus a very unstable image. - * - * The mask is applied in a special way. Namely, only pixels in the mask that - * line up to pixels outside the logo are used. The dynamic mask size means that - * the mask is just big enough so that the edges touch pixels outside the logo, - * so the blurring is kept to a minimum and at least the first boundary - * condition is met (that the image function itself is continuous), even if the - * second boundary condition (that the derivative of the image function is - * continuous) is not met. A masking algorithm that does preserve the second - * boundary coundition (perhaps something based on a highly-modified bi-cubic - * algorithm) should offer even better results on paper, but the noise in a - * typical TV signal should make anything based on derivatives hopelessly noisy. - */ - -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "bbox.h" -#include "lavfutils.h" -#include "lswsutils.h" - -typedef struct { - const AVClass *class; - char *filename; - /* Stores our collection of masks. The first is for an array of - the second for the y axis, and the third for the x axis. */ - int ***mask; - int max_mask_size; - int mask_w, mask_h; - - uint8_t *full_mask_data; - FFBoundingBox full_mask_bbox; - uint8_t *half_mask_data; - FFBoundingBox half_mask_bbox; -} RemovelogoContext; - -#define OFFSET(x) offsetof(RemovelogoContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption removelogo_options[] = { - { "filename", "set bitmap filename", OFFSET(filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { "f", "set bitmap filename", OFFSET(filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(removelogo); - -/** - * Choose a slightly larger mask size to improve performance. - * - * This function maps the absolute minimum mask size needed to the - * mask size we'll actually use. f(x) = x (the smallest that will - * work) will produce the sharpest results, but will be quite - * jittery. f(x) = 1.25x (what I'm using) is a good tradeoff in my - * opinion. This will calculate only at init-time, so you can put a - * long expression here without effecting performance. - */ -#define apply_mask_fudge_factor(x) (((x) >> 2) + x) - -/** - * Pre-process an image to give distance information. - * - * This function takes a bitmap image and converts it in place into a - * distance image. A distance image is zero for pixels outside of the - * logo and is the Manhattan distance (|dx| + |dy|) from the logo edge - * for pixels inside of the logo. This will overestimate the distance, - * but that is safe, and is far easier to implement than a proper - * pythagorean distance since I'm using a modified erosion algorithm - * to compute the distances. - * - * @param mask image which will be converted from a greyscale image - * into a distance image. - */ -static void convert_mask_to_strength_mask(uint8_t *data, int linesize, - int w, int h, int min_val, - int *max_mask_size) -{ - int x, y; - - /* How many times we've gone through the loop. Used in the - in-place erosion algorithm and to get us max_mask_size later on. */ - int current_pass = 0; - - /* set all non-zero values to 1 */ - for (y = 0; y < h; y++) - for (x = 0; x < w; x++) - data[y*linesize + x] = data[y*linesize + x] > min_val; - - /* For each pass, if a pixel is itself the same value as the - current pass, and its four neighbors are too, then it is - incremented. If no pixels are incremented by the end of the - pass, then we go again. Edge pixels are counted as always - excluded (this should be true anyway for any sane mask, but if - it isn't this will ensure that we eventually exit). */ - while (1) { - /* If this doesn't get set by the end of this pass, then we're done. */ - int has_anything_changed = 0; - uint8_t *current_pixel0 = data + 1 + linesize, *current_pixel; - current_pass++; - - for (y = 1; y < h-1; y++) { - current_pixel = current_pixel0; - for (x = 1; x < w-1; x++) { - /* Apply the in-place erosion transform. It is based - on the following two premises: - 1 - Any pixel that fails 1 erosion will fail all - future erosions. - - 2 - Only pixels having survived all erosions up to - the present will be >= to current_pass. - It doesn't matter if it survived the current pass, - failed it, or hasn't been tested yet. By using >= - instead of ==, we allow the algorithm to work in - place. */ - if ( *current_pixel >= current_pass && - *(current_pixel + 1) >= current_pass && - *(current_pixel - 1) >= current_pass && - *(current_pixel + linesize) >= current_pass && - *(current_pixel - linesize) >= current_pass) { - /* Increment the value since it still has not been - * eroded, as evidenced by the if statement that - * just evaluated to true. */ - (*current_pixel)++; - has_anything_changed = 1; - } - current_pixel++; - } - current_pixel0 += linesize; - } - if (!has_anything_changed) - break; - } - - /* Apply the fudge factor, which will increase the size of the - * mask a little to reduce jitter at the cost of more blur. */ - for (y = 1; y < h - 1; y++) - for (x = 1; x < w - 1; x++) - data[(y * linesize) + x] = apply_mask_fudge_factor(data[(y * linesize) + x]); - - /* As a side-effect, we now know the maximum mask size, which - * we'll use to generate our masks. */ - /* Apply the fudge factor to this number too, since we must ensure - * that enough masks are generated. */ - *max_mask_size = apply_mask_fudge_factor(current_pass + 1); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int load_mask(uint8_t **mask, int *w, int *h, - const char *filename, void *log_ctx) -{ - int ret; - enum AVPixelFormat pix_fmt; - uint8_t *src_data[4], *gray_data[4]; - int src_linesize[4], gray_linesize[4]; - - /* load image from file */ - if ((ret = ff_load_image(src_data, src_linesize, w, h, &pix_fmt, filename, log_ctx)) < 0) - return ret; - - /* convert the image to GRAY8 */ - if ((ret = ff_scale_image(gray_data, gray_linesize, *w, *h, AV_PIX_FMT_GRAY8, - src_data, src_linesize, *w, *h, pix_fmt, - log_ctx)) < 0) - goto end; - - /* copy mask to a newly allocated array */ - *mask = av_malloc(*w * *h); - if (!*mask) - ret = AVERROR(ENOMEM); - av_image_copy_plane(*mask, *w, gray_data[0], gray_linesize[0], *w, *h); - -end: - av_freep(&src_data[0]); - av_freep(&gray_data[0]); - return ret; -} - -/** - * Generate a scaled down image with half width, height, and intensity. - * - * This function not only scales down an image, but halves the value - * in each pixel too. The purpose of this is to produce a chroma - * filter image out of a luma filter image. The pixel values store the - * distance to the edge of the logo and halving the dimensions halves - * the distance. This function rounds up, because a downwards rounding - * error could cause the filter to fail, but an upwards rounding error - * will only cause a minor amount of excess blur in the chroma planes. - */ -static void generate_half_size_image(const uint8_t *src_data, int src_linesize, - uint8_t *dst_data, int dst_linesize, - int src_w, int src_h, - int *max_mask_size) -{ - int x, y; - - /* Copy over the image data, using the average of 4 pixels for to - * calculate each downsampled pixel. */ - for (y = 0; y < src_h/2; y++) { - for (x = 0; x < src_w/2; x++) { - /* Set the pixel if there exists a non-zero value in the - * source pixels, else clear it. */ - dst_data[(y * dst_linesize) + x] = - src_data[((y << 1) * src_linesize) + (x << 1)] || - src_data[((y << 1) * src_linesize) + (x << 1) + 1] || - src_data[(((y << 1) + 1) * src_linesize) + (x << 1)] || - src_data[(((y << 1) + 1) * src_linesize) + (x << 1) + 1]; - dst_data[(y * dst_linesize) + x] = FFMIN(1, dst_data[(y * dst_linesize) + x]); - } - } - - convert_mask_to_strength_mask(dst_data, dst_linesize, - src_w/2, src_h/2, 0, max_mask_size); -} - -static av_cold int init(AVFilterContext *ctx) -{ - RemovelogoContext *s = ctx->priv; - int ***mask; - int ret = 0; - int a, b, c, w, h; - int full_max_mask_size, half_max_mask_size; - - if (!s->filename) { - av_log(ctx, AV_LOG_ERROR, "The bitmap file name is mandatory\n"); - return AVERROR(EINVAL); - } - - /* Load our mask image. */ - if ((ret = load_mask(&s->full_mask_data, &w, &h, s->filename, ctx)) < 0) - return ret; - s->mask_w = w; - s->mask_h = h; - - convert_mask_to_strength_mask(s->full_mask_data, w, w, h, - 16, &full_max_mask_size); - - /* Create the scaled down mask image for the chroma planes. */ - if (!(s->half_mask_data = av_mallocz(w/2 * h/2))) - return AVERROR(ENOMEM); - generate_half_size_image(s->full_mask_data, w, - s->half_mask_data, w/2, - w, h, &half_max_mask_size); - - s->max_mask_size = FFMAX(full_max_mask_size, half_max_mask_size); - - /* Create a circular mask for each size up to max_mask_size. When - the filter is applied, the mask size is determined on a pixel - by pixel basis, with pixels nearer the edge of the logo getting - smaller mask sizes. */ - mask = (int ***)av_malloc(sizeof(int **) * (s->max_mask_size + 1)); - if (!mask) - return AVERROR(ENOMEM); - - for (a = 0; a <= s->max_mask_size; a++) { - mask[a] = (int **)av_malloc(sizeof(int *) * ((a * 2) + 1)); - if (!mask[a]) - return AVERROR(ENOMEM); - for (b = -a; b <= a; b++) { - mask[a][b + a] = (int *)av_malloc(sizeof(int) * ((a * 2) + 1)); - if (!mask[a][b + a]) - return AVERROR(ENOMEM); - for (c = -a; c <= a; c++) { - if ((b * b) + (c * c) <= (a * a)) /* Circular 0/1 mask. */ - mask[a][b + a][c + a] = 1; - else - mask[a][b + a][c + a] = 0; - } - } - } - s->mask = mask; - - /* Calculate our bounding rectangles, which determine in what - * region the logo resides for faster processing. */ - ff_calculate_bounding_box(&s->full_mask_bbox, s->full_mask_data, w, w, h, 0); - ff_calculate_bounding_box(&s->half_mask_bbox, s->half_mask_data, w/2, w/2, h/2, 0); - -#define SHOW_LOGO_INFO(mask_type) \ - av_log(ctx, AV_LOG_VERBOSE, #mask_type " x1:%d x2:%d y1:%d y2:%d max_mask_size:%d\n", \ - s->mask_type##_mask_bbox.x1, s->mask_type##_mask_bbox.x2, \ - s->mask_type##_mask_bbox.y1, s->mask_type##_mask_bbox.y2, \ - mask_type##_max_mask_size); - SHOW_LOGO_INFO(full); - SHOW_LOGO_INFO(half); - - return 0; -} - -static int config_props_input(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - RemovelogoContext *s = ctx->priv; - - if (inlink->w != s->mask_w || inlink->h != s->mask_h) { - av_log(ctx, AV_LOG_INFO, - "Mask image size %dx%d does not match with the input video size %dx%d\n", - s->mask_w, s->mask_h, inlink->w, inlink->h); - return AVERROR(EINVAL); - } - - return 0; -} - -/** - * Blur image. - * - * It takes a pixel that is inside the mask and blurs it. It does so - * by finding the average of all the pixels within the mask and - * outside of the mask. - * - * @param mask_data the mask plane to use for averaging - * @param image_data the image plane to blur - * @param w width of the image - * @param h height of the image - * @param x x-coordinate of the pixel to blur - * @param y y-coordinate of the pixel to blur - */ -static unsigned int blur_pixel(int ***mask, - const uint8_t *mask_data, int mask_linesize, - uint8_t *image_data, int image_linesize, - int w, int h, int x, int y) -{ - /* Mask size tells how large a circle to use. The radius is about - * (slightly larger than) mask size. */ - int mask_size; - int start_posx, start_posy, end_posx, end_posy; - int i, j; - unsigned int accumulator = 0, divisor = 0; - /* What pixel we are reading out of the circular blur mask. */ - const uint8_t *image_read_position; - /* What pixel we are reading out of the filter image. */ - const uint8_t *mask_read_position; - - /* Prepare our bounding rectangle and clip it if need be. */ - mask_size = mask_data[y * mask_linesize + x]; - start_posx = FFMAX(0, x - mask_size); - start_posy = FFMAX(0, y - mask_size); - end_posx = FFMIN(w - 1, x + mask_size); - end_posy = FFMIN(h - 1, y + mask_size); - - image_read_position = image_data + image_linesize * start_posy + start_posx; - mask_read_position = mask_data + mask_linesize * start_posy + start_posx; - - for (j = start_posy; j <= end_posy; j++) { - for (i = start_posx; i <= end_posx; i++) { - /* Check if this pixel is in the mask or not. Only use the - * pixel if it is not. */ - if (!(*mask_read_position) && mask[mask_size][i - start_posx][j - start_posy]) { - accumulator += *image_read_position; - divisor++; - } - - image_read_position++; - mask_read_position++; - } - - image_read_position += (image_linesize - ((end_posx + 1) - start_posx)); - mask_read_position += (mask_linesize - ((end_posx + 1) - start_posx)); - } - - /* If divisor is 0, it means that not a single pixel is outside of - the logo, so we have no data. Else we need to normalise the - data using the divisor. */ - return divisor == 0 ? 255: - (accumulator + (divisor / 2)) / divisor; /* divide, taking into account average rounding error */ -} - -/** - * Blur image plane using a mask. - * - * @param source The image to have it's logo removed. - * @param destination Where the output image will be stored. - * @param source_stride How far apart (in memory) two consecutive lines are. - * @param destination Same as source_stride, but for the destination image. - * @param width Width of the image. This is the same for source and destination. - * @param height Height of the image. This is the same for source and destination. - * @param is_image_direct If the image is direct, then source and destination are - * the same and we can save a lot of time by not copying pixels that - * haven't changed. - * @param filter The image that stores the distance to the edge of the logo for - * each pixel. - * @param logo_start_x smallest x-coordinate that contains at least 1 logo pixel. - * @param logo_start_y smallest y-coordinate that contains at least 1 logo pixel. - * @param logo_end_x largest x-coordinate that contains at least 1 logo pixel. - * @param logo_end_y largest y-coordinate that contains at least 1 logo pixel. - * - * This function processes an entire plane. Pixels outside of the logo are copied - * to the output without change, and pixels inside the logo have the de-blurring - * function applied. - */ -static void blur_image(int ***mask, - const uint8_t *src_data, int src_linesize, - uint8_t *dst_data, int dst_linesize, - const uint8_t *mask_data, int mask_linesize, - int w, int h, int direct, - FFBoundingBox *bbox) -{ - int x, y; - uint8_t *dst_line; - const uint8_t *src_line; - - if (!direct) - av_image_copy_plane(dst_data, dst_linesize, src_data, src_linesize, w, h); - - for (y = bbox->y1; y <= bbox->y2; y++) { - src_line = src_data + src_linesize * y; - dst_line = dst_data + dst_linesize * y; - - for (x = bbox->x1; x <= bbox->x2; x++) { - if (mask_data[y * mask_linesize + x]) { - /* Only process if we are in the mask. */ - dst_line[x] = blur_pixel(mask, - mask_data, mask_linesize, - dst_data, dst_linesize, - w, h, x, y); - } else { - /* Else just copy the data. */ - if (!direct) - dst_line[x] = src_line[x]; - } - } - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - RemovelogoContext *s = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpicref; - int direct = 0; - - if (av_frame_is_writable(inpicref)) { - direct = 1; - outpicref = inpicref; - } else { - outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) { - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpicref, inpicref); - } - - blur_image(s->mask, - inpicref ->data[0], inpicref ->linesize[0], - outpicref->data[0], outpicref->linesize[0], - s->full_mask_data, inlink->w, - inlink->w, inlink->h, direct, &s->full_mask_bbox); - blur_image(s->mask, - inpicref ->data[1], inpicref ->linesize[1], - outpicref->data[1], outpicref->linesize[1], - s->half_mask_data, inlink->w/2, - inlink->w/2, inlink->h/2, direct, &s->half_mask_bbox); - blur_image(s->mask, - inpicref ->data[2], inpicref ->linesize[2], - outpicref->data[2], outpicref->linesize[2], - s->half_mask_data, inlink->w/2, - inlink->w/2, inlink->h/2, direct, &s->half_mask_bbox); - - if (!direct) - av_frame_free(&inpicref); - - return ff_filter_frame(outlink, outpicref); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - RemovelogoContext *s = ctx->priv; - int a, b; - - av_freep(&s->full_mask_data); - av_freep(&s->half_mask_data); - - if (s->mask) { - /* Loop through each mask. */ - for (a = 0; a <= s->max_mask_size; a++) { - /* Loop through each scanline in a mask. */ - for (b = -a; b <= a; b++) { - av_freep(&s->mask[a][b + a]); /* Free a scanline. */ - } - av_freep(&s->mask[a]); - } - /* Free the array of pointers pointing to the masks. */ - av_freep(&s->mask); - } -} - -static const AVFilterPad removelogo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad removelogo_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_removelogo = { - .name = "removelogo", - .description = NULL_IF_CONFIG_SMALL("Remove a TV logo based on a mask image."), - .priv_size = sizeof(RemovelogoContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = removelogo_inputs, - .outputs = removelogo_outputs, - .priv_class = &removelogo_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_scale.c b/ffmpeg/libavfilter/vf_scale.c deleted file mode 100644 index 2e692cf..0000000 --- a/ffmpeg/libavfilter/vf_scale.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * scale video filter - */ - -#include <stdio.h> -#include <string.h> - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/avstring.h" -#include "libavutil/eval.h" -#include "libavutil/internal.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/avassert.h" -#include "libswscale/swscale.h" - -static const char *const var_names[] = { - "in_w", "iw", - "in_h", "ih", - "out_w", "ow", - "out_h", "oh", - "a", - "sar", - "dar", - "hsub", - "vsub", - "ohsub", - "ovsub", - NULL -}; - -enum var_name { - VAR_IN_W, VAR_IW, - VAR_IN_H, VAR_IH, - VAR_OUT_W, VAR_OW, - VAR_OUT_H, VAR_OH, - VAR_A, - VAR_SAR, - VAR_DAR, - VAR_HSUB, - VAR_VSUB, - VAR_OHSUB, - VAR_OVSUB, - VARS_NB -}; - -typedef struct { - const AVClass *class; - struct SwsContext *sws; ///< software scaler context - struct SwsContext *isws[2]; ///< software scaler context for interlaced material - AVDictionary *opts; - - /** - * New dimensions. Special values are: - * 0 = original width/height - * -1 = keep original aspect - */ - int w, h; - char *size_str; - unsigned int flags; ///sws flags - - int hsub, vsub; ///< chroma subsampling - int slice_y; ///< top of current output slice - int input_is_pal; ///< set to 1 if the input format is paletted - int output_is_pal; ///< set to 1 if the output format is paletted - int interlaced; - - char *w_expr; ///< width expression string - char *h_expr; ///< height expression string - char *flags_str; - - char *in_color_matrix; - char *out_color_matrix; - - int in_range; - int out_range; - - int out_h_chr_pos; - int out_v_chr_pos; - int in_h_chr_pos; - int in_v_chr_pos; - - int force_original_aspect_ratio; -} ScaleContext; - -static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts) -{ - ScaleContext *scale = ctx->priv; - int ret; - - if (scale->size_str && (scale->w_expr || scale->h_expr)) { - av_log(ctx, AV_LOG_ERROR, - "Size and width/height expressions cannot be set at the same time.\n"); - return AVERROR(EINVAL); - } - - if (scale->w_expr && !scale->h_expr) - FFSWAP(char *, scale->w_expr, scale->size_str); - - if (scale->size_str) { - char buf[32]; - if ((ret = av_parse_video_size(&scale->w, &scale->h, scale->size_str)) < 0) { - av_log(ctx, AV_LOG_ERROR, - "Invalid size '%s'\n", scale->size_str); - return ret; - } - snprintf(buf, sizeof(buf)-1, "%d", scale->w); - av_opt_set(scale, "w", buf, 0); - snprintf(buf, sizeof(buf)-1, "%d", scale->h); - av_opt_set(scale, "h", buf, 0); - } - if (!scale->w_expr) - av_opt_set(scale, "w", "iw", 0); - if (!scale->h_expr) - av_opt_set(scale, "h", "ih", 0); - - av_log(ctx, AV_LOG_VERBOSE, "w:%s h:%s flags:'%s' interl:%d\n", - scale->w_expr, scale->h_expr, (char *)av_x_if_null(scale->flags_str, ""), scale->interlaced); - - scale->flags = 0; - - if (scale->flags_str) { - const AVClass *class = sws_get_class(); - const AVOption *o = av_opt_find(&class, "sws_flags", NULL, 0, - AV_OPT_SEARCH_FAKE_OBJ); - int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags); - if (ret < 0) - return ret; - } - scale->opts = *opts; - *opts = NULL; - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - ScaleContext *scale = ctx->priv; - sws_freeContext(scale->sws); - sws_freeContext(scale->isws[0]); - sws_freeContext(scale->isws[1]); - scale->sws = NULL; - av_dict_free(&scale->opts); -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats; - enum AVPixelFormat pix_fmt; - int ret; - - if (ctx->inputs[0]) { - formats = NULL; - for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) - if ((sws_isSupportedInput(pix_fmt) || - sws_isSupportedEndiannessConversion(pix_fmt)) - && (ret = ff_add_format(&formats, pix_fmt)) < 0) { - ff_formats_unref(&formats); - return ret; - } - ff_formats_ref(formats, &ctx->inputs[0]->out_formats); - } - if (ctx->outputs[0]) { - formats = NULL; - for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) - if ((sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8 || - sws_isSupportedEndiannessConversion(pix_fmt)) - && (ret = ff_add_format(&formats, pix_fmt)) < 0) { - ff_formats_unref(&formats); - return ret; - } - ff_formats_ref(formats, &ctx->outputs[0]->in_formats); - } - - return 0; -} - -static const int *parse_yuv_type(const char *s, enum AVColorSpace colorspace) -{ - if (!s) - s = "bt601"; - - if (s && strstr(s, "bt709")) { - colorspace = AVCOL_SPC_BT709; - } else if (s && strstr(s, "fcc")) { - colorspace = AVCOL_SPC_FCC; - } else if (s && strstr(s, "smpte240m")) { - colorspace = AVCOL_SPC_SMPTE240M; - } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) { - colorspace = AVCOL_SPC_BT470BG; - } - - if (colorspace < 1 || colorspace > 7) { - colorspace = AVCOL_SPC_BT470BG; - } - - return sws_getCoefficients(colorspace); -} - -static int config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = outlink->src->inputs[0]; - enum AVPixelFormat outfmt = outlink->format; - ScaleContext *scale = ctx->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - const AVPixFmtDescriptor *out_desc = av_pix_fmt_desc_get(outlink->format); - int64_t w, h; - double var_values[VARS_NB], res; - char *expr; - int ret; - - var_values[VAR_IN_W] = var_values[VAR_IW] = inlink->w; - var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; - var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; - var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; - var_values[VAR_A] = (double) inlink->w / inlink->h; - var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; - var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; - var_values[VAR_HSUB] = 1 << desc->log2_chroma_w; - var_values[VAR_VSUB] = 1 << desc->log2_chroma_h; - var_values[VAR_OHSUB] = 1 << out_desc->log2_chroma_w; - var_values[VAR_OVSUB] = 1 << out_desc->log2_chroma_h; - - /* evaluate width and height */ - av_expr_parse_and_eval(&res, (expr = scale->w_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx); - scale->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res; - if ((ret = av_expr_parse_and_eval(&res, (expr = scale->h_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto fail; - scale->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res; - /* evaluate again the width, as it may depend on the output height */ - if ((ret = av_expr_parse_and_eval(&res, (expr = scale->w_expr), - var_names, var_values, - NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) - goto fail; - scale->w = res; - - w = scale->w; - h = scale->h; - - /* sanity check params */ - if (w < -1 || h < -1) { - av_log(ctx, AV_LOG_ERROR, "Size values less than -1 are not acceptable.\n"); - return AVERROR(EINVAL); - } - if (w == -1 && h == -1) - scale->w = scale->h = 0; - - if (!(w = scale->w)) - w = inlink->w; - if (!(h = scale->h)) - h = inlink->h; - if (w == -1) - w = av_rescale(h, inlink->w, inlink->h); - if (h == -1) - h = av_rescale(w, inlink->h, inlink->w); - - if (scale->force_original_aspect_ratio) { - int tmp_w = av_rescale(h, inlink->w, inlink->h); - int tmp_h = av_rescale(w, inlink->h, inlink->w); - - if (scale->force_original_aspect_ratio == 1) { - w = FFMIN(tmp_w, w); - h = FFMIN(tmp_h, h); - } else { - w = FFMAX(tmp_w, w); - h = FFMAX(tmp_h, h); - } - } - - if (w > INT_MAX || h > INT_MAX || - (h * inlink->w) > INT_MAX || - (w * inlink->h) > INT_MAX) - av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); - - outlink->w = w; - outlink->h = h; - - /* TODO: make algorithm configurable */ - - scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL; - if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8; - scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PAL || - av_pix_fmt_desc_get(outfmt)->flags & AV_PIX_FMT_FLAG_PSEUDOPAL; - - if (scale->sws) - sws_freeContext(scale->sws); - if (scale->isws[0]) - sws_freeContext(scale->isws[0]); - if (scale->isws[1]) - sws_freeContext(scale->isws[1]); - scale->isws[0] = scale->isws[1] = scale->sws = NULL; - if (inlink->w == outlink->w && inlink->h == outlink->h && - inlink->format == outlink->format) - ; - else { - struct SwsContext **swscs[3] = {&scale->sws, &scale->isws[0], &scale->isws[1]}; - int i; - - for (i = 0; i < 3; i++) { - struct SwsContext **s = swscs[i]; - *s = sws_alloc_context(); - if (!*s) - return AVERROR(ENOMEM); - - if (scale->opts) { - AVDictionaryEntry *e = NULL; - - while ((e = av_dict_get(scale->opts, "", e, AV_DICT_IGNORE_SUFFIX))) { - if ((ret = av_opt_set(*s, e->key, e->value, 0)) < 0) - return ret; - } - } - - av_opt_set_int(*s, "srcw", inlink ->w, 0); - av_opt_set_int(*s, "srch", inlink ->h >> !!i, 0); - av_opt_set_int(*s, "src_format", inlink->format, 0); - av_opt_set_int(*s, "dstw", outlink->w, 0); - av_opt_set_int(*s, "dsth", outlink->h >> !!i, 0); - av_opt_set_int(*s, "dst_format", outfmt, 0); - av_opt_set_int(*s, "sws_flags", scale->flags, 0); - - av_opt_set_int(*s, "src_h_chr_pos", scale->in_h_chr_pos, 0); - av_opt_set_int(*s, "src_v_chr_pos", scale->in_v_chr_pos, 0); - av_opt_set_int(*s, "dst_h_chr_pos", scale->out_h_chr_pos, 0); - av_opt_set_int(*s, "dst_v_chr_pos", scale->out_v_chr_pos, 0); - - if ((ret = sws_init_context(*s, NULL, NULL)) < 0) - return ret; - if (!scale->interlaced) - break; - } - } - - if (inlink->sample_aspect_ratio.num){ - outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); - } else - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d fmt:%s sar:%d/%d flags:0x%0x\n", - inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format), - inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den, - outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format), - outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den, - scale->flags); - return 0; - -fail: - av_log(NULL, AV_LOG_ERROR, - "Error when evaluating the expression '%s'.\n" - "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n", - expr, scale->w_expr, scale->h_expr); - return ret; -} - -static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, struct SwsContext *sws, int y, int h, int mul, int field) -{ - ScaleContext *scale = link->dst->priv; - const uint8_t *in[4]; - uint8_t *out[4]; - int in_stride[4],out_stride[4]; - int i; - - for(i=0; i<4; i++){ - int vsub= ((i+1)&2) ? scale->vsub : 0; - in_stride[i] = cur_pic->linesize[i] * mul; - out_stride[i] = out_buf->linesize[i] * mul; - in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i]; - out[i] = out_buf->data[i] + field * out_buf->linesize[i]; - } - if(scale->input_is_pal) - in[1] = cur_pic->data[1]; - if(scale->output_is_pal) - out[1] = out_buf->data[1]; - - return sws_scale(sws, in, in_stride, y/mul, h, - out,out_stride); -} - -static int filter_frame(AVFilterLink *link, AVFrame *in) -{ - ScaleContext *scale = link->dst->priv; - AVFilterLink *outlink = link->dst->outputs[0]; - AVFrame *out; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - char buf[32]; - int in_range; - - if( in->width != link->w - || in->height != link->h - || in->format != link->format) { - int ret; - snprintf(buf, sizeof(buf)-1, "%d", outlink->w); - av_opt_set(scale, "w", buf, 0); - snprintf(buf, sizeof(buf)-1, "%d", outlink->h); - av_opt_set(scale, "h", buf, 0); - - link->dst->inputs[0]->format = in->format; - link->dst->inputs[0]->w = in->width; - link->dst->inputs[0]->h = in->height; - - if ((ret = config_props(outlink)) < 0) - return ret; - } - - if (!scale->sws) - return ff_filter_frame(outlink, in); - - scale->hsub = desc->log2_chroma_w; - scale->vsub = desc->log2_chroma_h; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - - av_frame_copy_props(out, in); - out->width = outlink->w; - out->height = outlink->h; - - if(scale->output_is_pal) - avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); - - in_range = av_frame_get_color_range(in); - - if ( scale->in_color_matrix - || scale->out_color_matrix - || scale-> in_range != AVCOL_RANGE_UNSPECIFIED - || in_range != AVCOL_RANGE_UNSPECIFIED - || scale->out_range != AVCOL_RANGE_UNSPECIFIED) { - int in_full, out_full, brightness, contrast, saturation; - const int *inv_table, *table; - - sws_getColorspaceDetails(scale->sws, (int **)&inv_table, &in_full, - (int **)&table, &out_full, - &brightness, &contrast, &saturation); - - if (scale->in_color_matrix) - inv_table = parse_yuv_type(scale->in_color_matrix, av_frame_get_colorspace(in)); - if (scale->out_color_matrix) - table = parse_yuv_type(scale->out_color_matrix, AVCOL_SPC_UNSPECIFIED); - - if (scale-> in_range != AVCOL_RANGE_UNSPECIFIED) - in_full = (scale-> in_range == AVCOL_RANGE_JPEG); - else if (in_range != AVCOL_RANGE_UNSPECIFIED) - in_full = (in_range == AVCOL_RANGE_JPEG); - if (scale->out_range != AVCOL_RANGE_UNSPECIFIED) - out_full = (scale->out_range == AVCOL_RANGE_JPEG); - - sws_setColorspaceDetails(scale->sws, inv_table, in_full, - table, out_full, - brightness, contrast, saturation); - if (scale->isws[0]) - sws_setColorspaceDetails(scale->isws[0], inv_table, in_full, - table, out_full, - brightness, contrast, saturation); - if (scale->isws[1]) - sws_setColorspaceDetails(scale->isws[1], inv_table, in_full, - table, out_full, - brightness, contrast, saturation); - } - - av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den, - (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w, - (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h, - INT_MAX); - - if(scale->interlaced>0 || (scale->interlaced<0 && in->interlaced_frame)){ - scale_slice(link, out, in, scale->isws[0], 0, (link->h+1)/2, 2, 0); - scale_slice(link, out, in, scale->isws[1], 0, link->h /2, 2, 1); - }else{ - scale_slice(link, out, in, scale->sws, 0, link->h, 1, 0); - } - - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -static const AVClass *child_class_next(const AVClass *prev) -{ - return prev ? NULL : sws_get_class(); -} - -#define OFFSET(x) offsetof(ScaleContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption scale_options[] = { - { "w", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "width", "Output video width", OFFSET(w_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "h", "Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "height","Output video height", OFFSET(h_expr), AV_OPT_TYPE_STRING, .flags = FLAGS }, - { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "bilinear" }, .flags = FLAGS }, - { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS }, - { "size", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS }, - { "s", "set video size", OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS }, - { "in_color_matrix", "set input YCbCr type", OFFSET(in_color_matrix), AV_OPT_TYPE_STRING, { .str = "auto" }, .flags = FLAGS }, - { "out_color_matrix", "set output YCbCr type", OFFSET(out_color_matrix), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, - { "in_range", "set input color range", OFFSET( in_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" }, - { "out_range", "set output color range", OFFSET(out_range), AV_OPT_TYPE_INT, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 2, FLAGS, "range" }, - { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_UNSPECIFIED }, 0, 0, FLAGS, "range" }, - { "full", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" }, - { "jpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" }, - { "mpeg", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" }, - { "tv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_MPEG}, 0, 0, FLAGS, "range" }, - { "pc", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AVCOL_RANGE_JPEG}, 0, 0, FLAGS, "range" }, - { "in_v_chr_pos", "input vertical chroma position in luma grid/256" , OFFSET(in_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS }, - { "in_h_chr_pos", "input horizontal chroma position in luma grid/256", OFFSET(in_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS }, - { "out_v_chr_pos", "output vertical chroma position in luma grid/256" , OFFSET(out_v_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS }, - { "out_h_chr_pos", "output horizontal chroma position in luma grid/256", OFFSET(out_h_chr_pos), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 512, FLAGS }, - { "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, - { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, - { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, - { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, - { NULL } -}; - -static const AVClass scale_class = { - .class_name = "scale", - .item_name = av_default_item_name, - .option = scale_options, - .version = LIBAVUTIL_VERSION_INT, - .child_class_next = child_class_next, -}; - -static const AVFilterPad avfilter_vf_scale_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_scale_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vf_scale = { - .name = "scale", - .description = NULL_IF_CONFIG_SMALL("Scale the input video size and/or convert the image format."), - .init_dict = init_dict, - .uninit = uninit, - .query_formats = query_formats, - .priv_size = sizeof(ScaleContext), - .priv_class = &scale_class, - .inputs = avfilter_vf_scale_inputs, - .outputs = avfilter_vf_scale_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_setfield.c b/ffmpeg/libavfilter/vf_setfield.c deleted file mode 100644 index eb4df74..0000000 --- a/ffmpeg/libavfilter/vf_setfield.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2012 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * set field order - */ - -#include "libavutil/opt.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -enum SetFieldMode { - MODE_AUTO = -1, - MODE_BFF, - MODE_TFF, - MODE_PROG, -}; - -typedef struct { - const AVClass *class; - enum SetFieldMode mode; -} SetFieldContext; - -#define OFFSET(x) offsetof(SetFieldContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption setfield_options[] = { - {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_AUTO}, -1, MODE_PROG, FLAGS, "mode"}, - {"auto", "keep the same input field", 0, AV_OPT_TYPE_CONST, {.i64=MODE_AUTO}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"bff", "mark as bottom-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BFF}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"tff", "mark as top-field-first", 0, AV_OPT_TYPE_CONST, {.i64=MODE_TFF}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"prog", "mark as progressive", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PROG}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {NULL} -}; - -AVFILTER_DEFINE_CLASS(setfield); - -static int filter_frame(AVFilterLink *inlink, AVFrame *picref) -{ - SetFieldContext *setfield = inlink->dst->priv; - - if (setfield->mode == MODE_PROG) { - picref->interlaced_frame = 0; - } else if (setfield->mode != MODE_AUTO) { - picref->interlaced_frame = 1; - picref->top_field_first = setfield->mode; - } - return ff_filter_frame(inlink->dst->outputs[0], picref); -} - -static const AVFilterPad setfield_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad setfield_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_setfield = { - .name = "setfield", - .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."), - .priv_size = sizeof(SetFieldContext), - .priv_class = &setfield_class, - .inputs = setfield_inputs, - .outputs = setfield_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_showinfo.c b/ffmpeg/libavfilter/vf_showinfo.c deleted file mode 100644 index ade3e1a..0000000 --- a/ffmpeg/libavfilter/vf_showinfo.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * filter for showing textual video frame information - */ - -#include "libavutil/adler32.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/pixdesc.h" -#include "libavutil/timestamp.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - AVFilterContext *ctx = inlink->dst; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - uint32_t plane_checksum[4] = {0}, checksum = 0; - int i, plane, vsub = desc->log2_chroma_h; - - for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) { - int64_t linesize = av_image_get_linesize(frame->format, frame->width, plane); - uint8_t *data = frame->data[plane]; - int h = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h; - - if (linesize < 0) - return linesize; - - for (i = 0; i < h; i++) { - plane_checksum[plane] = av_adler32_update(plane_checksum[plane], data, linesize); - checksum = av_adler32_update(checksum, data, linesize); - data += frame->linesize[plane]; - } - } - - av_log(ctx, AV_LOG_INFO, - "n:%"PRId64" pts:%s pts_time:%s pos:%"PRId64" " - "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c " - "checksum:%08X plane_checksum:[%08X", - inlink->frame_count, - av_ts2str(frame->pts), av_ts2timestr(frame->pts, &inlink->time_base), av_frame_get_pkt_pos(frame), - desc->name, - frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den, - frame->width, frame->height, - !frame->interlaced_frame ? 'P' : /* Progressive */ - frame->top_field_first ? 'T' : 'B', /* Top / Bottom */ - frame->key_frame, - av_get_picture_type_char(frame->pict_type), - checksum, plane_checksum[0]); - - for (plane = 1; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) - av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]); - av_log(ctx, AV_LOG_INFO, "]\n"); - - return ff_filter_frame(inlink->dst->outputs[0], frame); -} - -static const AVFilterPad avfilter_vf_showinfo_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_showinfo_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO - }, - { NULL } -}; - -AVFilter ff_vf_showinfo = { - .name = "showinfo", - .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."), - .inputs = avfilter_vf_showinfo_inputs, - .outputs = avfilter_vf_showinfo_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_smartblur.c b/ffmpeg/libavfilter/vf_smartblur.c deleted file mode 100644 index 114ac6f..0000000 --- a/ffmpeg/libavfilter/vf_smartblur.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at> - * Copyright (c) 2012 Jeremy Tran - * - * 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 - * Apply a smartblur filter to the input video - * Ported from MPlayer libmpcodecs/vf_smartblur.c by Michael Niedermayer. - */ - -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libswscale/swscale.h" - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" - -#define RADIUS_MIN 0.1 -#define RADIUS_MAX 5.0 - -#define STRENGTH_MIN -1.0 -#define STRENGTH_MAX 1.0 - -#define THRESHOLD_MIN -30 -#define THRESHOLD_MAX 30 - -typedef struct { - float radius; - float strength; - int threshold; - float quality; - struct SwsContext *filter_context; -} FilterParam; - -typedef struct { - const AVClass *class; - FilterParam luma; - FilterParam chroma; - int hsub; - int vsub; - unsigned int sws_flags; -} SmartblurContext; - -#define OFFSET(x) offsetof(SmartblurContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption smartblur_options[] = { - { "luma_radius", "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS }, - { "lr" , "set luma radius", OFFSET(luma.radius), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, RADIUS_MIN, RADIUS_MAX, .flags=FLAGS }, - { "luma_strength", "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS }, - { "ls", "set luma strength", OFFSET(luma.strength), AV_OPT_TYPE_FLOAT, {.dbl=1.0}, STRENGTH_MIN, STRENGTH_MAX, .flags=FLAGS }, - { "luma_threshold", "set luma threshold", OFFSET(luma.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS }, - { "lt", "set luma threshold", OFFSET(luma.threshold), AV_OPT_TYPE_INT, {.i64=0}, THRESHOLD_MIN, THRESHOLD_MAX, .flags=FLAGS }, - - { "chroma_radius", "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, - { "cr", "set chroma radius", OFFSET(chroma.radius), AV_OPT_TYPE_FLOAT, {.dbl=RADIUS_MIN-1}, RADIUS_MIN-1, RADIUS_MAX, .flags=FLAGS }, - { "chroma_strength", "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, - { "cs", "set chroma strength", OFFSET(chroma.strength), AV_OPT_TYPE_FLOAT, {.dbl=STRENGTH_MIN-1}, STRENGTH_MIN-1, STRENGTH_MAX, .flags=FLAGS }, - { "chroma_threshold", "set chroma threshold", OFFSET(chroma.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS }, - { "ct", "set chroma threshold", OFFSET(chroma.threshold), AV_OPT_TYPE_INT, {.i64=THRESHOLD_MIN-1}, THRESHOLD_MIN-1, THRESHOLD_MAX, .flags=FLAGS }, - - { NULL } -}; - -AVFILTER_DEFINE_CLASS(smartblur); - -static av_cold int init(AVFilterContext *ctx) -{ - SmartblurContext *sblur = ctx->priv; - - /* make chroma default to luma values, if not explicitly set */ - if (sblur->chroma.radius < RADIUS_MIN) - sblur->chroma.radius = sblur->luma.radius; - if (sblur->chroma.strength < STRENGTH_MIN) - sblur->chroma.strength = sblur->luma.strength; - if (sblur->chroma.threshold < THRESHOLD_MIN) - sblur->chroma.threshold = sblur->luma.threshold; - - sblur->luma.quality = sblur->chroma.quality = 3.0; - sblur->sws_flags = SWS_BICUBIC; - - av_log(ctx, AV_LOG_VERBOSE, - "luma_radius:%f luma_strength:%f luma_threshold:%d " - "chroma_radius:%f chroma_strength:%f chroma_threshold:%d\n", - sblur->luma.radius, sblur->luma.strength, sblur->luma.threshold, - sblur->chroma.radius, sblur->chroma.strength, sblur->chroma.threshold); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - SmartblurContext *sblur = ctx->priv; - - sws_freeContext(sblur->luma.filter_context); - sws_freeContext(sblur->chroma.filter_context); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int alloc_sws_context(FilterParam *f, int width, int height, unsigned int flags) -{ - SwsVector *vec; - SwsFilter sws_filter; - - vec = sws_getGaussianVec(f->radius, f->quality); - - if (!vec) - return AVERROR(EINVAL); - - sws_scaleVec(vec, f->strength); - vec->coeff[vec->length / 2] += 1.0 - f->strength; - sws_filter.lumH = sws_filter.lumV = vec; - sws_filter.chrH = sws_filter.chrV = NULL; - f->filter_context = sws_getCachedContext(NULL, - width, height, AV_PIX_FMT_GRAY8, - width, height, AV_PIX_FMT_GRAY8, - flags, &sws_filter, NULL, NULL); - - sws_freeVec(vec); - - if (!f->filter_context) - return AVERROR(EINVAL); - - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - SmartblurContext *sblur = inlink->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - - sblur->hsub = desc->log2_chroma_w; - sblur->vsub = desc->log2_chroma_h; - - alloc_sws_context(&sblur->luma, inlink->w, inlink->h, sblur->sws_flags); - alloc_sws_context(&sblur->chroma, - FF_CEIL_RSHIFT(inlink->w, sblur->hsub), - FF_CEIL_RSHIFT(inlink->h, sblur->vsub), - sblur->sws_flags); - - return 0; -} - -static void blur(uint8_t *dst, const int dst_linesize, - const uint8_t *src, const int src_linesize, - const int w, const int h, const int threshold, - struct SwsContext *filter_context) -{ - int x, y; - int orig, filtered; - int diff; - /* Declare arrays of 4 to get aligned data */ - const uint8_t* const src_array[4] = {src}; - uint8_t *dst_array[4] = {dst}; - int src_linesize_array[4] = {src_linesize}; - int dst_linesize_array[4] = {dst_linesize}; - - sws_scale(filter_context, src_array, src_linesize_array, - 0, h, dst_array, dst_linesize_array); - - if (threshold > 0) { - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - orig = src[x + y * src_linesize]; - filtered = dst[x + y * dst_linesize]; - diff = orig - filtered; - - if (diff > 0) { - if (diff > 2 * threshold) - dst[x + y * dst_linesize] = orig; - else if (diff > threshold) - /* add 'diff' and substract 'threshold' from 'filtered' */ - dst[x + y * dst_linesize] = orig - threshold; - } else { - if (-diff > 2 * threshold) - dst[x + y * dst_linesize] = orig; - else if (-diff > threshold) - /* add 'diff' and 'threshold' to 'filtered' */ - dst[x + y * dst_linesize] = orig + threshold; - } - } - } - } else if (threshold < 0) { - for (y = 0; y < h; ++y) { - for (x = 0; x < w; ++x) { - orig = src[x + y * src_linesize]; - filtered = dst[x + y * dst_linesize]; - diff = orig - filtered; - - if (diff > 0) { - if (diff <= -threshold) - dst[x + y * dst_linesize] = orig; - else if (diff <= -2 * threshold) - /* substract 'diff' and 'threshold' from 'orig' */ - dst[x + y * dst_linesize] = filtered - threshold; - } else { - if (diff >= threshold) - dst[x + y * dst_linesize] = orig; - else if (diff >= 2 * threshold) - /* add 'threshold' and substract 'diff' from 'orig' */ - dst[x + y * dst_linesize] = filtered + threshold; - } - } - } - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) -{ - SmartblurContext *sblur = inlink->dst->priv; - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpic; - int cw = FF_CEIL_RSHIFT(inlink->w, sblur->hsub); - int ch = FF_CEIL_RSHIFT(inlink->h, sblur->vsub); - - outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpic) { - av_frame_free(&inpic); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpic, inpic); - - blur(outpic->data[0], outpic->linesize[0], - inpic->data[0], inpic->linesize[0], - inlink->w, inlink->h, sblur->luma.threshold, - sblur->luma.filter_context); - - if (inpic->data[2]) { - blur(outpic->data[1], outpic->linesize[1], - inpic->data[1], inpic->linesize[1], - cw, ch, sblur->chroma.threshold, - sblur->chroma.filter_context); - blur(outpic->data[2], outpic->linesize[2], - inpic->data[2], inpic->linesize[2], - cw, ch, sblur->chroma.threshold, - sblur->chroma.filter_context); - } - - av_frame_free(&inpic); - return ff_filter_frame(outlink, outpic); -} - -static const AVFilterPad smartblur_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad smartblur_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_smartblur = { - .name = "smartblur", - .description = NULL_IF_CONFIG_SMALL("Blur the input video without impacting the outlines."), - .priv_size = sizeof(SmartblurContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = smartblur_inputs, - .outputs = smartblur_outputs, - .priv_class = &smartblur_class, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_stereo3d.c b/ffmpeg/libavfilter/vf_stereo3d.c deleted file mode 100644 index 2140120..0000000 --- a/ffmpeg/libavfilter/vf_stereo3d.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Copyright (c) 2010 Gordon Schmidt <gordon.schmidt <at> s2000.tu-chemnitz.de> - * Copyright (c) 2013 Paul B Mahol - * - * 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/avassert.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -enum StereoCode { - ANAGLYPH_RC_GRAY, // anaglyph red/cyan gray - ANAGLYPH_RC_HALF, // anaglyph red/cyan half colored - ANAGLYPH_RC_COLOR, // anaglyph red/cyan colored - ANAGLYPH_RC_DUBOIS, // anaglyph red/cyan dubois - ANAGLYPH_GM_GRAY, // anaglyph green/magenta gray - ANAGLYPH_GM_HALF, // anaglyph green/magenta half colored - ANAGLYPH_GM_COLOR, // anaglyph green/magenta colored - ANAGLYPH_GM_DUBOIS, // anaglyph green/magenta dubois - ANAGLYPH_YB_GRAY, // anaglyph yellow/blue gray - ANAGLYPH_YB_HALF, // anaglyph yellow/blue half colored - ANAGLYPH_YB_COLOR, // anaglyph yellow/blue colored - ANAGLYPH_YB_DUBOIS, // anaglyph yellow/blue dubois - ANAGLYPH_RB_GRAY, // anaglyph red/blue gray - ANAGLYPH_RG_GRAY, // anaglyph red/green gray - MONO_L, // mono output for debugging (left eye only) - MONO_R, // mono output for debugging (right eye only) - INTERLEAVE_ROWS_LR, // row-interleave (left eye has top row) - INTERLEAVE_ROWS_RL, // row-interleave (right eye has top row) - SIDE_BY_SIDE_LR, // side by side parallel (left eye left, right eye right) - SIDE_BY_SIDE_RL, // side by side crosseye (right eye left, left eye right) - SIDE_BY_SIDE_2_LR, // side by side parallel with half width resolution - SIDE_BY_SIDE_2_RL, // side by side crosseye with half width resolution - ABOVE_BELOW_LR, // above-below (left eye above, right eye below) - ABOVE_BELOW_RL, // above-below (right eye above, left eye below) - ABOVE_BELOW_2_LR, // above-below with half height resolution - ABOVE_BELOW_2_RL, // above-below with half height resolution - ALTERNATING_LR, // alternating frames (left eye first, right eye second) - ALTERNATING_RL, // alternating frames (right eye first, left eye second) - STEREO_CODE_COUNT // TODO: needs autodetection -}; - -typedef struct StereoComponent { - enum StereoCode format; - int width, height; - int off_left, off_right; - int off_lstep, off_rstep; - int row_left, row_right; -} StereoComponent; - -static const int ana_coeff[][3][6] = { - [ANAGLYPH_RB_GRAY] = - {{19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 19595, 38470, 7471}}, - [ANAGLYPH_RG_GRAY] = - {{19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 19595, 38470, 7471}, - { 0, 0, 0, 0, 0, 0}}, - [ANAGLYPH_RC_GRAY] = - {{19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 19595, 38470, 7471}, - { 0, 0, 0, 19595, 38470, 7471}}, - [ANAGLYPH_RC_HALF] = - {{19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 0, 65536, 0}, - { 0, 0, 0, 0, 0, 65536}}, - [ANAGLYPH_RC_COLOR] = - {{65536, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 65536, 0}, - { 0, 0, 0, 0, 0, 65536}}, - [ANAGLYPH_RC_DUBOIS] = - {{29891, 32800, 11559, -2849, -5763, -102}, - {-2627, -2479, -1033, 24804, 48080, -1209}, - { -997, -1350, -358, -4729, -7403, 80373}}, - [ANAGLYPH_GM_GRAY] = - {{ 0, 0, 0, 19595, 38470, 7471}, - {19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 19595, 38470, 7471}}, - [ANAGLYPH_GM_HALF] = - {{ 0, 0, 0, 65536, 0, 0}, - {19595, 38470, 7471, 0, 0, 0}, - { 0, 0, 0, 0, 0, 65536}}, - [ANAGLYPH_GM_COLOR] = - {{ 0, 0, 0, 65536, 0, 0}, - { 0, 65536, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 65536}}, - [ANAGLYPH_GM_DUBOIS] = - {{-4063,-10354, -2556, 34669, 46203, 1573}, - {18612, 43778, 9372, -1049, -983, -4260}, - { -983, -1769, 1376, 590, 4915, 61407}}, - [ANAGLYPH_YB_GRAY] = - {{ 0, 0, 0, 19595, 38470, 7471}, - { 0, 0, 0, 19595, 38470, 7471}, - {19595, 38470, 7471, 0, 0, 0}}, - [ANAGLYPH_YB_HALF] = - {{ 0, 0, 0, 65536, 0, 0}, - { 0, 0, 0, 0, 65536, 0}, - {19595, 38470, 7471, 0, 0, 0}}, - [ANAGLYPH_YB_COLOR] = - {{ 0, 0, 0, 65536, 0, 0}, - { 0, 0, 0, 0, 65536, 0}, - { 0, 0, 65536, 0, 0, 0}}, - [ANAGLYPH_YB_DUBOIS] = - {{65535,-12650,18451, -987, -7590, -1049}, - {-1604, 56032, 4196, 370, 3826, -1049}, - {-2345,-10676, 1358, 5801, 11416, 56217}}, -}; - -typedef struct Stereo3DContext { - const AVClass *class; - StereoComponent in, out; - int width, height; - int row_step; - const int *ana_matrix[3]; - int nb_planes; - int linesize[4]; - int pheight[4]; - int hsub, vsub; - int pixstep[4]; - AVFrame *prev; - double ts_unit; -} Stereo3DContext; - -#define OFFSET(x) offsetof(Stereo3DContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption stereo3d_options[] = { - { "in", "set input format", OFFSET(in.format), AV_OPT_TYPE_INT, {.i64=SIDE_BY_SIDE_LR}, SIDE_BY_SIDE_LR, STEREO_CODE_COUNT-1, FLAGS, "in"}, - { "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "in" }, - { "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "in" }, - { "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "in" }, - { "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "in" }, - { "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "in" }, - { "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "in" }, - { "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "in" }, - { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "in" }, - { "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "in" }, - { "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "in" }, - { "out", "set output format", OFFSET(out.format), AV_OPT_TYPE_INT, {.i64=ANAGLYPH_RC_DUBOIS}, 0, STEREO_CODE_COUNT-1, FLAGS, "out"}, - { "ab2l", "above below half height left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_LR}, 0, 0, FLAGS, "out" }, - { "ab2r", "above below half height right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_2_RL}, 0, 0, FLAGS, "out" }, - { "abl", "above below left first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_LR}, 0, 0, FLAGS, "out" }, - { "abr", "above below right first", 0, AV_OPT_TYPE_CONST, {.i64=ABOVE_BELOW_RL}, 0, 0, FLAGS, "out" }, - { "agmc", "anaglyph green magenta color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_COLOR}, 0, 0, FLAGS, "out" }, - { "agmd", "anaglyph green magenta dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_DUBOIS}, 0, 0, FLAGS, "out" }, - { "agmg", "anaglyph green magenta gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_GRAY}, 0, 0, FLAGS, "out" }, - { "agmh", "anaglyph green magenta half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_GM_HALF}, 0, 0, FLAGS, "out" }, - { "al", "alternating frames left first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_LR}, 0, 0, FLAGS, "out" }, - { "ar", "alternating frames right first", 0, AV_OPT_TYPE_CONST, {.i64=ALTERNATING_RL}, 0, 0, FLAGS, "out" }, - { "arbg", "anaglyph red blue gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RB_GRAY}, 0, 0, FLAGS, "out" }, - { "arcc", "anaglyph red cyan color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_COLOR}, 0, 0, FLAGS, "out" }, - { "arcd", "anaglyph red cyan dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_DUBOIS}, 0, 0, FLAGS, "out" }, - { "arcg", "anaglyph red cyan gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_GRAY}, 0, 0, FLAGS, "out" }, - { "arch", "anaglyph red cyan half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RC_HALF}, 0, 0, FLAGS, "out" }, - { "argg", "anaglyph red green gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_RG_GRAY}, 0, 0, FLAGS, "out" }, - { "aybc", "anaglyph yellow blue color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_COLOR}, 0, 0, FLAGS, "out" }, - { "aybd", "anaglyph yellow blue dubois", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_DUBOIS}, 0, 0, FLAGS, "out" }, - { "aybg", "anaglyph yellow blue gray", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_GRAY}, 0, 0, FLAGS, "out" }, - { "aybh", "anaglyph yellow blue half color", 0, AV_OPT_TYPE_CONST, {.i64=ANAGLYPH_YB_HALF}, 0, 0, FLAGS, "out" }, - { "irl", "interleave rows left first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_LR}, 0, 0, FLAGS, "out" }, - { "irr", "interleave rows right first", 0, AV_OPT_TYPE_CONST, {.i64=INTERLEAVE_ROWS_RL}, 0, 0, FLAGS, "out" }, - { "ml", "mono left", 0, AV_OPT_TYPE_CONST, {.i64=MONO_L}, 0, 0, FLAGS, "out" }, - { "mr", "mono right", 0, AV_OPT_TYPE_CONST, {.i64=MONO_R}, 0, 0, FLAGS, "out" }, - { "sbs2l", "side by side half width left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_LR}, 0, 0, FLAGS, "out" }, - { "sbs2r", "side by side half width right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_2_RL}, 0, 0, FLAGS, "out" }, - { "sbsl", "side by side left first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_LR}, 0, 0, FLAGS, "out" }, - { "sbsr", "side by side right first", 0, AV_OPT_TYPE_CONST, {.i64=SIDE_BY_SIDE_RL}, 0, 0, FLAGS, "out" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(stereo3d); - -static const enum AVPixelFormat anaglyph_pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_NONE -}; - -static const enum AVPixelFormat other_pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_RGB48BE, AV_PIX_FMT_BGR48BE, - AV_PIX_FMT_RGB48LE, AV_PIX_FMT_BGR48LE, - AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_BGRA64BE, - AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_BGRA64LE, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, - AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, - AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRP9BE, AV_PIX_FMT_GBRP9LE, - AV_PIX_FMT_GBRP10BE, AV_PIX_FMT_GBRP10LE, - AV_PIX_FMT_GBRP12BE, AV_PIX_FMT_GBRP12LE, - AV_PIX_FMT_GBRP14BE, AV_PIX_FMT_GBRP14LE, - AV_PIX_FMT_GBRP16BE, AV_PIX_FMT_GBRP16LE, - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA422P, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_YUVJ411P, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_YUV420P9LE, AV_PIX_FMT_YUVA420P9LE, - AV_PIX_FMT_YUV420P9BE, AV_PIX_FMT_YUVA420P9BE, - AV_PIX_FMT_YUV422P9LE, AV_PIX_FMT_YUVA422P9LE, - AV_PIX_FMT_YUV422P9BE, AV_PIX_FMT_YUVA422P9BE, - AV_PIX_FMT_YUV444P9LE, AV_PIX_FMT_YUVA444P9LE, - AV_PIX_FMT_YUV444P9BE, AV_PIX_FMT_YUVA444P9BE, - AV_PIX_FMT_YUV420P10LE, AV_PIX_FMT_YUVA420P10LE, - AV_PIX_FMT_YUV420P10BE, AV_PIX_FMT_YUVA420P10BE, - AV_PIX_FMT_YUV422P10LE, AV_PIX_FMT_YUVA422P10LE, - AV_PIX_FMT_YUV422P10BE, AV_PIX_FMT_YUVA422P10BE, - AV_PIX_FMT_YUV444P10LE, AV_PIX_FMT_YUVA444P10LE, - AV_PIX_FMT_YUV444P10BE, AV_PIX_FMT_YUVA444P10BE, - AV_PIX_FMT_YUV420P12BE, AV_PIX_FMT_YUV420P12LE, - AV_PIX_FMT_YUV422P12BE, AV_PIX_FMT_YUV422P12LE, - AV_PIX_FMT_YUV444P12BE, AV_PIX_FMT_YUV444P12LE, - AV_PIX_FMT_YUV420P14BE, AV_PIX_FMT_YUV420P14LE, - AV_PIX_FMT_YUV422P14BE, AV_PIX_FMT_YUV422P14LE, - AV_PIX_FMT_YUV444P14BE, AV_PIX_FMT_YUV444P14LE, - AV_PIX_FMT_YUV420P16LE, AV_PIX_FMT_YUVA420P16LE, - AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_YUVA420P16BE, - AV_PIX_FMT_YUV422P16LE, AV_PIX_FMT_YUVA422P16LE, - AV_PIX_FMT_YUV422P16BE, AV_PIX_FMT_YUVA422P16BE, - AV_PIX_FMT_YUV444P16LE, AV_PIX_FMT_YUVA444P16LE, - AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUVA444P16BE, - AV_PIX_FMT_NONE -}; - -static int query_formats(AVFilterContext *ctx) -{ - Stereo3DContext *s = ctx->priv; - const enum AVPixelFormat *pix_fmts; - - switch (s->out.format) { - case ANAGLYPH_GM_COLOR: - case ANAGLYPH_GM_DUBOIS: - case ANAGLYPH_GM_GRAY: - case ANAGLYPH_GM_HALF: - case ANAGLYPH_RB_GRAY: - case ANAGLYPH_RC_COLOR: - case ANAGLYPH_RC_DUBOIS: - case ANAGLYPH_RC_GRAY: - case ANAGLYPH_RC_HALF: - case ANAGLYPH_RG_GRAY: - case ANAGLYPH_YB_COLOR: - case ANAGLYPH_YB_DUBOIS: - case ANAGLYPH_YB_GRAY: - case ANAGLYPH_YB_HALF: - pix_fmts = anaglyph_pix_fmts; - break; - default: - pix_fmts = other_pix_fmts; - } - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = ctx->inputs[0]; - Stereo3DContext *s = ctx->priv; - AVRational aspect = inlink->sample_aspect_ratio; - AVRational fps = inlink->frame_rate; - AVRational tb = inlink->time_base; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); - int ret; - - switch (s->in.format) { - case SIDE_BY_SIDE_2_LR: - case SIDE_BY_SIDE_LR: - case SIDE_BY_SIDE_2_RL: - case SIDE_BY_SIDE_RL: - if (inlink->w & 1) { - av_log(ctx, AV_LOG_ERROR, "width must be even\n"); - return AVERROR_INVALIDDATA; - } - break; - case ABOVE_BELOW_2_LR: - case ABOVE_BELOW_LR: - case ABOVE_BELOW_2_RL: - case ABOVE_BELOW_RL: - if (s->out.format == INTERLEAVE_ROWS_LR || - s->out.format == INTERLEAVE_ROWS_RL) { - if (inlink->h & 3) { - av_log(ctx, AV_LOG_ERROR, "height must be multiple of 4\n"); - return AVERROR_INVALIDDATA; - } - } - if (inlink->h & 1) { - av_log(ctx, AV_LOG_ERROR, "height must be even\n"); - return AVERROR_INVALIDDATA; - } - break; - } - - s->in.width = - s->width = inlink->w; - s->in.height = - s->height = inlink->h; - s->row_step = 1; - s->in.off_lstep = - s->in.off_rstep = - s->in.off_left = - s->in.off_right = - s->in.row_left = - s->in.row_right = 0; - - switch (s->in.format) { - case SIDE_BY_SIDE_2_LR: - aspect.num *= 2; - case SIDE_BY_SIDE_LR: - s->width = inlink->w / 2; - s->in.off_right = s->width; - break; - case SIDE_BY_SIDE_2_RL: - aspect.num *= 2; - case SIDE_BY_SIDE_RL: - s->width = inlink->w / 2; - s->in.off_left = s->width; - break; - case ABOVE_BELOW_2_LR: - aspect.den *= 2; - case ABOVE_BELOW_LR: - s->in.row_right = - s->height = inlink->h / 2; - break; - case ABOVE_BELOW_2_RL: - aspect.den *= 2; - case ABOVE_BELOW_RL: - s->in.row_left = - s->height = inlink->h / 2; - break; - case ALTERNATING_RL: - case ALTERNATING_LR: - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - fps.den *= 2; - tb.num *= 2; - break; - default: - av_log(ctx, AV_LOG_ERROR, "input format %d is not supported\n", s->in.format); - return AVERROR(EINVAL); - } - - s->out.width = s->width; - s->out.height = s->height; - s->out.off_lstep = - s->out.off_rstep = - s->out.off_left = - s->out.off_right = - s->out.row_left = - s->out.row_right = 0; - - switch (s->out.format) { - case ANAGLYPH_RB_GRAY: - case ANAGLYPH_RG_GRAY: - case ANAGLYPH_RC_GRAY: - case ANAGLYPH_RC_HALF: - case ANAGLYPH_RC_COLOR: - case ANAGLYPH_RC_DUBOIS: - case ANAGLYPH_GM_GRAY: - case ANAGLYPH_GM_HALF: - case ANAGLYPH_GM_COLOR: - case ANAGLYPH_GM_DUBOIS: - case ANAGLYPH_YB_GRAY: - case ANAGLYPH_YB_HALF: - case ANAGLYPH_YB_COLOR: - case ANAGLYPH_YB_DUBOIS: { - uint8_t rgba_map[4]; - - ff_fill_rgba_map(rgba_map, outlink->format); - s->ana_matrix[rgba_map[0]] = &ana_coeff[s->out.format][0][0]; - s->ana_matrix[rgba_map[1]] = &ana_coeff[s->out.format][1][0]; - s->ana_matrix[rgba_map[2]] = &ana_coeff[s->out.format][2][0]; - break; - } - case SIDE_BY_SIDE_2_LR: - aspect.den *= 2; - case SIDE_BY_SIDE_LR: - s->out.width = s->width * 2; - s->out.off_right = s->width; - break; - case SIDE_BY_SIDE_2_RL: - aspect.den *= 2; - case SIDE_BY_SIDE_RL: - s->out.width = s->width * 2; - s->out.off_left = s->width; - break; - case ABOVE_BELOW_2_LR: - aspect.num *= 2; - case ABOVE_BELOW_LR: - s->out.height = s->height * 2; - s->out.row_right = s->height; - break; - case ABOVE_BELOW_2_RL: - aspect.num *= 2; - case ABOVE_BELOW_RL: - s->out.height = s->height * 2; - s->out.row_left = s->height; - break; - case INTERLEAVE_ROWS_LR: - s->row_step = 2; - s->height = s->height / 2; - s->out.off_rstep = - s->in.off_rstep = 1; - break; - case INTERLEAVE_ROWS_RL: - s->row_step = 2; - s->height = s->height / 2; - s->out.off_lstep = - s->in.off_lstep = 1; - break; - case MONO_R: - s->in.off_left = s->in.off_right; - s->in.row_left = s->in.row_right; - case MONO_L: - break; - case ALTERNATING_RL: - case ALTERNATING_LR: - fps.num *= 2; - tb.den *= 2; - break; - default: - av_log(ctx, AV_LOG_ERROR, "output format %d is not supported\n", s->out.format); - return AVERROR(EINVAL); - } - - outlink->w = s->out.width; - outlink->h = s->out.height; - outlink->frame_rate = fps; - outlink->time_base = tb; - outlink->sample_aspect_ratio = aspect; - - if ((ret = av_image_fill_linesizes(s->linesize, outlink->format, s->width)) < 0) - return ret; - s->nb_planes = av_pix_fmt_count_planes(outlink->format); - av_image_fill_max_pixsteps(s->pixstep, NULL, desc); - s->ts_unit = av_q2d(av_inv_q(av_mul_q(outlink->frame_rate, outlink->time_base))); - s->pheight[1] = s->pheight[2] = FF_CEIL_RSHIFT(s->height, desc->log2_chroma_h); - s->pheight[0] = s->pheight[3] = s->height; - s->hsub = desc->log2_chroma_w; - s->vsub = desc->log2_chroma_h; - - return 0; -} - -static inline uint8_t ana_convert(const int *coeff, const uint8_t *left, const uint8_t *right) -{ - int sum; - - sum = coeff[0] * left[0] + coeff[3] * right[0]; //red in - sum += coeff[1] * left[1] + coeff[4] * right[1]; //green in - sum += coeff[2] * left[2] + coeff[5] * right[2]; //blue in - - return av_clip_uint8(sum >> 16); -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - AVFilterContext *ctx = inlink->dst; - Stereo3DContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out, *oleft, *oright, *ileft, *iright; - int out_off_left[4], out_off_right[4]; - int in_off_left[4], in_off_right[4]; - int i; - - switch (s->in.format) { - case ALTERNATING_LR: - case ALTERNATING_RL: - if (!s->prev) { - s->prev = inpicref; - return 0; - } - ileft = s->prev; - iright = inpicref; - if (s->in.format == ALTERNATING_RL) - FFSWAP(AVFrame *, ileft, iright); - break; - default: - ileft = iright = inpicref; - }; - - out = oleft = oright = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&s->prev); - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, inpicref); - - if (s->out.format == ALTERNATING_LR || - s->out.format == ALTERNATING_RL) { - oright = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!oright) { - av_frame_free(&oleft); - av_frame_free(&s->prev); - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(oright, inpicref); - } - - for (i = 0; i < 4; i++) { - int hsub = i == 1 || i == 2 ? s->hsub : 0; - int vsub = i == 1 || i == 2 ? s->vsub : 0; - in_off_left[i] = (FF_CEIL_RSHIFT(s->in.row_left, vsub) + s->in.off_lstep) * ileft->linesize[i] + FF_CEIL_RSHIFT(s->in.off_left * s->pixstep[i], hsub); - in_off_right[i] = (FF_CEIL_RSHIFT(s->in.row_right, vsub) + s->in.off_rstep) * iright->linesize[i] + FF_CEIL_RSHIFT(s->in.off_right * s->pixstep[i], hsub); - out_off_left[i] = (FF_CEIL_RSHIFT(s->out.row_left, vsub) + s->out.off_lstep) * oleft->linesize[i] + FF_CEIL_RSHIFT(s->out.off_left * s->pixstep[i], hsub); - out_off_right[i] = (FF_CEIL_RSHIFT(s->out.row_right, vsub) + s->out.off_rstep) * oright->linesize[i] + FF_CEIL_RSHIFT(s->out.off_right * s->pixstep[i], hsub); - } - - switch (s->out.format) { - case ALTERNATING_LR: - case ALTERNATING_RL: - case SIDE_BY_SIDE_LR: - case SIDE_BY_SIDE_RL: - case SIDE_BY_SIDE_2_LR: - case SIDE_BY_SIDE_2_RL: - case ABOVE_BELOW_LR: - case ABOVE_BELOW_RL: - case ABOVE_BELOW_2_LR: - case ABOVE_BELOW_2_RL: - case INTERLEAVE_ROWS_LR: - case INTERLEAVE_ROWS_RL: - for (i = 0; i < s->nb_planes; i++) { - av_image_copy_plane(oleft->data[i] + out_off_left[i], - oleft->linesize[i] * s->row_step, - ileft->data[i] + in_off_left[i], - ileft->linesize[i] * s->row_step, - s->linesize[i], s->pheight[i]); - av_image_copy_plane(oright->data[i] + out_off_right[i], - oright->linesize[i] * s->row_step, - iright->data[i] + in_off_right[i], - iright->linesize[i] * s->row_step, - s->linesize[i], s->pheight[i]); - } - break; - case MONO_L: - iright = ileft; - case MONO_R: - for (i = 0; i < s->nb_planes; i++) { - av_image_copy_plane(out->data[i], out->linesize[i], - iright->data[i] + in_off_left[i], - iright->linesize[i], - s->linesize[i], s->pheight[i]); - } - break; - case ANAGLYPH_RB_GRAY: - case ANAGLYPH_RG_GRAY: - case ANAGLYPH_RC_GRAY: - case ANAGLYPH_RC_HALF: - case ANAGLYPH_RC_COLOR: - case ANAGLYPH_RC_DUBOIS: - case ANAGLYPH_GM_GRAY: - case ANAGLYPH_GM_HALF: - case ANAGLYPH_GM_COLOR: - case ANAGLYPH_GM_DUBOIS: - case ANAGLYPH_YB_GRAY: - case ANAGLYPH_YB_HALF: - case ANAGLYPH_YB_COLOR: - case ANAGLYPH_YB_DUBOIS: { - int x, y, il, ir, o; - const uint8_t *lsrc = ileft->data[0]; - const uint8_t *rsrc = iright->data[0]; - uint8_t *dst = out->data[0]; - int out_width = s->out.width; - const int **ana_matrix = s->ana_matrix; - - for (y = 0; y < s->out.height; y++) { - o = out->linesize[0] * y; - il = in_off_left[0] + y * ileft->linesize[0]; - ir = in_off_right[0] + y * iright->linesize[0]; - for (x = 0; x < out_width; x++, il += 3, ir += 3, o+= 3) { - dst[o ] = ana_convert(ana_matrix[0], lsrc + il, rsrc + ir); - dst[o + 1] = ana_convert(ana_matrix[1], lsrc + il, rsrc + ir); - dst[o + 2] = ana_convert(ana_matrix[2], lsrc + il, rsrc + ir); - } - } - break; - } - default: - av_assert0(0); - } - - av_frame_free(&inpicref); - av_frame_free(&s->prev); - if (oright != oleft) { - if (s->out.format == ALTERNATING_LR) - FFSWAP(AVFrame *, oleft, oright); - oright->pts = outlink->frame_count * s->ts_unit; - ff_filter_frame(outlink, oright); - out = oleft; - oleft->pts = outlink->frame_count * s->ts_unit; - } else if (s->in.format == ALTERNATING_LR || - s->in.format == ALTERNATING_RL) { - out->pts = outlink->frame_count * s->ts_unit; - } - return ff_filter_frame(outlink, out); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - Stereo3DContext *s = ctx->priv; - - av_frame_free(&s->prev); -} - -static const AVFilterPad stereo3d_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad stereo3d_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_stereo3d = { - .name = "stereo3d", - .description = NULL_IF_CONFIG_SMALL("Convert video stereoscopic 3D view."), - .priv_size = sizeof(Stereo3DContext), - .uninit = uninit, - .query_formats = query_formats, - .inputs = stereo3d_inputs, - .outputs = stereo3d_outputs, - .priv_class = &stereo3d_class, -}; diff --git a/ffmpeg/libavfilter/vf_subtitles.c b/ffmpeg/libavfilter/vf_subtitles.c deleted file mode 100644 index e44f61d..0000000 --- a/ffmpeg/libavfilter/vf_subtitles.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2011 Baptiste Coudurier - * Copyright (c) 2011 Stefano Sabatini - * 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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Libass subtitles burning filter. - * - * @see{http://www.matroska.org/technical/specs/subtitles/ssa.html} - */ - -#include <ass/ass.h> - -#include "config.h" -#if CONFIG_SUBTITLES_FILTER -# include "libavcodec/avcodec.h" -# include "libavformat/avformat.h" -#endif -#include "libavutil/avstring.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "drawutils.h" -#include "avfilter.h" -#include "internal.h" -#include "formats.h" -#include "video.h" - -typedef struct { - const AVClass *class; - ASS_Library *library; - ASS_Renderer *renderer; - ASS_Track *track; - char *filename; - char *charenc; - uint8_t rgba_map[4]; - int pix_step[4]; ///< steps per pixel for each plane of the main output - int original_w, original_h; - FFDrawContext draw; -} AssContext; - -#define OFFSET(x) offsetof(AssContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -#define COMMON_OPTIONS \ - {"filename", "set the filename of file to read", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ - {"f", "set the filename of file to read", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ - {"original_size", "set the size of the original video (used to scale fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, \ - -/* libass supports a log level ranging from 0 to 7 */ -static const int ass_libavfilter_log_level_map[] = { - AV_LOG_QUIET, /* 0 */ - AV_LOG_PANIC, /* 1 */ - AV_LOG_FATAL, /* 2 */ - AV_LOG_ERROR, /* 3 */ - AV_LOG_WARNING, /* 4 */ - AV_LOG_INFO, /* 5 */ - AV_LOG_VERBOSE, /* 6 */ - AV_LOG_DEBUG, /* 7 */ -}; - -static void ass_log(int ass_level, const char *fmt, va_list args, void *ctx) -{ - int level = ass_libavfilter_log_level_map[ass_level]; - - av_vlog(ctx, level, fmt, args); - av_log(ctx, level, "\n"); -} - -static av_cold int init(AVFilterContext *ctx) -{ - AssContext *ass = ctx->priv; - - if (!ass->filename) { - av_log(ctx, AV_LOG_ERROR, "No filename provided!\n"); - return AVERROR(EINVAL); - } - - ass->library = ass_library_init(); - if (!ass->library) { - av_log(ctx, AV_LOG_ERROR, "Could not initialize libass.\n"); - return AVERROR(EINVAL); - } - ass_set_message_cb(ass->library, ass_log, ctx); - - ass->renderer = ass_renderer_init(ass->library); - if (!ass->renderer) { - av_log(ctx, AV_LOG_ERROR, "Could not initialize libass renderer.\n"); - return AVERROR(EINVAL); - } - - ass_set_fonts(ass->renderer, NULL, NULL, 1, NULL, 1); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - AssContext *ass = ctx->priv; - - if (ass->track) - ass_free_track(ass->track); - if (ass->renderer) - ass_renderer_done(ass->renderer); - if (ass->library) - ass_library_done(ass->library); -} - -static int query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - AssContext *ass = inlink->dst->priv; - - ff_draw_init(&ass->draw, inlink->format, 0); - - ass_set_frame_size (ass->renderer, inlink->w, inlink->h); - if (ass->original_w && ass->original_h) - ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h, - (double)ass->original_w / ass->original_h); - - return 0; -} - -/* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */ -#define AR(c) ( (c)>>24) -#define AG(c) (((c)>>16)&0xFF) -#define AB(c) (((c)>>8) &0xFF) -#define AA(c) ((0xFF-c) &0xFF) - -static void overlay_ass_image(AssContext *ass, AVFrame *picref, - const ASS_Image *image) -{ - for (; image; image = image->next) { - uint8_t rgba_color[] = {AR(image->color), AG(image->color), AB(image->color), AA(image->color)}; - FFDrawColor color; - ff_draw_color(&ass->draw, &color, rgba_color); - ff_blend_mask(&ass->draw, &color, - picref->data, picref->linesize, - picref->width, picref->height, - image->bitmap, image->stride, image->w, image->h, - 3, 0, image->dst_x, image->dst_y); - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *picref) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - AssContext *ass = ctx->priv; - int detect_change = 0; - double time_ms = picref->pts * av_q2d(inlink->time_base) * 1000; - ASS_Image *image = ass_render_frame(ass->renderer, ass->track, - time_ms, &detect_change); - - if (detect_change) - av_log(ctx, AV_LOG_DEBUG, "Change happened at time ms:%f\n", time_ms); - - overlay_ass_image(ass, picref, image); - - return ff_filter_frame(outlink, picref); -} - -static const AVFilterPad ass_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_input, - .needs_writable = 1, - }, - { NULL } -}; - -static const AVFilterPad ass_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -#if CONFIG_ASS_FILTER - -static const AVOption ass_options[] = { - COMMON_OPTIONS - {NULL}, -}; - -AVFILTER_DEFINE_CLASS(ass); - -static av_cold int init_ass(AVFilterContext *ctx) -{ - AssContext *ass = ctx->priv; - int ret = init(ctx); - - if (ret < 0) - return ret; - - ass->track = ass_read_file(ass->library, ass->filename, NULL); - if (!ass->track) { - av_log(ctx, AV_LOG_ERROR, - "Could not create a libass track when reading file '%s'\n", - ass->filename); - return AVERROR(EINVAL); - } - return 0; -} - -AVFilter ff_vf_ass = { - .name = "ass", - .description = NULL_IF_CONFIG_SMALL("Render ASS subtitles onto input video using the libass library."), - .priv_size = sizeof(AssContext), - .init = init_ass, - .uninit = uninit, - .query_formats = query_formats, - .inputs = ass_inputs, - .outputs = ass_outputs, - .priv_class = &ass_class, -}; -#endif - -#if CONFIG_SUBTITLES_FILTER - -static const AVOption subtitles_options[] = { - COMMON_OPTIONS - {"charenc", "set input character encoding", OFFSET(charenc), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS}, - {NULL}, -}; - -AVFILTER_DEFINE_CLASS(subtitles); - -static av_cold int init_subtitles(AVFilterContext *ctx) -{ - int ret, sid; - AVDictionary *codec_opts = NULL; - AVFormatContext *fmt = NULL; - AVCodecContext *dec_ctx = NULL; - AVCodec *dec = NULL; - const AVCodecDescriptor *dec_desc; - AVStream *st; - AVPacket pkt; - AssContext *ass = ctx->priv; - - /* Init libass */ - ret = init(ctx); - if (ret < 0) - return ret; - ass->track = ass_new_track(ass->library); - if (!ass->track) { - av_log(ctx, AV_LOG_ERROR, "Could not create a libass track\n"); - return AVERROR(EINVAL); - } - - /* Open subtitles file */ - ret = avformat_open_input(&fmt, ass->filename, NULL, NULL); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Unable to open %s\n", ass->filename); - goto end; - } - ret = avformat_find_stream_info(fmt, NULL); - if (ret < 0) - goto end; - - /* Locate subtitles stream */ - ret = av_find_best_stream(fmt, AVMEDIA_TYPE_SUBTITLE, -1, -1, NULL, 0); - if (ret < 0) { - av_log(ctx, AV_LOG_ERROR, "Unable to locate subtitle stream in %s\n", - ass->filename); - goto end; - } - sid = ret; - st = fmt->streams[sid]; - - /* Open decoder */ - dec_ctx = st->codec; - dec = avcodec_find_decoder(dec_ctx->codec_id); - if (!dec) { - av_log(ctx, AV_LOG_ERROR, "Failed to find subtitle codec %s\n", - avcodec_get_name(dec_ctx->codec_id)); - return AVERROR(EINVAL); - } - dec_desc = avcodec_descriptor_get(dec_ctx->codec_id); - if (dec_desc && !(dec_desc->props & AV_CODEC_PROP_TEXT_SUB)) { - av_log(ctx, AV_LOG_ERROR, - "Only text based subtitles are currently supported\n"); - return AVERROR_PATCHWELCOME; - } - if (ass->charenc) - av_dict_set(&codec_opts, "sub_charenc", ass->charenc, 0); - ret = avcodec_open2(dec_ctx, dec, &codec_opts); - if (ret < 0) - goto end; - - /* Decode subtitles and push them into the renderer (libass) */ - if (dec_ctx->subtitle_header) - ass_process_codec_private(ass->track, - dec_ctx->subtitle_header, - dec_ctx->subtitle_header_size); - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; - while (av_read_frame(fmt, &pkt) >= 0) { - int i, got_subtitle; - AVSubtitle sub = {0}; - - if (pkt.stream_index == sid) { - ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_subtitle, &pkt); - if (ret < 0) { - av_log(ctx, AV_LOG_WARNING, "Error decoding: %s (ignored)\n", - av_err2str(ret)); - } else if (got_subtitle) { - for (i = 0; i < sub.num_rects; i++) { - char *ass_line = sub.rects[i]->ass; - if (!ass_line) - break; - ass_process_data(ass->track, ass_line, strlen(ass_line)); - } - } - } - av_free_packet(&pkt); - avsubtitle_free(&sub); - } - -end: - av_dict_free(&codec_opts); - if (dec_ctx) - avcodec_close(dec_ctx); - if (fmt) - avformat_close_input(&fmt); - return ret; -} - -AVFilter ff_vf_subtitles = { - .name = "subtitles", - .description = NULL_IF_CONFIG_SMALL("Render text subtitles onto input video using the libass library."), - .priv_size = sizeof(AssContext), - .init = init_subtitles, - .uninit = uninit, - .query_formats = query_formats, - .inputs = ass_inputs, - .outputs = ass_outputs, - .priv_class = &subtitles_class, -}; -#endif diff --git a/ffmpeg/libavfilter/vf_super2xsai.c b/ffmpeg/libavfilter/vf_super2xsai.c deleted file mode 100644 index 686dac1..0000000 --- a/ffmpeg/libavfilter/vf_super2xsai.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2010 Niel van der Westhuizen <nielkie@gmail.com> - * Copyright (c) 2002 A'rpi - * Copyright (c) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) - * - * 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 - * Super 2xSaI video filter - * Ported from MPlayer libmpcodecs/vf_2xsai.c. - */ - -#include "libavutil/pixdesc.h" -#include "libavutil/intreadwrite.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - /* masks used for two pixels interpolation */ - uint32_t hi_pixel_mask; - uint32_t lo_pixel_mask; - - /* masks used for four pixels interpolation */ - uint32_t q_hi_pixel_mask; - uint32_t q_lo_pixel_mask; - - int bpp; ///< bytes per pixel, pixel stride for each (packed) pixel - int is_be; -} Super2xSaIContext; - -#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) - -#define INTERPOLATE(A, B) (((A & hi_pixel_mask) >> 1) + ((B & hi_pixel_mask) >> 1) + (A & B & lo_pixel_mask)) - -#define Q_INTERPOLATE(A, B, C, D) ((A & q_hi_pixel_mask) >> 2) + ((B & q_hi_pixel_mask) >> 2) + ((C & q_hi_pixel_mask) >> 2) + ((D & q_hi_pixel_mask) >> 2) \ - + ((((A & q_lo_pixel_mask) + (B & q_lo_pixel_mask) + (C & q_lo_pixel_mask) + (D & q_lo_pixel_mask)) >> 2) & q_lo_pixel_mask) - -static void super2xsai(AVFilterContext *ctx, - uint8_t *src, int src_linesize, - uint8_t *dst, int dst_linesize, - int width, int height) -{ - Super2xSaIContext *sai = ctx->priv; - unsigned int x, y; - uint32_t color[4][4]; - unsigned char *src_line[4]; - const int bpp = sai->bpp; - const uint32_t hi_pixel_mask = sai->hi_pixel_mask; - const uint32_t lo_pixel_mask = sai->lo_pixel_mask; - const uint32_t q_hi_pixel_mask = sai->q_hi_pixel_mask; - const uint32_t q_lo_pixel_mask = sai->q_lo_pixel_mask; - - /* Point to the first 4 lines, first line is duplicated */ - src_line[0] = src; - src_line[1] = src; - src_line[2] = src + src_linesize*FFMIN(1, height-1); - src_line[3] = src + src_linesize*FFMIN(2, height-1); - -#define READ_COLOR4(dst, src_line, off) dst = *((const uint32_t *)src_line + off) -#define READ_COLOR3(dst, src_line, off) dst = AV_RL24 (src_line + 3*off) -#define READ_COLOR2(dst, src_line, off) dst = sai->is_be ? AV_RB16(src_line + 2 * off) : AV_RL16(src_line + 2 * off) - - for (y = 0; y < height; y++) { - uint8_t *dst_line[2]; - - dst_line[0] = dst + dst_linesize*2*y; - dst_line[1] = dst + dst_linesize*(2*y+1); - - switch (bpp) { - case 4: - READ_COLOR4(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR4(color[0][2], src_line[0], 1); READ_COLOR4(color[0][3], src_line[0], 2); - READ_COLOR4(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR4(color[1][2], src_line[1], 1); READ_COLOR4(color[1][3], src_line[1], 2); - READ_COLOR4(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR4(color[2][2], src_line[2], 1); READ_COLOR4(color[2][3], src_line[2], 2); - READ_COLOR4(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR4(color[3][2], src_line[3], 1); READ_COLOR4(color[3][3], src_line[3], 2); - break; - case 3: - READ_COLOR3(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR3(color[0][2], src_line[0], 1); READ_COLOR3(color[0][3], src_line[0], 2); - READ_COLOR3(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR3(color[1][2], src_line[1], 1); READ_COLOR3(color[1][3], src_line[1], 2); - READ_COLOR3(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR3(color[2][2], src_line[2], 1); READ_COLOR3(color[2][3], src_line[2], 2); - READ_COLOR3(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR3(color[3][2], src_line[3], 1); READ_COLOR3(color[3][3], src_line[3], 2); - break; - default: - READ_COLOR2(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR2(color[0][2], src_line[0], 1); READ_COLOR2(color[0][3], src_line[0], 2); - READ_COLOR2(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR2(color[1][2], src_line[1], 1); READ_COLOR2(color[1][3], src_line[1], 2); - READ_COLOR2(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR2(color[2][2], src_line[2], 1); READ_COLOR2(color[2][3], src_line[2], 2); - READ_COLOR2(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR2(color[3][2], src_line[3], 1); READ_COLOR2(color[3][3], src_line[3], 2); - } - - for (x = 0; x < width; x++) { - uint32_t product1a, product1b, product2a, product2b; - -//--------------------------------------- B0 B1 B2 B3 0 1 2 3 -// 4 5* 6 S2 -> 4 5* 6 7 -// 1 2 3 S1 8 9 10 11 -// A0 A1 A2 A3 12 13 14 15 -//-------------------------------------- - if (color[2][1] == color[1][2] && color[1][1] != color[2][2]) { - product2b = color[2][1]; - product1b = product2b; - } else if (color[1][1] == color[2][2] && color[2][1] != color[1][2]) { - product2b = color[1][1]; - product1b = product2b; - } else if (color[1][1] == color[2][2] && color[2][1] == color[1][2]) { - int r = 0; - - r += GET_RESULT(color[1][2], color[1][1], color[1][0], color[3][1]); - r += GET_RESULT(color[1][2], color[1][1], color[2][0], color[0][1]); - r += GET_RESULT(color[1][2], color[1][1], color[3][2], color[2][3]); - r += GET_RESULT(color[1][2], color[1][1], color[0][2], color[1][3]); - - if (r > 0) - product1b = color[1][2]; - else if (r < 0) - product1b = color[1][1]; - else - product1b = INTERPOLATE(color[1][1], color[1][2]); - - product2b = product1b; - } else { - if (color[1][2] == color[2][2] && color[2][2] == color[3][1] && color[2][1] != color[3][2] && color[2][2] != color[3][0]) - product2b = Q_INTERPOLATE(color[2][2], color[2][2], color[2][2], color[2][1]); - else if (color[1][1] == color[2][1] && color[2][1] == color[3][2] && color[3][1] != color[2][2] && color[2][1] != color[3][3]) - product2b = Q_INTERPOLATE(color[2][1], color[2][1], color[2][1], color[2][2]); - else - product2b = INTERPOLATE(color[2][1], color[2][2]); - - if (color[1][2] == color[2][2] && color[1][2] == color[0][1] && color[1][1] != color[0][2] && color[1][2] != color[0][0]) - product1b = Q_INTERPOLATE(color[1][2], color[1][2], color[1][2], color[1][1]); - else if (color[1][1] == color[2][1] && color[1][1] == color[0][2] && color[0][1] != color[1][2] && color[1][1] != color[0][3]) - product1b = Q_INTERPOLATE(color[1][2], color[1][1], color[1][1], color[1][1]); - else - product1b = INTERPOLATE(color[1][1], color[1][2]); - } - - if (color[1][1] == color[2][2] && color[2][1] != color[1][2] && color[1][0] == color[1][1] && color[1][1] != color[3][2]) - product2a = INTERPOLATE(color[2][1], color[1][1]); - else if (color[1][1] == color[2][0] && color[1][2] == color[1][1] && color[1][0] != color[2][1] && color[1][1] != color[3][0]) - product2a = INTERPOLATE(color[2][1], color[1][1]); - else - product2a = color[2][1]; - - if (color[2][1] == color[1][2] && color[1][1] != color[2][2] && color[2][0] == color[2][1] && color[2][1] != color[0][2]) - product1a = INTERPOLATE(color[2][1], color[1][1]); - else if (color[1][0] == color[2][1] && color[2][2] == color[2][1] && color[2][0] != color[1][1] && color[2][1] != color[0][0]) - product1a = INTERPOLATE(color[2][1], color[1][1]); - else - product1a = color[1][1]; - - /* Set the calculated pixels */ - switch (bpp) { - case 4: - AV_WN32A(dst_line[0] + x * 8, product1a); - AV_WN32A(dst_line[0] + x * 8 + 4, product1b); - AV_WN32A(dst_line[1] + x * 8, product2a); - AV_WN32A(dst_line[1] + x * 8 + 4, product2b); - break; - case 3: - AV_WL24(dst_line[0] + x * 6, product1a); - AV_WL24(dst_line[0] + x * 6 + 3, product1b); - AV_WL24(dst_line[1] + x * 6, product2a); - AV_WL24(dst_line[1] + x * 6 + 3, product2b); - break; - default: // bpp = 2 - if (sai->is_be) { - AV_WB32(dst_line[0] + x * 4, product1a | (product1b << 16)); - AV_WB32(dst_line[1] + x * 4, product2a | (product2b << 16)); - } else { - AV_WL32(dst_line[0] + x * 4, product1a | (product1b << 16)); - AV_WL32(dst_line[1] + x * 4, product2a | (product2b << 16)); - } - } - - /* Move color matrix forward */ - color[0][0] = color[0][1]; color[0][1] = color[0][2]; color[0][2] = color[0][3]; - color[1][0] = color[1][1]; color[1][1] = color[1][2]; color[1][2] = color[1][3]; - color[2][0] = color[2][1]; color[2][1] = color[2][2]; color[2][2] = color[2][3]; - color[3][0] = color[3][1]; color[3][1] = color[3][2]; color[3][2] = color[3][3]; - - if (x < width - 3) { - x += 3; - switch (bpp) { - case 4: - READ_COLOR4(color[0][3], src_line[0], x); - READ_COLOR4(color[1][3], src_line[1], x); - READ_COLOR4(color[2][3], src_line[2], x); - READ_COLOR4(color[3][3], src_line[3], x); - break; - case 3: - READ_COLOR3(color[0][3], src_line[0], x); - READ_COLOR3(color[1][3], src_line[1], x); - READ_COLOR3(color[2][3], src_line[2], x); - READ_COLOR3(color[3][3], src_line[3], x); - break; - default: /* case 2 */ - READ_COLOR2(color[0][3], src_line[0], x); - READ_COLOR2(color[1][3], src_line[1], x); - READ_COLOR2(color[2][3], src_line[2], x); - READ_COLOR2(color[3][3], src_line[3], x); - } - x -= 3; - } - } - - /* We're done with one line, so we shift the source lines up */ - src_line[0] = src_line[1]; - src_line[1] = src_line[2]; - src_line[2] = src_line[3]; - - /* Read next line */ - src_line[3] = src_line[2]; - if (y < height - 3) - src_line[3] += src_linesize; - } // y loop -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_RGB565BE, AV_PIX_FMT_BGR565BE, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_BGR555BE, - AV_PIX_FMT_RGB565LE, AV_PIX_FMT_BGR565LE, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_BGR555LE, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_input(AVFilterLink *inlink) -{ - Super2xSaIContext *sai = inlink->dst->priv; - - sai->hi_pixel_mask = 0xFEFEFEFE; - sai->lo_pixel_mask = 0x01010101; - sai->q_hi_pixel_mask = 0xFCFCFCFC; - sai->q_lo_pixel_mask = 0x03030303; - sai->bpp = 4; - - switch (inlink->format) { - case AV_PIX_FMT_RGB24: - case AV_PIX_FMT_BGR24: - sai->bpp = 3; - break; - - case AV_PIX_FMT_RGB565BE: - case AV_PIX_FMT_BGR565BE: - sai->is_be = 1; - case AV_PIX_FMT_RGB565LE: - case AV_PIX_FMT_BGR565LE: - sai->hi_pixel_mask = 0xF7DEF7DE; - sai->lo_pixel_mask = 0x08210821; - sai->q_hi_pixel_mask = 0xE79CE79C; - sai->q_lo_pixel_mask = 0x18631863; - sai->bpp = 2; - break; - - case AV_PIX_FMT_BGR555BE: - case AV_PIX_FMT_RGB555BE: - sai->is_be = 1; - case AV_PIX_FMT_BGR555LE: - case AV_PIX_FMT_RGB555LE: - sai->hi_pixel_mask = 0x7BDE7BDE; - sai->lo_pixel_mask = 0x04210421; - sai->q_hi_pixel_mask = 0x739C739C; - sai->q_lo_pixel_mask = 0x0C630C63; - sai->bpp = 2; - break; - } - - return 0; -} - -static int config_output(AVFilterLink *outlink) -{ - AVFilterLink *inlink = outlink->src->inputs[0]; - - outlink->w = inlink->w*2; - outlink->h = inlink->h*2; - - av_log(inlink->dst, AV_LOG_VERBOSE, "fmt:%s size:%dx%d -> size:%dx%d\n", - av_get_pix_fmt_name(inlink->format), - inlink->w, inlink->h, outlink->w, outlink->h); - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref) -{ - AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *outpicref = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!outpicref) { - av_frame_free(&inpicref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(outpicref, inpicref); - outpicref->width = outlink->w; - outpicref->height = outlink->h; - - super2xsai(inlink->dst, inpicref->data[0], inpicref->linesize[0], - outpicref->data[0], outpicref->linesize[0], - inlink->w, inlink->h); - - av_frame_free(&inpicref); - return ff_filter_frame(outlink, outpicref); -} - -static const AVFilterPad super2xsai_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_input, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad super2xsai_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_output, - }, - { NULL } -}; - -AVFilter ff_vf_super2xsai = { - .name = "super2xsai", - .description = NULL_IF_CONFIG_SMALL("Scale the input by 2x using the Super2xSaI pixel art algorithm."), - .priv_size = sizeof(Super2xSaIContext), - .query_formats = query_formats, - .inputs = super2xsai_inputs, - .outputs = super2xsai_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_swapuv.c b/ffmpeg/libavfilter/vf_swapuv.c deleted file mode 100644 index 71ae243..0000000 --- a/ffmpeg/libavfilter/vf_swapuv.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@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 Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * swap UV filter - */ - -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -static void do_swap(AVFrame *frame) -{ - FFSWAP(uint8_t*, frame->data[1], frame->data[2]); - FFSWAP(int, frame->linesize[1], frame->linesize[2]); - FFSWAP(uint64_t, frame->error[1], frame->error[2]); - FFSWAP(AVBufferRef*, frame->buf[1], frame->buf[2]); -} - -static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h) -{ - AVFrame *picref = ff_default_get_video_buffer(link, w, h); - do_swap(picref); - return picref; -} - -static int filter_frame(AVFilterLink *link, AVFrame *inpicref) -{ - do_swap(inpicref); - return ff_filter_frame(link->dst->outputs[0], inpicref); -} - -static int is_planar_yuv(const AVPixFmtDescriptor *desc) -{ - int i; - - if (desc->flags & ~(AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA) || - desc->nb_components < 3 || - (desc->comp[1].depth_minus1 != desc->comp[2].depth_minus1)) - return 0; - for (i = 0; i < desc->nb_components; i++) { - if (desc->comp[i].offset_plus1 != 1 || - desc->comp[i].shift != 0 || - desc->comp[i].plane != i) - return 0; - } - - return 1; -} - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *formats = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (is_planar_yuv(desc)) - ff_add_format(&formats, fmt); - } - - ff_set_common_formats(ctx, formats); - return 0; -} - -static const AVFilterPad swapuv_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = get_video_buffer, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad swapuv_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_swapuv = { - .name = "swapuv", - .description = NULL_IF_CONFIG_SMALL("Swap U and V components."), - .query_formats = query_formats, - .inputs = swapuv_inputs, - .outputs = swapuv_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_thumbnail.c b/ffmpeg/libavfilter/vf_thumbnail.c deleted file mode 100644 index 1883154..0000000 --- a/ffmpeg/libavfilter/vf_thumbnail.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) 2011 Smartjog S.A.S, Clément BÅ“sch <clement.boesch@smartjog.com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Potential thumbnail lookup filter to reduce the risk of an inappropriate - * selection (such as a black frame) we could get with an absolute seek. - * - * Simplified version of algorithm by Vadim Zaliva <lord@crocodile.org>. - * @see http://notbrainsurgery.livejournal.com/29773.html - */ - -#include "libavutil/opt.h" -#include "avfilter.h" -#include "internal.h" - -#define HIST_SIZE (3*256) - -struct thumb_frame { - AVFrame *buf; ///< cached frame - int histogram[HIST_SIZE]; ///< RGB color distribution histogram of the frame -}; - -typedef struct { - const AVClass *class; - int n; ///< current frame - int n_frames; ///< number of frames for analysis - struct thumb_frame *frames; ///< the n_frames frames - AVRational tb; ///< copy of the input timebase to ease access -} ThumbContext; - -#define OFFSET(x) offsetof(ThumbContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption thumbnail_options[] = { - { "n", "set the frames batch size", OFFSET(n_frames), AV_OPT_TYPE_INT, {.i64=100}, 2, INT_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(thumbnail); - -static av_cold int init(AVFilterContext *ctx) -{ - ThumbContext *thumb = ctx->priv; - - thumb->frames = av_calloc(thumb->n_frames, sizeof(*thumb->frames)); - if (!thumb->frames) { - av_log(ctx, AV_LOG_ERROR, - "Allocation failure, try to lower the number of frames\n"); - return AVERROR(ENOMEM); - } - av_log(ctx, AV_LOG_VERBOSE, "batch size: %d frames\n", thumb->n_frames); - return 0; -} - -/** - * @brief Compute Sum-square deviation to estimate "closeness". - * @param hist color distribution histogram - * @param median average color distribution histogram - * @return sum of squared errors - */ -static double frame_sum_square_err(const int *hist, const double *median) -{ - int i; - double err, sum_sq_err = 0; - - for (i = 0; i < HIST_SIZE; i++) { - err = median[i] - (double)hist[i]; - sum_sq_err += err*err; - } - return sum_sq_err; -} - -static AVFrame *get_best_frame(AVFilterContext *ctx) -{ - AVFrame *picref; - ThumbContext *thumb = ctx->priv; - int i, j, best_frame_idx = 0; - int nb_frames = thumb->n; - double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1; - - // average histogram of the N frames - for (j = 0; j < FF_ARRAY_ELEMS(avg_hist); j++) { - for (i = 0; i < nb_frames; i++) - avg_hist[j] += (double)thumb->frames[i].histogram[j]; - avg_hist[j] /= nb_frames; - } - - // find the frame closer to the average using the sum of squared errors - for (i = 0; i < nb_frames; i++) { - sq_err = frame_sum_square_err(thumb->frames[i].histogram, avg_hist); - if (i == 0 || sq_err < min_sq_err) - best_frame_idx = i, min_sq_err = sq_err; - } - - // free and reset everything (except the best frame buffer) - for (i = 0; i < nb_frames; i++) { - memset(thumb->frames[i].histogram, 0, sizeof(thumb->frames[i].histogram)); - if (i != best_frame_idx) - av_frame_free(&thumb->frames[i].buf); - } - thumb->n = 0; - - // raise the chosen one - picref = thumb->frames[best_frame_idx].buf; - av_log(ctx, AV_LOG_INFO, "frame id #%d (pts_time=%f) selected " - "from a set of %d images\n", best_frame_idx, - picref->pts * av_q2d(thumb->tb), nb_frames); - thumb->frames[best_frame_idx].buf = NULL; - - return picref; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *frame) -{ - int i, j; - AVFilterContext *ctx = inlink->dst; - ThumbContext *thumb = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - int *hist = thumb->frames[thumb->n].histogram; - const uint8_t *p = frame->data[0]; - - // keep a reference of each frame - thumb->frames[thumb->n].buf = frame; - - // update current frame RGB histogram - for (j = 0; j < inlink->h; j++) { - for (i = 0; i < inlink->w; i++) { - hist[0*256 + p[i*3 ]]++; - hist[1*256 + p[i*3 + 1]]++; - hist[2*256 + p[i*3 + 2]]++; - } - p += frame->linesize[0]; - } - - // no selection until the buffer of N frames is filled up - thumb->n++; - if (thumb->n < thumb->n_frames) - return 0; - - return ff_filter_frame(outlink, get_best_frame(ctx)); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - int i; - ThumbContext *thumb = ctx->priv; - for (i = 0; i < thumb->n_frames && thumb->frames[i].buf; i++) - av_frame_free(&thumb->frames[i].buf); - av_freep(&thumb->frames); -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - ThumbContext *thumb = ctx->priv; - - /* loop until a frame thumbnail is available (when a frame is queued, - * thumb->n is reset to zero) */ - do { - int ret = ff_request_frame(ctx->inputs[0]); - if (ret == AVERROR_EOF && thumb->n) { - ret = ff_filter_frame(link, get_best_frame(ctx)); - if (ret < 0) - return ret; - ret = AVERROR_EOF; - } - if (ret < 0) - return ret; - } while (thumb->n); - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->dst; - ThumbContext *thumb = ctx->priv; - - thumb->tb = inlink->time_base; - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static const AVFilterPad thumbnail_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad thumbnail_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_thumbnail = { - .name = "thumbnail", - .description = NULL_IF_CONFIG_SMALL("Select the most representative frame in a given sequence of consecutive frames."), - .priv_size = sizeof(ThumbContext), - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = thumbnail_inputs, - .outputs = thumbnail_outputs, - .priv_class = &thumbnail_class, -}; diff --git a/ffmpeg/libavfilter/vf_tile.c b/ffmpeg/libavfilter/vf_tile.c deleted file mode 100644 index 786f4f6..0000000 --- a/ffmpeg/libavfilter/vf_tile.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * tile video filter - */ - -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "video.h" -#include "internal.h" - -typedef struct { - const AVClass *class; - unsigned w, h; - unsigned margin; - unsigned padding; - unsigned current; - unsigned nb_frames; - FFDrawContext draw; - FFDrawColor blank; - AVFrame *out_ref; - uint8_t rgba_color[4]; -} TileContext; - -#define REASONABLE_SIZE 1024 - -#define OFFSET(x) offsetof(TileContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption tile_options[] = { - { "layout", "set grid size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, - {.str = "6x5"}, 0, 0, FLAGS }, - { "nb_frames", "set maximum number of frame to render", OFFSET(nb_frames), - AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, - { "margin", "set outer border margin in pixels", OFFSET(margin), - AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1024, FLAGS }, - { "padding", "set inner border thickness in pixels", OFFSET(padding), - AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1024, FLAGS }, - { "color", "set the color of the unused area", OFFSET(rgba_color), AV_OPT_TYPE_COLOR, {.str = "black"}, .flags = FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(tile); - -static av_cold int init(AVFilterContext *ctx) -{ - TileContext *tile = ctx->priv; - - if (tile->w > REASONABLE_SIZE || tile->h > REASONABLE_SIZE) { - av_log(ctx, AV_LOG_ERROR, "Tile size %ux%u is insane.\n", - tile->w, tile->h); - return AVERROR(EINVAL); - } - - if (tile->nb_frames == 0) { - tile->nb_frames = tile->w * tile->h; - } else if (tile->nb_frames > tile->w * tile->h) { - av_log(ctx, AV_LOG_ERROR, "nb_frames must be less than or equal to %dx%d=%d\n", - tile->w, tile->h, tile->w * tile->h); - return AVERROR(EINVAL); - } - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - TileContext *tile = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - const unsigned total_margin_w = (tile->w - 1) * tile->padding + 2*tile->margin; - const unsigned total_margin_h = (tile->h - 1) * tile->padding + 2*tile->margin; - - if (inlink->w > (INT_MAX - total_margin_w) / tile->w) { - av_log(ctx, AV_LOG_ERROR, "Total width %ux%u is too much.\n", - tile->w, inlink->w); - return AVERROR(EINVAL); - } - if (inlink->h > (INT_MAX - total_margin_h) / tile->h) { - av_log(ctx, AV_LOG_ERROR, "Total height %ux%u is too much.\n", - tile->h, inlink->h); - return AVERROR(EINVAL); - } - outlink->w = tile->w * inlink->w + total_margin_w; - outlink->h = tile->h * inlink->h + total_margin_h; - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - outlink->frame_rate = av_mul_q(inlink->frame_rate, - (AVRational){ 1, tile->nb_frames }); - ff_draw_init(&tile->draw, inlink->format, 0); - ff_draw_color(&tile->draw, &tile->blank, tile->rgba_color); - - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - - return 0; -} - -static void get_current_tile_pos(AVFilterContext *ctx, unsigned *x, unsigned *y) -{ - TileContext *tile = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - const unsigned tx = tile->current % tile->w; - const unsigned ty = tile->current / tile->w; - - *x = tile->margin + (inlink->w + tile->padding) * tx; - *y = tile->margin + (inlink->h + tile->padding) * ty; -} - -static void draw_blank_frame(AVFilterContext *ctx, AVFrame *out_buf) -{ - TileContext *tile = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - unsigned x0, y0; - - get_current_tile_pos(ctx, &x0, &y0); - ff_fill_rectangle(&tile->draw, &tile->blank, - out_buf->data, out_buf->linesize, - x0, y0, inlink->w, inlink->h); - tile->current++; -} -static int end_last_frame(AVFilterContext *ctx) -{ - TileContext *tile = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out_buf = tile->out_ref; - int ret; - - while (tile->current < tile->nb_frames) - draw_blank_frame(ctx, out_buf); - ret = ff_filter_frame(outlink, out_buf); - tile->current = 0; - return ret; -} - -/* Note: direct rendering is not possible since there is no guarantee that - * buffers are fed to filter_frame in the order they were obtained from - * get_buffer (think B-frames). */ - -static int filter_frame(AVFilterLink *inlink, AVFrame *picref) -{ - AVFilterContext *ctx = inlink->dst; - TileContext *tile = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - unsigned x0, y0; - - if (!tile->current) { - tile->out_ref = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!tile->out_ref) { - av_frame_free(&picref); - return AVERROR(ENOMEM); - } - av_frame_copy_props(tile->out_ref, picref); - tile->out_ref->width = outlink->w; - tile->out_ref->height = outlink->h; - - /* fill surface once for margin/padding */ - if (tile->margin || tile->padding) - ff_fill_rectangle(&tile->draw, &tile->blank, - tile->out_ref->data, - tile->out_ref->linesize, - 0, 0, outlink->w, outlink->h); - } - - get_current_tile_pos(ctx, &x0, &y0); - ff_copy_rectangle2(&tile->draw, - tile->out_ref->data, tile->out_ref->linesize, - picref->data, picref->linesize, - x0, y0, 0, 0, inlink->w, inlink->h); - - av_frame_free(&picref); - if (++tile->current == tile->nb_frames) - return end_last_frame(ctx); - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - TileContext *tile = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - int r; - - r = ff_request_frame(inlink); - if (r == AVERROR_EOF && tile->current) - r = end_last_frame(ctx); - return r; -} - -static const AVFilterPad tile_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad tile_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_props, - .request_frame = request_frame, - }, - { NULL } -}; - -AVFilter ff_vf_tile = { - .name = "tile", - .description = NULL_IF_CONFIG_SMALL("Tile several successive frames together."), - .init = init, - .query_formats = query_formats, - .priv_size = sizeof(TileContext), - .inputs = tile_inputs, - .outputs = tile_outputs, - .priv_class = &tile_class, -}; diff --git a/ffmpeg/libavfilter/vf_tinterlace.c b/ffmpeg/libavfilter/vf_tinterlace.c deleted file mode 100644 index db82393..0000000 --- a/ffmpeg/libavfilter/vf_tinterlace.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2010 Baptiste Coudurier - * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com> - * - * 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 - * temporal field interlace filter, ported from MPlayer/libmpcodecs - */ - -#include "libavutil/opt.h" -#include "libavutil/imgutils.h" -#include "libavutil/avassert.h" -#include "avfilter.h" -#include "internal.h" - -enum TInterlaceMode { - MODE_MERGE = 0, - MODE_DROP_EVEN, - MODE_DROP_ODD, - MODE_PAD, - MODE_INTERLEAVE_TOP, - MODE_INTERLEAVE_BOTTOM, - MODE_INTERLACEX2, - MODE_NB, -}; - -typedef struct { - const AVClass *class; - enum TInterlaceMode mode; ///< interlace mode selected - int flags; ///< flags affecting interlacing algorithm - int frame; ///< number of the output frame - int vsub; ///< chroma vertical subsampling - AVFrame *cur; - AVFrame *next; - uint8_t *black_data[4]; ///< buffer used to fill padded lines - int black_linesize[4]; -} TInterlaceContext; - -#define OFFSET(x) offsetof(TInterlaceContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -#define TINTERLACE_FLAG_VLPF 01 - -static const AVOption tinterlace_options[] = { - {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"}, - {"merge", "merge fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_MERGE}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"drop_even", "drop even fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_EVEN}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"drop_odd", "drop odd fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_ODD}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"pad", "pad alternate lines with black", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PAD}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"interleave_top", "interleave top and bottom fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_TOP}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"interleave_bottom", "interleave bottom and top fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "mode"}, - {"interlacex2", "interlace fields from two consecutive frames", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLACEX2}, INT_MIN, INT_MAX, FLAGS, "mode"}, - - {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" }, - {"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" }, - {"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" }, - - {NULL} -}; - -AVFILTER_DEFINE_CLASS(tinterlace); - -#define FULL_SCALE_YUVJ_FORMATS \ - AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P - -static enum AVPixelFormat full_scale_yuvj_pix_fmts[] = { - FULL_SCALE_YUVJ_FORMATS, AV_PIX_FMT_NONE -}; - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_GRAY8, FULL_SCALE_YUVJ_FORMATS, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - TInterlaceContext *tinterlace = ctx->priv; - - av_frame_free(&tinterlace->cur ); - av_frame_free(&tinterlace->next); - av_freep(&tinterlace->black_data[0]); -} - -static int config_out_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - AVFilterLink *inlink = outlink->src->inputs[0]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); - TInterlaceContext *tinterlace = ctx->priv; - - tinterlace->vsub = desc->log2_chroma_h; - outlink->flags |= FF_LINK_FLAG_REQUEST_LOOP; - outlink->w = inlink->w; - outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD ? - inlink->h*2 : inlink->h; - - if (tinterlace->mode == MODE_PAD) { - uint8_t black[4] = { 16, 128, 128, 16 }; - int i, ret; - if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) - black[0] = black[3] = 0; - ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize, - outlink->w, outlink->h, outlink->format, 1); - if (ret < 0) - return ret; - - /* fill black picture with black */ - for (i = 0; i < 4 && tinterlace->black_data[i]; i++) { - int h = i == 1 || i == 2 ? FF_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h) : outlink->h; - memset(tinterlace->black_data[i], black[i], - tinterlace->black_linesize[i] * h); - } - } - if ((tinterlace->flags & TINTERLACE_FLAG_VLPF) - && !(tinterlace->mode == MODE_INTERLEAVE_TOP - || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) { - av_log(ctx, AV_LOG_WARNING, "low_pass_filter flag ignored with mode %d\n", - tinterlace->mode); - tinterlace->flags &= ~TINTERLACE_FLAG_VLPF; - } - av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", - tinterlace->mode, (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "on" : "off", - inlink->h, outlink->h); - - return 0; -} - -#define FIELD_UPPER 0 -#define FIELD_LOWER 1 -#define FIELD_UPPER_AND_LOWER 2 - -/** - * Copy picture field from src to dst. - * - * @param src_field copy from upper, lower field or both - * @param interleave leave a padding line between each copied line - * @param dst_field copy to upper or lower field, - * only meaningful when interleave is selected - * @param flags context flags - */ -static inline -void copy_picture_field(uint8_t *dst[4], int dst_linesize[4], - const uint8_t *src[4], int src_linesize[4], - enum AVPixelFormat format, int w, int src_h, - int src_field, int interleave, int dst_field, - int flags) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); - int plane, vsub = desc->log2_chroma_h; - int k = src_field == FIELD_UPPER_AND_LOWER ? 1 : 2; - int h, i; - - for (plane = 0; plane < desc->nb_components; plane++) { - int lines = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(src_h, vsub) : src_h; - int linesize = av_image_get_linesize(format, w, plane); - uint8_t *dstp = dst[plane]; - const uint8_t *srcp = src[plane]; - - if (linesize < 0) - return; - - lines = (lines + (src_field == FIELD_UPPER)) / k; - if (src_field == FIELD_LOWER) - srcp += src_linesize[plane]; - if (interleave && dst_field == FIELD_LOWER) - dstp += dst_linesize[plane]; - if (flags & TINTERLACE_FLAG_VLPF) { - // Low-pass filtering is required when creating an interlaced destination from - // a progressive source which contains high-frequency vertical detail. - // Filtering will reduce interlace 'twitter' and Moire patterning. - int srcp_linesize = src_linesize[plane] * k; - int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1); - for (h = lines; h > 0; h--) { - const uint8_t *srcp_above = srcp - src_linesize[plane]; - const uint8_t *srcp_below = srcp + src_linesize[plane]; - if (h == lines) srcp_above = srcp; // there is no line above - if (h == 1) srcp_below = srcp; // there is no line below - for (i = 0; i < linesize; i++) { - // this calculation is an integer representation of - // '0.5 * current + 0.25 * above + 0.25 * below' - // '1 +' is for rounding. */ - dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2; - } - dstp += dstp_linesize; - srcp += srcp_linesize; - } - } else { - av_image_copy_plane(dstp, dst_linesize[plane] * (interleave ? 2 : 1), - srcp, src_linesize[plane]*k, linesize, lines); - } - } -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *picref) -{ - AVFilterContext *ctx = inlink->dst; - AVFilterLink *outlink = ctx->outputs[0]; - TInterlaceContext *tinterlace = ctx->priv; - AVFrame *cur, *next, *out; - int field, tff, ret; - - av_frame_free(&tinterlace->cur); - tinterlace->cur = tinterlace->next; - tinterlace->next = picref; - - cur = tinterlace->cur; - next = tinterlace->next; - /* we need at least two frames */ - if (!tinterlace->cur) - return 0; - - switch (tinterlace->mode) { - case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into - * the lower field, generating a double-height video at half framerate */ - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) - return AVERROR(ENOMEM); - av_frame_copy_props(out, cur); - out->height = outlink->h; - out->interlaced_frame = 1; - out->top_field_first = 1; - - /* write odd frame lines into the upper field of the new frame */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)cur->data, cur->linesize, - inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, FIELD_UPPER, tinterlace->flags); - /* write even frame lines into the lower field of the new frame */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)next->data, next->linesize, - inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, FIELD_LOWER, tinterlace->flags); - av_frame_free(&tinterlace->next); - break; - - case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */ - case MODE_DROP_EVEN: /* only output odd frames, even frames are dropped; height unchanged, half framerate */ - out = av_frame_clone(tinterlace->mode == MODE_DROP_EVEN ? cur : next); - if (!out) - return AVERROR(ENOMEM); - av_frame_free(&tinterlace->next); - break; - - case MODE_PAD: /* expand each frame to double height, but pad alternate - * lines with black; framerate unchanged */ - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) - return AVERROR(ENOMEM); - av_frame_copy_props(out, cur); - out->height = outlink->h; - - field = (1 + tinterlace->frame) & 1 ? FIELD_UPPER : FIELD_LOWER; - /* copy upper and lower fields */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)cur->data, cur->linesize, - inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags); - /* pad with black the other field */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)tinterlace->black_data, tinterlace->black_linesize, - inlink->format, inlink->w, inlink->h, - FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags); - break; - - /* interleave upper/lower lines from odd frames with lower/upper lines from even frames, - * halving the frame rate and preserving image height */ - case MODE_INTERLEAVE_TOP: /* top field first */ - case MODE_INTERLEAVE_BOTTOM: /* bottom field first */ - tff = tinterlace->mode == MODE_INTERLEAVE_TOP; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) - return AVERROR(ENOMEM); - av_frame_copy_props(out, cur); - out->interlaced_frame = 1; - out->top_field_first = tff; - - /* copy upper/lower field from cur */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)cur->data, cur->linesize, - inlink->format, inlink->w, inlink->h, - tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER, - tinterlace->flags); - /* copy lower/upper field from next */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)next->data, next->linesize, - inlink->format, inlink->w, inlink->h, - tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER, - tinterlace->flags); - av_frame_free(&tinterlace->next); - break; - case MODE_INTERLACEX2: /* re-interlace preserving image height, double frame rate */ - /* output current frame first */ - out = av_frame_clone(cur); - if (!out) - return AVERROR(ENOMEM); - out->interlaced_frame = 1; - - if ((ret = ff_filter_frame(outlink, out)) < 0) - return ret; - - /* output mix of current and next frame */ - tff = next->top_field_first; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) - return AVERROR(ENOMEM); - av_frame_copy_props(out, next); - out->interlaced_frame = 1; - - /* write current frame second field lines into the second field of the new frame */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)cur->data, cur->linesize, - inlink->format, inlink->w, inlink->h, - tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER, - tinterlace->flags); - /* write next frame first field lines into the first field of the new frame */ - copy_picture_field(out->data, out->linesize, - (const uint8_t **)next->data, next->linesize, - inlink->format, inlink->w, inlink->h, - tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER, - tinterlace->flags); - break; - default: - av_assert0(0); - } - - ret = ff_filter_frame(outlink, out); - tinterlace->frame++; - - return ret; -} - -static const AVFilterPad tinterlace_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad tinterlace_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .config_props = config_out_props, - }, - { NULL } -}; - -AVFilter ff_vf_tinterlace = { - .name = "tinterlace", - .description = NULL_IF_CONFIG_SMALL("Perform temporal field interlacing."), - .priv_size = sizeof(TInterlaceContext), - .uninit = uninit, - .query_formats = query_formats, - .inputs = tinterlace_inputs, - .outputs = tinterlace_outputs, - .priv_class = &tinterlace_class, -}; diff --git a/ffmpeg/libavfilter/vf_transpose.c b/ffmpeg/libavfilter/vf_transpose.c deleted file mode 100644 index 7e471d4..0000000 --- a/ffmpeg/libavfilter/vf_transpose.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * Copyright (c) 2008 Vitor Sessak - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * transposition filter - * Based on MPlayer libmpcodecs/vf_rotate.c. - */ - -#include <stdio.h> - -#include "libavutil/intreadwrite.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/internal.h" -#include "libavutil/opt.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef enum { - TRANSPOSE_PT_TYPE_NONE, - TRANSPOSE_PT_TYPE_LANDSCAPE, - TRANSPOSE_PT_TYPE_PORTRAIT, -} PassthroughType; - -enum TransposeDir { - TRANSPOSE_CCLOCK_FLIP, - TRANSPOSE_CLOCK, - TRANSPOSE_CCLOCK, - TRANSPOSE_CLOCK_FLIP, -}; - -typedef struct { - const AVClass *class; - int hsub, vsub; - int pixsteps[4]; - - PassthroughType passthrough; ///< landscape passthrough mode enabled - enum TransposeDir dir; -} TransContext; - -static int query_formats(AVFilterContext *ctx) -{ - AVFilterFormats *pix_fmts = NULL; - int fmt; - - for (fmt = 0; fmt < AV_PIX_FMT_NB; fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM || - desc->log2_chroma_w != desc->log2_chroma_h)) - ff_add_format(&pix_fmts, fmt); - } - - - ff_set_common_formats(ctx, pix_fmts); - return 0; -} - -static int config_props_output(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - TransContext *trans = ctx->priv; - AVFilterLink *inlink = ctx->inputs[0]; - const AVPixFmtDescriptor *desc_out = av_pix_fmt_desc_get(outlink->format); - const AVPixFmtDescriptor *desc_in = av_pix_fmt_desc_get(inlink->format); - - if (trans->dir&4) { - av_log(ctx, AV_LOG_WARNING, - "dir values greater than 3 are deprecated, use the passthrough option instead\n"); - trans->dir &= 3; - trans->passthrough = TRANSPOSE_PT_TYPE_LANDSCAPE; - } - - if ((inlink->w >= inlink->h && trans->passthrough == TRANSPOSE_PT_TYPE_LANDSCAPE) || - (inlink->w <= inlink->h && trans->passthrough == TRANSPOSE_PT_TYPE_PORTRAIT)) { - av_log(ctx, AV_LOG_VERBOSE, - "w:%d h:%d -> w:%d h:%d (passthrough mode)\n", - inlink->w, inlink->h, inlink->w, inlink->h); - return 0; - } else { - trans->passthrough = TRANSPOSE_PT_TYPE_NONE; - } - - trans->hsub = desc_in->log2_chroma_w; - trans->vsub = desc_in->log2_chroma_h; - - av_image_fill_max_pixsteps(trans->pixsteps, NULL, desc_out); - - outlink->w = inlink->h; - outlink->h = inlink->w; - - if (inlink->sample_aspect_ratio.num){ - outlink->sample_aspect_ratio = av_div_q((AVRational){1,1}, inlink->sample_aspect_ratio); - } else - outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n", - inlink->w, inlink->h, trans->dir, outlink->w, outlink->h, - trans->dir == 1 || trans->dir == 3 ? "clockwise" : "counterclockwise", - trans->dir == 0 || trans->dir == 3); - return 0; -} - -static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h) -{ - TransContext *trans = inlink->dst->priv; - - return trans->passthrough ? - ff_null_get_video_buffer (inlink, w, h) : - ff_default_get_video_buffer(inlink, w, h); -} - -typedef struct ThreadData { - AVFrame *in, *out; -} ThreadData; - -static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, - int nb_jobs) -{ - TransContext *trans = ctx->priv; - ThreadData *td = arg; - AVFrame *out = td->out; - AVFrame *in = td->in; - int plane; - - for (plane = 0; out->data[plane]; plane++) { - int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; - int vsub = plane == 1 || plane == 2 ? trans->vsub : 0; - int pixstep = trans->pixsteps[plane]; - int inh = in->height >> vsub; - int outw = FF_CEIL_RSHIFT(out->width, hsub); - int outh = FF_CEIL_RSHIFT(out->height, vsub); - int start = (outh * jobnr ) / nb_jobs; - int end = (outh * (jobnr+1)) / nb_jobs; - uint8_t *dst, *src; - int dstlinesize, srclinesize; - int x, y; - - dstlinesize = out->linesize[plane]; - dst = out->data[plane] + start * dstlinesize; - src = in->data[plane]; - srclinesize = in->linesize[plane]; - - if (trans->dir&1) { - src += in->linesize[plane] * (inh-1); - srclinesize *= -1; - } - - if (trans->dir&2) { - dst = out->data[plane] + dstlinesize * (outh-start-1); - dstlinesize *= -1; - } - - switch (pixstep) { - case 1: - for (y = start; y < end; y++, dst += dstlinesize) - for (x = 0; x < outw; x++) - dst[x] = src[x*srclinesize + y]; - break; - case 2: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint16_t *)(dst + 2*x)) = *((uint16_t *)(src + x*srclinesize + y*2)); - } - break; - case 3: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) { - int32_t v = AV_RB24(src + x*srclinesize + y*3); - AV_WB24(dst + 3*x, v); - } - } - break; - case 4: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*srclinesize + y*4)); - } - break; - case 6: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) { - int64_t v = AV_RB48(src + x*srclinesize + y*6); - AV_WB48(dst + 6*x, v); - } - } - break; - case 8: - for (y = start; y < end; y++, dst += dstlinesize) { - for (x = 0; x < outw; x++) - *((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x*srclinesize + y*8)); - } - break; - } - } - - return 0; -} - -static int filter_frame(AVFilterLink *inlink, AVFrame *in) -{ - AVFilterContext *ctx = inlink->dst; - TransContext *trans = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - ThreadData td; - AVFrame *out; - - if (trans->passthrough) - return ff_filter_frame(outlink, in); - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - - if (in->sample_aspect_ratio.num == 0) { - out->sample_aspect_ratio = in->sample_aspect_ratio; - } else { - out->sample_aspect_ratio.num = in->sample_aspect_ratio.den; - out->sample_aspect_ratio.den = in->sample_aspect_ratio.num; - } - - td.in = in, td.out = out; - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads)); - av_frame_free(&in); - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(TransContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption transpose_options[] = { - { "dir", "set transpose direction", OFFSET(dir), AV_OPT_TYPE_INT, { .i64 = TRANSPOSE_CCLOCK_FLIP }, 0, 7, FLAGS, "dir" }, - { "cclock_flip", "rotate counter-clockwise with vertical flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .unit = "dir" }, - { "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .unit = "dir" }, - { "cclock", "rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .unit = "dir" }, - { "clock_flip", "rotate clockwise with vertical flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .unit = "dir" }, - - { "passthrough", "do not apply transposition if the input matches the specified geometry", - OFFSET(passthrough), AV_OPT_TYPE_INT, {.i64=TRANSPOSE_PT_TYPE_NONE}, 0, INT_MAX, FLAGS, "passthrough" }, - { "none", "always apply transposition", 0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_NONE}, INT_MIN, INT_MAX, FLAGS, "passthrough" }, - { "portrait", "preserve portrait geometry", 0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_PORTRAIT}, INT_MIN, INT_MAX, FLAGS, "passthrough" }, - { "landscape", "preserve landscape geometry", 0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_LANDSCAPE}, INT_MIN, INT_MAX, FLAGS, "passthrough" }, - - { NULL } -}; - -AVFILTER_DEFINE_CLASS(transpose); - -static const AVFilterPad avfilter_vf_transpose_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = get_video_buffer, - .filter_frame = filter_frame, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_transpose_outputs[] = { - { - .name = "default", - .config_props = config_props_output, - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_transpose = { - .name = "transpose", - .description = NULL_IF_CONFIG_SMALL("Transpose input video."), - .priv_size = sizeof(TransContext), - .priv_class = &transpose_class, - .query_formats = query_formats, - .inputs = avfilter_vf_transpose_inputs, - .outputs = avfilter_vf_transpose_outputs, - .flags = AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/vf_unsharp.c b/ffmpeg/libavfilter/vf_unsharp.c deleted file mode 100644 index b9f6821..0000000 --- a/ffmpeg/libavfilter/vf_unsharp.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Original copyright (c) 2002 Remi Guyomarch <rguyom@pobox.com> - * Port copyright (c) 2010 Daniel G. Taylor <dan@programmer-art.org> - * Relicensed to the LGPL with permission from Remi Guyomarch. - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * blur / sharpen filter, ported to FFmpeg from MPlayer - * libmpcodecs/unsharp.c. - * - * This code is based on: - * - * An Efficient algorithm for Gaussian blur using finite-state machines - * Frederick M. Waltz and John W. V. Miller - * - * SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII - * Originally published Boston, Nov 98 - * - * http://www.engin.umd.umich.edu/~jwvm/ece581/21_GBlur.pdf - */ - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/common.h" -#include "libavutil/imgutils.h" -#include "libavutil/mem.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "unsharp.h" -#include "unsharp_opencl.h" - -static void apply_unsharp( uint8_t *dst, int dst_stride, - const uint8_t *src, int src_stride, - int width, int height, UnsharpFilterParam *fp) -{ - uint32_t **sc = fp->sc; - uint32_t sr[MAX_MATRIX_SIZE - 1], tmp1, tmp2; - - int32_t res; - int x, y, z; - const uint8_t *src2 = NULL; //silence a warning - const int amount = fp->amount; - const int steps_x = fp->steps_x; - const int steps_y = fp->steps_y; - const int scalebits = fp->scalebits; - const int32_t halfscale = fp->halfscale; - - if (!amount) { - av_image_copy_plane(dst, dst_stride, src, src_stride, width, height); - return; - } - - for (y = 0; y < 2 * steps_y; y++) - memset(sc[y], 0, sizeof(sc[y][0]) * (width + 2 * steps_x)); - - for (y = -steps_y; y < height + steps_y; y++) { - if (y < height) - src2 = src; - - memset(sr, 0, sizeof(sr[0]) * (2 * steps_x - 1)); - for (x = -steps_x; x < width + steps_x; x++) { - tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width-1] : src2[x]; - for (z = 0; z < steps_x * 2; z += 2) { - tmp2 = sr[z + 0] + tmp1; sr[z + 0] = tmp1; - tmp1 = sr[z + 1] + tmp2; sr[z + 1] = tmp2; - } - for (z = 0; z < steps_y * 2; z += 2) { - tmp2 = sc[z + 0][x + steps_x] + tmp1; sc[z + 0][x + steps_x] = tmp1; - tmp1 = sc[z + 1][x + steps_x] + tmp2; sc[z + 1][x + steps_x] = tmp2; - } - if (x >= steps_x && y >= steps_y) { - const uint8_t *srx = src - steps_y * src_stride + x - steps_x; - uint8_t *dsx = dst - steps_y * dst_stride + x - steps_x; - - res = (int32_t)*srx + ((((int32_t) * srx - (int32_t)((tmp1 + halfscale) >> scalebits)) * amount) >> 16); - *dsx = av_clip_uint8(res); - } - } - if (y >= 0) { - dst += dst_stride; - src += src_stride; - } - } -} - -static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out) -{ - AVFilterLink *inlink = ctx->inputs[0]; - UnsharpContext *unsharp = ctx->priv; - int i, plane_w[3], plane_h[3]; - UnsharpFilterParam *fp[3]; - plane_w[0] = inlink->w; - plane_w[1] = plane_w[2] = FF_CEIL_RSHIFT(inlink->w, unsharp->hsub); - plane_h[0] = inlink->h; - plane_h[1] = plane_h[2] = FF_CEIL_RSHIFT(inlink->h, unsharp->vsub); - fp[0] = &unsharp->luma; - fp[1] = fp[2] = &unsharp->chroma; - for (i = 0; i < 3; i++) { - apply_unsharp(out->data[i], out->linesize[i], in->data[i], in->linesize[i], plane_w[i], plane_h[i], fp[i]); - } - return 0; -} - -static void set_filter_param(UnsharpFilterParam *fp, int msize_x, int msize_y, float amount) -{ - fp->msize_x = msize_x; - fp->msize_y = msize_y; - fp->amount = amount * 65536.0; - - fp->steps_x = msize_x / 2; - fp->steps_y = msize_y / 2; - fp->scalebits = (fp->steps_x + fp->steps_y) * 2; - fp->halfscale = 1 << (fp->scalebits - 1); -} - -static av_cold int init(AVFilterContext *ctx) -{ - int ret = 0; - UnsharpContext *unsharp = ctx->priv; - - - set_filter_param(&unsharp->luma, unsharp->lmsize_x, unsharp->lmsize_y, unsharp->lamount); - set_filter_param(&unsharp->chroma, unsharp->cmsize_x, unsharp->cmsize_y, unsharp->camount); - - unsharp->apply_unsharp = apply_unsharp_c; - if (!CONFIG_OPENCL && unsharp->opencl) { - av_log(ctx, AV_LOG_ERROR, "OpenCL support was not enabled in this build, cannot be selected\n"); - return AVERROR(EINVAL); - } - if (CONFIG_OPENCL && unsharp->opencl) { - unsharp->apply_unsharp = ff_opencl_apply_unsharp; - ret = ff_opencl_unsharp_init(ctx); - if (ret < 0) - return ret; - } - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int init_filter_param(AVFilterContext *ctx, UnsharpFilterParam *fp, const char *effect_type, int width) -{ - int z; - const char *effect = fp->amount == 0 ? "none" : fp->amount < 0 ? "blur" : "sharpen"; - - if (!(fp->msize_x & fp->msize_y & 1)) { - av_log(ctx, AV_LOG_ERROR, - "Invalid even size for %s matrix size %dx%d\n", - effect_type, fp->msize_x, fp->msize_y); - return AVERROR(EINVAL); - } - - av_log(ctx, AV_LOG_VERBOSE, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n", - effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0); - - for (z = 0; z < 2 * fp->steps_y; z++) - if (!(fp->sc[z] = av_malloc(sizeof(*(fp->sc[z])) * (width + 2 * fp->steps_x)))) - return AVERROR(ENOMEM); - - return 0; -} - -static int config_props(AVFilterLink *link) -{ - UnsharpContext *unsharp = link->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - int ret; - - unsharp->hsub = desc->log2_chroma_w; - unsharp->vsub = desc->log2_chroma_h; - - ret = init_filter_param(link->dst, &unsharp->luma, "luma", link->w); - if (ret < 0) - return ret; - ret = init_filter_param(link->dst, &unsharp->chroma, "chroma", FF_CEIL_RSHIFT(link->w, unsharp->hsub)); - if (ret < 0) - return ret; - - return 0; -} - -static void free_filter_param(UnsharpFilterParam *fp) -{ - int z; - - for (z = 0; z < 2 * fp->steps_y; z++) - av_free(fp->sc[z]); -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - UnsharpContext *unsharp = ctx->priv; - - if (CONFIG_OPENCL && unsharp->opencl) { - ff_opencl_unsharp_uninit(ctx); - } - - free_filter_param(&unsharp->luma); - free_filter_param(&unsharp->chroma); -} - -static int filter_frame(AVFilterLink *link, AVFrame *in) -{ - UnsharpContext *unsharp = link->dst->priv; - AVFilterLink *outlink = link->dst->outputs[0]; - AVFrame *out; - int ret = 0; - - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } - av_frame_copy_props(out, in); - if (CONFIG_OPENCL && unsharp->opencl) { - ret = ff_opencl_unsharp_process_inout_buf(link->dst, in, out); - if (ret < 0) - goto end; - } - - ret = unsharp->apply_unsharp(link->dst, in, out); -end: - av_frame_free(&in); - - if (ret < 0) - return ret; - return ff_filter_frame(outlink, out); -} - -#define OFFSET(x) offsetof(UnsharpContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -#define MIN_SIZE 3 -#define MAX_SIZE 63 -static const AVOption unsharp_options[] = { - { "luma_msize_x", "set luma matrix horizontal size", OFFSET(lmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "lx", "set luma matrix horizontal size", OFFSET(lmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "luma_msize_y", "set luma matrix vertical size", OFFSET(lmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "ly", "set luma matrix vertical size", OFFSET(lmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "luma_amount", "set luma effect strength", OFFSET(lamount), AV_OPT_TYPE_FLOAT, { .dbl = 1 }, -2, 5, FLAGS }, - { "la", "set luma effect strength", OFFSET(lamount), AV_OPT_TYPE_FLOAT, { .dbl = 1 }, -2, 5, FLAGS }, - { "chroma_msize_x", "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "cx", "set chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "chroma_msize_y", "set chroma matrix vertical size", OFFSET(cmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "cy", "set chroma matrix vertical size", OFFSET(cmsize_y), AV_OPT_TYPE_INT, { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS }, - { "chroma_amount", "set chroma effect strength", OFFSET(camount), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, -2, 5, FLAGS }, - { "ca", "set chroma effect strength", OFFSET(camount), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, -2, 5, FLAGS }, - { "opencl", "use OpenCL filtering capabilities", OFFSET(opencl), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(unsharp); - -static const AVFilterPad avfilter_vf_unsharp_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - .config_props = config_props, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_unsharp_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_unsharp = { - .name = "unsharp", - .description = NULL_IF_CONFIG_SMALL("Sharpen or blur the input video."), - .priv_size = sizeof(UnsharpContext), - .priv_class = &unsharp_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = avfilter_vf_unsharp_inputs, - .outputs = avfilter_vf_unsharp_outputs, - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, -}; diff --git a/ffmpeg/libavfilter/vf_vflip.c b/ffmpeg/libavfilter/vf_vflip.c deleted file mode 100644 index f6908e4..0000000 --- a/ffmpeg/libavfilter/vf_vflip.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * video vertical flip filter - */ - -#include "libavutil/internal.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -typedef struct { - int vsub; ///< vertical chroma subsampling -} FlipContext; - -static int config_input(AVFilterLink *link) -{ - FlipContext *flip = link->dst->priv; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format); - - flip->vsub = desc->log2_chroma_h; - - return 0; -} - -static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h) -{ - FlipContext *flip = link->dst->priv; - AVFrame *frame; - int i; - - frame = ff_get_video_buffer(link->dst->outputs[0], w, h); - if (!frame) - return NULL; - - for (i = 0; i < 4; i ++) { - int vsub = i == 1 || i == 2 ? flip->vsub : 0; - int height = FF_CEIL_RSHIFT(h, vsub); - - if (frame->data[i]) { - frame->data[i] += (height - 1) * frame->linesize[i]; - frame->linesize[i] = -frame->linesize[i]; - } - } - - return frame; -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - FlipContext *flip = link->dst->priv; - int i; - - for (i = 0; i < 4; i ++) { - int vsub = i == 1 || i == 2 ? flip->vsub : 0; - int height = FF_CEIL_RSHIFT(link->h, vsub); - - if (frame->data[i]) { - frame->data[i] += (height - 1) * frame->linesize[i]; - frame->linesize[i] = -frame->linesize[i]; - } - } - - return ff_filter_frame(link->dst->outputs[0], frame); -} -static const AVFilterPad avfilter_vf_vflip_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = get_video_buffer, - .filter_frame = filter_frame, - .config_props = config_input, - }, - { NULL } -}; - -static const AVFilterPad avfilter_vf_vflip_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - }, - { NULL } -}; - -AVFilter ff_vf_vflip = { - .name = "vflip", - .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."), - .priv_size = sizeof(FlipContext), - .inputs = avfilter_vf_vflip_inputs, - .outputs = avfilter_vf_vflip_outputs, -}; diff --git a/ffmpeg/libavfilter/vf_yadif.c b/ffmpeg/libavfilter/vf_yadif.c deleted file mode 100644 index 40383a4..0000000 --- a/ffmpeg/libavfilter/vf_yadif.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at> - * 2010 James Darnley <james.darnley@gmail.com> - * - * 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/avassert.h" -#include "libavutil/cpu.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/imgutils.h" -#include "libavutil/x86/asm.h" -#include "libavutil/x86/cpu.h" -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "yadif.h" - - -typedef struct ThreadData { - AVFrame *frame; - int plane; - int w, h; - int parity; - int tff; -} ThreadData; - -typedef struct YADIFContext { - const AVClass *class; - - enum YADIFMode mode; - enum YADIFParity parity; - enum YADIFDeint deint; - - int frame_pending; - - AVFrame *cur; - AVFrame *next; - AVFrame *prev; - AVFrame *out; - - /** - * Required alignment for filter_line - */ - void (*filter_line)(void *dst, - void *prev, void *cur, void *next, - int w, int prefs, int mrefs, int parity, int mode); - void (*filter_edges)(void *dst, void *prev, void *cur, void *next, - int w, int prefs, int mrefs, int parity, int mode); - - const AVPixFmtDescriptor *csp; - int eof; - uint8_t *temp_line; - int temp_line_size; -} YADIFContext; - -#define CHECK(j)\ - { int score = FFABS(cur[mrefs - 1 + j] - cur[prefs - 1 - j])\ - + FFABS(cur[mrefs + j] - cur[prefs - j])\ - + FFABS(cur[mrefs + 1 + j] - cur[prefs + 1 - j]);\ - if (score < spatial_score) {\ - spatial_score= score;\ - spatial_pred= (cur[mrefs + j] + cur[prefs - j])>>1;\ - -/* The is_not_edge argument here controls when the code will enter a branch - * which reads up to and including x-3 and x+3. */ - -#define FILTER(start, end, is_not_edge) \ - for (x = start; x < end; x++) { \ - int c = cur[mrefs]; \ - int d = (prev2[0] + next2[0])>>1; \ - int e = cur[prefs]; \ - int temporal_diff0 = FFABS(prev2[0] - next2[0]); \ - int temporal_diff1 =(FFABS(prev[mrefs] - c) + FFABS(prev[prefs] - e) )>>1; \ - int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \ - int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \ - int spatial_pred = (c+e) >> 1; \ - \ - if (is_not_edge) {\ - int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \ - + FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \ - CHECK(-1) CHECK(-2) }} }} \ - CHECK( 1) CHECK( 2) }} }} \ - }\ - \ - if (!(mode&2)) { \ - int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \ - int f = (prev2[2 * prefs] + next2[2 * prefs])>>1; \ - int max = FFMAX3(d - e, d - c, FFMIN(b - c, f - e)); \ - int min = FFMIN3(d - e, d - c, FFMAX(b - c, f - e)); \ - \ - diff = FFMAX3(diff, min, -max); \ - } \ - \ - if (spatial_pred > d + diff) \ - spatial_pred = d + diff; \ - else if (spatial_pred < d - diff) \ - spatial_pred = d - diff; \ - \ - dst[0] = spatial_pred; \ - \ - dst++; \ - cur++; \ - prev++; \ - next++; \ - prev2++; \ - next2++; \ - } - -static void filter_line_c(void *dst1, - void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int parity, int mode) -{ - uint8_t *dst = dst1; - uint8_t *prev = prev1; - uint8_t *cur = cur1; - uint8_t *next = next1; - int x; - uint8_t *prev2 = parity ? prev : cur ; - uint8_t *next2 = parity ? cur : next; - - /* The function is called with the pointers already pointing to data[3] and - * with 6 subtracted from the width. This allows the FILTER macro to be - * called so that it processes all the pixels normally. A constant value of - * true for is_not_edge lets the compiler ignore the if statement. */ - FILTER(0, w, 1) -} - -#define MAX_ALIGN 8 -static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int parity, int mode) -{ - uint8_t *dst = dst1; - uint8_t *prev = prev1; - uint8_t *cur = cur1; - uint8_t *next = next1; - int x; - uint8_t *prev2 = parity ? prev : cur ; - uint8_t *next2 = parity ? cur : next; - - /* Only edge pixels need to be processed here. A constant value of false - * for is_not_edge should let the compiler ignore the whole branch. */ - FILTER(0, 3, 0) - - dst = (uint8_t*)dst1 + w - (MAX_ALIGN-1); - prev = (uint8_t*)prev1 + w - (MAX_ALIGN-1); - cur = (uint8_t*)cur1 + w - (MAX_ALIGN-1); - next = (uint8_t*)next1 + w - (MAX_ALIGN-1); - prev2 = (uint8_t*)(parity ? prev : cur); - next2 = (uint8_t*)(parity ? cur : next); - - FILTER(w - (MAX_ALIGN-1), w - 3, 1) - FILTER(w - 3, w, 0) -} - - -static void filter_line_c_16bit(void *dst1, - void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int parity, - int mode) -{ - uint16_t *dst = dst1; - uint16_t *prev = prev1; - uint16_t *cur = cur1; - uint16_t *next = next1; - int x; - uint16_t *prev2 = parity ? prev : cur ; - uint16_t *next2 = parity ? cur : next; - mrefs /= 2; - prefs /= 2; - - FILTER(0, w, 1) -} - -static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, - int w, int prefs, int mrefs, int parity, int mode) -{ - uint16_t *dst = dst1; - uint16_t *prev = prev1; - uint16_t *cur = cur1; - uint16_t *next = next1; - int x; - uint16_t *prev2 = parity ? prev : cur ; - uint16_t *next2 = parity ? cur : next; - mrefs /= 2; - prefs /= 2; - - FILTER(0, 3, 0) - - dst = (uint16_t*)dst1 + w - (MAX_ALIGN/2-1); - prev = (uint16_t*)prev1 + w - (MAX_ALIGN/2-1); - cur = (uint16_t*)cur1 + w - (MAX_ALIGN/2-1); - next = (uint16_t*)next1 + w - (MAX_ALIGN/2-1); - prev2 = (uint16_t*)(parity ? prev : cur); - next2 = (uint16_t*)(parity ? cur : next); - - FILTER(w - (MAX_ALIGN/2-1), w - 3, 1) - FILTER(w - 3, w, 0) -} - -static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - YADIFContext *s = ctx->priv; - ThreadData *td = arg; - int refs = s->cur->linesize[td->plane]; - int df = (s->csp->comp[td->plane].depth_minus1 + 8) / 8; - int pix_3 = 3 * df; - int slice_start = (td->h * jobnr ) / nb_jobs; - int slice_end = (td->h * (jobnr+1)) / nb_jobs; - int y; - - /* filtering reads 3 pixels to the left/right; to avoid invalid reads, - * we need to call the c variant which avoids this for border pixels - */ - for (y = slice_start; y < slice_end; y++) { - if ((y ^ td->parity) & 1) { - uint8_t *prev = &s->prev->data[td->plane][y * refs]; - uint8_t *cur = &s->cur ->data[td->plane][y * refs]; - uint8_t *next = &s->next->data[td->plane][y * refs]; - uint8_t *dst = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]]; - int mode = y == 1 || y + 2 == td->h ? 2 : s->mode; - s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3, - next + pix_3, td->w - (3 + MAX_ALIGN/df-1), - y + 1 < td->h ? refs : -refs, - y ? -refs : refs, - td->parity ^ td->tff, mode); - s->filter_edges(dst, prev, cur, next, td->w, - y + 1 < td->h ? refs : -refs, - y ? -refs : refs, - td->parity ^ td->tff, mode); - } else { - memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]], - &s->cur->data[td->plane][y * refs], td->w * df); - } - } - return 0; -} - -static void filter(AVFilterContext *ctx, AVFrame *dstpic, - int parity, int tff) -{ - YADIFContext *yadif = ctx->priv; - ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; - int i; - - for (i = 0; i < yadif->csp->nb_components; i++) { - int w = dstpic->width; - int h = dstpic->height; - - if (i == 1 || i == 2) { - w = FF_CEIL_RSHIFT(w, yadif->csp->log2_chroma_w); - h = FF_CEIL_RSHIFT(h, yadif->csp->log2_chroma_h); - } - - - td.w = w; - td.h = h; - td.plane = i; - - ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads)); - } - - emms_c(); -} - -static int return_frame(AVFilterContext *ctx, int is_second) -{ - YADIFContext *yadif = ctx->priv; - AVFilterLink *link = ctx->outputs[0]; - int tff, ret; - - if (yadif->parity == -1) { - tff = yadif->cur->interlaced_frame ? - yadif->cur->top_field_first : 1; - } else { - tff = yadif->parity ^ 1; - } - - if (is_second) { - yadif->out = ff_get_video_buffer(link, link->w, link->h); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_copy_props(yadif->out, yadif->cur); - yadif->out->interlaced_frame = 0; - } - - filter(ctx, yadif->out, tff ^ !is_second, tff); - - if (is_second) { - int64_t cur_pts = yadif->cur->pts; - int64_t next_pts = yadif->next->pts; - - if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) { - yadif->out->pts = cur_pts + next_pts; - } else { - yadif->out->pts = AV_NOPTS_VALUE; - } - } - ret = ff_filter_frame(ctx->outputs[0], yadif->out); - - yadif->frame_pending = (yadif->mode&1) && !is_second; - return ret; -} - -static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b) -{ - int i; - for (i = 0; i < yadif->csp->nb_components; i++) - if (a->linesize[i] != b->linesize[i]) - return 1; - return 0; -} - -static void fixstride(AVFilterLink *link, AVFrame *f) -{ - AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height); - if(!dst) - return; - av_frame_copy_props(dst, f); - av_image_copy(dst->data, dst->linesize, - (const uint8_t **)f->data, f->linesize, - dst->format, dst->width, dst->height); - av_frame_unref(f); - av_frame_move_ref(f, dst); - av_frame_free(&dst); -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AVFilterContext *ctx = link->dst; - YADIFContext *yadif = ctx->priv; - - av_assert0(frame); - - if (yadif->frame_pending) - return_frame(ctx, 1); - - if (yadif->prev) - av_frame_free(&yadif->prev); - yadif->prev = yadif->cur; - yadif->cur = yadif->next; - yadif->next = frame; - - if (!yadif->cur) - return 0; - - if (checkstride(yadif, yadif->next, yadif->cur)) { - av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); - fixstride(link, yadif->next); - } - if (checkstride(yadif, yadif->next, yadif->cur)) - fixstride(link, yadif->cur); - if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev)) - fixstride(link, yadif->prev); - if (checkstride(yadif, yadif->next, yadif->cur) || (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))) { - av_log(ctx, AV_LOG_ERROR, "Failed to reallocate frame\n"); - return -1; - } - - if ((yadif->deint && !yadif->cur->interlaced_frame) || ctx->is_disabled) { - yadif->out = av_frame_clone(yadif->cur); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_free(&yadif->prev); - if (yadif->out->pts != AV_NOPTS_VALUE) - yadif->out->pts *= 2; - return ff_filter_frame(ctx->outputs[0], yadif->out); - } - - if (!yadif->prev && - !(yadif->prev = av_frame_clone(yadif->cur))) - return AVERROR(ENOMEM); - - yadif->out = ff_get_video_buffer(ctx->outputs[0], link->w, link->h); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_copy_props(yadif->out, yadif->cur); - yadif->out->interlaced_frame = 0; - - if (yadif->out->pts != AV_NOPTS_VALUE) - yadif->out->pts *= 2; - - return return_frame(ctx, 0); -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - YADIFContext *yadif = ctx->priv; - - if (yadif->frame_pending) { - return_frame(ctx, 1); - return 0; - } - - do { - int ret; - - if (yadif->eof) - return AVERROR_EOF; - - ret = ff_request_frame(link->src->inputs[0]); - - if (ret == AVERROR_EOF && yadif->cur) { - AVFrame *next = av_frame_clone(yadif->next); - - if (!next) - return AVERROR(ENOMEM); - - next->pts = yadif->next->pts * 2 - yadif->cur->pts; - - filter_frame(link->src->inputs[0], next); - yadif->eof = 1; - } else if (ret < 0) { - return ret; - } - } while (!yadif->cur); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - YADIFContext *yadif = ctx->priv; - - av_frame_free(&yadif->prev); - av_frame_free(&yadif->cur ); - av_frame_free(&yadif->next); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_GRAY16, - AV_PIX_FMT_YUV440P, - AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUV420P9, - AV_PIX_FMT_YUV422P9, - AV_PIX_FMT_YUV444P9, - AV_PIX_FMT_YUV420P10, - AV_PIX_FMT_YUV422P10, - AV_PIX_FMT_YUV444P10, - AV_PIX_FMT_YUV420P12, - AV_PIX_FMT_YUV422P12, - AV_PIX_FMT_YUV444P12, - AV_PIX_FMT_YUV420P14, - AV_PIX_FMT_YUV422P14, - AV_PIX_FMT_YUV444P14, - AV_PIX_FMT_YUV420P16, - AV_PIX_FMT_YUV422P16, - AV_PIX_FMT_YUV444P16, - AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUVA422P, - AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRAP, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - - return 0; -} - -static int config_props(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - YADIFContext *s = link->src->priv; - int cpu_flags = av_get_cpu_flags(); - int bit_depth = (!s->csp) ? 8 - : s->csp->comp[0].depth_minus1 + 1; - - link->time_base.num = link->src->inputs[0]->time_base.num; - link->time_base.den = link->src->inputs[0]->time_base.den * 2; - link->w = link->src->inputs[0]->w; - link->h = link->src->inputs[0]->h; - - if(s->mode&1) - link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1}); - - if (link->w < 3 || link->h < 3) { - av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n"); - return AVERROR(EINVAL); - } - - s->csp = av_pix_fmt_desc_get(link->format); - if (s->csp->comp[0].depth_minus1 / 8 == 1) { - s->filter_line = filter_line_c_16bit; - s->filter_edges = filter_edges_16bit; - } else { - s->filter_line = filter_line_c; - s->filter_edges = filter_edges; - } - -#if HAVE_YASM - if (bit_depth >= 15) { - if (EXTERNAL_SSE4(cpu_flags)) - s->filter_line = ff_yadif_filter_line_16bit_sse4; - else if (EXTERNAL_SSSE3(cpu_flags)) - s->filter_line = ff_yadif_filter_line_16bit_ssse3; - else if (EXTERNAL_SSE2(cpu_flags)) - s->filter_line = ff_yadif_filter_line_16bit_sse2; -#if ARCH_X86_32 - else if (EXTERNAL_MMXEXT(cpu_flags)) - s->filter_line = ff_yadif_filter_line_16bit_mmxext; -#endif /* ARCH_X86_32 */ - } else if ( bit_depth >= 9 && bit_depth <= 14) { - if (EXTERNAL_SSSE3(cpu_flags)) - s->filter_line = ff_yadif_filter_line_10bit_ssse3; - else if (EXTERNAL_SSE2(cpu_flags)) - s->filter_line = ff_yadif_filter_line_10bit_sse2; -#if ARCH_X86_32 - else if (EXTERNAL_MMXEXT(cpu_flags)) - s->filter_line = ff_yadif_filter_line_10bit_mmxext; -#endif /* ARCH_X86_32 */ - } else { - if (EXTERNAL_SSSE3(cpu_flags)) - s->filter_line = ff_yadif_filter_line_ssse3; - else if (EXTERNAL_SSE2(cpu_flags)) - s->filter_line = ff_yadif_filter_line_sse2; -#if ARCH_X86_32 - else if (EXTERNAL_MMXEXT(cpu_flags)) - s->filter_line = ff_yadif_filter_line_mmxext; -#endif /* ARCH_X86_32 */ - } -#endif /* HAVE_YASM */ - return 0; -} - - -#define OFFSET(x) offsetof(YADIFContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit } - -static const AVOption yadif_options[] = { - { "mode", "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=YADIF_MODE_SEND_FRAME}, 0, 3, FLAGS, "mode"}, - CONST("send_frame", "send one frame for each frame", YADIF_MODE_SEND_FRAME, "mode"), - CONST("send_field", "send one frame for each field", YADIF_MODE_SEND_FIELD, "mode"), - CONST("send_frame_nospatial", "send one frame for each frame, but skip spatial interlacing check", YADIF_MODE_SEND_FRAME_NOSPATIAL, "mode"), - CONST("send_field_nospatial", "send one frame for each field, but skip spatial interlacing check", YADIF_MODE_SEND_FIELD_NOSPATIAL, "mode"), - - { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=YADIF_PARITY_AUTO}, -1, 1, FLAGS, "parity" }, - CONST("tff", "assume top field first", YADIF_PARITY_TFF, "parity"), - CONST("bff", "assume bottom field first", YADIF_PARITY_BFF, "parity"), - CONST("auto", "auto detect parity", YADIF_PARITY_AUTO, "parity"), - - { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=YADIF_DEINT_ALL}, 0, 1, FLAGS, "deint" }, - CONST("all", "deinterlace all frames", YADIF_DEINT_ALL, "deint"), - CONST("interlaced", "only deinterlace frames marked as interlaced", YADIF_DEINT_INTERLACED, "deint"), - - { NULL } -}; - -AVFILTER_DEFINE_CLASS(yadif); - -AVFilter ff_vf_yadif = { - .name = "yadif", - .description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."), - .priv_size = sizeof(YADIFContext), - .priv_class = &yadif_class, - .uninit = uninit, - .query_formats = query_formats, - - .inputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { .name = NULL}}, - - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { .name = NULL}}, - - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS, -}; diff --git a/ffmpeg/libavfilter/video.c b/ffmpeg/libavfilter/video.c deleted file mode 100644 index 74c9161..0000000 --- a/ffmpeg/libavfilter/video.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2007 Bobby Bingham - * Copyright Stefano Sabatini <stefasab gmail com> - * Copyright Vitor Sessak <vitor1001 gmail com> - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> -#include <stdio.h> - -#include "libavutil/avassert.h" -#include "libavutil/buffer.h" -#include "libavutil/imgutils.h" -#include "libavutil/mem.h" - -#include "avfilter.h" -#include "internal.h" -#include "video.h" - -AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h) -{ - return ff_get_video_buffer(link->dst->outputs[0], w, h); -} - -/* TODO: set the buffer's priv member to a context structure for the whole - * filter chain. This will allow for a buffer pool instead of the constant - * alloc & free cycle currently implemented. */ -AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) -{ - AVFrame *frame = av_frame_alloc(); - int ret; - - if (!frame) - return NULL; - - frame->width = w; - frame->height = h; - frame->format = link->format; - - ret = av_frame_get_buffer(frame, 32); - if (ret < 0) - av_frame_free(&frame); - - return frame; -} - -#if FF_API_AVFILTERBUFFER -AVFilterBufferRef * -avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms, - int w, int h, enum AVPixelFormat format) -{ - AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer)); - AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef)); - - if (!pic || !picref) - goto fail; - - picref->buf = pic; - picref->buf->free = ff_avfilter_default_free_buffer; - if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps)))) - goto fail; - - pic->w = picref->video->w = w; - pic->h = picref->video->h = h; - - /* make sure the buffer gets read permission or it's useless for output */ - picref->perms = perms | AV_PERM_READ; - - pic->refcount = 1; - picref->type = AVMEDIA_TYPE_VIDEO; - pic->format = picref->format = format; - - memcpy(pic->data, data, 4*sizeof(data[0])); - memcpy(pic->linesize, linesize, 4*sizeof(linesize[0])); - memcpy(picref->data, pic->data, sizeof(picref->data)); - memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize)); - - pic-> extended_data = pic->data; - picref->extended_data = picref->data; - - picref->pts = AV_NOPTS_VALUE; - - return picref; - -fail: - if (picref && picref->video) - av_free(picref->video); - av_free(picref); - av_free(pic); - return NULL; -} -#endif - -AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h) -{ - AVFrame *ret = NULL; - - av_unused char buf[16]; - FF_TPRINTF_START(NULL, get_video_buffer); ff_tlog_link(NULL, link, 0); - - if (link->dstpad->get_video_buffer) - ret = link->dstpad->get_video_buffer(link, w, h); - - if (!ret) - ret = ff_default_get_video_buffer(link, w, h); - - return ret; -} diff --git a/ffmpeg/libavfilter/video.h b/ffmpeg/libavfilter/video.h deleted file mode 100644 index 56c58d6..0000000 --- a/ffmpeg/libavfilter/video.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2007 Bobby Bingham - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVFILTER_VIDEO_H -#define AVFILTER_VIDEO_H - -#include "avfilter.h" - -AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h); -AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h); - -/** - * Request a picture buffer with a specific set of permissions. - * - * @param link the output link to the filter from which the buffer will - * be requested - * @param w the minimum width of the buffer to allocate - * @param h the minimum height of the buffer to allocate - * @return A reference to the buffer. This must be unreferenced with - * avfilter_unref_buffer when you are finished with it. - */ -AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h); - -#endif /* AVFILTER_VIDEO_H */ diff --git a/ffmpeg/libavfilter/vsink_nullsink.c b/ffmpeg/libavfilter/vsink_nullsink.c deleted file mode 100644 index 281721b..0000000 --- a/ffmpeg/libavfilter/vsink_nullsink.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avfilter.h" -#include "internal.h" -#include "libavutil/internal.h" - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - av_frame_free(&frame); - return 0; -} - -static const AVFilterPad avfilter_vsink_nullsink_inputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, - }, - { NULL }, -}; - -AVFilter ff_vsink_nullsink = { - .name = "nullsink", - .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input video."), - - .priv_size = 0, - - .inputs = avfilter_vsink_nullsink_inputs, - .outputs = NULL, -}; diff --git a/ffmpeg/libavfilter/vsrc_cellauto.c b/ffmpeg/libavfilter/vsrc_cellauto.c deleted file mode 100644 index 95eabc1..0000000 --- a/ffmpeg/libavfilter/vsrc_cellauto.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) Stefano Sabatini 2011 - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * cellular automaton video source, based on Stephen Wolfram "experimentus crucis" - */ - -/* #define DEBUG */ - -#include "libavutil/file.h" -#include "libavutil/lfg.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/random_seed.h" -#include "libavutil/avstring.h" -#include "avfilter.h" -#include "internal.h" -#include "formats.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int w, h; - char *filename; - char *rule_str; - uint8_t *file_buf; - size_t file_bufsize; - uint8_t *buf; - int buf_prev_row_idx, buf_row_idx; - uint8_t rule; - uint64_t pts; - AVRational frame_rate; - double random_fill_ratio; - uint32_t random_seed; - int stitch, scroll, start_full; - int64_t generation; ///< the generation number, starting from 0 - AVLFG lfg; - char *pattern; -} CellAutoContext; - -#define OFFSET(x) offsetof(CellAutoContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM - -static const AVOption cellauto_options[] = { - { "filename", "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "f", "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "pattern", "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "p", "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS }, - { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS }, - { "rule", "set rule", OFFSET(rule), AV_OPT_TYPE_INT, {.i64 = 110}, 0, 255, FLAGS }, - { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS }, - { "ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS }, - { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS }, - { "seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS }, - { "scroll", "scroll pattern downward", OFFSET(scroll), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS }, - { "start_full", "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS }, - { "full", "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS }, - { "stitch", "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(cellauto); - -#ifdef DEBUG -static void show_cellauto_row(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - int i; - uint8_t *row = cellauto->buf + cellauto->w * cellauto->buf_row_idx; - char *line = av_malloc(cellauto->w + 1); - if (!line) - return; - - for (i = 0; i < cellauto->w; i++) - line[i] = row[i] ? '@' : ' '; - line[i] = 0; - av_log(ctx, AV_LOG_DEBUG, "generation:%"PRId64" row:%s|\n", cellauto->generation, line); - av_free(line); -} -#endif - -static int init_pattern_from_string(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - char *p; - int i, w = 0; - - w = strlen(cellauto->pattern); - av_log(ctx, AV_LOG_DEBUG, "w:%d\n", w); - - if (cellauto->w) { - if (w > cellauto->w) { - av_log(ctx, AV_LOG_ERROR, - "The specified width is %d which cannot contain the provided string width of %d\n", - cellauto->w, w); - return AVERROR(EINVAL); - } - } else { - /* width was not specified, set it to width of the provided row */ - cellauto->w = w; - cellauto->h = (double)cellauto->w * M_PHI; - } - - cellauto->buf = av_mallocz(sizeof(uint8_t) * cellauto->w * cellauto->h); - if (!cellauto->buf) - return AVERROR(ENOMEM); - - /* fill buf */ - p = cellauto->pattern; - for (i = (cellauto->w - w)/2;; i++) { - av_log(ctx, AV_LOG_DEBUG, "%d %c\n", i, *p == '\n' ? 'N' : *p); - if (*p == '\n' || !*p) - break; - else - cellauto->buf[i] = !!av_isgraph(*(p++)); - } - - return 0; -} - -static int init_pattern_from_file(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - int ret; - - ret = av_file_map(cellauto->filename, - &cellauto->file_buf, &cellauto->file_bufsize, 0, ctx); - if (ret < 0) - return ret; - - /* create a string based on the read file */ - cellauto->pattern = av_malloc(cellauto->file_bufsize + 1); - if (!cellauto->pattern) - return AVERROR(ENOMEM); - memcpy(cellauto->pattern, cellauto->file_buf, cellauto->file_bufsize); - cellauto->pattern[cellauto->file_bufsize] = 0; - - return init_pattern_from_string(ctx); -} - -static av_cold int init(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - int ret; - - if (!cellauto->w && !cellauto->filename && !cellauto->pattern) - av_opt_set(cellauto, "size", "320x518", 0); - - if (cellauto->filename && cellauto->pattern) { - av_log(ctx, AV_LOG_ERROR, "Only one of the filename or pattern options can be used\n"); - return AVERROR(EINVAL); - } - - if (cellauto->filename) { - if ((ret = init_pattern_from_file(ctx)) < 0) - return ret; - } else if (cellauto->pattern) { - if ((ret = init_pattern_from_string(ctx)) < 0) - return ret; - } else { - /* fill the first row randomly */ - int i; - - cellauto->buf = av_mallocz(sizeof(uint8_t) * cellauto->w * cellauto->h); - if (!cellauto->buf) - return AVERROR(ENOMEM); - if (cellauto->random_seed == -1) - cellauto->random_seed = av_get_random_seed(); - - av_lfg_init(&cellauto->lfg, cellauto->random_seed); - - for (i = 0; i < cellauto->w; i++) { - double r = (double)av_lfg_get(&cellauto->lfg) / UINT32_MAX; - if (r <= cellauto->random_fill_ratio) - cellauto->buf[i] = 1; - } - } - - av_log(ctx, AV_LOG_VERBOSE, - "s:%dx%d r:%d/%d rule:%d stitch:%d scroll:%d full:%d seed:%u\n", - cellauto->w, cellauto->h, cellauto->frame_rate.num, cellauto->frame_rate.den, - cellauto->rule, cellauto->stitch, cellauto->scroll, cellauto->start_full, - cellauto->random_seed); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - - av_file_unmap(cellauto->file_buf, cellauto->file_bufsize); - av_freep(&cellauto->buf); - av_freep(&cellauto->pattern); -} - -static int config_props(AVFilterLink *outlink) -{ - CellAutoContext *cellauto = outlink->src->priv; - - outlink->w = cellauto->w; - outlink->h = cellauto->h; - outlink->time_base = av_inv_q(cellauto->frame_rate); - - return 0; -} - -static void evolve(AVFilterContext *ctx) -{ - CellAutoContext *cellauto = ctx->priv; - int i, v, pos[3]; - uint8_t *row, *prev_row = cellauto->buf + cellauto->buf_row_idx * cellauto->w; - enum { NW, N, NE }; - - cellauto->buf_prev_row_idx = cellauto->buf_row_idx; - cellauto->buf_row_idx = cellauto->buf_row_idx == cellauto->h-1 ? 0 : cellauto->buf_row_idx+1; - row = cellauto->buf + cellauto->w * cellauto->buf_row_idx; - - for (i = 0; i < cellauto->w; i++) { - if (cellauto->stitch) { - pos[NW] = i-1 < 0 ? cellauto->w-1 : i-1; - pos[N] = i; - pos[NE] = i+1 == cellauto->w ? 0 : i+1; - v = prev_row[pos[NW]]<<2 | prev_row[pos[N]]<<1 | prev_row[pos[NE]]; - } else { - v = 0; - v|= i-1 >= 0 ? prev_row[i-1]<<2 : 0; - v|= prev_row[i ]<<1 ; - v|= i+1 < cellauto->w ? prev_row[i+1] : 0; - } - row[i] = !!(cellauto->rule & (1<<v)); - av_dlog(ctx, "i:%d context:%c%c%c -> cell:%d\n", i, - v&4?'@':' ', v&2?'@':' ', v&1?'@':' ', row[i]); - } - - cellauto->generation++; -} - -static void fill_picture(AVFilterContext *ctx, AVFrame *picref) -{ - CellAutoContext *cellauto = ctx->priv; - int i, j, k, row_idx = 0; - uint8_t *p0 = picref->data[0]; - - if (cellauto->scroll && cellauto->generation >= cellauto->h) - /* show on top the oldest row */ - row_idx = (cellauto->buf_row_idx + 1) % cellauto->h; - - /* fill the output picture with the whole buffer */ - for (i = 0; i < cellauto->h; i++) { - uint8_t byte = 0; - uint8_t *row = cellauto->buf + row_idx*cellauto->w; - uint8_t *p = p0; - for (k = 0, j = 0; j < cellauto->w; j++) { - byte |= row[j]<<(7-k++); - if (k==8 || j == cellauto->w-1) { - k = 0; - *p++ = byte; - byte = 0; - } - } - row_idx = (row_idx + 1) % cellauto->h; - p0 += picref->linesize[0]; - } -} - -static int request_frame(AVFilterLink *outlink) -{ - CellAutoContext *cellauto = outlink->src->priv; - AVFrame *picref = ff_get_video_buffer(outlink, cellauto->w, cellauto->h); - if (!picref) - return AVERROR(ENOMEM); - picref->sample_aspect_ratio = (AVRational) {1, 1}; - if (cellauto->generation == 0 && cellauto->start_full) { - int i; - for (i = 0; i < cellauto->h-1; i++) - evolve(outlink->src); - } - fill_picture(outlink->src, picref); - evolve(outlink->src); - - picref->pts = cellauto->pts++; - -#ifdef DEBUG - show_cellauto_row(outlink->src); -#endif - return ff_filter_frame(outlink, picref); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static const AVFilterPad cellauto_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_cellauto = { - .name = "cellauto", - .description = NULL_IF_CONFIG_SMALL("Create pattern generated by an elementary cellular automaton."), - .priv_size = sizeof(CellAutoContext), - .priv_class = &cellauto_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = cellauto_outputs, -}; diff --git a/ffmpeg/libavfilter/vsrc_life.c b/ffmpeg/libavfilter/vsrc_life.c deleted file mode 100644 index 029e1bb..0000000 --- a/ffmpeg/libavfilter/vsrc_life.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (c) Stefano Sabatini 2010 - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * life video source, based on John Conways' Life Game - */ - -/* #define DEBUG */ - -#include "libavutil/file.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/lfg.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/random_seed.h" -#include "libavutil/avstring.h" -#include "avfilter.h" -#include "internal.h" -#include "formats.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int w, h; - char *filename; - char *rule_str; - uint8_t *file_buf; - size_t file_bufsize; - - /** - * The two grid state buffers. - * - * A 0xFF (ALIVE_CELL) value means the cell is alive (or new born), while - * the decreasing values from 0xFE to 0 means the cell is dead; the range - * of values is used for the slow death effect, or mold (0xFE means dead, - * 0xFD means very dead, 0xFC means very very dead... and 0x00 means - * definitely dead/mold). - */ - uint8_t *buf[2]; - - uint8_t buf_idx; - uint16_t stay_rule; ///< encode the behavior for filled cells - uint16_t born_rule; ///< encode the behavior for empty cells - uint64_t pts; - AVRational frame_rate; - double random_fill_ratio; - uint32_t random_seed; - int stitch; - int mold; - uint8_t life_color[4]; - uint8_t death_color[4]; - uint8_t mold_color[4]; - AVLFG lfg; - void (*draw)(AVFilterContext*, AVFrame*); -} LifeContext; - -#define ALIVE_CELL 0xFF -#define OFFSET(x) offsetof(LifeContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption life_options[] = { - { "filename", "set source file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "f", "set source file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS }, - { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS }, - { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "rule", "set rule", OFFSET(rule_str), AV_OPT_TYPE_STRING, {.str = "B3/S23"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS }, - { "ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS }, - { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS }, - { "seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS }, - { "stitch", "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS }, - { "mold", "set mold speed for dead cells", OFFSET(mold), AV_OPT_TYPE_INT, {.i64=0}, 0, 0xFF, FLAGS }, - { "life_color", "set life color", OFFSET( life_color), AV_OPT_TYPE_COLOR, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "death_color", "set death color", OFFSET(death_color), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "mold_color", "set mold color", OFFSET( mold_color), AV_OPT_TYPE_COLOR, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(life); - -static int parse_rule(uint16_t *born_rule, uint16_t *stay_rule, - const char *rule_str, void *log_ctx) -{ - char *tail; - const char *p = rule_str; - *born_rule = 0; - *stay_rule = 0; - - if (strchr("bBsS", *p)) { - /* parse rule as a Born / Stay Alive code, see - * http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life */ - do { - uint16_t *rule = (*p == 'b' || *p == 'B') ? born_rule : stay_rule; - p++; - while (*p >= '0' && *p <= '8') { - *rule += 1<<(*p - '0'); - p++; - } - if (*p != '/') - break; - p++; - } while (strchr("bBsS", *p)); - - if (*p) - goto error; - } else { - /* parse rule as a number, expressed in the form STAY|(BORN<<9), - * where STAY and BORN encode the corresponding 9-bits rule */ - long int rule = strtol(rule_str, &tail, 10); - if (*tail) - goto error; - *born_rule = ((1<<9)-1) & rule; - *stay_rule = rule >> 9; - } - - return 0; - -error: - av_log(log_ctx, AV_LOG_ERROR, "Invalid rule code '%s' provided\n", rule_str); - return AVERROR(EINVAL); -} - -#ifdef DEBUG -static void show_life_grid(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - int i, j; - - char *line = av_malloc(life->w + 1); - if (!line) - return; - for (i = 0; i < life->h; i++) { - for (j = 0; j < life->w; j++) - line[j] = life->buf[life->buf_idx][i*life->w + j] == ALIVE_CELL ? '@' : ' '; - line[j] = 0; - av_log(ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line); - } - av_free(line); -} -#endif - -static int init_pattern_from_file(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - char *p; - int ret, i, i0, j, h = 0, w, max_w = 0; - - if ((ret = av_file_map(life->filename, &life->file_buf, &life->file_bufsize, - 0, ctx)) < 0) - return ret; - av_freep(&life->filename); - - /* prescan file to get the number of lines and the maximum width */ - w = 0; - for (i = 0; i < life->file_bufsize; i++) { - if (life->file_buf[i] == '\n') { - h++; max_w = FFMAX(w, max_w); w = 0; - } else { - w++; - } - } - av_log(ctx, AV_LOG_DEBUG, "h:%d max_w:%d\n", h, max_w); - - if (life->w) { - if (max_w > life->w || h > life->h) { - av_log(ctx, AV_LOG_ERROR, - "The specified size is %dx%d which cannot contain the provided file size of %dx%d\n", - life->w, life->h, max_w, h); - return AVERROR(EINVAL); - } - } else { - /* size was not specified, set it to size of the grid */ - life->w = max_w; - life->h = h; - } - - if (!(life->buf[0] = av_calloc(life->h * life->w, sizeof(*life->buf[0]))) || - !(life->buf[1] = av_calloc(life->h * life->w, sizeof(*life->buf[1])))) { - av_free(life->buf[0]); - av_free(life->buf[1]); - return AVERROR(ENOMEM); - } - - /* fill buf[0] */ - p = life->file_buf; - for (i0 = 0, i = (life->h - h)/2; i0 < h; i0++, i++) { - for (j = (life->w - max_w)/2;; j++) { - av_log(ctx, AV_LOG_DEBUG, "%d:%d %c\n", i, j, *p == '\n' ? 'N' : *p); - if (*p == '\n') { - p++; break; - } else - life->buf[0][i*life->w + j] = av_isgraph(*(p++)) ? ALIVE_CELL : 0; - } - } - life->buf_idx = 0; - - return 0; -} - -static av_cold int init(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - int ret; - - if (!life->w && !life->filename) - av_opt_set(life, "size", "320x240", 0); - - if ((ret = parse_rule(&life->born_rule, &life->stay_rule, life->rule_str, ctx)) < 0) - return ret; - - if (!life->mold && memcmp(life->mold_color, "\x00\x00\x00", 3)) - av_log(ctx, AV_LOG_WARNING, - "Mold color is set while mold isn't, ignoring the color.\n"); - - if (!life->filename) { - /* fill the grid randomly */ - int i; - - if (!(life->buf[0] = av_calloc(life->h * life->w, sizeof(*life->buf[0]))) || - !(life->buf[1] = av_calloc(life->h * life->w, sizeof(*life->buf[1])))) { - av_free(life->buf[0]); - av_free(life->buf[1]); - return AVERROR(ENOMEM); - } - if (life->random_seed == -1) - life->random_seed = av_get_random_seed(); - - av_lfg_init(&life->lfg, life->random_seed); - - for (i = 0; i < life->w * life->h; i++) { - double r = (double)av_lfg_get(&life->lfg) / UINT32_MAX; - if (r <= life->random_fill_ratio) - life->buf[0][i] = ALIVE_CELL; - } - life->buf_idx = 0; - } else { - if ((ret = init_pattern_from_file(ctx)) < 0) - return ret; - } - - av_log(ctx, AV_LOG_VERBOSE, - "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%u\n", - life->w, life->h, life->frame_rate.num, life->frame_rate.den, - life->rule_str, life->stay_rule, life->born_rule, life->stitch, - life->random_seed); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - - av_file_unmap(life->file_buf, life->file_bufsize); - av_freep(&life->rule_str); - av_freep(&life->buf[0]); - av_freep(&life->buf[1]); -} - -static int config_props(AVFilterLink *outlink) -{ - LifeContext *life = outlink->src->priv; - - outlink->w = life->w; - outlink->h = life->h; - outlink->time_base = av_inv_q(life->frame_rate); - - return 0; -} - -static void evolve(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - int i, j; - uint8_t *oldbuf = life->buf[ life->buf_idx]; - uint8_t *newbuf = life->buf[!life->buf_idx]; - - enum { NW, N, NE, W, E, SW, S, SE }; - - /* evolve the grid */ - for (i = 0; i < life->h; i++) { - for (j = 0; j < life->w; j++) { - int pos[8][2], n, alive, cell; - if (life->stitch) { - pos[NW][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NW][1] = (j-1) < 0 ? life->w-1 : j-1; - pos[N ][0] = (i-1) < 0 ? life->h-1 : i-1; pos[N ][1] = j ; - pos[NE][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NE][1] = (j+1) == life->w ? 0 : j+1; - pos[W ][0] = i ; pos[W ][1] = (j-1) < 0 ? life->w-1 : j-1; - pos[E ][0] = i ; pos[E ][1] = (j+1) == life->w ? 0 : j+1; - pos[SW][0] = (i+1) == life->h ? 0 : i+1; pos[SW][1] = (j-1) < 0 ? life->w-1 : j-1; - pos[S ][0] = (i+1) == life->h ? 0 : i+1; pos[S ][1] = j ; - pos[SE][0] = (i+1) == life->h ? 0 : i+1; pos[SE][1] = (j+1) == life->w ? 0 : j+1; - } else { - pos[NW][0] = (i-1) < 0 ? -1 : i-1; pos[NW][1] = (j-1) < 0 ? -1 : j-1; - pos[N ][0] = (i-1) < 0 ? -1 : i-1; pos[N ][1] = j ; - pos[NE][0] = (i-1) < 0 ? -1 : i-1; pos[NE][1] = (j+1) == life->w ? -1 : j+1; - pos[W ][0] = i ; pos[W ][1] = (j-1) < 0 ? -1 : j-1; - pos[E ][0] = i ; pos[E ][1] = (j+1) == life->w ? -1 : j+1; - pos[SW][0] = (i+1) == life->h ? -1 : i+1; pos[SW][1] = (j-1) < 0 ? -1 : j-1; - pos[S ][0] = (i+1) == life->h ? -1 : i+1; pos[S ][1] = j ; - pos[SE][0] = (i+1) == life->h ? -1 : i+1; pos[SE][1] = (j+1) == life->w ? -1 : j+1; - } - - /* compute the number of live neighbor cells */ - n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]] == ALIVE_CELL) + - (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]] == ALIVE_CELL) + - (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]] == ALIVE_CELL) + - (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]] == ALIVE_CELL) + - (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]] == ALIVE_CELL) + - (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]] == ALIVE_CELL) + - (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]] == ALIVE_CELL) + - (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]] == ALIVE_CELL); - cell = oldbuf[i*life->w + j]; - alive = 1<<n & (cell == ALIVE_CELL ? life->stay_rule : life->born_rule); - if (alive) *newbuf = ALIVE_CELL; // new cell is alive - else if (cell) *newbuf = cell - 1; // new cell is dead and in the process of mold - else *newbuf = 0; // new cell is definitely dead - av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, cell, *newbuf); - newbuf++; - } - } - - life->buf_idx = !life->buf_idx; -} - -static void fill_picture_monoblack(AVFilterContext *ctx, AVFrame *picref) -{ - LifeContext *life = ctx->priv; - uint8_t *buf = life->buf[life->buf_idx]; - int i, j, k; - - /* fill the output picture with the old grid buffer */ - for (i = 0; i < life->h; i++) { - uint8_t byte = 0; - uint8_t *p = picref->data[0] + i * picref->linesize[0]; - for (k = 0, j = 0; j < life->w; j++) { - byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++); - if (k==8 || j == life->w-1) { - k = 0; - *p++ = byte; - byte = 0; - } - } - } -} - -// divide by 255 and round to nearest -// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16 -#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16) - -static void fill_picture_rgb(AVFilterContext *ctx, AVFrame *picref) -{ - LifeContext *life = ctx->priv; - uint8_t *buf = life->buf[life->buf_idx]; - int i, j; - - /* fill the output picture with the old grid buffer */ - for (i = 0; i < life->h; i++) { - uint8_t *p = picref->data[0] + i * picref->linesize[0]; - for (j = 0; j < life->w; j++) { - uint8_t v = buf[i*life->w + j]; - if (life->mold && v != ALIVE_CELL) { - const uint8_t *c1 = life-> mold_color; - const uint8_t *c2 = life->death_color; - int death_age = FFMIN((0xff - v) * life->mold, 0xff); - *p++ = FAST_DIV255((c2[0] << 8) + ((int)c1[0] - (int)c2[0]) * death_age); - *p++ = FAST_DIV255((c2[1] << 8) + ((int)c1[1] - (int)c2[1]) * death_age); - *p++ = FAST_DIV255((c2[2] << 8) + ((int)c1[2] - (int)c2[2]) * death_age); - } else { - const uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color; - AV_WB24(p, c[0]<<16 | c[1]<<8 | c[2]); - p += 3; - } - } - } -} - -static int request_frame(AVFilterLink *outlink) -{ - LifeContext *life = outlink->src->priv; - AVFrame *picref = ff_get_video_buffer(outlink, life->w, life->h); - if (!picref) - return AVERROR(ENOMEM); - picref->sample_aspect_ratio = (AVRational) {1, 1}; - picref->pts = life->pts++; - - life->draw(outlink->src, picref); - evolve(outlink->src); -#ifdef DEBUG - show_life_grid(outlink->src); -#endif - return ff_filter_frame(outlink, picref); -} - -static int query_formats(AVFilterContext *ctx) -{ - LifeContext *life = ctx->priv; - enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE, AV_PIX_FMT_NONE }; - if (life->mold || memcmp(life-> life_color, "\xff\xff\xff", 3) - || memcmp(life->death_color, "\x00\x00\x00", 3)) { - pix_fmts[0] = AV_PIX_FMT_RGB24; - life->draw = fill_picture_rgb; - } else { - pix_fmts[0] = AV_PIX_FMT_MONOBLACK; - life->draw = fill_picture_monoblack; - } - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static const AVFilterPad life_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL} -}; - -AVFilter ff_vsrc_life = { - .name = "life", - .description = NULL_IF_CONFIG_SMALL("Create life."), - .priv_size = sizeof(LifeContext), - .priv_class = &life_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = life_outputs, -}; diff --git a/ffmpeg/libavfilter/vsrc_mandelbrot.c b/ffmpeg/libavfilter/vsrc_mandelbrot.c deleted file mode 100644 index 19dddf9..0000000 --- a/ffmpeg/libavfilter/vsrc_mandelbrot.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (c) 2011 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * The vsrc_color filter from Stefano Sabatini was used as template to create - * this - */ - -/** - * @file - * Mandelbrot fraktal renderer - */ - -#include "avfilter.h" -#include "formats.h" -#include "video.h" -#include "internal.h" -#include "libavutil/imgutils.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include <float.h> -#include <math.h> - -#define SQR(a) ((a)*(a)) - -enum Outer{ - ITERATION_COUNT, - NORMALIZED_ITERATION_COUNT, - WHITE, - OUTZ, -}; - -enum Inner{ - BLACK, - PERIOD, - CONVTIME, - MINCOL, -}; - -typedef struct Point { - double p[2]; - uint32_t val; -} Point; - -typedef struct { - const AVClass *class; - int w, h; - AVRational frame_rate; - uint64_t pts; - int maxiter; - double start_x; - double start_y; - double start_scale; - double end_scale; - double end_pts; - double bailout; - enum Outer outer; - enum Inner inner; - int cache_allocated; - int cache_used; - Point *point_cache; - Point *next_cache; - double (*zyklus)[2]; - uint32_t dither; - - double morphxf; - double morphyf; - double morphamp; -} MBContext; - -#define OFFSET(x) offsetof(MBContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -static const AVOption mandelbrot_options[] = { - {"size", "set frame size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="640x480"}, CHAR_MIN, CHAR_MAX, FLAGS }, - {"s", "set frame size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str="640x480"}, CHAR_MIN, CHAR_MAX, FLAGS }, - {"rate", "set frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, CHAR_MIN, CHAR_MAX, FLAGS }, - {"r", "set frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, CHAR_MIN, CHAR_MAX, FLAGS }, - {"maxiter", "set max iterations number", OFFSET(maxiter), AV_OPT_TYPE_INT, {.i64=7189}, 1, INT_MAX, FLAGS }, - {"start_x", "set the initial x position", OFFSET(start_x), AV_OPT_TYPE_DOUBLE, {.dbl=-0.743643887037158704752191506114774}, -100, 100, FLAGS }, - {"start_y", "set the initial y position", OFFSET(start_y), AV_OPT_TYPE_DOUBLE, {.dbl=-0.131825904205311970493132056385139}, -100, 100, FLAGS }, - {"start_scale", "set the initial scale value", OFFSET(start_scale), AV_OPT_TYPE_DOUBLE, {.dbl=3.0}, 0, FLT_MAX, FLAGS }, - {"end_scale", "set the terminal scale value", OFFSET(end_scale), AV_OPT_TYPE_DOUBLE, {.dbl=0.3}, 0, FLT_MAX, FLAGS }, - {"end_pts", "set the terminal pts value", OFFSET(end_pts), AV_OPT_TYPE_DOUBLE, {.dbl=400}, 0, INT64_MAX, FLAGS }, - {"bailout", "set the bailout value", OFFSET(bailout), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 0, FLT_MAX, FLAGS }, - {"morphxf", "set morph x frequency", OFFSET(morphxf), AV_OPT_TYPE_DOUBLE, {.dbl=0.01}, -FLT_MAX, FLT_MAX, FLAGS }, - {"morphyf", "set morph y frequency", OFFSET(morphyf), AV_OPT_TYPE_DOUBLE, {.dbl=0.0123}, -FLT_MAX, FLT_MAX, FLAGS }, - {"morphamp", "set morph amplitude", OFFSET(morphamp), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -FLT_MAX, FLT_MAX, FLAGS }, - - {"outer", "set outer coloring mode", OFFSET(outer), AV_OPT_TYPE_INT, {.i64=NORMALIZED_ITERATION_COUNT}, 0, INT_MAX, FLAGS, "outer" }, - {"iteration_count", "set iteration count mode", 0, AV_OPT_TYPE_CONST, {.i64=ITERATION_COUNT}, INT_MIN, INT_MAX, FLAGS, "outer" }, - {"normalized_iteration_count", "set normalized iteration count mode", 0, AV_OPT_TYPE_CONST, {.i64=NORMALIZED_ITERATION_COUNT}, INT_MIN, INT_MAX, FLAGS, "outer" }, - {"white", "set white mode", 0, AV_OPT_TYPE_CONST, {.i64=WHITE}, INT_MIN, INT_MAX, FLAGS, "outer" }, - {"outz", "set outz mode", 0, AV_OPT_TYPE_CONST, {.i64=OUTZ}, INT_MIN, INT_MAX, FLAGS, "outer" }, - - {"inner", "set inner coloring mode", OFFSET(inner), AV_OPT_TYPE_INT, {.i64=MINCOL}, 0, INT_MAX, FLAGS, "inner" }, - {"black", "set black mode", 0, AV_OPT_TYPE_CONST, {.i64=BLACK}, INT_MIN, INT_MAX, FLAGS, "inner"}, - {"period", "set period mode", 0, AV_OPT_TYPE_CONST, {.i64=PERIOD}, INT_MIN, INT_MAX, FLAGS, "inner"}, - {"convergence", "show time until convergence", 0, AV_OPT_TYPE_CONST, {.i64=CONVTIME}, INT_MIN, INT_MAX, FLAGS, "inner"}, - {"mincol", "color based on point closest to the origin of the iterations", 0, AV_OPT_TYPE_CONST, {.i64=MINCOL}, INT_MIN, INT_MAX, FLAGS, "inner"}, - - {NULL}, -}; - -AVFILTER_DEFINE_CLASS(mandelbrot); - -static av_cold int init(AVFilterContext *ctx) -{ - MBContext *mb = ctx->priv; - - mb->bailout *= mb->bailout; - - mb->start_scale /=mb->h; - mb->end_scale /=mb->h; - - mb->cache_allocated = mb->w * mb->h * 3; - mb->cache_used = 0; - mb->point_cache= av_malloc(sizeof(*mb->point_cache)*mb->cache_allocated); - mb-> next_cache= av_malloc(sizeof(*mb-> next_cache)*mb->cache_allocated); - mb-> zyklus = av_malloc(sizeof(*mb->zyklus) * (mb->maxiter+16)); - - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - MBContext *mb = ctx->priv; - - av_freep(&mb->point_cache); - av_freep(&mb-> next_cache); - av_freep(&mb->zyklus); -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_BGR32, - AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->src; - MBContext *mb = ctx->priv; - - if (av_image_check_size(mb->w, mb->h, 0, ctx) < 0) - return AVERROR(EINVAL); - - inlink->w = mb->w; - inlink->h = mb->h; - inlink->time_base = av_inv_q(mb->frame_rate); - - return 0; -} - -static void fill_from_cache(AVFilterContext *ctx, uint32_t *color, int *in_cidx, int *out_cidx, double py, double scale){ - MBContext *mb = ctx->priv; - if(mb->morphamp) - return; - for(; *in_cidx < mb->cache_used; (*in_cidx)++){ - Point *p= &mb->point_cache[*in_cidx]; - int x; - if(p->p[1] > py) - break; - x= round((p->p[0] - mb->start_x) / scale + mb->w/2); - if(x<0 || x >= mb->w) - continue; - if(color) color[x] = p->val; - if(out_cidx && *out_cidx < mb->cache_allocated) - mb->next_cache[(*out_cidx)++]= *p; - } -} - -static int interpol(MBContext *mb, uint32_t *color, int x, int y, int linesize) -{ - uint32_t a,b,c,d, i; - uint32_t ipol=0xFF000000; - int dist; - - if(!x || !y || x+1==mb->w || y+1==mb->h) - return 0; - - dist= FFMAX(FFABS(x-(mb->w>>1))*mb->h, FFABS(y-(mb->h>>1))*mb->w); - - if(dist<(mb->w*mb->h>>3)) - return 0; - - a=color[(x+1) + (y+0)*linesize]; - b=color[(x-1) + (y+1)*linesize]; - c=color[(x+0) + (y+1)*linesize]; - d=color[(x+1) + (y+1)*linesize]; - - if(a&&c){ - b= color[(x-1) + (y+0)*linesize]; - d= color[(x+0) + (y-1)*linesize]; - }else if(b&&d){ - a= color[(x+1) + (y-1)*linesize]; - c= color[(x-1) + (y-1)*linesize]; - }else if(c){ - d= color[(x+0) + (y-1)*linesize]; - a= color[(x-1) + (y+0)*linesize]; - b= color[(x+1) + (y-1)*linesize]; - }else if(d){ - c= color[(x-1) + (y-1)*linesize]; - a= color[(x-1) + (y+0)*linesize]; - b= color[(x+1) + (y-1)*linesize]; - }else - return 0; - - for(i=0; i<3; i++){ - int s= 8*i; - uint8_t ac= a>>s; - uint8_t bc= b>>s; - uint8_t cc= c>>s; - uint8_t dc= d>>s; - int ipolab= (ac + bc); - int ipolcd= (cc + dc); - if(FFABS(ipolab - ipolcd) > 5) - return 0; - if(FFABS(ac-bc)+FFABS(cc-dc) > 20) - return 0; - ipol |= ((ipolab + ipolcd + 2)/4)<<s; - } - color[x + y*linesize]= ipol; - return 1; -} - -static void draw_mandelbrot(AVFilterContext *ctx, uint32_t *color, int linesize, int64_t pts) -{ - MBContext *mb = ctx->priv; - int x,y,i, in_cidx=0, next_cidx=0, tmp_cidx; - double scale= mb->start_scale*pow(mb->end_scale/mb->start_scale, pts/mb->end_pts); - int use_zyklus=0; - fill_from_cache(ctx, NULL, &in_cidx, NULL, mb->start_y+scale*(-mb->h/2-0.5), scale); - tmp_cidx= in_cidx; - memset(color, 0, sizeof(*color)*mb->w); - for(y=0; y<mb->h; y++){ - int y1= y+1; - const double ci=mb->start_y+scale*(y-mb->h/2); - fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci, scale); - if(y1<mb->h){ - memset(color+linesize*y1, 0, sizeof(*color)*mb->w); - fill_from_cache(ctx, color+linesize*y1, &tmp_cidx, NULL, ci + 3*scale/2, scale); - } - - for(x=0; x<mb->w; x++){ - float av_uninit(epsilon); - const double cr=mb->start_x+scale*(x-mb->w/2); - double zr=cr; - double zi=ci; - uint32_t c=0; - double dv= mb->dither / (double)(1LL<<32); - mb->dither= mb->dither*1664525+1013904223; - - if(color[x + y*linesize] & 0xFF000000) - continue; - if(!mb->morphamp){ - if(interpol(mb, color, x, y, linesize)){ - if(next_cidx < mb->cache_allocated){ - mb->next_cache[next_cidx ].p[0]= cr; - mb->next_cache[next_cidx ].p[1]= ci; - mb->next_cache[next_cidx++].val = color[x + y*linesize]; - } - continue; - } - }else{ - zr += cos(pts * mb->morphxf) * mb->morphamp; - zi += sin(pts * mb->morphyf) * mb->morphamp; - } - - use_zyklus= (x==0 || mb->inner!=BLACK ||color[x-1 + y*linesize] == 0xFF000000); - if(use_zyklus) - epsilon= scale*1*sqrt(SQR(x-mb->w/2) + SQR(y-mb->h/2))/mb->w; - -#define Z_Z2_C(outr,outi,inr,ini)\ - outr= inr*inr - ini*ini + cr;\ - outi= 2*inr*ini + ci; - -#define Z_Z2_C_ZYKLUS(outr,outi,inr,ini, Z)\ - Z_Z2_C(outr,outi,inr,ini)\ - if(use_zyklus){\ - if(Z && fabs(mb->zyklus[i>>1][0]-outr)+fabs(mb->zyklus[i>>1][1]-outi) <= epsilon)\ - break;\ - }\ - mb->zyklus[i][0]= outr;\ - mb->zyklus[i][1]= outi;\ - - - - for(i=0; i<mb->maxiter-8; i++){ - double t; - Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0) - i++; - Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1) - i++; - Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0) - i++; - Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1) - i++; - Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0) - i++; - Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1) - i++; - Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0) - i++; - Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1) - if(zr*zr + zi*zi > mb->bailout){ - i-= FFMIN(7, i); - for(; i<mb->maxiter; i++){ - zr= mb->zyklus[i][0]; - zi= mb->zyklus[i][1]; - if(zr*zr + zi*zi > mb->bailout){ - switch(mb->outer){ - case ITERATION_COUNT: - zr = i; - c = lrintf((sin(zr)+1)*127) + lrintf((sin(zr/1.234)+1)*127)*256*256 + lrintf((sin(zr/100)+1)*127)*256; - break; - case NORMALIZED_ITERATION_COUNT: - zr = i + log2(log(mb->bailout) / log(zr*zr + zi*zi)); - c = lrintf((sin(zr)+1)*127) + lrintf((sin(zr/1.234)+1)*127)*256*256 + lrintf((sin(zr/100)+1)*127)*256; - break; - case WHITE: - c = 0xFFFFFF; - break; - case OUTZ: - zr /= mb->bailout; - zi /= mb->bailout; - c = (((int)(zr*128+128))&0xFF)*256 + (((int)(zi*128+128))&0xFF); - } - break; - } - } - break; - } - } - if(!c){ - if(mb->inner==PERIOD){ - int j; - for(j=i-1; j; j--) - if(SQR(mb->zyklus[j][0]-zr) + SQR(mb->zyklus[j][1]-zi) < epsilon*epsilon*10) - break; - if(j){ - c= i-j; - c= ((c<<5)&0xE0) + ((c<<10)&0xE000) + ((c<<15)&0xE00000); - } - }else if(mb->inner==CONVTIME){ - c= floor(i*255.0/mb->maxiter+dv)*0x010101; - } else if(mb->inner==MINCOL){ - int j; - double closest=9999; - int closest_index=0; - for(j=i-1; j>=0; j--) - if(SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]) < closest){ - closest= SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]); - closest_index= j; - } - closest = sqrt(closest); - c= lrintf((mb->zyklus[closest_index][0]/closest+1)*127+dv) + lrintf((mb->zyklus[closest_index][1]/closest+1)*127+dv)*256; - } - } - c |= 0xFF000000; - color[x + y*linesize]= c; - if(next_cidx < mb->cache_allocated){ - mb->next_cache[next_cidx ].p[0]= cr; - mb->next_cache[next_cidx ].p[1]= ci; - mb->next_cache[next_cidx++].val = c; - } - } - fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci + scale/2, scale); - } - FFSWAP(void*, mb->next_cache, mb->point_cache); - mb->cache_used = next_cidx; - if(mb->cache_used == mb->cache_allocated) - av_log(ctx, AV_LOG_INFO, "Mandelbrot cache is too small!\n"); -} - -static int request_frame(AVFilterLink *link) -{ - MBContext *mb = link->src->priv; - AVFrame *picref = ff_get_video_buffer(link, mb->w, mb->h); - if (!picref) - return AVERROR(ENOMEM); - - picref->sample_aspect_ratio = (AVRational) {1, 1}; - picref->pts = mb->pts++; - - draw_mandelbrot(link->src, (uint32_t*)picref->data[0], picref->linesize[0]/4, picref->pts); - return ff_filter_frame(link, picref); -} - -static const AVFilterPad mandelbrot_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_mandelbrot = { - .name = "mandelbrot", - .description = NULL_IF_CONFIG_SMALL("Render a Mandelbrot fractal."), - .priv_size = sizeof(MBContext), - .priv_class = &mandelbrot_class, - .init = init, - .uninit = uninit, - .query_formats = query_formats, - .inputs = NULL, - .outputs = mandelbrot_outputs, -}; diff --git a/ffmpeg/libavfilter/vsrc_mptestsrc.c b/ffmpeg/libavfilter/vsrc_mptestsrc.c deleted file mode 100644 index d045704..0000000 --- a/ffmpeg/libavfilter/vsrc_mptestsrc.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2002 Michael Niedermayer <michaelni@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. - */ - -/** - * @file - * MP test source, ported from MPlayer libmpcodecs/vf_test.c - */ - -#include "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "avfilter.h" -#include "internal.h" -#include "formats.h" -#include "video.h" - -#define WIDTH 512 -#define HEIGHT 512 - -enum test_type { - TEST_DC_LUMA, - TEST_DC_CHROMA, - TEST_FREQ_LUMA, - TEST_FREQ_CHROMA, - TEST_AMP_LUMA, - TEST_AMP_CHROMA, - TEST_CBP, - TEST_MV, - TEST_RING1, - TEST_RING2, - TEST_ALL, - TEST_NB -}; - -typedef struct MPTestContext { - const AVClass *class; - AVRational frame_rate; - int64_t pts, max_pts, duration; - int hsub, vsub; - enum test_type test; -} MPTestContext; - -#define OFFSET(x) offsetof(MPTestContext, x) -#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM -static const AVOption mptestsrc_options[]= { - { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS }, - { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS }, - { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS }, - - { "test", "set test to perform", OFFSET(test), AV_OPT_TYPE_INT, {.i64=TEST_ALL}, 0, INT_MAX, FLAGS, "test" }, - { "t", "set test to perform", OFFSET(test), AV_OPT_TYPE_INT, {.i64=TEST_ALL}, 0, INT_MAX, FLAGS, "test" }, - { "dc_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "dc_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "freq_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "freq_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "amp_luma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_LUMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "amp_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_CHROMA}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "cbp", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_CBP}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "mv", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_MV}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "ring1", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING1}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "ring2", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING2}, INT_MIN, INT_MAX, FLAGS, "test" }, - { "all", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_ALL}, INT_MIN, INT_MAX, FLAGS, "test" }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(mptestsrc); - -static double c[64]; - -static void init_idct(void) -{ - int i, j; - - for (i = 0; i < 8; i++) { - double s = i == 0 ? sqrt(0.125) : 0.5; - - for (j = 0; j < 8; j++) - c[i*8+j] = s*cos((M_PI/8.0)*i*(j+0.5)); - } -} - -static void idct(uint8_t *dst, int dst_linesize, int src[64]) -{ - int i, j, k; - double tmp[64]; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - double sum = 0.0; - - for (k = 0; k < 8; k++) - sum += c[k*8+j] * src[8*i+k]; - - tmp[8*i+j] = sum; - } - } - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++) { - double sum = 0.0; - - for (k = 0; k < 8; k++) - sum += c[k*8+i]*tmp[8*k+j]; - - dst[dst_linesize*i + j] = av_clip((int)floor(sum+0.5), 0, 255); - } - } -} - -static void draw_dc(uint8_t *dst, int dst_linesize, int color, int w, int h) -{ - int x, y; - - for (y = 0; y < h; y++) - for (x = 0; x < w; x++) - dst[x + y*dst_linesize] = color; -} - -static void draw_basis(uint8_t *dst, int dst_linesize, int amp, int freq, int dc) -{ - int src[64]; - - memset(src, 0, 64*sizeof(int)); - src[0] = dc; - if (amp) - src[freq] = amp; - idct(dst, dst_linesize, src); -} - -static void draw_cbp(uint8_t *dst[3], int dst_linesize[3], int cbp, int amp, int dc) -{ - if (cbp&1) draw_basis(dst[0] , dst_linesize[0], amp, 1, dc); - if (cbp&2) draw_basis(dst[0]+8 , dst_linesize[0], amp, 1, dc); - if (cbp&4) draw_basis(dst[0]+ 8*dst_linesize[0], dst_linesize[0], amp, 1, dc); - if (cbp&8) draw_basis(dst[0]+8+8*dst_linesize[0], dst_linesize[0], amp, 1, dc); - if (cbp&16) draw_basis(dst[1] , dst_linesize[1], amp, 1, dc); - if (cbp&32) draw_basis(dst[2] , dst_linesize[2], amp, 1, dc); -} - -static void dc_test(uint8_t *dst, int dst_linesize, int w, int h, int off) -{ - const int step = FFMAX(256/(w*h/256), 1); - int x, y, color = off; - - for (y = 0; y < h; y += 16) { - for (x = 0; x < w; x += 16) { - draw_dc(dst + x + y*dst_linesize, dst_linesize, color, 8, 8); - color += step; - } - } -} - -static void freq_test(uint8_t *dst, int dst_linesize, int off) -{ - int x, y, freq = 0; - - for (y = 0; y < 8*16; y += 16) { - for (x = 0; x < 8*16; x += 16) { - draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*(96+off), freq, 128*8); - freq++; - } - } -} - -static void amp_test(uint8_t *dst, int dst_linesize, int off) -{ - int x, y, amp = off; - - for (y = 0; y < 16*16; y += 16) { - for (x = 0; x < 16*16; x += 16) { - draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*amp, 1, 128*8); - amp++; - } - } -} - -static void cbp_test(uint8_t *dst[3], int dst_linesize[3], int off) -{ - int x, y, cbp = 0; - - for (y = 0; y < 16*8; y += 16) { - for (x = 0; x < 16*8; x += 16) { - uint8_t *dst1[3]; - dst1[0] = dst[0] + x*2 + y*2*dst_linesize[0]; - dst1[1] = dst[1] + x + y* dst_linesize[1]; - dst1[2] = dst[2] + x + y* dst_linesize[2]; - - draw_cbp(dst1, dst_linesize, cbp, (64+off)*4, 128*8); - cbp++; - } - } -} - -static void mv_test(uint8_t *dst, int dst_linesize, int off) -{ - int x, y; - - for (y = 0; y < 16*16; y++) { - if (y&16) - continue; - for (x = 0; x < 16*16; x++) - dst[x + y*dst_linesize] = x + off*8/(y/32+1); - } -} - -static void ring1_test(uint8_t *dst, int dst_linesize, int off) -{ - int x, y, color = 0; - - for (y = off; y < 16*16; y += 16) { - for (x = off; x < 16*16; x += 16) { - draw_dc(dst + x + y*dst_linesize, dst_linesize, ((x+y)&16) ? color : -color, 16, 16); - color++; - } - } -} - -static void ring2_test(uint8_t *dst, int dst_linesize, int off) -{ - int x, y; - - for (y = 0; y < 16*16; y++) { - for (x = 0; x < 16*16; x++) { - double d = sqrt((x-8*16)*(x-8*16) + (y-8*16)*(y-8*16)); - double r = d/20 - (int)(d/20); - if (r < off/30.0) { - dst[x + y*dst_linesize] = 255; - dst[x + y*dst_linesize+256] = 0; - } else { - dst[x + y*dst_linesize] = x; - dst[x + y*dst_linesize+256] = x; - } - } - } -} - -static av_cold int init(AVFilterContext *ctx) -{ - MPTestContext *test = ctx->priv; - - test->max_pts = test->duration >= 0 ? - av_rescale_q(test->duration, AV_TIME_BASE_Q, av_inv_q(test->frame_rate)) : -1; - test->pts = 0; - - av_log(ctx, AV_LOG_VERBOSE, "rate:%d/%d duration:%f\n", - test->frame_rate.num, test->frame_rate.den, - test->duration < 0 ? -1 : test->max_pts * av_q2d(av_inv_q(test->frame_rate))); - init_idct(); - - return 0; -} - -static int config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - MPTestContext *test = ctx->priv; - const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(outlink->format); - - test->hsub = pix_desc->log2_chroma_w; - test->vsub = pix_desc->log2_chroma_h; - - outlink->w = WIDTH; - outlink->h = HEIGHT; - outlink->time_base = av_inv_q(test->frame_rate); - - return 0; -} - -static int query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE - }; - - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - MPTestContext *test = outlink->src->priv; - AVFrame *picref; - int w = WIDTH, h = HEIGHT, - cw = FF_CEIL_RSHIFT(w, test->hsub), ch = FF_CEIL_RSHIFT(h, test->vsub); - unsigned int frame = outlink->frame_count; - enum test_type tt = test->test; - int i; - - if (test->max_pts >= 0 && test->pts > test->max_pts) - return AVERROR_EOF; - picref = ff_get_video_buffer(outlink, w, h); - if (!picref) - return AVERROR(ENOMEM); - picref->pts = test->pts++; - - // clean image - for (i = 0; i < h; i++) - memset(picref->data[0] + i*picref->linesize[0], 0, w); - for (i = 0; i < ch; i++) { - memset(picref->data[1] + i*picref->linesize[1], 128, cw); - memset(picref->data[2] + i*picref->linesize[2], 128, cw); - } - - if (tt == TEST_ALL && frame%30) /* draw a black frame at the beginning of each test */ - tt = (frame/30)%(TEST_NB-1); - - switch (tt) { - case TEST_DC_LUMA: dc_test(picref->data[0], picref->linesize[0], 256, 256, frame%30); break; - case TEST_DC_CHROMA: dc_test(picref->data[1], picref->linesize[1], 256, 256, frame%30); break; - case TEST_FREQ_LUMA: freq_test(picref->data[0], picref->linesize[0], frame%30); break; - case TEST_FREQ_CHROMA: freq_test(picref->data[1], picref->linesize[1], frame%30); break; - case TEST_AMP_LUMA: amp_test(picref->data[0], picref->linesize[0], frame%30); break; - case TEST_AMP_CHROMA: amp_test(picref->data[1], picref->linesize[1], frame%30); break; - case TEST_CBP: cbp_test(picref->data , picref->linesize , frame%30); break; - case TEST_MV: mv_test(picref->data[0], picref->linesize[0], frame%30); break; - case TEST_RING1: ring1_test(picref->data[0], picref->linesize[0], frame%30); break; - case TEST_RING2: ring2_test(picref->data[0], picref->linesize[0], frame%30); break; - } - - return ff_filter_frame(outlink, picref); -} - -static const AVFilterPad mptestsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_mptestsrc = { - .name = "mptestsrc", - .description = NULL_IF_CONFIG_SMALL("Generate various test pattern."), - .priv_size = sizeof(MPTestContext), - .priv_class = &mptestsrc_class, - .init = init, - .query_formats = query_formats, - .inputs = NULL, - .outputs = mptestsrc_outputs, -}; diff --git a/ffmpeg/libavfilter/vsrc_testsrc.c b/ffmpeg/libavfilter/vsrc_testsrc.c deleted file mode 100644 index 0ad1474..0000000 --- a/ffmpeg/libavfilter/vsrc_testsrc.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * Copyright (c) 2007 Nicolas George <nicolas.george@normalesup.org> - * Copyright (c) 2011 Stefano Sabatini - * Copyright (c) 2012 Paul B Mahol - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Misc test sources. - * - * testsrc is based on the test pattern generator demuxer by Nicolas George: - * http://lists.ffmpeg.org/pipermail/ffmpeg-devel/2007-October/037845.html - * - * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by - * Michael Niedermayer. - * - * smptebars and smptehdbars are by Paul B Mahol. - */ - -#include <float.h> - -#include "libavutil/avassert.h" -#include "libavutil/common.h" -#include "libavutil/opt.h" -#include "libavutil/imgutils.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/parseutils.h" -#include "avfilter.h" -#include "drawutils.h" -#include "formats.h" -#include "internal.h" -#include "video.h" - -typedef struct { - const AVClass *class; - int w, h; - unsigned int nb_frame; - AVRational time_base, frame_rate; - int64_t pts; - int64_t duration; ///< duration expressed in microseconds - AVRational sar; ///< sample aspect ratio - int draw_once; ///< draw only the first frame, always put out the same picture - int draw_once_reset; ///< draw only the first frame or in case of reset - AVFrame *picref; ///< cached reference containing the painted picture - - void (* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame); - - /* only used by testsrc */ - int nb_decimals; - - /* only used by color */ - FFDrawContext draw; - FFDrawColor color; - uint8_t color_rgba[4]; - - /* only used by rgbtest */ - uint8_t rgba_map[4]; - - /* only used by haldclut */ - int level; -} TestSourceContext; - -#define OFFSET(x) offsetof(TestSourceContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define SIZE_OPTIONS \ - { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ - { "s", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },\ - -#define COMMON_OPTIONS_NOSIZE \ - { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ - { "r", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, FLAGS },\ - { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ - { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = -1}, -1, INT64_MAX, FLAGS },\ - { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX, FLAGS }, - -#define COMMON_OPTIONS SIZE_OPTIONS COMMON_OPTIONS_NOSIZE - -static const AVOption options[] = { - COMMON_OPTIONS - { NULL } -}; - -static av_cold int init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->time_base = av_inv_q(test->frame_rate); - test->nb_frame = 0; - test->pts = 0; - - av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n", - test->w, test->h, test->frame_rate.num, test->frame_rate.den, - test->duration < 0 ? -1 : (double)test->duration/1000000, - test->sar.num, test->sar.den); - return 0; -} - -static av_cold void uninit(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - av_frame_free(&test->picref); -} - -static int config_props(AVFilterLink *outlink) -{ - TestSourceContext *test = outlink->src->priv; - - outlink->w = test->w; - outlink->h = test->h; - outlink->sample_aspect_ratio = test->sar; - outlink->frame_rate = test->frame_rate; - outlink->time_base = test->time_base; - - return 0; -} - -static int request_frame(AVFilterLink *outlink) -{ - TestSourceContext *test = outlink->src->priv; - AVFrame *frame; - - if (test->duration >= 0 && - av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration) - return AVERROR_EOF; - - if (test->draw_once) { - if (test->draw_once_reset) { - av_frame_free(&test->picref); - test->draw_once_reset = 0; - } - if (!test->picref) { - test->picref = - ff_get_video_buffer(outlink, test->w, test->h); - if (!test->picref) - return AVERROR(ENOMEM); - test->fill_picture_fn(outlink->src, test->picref); - } - frame = av_frame_clone(test->picref); - } else - frame = ff_get_video_buffer(outlink, test->w, test->h); - - if (!frame) - return AVERROR(ENOMEM); - frame->pts = test->pts; - frame->key_frame = 1; - frame->interlaced_frame = 0; - frame->pict_type = AV_PICTURE_TYPE_I; - frame->sample_aspect_ratio = test->sar; - if (!test->draw_once) - test->fill_picture_fn(outlink->src, frame); - - test->pts++; - test->nb_frame++; - - return ff_filter_frame(outlink, frame); -} - -#if CONFIG_COLOR_FILTER - -static const AVOption color_options[] = { - { "color", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color", OFFSET(color_rgba), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, FLAGS }, - COMMON_OPTIONS - { NULL } -}; - -AVFILTER_DEFINE_CLASS(color); - -static void color_fill_picture(AVFilterContext *ctx, AVFrame *picref) -{ - TestSourceContext *test = ctx->priv; - ff_fill_rectangle(&test->draw, &test->color, - picref->data, picref->linesize, - 0, 0, test->w, test->h); -} - -static av_cold int color_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - test->fill_picture_fn = color_fill_picture; - test->draw_once = 1; - return init(ctx); -} - -static int color_query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -static int color_config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->src; - TestSourceContext *test = ctx->priv; - int ret; - - ff_draw_init(&test->draw, inlink->format, 0); - ff_draw_color(&test->draw, &test->color, test->color_rgba); - - test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w); - test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h); - if (av_image_check_size(test->w, test->h, 0, ctx) < 0) - return AVERROR(EINVAL); - - if ((ret = config_props(inlink)) < 0) - return ret; - - return 0; -} - -static int color_process_command(AVFilterContext *ctx, const char *cmd, const char *args, - char *res, int res_len, int flags) -{ - TestSourceContext *test = ctx->priv; - int ret; - - if (!strcmp(cmd, "color") || !strcmp(cmd, "c")) { - uint8_t color_rgba[4]; - - ret = av_parse_color(color_rgba, args, -1, ctx); - if (ret < 0) - return ret; - - memcpy(test->color_rgba, color_rgba, sizeof(color_rgba)); - ff_draw_color(&test->draw, &test->color, test->color_rgba); - test->draw_once_reset = 1; - return 0; - } - - return AVERROR(ENOSYS); -} - -static const AVFilterPad color_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = color_config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_color = { - .name = "color", - .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."), - .priv_class = &color_class, - .priv_size = sizeof(TestSourceContext), - .init = color_init, - .uninit = uninit, - .query_formats = color_query_formats, - .inputs = NULL, - .outputs = color_outputs, - .process_command = color_process_command, -}; - -#endif /* CONFIG_COLOR_FILTER */ - -#if CONFIG_HALDCLUTSRC_FILTER - -static const AVOption haldclutsrc_options[] = { - { "level", "set level", OFFSET(level), AV_OPT_TYPE_INT, {.i64 = 6}, 2, 8, FLAGS }, - COMMON_OPTIONS_NOSIZE - { NULL } -}; - -AVFILTER_DEFINE_CLASS(haldclutsrc); - -static void haldclutsrc_fill_picture(AVFilterContext *ctx, AVFrame *frame) -{ - int i, j, k, x = 0, y = 0, is16bit = 0, step; - uint32_t alpha = 0; - const TestSourceContext *hc = ctx->priv; - int level = hc->level; - float scale; - const int w = frame->width; - const int h = frame->height; - const uint8_t *data = frame->data[0]; - const int linesize = frame->linesize[0]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - uint8_t rgba_map[4]; - - av_assert0(w == h && w == level*level*level); - - ff_fill_rgba_map(rgba_map, frame->format); - - switch (frame->format) { - case AV_PIX_FMT_RGB48: - case AV_PIX_FMT_BGR48: - case AV_PIX_FMT_RGBA64: - case AV_PIX_FMT_BGRA64: - is16bit = 1; - alpha = 0xffff; - break; - case AV_PIX_FMT_RGBA: - case AV_PIX_FMT_BGRA: - case AV_PIX_FMT_ARGB: - case AV_PIX_FMT_ABGR: - alpha = 0xff; - break; - } - - step = av_get_padded_bits_per_pixel(desc) >> (3 + is16bit); - scale = ((float)(1 << (8*(is16bit+1))) - 1) / (level*level - 1); - -#define LOAD_CLUT(nbits) do { \ - uint##nbits##_t *dst = ((uint##nbits##_t *)(data + y*linesize)) + x*step; \ - dst[rgba_map[0]] = av_clip_uint##nbits(i * scale); \ - dst[rgba_map[1]] = av_clip_uint##nbits(j * scale); \ - dst[rgba_map[2]] = av_clip_uint##nbits(k * scale); \ - if (step == 4) \ - dst[rgba_map[3]] = alpha; \ -} while (0) - - level *= level; - for (k = 0; k < level; k++) { - for (j = 0; j < level; j++) { - for (i = 0; i < level; i++) { - if (!is16bit) - LOAD_CLUT(8); - else - LOAD_CLUT(16); - if (++x == w) { - x = 0; - y++; - } - } - } - } -} - -static av_cold int haldclutsrc_init(AVFilterContext *ctx) -{ - TestSourceContext *hc = ctx->priv; - hc->fill_picture_fn = haldclutsrc_fill_picture; - hc->draw_once = 1; - return init(ctx); -} - -static int haldclutsrc_query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24, - AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, - AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, - AV_PIX_FMT_0RGB, AV_PIX_FMT_0BGR, - AV_PIX_FMT_RGB0, AV_PIX_FMT_BGR0, - AV_PIX_FMT_RGB48, AV_PIX_FMT_BGR48, - AV_PIX_FMT_RGBA64, AV_PIX_FMT_BGRA64, - AV_PIX_FMT_NONE, - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int haldclutsrc_config_props(AVFilterLink *outlink) -{ - AVFilterContext *ctx = outlink->src; - TestSourceContext *hc = ctx->priv; - - hc->w = hc->h = hc->level * hc->level * hc->level; - return config_props(outlink); -} - -static const AVFilterPad haldclutsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = haldclutsrc_config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_haldclutsrc = { - .name = "haldclutsrc", - .description = NULL_IF_CONFIG_SMALL("Provide an identity Hald CLUT."), - .priv_class = &haldclutsrc_class, - .priv_size = sizeof(TestSourceContext), - .init = haldclutsrc_init, - .uninit = uninit, - .query_formats = haldclutsrc_query_formats, - .inputs = NULL, - .outputs = haldclutsrc_outputs, -}; -#endif /* CONFIG_HALDCLUTSRC_FILTER */ - -#if CONFIG_NULLSRC_FILTER - -#define nullsrc_options options -AVFILTER_DEFINE_CLASS(nullsrc); - -static void nullsrc_fill_picture(AVFilterContext *ctx, AVFrame *picref) { } - -static av_cold int nullsrc_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->fill_picture_fn = nullsrc_fill_picture; - return init(ctx); -} - -static const AVFilterPad nullsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL }, -}; - -AVFilter ff_vsrc_nullsrc = { - .name = "nullsrc", - .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."), - .init = nullsrc_init, - .uninit = uninit, - .priv_size = sizeof(TestSourceContext), - .priv_class = &nullsrc_class, - .inputs = NULL, - .outputs = nullsrc_outputs, -}; - -#endif /* CONFIG_NULLSRC_FILTER */ - -#if CONFIG_TESTSRC_FILTER - -static const AVOption testsrc_options[] = { - COMMON_OPTIONS - { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS }, - { "n", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0}, 0, 17, FLAGS }, - { NULL } -}; - -AVFILTER_DEFINE_CLASS(testsrc); - -/** - * Fill a rectangle with value val. - * - * @param val the RGB value to set - * @param dst pointer to the destination buffer to fill - * @param dst_linesize linesize of destination - * @param segment_width width of the segment - * @param x horizontal coordinate where to draw the rectangle in the destination buffer - * @param y horizontal coordinate where to draw the rectangle in the destination buffer - * @param w width of the rectangle to draw, expressed as a number of segment_width units - * @param h height of the rectangle to draw, expressed as a number of segment_width units - */ -static void draw_rectangle(unsigned val, uint8_t *dst, int dst_linesize, int segment_width, - int x, int y, int w, int h) -{ - int i; - int step = 3; - - dst += segment_width * (step * x + y * dst_linesize); - w *= segment_width * step; - h *= segment_width; - for (i = 0; i < h; i++) { - memset(dst, val, w); - dst += dst_linesize; - } -} - -static void draw_digit(int digit, uint8_t *dst, int dst_linesize, - int segment_width) -{ -#define TOP_HBAR 1 -#define MID_HBAR 2 -#define BOT_HBAR 4 -#define LEFT_TOP_VBAR 8 -#define LEFT_BOT_VBAR 16 -#define RIGHT_TOP_VBAR 32 -#define RIGHT_BOT_VBAR 64 - struct { - int x, y, w, h; - } segments[] = { - { 1, 0, 5, 1 }, /* TOP_HBAR */ - { 1, 6, 5, 1 }, /* MID_HBAR */ - { 1, 12, 5, 1 }, /* BOT_HBAR */ - { 0, 1, 1, 5 }, /* LEFT_TOP_VBAR */ - { 0, 7, 1, 5 }, /* LEFT_BOT_VBAR */ - { 6, 1, 1, 5 }, /* RIGHT_TOP_VBAR */ - { 6, 7, 1, 5 } /* RIGHT_BOT_VBAR */ - }; - static const unsigned char masks[10] = { - /* 0 */ TOP_HBAR |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 1 */ RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR |RIGHT_TOP_VBAR, - /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 4 */ MID_HBAR |LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_BOT_VBAR, - /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR |RIGHT_BOT_VBAR, - /* 7 */ TOP_HBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR, - }; - unsigned mask = masks[digit]; - int i; - - draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13); - for (i = 0; i < FF_ARRAY_ELEMS(segments); i++) - if (mask & (1<<i)) - draw_rectangle(255, dst, dst_linesize, segment_width, - segments[i].x, segments[i].y, segments[i].w, segments[i].h); -} - -#define GRADIENT_SIZE (6 * 256) - -static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame) -{ - TestSourceContext *test = ctx->priv; - uint8_t *p, *p0; - int x, y; - int color, color_rest; - int icolor; - int radius; - int quad0, quad; - int dquad_x, dquad_y; - int grad, dgrad, rgrad, drgrad; - int seg_size; - int second; - int i; - uint8_t *data = frame->data[0]; - int width = frame->width; - int height = frame->height; - - /* draw colored bars and circle */ - radius = (width + height) / 4; - quad0 = width * width / 4 + height * height / 4 - radius * radius; - dquad_y = 1 - height; - p0 = data; - for (y = 0; y < height; y++) { - p = p0; - color = 0; - color_rest = 0; - quad = quad0; - dquad_x = 1 - width; - for (x = 0; x < width; x++) { - icolor = color; - if (quad < 0) - icolor ^= 7; - quad += dquad_x; - dquad_x += 2; - *(p++) = icolor & 1 ? 255 : 0; - *(p++) = icolor & 2 ? 255 : 0; - *(p++) = icolor & 4 ? 255 : 0; - color_rest += 8; - if (color_rest >= width) { - color_rest -= width; - color++; - } - } - quad0 += dquad_y; - dquad_y += 2; - p0 += frame->linesize[0]; - } - - /* draw sliding color line */ - p0 = p = data + frame->linesize[0] * (height * 3/4); - grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) % - GRADIENT_SIZE; - rgrad = 0; - dgrad = GRADIENT_SIZE / width; - drgrad = GRADIENT_SIZE % width; - for (x = 0; x < width; x++) { - *(p++) = - grad < 256 || grad >= 5 * 256 ? 255 : - grad >= 2 * 256 && grad < 4 * 256 ? 0 : - grad < 2 * 256 ? 2 * 256 - 1 - grad : grad - 4 * 256; - *(p++) = - grad >= 4 * 256 ? 0 : - grad >= 1 * 256 && grad < 3 * 256 ? 255 : - grad < 1 * 256 ? grad : 4 * 256 - 1 - grad; - *(p++) = - grad < 2 * 256 ? 0 : - grad >= 3 * 256 && grad < 5 * 256 ? 255 : - grad < 3 * 256 ? grad - 2 * 256 : 6 * 256 - 1 - grad; - grad += dgrad; - rgrad += drgrad; - if (rgrad >= GRADIENT_SIZE) { - grad++; - rgrad -= GRADIENT_SIZE; - } - if (grad >= GRADIENT_SIZE) - grad -= GRADIENT_SIZE; - } - p = p0; - for (y = height / 8; y > 0; y--) { - memcpy(p+frame->linesize[0], p, 3 * width); - p += frame->linesize[0]; - } - - /* draw digits */ - seg_size = width / 80; - if (seg_size >= 1 && height >= 13 * seg_size) { - int64_t p10decimals = 1; - double time = av_q2d(test->time_base) * test->nb_frame * - pow(10, test->nb_decimals); - if (time >= INT_MAX) - return; - - for (x = 0; x < test->nb_decimals; x++) - p10decimals *= 10; - - second = av_rescale_rnd(test->nb_frame * test->time_base.num, p10decimals, test->time_base.den, AV_ROUND_ZERO); - x = width - (width - seg_size * 64) / 2; - y = (height - seg_size * 13) / 2; - p = data + (x*3 + y * frame->linesize[0]); - for (i = 0; i < 8; i++) { - p -= 3 * 8 * seg_size; - draw_digit(second % 10, p, frame->linesize[0], seg_size); - second /= 10; - if (second == 0) - break; - } - } -} - -static av_cold int test_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->fill_picture_fn = test_fill_picture; - return init(ctx); -} - -static int test_query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_testsrc = { - .name = "testsrc", - .description = NULL_IF_CONFIG_SMALL("Generate test pattern."), - .priv_size = sizeof(TestSourceContext), - .priv_class = &testsrc_class, - .init = test_init, - .uninit = uninit, - .query_formats = test_query_formats, - .inputs = NULL, - .outputs = avfilter_vsrc_testsrc_outputs, -}; - -#endif /* CONFIG_TESTSRC_FILTER */ - -#if CONFIG_RGBTESTSRC_FILTER - -#define rgbtestsrc_options options -AVFILTER_DEFINE_CLASS(rgbtestsrc); - -#define R 0 -#define G 1 -#define B 2 -#define A 3 - -static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize, - int x, int y, int r, int g, int b, enum AVPixelFormat fmt, - uint8_t rgba_map[4]) -{ - int32_t v; - uint8_t *p; - - switch (fmt) { - case AV_PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break; - case AV_PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break; - case AV_PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break; - case AV_PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break; - case AV_PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break; - case AV_PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break; - case AV_PIX_FMT_RGB24: - case AV_PIX_FMT_BGR24: - v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)); - p = dst + 3*x + y*dst_linesize; - AV_WL24(p, v); - break; - case AV_PIX_FMT_RGBA: - case AV_PIX_FMT_BGRA: - case AV_PIX_FMT_ARGB: - case AV_PIX_FMT_ABGR: - v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)) + (255 << (rgba_map[A]*8)); - p = dst + 4*x + y*dst_linesize; - AV_WL32(p, v); - break; - } -} - -static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame) -{ - TestSourceContext *test = ctx->priv; - int x, y, w = frame->width, h = frame->height; - - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - int c = 256*x/w; - int r = 0, g = 0, b = 0; - - if (3*y < h ) r = c; - else if (3*y < 2*h) g = c; - else b = c; - - rgbtest_put_pixel(frame->data[0], frame->linesize[0], x, y, r, g, b, - ctx->outputs[0]->format, test->rgba_map); - } - } -} - -static av_cold int rgbtest_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->draw_once = 1; - test->fill_picture_fn = rgbtest_fill_picture; - return init(ctx); -} - -static int rgbtest_query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_RGBA, AV_PIX_FMT_ARGB, AV_PIX_FMT_BGRA, AV_PIX_FMT_ABGR, - AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, - AV_PIX_FMT_RGB444, AV_PIX_FMT_BGR444, - AV_PIX_FMT_RGB565, AV_PIX_FMT_BGR565, - AV_PIX_FMT_RGB555, AV_PIX_FMT_BGR555, - AV_PIX_FMT_NONE - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static int rgbtest_config_props(AVFilterLink *outlink) -{ - TestSourceContext *test = outlink->src->priv; - - ff_fill_rgba_map(test->rgba_map, outlink->format); - return config_props(outlink); -} - -static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = rgbtest_config_props, - }, - { NULL } -}; - -AVFilter ff_vsrc_rgbtestsrc = { - .name = "rgbtestsrc", - .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."), - .priv_size = sizeof(TestSourceContext), - .priv_class = &rgbtestsrc_class, - .init = rgbtest_init, - .uninit = uninit, - .query_formats = rgbtest_query_formats, - .inputs = NULL, - .outputs = avfilter_vsrc_rgbtestsrc_outputs, -}; - -#endif /* CONFIG_RGBTESTSRC_FILTER */ - -#if CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER - -static const uint8_t rainbow[7][4] = { - { 180, 128, 128, 255 }, /* gray */ - { 168, 44, 136, 255 }, /* yellow */ - { 145, 147, 44, 255 }, /* cyan */ - { 133, 63, 52, 255 }, /* green */ - { 63, 193, 204, 255 }, /* magenta */ - { 51, 109, 212, 255 }, /* red */ - { 28, 212, 120, 255 }, /* blue */ -}; - -static const uint8_t wobnair[7][4] = { - { 32, 240, 118, 255 }, /* blue */ - { 19, 128, 128, 255 }, /* 7.5% intensity black */ - { 54, 184, 198, 255 }, /* magenta */ - { 19, 128, 128, 255 }, /* 7.5% intensity black */ - { 188, 154, 16, 255 }, /* cyan */ - { 19, 128, 128, 255 }, /* 7.5% intensity black */ - { 191, 128, 128, 255 }, /* gray */ -}; - -static const uint8_t white[4] = { 235, 128, 128, 255 }; -static const uint8_t black[4] = { 19, 128, 128, 255 }; /* 7.5% intensity black */ - -/* pluge pulses */ -static const uint8_t neg4ire[4] = { 9, 128, 128, 255 }; /* 3.5% intensity black */ -static const uint8_t pos4ire[4] = { 29, 128, 128, 255 }; /* 11.5% intensity black */ - -/* fudged Q/-I */ -static const uint8_t i_pixel[4] = { 61, 153, 99, 255 }; -static const uint8_t q_pixel[4] = { 35, 174, 152, 255 }; - -static const uint8_t gray40[4] = { 104, 128, 128, 255 }; -static const uint8_t gray15[4] = { 49, 128, 128, 255 }; -static const uint8_t cyan[4] = { 188, 154, 16, 255 }; -static const uint8_t yellow[4] = { 219, 16, 138, 255 }; -static const uint8_t blue[4] = { 32, 240, 118, 255 }; -static const uint8_t red[4] = { 63, 102, 240, 255 }; -static const uint8_t black0[4] = { 16, 128, 128, 255 }; -static const uint8_t black2[4] = { 20, 128, 128, 255 }; -static const uint8_t black4[4] = { 25, 128, 128, 255 }; -static const uint8_t neg2[4] = { 12, 128, 128, 255 }; - -static void draw_bar(TestSourceContext *test, const uint8_t color[4], - unsigned x, unsigned y, unsigned w, unsigned h, - AVFrame *frame) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); - uint8_t *p, *p0; - int plane; - - x = FFMIN(x, test->w - 1); - y = FFMIN(y, test->h - 1); - w = FFMIN(w, test->w - x); - h = FFMIN(h, test->h - y); - - av_assert0(x + w <= test->w); - av_assert0(y + h <= test->h); - - for (plane = 0; frame->data[plane]; plane++) { - const int c = color[plane]; - const int linesize = frame->linesize[plane]; - int i, px, py, pw, ph; - - if (plane == 1 || plane == 2) { - px = x >> desc->log2_chroma_w; - pw = w >> desc->log2_chroma_w; - py = y >> desc->log2_chroma_h; - ph = h >> desc->log2_chroma_h; - } else { - px = x; - pw = w; - py = y; - ph = h; - } - - p0 = p = frame->data[plane] + py * linesize + px; - memset(p, c, pw); - p += linesize; - for (i = 1; i < ph; i++, p += linesize) - memcpy(p, p0, pw); - } -} - -static int smptebars_query_formats(AVFilterContext *ctx) -{ - static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, - AV_PIX_FMT_NONE, - }; - ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); - return 0; -} - -static const AVFilterPad smptebars_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, - }, - { NULL } -}; - -#if CONFIG_SMPTEBARS_FILTER - -#define smptebars_options options -AVFILTER_DEFINE_CLASS(smptebars); - -static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref) -{ - TestSourceContext *test = ctx->priv; - int r_w, r_h, w_h, p_w, p_h, i, tmp, x = 0; - const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); - - av_frame_set_colorspace(picref, AVCOL_SPC_BT470BG); - - r_w = FFALIGN((test->w + 6) / 7, 1 << pixdesc->log2_chroma_w); - r_h = FFALIGN(test->h * 2 / 3, 1 << pixdesc->log2_chroma_h); - w_h = FFALIGN(test->h * 3 / 4 - r_h, 1 << pixdesc->log2_chroma_h); - p_w = FFALIGN(r_w * 5 / 4, 1 << pixdesc->log2_chroma_w); - p_h = test->h - w_h - r_h; - - for (i = 0; i < 7; i++) { - draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref); - draw_bar(test, wobnair[i], x, r_h, r_w, w_h, picref); - x += r_w; - } - x = 0; - draw_bar(test, i_pixel, x, r_h + w_h, p_w, p_h, picref); - x += p_w; - draw_bar(test, white, x, r_h + w_h, p_w, p_h, picref); - x += p_w; - draw_bar(test, q_pixel, x, r_h + w_h, p_w, p_h, picref); - x += p_w; - tmp = FFALIGN(5 * r_w - x, 1 << pixdesc->log2_chroma_w); - draw_bar(test, black, x, r_h + w_h, tmp, p_h, picref); - x += tmp; - tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w); - draw_bar(test, neg4ire, x, r_h + w_h, tmp, p_h, picref); - x += tmp; - draw_bar(test, black, x, r_h + w_h, tmp, p_h, picref); - x += tmp; - draw_bar(test, pos4ire, x, r_h + w_h, tmp, p_h, picref); - x += tmp; - draw_bar(test, black, x, r_h + w_h, test->w - x, p_h, picref); -} - -static av_cold int smptebars_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->fill_picture_fn = smptebars_fill_picture; - test->draw_once = 1; - return init(ctx); -} - -AVFilter ff_vsrc_smptebars = { - .name = "smptebars", - .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."), - .priv_size = sizeof(TestSourceContext), - .priv_class = &smptebars_class, - .init = smptebars_init, - .uninit = uninit, - .query_formats = smptebars_query_formats, - .inputs = NULL, - .outputs = smptebars_outputs, -}; - -#endif /* CONFIG_SMPTEBARS_FILTER */ - -#if CONFIG_SMPTEHDBARS_FILTER - -#define smptehdbars_options options -AVFILTER_DEFINE_CLASS(smptehdbars); - -static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref) -{ - TestSourceContext *test = ctx->priv; - int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0; - const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); - - av_frame_set_colorspace(picref, AVCOL_SPC_BT709); - - d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w); - r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h); - draw_bar(test, gray40, x, 0, d_w, r_h, picref); - x += d_w; - - r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w); - for (i = 0; i < 7; i++) { - draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref); - x += r_w; - } - draw_bar(test, gray40, x, 0, test->w - x, r_h, picref); - y = r_h; - r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h); - draw_bar(test, cyan, 0, y, d_w, r_h, picref); - x = d_w; - draw_bar(test, i_pixel, x, y, r_w, r_h, picref); - x += r_w; - tmp = r_w * 6; - draw_bar(test, rainbow[0], x, y, tmp, r_h, picref); - x += tmp; - l_w = x; - draw_bar(test, blue, x, y, test->w - x, r_h, picref); - y += r_h; - draw_bar(test, yellow, 0, y, d_w, r_h, picref); - x = d_w; - draw_bar(test, q_pixel, x, y, r_w, r_h, picref); - x += r_w; - - for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) { - uint8_t yramp[4] = {0}; - - yramp[0] = i * 255 / tmp; - yramp[1] = 128; - yramp[2] = 128; - yramp[3] = 255; - - draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref); - x += 1 << pixdesc->log2_chroma_w; - } - draw_bar(test, red, x, y, test->w - x, r_h, picref); - y += r_h; - draw_bar(test, gray15, 0, y, d_w, test->h - y, picref); - x = d_w; - tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w); - draw_bar(test, black0, x, y, tmp, test->h - y, picref); - x += tmp; - tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w); - draw_bar(test, white, x, y, tmp, test->h - y, picref); - x += tmp; - tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w); - draw_bar(test, black0, x, y, tmp, test->h - y, picref); - x += tmp; - tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w); - draw_bar(test, neg2, x, y, tmp, test->h - y, picref); - x += tmp; - draw_bar(test, black0, x, y, tmp, test->h - y, picref); - x += tmp; - draw_bar(test, black2, x, y, tmp, test->h - y, picref); - x += tmp; - draw_bar(test, black0, x, y, tmp, test->h - y, picref); - x += tmp; - draw_bar(test, black4, x, y, tmp, test->h - y, picref); - x += tmp; - r_w = l_w - x; - draw_bar(test, black0, x, y, r_w, test->h - y, picref); - x += r_w; - draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref); -} - -static av_cold int smptehdbars_init(AVFilterContext *ctx) -{ - TestSourceContext *test = ctx->priv; - - test->fill_picture_fn = smptehdbars_fill_picture; - test->draw_once = 1; - return init(ctx); -} - -AVFilter ff_vsrc_smptehdbars = { - .name = "smptehdbars", - .description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."), - .priv_size = sizeof(TestSourceContext), - .priv_class = &smptehdbars_class, - .init = smptehdbars_init, - .uninit = uninit, - .query_formats = smptebars_query_formats, - .inputs = NULL, - .outputs = smptebars_outputs, -}; - -#endif /* CONFIG_SMPTEHDBARS_FILTER */ -#endif /* CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */ diff --git a/ffmpeg/libavfilter/x86/Makefile b/ffmpeg/libavfilter/x86/Makefile deleted file mode 100644 index be4ad83..0000000 --- a/ffmpeg/libavfilter/x86/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun_init.o -OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d_init.o -OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup_init.o -OBJS-$(CONFIG_SPP_FILTER) += x86/vf_spp.o -OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume_init.o - -YASM-OBJS-$(CONFIG_GRADFUN_FILTER) += x86/vf_gradfun.o -YASM-OBJS-$(CONFIG_HQDN3D_FILTER) += x86/vf_hqdn3d.o -YASM-OBJS-$(CONFIG_PULLUP_FILTER) += x86/vf_pullup.o -YASM-OBJS-$(CONFIG_VOLUME_FILTER) += x86/af_volume.o -YASM-OBJS-$(CONFIG_YADIF_FILTER) += x86/vf_yadif.o x86/yadif-16.o x86/yadif-10.o diff --git a/ffmpeg/libavfilter/x86/af_volume.asm b/ffmpeg/libavfilter/x86/af_volume.asm deleted file mode 100644 index f4cbcbc..0000000 --- a/ffmpeg/libavfilter/x86/af_volume.asm +++ /dev/null @@ -1,140 +0,0 @@ -;***************************************************************************** -;* x86-optimized functions for volume filter -;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com> -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg is free software; you can redistribute it and/or -;* modify it under the terms of the GNU Lesser General Public -;* License as published by the Free Software Foundation; either -;* version 2.1 of the License, or (at your option) any later version. -;* -;* FFmpeg is distributed in the hope that it will be useful, -;* but WITHOUT ANY WARRANTY; without even the implied warranty of -;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;* Lesser General Public License for more details. -;* -;* You should have received a copy of the GNU Lesser General Public -;* License along with FFmpeg; if not, write to the Free Software -;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "libavutil/x86/x86util.asm" - -SECTION_RODATA 32 - -pd_1_256: times 4 dq 0x3F70000000000000 -pd_int32_max: times 4 dq 0x41DFFFFFFFC00000 -pw_1: times 8 dw 1 -pw_128: times 8 dw 128 -pq_128: times 2 dq 128 - -SECTION_TEXT - -;------------------------------------------------------------------------------ -; void ff_scale_samples_s16(uint8_t *dst, const uint8_t *src, int len, -; int volume) -;------------------------------------------------------------------------------ - -INIT_XMM sse2 -cglobal scale_samples_s16, 4,4,4, dst, src, len, volume - movd m0, volumem - pshuflw m0, m0, 0 - punpcklwd m0, [pw_1] - mova m1, [pw_128] - lea lenq, [lend*2-mmsize] -.loop: - ; dst[i] = av_clip_int16((src[i] * volume + 128) >> 8); - mova m2, [srcq+lenq] - punpcklwd m3, m2, m1 - punpckhwd m2, m1 - pmaddwd m3, m0 - pmaddwd m2, m0 - psrad m3, 8 - psrad m2, 8 - packssdw m3, m2 - mova [dstq+lenq], m3 - sub lenq, mmsize - jge .loop - REP_RET - -;------------------------------------------------------------------------------ -; void ff_scale_samples_s32(uint8_t *dst, const uint8_t *src, int len, -; int volume) -;------------------------------------------------------------------------------ - -%macro SCALE_SAMPLES_S32 0 -cglobal scale_samples_s32, 4,4,4, dst, src, len, volume -%if ARCH_X86_32 && cpuflag(avx) - vbroadcastss xmm2, volumem -%else - movd xmm2, volumed - pshufd xmm2, xmm2, 0 -%endif - CVTDQ2PD m2, xmm2 - mulpd m2, m2, [pd_1_256] - mova m3, [pd_int32_max] - lea lenq, [lend*4-mmsize] -.loop: - CVTDQ2PD m0, [srcq+lenq ] - CVTDQ2PD m1, [srcq+lenq+mmsize/2] - mulpd m0, m0, m2 - mulpd m1, m1, m2 - minpd m0, m0, m3 - minpd m1, m1, m3 - cvtpd2dq xmm0, m0 - cvtpd2dq xmm1, m1 -%if cpuflag(avx) - vmovdqa [dstq+lenq ], xmm0 - vmovdqa [dstq+lenq+mmsize/2], xmm1 -%else - movq [dstq+lenq ], xmm0 - movq [dstq+lenq+mmsize/2], xmm1 -%endif - sub lenq, mmsize - jge .loop - REP_RET -%endmacro - -INIT_XMM sse2 -%define CVTDQ2PD cvtdq2pd -SCALE_SAMPLES_S32 -%if HAVE_AVX_EXTERNAL -%define CVTDQ2PD vcvtdq2pd -INIT_YMM avx -SCALE_SAMPLES_S32 -%endif -%undef CVTDQ2PD - -; NOTE: This is not bit-identical with the C version because it clips to -; [-INT_MAX, INT_MAX] instead of [INT_MIN, INT_MAX] - -INIT_XMM ssse3, atom -cglobal scale_samples_s32, 4,4,8, dst, src, len, volume - movd m4, volumem - pshufd m4, m4, 0 - mova m5, [pq_128] - pxor m6, m6 - lea lenq, [lend*4-mmsize] -.loop: - ; src[i] = av_clipl_int32((src[i] * volume + 128) >> 8); - mova m7, [srcq+lenq] - pabsd m3, m7 - pshufd m0, m3, q0100 - pshufd m1, m3, q0302 - pmuludq m0, m4 - pmuludq m1, m4 - paddq m0, m5 - paddq m1, m5 - psrlq m0, 7 - psrlq m1, 7 - shufps m2, m0, m1, q3131 - shufps m0, m0, m1, q2020 - pcmpgtd m2, m6 - por m0, m2 - psrld m0, 1 - psignd m0, m7 - mova [dstq+lenq], m0 - sub lenq, mmsize - jge .loop - REP_RET diff --git a/ffmpeg/libavfilter/x86/af_volume_init.c b/ffmpeg/libavfilter/x86/af_volume_init.c deleted file mode 100644 index 57c7eab..0000000 --- a/ffmpeg/libavfilter/x86/af_volume_init.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "libavutil/attributes.h" -#include "libavutil/cpu.h" -#include "libavutil/samplefmt.h" -#include "libavutil/x86/cpu.h" -#include "libavfilter/af_volume.h" - -void ff_scale_samples_s16_sse2(uint8_t *dst, const uint8_t *src, int len, - int volume); - -void ff_scale_samples_s32_sse2(uint8_t *dst, const uint8_t *src, int len, - int volume); -void ff_scale_samples_s32_ssse3_atom(uint8_t *dst, const uint8_t *src, int len, - int volume); -void ff_scale_samples_s32_avx(uint8_t *dst, const uint8_t *src, int len, - int volume); - -av_cold void ff_volume_init_x86(VolumeContext *vol) -{ - int cpu_flags = av_get_cpu_flags(); - enum AVSampleFormat sample_fmt = av_get_packed_sample_fmt(vol->sample_fmt); - - if (sample_fmt == AV_SAMPLE_FMT_S16) { - if (EXTERNAL_SSE2(cpu_flags) && vol->volume_i < 32768) { - vol->scale_samples = ff_scale_samples_s16_sse2; - vol->samples_align = 8; - } - } else if (sample_fmt == AV_SAMPLE_FMT_S32) { - if (EXTERNAL_SSE2(cpu_flags)) { - vol->scale_samples = ff_scale_samples_s32_sse2; - vol->samples_align = 4; - } - if (EXTERNAL_SSSE3(cpu_flags) && cpu_flags & AV_CPU_FLAG_ATOM) { - vol->scale_samples = ff_scale_samples_s32_ssse3_atom; - vol->samples_align = 4; - } - if (EXTERNAL_AVX(cpu_flags)) { - vol->scale_samples = ff_scale_samples_s32_avx; - vol->samples_align = 8; - } - } -} diff --git a/ffmpeg/libavfilter/x86/vf_hqdn3d.asm b/ffmpeg/libavfilter/x86/vf_hqdn3d.asm deleted file mode 100644 index 961127e..0000000 --- a/ffmpeg/libavfilter/x86/vf_hqdn3d.asm +++ /dev/null @@ -1,106 +0,0 @@ -;****************************************************************************** -;* Copyright (c) 2012 Loren Merritt -;* -;* This file is part of FFmpeg. -;* -;* FFmpeg is free software; you can redistribute it and/or -;* modify it under the terms of the GNU Lesser General Public -;* License as published by the Free Software Foundation; either -;* version 2.1 of the License, or (at your option) any later version. -;* -;* FFmpeg is distributed in the hope that it will be useful, -;* but WITHOUT ANY WARRANTY; without even the implied warranty of -;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;* Lesser General Public License for more details. -;* -;* You should have received a copy of the GNU Lesser General Public -;* License along with FFmpeg; if not, write to the Free Software -;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -;****************************************************************************** - -%include "libavutil/x86/x86util.asm" - -SECTION .text - -%macro LOWPASS 3 ; prevsample, cursample, lut - sub %1q, %2q -%if lut_bits != 8 - sar %1q, 8-lut_bits -%endif - movsx %1d, word [%3q+%1q*2] - add %1d, %2d -%endmacro - -%macro LOAD 3 ; dstreg, x, bitdepth -%if %3 == 8 - movzx %1, byte [srcq+%2] -%else - movzx %1, word [srcq+(%2)*2] -%endif -%if %3 != 16 - shl %1, 16-%3 - add %1, (1<<(15-%3))-1 -%endif -%endmacro - -%macro HQDN3D_ROW 1 ; bitdepth -%if ARCH_X86_64 -cglobal hqdn3d_row_%1_x86, 7,10,0, src, dst, lineant, frameant, width, spatial, temporal, pixelant, t0, t1 -%else -cglobal hqdn3d_row_%1_x86, 7,7,0, src, dst, lineant, frameant, width, spatial, temporal -%endif - %assign bytedepth (%1+7)>>3 - %assign lut_bits 4+4*(%1/16) - dec widthq - lea srcq, [srcq+widthq*bytedepth] - lea dstq, [dstq+widthq*bytedepth] - lea frameantq, [frameantq+widthq*2] - lea lineantq, [lineantq+widthq*2] - neg widthq - %define xq widthq -%if ARCH_X86_32 - mov dstmp, dstq - mov srcmp, srcq - mov frameantmp, frameantq - mov lineantmp, lineantq - %define dstq r0 - %define frameantq r0 - %define lineantq r0 - %define pixelantq r1 - %define pixelantd r1d - DECLARE_REG_TMP 2,3 -%endif - LOAD pixelantd, xq, %1 -ALIGN 16 -.loop: - movifnidn srcq, srcmp - LOAD t0d, xq+1, %1 ; skip on the last iteration to avoid overread -.loop2: - movifnidn lineantq, lineantmp - movzx t1d, word [lineantq+xq*2] - LOWPASS t1, pixelant, spatial - mov [lineantq+xq*2], t1w - LOWPASS pixelant, t0, spatial - movifnidn frameantq, frameantmp - movzx t0d, word [frameantq+xq*2] - LOWPASS t0, t1, temporal - mov [frameantq+xq*2], t0w - movifnidn dstq, dstmp -%if %1 != 16 - shr t0d, 16-%1 ; could eliminate this by storing from t0h, but only with some contraints on register allocation -%endif -%if %1 == 8 - mov [dstq+xq], t0b -%else - mov [dstq+xq*2], t0w -%endif - inc xq - jl .loop - je .loop2 - REP_RET -%endmacro ; HQDN3D_ROW - -HQDN3D_ROW 8 -HQDN3D_ROW 9 -HQDN3D_ROW 10 -HQDN3D_ROW 16 diff --git a/ffmpeg/libavfilter/x86/vf_hqdn3d_init.c b/ffmpeg/libavfilter/x86/vf_hqdn3d_init.c deleted file mode 100644 index b63916b..0000000 --- a/ffmpeg/libavfilter/x86/vf_hqdn3d_init.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2012 Loren Merritt - * - * 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 <stddef.h> -#include <stdint.h> - -#include "libavutil/attributes.h" -#include "libavfilter/vf_hqdn3d.h" -#include "config.h" - -void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, - uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, - int16_t *temporal); -void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, - uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, - int16_t *temporal); -void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, - uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, - int16_t *temporal); -void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, - uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, - int16_t *temporal); - -av_cold void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d) -{ -#if HAVE_YASM - hqdn3d->denoise_row[8] = ff_hqdn3d_row_8_x86; - hqdn3d->denoise_row[9] = ff_hqdn3d_row_9_x86; - hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86; - hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86; -#endif /* HAVE_YASM */ -} diff --git a/ffmpeg/libavfilter/x86/vf_yadif.asm b/ffmpeg/libavfilter/x86/vf_yadif.asm deleted file mode 100644 index ebc505c..0000000 --- a/ffmpeg/libavfilter/x86/vf_yadif.asm +++ /dev/null @@ -1,252 +0,0 @@ -;***************************************************************************** -;* x86-optimized functions for yadif filter -;* -;* Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at> -;* Copyright (c) 2013 Daniel Kang <daniel.d.kang@gmail.com> -;* -;* 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/x86/x86util.asm" - -SECTION_RODATA - -pb_1: times 16 db 1 -pw_1: times 8 dw 1 - -SECTION .text - -%macro CHECK 2 - movu m2, [curq+t1+%1] - movu m3, [curq+t0+%2] - mova m4, m2 - mova m5, m2 - pxor m4, m3 - pavgb m5, m3 - pand m4, [pb_1] - psubusb m5, m4 -%if mmsize == 16 - psrldq m5, 1 -%else - psrlq m5, 8 -%endif - punpcklbw m5, m7 - mova m4, m2 - psubusb m2, m3 - psubusb m3, m4 - pmaxub m2, m3 - mova m3, m2 - mova m4, m2 -%if mmsize == 16 - psrldq m3, 1 - psrldq m4, 2 -%else - psrlq m3, 8 - psrlq m4, 16 -%endif - punpcklbw m2, m7 - punpcklbw m3, m7 - punpcklbw m4, m7 - paddw m2, m3 - paddw m2, m4 -%endmacro - -%macro CHECK1 0 - mova m3, m0 - pcmpgtw m3, m2 - pminsw m0, m2 - mova m6, m3 - pand m5, m3 - pandn m3, m1 - por m3, m5 - mova m1, m3 -%endmacro - -%macro CHECK2 0 - paddw m6, [pw_1] - psllw m6, 14 - paddsw m2, m6 - mova m3, m0 - pcmpgtw m3, m2 - pminsw m0, m2 - pand m5, m3 - pandn m3, m1 - por m3, m5 - mova m1, m3 -%endmacro - -%macro LOAD 2 - movh %1, %2 - punpcklbw %1, m7 -%endmacro - -%macro FILTER 3 -.loop%1: - pxor m7, m7 - LOAD m0, [curq+t1] - LOAD m1, [curq+t0] - LOAD m2, [%2] - LOAD m3, [%3] - mova m4, m3 - paddw m3, m2 - psraw m3, 1 - mova [rsp+ 0], m0 - mova [rsp+16], m3 - mova [rsp+32], m1 - psubw m2, m4 - ABS1 m2, m4 - LOAD m3, [prevq+t1] - LOAD m4, [prevq+t0] - psubw m3, m0 - psubw m4, m1 - ABS1 m3, m5 - ABS1 m4, m5 - paddw m3, m4 - psrlw m2, 1 - psrlw m3, 1 - pmaxsw m2, m3 - LOAD m3, [nextq+t1] - LOAD m4, [nextq+t0] - psubw m3, m0 - psubw m4, m1 - ABS1 m3, m5 - ABS1 m4, m5 - paddw m3, m4 - psrlw m3, 1 - pmaxsw m2, m3 - mova [rsp+48], m2 - - paddw m1, m0 - paddw m0, m0 - psubw m0, m1 - psrlw m1, 1 - ABS1 m0, m2 - - movu m2, [curq+t1-1] - movu m3, [curq+t0-1] - mova m4, m2 - psubusb m2, m3 - psubusb m3, m4 - pmaxub m2, m3 -%if mmsize == 16 - mova m3, m2 - psrldq m3, 2 -%else - pshufw m3, m2, q0021 -%endif - punpcklbw m2, m7 - punpcklbw m3, m7 - paddw m0, m2 - paddw m0, m3 - psubw m0, [pw_1] - - CHECK -2, 0 - CHECK1 - CHECK -3, 1 - CHECK2 - CHECK 0, -2 - CHECK1 - CHECK 1, -3 - CHECK2 - - mova m6, [rsp+48] - cmp DWORD r8m, 2 - jge .end%1 - LOAD m2, [%2+t1*2] - LOAD m4, [%3+t1*2] - LOAD m3, [%2+t0*2] - LOAD m5, [%3+t0*2] - paddw m2, m4 - paddw m3, m5 - psrlw m2, 1 - psrlw m3, 1 - mova m4, [rsp+ 0] - mova m5, [rsp+16] - mova m7, [rsp+32] - psubw m2, m4 - psubw m3, m7 - mova m0, m5 - psubw m5, m4 - psubw m0, m7 - mova m4, m2 - pminsw m2, m3 - pmaxsw m3, m4 - pmaxsw m2, m5 - pminsw m3, m5 - pmaxsw m2, m0 - pminsw m3, m0 - pxor m4, m4 - pmaxsw m6, m3 - psubw m4, m2 - pmaxsw m6, m4 - -.end%1: - mova m2, [rsp+16] - mova m3, m2 - psubw m2, m6 - paddw m3, m6 - pmaxsw m1, m2 - pminsw m1, m3 - packuswb m1, m1 - - movh [dstq], m1 - add dstq, mmsize/2 - add prevq, mmsize/2 - add curq, mmsize/2 - add nextq, mmsize/2 - sub DWORD r4m, mmsize/2 - jg .loop%1 -%endmacro - -%macro YADIF 0 -%if ARCH_X86_32 -cglobal yadif_filter_line, 4, 6, 8, 80, dst, prev, cur, next, w, prefs, \ - mrefs, parity, mode -%else -cglobal yadif_filter_line, 4, 7, 8, 80, dst, prev, cur, next, w, prefs, \ - mrefs, parity, mode -%endif -%if ARCH_X86_32 - mov r4, r5mp - mov r5, r6mp - DECLARE_REG_TMP 4,5 -%else - movsxd r5, DWORD r5m - movsxd r6, DWORD r6m - DECLARE_REG_TMP 5,6 -%endif - - cmp DWORD paritym, 0 - je .parity0 - FILTER 1, prevq, curq - jmp .ret - -.parity0: - FILTER 0, curq, nextq - -.ret: - RET -%endmacro - -INIT_XMM ssse3 -YADIF -INIT_XMM sse2 -YADIF -%if ARCH_X86_32 -INIT_MMX mmxext -YADIF -%endif diff --git a/ffmpeg/libavfilter/x86/yadif-10.asm b/ffmpeg/libavfilter/x86/yadif-10.asm deleted file mode 100644 index d586deb..0000000 --- a/ffmpeg/libavfilter/x86/yadif-10.asm +++ /dev/null @@ -1,282 +0,0 @@ -;***************************************************************************** -;* x86-optimized functions for yadif filter -;* -;* Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at> -;* Copyright (c) 2013 Daniel Kang <daniel.d.kang@gmail.com> -;* Copyright (c) 2011-2013 James Darnley <james.darnley@gmail.com> -;* -;* 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/x86/x86util.asm" - -SECTION_RODATA - -pw_1: times 8 dw 1 - -SECTION .text - -%macro PABS 2 -%if cpuflag(ssse3) - pabsw %1, %1 -%else - pxor %2, %2 - pcmpgtw %2, %1 - pxor %1, %2 - psubw %1, %2 -%endif -%endmacro - -%macro PMAXUW 2 -%if cpuflag(sse4) - pmaxuw %1, %2 -%else - psubusw %1, %2 - paddusw %1, %2 -%endif -%endmacro - -%macro CHECK 2 - movu m2, [curq+t1+%1*2] - movu m3, [curq+t0+%2*2] - mova m4, m2 - mova m5, m2 - pxor m4, m3 - pavgw m5, m3 - pand m4, [pw_1] - psubusw m5, m4 -%if mmsize == 16 - psrldq m5, 2 -%else - psrlq m5, 16 -%endif - mova m4, m2 - psubusw m2, m3 - psubusw m3, m4 - PMAXUW m2, m3 - mova m3, m2 - mova m4, m2 -%if mmsize == 16 - psrldq m3, 2 - psrldq m4, 4 -%else - psrlq m3, 16 - psrlq m4, 32 -%endif - paddw m2, m3 - paddw m2, m4 -%endmacro - -%macro CHECK1 0 - mova m3, m0 - pcmpgtw m3, m2 - pminsw m0, m2 - mova m6, m3 - pand m5, m3 - pandn m3, m1 - por m3, m5 - mova m1, m3 -%endmacro - -; %macro CHECK2 0 -; paddw m6, [pw_1] -; psllw m6, 14 -; paddsw m2, m6 -; mova m3, m0 -; pcmpgtw m3, m2 -; pminsw m0, m2 -; pand m5, m3 -; pandn m3, m1 -; por m3, m5 -; mova m1, m3 -; %endmacro - -; This version of CHECK2 is required for 14-bit samples. The left-shift trick -; in the old code is not large enough to correctly select pixels or scores. - -%macro CHECK2 0 - mova m3, m0 - pcmpgtw m0, m2 - pand m0, m6 - mova m6, m0 - pand m5, m6 - pand m2, m0 - pandn m6, m1 - pandn m0, m3 - por m6, m5 - por m0, m2 - mova m1, m6 -%endmacro - -%macro LOAD 2 - movu %1, %2 -%endmacro - -%macro FILTER 3 -.loop%1: - pxor m7, m7 - LOAD m0, [curq+t1] - LOAD m1, [curq+t0] - LOAD m2, [%2] - LOAD m3, [%3] - mova m4, m3 - paddw m3, m2 - psraw m3, 1 - mova [rsp+ 0], m0 - mova [rsp+16], m3 - mova [rsp+32], m1 - psubw m2, m4 - PABS m2, m4 - LOAD m3, [prevq+t1] - LOAD m4, [prevq+t0] - psubw m3, m0 - psubw m4, m1 - PABS m3, m5 - PABS m4, m5 - paddw m3, m4 - psrlw m2, 1 - psrlw m3, 1 - pmaxsw m2, m3 - LOAD m3, [nextq+t1] - LOAD m4, [nextq+t0] - psubw m3, m0 - psubw m4, m1 - PABS m3, m5 - PABS m4, m5 - paddw m3, m4 - psrlw m3, 1 - pmaxsw m2, m3 - mova [rsp+48], m2 - - paddw m1, m0 - paddw m0, m0 - psubw m0, m1 - psrlw m1, 1 - PABS m0, m2 - - movu m2, [curq+t1-1*2] - movu m3, [curq+t0-1*2] - mova m4, m2 - psubusw m2, m3 - psubusw m3, m4 - PMAXUW m2, m3 -%if mmsize == 16 - mova m3, m2 - psrldq m3, 4 -%else - mova m3, m2 - psrlq m3, 32 -%endif - paddw m0, m2 - paddw m0, m3 - psubw m0, [pw_1] - - CHECK -2, 0 - CHECK1 - CHECK -3, 1 - CHECK2 - CHECK 0, -2 - CHECK1 - CHECK 1, -3 - CHECK2 - - mova m6, [rsp+48] - cmp DWORD r8m, 2 - jge .end%1 - LOAD m2, [%2+t1*2] - LOAD m4, [%3+t1*2] - LOAD m3, [%2+t0*2] - LOAD m5, [%3+t0*2] - paddw m2, m4 - paddw m3, m5 - psrlw m2, 1 - psrlw m3, 1 - mova m4, [rsp+ 0] - mova m5, [rsp+16] - mova m7, [rsp+32] - psubw m2, m4 - psubw m3, m7 - mova m0, m5 - psubw m5, m4 - psubw m0, m7 - mova m4, m2 - pminsw m2, m3 - pmaxsw m3, m4 - pmaxsw m2, m5 - pminsw m3, m5 - pmaxsw m2, m0 - pminsw m3, m0 - pxor m4, m4 - pmaxsw m6, m3 - psubw m4, m2 - pmaxsw m6, m4 - -.end%1: - mova m2, [rsp+16] - mova m3, m2 - psubw m2, m6 - paddw m3, m6 - pmaxsw m1, m2 - pminsw m1, m3 - - movu [dstq], m1 - add dstq, mmsize-4 - add prevq, mmsize-4 - add curq, mmsize-4 - add nextq, mmsize-4 - sub DWORD r4m, mmsize/2-2 - jg .loop%1 -%endmacro - -%macro YADIF 0 -%if ARCH_X86_32 -cglobal yadif_filter_line_10bit, 4, 6, 8, 80, dst, prev, cur, next, w, \ - prefs, mrefs, parity, mode -%else -cglobal yadif_filter_line_10bit, 4, 7, 8, 80, dst, prev, cur, next, w, \ - prefs, mrefs, parity, mode -%endif -%if ARCH_X86_32 - mov r4, r5mp - mov r5, r6mp - DECLARE_REG_TMP 4,5 -%else - movsxd r5, DWORD r5m - movsxd r6, DWORD r6m - DECLARE_REG_TMP 5,6 -%endif - - cmp DWORD paritym, 0 - je .parity0 - FILTER 1, prevq, curq - jmp .ret - -.parity0: - FILTER 0, curq, nextq - -.ret: - RET -%endmacro - -INIT_XMM ssse3 -YADIF -INIT_XMM sse2 -YADIF -%if ARCH_X86_32 -INIT_MMX mmxext -YADIF -%endif diff --git a/ffmpeg/libavfilter/x86/yadif-16.asm b/ffmpeg/libavfilter/x86/yadif-16.asm deleted file mode 100644 index a2e6006..0000000 --- a/ffmpeg/libavfilter/x86/yadif-16.asm +++ /dev/null @@ -1,347 +0,0 @@ -;***************************************************************************** -;* x86-optimized functions for yadif filter -;* -;* Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at> -;* Copyright (c) 2013 Daniel Kang <daniel.d.kang@gmail.com> -;* Copyright (c) 2011-2013 James Darnley <james.darnley@gmail.com> -;* -;* 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/x86/x86util.asm" - -SECTION_RODATA - -pw_1: times 8 dw 1 -pw_8000: times 8 dw 0x8000 -pd_1: times 4 dd 1 -pd_8000: times 4 dd 0x8000 - -SECTION .text - -%macro PIXSHIFT1 1 -%if cpuflag(sse2) - psrldq %1, 2 -%else - psrlq %1, 16 -%endif -%endmacro - -%macro PIXSHIFT2 1 -%if cpuflag(sse2) - psrldq %1, 4 -%else - psrlq %1, 32 -%endif -%endmacro - -%macro PABS 2 -%if cpuflag(ssse3) - pabsd %1, %1 -%else - pxor %2, %2 - pcmpgtd %2, %1 - pxor %1, %2 - psubd %1, %2 -%endif -%endmacro - -%macro PACK 1 -%if cpuflag(sse4) - packusdw %1, %1 -%else - psubd %1, [pd_8000] - packssdw %1, %1 - paddw %1, [pw_8000] -%endif -%endmacro - -%macro PMINSD 3 -%if cpuflag(sse4) - pminsd %1, %2 -%else - mova %3, %2 - pcmpgtd %3, %1 - pand %1, %3 - pandn %3, %2 - por %1, %3 -%endif -%endmacro - -%macro PMAXSD 3 -%if cpuflag(sse4) - pmaxsd %1, %2 -%else - mova %3, %1 - pcmpgtd %3, %2 - pand %1, %3 - pandn %3, %2 - por %1, %3 -%endif -%endmacro - -%macro PMAXUW 2 -%if cpuflag(sse4) - pmaxuw %1, %2 -%else - psubusw %1, %2 - paddusw %1, %2 -%endif -%endmacro - -%macro CHECK 2 - movu m2, [curq+t1+%1*2] - movu m3, [curq+t0+%2*2] - mova m4, m2 - mova m5, m2 - pxor m4, m3 - pavgw m5, m3 - pand m4, [pw_1] - psubusw m5, m4 -%if mmsize == 16 - psrldq m5, 2 -%else - psrlq m5, 16 -%endif - punpcklwd m5, m7 - mova m4, m2 - psubusw m2, m3 - psubusw m3, m4 - PMAXUW m2, m3 - mova m3, m2 - mova m4, m2 -%if mmsize == 16 - psrldq m3, 2 - psrldq m4, 4 -%else - psrlq m3, 16 - psrlq m4, 32 -%endif - punpcklwd m2, m7 - punpcklwd m3, m7 - punpcklwd m4, m7 - paddd m2, m3 - paddd m2, m4 -%endmacro - -%macro CHECK1 0 - mova m3, m0 - pcmpgtd m3, m2 - PMINSD m0, m2, m6 - mova m6, m3 - pand m5, m3 - pandn m3, m1 - por m3, m5 - mova m1, m3 -%endmacro - -%macro CHECK2 0 - paddd m6, [pd_1] - pslld m6, 30 - paddd m2, m6 - mova m3, m0 - pcmpgtd m3, m2 - PMINSD m0, m2, m4 - pand m5, m3 - pandn m3, m1 - por m3, m5 - mova m1, m3 -%endmacro - -; This version of CHECK2 has 3 fewer instructions on sets older than SSE4 but I -; am not sure whether it is any faster. A rewrite or refactor of the filter -; code should make it possible to eliminate the move intruction at the end. It -; exists to satisfy the expectation that the "score" values are in m1. - -; %macro CHECK2 0 -; mova m3, m0 -; pcmpgtd m0, m2 -; pand m0, m6 -; mova m6, m0 -; pand m5, m6 -; pand m2, m0 -; pandn m6, m1 -; pandn m0, m3 -; por m6, m5 -; por m0, m2 -; mova m1, m6 -; %endmacro - -%macro LOAD 2 - movh %1, %2 - punpcklwd %1, m7 -%endmacro - -%macro FILTER 3 -.loop%1: - pxor m7, m7 - LOAD m0, [curq+t1] - LOAD m1, [curq+t0] - LOAD m2, [%2] - LOAD m3, [%3] - mova m4, m3 - paddd m3, m2 - psrad m3, 1 - mova [rsp+ 0], m0 - mova [rsp+16], m3 - mova [rsp+32], m1 - psubd m2, m4 - PABS m2, m4 - LOAD m3, [prevq+t1] - LOAD m4, [prevq+t0] - psubd m3, m0 - psubd m4, m1 - PABS m3, m5 - PABS m4, m5 - paddd m3, m4 - psrld m2, 1 - psrld m3, 1 - PMAXSD m2, m3, m6 - LOAD m3, [nextq+t1] - LOAD m4, [nextq+t0] - psubd m3, m0 - psubd m4, m1 - PABS m3, m5 - PABS m4, m5 - paddd m3, m4 - psrld m3, 1 - PMAXSD m2, m3, m6 - mova [rsp+48], m2 - - paddd m1, m0 - paddd m0, m0 - psubd m0, m1 - psrld m1, 1 - PABS m0, m2 - - movu m2, [curq+t1-1*2] - movu m3, [curq+t0-1*2] - mova m4, m2 - psubusw m2, m3 - psubusw m3, m4 - PMAXUW m2, m3 -%if mmsize == 16 - mova m3, m2 - psrldq m3, 4 -%else - mova m3, m2 - psrlq m3, 32 -%endif - punpcklwd m2, m7 - punpcklwd m3, m7 - paddd m0, m2 - paddd m0, m3 - psubd m0, [pd_1] - - CHECK -2, 0 - CHECK1 - CHECK -3, 1 - CHECK2 - CHECK 0, -2 - CHECK1 - CHECK 1, -3 - CHECK2 - - mova m6, [rsp+48] - cmp DWORD r8m, 2 - jge .end%1 - LOAD m2, [%2+t1*2] - LOAD m4, [%3+t1*2] - LOAD m3, [%2+t0*2] - LOAD m5, [%3+t0*2] - paddd m2, m4 - paddd m3, m5 - psrld m2, 1 - psrld m3, 1 - mova m4, [rsp+ 0] - mova m5, [rsp+16] - mova m7, [rsp+32] - psubd m2, m4 - psubd m3, m7 - mova m0, m5 - psubd m5, m4 - psubd m0, m7 - mova m4, m2 - PMINSD m2, m3, m7 - PMAXSD m3, m4, m7 - PMAXSD m2, m5, m7 - PMINSD m3, m5, m7 - PMAXSD m2, m0, m7 - PMINSD m3, m0, m7 - pxor m4, m4 - PMAXSD m6, m3, m7 - psubd m4, m2 - PMAXSD m6, m4, m7 - -.end%1: - mova m2, [rsp+16] - mova m3, m2 - psubd m2, m6 - paddd m3, m6 - PMAXSD m1, m2, m7 - PMINSD m1, m3, m7 - PACK m1 - - movh [dstq], m1 - add dstq, mmsize/2 - add prevq, mmsize/2 - add curq, mmsize/2 - add nextq, mmsize/2 - sub DWORD r4m, mmsize/4 - jg .loop%1 -%endmacro - -%macro YADIF 0 -%if ARCH_X86_32 -cglobal yadif_filter_line_16bit, 4, 6, 8, 80, dst, prev, cur, next, w, \ - prefs, mrefs, parity, mode -%else -cglobal yadif_filter_line_16bit, 4, 7, 8, 80, dst, prev, cur, next, w, \ - prefs, mrefs, parity, mode -%endif -%if ARCH_X86_32 - mov r4, r5mp - mov r5, r6mp - DECLARE_REG_TMP 4,5 -%else - movsxd r5, DWORD r5m - movsxd r6, DWORD r6m - DECLARE_REG_TMP 5,6 -%endif - - cmp DWORD paritym, 0 - je .parity0 - FILTER 1, prevq, curq - jmp .ret - -.parity0: - FILTER 0, curq, nextq - -.ret: - RET -%endmacro - -INIT_XMM sse4 -YADIF -INIT_XMM ssse3 -YADIF -INIT_XMM sse2 -YADIF -%if ARCH_X86_32 -INIT_MMX mmxext -YADIF -%endif diff --git a/ffmpeg/libavfilter/yadif.h b/ffmpeg/libavfilter/yadif.h deleted file mode 100644 index 5afe014..0000000 --- a/ffmpeg/libavfilter/yadif.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ - -#ifndef AVFILTER_YADIF_H -#define AVFILTER_YADIF_H - -#include "avfilter.h" - -enum YADIFMode { - YADIF_MODE_SEND_FRAME = 0, ///< send 1 frame for each frame - YADIF_MODE_SEND_FIELD = 1, ///< send 1 frame for each field - YADIF_MODE_SEND_FRAME_NOSPATIAL = 2, ///< send 1 frame for each frame but skips spatial interlacing check - YADIF_MODE_SEND_FIELD_NOSPATIAL = 3, ///< send 1 frame for each field but skips spatial interlacing check -}; - -enum YADIFParity { - YADIF_PARITY_TFF = 0, ///< top field first - YADIF_PARITY_BFF = 1, ///< bottom field first - YADIF_PARITY_AUTO = -1, ///< auto detection -}; - -enum YADIFDeint { - YADIF_DEINT_ALL = 0, ///< deinterlace all frames - YADIF_DEINT_INTERLACED = 1, ///< only deinterlace frames marked as interlaced -}; - -void ff_yadif_filter_line_mmxext(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_sse2(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_ssse3(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); - -void ff_yadif_filter_line_16bit_mmxext(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_16bit_sse2(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_16bit_ssse3(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_16bit_sse4(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); - -void ff_yadif_filter_line_10bit_mmxext(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_10bit_sse2(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); -void ff_yadif_filter_line_10bit_ssse3(void *dst, void *prev, void *cur, - void *next, int w, int prefs, - int mrefs, int parity, int mode); - -#endif /* AVFILTER_YADIF_H */ |
