[PATCH 4/7] wmp: Add media completion notifications
Zebediah Figura
z.figura12 at gmail.com
Tue Mar 13 10:31:01 CDT 2018
On 12/03/18 23:34, Anton Romanov wrote:
> Signed-off-by: Anton Romanov <theli.ua at gmail.com>
> ---
> dlls/wmp/player.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-
> dlls/wmp/wmp_private.h | 5 ++++
> 2 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c
> index 81ce9f2969..42ee06315a 100644
> --- a/dlls/wmp/player.c
> +++ b/dlls/wmp/player.c
> @@ -25,6 +25,7 @@
> WINE_DEFAULT_DEBUG_CHANNEL(wmp);
>
> static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state);
> +static DWORD CALLBACK WMP_event_thread(LPVOID parm);
>
> static inline WMPMedia *impl_from_IWMPMedia(IWMPMedia *iface)
> {
> @@ -197,18 +198,20 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia
> {
> WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
> TRACE("(%p)->(%p)\n", This, pMedia);
> +
> if(pMedia == NULL) {
> return E_POINTER;
> }
> update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING);
> if(This->wmpmedia != NULL) {
> + IWMPControls_stop(&This->IWMPControls_iface);
> IWMPMedia_Release(This->wmpmedia);
> }
> update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED);
> update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA);
>
> + IWMPMedia_AddRef(pMedia);
> This->wmpmedia = pMedia;
> - IWMPMedia_AddRef(This->wmpmedia);
> return S_OK;
> }
>
> @@ -1401,6 +1404,11 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
> hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl,
> (void**)&This->media_control);
> update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN);
> + if (SUCCEEDED(hres))
> + hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent,
> + (void**)&This->media_event);
> + This->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL);
> + This->event_thread = CreateThread(NULL, 0, WMP_event_thread, This, 0, NULL);
This->stop_event will be leaked here if it was already set; probably you
want to close it in WMPControls_stop() instead.
> HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia)
> {
> WMPMedia *media = heap_alloc_zero(sizeof(WMPMedia));
> +
> + if (!media) {
> + return E_OUTOFMEMORY;
> + }
> +
> media->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl;
> media->url = heap_strdupW(url);
> media->ref = 1;
This belongs in the same patch where this function was added.
> @@ -1851,3 +1873,47 @@ static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state)
> call_sink(wmp->wmpocx, type,
> &dispparams);
> }
> +
> +static DWORD CALLBACK WMP_event_thread(LPVOID parm)
> +{
> + WindowsMediaPlayer* wmp = (WindowsMediaPlayer *)parm;
> + HRESULT hr;
> + HANDLE handle[2];
> + DWORD n = 0, ret = 0;
> +
> + handle[n++] = wmp->stop_event;
> + IMediaEvent_GetEventHandle(wmp->media_event, (OAEVENT *)&handle[n++]);
> + for (;;) {
> + DWORD r;
> +
> + r = WaitForMultipleObjects(n, handle, FALSE, INFINITE);
> + if (r == WAIT_OBJECT_0) {
> + TRACE("got stop event\n");
> + break;
> + }
> + else if (r == WAIT_OBJECT_0+1) {
> + LONG event_code;
> + LONG_PTR p1, p2;
> + do {
> + hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0);
> + if (SUCCEEDED(hr)) {
> + TRACE("got event_code = 0x%02x\n", event_code);
> + /* For now we only handle EC_COMPLETE */
> + if (event_code == EC_COMPLETE) {
> + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_MEDIA_ENDED);
> + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING);
> + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED);
> + }
> +
> + IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2);
> + }
> + } while (hr == S_OK);
> + }
> + else {
> + TRACE("Unknown error (%d)\n", (int)r);
> + break;
> + }
> + }
This probably deserves an ERR more than a TRACE.
> +
> + return ret;
> +}
> diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h
> index b2077fe77d..1ffc36c74c 100644
> --- a/dlls/wmp/wmp_private.h
> +++ b/dlls/wmp/wmp_private.h
> @@ -75,6 +75,11 @@ struct WindowsMediaPlayer {
> /* DirectShow stuff */
> IGraphBuilder* pFilterGraph;
> IMediaControl* media_control;
> + IMediaEvent* media_event;
> +
> + /* Async event notification */
> + HANDLE event_thread;
> + HANDLE stop_event;
> };
>
> void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
>
More information about the wine-devel
mailing list