Tuukka:

So far, all I've noticed wrong is the Unicode handling for metadata (artist, 
title, etc.)
The enclosed patch fixes that.

I also noticed that you're apparently having problems with Unicode paths under 
MS Windows.  After digging around for a while, it appears that this is a known 
bug, though ff_win32_open() in libavformat/os_support.c (at least in my version 
of ffmpeg, i.e. 1.0.5) seems to be doing the right thing for UTF-8.  So it's 
still a mystery.  But maybe this will help you track down the problem.

Steven Boswell
--- mixxx-cleaned/src/soundsourceffmpeg.cpp	2013-05-12 11:34:19.268383000 -0700
+++ mixxx/src/soundsourceffmpeg.cpp	2013-05-12 14:59:54.378017031 -0700
@@ -29,6 +29,7 @@
 //#endif
 
 #include <QDebug>
+#include <QTextCodec>
 
 static QMutex ffmpegmutex;
 static bool ffmpeginit = false;
@@ -161,6 +162,8 @@
      * The method toLocal8Bit() returns the local 8-bit representation of the string as a QByteArray.
      * The returned byte array is undefined if the string contains characters not supported
      * by the local 8-bit encoding.
+	 *
+	 * See https://ffmpeg.org/trac/ffmpeg/ticket/819 for relevant bug report.
      */
     QByteArray qBAFilename = m_qFilename.toLocal8Bit();
 #else
@@ -691,6 +694,8 @@
      * The method toLocal8Bit() returns the local 8-bit representation of the string as a QByteArray.
      * The returned byte array is undefined if the string contains characters not supported
      * by the local 8-bit encoding.
+	 *
+	 * See https://ffmpeg.org/trac/ffmpeg/ticket/819 for relevant bug report.
      */
     QByteArray qBAFilename = m_qFilename.toLocal8Bit();
 #else
@@ -729,23 +734,32 @@
 
     //qDebug() << "ffmpeg: Parse HEADER [MP3,WMA]";
 
+	// Prepare to decode UTF-8.
+	QTextCodec* pUtf8Decoder = QTextCodec::codecForName("UTF-8");
+
     while ((FmtTag = av_dict_get(FmtCtx->metadata, "", FmtTag, AV_DICT_IGNORE_SUFFIX))) {
+		// Convert the value.
+		QString strValue;
+		if (pUtf8Decoder != NULL)
+			strValue = pUtf8Decoder->toUnicode (FmtTag->value);
+		else
+			strValue = FmtTag->value;
 
         if( !strncmp( FmtTag->key, "artist", 7) ) {
-            //qDebug() << "ffmpeg: HEADER [MP3,WMA] artist: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setArtist(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [MP3,WMA] artist: " << FmtTag->key << " = "<< strValue;
+            this->setArtist(strValue);
         } else if( !strncmp( FmtTag->key, "album", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [MP3,WMA] album: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setAlbum(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [MP3,WMA] album: " << FmtTag->key << " = "<< strValue;
+            this->setAlbum(strValue);
         } else if( !strncmp( FmtTag->key, "date", 4) ) {
-            //qDebug() << "ffmpeg: HEADER [MP3,WMA] date: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setYear(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [MP3,WMA] date: " << FmtTag->key << " = "<< strValue;
+            this->setYear(strValue);
         } else if( !strncmp( FmtTag->key, "genre", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [MP3,WMA] genre: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setGenre(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [MP3,WMA] genre: " << FmtTag->key << " = "<< strValue;
+            this->setGenre(strValue);
         } else if( !strncmp( FmtTag->key, "title", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [MP3,WMA] genre: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setTitle(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [MP3,WMA] genre: " << FmtTag->key << " = "<< strValue;
+            this->setTitle(strValue);
         }
 
 
@@ -754,30 +768,37 @@
     //qDebug() << "ffmpeg: Parse HEADER [OGG, FLAC]";
 
     while ((FmtTag = av_dict_get(FmtCtx->streams[m_iAudioStream]->metadata, "", FmtTag, AV_DICT_IGNORE_SUFFIX))) {
+		// Convert the value.
+		QString strValue;
+		if (pUtf8Decoder != NULL)
+			strValue = pUtf8Decoder->toUnicode (FmtTag->value);
+		else
+			strValue = FmtTag->value;
+
         if( !strncmp( FmtTag->key, "ARTIST", 7) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] artist: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setArtist(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] artist: " << FmtTag->key << " = "<< strValue;
+            this->setArtist(strValue);
         } else if( !strncmp( FmtTag->key, "ALBUM", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] album: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setAlbum(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] album: " << FmtTag->key << " = "<< strValue;
+            this->setAlbum(strValue);
         } else if( !strncmp( FmtTag->key, "YEAR", 4) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] year: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setYear(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] year: " << FmtTag->key << " = "<< strValue;
+            this->setYear(strValue);
         } else if( !strncmp( FmtTag->key, "GENRE", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] genre: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setGenre(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] genre: " << FmtTag->key << " = "<< strValue;
+            this->setGenre(strValue);
         } else if( !strncmp( FmtTag->key, "TITLE", 5) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] title: " << FmtTag->key << " = "<< FmtTag->value;
-            this->setTitle(FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] title: " << FmtTag->key << " = "<< strValue;
+            this->setTitle(strValue);
         } else if( !strncmp( FmtTag->key, "REPLAYGAIN_TRACK_PEAK", 20) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_TRACK_PEAK: " << FmtTag->key << " = "<< FmtTag->value;
+            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_TRACK_PEAK: " << FmtTag->key << " = "<< strValue;
         } else if( !strncmp( FmtTag->key, "REPLAYGAIN_TRACK_GAIN", 20) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_TRACK_GAIN: " << FmtTag->key << " = "<< FmtTag->value;
-            this->parseReplayGainString (FmtTag->value);
+            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_TRACK_GAIN: " << FmtTag->key << " = "<< strValue;
+            this->parseReplayGainString (strValue);
         } else if( !strncmp( FmtTag->key, "REPLAYGAIN_ALBUM_PEAK", 20) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_ALBUM_PEAK: " << FmtTag->key << " = "<< FmtTag->value;
+            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_ALBUM_PEAK: " << FmtTag->key << " = "<< strValue;
         } else if( !strncmp( FmtTag->key, "REPLAYGAIN_ALBUM_GAIN", 20) ) {
-            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_ALBUM_GAIN: " << FmtTag->key << " = "<< FmtTag->value;
+            //qDebug() << "ffmpeg: HEADER [OGG] REPLAYGAIN_ALBUM_GAIN: " << FmtTag->key << " = "<< strValue;
         }
 
 
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and 
their applications. This 200-page book is written by three acclaimed 
leaders in the field. The early access version is available now. 
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
_______________________________________________
Get Mixxx, the #1 Free MP3 DJ Mixing software Today
http://mixxx.org


Mixxx-devel mailing list
Mixxx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mixxx-devel

Reply via email to