src/3rdparty/phonon/qt7/quicktimemetadata.mm
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /*  This file is part of the KDE project.
       
     2 
       
     3     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 
       
     5     This library is free software: you can redistribute it and/or modify
       
     6     it under the terms of the GNU Lesser General Public License as published by
       
     7     the Free Software Foundation, either version 2.1 or 3 of the License.
       
     8 
       
     9     This library is distributed in the hope that it will be useful,
       
    10     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12     GNU Lesser General Public License for more details.
       
    13 
       
    14     You should have received a copy of the GNU Lesser General Public License
       
    15     along with this library.  If not, see <http://www.gnu.org/licenses/>.
       
    16 */
       
    17 
       
    18 #include <QtCore/QFileInfo>
       
    19 #include "quicktimemetadata.h"
       
    20 #include "quicktimevideoplayer.h"
       
    21 
       
    22 QT_BEGIN_NAMESPACE
       
    23 
       
    24 namespace Phonon
       
    25 {
       
    26 namespace QT7
       
    27 {
       
    28 
       
    29 QuickTimeMetaData::QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer)
       
    30 {
       
    31     m_videoPlayer = videoPlayer;
       
    32     m_movieChanged = false;
       
    33 }
       
    34 
       
    35 void QuickTimeMetaData::update()
       
    36 {
       
    37     m_movieChanged = true;
       
    38     m_metaData.clear();
       
    39 }
       
    40 
       
    41 #ifdef QUICKTIME_C_API_AVAILABLE
       
    42 
       
    43 QString QuickTimeMetaData::stripCopyRightSymbol(const QString &key)
       
    44 {
       
    45     return key.right(key.length()-1);
       
    46 }
       
    47 
       
    48 QString QuickTimeMetaData::convertQuickTimeKeyToUserKey(const QString &key)
       
    49 {
       
    50     if (key == QLatin1String("com.apple.quicktime.displayname"))
       
    51         return QLatin1String("nam");
       
    52     else if (key == QLatin1String("com.apple.quicktime.album"))
       
    53         return QLatin1String("alb");
       
    54     else if (key == QLatin1String("com.apple.quicktime.artist"))
       
    55         return QLatin1String("ART");
       
    56     else
       
    57         return QLatin1String("???");
       
    58 }
       
    59 
       
    60 OSStatus QuickTimeMetaData::readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass,
       
    61     QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size)
       
    62 {
       
    63 	QTPropertyValueType type;
       
    64 	ByteCount propSize;
       
    65 	UInt32 propFlags;
       
    66 	OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags);
       
    67     BACKEND_ASSERT3(err == noErr, "Could not read meta data value size", NORMAL_ERROR, err)
       
    68 
       
    69     *value = malloc(propSize);
       
    70 
       
    71 	err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size);
       
    72     BACKEND_ASSERT3(err == noErr, "Could not read meta data value", NORMAL_ERROR, err)
       
    73 
       
    74     if (type == 'code' || type == 'itsk' || type == 'itlk') {
       
    75         // convert from native endian to big endian
       
    76     	OSTypePtr pType = (OSTypePtr)*value;
       
    77     	*pType = EndianU32_NtoB(*pType);
       
    78     }
       
    79 
       
    80 	return err;
       
    81 }
       
    82 
       
    83 UInt32 QuickTimeMetaData::getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item)
       
    84 {
       
    85 	QTPropertyValuePtr value = 0;
       
    86 	ByteCount ignore = 0;
       
    87 	OSStatus err = readMetaValue(
       
    88 	    metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore);
       
    89     BACKEND_ASSERT3(err == noErr, "Could not read meta data type", NORMAL_ERROR, 0)
       
    90     UInt32 type = *((UInt32 *) value);
       
    91     if (value)
       
    92 	    free(value);
       
    93 	return type;
       
    94 }
       
    95 
       
    96 QString QuickTimeMetaData::getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id)
       
    97 {
       
    98 	QTPropertyValuePtr value = 0;
       
    99 	ByteCount size = 0;
       
   100 	OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size);
       
   101     BACKEND_ASSERT3(err == noErr, "Could not read meta data item", NORMAL_ERROR, QString())
       
   102     BACKEND_ASSERT3(value != 0, "Could not read meta data item", NORMAL_ERROR, QString())
       
   103 
       
   104     QString string;
       
   105     UInt32 dataType = getMetaType(metaDataRef, item);
       
   106     switch (dataType){
       
   107     case kQTMetaDataTypeUTF8:
       
   108     case kQTMetaDataTypeMacEncodedText:
       
   109         string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false));
       
   110         break;
       
   111     case kQTMetaDataTypeUTF16BE:
       
   112         string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false));
       
   113         break;
       
   114     default:
       
   115         break;
       
   116     }
       
   117 
       
   118     if (value)
       
   119 	    free(value);
       
   120     return string;
       
   121 }
       
   122 
       
   123 void QuickTimeMetaData::readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap<QString, QString> &result)
       
   124 {
       
   125 	QTMetaDataItem item = kQTMetaDataItemUninitialized;
       
   126     OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
       
   127 	while (err == noErr){
       
   128         QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key);
       
   129         if (format == kQTMetaDataStorageFormatQuickTime)
       
   130             key = convertQuickTimeKeyToUserKey(key);
       
   131         else
       
   132             key = stripCopyRightSymbol(key);
       
   133 
       
   134 	    if (!result.contains(key)){
       
   135 	        QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value);
       
   136             result.insert(key, val);
       
   137         }
       
   138         err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item);
       
   139 	}
       
   140 }
       
   141 
       
   142 #endif // QUICKTIME_C_API_AVAILABLE
       
   143 
       
   144 void QuickTimeMetaData::guessMetaDataForCD()
       
   145 {
       
   146     QString album = QFileInfo(m_videoPlayer->movieCompactDiscPath()).fileName();
       
   147     QString title = QFileInfo(m_videoPlayer->currentTrackPath()).fileName();
       
   148     title = title.left(title.lastIndexOf('.'));
       
   149     m_metaData.insert(QLatin1String("ALBUM"), album);
       
   150     m_metaData.insert(QLatin1String("TITLE"), title);
       
   151     m_metaData.insert(QLatin1String("TRACKNUMBER"), QString::number(m_videoPlayer->currentTrack()));
       
   152 }
       
   153 
       
   154 void QuickTimeMetaData::readMetaDataFromMovie()
       
   155 {
       
   156     QMultiMap<QString, QString> metaMap;
       
   157 
       
   158 #ifdef QUICKTIME_C_API_AVAILABLE
       
   159     QTMetaDataRef metaDataRef;
       
   160 	OSStatus err = QTCopyMovieMetaData([m_videoPlayer->qtMovie() quickTimeMovie], &metaDataRef);
       
   161     BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR)
       
   162 
       
   163     readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap);
       
   164     readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap);
       
   165     readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap);
       
   166 #else
       
   167 	NSString *name = [m_videoPlayer->qtMovie() attributeForKey:@"QTMovieDisplayNameAttribute"];
       
   168 	metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String]));
       
   169 #endif // QUICKTIME_C_API_AVAILABLE
       
   170 
       
   171     m_metaData.insert(QLatin1String("ARTIST"), metaMap.value(QLatin1String("ART")));
       
   172     m_metaData.insert(QLatin1String("ALBUM"), metaMap.value(QLatin1String("alb")));
       
   173     m_metaData.insert(QLatin1String("TITLE"), metaMap.value(QLatin1String("nam")));
       
   174     m_metaData.insert(QLatin1String("DATE"), metaMap.value(QLatin1String("day")));
       
   175     m_metaData.insert(QLatin1String("GENRE"), metaMap.value(QLatin1String("gnre")));
       
   176     m_metaData.insert(QLatin1String("TRACKNUMBER"), metaMap.value(QLatin1String("trk")));
       
   177     m_metaData.insert(QLatin1String("DESCRIPTION"), metaMap.value(QLatin1String("des")));
       
   178 }
       
   179 
       
   180 void QuickTimeMetaData::readMetaData()
       
   181 {
       
   182 	if (!m_videoPlayer)
       
   183         return;
       
   184 
       
   185     if (m_videoPlayer->mediaSource().type() == Phonon::MediaSource::Disc)
       
   186         guessMetaDataForCD();
       
   187     else
       
   188         readMetaDataFromMovie();
       
   189 }
       
   190 
       
   191 QMultiMap<QString, QString> QuickTimeMetaData::metaData()
       
   192 {
       
   193     if (m_videoPlayer && m_videoPlayer->hasMovie() && m_movieChanged)
       
   194         readMetaData();
       
   195     return m_metaData;
       
   196 }
       
   197 
       
   198 }}
       
   199 
       
   200 QT_END_NAMESPACE