From b1ac139d89b9fc55b70ad3411af2f75fe8b17805 Mon Sep 17 00:00:00 2001 From: Kirill Gavrilov Date: Wed, 20 Apr 2011 14:36:44 +0300 Subject: Handle unicode file names on windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All file names should be in UTF-8 within libavformat. This is handled by mapping the open() function to an internal one in os_support.h for windows. fopen() could be overridden in the same way, but if that would be used from ffmpeg.c, it would add a dependency on an ff prefixed internal lavf function. Signed-off-by: Martin Storsjö --- cmdutils.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'cmdutils.c') diff --git a/cmdutils.c b/cmdutils.c index f1cbd55..f25f61d 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -155,6 +155,66 @@ static const OptionDef* find_option(const OptionDef *po, const char *name){ return po; } +#if defined(_WIN32) && !defined(__MINGW32CE__) +/* Will be leaked on exit */ +static char** win32_argv_utf8 = NULL; +static int win32_argc = 0; + +/** + * Prepare command line arguments for executable. + * For Windows - perform wide-char to UTF-8 conversion. + * Input arguments should be main() function arguments. + * @param argc_ptr Arguments number (including executable) + * @param argv_ptr Arguments list. + */ +static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) +{ + char *argstr_flat; + wchar_t **argv_w; + int i, buffsize = 0, offset = 0; + + if (win32_argv_utf8) { + *argc_ptr = win32_argc; + *argv_ptr = win32_argv_utf8; + return; + } + + win32_argc = 0; + argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc); + if (win32_argc <= 0 || !argv_w) + return; + + /* determine the UTF-8 buffer size (including NULL-termination symbols) */ + for (i = 0; i < win32_argc; i++) + buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, + NULL, 0, NULL, NULL); + + win32_argv_utf8 = av_mallocz(sizeof(char*) * (win32_argc + 1) + buffsize); + argstr_flat = (char*)win32_argv_utf8 + sizeof(char*) * (win32_argc + 1); + if (win32_argv_utf8 == NULL) { + LocalFree(argv_w); + return; + } + + for (i = 0; i < win32_argc; i++) { + win32_argv_utf8[i] = &argstr_flat[offset]; + offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1, + &argstr_flat[offset], + buffsize - offset, NULL, NULL); + } + win32_argv_utf8[i] = NULL; + LocalFree(argv_w); + + *argc_ptr = win32_argc; + *argv_ptr = win32_argv_utf8; +} +#else +static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr) +{ + /* nothing to do */ +} +#endif /* WIN32 && !__MINGW32CE__ */ + void parse_options(int argc, char **argv, const OptionDef *options, void (* parse_arg_function)(const char*)) { @@ -162,6 +222,9 @@ void parse_options(int argc, char **argv, const OptionDef *options, int optindex, handleoptions=1; const OptionDef *po; + /* perform system-dependent conversions for arguments list */ + prepare_app_arguments(&argc, &argv); + /* parse options */ optindex = 1; while (optindex < argc) { -- cgit v1.1