Rémi Bernon : qasf: Implement ASF Reader filter stream stubs.

Alexandre Julliard julliard at winehq.org
Wed May 25 16:51:46 CDT 2022


Module: wine
Branch: master
Commit: c39dbe1f31435e715cd10bdf83be864e00346699
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c39dbe1f31435e715cd10bdf83be864e00346699

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Mon May 23 13:20:51 2022 +0200

qasf: Implement ASF Reader filter stream stubs.

Signed-off-by: Rémi Bernon <rbernon at 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);
 




More information about the wine-cvs mailing list