您的位置:首页 > 编程语言

Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)

2013-10-29 00:34 519 查看
=====================================================

Media Player Classic - HC 源代码分析系列文章列表:

Media Player Classic - HC 源代码分析 1:整体结构

Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)

Media Player Classic - HC 源代码分析 4:核心类 (CMainFrame)(3)

Media Player Classic - HC 源代码分析 5:关于对话框 (CAboutDlg)

Media Player Classic - HC 源代码分析 6:MediaInfo选项卡 (CPPageFileMediaInfo)

Media Player Classic - HC 源代码分析 7:详细信息选项卡(CPPageFileInfoDetails)

=====================================================





此前已经写了2篇文章介绍Media Player Classic - HC (mpc-hc)源代码中的核心类 CMainFrame:

Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

Media Player Classic - HC 源代码分析 3:核心类 (CMainFrame)(2)

此前的文章一直都是围绕着OpenMedia()以及其调用的函数进行分析的。研究的都是和文件打开有关系的功能。在这里再介绍一些其它函数。

在mpc-hc开始运行的时候,会调用OnCreate():

<span style="font-family:Arial;font-size:12px;">//刚打开的时候加载
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (__super::OnCreate(lpCreateStruct) == -1) {
return -1;
}
//加载菜单
m_popup.LoadMenu(IDR_POPUP);
m_popupmain.LoadMenu(IDR_POPUPMAIN);

// create a view to occupy the client area of the frame
// 创建视频画面部分?
if (!m_wndView.Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, nullptr)) {
TRACE(_T("Failed to create view window\n"));
return -1;
}
// Should never be RTLed
m_wndView.ModifyStyleEx(WS_EX_LAYOUTRTL, WS_EX_NOINHERITLAYOUT);

// static bars
//各种状态栏
BOOL bResult = m_wndStatusBar.Create(this);
if (bResult) {
bResult = m_wndStatsBar.Create(this);
}
if (bResult) {
bResult = m_wndInfoBar.Create(this);
}
if (bResult) {
bResult = m_wndToolBar.Create(this);
}
if (bResult) {
bResult = m_wndSeekBar.Create(this);
}
if (!bResult) {
TRACE(_T("Failed to create all control bars\n"));
return -1;      // fail to create
}
// 各种Bar
m_pFullscreenWnd = DEBUG_NEW CFullscreenWnd(this);

m_bars.AddTail(&m_wndSeekBar);
m_bars.AddTail(&m_wndToolBar);
m_bars.AddTail(&m_wndInfoBar);
m_bars.AddTail(&m_wndStatsBar);
m_bars.AddTail(&m_wndStatusBar);

m_wndSeekBar.Enable(false);

// dockable bars
// 可停靠的
EnableDocking(CBRS_ALIGN_ANY);

m_dockingbars.RemoveAll();

