www.pudn.com > src.rar > TextInputPin.cpp
#include "stdafx.h"
#include "DirectVobSubFilter.h"
#include "TextInputPin.h"
#include "SubtitleSource.h"
CTextInputPin::CTextInputPin(CDirectVobSubFilter* pFilter, CCritSec* pLock, HRESULT* phr) :
CBaseInputPin(NAME("CTextInputPin"),
pFilter,
pLock,
phr, // Return code
L"Input"), // Pin name
m_pFilter(pFilter)
{
}
HRESULT CTextInputPin::CheckMediaType(const CMediaType* pmt)
{
// VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->Format();
return(IsEqualGUID(*pmt->Type(), MEDIATYPE_Text) ? S_OK : E_FAIL);
}
HRESULT CTextInputPin::CompleteConnect(IPin* pReceivePin)
{
PIN_INFO pi;
pReceivePin->QueryPinInfo(&pi);
if(pi.pFilter)
{
m_pFilter->AddTextStream(m_name = CString(pi.achName));
pi.pFilter->Release();
}
RefreshNameFromPBag();
HRESULT hr = m_pFilter->CompleteConnect(PINDIR_INPUT, pReceivePin);
if(FAILED(hr))
return hr;
return CBaseInputPin::CompleteConnect(pReceivePin);
}
HRESULT CTextInputPin::BreakConnect()
{
m_pFilter->RemoveTextStream(m_name);
ASSERT(IsStopped());
m_pFilter->BreakConnect(PINDIR_INPUT);
return CBaseInputPin::BreakConnect();
}
STDMETHODIMP CTextInputPin::Receive(IMediaSample* pSample)
{
//DbgLog((LOG_TRACE, 0, _T("CTextInputPin::Receive")));
CAutoLock lck(&m_pFilter->m_csReceive);
HRESULT hr;
hr = CBaseInputPin::Receive(pSample);
if(FAILED(hr)) return hr;
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();
if(!strncmp((char*)pData, __GAB1__, strlen(__GAB1__)))
{
char* ptr = (char*)&pData[strlen(__GAB1__)+1];
char* end = (char*)&pData[len];
while(ptr < end)
{
ushort tag = *((ushort*)(ptr)); ptr += 2;
ushort size = *((ushort*)(ptr)); ptr += 2;
if(tag == __GAB1_LANGUAGE__)
{
CString tmp = ptr; // The unicode CString::operator = (char*) will use CP_ACP here, unfortunately that's not good for us...
#ifdef UNICODE
for(int i = 0, j = tmp.GetLength(); i < j; i++) tmp.SetAt(i, ptr[i]); // to correct the above mentioned problem, we store it as raw MBCS and set fUnicode to false
#endif
m_pFilter->ChangeName(m_name, tmp, false);
m_name = tmp;
}
else if(tag == __GAB1_ENTRY__)
{
CString tmp = &ptr[8];
#ifdef UNICODE
for(int i = 0, j = tmp.GetLength(); i < j; i++) tmp.SetAt(i, ptr[8+i]);
#endif
m_pFilter->AddNewEntryToTextStream(m_name, tmp, *(int*)(ptr), *(int*)(ptr+4));
}
else if(tag == __GAB1_LANGUAGE_UNICODE__)
{
CString old = m_name;
m_pFilter->ChangeName(old, m_name = (WCHAR*)ptr, true);
}
else if(tag == __GAB1_ENTRY_UNICODE__)
{
m_pFilter->AddNewEntryToTextStream(m_name, (WCHAR*)(ptr+8), *(int*)(ptr), *(int*)(ptr+4));
}
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)
{
ushort tag = *((ushort*)(ptr)); ptr += 2;
uint size = *((uint*)(ptr)); ptr += 4;
if(tag == __GAB1_LANGUAGE_UNICODE__)
{
CString old = m_name;
m_pFilter->ChangeName(old, m_name = (WCHAR*)ptr);
}
else if(tag == __GAB1_RAWTEXTSUBTITLE__)
{
m_pFilter->OpenRawTextSubtitle(m_name, (BYTE*)ptr, size);
}
ptr += size;
}
}
else if(pData != 0 && len > 1 && *pData != 0)
{
CString str = (char*)pData;
#ifdef UNICODE
for(int i = 0, j = str.GetLength(); i < j; i++) str.SetAt(i, (char)pData[i]);
#endif
str.Replace(_T("\r\n"), _T("\n"));
str.TrimLeft(); str.TrimRight();
str.Replace(_T(""), _T("{\\i1}"));
str.Replace(_T(""), _T("{\\i}"));
str.Replace(_T(""), _T("{\\b1}"));
str.Replace(_T(""), _T("{\\b}"));
str.Replace(_T(""), _T("{\\u1}"));
str.Replace(_T(""), _T("{\\u}"));
if(!str.IsEmpty())
{
RefreshNameFromPBag();
m_pFilter->AddNewEntryToTextStream(m_name, str, (int)(tStart / 10000), (int)(tStop / 10000));
}
}
return S_OK;
}
STDMETHODIMP CTextInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
CAutoLock lck(&m_pFilter->m_csReceive);
m_pFilter->RemoveEntriesFromTextStream(m_name);
RefreshNameFromPBag();
return CBaseInputPin::NewSegment(tStart, tStop, dRate);
}
void CTextInputPin::RefreshNameFromPBag()
{
return;
CComQIPtr pPB = m_Connected;
if(pPB)
{
CComBSTR name("LANGUAGE");
CComVariant var;
if(pPB->Read(name, &var, NULL) == S_OK)
{
CString old = m_name;
m_pFilter->ChangeName(old, m_name = var.bstrVal, false);
}
}
}