Fixes the following issues: - OpenFile failes on native with VFW_E_CANNOT_CONNECT as there are no renderes in the graph. - IMediaSeeking checks are called with a wrong object. - IMediaSeeking checks fail as there are no streams.
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/tests/amstream.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index a81cdba3f3..e962d85e73 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -231,8 +231,10 @@ static void test_interfaces(void)
static void test_openfile(void) { + IMediaStreamFilter *filter; IAMMultiMediaStream *pams; HRESULT hr; + LONG ref; IGraphBuilder* pgraph;
if (!(pams = create_ammultimediastream())) @@ -245,13 +247,9 @@ static void test_openfile(void) if (pgraph) IGraphBuilder_Release(pgraph);
- check_interface(pams, &IID_IMediaSeeking, FALSE); - - hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0); + hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", AMMSF_NORENDER); ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
- check_interface(pams, &IID_IMediaSeeking, TRUE); - hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph); ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr); ok(pgraph!=NULL, "Filtergraph should be created\n"); @@ -260,6 +258,24 @@ static void test_openfile(void) IGraphBuilder_Release(pgraph);
IAMMultiMediaStream_Release(pams); + + pams = create_ammultimediastream(); + hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilter(pams, &filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_interface(filter, &IID_IMediaSeeking, FALSE); + + hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + check_interface(filter, &IID_IMediaSeeking, TRUE); + + ref = IAMMultiMediaStream_Release(pams); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IMediaStreamFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); }
static void test_renderfile(void)
Fixes the following issues: - AddMediaStream with AMMSF_ADDDEFAULTRENDERER fails if there is no sound card. - GetSurface actually returns a non-NULL surface as CreateSample creates the surface if it was not provided. - CreateSample with the pdds7 surface fails with DDERR_INVALIDSURFACETYPE as the surface size does not match the video size.
Signed-off-by: Anton Baskanov baskanov@gmail.com ---
v2: Fixed a test failure. --- dlls/amstream/tests/amstream.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index e962d85e73..9abb76b996 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -303,7 +303,7 @@ static void test_renderfile(void) ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); - ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr); + ok(hr==S_OK || hr==VFW_E_NO_AUDIO_HARDWARE, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0); ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr); @@ -322,14 +322,15 @@ static void test_renderfile(void) surface = NULL; hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect); ok(hr == S_OK, "got 0x%08x\n", hr); - ok(surface == NULL, "got %p\n", surface); + ok(surface != NULL, "expected non-NULL surface\n"); + IDirectDrawSurface_Release(surface); IDirectDrawStreamSample_Release(pddsample);
hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface); ok(hr == S_OK, "got 0x%08x\n", hr);
EXPECT_REF(surface, 1); - hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample); + hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, &rect, 0, &pddsample); ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr); EXPECT_REF(surface, 2); IDirectDrawStreamSample_Release(pddsample);
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/tests/Makefile.in | 3 ++ dlls/amstream/tests/amstream.c | 66 +++++++++++++++++++++++++------- dlls/amstream/tests/rsrc.rc | 25 ++++++++++++ dlls/amstream/tests/test.avi | Bin 0 -> 12088 bytes 4 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 dlls/amstream/tests/rsrc.rc create mode 100644 dlls/amstream/tests/test.avi
diff --git a/dlls/amstream/tests/Makefile.in b/dlls/amstream/tests/Makefile.in index 81eaed3c15..eb756ddf39 100644 --- a/dlls/amstream/tests/Makefile.in +++ b/dlls/amstream/tests/Makefile.in @@ -3,3 +3,6 @@ IMPORTS = strmbase strmiids uuid ddraw ole32 user32
C_SRCS = \ amstream.c + +RC_SRCS = \ + rsrc.rc diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 9abb76b996..aeedb62b00 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -53,6 +53,48 @@ static const AM_MEDIA_TYPE audio_mt = static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}"; static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
+static const WCHAR *load_resource(const WCHAR *name) +{ + HMODULE module = GetModuleHandleA(NULL); + HRSRC resource; + DWORD written; + HGLOBAL data; + HANDLE file; + WCHAR *path; + DWORD size; + void *ptr; + + path = calloc(MAX_PATH + 1, sizeof(WCHAR)); + ok(!!path, "Failed to allocate temp path string.\n"); + GetTempPathW(MAX_PATH + 1, path); + wcscat(path, name); + + file = CreateFileW(path, 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(path), GetLastError()); + + resource = FindResourceW(module, name, (const WCHAR *)RT_RCDATA); + ok(!!resource, "Failed to find resource %s, error %u.\n", wine_dbgstr_w(name), GetLastError()); + + data = LoadResource(module, resource); + size = SizeofResource(module, resource); + + ptr = LockResource(data); + + WriteFile(file, ptr, size, &written, NULL); + ok(written == size, "Failed to write file %s.\n", wine_dbgstr_w(path)); + + CloseHandle(file); + + return path; +} + +static void unload_resource(const WCHAR *path) +{ + BOOL ret = DeleteFileW(path); + ok(ret, "Failed to delete file %s.\n", wine_dbgstr_w(path)); + free((void *)path); +} + #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) static void _expect_ref(IUnknown* obj, ULONG ref, int line) { @@ -229,7 +271,7 @@ static void test_interfaces(void) ok(!ref, "Got outstanding refcount %u.\n", ref); }
-static void test_openfile(void) +static void test_openfile(const WCHAR *test_avi_path) { IMediaStreamFilter *filter; IAMMultiMediaStream *pams; @@ -247,7 +289,7 @@ static void test_openfile(void) if (pgraph) IGraphBuilder_Release(pgraph);
- hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", AMMSF_NORENDER); + hr = IAMMultiMediaStream_OpenFile(pams, test_avi_path, AMMSF_NORENDER); ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph); @@ -267,7 +309,7 @@ static void test_openfile(void)
check_interface(filter, &IID_IMediaSeeking, FALSE);
- hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0); + hr = IAMMultiMediaStream_OpenFile(pams, test_avi_path, 0); ok(hr == S_OK, "Got hr %#x.\n", hr);
check_interface(filter, &IID_IMediaSeeking, TRUE); @@ -278,7 +320,7 @@ static void test_openfile(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
-static void test_renderfile(void) +static void test_renderfile(const WCHAR *test_avi_path) { IAMMultiMediaStream *pams; HRESULT hr; @@ -305,7 +347,7 @@ static void test_renderfile(void) hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL); ok(hr==S_OK || hr==VFW_E_NO_AUDIO_HARDWARE, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
- hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0); + hr = IAMMultiMediaStream_OpenFile(pams, test_avi_path, 0); ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream); @@ -5073,7 +5115,7 @@ static void test_ddrawstream_getsetdirectdraw(void)
START_TEST(amstream) { - HANDLE file; + const WCHAR *test_avi_path;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
@@ -5088,14 +5130,12 @@ START_TEST(amstream) test_media_types(); test_IDirectDrawStreamSample();
- file = CreateFileW(L"test.avi", 0, 0, NULL, OPEN_EXISTING, 0, NULL); - if (file != INVALID_HANDLE_VALUE) - { - CloseHandle(file); + test_avi_path = load_resource(L"test.avi");
- test_openfile(); - test_renderfile(); - } + test_openfile(test_avi_path); + test_renderfile(test_avi_path); + + unload_resource(test_avi_path);
test_audiodata_query_interface(); test_audiodata_get_info(); diff --git a/dlls/amstream/tests/rsrc.rc b/dlls/amstream/tests/rsrc.rc new file mode 100644 index 0000000000..e1fc277503 --- /dev/null +++ b/dlls/amstream/tests/rsrc.rc @@ -0,0 +1,25 @@ +/* + * Resource file for amstream tests. + * + * Copyright 2020 Anton Baskanov + * + * 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 "windef.h" + +/* ffmpeg -f lavfi -i smptebars -f lavfi -i "sine=frequency=1000" -t 0.1 -r 10 -ar 8000 -f avi -vcodec rawvideo -vf scale=32x24 -acodec pcm_u8 test.avi */ +/* @makedep: test.avi */ +test.avi RCDATA "test.avi" diff --git a/dlls/amstream/tests/test.avi b/dlls/amstream/tests/test.avi new file mode 100644 index 0000000000000000000000000000000000000000..70aead54538fbc89b9c563121bbf217a5a78131d GIT binary patch literal 12088 zcmWIYbaOM%XJBv)^HlKh3=Y|&#K4e|Qk0WemYHF}z`(Gejgi5@2gm>d0Zs-6MhKIE z2_nLv0Hh_LV#pN8tOo)N48<iyIY10Ht1L66*we(w09hT#JT9mJh~2=#!0;akU}_YA zrUUh-X#fR4SOJJZ_AxT>Fo4VgsYeH1p?=;HK)Yd51_mj~=xRp!qaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd72GI|RxKiV9qiya*b9Pyk}kxB@e9)Bwf?jYojQ zV0;jb4nX4^HE81;iKQvUAic-{#CMQ~h$t{KFzf;{LE{|A>OkWhK%;<T8^AFapjr@S zWZ+=H7|$>)PlA{<N{)uWXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjFb=n zjSsK@2NLpAa&v$v<HtzxI2M0`#$%*_;+}qP{+_{ZA$&l#Phwe`skxqov7VuU0eCd! z2XF*t6pV(zXb6nF5CD}B*Vq{ta`VeFK`X;RE6BD2!P-TO7ccH=ZfR{OEG#Ta2o4Pm zc6M@dHd9hjQ31;@1S;riYH6u2C@3t74-Ns!J32a<Dk&=~Zvlce3l}X~+}YF&k}oKX z4+;qlastUKj>^+Ke6|C@`o&9@ECt68F#3w)1A{|?!0{umprEi42o_G8Hhp?aT|+}v zMn+~<Tv&KSn7ys7ow=?a1gOhMOG|l#hedlyN=k}Gv^6$Y%8QEe2W?ujW{r}PlCq4L zlA>Z@Qe>dBu&^+1Ktpv+v7~?yxBrG!t5%r<fnn60Tet4Ln5nL(si`d`0yIQ|gIhpU zS{4W_fxtNN<NJ4Szb#PG*3r?E=H=t#<7ML#5EJDE0t+B8j(_|5_3JP5m34G<bfx(O z1O)imf%0NNh5#XXu=xpZ-vIT`gXrgn>K7LW=_e%L*y64dwPd2V`+|f0v9;H(HZ;2d z`4ha{798k{t+@)~D@QKw_i~%Rzb~fd>J?J?^-V5H5sUjhUFRPF>c4)iy~{@{ZrLPX zulf7>;%m>JJ9&C?@q}$_8fvG`>#b>MZ(q1*W@A(DnpJZeni?A$>+5IFnbBC+xq99F zy7~s7K;xXbVE)>9^$lRq*w{5CLqp%vYQ?E@H}@A6H#BrjNmtjiv|MrO?2Y|}MGXy| zlYx8-i{&TJ-q=SDziUdGijKMY$}>Ro3ybROJ11qESlQXl+jIERuA<_?!s_~|JJ;1# z`&cG-x7ODuC8gIj_spE!TUl0JU*Fi6kdRtm-!ge>FVO8E4<rKl4K0(W^g`Wl0G!cT z1uTl2x+ZitloXUSbVKNRDBaNA4;HV7(lB{+afCcXJxm=;oO<SgTnw7Sg1HOkZWtfc z{(*BR%srUy1NmSl&<DujJs91I(|ruEH~=OXSOmj7K)Z;?9iTWJiral4A9w=e0PcQD z6DUJwN`+wp&_qzp4w_2^tpNws@F1H&{2m}1l+$2*J66bCER4^<#=rnd6)^rGARm;@ MVf+?g%K_wK0F@rn4FCWD
literal 0 HcmV?d00001
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/tests/amstream.c | 890 ++++++++++++++++----------------- 1 file changed, 445 insertions(+), 445 deletions(-)
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index aeedb62b00..feb195140e 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -711,6 +711,279 @@ static void check_enum_stream_(int line, IAMMultiMediaStream *mmstream, } }
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; + IMediaSeeking IMediaSeeking_iface; + LONGLONG current_position; + LONGLONG stop_position; + HRESULT get_duration_hr; + HRESULT set_positions_hr; +}; + +static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, filter); +} + +static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + if (!index) + return &filter->source.pin; + return NULL; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); +} + +static HRESULT testfilter_init_stream(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + + BaseOutputPinImpl_Active(&filter->source); + return S_OK; +} + +static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + + BaseOutputPinImpl_Inactive(&filter->source); + return S_OK; +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy, + .filter_init_stream = testfilter_init_stream, + .filter_cleanup_stream = testfilter_cleanup_stream, +}; + +static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, source.pin); +} + +static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) +{ + struct testfilter *filter = impl_from_base_pin(iface); + + if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl) + *out = &filter->IMediaSeeking_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + + return S_OK; +} + +static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface, + IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested) +{ + ALLOCATOR_PROPERTIES actual; + + if (!requested->cbAlign) + requested->cbAlign = 1; + + if (requested->cbBuffer < 4096) + requested->cbBuffer = 4096; + + if (!requested->cBuffers) + requested->cBuffers = 2; + + return IMemAllocator_SetProperties(alloc, requested, &actual); +} + +static const struct strmbase_source_ops testsource_ops = +{ + .base.pin_query_interface = testsource_query_interface, + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideBufferSize = testsource_DecideBufferSize, + .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, +}; + +static void testfilter_init(struct testfilter *filter) +{ + static const GUID clsid = {0xabacab}; + memset(filter, 0, sizeof(*filter)); + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + filter->stop_position = 0x8000000000000000ULL; +} + +static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface); +} + +static HRESULT WINAPI testsource_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out); +} + +static ULONG WINAPI testsource_seeking_AddRef(IMediaSeeking *iface) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface); +} + +static ULONG WINAPI testsource_seeking_Release(IMediaSeeking *iface) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + return IBaseFilter_Release(&filter->filter.IBaseFilter_iface); +} + +static HRESULT WINAPI testsource_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + + if (SUCCEEDED(filter->get_duration_hr)) + *duration = 0x8000000000000000ULL; + + return filter->get_duration_hr; +} + +static HRESULT WINAPI testsource_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, + const GUID *target_format, LONGLONG source, const GUID *source_format) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags, + LONGLONG *stop_ptr, DWORD stop_flags) +{ + struct testfilter *filter = impl_from_IMediaSeeking(iface); + + if (SUCCEEDED(filter->set_positions_hr)) + { + if (current_ptr) + filter->current_position = *current_ptr; + + if (stop_ptr) + filter->stop_position = *stop_ptr; + } + + return filter->set_positions_hr; +} + +static HRESULT WINAPI testsource_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_SetRate(IMediaSeeking *iface, double rate) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetRate(IMediaSeeking *iface, double *rate) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testsource_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IMediaSeekingVtbl testsource_seeking_vtbl = +{ + testsource_seeking_QueryInterface, + testsource_seeking_AddRef, + testsource_seeking_Release, + testsource_seeking_GetCapabilities, + testsource_seeking_CheckCapabilities, + testsource_seeking_IsFormatSupported, + testsource_seeking_QueryPreferredFormat, + testsource_seeking_GetTimeFormat, + testsource_seeking_IsUsingTimeFormat, + testsource_seeking_SetTimeFormat, + testsource_seeking_GetDuration, + testsource_seeking_GetStopPosition, + testsource_seeking_GetCurrentPosition, + testsource_seeking_ConvertTimeFormat, + testsource_seeking_SetPositions, + testsource_seeking_GetPositions, + testsource_seeking_GetAvailable, + testsource_seeking_SetRate, + testsource_seeking_GetRate, + testsource_seeking_GetPreroll, +}; + #define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d) static void check_get_stream_(int line, IAMMultiMediaStream *mmstream, IMediaStreamFilter *filter, const GUID *mspid, IMediaStream *expect) @@ -2186,171 +2459,51 @@ static void test_IDirectDrawStreamSample(void)
error: if (ddraw_stream) - IDirectDrawMediaStream_Release(ddraw_stream); - if (stream) - IMediaStream_Release(stream); - - release_directdraw(); - IAMMultiMediaStream_Release(mmstream); -} - -static IUnknown *create_audio_data(void) -{ - IUnknown *audio_data = NULL; - HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (void **)&audio_data); - ok(S_OK == result, "got 0x%08x\n", result); - return audio_data; -} - -static void test_audiodata_query_interface(void) -{ - IUnknown *unknown = create_audio_data(); - IMemoryData *memory_data = NULL; - IAudioData *audio_data = NULL; - - HRESULT result; - - result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data); - ok(E_NOINTERFACE == result, "got 0x%08x\n", result); - - result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); - ok(S_OK == result, "got 0x%08x\n", result); - if (S_OK == result) - { - result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data); - ok(E_NOINTERFACE == result, "got 0x%08x\n", result); - - IAudioData_Release(audio_data); - } - - IUnknown_Release(unknown); -} - -static void test_audiodata_get_info(void) -{ - IUnknown *unknown = create_audio_data(); - IAudioData *audio_data = NULL; - - HRESULT result; - - result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); - if (FAILED(result)) - { - /* test_audiodata_query_interface handles this case */ - skip("No IAudioData\n"); - goto out_unknown; - } - - result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL); - ok(MS_E_NOTINIT == result, "got 0x%08x\n", result); - - IAudioData_Release(audio_data); - -out_unknown: - IUnknown_Release(unknown); -} - -static void test_audiodata_set_buffer(void) -{ - IUnknown *unknown = create_audio_data(); - IAudioData *audio_data = NULL; - BYTE buffer[100] = {0}; - DWORD length = 0; - BYTE *data = NULL; - - HRESULT result; - - result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); - if (FAILED(result)) - { - /* test_audiodata_query_interface handles this case */ - skip("No IAudioData\n"); - goto out_unknown; - } - - result = IAudioData_SetBuffer(audio_data, 100, NULL, 0); - ok(S_OK == result, "got 0x%08x\n", result); - - data = (BYTE *)0xdeadbeef; - length = 0xdeadbeef; - result = IAudioData_GetInfo(audio_data, &length, &data, NULL); - ok(S_OK == result, "got 0x%08x\n", result); - ok(100 == length, "got %u\n", length); - ok(NULL != data, "got %p\n", data); - - result = IAudioData_SetBuffer(audio_data, 0, buffer, 0); - ok(E_INVALIDARG == result, "got 0x%08x\n", result); - - result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0); - ok(S_OK == result, "got 0x%08x\n", result); - - data = (BYTE *)0xdeadbeef; - length = 0xdeadbeef; - result = IAudioData_GetInfo(audio_data, &length, &data, NULL); - ok(S_OK == result, "got 0x%08x\n", result); - ok(sizeof(buffer) == length, "got %u\n", length); - ok(buffer == data, "got %p\n", data); + IDirectDrawMediaStream_Release(ddraw_stream); + if (stream) + IMediaStream_Release(stream);
- IAudioData_Release(audio_data); + release_directdraw(); + IAMMultiMediaStream_Release(mmstream); +}
-out_unknown: - IUnknown_Release(unknown); +static IUnknown *create_audio_data(void) +{ + IUnknown *audio_data = NULL; + HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&audio_data); + ok(S_OK == result, "got 0x%08x\n", result); + return audio_data; }
-static void test_audiodata_set_actual(void) +static void test_audiodata_query_interface(void) { IUnknown *unknown = create_audio_data(); + IMemoryData *memory_data = NULL; IAudioData *audio_data = NULL; - BYTE buffer[100] = {0}; - DWORD actual_data = 0;
HRESULT result;
- result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); - if (FAILED(result)) - { - /* test_audiodata_query_interface handles this case */ - skip("No IAudioData\n"); - goto out_unknown; - } - - result = IAudioData_SetActual(audio_data, 0); - ok(S_OK == result, "got 0x%08x\n", result); - - result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0); - ok(S_OK == result, "got 0x%08x\n", result); - - result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1); - ok(E_INVALIDARG == result, "got 0x%08x\n", result); - - result = IAudioData_SetActual(audio_data, sizeof(buffer)); - ok(S_OK == result, "got 0x%08x\n", result); - - actual_data = 0xdeadbeef; - result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data); - ok(S_OK == result, "got 0x%08x\n", result); - ok(sizeof(buffer) == actual_data, "got %u\n", actual_data); - - result = IAudioData_SetActual(audio_data, 0); - ok(S_OK == result, "got 0x%08x\n", result); + result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data); + ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
- actual_data = 0xdeadbeef; - result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data); + result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); ok(S_OK == result, "got 0x%08x\n", result); - ok(0 == actual_data, "got %u\n", actual_data); + if (S_OK == result) + { + result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data); + ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
- IAudioData_Release(audio_data); + IAudioData_Release(audio_data); + }
-out_unknown: IUnknown_Release(unknown); }
-static void test_audiodata_get_format(void) +static void test_audiodata_get_info(void) { IUnknown *unknown = create_audio_data(); IAudioData *audio_data = NULL; - WAVEFORMATEX wave_format = {0};
HRESULT result;
@@ -2362,25 +2515,8 @@ static void test_audiodata_get_format(void) goto out_unknown; }
- result = IAudioData_GetFormat(audio_data, NULL); - ok(E_POINTER == result, "got 0x%08x\n", result); - - wave_format.wFormatTag = 0xdead; - wave_format.nChannels = 0xdead; - wave_format.nSamplesPerSec = 0xdeadbeef; - wave_format.nAvgBytesPerSec = 0xdeadbeef; - wave_format.nBlockAlign = 0xdead; - wave_format.wBitsPerSample = 0xdead; - wave_format.cbSize = 0xdead; - result = IAudioData_GetFormat(audio_data, &wave_format); - ok(S_OK == result, "got 0x%08x\n", result); - ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag); - ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels); - ok(11025 == wave_format.nSamplesPerSec, "got %u\n", wave_format.nSamplesPerSec); - ok(22050 == wave_format.nAvgBytesPerSec, "got %u\n", wave_format.nAvgBytesPerSec); - ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign); - ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample); - ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize); + result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL); + ok(MS_E_NOTINIT == result, "got 0x%08x\n", result);
IAudioData_Release(audio_data);
@@ -2388,11 +2524,13 @@ out_unknown: IUnknown_Release(unknown); }
-static void test_audiodata_set_format(void) +static void test_audiodata_set_buffer(void) { IUnknown *unknown = create_audio_data(); IAudioData *audio_data = NULL; - WAVEFORMATPCMEX wave_format = {{0}}; + BYTE buffer[100] = {0}; + DWORD length = 0; + BYTE *data = NULL;
HRESULT result;
@@ -2404,328 +2542,190 @@ static void test_audiodata_set_format(void) goto out_unknown; }
- result = IAudioData_SetFormat(audio_data, NULL); - ok(E_POINTER == result, "got 0x%08x\n", result); + result = IAudioData_SetBuffer(audio_data, 100, NULL, 0); + ok(S_OK == result, "got 0x%08x\n", result);
- wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - wave_format.Format.nChannels = 2; - wave_format.Format.nSamplesPerSec = 44100; - wave_format.Format.nAvgBytesPerSec = 176400; - wave_format.Format.nBlockAlign = 4; - wave_format.Format.wBitsPerSample = 16; - wave_format.Format.cbSize = 22; - wave_format.Samples.wValidBitsPerSample = 16; - wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO; - wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - result = IAudioData_SetFormat(audio_data, &wave_format.Format); + data = (BYTE *)0xdeadbeef; + length = 0xdeadbeef; + result = IAudioData_GetInfo(audio_data, &length, &data, NULL); + ok(S_OK == result, "got 0x%08x\n", result); + ok(100 == length, "got %u\n", length); + ok(NULL != data, "got %p\n", data); + + result = IAudioData_SetBuffer(audio_data, 0, buffer, 0); ok(E_INVALIDARG == result, "got 0x%08x\n", result);
- wave_format.Format.wFormatTag = WAVE_FORMAT_PCM; - wave_format.Format.nChannels = 2; - wave_format.Format.nSamplesPerSec = 44100; - wave_format.Format.nAvgBytesPerSec = 176400; - wave_format.Format.nBlockAlign = 4; - wave_format.Format.wBitsPerSample = 16; - wave_format.Format.cbSize = 0; - result = IAudioData_SetFormat(audio_data, &wave_format.Format); + result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0); ok(S_OK == result, "got 0x%08x\n", result);
- wave_format.Format.wFormatTag = 0xdead; - wave_format.Format.nChannels = 0xdead; - wave_format.Format.nSamplesPerSec = 0xdeadbeef; - wave_format.Format.nAvgBytesPerSec = 0xdeadbeef; - wave_format.Format.nBlockAlign = 0xdead; - wave_format.Format.wBitsPerSample = 0xdead; - wave_format.Format.cbSize = 0xdead; - result = IAudioData_GetFormat(audio_data, &wave_format.Format); + data = (BYTE *)0xdeadbeef; + length = 0xdeadbeef; + result = IAudioData_GetInfo(audio_data, &length, &data, NULL); ok(S_OK == result, "got 0x%08x\n", result); - ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag); - ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels); - ok(44100 == wave_format.Format.nSamplesPerSec, "got %u\n", wave_format.Format.nSamplesPerSec); - ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %u\n", wave_format.Format.nAvgBytesPerSec); - ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign); - ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample); - ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize); + ok(sizeof(buffer) == length, "got %u\n", length); + ok(buffer == data, "got %p\n", data);
IAudioData_Release(audio_data);
-out_unknown: - IUnknown_Release(unknown); -} - -struct testfilter -{ - struct strmbase_filter filter; - struct strmbase_source source; - IMediaSeeking IMediaSeeking_iface; - LONGLONG current_position; - LONGLONG stop_position; - HRESULT get_duration_hr; - HRESULT set_positions_hr; -}; - -static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface) -{ - return CONTAINING_RECORD(iface, struct testfilter, filter); -} - -static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) -{ - struct testfilter *filter = impl_from_BaseFilter(iface); - if (!index) - return &filter->source.pin; - return NULL; -} - -static void testfilter_destroy(struct strmbase_filter *iface) -{ - struct testfilter *filter = impl_from_BaseFilter(iface); - strmbase_source_cleanup(&filter->source); - strmbase_filter_cleanup(&filter->filter); -} - -static HRESULT testfilter_init_stream(struct strmbase_filter *iface) -{ - struct testfilter *filter = impl_from_BaseFilter(iface); - - BaseOutputPinImpl_Active(&filter->source); - return S_OK; -} - -static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface) -{ - struct testfilter *filter = impl_from_BaseFilter(iface); - - BaseOutputPinImpl_Inactive(&filter->source); - return S_OK; -} - -static const struct strmbase_filter_ops testfilter_ops = -{ - .filter_get_pin = testfilter_get_pin, - .filter_destroy = testfilter_destroy, - .filter_init_stream = testfilter_init_stream, - .filter_cleanup_stream = testfilter_cleanup_stream, -}; - -static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface) -{ - return CONTAINING_RECORD(iface, struct testfilter, source.pin); -} - -static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) -{ - struct testfilter *filter = impl_from_base_pin(iface); - - if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl) - *out = &filter->IMediaSeeking_iface; - else - return E_NOINTERFACE; - - IUnknown_AddRef((IUnknown *)*out); - - return S_OK; -} - -static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface, - IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested) -{ - ALLOCATOR_PROPERTIES actual; - - if (!requested->cbAlign) - requested->cbAlign = 1; - - if (requested->cbBuffer < 4096) - requested->cbBuffer = 4096; - - if (!requested->cBuffers) - requested->cBuffers = 2; - - return IMemAllocator_SetProperties(alloc, requested, &actual); -} - -static const struct strmbase_source_ops testsource_ops = -{ - .base.pin_query_interface = testsource_query_interface, - .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, - .pfnDecideBufferSize = testsource_DecideBufferSize, - .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator, -}; - -static void testfilter_init(struct testfilter *filter) -{ - static const GUID clsid = {0xabacab}; - memset(filter, 0, sizeof(*filter)); - strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); - strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); - filter->stop_position = 0x8000000000000000ULL; -} - -static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface) -{ - return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface); +out_unknown: + IUnknown_Release(unknown); }
-static HRESULT WINAPI testsource_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out) +static void test_audiodata_set_actual(void) { - struct testfilter *filter = impl_from_IMediaSeeking(iface); - return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out); -} + IUnknown *unknown = create_audio_data(); + IAudioData *audio_data = NULL; + BYTE buffer[100] = {0}; + DWORD actual_data = 0;
-static ULONG WINAPI testsource_seeking_AddRef(IMediaSeeking *iface) -{ - struct testfilter *filter = impl_from_IMediaSeeking(iface); - return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface); -} + HRESULT result;
-static ULONG WINAPI testsource_seeking_Release(IMediaSeeking *iface) -{ - struct testfilter *filter = impl_from_IMediaSeeking(iface); - return IBaseFilter_Release(&filter->filter.IBaseFilter_iface); -} + result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); + if (FAILED(result)) + { + /* test_audiodata_query_interface handles this case */ + skip("No IAudioData\n"); + goto out_unknown; + }
-static HRESULT WINAPI testsource_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_SetActual(audio_data, 0); + ok(S_OK == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0); + ok(S_OK == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1); + ok(E_INVALIDARG == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_SetActual(audio_data, sizeof(buffer)); + ok(S_OK == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + actual_data = 0xdeadbeef; + result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data); + ok(S_OK == result, "got 0x%08x\n", result); + ok(sizeof(buffer) == actual_data, "got %u\n", actual_data);
-static HRESULT WINAPI testsource_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_SetActual(audio_data, 0); + ok(S_OK == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + actual_data = 0xdeadbeef; + result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data); + ok(S_OK == result, "got 0x%08x\n", result); + ok(0 == actual_data, "got %u\n", actual_data); + + IAudioData_Release(audio_data); + +out_unknown: + IUnknown_Release(unknown); }
-static HRESULT WINAPI testsource_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration) +static void test_audiodata_get_format(void) { - struct testfilter *filter = impl_from_IMediaSeeking(iface); + IUnknown *unknown = create_audio_data(); + IAudioData *audio_data = NULL; + WAVEFORMATEX wave_format = {0};
- if (SUCCEEDED(filter->get_duration_hr)) - *duration = 0x8000000000000000ULL; + HRESULT result;
- return filter->get_duration_hr; -} + result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); + if (FAILED(result)) + { + /* test_audiodata_query_interface handles this case */ + skip("No IAudioData\n"); + goto out_unknown; + }
-static HRESULT WINAPI testsource_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + result = IAudioData_GetFormat(audio_data, NULL); + ok(E_POINTER == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + wave_format.wFormatTag = 0xdead; + wave_format.nChannels = 0xdead; + wave_format.nSamplesPerSec = 0xdeadbeef; + wave_format.nAvgBytesPerSec = 0xdeadbeef; + wave_format.nBlockAlign = 0xdead; + wave_format.wBitsPerSample = 0xdead; + wave_format.cbSize = 0xdead; + result = IAudioData_GetFormat(audio_data, &wave_format); + ok(S_OK == result, "got 0x%08x\n", result); + ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag); + ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels); + ok(11025 == wave_format.nSamplesPerSec, "got %u\n", wave_format.nSamplesPerSec); + ok(22050 == wave_format.nAvgBytesPerSec, "got %u\n", wave_format.nAvgBytesPerSec); + ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign); + ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample); + ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize);
-static HRESULT WINAPI testsource_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, - const GUID *target_format, LONGLONG source, const GUID *source_format) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + IAudioData_Release(audio_data); + +out_unknown: + IUnknown_Release(unknown); }
-static HRESULT WINAPI testsource_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags, - LONGLONG *stop_ptr, DWORD stop_flags) +static void test_audiodata_set_format(void) { - struct testfilter *filter = impl_from_IMediaSeeking(iface); + IUnknown *unknown = create_audio_data(); + IAudioData *audio_data = NULL; + WAVEFORMATPCMEX wave_format = {{0}};
- if (SUCCEEDED(filter->set_positions_hr)) - { - if (current_ptr) - filter->current_position = *current_ptr; + HRESULT result;
- if (stop_ptr) - filter->stop_position = *stop_ptr; + result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data); + if (FAILED(result)) + { + /* test_audiodata_query_interface handles this case */ + skip("No IAudioData\n"); + goto out_unknown; }
- return filter->set_positions_hr; -} + result = IAudioData_SetFormat(audio_data, NULL); + ok(E_POINTER == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wave_format.Format.nChannels = 2; + wave_format.Format.nSamplesPerSec = 44100; + wave_format.Format.nAvgBytesPerSec = 176400; + wave_format.Format.nBlockAlign = 4; + wave_format.Format.wBitsPerSample = 16; + wave_format.Format.cbSize = 22; + wave_format.Samples.wValidBitsPerSample = 16; + wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO; + wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + result = IAudioData_SetFormat(audio_data, &wave_format.Format); + ok(E_INVALIDARG == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + wave_format.Format.wFormatTag = WAVE_FORMAT_PCM; + wave_format.Format.nChannels = 2; + wave_format.Format.nSamplesPerSec = 44100; + wave_format.Format.nAvgBytesPerSec = 176400; + wave_format.Format.nBlockAlign = 4; + wave_format.Format.wBitsPerSample = 16; + wave_format.Format.cbSize = 0; + result = IAudioData_SetFormat(audio_data, &wave_format.Format); + ok(S_OK == result, "got 0x%08x\n", result);
-static HRESULT WINAPI testsource_seeking_SetRate(IMediaSeeking *iface, double rate) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + wave_format.Format.wFormatTag = 0xdead; + wave_format.Format.nChannels = 0xdead; + wave_format.Format.nSamplesPerSec = 0xdeadbeef; + wave_format.Format.nAvgBytesPerSec = 0xdeadbeef; + wave_format.Format.nBlockAlign = 0xdead; + wave_format.Format.wBitsPerSample = 0xdead; + wave_format.Format.cbSize = 0xdead; + result = IAudioData_GetFormat(audio_data, &wave_format.Format); + ok(S_OK == result, "got 0x%08x\n", result); + ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag); + ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels); + ok(44100 == wave_format.Format.nSamplesPerSec, "got %u\n", wave_format.Format.nSamplesPerSec); + ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %u\n", wave_format.Format.nAvgBytesPerSec); + ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign); + ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample); + ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize);
-static HRESULT WINAPI testsource_seeking_GetRate(IMediaSeeking *iface, double *rate) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; -} + IAudioData_Release(audio_data);
-static HRESULT WINAPI testsource_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll) -{ - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; +out_unknown: + IUnknown_Release(unknown); }
-static const IMediaSeekingVtbl testsource_seeking_vtbl = -{ - testsource_seeking_QueryInterface, - testsource_seeking_AddRef, - testsource_seeking_Release, - testsource_seeking_GetCapabilities, - testsource_seeking_CheckCapabilities, - testsource_seeking_IsFormatSupported, - testsource_seeking_QueryPreferredFormat, - testsource_seeking_GetTimeFormat, - testsource_seeking_IsUsingTimeFormat, - testsource_seeking_SetTimeFormat, - testsource_seeking_GetDuration, - testsource_seeking_GetStopPosition, - testsource_seeking_GetCurrentPosition, - testsource_seeking_ConvertTimeFormat, - testsource_seeking_SetPositions, - testsource_seeking_GetPositions, - testsource_seeking_GetAvailable, - testsource_seeking_SetRate, - testsource_seeking_GetRate, - testsource_seeking_GetPreroll, -}; - struct testclock { IReferenceClock IReferenceClock_iface;
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/multimedia.c | 4 ++ dlls/amstream/tests/amstream.c | 71 ++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/dlls/amstream/multimedia.c b/dlls/amstream/multimedia.c index f615e436b1..b2c9082cae 100644 --- a/dlls/amstream/multimedia.c +++ b/dlls/amstream/multimedia.c @@ -153,7 +153,11 @@ static HRESULT WINAPI multimedia_stream_SetState(IAMMultiMediaStream *iface, STR TRACE("(%p/%p)->(%u)\n", This, iface, new_state);
if (new_state == STREAMSTATE_RUN) + { hr = IMediaControl_Run(This->media_control); + if (SUCCEEDED(hr)) + hr = S_OK; + } else if (new_state == STREAMSTATE_STOP) hr = IMediaControl_Stop(This->media_control);
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index feb195140e..b0450a0600 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -720,6 +720,8 @@ struct testfilter LONGLONG stop_position; HRESULT get_duration_hr; HRESULT set_positions_hr; + HRESULT init_stream_hr; + HRESULT cleanup_stream_hr; };
static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface) @@ -746,16 +748,20 @@ static HRESULT testfilter_init_stream(struct strmbase_filter *iface) { struct testfilter *filter = impl_from_BaseFilter(iface);
- BaseOutputPinImpl_Active(&filter->source); - return S_OK; + if (SUCCEEDED(filter->init_stream_hr)) + BaseOutputPinImpl_Active(&filter->source); + + return filter->init_stream_hr; }
static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface) { struct testfilter *filter = impl_from_BaseFilter(iface);
- BaseOutputPinImpl_Inactive(&filter->source); - return S_OK; + if (SUCCEEDED(filter->cleanup_stream_hr)) + BaseOutputPinImpl_Inactive(&filter->source); + + return filter->cleanup_stream_hr; }
static const struct strmbase_filter_ops testfilter_ops = @@ -2072,6 +2078,62 @@ static void test_initialize(void) IUnknown_Release(graph_inner_unk); }
+static void test_set_state(void) +{ + IAMMultiMediaStream *mmstream = create_ammultimediastream(); + struct testfilter source; + IGraphBuilder *graph; + HRESULT hr; + ULONG ref; + + hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(graph != NULL, "Expected non-NULL graph.\n"); + testfilter_init(&source); + + hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + source.init_stream_hr = E_FAIL; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); + ok(hr == E_FAIL, "Got hr %#x.\n", hr); + source.init_stream_hr = S_OK; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + source.init_stream_hr = S_FALSE; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); + ok(hr == S_OK, "Got hr %#x.\n", hr); + source.init_stream_hr = S_OK; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); + ok(hr == S_OK, "Got hr %#x.\n", hr); + source.cleanup_stream_hr = E_FAIL; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == E_FAIL, "Got hr %#x.\n", hr); + source.cleanup_stream_hr = S_OK; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN); + ok(hr == S_OK, "Got hr %#x.\n", hr); + source.cleanup_stream_hr = S_FALSE; + hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + source.cleanup_stream_hr = S_OK; + + ref = IAMMultiMediaStream_Release(mmstream); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IGraphBuilder_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + static void test_enum_media_types(void) { IAMMultiMediaStream *mmstream = create_ammultimediastream(); @@ -5126,6 +5188,7 @@ START_TEST(amstream) test_find_pin(); test_pin_info(); test_initialize(); + test_set_state(); test_enum_media_types(); test_media_types(); test_IDirectDrawStreamSample();
Signed-off-by: Anton Baskanov baskanov@gmail.com --- dlls/amstream/multimedia.c | 3 +++ dlls/amstream/tests/amstream.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+)
diff --git a/dlls/amstream/multimedia.c b/dlls/amstream/multimedia.c index b2c9082cae..200bd5c4a5 100644 --- a/dlls/amstream/multimedia.c +++ b/dlls/amstream/multimedia.c @@ -449,6 +449,9 @@ static HRESULT WINAPI multimedia_stream_OpenFile(IAMMultiMediaStream *iface,
IMediaStreamFilter_SupportSeeking(This->filter, This->type == STREAMTYPE_READ);
+ if (SUCCEEDED(ret) && (flags & AMMSF_RUN)) + ret = IAMMultiMediaStream_SetState(iface, STREAMSTATE_RUN); + if (EnumPins) IEnumPins_Release(EnumPins); if (BaseFilter) diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index b0450a0600..c0908545ce 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -273,8 +273,10 @@ static void test_interfaces(void)
static void test_openfile(const WCHAR *test_avi_path) { + IMediaControl *media_control; IMediaStreamFilter *filter; IAMMultiMediaStream *pams; + OAFilterState state; HRESULT hr; LONG ref; IGraphBuilder* pgraph; @@ -318,6 +320,29 @@ static void test_openfile(const WCHAR *test_avi_path) ok(!ref, "Got outstanding refcount %d.\n", ref); ref = IMediaStreamFilter_Release(filter); ok(!ref, "Got outstanding refcount %d.\n", ref); + + pams = create_ammultimediastream(); + hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(pgraph != NULL, "Expected non-NULL graph.\n"); + hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaControl, (void **)&media_control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IAMMultiMediaStream_OpenFile(pams, test_avi_path, AMMSF_RUN); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + state = 0xdeadbeef; + hr = IMediaControl_GetState(media_control, INFINITE, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(state == State_Running, "Got state %#x.\n", state); + + ref = IAMMultiMediaStream_Release(pams); + ok(!ref, "Got outstanding refcount %d.\n", ref); + IMediaControl_Release(media_control); + ref = IGraphBuilder_Release(pgraph); + ok(!ref, "Got outstanding refcount %d.\n", ref); }
static void test_renderfile(const WCHAR *test_avi_path)