39 value = QString::fromUtf16(
reinterpret_cast<
const char16_t *>(var.pwszVal));
42 value =
int(var.lVal);
45 value = uint(var.ulVal);
48 value = qulonglong(var.uhVal.QuadPart);
51 value =
bool(var.boolVal);
55 if (!FileTimeToSystemTime(&var.filetime, &t))
58 value = QDateTime(QDate(t.wYear, t.wMonth, t.wDay),
59 QTime(t.wHour, t.wMinute, t.wSecond, t.wMilliseconds),
60 QTimeZone(QTimeZone::UTC));
65 if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME)))
67 void *data = malloc(stat.cbSize.QuadPart);
69 if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) {
73 value = QImage::fromData((
const uchar*)data, read);
77 case VT_VECTOR | VT_LPWSTR:
79 for (ULONG i = 0; i < var.calpwstr.cElems; ++i)
80 vList.append(QString::fromUtf16(
reinterpret_cast<
const char16_t *>(var.calpwstr.pElems[i])));
92 QtMultimediaPrivate::ScopedPropVariant pv;
93 if (FAILED(content->GetValue(key, pv.get())))
96 QVariant value = convertValue(pv.var);
101 if (key == PKEY_Media_ClassPrimaryID ) {
102 QString v = value.toString();
103 if (v == u"{D1607DBC-E323-4BE2-86A1-48A42A28441E}")
105 else if (v == u"{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}")
107 else if (v == u"{01CD0F29-DA4E-4157-897B-6275D50C4F11}")
109 else if (v == u"{FCF24A76-9A57-4036-990D-E35DD8B244E1}")
111 }
else if (key == PKEY_Media_Duration) {
113 value = (value.toLongLong() + 10000) / 10000;
114 }
else if (key == PKEY_Video_Compression) {
115 value =
int(QWMF::codecForVideoFormat(value.toUuid()));
116 }
else if (key == PKEY_Audio_Format) {
117 value =
int(QWMF::codecForAudioFormat(value.toUuid()));
118 }
else if (key == PKEY_Video_FrameHeight ) {
120 res.setHeight(value.toUInt());
121 if (SUCCEEDED(content->GetValue(PKEY_Video_FrameWidth, pv.get())))
122 res.setWidth(convertValue(pv.var).toUInt());
124 }
else if (key == PKEY_Video_Orientation) {
125 uint orientation = 0;
126 if (SUCCEEDED(content->GetValue(PKEY_Video_Orientation, pv.get())))
127 orientation = convertValue(pv.var).toUInt();
129 }
else if (key == PKEY_Video_FrameRate) {
130 value = value.toReal() / 1000.f;
136QMediaMetaData
MFMetaData::fromNative(IMFMediaSource* mediaSource)
138 QMediaMetaData metaData;
143 ComPtr<IPropertyStore> content;
144 if (SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&content))))
145 metaData = fromNative(content.Get());
150 ComPtr<IMFMetadataProvider> provider;
151 if (SUCCEEDED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&provider)))) {
152 ComPtr<IMFPresentationDescriptor> pd;
153 if (SUCCEEDED(mediaSource->CreatePresentationDescriptor(&pd))) {
154 ComPtr<IMFMetadata> metadata;
155 if (SUCCEEDED(provider->GetMFMetadata(pd.Get(), 0, 0, &metadata))) {
156 const QMediaMetaData mfData = fromNative(metadata.Get());
157 for (
const auto &[key, value] : mfData.asKeyValueRange()) {
158 if (!metaData.value(key).isValid())
159 metaData.insert(key, value);
173 QtMultimediaPrivate::ScopedPropVariant names;
174 if (FAILED(metadata->GetAllPropertyNames(names.get())))
177 QMediaMetaData metaData;
182 static const QVarLengthFlatMap<QStringView, QMediaMetaData::Key, 12> nameToKey({
183 { u"Title", QMediaMetaData::Title },
184 { u"Author", QMediaMetaData::ContributingArtist },
185 { u"WM/AlbumTitle", QMediaMetaData::AlbumTitle },
186 { u"WM/AlbumArtist", QMediaMetaData::AlbumArtist },
187 { u"WM/Composer", QMediaMetaData::Composer },
188 { u"WM/Genre", QMediaMetaData::Genre },
189 { u"WM/TrackNumber", QMediaMetaData::TrackNumber },
190 { u"Description", QMediaMetaData::Description },
191 { u"Copyright", QMediaMetaData::Copyright },
192 { u"WM/Publisher", QMediaMetaData::Publisher },
193 { u"WM/Language", QMediaMetaData::Language },
194 { u"WM/AuthorURL", QMediaMetaData::Url },
197 if (names->vt == (VT_VECTOR | VT_LPWSTR)) {
198 for (ULONG i = 0; i < names->calpwstr.cElems; ++i) {
199 const QStringView name(names->calpwstr.pElems[i]);
203 if (name == u"WM/Picture") {
204 QtMultimediaPrivate::ScopedPropVariant value;
205 if (SUCCEEDED(metadata->GetProperty(names->calpwstr.pElems[i], value.get()))
206 && value->vt == VT_BLOB) {
207 QImage img = imageFromAsfFlatPicture(value->blob);
209 metaData.insert(QMediaMetaData::CoverArtImage, img);
214 auto it = nameToKey.find(name);
215 if (it == nameToKey.end())
218 QtMultimediaPrivate::ScopedPropVariant value;
219 if (SUCCEEDED(metadata->GetProperty(names->calpwstr.pElems[i], value.get()))) {
220 QVariant v = convertValue(value.var);
222 metaData.insert(it.value(), v);
230QMediaMetaData
MFMetaData::fromNative(IPropertyStore *content)
232 QMediaMetaData metaData;
238 if (SUCCEEDED(content->GetCount(&cProps))) {
239 for (DWORD i = 0; i < cProps; i++)
242 if (FAILED(content->GetAt(i, &key)))
244 QMediaMetaData::Key mediaKey;
245 if (key == PKEY_Author) {
246 mediaKey = QMediaMetaData::Author;
247 }
else if (key == PKEY_Title) {
248 mediaKey = QMediaMetaData::Title;
253 }
else if (key == PKEY_Media_EncodingSettings) {
254 mediaKey = QMediaMetaData::Description;
255 }
else if (key == PKEY_Copyright) {
256 mediaKey = QMediaMetaData::Copyright;
257 }
else if (key == PKEY_Comment) {
258 mediaKey = QMediaMetaData::Comment;
259 }
else if (key == PKEY_Media_ProviderStyle) {
260 mediaKey = QMediaMetaData::Genre;
261 }
else if (key == PKEY_Media_DateEncoded) {
262 mediaKey = QMediaMetaData::Date;
267 }
else if (key == PKEY_Language) {
268 mediaKey = QMediaMetaData::Language;
269 }
else if (key == PKEY_Media_Publisher) {
270 mediaKey = QMediaMetaData::Publisher;
271 }
else if (key == PKEY_Media_ClassPrimaryID) {
272 mediaKey = QMediaMetaData::MediaType;
273 }
else if (key == PKEY_Media_Duration) {
274 mediaKey = QMediaMetaData::Duration;
275 }
else if (key == PKEY_Audio_EncodingBitrate) {
276 mediaKey = QMediaMetaData::AudioBitRate;
277 }
else if (key == PKEY_Audio_Format) {
278 mediaKey = QMediaMetaData::AudioCodec;
287 }
else if (key == PKEY_Music_AlbumTitle) {
288 mediaKey = QMediaMetaData::AlbumTitle;
289 }
else if (key == PKEY_Music_AlbumArtist) {
290 mediaKey = QMediaMetaData::AlbumArtist;
291 }
else if (key == PKEY_Music_Artist) {
292 mediaKey = QMediaMetaData::ContributingArtist;
293 }
else if (key == PKEY_Music_Composer) {
294 mediaKey = QMediaMetaData::Composer;
301 }
else if (key == PKEY_Music_TrackNumber) {
302 mediaKey = QMediaMetaData::TrackNumber;
303 }
else if (key == PKEY_Music_Genre) {
304 mediaKey = QMediaMetaData::Genre;
305 }
else if (key == PKEY_ThumbnailStream) {
306 QVariant val = metaDataValue(content, key);
307 if (val.canConvert<QImage>())
308 QtMultimediaPrivate::setCoverArtImage(metaData, val.value<QImage>());
310 }
else if (key == PKEY_Video_FrameHeight) {
311 mediaKey = QMediaMetaData::Resolution;
312 }
else if (key == PKEY_Video_Orientation) {
313 mediaKey = QMediaMetaData::Orientation;
314 }
else if (key == PKEY_Video_FrameRate) {
315 mediaKey = QMediaMetaData::VideoFrameRate;
316 }
else if (key == PKEY_Video_EncodingBitrate) {
317 mediaKey = QMediaMetaData::VideoBitRate;
318 }
else if (key == PKEY_Video_Compression) {
319 mediaKey = QMediaMetaData::VideoCodec;
327 metaData.insert(mediaKey, metaDataValue(content, key));
337 case QMediaMetaData::Key::Title:
339 case QMediaMetaData::Key::Author:
341 case QMediaMetaData::Key::Comment:
343 case QMediaMetaData::Key::Genre:
344 return PKEY_Music_Genre;
345 case QMediaMetaData::Key::Copyright:
346 return PKEY_Copyright;
347 case QMediaMetaData::Key::Publisher:
348 return PKEY_Media_Publisher;
349 case QMediaMetaData::Key::Url:
350 return PKEY_Media_AuthorUrl;
351 case QMediaMetaData::Key::AlbumTitle:
352 return PKEY_Music_AlbumTitle;
353 case QMediaMetaData::Key::AlbumArtist:
354 return PKEY_Music_AlbumArtist;
355 case QMediaMetaData::Key::TrackNumber:
356 return PKEY_Music_TrackNumber;
357 case QMediaMetaData::Key::Date:
358 return PKEY_Media_DateEncoded;
359 case QMediaMetaData::Key::Composer:
360 return PKEY_Music_Composer;
361 case QMediaMetaData::Key::Duration:
362 return PKEY_Media_Duration;
363 case QMediaMetaData::Key::Language:
364 return PKEY_Language;
365 case QMediaMetaData::Key::Description:
366 return PKEY_Media_EncodingSettings;
367 case QMediaMetaData::Key::AudioBitRate:
368 return PKEY_Audio_EncodingBitrate;
369 case QMediaMetaData::Key::ContributingArtist:
370 return PKEY_Music_Artist;
371#if QT_DEPRECATED_SINCE(6
, 12
)
372 case QtMultimediaPrivate::deprecatedThumbnailImage:
374 case QMediaMetaData::Key::CoverArtImage:
375 return PKEY_ThumbnailStream;
376 case QMediaMetaData::Key::Orientation:
377 return PKEY_Video_Orientation;
378 case QMediaMetaData::Key::VideoFrameRate:
379 return PKEY_Video_FrameRate;
380 case QMediaMetaData::Key::VideoBitRate:
381 return PKEY_Video_EncodingBitrate;
382 case QMediaMetaData::MediaType:
383 return PKEY_Media_ClassPrimaryID;
385 return PROP_KEY_NULL;
425void MFMetaData::toNative(
const QMediaMetaData &metaData, IPropertyStore *content)
429 for (
const auto &key : metaData.keys()) {
431 QVariant value = metaData.value(key);
433 if (key == QMediaMetaData::Key::MediaType) {
435 QString strValue = metaData.stringValue(key);
440 if (strValue == u"Music")
441 v = u"{D1607DBC-E323-4BE2-86A1-48A42A28441E}"_s;
442 else if (strValue == u"Video")
443 v = u"{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}"_s;
444 else if (strValue == u"Audio")
445 v = u"{01CD0F29-DA4E-4157-897B-6275D50C4F11}"_s;
447 v = u"{FCF24A76-9A57-4036-990D-E35DD8B244E1}"_s;
449 setStringProperty(content, PKEY_Media_ClassPrimaryID, v);
451 }
else if (key == QMediaMetaData::Key::Duration) {
453 setUInt64Property(content, PKEY_Media_Duration, value.toULongLong() * 10000);
455 }
else if (key == QMediaMetaData::Key::Resolution) {
457 QSize res = value.toSize();
458 setUInt32Property(content, PKEY_Video_FrameWidth, quint32(res.width()));
459 setUInt32Property(content, PKEY_Video_FrameHeight, quint32(res.height()));
461 }
else if (key == QMediaMetaData::Key::Orientation) {
463 setUInt32Property(content, PKEY_Video_Orientation, value.toUInt());
465 }
else if (key == QMediaMetaData::Key::VideoFrameRate) {
467 qreal fps = value.toReal();
468 setUInt32Property(content, PKEY_Video_FrameRate, quint32(fps * 1000));
470 }
else if (key == QMediaMetaData::Key::TrackNumber) {
472 setUInt32Property(content, PKEY_Music_TrackNumber, value.toUInt());
474 }
else if (key == QMediaMetaData::Key::AudioBitRate) {
476 setUInt32Property(content, PKEY_Audio_EncodingBitrate, value.toUInt());
478 }
else if (key == QMediaMetaData::Key::VideoBitRate) {
480 setUInt32Property(content, PKEY_Video_EncodingBitrate, value.toUInt());
482 }
else if (key == QMediaMetaData::Key::Date) {
486 ULARGE_INTEGER t = {};
487 t.QuadPart = ULONGLONG(value.toDateTime().toUTC().toMSecsSinceEpoch() * 10000
488 + 116444736000000000LL);
491 ft.dwHighDateTime = t.HighPart;
492 ft.dwLowDateTime = t.LowPart;
494 setFileTimeProperty(content, PKEY_Media_DateEncoded, &ft);
500 REFPROPERTYKEY propKey = propertyKeyForMetaDataKey(key);
502 if (propKey != PROP_KEY_NULL) {
503 QString strValue = metaData.stringValue(key);
504 if (!strValue.isEmpty())
505 setStringProperty(content, propKey, strValue);