FFmpeg
Data Structures | Macros | Enumerations | Functions | Variables
vf_fieldmatch.c File Reference

Fieldmatching filter, ported from VFM filter (VapourSynth) by Clément. More...

#include <inttypes.h>
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavutil/timestamp.h"
#include "avfilter.h"
#include "filters.h"
#include "internal.h"

Go to the source code of this file.

Data Structures

struct  FieldMatchContext
 

Macros

#define INPUT_MAIN   0
 
#define INPUT_CLEANSRC   1
 
#define OFFSET(x)   offsetof(FieldMatchContext, x)
 
#define FLAGS   AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
#define FILTER(xm2, xm1, xp1, xp2)
 
#define HAS_FF_AROUND(p, lz)
 
#define C_ARRAY_ADD(v)
 
#define VERTICAL_HALF(y_start, y_end)
 
#define LOAD_COMB(mid)
 
#define SLIDING_FRAME_WINDOW(prv, src, nxt)
 

Enumerations

enum  fieldmatch_parity { FM_PARITY_AUTO = -1, FM_PARITY_BOTTOM = 0, FM_PARITY_TOP = 1 }
 
enum  matching_mode {
  MODE_PC, MODE_PC_N, MODE_PC_U, MODE_PC_N_UB,
  MODE_PCN, MODE_PCN_UB, NB_MODE
}
 
enum  comb_matching_mode { COMBMATCH_NONE, COMBMATCH_SC, COMBMATCH_FULL, NB_COMBMATCH }
 
enum  comb_dbg { COMBDBG_NONE, COMBDBG_PCN, COMBDBG_PCNUB, NB_COMBDBG }
 
enum  {
  mP, mC, mN, mB,
  mU
}
 

Functions

 AVFILTER_DEFINE_CLASS (fieldmatch)
 
static int get_width (const FieldMatchContext *fm, const AVFrame *f, int plane)
 
static int get_height (const FieldMatchContext *fm, const AVFrame *f, int plane)
 
static int64_t luma_abs_diff (const AVFrame *f1, const AVFrame *f2)
 
static void fill_buf (uint8_t *data, int w, int h, int linesize, uint8_t v)
 
static int calc_combed_score (const FieldMatchContext *fm, const AVFrame *src)
 
static void build_abs_diff_mask (const uint8_t *prvp, int prv_linesize, const uint8_t *nxtp, int nxt_linesize, uint8_t *tbuffer, int tbuf_linesize, int width, int height)
 
static void build_diff_map (FieldMatchContext *fm, const uint8_t *prvp, int prv_linesize, const uint8_t *nxtp, int nxt_linesize, uint8_t *dstp, int dst_linesize, int height, int width, int plane)
 Build a map over which pixels differ a lot/a little. More...
 
static int get_field_base (int match, int field)
 
static AVFrameselect_frame (FieldMatchContext *fm, int match)
 
static int compare_fields (FieldMatchContext *fm, int match1, int match2, int field)
 
static void copy_fields (const FieldMatchContext *fm, AVFrame *dst, const AVFrame *src, int field)
 
static AVFramecreate_weave_frame (AVFilterContext *ctx, int match, int field, const AVFrame *prv, AVFrame *src, const AVFrame *nxt)
 
static int checkmm (AVFilterContext *ctx, int *combs, int m1, int m2, AVFrame **gen_frames, int field)
 
static int filter_frame (AVFilterLink *inlink, AVFrame *in)
 
static int activate (AVFilterContext *ctx)
 
static int query_formats (AVFilterContext *ctx)
 
static int config_input (AVFilterLink *inlink)
 
static av_cold int fieldmatch_init (AVFilterContext *ctx)
 
static av_cold void fieldmatch_uninit (AVFilterContext *ctx)
 
static int config_output (AVFilterLink *outlink)
 

Variables

static const AVOption fieldmatch_options []
 
static const int fxo0m [] = { mP, mC, mN, mB, mU }
 
static const int fxo1m [] = { mN, mC, mP, mU, mB }
 
static const AVFilterPad fieldmatch_outputs []
 
AVFilter ff_vf_fieldmatch
 

Detailed Description

Fieldmatching filter, ported from VFM filter (VapourSynth) by Clément.

Fredrik Mellbin is the author of the VIVTC/VFM filter, which is itself a light clone of the TIVTC/TFM (AviSynth) filter written by Kevin Stone (tritical), the original author.

See also
http://bengal.missouri.edu/~kes25c/
http://www.vapoursynth.com/about/

Definition in file vf_fieldmatch.c.

Macro Definition Documentation

#define INPUT_MAIN   0

Definition at line 43 of file vf_fieldmatch.c.

Referenced by activate(), config_output(), fieldmatch_init(), filter_frame(), and query_formats().

#define INPUT_CLEANSRC   1

Definition at line 44 of file vf_fieldmatch.c.

Referenced by activate(), config_output(), fieldmatch_init(), filter_frame(), and query_formats().

#define OFFSET (   x)    offsetof(FieldMatchContext, x)

