HRESULT wasapi_change_init(struct ao *ao) { MP_DBG(ao, "Setting up monitoring on playback device\n"); struct wasapi_state *state = (struct wasapi_state *)ao->priv; struct change_notify *change = &state->change; /* COM voodoo to emulate c++ class */ change->client.lpVtbl = &sIMMDeviceEnumeratorVtbl_vtbl; /* so the callbacks can access the ao */ change->ao = ao; /* get the device string to compare with the pwstrDeviceId argument in callbacks */ HRESULT hr = IMMDevice_GetId(state->pDevice, &change->monitored); EXIT_ON_ERROR(hr); /* register the change notification client */ hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback( state->pEnumerator, (IMMNotificationClient *)change); EXIT_ON_ERROR(hr); MP_VERBOSE(state, "Monitoring changes in device: %S\n", state->change.monitored); return hr; exit_label: MP_ERR(state, "Error setting up device change monitoring: %s\n", wasapi_explain_err(hr)); wasapi_change_uninit(ao); return hr; }
HRESULT wasapi_change_init(struct ao *ao, bool is_hotplug) { struct wasapi_state *state = ao->priv; struct change_notify *change = &state->change; HRESULT hr; /* COM voodoo to emulate c++ class */ change->client.lpVtbl = &sIMMDeviceEnumeratorVtbl_vtbl; /* register the change notification client */ hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback( state->pEnumerator, (IMMNotificationClient *)change); EXIT_ON_ERROR(hr); /* so the callbacks can access the ao */ change->ao = ao; /* whether or not this is the hotplug instance */ change->is_hotplug = is_hotplug; if (is_hotplug) { MP_DBG(ao, "Monitoring for hotplug events\n"); } else { /* Get the device string to compare with the pwstrDeviceId */ hr = IMMDevice_GetId(state->pDevice, &change->monitored); EXIT_ON_ERROR(hr); MP_VERBOSE(ao, "Monitoring changes in device %S\n", change->monitored); } return hr; exit_label: MP_ERR(state, "Error setting up device change monitoring: %s\n", mp_HRESULT_to_str(hr)); wasapi_change_uninit(ao); return hr; }
HRESULT wasapi_change_init(struct ao *ao, bool is_hotplug) { struct wasapi_state *state = ao->priv; struct change_notify *change = &state->change; HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void **)&change->pEnumerator); EXIT_ON_ERROR(hr); // COM voodoo to emulate c++ class change->client.lpVtbl = &sIMMNotificationClientVtbl; // register the change notification client hr = IMMDeviceEnumerator_RegisterEndpointNotificationCallback( change->pEnumerator, (IMMNotificationClient *)change); EXIT_ON_ERROR(hr); // so the callbacks can access the ao change->ao = ao; // whether or not this is the hotplug instance change->is_hotplug = is_hotplug; if (is_hotplug) { MP_DBG(ao, "Monitoring for hotplug events\n"); } else { // Get the device string to compare with the pwstrDeviceId change->monitored = state->deviceID; MP_VERBOSE(ao, "Monitoring changes in device %S\n", change->monitored); } return hr; exit_label: MP_ERR(state, "Error setting up device change monitoring: %s\n", mp_HRESULT_to_str(hr)); wasapi_change_uninit(ao); return hr; }
JNIEXPORT jlong JNICALL Java_org_jitsi_impl_neomedia_jmfext_media_protocol_wasapi_WASAPI_CoCreateInstance (JNIEnv *env, jclass clazz, jstring clsid, jlong pUnkOuter, jint dwClsContext, jstring iid) { HRESULT hr; CLSID clsid_; LPVOID pv; if (clsid) { const jchar *szClsid = (*env)->GetStringChars(env, clsid, NULL); if (szClsid) { hr = CLSIDFromString((LPOLESTR) szClsid, &clsid_); (*env)->ReleaseStringChars(env, clsid, szClsid); if (FAILED(hr)) WASAPI_throwNewHResultException(env, hr, __func__, __LINE__); } else hr = E_OUTOFMEMORY; } else hr = S_OK; if (SUCCEEDED(hr)) { IID iid_; hr = WASAPI_iidFromString(env, iid, &iid_); if (SUCCEEDED(hr)) { hr = CoCreateInstance( &clsid_, (LPUNKNOWN) (intptr_t) pUnkOuter, (DWORD) dwClsContext, &iid_, &pv); if (SUCCEEDED(hr)) { /* * There is statically allocated IMMNotificationClient instance * which is to be registered with every IMMDeviceEnumerator * instance. */ if (IsEqualIID(__uuidof(IID_IMMDeviceEnumerator), &iid_)) { IMMDeviceEnumerator_RegisterEndpointNotificationCallback( (IMMDeviceEnumerator *) pv, (IMMNotificationClient *) &WASAPI_iMMNotificationClient); } } else { pv = NULL; WASAPI_throwNewHResultException(env, hr, __func__, __LINE__); } } else pv = NULL; } else pv = NULL; return (jlong) (intptr_t) pv; }