This supersedes merge request 116.
-- v2: qasf: Implement ASF Reader filter stream stubs. qasf: Create and open a WMReader in the ASF Reader filter. qasf: Rename variables and functions. qasf: Constify filter_ops. qasf/tests: Add more ASF Reader filter tests.
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/tests/Makefile.in | 2 + dlls/qasf/tests/asfreader.c | 234 +++++++++++++++++++++++++++++++++++- dlls/qasf/tests/resource.rc | 25 ++++ dlls/qasf/tests/test.wmv | Bin 0 -> 45663 bytes 4 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 dlls/qasf/tests/resource.rc create mode 100644 dlls/qasf/tests/test.wmv
diff --git a/dlls/qasf/tests/Makefile.in b/dlls/qasf/tests/Makefile.in index 4b8d40671fb..bc962ebb657 100644 --- a/dlls/qasf/tests/Makefile.in +++ b/dlls/qasf/tests/Makefile.in @@ -4,3 +4,5 @@ IMPORTS = strmbase dmoguids strmiids uuid msdmo ole32 C_SRCS = \ asfreader.c \ dmowrapper.c + +RC_SRCS = resource.rc diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c index f4f8b9e2e19..54c38263464 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -21,18 +21,21 @@
#define COBJMACROS
+#include <stdbool.h> #include "dshow.h" +#include "mediaobj.h" +#include "propsys.h" +#include "dvdmedia.h" #include "wine/strmbase.h" #include "wine/test.h"
#include "initguid.h" +#include "wmsdk.h" +#include "wmcodecdsp.h"
+DEFINE_GUID(WMMEDIASUBTYPE_WMV1,0x31564d57,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); static const GUID testguid = {0x22222222, 0x2222, 0x2222, {0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}};
-DEFINE_GUID(IID_IWMHeaderInfo, 0x96406bda, 0x2b2b, 0x11d3, 0xb3, 0x6b, 0x00, 0xc0, 0x4f, 0x61, 0x08, 0xff); -DEFINE_GUID(IID_IWMReaderAdvanced, 0x96406bea, 0x2b2b, 0x11d3, 0xb3, 0x6b, 0x00, 0xc0, 0x4f, 0x61, 0x08, 0xff); -DEFINE_GUID(IID_IWMReaderAdvanced2, 0xae14a945, 0xb90c, 0x4d0d, 0x91, 0x27, 0x80, 0xd6, 0x65, 0xf7, 0xd7, 0x3e); - static IBaseFilter *create_asf_reader(void) { IBaseFilter *filter = NULL; @@ -45,6 +48,31 @@ static IBaseFilter *create_asf_reader(void) return filter; }
+static WCHAR *load_resource(const WCHAR *name) +{ + static WCHAR pathW[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(ARRAY_SIZE(pathW), pathW); + wcscat(pathW, name); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %lu.\n", + wine_dbgstr_w(pathW), GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok(!!res, "Failed to load resource, error %lu.\n", GetLastError()); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n"); + CloseHandle(file); + + return pathW; +} + static ULONG get_refcount(void *iface) { IUnknown *unknown = iface; @@ -183,8 +211,146 @@ static void test_aggregation(void) ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref); }
+static bool compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) +{ + return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat)) + && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); +} + +static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expect_dir, + const WCHAR *expect_name, const WCHAR *expect_id, AM_MEDIA_TYPE *expect_mt, unsigned int expect_mt_count) +{ + IEnumMediaTypes *enum_mt; + AM_MEDIA_TYPE *mt; + unsigned int i; + PIN_INFO info; + HRESULT hr; + WCHAR *id; + + hr = IPin_QueryPinInfo(pin, &info); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(info.pFilter == expect_filter, "Got filter %p.\n", info.pFilter); + ok(info.dir == expect_dir, "Got dir %#x.\n", info.dir); + todo_wine + ok(!wcscmp(info.achName, expect_name), "Got name %s.\n", debugstr_w(info.achName)); + IBaseFilter_Release(info.pFilter); + + hr = IPin_QueryId(pin, &id); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(id, expect_id), "Got id %s.\n", debugstr_w(id)); + CoTaskMemFree(id); + + hr = IPin_EnumMediaTypes(pin, &enum_mt); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr != S_OK) goto skip_enum_mt; + for (i = 0; (hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL)) == S_OK; i++) + { + if (i < expect_mt_count) + { + todo_wine + ok(compare_media_types(mt, expect_mt + i), "Media type %u didn't match.\n", i); + } + FreeMediaType(mt); + CoTaskMemFree(mt); + } + todo_wine + ok(i == expect_mt_count, "Got %u types.\n", i); + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + IEnumMediaTypes_Release(enum_mt); + +skip_enum_mt: + check_interface(pin, &IID_IPin, TRUE); + check_interface(pin, &IID_IUnknown, TRUE); + todo_wine + check_interface(pin, &IID_IMediaSeeking, TRUE); + todo_wine + check_interface(pin, &IID_IQualityControl, TRUE); + check_interface(pin, &IID_IServiceProvider, FALSE); + check_interface(pin, &IID_IWMStreamConfig, FALSE); +} + static void test_filesourcefilter(void) { + static const MSAUDIO1WAVEFORMAT msaudio1_format = + { + .wfx.wFormatTag = WAVE_FORMAT_MSAUDIO1, + .wfx.nChannels = 1, + .wfx.nSamplesPerSec = 44100, + .wfx.nBlockAlign = 743, + .wfx.nAvgBytesPerSec = 16000, + .wfx.wBitsPerSample = 16, + .wfx.cbSize = sizeof(MSAUDIO1WAVEFORMAT) - sizeof(WAVEFORMATEX), + .wEncodeOptions = 1, + }; + static const VIDEOINFOHEADER2 wmv1_info2 = + { + .rcSource = {0, 0, 64, 48}, + .rcTarget = {0, 0, 64, 48}, + .dwBitRate = 189464, + .dwPictAspectRatioX = 64, + .dwPictAspectRatioY = 48, + .bmiHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 64, + .biHeight = 48, + .biPlanes = 1, + .biBitCount = 24, + .biCompression = MAKEFOURCC('W','M','V','1'), + .biSizeImage = 64 * 48 * 3, + }, + }; + static const VIDEOINFOHEADER wmv1_info = + { + .rcSource = {0, 0, 64, 48}, + .rcTarget = {0, 0, 64, 48}, + .dwBitRate = 189464, + .bmiHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 64, + .biHeight = 48, + .biPlanes = 1, + .biBitCount = 24, + .biCompression = MAKEFOURCC('W','M','V','1'), + .biSizeImage = 64 * 48 * 3, + }, + }; + AM_MEDIA_TYPE audio_mt[] = + { + { + .majortype = MEDIATYPE_Audio, + .subtype = MEDIASUBTYPE_MSAUDIO1, + .bFixedSizeSamples = TRUE, + .lSampleSize = 743, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(MSAUDIO1WAVEFORMAT), + .pbFormat = (BYTE *)&msaudio1_format, + }, + }; + AM_MEDIA_TYPE video_mt[] = + { + { + .majortype = MEDIATYPE_Video, + .subtype = WMMEDIASUBTYPE_WMV1, + .formattype = FORMAT_VideoInfo2, + .bTemporalCompression = TRUE, + .cbFormat = sizeof(VIDEOINFOHEADER2), + .pbFormat = (BYTE *)&wmv1_info2, + }, + { + .majortype = MEDIATYPE_Video, + .subtype = WMMEDIASUBTYPE_WMV1, + .formattype = FORMAT_VideoInfo, + .bTemporalCompression = TRUE, + .cbFormat = sizeof(VIDEOINFOHEADER), + .pbFormat = (BYTE *)&wmv1_info, + }, + }; + + const WCHAR *filename = load_resource(L"test.wmv"); IBaseFilter *filter = create_asf_reader(); IFileSourceFilter *filesource; IFilterGraph2 *graph; @@ -289,6 +455,66 @@ static void test_filesourcefilter(void) ok(type.pbFormat == ptr, "Got format block %p.\n", type.pbFormat); CoTaskMemFree(olepath);
+ hr = IFileSourceFilter_Load(filesource, filename, NULL); + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + IBaseFilter_Release(filter); + ref = IFileSourceFilter_Release(filesource); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + + + filter = create_asf_reader(); + hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFileSourceFilter_Load(filesource, filename, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFilterGraph2_AddFilter(graph, filter, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + olepath = (void *)0xdeadbeef; + memset(&type, 0x22, sizeof(type)); + hr = IFileSourceFilter_GetCurFile(filesource, &olepath, &type); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!wcscmp(olepath, filename), "Got file %s.\n", wine_dbgstr_w(olepath)); + ok(IsEqualGUID(&type.majortype, &MEDIATYPE_NULL), "Got majortype %s.\n", + wine_dbgstr_guid(&type.majortype)); + ok(IsEqualGUID(&type.subtype, &MEDIASUBTYPE_NULL), "Got subtype %s.\n", + wine_dbgstr_guid(&type.subtype)); + ok(type.bFixedSizeSamples == 0x22222222, "Got fixed size %d.\n", type.bFixedSizeSamples); + ok(type.bTemporalCompression == 0x22222222, "Got temporal compression %d.\n", type.bTemporalCompression); + ok(!type.lSampleSize, "Got sample size %lu.\n", type.lSampleSize); + ok(IsEqualGUID(&type.formattype, &testguid), "Got format type %s.\n", wine_dbgstr_guid(&type.formattype)); + ok(!type.pUnk, "Got pUnk %p.\n", type.pUnk); + ok(!type.cbFormat, "Got format size %lu.\n", type.cbFormat); + ok(type.pbFormat == ptr, "Got format block %p.\n", type.pbFormat); + CoTaskMemFree(olepath); + + hr = IBaseFilter_EnumPins(filter, &enumpins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IEnumPins_Next(enumpins, 1, pins, NULL); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr != S_OK) goto skip_pins; + check_pin(pins[0], filter, PINDIR_OUTPUT, L"Raw Video 0", L"Raw Video 0", video_mt, ARRAY_SIZE(video_mt)); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enumpins, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + check_pin(pins[0], filter, PINDIR_OUTPUT, L"Raw Audio 1", L"Raw Audio 1", audio_mt, ARRAY_SIZE(audio_mt)); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enumpins, 1, pins, NULL); +skip_pins: + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + IEnumPins_Release(enumpins); + ref = IFilterGraph2_Release(graph); ok(!ref, "Got outstanding refcount %ld.\n", ref); IBaseFilter_Release(filter); diff --git a/dlls/qasf/tests/resource.rc b/dlls/qasf/tests/resource.rc new file mode 100644 index 00000000000..2d5184b3f73 --- /dev/null +++ b/dlls/qasf/tests/resource.rc @@ -0,0 +1,25 @@ +/* + * Resource file for qasf tests. + * + * Copyright 2022 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" + +/* ffmpeg -f lavfi -i smptebars -f lavfi -i "sine=frequency=700" -t 2.0 -f asf -vcodec wmv1 -vf scale=64x48 -acodec wmav1 test.wmv */ +/* @makedep: test.wmv */ +test.wmv RCDATA test.wmv diff --git a/dlls/qasf/tests/test.wmv b/dlls/qasf/tests/test.wmv new file mode 100644 index 0000000000000000000000000000000000000000..fa953771cd31213ec24bef9000127125047e0623 GIT binary patch literal 45663 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
literal 0 HcmV?d00001
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/asfreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index a037728079f..ba782f19ad9 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -66,7 +66,7 @@ static HRESULT asf_reader_query_interface(struct strmbase_filter *iface, REFIID return E_NOINTERFACE; }
-static struct strmbase_filter_ops filter_ops = +static const struct strmbase_filter_ops filter_ops = { .filter_get_pin = asf_reader_get_pin, .filter_destroy = asf_reader_destroy,
This merge request was approved by Alexandre Julliard.
From: Rémi Bernon rbernon@codeweavers.com
* filesourcefilter_ prefix to file_source_. * type to media_type. * filename to file_name. * impl_reader_from_strmbase_filter to impl_from_strmbase_filter.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/asfreader.c | 76 +++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index ba782f19ad9..a657b719456 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -27,11 +27,11 @@ struct asf_reader struct strmbase_filter filter; IFileSourceFilter IFileSourceFilter_iface;
- AM_MEDIA_TYPE type; - WCHAR *filename; + AM_MEDIA_TYPE media_type; + WCHAR *file_name; };
-static inline struct asf_reader *impl_reader_from_strmbase_filter(struct strmbase_filter *iface) +static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) { return CONTAINING_RECORD(iface, struct asf_reader, filter); } @@ -43,10 +43,10 @@ static struct strmbase_pin *asf_reader_get_pin(struct strmbase_filter *iface, un
static void asf_reader_destroy(struct strmbase_filter *iface) { - struct asf_reader *filter = impl_reader_from_strmbase_filter(iface); + struct asf_reader *filter = impl_from_strmbase_filter(iface);
- free(filter->filename); - FreeMediaType(&filter->type); + free(filter->file_name); + FreeMediaType(&filter->media_type);
strmbase_filter_cleanup(&filter->filter); free(filter); @@ -54,7 +54,7 @@ static void asf_reader_destroy(struct strmbase_filter *iface)
static HRESULT asf_reader_query_interface(struct strmbase_filter *iface, REFIID iid, void **out) { - struct asf_reader *filter = impl_reader_from_strmbase_filter(iface); + struct asf_reader *filter = impl_from_strmbase_filter(iface);
if (IsEqualGUID(iid, &IID_IFileSourceFilter)) { @@ -78,84 +78,84 @@ static inline struct asf_reader *impl_from_IFileSourceFilter(IFileSourceFilter * return CONTAINING_RECORD(iface, struct asf_reader, IFileSourceFilter_iface); }
-static HRESULT WINAPI filesourcefilter_QueryInterface(IFileSourceFilter *iface, REFIID iid, void **out) +static HRESULT WINAPI file_source_QueryInterface(IFileSourceFilter *iface, REFIID iid, void **out) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface);
return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out); }
-static ULONG WINAPI filesourcefilter_AddRef(IFileSourceFilter *iface) +static ULONG WINAPI file_source_AddRef(IFileSourceFilter *iface) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface);
return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface); }
-static ULONG WINAPI filesourcefilter_Release(IFileSourceFilter *iface) +static ULONG WINAPI file_source_Release(IFileSourceFilter *iface) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface);
return IBaseFilter_Release(&filter->filter.IBaseFilter_iface); }
-static HRESULT WINAPI filesourcefilter_Load(IFileSourceFilter *iface, LPCOLESTR filename, const AM_MEDIA_TYPE *type) +static HRESULT WINAPI file_source_Load(IFileSourceFilter *iface, LPCOLESTR file_name, const AM_MEDIA_TYPE *media_type) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface);
- TRACE("filter %p, filename %s, type %p.\n", filter, debugstr_w(filename), type); - strmbase_dump_media_type(type); + TRACE("filter %p, file_name %s, media_type %p.\n", filter, debugstr_w(file_name), media_type); + strmbase_dump_media_type(media_type);
- if (!filename) + if (!file_name) return E_POINTER;
- if (filter->filename) + if (filter->file_name) return E_FAIL;
- if (!(filter->filename = wcsdup(filename))) + if (!(filter->file_name = wcsdup(file_name))) return E_OUTOFMEMORY;
- if (type) - CopyMediaType(&filter->type, type); + if (media_type) + CopyMediaType(&filter->media_type, media_type);
return S_OK; }
-static HRESULT WINAPI filesourcefilter_GetCurFile(IFileSourceFilter *iface, LPOLESTR *filename, AM_MEDIA_TYPE *type) +static HRESULT WINAPI file_source_GetCurFile(IFileSourceFilter *iface, LPOLESTR *file_name, AM_MEDIA_TYPE *media_type) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface);
- TRACE("filter %p, filename %p, type %p.\n", filter, filename, type); + TRACE("filter %p, file_name %p, media_type %p.\n", filter, file_name, media_type);
- if (!filename) + if (!file_name) return E_POINTER; - *filename = NULL; + *file_name = NULL;
- if (type) + if (media_type) { - type->majortype = filter->type.majortype; - type->subtype = filter->type.subtype; - type->lSampleSize = filter->type.lSampleSize; - type->pUnk = filter->type.pUnk; - type->cbFormat = filter->type.cbFormat; + media_type->majortype = filter->media_type.majortype; + media_type->subtype = filter->media_type.subtype; + media_type->lSampleSize = filter->media_type.lSampleSize; + media_type->pUnk = filter->media_type.pUnk; + media_type->cbFormat = filter->media_type.cbFormat; }
- if (filter->filename) + if (filter->file_name) { - *filename = CoTaskMemAlloc((wcslen(filter->filename) + 1) * sizeof(WCHAR)); - wcscpy(*filename, filter->filename); + *file_name = CoTaskMemAlloc((wcslen(filter->file_name) + 1) * sizeof(WCHAR)); + wcscpy(*file_name, filter->file_name); }
return S_OK; }
-static const IFileSourceFilterVtbl filesourcefilter_vtbl = +static const IFileSourceFilterVtbl file_source_vtbl = { - filesourcefilter_QueryInterface, - filesourcefilter_AddRef, - filesourcefilter_Release, - filesourcefilter_Load, - filesourcefilter_GetCurFile, + file_source_QueryInterface, + file_source_AddRef, + file_source_Release, + file_source_Load, + file_source_GetCurFile, };
HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) @@ -166,7 +166,7 @@ HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) return E_OUTOFMEMORY;
strmbase_filter_init(&object->filter, outer, &CLSID_WMAsfReader, &filter_ops); - object->IFileSourceFilter_iface.lpVtbl = &filesourcefilter_vtbl; + object->IFileSourceFilter_iface.lpVtbl = &file_source_vtbl;
TRACE("Created WM ASF reader %p.\n", object); *out = &object->filter.IUnknown_inner;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115527
Your paranoid android.
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The win32 Wine build failed
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The wow64 Wine build failed
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/Makefile.in | 2 +- dlls/qasf/asfreader.c | 124 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/dlls/qasf/Makefile.in b/dlls/qasf/Makefile.in index ee8fd0451e1..05c947b6255 100644 --- a/dlls/qasf/Makefile.in +++ b/dlls/qasf/Makefile.in @@ -1,5 +1,5 @@ MODULE = qasf.dll -IMPORTS = strmbase dmoguids strmiids uuid ole32 oleaut32 +IMPORTS = strmbase dmoguids strmiids uuid ole32 oleaut32 wmvcore
C_SRCS = \ asfreader.c \ diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index a657b719456..b65529ec3bf 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -20,6 +20,11 @@
#include "qasf_private.h"
+#include "mediaobj.h" +#include "propsys.h" +#include "initguid.h" +#include "wmsdkidl.h" + WINE_DEFAULT_DEBUG_CHANNEL(quartz);
struct asf_reader @@ -29,6 +34,9 @@ struct asf_reader
AM_MEDIA_TYPE media_type; WCHAR *file_name; + + IWMReaderCallback *callback; + IWMReader *reader; };
static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -47,6 +55,8 @@ static void asf_reader_destroy(struct strmbase_filter *iface)
free(filter->file_name); FreeMediaType(&filter->media_type); + IWMReaderCallback_Release(filter->callback); + IWMReader_Release(filter->reader);
strmbase_filter_cleanup(&filter->filter); free(filter); @@ -102,6 +112,7 @@ static ULONG WINAPI file_source_Release(IFileSourceFilter *iface) static HRESULT WINAPI file_source_Load(IFileSourceFilter *iface, LPCOLESTR file_name, const AM_MEDIA_TYPE *media_type) { struct asf_reader *filter = impl_from_IFileSourceFilter(iface); + HRESULT hr;
TRACE("filter %p, file_name %s, media_type %p.\n", filter, debugstr_w(file_name), media_type); strmbase_dump_media_type(media_type); @@ -118,6 +129,9 @@ static HRESULT WINAPI file_source_Load(IFileSourceFilter *iface, LPCOLESTR file_ if (media_type) CopyMediaType(&filter->media_type, media_type);
+ if (FAILED(hr = IWMReader_Open(filter->reader, filter->file_name, filter->callback, NULL))) + WARN("Failed to open WM reader, hr %#lx.\n", hr); + return S_OK; }
@@ -158,13 +172,123 @@ static const IFileSourceFilterVtbl file_source_vtbl = file_source_GetCurFile, };
+struct asf_callback +{ + IWMReaderCallback IWMReaderCallback_iface; + LONG ref; + + struct asf_reader *filter; +}; + +static inline struct asf_callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface) +{ + return CONTAINING_RECORD(iface, struct asf_callback, IWMReaderCallback_iface); +} + +static HRESULT WINAPI reader_callback_QueryInterface(IWMReaderCallback *iface, const IID *iid, void **out) +{ + struct asf_callback *callback = impl_from_IWMReaderCallback(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IWMStatusCallback) + || IsEqualGUID(iid, &IID_IWMReaderCallback)) + *out = &callback->IWMReaderCallback_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI reader_callback_AddRef(IWMReaderCallback *iface) +{ + struct asf_callback *callback = impl_from_IWMReaderCallback(iface); + ULONG ref = InterlockedIncrement(&callback->ref); + + TRACE("%p increasing ref to %lu.\n", callback, ref); + + return ref; +} + +static ULONG WINAPI reader_callback_Release(IWMReaderCallback *iface) +{ + struct asf_callback *callback = impl_from_IWMReaderCallback(iface); + ULONG ref = InterlockedDecrement(&callback->ref); + + TRACE("%p decreasing ref to %lu.\n", callback, ref); + + if (!ref) + free(callback); + + return ref; +} + +static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS status, HRESULT hr, + WMT_ATTR_DATATYPE type, BYTE *value, void *context) +{ + FIXME("iface %p, status %d, hr %#lx, type %d, value %p, context %p stub!\n", + iface, status, hr, type, value, context); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_callback_OnSample(IWMReaderCallback *iface, DWORD output, QWORD time, + QWORD duration, DWORD flags, INSSBuffer *sample, void *context) +{ + FIXME("iface %p, output %lu, time %I64u, duration %I64u, flags %#lx, sample %p, context %p stub!\n", + iface, output, time, duration, flags, sample, context); + return E_NOTIMPL; +} + +static const IWMReaderCallbackVtbl reader_callback_vtbl = +{ + reader_callback_QueryInterface, + reader_callback_AddRef, + reader_callback_Release, + reader_callback_OnStatus, + reader_callback_OnSample, +}; + +static HRESULT asf_callback_create(struct asf_reader *filter, IWMReaderCallback **out) +{ + struct asf_callback *callback; + + if (!(callback = calloc(1, sizeof(*callback)))) + return E_OUTOFMEMORY; + + callback->IWMReaderCallback_iface.lpVtbl = &reader_callback_vtbl; + callback->filter = filter; + callback->ref = 1; + + *out = &callback->IWMReaderCallback_iface; + return S_OK; +} + HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) { struct asf_reader *object; + HRESULT hr;
if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
+ if (FAILED(hr = WMCreateReader(NULL, 0, &object->reader))) + { + free(object); + return hr; + } + if (FAILED(hr = asf_callback_create(object, &object->callback))) + { + IWMReader_Release(object->reader); + free(object); + return hr; + } + strmbase_filter_init(&object->filter, outer, &CLSID_WMAsfReader, &filter_ops); object->IFileSourceFilter_iface.lpVtbl = &file_source_vtbl;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115528
Your paranoid android.
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The win32 Wine build failed
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The wow64 Wine build failed
From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/asfreader.c | 92 +++++++++++++++++++++++++++++++++++-- dlls/qasf/tests/asfreader.c | 6 --- 2 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index b65529ec3bf..13b6e2d7bbe 100644 --- a/dlls/qasf/asfreader.c +++ b/dlls/qasf/asfreader.c @@ -27,6 +27,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+struct asf_stream +{ + struct strmbase_source source; + DWORD index; +}; + struct asf_reader { struct strmbase_filter filter; @@ -37,6 +43,9 @@ struct asf_reader
IWMReaderCallback *callback; IWMReader *reader; + + UINT stream_count; + struct asf_stream streams[16]; };
static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -46,12 +55,31 @@ static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filte
static struct strmbase_pin *asf_reader_get_pin(struct strmbase_filter *iface, unsigned int index) { - return NULL; + struct asf_reader *filter = impl_from_strmbase_filter(iface); + struct strmbase_pin *pin = NULL; + + TRACE("iface %p, index %u.\n", iface, index); + + EnterCriticalSection(&filter->filter.filter_cs); + if (index < filter->stream_count) + pin = &filter->streams[index].source.pin; + LeaveCriticalSection(&filter->filter.filter_cs); + + return pin; }
static void asf_reader_destroy(struct strmbase_filter *iface) { struct asf_reader *filter = impl_from_strmbase_filter(iface); + struct strmbase_source *source; + + while (filter->stream_count--) + { + source = &filter->streams[filter->stream_count].source; + if (source->pin.peer) IPin_Disconnect(source->pin.peer); + IPin_Disconnect(&source->pin.IPin_iface); + strmbase_source_cleanup(source); + }
free(filter->file_name); FreeMediaType(&filter->media_type); @@ -83,6 +111,20 @@ static const struct strmbase_filter_ops filter_ops = .filter_query_interface = asf_reader_query_interface, };
+static HRESULT WINAPI asf_reader_DecideBufferSize(struct strmbase_source *iface, + IMemAllocator *allocator, ALLOCATOR_PROPERTIES *req_props) +{ + FIXME("iface %p, allocator %p, req_props %p stub!\n", iface, allocator, req_props); + return E_NOTIMPL; +} + +static const struct strmbase_source_ops source_ops = +{ + .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideBufferSize = asf_reader_DecideBufferSize, +}; + static inline struct asf_reader *impl_from_IFileSourceFilter(IFileSourceFilter *iface) { return CONTAINING_RECORD(iface, struct asf_reader, IFileSourceFilter_iface); @@ -232,9 +274,51 @@ static ULONG WINAPI reader_callback_Release(IWMReaderCallback *iface) static HRESULT WINAPI reader_callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS status, HRESULT hr, WMT_ATTR_DATATYPE type, BYTE *value, void *context) { - FIXME("iface %p, status %d, hr %#lx, type %d, value %p, context %p stub!\n", + struct asf_reader *filter = impl_from_IWMReaderCallback(iface)->filter; + DWORD i, stream_count; + WCHAR name[MAX_PATH]; + + TRACE("iface %p, status %d, hr %#lx, type %d, value %p, context %p.\n", iface, status, hr, type, value, context); - return E_NOTIMPL; + + switch (status) + { + case WMT_OPENED: + if (FAILED(hr)) + { + ERR("Failed to open WMReader, hr %#lx.\n", hr); + break; + } + if (FAILED(hr = IWMReader_GetOutputCount(filter->reader, &stream_count))) + { + ERR("Failed to get WMReader output count, hr %#lx.\n", hr); + break; + } + if (stream_count > ARRAY_SIZE(filter->streams)) + { + FIXME("Found %lu streams, not supported!\n", stream_count); + stream_count = ARRAY_SIZE(filter->streams); + } + + EnterCriticalSection(&filter->filter.filter_cs); + for (i = 0; i < stream_count; ++i) + { + struct asf_stream *stream = filter->streams + i; + swprintf(name, ARRAY_SIZE(name), L"Raw Stream %u", stream->index); + strmbase_source_init(&stream->source, &filter->filter, name, &source_ops); + } + filter->stream_count = stream_count; + LeaveCriticalSection(&filter->filter.filter_cs); + + BaseFilterImpl_IncrementPinVersion(&filter->filter); + break; + + default: + WARN("Ignoring status %#x.\n", status); + break; + } + + return S_OK; }
static HRESULT WINAPI reader_callback_OnSample(IWMReaderCallback *iface, DWORD output, QWORD time, @@ -273,6 +357,7 @@ HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) { struct asf_reader *object; HRESULT hr; + int i;
if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; @@ -289,6 +374,7 @@ HRESULT asf_reader_create(IUnknown *outer, IUnknown **out) return hr; }
+ for (i = 0; i < ARRAY_SIZE(object->streams); ++i) object->streams[i].index = i; strmbase_filter_init(&object->filter, outer, &CLSID_WMAsfReader, &filter_ops); object->IFileSourceFilter_iface.lpVtbl = &file_source_vtbl;
diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c index 54c38263464..494d0384ac8 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -242,9 +242,7 @@ static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expec CoTaskMemFree(id);
hr = IPin_EnumMediaTypes(pin, &enum_mt); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) goto skip_enum_mt; for (i = 0; (hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL)) == S_OK; i++) { if (i < expect_mt_count) @@ -260,7 +258,6 @@ static void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expec ok(hr == S_FALSE, "Got hr %#lx.\n", hr); IEnumMediaTypes_Release(enum_mt);
-skip_enum_mt: check_interface(pin, &IID_IPin, TRUE); check_interface(pin, &IID_IUnknown, TRUE); todo_wine @@ -499,9 +496,7 @@ static void test_filesourcefilter(void) ok(hr == S_OK, "Got hr %#lx.\n", hr);
hr = IEnumPins_Next(enumpins, 1, pins, NULL); - todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); - if (hr != S_OK) goto skip_pins; check_pin(pins[0], filter, PINDIR_OUTPUT, L"Raw Video 0", L"Raw Video 0", video_mt, ARRAY_SIZE(video_mt)); IPin_Release(pins[0]);
@@ -511,7 +506,6 @@ static void test_filesourcefilter(void) IPin_Release(pins[0]);
hr = IEnumPins_Next(enumpins, 1, pins, NULL); -skip_pins: ok(hr == S_FALSE, "Got hr %#lx.\n", hr); IEnumPins_Release(enumpins);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=115529
Your paranoid android.
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The win32 Wine build failed
=== debian11 (build log) ===
../wine/dlls/wined3d/texture.c:839:13: error: too many arguments to function ‘wined3d_resource_memory_colour_fill’ Task: The wow64 Wine build failed