2011/4/15 Kirill Gavrilov <[email protected]>

> Hmmm... agree that would be better (patch in attach).
>

Oh, forget attach itself...
-----------------------------------------------
Kirill Gavrilov,
Software designer.
diff --git a/cmdutils.c b/cmdutils.c
index 5b7b508..4852de3 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -155,6 +155,77 @@ static const OptionDef* find_option(const OptionDef *po, const char *name){
     return po;
 }
 
+/**
+ * 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);
+
+#if(defined(_WIN32) || defined(__WIN32__))
+static char** win32_argv_utf8 = NULL; /* should be released with av_freep() if needed... */
+static int win32_argc = 0;
+
+void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
+{
+    char *argstr_flat;
+    wchar_t **argvW;
+    int argId;
+    int aBuffSize;
+    int anOffset;
+
+    if(win32_argv_utf8 != NULL) {
+        *argc_ptr = win32_argc;
+        *argv_ptr = win32_argv_utf8;
+    }
+
+    win32_argc = 0;
+    argvW = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
+    if(win32_argc <= 0 || argvW == NULL) {
+        return;
+    }
+
+    argId = 0;
+    aBuffSize = 0;
+    /* determine the UTF-8 buffer size (including NULL-termination symbols) */
+    while(argId < win32_argc) {
+        aBuffSize += WideCharToMultiByte(CP_UTF8, 0, argvW[argId++], -1,
+                                         NULL, 0, NULL, NULL);
+    }
+    /* allocate one-big-buffer */
+    win32_argv_utf8 = (char** )av_malloc(sizeof(char*) * (win32_argc + 1) + aBuffSize);
+    argstr_flat = (char* )win32_argv_utf8 + sizeof(char*) * (win32_argc + 1);
+    if(win32_argv_utf8 == NULL) {
+        return;
+    }
+
+    /* simulate trailing NULL in generic main() function arguments list */
+    win32_argv_utf8[win32_argc] = NULL;
+
+    /* now convert each parameter */
+    argId = 0;
+    anOffset = 0;
+    while(argId < win32_argc) {
+        win32_argv_utf8[argId] = &argstr_flat[anOffset];
+        anOffset += WideCharToMultiByte(CP_UTF8, 0, argvW[argId++], -1,
+                                        &argstr_flat[anOffset], aBuffSize - anOffset, NULL, NULL);
+    }
+    /* release wide-char list */
+    LocalFree(argvW);
+
+    /* setup input arguments */
+    *argc_ptr = win32_argc;
+    *argv_ptr = win32_argv_utf8;
+}
+#else
+void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
+{
+    /* nothing to do */
+}
+#endif /* WIN32 */
+
 void parse_options(int argc, char **argv, const OptionDef *options,
                    void (* parse_arg_function)(const char*))
 {
@@ -162,6 +233,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) {
diff --git a/libavformat/file.c b/libavformat/file.c
index 9d28a89..0b71ed9 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -70,7 +70,7 @@ static int file_open(URLContext *h, const char *filename, int flags)
 #ifdef O_BINARY
     access |= O_BINARY;
 #endif
-    fd = open(filename, access, 0666);
+    fd = ff_open_file(filename, access, 0666);
     if (fd == -1)
         return AVERROR(errno);
     h->priv_data = (void *) (intptr_t) fd;
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 0b7b59e..e7146ea 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -28,6 +28,47 @@
 #include "avformat.h"
 #include "os_support.h"
 
+#if(defined(_WIN32) || defined(__WIN32__))
+#include <windows.h>
+
+int ff_open_file(const char *filenameUtf8, int oflag, int pmode)
+{
+    int fd;
+    int uChars;
+    wchar_t *filenameUtf16;
+
+    /* convert UTF-8 to wide chars */
+    uChars = MultiByteToWideChar(CP_UTF8, 0,
+                                 filenameUtf8, -1,
+                                 NULL, 0);
+    if(uChars <= 0) {
+        return -1;
+    }
+    filenameUtf16 = (wchar_t* )av_malloc(sizeof(wchar_t) * uChars);
+    memset(filenameUtf16, 0, sizeof(wchar_t) * uChars);
+    MultiByteToWideChar(CP_UTF8, 0,
+                        filenameUtf8, -1,
+                        filenameUtf16, uChars);
+
+    fd = _wopen(filenameUtf16, oflag, pmode);
+    av_freep(&filenameUtf16);
+
+    /* filename maybe be in CP_ACP */
+    if(fd == -1 && !(oflag & O_CREAT)) {
+        return open(filenameUtf8, oflag, pmode);
+    }
+
+    return fd;
+}
+#else
+#include <fcntl.h>
+
+int ff_open_file(const char *filename, int oflag, int pmode)
+{
+    return open(filename, oflag, pmode);
+}
+#endif /* WIN32 */
+
 #if CONFIG_NETWORK
 #include <fcntl.h>
 #include <unistd.h>
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index df32151..ae7e197 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -45,6 +45,16 @@ static inline int is_dos_path(const char *path)
     return 0;
 }
 
+/**
+ * System-dependent open file function.
+ * @param filename File path in system-dependent encoding format
+ * should be UTF-8 in Windows
+ * @param oflag Type of operations allowed
+ * @param pmode Permission mode
+ * @return File descriptor for the opened file; -1 indicates an error.
+ */
+int ff_open_file(const char *filename, int oflag, int pmode);
+
 #if CONFIG_NETWORK
 #if !HAVE_SOCKLEN_T
 typedef int socklen_t;
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to