From: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/qasf/asfreader.c | 97 +++++++++++++++++++++++++++++++++++-- dlls/qasf/tests/asfreader.c | 6 --- 2 files changed, 94 insertions(+), 9 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c index c38943ec247..a570687f9d1 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,8 +43,16 @@ struct asf_reader
IWMReaderCallback *callback; IWMReader *reader; + + UINT stream_count; + struct asf_stream streams[16]; };
+static inline struct asf_stream *impl_from_strmbase_pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct asf_stream, source.pin); +} + static inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface) { return CONTAINING_RECORD(iface, struct asf_reader, filter); @@ -46,12 +60,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 +116,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 +279,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)) + { + WARN("Failed to open WMReader, hr %#lx\n", hr); + break; + } + if (FAILED(hr = IWMReader_GetOutputCount(filter->reader, &stream_count))) + { + WARN("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 +362,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 +379,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 a2b56ee29de..cda7eca602d 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -241,9 +241,7 @@ static inline void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTIO 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; hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL); for (i = 0; hr == S_OK; hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL), i++) { @@ -260,7 +258,6 @@ static inline void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTIO 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);