Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/main.c | 65 +++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 32 deletions(-)
diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index 516b5928b1..3936b5b598 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -838,6 +838,35 @@ HRESULT WINAPI MFCreateSinkWriterFromMediaSink(IMFMediaSink *sink, IMFAttributes return create_sink_writer_from_sink(sink, attributes, &IID_IMFSinkWriter, (void **)writer); }
+static HRESULT create_source_reader_from_object(IUnknown *unk, IMFAttributes *attributes, REFIID riid, void **out) +{ + IMFMediaSource *source = NULL; + IMFByteStream *stream = NULL; + HRESULT hr; + + hr = IUnknown_QueryInterface(unk, &IID_IMFMediaSource, (void **)&source); + if (FAILED(hr)) + hr = IUnknown_QueryInterface(unk, &IID_IMFByteStream, (void **)&stream); + + if (source) + { + UINT32 disconnect = 0; + + if (attributes) + IMFAttributes_GetUINT32(attributes, &MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN, &disconnect); + hr = create_source_reader_from_source(source, attributes, !disconnect, riid, out); + } + else if (stream) + hr = create_source_reader_from_stream(stream, attributes, riid, out); + + if (source) + IMFMediaSource_Release(source); + if (stream) + IMFByteStream_Release(stream); + + return hr; +} + /*********************************************************************** * MFCreateSourceReaderFromByteStream (mfreadwrite.@) */ @@ -846,23 +875,18 @@ HRESULT WINAPI MFCreateSourceReaderFromByteStream(IMFByteStream *stream, IMFAttr { TRACE("%p, %p, %p.\n", stream, attributes, reader);
- return create_source_reader_from_stream(stream, attributes, &IID_IMFSourceReader, (void **)reader); + return create_source_reader_from_object((IUnknown *)stream, attributes, &IID_IMFSourceReader, (void **)reader); }
/*********************************************************************** * MFCreateSourceReaderFromMediaSource (mfreadwrite.@) */ HRESULT WINAPI MFCreateSourceReaderFromMediaSource(IMFMediaSource *source, IMFAttributes *attributes, - IMFSourceReader **reader) + IMFSourceReader **reader) { - UINT32 disconnect = 0; - TRACE("%p, %p, %p.\n", source, attributes, reader);
- if (attributes) - IMFAttributes_GetUINT32(attributes, &MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN, &disconnect); - - return create_source_reader_from_source(source, attributes, !disconnect, &IID_IMFSourceReader, (void **)reader); + return create_source_reader_from_object((IUnknown *)source, attributes, &IID_IMFSourceReader, (void **)reader); }
/*********************************************************************** @@ -924,30 +948,7 @@ static HRESULT WINAPI readwrite_factory_CreateInstanceFromObject(IMFReadWriteCla
if (IsEqualGUID(clsid, &CLSID_MFSourceReader)) { - IMFMediaSource *source = NULL; - IMFByteStream *stream = NULL; - - hr = IUnknown_QueryInterface(unk, &IID_IMFByteStream, (void **)&stream); - if (FAILED(hr)) - hr = IUnknown_QueryInterface(unk, &IID_IMFMediaSource, (void **)&source); - - if (stream) - hr = create_source_reader_from_stream(stream, attributes, riid, out); - else if (source) - { - UINT32 disconnect = 0; - - if (attributes) - IMFAttributes_GetUINT32(attributes, &MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN, &disconnect); - hr = create_source_reader_from_source(source, attributes, !disconnect, riid, out); - } - - if (source) - IMFMediaSource_Release(source); - if (stream) - IMFByteStream_Release(stream); - - return hr; + return create_source_reader_from_object(unk, attributes, riid, out); } else if (IsEqualGUID(clsid, &CLSID_MFSinkWriter)) {
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)