[FFmpeg-cvslog] cmdutils: allow to set the report file name.
Nicolas George
git at videolan.org
Sun Nov 4 11:00:17 CET 2012
ffmpeg | branch: master | Nicolas George <nicolas.george at normalesup.org> | Fri Nov 2 13:15:51 2012 +0100| [1fa47f8deafed3263ecdf5b0eb4807b77cfbb868] | committer: Nicolas George
cmdutils: allow to set the report file name.
The file name can be set by setting the FFREPORT environment
variable to "file=something".
Fix trac ticket #1823.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1fa47f8deafed3263ecdf5b0eb4807b77cfbb868
---
cmdutils.c | 86 ++++++++++++++++++++++++++++++++++++------
doc/avtools-common-opts.texi | 16 +++++++-
2 files changed, 89 insertions(+), 13 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index f696700..2375d4e 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -41,6 +41,7 @@
#endif
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
#include "libavutil/mathematics.h"
#include "libavutil/imgutils.h"
#include "libavutil/parseutils.h"
@@ -58,6 +59,8 @@
#include <sys/resource.h>
#endif
+static int init_report(const char *env);
+
struct SwsContext *sws_opts;
SwrContext *swr_opts;
AVDictionary *format_opts, *codec_opts;
@@ -414,13 +417,14 @@ static void dump_argument(const char *a)
void parse_loglevel(int argc, char **argv, const OptionDef *options)
{
int idx = locate_option(argc, argv, options, "loglevel");
+ const char *env;
if (!idx)
idx = locate_option(argc, argv, options, "v");
if (idx && argv[idx + 1])
opt_loglevel(NULL, "loglevel", argv[idx + 1]);
idx = locate_option(argc, argv, options, "report");
- if (idx || getenv("FFREPORT")) {
- opt_report("report");
+ if ((env = getenv("FFREPORT")) || idx) {
+ init_report(env);
if (report_file) {
int i;
fprintf(report_file, "Command line:\n");
@@ -528,24 +532,78 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
return 0;
}
-int opt_report(const char *opt)
+static void expand_filename_template(AVBPrint *bp, const char *template,
+ struct tm *tm)
+{
+ int c;
+
+ while ((c = *(template++))) {
+ if (c == '%') {
+ if (!(c = *(template++)))
+ break;
+ switch (c) {
+ case 'p':
+ av_bprintf(bp, "%s", program_name);
+ break;
+ case 't':
+ av_bprintf(bp, "%04d%02d%02d-%02d%02d%02d",
+ tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ break;
+ case '%':
+ av_bprint_chars(bp, c, 1);
+ break;
+ }
+ } else {
+ av_bprint_chars(bp, c, 1);
+ }
+ }
+}
+
+static int init_report(const char *env)
{
- char filename[64];
+ const char *filename_template = "%p-%t.log";
+ char *key, *val;
+ int ret, count = 0;
time_t now;
struct tm *tm;
+ AVBPrint filename;
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");
+
+ while (env && *env) {
+ if ((ret = av_opt_get_key_value(&env, "=", ":", 0, &key, &val)) < 0) {
+ if (count)
+ av_log(NULL, AV_LOG_ERROR,
+ "Failed to parse FFREPORT environment variable: %s\n",
+ av_err2str(ret));
+ break;
+ }
+ count++;
+ if (!strcmp(key, "file")) {
+ filename_template = val;
+ val = NULL;
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Unknown key '%s' in FFREPORT\n", key);
+ }
+ av_free(val);
+ av_free(key);
+ }
+
+ av_bprint_init(&filename, 0, 1);
+ expand_filename_template(&filename, filename_template, tm);
+ if (!av_bprint_is_complete(&filename)) {
+ av_log(NULL, AV_LOG_ERROR, "Out of memory building report file name\n");
+ return AVERROR(ENOMEM);
+ }
+
+ report_file = fopen(filename.str, "w");
if (!report_file) {
av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
- filename, strerror(errno));
+ filename.str, strerror(errno));
return AVERROR(errno);
}
av_log_set_callback(log_callback_report);
@@ -555,11 +613,17 @@ int opt_report(const char *opt)
program_name,
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec,
- filename);
+ filename.str);
av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
+ av_bprint_finalize(&filename, NULL);
return 0;
}
+int opt_report(const char *opt)
+{
+ return init_report(NULL);
+}
+
int opt_max_alloc(void *optctx, const char *opt, const char *arg)
{
char *tail;
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index 1fc12aa..d43ff6e 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -151,8 +151,20 @@ 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.
+Setting the environment variable @code{FFREPORT} to any value has the same
+effect. If the value is a ':'-separated key=value sequence, these options
+will affect the report; options values must be
+ at ref{quoting_and_escaping, escaped} if they contain special characters or
+the options delimiter ':'. The following option is recognized:
+ at table @option
+ at item file
+set the file name to use for the report; @code{%p} is expanded to the name
+of the program, @code{%t} is expanded to a timestamp, @code{%%} is expanded
+to a plain @code{%}
+ at end table
+
+Errors in parsing the environment variable are not fatal, and will not
+appear in the report.
@item -cpuflags flags (@emph{global})
Allows setting and clearing cpu flags. This option is intended
More information about the ffmpeg-cvslog
mailing list