m_wndSubresyncBar.Create(this, AFX_IDW_DOCKBAR_TOP, &m_csSubLock);
m_wndSubresyncBar.SetBarStyle(m_wndSubresyncBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndSubresyncBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndSubresyncBar.SetHeight(200);
m_dockingbars.AddTail(&m_wndSubresyncBar);

m_wndPlaylistBar.Create(this, AFX_IDW_DOCKBAR_BOTTOM);
m_wndPlaylistBar.SetBarStyle(m_wndPlaylistBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndPlaylistBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndPlaylistBar.SetHeight(100);
m_dockingbars.AddTail(&m_wndPlaylistBar);
m_wndPlaylistBar.LoadPlaylist(GetRecentFile());

m_wndEditListEditor.Create(this, AFX_IDW_DOCKBAR_RIGHT);
m_wndEditListEditor.SetBarStyle(m_wndEditListEditor.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndEditListEditor.EnableDocking(CBRS_ALIGN_ANY);
m_dockingbars.AddTail(&m_wndEditListEditor);
m_wndEditListEditor.SetHeight(100);

m_wndCaptureBar.Create(this, AFX_IDW_DOCKBAR_LEFT);
m_wndCaptureBar.SetBarStyle(m_wndCaptureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndCaptureBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
m_dockingbars.AddTail(&m_wndCaptureBar);

m_wndNavigationBar.Create(this, AFX_IDW_DOCKBAR_LEFT);
m_wndNavigationBar.SetBarStyle(m_wndNavigationBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndNavigationBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT);
m_dockingbars.AddTail(&m_wndNavigationBar);

m_wndShaderEditorBar.Create(this, AFX_IDW_DOCKBAR_TOP);
m_wndShaderEditorBar.SetBarStyle(m_wndShaderEditorBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndShaderEditorBar.EnableDocking(CBRS_ALIGN_ANY);
m_dockingbars.AddTail(&m_wndShaderEditorBar);

// Hide all dockable bars by default
POSITION pos = m_dockingbars.GetHeadPosition();
while (pos) {
m_dockingbars.GetNext(pos)->ShowWindow(SW_HIDE);
}

m_fileDropTarget.Register(this);

const CAppSettings& s = AfxGetAppSettings();

// Load the controls
m_nCS = s.nCS;
ShowControls(m_nCS);
//是否在最前?
SetAlwaysOnTop(s.iOnTop);
//显示系统托盘图标
ShowTrayIcon(s.fTrayIcon);
//焦点
SetFocus();
//创建CGraphThread类的线程
m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
//设置。。
if (m_pGraphThread) {
m_pGraphThread->SetMainFrame(this);
}

if (s.nCmdlnWebServerPort != 0) {
if (s.nCmdlnWebServerPort > 0) {
StartWebServer(s.nCmdlnWebServerPort);
} else if (s.fEnableWebServer) {
StartWebServer(s.nWebServerPort);
}
}

// Casimir666 : reload Shaders
{
CString strList = s.strShaderList;
CString strRes;
int curPos = 0;

strRes = strList.Tokenize(_T("|"), curPos);
while (!strRes.IsEmpty()) {
m_shaderlabels.AddTail(strRes);
strRes = strList.Tokenize(_T("|"), curPos);
}
}
{
CString strList = s.strShaderListScreenSpace;
CString strRes;
int curPos = 0;

strRes = strList.Tokenize(_T("|"), curPos);
while (!strRes.IsEmpty()) {
m_shaderlabelsScreenSpace.AddTail(strRes);
strRes = strList.Tokenize(_T("|"), curPos);
}
}

m_bToggleShader = s.fToggleShader;
m_bToggleShaderScreenSpace = s.fToggleShaderScreenSpace;
//标题
m_strTitle.LoadString(IDR_MAINFRAME);

#ifdef MPCHC_LITE
m_strTitle += _T(" Lite");
#endif
//设置窗口标题
SetWindowText(m_strTitle);
m_Lcd.SetMediaTitle(LPCTSTR(m_strTitle));

WTSRegisterSessionNotification();

if (s.bNotifySkype) {
m_pSkypeMoodMsgHandler.Attach(DEBUG_NEW SkypeMoodMsgHandler());
m_pSkypeMoodMsgHandler->Connect(m_hWnd);
}

return 0;
}</span>

在mpc-hc关闭的时候,会调用OnDestroy():

<span style="font-family:Arial;font-size:12px;">//关闭的时候加载
void CMainFrame::OnDestroy()
{
WTSUnRegisterSessionNotification();
//关闭系统托盘图标
ShowTrayIcon(false);
m_fileDropTarget.Revoke();
//线程还在运行的话
if (m_pGraphThread) {
CAMMsgEvent e;
//退出
m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
if (!e.Wait(5000)) {
TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
TerminateThread(m_pGraphThread->m_hThread, (DWORD) - 1);
}
}

if (m_pFullscreenWnd) {
if (m_pFullscreenWnd->IsWindow()) {
m_pFullscreenWnd->DestroyWindow();
}
delete m_pFullscreenWnd;
}

__super::OnDestroy();
}</span>

在关闭一个媒体的时候,会调用OnClose():

//关闭的时候加载
void CMainFrame::OnClose()
{
//获取设置
CAppSettings& s = AfxGetAppSettings();
// Casimir666 : save shaders list
{
POSITION pos;
CString strList = "";

pos = m_shaderlabels.GetHeadPosition();
while (pos) {
strList += m_shaderlabels.GetAt(pos) + "|";
m_dockingbars.GetNext(pos);
}
s.strShaderList = strList;
}
{
POSITION pos;
CString  strList = "";

pos = m_shaderlabelsScreenSpace.GetHeadPosition();
while (pos) {
strList += m_shaderlabelsScreenSpace.GetAt(pos) + "|";
m_dockingbars.GetNext(pos);
}
s.strShaderListScreenSpace = strList;
}

s.fToggleShader = m_bToggleShader;
s.fToggleShaderScreenSpace = m_bToggleShaderScreenSpace;

s.dZoomX = m_ZoomX;
s.dZoomY = m_ZoomY;
//存储播放列表
m_wndPlaylistBar.SavePlaylist();
//存储控制条
SaveControlBars();

ShowWindow(SW_HIDE);
//关闭媒体(非private)
CloseMedia();

s.WinLircClient.DisConnect();
s.UIceClient.DisConnect();

SendAPICommand(CMD_DISCONNECT, L"\0");  // according to CMD_NOTIFYENDOFSTREAM (ctrl+f it here), you're not supposed to send NULL here
//调用父类onclose
__super::OnClose();
}

同时还有一个定时器函数OnTimer()。根据不同的nIDEvent做不同的处理操作。

//定时刷新的操作
void CMainFrame::OnTimer(UINT_PTR nIDEvent)
{
switch (nIDEvent) {
//当前播放到的位置
case TIMER_STREAMPOSPOLLER:
if (m_iMediaLoadState == MLS_LOADED) {
REFERENCE_TIME rtNow = 0, rtDur = 0;
//播放方式是文件的时候(还可以是DVD或者摄像头)
if (GetPlaybackMode() == PM_FILE) {
//当前位置
m_pMS->GetCurrentPosition(&rtNow);
//时常
m_pMS->GetDuration(&rtDur);

// Casimir666 : autosave subtitle sync after play
if ((m_nCurSubtitle >= 0) && (m_rtCurSubPos != rtNow)) {
if (m_lSubtitleShift != 0) {
if (m_wndSubresyncBar.SaveToDisk()) {
m_OSD.DisplayMessage(OSD_TOPLEFT, ResStr(IDS_AG_SUBTITLES_SAVED), 500);
} else {
m_OSD.DisplayMessage(OSD_TOPLEFT, ResStr(IDS_MAINFRM_4));
}
}
m_nCurSubtitle   = -1;
m_lSubtitleShift = 0;
}

if (!m_fEndOfStream) {
CAppSettings& s = AfxGetAppSettings();

if (m_bRememberFilePos) {
FILE_POSITION* filePosition = s.filePositions.GetLatestEntry();

if (filePosition) {
filePosition->llPosition = rtNow;

LARGE_INTEGER time;
QueryPerformanceCounter(&time);
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
if ((time.QuadPart - m_liLastSaveTime.QuadPart) >= 30 * freq.QuadPart) { // save every half of minute
m_liLastSaveTime = time;
s.filePositions.SaveLatestEntry();
}
}
}
}

if (m_rtDurationOverride >= 0) {
rtDur = m_rtDurationOverride;
}
//设置滑动条控件的参数(位置等。。。)
g_bNoDuration = rtDur <= 0;
m_wndSeekBar.Enable(rtDur > 0);
m_wndSeekBar.SetRange(0, rtDur);
m_wndSeekBar.SetPos(rtNow);
m_OSD.SetRange(0, rtDur);
m_OSD.SetPos(rtNow);
m_Lcd.SetMediaRange(0, rtDur);
m_Lcd.SetMediaPos(rtNow);
} else if (GetPlaybackMode() == PM_CAPTURE) {
//如果是摄像头的话,就没有时长信息了
m_pMS->GetCurrentPosition(&rtNow);
if (m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux) {
CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
if (!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow))) {
rtNow = 0;
}
}

if (m_rtDurationOverride >= 0) {
rtDur = m_rtDurationOverride;
}

g_bNoDuration = rtDur <= 0;
m_wndSeekBar.Enable(false);
m_wndSeekBar.SetRange(0, rtDur);
m_wndSeekBar.SetPos(rtNow);
m_OSD.SetRange(0, rtDur);
m_OSD.SetPos(rtNow);
m_Lcd.SetMediaRange(0, rtDur);
m_Lcd.SetMediaPos(rtNow);
}

if (m_pCAP && GetPlaybackMode() != PM_FILE) {
g_bExternalSubtitleTime = true;
if (m_pDVDI) {
DVD_PLAYBACK_LOCATION2 Location;
if (m_pDVDI->GetCurrentLocation(&Location) == S_OK) {
double fps = Location.TimeCodeFlags == DVD_TC_FLAG_25fps ? 25.0
: Location.TimeCodeFlags == DVD_TC_FLAG_30fps ? 30.0
: Location.TimeCodeFlags == DVD_TC_FLAG_DropFrame ? 29.97
: 25.0;

REFERENCE_TIME rtTimeCode = HMSF2RT(Location.TimeCode, fps);
m_pCAP->SetTime(rtTimeCode);
} else {
m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
}
} else {
// Set rtNow to support DVB subtitle
m_pCAP->SetTime(rtNow);
}
} else {
g_bExternalSubtitleTime = false;
}
}
break;
case TIMER_STREAMPOSPOLLER2:
if (m_iMediaLoadState == MLS_LOADED) {
__int64 start, stop, pos;
m_wndSeekBar.GetRange(start, stop);
pos = m_wndSeekBar.GetPosReal();

GUID tf;
m_pMS->GetTimeFormat(&tf);

if (GetPlaybackMode() == PM_CAPTURE && !m_fCapturing) {
CString str = ResStr(IDS_CAPTURE_LIVE);

long lChannel = 0, lVivSub = 0, lAudSub = 0;
if (m_pAMTuner
&& m_wndCaptureBar.m_capdlg.IsTunerActive()
&& SUCCEEDED(m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub))) {
CString ch;
ch.Format(_T(" (ch%d)"), lChannel);
str += ch;
}

m_wndStatusBar.SetStatusTimer(str);
} else {
m_wndStatusBar.SetStatusTimer(pos, stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
if (m_bRemainingTime) {
m_OSD.DisplayMessage(OSD_TOPLEFT, m_wndStatusBar.GetStatusTimer());
}
}

m_wndSubresyncBar.SetTime(pos);

if (m_pCAP && GetMediaState() == State_Paused) {
m_pCAP->Paint(false);
}
}
break;
case TIMER_FULLSCREENCONTROLBARHIDER: {
CPoint p;
GetCursorPos(&p);

CRect r;
GetWindowRect(r);
bool fCursorOutside = !r.PtInRect(p);

CWnd* pWnd = WindowFromPoint(p);
if (pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside)) {
if (AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut >= 0) {
ShowControls(CS_NONE);
}
}
}
break;
case TIMER_FULLSCREENMOUSEHIDER: {
CPoint p;
GetCursorPos(&p);

CRect r;
GetWindowRect(r);
bool fCursorOutside = !r.PtInRect(p);
CWnd* pWnd = WindowFromPoint(p);
if (IsD3DFullScreenMode()) {
if (pWnd && !m_bInOptions && *pWnd == *m_pFullscreenWnd) {
m_pFullscreenWnd->ShowCursor(false);
}
KillTimer(TIMER_FULLSCREENMOUSEHIDER);
} else {
if (pWnd && !m_bInOptions && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside)) {
m_fHideCursor = true;
SetCursor(nullptr);
}
}
}
break;
//统计量
case TIMER_STATS: {
//接收端质量信息:抖动,抖动,视音频同步情况等。。。
if (m_pQP) {
CString rate;
rate.Format(_T("%.2f"), m_dSpeedRate);
rate = _T("(") + rate + _T("x)");
//信息
CString info;
int val = 0;
//平均帧率
m_pQP->get_AvgFrameRate(&val); // We hang here due to a lock that never gets released.
info.Format(_T("%d.%02d %s"), val / 100, val % 100, rate);
m_wndStatsBar.SetLine(ResStr(IDS_AG_FRAMERATE), info);

int avg, dev;
//抖动
m_pQP->get_AvgSyncOffset(&avg);
m_pQP->get_DevSyncOffset(&dev);
info.Format(ResStr(IDS_STATSBAR_SYNC_OFFSET_FORMAT), avg, dev);
m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_SYNC_OFFSET), info);
//掉帧
int drawn, dropped;
m_pQP->get_FramesDrawn(&drawn);
m_pQP->get_FramesDroppedInRenderer(&dropped);
info.Format(IDS_MAINFRM_6, drawn, dropped);
m_wndStatsBar.SetLine(ResStr(IDS_AG_FRAMES), info);
//抖动
m_pQP->get_Jitter(&val);
info.Format(_T("%d ms"), val);
m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_JITTER), info);
}
//缓存信息
if (m_pBI) {
CAtlList<CString> sl;
//获取数量
for (int i = 0, j = m_pBI->GetCount(); i < j; i++) {
int samples, size;
//获取缓存状态
if (S_OK == m_pBI->GetStatus(i, samples, size)) {
CString str;
str.Format(_T("[%d]: %03d/%d KB"), i, samples, size / 1024);
sl.AddTail(str);
}
}

if (!sl.IsEmpty()) {
CString str;
str.Format(_T("%s (p%u)"), Implode(sl, ' '), m_pBI->GetPriority());

m_wndStatsBar.SetLine(ResStr(IDS_AG_BUFFERS), str);
}
}
//比特率信息
CInterfaceList<IBitRateInfo> pBRIs;

BeginEnumFilters(m_pGB, pEF, pBF) {
BeginEnumPins(pBF, pEP, pPin) {
if (CComQIPtr<IBitRateInfo> pBRI = pPin) {
pBRIs.AddTail(pBRI);
}
}
EndEnumPins;

if (!pBRIs.IsEmpty()) {
CAtlList<CString> sl;

POSITION pos = pBRIs.GetHeadPosition();
for (int i = 0; pos; i++) {
//比特率接口
IBitRateInfo* pBRI = pBRIs.GetNext(pos);
//当前比特率
DWORD cur = pBRI->GetCurrentBitRate() / 1000;
//平均比特率
DWORD avg = pBRI->GetAverageBitRate() / 1000;

if (avg == 0) {
continue;
}
//添加到字符串
CString str;
if (cur != avg) {
str.Format(_T("[%d]: %u/%u Kb/s"), i, avg, cur);
} else {
str.Format(_T("[%d]: %u Kb/s"), i, avg);
}
//加入
sl.AddTail(str);
}

if (!sl.IsEmpty()) {
m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_BITRATE), Implode(sl, ' ') + ResStr(IDS_STATSBAR_BITRATE_AVG_CUR));
}

break;
}
}
EndEnumFilters;

if (GetPlaybackMode() == PM_DVD) { // we also use this timer to update the info panel for DVD playback
ULONG ulAvailable, ulCurrent;

// Location

CString Location('-');

DVD_PLAYBACK_LOCATION2 loc;
ULONG ulNumOfVolumes, ulVolume;
DVD_DISC_SIDE Side;
ULONG ulNumOfTitles;
ULONG ulNumOfChapters;

if (SUCCEEDED(m_pDVDI->GetCurrentLocation(&loc))
&& SUCCEEDED(m_pDVDI->GetNumberOfChapters(loc.TitleNum, &ulNumOfChapters))
&& SUCCEEDED(m_pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles))) {
Location.Format(IDS_MAINFRM_9,
ulVolume, ulNumOfVolumes,
loc.TitleNum, ulNumOfTitles,
loc.ChapterNum, ulNumOfChapters);
ULONG tsec = (loc.TimeCode.bHours * 3600)
+ (loc.TimeCode.bMinutes * 60)
+ (loc.TimeCode.bSeconds);
/* This might not always work, such as on resume */
if (loc.ChapterNum != m_lCurrentChapter) {
m_lCurrentChapter = loc.ChapterNum;
m_lChapterStartTime = tsec;
} else {
/* If a resume point was used, and the user chapter jumps,
then it might do some funky time jumping.  Try to 'fix' the
chapter start time if this happens */
if (m_lChapterStartTime > tsec) {
m_lChapterStartTime = tsec;
}
}
}

