SubtitleInputPin.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:10k
- /*
- * Copyright (C) 2003-2005 Gabest
- * http://www.gabest.org
- *
- * This Program 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 2, or (at your option)
- * any later version.
- *
- * This Program 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 GNU Make; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- */
- #include "stdafx.h"
- #include "SubtitleInputPin.h"
- #include "VobSubFile.h"
- #include "RTS.h"
- #include <initguid.h>
- #include "....includematroskamatroska.h"
- // our first format id
- #define __GAB1__ "GAB1"
- // our tags for __GAB1__ (ushort) + size (ushort)
- // "lang" + '0'
- #define __GAB1_LANGUAGE__ 0
- // (int)start+(int)stop+(char*)line+'0'
- #define __GAB1_ENTRY__ 1
- // L"lang" + '0'
- #define __GAB1_LANGUAGE_UNICODE__ 2
- // (int)start+(int)stop+(WCHAR*)line+'0'
- #define __GAB1_ENTRY_UNICODE__ 3
- // same as __GAB1__, but the size is (uint) and only __GAB1_LANGUAGE_UNICODE__ is valid
- #define __GAB2__ "GAB2"
- // (BYTE*)
- #define __GAB1_RAWTEXTSUBTITLE__ 4
- CSubtitleInputPin::CSubtitleInputPin(CBaseFilter* pFilter, CCritSec* pLock, CCritSec* pSubLock, HRESULT* phr)
- : CBaseInputPin(NAME("CSubtitleInputPin"), pFilter, pLock, phr, L"Input")
- , m_pSubLock(pSubLock)
- {
- m_bCanReconnectWhenActive = TRUE;
- }
- HRESULT CSubtitleInputPin::CheckMediaType(const CMediaType* pmt)
- {
- return pmt->majortype == MEDIATYPE_Text && (pmt->subtype == MEDIASUBTYPE_NULL || pmt->subtype == FOURCCMap((DWORD)0))
- || pmt->majortype == MEDIATYPE_Subtitle && pmt->subtype == MEDIASUBTYPE_UTF8
- || pmt->majortype == MEDIATYPE_Subtitle && (pmt->subtype == MEDIASUBTYPE_SSA || pmt->subtype == MEDIASUBTYPE_ASS)
- || pmt->majortype == MEDIATYPE_Subtitle && (pmt->subtype == MEDIASUBTYPE_VOBSUB)
- ? S_OK
- : E_FAIL;
- }
- HRESULT CSubtitleInputPin::CompleteConnect(IPin* pReceivePin)
- {
- if(m_mt.majortype == MEDIATYPE_Text)
- {
- if(!(m_pSubStream = new CRenderedTextSubtitle(m_pSubLock))) return E_FAIL;
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- pRTS->m_name = CString(GetPinName(pReceivePin)) + _T(" (embeded)");
- pRTS->m_dstScreenSize = CSize(384, 288);
- pRTS->CreateDefaultStyle(DEFAULT_CHARSET);
- }
- else if(m_mt.majortype == MEDIATYPE_Subtitle)
- {
- SUBTITLEINFO* psi = (SUBTITLEINFO*)m_mt.pbFormat;
- DWORD dwOffset = psi->dwOffset;
- CString name = ISO6392ToLanguage(psi->IsoLang);
- if(name.IsEmpty()) name = _T("English");
- if(wcslen(psi->TrackName) > 0) name += _T(" (") + CString(psi->TrackName) + _T(")");
- if(m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/
- || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS)
- {
- if(!(m_pSubStream = new CRenderedTextSubtitle(m_pSubLock))) return E_FAIL;
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- pRTS->m_name = name;
- pRTS->m_dstScreenSize = CSize(384, 288);
- pRTS->CreateDefaultStyle(DEFAULT_CHARSET);
- if(dwOffset > 0 && m_mt.cbFormat - dwOffset > 0)
- {
- CMediaType mt = m_mt;
- if(mt.pbFormat[dwOffset+0] != 0xef
- && mt.pbFormat[dwOffset+1] != 0xbb
- && mt.pbFormat[dwOffset+2] != 0xfb)
- {
- dwOffset -= 3;
- mt.pbFormat[dwOffset+0] = 0xef;
- mt.pbFormat[dwOffset+1] = 0xbb;
- mt.pbFormat[dwOffset+2] = 0xbf;
- }
- pRTS->Open(mt.pbFormat + dwOffset, mt.cbFormat - dwOffset, DEFAULT_CHARSET, pRTS->m_name);
- }
- }
- else if(m_mt.subtype == MEDIASUBTYPE_VOBSUB)
- {
- if(!(m_pSubStream = new CVobSubStream(m_pSubLock))) return E_FAIL;
- CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream;
- pVSS->Open(name, m_mt.pbFormat + dwOffset, m_mt.cbFormat - dwOffset);
- }
- }
- AddSubStream(m_pSubStream);
- return __super::CompleteConnect(pReceivePin);
- }
- HRESULT CSubtitleInputPin::BreakConnect()
- {
- RemoveSubStream(m_pSubStream);
- m_pSubStream = NULL;
- ASSERT(IsStopped());
- return __super::BreakConnect();
- }
- STDMETHODIMP CSubtitleInputPin::ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt)
- {
- if(m_Connected)
- {
- RemoveSubStream(m_pSubStream);
- m_pSubStream = NULL;
- m_Connected->Release();
- m_Connected = NULL;
- }
- return __super::ReceiveConnection(pConnector, pmt);
- }
- STDMETHODIMP CSubtitleInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
- {
- CAutoLock cAutoLock(&m_csReceive);
- if(m_mt.majortype == MEDIATYPE_Text
- || m_mt.majortype == MEDIATYPE_Subtitle
- && (m_mt.subtype == MEDIASUBTYPE_UTF8 /*|| m_mt.subtype == MEDIASUBTYPE_USF*/
- || m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS))
- {
- CAutoLock cAutoLock(m_pSubLock);
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- pRTS->RemoveAll();
- pRTS->CreateSegments();
- }
- else if(m_mt.majortype == MEDIATYPE_Subtitle
- && (m_mt.subtype == MEDIASUBTYPE_VOBSUB))
- {
- CAutoLock cAutoLock(m_pSubLock);
- CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream;
- pVSS->RemoveAll();
- }
- return __super::NewSegment(tStart, tStop, dRate);
- }
- STDMETHODIMP CSubtitleInputPin::Receive(IMediaSample* pSample)
- {
- HRESULT hr;
- hr = __super::Receive(pSample);
- if(FAILED(hr)) return hr;
- CAutoLock cAutoLock(&m_csReceive);
- REFERENCE_TIME tStart, tStop;
- pSample->GetTime(&tStart, &tStop);
- tStart += m_tStart;
- tStop += m_tStart;
- BYTE* pData = NULL;
- hr = pSample->GetPointer(&pData);
- if(FAILED(hr) || pData == NULL) return hr;
- int len = pSample->GetActualDataLength();
- bool fInvalidate = false;
- if(m_mt.majortype == MEDIATYPE_Text)
- {
- CAutoLock cAutoLock(m_pSubLock);
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__)))
- {
- char* ptr = (char*)&pData[strlen(__GAB1__)+1];
- char* end = (char*)&pData[len];
- while(ptr < end)
- {
- WORD tag = *((WORD*)(ptr)); ptr += 2;
- WORD size = *((WORD*)(ptr)); ptr += 2;
- if(tag == __GAB1_LANGUAGE__)
- {
- pRTS->m_name = CString(ptr);
- }
- else if(tag == __GAB1_ENTRY__)
- {
- pRTS->Add(AToW(&ptr[8]), false, *(int*)ptr, *(int*)(ptr+4));
- fInvalidate = true;
- }
- else if(tag == __GAB1_LANGUAGE_UNICODE__)
- {
- pRTS->m_name = (WCHAR*)ptr;
- }
- else if(tag == __GAB1_ENTRY_UNICODE__)
- {
- pRTS->Add((WCHAR*)(ptr+8), true, *(int*)ptr, *(int*)(ptr+4));
- fInvalidate = true;
- }
- ptr += size;
- }
- }
- else if(!strncmp((char*)pData, __GAB2__, strlen(__GAB2__)))
- {
- char* ptr = (char*)&pData[strlen(__GAB2__)+1];
- char* end = (char*)&pData[len];
- while(ptr < end)
- {
- WORD tag = *((WORD*)(ptr)); ptr += 2;
- DWORD size = *((DWORD*)(ptr)); ptr += 4;
- if(tag == __GAB1_LANGUAGE_UNICODE__)
- {
- pRTS->m_name = (WCHAR*)ptr;
- }
- else if(tag == __GAB1_RAWTEXTSUBTITLE__)
- {
- pRTS->Open((BYTE*)ptr, size, DEFAULT_CHARSET, pRTS->m_name);
- fInvalidate = true;
- }
- ptr += size;
- }
- }
- else if(pData != 0 && len > 1 && *pData != 0)
- {
- CStringA str((char*)pData, len);
- str.Replace("rn", "n");
- str.Trim();
- if(!str.IsEmpty())
- {
- pRTS->Add(AToW(str), false, (int)(tStart / 10000), (int)(tStop / 10000));
- fInvalidate = true;
- }
- }
- }
- else if(m_mt.majortype == MEDIATYPE_Subtitle)
- {
- CAutoLock cAutoLock(m_pSubLock);
- if(m_mt.subtype == MEDIASUBTYPE_UTF8)
- {
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
- if(!str.IsEmpty())
- {
- pRTS->Add(str, true, (int)(tStart / 10000), (int)(tStop / 10000));
- fInvalidate = true;
- }
- }
- else if(m_mt.subtype == MEDIASUBTYPE_SSA || m_mt.subtype == MEDIASUBTYPE_ASS)
- {
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
- CStringW str = UTF8To16(CStringA((LPCSTR)pData, len)).Trim();
- if(!str.IsEmpty())
- {
- STSEntry stse;
- CList<CStringW> sl;
- Explode(str, sl, ',', 9);
- if(sl.GetCount() == 9)
- {
- stse.readorder = wcstol(sl.RemoveHead(), NULL, 10);
- stse.layer = wcstol(sl.RemoveHead(), NULL, 10);
- stse.style = sl.RemoveHead();
- stse.actor = sl.RemoveHead();
- stse.marginRect.left = wcstol(sl.RemoveHead(), NULL, 10);
- stse.marginRect.right = wcstol(sl.RemoveHead(), NULL, 10);
- stse.marginRect.top = stse.marginRect.bottom = wcstol(sl.RemoveHead(), NULL, 10);
- stse.effect = sl.RemoveHead();
- stse.str = sl.RemoveHead();
- }
- if(!stse.str.IsEmpty())
- {
- pRTS->Add(stse.str, true, (int)(tStart / 10000), (int)(tStop / 10000),
- stse.style, stse.actor, stse.effect, stse.marginRect, stse.layer, stse.readorder);
- fInvalidate = true;
- }
- }
- }
- else if(m_mt.subtype == MEDIASUBTYPE_VOBSUB)
- {
- CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)m_pSubStream;
- pVSS->Add(tStart, tStop, pData, len);
- }
- }
- if(fInvalidate)
- {
- TRACE(_T("InvalidateSubtitle(%I64d, ..)n"), tStart);
- // IMPORTANT: m_pSubLock must not be locked when calling this
- InvalidateSubtitle(tStart, m_pSubStream);
- }
- hr = S_OK;
- return hr;
- }