diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2011-12-08 14:42:24 +0100 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2011-12-10 16:40:03 +0100 |
commit | 337ce558b696f49138a1ef170b219fe73b955b51 (patch) | |
tree | 55d260bab37fe558a75f71c5b056fc02e298f77a | |
parent | 5207f9597e96b4f38e4e392c4a32a8ff6601b3d4 (diff) | |
download | ffmpeg-337ce558b696f49138a1ef170b219fe73b955b51.tar.gz |
fftools: add -report option.
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | cmdutils.c | 85 | ||||
-rw-r--r-- | cmdutils.h | 2 | ||||
-rw-r--r-- | cmdutils_common_opts.h | 1 | ||||
-rw-r--r-- | doc/avtools-common-opts.texi | 10 |
5 files changed, 99 insertions, 0 deletions
@@ -131,6 +131,7 @@ easier to use. The changes are: - life source - PCM format support in OMA demuxer - CLJR encoder +- new option: -report version 0.8: diff --git a/cmdutils.c b/cmdutils.c index 62c87cb6b6..65628fcc86 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -55,6 +55,8 @@ AVDictionary *format_opts, *codec_opts; static const int this_year = 2011; +static FILE *report_file; + void init_opts(void) { #if CONFIG_SWSCALE @@ -77,6 +79,20 @@ void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) vfprintf(stdout, fmt, vl); } +static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl) +{ + va_list vl2; + char line[1024]; + static int print_prefix = 1; + + va_copy(vl2, vl); + av_log_default_callback(ptr, level, fmt, vl); + av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix); + va_end(vl2); + fputs(line, report_file); + fflush(report_file); +} + double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max) { char *tail; @@ -344,6 +360,30 @@ static int locate_option(int argc, char **argv, const OptionDef *options, const return 0; } +static void dump_argument(const char *a) +{ + const unsigned char *p; + + for (p = a; *p; p++) + if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') || + *p == '_' || (*p >= 'a' && *p <= 'z'))) + break; + if (!*p) { + fputs(a, report_file); + return; + } + fputc('"', report_file); + for (p = a; *p; p++) { + if (*p == '\\' || *p == '"' || *p == '$' || *p == '`') + fprintf(report_file, "\\%c", *p); + else if (*p < ' ' || *p > '~') + fprintf(report_file, "\\x%02x", *p); + else + fputc(*p, report_file); + } + fputc('"', report_file); +} + void parse_loglevel(int argc, char **argv, const OptionDef *options) { int idx = locate_option(argc, argv, options, "loglevel"); @@ -351,6 +391,19 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options) idx = locate_option(argc, argv, options, "v"); if (idx && argv[idx + 1]) opt_loglevel("loglevel", argv[idx + 1]); + idx = locate_option(argc, argv, options, "report"); + if (idx || getenv("FFREPORT")) { + opt_report("report"); + if (report_file) { + int i; + fprintf(report_file, "Command line:\n"); + for (i = 0; i < argc; i++) { + dump_argument(argv[i]); + fputc(i < argc - 1 ? ' ' : '\n', report_file); + } + fflush(report_file); + } + } } #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) return 0; } +int opt_report(const char *opt) +{ + char filename[64]; + time_t now; + struct tm *tm; + + if (report_file) /* already opened */ + return 0; + time(&now); + tm = localtime(&now); + snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log", + program_name, + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + report_file = fopen(filename, "w"); + if (!report_file) { + av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n", + filename, strerror(errno)); + return AVERROR(errno); + } + av_log_set_callback(log_callback_report); + av_log(NULL, AV_LOG_INFO, + "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n" + "Report written to \"%s\"\n", + program_name, + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + filename); + av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE)); + return 0; +} + int opt_codec_debug(const char *opt, const char *arg) { av_log_set_level(AV_LOG_DEBUG); diff --git a/cmdutils.h b/cmdutils.h index 4773c3d3f4..15f983643a 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -76,6 +76,8 @@ int opt_default(const char *opt, const char *arg); */ int opt_loglevel(const char *opt, const char *arg); +int opt_report(const char *opt); + int opt_codec_debug(const char *opt, const char *arg); /** diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h index cced0bb895..058f2b1e2f 100644 --- a/cmdutils_common_opts.h +++ b/cmdutils_common_opts.h @@ -14,3 +14,4 @@ { "loglevel", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" }, { "v", HAS_ARG, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" }, { "debug", HAS_ARG, {(void*)opt_codec_debug}, "set debug flags", "flags" }, + { "report", 0, {(void*)opt_report}, "generate a report" }, diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi index 52f4efcddc..b97a3c8b2a 100644 --- a/doc/avtools-common-opts.texi +++ b/doc/avtools-common-opts.texi @@ -123,6 +123,16 @@ the environment variable @env{FFMPEG_FORCE_COLOR}. The use of the environment variable @env{NO_COLOR} is deprecated and will be dropped in a following FFmpeg version. +@item -report +Dump full command line and console output to a file named +@code{@var{program}-@var{YYYYMMDD}-@var{HHMMSS}.log} in the current +directory. +This file can be useful for bug reports. +It also implies @code{-loglevel verbose}. + +Note: setting the environment variable @code{FFREPORT} to any value has the +same effect. + @end table @section AVOptions |