/* * $Id$ * * (C) 2003-2006 Gabest * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Mplayerc is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "stdafx.h" #include #include #include "mplayerc.h" #include "MainFrm.h" #include "TextPassThruFilter.h" #include #include "../../DSUtil/DSUtil.h" #include "../../Subtitles/SubtitleInputPin.h" // // CTextPassThruInputPin // class CTextPassThruInputPin : public CSubtitleInputPin { CTextPassThruFilter* m_pTPTFilter; CComPtr m_pSubStreamOld; protected: void AddSubStream(ISubStream* pSubStream) { if(m_pSubStreamOld) { if(pSubStream) m_pTPTFilter->m_pMainFrame->ReplaceSubtitle(m_pSubStreamOld, pSubStream); m_pSubStreamOld = NULL; } } void RemoveSubStream(ISubStream* pSubStream) { m_pSubStreamOld = pSubStream; } void InvalidateSubtitle(REFERENCE_TIME rtStart, ISubStream* pSubStream) { m_pTPTFilter->m_pMainFrame->InvalidateSubtitle((DWORD_PTR)pSubStream, rtStart); } public: CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr); STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); STDMETHODIMP Receive(IMediaSample* pSample); STDMETHODIMP EndOfStream(); STDMETHODIMP BeginFlush(); STDMETHODIMP EndFlush(); HRESULT CompleteConnect(IPin* pReceivePin); }; // // CTextPassThruOutputPin // class CTextPassThruOutputPin : public CBaseOutputPin { CTextPassThruFilter* m_pTPTFilter; public: CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr); HRESULT CheckMediaType(const CMediaType* mtOut); HRESULT DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties); HRESULT GetMediaType(int iPosition, CMediaType* pmt); STDMETHODIMP Notify(IBaseFilter* pSender, Quality q) { return S_OK; } }; /////////// CTextPassThruInputPin::CTextPassThruInputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr) : CSubtitleInputPin(pTPTFilter, pLock, pSubLock, phr) , m_pTPTFilter(pTPTFilter) { } STDMETHODIMP CTextPassThruInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) { HRESULT hr = __super::NewSegment(tStart, tStop, dRate); if(FAILED(hr)) return hr; return m_pTPTFilter->m_pOutput->DeliverNewSegment(tStart, tStop, dRate); } STDMETHODIMP CTextPassThruInputPin::Receive(IMediaSample* pSample) { HRESULT hr = __super::Receive(pSample); if(FAILED(hr)) return hr; return m_pTPTFilter->m_pOutput->Deliver(pSample); } STDMETHODIMP CTextPassThruInputPin::EndOfStream() { HRESULT hr = __super::EndOfStream(); if(FAILED(hr)) return hr; return m_pTPTFilter->m_pOutput->DeliverEndOfStream(); } STDMETHODIMP CTextPassThruInputPin::BeginFlush() { HRESULT hr = __super::BeginFlush(); if(FAILED(hr)) return hr; return m_pTPTFilter->m_pOutput->DeliverBeginFlush(); } STDMETHODIMP CTextPassThruInputPin::EndFlush() { HRESULT hr = __super::EndFlush(); if(FAILED(hr)) return hr; return m_pTPTFilter->m_pOutput->DeliverEndFlush(); } HRESULT CTextPassThruInputPin::CompleteConnect(IPin* pReceivePin) { HRESULT hr = __super::CompleteConnect(pReceivePin); if(FAILED(hr) || !m_pTPTFilter->m_pOutput->IsConnected()) return hr; return m_pTPTFilter->ReconnectPin(m_pTPTFilter->m_pOutput, &m_mt); } // CTextPassThruOutputPin::CTextPassThruOutputPin(CTextPassThruFilter* pTPTFilter, CCritSec* pLock, HRESULT* phr) : CBaseOutputPin(NAME(""), pTPTFilter, pLock, phr, L"Out") , m_pTPTFilter(pTPTFilter) { } HRESULT CTextPassThruOutputPin::CheckMediaType(const CMediaType* mtOut) { CMediaType mt; return S_OK == m_pTPTFilter->m_pInput->ConnectionMediaType(&mt) && mt == *mtOut ? S_OK : E_FAIL; } HRESULT CTextPassThruOutputPin::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties) { if(m_pTPTFilter->m_pInput->IsConnected() == FALSE) return E_UNEXPECTED; CComPtr pAllocatorIn; m_pTPTFilter->m_pInput->GetAllocator(&pAllocatorIn); if(!pAllocatorIn) return E_UNEXPECTED; pAllocatorIn->GetProperties(pProperties); HRESULT hr; ALLOCATOR_PROPERTIES Actual; if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) return hr; return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer ? E_FAIL : NOERROR); } HRESULT CTextPassThruOutputPin::GetMediaType(int iPosition, CMediaType* pmt) { if(m_pTPTFilter->m_pInput->IsConnected() == FALSE) return E_UNEXPECTED; if(iPosition < 0) return E_INVALIDARG; if(iPosition > 0) return VFW_S_NO_MORE_ITEMS; m_pTPTFilter->m_pInput->ConnectionMediaType(pmt); return S_OK; } // // CTextPassThruFilter // CTextPassThruFilter::CTextPassThruFilter(CMainFrame* pMainFrame) : CBaseFilter(NAME("CTextPassThruFilter"), NULL, this, __uuidof(this)) , m_pMainFrame(pMainFrame) { HRESULT hr; m_pInput = DNew CTextPassThruInputPin(this, this, &m_pMainFrame->m_csSubLock, &hr); m_pOutput = DNew CTextPassThruOutputPin(this, this, &hr); } CTextPassThruFilter::~CTextPassThruFilter() { delete m_pInput; m_pInput = NULL; delete m_pOutput; m_pOutput = NULL; } STDMETHODIMP CTextPassThruFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv) { if(m_pInput && riid == __uuidof(ISubStream)) { if(CComPtr pSubStream = m_pInput->GetSubStream()) { *ppv = pSubStream.Detach(); return S_OK; } } return __super::NonDelegatingQueryInterface(riid, ppv); } int CTextPassThruFilter::GetPinCount() { return 2; } CBasePin* CTextPassThruFilter::GetPin(int n) { if(n == 0) return m_pInput; else if(n == 1) return m_pOutput; return NULL; }