[PATCH 5/5] qasf: Implement ASF Reader filter stream stubs.
Rémi Bernon
wine at gitlab.winehq.org
Mon May 23 07:07:47 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/qasf/asfreader.c | 114 +++++++++++++++++++++++++++++++++++-
dlls/qasf/tests/asfreader.c | 3 -
2 files changed, 111 insertions(+), 6 deletions(-)
diff --git a/dlls/qasf/asfreader.c b/dlls/qasf/asfreader.c
index c38943ec247..29a3f578e7c 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,36 @@ struct asf_reader
IWMReaderCallback *callback;
IWMReader *reader;
+
+ LONG 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 HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ struct asf_stream *stream = impl_from_strmbase_pin(iface);
+
+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+ if (IsEqualGUID(iid, &IID_IUnknown)
+ || IsEqualGUID(iid, &IID_IPin))
+ *out = &stream->source.pin.IPin_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 inline struct asf_reader *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct asf_reader, filter);
@@ -46,12 +80,29 @@ 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;
+
+ TRACE("iface %p, index %u.\n", iface, index);
+
+ if (index >= InterlockedOr(&filter->stream_count, 0)) pin = NULL;
+ else pin = &filter->streams[index].source.pin;
+
+ 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 +134,21 @@ 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 =
+{
+ .base.pin_query_interface = source_query_interface,
+ .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 +298,49 @@ 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);
+ }
+
+ 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);
+ }
+
+ InterlockedExchange(&filter->stream_count, stream_count);
+ 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 +379,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 +396,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..b3e605f0c22 100644
--- a/dlls/qasf/tests/asfreader.c
+++ b/dlls/qasf/tests/asfreader.c
@@ -499,9 +499,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 +509,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);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/116
More information about the wine-devel
mailing list