vf_curves.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Clément Bœsch
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/opt.h"
22 #include "libavutil/bprint.h"
23 #include "libavutil/eval.h"
24 #include "libavutil/file.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/avassert.h"
27 #include "avfilter.h"
28 #include "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 struct keypoint {
33  double x, y;
34  struct keypoint *next;
35 };
36 
37 #define NB_COMP 3
38 
39 enum preset {
52 };
53 
54 typedef struct {
55  const AVClass *class;
56  enum preset preset;
57  char *comp_points_str[NB_COMP + 1];
59  uint8_t graph[NB_COMP + 1][256];
60  char *psfile;
62 
63 #define OFFSET(x) offsetof(CurvesContext, x)
64 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
65 static const AVOption curves_options[] = {
66  { "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=PRESET_NONE}, PRESET_NONE, NB_PRESETS-1, FLAGS, "preset_name" },
67  { "none", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NONE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
68  { "color_negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_COLOR_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
69  { "cross_process", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_CROSS_PROCESS}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
70  { "darker", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_DARKER}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
71  { "increase_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_INCREASE_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
72  { "lighter", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LIGHTER}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
73  { "linear_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_LINEAR_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
74  { "medium_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_MEDIUM_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
75  { "negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
76  { "strong_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_STRONG_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
77  { "vintage", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VINTAGE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
78  { "master","set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
79  { "m", "set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
80  { "red", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
81  { "r", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
82  { "green", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
83  { "g", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
84  { "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
85  { "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
86  { "all", "set points coordinates for all components", OFFSET(comp_points_str_all), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
87  { "psfile", "set Photoshop curves file name", OFFSET(psfile), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
88  { NULL }
89 };
90 
91 AVFILTER_DEFINE_CLASS(curves);
92 
93 static const struct {
94  const char *r;
95  const char *g;
96  const char *b;
97  const char *master;
98 } curves_presets[] = {
100  "0/1 0.129/1 0.466/0.498 0.725/0 1/0",
101  "0/1 0.109/1 0.301/0.498 0.517/0 1/0",
102  "0/1 0.098/1 0.235/0.498 0.423/0 1/0",
103  },
105  "0.25/0.156 0.501/0.501 0.686/0.745",
106  "0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
107  "0.231/0.094 0.709/0.874",
108  },
109  [PRESET_DARKER] = { .master = "0.5/0.4" },
110  [PRESET_INCREASE_CONTRAST] = { .master = "0.149/0.066 0.831/0.905 0.905/0.98" },
111  [PRESET_LIGHTER] = { .master = "0.4/0.5" },
112  [PRESET_LINEAR_CONTRAST] = { .master = "0.305/0.286 0.694/0.713" },
113  [PRESET_MEDIUM_CONTRAST] = { .master = "0.286/0.219 0.639/0.643" },
114  [PRESET_NEGATIVE] = { .master = "0/1 1/0" },
115  [PRESET_STRONG_CONTRAST] = { .master = "0.301/0.196 0.592/0.6 0.686/0.737" },
116  [PRESET_VINTAGE] = {
117  "0/0.11 0.42/0.51 1/0.95",
118  "0.50/0.48",
119  "0/0.22 0.49/0.44 1/0.8",
120  }
121 };
122 
123 static struct keypoint *make_point(double x, double y, struct keypoint *next)
124 {
125  struct keypoint *point = av_mallocz(sizeof(*point));
126 
127  if (!point)
128  return NULL;
129  point->x = x;
130  point->y = y;
131  point->next = next;
132  return point;
133 }
134 
135 static int parse_points_str(AVFilterContext *ctx, struct keypoint **points, const char *s)
136 {
137  char *p = (char *)s; // strtod won't alter the string
138  struct keypoint *last = NULL;
139 
140  /* construct a linked list based on the key points string */
141  while (p && *p) {
142  struct keypoint *point = make_point(0, 0, NULL);
143  if (!point)
144  return AVERROR(ENOMEM);
145  point->x = av_strtod(p, &p); if (p && *p) p++;
146  point->y = av_strtod(p, &p); if (p && *p) p++;
147  if (point->x < 0 || point->x > 1 || point->y < 0 || point->y > 1) {
148  av_log(ctx, AV_LOG_ERROR, "Invalid key point coordinates (%f;%f), "
149  "x and y must be in the [0;1] range.\n", point->x, point->y);
150  return AVERROR(EINVAL);
151  }
152  if (!*points)
153  *points = point;
154  if (last) {
155  if ((int)(last->x * 255) >= (int)(point->x * 255)) {
156  av_log(ctx, AV_LOG_ERROR, "Key point coordinates (%f;%f) "
157  "and (%f;%f) are too close from each other or not "
158  "strictly increasing on the x-axis\n",
159  last->x, last->y, point->x, point->y);
160  return AVERROR(EINVAL);
161  }
162  last->next = point;
163  }
164  last = point;
165  }
166 
167  /* auto insert first key point if missing at x=0 */
168  if (!*points) {
169  last = make_point(0, 0, NULL);
170  if (!last)
171  return AVERROR(ENOMEM);
172  last->x = last->y = 0;
173  *points = last;
174  } else if ((*points)->x != 0.) {
175  struct keypoint *newfirst = make_point(0, 0, *points);
176  if (!newfirst)
177  return AVERROR(ENOMEM);
178  *points = newfirst;
179  }
180 
181  av_assert0(last);
182 
183  /* auto insert last key point if missing at x=1 */
184  if (last->x != 1.) {
185  struct keypoint *point = make_point(1, 1, NULL);
186  if (!point)
187  return AVERROR(ENOMEM);
188  last->next = point;
189  }
190 
191  return 0;
192 }
193 
194 static int get_nb_points(const struct keypoint *d)
195 {
196  int n = 0;
197  while (d) {
198  n++;
199  d = d->next;
200  }
201  return n;
202 }
203 
204 /**
205  * Natural cubic spline interpolation
206  * Finding curves using Cubic Splines notes by Steven Rauch and John Stockie.
207  * @see http://people.math.sfu.ca/~stockie/teaching/macm316/notes/splines.pdf
208  */
209 static int interpolate(AVFilterContext *ctx, uint8_t *y, const struct keypoint *points)
210 {
211  int i, ret = 0;
212  const struct keypoint *point;
213  double xprev = 0;
214 
215  int n = get_nb_points(points); // number of splines
216 
217  double (*matrix)[3] = av_calloc(n, sizeof(*matrix));
218  double *h = av_malloc((n - 1) * sizeof(*h));
219  double *r = av_calloc(n, sizeof(*r));
220 
221  if (!matrix || !h || !r) {
222  ret = AVERROR(ENOMEM);
223  goto end;
224  }
225 
226  /* h(i) = x(i+1) - x(i) */
227  i = -1;
228  for (point = points; point; point = point->next) {
229  if (i != -1)
230  h[i] = point->x - xprev;
231  xprev = point->x;
232  i++;
233  }
234 
235  /* right-side of the polynomials, will be modified to contains the solution */
236  point = points;
237  for (i = 1; i < n - 1; i++) {
238  double yp = point->y,
239  yc = point->next->y,
240  yn = point->next->next->y;
241  r[i] = 6 * ((yn-yc)/h[i] - (yc-yp)/h[i-1]);
242  point = point->next;
243  }
244 
245 #define B 0 /* sub diagonal (below main) */
246 #define M 1 /* main diagonal (center) */
247 #define A 2 /* sup diagonal (above main) */
248 
249  /* left side of the polynomials into a tridiagonal matrix. */
250  matrix[0][M] = matrix[n - 1][M] = 1;
251  for (i = 1; i < n - 1; i++) {
252  matrix[i][B] = h[i-1];
253  matrix[i][M] = 2 * (h[i-1] + h[i]);
254  matrix[i][A] = h[i];
255  }
256 
257  /* tridiagonal solving of the linear system */
258  for (i = 1; i < n; i++) {
259  double den = matrix[i][M] - matrix[i][B] * matrix[i-1][A];
260  double k = den ? 1./den : 1.;
261  matrix[i][A] *= k;
262  r[i] = (r[i] - matrix[i][B] * r[i - 1]) * k;
263  }
264  for (i = n - 2; i >= 0; i--)
265  r[i] = r[i] - matrix[i][A] * r[i + 1];
266 
267  /* compute the graph with x=[0..255] */
268  i = 0;
269  point = points;
270  av_assert0(point->next); // always at least 2 key points
271  while (point->next) {
272  double yc = point->y;
273  double yn = point->next->y;
274 
275  double a = yc;
276  double b = (yn-yc)/h[i] - h[i]*r[i]/2. - h[i]*(r[i+1]-r[i])/6.;
277  double c = r[i] / 2.;
278  double d = (r[i+1] - r[i]) / (6.*h[i]);
279 
280  int x;
281  int x_start = point->x * 255;
282  int x_end = point->next->x * 255;
283 
284  av_assert0(x_start >= 0 && x_start <= 255 &&
285  x_end >= 0 && x_end <= 255);
286 
287  for (x = x_start; x <= x_end; x++) {
288  double xx = (x - x_start) * 1/255.;
289  double yy = a + b*xx + c*xx*xx + d*xx*xx*xx;
290  y[x] = av_clipf(yy, 0, 1) * 255;
291  av_log(ctx, AV_LOG_DEBUG, "f(%f)=%f -> y[%d]=%d\n", xx, yy, x, y[x]);
292  }
293 
294  point = point->next;
295  i++;
296  }
297 
298 end:
299  av_free(matrix);
300  av_free(h);
301  av_free(r);
302  return ret;
303 }
304 
305 static int parse_psfile(AVFilterContext *ctx, const char *fname)
306 {
307  CurvesContext *curves = ctx->priv;
308  uint8_t *buf;
309  size_t size;
310  int i, ret, av_unused(version), nb_curves;
311  AVBPrint ptstr;
312  static const int comp_ids[] = {3, 0, 1, 2};
313 
315 
316  ret = av_file_map(fname, &buf, &size, 0, NULL);
317  if (ret < 0)
318  return ret;
319 
320 #define READ16(dst) do { \
321  if (size < 2) \
322  return AVERROR_INVALIDDATA; \
323  dst = AV_RB16(buf); \
324  buf += 2; \
325  size -= 2; \
326 } while (0)
327 
328  READ16(version);
329  READ16(nb_curves);
330  for (i = 0; i < FFMIN(nb_curves, FF_ARRAY_ELEMS(comp_ids)); i++) {
331  int nb_points, n;
332  av_bprint_clear(&ptstr);
333  READ16(nb_points);
334  for (n = 0; n < nb_points; n++) {
335  int y, x;
336  READ16(y);
337  READ16(x);
338  av_bprintf(&ptstr, "%f/%f ", x / 255., y / 255.);
339  }
340  if (*ptstr.str) {
341  char **pts = &curves->comp_points_str[comp_ids[i]];
342  if (!*pts) {
343  *pts = av_strdup(ptstr.str);
344  av_log(ctx, AV_LOG_DEBUG, "curves %d (intid=%d) [%d points]: [%s]\n",
345  i, comp_ids[i], nb_points, *pts);
346  if (!*pts) {
347  ret = AVERROR(ENOMEM);
348  goto end;
349  }
350  }
351  }
352  }
353 end:
354  av_bprint_finalize(&ptstr, NULL);
355  av_file_unmap(buf, size);
356  return ret;
357 }
358 
359 static av_cold int init(AVFilterContext *ctx)
360 {
361  int i, j, ret;
362  CurvesContext *curves = ctx->priv;
363  struct keypoint *comp_points[NB_COMP + 1] = {0};
364  char **pts = curves->comp_points_str;
365  const char *allp = curves->comp_points_str_all;
366 
367  //if (!allp && curves->preset != PRESET_NONE && curves_presets[curves->preset].all)
368  // allp = curves_presets[curves->preset].all;
369 
370  if (allp) {
371  for (i = 0; i < NB_COMP; i++) {
372  if (!pts[i])
373  pts[i] = av_strdup(allp);
374  if (!pts[i])
375  return AVERROR(ENOMEM);
376  }
377  }
378 
379  if (curves->psfile) {
380  ret = parse_psfile(ctx, curves->psfile);
381  if (ret < 0)
382  return ret;
383  }
384 
385  if (curves->preset != PRESET_NONE) {
386 #define SET_COMP_IF_NOT_SET(n, name) do { \
387  if (!pts[n] && curves_presets[curves->preset].name) { \
388  pts[n] = av_strdup(curves_presets[curves->preset].name); \
389  if (!pts[n]) \
390  return AVERROR(ENOMEM); \
391  } \
392 } while (0)
397  }
398 
399  for (i = 0; i < NB_COMP + 1; i++) {
400  ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
401  if (ret < 0)
402  return ret;
403  ret = interpolate(ctx, curves->graph[i], comp_points[i]);
404  if (ret < 0)
405  return ret;
406  }
407 
408  if (pts[NB_COMP]) {
409  for (i = 0; i < NB_COMP; i++)
410  for (j = 0; j < 256; j++)
411  curves->graph[i][j] = curves->graph[NB_COMP][curves->graph[i][j]];
412  }
413 
414  if (av_log_get_level() >= AV_LOG_VERBOSE) {
415  for (i = 0; i < NB_COMP; i++) {
416  struct keypoint *point = comp_points[i];
417  av_log(ctx, AV_LOG_VERBOSE, "#%d points:", i);
418  while (point) {
419  av_log(ctx, AV_LOG_VERBOSE, " (%f;%f)", point->x, point->y);
420  point = point->next;
421  }
422  av_log(ctx, AV_LOG_VERBOSE, "\n");
423  av_log(ctx, AV_LOG_VERBOSE, "#%d values:", i);
424  for (j = 0; j < 256; j++)
425  av_log(ctx, AV_LOG_VERBOSE, " %02X", curves->graph[i][j]);
426  av_log(ctx, AV_LOG_VERBOSE, "\n");
427  }
428  }
429 
430  for (i = 0; i < NB_COMP + 1; i++) {
431  struct keypoint *point = comp_points[i];
432  while (point) {
433  struct keypoint *next = point->next;
434  av_free(point);
435  point = next;
436  }
437  }
438 
439  return 0;
440 }
441 
443 {
444  static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE};
446  return 0;
447 }
448 
449 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
450 {
451  int x, y, i, direct = 0;
452  AVFilterContext *ctx = inlink->dst;
453  CurvesContext *curves = ctx->priv;
454  AVFilterLink *outlink = inlink->dst->outputs[0];
455  AVFrame *out;
456  uint8_t *dst;
457  const uint8_t *src;
458 
459  if (av_frame_is_writable(in)) {
460  direct = 1;
461  out = in;
462  } else {
463  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
464  if (!out) {
465  av_frame_free(&in);
466  return AVERROR(ENOMEM);
467  }
468  av_frame_copy_props(out, in);
469  }
470 
471  dst = out->data[0];
472  src = in ->data[0];
473 
474  for (y = 0; y < inlink->h; y++) {
475  uint8_t *dstp = dst;
476  const uint8_t *srcp = src;
477 
478  for (x = 0; x < inlink->w; x++)
479  for (i = 0; i < NB_COMP; i++, dstp++, srcp++)
480  *dstp = curves->graph[i][*srcp];
481  dst += out->linesize[0];
482  src += in ->linesize[0];
483  }
484 
485  if (!direct)
486  av_frame_free(&in);
487 
488  return ff_filter_frame(outlink, out);
489 }
490 
491 static const AVFilterPad curves_inputs[] = {
492  {
493  .name = "default",
494  .type = AVMEDIA_TYPE_VIDEO,
495  .filter_frame = filter_frame,
496  },
497  { NULL }
498 };
499 
500 static const AVFilterPad curves_outputs[] = {
501  {
502  .name = "default",
503  .type = AVMEDIA_TYPE_VIDEO,
504  },
505  { NULL }
506 };
507 
509  .name = "curves",
510  .description = NULL_IF_CONFIG_SMALL("Adjust components curves."),
511  .priv_size = sizeof(CurvesContext),
512  .init = init,
514  .inputs = curves_inputs,
515  .outputs = curves_outputs,
516  .priv_class = &curves_class,
517 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:424
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
AVOption.
Definition: opt.h:251
struct keypoint * next
Definition: vf_curves.c:34
static const AVFilterPad outputs[]
Definition: af_ashowinfo.c:117
external API header
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:70
const char * g
Definition: vf_curves.c:95
static int interpolate(AVFilterContext *ctx, uint8_t *y, const struct keypoint *points)
Natural cubic spline interpolation Finding curves using Cubic Splines notes by Steven Rauch and John ...
Definition: vf_curves.c:209
static struct keypoint * make_point(double x, double y, struct keypoint *next)
Definition: vf_curves.c:123
const char * b
Definition: vf_curves.c:96
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
#define FF_ARRAY_ELEMS(a)
int version
Definition: avisynth_c.h:666
const char * master
Definition: vf_curves.c:97
static const struct @117 curves_presets[]
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:143
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:193
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
set threshold d
char * psfile
Definition: vf_curves.c:60
BYTE int const BYTE * srcp
Definition: avisynth_c.h:713
const char * name
Pad name.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
int av_log_get_level(void)
Definition: log.c:264
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
#define av_cold
Definition: attributes.h:78
static const AVOption curves_options[]
Definition: vf_curves.c:65
AVOptions.
#define NB_COMP
Definition: vf_curves.c:37
end end
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_curves.c:449
Misc file utilities.
void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:545
#define B
char * comp_points_str_all
Definition: vf_curves.c:58
A filter pad used for either input or output.
#define FLAGS
Definition: vf_curves.c:64
#define SET_COMP_IF_NOT_SET(n, name)
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
AVFilter avfilter_vf_curves
Definition: vf_curves.c:508
BYTE * dstp
Definition: avisynth_c.h:713
#define READ16(dst)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
Definition: bprint.c:68
const char * r
Definition: vf_curves.c:94
void * priv
private data for use by the filter
Definition: avfilter.h:545
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:361
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int size
#define M
double x
Definition: vf_curves.c:33
#define AV_LOG_VERBOSE
Definition: log.h:157
Buffer to print data progressively.
Definition: bprint.h:75
char * comp_points_str[NB_COMP+1]
Definition: vf_curves.c:57
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
double av_strtod(const char *numstr, char **tail)
Parse the string in numstr and return its value as a double.
Definition: eval.c:89
enum preset preset
Definition: vf_curves.c:56
for k
NULL
Definition: eval.c:55
#define AV_BPRINT_SIZE_AUTOMATIC
Definition: bprint.h:90
AVS_Value src
Definition: avisynth_c.h:523
static int parse_psfile(AVFilterContext *ctx, const char *fname)
Definition: vf_curves.c:305
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:220
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
double y
Definition: vf_curves.c:33
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static int parse_points_str(AVFilterContext *ctx, struct keypoint **points, const char *s)
Definition: vf_curves.c:135
void * buf
Definition: avisynth_c.h:594
static av_cold int init(AVFilterContext *ctx)
Definition: vf_curves.c:359
static int get_nb_points(const struct keypoint *d)
Definition: vf_curves.c:194
#define OFFSET(x)
Definition: vf_curves.c:63
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
Filter definition.
Definition: avfilter.h:436
synthesis window for stochastic i
const char * name
filter name
Definition: avfilter.h:437
static const AVFilterPad curves_inputs[]
Definition: vf_curves.c:491
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define A
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
Definition: mem.c:213
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:185
AVFILTER_DEFINE_CLASS(curves)
preset
Definition: vf_curves.c:39
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
static double c[64]
uint8_t graph[NB_COMP+1][256]
Definition: vf_curves.c:59
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
An instance of a filter.
Definition: avfilter.h:524
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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_dlog(ac->avr,"%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-> out
static int query_formats(AVFilterContext *ctx)
Definition: vf_curves.c:442
internal API functions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:66
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 av_unused
Definition: attributes.h:114
static const AVFilterPad curves_outputs[]
Definition: vf_curves.c:500
simple arithmetic expression evaluator