[PATCH 2/3] qdvd: Add a stub dvd navigator filter.

Zebediah Figura z.figura12 at gmail.com
Thu Jul 16 11:28:43 CDT 2020


On 7/15/20 11:16 PM, Gijs Vermeulen wrote:
> Signed-off-by: Gijs Vermeulen <gijsvrm at gmail.com>
> ---
>  dlls/qdvd/Makefile.in       |   3 +
>  dlls/qdvd/navigator.c       |  67 +++++++++++++
>  dlls/qdvd/qdvd_classes.idl  |   7 ++
>  dlls/qdvd/qdvd_main.c       |   3 +
>  dlls/qdvd/qdvd_private.h    |   1 +
>  dlls/qdvd/tests/Makefile.in |   3 +-
>  dlls/qdvd/tests/navigator.c | 191 ++++++++++++++++++++++++++++++++++++
>  7 files changed, 274 insertions(+), 1 deletion(-)
>  create mode 100644 dlls/qdvd/navigator.c
>  create mode 100644 dlls/qdvd/tests/navigator.c
> 
> diff --git a/dlls/qdvd/Makefile.in b/dlls/qdvd/Makefile.in
> index 8f5089b3ac..e100870d32 100644
> --- a/dlls/qdvd/Makefile.in
> +++ b/dlls/qdvd/Makefile.in
> @@ -1,10 +1,13 @@
>  MODULE    = qdvd.dll
>  IMPORTS   = strmiids uuid ole32
> +PARENTSRC = ../strmbase

PARENTSRC is a bit of a hack for modules that aren't PE yet and thus
can't import strmbase; you just want to import strmbase normally.

The rest of the patch and 3/3 looks fine to me.

