📄 ctlutil.cpp
字号:
ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET);
return hr;
}
m_StartMedia = StartMedia;
m_EndMedia = EndMedia;
m_bReset = FALSE;
return NOERROR;
}
// Sets the media times the object should report
HRESULT
CRendererPosPassThru::RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime)
{
CAutoLock cAutoLock(&m_PositionLock);
m_StartMedia = StartTime;
m_EndMedia = EndTime;
m_bReset = FALSE;
return NOERROR;
}
// Return the current media times registered in the object
HRESULT
CRendererPosPassThru::GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime)
{
ASSERT(pStartTime);
CAutoLock cAutoLock(&m_PositionLock);
if (m_bReset == TRUE) {
return E_FAIL;
}
// We don't have to return the end time
HRESULT hr = ConvertTimeFormat( pStartTime, 0, m_StartMedia, &TIME_FORMAT_MEDIA_TIME );
if (pEndTime && SUCCEEDED(hr)) {
hr = ConvertTimeFormat( pEndTime, 0, m_EndMedia, &TIME_FORMAT_MEDIA_TIME );
}
return hr;
}
// Resets the media times we hold
HRESULT
CRendererPosPassThru::ResetMediaTime()
{
CAutoLock cAutoLock(&m_PositionLock);
m_StartMedia = 0;
m_EndMedia = 0;
m_bReset = TRUE;
return NOERROR;
}
// Intended to be called by the owing filter during EOS processing so
// that the media times can be adjusted to the stop time. This ensures
// that the GetCurrentPosition will actully get to the stop position.
HRESULT
CRendererPosPassThru::EOS()
{
HRESULT hr;
if ( m_bReset == TRUE ) hr = E_FAIL;
else
{
LONGLONG llStop;
if SUCCEEDED(hr=GetStopPosition(&llStop))
{
CAutoLock cAutoLock(&m_PositionLock);
m_StartMedia =
m_EndMedia = llStop;
}
}
return hr;
}
// -- CSourceSeeking implementation ------------
CSourceSeeking::CSourceSeeking(
const TCHAR * pName,
LPUNKNOWN pUnk,
HRESULT* phr,
CCritSec * pLock) :
CUnknown(pName, pUnk),
m_pLock(pLock),
m_rtStart((long)0)
{
m_rtStop = _I64_MAX / 2;
m_rtDuration = m_rtStop;
m_dRateSeeking = 1.0;
m_dwSeekingCaps = AM_SEEKING_CanSeekForwards
| AM_SEEKING_CanSeekBackwards
| AM_SEEKING_CanSeekAbsolute
| AM_SEEKING_CanGetStopPos
| AM_SEEKING_CanGetDuration
| AM_SEEKING_CanGetCurrentPos;
}
HRESULT CSourceSeeking::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
if(riid == IID_IMediaSeeking) {
CheckPointer(ppv, E_POINTER);
return GetInterface(static_cast<IMediaSeeking *>(this), ppv);
}
else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
HRESULT CSourceSeeking::IsFormatSupported(const GUID * pFormat)
{
CheckPointer(pFormat, E_POINTER);
// only seeking in time (REFERENCE_TIME units) is supported
return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
}
HRESULT CSourceSeeking::QueryPreferredFormat(GUID *pFormat)
{
CheckPointer(pFormat, E_POINTER);
*pFormat = TIME_FORMAT_MEDIA_TIME;
return S_OK;
}
HRESULT CSourceSeeking::SetTimeFormat(const GUID * pFormat)
{
CheckPointer(pFormat, E_POINTER);
// nothing to set; just check that it's TIME_FORMAT_TIME
return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : E_INVALIDARG;
}
HRESULT CSourceSeeking::IsUsingTimeFormat(const GUID * pFormat)
{
CheckPointer(pFormat, E_POINTER);
return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
}
HRESULT CSourceSeeking::GetTimeFormat(GUID *pFormat)
{
CheckPointer(pFormat, E_POINTER);
*pFormat = TIME_FORMAT_MEDIA_TIME;
return S_OK;
}
HRESULT CSourceSeeking::GetDuration(LONGLONG *pDuration)
{
CheckPointer(pDuration, E_POINTER);
CAutoLock lock(m_pLock);
*pDuration = m_rtDuration;
return S_OK;
}
HRESULT CSourceSeeking::GetStopPosition(LONGLONG *pStop)
{
CheckPointer(pStop, E_POINTER);
CAutoLock lock(m_pLock);
*pStop = m_rtStop;
return S_OK;
}
HRESULT CSourceSeeking::GetCurrentPosition(LONGLONG *pCurrent)
{
// GetCurrentPosition is typically supported only in renderers and
// not in source filters.
return E_NOTIMPL;
}
HRESULT CSourceSeeking::GetCapabilities( DWORD * pCapabilities )
{
CheckPointer(pCapabilities, E_POINTER);
*pCapabilities = m_dwSeekingCaps;
return S_OK;
}
HRESULT CSourceSeeking::CheckCapabilities( DWORD * pCapabilities )
{
CheckPointer(pCapabilities, E_POINTER);
//
// returns S_OK if all caps are present;
// S_FALSE if some are present;
// E_FAIL if none is present;
// *pCapabilities will reflect the caps supported
//
return (~m_dwSeekingCaps & *pCapabilities) ?
((*pCapabilities &= m_dwSeekingCaps) ? S_FALSE : E_FAIL) :
S_OK;
}
HRESULT CSourceSeeking::ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat,
LONGLONG Source, const GUID * pSourceFormat )
{
CheckPointer(pTarget, E_POINTER);
// format guids can be null to indicate current format
// since we only support TIME_FORMAT_MEDIA_TIME, we don't really
// offer any conversions.
if(pTargetFormat == 0 || *pTargetFormat == TIME_FORMAT_MEDIA_TIME)
{
if(pSourceFormat == 0 || *pSourceFormat == TIME_FORMAT_MEDIA_TIME)
{
*pTarget = Source;
return S_OK;
}
}
return E_INVALIDARG;
}
HRESULT CSourceSeeking::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
, LONGLONG * pStop, DWORD StopFlags )
{
DWORD StopPosBits = StopFlags & AM_SEEKING_PositioningBitsMask;
DWORD StartPosBits = CurrentFlags & AM_SEEKING_PositioningBitsMask;
if(StopFlags) {
CheckPointer(pStop, E_POINTER);
// accept only relative, incremental, or absolute positioning
if(StopPosBits != StopFlags) {
return E_INVALIDARG;
}
}
if(CurrentFlags) {
CheckPointer(pCurrent, E_POINTER);
if(StartPosBits != AM_SEEKING_AbsolutePositioning &&
StartPosBits != AM_SEEKING_RelativePositioning) {
return E_INVALIDARG;
}
}
// scope for autolock
{
CAutoLock lock(m_pLock);
// set start position
if(StartPosBits == AM_SEEKING_AbsolutePositioning)
{
m_rtStart = *pCurrent;
}
else if(StartPosBits == AM_SEEKING_RelativePositioning)
{
m_rtStart += *pCurrent;
}
// set stop position
if(StopPosBits == AM_SEEKING_AbsolutePositioning)
{
m_rtStop = *pStop;
}
else if(StopPosBits == AM_SEEKING_IncrementalPositioning)
{
m_rtStop = m_rtStart + *pStop;
}
else if(StopPosBits == AM_SEEKING_RelativePositioning)
{
m_rtStop = m_rtStop + *pStop;
}
}
HRESULT hr = S_OK;
if(SUCCEEDED(hr) && StopPosBits) {
hr = ChangeStop();
}
if(StartPosBits) {
hr = ChangeStart();
}
return hr;
}
HRESULT CSourceSeeking::GetPositions( LONGLONG * pCurrent, LONGLONG * pStop )
{
if(pCurrent) {
*pCurrent = m_rtStart;
}
if(pStop) {
*pStop = m_rtStop;
}
return S_OK;;
}
HRESULT CSourceSeeking::GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest )
{
if(pEarliest) {
*pEarliest = 0;
}
if(pLatest) {
CAutoLock lock(m_pLock);
*pLatest = m_rtDuration;
}
return S_OK;
}
HRESULT CSourceSeeking::SetRate( double dRate)
{
{
CAutoLock lock(m_pLock);
m_dRateSeeking = dRate;
}
return ChangeRate();
}
HRESULT CSourceSeeking::GetRate( double * pdRate)
{
CheckPointer(pdRate, E_POINTER);
CAutoLock lock(m_pLock);
*pdRate = m_dRateSeeking;
return S_OK;
}
HRESULT CSourceSeeking::GetPreroll(LONGLONG *pPreroll)
{
CheckPointer(pPreroll, E_POINTER);
*pPreroll = 0;
return S_OK;
}
// --- CSourcePosition implementation ----------
CSourcePosition::CSourcePosition(const TCHAR * pName,
LPUNKNOWN pUnk,
HRESULT* phr,
CCritSec * pLock) :
CMediaPosition(pName, pUnk),
m_pLock(pLock),
m_Start(CRefTime((LONGLONG)0))
{
m_Stop = _I64_MAX;
m_Rate = 1.0;
}
STDMETHODIMP
CSourcePosition::get_Duration(REFTIME * plength)
{
CheckPointer(plength,E_POINTER);
ValidateReadWritePtr(plength,sizeof(REFTIME));
CAutoLock lock(m_pLock);
*plength = m_Duration;
return S_OK;
}
STDMETHODIMP
CSourcePosition::put_CurrentPosition(REFTIME llTime)
{
m_pLock->Lock();
m_Start = llTime;
m_pLock->Unlock();
return ChangeStart();
}
STDMETHODIMP
CSourcePosition::get_StopTime(REFTIME * pllTime)
{
CheckPointer(pllTime,E_POINTER);
ValidateReadWritePtr(pllTime,sizeof(REFTIME));
CAutoLock lock(m_pLock);
*pllTime = m_Stop;
return S_OK;
}
STDMETHODIMP
CSourcePosition::put_StopTime(REFTIME llTime)
{
m_pLock->Lock();
m_Stop = llTime;
m_pLock->Unlock();
return ChangeStop();
}
STDMETHODIMP
CSourcePosition::get_PrerollTime(REFTIME * pllTime)
{
CheckPointer(pllTime,E_POINTER);
ValidateReadWritePtr(pllTime,sizeof(REFTIME));
return E_NOTIMPL;
}
STDMETHODIMP
CSourcePosition::put_PrerollTime(REFTIME llTime)
{
return E_NOTIMPL;
}
STDMETHODIMP
CSourcePosition::get_Rate(double * pdRate)
{
CheckPointer(pdRate,E_POINTER);
ValidateReadWritePtr(pdRate,sizeof(double));
CAutoLock lock(m_pLock);
*pdRate = m_Rate;
return S_OK;
}
STDMETHODIMP
CSourcePosition::put_Rate(double dRate)
{
m_pLock->Lock();
m_Rate = dRate;
m_pLock->Unlock();
return ChangeRate();
}
// By default we can seek forwards
STDMETHODIMP
CSourcePosition::CanSeekForward(LONG *pCanSeekForward)
{
CheckPointer(pCanSeekForward,E_POINTER);
*pCanSeekForward = OATRUE;
return S_OK;
}
// By default we can seek backwards
STDMETHODIMP
CSourcePosition::CanSeekBackward(LONG *pCanSeekBackward)
{
CheckPointer(pCanSeekBackward,E_POINTER);
*pCanSeekBackward = OATRUE;
return S_OK;
}
// --- Implementation of CBasicAudio class ----------
CBasicAudio::CBasicAudio(const TCHAR * pName,LPUNKNOWN punk) :
CUnknown(pName, punk)
{
}
// overriden to publicise our interfaces
STDMETHODIMP
CBasicAudio::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
ValidateReadWritePtr(ppv,sizeof(PVOID));
if (riid == IID_IBasicAudio) {
return GetInterface( (IBasicAudio *) this, ppv);
} else {
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
STDMETHODIMP
CBasicAudio::GetTypeInfoCount(UINT * pctinfo)
{
return m_basedisp.GetTypeInfoCount(pctinfo);
}
STDMETHODIMP
CBasicAudio::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo ** pptinfo)
{
return m_basedisp.GetTypeInfo(
IID_IBasicAudio,
itinfo,
lcid,
pptinfo);
}
STDMETHODIMP
CBasicAudio::GetIDsOfNames(
REFIID riid,
OLECHAR ** rgszNames,
UINT cNames,
LCID lcid,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -