Browse code

lavfi/curves: add plot option

Clément Bœsch authored on 2016/07/22 08:17:44
Showing 2 changed files
... ...
@@ -5750,6 +5750,8 @@ options. In this case, the unset component(s) will fallback on this
5750 5750
 @option{all} setting.
5751 5751
 @item psfile
5752 5752
 Specify a Photoshop curves file (@code{.acv}) to import the settings from.
5753
+@item plot
5754
+Save Gnuplot script of the curves in specified file.
5753 5755
 @end table
5754 5756
 
5755 5757
 To avoid some filtergraph syntax conflicts, each key points list need to be
... ...
@@ -5796,6 +5798,14 @@ Use a Photoshop preset and redefine the points of the green component:
5796 5796
 @example
5797 5797
 curves=psfile='MyCurvesPresets/purple.acv':green='0/0 0.45/0.53 1/1'
5798 5798
 @end example
5799
+
5800
+@item
5801
+Check out the curves of the @code{cross_process} profile using @command{ffmpeg}
5802
+and @command{gnuplot}:
5803
+@example
5804
+ffmpeg -f lavfi -i color -vf curves=cross_process:plot=/tmp/curves.plt -frames:v 1 -f null -
5805
+gnuplot -p /tmp/curves.plt
5806
+@end example
5799 5807
 @end itemize
5800 5808
 
5801 5809
 @section datascope
... ...
@@ -67,6 +67,7 @@ typedef struct {
67 67
     char *psfile;
68 68
     uint8_t rgba_map[4];
69 69
     int step;
70
+    char *plot_filename;
70 71
 } CurvesContext;
71 72
 
72 73
 typedef struct ThreadData {
... ...
@@ -98,6 +99,7 @@ static const AVOption curves_options[] = {
98 98
     { "b",     "set blue points coordinates",  OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
99 99
     { "all",   "set points coordinates for all components", OFFSET(comp_points_str_all), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
100 100
     { "psfile", "set Photoshop curves file name", OFFSET(psfile), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
101
+    { "plot", "save Gnuplot script of the curves in specified file", OFFSET(plot_filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
101 102
     { NULL }
102 103
 };
103 104
 
... ...
@@ -377,6 +379,65 @@ end:
377 377
     return ret;
378 378
 }
379 379
 
380
+static int dump_curves(const char *fname, uint8_t graph[NB_COMP + 1][256],
381
+                       struct keypoint *comp_points[NB_COMP + 1])
382
+{
383
+    int i;
384
+    AVBPrint buf;
385
+    static const char * const colors[] = { "red", "green", "blue", "#404040", };
386
+    FILE *f = av_fopen_utf8(fname, "w");
387
+
388
+    av_assert0(FF_ARRAY_ELEMS(colors) == NB_COMP + 1);
389
+
390
+    if (!f) {
391
+        int ret = AVERROR(errno);
392
+        av_log(NULL, AV_LOG_ERROR, "Cannot open file '%s' for writing: %s\n",
393
+               fname, av_err2str(ret));
394
+        return ret;
395
+    }
396
+
397
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
398
+
399
+    av_bprintf(&buf, "set xtics 0.1\n");
400
+    av_bprintf(&buf, "set ytics 0.1\n");
401
+    av_bprintf(&buf, "set size square\n");
402
+    av_bprintf(&buf, "set grid\n");
403
+
404
+    for (i = 0; i < FF_ARRAY_ELEMS(colors); i++) {
405
+        av_bprintf(&buf, "%s'-' using 1:2 with lines lc '%s' title ''",
406
+                   i ? ", " : "plot ", colors[i]);
407
+        if (comp_points[i])
408
+            av_bprintf(&buf, ", '-' using 1:2 with points pointtype 3 lc '%s' title ''",
409
+                    colors[i]);
410
+    }
411
+    av_bprintf(&buf, "\n");
412
+
413
+    for (i = 0; i < FF_ARRAY_ELEMS(colors); i++) {
414
+        int x;
415
+
416
+        /* plot generated values */
417
+        for (x = 0; x < 256; x++)
418
+            av_bprintf(&buf, "%f %f\n", x/255., graph[i][x]/255.);
419
+        av_bprintf(&buf, "e\n");
420
+
421
+        /* plot user knots */
422
+        if (comp_points[i]) {
423
+            const struct keypoint *point = comp_points[i];
424
+
425
+            while (point) {
426
+                av_bprintf(&buf, "%f %f\n", point->x, point->y);
427
+                point = point->next;
428
+            }
429
+            av_bprintf(&buf, "e\n");
430
+        }
431
+    }
432
+
433
+    fwrite(buf.str, 1, buf.len, f);
434
+    fclose(f);
435
+    av_bprint_finalize(&buf, NULL);
436
+    return 0;
437
+}
438
+
380 439
 static av_cold int init(AVFilterContext *ctx)
381 440
 {
382 441
     int i, j, ret;
... ...
@@ -448,6 +509,9 @@ static av_cold int init(AVFilterContext *ctx)
448 448
         }
449 449
     }
450 450
 
451
+    if (curves->plot_filename)
452
+        dump_curves(curves->plot_filename, curves->graph, comp_points);
453
+
451 454
     for (i = 0; i < NB_COMP + 1; i++) {
452 455
         struct keypoint *point = comp_points[i];
453 456
         while (point) {