21#include "config_components.h"
82#define OFFSET(x) offsetof(LUT2Context, x)
83#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
84#define TFLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
103 for (
i = 0;
i < 4;
i++) {
112 AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P, \
113 AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, \
114 AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV420P, \
115 AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, \
116 AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, \
117 AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRAP,
120 AV_PIX_FMT_GBRP9, AV_PIX_FMT_GRAY9, \
121 AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, \
122 AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9,
125 AV_PIX_FMT_GRAY10, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10, \
126 AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, \
127 AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10,
130 AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV440P12, \
131 AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA444P12, \
132 AV_PIX_FMT_GRAY12, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRP12,
135 AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, \
136 AV_PIX_FMT_GRAY14, AV_PIX_FMT_GBRP14,
139 AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, \
140 AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, \
141 AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_GRAY16,
182 if (
s->tlut2 || !
s->odepth)
190 case 8:
pix_fmts = bit8_pix_fmts;
break;
191 case 9:
pix_fmts = bit9_pix_fmts;
break;
192 case 10:
pix_fmts = bit10_pix_fmts;
break;
193 case 12:
pix_fmts = bit12_pix_fmts;
break;
194 case 14:
pix_fmts = bit14_pix_fmts;
break;
195 case 16:
pix_fmts = bit16_pix_fmts;
break;
208 int vsub =
desc->log2_chroma_h;
212 s->heightx[0] =
s->heightx[3] = inlink->
h;
214 s->widthx[0] =
s->widthx[3] = inlink->
w;
216 s->var_values[
VAR_W] = inlink->
w;
217 s->var_values[
VAR_H] = inlink->
h;
218 s->depthx =
desc->comp[0].depth;
222 s->depthy =
desc->comp[0].depth;
235 int vsub =
desc->log2_chroma_h;
238 s->depthy =
desc->comp[0].depth;
241 s->heighty[0] =
s->heighty[3] = inlink->
h;
243 s->widthy[0] =
s->widthy[3] = inlink->
w;
248#define DEFINE_LUT2(zname, xname, yname, ztype, xtype, ytype, zdiv, xdiv, ydiv) \
249static int lut2_##zname##_##xname##_##yname(AVFilterContext *ctx, \
251 int jobnr, int nb_jobs) \
253 LUT2Context *s = ctx->priv; \
254 ThreadData *td = arg; \
255 AVFrame *out = td->out; \
256 AVFrame *srcx = td->srcx; \
257 AVFrame *srcy = td->srcy; \
258 const int odepth = s->odepth; \
261 for (p = 0; p < s->nb_planes; p++) { \
262 const int slice_start = ff_slice_pos(s->heightx[p], jobnr, nb_jobs); \
263 const int slice_end = ff_slice_pos(s->heightx[p], jobnr + 1, nb_jobs); \
264 const uint16_t *lut = s->lut[p]; \
265 const xtype *srcxx; \
266 const ytype *srcyy; \
269 dst = (ztype *)(out->data[p] + slice_start * out->linesize[p]); \
270 srcxx = (const xtype *)(srcx->data[p] + slice_start * srcx->linesize[p]);\
271 srcyy = (const ytype *)(srcy->data[p] + slice_start * srcy->linesize[p]);\
273 for (y = slice_start; y < slice_end; y++) { \
274 for (x = 0; x < s->widthx[p]; x++) { \
275 dst[x] = av_clip_uintp2_c(lut[(srcyy[x] << s->depthx) | srcxx[x]], odepth); \
278 dst += out->linesize[p] / zdiv; \
279 srcxx += srcx->linesize[p] / xdiv; \
280 srcyy += srcy->linesize[p] / ydiv; \
286DEFINE_LUT2(8, 8, 8, uint8_t, uint8_t, uint8_t, 1, 1, 1)
287DEFINE_LUT2(8, 8, 16, uint8_t, uint8_t, uint16_t, 1, 1, 2)
288DEFINE_LUT2(8, 16, 8, uint8_t, uint16_t, uint8_t, 1, 2, 1)
289DEFINE_LUT2(8, 16, 16, uint8_t, uint16_t, uint16_t, 1, 2, 2)
290DEFINE_LUT2(16, 8, 8, uint16_t, uint8_t, uint8_t, 2, 1, 1)
291DEFINE_LUT2(16, 8, 16, uint16_t, uint8_t, uint16_t, 2, 1, 2)
292DEFINE_LUT2(16, 16, 8, uint16_t, uint16_t, uint8_t, 2, 2, 1)
293DEFINE_LUT2(16, 16, 16, uint16_t, uint16_t, uint16_t, 2, 2, 2)
307 if (
ctx->is_disabled || !srcy) {
308 out = av_frame_clone(srcx);
310 return AVERROR(ENOMEM);
314 out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
316 return AVERROR(ENOMEM);
317 av_frame_copy_props(out, srcx);
322 ff_filter_execute(ctx, s->lut2, &td, NULL,
323 FFMIN(s->heightx[1], ff_filter_get_nb_threads(ctx)));
337 s->depth =
s->depthx +
s->depthy;
338 s->nb_planes =
s->nb_planesx;
340 s->lut2 =
s->depth > 16 ? lut2_16_16_16 : lut2_8_8_8;
342 if (
s->depthx == 8 &&
s->depthy == 8 &&
s->odepth > 8)
343 s->lut2 = lut2_16_8_8;
344 if (
s->depthx > 8 &&
s->depthy == 8 &&
s->odepth > 8)
345 s->lut2 = lut2_16_16_8;
346 if (
s->depthx == 8 &&
s->depthy > 8 &&
s->odepth > 8)
347 s->lut2 = lut2_16_8_16;
348 if (
s->depthx == 8 &&
s->depthy == 8 &&
s->odepth == 8)
349 s->lut2 = lut2_8_8_8;
350 if (
s->depthx > 8 &&
s->depthy == 8 &&
s->odepth == 8)
351 s->lut2 = lut2_8_16_8;
352 if (
s->depthx == 8 &&
s->depthy > 8 &&
s->odepth == 8)
353 s->lut2 = lut2_8_8_16;
354 if (
s->depthx > 8 &&
s->depthy > 8 &&
s->odepth == 8)
355 s->lut2 = lut2_8_16_16;
357 s->odepth =
s->depthx;
360 for (p = 0; p <
s->nb_planes; p++) {
367 for (p = 0; p <
s->nb_planes; p++) {
373 s->comp_expr[p] =
NULL;
378 "Error when parsing the expression '%s' for the component %d.\n",
379 s->comp_expr_str[p], p);
384 for (y = 0; y < (1 <<
s->depthy); y++) {
386 for (x = 0; x < (1 <<
s->depthx); x++) {
391 "Error when evaluating the expression '%s' for the values %d and %d for the component %d.\n",
392 s->comp_expr_str[p], x, y, p);
396 s->lut[p][(y <<
s->depthx) + x] = res;
415 int vsub =
desc->log2_chroma_h;
418 outlink->
w = srcx->
w;
419 outlink->
h = srcx->
h;
426 s->height[0] =
s->height[3] = outlink->
h;
428 s->width[0] =
s->width[3] = outlink->
w;
435 if (srcx->
w != srcy->
w || srcx->
h != srcy->
h) {
437 "(size %dx%d) do not match the corresponding "
438 "second input link %s parameters (size %dx%d)\n",
439 ctx->input_pads[0].name, srcx->
w, srcx->
h,
440 ctx->input_pads[1].name,
445 if (
s->nb_planesx !=
s->nb_planesy) {
447 "(%d) do not match the corresponding "
448 "second input link %s number of planes (%d)\n",
449 ctx->input_pads[0].name,
s->nb_planesx,
450 ctx->input_pads[1].name,
s->nb_planesy);
454 if (
s->nb_planesx !=
s->nb_planes) {
456 "(%d) do not match the corresponding "
457 "output link %s number of planes (%d)\n",
458 ctx->input_pads[0].name,
s->nb_planesx,
459 ctx->output_pads[0].name,
s->nb_planes);
463 if (
s->widthx[1] !=
s->widthy[1] ||
s->heightx[1] !=
s->heighty[1]) {
465 "(size %dx%d) do not match the corresponding "
466 "second input link %s 2nd plane (size %dx%d)\n",
467 ctx->input_pads[0].name,
s->widthx[1],
s->heightx[1],
468 ctx->input_pads[1].name,
469 s->widthy[1],
s->heighty[1]);
473 if (
s->widthx[2] !=
s->widthy[2] ||
s->heightx[2] !=
s->heighty[2]) {
475 "(size %dx%d) do not match the corresponding "
476 "second input link %s 3rd plane (size %dx%d)\n",
477 ctx->input_pads[0].name,
s->widthx[2],
s->heightx[2],
478 ctx->input_pads[1].name,
479 s->widthy[2],
s->heighty[2]);
483 if (
s->widthx[1] !=
s->width[1] ||
s->heightx[1] !=
s->height[1]) {
485 "(size %dx%d) do not match the corresponding "
486 "output link %s 2nd plane (size %dx%d)\n",
487 ctx->input_pads[0].name,
s->widthx[1],
s->heightx[1],
488 ctx->output_pads[0].name,
s->width[1],
s->height[1]);
492 if (
s->widthx[2] !=
s->width[2] ||
s->heightx[2] !=
s->height[2]) {
494 "(size %dx%d) do not match the corresponding "
495 "output link %s 3rd plane (size %dx%d)\n",
496 ctx->input_pads[0].name,
s->widthx[2],
s->heightx[2],
497 ctx->output_pads[0].name,
s->width[2],
s->height[2]);
553 char *res,
int res_len,
int flags)
563#define lut2_options options
569 .p.description =
NULL_IF_CONFIG_SMALL(
"Compute and apply a lookup table from two video inputs."),
570 .p.priv_class = &lut2_class,
573 .preinit = lut2_framesync_preinit,
583#if CONFIG_TLUT2_FILTER
589 s->tlut2 = !strcmp(
ctx->filter->name,
"tlut2");
591 if (!(
s->odepth == 0 ||
s->odepth == 8 ||
s->odepth == 9 ||
s->odepth == 10 ||
592 s->odepth == 12 ||
s->odepth == 14 ||
s->odepth == 16)) {
609 if (
ctx->is_disabled) {
627 td.
srcy =
s->prev_frame;
639static const AVOption tlut2_options[] = {
653 .filter_frame = tlut2_filter_frame,
668 .p.description =
NULL_IF_CONFIG_SMALL(
"Compute and apply a lookup table from two successive frames."),
669 .p.priv_class = &tlut2_class,
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
const FFFilter ff_vf_tlut2
const FFFilter ff_vf_lut2
static AVFormatContext * ctx
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Main libavfilter public API header.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
#define fs(width, name, subs,...)
common internal and external API header
#define AV_CEIL_RSHIFT(a, b)
int(* init)(AVBSFContext *ctx)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
simple arithmetic expression evaluator
static av_always_inline int process_frame(AVTextFormatContext *tfc, InputFile *ifile, AVFrame *frame, const AVPacket *pkt, int *packet_new)
int ff_framesync_configure(FFFrameSync *fs)
Configure a frame sync structure.
int ff_framesync_activate(FFFrameSync *fs)
Examine the frames in the filter's input and try to produce output.
int ff_framesync_get_frame(FFFrameSync *fs, unsigned in, AVFrame **rframe, unsigned get)
Get the current frame in an input.
void ff_framesync_uninit(FFFrameSync *fs)
Free all memory currently allocated.
int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in)
Initialize a frame sync structure.
#define FRAMESYNC_DEFINE_CLASS(name, context, field)
@ EXT_INFINITY
Extend the frame to infinity.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, int props)
Remove and free all side data instances that match any of the given side data properties.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
@ AV_SIDE_DATA_PROP_COLOR_DEPENDENT
Side data depends on the video color space.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
static enum AVPixelFormat all_pix_fmts[]
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
static FilterLink * ff_filter_link(AVFilterLink *link)
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
Macro definitions for various function/variable attributes.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
Memory handling functions.
static const char *const var_names[]
@ EXT_STOP
Completely stop all streams with this one.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
AVPixelFormat
Pixel format.
Describe the class of an AVClass context structure.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
enum FFFrameSyncExtMode after
Extrapolation mode for timestamps after the last frame.
enum FFFrameSyncExtMode before
Extrapolation mode for timestamps before the first frame.
AVRational time_base
Time base for the incoming frames.
unsigned sync
Synchronization level: frames on input at the highest sync level will generate output frame events.
Link properties exposed to filter code, but not external callers.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable.
double var_values[VAR_VARS_NB]
uint16_t * lut[4]
lookup table for each component
int(* lut2)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Used for passing data between threads.
#define av_malloc_array(a, b)
static int lut2_config_output(AVFilterLink *outlink)
static int config_inputx(AVFilterLink *inlink)
#define DEFINE_LUT2(zname, xname, yname, ztype, xtype, ytype, zdiv, xdiv, ydiv)
static int config_inputy(AVFilterLink *inlink)
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static int config_output(AVFilterLink *outlink)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.