--- 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. + +@item -cmdline_from_file script_filename.txt +Commandline script file. +@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:@* +@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" +@end example + @end table @section AVOptions -- 2.5.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel