Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/main.c | 72 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index 3936b5b598..9bed20144f 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -576,6 +576,71 @@ failed: return hr; }
+static HRESULT bytestream_get_url_hint(IMFByteStream *stream, WCHAR const **url) +{ + static const UINT8 asfmagic[] = {0x30,0x26,0xb2,0x75,0x8e,0x66,0xcf,0x11,0xa6,0xd9,0x00,0xaa,0x00,0x62,0xce,0x6c}; + static const WCHAR asfW[] = {'.','a','s','f',0}; + static const struct stream_content_url_hint + { + const UINT8 *magic; + UINT32 magic_len; + const WCHAR *url; + } + url_hints[] = + { + { asfmagic, sizeof(asfmagic), asfW }, + }; + IMFAttributes *attributes; + UINT32 length = 0; + UINT8 buffer[16]; + DWORD caps = 0; + QWORD position; + unsigned int i; + HRESULT hr; + + *url = NULL; + + if (SUCCEEDED(IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes))) + { + IMFAttributes_GetStringLength(attributes, &MF_BYTESTREAM_CONTENT_TYPE, &length); + IMFAttributes_Release(attributes); + } + + if (length) + return S_OK; + + if (FAILED(hr = IMFByteStream_GetCapabilities(stream, &caps))) + return hr; + + if (!(caps & MFBYTESTREAM_IS_SEEKABLE)) + return S_OK; + + if (FAILED(hr = IMFByteStream_GetCurrentPosition(stream, &position))) + return hr; + + hr = IMFByteStream_Read(stream, buffer, sizeof(buffer), &length); + IMFByteStream_SetCurrentPosition(stream, position); + if (FAILED(hr)) + return hr; + + if (length < sizeof(buffer)) + return S_OK; + + for (i = 0; i < ARRAY_SIZE(url_hints); ++i) + { + if (!memcmp(buffer, url_hints[i].magic, min(url_hints[i].magic_len, length))) + { + *url = url_hints[i].url; + break; + } + } + + if (!*url) + WARN("Unrecognized content type %s.\n", debugstr_an((char *)buffer, length)); + + return S_OK; +} + static HRESULT create_source_reader_from_stream(IMFByteStream *stream, IMFAttributes *attributes, REFIID riid, void **out) { @@ -583,8 +648,13 @@ static HRESULT create_source_reader_from_stream(IMFByteStream *stream, IMFAttrib IMFSourceResolver *resolver; MF_OBJECT_TYPE obj_type; IMFMediaSource *source; + const WCHAR *url; HRESULT hr;
+ /* If stream does not have content type set, try to guess from starting byte sequence. */ + if (FAILED(hr = bytestream_get_url_hint(stream, &url))) + return hr; + if (FAILED(hr = MFCreateSourceResolver(&resolver))) return hr;
@@ -592,7 +662,7 @@ static HRESULT create_source_reader_from_stream(IMFByteStream *stream, IMFAttrib IMFAttributes_GetUnknown(attributes, &MF_SOURCE_READER_MEDIASOURCE_CONFIG, &IID_IPropertyStore, (void **)&props);
- hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, props, + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, url, MF_RESOLUTION_MEDIASOURCE, props, &obj_type, (IUnknown **)&source); IMFSourceResolver_Release(resolver); if (props)