Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/mpegsplit.c | 294 ++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+)
diff --git a/dlls/quartz/tests/mpegsplit.c b/dlls/quartz/tests/mpegsplit.c index 9a63636337..fc47c50e0a 100644 --- a/dlls/quartz/tests/mpegsplit.c +++ b/dlls/quartz/tests/mpegsplit.c @@ -20,6 +20,7 @@
#define COBJMACROS #include "dshow.h" +#include "mmreg.h" #include "wine/test.h"
static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0}; @@ -27,6 +28,8 @@ static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0}; static const WCHAR inputW[] = {'I','n','p','u','t',0}; static const WCHAR audioW[] = {'A','u','d','i','o',0};
+static const GUID MEDIASUBTYPE_mp3 = {0x00000055,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}}; + static IBaseFilter *create_mpeg_splitter(void) { IBaseFilter *filter = NULL; @@ -425,6 +428,296 @@ static void test_pin_info(void) ok(ret, "Failed to delete file, error %u.\n", GetLastError()); }
+static void test_media_types(void) +{ + MPEG1WAVEFORMAT expect_wfx = + { + {WAVE_FORMAT_MPEG, 1, 48000, 8000, 192, 0, sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX)}, + ACM_MPEG_LAYER3, 64000, ACM_MPEG_SINGLECHANNEL, 0, 1, ACM_MPEG_PROTECTIONBIT | ACM_MPEG_ID_MPEG1, 0, 0 + }; + static const MPEGLAYER3WAVEFORMAT expect_mp3_wfx = + { + {WAVE_FORMAT_MPEGLAYER3, 1, 48000, 8000, 1, 0, sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX)}, + MPEGLAYER3_ID_MPEG, 0, 192, 1, 0 + }; + + const WCHAR *filename = load_resource(mp3file); + AM_MEDIA_TYPE mt = {0}, *pmt, expect_mt = {0}; + IBaseFilter *filter = create_mpeg_splitter(); + IEnumMediaTypes *enummt; + IFilterGraph2 *graph; + HRESULT hr; + ULONG ref; + IPin *pin; + BOOL ret; + + IBaseFilter_FindPin(filter, inputW, &pin); + + hr = IPin_EnumMediaTypes(pin, &enummt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + expect_mt.majortype = MEDIATYPE_Stream; + expect_mt.bFixedSizeSamples = TRUE; + expect_mt.bTemporalCompression = TRUE; + expect_mt.lSampleSize = 1; + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + expect_mt.subtype = MEDIASUBTYPE_MPEG1System; + if (hr == S_OK) + { + ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + CoTaskMemFree(pmt); + } + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + expect_mt.subtype = MEDIASUBTYPE_MPEG1VideoCD; + if (hr == S_OK) + { + ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + CoTaskMemFree(pmt); + } + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + expect_mt.subtype = MEDIASUBTYPE_MPEG1Video; + if (hr == S_OK) + { + ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + CoTaskMemFree(pmt); + } + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + expect_mt.subtype = MEDIASUBTYPE_MPEG1Audio; + if (hr == S_OK) + { + ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + CoTaskMemFree(pmt); + } + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + IEnumMediaTypes_Release(enummt); + + mt.majortype = MEDIATYPE_Stream; + mt.subtype = MEDIASUBTYPE_MPEG1Audio; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1Video; + hr = IPin_QueryAccept(pin, &mt); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1VideoCD; + hr = IPin_QueryAccept(pin, &mt); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1System; + hr = IPin_QueryAccept(pin, &mt); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1AudioPayload; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1Payload; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + mt.subtype = MEDIASUBTYPE_MPEG1Packet; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + mt.subtype = GUID_NULL; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + mt.majortype = MEDIATYPE_Audio; + mt.subtype = MEDIASUBTYPE_MPEG1Audio; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + mt.majortype = MEDIATYPE_Stream; + mt.bFixedSizeSamples = TRUE; + mt.bTemporalCompression = TRUE; + mt.lSampleSize = 123; + mt.formattype = FORMAT_WaveFormatEx; + hr = IPin_QueryAccept(pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + graph = connect_input(filter, filename); + + /* Connecting input doesn't change the reported media types. */ + hr = IPin_EnumMediaTypes(pin, &enummt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + expect_mt.subtype = MEDIASUBTYPE_MPEG1System; + if (hr == S_OK) + { + ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n"); + CoTaskMemFree(pmt); + } + + IEnumMediaTypes_Release(enummt); + IPin_Release(pin); + + IBaseFilter_FindPin(filter, audioW, &pin); + + hr = IPin_EnumMediaTypes(pin, &enummt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n", + wine_dbgstr_guid(&pmt->majortype)); + todo_wine ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload), "Got subtype %s.\n", + wine_dbgstr_guid(&pmt->subtype)); + todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples); + ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression); + todo_wine ok(pmt->lSampleSize == 1, "Got sample size %u.\n", pmt->lSampleSize); + ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", + wine_dbgstr_guid(&pmt->formattype)); + ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk); + todo_wine ok(pmt->cbFormat == sizeof(MPEG1WAVEFORMAT), "Got format size %u.\n", pmt->cbFormat); + if (pmt->cbFormat == sizeof(MPEG1WAVEFORMAT)) + { + /* Native will sometimes leave junk in the joint stereo flags. */ + expect_wfx.fwHeadModeExt = ((MPEG1WAVEFORMAT *)pmt->pbFormat)->fwHeadModeExt; + ok(!memcmp(pmt->pbFormat, &expect_wfx, sizeof(MPEG1WAVEFORMAT)), "Format blocks didn't match.\n"); + } + + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + pmt->bFixedSizeSamples = FALSE; + pmt->bTemporalCompression = TRUE; + pmt->lSampleSize = 123; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + pmt->majortype = MEDIATYPE_Video; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->majortype = MEDIATYPE_Audio; + + pmt->subtype = MEDIASUBTYPE_MPEG1Audio; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1Packet; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1Video; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1AudioPayload; + + pmt->formattype = FORMAT_None; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->formattype = GUID_NULL; + hr = IPin_QueryAccept(pin, pmt); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->formattype = FORMAT_WaveFormatEx; + + CoTaskMemFree(pmt->pbFormat); + CoTaskMemFree(pmt); + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr != S_OK) + goto done; + ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n", + wine_dbgstr_guid(&pmt->majortype)); + ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Payload), "Got subtype %s.\n", + wine_dbgstr_guid(&pmt->subtype)); + ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples); + ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression); + ok(pmt->lSampleSize == 1, "Got sample size %u.\n", pmt->lSampleSize); + ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", + wine_dbgstr_guid(&pmt->formattype)); + ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk); + ok(pmt->cbFormat == sizeof(MPEG1WAVEFORMAT), "Got format size %u.\n", pmt->cbFormat); + /* Native will sometimes leave junk in the joint stereo flags. */ + expect_wfx.fwHeadModeExt = ((MPEG1WAVEFORMAT *)pmt->pbFormat)->fwHeadModeExt; + ok(!memcmp(pmt->pbFormat, &expect_wfx, sizeof(MPEG1WAVEFORMAT)), "Format blocks didn't match.\n"); + + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + CoTaskMemFree(pmt->pbFormat); + CoTaskMemFree(pmt); + + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n", + wine_dbgstr_guid(&pmt->majortype)); + ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_mp3), "Got subtype %s.\n", + wine_dbgstr_guid(&pmt->subtype)); + ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples); + ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression); + ok(pmt->lSampleSize == 1, "Got sample size %u.\n", pmt->lSampleSize); + ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", + wine_dbgstr_guid(&pmt->formattype)); + ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk); + ok(pmt->cbFormat == sizeof(MPEGLAYER3WAVEFORMAT), "Got format size %u.\n", pmt->cbFormat); + ok(!memcmp(pmt->pbFormat, &expect_mp3_wfx, sizeof(MPEGLAYER3WAVEFORMAT)), + "Format blocks didn't match.\n"); + + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + pmt->bFixedSizeSamples = FALSE; + pmt->bTemporalCompression = TRUE; + pmt->lSampleSize = 123; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + pmt->majortype = MEDIATYPE_Video; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->majortype = MEDIATYPE_Audio; + + pmt->subtype = MEDIASUBTYPE_MPEG1Audio; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1Packet; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1Video; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->subtype = MEDIASUBTYPE_MPEG1AudioPayload; + + pmt->formattype = FORMAT_None; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->formattype = GUID_NULL; + hr = IPin_QueryAccept(pin, pmt); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + pmt->formattype = FORMAT_WaveFormatEx; + + CoTaskMemFree(pmt->pbFormat); + CoTaskMemFree(pmt); + +done: + hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + IEnumMediaTypes_Release(enummt); + IPin_Release(pin); + + IFilterGraph2_Release(graph); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete file, error %u.\n", GetLastError()); +} + START_TEST(mpegsplit) { CoInitialize(NULL); @@ -433,6 +726,7 @@ START_TEST(mpegsplit) test_enum_pins(); test_find_pin(); test_pin_info(); + test_media_types();
CoUninitialize(); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/Makefile.in | 3 +- dlls/quartz/tests/waveparser.c | 81 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 dlls/quartz/tests/waveparser.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in index 03f13899d3..34a111462f 100644 --- a/dlls/quartz/tests/Makefile.in +++ b/dlls/quartz/tests/Makefile.in @@ -11,7 +11,8 @@ C_SRCS = \ misc.c \ mpegsplit.c \ referenceclock.c \ - videorenderer.c + videorenderer.c \ + waveparser.c
RC_SRCS = \ diff --git a/dlls/quartz/tests/waveparser.c b/dlls/quartz/tests/waveparser.c new file mode 100644 index 0000000000..3923c5dc9d --- /dev/null +++ b/dlls/quartz/tests/waveparser.c @@ -0,0 +1,81 @@ +/* + * WAVE parser filter unit tests + * + * Copyright 2018 Zebediah Figura + * + * 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/test.h" + +static IBaseFilter *create_wave_parser(void) +{ + IBaseFilter *filter = NULL; + HRESULT hr = CoCreateInstance(&CLSID_WAVEParser, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + return filter; +} + +#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_wave_parser(); + + check_interface(filter, &IID_IBaseFilter, TRUE); + check_interface(filter, &IID_IMediaFilter, TRUE); + check_interface(filter, &IID_IPersist, 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_IKsPropertySet, FALSE); + check_interface(filter, &IID_IMediaPosition, FALSE); + check_interface(filter, &IID_IMediaSeeking, FALSE); + check_interface(filter, &IID_IPersistPropertyBag, 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); +} + +START_TEST(waveparser) +{ + CoInitialize(NULL); + + test_interfaces(); + + CoUninitialize(); +}
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/filtergraph.c | 2 ++ dlls/quartz/tests/rsrc.rc | 4 ++++ dlls/quartz/tests/test.wav | Bin 0 -> 4488 bytes 3 files changed, 6 insertions(+) create mode 100644 dlls/quartz/tests/test.wav
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 88d964c883..f0e4b58cb3 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -42,6 +42,7 @@ typedef struct TestFilterImpl static const WCHAR avifile[] = {'t','e','s','t','.','a','v','i',0}; static const WCHAR mpegfile[] = {'t','e','s','t','.','m','p','g',0}; static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0}; +static const WCHAR wavefile[] = {'t','e','s','t','.','w','a','v',0};
static WCHAR *load_resource(const WCHAR *name) { @@ -3215,6 +3216,7 @@ START_TEST(filtergraph) test_render_run(avifile, FALSE, TRUE); test_render_run(mpegfile, TRUE, TRUE); test_render_run(mp3file, TRUE, FALSE); + test_render_run(wavefile, TRUE, FALSE); test_enum_filters(); test_graph_builder_render(); test_graph_builder_connect(); diff --git a/dlls/quartz/tests/rsrc.rc b/dlls/quartz/tests/rsrc.rc index 282cb1f7f2..660ad476e1 100644 --- a/dlls/quartz/tests/rsrc.rc +++ b/dlls/quartz/tests/rsrc.rc @@ -31,3 +31,7 @@ test.mpg RCDATA "test.mpg" /* ffmpeg -f lavfi -i "sine=frequency=500" -t 0.5 -ar 48000 -b:a 32k -f mp3 -acodec mp3 test.mp3 */ /* @makedep: test.mp3 */ test.mp3 RCDATA "test.mp3" + +/* ffmpeg -f lavfi -i "sine=frequency=600" -t 0.1 -ar 44100 -f wav -acodec pcm_u8 test.wav */ +/* @makedep: test.wav */ +test.wav RCDATA "test.wav" diff --git a/dlls/quartz/tests/test.wav b/dlls/quartz/tests/test.wav new file mode 100644 index 0000000000000000000000000000000000000000..51d23936196da1a0452c78713c8af819259d225e GIT binary patch literal 4488 zcmWIYbaQJEWMBw)40BD(Em06)U|?VbLYFlRV9dzC!QkT=93ll2_w;k~_Y8Im;RCXL z63fy|&GbwR^b8FQ8B!8U60LxyG&DA~w6?W(c6Imk^!D}jLqT6(Z%=nuXGeQmYjaa$ zeO*m;Rb_cuX-RQWQDFfL6c!d0mz0*3S5#Kl)YdmNHMg|2cYsVnGN`|=7h+OdYfE!u zLtSl6Rb>Ulq(Zn!AcH_ARa910*VfgKI%zbNM$^)0jvFnPMvKbP3T3p~9c`R|TVA8> dC3y36v{gCU_8#q_jCPtvyOyIJ@PQhp007ieqznK6
literal 0 HcmV?d00001
In particular, the test file just added contains 'LIST' chunks.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/quartz_private.h | 8 ++++++++ dlls/quartz/waveparser.c | 18 ++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h index db9c3bdc8a..be31c92946 100644 --- a/dlls/quartz/quartz_private.h +++ b/dlls/quartz/quartz_private.h @@ -30,9 +30,17 @@ #include "wingdi.h" #include "winuser.h" #include "dshow.h" +#include "wine/debug.h" #include "wine/strmbase.h" #include "wine/list.h"
+static inline const char *debugstr_fourcc(DWORD fourcc) +{ + if (!fourcc) return "''"; + return wine_dbg_sprintf("'%c%c%c%c'", (char)(fourcc), (char)(fourcc >> 8), + (char)(fourcc >> 16), (char)(fourcc >> 24)); +} + /* see IAsyncReader::Request on MSDN for the explanation of this */ #define MEDIATIME_FROM_BYTES(x) ((LONGLONG)(x) * 10000000) #define SEC_FROM_MEDIATIME(time) ((time) / 10000000) diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c index 834b6344d2..609f192820 100644 --- a/dlls/quartz/waveparser.c +++ b/dlls/quartz/waveparser.c @@ -296,20 +296,14 @@ static HRESULT WAVEParser_InputPin_PreConnect(IPin * iface, IPin * pConnectPin,
pos += chunk.cb; hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk); - if (chunk.fcc == mmioFOURCC('f','a','c','t')) + while (chunk.fcc != mmioFOURCC('d','a','t','a')) { - FIXME("'fact' chunk not supported yet\n"); - pos += sizeof(chunk) + chunk.cb; - hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk); + FIXME("Ignoring %s chunk.\n", debugstr_fourcc(chunk.fcc)); + pos += sizeof(chunk) + chunk.cb; + hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(chunk), (BYTE *)&chunk); + if (hr != S_OK) + return E_FAIL; } - if (chunk.fcc != mmioFOURCC('d','a','t','a')) - { - ERR("Expected 'data' chunk, but got %.04s\n", (LPSTR)&chunk.fcc); - return E_FAIL; - } - - if (hr != S_OK) - return E_FAIL;
pWAVEParser->StartOfFile = MEDIATIME_FROM_BYTES(pos + sizeof(RIFFCHUNK)); pWAVEParser->EndOfFile = MEDIATIME_FROM_BYTES(pos + chunk.cb + sizeof(RIFFCHUNK));
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/waveparser.c | 206 +++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+)
diff --git a/dlls/quartz/tests/waveparser.c b/dlls/quartz/tests/waveparser.c index 3923c5dc9d..377d33be83 100644 --- a/dlls/quartz/tests/waveparser.c +++ b/dlls/quartz/tests/waveparser.c @@ -22,6 +22,8 @@ #include "dshow.h" #include "wine/test.h"
+static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; + static IBaseFilter *create_wave_parser(void) { IBaseFilter *filter = NULL; @@ -31,6 +33,72 @@ static IBaseFilter *create_wave_parser(void) return filter; }
+static const WCHAR wavefile[] = {'t','e','s','t','.','w','a','v',0}; + +static WCHAR *load_resource(const WCHAR *name) +{ + static WCHAR pathW[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(ARRAY_SIZE(pathW), pathW); + lstrcatW(pathW, name); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %u.\n", + wine_dbgstr_w(pathW), GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok(!!res, "Failed to load resource, error %u.\n", GetLastError()); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n"); + CloseHandle(file); + + return pathW; +} + +static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + +static IFilterGraph2 *connect_input(IBaseFilter *splitter, const WCHAR *filename) +{ + static const WCHAR outputW[] = {'O','u','t','p','u','t',0}; + IFileSourceFilter *filesource; + IFilterGraph2 *graph; + IBaseFilter *reader; + IPin *source, *sink; + HRESULT hr; + + CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&reader); + IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource); + IFileSourceFilter_Load(filesource, filename, NULL); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_AddFilter(graph, reader, NULL); + IFilterGraph2_AddFilter(graph, splitter, NULL); + + IBaseFilter_FindPin(splitter, sink_name, &sink); + IBaseFilter_FindPin(reader, outputW, &source); + + hr = IFilterGraph2_ConnectDirect(graph, source, sink, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IPin_Release(source); + IPin_Release(sink); + IBaseFilter_Release(reader); + IFileSourceFilter_Release(filesource); + return graph; +} + #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) { @@ -71,11 +139,149 @@ static void test_interfaces(void) IBaseFilter_Release(filter); }
+static void test_enum_pins(void) +{ + const WCHAR *filename = load_resource(wavefile); + IBaseFilter *filter = create_wave_parser(); + IEnumPins *enum1, *enum2; + IFilterGraph2 *graph; + ULONG count, ref; + IPin *pins[3]; + HRESULT hr; + BOOL ret; + + ref = get_refcount(filter); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IBaseFilter_EnumPins(filter, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IBaseFilter_EnumPins(filter, &enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IEnumPins_Next(enum1, 1, NULL, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); +todo_wine + ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(pins[0]); +todo_wine + ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + IPin_Release(pins[0]); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(!count, "Got count %u.\n", count); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, NULL); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Clone(enum1, &enum2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 2); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum2, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + IEnumPins_Release(enum2); + + graph = connect_input(filter, filename); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); +todo_wine + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 2, "Got count %u.\n", count); + IPin_Release(pins[0]); + IPin_Release(pins[1]); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 3, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(count == 2, "Got count %u.\n", count); + IPin_Release(pins[0]); + IPin_Release(pins[1]); + + IEnumPins_Release(enum1); + IFilterGraph2_Release(graph); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete file, error %u.\n", GetLastError()); +} + START_TEST(waveparser) { CoInitialize(NULL);
test_interfaces(); + test_enum_pins();
CoUninitialize(); }