-- v2: mfmediaengine: Pass volume changes to the audio renderer.
From: Bernhard Kölbl besentv@gmail.com
Testing playback of a short mp4 file with h264 video and aac audio.
This test would hang before the changes made to media format handling for output nodes in the media session. Adding it now to reduce the risk of regressions. --- dlls/mfmediaengine/tests/mfmediaengine.c | 192 +++++++++++++++++++++++ dlls/mfmediaengine/tests/resource.rc | 7 + dlls/mfmediaengine/tests/test.mp4 | Bin 0 -> 4355 bytes 3 files changed, 199 insertions(+) create mode 100644 dlls/mfmediaengine/tests/test.mp4
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 3a5b2bf8253..df662e356af 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1313,6 +1313,197 @@ done: CloseHandle(notify.ready_event); }
+static WCHAR *unpack_resource(const WCHAR *name) +{ + static WCHAR path[MAX_PATH]; + void *res_data; + DWORD written; + HANDLE file; + HRSRC res; + + GetTempPathW(ARRAY_SIZE(path), path); + lstrcatW(path, name); + + file = CreateFileW(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n", wine_dbgstr_w(path), GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok(res != 0, "couldn't find resource\n"); + + res_data = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, res_data, SizeofResource(GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "couldn't write resource\n" ); + + CloseHandle(file); + + return path; +} + +struct playback_notify +{ + IMFMediaEngineNotify IMFMediaEngineNotify_iface; + + IMFMediaEngineEx *media_engine; + HANDLE ended_event; + HANDLE ready_event; + HRESULT error; +}; + +static HRESULT WINAPI playback_notify_QueryInterface(IMFMediaEngineNotify *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IMFMediaEngineNotify)) + { + *obj = iface; + IMFMediaEngineNotify_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI playback_notify_AddRef(IMFMediaEngineNotify *iface) +{ + return 2; +} + +static ULONG WINAPI playback_notify_Release(IMFMediaEngineNotify *iface) +{ + return 1; +} + +static HRESULT WINAPI playback_notify_EventNotify(IMFMediaEngineNotify *iface, DWORD event, DWORD_PTR param1, DWORD param2) +{ + struct playback_notify *notify = CONTAINING_RECORD(iface, struct playback_notify, IMFMediaEngineNotify_iface); + IMFMediaEngineEx *media_engine = notify->media_engine; + DWORD width, height; + HRESULT hr; + BOOL ret; + + switch (event) + { + case MF_MEDIA_ENGINE_EVENT_CANPLAY: + hr = IMFMediaEngineEx_Play(media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + break; + + case MF_MEDIA_ENGINE_EVENT_FORMATCHANGE: + ret = IMFMediaEngineEx_HasVideo(media_engine); + ok(ret, "Unexpected HasVideo %u.\n", ret); + hr = IMFMediaEngineEx_GetNativeVideoSize(media_engine, &width, &height); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(width == 32, "Unexpected width %lu.\n", width); + ok(height == 24, "Unexpected height %lu.\n", height); + break; + + case MF_MEDIA_ENGINE_EVENT_ERROR: + ok(broken(param2 == MF_E_UNSUPPORTED_BYTESTREAM_TYPE), "Unexpected error %#lx\n", param2); + notify->error = param2; + /* fallthrough */ + case MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY: + hr = IMFMediaEngineEx_Play(media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE: + SetEvent(notify->ready_event); + break; + case MF_MEDIA_ENGINE_EVENT_ENDED: + SetEvent(notify->ended_event); + break; + } + + return S_OK; +} + +static IMFMediaEngineNotifyVtbl playback_notify_vtbl = +{ + playback_notify_QueryInterface, + playback_notify_AddRef, + playback_notify_Release, + playback_notify_EventNotify, +}; + +static void test_video_playback(void) +{ + struct playback_notify notify = {{&playback_notify_vtbl}}; + IMFMediaEngineEx *media_engine; + IMFDXGIDeviceManager *manager; + double current_time, duration; + LONGLONG presentation_time; + WCHAR *filename = NULL; + ID3D11Device *device; + UINT token; + HRESULT hr; + DWORD res; + + notify.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!notify.ready_event, "CreateEventW failed, error %lu\n", GetLastError()); + + notify.ended_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!notify.ended_event, "CreateEventW failed, error %lu\n", GetLastError()); + + if (!(device = create_d3d11_device())) + { + skip("Failed to create a D3D11 device, skipping tests.\n"); + return; + } + + hr = pMFCreateDXGIDeviceManager(&token, &manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + media_engine = create_media_engine_ex(¬ify.IMFMediaEngineNotify_iface, + manager, DXGI_FORMAT_B8G8R8X8_UNORM); + + IMFDXGIDeviceManager_Release(manager); + + media_engine = create_media_engine_ex(¬ify.IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM); + + if (!(notify.media_engine = media_engine)) + return; + + filename = unpack_resource(L"test.mp4"); + ok(!!filename, "Failed to unpack resource.\n"); + + hr = IMFMediaEngineEx_SetSource(media_engine, filename); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + res = WaitForSingleObject(notify.ready_event, 5000); + ok(!res, "Unexpected res %#lx.\n", res); + + if (FAILED(notify.error)) + { + win_skip("Media engine reported error %#lx, skipping tests.\n", notify.error); + goto done; + } + + duration = IMFMediaEngineEx_GetDuration(media_engine); + todo_wine ok(duration == 0.167, "IMFMediaEngineEx_GetDuration returned %lf.\n", duration); + + while (WaitForSingleObject(notify.ended_event, 25) > WAIT_OBJECT_0) + { + current_time = IMFMediaEngineEx_GetCurrentTime(media_engine); + ok(current_time <= 0.260, "IMFMediaEngineEx_GetCurrentTime returned %lf.\n", current_time); + + hr = IMFMediaEngineEx_OnVideoStreamTick(media_engine, &presentation_time); + ok(hr == S_OK || hr == S_FALSE, "Unexpected hr %#lx.\n", hr); + ok(presentation_time <= 1670000, "presentation_time was %llu.\n", presentation_time); + } + + current_time = IMFMediaEngineEx_GetCurrentTime(media_engine); + ok(current_time <= 0.260, "IMFMediaEngineEx_GetCurrentTime returned %lf.\n", current_time); + +done: + IMFMediaEngineEx_Shutdown(media_engine); + IMFMediaEngineEx_Release(media_engine); + + ID3D11Device_Release(device); + + CloseHandle(notify.ended_event); + CloseHandle(notify.ready_event); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -1344,6 +1535,7 @@ START_TEST(mfmediaengine) test_SetSourceFromByteStream(); test_audio_configuration(); test_TransferVideoFrames(); + test_video_playback();
IMFMediaEngineClassFactory_Release(factory);
diff --git a/dlls/mfmediaengine/tests/resource.rc b/dlls/mfmediaengine/tests/resource.rc index 50152586758..60ef1da78e6 100644 --- a/dlls/mfmediaengine/tests/resource.rc +++ b/dlls/mfmediaengine/tests/resource.rc @@ -30,3 +30,10 @@ i420-64x64.avi RCDATA i420-64x64.avi /* Generated from running the tests on Windows */ /* @makedep: rgb32frame.bmp */ rgb32frame.bmp RCDATA rgb32frame.bmp + +/* ffmpeg -filter_complex "testsrc=duration=0.16:size=32x24:rate=30,colorspace=iall=bt709:all=bt709:format=yuv420p[0]; \ + * sine=frequency=1000:duration=0.16[1]" -c:v h264 -profile:v main \ + * -map "[0]:v" -map "[1]:a" -to 0.16s -f mp4 -y test.mp4 + */ +/* @makedep: test.mp4 */ +test.mp4 RCDATA test.mp4 diff --git a/dlls/mfmediaengine/tests/test.mp4 b/dlls/mfmediaengine/tests/test.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..bb367c996be78ac1dec5c6c9e40d4c1d2e26d1a4 GIT binary patch literal 4355 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
literal 0 HcmV?d00001
From: Bernhard Kölbl besentv@gmail.com
--- dlls/mfmediaengine/main.c | 58 ++++++++++++++++++++---- dlls/mfmediaengine/tests/mfmediaengine.c | 3 ++ 2 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index b2ddc376db8..c15fdbd164c 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -174,6 +174,10 @@ struct media_engine } cb; } d3d11; } video_frame; + struct + { + IMFMediaSink *sar; + } audio_renderer; CRITICAL_SECTION cs; };
@@ -1002,27 +1006,36 @@ static HRESULT media_engine_create_source_node(IMFMediaSource *source, IMFPresen static HRESULT media_engine_create_audio_renderer(struct media_engine *engine, IMFTopologyNode **node) { unsigned int category, role; - IMFActivate *sar_activate; + IMFAttributes *attrs; + IMFStreamSink *sink; + IMFMediaSink *sar; HRESULT hr;
*node = NULL;
- if (FAILED(hr = MFCreateAudioRendererActivate(&sar_activate))) + if (FAILED(hr = MFCreateAttributes(&attrs, 2))) return hr;
/* Configuration attributes keys differ between Engine and SAR. */ if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, &category))) - IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, category); + IMFAttributes_SetUINT32(attrs, &MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, category); if (SUCCEEDED(IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, &role))) - IMFActivate_SetUINT32(sar_activate, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, role); + IMFAttributes_SetUINT32(attrs, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, role); + + if (FAILED(hr = MFCreateAudioRenderer(attrs, &sar))) + return hr; + + if (FAILED(hr = IMFMediaSink_GetStreamSinkByIndex(sar, 0, &sink))) + return hr;
if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, node))) { - IMFTopologyNode_SetObject(*node, (IUnknown *)sar_activate); + IMFTopologyNode_SetObject(*node, (IUnknown *)sink); IMFTopologyNode_SetUINT32(*node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE); }
- IMFActivate_Release(sar_activate); + IMFStreamSink_Release(sink); + engine->audio_renderer.sar = sar;
return hr; } @@ -1084,6 +1097,12 @@ static void media_engine_clear_presentation(struct media_engine *engine) if (engine->presentation.pd) IMFPresentationDescriptor_Release(engine->presentation.pd); memset(&engine->presentation, 0, sizeof(engine->presentation)); + if (engine->audio_renderer.sar) + { + IMFMediaSink_Shutdown(engine->audio_renderer.sar); + IMFMediaSink_Release(engine->audio_renderer.sar); + engine->audio_renderer.sar = NULL; + } }
static HRESULT media_engine_create_topology(struct media_engine *engine, IMFMediaSource *source) @@ -1999,6 +2018,7 @@ static double WINAPI media_engine_GetVolume(IMFMediaEngineEx *iface) static HRESULT WINAPI media_engine_SetVolume(IMFMediaEngineEx *iface, double volume) { struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + IMFGetService *service = NULL; HRESULT hr = S_OK;
TRACE("%p, %f.\n", iface, volume); @@ -2008,9 +2028,31 @@ static HRESULT WINAPI media_engine_SetVolume(IMFMediaEngineEx *iface, double vol hr = MF_E_SHUTDOWN; else if (volume != engine->volume) { - engine->volume = volume; - IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + IMFSimpleAudioVolume *sa_volume; + + if (!engine->audio_renderer.sar) + { + hr = E_FAIL; + goto done; + } + + if (FAILED(hr = IMFMediaSink_QueryInterface(engine->audio_renderer.sar, &IID_IMFGetService, (void **)&service))) + goto done; + + if (FAILED(hr = IMFGetService_GetService(service, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, (void **)&sa_volume))) + goto done; + + if (SUCCEEDED(hr = IMFSimpleAudioVolume_SetMasterVolume(sa_volume, (float)volume))) + { + engine->volume = volume; + IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE, 0, 0); + } + + IMFSimpleAudioVolume_Release(sa_volume); } +done: + if (service) + IMFGetService_Release(service); LeaveCriticalSection(&engine->cs);
return hr; diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index df662e356af..0d4d89af0f3 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -1472,6 +1472,9 @@ static void test_video_playback(void) res = WaitForSingleObject(notify.ready_event, 5000); ok(!res, "Unexpected res %#lx.\n", res);
+ hr = IMFMediaEngineEx_SetVolume(media_engine, 0.1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(notify.error)) { win_skip("Media engine reported error %#lx, skipping tests.\n", notify.error);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126687
Your paranoid android.
=== w1064v1809 (32 bit report) ===
mfmediaengine: mfmediaengine.c:1490: Test failed: IMFMediaEngineEx_GetCurrentTime returned 0.269275. mfmediaengine.c:1498: Test failed: IMFMediaEngineEx_GetCurrentTime returned 0.269275.