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 <windows.h>
00024 #include <commdlg.h>
00025 #include "mplayerc.h"
00026 #include "mainfrm.h"
00027 #include "TextPassThruFilter.h"
00028 #include "..\..\..\include\matroska\matroska.h"
00029 #include "..\..\DSUtil\DSUtil.h"
00030
00031
00032
00033
00034
00035 #include "..\..\subtitles\SubtitleInputPin.h"
00036
00037 class CTextPassThruInputPin : public CSubtitleInputPin
00038 {
00039 CTextPassThruFilter* m_pTPTFilter;
00040 CComPtr<ISubStream> m_pSubStreamOld;
00041
00042 protected:
00043 void AddSubStream(ISubStream* pSubStream)
00044 {
00045 if(m_pSubStreamOld)
00046 {
00047 if(pSubStream) m_pTPTFilter->m_pMainFrame->ReplaceSubtitle(m_pSubStreamOld, pSubStream);
00048 m_pSubStreamOld = NULL;
00049 }
00050 }
00051
00052 void RemoveSubStream(ISubStream* pSubStream)
00053 {
00054 m_pSubStreamOld = pSubStream;
00055 }
00056
00057 void InvalidateSubtitle(REFERENCE_TIME rtStart, ISubStream* pSubStream)
00058 {
00059 m_pTPTFilter->m_pMainFrame->InvalidateSubtitle((DWORD_PTR)pSubStream, rtStart);
00060 }
00061
00062 public:
00063 CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr);
00064 STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
00065 STDMETHODIMP Receive(IMediaSample* pSample);
00066 STDMETHODIMP EndOfStream();
00067 STDMETHODIMP BeginFlush();
00068 STDMETHODIMP EndFlush();
00069 };
00070
00071
00072
00073
00074
00075 class CTextPassThruOutputPin : public CBaseOutputPin
00076 {
00077 CTextPassThruFilter* m_pTPTFilter;
00078
00079 public:
00080 CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr);
00081
00082 HRESULT CheckMediaType(const CMediaType* mtOut);
00083 HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties);
00084 HRESULT GetMediaType(int iPosition, CMediaType* pmt);
00085 STDMETHODIMP Notify(IBaseFilter* pSender, Quality q) {return S_OK;}
00086 };
00087
00089
00090 CTextPassThruInputPin::CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr)
00091 : CSubtitleInputPin(pTPTFilter, pLock, pSubLock, phr)
00092 , m_pTPTFilter(pTPTFilter)
00093 {
00094 }
00095
00096 STDMETHODIMP CTextPassThruInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00097 {
00098 HRESULT hr = __super::NewSegment(tStart, tStop, dRate);
00099 if(FAILED(hr)) return hr;
00100 return m_pTPTFilter->m_pOutput->DeliverNewSegment(tStart, tStop, dRate);
00101 }
00102
00103 STDMETHODIMP CTextPassThruInputPin::Receive(IMediaSample* pSample)
00104 {
00105 HRESULT hr = __super::Receive(pSample);
00106 if(FAILED(hr)) return hr;
00107 return m_pTPTFilter->m_pOutput->Deliver(pSample);
00108 }
00109
00110 STDMETHODIMP CTextPassThruInputPin::EndOfStream()
00111 {
00112 HRESULT hr = __super::EndOfStream();
00113 if(FAILED(hr)) return hr;
00114 return m_pTPTFilter->m_pOutput->DeliverEndOfStream();
00115 }
00116
00117 STDMETHODIMP CTextPassThruInputPin::BeginFlush()
00118 {
00119 HRESULT hr = __super::BeginFlush();
00120 if(FAILED(hr)) return hr;
00121 return m_pTPTFilter->m_pOutput->DeliverBeginFlush();
00122 }
00123
00124 STDMETHODIMP CTextPassThruInputPin::EndFlush()
00125 {
00126 HRESULT hr = __super::EndFlush();
00127 if(FAILED(hr)) return hr;
00128 return m_pTPTFilter->m_pOutput->DeliverEndFlush();
00129 }
00130
00131
00132
00133 CTextPassThruOutputPin::CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr)
00134 : CBaseOutputPin(NAME(""), pTPTFilter, pLock, phr, L"Out")
00135 , m_pTPTFilter(pTPTFilter)
00136 {
00137 }
00138
00139 HRESULT CTextPassThruOutputPin::CheckMediaType(const CMediaType* mtOut)
00140 {
00141 CMediaType mt;
00142 return S_OK == m_pTPTFilter->m_pInput->ConnectionMediaType(&mt) && mt == *mtOut
00143 ? S_OK
00144 : E_FAIL;
00145 }
00146
00147 HRESULT CTextPassThruOutputPin::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
00148 {
00149 if(m_pTPTFilter->m_pInput->IsConnected() == FALSE)
00150 return E_UNEXPECTED;
00151
00152 CComPtr<IMemAllocator> pAllocatorIn;
00153 m_pTPTFilter->m_pInput->GetAllocator(&pAllocatorIn);
00154 if(!pAllocatorIn) return E_UNEXPECTED;
00155
00156 pAllocatorIn->GetProperties(pProperties);
00157
00158 HRESULT hr;
00159 ALLOCATOR_PROPERTIES Actual;
00160 if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
00161 return hr;
00162
00163 return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
00164 ? E_FAIL
00165 : NOERROR);
00166 }
00167
00168 HRESULT CTextPassThruOutputPin::GetMediaType(int iPosition, CMediaType* pmt)
00169 {
00170 if(m_pTPTFilter->m_pInput->IsConnected() == FALSE)
00171 return E_UNEXPECTED;
00172
00173 if(iPosition < 0) return E_INVALIDARG;
00174 if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
00175
00176 m_pTPTFilter->m_pInput->ConnectionMediaType(pmt);
00177
00178 return S_OK;
00179 }
00180
00181
00182
00183
00184
00185 CTextPassThruFilter::CTextPassThruFilter(CMainFrame* pMainFrame)
00186 : CBaseFilter(NAME("CTextPassThruFilter"), NULL, this, __uuidof(this))
00187 , m_pMainFrame(pMainFrame)
00188 {
00189 HRESULT hr;
00190 m_pInput = new CTextPassThruInputPin(this, this, &m_pMainFrame->m_csSubLock, &hr);
00191 m_pOutput = new CTextPassThruOutputPin(this, this, &hr);
00192 }
00193
00194 CTextPassThruFilter::~CTextPassThruFilter()
00195 {
00196 delete m_pInput; m_pInput = NULL;
00197 delete m_pOutput; m_pOutput = NULL;
00198 }
00199
00200 STDMETHODIMP CTextPassThruFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00201 {
00202 if(m_pInput && riid == __uuidof(ISubStream))
00203 {
00204 if(CComPtr<ISubStream> pSubStream = m_pInput->GetSubStream())
00205 {
00206 *ppv = pSubStream.Detach();
00207 return S_OK;
00208 }
00209 }
00210
00211 return __super::NonDelegatingQueryInterface(riid, ppv);
00212 }
00213
00214 int CTextPassThruFilter::GetPinCount()
00215 {
00216 return 2;
00217 }
00218
00219 CBasePin* CTextPassThruFilter::GetPin(int n)
00220 {
00221 if(n == 0) return m_pInput;
00222 else if(n == 1) return m_pOutput;
00223 return NULL;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250