//=========================================================================== // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1992 - 1998 Microsoft Corporation. All Rights Reserved. // //=========================================================================== // // filename: cvcrutil.cpp // // Base classes implementing external device control (VCR) interfaces. // Derive from these and implement just the custom method and property // methods. // #include #include #include #include #include #include #include #include "vcruids.h" #include #include #include "ctimecod.h" #include "cdevcom.h" #include "cvcrutil.h" #define DbgFunc(a) DbgLog(( LOG_TRACE, \ 2, \ TEXT("VCRTC::%16hu"), \ TEXT(a) \ )); const long ExtVidConnType[] = { PhysConn_Video_Tuner, PhysConn_Video_Composite, PhysConn_Video_SVideo, PhysConn_Video_RGB, PhysConn_Video_YRYBY, PhysConn_Video_SerialDigital, PhysConn_Video_ParallelDigital, PhysConn_Video_SCSI, PhysConn_Video_AUX, PhysConn_Video_1394, PhysConn_Video_USB }; const int ExtVidConnCnt = sizeof(ExtVidConnType); const TCHAR *strExtVidConnType[] = { TEXT("Tuner"), TEXT("Composite"), TEXT("S-Video"), TEXT("RGB"), TEXT("Y//R-Y//B-Y"), TEXT("Serial Digital"), TEXT("Parallel Digital"), TEXT("SCSI"), TEXT("AUX"), TEXT("1394"), TEXT("USB") }; const long ExtAudConnType[] = { PhysConn_Audio_Tuner, PhysConn_Audio_Line, PhysConn_Audio_Mic, PhysConn_Audio_AESDigital, PhysConn_Audio_SPDIFDigital, PhysConn_Audio_SCSI, PhysConn_Audio_AUX, PhysConn_Audio_1394, PhysConn_Audio_USB }; const int ExtAudConnCnt = sizeof(ExtAudConnType); const TCHAR *strExtAudConnType[] = { TEXT("Tuner"), TEXT("Line"), TEXT("Mic"), TEXT("AES Digital"), TEXT("SPDIF Digital"), TEXT("SCSI"), TEXT("AUX"), TEXT("1394"), TEXT("USB") }; static TCHAR m_buf[32]; static TCHAR m_buf1[32]; const TCHAR strDummyDeviceVersion[] = TEXT("1.0"); static TIMECODE_SAMPLE m_tcsLastTimecode; //------------------------------------------ // // CAMPhysicalPinInfo Implementation // //------------------------------------------ CAMPhysicalPinInfo::CAMPhysicalPinInfo(HRESULT * phr, TCHAR *tszName) : CUnknown( tszName, NULL ) { } //------------------------------------------ // // Destructor // //------------------------------------------ CAMPhysicalPinInfo::~CAMPhysicalPinInfo() { } //------------------------------------------ // // NonDelegatingQueryInterface // // Reveal our Interface //------------------------------------------ STDMETHODIMP CAMPhysicalPinInfo::NonDelegatingQueryInterface(REFIID riid, void **ppv) { CAutoLock cObjectLock(&m_StateLock); if (riid == IID_IAMPhysicalPinInfo) return GetInterface((IAMPhysicalPinInfo *) this, ppv); else return CUnknown::NonDelegatingQueryInterface(riid, ppv); } //------------------------------------------ // // CAMExtDevice implementation // //------------------------------------------ CAMExtDevice::CAMExtDevice(HRESULT * phr, TCHAR *tszName) : CUnknown( tszName, NULL ), m_devcom(NULL), m_CurDevicePort(0), m_PowerMode(0) { HRESULT Result; // must have a way to talk to a machine m_devcom = new CDevCom((CBaseFilter *)this, &Result); if (m_devcom == NULL || Result) { *phr = E_OUTOFMEMORY; return; } // initialize the capabilities structures - we default to a test VCR, // in this case a simple SVHS recorder such as the SVO-5800 (RS-422) // or other machine with an SVBK-10 RS-232 interface m_DevCaps.CanRecord = OATRUE; m_DevCaps.CanRecordStrobe = OAFALSE; m_DevCaps.HasAudio = OATRUE; m_DevCaps.HasVideo = OATRUE; m_DevCaps.UsesFiles = OAFALSE; m_DevCaps.CanSave = OAFALSE; m_DevCaps.DeviceType = ED_DEVTYPE_VCR; m_DevCaps.TCRead = OATRUE; m_DevCaps.TCWrite = OAFALSE; m_DevCaps.CTLRead = OATRUE; m_DevCaps.IndexRead = OAFALSE; m_DevCaps.Preroll = 150L; m_DevCaps.Postroll = 30L;; m_DevCaps.SyncAcc = ED_SYNCACC_PRECISE; m_DevCaps.NormRate = ED_RATE_2997; m_DevCaps.CanPreview = OATRUE; m_DevCaps.CanMonitorSrc = OATRUE; m_DevCaps.CanTest = OATRUE; m_DevCaps.VideoIn = OATRUE; m_DevCaps.AudioIn = OATRUE; m_DevCaps.Calibrate = OAFALSE; m_DevCaps.SeekType = ED_SEEK_SLOW; // default comm port and power state put_DevicePort(DEV_PORT_COM2); put_DevicePower(ED_POWER_ON); } //------------------------------------------ // // Destructor // //------------------------------------------ CAMExtDevice::~CAMExtDevice() { m_devcom->CloseDevPort(); } //------------------------------------------ // // NonDelegatingQueryInterface // // Reveal our Interface //------------------------------------------ STDMETHODIMP CAMExtDevice::NonDelegatingQueryInterface(REFIID riid, void **ppv) { CAutoLock cObjectLock(&m_StateLock); if (riid == IID_IAMExtDevice) return GetInterface((IAMExtDevice *) this, ppv); else return CUnknown::NonDelegatingQueryInterface(riid, ppv); } //------------------------------------------ // // GetCapability // // General device capabilities property //------------------------------------------ HRESULT CAMExtDevice::GetCapability(long Capability, long *pValue, double *pdblValue ) { HRESULT result = S_OK; switch (Capability){ case ED_DEVCAP_CAN_RECORD: *pValue = m_DevCaps.CanRecord; break; case ED_DEVCAP_CAN_RECORD_STROBE: *pValue = m_DevCaps.CanRecordStrobe; break; case ED_DEVCAP_HAS_AUDIO: *pValue = m_DevCaps.HasAudio; break; case ED_DEVCAP_HAS_VIDEO: *pValue = m_DevCaps.HasVideo; break; case ED_DEVCAP_USES_FILES: *pValue = m_DevCaps.UsesFiles; break; case ED_DEVCAP_CAN_SAVE: *pValue = m_DevCaps.CanSave; break; case ED_DEVCAP_DEVICE_TYPE: *pValue = m_DevCaps.DeviceType; break; case ED_DEVCAP_TIMECODE_READ: *pValue = m_DevCaps.TCRead; break; case ED_DEVCAP_TIMECODE_WRITE: *pValue = m_DevCaps.TCWrite; break; case ED_DEVCAP_CTLTRK_READ: *pValue = m_DevCaps.CTLRead; break; case ED_DEVCAP_INDEX_READ: *pValue = m_DevCaps.IndexRead; break; case ED_DEVCAP_PREROLL: *pValue = m_DevCaps.Preroll; break; case ED_DEVCAP_POSTROLL: *pValue = m_DevCaps.Postroll; break; case ED_DEVCAP_SYNC_ACCURACY: *pValue = m_DevCaps.SyncAcc; break; case ED_DEVCAP_NORMAL_RATE: *pValue = m_DevCaps.NormRate; break; case ED_DEVCAP_CAN_PREVIEW: *pValue = m_DevCaps.CanPreview; break; case ED_DEVCAP_CAN_MONITOR_SOURCES: *pValue = m_DevCaps.CanMonitorSrc; break; case ED_DEVCAP_CAN_TEST: *pValue = m_DevCaps.CanTest; break; case ED_DEVCAP_VIDEO_INPUTS: *pValue = m_DevCaps.VideoIn; break; case ED_DEVCAP_AUDIO_INPUTS: *pValue = m_DevCaps.AudioIn; break; case ED_DEVCAP_NEEDS_CALIBRATING: *pValue = m_DevCaps.Calibrate; break; case ED_DEVCAP_SEEK_TYPE: *pValue = m_DevCaps.SeekType; break; default: result = VFW_E_NOT_FOUND; } return S_OK; } //------------------------------------------ // // get_ExternalDeviceID // // Get external device identification string //------------------------------------------ HRESULT CAMExtDevice::get_ExternalDeviceID(LPOLESTR * ppszData) { int Cookie; CheckPointer(ppszData, E_POINTER); *ppszData = NULL; // query the device if (m_devcom->SendDevCmd(DEVICE_TYPE_REQUEST, &Cookie) ) return E_FAIL; if (m_devcom->Wait4DevResponse(m_buf, Cookie)) return E_FAIL; m_devcom->ProcessDeviceTypeResponse(m_buf, m_buf1); if (m_buf1 !=NULL) { *ppszData = (LPOLESTR) QzTaskMemAlloc(sizeof(WCHAR) * (1+lstrlenW((LPOLESTR)m_buf1))); if (*ppszData !=NULL) lstrcpyW(*ppszData, (LPOLESTR)m_buf1); } return S_OK; } //------------------------------------------ // // get_ExternalDeviceVersion // //------------------------------------------ HRESULT CAMExtDevice::get_ExternalDeviceVersion(LPOLESTR * ppszData) { // The sample machine doesn't support this, so send // a dummy response CheckPointer(ppszData, E_POINTER); *ppszData = NULL; // query the device *ppszData = (LPOLESTR) QzTaskMemAlloc(sizeof(WCHAR) * \ (1+lstrlenW((LPOLESTR)strDummyDeviceVersion))); if (*ppszData !=NULL) lstrcpyW(*ppszData, (LPOLESTR)strDummyDeviceVersion); return S_OK; } //------------------------------------------ // // put_DevicePower // // Controls the external device's power mode. // Unfortunately, the sample machine doesn't support this //------------------------------------------ HRESULT CAMExtDevice::put_DevicePower(long PowerMode) { TESTFLAG(PowerMode, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // get_DevicePower // //------------------------------------------ HRESULT CAMExtDevice::get_DevicePower(long *pPowerMode) { // if the device port is being simulated, assume power off if (m_CurDevicePort == DEV_PORT_SIM) m_PowerMode = ED_POWER_OFF; else m_PowerMode = ED_POWER_ON; *pPowerMode = m_PowerMode; return S_OK; } //------------------------------------------ // // Calibrate // //------------------------------------------ HRESULT CAMExtDevice::Calibrate(HEVENT hEvent, long Mode, long *pStatus) { TESTFLAG( Mode , OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // get_DevicePort // //------------------------------------------ HRESULT CAMExtDevice::get_DevicePort(long *pDevicePort) { *pDevicePort = m_CurDevicePort; return S_OK; } //------------------------------------------ // // put_DevicePort // //------------------------------------------ HRESULT CAMExtDevice::put_DevicePort(long DevicePort) { TESTFLAG( DevicePort, OATRUE); if ( DevicePort != m_CurDevicePort ) { // range check if ((DevicePort < DEV_PORT_MIN) || (DevicePort > DEV_PORT_MAX)) return VFW_E_NOT_FOUND; // find correct error code if ( (m_CurDevicePort != NULL) & (m_CurDevicePort !=DEV_PORT_SIM) ) m_devcom->CloseDevPort(); if (m_devcom->OpenDevPort(DevicePort)) m_CurDevicePort = DEV_PORT_SIM; else m_CurDevicePort = DevicePort; } return S_OK; } //------------------------------------------ // // CAMExtTransport implementation // //------------------------------------------ CAMExtTransport::CAMExtTransport(HRESULT * phr, TCHAR *tszName) : CUnknown( tszName, NULL ), m_pTDevCom(NULL), m_lastmode(0L), m_mediastate(0L), m_localcontrol(0L) { // initialize the video parms m_TranVidParms.OutputMode = ED_PLAYBACK; m_TranVidParms.Input = 0; // use the first (zeroth) input as the default m_TranAudParms.EnableOutput = ED_AUDIO_ALL; m_TranAudParms.EnableRecord = 0L; m_TranAudParms.Input = 0; m_TranAudParms.MonitorSource = 0; m_TranStatus.Mode = ED_MODE_STOP; m_TranStatus.LastError = 0L; m_TranStatus.RecordInhibit = OAFALSE; m_TranStatus.ServoLock = OAFALSE; m_TranStatus.MediaPresent = OAFALSE; m_TranStatus.MediaLength = m_TranStatus.MediaSize = m_TranStatus.MediaTrackCount = m_TranStatus.MediaTrackLength = m_TranStatus.MediaTrackSide = m_TranStatus.MediaType = 0L; m_TranStatus.LinkMode = OATRUE; // default to "linked" m_TranStatus.NotifyOn = OAFALSE; // disable event notification m_localcontrol = FALSE; } //------------------------------------------ // // Destructor // //------------------------------------------ CAMExtTransport::~CAMExtTransport() { } //------------------------------------------ // // NonDelegatingQueryInterface // // Reveal our Interface //------------------------------------------ STDMETHODIMP CAMExtTransport::NonDelegatingQueryInterface(REFIID riid, void **ppv) { CAutoLock cObjectLock(&m_StateLock); if (riid == IID_IAMExtTransport) return GetInterface((IAMExtTransport *) this, ppv); else return CUnknown::NonDelegatingQueryInterface(riid, ppv); } //------------------------------------------ // // SetCommunicationObject // //------------------------------------------ HRESULT CAMExtTransport::SetCommunicationObject(CDevCom *pCDevCom) { m_pTDevCom = pCDevCom; return S_OK; } //------------------------------------------ // // GetCapability // // Transport capabilities property //------------------------------------------ HRESULT CAMExtTransport::GetCapability(long Capability, long *pValue, double *pdblValue ) { return E_NOTIMPL; } //------------------------------------------ // // put_MediaState // //------------------------------------------ HRESULT CAMExtTransport::put_MediaState(long State) { TESTFLAG(State, OATRUE); int Cookie; // the only thing we'll do here is eject - all others imply // a bigger state change (like STOP->FREEZE) that we'd like to // do here if (State == ED_MEDIA_UNLOAD) { if (m_TranStatus.Mode != ED_MODE_STOP) CAMExtTransport::put_Mode(ED_MODE_STOP); if (m_pTDevCom->SendDevCmd(EJECT, &Cookie)) return E_FAIL; if (m_pTDevCom->Wait4DevResponse(m_buf, Cookie)) return E_FAIL; Sleep(4000); // wait a bit until the machine completes m_mediastate = State; return S_OK; } return E_NOTIMPL; } //------------------------------------------ // // get_MediaState // //------------------------------------------ HRESULT CAMExtTransport::get_MediaState(long FAR* pState) { int Cookie; BOOL bStatusRet; // This might be different for a device other than a VCR, but: // ED_MEDIA_SPIN_UP: media inserted and not stopped // ED_MEDIA_SPIN_DOWN: media inserted and stopped // ED_MEDIA_UNLOAD: media ejected if (m_TranStatus.Mode == ED_MODE_STOP) { // check device for presence of media do { if (m_pTDevCom->SendDevCmd(REQUEST_STATUS, &Cookie)) return E_FAIL; if (m_pTDevCom->Wait4DevResponse(m_buf, Cookie)) return E_FAIL; bStatusRet = m_pTDevCom->ProcessDeviceStatusResponse(m_buf, &m_VcrStatus); } while (bStatusRet); if (m_VcrStatus.bCassetteOut == OATRUE) *pState = ED_MEDIA_UNLOAD; else *pState = ED_MEDIA_SPIN_DOWN; } else *pState = ED_MEDIA_SPIN_UP; m_mediastate = *pState; return S_OK; } //------------------------------------------ // // put_LocalControl // //------------------------------------------ HRESULT CAMExtTransport::put_LocalControl(long State) { TESTFLAG(State, OATRUE); long temp; int Cookie; DWORD dwResult; if (State == OATRUE) temp = LOCAL_ON; else temp = LOCAL_OFF; dwResult = m_pTDevCom->SendDevCmd(temp, &Cookie); if (dwResult == DEV_COMM_ERR_COMMAND_NOT_SUPPORTED) return E_NOTIMPL; if (dwResult) return E_FAIL; if (m_pTDevCom->Wait4DevResponse(m_buf, Cookie)) return E_FAIL; return S_OK; } //------------------------------------------ // // get_LocalControl // //------------------------------------------ HRESULT CAMExtTransport::get_LocalControl(long FAR* pState) { int Cookie; if (m_pTDevCom->SendDevCmd(REQUEST_STATUS, &Cookie)) return E_FAIL; if (m_pTDevCom->Wait4DevResponse(m_buf, Cookie)) return E_FAIL; m_pTDevCom->ProcessDeviceStatusResponse(m_buf, &m_VcrStatus); *pState = m_VcrStatus.bLocal; return S_OK; } //------------------------------------------ // // GetStatus // //------------------------------------------ HRESULT CAMExtTransport::GetStatus(long StatusItem, long FAR* pValue) { switch (StatusItem) { case ED_LINK_MODE: *pValue = m_TranStatus.LinkMode; return S_OK; default: return E_NOTIMPL; } } //------------------------------------------ // // GetTransportBasicParameters // //------------------------------------------ HRESULT CAMExtTransport::GetTransportBasicParameters(long Param, long FAR* pValue, LPOLESTR * ppszData) { return E_NOTIMPL; } //------------------------------------------ // // SetTransportBasicParameters // //------------------------------------------ HRESULT CAMExtTransport::SetTransportBasicParameters(long Param, long Value, LPCOLESTR pszData) { // we test false because this is not implemented TESTFLAG(Param, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // GetTransportVideoParameters // //------------------------------------------ HRESULT CAMExtTransport::GetTransportVideoParameters(long Param, long FAR* pValue) { HRESULT hr = S_OK; switch (Param) { case ED_TRANSVIDEO_SET_OUTPUT: *pValue = m_TranVidParms.OutputMode; break; case ED_TRANSVIDEO_SET_SOURCE: *pValue = m_TranVidParms.Input; break; default: hr = VFW_E_NOT_FOUND; } return hr; } //------------------------------------------ // // SetTransportVideoParameters // //------------------------------------------ HRESULT CAMExtTransport::SetTransportVideoParameters(long Param, long Value) { // we test false because this is not implemented TESTFLAG(Param, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // GetTransportAudioParameters // //------------------------------------------ HRESULT CAMExtTransport::GetTransportAudioParameters(long Param, long FAR* pValue) { HRESULT hr = S_OK; switch (Param) { case ED_TRANSAUDIO_ENABLE_OUTPUT: *pValue = m_TranAudParms.EnableOutput; break; case ED_TRANSAUDIO_ENABLE_RECORD: *pValue = m_TranAudParms.EnableRecord; break; case ED_TRANSAUDIO_SET_SOURCE: *pValue = m_TranAudParms.Input; break; case ED_TRANSAUDIO_SET_MONITOR: *pValue = m_TranAudParms.MonitorSource; break; default: hr = VFW_E_NOT_FOUND; } return hr; } //------------------------------------------ // // SetTransportAudioParameters // //------------------------------------------ HRESULT CAMExtTransport::SetTransportAudioParameters(long Param, long Value) { // we test false because this is not implemented TESTFLAG(Param, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // put_Mode // //------------------------------------------ HRESULT CAMExtTransport::put_Mode(long Mode) { HRESULT result = S_OK; DWORD cmdresult; static TCHAR buf[32]; int Cookie; TESTFLAG(Mode, OATRUE); if ( Mode == m_TranStatus.Mode ) return S_OK; // don't repeat commands if ( m_localcontrol == TRUE ) return ED_ERR_DEVICE_NOT_READY; switch (Mode) { case ED_MODE_PLAY: cmdresult = m_pTDevCom->SendDevCmd(PLAY, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_PLAY; break; case ED_MODE_STOP: cmdresult = m_pTDevCom->SendDevCmd(STOP, &Cookie); ASSERT(cmdresult == 0L); if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; cmdresult = m_pTDevCom->SendDevCmd(STANDBY_OFF, &Cookie); // we know that some machines don't support STANDBY_OFF if (cmdresult != 0 && cmdresult != DEV_COMM_ERR_COMMAND_NOT_SUPPORTED ) ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_STOP; break; case ED_MODE_FREEZE: if (m_TranStatus.Mode == ED_MODE_STOP) { return result; } cmdresult = m_pTDevCom->SendDevCmd(FREEZE_ON, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_FREEZE; break; case ED_MODE_THAW: cmdresult = m_pTDevCom->SendDevCmd(FREEZE_OFF, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_TranStatus.Mode = m_lastmode; break; case ED_MODE_FF: cmdresult = m_pTDevCom->SendDevCmd(FFWD, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_FF; break; case ED_MODE_REW: cmdresult = m_pTDevCom->SendDevCmd(REWIND, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_REW; break; case ED_MODE_RECORD: cmdresult = m_pTDevCom->SendDevCmd(RECORD, &Cookie); ASSERT(cmdresult == 0L); if (cmdresult == 0L) if (m_pTDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; m_lastmode = m_TranStatus.Mode; m_TranStatus.Mode = ED_MODE_RECORD; break; case ED_MODE_RECORD_STROBE: result = E_NOTIMPL; break; case ED_MODE_STEP_FWD: result = E_NOTIMPL; break; case ED_MODE_STEP_REV: result = E_NOTIMPL; break; case ED_MODE_SHUTTLE: result = E_NOTIMPL; break; case ED_MODE_LINK_ON: m_TranStatus.LinkMode = OATRUE; break; case ED_MODE_LINK_OFF: m_TranStatus.LinkMode = OAFALSE; break; default: result = E_NOTIMPL; } // clean up if things went well return result; } //------------------------------------------ // // get_Mode // //------------------------------------------ HRESULT CAMExtTransport::get_Mode(long FAR* pMode) { *pMode = m_TranStatus.Mode; return S_OK; } //------------------------------------------ // // put_Rate // //------------------------------------------ HRESULT CAMExtTransport::put_Rate(double dblRate) { // add Test flag support return E_NOTIMPL; } //------------------------------------------ // // get_Rate // //------------------------------------------ HRESULT CAMExtTransport::get_Rate(double FAR* pdblRate) { return E_NOTIMPL; } //------------------------------------------ // // GetChase // //------------------------------------------ HRESULT CAMExtTransport::GetChase(long FAR* pEnabled, long FAR* pOffset, HEVENT FAR* phEvent) { return E_NOTIMPL; } //------------------------------------------ // // SetChase // //------------------------------------------ HRESULT CAMExtTransport::SetChase(long Enable, long Offset, HEVENT hEvent) { return E_NOTIMPL; } //------------------------------------------ // // GetBump // //------------------------------------------ HRESULT CAMExtTransport::GetBump(long FAR* pSpeed, long FAR* pDuration) { return E_NOTIMPL; } //------------------------------------------ // // SetBump // //------------------------------------------ HRESULT CAMExtTransport::SetBump(long Speed, long Duration) { return E_NOTIMPL; } //------------------------------------------ // // get_AntiClogControl // //------------------------------------------ HRESULT CAMExtTransport::get_AntiClogControl(long FAR* pEnabled) { return E_NOTIMPL; } //------------------------------------------ // // put_AntiClogControl // //------------------------------------------ HRESULT CAMExtTransport::put_AntiClogControl(long Enable) { TESTFLAG(Enable, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // GetEditPropertySet // //------------------------------------------ HRESULT CAMExtTransport::GetEditPropertySet(long EditID, long FAR* pState) { return E_NOTIMPL; } //------------------------------------------ // // SetEditPropertySet // //------------------------------------------ HRESULT CAMExtTransport::SetEditPropertySet(long FAR* pEditID, long State) { TESTFLAG(State, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // GetEditProperty // //------------------------------------------ HRESULT CAMExtTransport::GetEditProperty(long EditID, long Param, long FAR* pValue) { return E_NOTIMPL; } //------------------------------------------ // // SetEditProperty // //------------------------------------------ HRESULT CAMExtTransport::SetEditProperty(long EditID, long Param, long Value) { return E_NOTIMPL; } //------------------------------------------ // // get_EditStart // //------------------------------------------ HRESULT CAMExtTransport::get_EditStart(long FAR* pValue) { return E_NOTIMPL; } //------------------------------------------ // // put_EditStart // //------------------------------------------ HRESULT CAMExtTransport::put_EditStart(long Value) { TESTFLAG(Value, OAFALSE); return E_NOTIMPL; } //------------------------------------------ // // CAMTcr implementation // //------------------------------------------ CAMTcr::CAMTcr(HRESULT * phr, TCHAR *tszName) : CUnknown( tszName, NULL ), m_pTCDevCom(NULL), m_timecode(NULL), m_bNotify(0L), m_dwSource(0L) { // need some help with timecode m_timecode = new CTimecode(); // initialize local storage m_tcsLastTimecode.qwTick = 0L; m_tcsLastTimecode.timecode.wFrameRate = 0; m_tcsLastTimecode.timecode.wFrameFract = 0; m_tcsLastTimecode.timecode.dwFrames = 0L; m_tcsLastTimecode.dwUser = 0L; m_tcsLastTimecode.dwFlags = 0L; m_bNotify = OAFALSE; } //------------------------------------------ // // Destructor // //------------------------------------------ CAMTcr::~CAMTcr() { } //------------------------------------------ // // NonDelegatingQueryInterface // // Reveal our Interface //------------------------------------------ STDMETHODIMP CAMTcr::NonDelegatingQueryInterface(REFIID riid, void **ppv) { CAutoLock cObjectLock(&m_StateLock); if (riid == IID_IAMTimecodeReader) return GetInterface((IAMTimecodeReader *) this, ppv); else return CUnknown::NonDelegatingQueryInterface(riid, ppv); } //------------------------------------------ // // SetCommunicationObject // //------------------------------------------ HRESULT CAMTcr::SetCommunicationObject(CDevCom *pCDevCom) { m_pTCDevCom = pCDevCom; return S_OK; } //------------------------------------------ // // GetTCRMode // //------------------------------------------ HRESULT CAMTcr::GetTCRMode(long Param, long FAR* pValue) { TESTFLAG(Param, OATRUE); // the real implementation will use a table instead // of a switch. This seriously partial implementation // is just to get basic timecode reading right switch (Param) { case ED_TCR_SOURCE: *pValue = m_dwSource; return S_OK; case ED_MODE_NOTIFY_ENABLE: *pValue = m_bNotify; return S_OK; default: return E_NOTIMPL; } return E_NOTIMPL; } //------------------------------------------ // // get_VITCLine // //------------------------------------------ HRESULT CAMTcr::get_VITCLine(long * pLine) { return E_NOTIMPL; } //------------------------------------------ // // put_VITCLine // //------------------------------------------ HRESULT CAMTcr::put_VITCLine(long Line) { return E_NOTIMPL; } //------------------------------------------ // // SetTCRMode // //------------------------------------------ HRESULT CAMTcr::SetTCRMode(long Param, long Value) { TCHAR buf[20]; int Cookie; DWORD dwResult; TESTFLAG(Param, OATRUE); // the real implementation will use a table instead // of a switch. This seriously partial implementation // is just to get basic timecode reading right switch (Param) { case ED_TCR_SOURCE: if ( Value == ED_TCR_LTC ) { dwResult = m_pTCDevCom->SendDevCmd(TIMER_MODE_SELECT_LTC, &Cookie); // we know that some machines don't support this command // and don't even ask for an answer if ( dwResult == DEV_COMM_ERR_COMMAND_NOT_SUPPORTED) return E_NOTIMPL; if ( dwResult ) // fail on all other result codes return E_FAIL; if (m_pTCDevCom->Wait4DevResponse(buf, Cookie)) return E_FAIL; } // must have a valid TCR mode selected before using this one. if ( Value == ED_TCR_LAST_VALUE && m_dwSource == 0L) return E_FAIL; m_dwSource = Value; return S_OK; case ED_MODE_NOTIFY_ENABLE: m_bNotify = Value; return S_OK; default: return E_NOTIMPL; } return E_NOTIMPL; } //------------------------------------------ // // GetTimecode // //------------------------------------------ HRESULT CAMTcr::GetTimecode( PTIMECODE_SAMPLE pTimecodeSample) { DWORD cmdresult; static TCHAR buf[32]; DWORD fcm; int Cookie; LONG lFrame, lUser ; if (m_dwSource == ED_TCR_LAST_VALUE) { // notification is probably enabled and the caller just wants // the last read value pTimecodeSample->timecode.wFrameRate = m_tcsLastTimecode.timecode.wFrameRate; pTimecodeSample->timecode.dwFrames = m_tcsLastTimecode.timecode.dwFrames; pTimecodeSample->dwUser = m_tcsLastTimecode.dwUser; pTimecodeSample->dwFlags = m_tcsLastTimecode.dwFlags; return S_OK; } cmdresult = m_pTCDevCom->SendDevCmd(READ_TC, &Cookie); if ( cmdresult == 0L ) { // commands might get refused if ( (cmdresult = m_pTCDevCom->Wait4DevResponse(buf, Cookie)) ) return cmdresult;//E_FAIL; m_pTCDevCom->ProcessVcrTC(buf, &fcm, &lFrame, &lUser); pTimecodeSample->timecode.wFrameRate = (WORD)fcm; pTimecodeSample->timecode.dwFrames = (DWORD) lFrame ; pTimecodeSample->dwUser = (DWORD) lUser ; pTimecodeSample->dwFlags = 0L; // save a copy in case notification mode is turned on. m_tcsLastTimecode.timecode.wFrameRate = (WORD)fcm; m_tcsLastTimecode.timecode.dwFrames = (DWORD) lFrame ; m_tcsLastTimecode.dwUser = (DWORD) lUser ; m_tcsLastTimecode.dwFlags = 0L; return S_OK; } // leave the reference time alone for now // (to be filled in by calling filter) return S_FALSE; } //eof cvcrutil.cpp