2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
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)
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.
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
27 #include "TextPassThruFilter.h"
28 #include "..\..\..\include\moreuuids.h"
29 #include "..\..\DSUtil\DSUtil.h"
30 #include "..\..\subtitles\SubtitleInputPin.h"
33 // CTextPassThruInputPin
36 class CTextPassThruInputPin
: public CSubtitleInputPin
38 CTextPassThruFilter
* m_pTPTFilter
;
39 CComPtr
<ISubStream
> m_pSubStreamOld
;
42 void AddSubStream(ISubStream
* pSubStream
)
46 if(pSubStream
) m_pTPTFilter
->m_pMainFrame
->ReplaceSubtitle(m_pSubStreamOld
, pSubStream
);
47 m_pSubStreamOld
= NULL
;
51 void RemoveSubStream(ISubStream
* pSubStream
)
53 m_pSubStreamOld
= pSubStream
;
56 void InvalidateSubtitle(REFERENCE_TIME rtStart
, ISubStream
* pSubStream
)
58 m_pTPTFilter
->m_pMainFrame
->InvalidateSubtitle((DWORD_PTR
)pSubStream
, rtStart
);
62 CTextPassThruInputPin(CTextPassThruFilter
* pTPTFilter
, CCritSec
* pLock
, CCritSec
* pSubLock
, HRESULT
* phr
);
63 STDMETHODIMP
NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
);
64 STDMETHODIMP
Receive(IMediaSample
* pSample
);
65 STDMETHODIMP
EndOfStream();
66 STDMETHODIMP
BeginFlush();
67 STDMETHODIMP
EndFlush();
71 // CTextPassThruOutputPin
74 class CTextPassThruOutputPin
: public CBaseOutputPin
76 CTextPassThruFilter
* m_pTPTFilter
;
79 CTextPassThruOutputPin(CTextPassThruFilter
* pTPTFilter
, CCritSec
* pLock
, HRESULT
* phr
);
81 HRESULT
CheckMediaType(const CMediaType
* mtOut
);
82 HRESULT
DecideBufferSize(IMemAllocator
* pAllocator
, ALLOCATOR_PROPERTIES
* pProperties
);
83 HRESULT
GetMediaType(int iPosition
, CMediaType
* pmt
);
84 STDMETHODIMP
Notify(IBaseFilter
* pSender
, Quality q
) {return S_OK
;}
89 CTextPassThruInputPin::CTextPassThruInputPin(CTextPassThruFilter
* pTPTFilter
, CCritSec
* pLock
, CCritSec
* pSubLock
, HRESULT
* phr
)
90 : CSubtitleInputPin(pTPTFilter
, pLock
, pSubLock
, phr
)
91 , m_pTPTFilter(pTPTFilter
)
95 STDMETHODIMP
CTextPassThruInputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
97 HRESULT hr
= __super::NewSegment(tStart
, tStop
, dRate
);
98 if(FAILED(hr
)) return hr
;
99 return m_pTPTFilter
->m_pOutput
->DeliverNewSegment(tStart
, tStop
, dRate
);
102 STDMETHODIMP
CTextPassThruInputPin::Receive(IMediaSample
* pSample
)
104 HRESULT hr
= __super::Receive(pSample
);
105 if(FAILED(hr
)) return hr
;
106 return m_pTPTFilter
->m_pOutput
->Deliver(pSample
);
109 STDMETHODIMP
CTextPassThruInputPin::EndOfStream()
111 HRESULT hr
= __super::EndOfStream();
112 if(FAILED(hr
)) return hr
;
113 return m_pTPTFilter
->m_pOutput
->DeliverEndOfStream();
116 STDMETHODIMP
CTextPassThruInputPin::BeginFlush()
118 HRESULT hr
= __super::BeginFlush();
119 if(FAILED(hr
)) return hr
;
120 return m_pTPTFilter
->m_pOutput
->DeliverBeginFlush();
123 STDMETHODIMP
CTextPassThruInputPin::EndFlush()
125 HRESULT hr
= __super::EndFlush();
126 if(FAILED(hr
)) return hr
;
127 return m_pTPTFilter
->m_pOutput
->DeliverEndFlush();
132 CTextPassThruOutputPin::CTextPassThruOutputPin(CTextPassThruFilter
* pTPTFilter
, CCritSec
* pLock
, HRESULT
* phr
)
133 : CBaseOutputPin(NAME(""), pTPTFilter
, pLock
, phr
, L
"Out")
134 , m_pTPTFilter(pTPTFilter
)
138 HRESULT
CTextPassThruOutputPin::CheckMediaType(const CMediaType
* mtOut
)
141 return S_OK
== m_pTPTFilter
->m_pInput
->ConnectionMediaType(&mt
) && mt
== *mtOut
146 HRESULT
CTextPassThruOutputPin::DecideBufferSize(IMemAllocator
* pAllocator
, ALLOCATOR_PROPERTIES
* pProperties
)
148 if(m_pTPTFilter
->m_pInput
->IsConnected() == FALSE
)
151 CComPtr
<IMemAllocator
> pAllocatorIn
;
152 m_pTPTFilter
->m_pInput
->GetAllocator(&pAllocatorIn
);
153 if(!pAllocatorIn
) return E_UNEXPECTED
;
155 pAllocatorIn
->GetProperties(pProperties
);
158 ALLOCATOR_PROPERTIES Actual
;
159 if(FAILED(hr
= pAllocator
->SetProperties(pProperties
, &Actual
)))
162 return(pProperties
->cBuffers
> Actual
.cBuffers
|| pProperties
->cbBuffer
> Actual
.cbBuffer
167 HRESULT
CTextPassThruOutputPin::GetMediaType(int iPosition
, CMediaType
* pmt
)
169 if(m_pTPTFilter
->m_pInput
->IsConnected() == FALSE
)
172 if(iPosition
< 0) return E_INVALIDARG
;
173 if(iPosition
> 0) return VFW_S_NO_MORE_ITEMS
;
175 m_pTPTFilter
->m_pInput
->ConnectionMediaType(pmt
);
181 // CTextPassThruFilter
184 CTextPassThruFilter::CTextPassThruFilter(CMainFrame
* pMainFrame
)
185 : CBaseFilter(NAME("CTextPassThruFilter"), NULL
, this, __uuidof(this))
186 , m_pMainFrame(pMainFrame
)
189 m_pInput
= new CTextPassThruInputPin(this, this, &m_pMainFrame
->m_csSubLock
, &hr
);
190 m_pOutput
= new CTextPassThruOutputPin(this, this, &hr
);
193 CTextPassThruFilter::~CTextPassThruFilter()
195 delete m_pInput
; m_pInput
= NULL
;
196 delete m_pOutput
; m_pOutput
= NULL
;
199 STDMETHODIMP
CTextPassThruFilter::NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
201 if(m_pInput
&& riid
== __uuidof(ISubStream
))
203 if(CComPtr
<ISubStream
> pSubStream
= m_pInput
->GetSubStream())
205 *ppv
= pSubStream
.Detach();
210 return __super::NonDelegatingQueryInterface(riid
, ppv
);
213 int CTextPassThruFilter::GetPinCount()
218 CBasePin
* CTextPassThruFilter::GetPin(int n
)
220 if(n
== 0) return m_pInput
;
221 else if(n
== 1) return m_pOutput
;
226 void CTextPassThruFilter::SetName()
228 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pRTS;
230 CAutoLock cAutoLock(&m_pMainFrame->m_csSubLock);
232 if(CComQIPtr<IPropertyBag> pPB = m_pTPTInput->GetConnected())
235 if(SUCCEEDED(pPB->Read(L"LANGUAGE", &var, NULL)))
237 pRTS->m_name = CString(var.bstrVal) + _T(" (embeded)");
241 if(pRTS->m_name.IsEmpty())
244 m_pTPTInput->GetConnected()->QueryPinInfo(&pi);
245 pRTS->m_name = CString(CStringW(pi.achName)) + _T(" (embeded)");