From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/media_source.c | 75 ++++++++++++--------- dlls/winegstreamer/quartz_parser.c | 49 +++++++++----- dlls/winegstreamer/wm_reader.c | 102 +++++++++++++++-------------- 3 files changed, 129 insertions(+), 97 deletions(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index f07b83f413e..ac23b1bc94c 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -592,12 +592,54 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = source_async_commands_Invoke, };
+static void handle_read_request(struct media_source *source, QWORD file_size, + void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size) +{ + IMFByteStream *byte_stream = source->byte_stream; + ULONG ret_size = 0; + HRESULT hr; + void *data; + + if (offset >= file_size) + size = 0; + else if (offset + size >= file_size) + size = file_size - offset; + + if (!array_reserve(buffer, buffer_size, size, 1)) + { + wg_parser_push_data(source->wg_parser, NULL, 0); + return; + } + data = *buffer; + + /* Some IMFByteStreams (including the standard file-based stream) return + * an error when reading past the file size. */ + + if (!size) + hr = S_OK; + else if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset))) + hr = IMFByteStream_Read(byte_stream, data, size, &ret_size); + + if (FAILED(hr)) + { + ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); + data = NULL; + } + else if (ret_size != size) + { + ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size); + size = ret_size; + } + + wg_parser_push_data(source->wg_parser, data, size); +} + static DWORD CALLBACK read_thread(void *arg) { struct media_source *source = arg; IMFByteStream *byte_stream = source->byte_stream; size_t buffer_size = 4096; - uint64_t file_size; + QWORD file_size; void *data;
if (!(data = malloc(buffer_size))) @@ -610,41 +652,12 @@ static DWORD CALLBACK read_thread(void *arg) while (!source->read_thread_shutdown) { uint64_t offset; - ULONG ret_size; uint32_t size; - HRESULT hr;
if (!wg_parser_get_next_read_offset(source->wg_parser, &offset, &size)) continue;
- if (offset >= file_size) - size = 0; - else if (offset + size >= file_size) - size = file_size - offset; - - /* Some IMFByteStreams (including the standard file-based stream) return - * an error when reading past the file size. */ - if (!size) - { - wg_parser_push_data(source->wg_parser, data, 0); - continue; - } - - if (!array_reserve(&data, &buffer_size, size, 1)) - { - free(data); - return 0; - } - - ret_size = 0; - - if (SUCCEEDED(hr = IMFByteStream_SetCurrentPosition(byte_stream, offset))) - hr = IMFByteStream_Read(byte_stream, data, size, &ret_size); - if (FAILED(hr)) - ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - else if (ret_size != size) - ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size); - wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size); + handle_read_request(source, file_size, &data, &buffer_size, offset, size); }
free(data); diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 34848c0b503..0e9f183d499 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -865,12 +865,41 @@ static DWORD CALLBACK stream_thread(void *arg) return 0; }
+static void handle_read_request(struct parser *filter, LONGLONG file_size, + void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size) +{ + HRESULT hr; + void *data; + + if (offset >= file_size) + size = 0; + else if (offset + size >= file_size) + size = file_size - offset; + + if (!array_reserve(buffer, buffer_size, size, 1)) + { + wg_parser_push_data(filter->wg_parser, NULL, 0); + return; + } + data = *buffer; + + hr = IAsyncReader_SyncRead(filter->reader, offset, size, data); + + if (FAILED(hr)) + { + ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); + data = NULL; + } + + wg_parser_push_data(filter->wg_parser, data, size); +} + static DWORD CALLBACK read_thread(void *arg) { struct parser *filter = arg; LONGLONG file_size, unused; size_t buffer_size = 4096; - void *data = NULL; + void *data;
if (!(data = malloc(buffer_size))) return 0; @@ -883,27 +912,11 @@ static DWORD CALLBACK read_thread(void *arg) { uint64_t offset; uint32_t size; - HRESULT hr;
if (!wg_parser_get_next_read_offset(filter->wg_parser, &offset, &size)) continue;
- if (offset >= file_size) - size = 0; - else if (offset + size >= file_size) - size = file_size - offset; - - if (!array_reserve(&data, &buffer_size, size, 1)) - { - free(data); - return 0; - } - - hr = IAsyncReader_SyncRead(filter->reader, offset, size, data); - if (FAILED(hr)) - ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - - wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size); + handle_read_request(filter, file_size, &data, &buffer_size, offset, size); }
free(data); diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 03adea8a318..9d1eb2a95ed 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -526,6 +526,59 @@ static const IWMMediaPropsVtbl stream_props_vtbl = stream_props_SetMediaType, };
+static void handle_read_request(struct wm_reader *reader, uint64_t file_size, + void **buffer, size_t *buffer_size, uint64_t offset, uint32_t size) +{ + IStream *stream = reader->source_stream; + LARGE_INTEGER large_offset; + HANDLE file = reader->file; + ULONG ret_size = 0; + HRESULT hr; + void *data; + + if (offset >= file_size) + size = 0; + else if (offset + size >= file_size) + size = file_size - offset; + + if (!array_reserve(buffer, buffer_size, size, 1)) + { + wg_parser_push_data(reader->wg_parser, NULL, 0); + return; + } + data = *buffer; + + large_offset.QuadPart = offset; + if (!size) + hr = S_OK; + else if (file) + { + if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN) + || !ReadFile(file, data, size, &ret_size, NULL)) + hr = HRESULT_FROM_WIN32(GetLastError()); + else + hr = S_OK; + } + else + { + if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL))) + hr = IStream_Read(stream, data, size, &ret_size); + } + + if (FAILED(hr)) + { + ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); + data = NULL; + } + else if (ret_size != size) + { + ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size); + size = ret_size; + } + + wg_parser_push_data(reader->wg_parser, data, size); +} + static DWORD CALLBACK read_thread(void *arg) { struct wm_reader *reader = arg; @@ -557,60 +610,13 @@ static DWORD CALLBACK read_thread(void *arg)
while (!reader->read_thread_shutdown) { - LARGE_INTEGER large_offset; uint64_t offset; - ULONG ret_size; uint32_t size; - HRESULT hr;
if (!wg_parser_get_next_read_offset(reader->wg_parser, &offset, &size)) continue;
- if (offset >= file_size) - size = 0; - else if (offset + size >= file_size) - size = file_size - offset; - - if (!size) - { - wg_parser_push_data(reader->wg_parser, data, 0); - continue; - } - - if (!array_reserve(&data, &buffer_size, size, 1)) - { - free(data); - return 0; - } - - ret_size = 0; - - large_offset.QuadPart = offset; - if (file) - { - if (!SetFilePointerEx(file, large_offset, NULL, FILE_BEGIN) - || !ReadFile(file, data, size, &ret_size, NULL)) - { - ERR("Failed to read %u bytes at offset %I64u, error %lu.\n", size, offset, GetLastError()); - wg_parser_push_data(reader->wg_parser, NULL, 0); - continue; - } - } - else - { - if (SUCCEEDED(hr = IStream_Seek(stream, large_offset, STREAM_SEEK_SET, NULL))) - hr = IStream_Read(stream, data, size, &ret_size); - if (FAILED(hr)) - { - ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr); - wg_parser_push_data(reader->wg_parser, NULL, 0); - continue; - } - } - - if (ret_size != size) - ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size); - wg_parser_push_data(reader->wg_parser, data, ret_size); + handle_read_request(reader, file_size, &data, &buffer_size, offset, size); }
free(data);