static void rungraph(void) { HRESULT hr; IMediaControl* pmc; IMediaEvent* pme; HANDLE hEvent; hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaControl, (LPVOID*)&pmc); ok(hr==S_OK, "Cannot get IMediaControl interface returned: %lx\n", hr); hr = IMediaControl_Run(pmc); ok(hr==S_FALSE, "Cannot run the graph returned: %lx\n", hr); hr = IGraphBuilder_QueryInterface(pgraph, &IID_IMediaEvent, (LPVOID*)&pme); ok(hr==S_OK, "Cannot get IMediaEvent interface returned: %lx\n", hr); hr = IMediaEvent_GetEventHandle(pme, (OAEVENT*)&hEvent); ok(hr==S_OK, "Cannot get event handle returned: %lx\n", hr); /* WaitForSingleObject(hEvent, INFINITE); */ Sleep(20000); hr = IMediaControl_Release(pme); ok(hr==2, "Releasing mediaevent returned: %lx\n", hr); hr = IMediaControl_Stop(pmc); ok(hr==S_OK, "Cannot stop the graph returned: %lx\n", hr); hr = IMediaControl_Release(pmc); ok(hr==1, "Releasing mediacontrol returned: %lx\n", hr); }
/*************************************************************************** * 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; }
static int dshow_read_header(AVFormatContext *avctx) { struct dshow_ctx *ctx = avctx->priv_data; IGraphBuilder *graph = NULL; ICreateDevEnum *devenum = NULL; IMediaControl *control = NULL; IMediaEvent *media_event = NULL; HANDLE media_event_handle; HANDLE proc; int ret = AVERROR(EIO); int r; CoInitialize(0); if (!ctx->list_devices && !parse_device_name(avctx)) { av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n"); goto error; } ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id : AV_CODEC_ID_RAWVIDEO; if (ctx->pixel_format != AV_PIX_FMT_NONE) { if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) { av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when " "video codec is not set or set to rawvideo\n"); ret = AVERROR(EINVAL); goto error; } } if (ctx->framerate) { r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate); if (r < 0) { av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate); goto error; } } r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void **) &graph); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n"); goto error; } ctx->graph = graph; r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum, (void **) &devenum); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n"); goto error; } if (ctx->list_devices) { av_log(avctx, AV_LOG_INFO, "DirectShow video devices (some may be both video and audio devices)\n"); dshow_cycle_devices(avctx, devenum, VideoDevice, VideoSourceDevice, NULL); av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n"); dshow_cycle_devices(avctx, devenum, AudioDevice, AudioSourceDevice, NULL); ret = AVERROR_EXIT; goto error; } if (ctx->list_options) { if (ctx->device_name[VideoDevice]) if ((r = dshow_list_device_options(avctx, devenum, VideoDevice, VideoSourceDevice))) { ret = r; goto error; } if (ctx->device_name[AudioDevice]) { if (dshow_list_device_options(avctx, devenum, AudioDevice, AudioSourceDevice)) { /* show audio options from combined video+audio sources as fallback */ if ((r = dshow_list_device_options(avctx, devenum, AudioDevice, VideoSourceDevice))) { ret = r; goto error; } } } } if (ctx->device_name[VideoDevice]) { if ((r = dshow_open_device(avctx, devenum, VideoDevice, VideoSourceDevice)) < 0 || (r = dshow_add_device(avctx, VideoDevice)) < 0) { ret = r; goto error; } } if (ctx->device_name[AudioDevice]) { if ((r = dshow_open_device(avctx, devenum, AudioDevice, AudioSourceDevice)) < 0 || (r = dshow_add_device(avctx, AudioDevice)) < 0) { av_log(avctx, AV_LOG_INFO, "Searching for audio device within video devices for %s\n", ctx->device_name[AudioDevice]); /* see if there's a video source with an audio pin with the given audio name */ if ((r = dshow_open_device(avctx, devenum, AudioDevice, VideoSourceDevice)) < 0 || (r = dshow_add_device(avctx, AudioDevice)) < 0) { ret = r; goto error; } } } if (ctx->list_options) { /* allow it to list crossbar options in dshow_open_device */ ret = AVERROR_EXIT; goto error; } ctx->curbufsize[0] = 0; ctx->curbufsize[1] = 0; ctx->mutex = CreateMutex(NULL, 0, NULL); if (!ctx->mutex) { av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n"); goto error; } ctx->event[1] = CreateEvent(NULL, 1, 0, NULL); if (!ctx->event[1]) { av_log(avctx, AV_LOG_ERROR, "Could not create Event\n"); goto error; } r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n"); goto error; } ctx->control = control; r = IGraphBuilder_QueryInterface(graph, &IID_IMediaEvent, (void **) &media_event); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get media event.\n"); goto error; } ctx->media_event = media_event; r = IMediaEvent_GetEventHandle(media_event, (void *) &media_event_handle); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not get media event handle.\n"); goto error; } proc = GetCurrentProcess(); r = DuplicateHandle(proc, media_event_handle, proc, &ctx->event[0], 0, 0, DUPLICATE_SAME_ACCESS); if (!r) { av_log(avctx, AV_LOG_ERROR, "Could not duplicate media event handle.\n"); goto error; } r = IMediaControl_Run(control); if (r == S_FALSE) { OAFilterState pfs; r = IMediaControl_GetState(control, 0, &pfs); } if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not run graph (sometimes caused by a device already in use by other application)\n"); goto error; } ret = 0; error: if (devenum) ICreateDevEnum_Release(devenum); if (ret < 0) dshow_read_close(avctx); return ret; }