00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include "BaseSource.h"
00024 #include "..\..\..\DSUtil\DSUtil.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 CBaseStream::CBaseStream(TCHAR* name, CSource* pParent, HRESULT* phr)
00035 : CSourceStream(name, phr, pParent, L"Output")
00036 , CSourceSeeking(name, (IPin*)this, phr, &m_cSharedState)
00037 , m_bDiscontinuity(FALSE), m_bFlushing(FALSE)
00038 {
00039 CAutoLock cAutoLock(&m_cSharedState);
00040
00041 m_AvgTimePerFrame = 0;
00042 m_rtDuration = 0;
00043 m_rtStop = m_rtDuration;
00044 }
00045
00046 CBaseStream::~CBaseStream()
00047 {
00048 CAutoLock cAutoLock(&m_cSharedState);
00049 }
00050
00051 STDMETHODIMP CBaseStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00052 {
00053 CheckPointer(ppv, E_POINTER);
00054
00055 return (riid == IID_IMediaSeeking) ? CSourceSeeking::NonDelegatingQueryInterface(riid, ppv)
00056 : CSourceStream::NonDelegatingQueryInterface(riid, ppv);
00057 }
00058
00059 void CBaseStream::UpdateFromSeek()
00060 {
00061 if(ThreadExists())
00062 {
00063
00064
00065
00066
00067
00068 m_bFlushing = TRUE;
00069
00070 DeliverBeginFlush();
00071
00072 Stop();
00073
00074 DeliverEndFlush();
00075
00076 m_bFlushing = FALSE;
00077
00078
00079 Run();
00080 }
00081 }
00082
00083 HRESULT CBaseStream::SetRate(double dRate)
00084 {
00085 if(dRate <= 0)
00086 return E_INVALIDARG;
00087
00088 {
00089 CAutoLock lock(CSourceSeeking::m_pLock);
00090 m_dRateSeeking = dRate;
00091 }
00092
00093 UpdateFromSeek();
00094
00095 return S_OK;
00096 }
00097
00098 HRESULT CBaseStream::OnThreadStartPlay()
00099 {
00100 m_bDiscontinuity = TRUE;
00101 return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
00102 }
00103
00104 HRESULT CBaseStream::ChangeStart()
00105 {
00106 {
00107 CAutoLock lock(CSourceSeeking::m_pLock);
00108 m_rtSampleTime = 0;
00109 m_rtPosition = m_rtStart;
00110 }
00111
00112 UpdateFromSeek();
00113
00114 return S_OK;
00115 }
00116
00117 HRESULT CBaseStream::ChangeStop()
00118 {
00119 {
00120 CAutoLock lock(CSourceSeeking::m_pLock);
00121 if(m_rtPosition < m_rtStop)
00122 return S_OK;
00123 }
00124
00125
00126 UpdateFromSeek();
00127
00128 return S_OK;
00129 }
00130
00131 HRESULT CBaseStream::OnThreadCreate()
00132 {
00133 CAutoLock cAutoLockShared(&m_cSharedState);
00134
00135 m_rtSampleTime = 0;
00136 m_rtPosition = m_rtStart;
00137
00138 return CSourceStream::OnThreadCreate();
00139 }
00140
00141 HRESULT CBaseStream::FillBuffer(IMediaSample* pSample)
00142 {
00143 HRESULT hr;
00144
00145 {
00146 CAutoLock cAutoLockShared(&m_cSharedState);
00147
00148 if(m_rtPosition >= m_rtStop)
00149 return S_FALSE;
00150
00151 BYTE* pOut = NULL;
00152 if(FAILED(hr = pSample->GetPointer(&pOut)) || !pOut)
00153 return S_FALSE;
00154
00155 int nFrame = m_rtPosition / m_AvgTimePerFrame;
00156
00157 long len = pSample->GetSize();
00158
00159 hr = FillBuffer(pSample, nFrame, pOut, len);
00160 if(hr != S_OK) return hr;
00161
00162 pSample->SetActualDataLength(len);
00163
00164 REFERENCE_TIME rtStart, rtStop;
00165
00166 rtStart = static_cast<REFERENCE_TIME>(m_rtSampleTime / m_dRateSeeking);
00167 rtStop = rtStart + static_cast<int>(m_AvgTimePerFrame / m_dRateSeeking);
00168 pSample->SetTime(&rtStart, &rtStop);
00169
00170 m_rtSampleTime += m_AvgTimePerFrame;
00171 m_rtPosition += m_AvgTimePerFrame;
00172 }
00173
00174 pSample->SetSyncPoint(TRUE);
00175
00176 if(m_bDiscontinuity)
00177 {
00178 pSample->SetDiscontinuity(TRUE);
00179 m_bDiscontinuity = FALSE;
00180 }
00181
00182 return S_OK;
00183 }
00184
00185 STDMETHODIMP CBaseStream::Notify(IBaseFilter* pSender, Quality q)
00186 {
00187 return E_NOTIMPL;
00188 }