From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- dlls/mfplat/main.c | 99 +++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 59 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index cee052defeb..e28dc677cdb 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -3952,7 +3952,7 @@ static HRESULT WINAPI bytestream_stream_GetCapabilities(IMFByteStream *iface, DW return S_OK; }
-static HRESULT WINAPI bytestream_GetCapabilities(IMFByteStream *iface, DWORD *capabilities) +static HRESULT WINAPI bytestream_file_GetCapabilities(IMFByteStream *iface, DWORD *capabilities) { struct bytestream *stream = impl_from_IMFByteStream(iface);
@@ -3963,14 +3963,14 @@ static HRESULT WINAPI bytestream_GetCapabilities(IMFByteStream *iface, DWORD *ca return S_OK; }
-static HRESULT WINAPI bytestream_SetLength(IMFByteStream *iface, QWORD length) +static HRESULT WINAPI bytestream_file_SetLength(IMFByteStream *iface, QWORD length) { FIXME("%p, %s\n", iface, wine_dbgstr_longlong(length));
return E_NOTIMPL; }
-static HRESULT WINAPI bytestream_file_GetCurrentPosition(IMFByteStream *iface, QWORD *position) +static HRESULT WINAPI bytestream_GetCurrentPosition(IMFByteStream *iface, QWORD *position) { struct bytestream *stream = impl_from_IMFByteStream(iface);
@@ -4068,7 +4068,7 @@ static HRESULT WINAPI bytestream_EndRead(IMFByteStream *iface, IMFAsyncResult *r return bytestream_complete_io_request(stream, ASYNC_STREAM_OP_READ, result, byte_read); }
-static HRESULT WINAPI bytestream_Write(IMFByteStream *iface, const BYTE *data, ULONG count, ULONG *written) +static HRESULT WINAPI bytestream_file_Write(IMFByteStream *iface, const BYTE *data, ULONG count, ULONG *written) { FIXME("%p, %p, %lu, %p\n", iface, data, count, written);
@@ -4094,22 +4094,44 @@ static HRESULT WINAPI bytestream_EndWrite(IMFByteStream *iface, IMFAsyncResult * return bytestream_complete_io_request(stream, ASYNC_STREAM_OP_WRITE, result, written); }
-static HRESULT WINAPI bytestream_Seek(IMFByteStream *iface, MFBYTESTREAM_SEEK_ORIGIN seek, LONGLONG offset, - DWORD flags, QWORD *current) +static HRESULT WINAPI bytestream_Seek(IMFByteStream *iface, MFBYTESTREAM_SEEK_ORIGIN origin, LONGLONG offset, + DWORD flags, QWORD *current) { - FIXME("%p, %u, %s, 0x%08lx, %p\n", iface, seek, wine_dbgstr_longlong(offset), flags, current); + struct bytestream *stream = impl_from_IMFByteStream(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %u, %s, %#lx, %p.\n", iface, origin, wine_dbgstr_longlong(offset), flags, current); + + EnterCriticalSection(&stream->cs); + + switch (origin) + { + case msoBegin: + stream->position = offset; + break; + case msoCurrent: + stream->position += offset; + break; + default: + WARN("Unknown origin mode %d.\n", origin); + hr = E_INVALIDARG; + } + + *current = stream->position; + + LeaveCriticalSection(&stream->cs); + + return hr; }
-static HRESULT WINAPI bytestream_Flush(IMFByteStream *iface) +static HRESULT WINAPI bytestream_file_Flush(IMFByteStream *iface) { FIXME("%p\n", iface);
return E_NOTIMPL; }
-static HRESULT WINAPI bytestream_Close(IMFByteStream *iface) +static HRESULT WINAPI bytestream_file_Close(IMFByteStream *iface) { FIXME("%p\n", iface);
@@ -4134,21 +4156,21 @@ static const IMFByteStreamVtbl bytestream_file_vtbl = bytestream_QueryInterface, bytestream_AddRef, bytestream_Release, - bytestream_GetCapabilities, + bytestream_file_GetCapabilities, bytestream_file_GetLength, - bytestream_SetLength, - bytestream_file_GetCurrentPosition, + bytestream_file_SetLength, + bytestream_GetCurrentPosition, bytestream_SetCurrentPosition, bytestream_file_IsEndOfStream, bytestream_file_Read, bytestream_BeginRead, bytestream_EndRead, - bytestream_Write, + bytestream_file_Write, bytestream_BeginWrite, bytestream_EndWrite, bytestream_Seek, - bytestream_Flush, - bytestream_Close + bytestream_file_Flush, + bytestream_file_Close };
static HRESULT WINAPI bytestream_stream_GetLength(IMFByteStream *iface, QWORD *length) @@ -4185,17 +4207,6 @@ static HRESULT WINAPI bytestream_stream_SetLength(IMFByteStream *iface, QWORD le return hr; }
-static HRESULT WINAPI bytestream_stream_GetCurrentPosition(IMFByteStream *iface, QWORD *position) -{ - struct bytestream *stream = impl_from_IMFByteStream(iface); - - TRACE("%p, %p.\n", iface, position); - - *position = stream->position; - - return S_OK; -} - static HRESULT WINAPI bytestream_stream_IsEndOfStream(IMFByteStream *iface, BOOL *ret) { struct bytestream *stream = impl_from_IMFByteStream(iface); @@ -4258,36 +4269,6 @@ static HRESULT WINAPI bytestream_stream_Write(IMFByteStream *iface, const BYTE * return hr; }
-static HRESULT WINAPI bytestream_stream_Seek(IMFByteStream *iface, MFBYTESTREAM_SEEK_ORIGIN origin, LONGLONG offset, - DWORD flags, QWORD *current) -{ - struct bytestream *stream = impl_from_IMFByteStream(iface); - HRESULT hr = S_OK; - - TRACE("%p, %u, %s, %#lx, %p.\n", iface, origin, wine_dbgstr_longlong(offset), flags, current); - - EnterCriticalSection(&stream->cs); - - switch (origin) - { - case msoBegin: - stream->position = offset; - break; - case msoCurrent: - stream->position += offset; - break; - default: - WARN("Unknown origin mode %d.\n", origin); - hr = E_INVALIDARG; - } - - *current = stream->position; - - LeaveCriticalSection(&stream->cs); - - return hr; -} - static HRESULT WINAPI bytestream_stream_Flush(IMFByteStream *iface) { struct bytestream *stream = impl_from_IMFByteStream(iface); @@ -4312,7 +4293,7 @@ static const IMFByteStreamVtbl bytestream_stream_vtbl = bytestream_stream_GetCapabilities, bytestream_stream_GetLength, bytestream_stream_SetLength, - bytestream_stream_GetCurrentPosition, + bytestream_GetCurrentPosition, bytestream_SetCurrentPosition, bytestream_stream_IsEndOfStream, bytestream_stream_Read, @@ -4321,7 +4302,7 @@ static const IMFByteStreamVtbl bytestream_stream_vtbl = bytestream_stream_Write, bytestream_BeginWrite, bytestream_EndWrite, - bytestream_stream_Seek, + bytestream_Seek, bytestream_stream_Flush, bytestream_stream_Close, };
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- dlls/mfplat/main.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index e28dc677cdb..a87d388f511 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -4371,7 +4371,6 @@ static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback { struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; - LARGE_INTEGER position; IUnknown *object; HRESULT hr;
@@ -4382,13 +4381,8 @@ static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback
EnterCriticalSection(&stream->cs);
- position.QuadPart = op->position; - if (SUCCEEDED(hr = IStream_Seek(stream->stream, position, STREAM_SEEK_SET, NULL))) - { - if (SUCCEEDED(hr = IStream_Read(stream->stream, op->u.dest, op->requested_length, &op->actual_length))) - stream->position += op->actual_length; - } - + hr = IMFByteStream_Read(&stream->IMFByteStream_iface, op->u.dest, op->requested_length, &op->actual_length); + if(FAILED(hr)) TRACE("Read failed: %#lx\n", hr); IMFAsyncResult_SetStatus(op->caller, hr); list_add_tail(&stream->pending, &op->entry);
@@ -4403,7 +4397,6 @@ static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback { struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; - LARGE_INTEGER position; IUnknown *object; HRESULT hr;
@@ -4414,13 +4407,8 @@ static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback
EnterCriticalSection(&stream->cs);
- position.QuadPart = op->position; - if (SUCCEEDED(hr = IStream_Seek(stream->stream, position, STREAM_SEEK_SET, NULL))) - { - if (SUCCEEDED(hr = IStream_Write(stream->stream, op->u.src, op->requested_length, &op->actual_length))) - stream->position += op->actual_length; - } - + hr = IMFByteStream_Write(&stream->IMFByteStream_iface, op->u.src, op->requested_length, &op->actual_length); + if(FAILED(hr)) TRACE("Write failed: %#lx\n", hr); IMFAsyncResult_SetStatus(op->caller, hr); list_add_tail(&stream->pending, &op->entry);
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- dlls/mfplat/main.c | 52 +++++++++------------------------------------- 1 file changed, 10 insertions(+), 42 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index a87d388f511..04060a78b90 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -4367,7 +4367,7 @@ static const IMFAttributesVtbl bytestream_attributes_vtbl = mfattributes_CopyAllItems };
-static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) +static HRESULT WINAPI bytestream_read_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; @@ -4393,7 +4393,7 @@ static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback return S_OK; }
-static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) +static HRESULT WINAPI bytestream_write_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; @@ -4419,22 +4419,22 @@ static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback return S_OK; }
-static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_read_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_read_callback_AddRef, bytestream_read_callback_Release, bytestream_callback_GetParameters, - bytestream_stream_read_callback_Invoke, + bytestream_read_callback_Invoke, };
-static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_write_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_write_callback_AddRef, bytestream_write_callback_Release, bytestream_callback_GetParameters, - bytestream_stream_write_callback_Invoke, + bytestream_write_callback_Invoke, };
/*********************************************************************** @@ -4460,8 +4460,8 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt
object->IMFByteStream_iface.lpVtbl = &bytestream_stream_vtbl; object->attributes.IMFAttributes_iface.lpVtbl = &bytestream_attributes_vtbl; - object->read_callback.lpVtbl = &bytestream_stream_read_callback_vtbl; - object->write_callback.lpVtbl = &bytestream_stream_write_callback_vtbl; + object->read_callback.lpVtbl = &bytestream_read_callback_vtbl; + object->write_callback.lpVtbl = &bytestream_write_callback_vtbl; InitializeCriticalSection(&object->cs); list_init(&object->pending);
@@ -4485,38 +4485,6 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt return S_OK; }
-static HRESULT WINAPI bytestream_file_read_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) -{ - FIXME("%p, %p.\n", iface, result); - - return E_NOTIMPL; -} - -static HRESULT WINAPI bytestream_file_write_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) -{ - FIXME("%p, %p.\n", iface, result); - - return E_NOTIMPL; -} - -static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl = -{ - bytestream_callback_QueryInterface, - bytestream_read_callback_AddRef, - bytestream_read_callback_Release, - bytestream_callback_GetParameters, - bytestream_file_read_callback_Invoke, -}; - -static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl = -{ - bytestream_callback_QueryInterface, - bytestream_write_callback_AddRef, - bytestream_write_callback_Release, - bytestream_callback_GetParameters, - bytestream_file_write_callback_Invoke, -}; - static HRESULT WINAPI bytestream_file_getservice_QueryInterface(IMFGetService *iface, REFIID riid, void **obj) { struct bytestream *stream = impl_bytestream_from_IMFGetService(iface); @@ -4623,8 +4591,8 @@ static HRESULT create_file_bytestream(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPE object->IMFByteStream_iface.lpVtbl = &bytestream_file_vtbl; object->attributes.IMFAttributes_iface.lpVtbl = &bytestream_attributes_vtbl; object->IMFGetService_iface.lpVtbl = &bytestream_file_getservice_vtbl; - object->read_callback.lpVtbl = &bytestream_file_read_callback_vtbl; - object->write_callback.lpVtbl = &bytestream_file_write_callback_vtbl; + object->read_callback.lpVtbl = &bytestream_read_callback_vtbl; + object->write_callback.lpVtbl = &bytestream_write_callback_vtbl; InitializeCriticalSection(&object->cs); list_init(&object->pending); object->capabilities = capabilities;
From: Andrew Eikum aeikum@codeweavers.com
Signed-off-by: Andrew Eikum aeikum@codeweavers.com --- dlls/mfplat/tests/mfplat.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 8d21f2ed60e..101d06f5cb5 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -1962,6 +1962,7 @@ static void test_MFCreateMFByteStreamOnStream(void) ULONG ref, size; HRESULT hr; UINT count; + QWORD to;
if(!pMFCreateMFByteStreamOnStream) { @@ -2045,11 +2046,45 @@ static void test_MFCreateMFByteStreamOnStream(void) ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr); ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
+ /* IMFByteStream maintains position separately from IStream */ + caps = 0; + hr = IStream_Read(stream, &caps, sizeof(caps), &size); + ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr); + ok(size == 4, "Unexpected size.\n"); + ok(caps == 0xffff0000, "Unexpected content.\n"); + caps = 0; hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size); ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(size == 4, "Unexpected size.\n"); ok(caps == 0xffff0000, "Unexpected content.\n");
+ caps = 0; + hr = IStream_Read(stream, &caps, sizeof(caps), &size); + ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr); + ok(size == 0, "Unexpected size.\n"); + ok(caps == 0, "Unexpected content.\n"); + + hr = IMFByteStream_Seek(bytestream, msoBegin, 0, 0, &to); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + + hr = IStream_Read(stream, &caps, sizeof(caps), &size); + ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr); + ok(size == 0, "Unexpected size.\n"); + ok(caps == 0, "Unexpected content.\n"); + + caps = 0; + hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(size == 4, "Unexpected size.\n"); + ok(caps == 0xffff0000, "Unexpected content.\n"); + + caps = 0; + hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(size == 0, "Unexpected size.\n"); + ok(caps == 0, "Unexpected content.\n"); + IMFAttributes_Release(attributes); IMFByteStream_Release(bytestream); IStream_Release(stream);
For async read/write, I'm going to check if RTWQASYNCRESULT fields like overlapped structure and byte count are used, maybe it should be using async io.
As far as I can tell disk file case works a bit differently on Windows. It's using dwBytesTransferred, and probably some of OVERLAPPED fields, e.g. EndRead()/EndWrite() will return precisely what's in dwByteTransferred. Unfortunately it's not that straightforward, and some internal bookkeeping is still happening and End* methods can't solely rely on result data. Buy let's ignore that for now, it's not clear of bringing async IO to already async MF reads is worth it.
This merge request was approved by Nikolay Sivov.