/*************************************************************************** * MCIQTZ_notifyThread [internal] */ static DWORD CALLBACK MCIQTZ_notifyThread(LPVOID parm) { WINE_MCIQTZ* wma = (WINE_MCIQTZ *)parm; HRESULT hr; HANDLE handle[2]; DWORD n = 0, ret = 0; handle[n++] = wma->stop_event; IMediaEvent_GetEventHandle(wma->mevent, (OAEVENT *)&handle[n++]); for (;;) { DWORD r; HANDLE old; r = WaitForMultipleObjects(n, handle, FALSE, INFINITE); if (r == WAIT_OBJECT_0) { TRACE("got stop event\n"); old = InterlockedExchangePointer(&wma->callback, NULL); if (old) mciDriverNotify(old, wma->notify_devid, MCI_NOTIFY_ABORTED); break; } else if (r == WAIT_OBJECT_0+1) { LONG event_code; LONG_PTR p1, p2; do { hr = IMediaEvent_GetEvent(wma->mevent, &event_code, &p1, &p2, 0); if (SUCCEEDED(hr)) { TRACE("got event_code = 0x%02x\n", event_code); IMediaEvent_FreeEventParams(wma->mevent, event_code, p1, p2); } } while (hr == S_OK && event_code != EC_COMPLETE); if (hr == S_OK && event_code == EC_COMPLETE) { old = InterlockedExchangePointer(&wma->callback, NULL); if (old) mciDriverNotify(old, wma->notify_devid, MCI_NOTIFY_SUCCESSFUL); break; } } else { TRACE("Unknown error (%d)\n", (int)r); break; } } hr = IMediaControl_Stop(wma->pmctrl); if (FAILED(hr)) { TRACE("Cannot stop filtergraph (hr = %x)\n", hr); ret = MCIERR_INTERNAL; } return ret; }
/** * Checks media events from DirectShow and returns -1 on error or EOF. Also * purges all events that might be in the event queue to stop the trigger * of event notification. */ static int dshow_check_event_queue(IMediaEvent *media_event) { LONG_PTR p1, p2; long code; int ret = 0; while (IMediaEvent_GetEvent(media_event, &code, &p1, &p2, 0) != E_ABORT) { if (code == EC_COMPLETE || code == EC_DEVICE_LOST || code == EC_ERRORABORT) ret = -1; IMediaEvent_FreeEventParams(media_event, code, p1, p2); } return ret; }