📄 dvbteletextsubtitles.cpp
字号:
int desired_page = (m_nSubtitlesDecimalPage % 10) | ( ( ( (m_nSubtitlesDecimalPage - (100 * (m_nSubtitlesDecimalPage / 100) ) ) % 100) / 10) << 4) | ( (m_nSubtitlesDecimalPage / 100) << 8);
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
SMagazineSubPageInstances& instances = m_Magazines[mag].m_Pages[page_in_mag].m_SubPages[m_nSubtitlesDecimalSubPage];
SMagazineSubPageInstances::iterator instance_it;
for (SMagazineSubPageInstances::reverse_iterator instance_it = instances.rbegin(); instance_it != instances.rend(); instance_it++)
{
unsigned int sh = (unsigned int)(instance_it->m_StartMilliseconds/(1000*60*60));
unsigned int sm = (unsigned int)((instance_it->m_StartMilliseconds/(1000*60))-(sh*60));
unsigned int ss = (unsigned int)((instance_it->m_StartMilliseconds/1000)-(sh*3600)-(sm*60));
unsigned int su = (unsigned int)(instance_it->m_StartMilliseconds-(sh*1000*60*60)-(sm*1000*60)-(ss*1000));
unsigned int eh = (unsigned int)(instance_it->m_EndMilliseconds/(1000*60*60));
unsigned int em = (unsigned int)((instance_it->m_EndMilliseconds/(1000*60))-(eh*60));
unsigned int es = (unsigned int)((instance_it->m_EndMilliseconds/1000)-(eh*3600)-(em*60));
unsigned int eu = (unsigned int)(instance_it->m_EndMilliseconds-(eh*1000*60*60)-(em*1000*60)-(es*1000));
vector<STeletextSubtitleLine> texts;
instance_it->GenerateIsoTextLines
(
texts,
FALSE,
23
);
char* text = "";
if (texts.size() != 0)
{
text = texts.front().text;
}
char buff[512];
sprintf(buff, "Page(0x%x) SubPage(0x%x) %d:%02d:%02d.%03d end=%d:%02d:%02d.%03d (%s)\r\n", instance_it->m_nPage, instance_it->m_nSubPage, sh, sm, ss, su, eh, em, es, eu, text);
ATLTRACE(buff);
}
return S_OK;
}
//
// NonDelegatingQueryInterface
//
// Override CUnknown method.
// Part of the basic COM (Compound Object Model) mechanism.
// This is how we expose our interfaces.
//
STDMETHODIMP CDVBTeletextSubtitles::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);
if (riid == __uuidof(IDVBTeletextSubtitles))
{
return GetInterface((IDVBTeletextSubtitles*)this, ppv);
}
else if (riid == __uuidof(ISpecifyPropertyPages))
{
return GetInterface((ISpecifyPropertyPages*)this, ppv);
}
else if (riid == IID_IPersistStream)
{
return GetInterface((IPersistStream*)this, ppv);
}
else
{
return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
} // NonDelegatingQueryInterface
STDMETHODIMP CDVBTeletextSubtitles::GetClassID(OUT CLSID * pCLSID)
{
*pCLSID = CLSID_DVBTeletextSubtitles;
return S_OK;
}
int CDVBTeletextSubtitles::SizeMax(void)
{
return
sizeof(m_nTeletextPid)
+
sizeof(m_nSubtitlesDecimalPage)
+
sizeof(m_nSubtitlesDecimalSubPage)
+
sizeof(m_DisplayHeadingLine)
+
sizeof(m_nLastLine)
+
sizeof(m_pTeletextOutput->m_TextMode)
+
sizeof(m_Colours);
}
HRESULT CDVBTeletextSubtitles::WriteToStream(IStream* stream)
{
HRESULT hr;
LockFilter();
hr = stream->Write((BYTE*)&m_nTeletextPid, sizeof(m_nTeletextPid), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_nSubtitlesDecimalPage, sizeof(m_nSubtitlesDecimalPage), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_nSubtitlesDecimalSubPage, sizeof(m_nSubtitlesDecimalSubPage), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_DisplayHeadingLine, sizeof(m_DisplayHeadingLine), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_nLastLine, sizeof(m_nLastLine), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_pTeletextOutput->m_TextMode, sizeof(m_pTeletextOutput->m_TextMode), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Write((BYTE*)&m_Colours, sizeof(m_Colours), NULL);
if (SUCCEEDED(hr))
{
hr = m_FilePath.WriteToStream(stream);
}
}
}
}
}
}
}
UnlockFilter();
return hr ;
}
HRESULT
CDVBTeletextSubtitles::ReadFromStream(IStream* stream)
{
HRESULT hr;
LockFilter();
hr = stream->Read((BYTE*)&m_nTeletextPid, sizeof(m_nTeletextPid), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_nSubtitlesDecimalPage, sizeof(m_nSubtitlesDecimalPage), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_nSubtitlesDecimalSubPage, sizeof(m_nSubtitlesDecimalSubPage), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_DisplayHeadingLine, sizeof(m_DisplayHeadingLine), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_nLastLine, sizeof(m_nLastLine), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_pTeletextOutput->m_TextMode, sizeof(m_pTeletextOutput->m_TextMode), NULL);
if (SUCCEEDED(hr))
{
hr = stream->Read((BYTE*)&m_Colours, sizeof(m_Colours), NULL);
if (SUCCEEDED(hr))
{
m_FilePath.Empty();
hr = m_FilePath.ReadFromStream(stream);
}
}
}
}
}
}
}
UnlockFilter();
return hr ;
}
//-----------------------------------------------------------------------------
// ISpecifyPropertyPages implementation
//-----------------------------------------------------------------------------
//
// GetPages
//
// Returns the clsid's of the property pages we support
//
STDMETHODIMP CDVBTeletextSubtitles::GetPages(CAUUID *pPages)
{
CheckPointer(pPages,E_POINTER);
pPages->cElems = 1;
pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
if (pPages->pElems == NULL)
return E_OUTOFMEMORY;
*(pPages->pElems) = CLSID_CDVBTeletextSubtitlesPropertiesPage1;
return NOERROR;
} // GetPages
STDMETHODIMP CDVBTeletextSubtitles::get_InputPidMap(IEnumPIDMap** enum_map)
{
CComPtr<IPin> connected_pin;
HRESULT hr = m_pTeletextPIDInput->ConnectedTo(&connected_pin);
if (SUCCEEDED(hr))
{
hr = E_NOINTERFACE;
CComQIPtr<IMPEG2PIDMap> mpeg2pidmap = connected_pin;
if (mpeg2pidmap != NULL)
{
hr = mpeg2pidmap->EnumPIDMap(enum_map);
}
}
return hr;
}
void CDVBTeletextSubtitles::ClearSubPages(void)
{
int desired_page = (m_nSubtitlesDecimalPage % 10) | ( ( ( (m_nSubtitlesDecimalPage - (100 * (m_nSubtitlesDecimalPage / 100) ) ) % 100) / 10) << 4) | ( (m_nSubtitlesDecimalPage / 100) << 8);
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
SMagazineSubPageInstances& instances = m_Magazines[mag].m_Pages[page_in_mag].m_SubPages[m_nSubtitlesDecimalSubPage];
// erase all but the first few elements
if (instances.size() > 5)
{
SMagazineSubPageInstances::iterator latest = instances.begin();
latest++;
latest++;
latest++;
latest++;
instances.erase(latest, instances.end());
}
}
DWORD CDVBTeletextSubtitles::GetIntervalToNextEvent(void)
{
//
// Get the current reference time in milliseconds.
//
__int64 reference_time_milliseconds = 0;
CComQIPtr<IMediaFilter> media_filter = m_pGraph;
if (media_filter != NULL)
{
CComPtr<IReferenceClock> reference_clock;
media_filter->GetSyncSource(&reference_clock);
if (reference_clock != NULL)
{
REFERENCE_TIME reference_time;
reference_clock->GetTime(&reference_time);
reference_time_milliseconds = ConvertToMilliseconds(reference_time);
}
}
int desired_page = (m_nSubtitlesDecimalPage % 10) | ( ( ( (m_nSubtitlesDecimalPage - (100 * (m_nSubtitlesDecimalPage / 100) ) ) % 100) / 10) << 4) | ( (m_nSubtitlesDecimalPage / 100) << 8);
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
__int64 next_event_time = LLONG_MAX;
SMagazineSubPageInstances& instances = m_Magazines[mag].m_Pages[page_in_mag].m_SubPages[m_nSubtitlesDecimalSubPage];
if (!instances.empty())
{
for (std::list<SMagazineSubPage>::iterator it = instances.begin(); it != instances.end(); it++)
{
SMagazineSubPage& sub_page = *it;
if (sub_page.m_EndMilliseconds != 0)
{
if (sub_page.m_StartMilliseconds < next_event_time)
{
next_event_time = sub_page.m_StartMilliseconds;
}
if (sub_page.m_EndMilliseconds < next_event_time)
{
next_event_time = sub_page.m_EndMilliseconds;
}
}
}
}
__int64 interval = (next_event_time - reference_time_milliseconds);
if (interval < 0)
{
//
// Do it now!
//
return 0;
}
else
{
return (DWORD)interval;
}
}
// Return whether first element is greater than the second
bool UDgreater(SMagazineSubPage* elem1, SMagazineSubPage* elem2)
{
return !(*elem1 < *elem2);
}
void CDVBTeletextSubtitles::GetSubPageInstances(std::vector<SMagazineSubPage*>& results)
{
int desired_page = (m_nSubtitlesDecimalPage % 10) | ( ( ( (m_nSubtitlesDecimalPage - (100 * (m_nSubtitlesDecimalPage / 100) ) ) % 100) / 10) << 4) | ( (m_nSubtitlesDecimalPage / 100) << 8);
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
SMagazineSubPageInstances& instances = m_Magazines[mag].m_Pages[page_in_mag].m_SubPages[m_nSubtitlesDecimalSubPage];
if (!instances.empty())
{
for (std::list<SMagazineSubPage>::iterator it = instances.begin(); it != instances.end(); it++)
{
SMagazineSubPage* sub_page = &*it;
results.push_back(sub_page);
}
sort(results.begin(), results.end(), UDgreater);
}
}
void CDVBTeletextSubtitles::GetSubPagesAt(__int64 sub_page_time, std::vector<SMagazineSubPage*>& results)
{
int desired_page = (m_nSubtitlesDecimalPage % 10) | ( ( ( (m_nSubtitlesDecimalPage - (100 * (m_nSubtitlesDecimalPage / 100) ) ) % 100) / 10) << 4) | ( (m_nSubtitlesDecimalPage / 100) << 8);
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
SMagazineSubPageInstances& instances = m_Magazines[mag].m_Pages[page_in_mag].m_SubPages[m_nSubtitlesDecimalSubPage];
if (!instances.empty())
{
sub_page_time -= m_SubtitleDelayTime;
for (std::list<SMagazineSubPage>::iterator it = instances.begin(); it != instances.end(); it++)
{
SMagazineSubPage* sub_page = &*it;
// if (sub_page->m_EndMilliseconds != 0)
{
if
(
/*
(
(sub_page->m_EndMilliseconds == 0)
&&
(sub_page->m_StartMilliseconds <= sub_page_time)
)
||
*/
(
(sub_page->m_StartMilliseconds <= (sub_page_time + m_SubtitleDelayRange))
&&
(sub_page->m_EndMilliseconds >= (sub_page_time - m_SubtitleDelayRange))
)
)
{
results.push_back(sub_page);
}
}
}
sort(results.begin(), results.end(), UDgreater);
}
}
//
// NonDelegatingQueryInterface
//
// Override CUnknown method.
// Part of the basic COM (Compound Object Model) mechanism.
// This is how we expose our interfaces.
//
STDMETHODIMP CDVBTeletextPageEnumerator::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);
if (riid == __uuidof(IEnumTeletextPages))
{
return GetInterface((IEnumTeletextPages*)this, ppv);
}
else
{
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
} // NonDelegatingQueryInterface
// IEnumTeletextPages methods
STDMETHODIMP CDVBTeletextPageEnumerator::Next
(
/*[in]*/ ULONG cRequest,
/* [size_is][out][in] */ int* pPage,
/* [out] */ ULONG *pcReceived
)
{
int index = m_nIndex++;
for (std::map<int, SMagazine>::iterator it = m_pFilter->m_Magazines.begin(); it != m_pFilter->m_Magazines.end(); it++)
{
for (std::map<int, SMagazinePage>::iterator mag_it = it->second.m_Pages.begin(); mag_it != it->second.m_Pages.end(); mag_it++)
{
if (mag_it->second.HasValidSubPages())
{
// ETSI EN 300 706 (Table 1) says
// "
//
// NOTE: It is not intended that the viewer should be provided with the means to select
// directly pages with hexadecimal elements in their address.
//
// "
int page = mag_it->second.GetPage();
if
(
((page & 0xF) <= 0x9)
&&
((page & 0xF0) <= 0x90)
)
{
if (index-- <= 0)
{
*pPage++ = page;
(*pcReceived)++;
if (--cRequest == 0)
{
return S_OK;
}
}
}
}
}
}
return E_FAIL;
}
STDMETHODIMP CDVBTeletextPageEnumerator::Skip(/*[in]*/ ULONG cRecords)
{
m_nIndex += cRecords;
return S_OK;
}
STDMETHODIMP CDVBTeletextPageEnumerator::Reset(void)
{
m_nIndex = 0;
return S_OK;
}
STDMETHODIMP CDVBTeletextPageEnumerator::Clone(/*[out]*/ IEnumTeletextPages** enum_pages)
{
*enum_pages = new CDVBTeletextPageEnumerator(m_pFilter);
(*enum_pages)->AddRef();
return S_OK;
}
STDMETHODIMP CDVBTeletextSubPageEnumerator::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);
if (riid == __uuidof(IEnumTeletextSubPages))
{
return GetInterface((IEnumTeletextSubPages*)this, ppv);
}
else
{
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
}
}
// IEnumTeletextSubPages methods
STDMETHODIMP CDVBTeletextSubPageEnumerator::Next
(
/*[in]*/ ULONG cRequest,
/* [size_is][out][in] */ int* pSubPage,
/* [out] */ int* pOccurances,
/* [out] */ ULONG *pcReceived
)
{
int desired_page = m_nPage;
int mag = (desired_page & 0x0f00) >> 8;
int page_in_mag = desired_page & 0x0ff;
SMagazinePage& magazine_page = m_pFilter->m_Magazines[mag].m_Pages[page_in_mag];
int index = m_nIndex++;
for (std::map<int, SMagazineSubPageInstances>::iterator it = magazine_page.m_SubPages.begin(); it != magazine_page.m_SubPages.end(); it++)
{
if (index-- <= 0)
{
*pSubPage++ = it->first;
*pOccurances++ = it->second.size();
(*pcReceived)++;
if (--cRequest == 0)
{
return S_OK;
}
}
}
return E_FAIL;
}
STDMETHODIMP CDVBTeletextSubPageEnumerator::Skip(/*[in]*/ ULONG cRecords)
{
m_nIndex += cRecords;
return S_OK;
}
STDMETHODIMP CDVBTeletextSubPageEnumerator::Reset(void)
{
m_nIndex = 0;
return S_OK;
}
STDMETHODIMP CDVBTeletextSubPageEnumerator::Clone(/*[out]*/ IEnumTeletextSubPages** enum_subpages)
{
*enum_subpages = new CDVBTeletextSubPageEnumerator(m_nPage, m_pFilter);
(*enum_subpages)->AddRef();
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -