diff -r 000000000000 -r 1918ee327afb src/3rdparty/phonon/qt7/quicktimemetadata.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/3rdparty/phonon/qt7/quicktimemetadata.mm Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,200 @@ +/* This file is part of the KDE project. + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 2.1 or 3 of the License. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this library. If not, see . +*/ + +#include +#include "quicktimemetadata.h" +#include "quicktimevideoplayer.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace QT7 +{ + +QuickTimeMetaData::QuickTimeMetaData(QuickTimeVideoPlayer *videoPlayer) +{ + m_videoPlayer = videoPlayer; + m_movieChanged = false; +} + +void QuickTimeMetaData::update() +{ + m_movieChanged = true; + m_metaData.clear(); +} + +#ifdef QUICKTIME_C_API_AVAILABLE + +QString QuickTimeMetaData::stripCopyRightSymbol(const QString &key) +{ + return key.right(key.length()-1); +} + +QString QuickTimeMetaData::convertQuickTimeKeyToUserKey(const QString &key) +{ + if (key == QLatin1String("com.apple.quicktime.displayname")) + return QLatin1String("nam"); + else if (key == QLatin1String("com.apple.quicktime.album")) + return QLatin1String("alb"); + else if (key == QLatin1String("com.apple.quicktime.artist")) + return QLatin1String("ART"); + else + return QLatin1String("???"); +} + +OSStatus QuickTimeMetaData::readMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, QTPropertyClass propClass, + QTPropertyID id, QTPropertyValuePtr *value, ByteCount *size) +{ + QTPropertyValueType type; + ByteCount propSize; + UInt32 propFlags; + OSStatus err = QTMetaDataGetItemPropertyInfo(metaDataRef, item, propClass, id, &type, &propSize, &propFlags); + BACKEND_ASSERT3(err == noErr, "Could not read meta data value size", NORMAL_ERROR, err) + + *value = malloc(propSize); + + err = QTMetaDataGetItemProperty(metaDataRef, item, propClass, id, propSize, *value, size); + BACKEND_ASSERT3(err == noErr, "Could not read meta data value", NORMAL_ERROR, err) + + if (type == 'code' || type == 'itsk' || type == 'itlk') { + // convert from native endian to big endian + OSTypePtr pType = (OSTypePtr)*value; + *pType = EndianU32_NtoB(*pType); + } + + return err; +} + +UInt32 QuickTimeMetaData::getMetaType(QTMetaDataRef metaDataRef, QTMetaDataItem item) +{ + QTPropertyValuePtr value = 0; + ByteCount ignore = 0; + OSStatus err = readMetaValue( + metaDataRef, item, kPropertyClass_MetaDataItem, kQTMetaDataItemPropertyID_DataType, &value, &ignore); + BACKEND_ASSERT3(err == noErr, "Could not read meta data type", NORMAL_ERROR, 0) + UInt32 type = *((UInt32 *) value); + if (value) + free(value); + return type; +} + +QString QuickTimeMetaData::getMetaValue(QTMetaDataRef metaDataRef, QTMetaDataItem item, SInt32 id) +{ + QTPropertyValuePtr value = 0; + ByteCount size = 0; + OSStatus err = readMetaValue(metaDataRef, item, kPropertyClass_MetaDataItem, id, &value, &size); + BACKEND_ASSERT3(err == noErr, "Could not read meta data item", NORMAL_ERROR, QString()) + BACKEND_ASSERT3(value != 0, "Could not read meta data item", NORMAL_ERROR, QString()) + + QString string; + UInt32 dataType = getMetaType(metaDataRef, item); + switch (dataType){ + case kQTMetaDataTypeUTF8: + case kQTMetaDataTypeMacEncodedText: + string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF8, false)); + break; + case kQTMetaDataTypeUTF16BE: + string = PhononCFString::toQString(CFStringCreateWithBytes(0, (UInt8*)value, size, kCFStringEncodingUTF16BE, false)); + break; + default: + break; + } + + if (value) + free(value); + return string; +} + +void QuickTimeMetaData::readFormattedData(QTMetaDataRef metaDataRef, OSType format, QMultiMap &result) +{ + QTMetaDataItem item = kQTMetaDataItemUninitialized; + OSStatus err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item); + while (err == noErr){ + QString key = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Key); + if (format == kQTMetaDataStorageFormatQuickTime) + key = convertQuickTimeKeyToUserKey(key); + else + key = stripCopyRightSymbol(key); + + if (!result.contains(key)){ + QString val = getMetaValue(metaDataRef, item, kQTMetaDataItemPropertyID_Value); + result.insert(key, val); + } + err = QTMetaDataGetNextItem(metaDataRef, format, item, kQTMetaDataKeyFormatWildcard, 0, 0, &item); + } +} + +#endif // QUICKTIME_C_API_AVAILABLE + +void QuickTimeMetaData::guessMetaDataForCD() +{ + QString album = QFileInfo(m_videoPlayer->movieCompactDiscPath()).fileName(); + QString title = QFileInfo(m_videoPlayer->currentTrackPath()).fileName(); + title = title.left(title.lastIndexOf('.')); + m_metaData.insert(QLatin1String("ALBUM"), album); + m_metaData.insert(QLatin1String("TITLE"), title); + m_metaData.insert(QLatin1String("TRACKNUMBER"), QString::number(m_videoPlayer->currentTrack())); +} + +void QuickTimeMetaData::readMetaDataFromMovie() +{ + QMultiMap metaMap; + +#ifdef QUICKTIME_C_API_AVAILABLE + QTMetaDataRef metaDataRef; + OSStatus err = QTCopyMovieMetaData([m_videoPlayer->qtMovie() quickTimeMovie], &metaDataRef); + BACKEND_ASSERT2(err == noErr, "Could not read QuickTime meta data", NORMAL_ERROR) + + readFormattedData(metaDataRef, kQTMetaDataStorageFormatUserData, metaMap); + readFormattedData(metaDataRef, kQTMetaDataStorageFormatQuickTime, metaMap); + readFormattedData(metaDataRef, kQTMetaDataStorageFormatiTunes, metaMap); +#else + NSString *name = [m_videoPlayer->qtMovie() attributeForKey:@"QTMovieDisplayNameAttribute"]; + metaMap.insert(QLatin1String("nam"), QString::fromUtf8([name UTF8String])); +#endif // QUICKTIME_C_API_AVAILABLE + + m_metaData.insert(QLatin1String("ARTIST"), metaMap.value(QLatin1String("ART"))); + m_metaData.insert(QLatin1String("ALBUM"), metaMap.value(QLatin1String("alb"))); + m_metaData.insert(QLatin1String("TITLE"), metaMap.value(QLatin1String("nam"))); + m_metaData.insert(QLatin1String("DATE"), metaMap.value(QLatin1String("day"))); + m_metaData.insert(QLatin1String("GENRE"), metaMap.value(QLatin1String("gnre"))); + m_metaData.insert(QLatin1String("TRACKNUMBER"), metaMap.value(QLatin1String("trk"))); + m_metaData.insert(QLatin1String("DESCRIPTION"), metaMap.value(QLatin1String("des"))); +} + +void QuickTimeMetaData::readMetaData() +{ + if (!m_videoPlayer) + return; + + if (m_videoPlayer->mediaSource().type() == Phonon::MediaSource::Disc) + guessMetaDataForCD(); + else + readMetaDataFromMovie(); +} + +QMultiMap QuickTimeMetaData::metaData() +{ + if (m_videoPlayer && m_videoPlayer->hasMovie() && m_movieChanged) + readMetaData(); + return m_metaData; +} + +}} + +QT_END_NAMESPACE