[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