[FFmpeg-devel] [PATCH] avutil/log: in colored_fputs, convert string from utf8 to CP_ACP charset on Windows

ZHOU Zehua zhouzehuasx at gmail.com
Wed Feb 19 09:09:48 CET 2014


From: ZHOU Zehua <zhouzehua at gmail.com>

The strings in ffmpeg are mostly in utf8 charset, but the default
charset of Windows Console is not utf8. As a result, the log output is
garbled. This commit adds code to convert string from utf8 to CP_ACP
before printed on Windows.

Note: If the input string is not in utf8, the conversion is supposed to
fail and the original input string will be printed.
---
 libavutil/log.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/libavutil/log.c b/libavutil/log.c
index 38ce1e8..0389a1e 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -50,6 +50,10 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static int av_log_level = AV_LOG_INFO;
 static int flags;
 
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+#include<windows.h>
+#endif
+
 #if HAVE_SETCONSOLETEXTATTRIBUTE
 #include <windows.h>
 static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
@@ -103,9 +107,35 @@ static int use_color = -1;
 
 static void colored_fputs(int level, const char *str)
 {
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+    int num_wchars, num_chars;
+    wchar_t *wstr = NULL;
+    const char *str_orig = NULL;
+    char *str_acp = NULL; /* str in CP_ACP charset */
+#endif
+
     if (!*str)
         return;
 
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+    /* convert UTF-8 to wide chars, and then convert wide chars to CP_ACP */
+    num_wchars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, NULL, 0);
+    if (num_wchars > 0) {
+        wstr = av_mallocz(sizeof(wchar_t) * num_wchars);
+        if (wstr) {
+            MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, num_wchars);
+            num_chars = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL ,NULL);
+            str_acp = av_mallocz(sizeof(char) * num_chars);
+            if (str_acp) {
+                WideCharToMultiByte(CP_ACP, 0, wstr, -1, str_acp, num_chars, NULL, NULL);
+                str_orig = str;
+                str = str_acp;
+            }
+            av_freep(&wstr);
+        }
+    }
+#endif
+
     if (use_color < 0) {
 #if HAVE_SETCONSOLETEXTATTRIBUTE
         CONSOLE_SCREEN_BUFFER_INFO con_info;
@@ -152,6 +182,13 @@ static void colored_fputs(int level, const char *str)
         fputs(str, stderr);
 #endif
 
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+    if (str_acp) {
+        str = str_orig;
+        str_orig = NULL;
+        av_freep(&str_acp);
+    }
+#endif
 }
 
 const char *av_default_item_name(void *ptr)
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list