>  
>  EXTRADLLFLAGS = -mno-cygwin
>  
>  C_SRCS = \
> +	filter.c \
>  	graph.c \
> +	navigator.c \
>  	qdvd_main.c
>  
>  IDL_SRCS = \
> diff --git a/dlls/qdvd/navigator.c b/dlls/qdvd/navigator.c
> new file mode 100644
> index 0000000000..1e121dde60
> --- /dev/null
> +++ b/dlls/qdvd/navigator.c
> @@ -0,0 +1,67 @@
> +/*
> + * Navigator filter
> + *
> + * Copyright 2020 Gijs Vermeulen
> + *
> + * 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 "qdvd_private.h"
> +#include "wine/strmbase.h"
> +
> +WINE_DEFAULT_DEBUG_CHANNEL(qdvd);
> +
> +struct navigator
> +{
> +    struct strmbase_filter filter;
> +};
> +
> +static inline struct navigator *impl_from_strmbase_filter(struct strmbase_filter *filter)
> +{
> +    return CONTAINING_RECORD(filter, struct navigator, filter);
> +}
> +
> +static struct strmbase_pin *navigator_get_pin(struct strmbase_filter *iface, unsigned int index)
> +{
> +    return NULL;
> +}
> +
> +static void navigator_destroy(struct strmbase_filter *iface)
> +{
> +    struct navigator *filter = impl_from_strmbase_filter(iface);
> +
> +    strmbase_filter_cleanup(&filter->filter);
> +    free(filter);
> +}
> +
> +static const struct strmbase_filter_ops filter_ops =
> +{
> +    .filter_get_pin = navigator_get_pin,
> +    .filter_destroy = navigator_destroy,
> +};
> +
> +HRESULT navigator_create(IUnknown *outer, IUnknown **out)
> +{
> +    struct navigator *object;
> +
> +    if (!(object = calloc(1, sizeof(*object))))
> +        return E_OUTOFMEMORY;
> +
> +    strmbase_filter_init(&object->filter, outer, &CLSID_DVDNavigator, &filter_ops);
> +
> +    TRACE("Created DVD Navigator filter %p.\n", object);
> +    *out = &object->filter.IUnknown_inner;
> +    return S_OK;
> +}
> diff --git a/dlls/qdvd/qdvd_classes.idl b/dlls/qdvd/qdvd_classes.idl
> index 7fd2a081ba..c55c7e3944 100644
> --- a/dlls/qdvd/qdvd_classes.idl
> +++ b/dlls/qdvd/qdvd_classes.idl
> @@ -24,3 +24,10 @@
>      uuid(fcc152b7-f372-11d0-8e00-00c04fd7c08b),
>  ]
>  coclass DvdGraphBuilder {}
> +
> +[
> +    helpstring("DVD Navigator Filter"),
> +    threading(both),
> +    uuid(9b8c4620-2c1a-11d0-8493-00a02438ad48),
> +]
> +coclass DVDNavigator {}
> diff --git a/dlls/qdvd/qdvd_main.c b/dlls/qdvd/qdvd_main.c
> index c529533e44..2fdb108877 100644
> --- a/dlls/qdvd/qdvd_main.c
> +++ b/dlls/qdvd/qdvd_main.c
> @@ -100,6 +100,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
>  };
>  
>  static struct class_factory graph_builder_cf = {{&class_factory_vtbl}, graph_builder_create};
> +static struct class_factory navigator_cf = {{&class_factory_vtbl}, navigator_create};
>  
>  BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
>  {
> @@ -120,6 +121,8 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out)
>  
>      if (IsEqualGUID(clsid, &CLSID_DvdGraphBuilder))
>          return IClassFactory_QueryInterface(&graph_builder_cf.IClassFactory_iface, iid, out);
> +    if (IsEqualGUID(clsid, &CLSID_DVDNavigator))
> +        return IClassFactory_QueryInterface(&navigator_cf.IClassFactory_iface, iid, out);
>  
>      FIXME("%s not available, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid));
>      return CLASS_E_CLASSNOTAVAILABLE;
> diff --git a/dlls/qdvd/qdvd_private.h b/dlls/qdvd/qdvd_private.h
> index 297949ee60..48fced46f1 100644
> --- a/dlls/qdvd/qdvd_private.h
> +++ b/dlls/qdvd/qdvd_private.h
> @@ -26,5 +26,6 @@
>  #include "wine/debug.h"
>  
>  HRESULT graph_builder_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
> +HRESULT navigator_create(IUnknown *outer, IUnknown **out) DECLSPEC_HIDDEN;
>  
>  #endif /* QDVD_PRIVATE_H */
> diff --git a/dlls/qdvd/tests/Makefile.in b/dlls/qdvd/tests/Makefile.in
> index 3e9efd9c74..57f8fbba5a 100644
> --- a/dlls/qdvd/tests/Makefile.in
> +++ b/dlls/qdvd/tests/Makefile.in
> @@ -2,4 +2,5 @@ TESTDLL   = qdvd.dll
>  IMPORTS   = strmiids uuid ole32
>  
>  C_SRCS = \
> -    graph.c
> +    graph.c \
> +    navigator.c
> diff --git a/dlls/qdvd/tests/navigator.c b/dlls/qdvd/tests/navigator.c
> new file mode 100644
> index 0000000000..f01e428b4e
> --- /dev/null
> +++ b/dlls/qdvd/tests/navigator.c
> @@ -0,0 +1,191 @@
> +/*
> + * Navigator filter unit tests
> + *
> + * Copyright 2020 Gijs Vermeulen
> + *
> + * 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
> + */
> +
> +#define COBJMACROS
> +#include "dshow.h"
> +#include "wine/strmbase.h"
> +#include "wine/test.h"
> +
> +static IBaseFilter *create_navigator(void)
> +{
> +    IBaseFilter *filter = NULL;
> +    HRESULT hr = CoCreateInstance(&CLSID_DVDNavigator, NULL,
> +            CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&filter);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    return filter;
> +}
> +
> +static ULONG get_refcount(void *iface)
> +{
> +    IUnknown *unknown = iface;
> +    IUnknown_AddRef(unknown);
> +    return IUnknown_Release(unknown);
> +}
> +
> +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
> +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
> +{
> +    IUnknown *iface = iface_ptr;
> +    HRESULT hr, expected_hr;
> +    IUnknown *unk;
> +
> +    expected_hr = supported ? S_OK : E_NOINTERFACE;
> +
> +    hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
> +    ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
> +    if (SUCCEEDED(hr))
> +        IUnknown_Release(unk);
> +}
> +
> +static void test_interfaces(void)
> +{
> +    IBaseFilter *filter = create_navigator();
> +
> +    check_interface(filter, &IID_IBaseFilter, TRUE);
> +    todo_wine check_interface(filter, &IID_IDvdControl, TRUE);
> +    todo_wine check_interface(filter, &IID_IDvdControl2, TRUE);
> +    todo_wine check_interface(filter, &IID_IDvdInfo, TRUE);
> +    todo_wine check_interface(filter, &IID_IDvdInfo2, TRUE);
> +    check_interface(filter, &IID_IMediaFilter, TRUE);
> +    check_interface(filter, &IID_IPersist, TRUE);
> +    todo_wine check_interface(filter, &IID_ISpecifyPropertyPages, TRUE);
> +    check_interface(filter, &IID_IUnknown, TRUE);
> +
> +    check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
> +    check_interface(filter, &IID_IBasicAudio, FALSE);
> +    check_interface(filter, &IID_IBasicVideo, FALSE);
> +    check_interface(filter, &IID_IFileSourceFilter, FALSE);
> +    check_interface(filter, &IID_IKsPropertySet, FALSE);
> +    check_interface(filter, &IID_IMediaPosition, FALSE);
> +    check_interface(filter, &IID_IMediaSeeking, FALSE);
> +    check_interface(filter, &IID_IPersistPropertyBag, FALSE);
> +    check_interface(filter, &IID_IPersistStream, FALSE);
> +    check_interface(filter, &IID_IPin, FALSE);
> +    check_interface(filter, &IID_IQualityControl, FALSE);
> +    check_interface(filter, &IID_IQualProp, FALSE);
> +    check_interface(filter, &IID_IReferenceClock, FALSE);
> +    check_interface(filter, &IID_IVideoWindow, FALSE);
> +
> +    IBaseFilter_Release(filter);
> +}
> +
> +static const GUID test_iid = {0x33333333};
> +static LONG outer_ref = 1;
> +
> +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
> +{
> +    if (IsEqualGUID(iid, &IID_IUnknown)
> +            || IsEqualGUID(iid, &IID_IBaseFilter)
> +            || IsEqualGUID(iid, &test_iid))
> +    {
> +        *out = (IUnknown *)0xdeadbeef;
> +        return S_OK;
> +    }
> +    ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
> +    return E_NOINTERFACE;
> +}
> +
> +static ULONG WINAPI outer_AddRef(IUnknown *iface)
> +{
> +    return InterlockedIncrement(&outer_ref);
> +}
> +
> +static ULONG WINAPI outer_Release(IUnknown *iface)
> +{
> +    return InterlockedDecrement(&outer_ref);
> +}
> +
> +static const IUnknownVtbl outer_vtbl =
> +{
> +    outer_QueryInterface,
> +    outer_AddRef,
> +    outer_Release,
> +};
> +
> +static IUnknown test_outer = {&outer_vtbl};
> +
> +static void test_aggregation(void)
> +{
> +    IBaseFilter *filter, *filter2;
> +    IUnknown *unk, *unk2;
> +    HRESULT hr;
> +    ULONG ref;
> +
> +    filter = (IBaseFilter *)0xdeadbeef;
> +    hr = CoCreateInstance(&CLSID_DVDNavigator, &test_outer, CLSCTX_INPROC_SERVER,
> +            &IID_IBaseFilter, (void **)&filter);
> +    ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
> +    ok(!filter, "Got interface %p.\n", filter);
> +
> +    hr = CoCreateInstance(&CLSID_DVDNavigator, &test_outer, CLSCTX_INPROC_SERVER,
> +            &IID_IUnknown, (void **)&unk);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
> +    ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
> +    ref = get_refcount(unk);
> +    ok(ref == 1, "Got unexpected refcount %d.\n", ref);
> +
> +    ref = IUnknown_AddRef(unk);
> +    ok(ref == 2, "Got unexpected refcount %d.\n", ref);
> +    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
> +
> +    ref = IUnknown_Release(unk);
> +    ok(ref == 1, "Got unexpected refcount %d.\n", ref);
> +    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
> +
> +    hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
> +    IUnknown_Release(unk2);
> +
> +    hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +
> +    hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
> +
> +    hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
> +
> +    hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
> +    ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
> +    ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
> +
> +    hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
> +    ok(hr == S_OK, "Got hr %#x.\n", hr);
> +    ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
> +
> +    IBaseFilter_Release(filter);
> +    ref = IUnknown_Release(unk);
> +    ok(!ref, "Got unexpected refcount %d.\n", ref);
> +    ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
> +}
> +
> +START_TEST(navigator)
> +{
> +    CoInitializeEx(NULL, COINIT_MULTITHREADED);
> +
> +    test_interfaces();
> +    test_aggregation();
> +
> +    CoUninitialize();
> +}
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20200716/461a0f8a/attachment.sig>


More information about the wine-devel mailing list