mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
Handle unicode file names on windows
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ö <martin@martin.st>
This commit is contained in:
parent
9261e6cf3f
commit
b1ac139d89
63
cmdutils.c
63
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) {
|
||||
|
@ -28,6 +28,34 @@
|
||||
#include "avformat.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
#include <windows.h>
|
||||
|
||||
#undef open
|
||||
int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
|
||||
{
|
||||
int fd;
|
||||
int num_chars;
|
||||
wchar_t *filename_w;
|
||||
|
||||
/* convert UTF-8 to wide chars */
|
||||
num_chars = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0);
|
||||
if (num_chars <= 0)
|
||||
return -1;
|
||||
filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
|
||||
MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
|
||||
|
||||
fd = _wopen(filename_w, oflag, pmode);
|
||||
av_freep(&filename_w);
|
||||
|
||||
/* filename maybe be in CP_ACP */
|
||||
if (fd == -1 && !(oflag & O_CREAT))
|
||||
return open(filename_utf8, oflag, pmode);
|
||||
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_NETWORK
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
@ -45,6 +45,11 @@ static inline int is_dos_path(const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32CE__)
|
||||
int ff_win32_open(const char *filename, int oflag, int pmode);
|
||||
#define open ff_win32_open
|
||||
#endif
|
||||
|
||||
#if CONFIG_NETWORK
|
||||
#if !HAVE_SOCKLEN_T
|
||||
typedef int socklen_t;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 53
|
||||
#define LIBAVFORMAT_VERSION_MINOR 0
|
||||
#define LIBAVFORMAT_VERSION_MICRO 2
|
||||
#define LIBAVFORMAT_VERSION_MICRO 3
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user