Definition at line 114 of file vf_fieldmatch.c.

Definition at line 115 of file vf_fieldmatch.c.

#define FILTER (   xm2,
  xm1,
  xp1,
  xp2 
)
Value:
abs( 4 * srcp[x] \
-3 * (srcp[x + (xm1)*src_linesize] + srcp[x + (xp1)*src_linesize]) \
+ (srcp[x + (xm2)*src_linesize] + srcp[x + (xp2)*src_linesize])) > cthresh6
BYTE int const BYTE * srcp
Definition: avisynth_c.h:908
#define abs(x)
Definition: cuda_runtime.h:35

Referenced by calc_combed_score().

#define HAS_FF_AROUND (   p,
  lz 
)
Value:
(p[(x)-1 - (lz)] == 0xff || p[(x) - (lz)] == 0xff || p[(x)+1 - (lz)] == 0xff || \
p[(x)-1 ] == 0xff || p[(x)+1 ] == 0xff || \
p[(x)-1 + (lz)] == 0xff || p[(x) + (lz)] == 0xff || p[(x)+1 + (lz)] == 0xff)

Referenced by calc_combed_score().

#define C_ARRAY_ADD (   v)
Value:
do { \
const int box1 = (x / blockx) * 4; \
const int box2 = ((x + xhalf) / blockx) * 4; \
c_array[temp1 + box1 ] += v; \
c_array[temp1 + box2 + 1] += v; \
c_array[temp2 + box1 + 2] += v; \
c_array[temp2 + box2 + 3] += v; \
} while (0)

Referenced by calc_combed_score().

#define VERTICAL_HALF (   y_start,
  y_end 
)
Value:
do { \
for (y = y_start; y < y_end; y++) { \
const int temp1 = (y / blocky) * xblocks4; \
const int temp2 = ((y + yhalf) / blocky) * xblocks4; \
for (x = 0; x < width; x++) \
if (cmkp[x - cmk_linesize] == 0xff && \
cmkp[x ] == 0xff && \
cmkp[x + cmk_linesize] == 0xff) \
cmkp += cmk_linesize; \
} \
} while (0)
#define C_ARRAY_ADD(v)
#define width
for(j=16;j >0;--j)

Referenced by calc_combed_score().

#define LOAD_COMB (   mid)
Value:
do { \
if (combs[mid] < 0) { \
if (!gen_frames[mid]) \
gen_frames[mid] = create_weave_frame(ctx, mid, field, \
fm->prv, fm->src, fm->nxt); \
combs[mid] = calc_combed_score(fm, gen_frames[mid]); \
} \
} while (0)
static AVFrame * create_weave_frame(AVFilterContext *ctx, int match, int field, const AVFrame *prv, AVFrame *src, const AVFrame *nxt)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
AVFormatContext * ctx
Definition: movenc.c:48
if(ret)
static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)

Referenced by checkmm().

#define SLIDING_FRAME_WINDOW (   prv,
  src,
  nxt 
)
Value:
do { \
if (prv != src) /* 2nd loop exception (1st has prv==src and we don't want to loose src) */ \
prv = src; \
src = nxt; \
if (in) \
nxt = in; \
if (!prv) \
prv = src; \
if (!prv) /* received only one frame at that point */ \
av_assert0(prv && src && nxt); \
} while (0)
#define src
Definition: vp8dsp.c:254
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
if(ret)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a it should return

Referenced by filter_frame().

Enumeration Type Documentation

Enumerator
FM_PARITY_AUTO 
FM_PARITY_BOTTOM 
FM_PARITY_TOP 

Definition at line 46 of file vf_fieldmatch.c.

Enumerator
MODE_PC 
MODE_PC_N 
MODE_PC_U 
MODE_PC_N_UB 
MODE_PCN 
MODE_PCN_UB 
NB_MODE 

Definition at line 52 of file vf_fieldmatch.c.

Enumerator
COMBMATCH_NONE 
COMBMATCH_SC 
COMBMATCH_FULL 
NB_COMBMATCH 

Definition at line 62 of file vf_fieldmatch.c.

enum comb_dbg
Enumerator
COMBDBG_NONE 
COMBDBG_PCN 
COMBDBG_PCNUB 
NB_COMBDBG 

Definition at line 69 of file vf_fieldmatch.c.

anonymous enum
Enumerator
mP 
mC 
mN 
mB 
mU 

Definition at line 473 of file vf_fieldmatch.c.

Function Documentation

AVFILTER_DEFINE_CLASS ( fieldmatch  )
static int get_width ( const FieldMatchContext fm,
const AVFrame f,
int  plane 
)
static

Definition at line 156 of file vf_fieldmatch.c.

Referenced by calc_combed_score(), compare_fields(), and copy_fields().

static int get_height ( const FieldMatchContext fm,
const AVFrame f,
int  plane 
)
static

Definition at line 161 of file vf_fieldmatch.c.

Referenced by calc_combed_score(), compare_fields(), and copy_fields().