m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_LOCATION), Location);

// Video

CString Video('-');

DVD_VideoAttributes VATR;

if (SUCCEEDED(m_pDVDI->GetCurrentAngle(&ulAvailable, &ulCurrent))
&& SUCCEEDED(m_pDVDI->GetCurrentVideoAttributes(&VATR))) {
Video.Format(IDS_MAINFRM_10,
ulCurrent, ulAvailable,
VATR.ulSourceResolutionX, VATR.ulSourceResolutionY, VATR.ulFrameRate,
VATR.ulAspectX, VATR.ulAspectY);
}

m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_VIDEO), Video);

// Audio

CString Audio('-');

DVD_AudioAttributes AATR;

if (SUCCEEDED(m_pDVDI->GetCurrentAudio(&ulAvailable, &ulCurrent))
&& SUCCEEDED(m_pDVDI->GetAudioAttributes(ulCurrent, &AATR))) {
CString lang;
if (AATR.Language) {
int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
lang.ReleaseBufferSetLength(max(len - 1, 0));
} else {
lang.Format(IDS_AG_UNKNOWN, ulCurrent + 1);
}

switch (AATR.LanguageExtension) {
case DVD_AUD_EXT_NotSpecified:
default:
break;
case DVD_AUD_EXT_Captions:
lang += _T(" (Captions)");
break;
case DVD_AUD_EXT_VisuallyImpaired:
lang += _T(" (Visually Impaired)");
break;
case DVD_AUD_EXT_DirectorComments1:
lang += _T(" (Director Comments 1)");
break;
case DVD_AUD_EXT_DirectorComments2:
lang += _T(" (Director Comments 2)");
break;
}

CString format = GetDVDAudioFormatName(AATR);

Audio.Format(IDS_MAINFRM_11,
lang,
format,
AATR.dwFrequency,
AATR.bQuantization,
AATR.bNumberOfChannels,
(AATR.bNumberOfChannels > 1 ? ResStr(IDS_MAINFRM_13) : ResStr(IDS_MAINFRM_12)));

m_wndStatusBar.SetStatusBitmap(
AATR.bNumberOfChannels == 1 ? IDB_AUDIOTYPE_MONO
: AATR.bNumberOfChannels >= 2 ? IDB_AUDIOTYPE_STEREO
: IDB_AUDIOTYPE_NOAUDIO);
}

