From 2d54a14ac130812965d89237c8ede479cc2e2df6 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 20 Dec 2012 15:01:08 +0100 Subject: WMF: added more metadata keys (on Windows 7 and later). Change-Id: I01eebd0582d33eb3d581176bba2a84fa75db2463 Reviewed-by: Jason Barron Reviewed-by: Yoann Lopes --- src/plugins/wmf/player/mfmetadatacontrol.cpp | 221 ++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 5 deletions(-) diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp index 18c6a4204..142b8650b 100644 --- a/src/plugins/wmf/player/mfmetadatacontrol.cpp +++ b/src/plugins/wmf/player/mfmetadatacontrol.cpp @@ -39,12 +39,95 @@ ** ****************************************************************************/ +#include +#include + #include "mfmetadatacontrol.h" #include "mfplayerservice.h" #include "Propkey.h" //#define DEBUG_MEDIAFOUNDATION +static QString nameForGUID(GUID guid) +{ + // Audio formats + if (guid == MFAudioFormat_AAC) + return QStringLiteral("MPEG AAC Audio"); + else if (guid == MFAudioFormat_ADTS) + return QStringLiteral("MPEG ADTS AAC Audio"); + else if (guid == MFAudioFormat_Dolby_AC3_SPDIF) + return QStringLiteral("Dolby AC-3 SPDIF"); + else if (guid == MFAudioFormat_DRM) + return QStringLiteral("DRM"); + else if (guid == MFAudioFormat_DTS) + return QStringLiteral("Digital Theater Systems Audio (DTS)"); + else if (guid == MFAudioFormat_Float) + return QStringLiteral("IEEE Float Audio"); + else if (guid == MFAudioFormat_MP3) + return QStringLiteral("MPEG Audio Layer-3 (MP3)"); + else if (guid == MFAudioFormat_MPEG) + return QStringLiteral("MPEG-1 Audio"); + else if (guid == MFAudioFormat_MSP1) + return QStringLiteral("Windows Media Audio Voice"); + else if (guid == MFAudioFormat_PCM) + return QStringLiteral("Uncompressed PCM Audio"); + else if (guid == MFAudioFormat_WMASPDIF) + return QStringLiteral("Windows Media Audio 9 SPDIF"); + else if (guid == MFAudioFormat_WMAudioV8) + return QStringLiteral("Windows Media Audio 8 (WMA2)"); + else if (guid == MFAudioFormat_WMAudioV9) + return QStringLiteral("Windows Media Audio 9 (WMA3"); + else if (guid == MFAudioFormat_WMAudio_Lossless) + return QStringLiteral("Windows Media Audio 9 Lossless"); + + // Video formats + if (guid == MFVideoFormat_DV25) + return QStringLiteral("DVCPRO 25 (DV25)"); + else if (guid == MFVideoFormat_DV50) + return QStringLiteral("DVCPRO 50 (DV50)"); + else if (guid == MFVideoFormat_DVC) + return QStringLiteral("DVC/DV Video"); + else if (guid == MFVideoFormat_DVH1) + return QStringLiteral("DVCPRO 100 (DVH1)"); + else if (guid == MFVideoFormat_DVHD) + return QStringLiteral("HD-DVCR (DVHD)"); + else if (guid == MFVideoFormat_DVSD) + return QStringLiteral("SDL-DVCR (DVSD)"); + else if (guid == MFVideoFormat_DVSL) + return QStringLiteral("SD-DVCR (DVSL)"); + else if (guid == MFVideoFormat_H264) + return QStringLiteral("H.264 Video"); + else if (guid == MFVideoFormat_M4S2) + return QStringLiteral("MPEG-4 part 2 Video (M4S2)"); + else if (guid == MFVideoFormat_MJPG) + return QStringLiteral("Motion JPEG (MJPG)"); + else if (guid == MFVideoFormat_MP43) + return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)"); + else if (guid == MFVideoFormat_MP4S) + return QStringLiteral("ISO MPEG 4 version 1 (MP4S)"); + else if (guid == MFVideoFormat_MP4V) + return QStringLiteral("MPEG-4 part 2 Video (MP4V)"); + else if (guid == MFVideoFormat_MPEG2) + return QStringLiteral("MPEG-2 Video"); + else if (guid == MFVideoFormat_MPG1) + return QStringLiteral("MPEG-1 Video"); + else if (guid == MFVideoFormat_MSS1) + return QStringLiteral("Windows Media Screen 1 (MSS1)"); + else if (guid == MFVideoFormat_MSS2) + return QStringLiteral("Windows Media Video 9 Screen (MSS2)"); + else if (guid == MFVideoFormat_WMV1) + return QStringLiteral("Windows Media Video 7 (WMV1)"); + else if (guid == MFVideoFormat_WMV2) + return QStringLiteral("Windows Media Video 8 (WMV2)"); + else if (guid == MFVideoFormat_WMV3) + return QStringLiteral("Windows Media Video 9 (WMV3)"); + else if (guid == MFVideoFormat_WVC1) + return QStringLiteral("Windows Media Video VC1 (WVC1)"); + + else + return QStringLiteral("Unknown codec"); +} + MFMetaDataControl::MFMetaDataControl(QObject *parent) : QMetaDataReaderControl(parent) , m_metaData(0) @@ -83,9 +166,46 @@ QVariant MFMetaDataControl::metaData(const QString &key) const else if (m_metaData) hr = m_metaData->GetProperty(reinterpret_cast(m_commonNames[index].utf16()), &var); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr)) { value = convertValue(var); + // some metadata needs to be reformatted + if (value.isValid() && m_content) { + if (key == QMediaMetaData::MediaType) { + QString v = value.toString(); + if (v == QLatin1String("{D1607DBC-E323-4BE2-86A1-48A42A28441E}")) + value = QStringLiteral("Music"); + else if (v == QLatin1String("{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}")) + value = QStringLiteral("Video"); + else if (v == QLatin1String("{01CD0F29-DA4E-4157-897B-6275D50C4F11}")) + value = QStringLiteral("Audio"); + else if (v == QLatin1String("{FCF24A76-9A57-4036-990D-E35DD8B244E1}")) + value = QStringLiteral("Other"); + } else if (key == QMediaMetaData::Duration) { + // duration is provided in 100-nanosecond units, convert to milliseconds + value = (value.toLongLong() + 10000) / 10000; + } else if (key == QMediaMetaData::AudioCodec || key == QMediaMetaData::VideoCodec) { + GUID guid; + if (SUCCEEDED(CLSIDFromString((const WCHAR*)value.toString().utf16(), &guid))) + value = nameForGUID(guid); + } else if (key == QMediaMetaData::Resolution) { + QSize res; + res.setHeight(value.toUInt()); + if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_FrameWidth, &var))) + res.setWidth(convertValue(var).toUInt()); + value = res; + } else if (key == QMediaMetaData::PixelAspectRatio) { + QSize aspectRatio; + aspectRatio.setWidth(value.toUInt()); + if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_VerticalAspectRatio, &var))) + aspectRatio.setHeight(convertValue(var).toUInt()); + value = aspectRatio; + } else if (key == QMediaMetaData::VideoFrameRate) { + value = value.toReal() / 1000.f; + } + } + } + PropVariantClear(&var); return value; } @@ -93,9 +213,6 @@ QVariant MFMetaDataControl::metaData(const QString &key) const QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const { QVariant value; - //form MSDN: http://msdn.microsoft.com/en-us/library/ff384862%28v=VS.85%29.aspx - //it seems that those 4 types are enough for media foundation metadata - //add more later if necessary switch (var.vt) { case VT_LPWSTR: value = QString::fromUtf16(reinterpret_cast(var.pwszVal)); @@ -109,6 +226,33 @@ QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const case VT_BOOL: value = bool(var.boolVal); break; + case VT_FILETIME: + SYSTEMTIME sysDate; + if (!FileTimeToSystemTime(&var.filetime, &sysDate)) + break; + value = QDate(sysDate.wYear, sysDate.wMonth, sysDate.wDay); + break; + case VT_STREAM: + { + STATSTG stat; + if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME))) + break; + void *data = malloc(stat.cbSize.QuadPart); + ULONG read = 0; + if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) { + free(data); + break; + } + value = QImage::fromData((const uchar*)data, read); + free(data); + } + break; + case VT_VECTOR | VT_LPWSTR: + QStringList vList; + for (ULONG i = 0; i < var.calpwstr.cElems; ++i) + vList.append(QString::fromUtf16(reinterpret_cast(var.calpwstr.pElems[i]))); + value = vList; + break; } return value; } @@ -147,13 +291,80 @@ void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMed m_availableMetaDatas.push_back(QMediaMetaData::Author); } else if (key == PKEY_Title) { m_availableMetaDatas.push_back(QMediaMetaData::Title); + } else if (key == PKEY_Media_SubTitle) { + m_availableMetaDatas.push_back(QMediaMetaData::SubTitle); } else if (key == PKEY_ParentalRating) { m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating); } else if (key == PKEY_Comment) { m_availableMetaDatas.push_back(QMediaMetaData::Description); } else if (key == PKEY_Copyright) { m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - //TODO: add more common keys + } else if (key == PKEY_Comment) { + m_availableMetaDatas.push_back(QMediaMetaData::Comment); + } else if (key == PKEY_Media_ProviderStyle) { + m_availableMetaDatas.push_back(QMediaMetaData::Genre); + } else if (key == PKEY_Media_Year) { + m_availableMetaDatas.push_back(QMediaMetaData::Year); + } else if (key == PKEY_Media_DateEncoded) { + m_availableMetaDatas.push_back(QMediaMetaData::Date); + } else if (key == PKEY_Rating) { + m_availableMetaDatas.push_back(QMediaMetaData::UserRating); + } else if (key == PKEY_Keywords) { + m_availableMetaDatas.push_back(QMediaMetaData::Keywords); + } else if (key == PKEY_Language) { + m_availableMetaDatas.push_back(QMediaMetaData::Language); + } else if (key == PKEY_Media_Publisher) { + m_availableMetaDatas.push_back(QMediaMetaData::Publisher); + } else if (key == PKEY_Media_ClassPrimaryID) { + m_availableMetaDatas.push_back(QMediaMetaData::MediaType); + } else if (key == PKEY_Media_Duration) { + m_availableMetaDatas.push_back(QMediaMetaData::Duration); + } else if (key == PKEY_Audio_EncodingBitrate) { + m_availableMetaDatas.push_back(QMediaMetaData::AudioBitRate); + } else if (key == PKEY_Audio_Format) { + m_availableMetaDatas.push_back(QMediaMetaData::AudioCodec); + } else if (key == PKEY_Media_AverageLevel) { + m_availableMetaDatas.push_back(QMediaMetaData::AverageLevel); + } else if (key == PKEY_Audio_ChannelCount) { + m_availableMetaDatas.push_back(QMediaMetaData::ChannelCount); + } else if (key == PKEY_Audio_PeakValue) { + m_availableMetaDatas.push_back(QMediaMetaData::PeakValue); + } else if (key == PKEY_Audio_SampleRate) { + m_availableMetaDatas.push_back(QMediaMetaData::SampleRate); + } else if (key == PKEY_Music_AlbumTitle) { + m_availableMetaDatas.push_back(QMediaMetaData::AlbumTitle); + } else if (key == PKEY_Music_AlbumArtist) { + m_availableMetaDatas.push_back(QMediaMetaData::AlbumArtist); + } else if (key == PKEY_Music_Artist) { + m_availableMetaDatas.push_back(QMediaMetaData::ContributingArtist); + } else if (key == PKEY_Music_Composer) { + m_availableMetaDatas.push_back(QMediaMetaData::Composer); + } else if (key == PKEY_Music_Conductor) { + m_availableMetaDatas.push_back(QMediaMetaData::Conductor); + } else if (key == PKEY_Music_Lyrics) { + m_availableMetaDatas.push_back(QMediaMetaData::Lyrics); + } else if (key == PKEY_Music_Mood) { + m_availableMetaDatas.push_back(QMediaMetaData::Mood); + } else if (key == PKEY_Music_TrackNumber) { + m_availableMetaDatas.push_back(QMediaMetaData::TrackNumber); + } else if (key == PKEY_Music_Genre) { + m_availableMetaDatas.push_back(QMediaMetaData::Genre); + } else if (key == PKEY_ThumbnailStream) { + m_availableMetaDatas.push_back(QMediaMetaData::ThumbnailImage); + } else if (key == PKEY_Video_FrameHeight) { + m_availableMetaDatas.push_back(QMediaMetaData::Resolution); + } else if (key == PKEY_Video_HorizontalAspectRatio) { + m_availableMetaDatas.push_back(QMediaMetaData::PixelAspectRatio); + } else if (key == PKEY_Video_FrameRate) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoFrameRate); + } else if (key == PKEY_Video_EncodingBitrate) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoBitRate); + } else if (key == PKEY_Video_Compression) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoCodec); + } else if (key == PKEY_Video_Director) { + m_availableMetaDatas.push_back(QMediaMetaData::Director); + } else if (key == PKEY_Media_Writer) { + m_availableMetaDatas.push_back(QMediaMetaData::Writer); } else { common = false; //TODO: add more extended keys -- cgit v1.2.3