BaseSource.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:4k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "BaseSource.h"
  23. #include "......DSUtilDSUtil.h"
  24. //
  25. // CBaseSource
  26. //
  27. //
  28. // CBaseStream
  29. //
  30. CBaseStream::CBaseStream(TCHAR* name, CSource* pParent, HRESULT* phr) 
  31. : CSourceStream(name, phr, pParent, L"Output")
  32. , CSourceSeeking(name, (IPin*)this, phr, &m_cSharedState)
  33. , m_bDiscontinuity(FALSE), m_bFlushing(FALSE)
  34. {
  35. CAutoLock cAutoLock(&m_cSharedState);
  36. m_AvgTimePerFrame = 0;
  37. m_rtDuration = 0;
  38. m_rtStop = m_rtDuration;
  39. }
  40. CBaseStream::~CBaseStream()
  41. {
  42. CAutoLock cAutoLock(&m_cSharedState);
  43. }
  44. STDMETHODIMP CBaseStream::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  45. {
  46.     CheckPointer(ppv, E_POINTER);
  47. return (riid == IID_IMediaSeeking) ? CSourceSeeking::NonDelegatingQueryInterface(riid, ppv)
  48. : CSourceStream::NonDelegatingQueryInterface(riid, ppv);
  49. }
  50. void CBaseStream::UpdateFromSeek()
  51. {
  52. if(ThreadExists())
  53. {
  54. // next time around the loop, the worker thread will
  55. // pick up the position change.
  56. // We need to flush all the existing data - we must do that here
  57. // as our thread will probably be blocked in GetBuffer otherwise
  58.     
  59. m_bFlushing = TRUE;
  60. DeliverBeginFlush();
  61. // make sure we have stopped pushing
  62. Stop();
  63. // complete the flush
  64. DeliverEndFlush();
  65.         m_bFlushing = FALSE;
  66. // restart
  67. Run();
  68. }
  69. }
  70. HRESULT CBaseStream::SetRate(double dRate)
  71. {
  72. if(dRate <= 0)
  73. return E_INVALIDARG;
  74. {
  75. CAutoLock lock(CSourceSeeking::m_pLock);
  76. m_dRateSeeking = dRate;
  77. }
  78. UpdateFromSeek();
  79. return S_OK;
  80. }
  81. HRESULT CBaseStream::OnThreadStartPlay()
  82. {
  83.     m_bDiscontinuity = TRUE;
  84.     return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
  85. }
  86. HRESULT CBaseStream::ChangeStart()
  87. {
  88.     {
  89.         CAutoLock lock(CSourceSeeking::m_pLock);
  90. m_rtSampleTime = 0;
  91. m_rtPosition = m_rtStart;
  92.     }
  93.     UpdateFromSeek();
  94.     return S_OK;
  95. }
  96. HRESULT CBaseStream::ChangeStop()
  97. {
  98.     {
  99.         CAutoLock lock(CSourceSeeking::m_pLock);
  100.         if(m_rtPosition < m_rtStop)
  101. return S_OK;
  102.     }
  103.     // We're already past the new stop time -- better flush the graph.
  104.     UpdateFromSeek();
  105.     return S_OK;
  106. }
  107. HRESULT CBaseStream::OnThreadCreate()
  108. {
  109.     CAutoLock cAutoLockShared(&m_cSharedState);
  110.     m_rtSampleTime = 0;
  111.     m_rtPosition = m_rtStart;
  112.     return CSourceStream::OnThreadCreate();
  113. }
  114. HRESULT CBaseStream::FillBuffer(IMediaSample* pSample)
  115. {
  116. HRESULT hr;
  117. {
  118. CAutoLock cAutoLockShared(&m_cSharedState);
  119.         if(m_rtPosition >= m_rtStop)
  120. return S_FALSE;
  121. BYTE* pOut = NULL;
  122. if(FAILED(hr = pSample->GetPointer(&pOut)) || !pOut)
  123. return S_FALSE;
  124. int nFrame = m_rtPosition / m_AvgTimePerFrame; // (int)(1.0 * m_rtPosition / m_AvgTimePerFrame + 0.5);
  125. long len = pSample->GetSize();
  126. hr = FillBuffer(pSample, nFrame, pOut, len);
  127. if(hr != S_OK) return hr;
  128. pSample->SetActualDataLength(len);
  129. REFERENCE_TIME rtStart, rtStop;
  130.         // The sample times are modified by the current rate.
  131.         rtStart = static_cast<REFERENCE_TIME>(m_rtSampleTime / m_dRateSeeking);
  132.         rtStop  = rtStart + static_cast<int>(m_AvgTimePerFrame / m_dRateSeeking);
  133. pSample->SetTime(&rtStart, &rtStop);
  134.         m_rtSampleTime += m_AvgTimePerFrame;
  135.         m_rtPosition += m_AvgTimePerFrame;
  136. }
  137. pSample->SetSyncPoint(TRUE);
  138. if(m_bDiscontinuity) 
  139.     {
  140. pSample->SetDiscontinuity(TRUE);
  141. m_bDiscontinuity = FALSE;
  142. }
  143. return S_OK;
  144. }
  145. STDMETHODIMP CBaseStream::Notify(IBaseFilter* pSender, Quality q)
  146. {
  147. return E_NOTIMPL;
  148. }