#include "precomp.h" extern HANDLE g_hVidEventHalfDuplex; /////////////////////////////////////////////////////// // // Public methods // VideoInControl::VideoInControl ( void ) { } VideoInControl::~VideoInControl ( void ) { } VideoOutControl::VideoOutControl ( void ) { } VideoOutControl::~VideoOutControl ( void ) { } HRESULT VideoInControl::Initialize ( MEDIACTRLINIT * p ) { HRESULT hr = DPR_SUCCESS; DEBUGMSG (ZONE_VERBOSE, ("VideoInControl::Initialize: enter.\r\n")); m_dwFlags = p->dwFlags; m_hEvent = NULL; m_uDuration = MC_DEF_DURATION; m_uTimeout = MC_DEF_RECORD_TIMEOUT; m_uPrefeed = MC_DEF_RECORD_BUFS; //Request the max, and let QOS throttle us back m_FPSRequested = m_FPSMax = 2997; DEBUGMSG (ZONE_VERBOSE, ("VideoInControl::Initialize: exit, hr=0x%lX\r\n", hr)); return hr; } HRESULT VideoOutControl::Initialize ( MEDIACTRLINIT * p ) { HRESULT hr = DPR_SUCCESS; DEBUGMSG (ZONE_VERBOSE, ("VideoOutControl::Initialize: enter.\r\n")); if ((hr =MediaControl::Initialize( p)) != DPR_SUCCESS) return hr; m_uTimeout = MC_DEF_PLAY_TIMEOUT; m_uPrefeed = MC_DEF_PLAY_BUFS; DEBUGMSG (ZONE_VERBOSE, ("VideoOutControl::Initialize: exit, hr=0x%lX\r\n", hr)); return hr; } HRESULT VideoInControl::Configure ( MEDIACTRLCONFIG * p ) { UINT uBlockAlign; DEBUGMSG (ZONE_VERBOSE, ("VideoInControl::Configure: enter.\r\n")); m_hStrm = p->hStrm; m_uDevId = p->uDevId; m_pDevFmt = p->pDevFmt; if (m_pDevFmt == NULL) return DPR_INVALID_PARAMETER; if ((m_uDuration = p->uDuration) == MC_USING_DEFAULT) { m_cbSizeDevData = ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec * p->cbSamplesPerPkt /((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; m_uDuration = p->cbSamplesPerPkt*1000 /((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; } else { // roughly calculate the buffer size based on 20ms m_cbSizeDevData = ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec * m_uDuration / 1000; // need to be on the block alignment boundary uBlockAlign = ((VIDEOFORMATEX *) m_pDevFmt)->nBlockAlign; m_cbSizeDevData = ((m_cbSizeDevData + uBlockAlign - 1) / uBlockAlign) * uBlockAlign; } // at configuration we set the max. frame rate if (m_uDuration) m_FPSMax = 100000 / m_uDuration; // convert msec/frame to fps m_FPSRequested = ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec * 100; DEBUGMSG (ZONE_VERBOSE, ("VideoInControl::Configure: exit\r\n")); return DPR_SUCCESS; } HRESULT VideoOutControl::Configure ( MEDIACTRLCONFIG * p ) { UINT uBlockAlign; DEBUGMSG (ZONE_VERBOSE, ("VideoOutControl::Configure: enter.\r\n")); m_hStrm = p->hStrm; m_uDevId = p->uDevId; m_pDevFmt = p->pDevFmt; if (m_pDevFmt == NULL) return DPR_INVALID_PARAMETER; if ((m_uDuration = p->uDuration) == MC_USING_DEFAULT) { m_cbSizeDevData = ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec * p->cbSamplesPerPkt /((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; m_uDuration = p->cbSamplesPerPkt*1000 /((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; } else { // roughly calculate the buffer size based on 20ms m_cbSizeDevData = ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec * m_uDuration / 1000; // need to be on the block alignment boundary uBlockAlign = ((VIDEOFORMATEX *) m_pDevFmt)->nBlockAlign; m_cbSizeDevData = ((m_cbSizeDevData + uBlockAlign - 1) / uBlockAlign) * uBlockAlign; } DEBUGMSG (ZONE_VERBOSE, ("VideoOutControl::Configure: exit\r\n")); return DPR_SUCCESS; } HRESULT VideoInControl::Open ( void ) { HRESULT hr; FINDCAPTUREDEVICE fcd; HFRAMEBUF hbuf; DWORD dwSize, i; LPBITMAPINFOHEADER lpbi; int iWidth, iHeight; char szName[MAX_PATH]; fcd.dwSize = sizeof (FINDCAPTUREDEVICE); if (m_uDevId == -1) FindFirstCaptureDevice(&fcd, NULL); else { if (!FindFirstCaptureDeviceByIndex(&fcd, m_uDevId)) { // Update m_uDevId with new device index if (FindFirstCaptureDevice(&fcd, NULL)) m_uDevId = fcd.nDeviceIndex; } } #ifndef NO_QCCOLOR_HACK if (fcd.szDeviceName[0] && lstrcmpi(fcd.szDeviceName, "qccolor.drv") == 0) { // this hack clears out the [conf] section of qccolor.ini to prevent problems in // setformat when the driver initializes to an unknown format that is recorded in // the ini file. dwSize = GetModuleFileName(NULL, szName, sizeof(szName)); for (i = dwSize-1; i; i--) if (szName[i] == '\\' || szName[i] == ':') break; i++; MoveMemory (szName, &szName[i], dwSize-i+1); dwSize -= i; for (i = dwSize-1; i; i--) if (szName[i] == '.') { szName[i] = 0; break; } dwSize = 0; WritePrivateProfileSection(szName, (LPCTSTR)&dwSize, "QCCOLOR.INI"); } #endif if (!(m_hDev = (DPHANDLE)OpenCaptureDevice(fcd.nDeviceIndex)) && m_uDevId != -1) { DEBUGMSG (1, ("MediaVidCtrl::Open: OpenCaptureDevice failed, trying VIDEO_MAPPER\r\n" )); FindFirstCaptureDevice(&fcd, NULL); if (m_hDev = (DPHANDLE)OpenCaptureDevice(fcd.nDeviceIndex)) m_uDevId = (UINT) -1; // use VIDEO_MAPPER next time } if (m_hDev) { hr = DPR_SUCCESS; } else { DEBUGMSG (1, ("MediaVidCtrl::Open: OpenCaptureDevice failed\r\n" )); hr = DPR_CANT_OPEN_DEV; } return hr; } HRESULT VideoOutControl::Open ( void ) { return DPR_SUCCESS; } HRESULT VideoInControl::Close ( void ) { HRESULT hr = DPR_INVALID_PLATFORM; if (m_hDev) { CloseCaptureDevice((HCAPDEV)m_hDev); hr = DPR_SUCCESS; } else { hr = DPR_INVALID_HANDLE; } m_hDev = NULL; return hr; } HRESULT VideoOutControl::Close ( void ) { return DPR_SUCCESS; } HRESULT VideoInControl::Start ( void ) { return DPR_SUCCESS; } HRESULT VideoOutControl::Start ( void ) { return DPR_SUCCESS; } HRESULT VideoInControl::Stop ( void ) { return DPR_SUCCESS; } HRESULT VideoOutControl::Stop ( void ) { return DPR_INVALID_PARAMETER; } HRESULT VideoInControl::Reset ( void ) { return VideoInControl::Stop(); } HRESULT VideoOutControl::Reset ( void ) { return DPR_SUCCESS; } HRESULT VideoInControl::DisplayDriverDialog (HWND hwnd, DWORD dwDlgId) { HRESULT hr = DPR_SUCCESS; DWORD dwRes; PDWORD pdwMask; if (m_hDev) { if (dwDlgId & CAPTURE_DIALOG_SOURCE) dwDlgId = CAPDEV_DIALOG_SOURCE; else dwDlgId = CAPDEV_DIALOG_IMAGE; #if 1 if (!CaptureDeviceDialog(m_hDev, hwnd, dwDlgId, NULL)) { #else if (!CaptureDeviceDialog(m_hDev, hwnd, dwDlgId, &((VIDEOFORMATEX *)m_pDevFmt)->bih)) { #endif dwRes = GetLastError(); if (dwRes == ERROR_DCAP_DIALOG_FORMAT || dwRes == ERROR_DCAP_DIALOG_STREAM) { DEBUGMSG (1, ("MediaVidCtrl::Open: CaptureDeviceDialog failed\r\n" )); hr = DPR_CONVERSION_FAILED; // user did something in the dialog that caused a problem } else hr = DPR_INVALID_PARAMETER; } } else hr = DPR_INVALID_HANDLE; return hr; } HRESULT VideoInControl::SetProp ( DWORD dwPropId, DWORD_PTR dwPropVal ) { HRESULT hr = DPR_SUCCESS; UINT ms; switch (dwPropId) { case MC_PROP_TIMEOUT: m_uTimeout = (DWORD)dwPropVal; break; case MC_PROP_PREFEED: m_uPrefeed = (DWORD)dwPropVal; break; case MC_PROP_VIDEO_FRAME_RATE: case MC_PROP_MAX_VIDEO_FRAME_RATE: break; default: hr = MediaControl::SetProp(dwPropId, dwPropVal ); break; } return hr; } HRESULT VideoOutControl::SetProp ( DWORD dwPropId, DWORD_PTR dwPropVal ) { HRESULT hr = DPR_SUCCESS; switch (dwPropId) { case MC_PROP_TIMEOUT: m_uTimeout = (DWORD)dwPropVal; break; case MC_PROP_PREFEED: m_uPrefeed = (DWORD)dwPropVal; break; default: hr = MediaControl::SetProp(dwPropId, dwPropVal ); break; } return hr; } HRESULT VideoInControl::GetProp ( DWORD dwPropId, PDWORD_PTR pdwPropVal ) { HRESULT hr = DPR_SUCCESS; DWORD dwMask; if (pdwPropVal) { switch (dwPropId) { case MC_PROP_TIMEOUT: *pdwPropVal = m_uTimeout; break; case MC_PROP_PREFEED: *pdwPropVal = m_uPrefeed; break; case MC_PROP_SPP: // *pdwPropVal = (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec // * m_uDuration / 100UL; *pdwPropVal = m_cbSizeDevData * (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec /(DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec; break; case MC_PROP_SPS: *pdwPropVal = (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; break; case MC_PROP_VIDEO_FRAME_RATE: case MC_PROP_MAX_VIDEO_FRAME_RATE: break; case MC_PROP_VFW_DIALOGS: *pdwPropVal = 0; if (vcmGetDevCapsDialogs(m_uDevId, &dwMask) == (MMRESULT)MMSYSERR_NOERROR) { if (dwMask & SOURCE_DLG_ON) *pdwPropVal = CAPTURE_DIALOG_SOURCE; if (dwMask & FORMAT_DLG_ON) *pdwPropVal |= CAPTURE_DIALOG_FORMAT; } break; default: hr = MediaControl::GetProp( dwPropId, pdwPropVal ); break; } } else { hr = DPR_INVALID_PARAMETER; } return hr; } HRESULT VideoOutControl::GetProp ( DWORD dwPropId, PDWORD_PTR pdwPropVal ) { HRESULT hr = DPR_SUCCESS; if (pdwPropVal) { switch (dwPropId) { case MC_PROP_TIMEOUT: *pdwPropVal = m_uTimeout; break; case MC_PROP_PREFEED: *pdwPropVal = m_uPrefeed; break; case MC_PROP_SPP: // *pdwPropVal = (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec // * m_uDuration / 100UL; *pdwPropVal = m_cbSizeDevData * (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec /(DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nAvgBytesPerSec; break; case MC_PROP_SPS: *pdwPropVal = (DWORD) ((VIDEOFORMATEX *) m_pDevFmt)->nSamplesPerSec; default: hr = MediaControl::GetProp( dwPropId, pdwPropVal ); break; } } else { hr = DPR_INVALID_PARAMETER; } return hr; }