BaseSource.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include "BaseSource.h"
00024 #include "..\..\..\DSUtil\DSUtil.h"
00025 
00026 //
00027 // CBaseSource
00028 //
00029 
00030 //
00031 // CBaseStream
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                 // next time around the loop, the worker thread will
00064                 // pick up the position change.
00065                 // We need to flush all the existing data - we must do that here
00066                 // as our thread will probably be blocked in GetBuffer otherwise
00067             
00068                 m_bFlushing = TRUE;
00069 
00070                 DeliverBeginFlush();
00071                 // make sure we have stopped pushing
00072                 Stop();
00073                 // complete the flush
00074                 DeliverEndFlush();
00075 
00076         m_bFlushing = FALSE;
00077 
00078                 // restart
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     // We're already past the new stop time -- better flush the graph.
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; // (int)(1.0 * m_rtPosition / m_AvgTimePerFrame + 0.5);
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         // The sample times are modified by the current rate.
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 }

Generated on Tue Dec 13 14:47:23 2005 for guliverkli by  doxygen 1.4.5