/****************************************************************************** * MCIAVI_mciUpdate [internal] */ static DWORD MCIQTZ_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms) { WINE_MCIQTZ *wma; DWORD res = 0; TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms); if (!lpParms) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; if (dwFlags & MCI_DGV_UPDATE_HDC) { LONG state, size; BYTE *data; BITMAPINFO *info; HRESULT hr; RECT src, dest; LONG visible = OATRUE; res = MCIERR_INTERNAL; IMediaControl_GetState(wma->pmctrl, -1, &state); if (state == State_Running) return MCIERR_UNSUPPORTED_FUNCTION; /* If in stopped state, nothing has been drawn to screen * moving to pause, which is needed for the old dib renderer, will result * in a single frame drawn, so hide the window here */ IVideoWindow_get_Visible(wma->vidwin, &visible); if (wma->parent) IVideoWindow_put_Visible(wma->vidwin, OAFALSE); /* FIXME: Should we check the original state and restore it? */ IMediaControl_Pause(wma->pmctrl); IMediaControl_GetState(wma->pmctrl, -1, &state); if (FAILED(hr = IBasicVideo_GetCurrentImage(wma->vidbasic, &size, NULL))) { WARN("Could not get image size (hr = %x)\n", hr); goto out; } data = HeapAlloc(GetProcessHeap(), 0, size); info = (BITMAPINFO*)data; IBasicVideo_GetCurrentImage(wma->vidbasic, &size, (LONG*)data); data += info->bmiHeader.biSize; IBasicVideo_GetSourcePosition(wma->vidbasic, &src.left, &src.top, &src.right, &src.bottom); IBasicVideo_GetDestinationPosition(wma->vidbasic, &dest.left, &dest.top, &dest.right, &dest.bottom); StretchDIBits(lpParms->hDC, dest.left, dest.top, dest.right + dest.left, dest.bottom + dest.top, src.left, src.top, src.right + src.left, src.bottom + src.top, data, info, DIB_RGB_COLORS, SRCCOPY); HeapFree(GetProcessHeap(), 0, data); res = 0; out: if (wma->parent) IVideoWindow_put_Visible(wma->vidwin, visible); } else if (dwFlags) FIXME("Unhandled flags %x\n", dwFlags); return res; }
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; }
static int dshow_read_header(AVFormatContext *avctx) { struct dshow_ctx *ctx = avctx->priv_data; IGraphBuilder *graph = NULL; ICreateDevEnum *devenum = NULL; IMediaControl *control = NULL; int ret = AVERROR(EIO); int r; 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; } } CoInitialize(0); 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\n"); dshow_cycle_devices(avctx, devenum, VideoDevice, NULL); av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n"); dshow_cycle_devices(avctx, devenum, AudioDevice, NULL); ret = AVERROR_EXIT; goto error; } if (ctx->list_options) { if (ctx->device_name[VideoDevice]) dshow_list_device_options(avctx, devenum, VideoDevice); if (ctx->device_name[AudioDevice]) dshow_list_device_options(avctx, devenum, AudioDevice); ret = AVERROR_EXIT; goto error; } if (ctx->device_name[VideoDevice]) { if ((r = dshow_open_device(avctx, devenum, VideoDevice)) < 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)) < 0 || (r = dshow_add_device(avctx, AudioDevice)) < 0) { ret = r; goto error; } } ctx->mutex = CreateMutex(NULL, 0, NULL); if (!ctx->mutex) { av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n"); goto error; } ctx->event = CreateEvent(NULL, 1, 0, NULL); if (!ctx->event) { 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 = 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 filter\n"); goto error; } ret = 0; error: if (ret < 0) dshow_read_close(avctx); if (devenum) ICreateDevEnum_Release(devenum); return ret; }
/*************************************************************************** * MCIQTZ_mciStatus [internal] */ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpParms) { WINE_MCIQTZ* wma; HRESULT hr; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); if (!lpParms) return MCIERR_NULL_PARAMETER_BLOCK; wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; if (!(dwFlags & MCI_STATUS_ITEM)) { WARN("No status item specified\n"); return MCIERR_UNRECOGNIZED_COMMAND; } switch (lpParms->dwItem) { case MCI_STATUS_LENGTH: { LONGLONG duration = -1; GUID format; switch (wma->time_format) { case MCI_FORMAT_MILLISECONDS: format = TIME_FORMAT_MEDIA_TIME; break; case MCI_FORMAT_FRAMES: format = TIME_FORMAT_FRAME; break; default: ERR("Unhandled format %x\n", wma->time_format); break; } hr = IMediaSeeking_SetTimeFormat(wma->seek, &format); if (FAILED(hr)) { FIXME("Cannot set time format (hr = %x)\n", hr); lpParms->dwReturn = 0; break; } hr = IMediaSeeking_GetDuration(wma->seek, &duration); if (FAILED(hr) || duration < 0) { FIXME("Cannot read duration (hr = %x)\n", hr); lpParms->dwReturn = 0; } else if (wma->time_format != MCI_FORMAT_MILLISECONDS) lpParms->dwReturn = duration; else lpParms->dwReturn = duration / 10000; break; } case MCI_STATUS_POSITION: { REFERENCE_TIME curpos; hr = IMediaSeeking_GetCurrentPosition(wma->seek, &curpos); if (FAILED(hr)) { FIXME("Cannot get position (hr = %x)\n", hr); return MCIERR_INTERNAL; } lpParms->dwReturn = curpos / 10000; break; } case MCI_STATUS_NUMBER_OF_TRACKS: FIXME("MCI_STATUS_NUMBER_OF_TRACKS not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_MODE: { LONG state = State_Stopped; IMediaControl_GetState(wma->pmctrl, -1, &state); if (state == State_Stopped) lpParms->dwReturn = MCI_MODE_STOP; else if (state == State_Running) { LONG code; LONG_PTR p1, p2; lpParms->dwReturn = MCI_MODE_PLAY; do { hr = IMediaEvent_GetEvent(wma->mevent, &code, &p1, &p2, 0); if (hr == S_OK && code == EC_COMPLETE){ lpParms->dwReturn = MCI_MODE_STOP; IMediaControl_Stop(wma->pmctrl); } } while (hr == S_OK); } else if (state == State_Paused) lpParms->dwReturn = MCI_MODE_PAUSE; break; } case MCI_STATUS_MEDIA_PRESENT: FIXME("MCI_STATUS_MEDIA_PRESENT not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_TIME_FORMAT: lpParms->dwReturn = wma->time_format; break; case MCI_STATUS_READY: FIXME("MCI_STATUS_READY not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_CURRENT_TRACK: FIXME("MCI_STATUS_CURRENT_TRACK not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; default: FIXME("Unknown command %08X\n", lpParms->dwItem); return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_NOTIFY) mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)), wDevID, MCI_NOTIFY_SUCCESSFUL); return 0; }
/*************************************************************************** * MCIQTZ_mciStatus [internal] */ static DWORD MCIQTZ_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpParms) { WINE_MCIQTZ* wma; HRESULT hr; DWORD ret = MCI_INTEGER_RETURNED; TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); wma = MCIQTZ_mciGetOpenDev(wDevID); if (!wma) return MCIERR_INVALID_DEVICE_ID; if (!(dwFlags & MCI_STATUS_ITEM)) { WARN("No status item specified\n"); return MCIERR_UNRECOGNIZED_COMMAND; } switch (lpParms->dwItem) { case MCI_STATUS_LENGTH: { LONGLONG duration = -1; GUID format; switch (wma->time_format) { case MCI_FORMAT_MILLISECONDS: format = TIME_FORMAT_MEDIA_TIME; break; case MCI_FORMAT_FRAMES: format = TIME_FORMAT_FRAME; break; default: ERR("Unhandled format %x\n", wma->time_format); break; } hr = IMediaSeeking_SetTimeFormat(wma->seek, &format); if (FAILED(hr)) { FIXME("Cannot set time format (hr = %x)\n", hr); lpParms->dwReturn = 0; break; } hr = IMediaSeeking_GetDuration(wma->seek, &duration); if (FAILED(hr) || duration < 0) { FIXME("Cannot read duration (hr = %x)\n", hr); lpParms->dwReturn = 0; } else if (wma->time_format != MCI_FORMAT_MILLISECONDS) lpParms->dwReturn = duration; else lpParms->dwReturn = duration / 10000; break; } case MCI_STATUS_POSITION: { REFERENCE_TIME curpos; hr = IMediaSeeking_GetCurrentPosition(wma->seek, &curpos); if (FAILED(hr)) { FIXME("Cannot get position (hr = %x)\n", hr); return MCIERR_INTERNAL; } lpParms->dwReturn = curpos / 10000; break; } case MCI_STATUS_NUMBER_OF_TRACKS: FIXME("MCI_STATUS_NUMBER_OF_TRACKS not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_MODE: { LONG state = State_Stopped; IMediaControl_GetState(wma->pmctrl, -1, &state); if (state == State_Stopped) lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_STOP, MCI_MODE_STOP); else if (state == State_Running) { lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PLAY, MCI_MODE_PLAY); if (!wma->thread || WaitForSingleObject(wma->thread, 0) == WAIT_OBJECT_0) lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_STOP, MCI_MODE_STOP); } else if (state == State_Paused) lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PAUSE, MCI_MODE_PAUSE); ret = MCI_RESOURCE_RETURNED; break; } case MCI_STATUS_MEDIA_PRESENT: FIXME("MCI_STATUS_MEDIA_PRESENT not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_TIME_FORMAT: lpParms->dwReturn = MAKEMCIRESOURCE(wma->time_format, MCI_FORMAT_RETURN_BASE + wma->time_format); ret = MCI_RESOURCE_RETURNED; break; case MCI_STATUS_READY: FIXME("MCI_STATUS_READY not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; case MCI_STATUS_CURRENT_TRACK: FIXME("MCI_STATUS_CURRENT_TRACK not implemented yet\n"); return MCIERR_UNRECOGNIZED_COMMAND; default: FIXME("Unknown command %08X\n", lpParms->dwItem); return MCIERR_UNRECOGNIZED_COMMAND; } if (dwFlags & MCI_NOTIFY) MCIQTZ_mciNotify(lpParms->dwCallback, wma, MCI_NOTIFY_SUCCESSFUL); return ret; }