mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added mf_http_support patchset
This commit is contained in:
parent
93f5b4f6a0
commit
49770c6bc6
@ -0,0 +1,24 @@
|
||||
From 252a1d6bb99c83ce8a0289fbd1f4fe135e2c55cd Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Fri, 25 Oct 2024 13:19:02 +0200
|
||||
Subject: [PATCH] include: Add MFNETSOURCE_STATISTICS_SERVICE definition.
|
||||
|
||||
---
|
||||
include/mfidl.idl | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/include/mfidl.idl b/include/mfidl.idl
|
||||
index 666af53c6e3..a8c5af05e68 100644
|
||||
--- a/include/mfidl.idl
|
||||
+++ b/include/mfidl.idl
|
||||
@@ -1626,6 +1626,7 @@ cpp_quote("EXTERN_GUID(MR_STREAM_VOLUME_SERVICE, 0xf8b5fa2f, 0x32ef, 0x46f5, 0xb
|
||||
cpp_quote("EXTERN_GUID(MR_AUDIO_POLICY_SERVICE, 0x911fd737, 0x6775, 0x4ab0, 0xa6, 0x14, 0x29, 0x78, 0x62, 0xfd, 0xac, 0x88);")
|
||||
cpp_quote("EXTERN_GUID(MF_PROPERTY_HANDLER_SERVICE, 0xa3face02, 0x32b8, 0x41dd, 0x90, 0xe7, 0x5f, 0xef, 0x7c, 0x89, 0x91, 0xb5);")
|
||||
cpp_quote("EXTERN_GUID(MF_WORKQUEUE_SERVICES, 0x8e37d489, 0x41e0, 0x413a, 0x90, 0x68, 0x28, 0x7c, 0x88, 0x6d, 0x8d, 0xda);")
|
||||
+cpp_quote("EXTERN_GUID(MFNETSOURCE_STATISTICS_SERVICE, 0x3cb1f275, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1);")
|
||||
|
||||
cpp_quote("EXTERN_GUID(MF_PROGRESSIVE_CODING_CONTENT, 0x8f020eea, 0x1508, 0x471f, 0x9d, 0xa6, 0x50, 0x7d, 0x7c, 0xfa, 0x40, 0xdb);")
|
||||
cpp_quote("EXTERN_GUID(MF_NALU_LENGTH_SET, 0xa7911d53, 0x12a4, 0x4965, 0xae, 0x70, 0x6e, 0xad, 0xd6, 0xff, 0x05, 0x51);")
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,383 @@
|
||||
From 0d4a7cf6b9bb3a57a098762113ca1750c43a810e Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Fri, 25 Oct 2024 10:47:30 +0200
|
||||
Subject: [PATCH] mf/tests: Add network bytestream tests.
|
||||
|
||||
---
|
||||
dlls/mf/tests/mf.c | 347 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 347 insertions(+)
|
||||
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index d0f1f1cf0a4..61daaf35741 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -4726,6 +4726,7 @@ static void test_evr(void)
|
||||
|
||||
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
+ if (!sink) return;
|
||||
|
||||
check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
|
||||
check_interface(sink, &IID_IMFVideoRenderer, TRUE);
|
||||
@@ -6803,6 +6804,351 @@ static void test_media_session_Close(void)
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
}
|
||||
|
||||
+static void test_network_bytestream(void)
|
||||
+{
|
||||
+ static const WCHAR *URL = L"http://test.winehq.org/tests/test.mp3";
|
||||
+ static const WCHAR *EFFECTIVE_URL = L"http://test.winehq.org:80/tests/test.mp3";
|
||||
+ static const WCHAR *CONTENT_TYPE = L"audio/mpeg";
|
||||
+ static const BYTE LAST_MODIFIED_TIME[] = { 0x00, 0x3b, 0x4b, 0xbf, 0x05, 0x80, 0xd8, 0x01 };
|
||||
+
|
||||
+ IMFSourceResolver *resolver;
|
||||
+ IUnknown *object = NULL, *bs = NULL;
|
||||
+ MF_OBJECT_TYPE obj_type;
|
||||
+ HRESULT hr;
|
||||
+ void *ptr;
|
||||
+
|
||||
+ hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
+ ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr);
|
||||
+
|
||||
+ hr = MFCreateSourceResolver(&resolver);
|
||||
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
+
|
||||
+ if (object) IUnknown_Release(object);
|
||||
+
|
||||
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
+ object = NULL;
|
||||
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://nonexistent.url/file.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
|
||||
+ todo_wine
|
||||
+ ok(hr == NS_E_SERVER_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
+ ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
|
||||
+ if (object) IUnknown_Release(object);
|
||||
+
|
||||
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
+ object = NULL;
|
||||
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
|
||||
+ todo_wine
|
||||
+ ok(hr == NS_E_FILE_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
|
||||
+ if (object) IUnknown_Release(object);
|
||||
+
|
||||
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
+ object = NULL;
|
||||
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, URL, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(obj_type == MF_OBJECT_BYTESTREAM, "Unexpected obj_type %#x.\n", obj_type);
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IMFAttributes, &ptr);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ IMFAttributes *attr = ptr;
|
||||
+ UINT32 count = 0;
|
||||
+ PROPVARIANT var;
|
||||
+ GUID key = {0};
|
||||
+
|
||||
+ hr = IMFAttributes_GetCount(attr, &count);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(count == 3, "count = %u\n", count);
|
||||
+
|
||||
+ PropVariantInit(&var);
|
||||
+
|
||||
+ hr = IMFAttributes_GetItemByIndex(attr, 0, &key, &var);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_EFFECTIVE_URL), "Got key %s\n", debugstr_guid(&key));
|
||||
+ ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
|
||||
+ todo_wine
|
||||
+ ok(!lstrcmpW(var.pwszVal, EFFECTIVE_URL), "Got value %s\n", var.pszVal);
|
||||
+ memset(&key, 0, sizeof(key));
|
||||
+ PropVariantClear(&var);
|
||||
+
|
||||
+ hr = IMFAttributes_GetItemByIndex(attr, 1, &key, &var);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_CONTENT_TYPE), "Got key %s\n", debugstr_guid(&key));
|
||||
+ ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
|
||||
+ todo_wine
|
||||
+ ok(!lstrcmpW(var.pwszVal, CONTENT_TYPE), "Got value %s\n", var.pszVal);
|
||||
+ memset(&key, 0, sizeof(key));
|
||||
+ PropVariantClear(&var);
|
||||
+
|
||||
+ hr = IMFAttributes_GetItemByIndex(attr, 2, &key, &var);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_LAST_MODIFIED_TIME), "Got key %s\n", debugstr_guid(&key));
|
||||
+ todo_wine
|
||||
+ ok(var.vt == (VT_VECTOR | VT_I1 | VT_NULL), "Got type %d\n", var.vt);
|
||||
+ todo_wine
|
||||
+ ok(var.blob.cbSize == sizeof(LAST_MODIFIED_TIME), "Got size %lu\n", var.blob.cbSize);
|
||||
+ todo_wine
|
||||
+ ok(var.blob.pBlobData != NULL, "Got NULL value\n");
|
||||
+ if (var.blob.cbSize == sizeof(LAST_MODIFIED_TIME) && var.blob.pBlobData)
|
||||
+ ok(!memcmp(var.blob.pBlobData, LAST_MODIFIED_TIME, sizeof(LAST_MODIFIED_TIME)), "Got wrong value\n");
|
||||
+ memset(&key, 0, sizeof(key));
|
||||
+ PropVariantClear(&var);
|
||||
+
|
||||
+ hr = IMFAttributes_GetItemByIndex(attr, 3, &key, &var);
|
||||
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
|
||||
+ ok(IsEqualGUID(&key, &GUID_NULL), "Got key %s\n", debugstr_guid(&key));
|
||||
+ ok(var.vt == VT_EMPTY, "Got type %d\n", var.vt);
|
||||
+ memset(&key, 0, sizeof(key));
|
||||
+ PropVariantClear(&var);
|
||||
+
|
||||
+ IUnknown_Release((IUnknown *)ptr);
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamCacheControl, &ptr);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ IMFByteStreamCacheControl *ctrl = ptr;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ hr = IMFByteStreamCacheControl_StopBackgroundTransfer(ctrl);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ IMFByteStreamCacheControl_Release(ctrl);
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamBuffering, &ptr);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ MFBYTESTREAM_BUFFERING_PARAMS params = {0};
|
||||
+ IMFByteStreamBuffering *buffering = ptr;
|
||||
+ MF_LEAKY_BUCKET_PAIR bucket = {0};
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_StopBuffering(buffering);
|
||||
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, FALSE);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, TRUE);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_StopBuffering(buffering);
|
||||
+ ok(hr == S_OK || hr == S_FALSE, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, NULL);
|
||||
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ params.cbTotalFileSize = -1;
|
||||
+ params.cbPlayableDataSize = -1;
|
||||
+ params.prgBuckets = NULL;
|
||||
+ params.cBuckets = 0;
|
||||
+ params.qwNetBufferingTime = 0;
|
||||
+ params.qwExtraBufferingTimeDuringSeek = 0;
|
||||
+ params.qwPlayDuration = 0;
|
||||
+ params.dRate = 1.0f;
|
||||
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, ¶ms);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ params.cBuckets = 1;
|
||||
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, ¶ms);
|
||||
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ params.prgBuckets = &bucket;
|
||||
+ bucket.dwBitrate = 0;
|
||||
+ bucket.msBufferWindow = 0;
|
||||
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, ¶ms);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ params.cbTotalFileSize = 0xdeadbeef;
|
||||
+ params.cbPlayableDataSize = 0xdeadbeef;
|
||||
+ bucket.dwBitrate = 0xdeadbeef;
|
||||
+ bucket.msBufferWindow = 0xdeadbeef;
|
||||
+ params.qwNetBufferingTime = 0xdeadbeef;
|
||||
+ params.qwExtraBufferingTimeDuringSeek = 0xdeadbeef;
|
||||
+ params.qwPlayDuration = 0xdeadbeef;
|
||||
+ params.dRate = 12345.0f;
|
||||
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, ¶ms);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, TRUE);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ IMFByteStreamBuffering_Release(buffering);
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamTimeSeek, &ptr);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ QWORD start_time = 0xdeadbeef, stop_time = 0xdeadbef0, duration = 0xdeadbef1;
|
||||
+ IMFByteStreamTimeSeek *seek = ptr;
|
||||
+ BOOL b = 0xdeadbeef;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, NULL, NULL, NULL);
|
||||
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, &start_time, &stop_time, &duration);
|
||||
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
|
||||
+ ok(start_time == 0, "start_time = %I64u\n", start_time);
|
||||
+ ok(stop_time == 0, "stop_time = %I64u\n", stop_time);
|
||||
+ ok(duration == 0, "duration = %I64u\n", duration);
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_IsTimeSeekSupported(seek, NULL);
|
||||
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_IsTimeSeekSupported(seek, &b);
|
||||
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
|
||||
+ ok(!b, "supported = %x\n", b);
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_TimeSeek(seek, 0);
|
||||
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, &start_time, &stop_time, &duration);
|
||||
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
|
||||
+ ok(start_time == 0, "start_time = %I64u\n", start_time);
|
||||
+ ok(stop_time == 0, "stop_time = %I64u\n", stop_time);
|
||||
+ ok(duration == 0, "duration = %I64u\n", duration);
|
||||
+
|
||||
+ IMFByteStreamTimeSeek_Release(seek);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ BYTE *tmp = malloc(8192);
|
||||
+ ULONG read = 0, written = 0;
|
||||
+ QWORD len = 0;
|
||||
+
|
||||
+ hr = IMFByteStream_SetLength((IMFByteStream*)object, 1000);
|
||||
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStream_SetCurrentPosition((IMFByteStream*)object, 1000);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStream_Read((IMFByteStream*)object, tmp, 8192, &read);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(read == 3365, "read = %lu\n", read);
|
||||
+
|
||||
+ hr = IMFByteStream_SetCurrentPosition((IMFByteStream*)object, 1000);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
+ hr = IMFByteStream_Write((IMFByteStream*)object, tmp, 1000, &written);
|
||||
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
|
||||
+ ok(written == 0, "written = %lu\n", written);
|
||||
+
|
||||
+ free(tmp);
|
||||
+
|
||||
+ hr = IMFByteStream_GetLength((IMFByteStream*)object, &len);
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ ok(len != 0, "len = %I64u\n", len);
|
||||
+
|
||||
+ hr = IMFByteStream_Flush((IMFByteStream*)object);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = MFGetService(object, &MFNETSOURCE_STATISTICS_SERVICE, &IID_IPropertyStore, &ptr);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ IPropertyStore *pstore = ptr;
|
||||
+ DWORD count = 0;
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IPropertyStore, &ptr);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(ptr == (void *)pstore, "Got different IPropertyStore: %p != %p.\n", ptr, pstore);
|
||||
+ IPropertyStore_Release((IPropertyStore *)ptr);
|
||||
+
|
||||
+ hr = IPropertyStore_GetCount(pstore, &count);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ ok(count == 0, "Got count %lu.\n", count);
|
||||
+
|
||||
+ IPropertyStore_Release(pstore);
|
||||
+ }
|
||||
+
|
||||
+ ptr = NULL;
|
||||
+ hr = IUnknown_QueryInterface(object, &IID_IMFMediaEventGenerator, &ptr);
|
||||
+ todo_wine
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+ todo_wine
|
||||
+ ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
+ if (SUCCEEDED(hr) && ptr)
|
||||
+ {
|
||||
+ IMFMediaEvent *evt = (void *)(DWORD_PTR)0xdeadbeef;
|
||||
+ BOOL seen_caps_changed = FALSE, buffering = FALSE;
|
||||
+ IMFMediaEventGenerator *gen = ptr;
|
||||
+ MediaEventType type;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ while (SUCCEEDED(hr = IMFMediaEventGenerator_GetEvent(gen, MF_EVENT_FLAG_NO_WAIT, &evt)))
|
||||
+ {
|
||||
+ type = (MediaEventType)0xdeadbeef;
|
||||
+ hr = IMFMediaEvent_GetType(evt, &type);
|
||||
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
+ if (type == MEByteStreamCharacteristicsChanged)
|
||||
+ {
|
||||
+ ok(!seen_caps_changed, "got multiple MEByteStreamCharacteristicsChanged events\n");
|
||||
+ seen_caps_changed = TRUE;
|
||||
+ }
|
||||
+ else if (type == MEBufferingStarted)
|
||||
+ {
|
||||
+ ok(!buffering, "got MEBufferingStopped without MEBufferingStarted\n");
|
||||
+ buffering = TRUE;
|
||||
+ }
|
||||
+ else if (type == MEBufferingStopped)
|
||||
+ buffering = FALSE;
|
||||
+ else
|
||||
+ ok(0, "Unexpected event type %#lx\n", type);
|
||||
+
|
||||
+ IMFMediaEvent_Release(evt);
|
||||
+ }
|
||||
+ ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
+ IMFMediaEventGenerator_Release(gen);
|
||||
+ }
|
||||
+
|
||||
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
+ bs = NULL;
|
||||
+ hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, (void *)object, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, &obj_type, &bs);
|
||||
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
+ ok(obj_type == MF_OBJECT_MEDIASOURCE, "Unexpected obj_type %#x.\n", obj_type);
|
||||
+
|
||||
+ if (bs) IUnknown_Release(bs);
|
||||
+ if (object) IUnknown_Release(object);
|
||||
+
|
||||
+ IMFSourceResolver_Release(resolver);
|
||||
+
|
||||
+ hr = MFShutdown();
|
||||
+ ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr);
|
||||
+}
|
||||
+
|
||||
START_TEST(mf)
|
||||
{
|
||||
init_functions();
|
||||
@@ -6838,5 +7184,6 @@ START_TEST(mf)
|
||||
test_media_session_Start();
|
||||
test_MFEnumDeviceSources();
|
||||
test_media_session_Close();
|
||||
+ test_network_bytestream();
|
||||
test_media_session_source_shutdown();
|
||||
}
|
||||
--
|
||||
2.45.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,346 @@
|
||||
From 68227ee19646a7c98f1b1e6eed72a7a6a2a21fc1 Mon Sep 17 00:00:00 2001
|
||||
From: Torge Matthies <tmatthies@codeweavers.com>
|
||||
Date: Fri, 25 Oct 2024 10:47:31 +0200
|
||||
Subject: [PATCH] mf: Implement and use HttpSchemePlugin.
|
||||
|
||||
---
|
||||
dlls/mf/main.c | 2 ++
|
||||
dlls/mf/mf.idl | 6 ++++++
|
||||
dlls/mf/mf.rgs | 16 ++++++++++++++--
|
||||
dlls/mf/mf_private.h | 1 +
|
||||
dlls/mf/scheme_handler.c | 33 +++++++++++++++++++++++++++++++++
|
||||
dlls/mf/tests/mf.c | 38 ++++----------------------------------
|
||||
dlls/mfplat/mfplat.spec | 3 +++
|
||||
dlls/mfplat/network.c | 5 +++++
|
||||
8 files changed, 68 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/main.c b/dlls/mf/main.c
|
||||
index e74a4ae8e4c..120343a1be2 100644
|
||||
--- a/dlls/mf/main.c
|
||||
+++ b/dlls/mf/main.c
|
||||
@@ -549,6 +549,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
|
||||
};
|
||||
|
||||
static struct class_factory file_scheme_handler_factory = { { &class_factory_vtbl }, file_scheme_handler_construct };
|
||||
+static struct class_factory http_scheme_handler_factory = { { &class_factory_vtbl }, http_scheme_handler_construct };
|
||||
static struct class_factory urlmon_scheme_handler_factory = { { &class_factory_vtbl }, urlmon_scheme_handler_construct };
|
||||
|
||||
static const struct class_object
|
||||
@@ -559,6 +560,7 @@ static const struct class_object
|
||||
class_objects[] =
|
||||
{
|
||||
{ &CLSID_FileSchemePlugin, &file_scheme_handler_factory.IClassFactory_iface },
|
||||
+ { &CLSID_HttpSchemePlugin, &http_scheme_handler_factory.IClassFactory_iface },
|
||||
{ &CLSID_UrlmonSchemePlugin, &urlmon_scheme_handler_factory.IClassFactory_iface },
|
||||
};
|
||||
|
||||
diff --git a/dlls/mf/mf.idl b/dlls/mf/mf.idl
|
||||
index 4f5ef36c965..ca05a991ca9 100644
|
||||
--- a/dlls/mf/mf.idl
|
||||
+++ b/dlls/mf/mf.idl
|
||||
@@ -25,6 +25,12 @@
|
||||
]
|
||||
coclass FileSchemePlugin { }
|
||||
|
||||
+[
|
||||
+ threading(both),
|
||||
+ uuid(44cb442b-9da9-49df-b3fd-023777b16e50)
|
||||
+]
|
||||
+coclass HttpSchemePlugin {}
|
||||
+
|
||||
[
|
||||
threading(both),
|
||||
uuid(9ec4b4f9-3029-45ad-947b-344de2a249e2)
|
||||
diff --git a/dlls/mf/mf.rgs b/dlls/mf/mf.rgs
|
||||
index f06576baccb..778b07e65ed 100644
|
||||
--- a/dlls/mf/mf.rgs
|
||||
+++ b/dlls/mf/mf.rgs
|
||||
@@ -14,11 +14,23 @@ HKLM
|
||||
}
|
||||
'http:'
|
||||
{
|
||||
- val '{9ec4b4f9-3029-45ad-947b-344de2a249e2}' = s 'Urlmon Scheme Handler'
|
||||
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
|
||||
}
|
||||
'https:'
|
||||
{
|
||||
- val '{9ec4b4f9-3029-45ad-947b-344de2a249e2}' = s 'Urlmon Scheme Handler'
|
||||
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
|
||||
+ }
|
||||
+ 'httpd:'
|
||||
+ {
|
||||
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
|
||||
+ }
|
||||
+ 'httpsd:'
|
||||
+ {
|
||||
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
|
||||
+ }
|
||||
+ 'mms:'
|
||||
+ {
|
||||
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h
|
||||
index 1f2ef17a8c9..adb35e14194 100644
|
||||
--- a/dlls/mf/mf_private.h
|
||||
+++ b/dlls/mf/mf_private.h
|
||||
@@ -114,6 +114,7 @@ static inline const char *debugstr_propvar(const PROPVARIANT *v)
|
||||
}
|
||||
|
||||
extern HRESULT file_scheme_handler_construct(REFIID riid, void **obj);
|
||||
+extern HRESULT http_scheme_handler_construct(REFIID riid, void **obj);
|
||||
extern HRESULT urlmon_scheme_handler_construct(REFIID riid, void **obj);
|
||||
|
||||
extern BOOL mf_is_sample_copier_transform(IMFTransform *transform);
|
||||
diff --git a/dlls/mf/scheme_handler.c b/dlls/mf/scheme_handler.c
|
||||
index 7e92748aeb9..3cd16319b2a 100644
|
||||
--- a/dlls/mf/scheme_handler.c
|
||||
+++ b/dlls/mf/scheme_handler.c
|
||||
@@ -483,6 +483,39 @@ HRESULT file_scheme_handler_construct(REFIID riid, void **obj)
|
||||
return hr;
|
||||
}
|
||||
|
||||
+WINAPI HRESULT __wine_create_http_bytestream(const WCHAR *url, void **out);
|
||||
+
|
||||
+static HRESULT http_stream_create(const WCHAR *url, DWORD flags, IMFByteStream **out)
|
||||
+{
|
||||
+ if (flags & MF_RESOLUTION_WRITE)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ return __wine_create_http_bytestream(url, (void **)out);
|
||||
+}
|
||||
+
|
||||
+HRESULT http_scheme_handler_construct(REFIID riid, void **obj)
|
||||
+{
|
||||
+ struct scheme_handler *handler;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ TRACE("%s, %p.\n", debugstr_guid(riid), obj);
|
||||
+
|
||||
+ if (!(handler = calloc(1, sizeof(*handler))))
|
||||
+ return E_OUTOFMEMORY;
|
||||
+
|
||||
+ handler->IMFSchemeHandler_iface.lpVtbl = &scheme_handler_vtbl;
|
||||
+ handler->IMFAsyncCallback_iface.lpVtbl = &scheme_handler_callback_vtbl;
|
||||
+ handler->refcount = 1;
|
||||
+ list_init(&handler->results);
|
||||
+ InitializeCriticalSection(&handler->cs);
|
||||
+ handler->create_stream = http_stream_create;
|
||||
+
|
||||
+ hr = IMFSchemeHandler_QueryInterface(&handler->IMFSchemeHandler_iface, riid, obj);
|
||||
+ IMFSchemeHandler_Release(&handler->IMFSchemeHandler_iface);
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
static HRESULT urlmon_stream_create(const WCHAR *url, DWORD flags, IMFByteStream **out)
|
||||
{
|
||||
IMFAttributes *attributes;
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index 61daaf35741..39dfe3ca1b2 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -5384,7 +5384,6 @@ static void test_scheme_resolvers(void)
|
||||
for (i = 0; i < ARRAY_SIZE(urls); i++)
|
||||
{
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, urls[i], MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine_if(i >= 2)
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
if (hr != S_OK)
|
||||
continue;
|
||||
@@ -5408,7 +5407,6 @@ static void test_scheme_resolvers(void)
|
||||
hr = IMFAttributes_GetItem(attributes, &MF_BYTESTREAM_CONTENT_TYPE, NULL);
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
hr = IMFAttributes_GetItem(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, NULL);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
IMFAttributes_Release(attributes);
|
||||
|
||||
@@ -5416,8 +5414,7 @@ static void test_scheme_resolvers(void)
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
hr = IMFByteStream_GetCapabilities(byte_stream, &caps);
|
||||
ok(hr == S_OK, "got hr %#lx\n", hr);
|
||||
- todo_wine
|
||||
- ok(caps == (expect_caps | MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED)
|
||||
+ ok(caps == expect_caps || caps == (expect_caps | MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED)
|
||||
|| caps == (expect_caps | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
|
||||
"got caps %#lx\n", caps);
|
||||
hr = IMFByteStream_GetLength(byte_stream, &length);
|
||||
@@ -5436,35 +5433,25 @@ static void test_scheme_resolvers(void)
|
||||
ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got hr %#lx\n", hr);
|
||||
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_SERVER_NOT_FOUND, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"https://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpd://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpsd://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"mms://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
|
||||
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"https://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpd://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpsd://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"mms://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
|
||||
- todo_wine
|
||||
ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got hr %#lx\n", hr);
|
||||
|
||||
IMFSourceResolver_Release(resolver);
|
||||
@@ -6828,7 +6815,6 @@ static void test_network_bytestream(void)
|
||||
obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
object = NULL;
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://nonexistent.url/file.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_SERVER_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
|
||||
if (object) IUnknown_Release(object);
|
||||
@@ -6836,9 +6822,7 @@ static void test_network_bytestream(void)
|
||||
obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
|
||||
object = NULL;
|
||||
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
|
||||
- todo_wine
|
||||
ok(hr == NS_E_FILE_NOT_FOUND, "Got hr %#lx.\n", hr);
|
||||
- todo_wine
|
||||
ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
|
||||
if (object) IUnknown_Release(object);
|
||||
|
||||
@@ -6861,7 +6845,6 @@ static void test_network_bytestream(void)
|
||||
|
||||
hr = IMFAttributes_GetCount(attr, &count);
|
||||
ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
- todo_wine
|
||||
ok(count == 3, "count = %u\n", count);
|
||||
|
||||
PropVariantInit(&var);
|
||||
@@ -6870,7 +6853,6 @@ static void test_network_bytestream(void)
|
||||
ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
ok(IsEqualGUID(&key, &MF_BYTESTREAM_EFFECTIVE_URL), "Got key %s\n", debugstr_guid(&key));
|
||||
ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
|
||||
- todo_wine
|
||||
ok(!lstrcmpW(var.pwszVal, EFFECTIVE_URL), "Got value %s\n", var.pszVal);
|
||||
memset(&key, 0, sizeof(key));
|
||||
PropVariantClear(&var);
|
||||
@@ -6879,21 +6861,15 @@ static void test_network_bytestream(void)
|
||||
ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
ok(IsEqualGUID(&key, &MF_BYTESTREAM_CONTENT_TYPE), "Got key %s\n", debugstr_guid(&key));
|
||||
ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
|
||||
- todo_wine
|
||||
ok(!lstrcmpW(var.pwszVal, CONTENT_TYPE), "Got value %s\n", var.pszVal);
|
||||
memset(&key, 0, sizeof(key));
|
||||
PropVariantClear(&var);
|
||||
|
||||
hr = IMFAttributes_GetItemByIndex(attr, 2, &key, &var);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
- todo_wine
|
||||
ok(IsEqualGUID(&key, &MF_BYTESTREAM_LAST_MODIFIED_TIME), "Got key %s\n", debugstr_guid(&key));
|
||||
- todo_wine
|
||||
ok(var.vt == (VT_VECTOR | VT_I1 | VT_NULL), "Got type %d\n", var.vt);
|
||||
- todo_wine
|
||||
ok(var.blob.cbSize == sizeof(LAST_MODIFIED_TIME), "Got size %lu\n", var.blob.cbSize);
|
||||
- todo_wine
|
||||
ok(var.blob.pBlobData != NULL, "Got NULL value\n");
|
||||
if (var.blob.cbSize == sizeof(LAST_MODIFIED_TIME) && var.blob.pBlobData)
|
||||
ok(!memcmp(var.blob.pBlobData, LAST_MODIFIED_TIME, sizeof(LAST_MODIFIED_TIME)), "Got wrong value\n");
|
||||
@@ -6912,9 +6888,7 @@ static void test_network_bytestream(void)
|
||||
|
||||
ptr = NULL;
|
||||
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamCacheControl, &ptr);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
- todo_wine
|
||||
ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
if (SUCCEEDED(hr) && ptr)
|
||||
{
|
||||
@@ -6929,9 +6903,7 @@ static void test_network_bytestream(void)
|
||||
|
||||
ptr = NULL;
|
||||
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamBuffering, &ptr);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
- todo_wine
|
||||
ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
if (SUCCEEDED(hr) && ptr)
|
||||
{
|
||||
@@ -6998,9 +6970,7 @@ static void test_network_bytestream(void)
|
||||
|
||||
ptr = NULL;
|
||||
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamTimeSeek, &ptr);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
- todo_wine
|
||||
ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
if (SUCCEEDED(hr) && ptr)
|
||||
{
|
||||
@@ -7059,6 +7029,9 @@ static void test_network_bytestream(void)
|
||||
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
|
||||
ok(written == 0, "written = %lu\n", written);
|
||||
|
||||
+ hr = IMFByteStream_BeginWrite((IMFByteStream*)object, tmp, 1000, (void *)(DWORD_PTR)0xdeadbeef, NULL);
|
||||
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
|
||||
+
|
||||
free(tmp);
|
||||
|
||||
hr = IMFByteStream_GetLength((IMFByteStream*)object, &len);
|
||||
@@ -7066,7 +7039,6 @@ static void test_network_bytestream(void)
|
||||
ok(len != 0, "len = %I64u\n", len);
|
||||
|
||||
hr = IMFByteStream_Flush((IMFByteStream*)object);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx\n", hr);
|
||||
}
|
||||
|
||||
@@ -7094,9 +7066,7 @@ static void test_network_bytestream(void)
|
||||
|
||||
ptr = NULL;
|
||||
hr = IUnknown_QueryInterface(object, &IID_IMFMediaEventGenerator, &ptr);
|
||||
- todo_wine
|
||||
ok(hr == S_OK, "Got hr %#lx.\n", hr);
|
||||
- todo_wine
|
||||
ok(ptr != NULL, "Got NULL ptr.\n");
|
||||
if (SUCCEEDED(hr) && ptr)
|
||||
{
|
||||
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
|
||||
index 7b356f9f457..f55f49b7e8c 100644
|
||||
--- a/dlls/mfplat/mfplat.spec
|
||||
+++ b/dlls/mfplat/mfplat.spec
|
||||
@@ -181,3 +181,6 @@
|
||||
@ stdcall -ret64 MFllMulDiv(int64 int64 int64 int64)
|
||||
@ stub PropVariantFromStream
|
||||
@ stub PropVariantToStream
|
||||
+
|
||||
+# Wine extension
|
||||
+@ stdcall __wine_create_http_bytestream(wstr ptr)
|
||||
diff --git a/dlls/mfplat/network.c b/dlls/mfplat/network.c
|
||||
index d9a2981f5a7..2369dbf31fd 100644
|
||||
--- a/dlls/mfplat/network.c
|
||||
+++ b/dlls/mfplat/network.c
|
||||
@@ -2012,3 +2012,8 @@ error:
|
||||
hr = MF_E_UNSUPPORTED_BYTESTREAM_TYPE;
|
||||
return hr;
|
||||
}
|
||||
+
|
||||
+WINAPI HRESULT __wine_create_http_bytestream(const WCHAR *url, void **out)
|
||||
+{
|
||||
+ return create_http_bytestream(url, out);
|
||||
+}
|
||||
--
|
||||
2.45.2
|
||||
|
5
patches/mf_http_support/definition
Normal file
5
patches/mf_http_support/definition
Normal file
@ -0,0 +1,5 @@
|
||||
Fixes: [52769] mf: Add HTTP/HTTPS IMFByteStream implementation.
|
||||
|
||||
# MR https://gitlab.winehq.org/wine/wine/-/merge_requests/6733
|
||||
|
||||
# Game: The good life.
|
Loading…
x
Reference in New Issue
Block a user