diff --git a/dlls/dsdmo/Makefile.in b/dlls/dsdmo/Makefile.in index 3787415abd6..d184b025ad0 100644 --- a/dlls/dsdmo/Makefile.in +++ b/dlls/dsdmo/Makefile.in @@ -1,5 +1,5 @@ MODULE = dsdmo.dll -IMPORTS = dmoguids uuid +IMPORTS = dmoguids strmiids uuid EXTRADLLFLAGS = -mno-cygwin diff --git a/dlls/dsdmo/main.c b/dlls/dsdmo/main.c index cc06dfe6f5c..9d4fbc5b785 100644 --- a/dlls/dsdmo/main.c +++ b/dlls/dsdmo/main.c @@ -20,6 +20,7 @@ #include "dmo.h" #include "mmreg.h" #include "mmsystem.h" +#include "uuids.h" #include "initguid.h" #include "dsound.h" #include "rpcproxy.h" @@ -38,6 +39,9 @@ struct effect IUnknown *outer_unk; LONG refcount; + CRITICAL_SECTION cs; + WAVEFORMATEX format; + const struct effect_ops *ops; }; @@ -92,6 +96,8 @@ static ULONG WINAPI effect_inner_Release(IUnknown *iface) if (!refcount) { + effect->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&effect->cs); effect->ops->destroy(effect); } return refcount; @@ -159,8 +165,63 @@ static HRESULT WINAPI effect_GetOutputType(IMediaObject *iface, DWORD index, DWO static HRESULT WINAPI effect_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) { - FIXME("iface %p, index %u, type %p, flags %#x, stub!\n", iface, index, type, flags); - return E_NOTIMPL; + struct effect *effect = impl_from_IMediaObject(iface); + const WAVEFORMATEX *format; + + TRACE("iface %p, index %u, type %p, flags %#x.\n", iface, index, type, flags); + + if (flags & DMO_SET_TYPEF_CLEAR) + { + EnterCriticalSection(&effect->cs); + memset(&effect->format, 0, sizeof(effect->format)); + LeaveCriticalSection(&effect->cs); + return S_OK; + } + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!IsEqualGUID(&type->subtype, &MEDIASUBTYPE_PCM) + && !IsEqualGUID(&type->subtype, &MEDIASUBTYPE_IEEE_FLOAT)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) + return DMO_E_TYPE_NOT_ACCEPTED; + + format = (const WAVEFORMATEX *)type->pbFormat; + if (format->wFormatTag == WAVE_FORMAT_PCM) + { + if (format->wBitsPerSample != 8 && format->wBitsPerSample != 16) + { + WARN("Rejecting %u-bit integer PCM.\n", format->wBitsPerSample); + return DMO_E_TYPE_NOT_ACCEPTED; + } + } + else if (format->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + { + if (format->wBitsPerSample != 32) + { + WARN("Rejecting %u-bit float PCM.\n", format->wBitsPerSample); + return DMO_E_TYPE_NOT_ACCEPTED; + } + } + else + { + WARN("Rejecting tag %#x.\n", format->wFormatTag); + return DMO_E_TYPE_NOT_ACCEPTED; + } + + if (format->nChannels != 1 && format->nChannels != 2) + { + WARN("Rejecting %u channels.\n", format->nChannels); + return DMO_E_TYPE_NOT_ACCEPTED; + } + + EnterCriticalSection(&effect->cs); + effect->format = *format; + LeaveCriticalSection(&effect->cs); + + return S_OK; } static HRESULT WINAPI effect_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) @@ -346,6 +407,9 @@ static void effect_init(struct effect *effect, IUnknown *outer, const struct eff effect->IMediaObject_iface.lpVtbl = &effect_vtbl; effect->IMediaObjectInPlace_iface.lpVtbl = &effect_inplace_vtbl; + InitializeCriticalSection(&effect->cs); + effect->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": effect.cs"); + effect->ops = ops; } diff --git a/dlls/dsdmo/tests/dsdmo.c b/dlls/dsdmo/tests/dsdmo.c index cb6e698b6ec..d1cf2575de2 100644 --- a/dlls/dsdmo/tests/dsdmo.c +++ b/dlls/dsdmo/tests/dsdmo.c @@ -206,32 +206,32 @@ static void test_media_types(const GUID *clsid) mt.majortype = MEDIATYPE_Video; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.majortype = GUID_NULL; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.majortype = MEDIATYPE_Audio; mt.subtype = MEDIASUBTYPE_RGB8; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.subtype = GUID_NULL; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.subtype = MEDIASUBTYPE_IEEE_FLOAT; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); mt.subtype = MEDIASUBTYPE_PCM; mt.formattype = FORMAT_VideoInfo; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.formattype = FORMAT_None; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.formattype = GUID_NULL; hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); mt.formattype = FORMAT_WaveFormatEx; for (i = 0; i < ARRAY_SIZE(sample_rates); ++i) @@ -247,7 +247,7 @@ static void test_media_types(const GUID *clsid) build_pcm_format(&wfx, depths[j].format, depths[j].depth, sample_rates[i], channels); hr = IMediaObject_SetInputType(dmo, 0, &mt, 0); - todo_wine ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", + ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", hr, sample_rates[i], channels, depths[j].format, depths[j].depth); /* The output type must match the input type. */ @@ -273,7 +273,7 @@ static void test_media_types(const GUID *clsid) hr, sample_rates[i], channels, depths[j].format, depths[j].depth); hr = IMediaObject_SetInputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); - todo_wine ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", + ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", hr, sample_rates[i], channels, depths[j].format, depths[j].depth); hr = IMediaObject_SetOutputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); @@ -281,7 +281,7 @@ static void test_media_types(const GUID *clsid) hr, sample_rates[i], channels, depths[j].format, depths[j].depth); hr = IMediaObject_SetInputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); - todo_wine ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", + ok(hr == S_OK, "Got hr %#x for %u Hz, %u channels, format %#x, depth %u.\n", hr, sample_rates[i], channels, depths[j].format, depths[j].depth); } }