Some tests reuse the same MP4 stream and are currently passing only because we have the generic byte stream handler fallback. They pass on Windows too, so I'm assuming the stream is seeked before looking for the hints. We could also very well remove the position restore because the media sources are rewinding the stream later too, but I've kept it like it was.
-- v2: mfplat: Seek byte stream to the start for URL hint detection. mfplat/tests: Test source resolver bytestream interactions.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 66 +++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 6a2761e6613..a984b471fa5 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -1198,13 +1198,16 @@ static void test_source_resolver(void) MF_OBJECT_TYPE obj_type; IMFStreamDescriptor *sd; IUnknown *cancel_cookie; - IMFByteStream *stream; + IMFByteStream *stream, *tmp_stream; IMFGetService *get_service; IMFRateSupport *rate_support; WCHAR pathW[MAX_PATH]; int i, sample_count; + DWORD size, flags; + BYTE buffer[1024]; WCHAR *filename; PROPVARIANT var; + QWORD length; HRESULT hr; GUID guid; float rate; @@ -1321,6 +1324,67 @@ static void test_source_resolver(void) ok(!refcount, "Unexpected refcount %ld\n", refcount); IMFByteStream_Release(stream);
+ /* test that bytestream position doesn't matter */ + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_SetCurrentPosition(stream, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, + &obj_type, (IUnknown **)&mediasource); + ok(hr == S_OK || broken(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE) /* w7 || w8 */, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) IMFMediaSource_Release(mediasource); + IMFByteStream_Release(stream); + + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_GetLength(stream, &length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_SetCurrentPosition(stream, length); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, + &obj_type, (IUnknown **)&mediasource); + ok(hr == S_OK || broken(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE) /* w7 || w8 */, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) IMFMediaSource_Release(mediasource); + IMFByteStream_Release(stream); + + /* stream must have a valid header, media cannot start in the middle of a stream */ + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &tmp_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateTempFile(MF_ACCESSMODE_READ | MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST, MF_FILEFLAGS_NONE, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + memset(buffer, 0xcd, sizeof(buffer)); + hr = IMFByteStream_Write(stream, buffer, sizeof(buffer), &size); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + do + { + hr = IMFByteStream_Read(tmp_stream, buffer, sizeof(buffer), &size); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_Write(stream, buffer, size, &size); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + while (size >= sizeof(buffer)); + IMFByteStream_Release(tmp_stream); + hr = IMFByteStream_SetCurrentPosition(stream, sizeof(buffer)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + flags = MF_RESOLUTION_MEDIASOURCE; + flags |= MF_RESOLUTION_KEEP_BYTE_STREAM_ALIVE_ON_FAIL; + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, flags, NULL, + &obj_type, (IUnknown **)&mediasource); + todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "Unexpected hr %#lx.\n", hr); + + flags |= MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE; + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, flags, NULL, + &obj_type, (IUnknown **)&mediasource); + todo_wine ok(hr == MF_E_SOURCERESOLVER_MUTUALLY_EXCLUSIVE_FLAGS, "Unexpected hr %#lx.\n", hr); + + flags = MF_RESOLUTION_MEDIASOURCE; + flags |= MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE; + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, flags, NULL, + &obj_type, (IUnknown **)&mediasource); + todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "Unexpected hr %#lx.\n", hr); + IMFByteStream_Release(stream); + /* We have to create a new bytestream here, because all following * calls to CreateObjectFromByteStream will fail. */ hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index aa987ff0496..4ed607686f1 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -6257,10 +6257,9 @@ static HRESULT resolver_get_bytestream_url_hint(IMFByteStream *stream, WCHAR con
if (FAILED(hr = IMFByteStream_GetCurrentPosition(stream, &position))) return hr; - - hr = IMFByteStream_Read(stream, buffer, sizeof(buffer), &length); - IMFByteStream_SetCurrentPosition(stream, position); - if (FAILED(hr)) + if (position && FAILED(hr = IMFByteStream_SetCurrentPosition(stream, 0))) + return hr; + if (FAILED(hr = IMFByteStream_Read(stream, buffer, sizeof(buffer), &length))) return hr;
if (length < sizeof(buffer))
v2: Add some tests.
Anything else I can do here?
On Tue Oct 1 10:06:51 2024 +0000, Rémi Bernon wrote:
Anything else I can do here?
No, let's have it. One thing to watch out is games that provide their own IMFByteStream implementation, in case SetPosition misbehaves there somehow. I think it was either UE or Unity.
This merge request was approved by Nikolay Sivov.