Go to the documentation of this file.
36 #define LB_MASK 0x00FEFEFE
37 #define RED_BLUE_MASK 0x00FF00FF
38 #define GREEN_MASK 0x0000FF00
58 #define OFFSET(x) offsetof(XBRContext, x)
59 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
67 static uint32_t
pixel_diff(uint32_t x, uint32_t y,
const uint32_t *r2y)
69 #define YMASK 0xff0000
70 #define UMASK 0x00ff00
71 #define VMASK 0x0000ff
72 #define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
74 uint32_t yuv1 = r2y[x & 0xffffff];
75 uint32_t yuv2 = r2y[y & 0xffffff];
82 #define ALPHA_BLEND_128_W(a, b) ((((a) & LB_MASK) >> 1) + (((b) & LB_MASK) >> 1))
83 #define ALPHA_BLEND_BASE(a, b, m, s) ( (RED_BLUE_MASK & (((a) & RED_BLUE_MASK) + (((((b) & RED_BLUE_MASK) - ((a) & RED_BLUE_MASK)) * (m)) >> (s)))) \
84 | (GREEN_MASK & (((a) & GREEN_MASK) + (((((b) & GREEN_MASK) - ((a) & GREEN_MASK)) * (m)) >> (s)))))
85 #define ALPHA_BLEND_32_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 3)
86 #define ALPHA_BLEND_64_W(a, b) ALPHA_BLEND_BASE(a, b, 1, 2)
87 #define ALPHA_BLEND_192_W(a, b) ALPHA_BLEND_BASE(a, b, 3, 2)
88 #define ALPHA_BLEND_224_W(a, b) ALPHA_BLEND_BASE(a, b, 7, 3)
90 #define df(A, B) pixel_diff(A, B, r2y)
91 #define eq(A, B) (df(A, B) < 155)
93 #define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
94 N0, N1, N2, N3) do { \
95 if (PE != PH && PE != PF) { \
96 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
97 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
99 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
100 if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
101 && (!eq(PF,I4) && !eq(PH,I5)) \
102 || eq(PE,PG) || eq(PE,PC))) { \
103 const unsigned ke = df(PF,PG); \
104 const unsigned ki = df(PH,PC); \
105 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
106 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
108 E[N3] = ALPHA_BLEND_224_W(E[N3], px); \
109 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
112 E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
113 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
115 E[N3] = ALPHA_BLEND_192_W(E[N3], px); \
116 E[N1] = ALPHA_BLEND_64_W( E[N1], px); \
118 E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
121 E[N3] = ALPHA_BLEND_128_W(E[N3], px); \
127 #define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
128 N0, N1, N2, N3, N4, N5, N6, N7, N8) do { \
129 if (PE != PH && PE != PF) { \
130 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
131 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
133 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
134 if (e < i && (!eq(PF,PB) && !eq(PF,PC) || !eq(PH,PD) && !eq(PH,PG) || eq(PE,PI) \
135 && (!eq(PF,F4) && !eq(PF,I4) || !eq(PH,H5) && !eq(PH,I5)) \
136 || eq(PE,PG) || eq(PE,PC))) { \
137 const unsigned ke = df(PF,PG); \
138 const unsigned ki = df(PH,PC); \
139 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
140 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
142 E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
143 E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
148 E[N7] = ALPHA_BLEND_192_W(E[N7], px); \
149 E[N5] = ALPHA_BLEND_64_W( E[N5], px); \
150 E[N6] = ALPHA_BLEND_64_W( E[N6], px); \
153 E[N5] = ALPHA_BLEND_192_W(E[N5], px); \
154 E[N7] = ALPHA_BLEND_64_W( E[N7], px); \
155 E[N2] = ALPHA_BLEND_64_W( E[N2], px); \
158 E[N8] = ALPHA_BLEND_224_W(E[N8], px); \
159 E[N5] = ALPHA_BLEND_32_W( E[N5], px); \
160 E[N7] = ALPHA_BLEND_32_W( E[N7], px); \
163 E[N8] = ALPHA_BLEND_128_W(E[N8], px); \
169 #define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, \
170 N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0) do { \
171 if (PE != PH && PE != PF) { \
172 const unsigned e = df(PE,PC) + df(PE,PG) + df(PI,H5) + df(PI,F4) + (df(PH,PF)<<2); \
173 const unsigned i = df(PH,PD) + df(PH,I5) + df(PF,I4) + df(PF,PB) + (df(PE,PI)<<2); \
175 const unsigned px = df(PE,PF) <= df(PE,PH) ? PF : PH; \
176 if (e < i && (!eq(PF,PB) && !eq(PH,PD) || eq(PE,PI) \
177 && (!eq(PF,I4) && !eq(PH,I5)) \
178 || eq(PE,PG) || eq(PE,PC))) { \
179 const unsigned ke = df(PF,PG); \
180 const unsigned ki = df(PH,PC); \
181 const int left = ke<<1 <= ki && PE != PG && PD != PG; \
182 const int up = ke >= ki<<1 && PE != PC && PB != PC; \
184 E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
185 E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
186 E[N15] = E[N14] = E[N11] = px; \
187 E[N10] = E[N3] = E[N12]; \
190 E[N11] = ALPHA_BLEND_192_W(E[N11], px); \
191 E[N13] = ALPHA_BLEND_192_W(E[N13], px); \
192 E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
193 E[N12] = ALPHA_BLEND_64_W( E[N12], px); \
197 E[N14] = ALPHA_BLEND_192_W(E[N14], px); \
198 E[N7 ] = ALPHA_BLEND_192_W(E[N7 ], px); \
199 E[N10] = ALPHA_BLEND_64_W( E[N10], px); \
200 E[N3 ] = ALPHA_BLEND_64_W( E[N3 ], px); \
204 E[N11] = ALPHA_BLEND_128_W(E[N11], px); \
205 E[N14] = ALPHA_BLEND_128_W(E[N14], px); \
209 E[N15] = ALPHA_BLEND_128_W(E[N15], px); \
220 const uint32_t *r2y =
td->rgbtoyuv;
221 const int slice_start = (
input->height * jobnr ) / nb_jobs;
223 const int nl =
output->linesize[0] >> 2;
224 const int nl1 = nl + nl;
225 const int nl2 = nl1 + nl;
227 for (y = slice_start; y <
slice_end; y++) {
229 uint32_t *
E = (uint32_t *)(
output->data[0] + y *
output->linesize[0] *
n);
230 const uint32_t *sa2 = (uint32_t *)(
input->data[0] + y *
input->linesize[0] - 8);
231 const uint32_t *sa1 = sa2 - (
input->linesize[0]>>2);
232 const uint32_t *sa0 = sa1 - (
input->linesize[0]>>2);
233 const uint32_t *sa3 = sa2 + (
input->linesize[0]>>2);
234 const uint32_t *sa4 = sa3 + (
input->linesize[0]>>2);
243 if (y >=
input->height - 2) {
245 if (y ==
input->height - 1) {
250 for (x = 0; x <
input->width; x++) {
251 const uint32_t
B1 = sa0[2];
252 const uint32_t PB = sa1[2];
253 const uint32_t PE = sa2[2];
254 const uint32_t PH = sa3[2];
255 const uint32_t H5 = sa4[2];
257 const int pprev = 2 - (x > 0);
258 const uint32_t
A1 = sa0[pprev];
259 const uint32_t PA = sa1[pprev];
260 const uint32_t
PD = sa2[pprev];
261 const uint32_t PG = sa3[pprev];
262 const uint32_t G5 = sa4[pprev];
264 const int pprev2 = pprev - (x > 1);
265 const uint32_t A0 = sa1[pprev2];
266 const uint32_t D0 = sa2[pprev2];
267 const uint32_t G0 = sa3[pprev2];
269 const int pnext = 3 - (x ==
input->width - 1);
270 const uint32_t
C1 = sa0[pnext];
271 const uint32_t PC = sa1[pnext];
272 const uint32_t
PF = sa2[pnext];
273 const uint32_t PI = sa3[pnext];
274 const uint32_t I5 = sa4[pnext];
276 const int pnext2 = pnext + 1 - (x >=
input->width - 2);
277 const uint32_t
C4 = sa1[pnext2];
278 const uint32_t F4 = sa2[pnext2];
279 const uint32_t I4 = sa3[pnext2];
283 E[nl] =
E[nl + 1] = PE;
285 FILT2(PE, PI, PH,
PF, PG, PC,
PD, PB, PA, G5,
C4, G0, D0,
C1,
B1, F4, I4, H5, I5, A0,
A1, 0, 1, nl, nl+1);
286 FILT2(PE, PC,
PF, PB, PI, PA, PH,
PD, PG, I4,
A1, I5, H5, A0, D0,
B1,
C1, F4,
C4, G5, G0, nl, 0, nl+1, 1);
287 FILT2(PE, PA, PB,
PD, PC, PG,
PF, PH, PI,
C1, G0,
C4, F4, G5, H5, D0, A0,
B1,
A1, I4, I5, nl+1, nl, 1, 0);
288 FILT2(PE, PG,
PD, PH, PA, PI, PB,
PF, PC, A0, I5,
A1,
B1, I4, F4, H5, G5, D0, G0,
C1,
C4, 1, nl+1, 0, nl);
291 E[nl] =
E[nl+1] =
E[nl+2] =
292 E[nl1] =
E[nl1+1] =
E[nl1+2] = PE;
294 FILT3(PE, PI, PH,
PF, PG, PC,
PD, PB, PA, G5,
C4, G0, D0,
C1,
B1, F4, I4, H5, I5, A0,
A1, 0, 1, 2, nl, nl+1, nl+2, nl1, nl1+1, nl1+2);
295 FILT3(PE, PC,
PF, PB, PI, PA, PH,
PD, PG, I4,
A1, I5, H5, A0, D0,
B1,
C1, F4,
C4, G5, G0, nl1, nl, 0, nl1+1, nl+1, 1, nl1+2, nl+2, 2);
296 FILT3(PE, PA, PB,
PD, PC, PG,
PF, PH, PI,
C1, G0,
C4, F4, G5, H5, D0, A0,
B1,
A1, I4, I5, nl1+2, nl1+1, nl1, nl+2, nl+1, nl, 2, 1, 0);
297 FILT3(PE, PG,
PD, PH, PA, PI, PB,
PF, PC, A0, I5,
A1,
B1, I4, F4, H5, G5, D0, G0,
C1,
C4, 2, nl+2, nl1+2, 1, nl+1, nl1+1, 0, nl, nl1);
299 E[0] =
E[1] =
E[2] =
E[3] =
300 E[nl] =
E[nl+1] =
E[nl+2] =
E[nl+3] =
301 E[nl1] =
E[nl1+1] =
E[nl1+2] =
E[nl1+3] =
302 E[nl2] =
E[nl2+1] =
E[nl2+2] =
E[nl2+3] = PE;
304 FILT4(PE, PI, PH,
PF, PG, PC,
PD, PB, PA, G5,
C4, G0, D0,
C1,
B1, F4, I4, H5, I5, A0,
A1, nl2+3, nl2+2, nl1+3, 3, nl+3, nl1+2, nl2+1, nl2, nl1+1, nl+2, 2, 1, nl+1, nl1, nl, 0);
305 FILT4(PE, PC,
PF, PB, PI, PA, PH,
PD, PG, I4,
A1, I5, H5, A0, D0,
B1,
C1, F4,
C4, G5, G0, 3, nl+3, 2, 0, 1, nl+2, nl1+3, nl2+3, nl1+2, nl+1, nl, nl1, nl1+1, nl2+2, nl2+1, nl2);
306 FILT4(PE, PA, PB,
PD, PC, PG,
PF, PH, PI,
C1, G0,
C4, F4, G5, H5, D0, A0,
B1,
A1, I4, I5, 0, 1, nl, nl2, nl1, nl+1, 2, 3, nl+2, nl1+1, nl2+1, nl2+2, nl1+2, nl+3, nl1+3, nl2+3);
307 FILT4(PE, PG,
PD, PH, PA, PI, PB,
PF, PC, A0, I5,
A1,
B1, I4, F4, H5, G5, D0, G0,
C1,
C4, nl2, nl1, nl2+1, nl2+3, nl2+2, nl1+1, nl, 0, nl+1, nl1+2, nl1+3, nl+3, nl+2, 1, 2, 3);
321 #define XBR_FUNC(size) \
322 static int xbr##size##x(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \
324 xbr_filter(arg, jobnr, nb_jobs, size); \
373 td.rgbtoyuv =
s->rgbtoyuv;
376 out->width = outlink->
w;
377 out->height = outlink->
h;
386 static const xbrfunc_t xbrfuncs[] = {xbr2x, xbr3x, xbr4x};
391 for (bg = -255; bg < 256; bg++) {
392 for (rg = -255; rg < 256; rg++) {
393 const uint32_t
u = (uint32_t)((-169*rg + 500*bg)/1000) + 128;
394 const uint32_t v = (uint32_t)(( 500*rg - 81*bg)/1000) + 128;
395 int startg =
FFMAX3(-bg, -rg, 0);
396 int endg =
FFMIN3(255-bg, 255-rg, 255);
397 uint32_t y = (uint32_t)(( 299*rg + 1000*startg + 114*bg)/1000);
398 c = bg + rg * (1 << 16) + 0x010101 * startg;
399 for (
g = startg;
g <= endg;
g++) {
400 s->rgbtoyuv[
c] = ((y++) << 16) + (
u << 8) + v;
406 s->func = xbrfuncs[
s->n - 2];
435 .priv_class = &xbr_class,
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
AVPixelFormat
Pixel format.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
#define u(width, name, range_min, range_max)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static const AVFilterPad xbr_outputs[]
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
This structure describes decoded (raw) audio or video data.
static const AVFilterPad xbr_inputs[]
#define PD(a, b)
Pack two delta values (a,b) into one 16-bit word according with endianness of the host machine.
const char * name
Filter name.
AVFormatInternal * internal
An opaque field for libavformat internal usage.
A link between two filters.
static const AVOption xbr_options[]
A filter pad used for either input or output.
int(* xbrfunc_t)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
uint32_t rgbtoyuv[1<< 24]
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
static enum AVPixelFormat pix_fmts[]
static int query_formats(AVFilterContext *ctx)
Describe the class of an AVClass context structure.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static av_always_inline void xbr_filter(const ThreadData *td, int jobnr, int nb_jobs, int n)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static int config_output(AVFilterLink *outlink)
const uint32_t * rgbtoyuv
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
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
int w
agreed upon image width
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Used for passing data between threads.
const char * name
Pad name.
#define AV_PIX_FMT_0RGB32
#define FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N15, N14, N11, N3, N7, N10, N13, N12, N9, N6, N2, N1, N5, N8, N4, N0)
int h
agreed upon image height
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
static uint32_t pixel_diff(uint32_t x, uint32_t y, const uint32_t *r2y)
static int init(AVFilterContext *ctx)
#define flags(name, subs,...)
AVFILTER_DEFINE_CLASS(xbr)
#define FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3)
#define FILT3(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, N4, N5, N6, N7, N8)