⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvbteletextsubtitles.cpp

📁 Teletext module usually used in the DVB area.
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    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 + -