📄 teletextoutputpin.cpp
字号:
hr = mix_config->SetBlendingParameter(255);
hr = mix_config->SetAspectRatioMode(AM_ARMODE_STRETCHED_AS_PRIMARY);
hr = mix_config->SetRelativePosition(0, 0, 10000, 10000);
}
break;
}
}
}
HDC hdc = GetDC(NULL);
m_DC = CreateCompatibleDC(hdc);
if (m_DC == NULL)
{
return S_OK;
}
m_Bitmap = CreateCompatibleBitmap(hdc, m_nWidth, m_nHeight);
if (m_Bitmap == NULL)
{
return S_OK;
}
ReleaseDC(NULL, hdc);
m_OldObject = SelectObject(m_DC, m_Bitmap);
if (m_OldObject == NULL)
{
return S_OK;
}
m_CurrentFont = CreateFont
(
row_height * 2,
column_width - 1,
0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, PROOF_QUALITY, FIXED_PITCH,
"Lucinda Console"
);
if (m_CurrentFont != NULL)
{
m_OldFont = (HFONT)SelectObject(m_DC, m_CurrentFont);
}
m_SupplementaryFont = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PROOF_QUALITY, FIXED_PITCH,
"Lucinda Console");
}
//
// Fill the background with m_Colours[Colour_Key].
//
int old_mode = SetBkMode(m_DC, m_TextMode);
COLORREF old_bk_colour = SetBkColor(m_DC, ((CDVBTeletextSubtitles*)m_pFilter)->m_Colours[Colour_Key]);
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right = m_nWidth;
rc.bottom = m_nHeight;
ExtTextOut(m_DC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
//
// Default text background colour
//
SetBkColor(m_DC, ((CDVBTeletextSubtitles*)m_pFilter)->m_Colours[Colour_Background]);
//
// Get the current reference time in milliseconds.
//
__int64 reference_time_milliseconds = 0;
CComQIPtr<IMediaFilter> media_filter = ((CDVBTeletextSubtitles*)m_pFilter)->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);
if (m_FirstReferenceTimeMilliseconds == 0)
{
m_FirstReferenceTimeMilliseconds = reference_time_milliseconds;
}
reference_time_milliseconds -= m_FirstReferenceTimeMilliseconds;
}
}
std::vector<SMagazineSubPage*> results;
((CDVBTeletextSubtitles*)m_pFilter)->GetSubPagesAt(reference_time_milliseconds, results);
#define MODE 1
#if MODE==0
HFONT OldFont = (HFONT)SelectObject(m_DC, m_SupplementaryFont);
#endif
COLORREF old_text_colour = SetTextColor(m_DC, RGB(255,255,255));
COLORREF old_text_bkcolour = SetBkColor(m_DC, RGB(0,0,0));
#if MODE==0
SIZE size;
GetTextExtentPoint(m_DC, "x", 1, &size);
int pos = m_nHeight - size.cy;
#endif
#if MODE==0
char buff[512];
#endif
std::vector<SMagazineSubPage*>::iterator magazine_sub_page_it = results.begin();
while (magazine_sub_page_it != results.end())
{
SMagazineSubPage* sub_page = *magazine_sub_page_it;
//
// Draw the text!!!
//
vector<STeletextSubtitleLine> texts;
// SMagazineSubPage* sub_page = ((CDVBTeletextSubtitles*)m_pFilter)->GetSubPageAt(reference_time_milliseconds);
__int64 start_milliseconds = 0;
__int64 end_milliseconds = 0;
if ((sub_page != NULL) && sub_page->m_Valid)
{
sub_page->GenerateIsoTextLines
(
texts,
((CDVBTeletextSubtitles*)m_pFilter)->m_DisplayHeadingLine,
((CDVBTeletextSubtitles*)m_pFilter)->m_nLastLine
);
start_milliseconds = sub_page->m_StartMilliseconds;
end_milliseconds = sub_page->m_EndMilliseconds;
sub_page->m_Displayed = true;
}
// ((CDVBTeletextSubtitles*)m_pFilter)->ClearSubPages();
unsigned int sh = (unsigned int)(start_milliseconds/(1000*60*60));
unsigned int sm = (unsigned int)((start_milliseconds/(1000*60))-(sh*60));
unsigned int ss = (unsigned int)((start_milliseconds/1000)-(sh*3600)-(sm*60));
unsigned int su = (unsigned int)(start_milliseconds-(sh*1000*60*60)-(sm*1000*60)-(ss*1000));
unsigned int eh = (unsigned int)(end_milliseconds/(1000*60*60));
unsigned int em = (unsigned int)((end_milliseconds/(1000*60))-(eh*60));
unsigned int es = (unsigned int)((end_milliseconds/1000)-(eh*3600)-(em*60));
unsigned int eu = (unsigned int)(end_milliseconds-(eh*1000*60*60)-(em*1000*60)-(es*1000));
vector<STeletextSubtitleLine>::iterator it = texts.begin();
for (;it != texts.end(); it++)
{
STeletextSubtitleLine subtitle_line = *it;
COLORREF old_text_colour = SetTextColor(m_DC, ((CDVBTeletextSubtitles*)m_pFilter)->m_Colours[subtitle_line.m_Colour]);
COLORREF old_text_bkcolour = SetBkColor(m_DC, ((CDVBTeletextSubtitles*)m_pFilter)->m_Colours[subtitle_line.m_BackgroundColour]);
#if MODE!=0
int length = _tcslen(subtitle_line.text);
char buffer[200];
memset(&buffer, _T(' '), sizeof(buffer) - 1);
memcpy(&buffer[subtitle_line.column - 1], subtitle_line.text, length);
buffer[40] = _T('\0');
TextOut
(
m_DC,
0,
subtitle_line.row * row_height,
buffer, 40
);
#else
sprintf(buff, "%d:%02d:%02d.%03d end=%d:%02d:%02d.%03d (%d,%d) %s"/*" ref=%d:%02d:%02d.%03d"*/, sh, sm, ss, su, eh, em, es, eu, subtitle_line.row, subtitle_line.column, subtitle_line.text);
TextOut
(
m_DC,
200,
pos,
buff,
_tcslen(buff)
);
pos -= size.cy;
#endif
SetBkColor(m_DC, old_text_bkcolour);
SetTextColor(m_DC, old_text_colour);
}
// SetBkMode(m_DC, OPAQUE);
/*
TextOut
(
m_DC,
0,
pos, // + 70,
buff,
_tcslen(buff)
);
*/
magazine_sub_page_it++;
#if MODE==0
if (pos < 0)
{
break;
}
#endif
}
#if MODE==0
DWORD subtitle_delay_time = 0;
((CDVBTeletextSubtitles*)m_pFilter)->get_SubtitleDelayTime(&subtitle_delay_time);
DWORD subtitle_delay_range = 0;
((CDVBTeletextSubtitles*)m_pFilter)->get_SubtitleDelayRange(&subtitle_delay_range);
{
unsigned int rh = (unsigned int)(reference_time_milliseconds/(1000*60*60));
unsigned int rm = (unsigned int)((reference_time_milliseconds/(1000*60))-(rh*60));
unsigned int rs = (unsigned int)((reference_time_milliseconds/1000)-(rh*3600)-(rm*60));
unsigned int ru = (unsigned int)(reference_time_milliseconds-(rh*1000*60*60)-(rm*1000*60)-(rs*1000));
sprintf(buff, "T=%d R=%d ref=%d:%02d:%02d.%03d", subtitle_delay_time, subtitle_delay_range, rh, rm, rs, ru);
TextOut
(
m_DC,
0,
m_nHeight - size.cy * 4,
buff,
_tcslen(buff)
);
}
{
__int64 reference_time_milliseconds_begin = reference_time_milliseconds - subtitle_delay_time;
reference_time_milliseconds_begin -= subtitle_delay_range;
unsigned int rbh = (unsigned int)(reference_time_milliseconds_begin/(1000*60*60));
unsigned int rbm = (unsigned int)((reference_time_milliseconds_begin/(1000*60))-(rbh*60));
unsigned int rbs = (unsigned int)((reference_time_milliseconds_begin/1000)-(rbh*3600)-(rbm*60));
unsigned int rbu = (unsigned int)(reference_time_milliseconds_begin-(rbh*1000*60*60)-(rbm*1000*60)-(rbs*1000));
sprintf(buff, "refb=%d:%02d:%02d.%03d", rbh, rbm, rbs, rbu);
TextOut
(
m_DC,
0,
m_nHeight - size.cy * 3,
buff,
_tcslen(buff)
);
}
{
__int64 reference_time_milliseconds_end = reference_time_milliseconds - subtitle_delay_time;
reference_time_milliseconds_end += subtitle_delay_range;
unsigned int reh = (unsigned int)(reference_time_milliseconds_end/(1000*60*60));
unsigned int rem = (unsigned int)((reference_time_milliseconds_end/(1000*60))-(reh*60));
unsigned int res = (unsigned int)((reference_time_milliseconds_end/1000)-(reh*3600)-(rem*60));
unsigned int reu = (unsigned int)(reference_time_milliseconds_end-(reh*1000*60*60)-(rem*1000*60)-(res*1000));
sprintf(buff, "refe=%d:%02d:%02d.%03d", reh, rem, res, reu);
TextOut
(
m_DC,
0,
m_nHeight - size.cy * 2,
buff,
_tcslen(buff)
);
}
SelectObject(m_DC, OldFont);
#endif
SetBkColor(m_DC, old_bk_colour);
SetBkMode(m_DC, old_mode);
SetBkColor(m_DC, old_text_bkcolour);
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)m_mt.pbFormat;
// Copy the DIB bits over into our filter's output buffer.
// Access the sample's data buffer
BYTE *pData;
pSample->GetPointer(&pData);
// Copy the bitmap data into the provided BYTE buffer
GetDIBits
(
m_DC,
m_Bitmap,
0,
m_nHeight,
pData,
(BITMAPINFO*)&(pVih->bmiHeader),
DIB_RGB_COLORS
);
// pSample->SetActualDataLength();
// Set the timestamps that will govern playback frame rate.
// If this file is getting written out as an AVI,
// then you'll also need to configure the AVI Mux filter to
// set the Average Time Per Frame for the AVI Header.
// The current time is the sample's start.
REFERENCE_TIME rtStart = m_iFrameNumber * m_rtFrameLength;
REFERENCE_TIME rtStop = rtStart + m_rtFrameLength;
// pSample->SetTime(&rtStart, &rtStop);
m_iFrameNumber++;
return S_OK;
}
HRESULT
CTeletextOutputPin::DoBufferProcessingLoop(void)
{
// too bad CheckRequest wasn't virtual ;(
Command com;
OnThreadStartPlay();
do
{
while (1)
{
HANDLE requests[2] =
{
GetRequestHandle(),
m_EventDataReady
};
DWORD timeout = 100; // ((CDVBTeletextSubtitles*)m_pFilter)->GetIntervalToNextEvent();
DWORD result = WaitForMultipleObjects(sizeof(requests) / sizeof(requests[0]), requests, FALSE, timeout);
if (result == WAIT_OBJECT_0)
{
if (CheckRequest(&com))
{
break;
}
}
else if (result == (WAIT_OBJECT_0 + 1))
{
m_EventDataReady.Reset();
}
else if (result == (WAIT_TIMEOUT)) // some data needs to be sent now
{
CComPtr<IMediaSample> sample;
HRESULT hr = GetDeliveryBuffer(&sample, NULL, NULL, 0);
if (FAILED(hr))
{
Sleep(1);
continue;
// go round again. Perhaps the error will go away
// or the allocator is decommited & we will be asked to
// exit soon.
}
hr = FillBuffer(sample);
if (hr == S_OK)
{
m_EventDataReady.Reset();
hr = Deliver(sample);
sample.Release();
// downstream filter returns S_FALSE if it wants us to
// stop or an error if it's reporting an error.
if (hr != S_OK)
{
DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr));
return S_OK;
}
}
else if (hr == S_FALSE)
{
// derived class wants us to stop pushing data
DeliverEndOfStream();
return S_OK;
}
else
{
// derived class encountered an error
DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr));
DeliverEndOfStream();
m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0);
return hr;
}
}
}
// For all commands sent to us there must be a Reply call!
if (com == CMD_RUN || com == CMD_PAUSE)
{
Reply(NOERROR);
}
else if (com != CMD_STOP)
{
Reply((DWORD) E_UNEXPECTED);
DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!")));
}
} while (com != CMD_STOP);
return S_FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -