Browse code

fftools: add -report option.

Nicolas George authored on 2011/12/08 22:42:24
Showing 5 changed files
... ...
@@ -131,6 +131,7 @@ easier to use. The changes are:
131 131
 - life source
132 132
 - PCM format support in OMA demuxer
133 133
 - CLJR encoder
134
+- new option: -report
134 135
 
135 136
 
136 137
 version 0.8:
... ...
@@ -55,6 +55,8 @@ AVDictionary *format_opts, *codec_opts;
55 55
 
56 56
 static const int this_year = 2011;
57 57
 
58
+static FILE *report_file;
59
+
58 60
 void init_opts(void)
59 61
 {
60 62
 #if CONFIG_SWSCALE
... ...
@@ -77,6 +79,20 @@ void log_callback_help(void* ptr, int level, const char* fmt, va_list vl)
77 77
     vfprintf(stdout, fmt, vl);
78 78
 }
79 79
 
80
+static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
81
+{
82
+    va_list vl2;
83
+    char line[1024];
84
+    static int print_prefix = 1;
85
+
86
+    va_copy(vl2, vl);
87
+    av_log_default_callback(ptr, level, fmt, vl);
88
+    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
89
+    va_end(vl2);
90
+    fputs(line, report_file);
91
+    fflush(report_file);
92
+}
93
+
80 94
 double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
81 95
 {
82 96
     char *tail;
... ...
@@ -344,6 +360,30 @@ static int locate_option(int argc, char **argv, const OptionDef *options, const
344 344
     return 0;
345 345
 }
346 346
 
347
+static void dump_argument(const char *a)
348
+{
349
+    const unsigned char *p;
350
+
351
+    for (p = a; *p; p++)
352
+        if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
353
+              *p == '_' || (*p >= 'a' && *p <= 'z')))
354
+            break;
355
+    if (!*p) {
356
+        fputs(a, report_file);
357
+        return;
358
+    }
359
+    fputc('"', report_file);
360
+    for (p = a; *p; p++) {
361
+        if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
362
+            fprintf(report_file, "\\%c", *p);
363
+        else if (*p < ' ' || *p > '~')
364
+            fprintf(report_file, "\\x%02x", *p);
365
+        else
366
+            fputc(*p, report_file);
367
+    }
368
+    fputc('"', report_file);
369
+}
370
+
347 371
 void parse_loglevel(int argc, char **argv, const OptionDef *options)
348 372
 {
349 373
     int idx = locate_option(argc, argv, options, "loglevel");
... ...
@@ -351,6 +391,19 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options)
351 351
         idx = locate_option(argc, argv, options, "v");
352 352
     if (idx && argv[idx + 1])
353 353
         opt_loglevel("loglevel", argv[idx + 1]);
354
+    idx = locate_option(argc, argv, options, "report");
355
+    if (idx || getenv("FFREPORT")) {
356
+        opt_report("report");
357
+        if (report_file) {
358
+            int i;
359
+            fprintf(report_file, "Command line:\n");
360
+            for (i = 0; i < argc; i++) {
361
+                dump_argument(argv[i]);
362
+                fputc(i < argc - 1 ? ' ' : '\n', report_file);
363
+            }
364
+            fflush(report_file);
365
+        }
366
+    }
354 367
 }
355 368
 
356 369
 #define FLAGS(o) ((o)->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
... ...
@@ -424,6 +477,38 @@ int opt_loglevel(const char *opt, const char *arg)
424 424
     return 0;
425 425
 }
426 426
 
427
+int opt_report(const char *opt)
428
+{
429
+    char filename[64];
430
+    time_t now;
431
+    struct tm *tm;
432
+
433
+    if (report_file) /* already opened */
434
+        return 0;
435
+    time(&now);
436
+    tm = localtime(&now);
437
+    snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
438
+             program_name,
439
+             tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
440
+             tm->tm_hour, tm->tm_min, tm->tm_sec);
441
+    report_file = fopen(filename, "w");
442
+    if (!report_file) {
443
+        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
444
+               filename, strerror(errno));
445
+        return AVERROR(errno);
446
+    }
447
+    av_log_set_callback(log_callback_report);
448
+    av_log(NULL, AV_LOG_INFO,
449
+           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
450
+           "Report written to \"%s\"\n",
451
+           program_name,
452
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
453
+           tm->tm_hour, tm->tm_min, tm->tm_sec,
454
+           filename);
455
+    av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
456
+    return 0;
457
+}
458
+
427 459
 int opt_codec_debug(const char *opt, const char *arg)
428 460
 {
429 461
     av_log_set_level(AV_LOG_DEBUG);
... ...
@@ -76,6 +76,8 @@ int opt_default(const char *opt, const char *arg);
76 76
  */
77 77
 int opt_loglevel(const char *opt, const char *arg);
78 78
 
79
+int opt_report(const char *opt);
80
+
79 81
 int opt_codec_debug(const char *opt, const char *arg);
80 82
 
81 83
 /**
... ...
@@ -14,3 +14,4 @@
14 14
     { "loglevel", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
15 15
     { "v", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
16 16
     { "debug", HAS_ARG, {(void*)opt_codec_debug}, "set debug flags", "flags" },
17
+    { "report", 0, {(void*)opt_report}, "generate a report" },
... ...
@@ -123,6 +123,16 @@ the environment variable @env{FFMPEG_FORCE_COLOR}.
123 123
 The use of the environment variable @env{NO_COLOR} is deprecated and
124 124
 will be dropped in a following FFmpeg version.
125 125
 
126
+@item -report
127
+Dump full command line and console output to a file named
128
+@code{@var{program}-@var{YYYYMMDD}-@var{HHMMSS}.log} in the current
129
+directory.
130
+This file can be useful for bug reports.
131
+It also implies @code{-loglevel verbose}.
132
+
133
+Note: setting the environment variable @code{FFREPORT} to any value has the
134
+same effect.
135
+
126 136
 @end table
127 137
 
128 138
 @section AVOptions