m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUDIO), Audio);

// Subtitles

CString Subtitles('-');

BOOL bIsDisabled;
DVD_SubpictureAttributes SATR;

if (SUCCEEDED(m_pDVDI->GetCurrentSubpicture(&ulAvailable, &ulCurrent, &bIsDisabled))
&& SUCCEEDED(m_pDVDI->GetSubpictureAttributes(ulCurrent, &SATR))) {
CString lang;
int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
lang.ReleaseBufferSetLength(max(len - 1, 0));

switch (SATR.LanguageExtension) {
case DVD_SP_EXT_NotSpecified:
default:
break;
case DVD_SP_EXT_Caption_Normal:
lang += _T("");
break;
case DVD_SP_EXT_Caption_Big:
lang += _T(" (Big)");
break;
case DVD_SP_EXT_Caption_Children:
lang += _T(" (Children)");
break;
case DVD_SP_EXT_CC_Normal:
lang += _T(" (CC)");
break;
case DVD_SP_EXT_CC_Big:
lang += _T(" (CC Big)");
break;
case DVD_SP_EXT_CC_Children:
lang += _T(" (CC Children)");
break;
case DVD_SP_EXT_Forced:
lang += _T(" (Forced)");
break;
case DVD_SP_EXT_DirectorComments_Normal:
lang += _T(" (Director Comments)");
break;
case DVD_SP_EXT_DirectorComments_Big:
lang += _T(" (Director Comments, Big)");
break;
case DVD_SP_EXT_DirectorComments_Children:
lang += _T(" (Director Comments, Children)");
break;
}

if (bIsDisabled) {
lang = _T("-");
}

Subtitles.Format(_T("%s"),
lang);
}

m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), Subtitles);
} else if (GetPlaybackMode() == PM_CAPTURE && AfxGetAppSettings().iDefaultCaptureDevice == 1) {
CComQIPtr<IBDATuner> pTun = m_pGB;
BOOLEAN bPresent;
BOOLEAN bLocked;
LONG lDbStrength;
LONG lPercentQuality;
CString Signal;

if (SUCCEEDED(pTun->GetStats(bPresent, bLocked, lDbStrength, lPercentQuality)) && bPresent) {
Signal.Format(ResStr(IDS_STATSBAR_SIGNAL_FORMAT), (int)lDbStrength, lPercentQuality);
m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_SIGNAL), Signal);
}
} else if (GetPlaybackMode() == PM_FILE) {
UpdateChapterInInfoBar();
}

if (GetMediaState() == State_Running && !m_fAudioOnly) {
BOOL fActive = FALSE;
if (SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0,       &fActive, 0)) {
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE,   nullptr,     SPIF_SENDWININICHANGE); // this might not be needed at all...
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fActive, nullptr,     SPIF_SENDWININICHANGE);
}

fActive = FALSE;
if (SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0,       &fActive, 0)) {
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE,   nullptr,     SPIF_SENDWININICHANGE); // this might not be needed at all...
SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fActive, nullptr,     SPIF_SENDWININICHANGE);
}
// prevent screensaver activate, monitor sleep/turn off after playback
SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
}
}
break;
case TIMER_STATUSERASER: {
KillTimer(TIMER_STATUSERASER);
m_playingmsg.Empty();
}
break;
case TIMER_DVBINFO_UPDATER:
KillTimer(TIMER_DVBINFO_UPDATER);
ShowCurrentChannelInfo(false, false);
break;
}

__super::OnTimer(nIDEvent);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