[FFmpeg-devel] [PATCH] avutil/log: in colored_fputs, convert string from utf8 to CP_ACP charset on Windows
周泽华
zhouzehua at gmail.com
Thu Feb 20 06:20:59 CET 2014
Thanks for your reply.
Let me first show my situation. I have a mp3 file, in which the metadata is in
CP936 charset (CP_ACP is system dependent and is CP936 on my Windows). I issue
'ffprobe path_to_file' to see the information of the file. In the
'prepare_app_arguments' function of cmdutils.c , the arguments of ffprobe are
converted to utf8, so 'path_to_file' is stored in utf8 in ffmpeg, while the
metadata is stored in CP936. Both 'path_to_file' and metadata are sent to log
via 'colored_fputs'. So we can only detect the charset of input string at
runtime, not build time. I searched the internet and did not find any better
way to detect the charset.
I think the commit is an improvement. Before the commit, 'path_to_file' is
always garbled. If the metadata of a mp3 file is in utf8 charset, the log
output is also garbled. After the commit, the log output is garbled when
string in CP_ACP is converted 'from utf8 to CP_ACP successfully', which
is wrong and happens rarely as I observe.
About the unneeded code: I thought setting pointers to original value or null
is good. Anyway, a patch without these unneeded code is attached.
2014-02-20 10:41 GMT+08:00 Michael Niedermayer <michaelni at gmx.at>:
> On Wed, Feb 19, 2014 at 04:09:48PM +0800, ZHOU Zehua wrote:
>> 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
>
> however exactly this is supposed to be detected, it should probably be
> done in configure and set some appropriate define like maybe
> HAVE_CP_ACP or something
> maybe theres also a cleaner way to detect this i dont know
>
>
>
>> +
>> #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;
>
> these look unneeded
>
>
>> + av_freep(&str_acp);
>> + }
>> +#endif
>
>
>
>
>> }
>>
>> const char *av_default_item_name(void *ptr)
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Breaking DRM is a little like attempting to break through a door even
> though the window is wide open and the only thing in the house is a bunch
> of things you dont want and which you would get tomorrow for free anyway
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-avutil-log-in-colored_fputs-convert-string-from-utf8.patch
Type: application/octet-stream
Size: 2718 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140220/da8056ad/attachment.obj>
More information about the ffmpeg-devel
mailing list