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