www.pudn.com > VOBSUB.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); 
		} 
	} 
}