static int64_t luma_abs_diff ( const AVFrame f1,
const AVFrame f2 
)
static

Definition at line 166 of file vf_fieldmatch.c.

Referenced by filter_frame().

static void fill_buf ( uint8_t data,
int  w,
int  h,
int  linesize,
uint8_t  v 
)
static

Definition at line 186 of file vf_fieldmatch.c.

Referenced by calc_combed_score(), compare_fields(), and intercept_id3().

static int calc_combed_score ( const FieldMatchContext fm,
const AVFrame src 
)
static

Definition at line 196 of file vf_fieldmatch.c.

Referenced by filter_frame().

static void build_abs_diff_mask ( const uint8_t prvp,
int  prv_linesize,
const uint8_t nxtp,
int  nxt_linesize,
uint8_t tbuffer,
int  tbuf_linesize,
int  width,
int  height 
)
static

Definition at line 394 of file vf_fieldmatch.c.

Referenced by build_diff_map().

static void build_diff_map ( FieldMatchContext fm,
const uint8_t prvp,
int  prv_linesize,
const uint8_t nxtp,
int  nxt_linesize,
uint8_t dstp,
int  dst_linesize,
int  height,
int  width,
int  plane 
)
static

Build a map over which pixels differ a lot/a little.

Definition at line 415 of file vf_fieldmatch.c.

Referenced by compare_fields().

static int get_field_base ( int  match,
int  field 
)
static

Definition at line 475 of file vf_fieldmatch.c.

Referenced by compare_fields().

static AVFrame* select_frame ( FieldMatchContext fm,
int  match 
)
static

Definition at line 480 of file vf_fieldmatch.c.

Referenced by compare_fields().

static int compare_fields ( FieldMatchContext fm,
int  match1,
int  match2,
int  field 
)
static

Definition at line 487 of file vf_fieldmatch.c.

Referenced by filter_frame().

static void copy_fields ( const FieldMatchContext fm,
AVFrame dst,
const AVFrame src,
int  field 
)
static

Definition at line 609 of file vf_fieldmatch.c.

Referenced by create_weave_frame().

static AVFrame* create_weave_frame ( AVFilterContext ctx,
int  match,
int  field,
const AVFrame prv,
AVFrame src,
const AVFrame nxt 
)
static

Definition at line 622 of file vf_fieldmatch.c.

Referenced by filter_frame().

static int checkmm ( AVFilterContext ctx,
int combs,
int  m1,
int  m2,
AVFrame **  gen_frames,
int  field 
)
static

Definition at line 649 of file vf_fieldmatch.c.

Referenced by filter_frame().

static int filter_frame ( AVFilterLink inlink,
AVFrame in 
)
static

Definition at line 676 of file vf_fieldmatch.c.

Referenced by activate().

static int activate ( AVFilterContext ctx)
static

Definition at line 835 of file vf_fieldmatch.c.

static int query_formats ( AVFilterContext ctx)
static

Definition at line 886 of file vf_fieldmatch.c.

static int config_input ( AVFilterLink inlink)
static

Definition at line 932 of file vf_fieldmatch.c.

Referenced by fieldmatch_init().

static av_cold int fieldmatch_init ( AVFilterContext ctx)
static

Definition at line 963 of file vf_fieldmatch.c.

static av_cold void fieldmatch_uninit ( AVFilterContext ctx)
static

Definition at line 1005 of file vf_fieldmatch.c.

static int config_output ( AVFilterLink outlink)
static

Definition at line 1028 of file vf_fieldmatch.c.

Variable Documentation

const AVOption fieldmatch_options[]
static

Definition at line 117 of file vf_fieldmatch.c.

const int fxo0m[] = { mP, mC, mN, mB, mU }
static

Definition at line 673 of file vf_fieldmatch.c.

Referenced by filter_frame().

const int fxo1m[] = { mN, mC, mP, mU, mB }
static

Definition at line 674 of file vf_fieldmatch.c.

Referenced by filter_frame().

const AVFilterPad fieldmatch_outputs[]
static
Initial value:
= {
{
.name = "default",
.config_props = config_output,
},
{ NULL }
}
#define NULL
Definition: coverity.c:32
static int config_output(AVFilterLink *outlink)

Definition at line 1045 of file vf_fieldmatch.c.

AVFilter ff_vf_fieldmatch
Initial value:
= {
.name = "fieldmatch",
.description = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
.query_formats = query_formats,
.priv_size = sizeof(FieldMatchContext),
.priv_class = &fieldmatch_class,
}
#define NULL
Definition: coverity.c:32
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:105
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
static av_cold int fieldmatch_init(AVFilterContext *ctx)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static const AVFilterPad fieldmatch_outputs[]
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
static int activate(AVFilterContext *ctx)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
#define flags(name, subs,...)
Definition: cbs_av1.c:561
static int query_formats(AVFilterContext *ctx)
static av_cold void fieldmatch_uninit(AVFilterContext *ctx)

Definition at line 1054 of file vf_fieldmatch.c.