[FFmpeg-devel] [PATCH] -cmdline_from_file new paramter
Procontrol Robert Kovacs
kovacsrobi at proci.hu
Wed Jan 6 18:37:16 CET 2016
---
cmdutils.c | 186 +++++++++++++++++++++++++++++++++++++++++++
doc/fftools-common-opts.texi | 41 ++++++++++
2 files changed, 227 insertions(+)
diff --git a/cmdutils.c b/cmdutils.c
index e0d2807..5441485 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -732,6 +732,189 @@ void uninit_parse_context(OptionParseContext *octx)
uninit_opts();
}
+/*
+ * read file contents into a string (copy from ffmpeg.c, because I don't how call original function from here)
+ */
+static uint8_t *read_file(const char *filename)
+{
+ AVIOContext *pb = NULL;
+ AVIOContext *dyn_buf = NULL;
+ int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
+ uint8_t buf[1024], *str;
+
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
+ return NULL;
+ }
+
+ ret = avio_open_dyn_buf(&dyn_buf);
+ if (ret < 0) {
+ avio_closep(&pb);
+ return NULL;
+ }
+ while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
+ avio_write(dyn_buf, buf, ret);
+ avio_w8(dyn_buf, 0);
+ avio_closep(&pb);
+
+ ret = avio_close_dyn_buf(dyn_buf, &str);
+ if (ret < 0)
+ return NULL;
+ return str;
+}
+
+/*
+ * Replace original program command line args, if use -cmdline_from_file parameter.
+ * @param argc Original main argc replaced to new from script
+ * @param argv Original main argv replaced to new from script
+ */
+static int parse_commandline_script_from_file(int *argc, char ***argv)
+{
+
+ int arguments_number=1;
+ int argument_max_size=500;
+ int argument_max_num=200;
+ int textindicator=0;
+ char ** buf;
+ int block_comment_active=0;
+ int last_block_comment_active=0;
+ int inline_comment_active=0;
+ int count=0;
+ int script_argc = 0;
+ uint8_t *controlfile_str;
+
+ /* Check -cmdline_from_file parameter */
+ for (count = 0; count < *argc; count++)
+ {
+ if (!strcmp( (*argv)[count], "-cmdline_from_file"))
+ {
+ script_argc=count;
+ }
+ }
+
+ /* if not have this parameter, return to original split_commandline function, without modification. */
+ if (script_argc == 0)
+ {
+ return 0;
+ }
+
+ av_log(NULL, AV_LOG_INFO, "Have -cmdline_from_file paramter on %i position. Fully replace program parameters now!\n", script_argc);
+
+ controlfile_str = read_file( (*argv)[ script_argc+1 ] );
+ if (!controlfile_str)
+ {
+ return AVERROR(EINVAL);
+ } else
+ {
+ int i=0;
+ int character_index=0;
+ char actualcharacter;
+ char lastcharacter='q';
+
+ buf= (char**) malloc(sizeof(char*)*(argument_max_num));
+ buf[arguments_number]=(char*) malloc(argument_max_size* sizeof(char));
+
+ while((actualcharacter=controlfile_str[i])!='\0')
+ {
+ i++;
+ /* watch comment block end */
+ if ((actualcharacter=='*')&&(lastcharacter=='/'))
+ {
+ block_comment_active=1;
+ continue;
+ }
+
+ /* watch comment block start */
+ if ((actualcharacter=='/')&&(lastcharacter=='*'))
+ {
+ block_comment_active=0;
+ character_index--;
+ }
+
+ /* watch inline comment */
+ if ((actualcharacter=='/')&&(lastcharacter=='/'))
+ {
+ inline_comment_active=1;
+ character_index--;
+ continue;
+ }
+
+ /* watch inline comment end (newline) */
+ if ((inline_comment_active)&&((actualcharacter=='\n'))) //'\0x1D' chr(13)
+ {
+ inline_comment_active=0;
+ }
+
+ /* store characters, if not block comment active */
+ if ((!block_comment_active)&&(!last_block_comment_active)&&(!inline_comment_active))
+ {
+ /* Check string bracketed block start or stop */
+ if (actualcharacter=='"')
+ {
+ textindicator++;
+ textindicator=textindicator%2;
+ }
+ /* New parameter, not in bracket */
+ if (((actualcharacter==' ')&&(textindicator==0))||((actualcharacter=='\n')&&(textindicator==0)&&(lastcharacter!='\n')))
+ {
+ /* New parameter parsed. Close argument last character position with 0x00. Close arg, and prepare next. */
+ if (character_index!=0)
+ {
+ buf[arguments_number][character_index]='\0';
+ character_index=0;
+ arguments_number++;
+ }
+ }
+ /* New character. */
+ if ( !((actualcharacter=='\n') || (actualcharacter=='"') || ((actualcharacter==' ') && (textindicator==0))) )
+ {
+ /* Prepare memory for new arg. */
+ if (character_index==0)
+ {
+ buf[arguments_number+1]=(char*) malloc(argument_max_size* sizeof(char));
+ }
+
+ buf[arguments_number][character_index]=actualcharacter;
+ character_index++;
+ /* Close the last open string */
+ buf[arguments_number][character_index]='\0';
+ }
+ }
+ lastcharacter=actualcharacter;
+ last_block_comment_active=block_comment_active;
+ }
+
+ if (lastcharacter!='\n')
+ {
+ buf[arguments_number][character_index]='\0';
+ if (inline_comment_active!=1)
+ {
+ arguments_number++;
+ }
+ }
+
+ /* copy the program name */
+ buf[0]=(*argv)[0];
+
+ /* argv close */
+ buf[arguments_number]=NULL;
+
+ /* debug parsed command line */
+ av_log(NULL, AV_LOG_DEBUG, "Extracted (%i) arguments from file:\n", arguments_number);
+ for (count = 0; count <= arguments_number; count++)
+ {
+ av_log(NULL, AV_LOG_DEBUG, "%s ", buf[count]);
+ }
+ av_log(NULL, AV_LOG_DEBUG, "\n");
+ }
+
+ *argc=arguments_number;
+ *argv=buf;
+
+ /* Return to original split_commandline function, and parse options and open all input, output files */
+ return 1;
+}
+
int split_commandline(OptionParseContext *octx, int argc, char *argv[],
const OptionDef *options,
const OptionGroupDef *groups, int nb_groups)
@@ -741,6 +924,9 @@ int split_commandline(OptionParseContext *octx, int argc, char *argv[],
/* perform system-dependent conversions for arguments list */
prepare_app_arguments(&argc, &argv);
+
+ /* check cmdline_from_file parameter, and modify argc and argv */
+ parse_commandline_script_from_file(&argc, &argv);
init_parse_context(octx, groups, nb_groups);
av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");
diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi
index 509c8bc..198a5ec 100644
--- a/doc/fftools-common-opts.texi
+++ b/doc/fftools-common-opts.texi
@@ -354,6 +354,47 @@ FFmpeg has been compiled with @code{--enable-opencl}.
@var{options} must be a list of @var{key}=@var{value} option pairs
separated by ':'. See the ``OpenCL Options'' section in the
ffmpeg-utils manual for the list of supported options.
+
+ at item -cmdline_from_file script_filename.txt
+Commandline script file.
+ at code{ffmpeg -cmdline_from_file script_filename.txt}
+@*@*
+This option is read command line parameters from external file. Replace original arguments.
+You can use same control file on Windows and linux systems, no problem on batch file %% character and etc.
+The script_filename maybe get from http, or ftp url. http://127.0.0.1/script_filename.txt
+You can use inline comments (with //) or comment section block (with /* */) in script file.
+You can separate cmdline script with enter. Hereby your ffmpeg command line parameters will maybe readable! :)@*
+@*Example:@*
+ at example
+ffmpeg -cmdline_from_file control1.txt
+
+control1.txt:
+-f lavfi
+-i testsrc
+out.flv
+
+ffmpeg -cmdline_from_file http://127.0.0.1/control2.txt
+control2.txt:
+-y -re
+-f
+lavfi
+-i testsrc=size=1280x720:/*Comments inside code*/rate=30
+-f
+lavfi /*
+More rows
+comments
+*/
+
+-i
+aevalsrc=0
+//Inline comment, and after separate code with enter
+-an
+-c:v rawvideo
+-pix_fmt
+yuv420p
+-f sdl "SDL/*Comment inside string*/output"
+ at end example
+
@end table
@section AVOptions
--
2.5.2
More information about the ffmpeg-devel
mailing list