diff --git a/src/mpc-hc/AppSettings.cpp b/src/mpc-hc/AppSettings.cpp index 09557419887..da1a17a43ab 100644 --- a/src/mpc-hc/AppSettings.cpp +++ b/src/mpc-hc/AppSettings.cpp @@ -117,7 +117,10 @@ CAppSettings::CAppSettings() , nAudioMaxNormFactor(400) , bAllowOverridingExternalSplitterChoice(false) , iAnalogCountry(1) - , iDefaultCaptureDevice(0) + , bEnabledAnalogCapture(false) + , bEnabledDVB(false) + , bEnabledIPTV(false) + , bUseIGMPMembership(false) , fExitFullScreenAtTheEnd(true) , fLaunchfullscreen(false) , fD3DFullscreen(false) @@ -803,7 +806,7 @@ void CAppSettings::SaveSettings() pApp->WriteProfileInt(IDS_R_SETTINGS, IDS_RS_LCD_SUPPORT, fLCDSupport); // Save analog capture settings - pApp->WriteProfileInt(IDS_R_SETTINGS, IDS_RS_DEFAULT_CAPTURE, iDefaultCaptureDevice); + pApp->WriteProfileInt(IDS_R_CAPTURE, IDS_RS_ENABLE_ANALOGCAPTURE, bEnabledAnalogCapture); pApp->WriteProfileString(IDS_R_CAPTURE, IDS_RS_VIDEO_DISP_NAME, strAnalogVideo); pApp->WriteProfileString(IDS_R_CAPTURE, IDS_RS_AUDIO_DISP_NAME, strAnalogAudio); pApp->WriteProfileInt(IDS_R_CAPTURE, IDS_RS_COUNTRY, iAnalogCountry); @@ -811,6 +814,7 @@ void CAppSettings::SaveSettings() // Save digital capture settings (BDA) pApp->WriteProfileString(IDS_R_DVB, nullptr, nullptr); // Ensure the section is cleared before saving the new settings + pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_ENABLE_DVB, bEnabledDVB); pApp->WriteProfileString(IDS_R_DVB, IDS_RS_BDA_NETWORKPROVIDER, strBDANetworkProvider); pApp->WriteProfileString(IDS_R_DVB, IDS_RS_BDA_TUNER, strBDATuner); pApp->WriteProfileString(IDS_R_DVB, IDS_RS_BDA_RECEIVER, strBDAReceiver); @@ -824,6 +828,8 @@ void CAppSettings::SaveSettings() pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_DVB_LAST_CHANNEL, nDVBLastChannel); pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_DVB_REBUILD_FG, nDVBRebuildFilterGraph); pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_DVB_STOP_FG, nDVBStopFilterGraph); + pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_ENABLE_IPTV, bEnabledIPTV); + pApp->WriteProfileInt(IDS_R_DVB, IDS_RS_USE_IGMPMEMBERSHIP, bUseIGMPMembership); for (size_t i = 0; i < m_DVBChannels.size(); i++) { CString numChannel; @@ -1593,16 +1599,17 @@ void CAppSettings::LoadSettings() fLCDSupport = !!pApp->GetProfileInt(IDS_R_SETTINGS, IDS_RS_LCD_SUPPORT, FALSE); - // Save analog capture settings - iDefaultCaptureDevice = pApp->GetProfileInt(IDS_R_SETTINGS, IDS_RS_DEFAULT_CAPTURE, 0); + // Load analog capture settings + bEnabledAnalogCapture = !!pApp->GetProfileInt(IDS_R_CAPTURE, IDS_RS_ENABLE_ANALOGCAPTURE, FALSE); strAnalogVideo = pApp->GetProfileString(IDS_R_CAPTURE, IDS_RS_VIDEO_DISP_NAME, _T("dummy")); strAnalogAudio = pApp->GetProfileString(IDS_R_CAPTURE, IDS_RS_AUDIO_DISP_NAME, _T("dummy")); iAnalogCountry = pApp->GetProfileInt(IDS_R_CAPTURE, IDS_RS_COUNTRY, 1); + // Load digital TV settings + bEnabledDVB = !!pApp->GetProfileInt(IDS_R_DVB, IDS_RS_ENABLE_DVB, FALSE); strBDANetworkProvider = pApp->GetProfileString(IDS_R_DVB, IDS_RS_BDA_NETWORKPROVIDER); strBDATuner = pApp->GetProfileString(IDS_R_DVB, IDS_RS_BDA_TUNER); strBDAReceiver = pApp->GetProfileString(IDS_R_DVB, IDS_RS_BDA_RECEIVER); - //sBDAStandard = pApp->GetProfileString(IDS_R_DVB, IDS_RS_BDA_STANDARD); iBDAScanFreqStart = pApp->GetProfileInt(IDS_R_DVB, IDS_RS_BDA_SCAN_FREQ_START, 474000); iBDAScanFreqEnd = pApp->GetProfileInt(IDS_R_DVB, IDS_RS_BDA_SCAN_FREQ_END, 858000); iBDABandwidth = pApp->GetProfileInt(IDS_R_DVB, IDS_RS_BDA_BANDWIDTH, 8); @@ -1614,6 +1621,8 @@ void CAppSettings::LoadSettings() nDVBStopFilterGraph = (DVB_StopFilterGraph) pApp->GetProfileInt(IDS_R_DVB, IDS_RS_DVB_STOP_FG, DVB_STOP_FG_WHEN_SWITCHING); nNextChannelCount = pApp->GetProfileInt(IDS_R_DVB, IDS_RS_DVB_NEXTCHANNELCOUNT, 0); + bEnabledIPTV = !!pApp->GetProfileInt(IDS_R_DVB, IDS_RS_ENABLE_IPTV, FALSE); + bUseIGMPMembership = !!pApp->GetProfileInt(IDS_R_DVB, IDS_RS_USE_IGMPMEMBERSHIP, FALSE); for (int iChannel = 0; ; iChannel++) { CString strTemp; strTemp.Format(_T("%d"), iChannel); diff --git a/src/mpc-hc/AppSettings.h b/src/mpc-hc/AppSettings.h index 239d84a7977..4471ede4ef0 100644 --- a/src/mpc-hc/AppSettings.h +++ b/src/mpc-hc/AppSettings.h @@ -532,11 +532,14 @@ class CAppSettings // Sync Renderer Settings - // Capture (BDA configuration) - int iDefaultCaptureDevice; // Default capture device (analog=0, 1=digital) + // Capture (Analog configuration) + bool bEnabledAnalogCapture; CString strAnalogVideo; CString strAnalogAudio; int iAnalogCountry; + + // Digital TV configuration + bool bEnabledDVB; CString strBDANetworkProvider; CString strBDATuner; CString strBDAReceiver; @@ -551,6 +554,8 @@ class CAppSettings UINT nNextChannelCount; DVB_RebuildFilterGraph nDVBRebuildFilterGraph; DVB_StopFilterGraph nDVBStopFilterGraph; + bool bEnabledIPTV; + bool bUseIGMPMembership; // Internal Filters bool SrcFilters[SRC_LAST + !SRC_LAST]; diff --git a/src/mpc-hc/IPTVMcastTools.cpp b/src/mpc-hc/IPTVMcastTools.cpp new file mode 100644 index 00000000000..4b1d24de688 --- /dev/null +++ b/src/mpc-hc/IPTVMcastTools.cpp @@ -0,0 +1,209 @@ +/* +* (C) 2009-2014 see Authors.txt +* +* This file is part of MPC-HC. +* +* MPC-HC is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* MPC-HC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#include "stdafx.h" +#include +#include "IPTVMcastTools.h" +#include +#include +#include + +#define _BSD_SOURCE + +typedef int socklen_t; + +#define UDP_TX_BUF_SIZE 32768 +#define UDP_MAX_PKT_SIZE 65536 + + + +CIPTVMcastTools::CIPTVMcastTools() + : m_udp_fd(0), + m_socket(0), + m_is_multicast(false) + +{ +} + +CIPTVMcastTools::~CIPTVMcastTools() +{ +} + + +SOCKET CIPTVMcastTools::udp_socket_create(UINT32 local_addr, USHORT port) +{ + int iRet = -1; + SOCKET udp_fd = -1; + + // Initialize Winsock + if (WSAStartup(MAKEWORD(2, 2), &m_wsa) == 0) { + // Create socket + udp_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (udp_fd != INVALID_SOCKET) { + + memset(&m_sockaddr, 0, sizeof(m_sockaddr)); + m_sockaddr.sin_family = AF_INET; + m_sockaddr.sin_port = port; + m_sockaddr.sin_addr.s_addr = local_addr; + + int reuse = 1; + iRet = setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)); + + if (iRet != SOCKET_ERROR) { + // bind the socket + iRet = bind(udp_fd, (SOCKADDR*)&m_sockaddr, sizeof(m_sockaddr)); + if (iRet != SOCKET_ERROR) { + iRet = udp_fd; + } else { + HRESULT hr = WSAGetLastError(); + TRACE(_T("Error when binding socket: %u \n"), hr); + } + } + } + } + + if (iRet < 0) { + // Something went wrong + if (udp_fd >= 0) { + closesocket(udp_fd); + ASSERT(FALSE); + } + WSACleanup(); + } + return iRet; +} + +void CIPTVMcastTools::udp_socket_close() +{ + closesocket(m_udp_fd); + WSACleanup(); + m_udp_fd = 0; + m_socket = 0; + m_is_multicast = false; +} + + +CString CIPTVMcastTools::get_IPv4_Addr(CString sAddr) +{ + CString sIPAddr = _T("0.0.0.0"); + + int iPos0 = sAddr.Find(_T("@")); + int iBase = 1; + if (iPos0 < 0) { + iPos0 = sAddr.Find(_T("://")); + iBase = 3; + } + if (iPos0 >= 0) { + int iPos1 = sAddr.ReverseFind(_T(':')); + if (iPos1 < 0) { + iPos1 = sAddr.GetLength() - 1; + } + sIPAddr = sAddr.Mid(iBase + iPos0, iPos1 - iPos0 - iBase); + } else { + ASSERT(FALSE); + } + return sIPAddr; +} + +USHORT CIPTVMcastTools::get_IPv4_Port(CString sAddr) +{ + USHORT uPort; + int iPos = sAddr.ReverseFind(_T(':')); + CString sPort = sAddr.Right(sAddr.GetLength() - iPos - 1); + CT2CA pszConvertedAnsiString(sPort); + char* str = pszConvertedAnsiString; + uPort = atoi(str); + + return uPort; +} + +bool CIPTVMcastTools::is_multicast_address(UINT32 uIPAddr) +{ + return ((uIPAddr >= MULTICAST_FROM) && (uIPAddr <= MULTICAST_TO)); +} + + +int CIPTVMcastTools::udp_multicast_join_group(UINT32 ip_addr, USHORT port) +{ + int iResult = 0; + + // checks whether the address is within the range of addresses reserved for multicasting + m_is_multicast = is_multicast_address(ip_addr); + + if (m_is_multicast) { + m_imr.imr_interface.s_addr = htonl(INADDR_ANY); + m_imr.imr_multiaddr.s_addr = ip_addr; + + m_udp_fd = udp_socket_create(htonl(INADDR_ANY), port); + if (m_udp_fd <= 0) { + iResult = m_udp_fd; + } else { + iResult = join_source_group(m_udp_fd, m_imr.imr_multiaddr.s_addr, m_imr.imr_interface.s_addr); + + if (iResult != 0) { + HRESULT hr = WSAGetLastError(); + TRACE(_T("Error when trying to join multicast group: %u \n"), hr); + WSACleanup(); + ASSERT(FALSE); + } + } + } + + return iResult; +} + +int CIPTVMcastTools::udp_multicast_join_group(CString sAddr) +{ + int iResult; + CT2CA pszConvertedAnsiString(get_IPv4_Addr(sAddr)); + char* sGrpAddr = pszConvertedAnsiString; + + USHORT uPort = get_IPv4_Port(sAddr); + iResult = udp_multicast_join_group(inet_addr(sGrpAddr), uPort); + + return iResult; +} + +void CIPTVMcastTools::udp_multicast_leave_group() +{ + if (m_is_multicast && m_udp_fd > 0) { + leave_source_group(m_udp_fd, m_imr.imr_multiaddr.s_addr, m_imr.imr_interface.s_addr); + udp_socket_close(); + } +} + +int CIPTVMcastTools::join_source_group(int sd, UINT32 grpaddr, UINT32 iaddr) +{ + struct ip_mreq imr; + + imr.imr_multiaddr.s_addr = grpaddr; + imr.imr_interface.s_addr = iaddr; + return setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&imr, sizeof(imr)); +} + + +int CIPTVMcastTools::leave_source_group(int sd, UINT32 grpaddr, UINT32 iaddr) +{ + struct ip_mreq_source imr; + + imr.imr_multiaddr.s_addr = grpaddr; + imr.imr_interface.s_addr = iaddr; + return setsockopt(sd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&imr, sizeof(imr)); +} diff --git a/src/mpc-hc/IPTVMcastTools.h b/src/mpc-hc/IPTVMcastTools.h new file mode 100644 index 00000000000..40c288e7f22 --- /dev/null +++ b/src/mpc-hc/IPTVMcastTools.h @@ -0,0 +1,59 @@ +/* +* (C) 2003-2006 Gabest +* (C) 2006-2014 see Authors.txt +* +* This file is part of MPC-HC. +* +* MPC-HC is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* MPC-HC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#pragma once + +// Multicast range: +#define MULTICAST_FROM inet_addr("224.0.0.0") +#define MULTICAST_TO inet_addr("239.255.255.255") + +class CIPTVMcastTools +{ +public: + CIPTVMcastTools(); + ~CIPTVMcastTools(); + + // Membership management + int udp_multicast_join_group(CString sAddr); + int udp_multicast_join_group(UINT32 ip_addr, USHORT port); + void udp_multicast_leave_group(); + +private: + SOCKET m_udp_fd; + boolean m_is_multicast; + SOCKET m_socket; + struct sockaddr_in m_sockaddr; + WSADATA m_wsa; + struct ip_mreq m_imr; + + // Socket management + SOCKET udp_socket_create(UINT32 local_addr, USHORT port); + void udp_socket_close(); + + // Membership management + int join_source_group(int sd, UINT32 grpaddr, UINT32 iaddr); + int leave_source_group(int sd, UINT32 grpaddr, UINT32 iaddr); + CString get_IPv4_Addr(CString sAddr); + USHORT get_IPv4_Port(CString sAddr); + bool is_multicast_address(UINT32 uIPAddr); + +}; + diff --git a/src/mpc-hc/IPTVScanDlg.cpp b/src/mpc-hc/IPTVScanDlg.cpp index 725f25554ad..a819fb00a03 100644 --- a/src/mpc-hc/IPTVScanDlg.cpp +++ b/src/mpc-hc/IPTVScanDlg.cpp @@ -46,6 +46,7 @@ IMPLEMENT_DYNAMIC(CIPTVScanDlg, CDialog) CIPTVScanDlg::CIPTVScanDlg(CWnd* pParent /*=nullptr*/) : CDialog(CIPTVScanDlg::IDD, pParent) , m_iChannelAdditionMethod(0) + , m_bRemoveChannels(FALSE) { } @@ -92,16 +93,23 @@ void CIPTVScanDlg::DoDataExchange(CDataExchange* pDX) } BEGIN_MESSAGE_MAP(CIPTVScanDlg, CDialog) - ON_BN_CLICKED(ID_SAVE, OnBnClickedSave) - ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel) - ON_BN_CLICKED(IDC_NEW_CHANNEL, OnBnClickedNewChannel) - ON_BN_CLICKED(IDC_IMPORT_LIST, OnBnClickedImportList) + ON_BN_CLICKED(ID_SAVE, OnClickedSave) + ON_BN_CLICKED(IDCANCEL, OnClickedCancel) + ON_BN_CLICKED(IDC_NEW_CHANNEL, OnClickedNewChannel) + ON_BN_CLICKED(IDC_IMPORT_LIST, OnClickedImportList) + ON_BN_CLICKED(IDC_CHECK_REMOVE_CHANNELS, OnUpdateData) ON_CONTROL_RANGE(BN_CLICKED, IDC_RADIO1, IDC_RADIO4, OnUpdateAddChannelMethod) END_MESSAGE_MAP() // CIPTVScanDlg message handlers +void CIPTVScanDlg::OnUpdateData() +{ + UpdateData(true); +} + + void CIPTVScanDlg::OnUpdateAddChannelMethod(UINT nId) { switch (nId) { @@ -140,17 +148,18 @@ void CIPTVScanDlg::OnUpdateAddChannelMethod(UINT nId) } } -void CIPTVScanDlg::OnBnClickedSave() +void CIPTVScanDlg::OnClickedSave() { auto& DVBChannels = AfxGetAppSettings().m_DVBChannels; const int maxChannelsNum = ID_NAVIGATE_JUMPTO_SUBITEM_END - ID_NAVIGATE_JUMPTO_SUBITEM_START + 1; CAppSettings& s = AfxGetAppSettings(); int iChannel = 0; - UpdateData(); if (m_bRemoveChannels) { // Remove only IPTV Channels - auto it = std::remove_if(std::begin(DVBChannels), std::end(DVBChannels), IsChannelIPTV); + auto new_end = std::remove_if(std::begin(DVBChannels), std::end(DVBChannels), IsChannelIPTV); + DVBChannels.erase(new_end, DVBChannels.end()); + s.nNextChannelCount = 0; } for (int i = 0; i < m_ChannelList.GetItemCount(); i++) { @@ -205,7 +214,7 @@ void CIPTVScanDlg::OnBnClickedSave() } -void CIPTVScanDlg::OnBnClickedCancel() +void CIPTVScanDlg::OnClickedCancel() { // Set the current channel and close the dialog GetParent()->SendMessage(WM_DTV_SETCHANNEL, (WPARAM)AfxGetAppSettings().nDVBLastChannel); @@ -213,7 +222,7 @@ void CIPTVScanDlg::OnBnClickedCancel() } -void CIPTVScanDlg::OnBnClickedNewChannel() +void CIPTVScanDlg::OnClickedNewChannel() { CString strChannelName; CString strURL; @@ -228,7 +237,7 @@ void CIPTVScanDlg::OnBnClickedNewChannel() } -void CIPTVScanDlg::OnBnClickedImportList() +void CIPTVScanDlg::OnClickedImportList() { CString sFilename; // Call file selection (currently m3u format only) diff --git a/src/mpc-hc/IPTVScanDlg.h b/src/mpc-hc/IPTVScanDlg.h index 6183e5a48f6..bd55a263488 100644 --- a/src/mpc-hc/IPTVScanDlg.h +++ b/src/mpc-hc/IPTVScanDlg.h @@ -65,10 +65,10 @@ class CIPTVScanDlg : public CDialog int m_iChannelAdditionMethod; afx_msg LRESULT OnNewChannel(WPARAM wParam, LPARAM lParam); - - afx_msg void OnBnClickedSave(); - afx_msg void OnBnClickedCancel(); - afx_msg void OnBnClickedNewChannel(); - afx_msg void OnBnClickedImportList(); + afx_msg void OnUpdateData(); + afx_msg void OnClickedSave(); + afx_msg void OnClickedCancel(); + afx_msg void OnClickedNewChannel(); + afx_msg void OnClickedImportList(); afx_msg void OnUpdateAddChannelMethod(UINT nID); }; diff --git a/src/mpc-hc/MainFrm.cpp b/src/mpc-hc/MainFrm.cpp index 628ecefd71d..38ead0341df 100644 --- a/src/mpc-hc/MainFrm.cpp +++ b/src/mpc-hc/MainFrm.cpp @@ -197,6 +197,7 @@ BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_MESSAGE(WM_REARRANGERENDERLESS, OnRepaintRenderLess) ON_MESSAGE_VOID(WM_SAVESETTINGS, SaveAppSettings) + ON_MESSAGE_VOID(WM_DTV_REFRESHSETTINGS, OnRefreshPlayerSettings) ON_WM_NCHITTEST() @@ -776,6 +777,7 @@ CMainFrame::CMainFrame() // disabled but it avoids some unwanted cases where programmatically // disabled menu items are always re-enabled by CFrameWnd. m_bAutoMenuEnable = FALSE; + m_pMulticastMembership = nullptr; EventRouter::EventSelection receives; receives.insert(MpcEvent::SHADER_SELECTION_CHANGED); @@ -1847,7 +1849,7 @@ void CMainFrame::OnTimer(UINT_PTR nIDEvent) } } break; - case PM_DIGITAL_CAPTURE: + case PM_DIGITAL_TV: g_bExternalSubtitleTime = true; m_pMS->GetCurrentPosition(&rtNow); break; @@ -1884,7 +1886,7 @@ void CMainFrame::OnTimer(UINT_PTR nIDEvent) m_OSD.DisplayMessage(OSD_TOPLEFT, m_wndStatusBar.GetStatusTimer()); } break; - case PM_DIGITAL_CAPTURE: { + case PM_DIGITAL_TV: { if (m_pDVBState) { EventDescriptor& NowNext = m_pDVBState->NowNext; time_t tNow; @@ -2166,17 +2168,19 @@ void CMainFrame::OnTimer(UINT_PTR nIDEvent) } m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), Subtitles); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { if (m_pDVBState->bActive) { if (m_pDVBState->pChannel->IsDVB()) { CComQIPtr pTun = m_pGB; - BOOLEAN bPresent, bLocked; - LONG lDbStrength, 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); + if (pTun) { + BOOLEAN bPresent, bLocked; + LONG lDbStrength, 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 { @@ -2420,7 +2424,7 @@ LRESULT CMainFrame::OnGraphNotify(WPARAM wParam, LPARAM lParam) if (!m_pVidCap && m_pVidCap == pBF || !m_pAudCap && m_pAudCap == pBF) { SendMessage(WM_COMMAND, ID_FILE_CLOSE_AND_RESTORE); } - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { SendMessage(WM_COMMAND, ID_FILE_CLOSE_AND_RESTORE); } } @@ -2769,7 +2773,7 @@ LRESULT CMainFrame::OnResetDevice(WPARAM wParam, LPARAM lParam) m_pMC->Run(); // When restarting DVB capture, we need to set again the channel. - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { m_pDVBState->bSetChannelActive = false; SetChannel(AfxGetAppSettings().nDVBLastChannel); } @@ -2794,6 +2798,16 @@ void CMainFrame::SaveAppSettings() } } +void CMainFrame::OnRefreshPlayerSettings() +{ + if (GetPlaybackMode() == PM_DIGITAL_TV) { + m_wndNavigationBar.m_navdlg.ResetTabs(); + m_wndNavigationBar.m_navdlg.SetChannelInfoAvailable(FALSE); + m_pDVBState->bSetChannelActive = true; + PostMessage(WM_COMMAND, ID_FILE_OPENDIGITALTV); + } +} + LRESULT CMainFrame::OnNcHitTest(CPoint point) { LRESULT nHitTest = __super::OnNcHitTest(point); @@ -3300,7 +3314,7 @@ LRESULT CMainFrame::OnFilePostOpenmedia(WPARAM wParam, LPARAM lParam) } // initiate Capture panel with the new media - if (auto pDeviceData = dynamic_cast(m_lastOMD.m_p)) { + if (auto pDeviceData = dynamic_cast(m_lastOMD.m_p)) { m_wndCaptureBar.m_capdlg.SetVideoInput(pDeviceData->vinput); m_wndCaptureBar.m_capdlg.SetVideoChannel(pDeviceData->vchannel); m_wndCaptureBar.m_capdlg.SetAudioInput(pDeviceData->ainput); @@ -3340,7 +3354,7 @@ LRESULT CMainFrame::OnFilePostOpenmedia(WPARAM wParam, LPARAM lParam) UpdateControlState(CMainFrame::UPDATE_LOGO); } - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { // show navigation panel when it's available and not disabled if (!s.fHideNavigation) { m_wndNavigationBar.m_navdlg.UpdateElementList(); @@ -3385,7 +3399,7 @@ LRESULT CMainFrame::OnFilePostOpenmedia(WPARAM wParam, LPARAM lParam) // For IPTV: check whether the stream could be finally opened. Otherwise status to remain stopped. int iError = 0; - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { OpenNetworkData* pNw = dynamic_cast(m_lastOMD.m_p); if (pNw) { iError = pNw->err; @@ -3424,7 +3438,7 @@ LRESULT CMainFrame::OnFilePostOpenmedia(WPARAM wParam, LPARAM lParam) SetupRecentFilesSubMenu(); // notify listeners - if (GetPlaybackMode() != PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() != PM_DIGITAL_TV) { SendNowPlayingToSkype(); SendNowPlayingToApi(); } @@ -4031,7 +4045,17 @@ void CMainFrame::OnFileOpenmedia() void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI) { - pCmdUI->Enable(GetLoadState() != MLS::LOADING); + const auto& s = AfxGetAppSettings(); + switch (pCmdUI->m_nID) { + case ID_FILE_OPENDIGITALTV: + pCmdUI->Enable((GetLoadState() != MLS::LOADING) && ((s.bEnabledDVB && s.strBDATuner != _T("")) || s.bEnabledIPTV)); + break; + case ID_FILE_OPENDEVICE: + pCmdUI->Enable((GetLoadState() != MLS::LOADING) && (s.bEnabledAnalogCapture)); + break; + default: + pCmdUI->Enable(GetLoadState() != MLS::LOADING); + } } BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCDS) @@ -4300,6 +4324,7 @@ void CMainFrame::OnFileOpendvd() } } +// Open analog device void CMainFrame::OnFileOpendevice() { const CAppSettings& s = AfxGetAppSettings(); @@ -4315,7 +4340,7 @@ void CMainFrame::OnFileOpendevice() m_wndPlaylistBar.Empty(); - CAutoPtr p(DEBUG_NEW OpenDeviceData()); + CAutoPtr p(DEBUG_NEW OpenDeviceAnalogData()); if (p) { p->DisplayName[0] = s.strAnalogVideo; p->DisplayName[1] = s.strAnalogAudio; @@ -4323,6 +4348,7 @@ void CMainFrame::OnFileOpendevice() OpenMedia(p); } +// Open DVB or IPTV void CMainFrame::OnFileOpendigitalTV() { CAppSettings& s = AfxGetAppSettings(); @@ -4339,22 +4365,68 @@ void CMainFrame::OnFileOpendigitalTV() m_wndPlaylistBar.Empty(); CDVBChannel* pChannel = s.FindChannelByPref(s.nDVBLastChannel); + if (!m_pDVBState || !m_pDVBState->bSetChannelActive) { + m_wndNavigationBar.m_navdlg.ResetTabs(); + } + if (pChannel) { if (pChannel->IsDVB()) { - CAutoPtr p(DEBUG_NEW OpenDeviceData()); - OpenMedia(p); + if (s.bEnabledDVB) { + CAutoPtr p(DEBUG_NEW OpenDeviceDigitalData()); + if (p) { + p->nDVBChannel = s.nDVBLastChannel; + p->err = 0; + } + OpenMedia(p); + } else { + CAutoPtr p(DEBUG_NEW OpenNetworkData()); + // The channel is DVB and DVB disabled. + // Then sets a default url address and raises error flag + p->address = _T("rtp://0.0.0.0"); + p->err = 1; + OpenMedia(p); + } } else { - CAutoPtr p(DEBUG_NEW OpenNetworkData()); - p->address = pChannel->GetUrl(); - p->err = 0; - OpenMedia(p); + if (s.bEnabledIPTV) { + CAutoPtr p(DEBUG_NEW OpenNetworkData()); + if (p) { + p->address = pChannel->GetUrl(); + p->err = 0; + } + + if (s.bUseIGMPMembership) { + // Manages IGMPv2 multicast membership + if (m_pMulticastMembership == nullptr) { + m_pMulticastMembership = DEBUG_NEW CIPTVMcastTools(); + } + m_pMulticastMembership->udp_multicast_join_group(p->address); + } + OpenMedia(p); + } else { + // The channel is IPTV and IPTV disabled + // Then sets a default DVB channel + s.nDVBLastChannel = 0xFFFF; + CAutoPtr p(DEBUG_NEW OpenDeviceDigitalData()); + if (p) { + p->nDVBChannel = s.nDVBLastChannel; + p->err = 1; + } + OpenMedia(p); + } } } else { - if (s.strBDATuner != _T("")) { - CAutoPtr p(DEBUG_NEW OpenDeviceData()); + // Non existing channel + if (s.bEnabledDVB && s.strBDATuner != _T("")) { + // DVB enabled and tuner selected -> open in DVB mode + CAutoPtr p(DEBUG_NEW OpenDeviceDigitalData()); + if (p) { + p->nDVBChannel = s.nDVBLastChannel; + p->err = 1; + } OpenMedia(p); } else { CAutoPtr p(DEBUG_NEW OpenNetworkData()); + // DVB cannot be selected -> Open in IPTV mode // sets a default url address and raises error flag p->address = _T("rtp://0.0.0.0"); p->err = 1; @@ -5103,7 +5175,7 @@ void CMainFrame::OnFileSaveImage() prefix.Format(_T("%s_snapshot_%s"), GetFileName(), GetVidPos()); } else if (GetPlaybackMode() == PM_DVD) { prefix.Format(_T("dvd_snapshot_%s"), GetVidPos()); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { prefix.Format(_T("%s_snapshot"), m_pDVBState->sChannelName); } psrc.Combine(s.strSnapshotPath, MakeSnapshotFileName(prefix)); @@ -5164,7 +5236,7 @@ void CMainFrame::OnFileSaveImageAuto() prefix.Format(_T("%s_snapshot_%s"), GetFileName(), GetVidPos()); } else if (GetPlaybackMode() == PM_DVD) { prefix.Format(_T("dvd_snapshot_%s"), GetVidPos()); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { prefix.Format(_T("%s_snapshot"), m_pDVBState->sChannelName); } @@ -6471,7 +6543,7 @@ void CMainFrame::OnViewNavigation() void CMainFrame::OnUpdateViewNavigation(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_controls.ControlChecked(CMainFrameControls::Panel::NAVIGATION)); - pCmdUI->Enable(GetLoadState() == MLS::LOADED && GetPlaybackMode() == PM_DIGITAL_CAPTURE); + pCmdUI->Enable(GetLoadState() == MLS::LOADED && GetPlaybackMode() == PM_DIGITAL_TV); } void CMainFrame::OnViewCapture() @@ -7007,7 +7079,7 @@ void CMainFrame::OnPlayPlay() m_pDVDC->Pause(FALSE); } else if (GetPlaybackMode() == PM_ANALOG_CAPTURE) { m_pMC->Stop(); // audio preview won't be in sync if we run it from paused state - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { bVideoWndNeedReset = false; // SetChannel deals with MoveVideoWindow m_pDVBState->bSetChannelActive = false; SetChannel(s.nDVBLastChannel); @@ -7071,7 +7143,7 @@ void CMainFrame::OnPlayPlay() if (strOSD.IsEmpty()) { strOSD = strPlay; } - if (GetPlaybackMode() != PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() != PM_DIGITAL_TV) { m_OSD.DisplayMessage(OSD_TOPLEFT, strOSD, 3000); } } @@ -7181,7 +7253,7 @@ void CMainFrame::OnPlayStop() m_pDVDC->SetOption(DVD_ResetOnStop, TRUE); m_pMC->Stop(); m_pDVDC->SetOption(DVD_ResetOnStop, FALSE); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { m_pMC->Stop(); m_pDVBState->bActive = false; OpenSetupWindowTitle(); @@ -7257,7 +7329,7 @@ void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI) fEnable = false; } else if (m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) { fEnable = false; - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE && pCmdUI->m_nID == ID_PLAY_PAUSE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV && pCmdUI->m_nID == ID_PLAY_PAUSE) { fEnable = false; // Disable pause for digital capture mode to avoid accidental playback stop. We don't support time shifting yet. } } else if (GetPlaybackMode() == PM_DVD) { @@ -7614,7 +7686,7 @@ void CMainFrame::OnUpdatePlayChangeRate(CCmdUI* pCmdUI) fEnable = false; } else if (GetPlaybackMode() == PM_ANALOG_CAPTURE && (!m_wndCaptureBar.m_capdlg.IsTunerActive() || m_fCapturing)) { fEnable = false; - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { fEnable = false; } else if (m_fLiveWM) { fEnable = false; @@ -7867,7 +7939,7 @@ void CMainFrame::OnPlayAudio(UINT nID) } } else if (GetPlaybackMode() == PM_FILE) { OnNavStreamSelectSubMenu(i, 1); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { if (CDVBChannel* pChannel = m_pDVBState->pChannel) { OnNavStreamSelectSubMenu(i, 1); pChannel->SetDefaultAudio(i); @@ -7895,7 +7967,7 @@ void CMainFrame::OnPlaySubtitles(UINT nID) } } - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { if (CDVBChannel* pChannel = m_pDVBState->pChannel) { OnNavStreamSelectSubMenu(i, 2); pChannel->SetDefaultSubtitle(i); @@ -8437,7 +8509,7 @@ void CMainFrame::OnNavigateSkip(UINT nID) } SeekToDVDChapter((nID == ID_NAVIGATE_SKIPBACK) ? -1 : 1, true); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { int nCurrentChannel = s.nDVBLastChannel; if (nID == ID_NAVIGATE_SKIPBACK) { @@ -8466,7 +8538,7 @@ void CMainFrame::OnUpdateNavigateSkip(CCmdUI* pCmdUI) && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu) || (GetPlaybackMode() == PM_FILE && s.fUseSearchInFolder) || (GetPlaybackMode() == PM_FILE && !s.fUseSearchInFolder && (m_wndPlaylistBar.GetCount() > 1 || m_pCB->ChapGetCount() > 1)) - || (GetPlaybackMode() == PM_DIGITAL_CAPTURE && !m_pDVBState->bSetChannelActive))); + || (GetPlaybackMode() == PM_DIGITAL_TV && !m_pDVBState->bSetChannelActive))); } void CMainFrame::OnNavigateSkipFile(UINT nID) @@ -8618,7 +8690,7 @@ void CMainFrame::OnNavigateJumpTo(UINT nID) } } else if (GetPlaybackMode() == PM_DVD) { SeekToDVDChapter(nID - ID_NAVIGATE_JUMPTO_SUBITEM_START + 1); - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { int nChannel = nID - ID_NAVIGATE_JUMPTO_SUBITEM_START; if (s.nDVBLastChannel != nChannel) { @@ -8683,7 +8755,7 @@ void CMainFrame::OnTunerScan() void CMainFrame::OnUpdateTunerScan(CCmdUI* pCmdUI) { - pCmdUI->Enable(GetLoadState() == MLS::LOADED && GetPlaybackMode() == PM_DIGITAL_CAPTURE); + pCmdUI->Enable(GetLoadState() == MLS::LOADED && GetPlaybackMode() == PM_DIGITAL_TV); } // favorites @@ -8897,7 +8969,7 @@ void CMainFrame::AddFavorite(bool fDisplayMessage, bool fShowDialog) s.AddFav(FAV_DVD, str); osdMsg = IDS_DVD_FAV_ADDED; } - } // TODO: PM_ANALOG_CAPTURE and PM_DIGITAL_CAPTURE + } // TODO: PM_ANALOG_CAPTURE and PM_DIGITAL_TV if (fDisplayMessage && osdMsg) { CString osdMsgStr = ResStr(osdMsg); @@ -10367,12 +10439,10 @@ void CMainFrame::OpenCreateGraphObject(OpenMediaData* pOMD) m_pGB = DEBUG_NEW CFGManagerPlayer(_T("CFGManagerPlayer"), nullptr, m_pVideoWnd->m_hWnd); } else if (OpenDVDData* p = dynamic_cast(pOMD)) { m_pGB = DEBUG_NEW CFGManagerDVD(_T("CFGManagerDVD"), nullptr, m_pVideoWnd->m_hWnd); - } else if (OpenDeviceData* p = dynamic_cast(pOMD)) { - if (s.iDefaultCaptureDevice == 1) { - m_pGB = DEBUG_NEW CFGManagerBDA(_T("CFGManagerBDA"), nullptr, m_pVideoWnd->m_hWnd); - } else { - m_pGB = DEBUG_NEW CFGManagerCapture(_T("CFGManagerCapture"), nullptr, m_pVideoWnd->m_hWnd); - } + } else if (OpenDeviceDigitalData* p = dynamic_cast(pOMD)) { + m_pGB = DEBUG_NEW CFGManagerBDA(_T("CFGManagerBDA"), nullptr, m_pVideoWnd->m_hWnd); + } else if (OpenDeviceAnalogData* p = dynamic_cast(pOMD)) { + m_pGB = DEBUG_NEW CFGManagerCapture(_T("CFGManagerCapture"), nullptr, m_pVideoWnd->m_hWnd); } if (!m_pGB) { @@ -10560,13 +10630,22 @@ void CMainFrame::OpenNetwork(OpenNetworkData* pOND) throw (UINT)IDS_MAINFRM_81; } - CAppSettings& s = AfxGetAppSettings(); + const CAppSettings& s = AfxGetAppSettings(); CString UI_Text = _T("Opening stream..."); // ResStr(err); m_wndStatusBar.SetStatusMessage(UI_Text); - HRESULT hr = m_pGB->RenderFile(CStringW(pOND->address), nullptr); + HRESULT hr; + if (pOND->err != 1) { + hr = m_pGB->RenderFile(CStringW(pOND->address), nullptr); + } else { + hr = E_FAIL; + } if (FAILED(hr)) { + // if failed we cancel any active SetChannel operation + if (m_pDVBState) { + m_pDVBState->bSetChannelActive = false; + } if (s.fReportFailedPins) { CComQIPtr pGBDE = m_pGB; if (pGBDE && pGBDE->GetCount()) { @@ -10643,6 +10722,8 @@ void CMainFrame::OpenNetwork(OpenNetworkData* pOND) } EndEnumFilters; } + // If failed we don't change the window size + m_nLockedZoomVideoWindow++; } if (s.fReportFailedPins) { CComQIPtr pGBDE = m_pGB; @@ -10657,7 +10738,7 @@ void CMainFrame::OpenNetwork(OpenNetworkData* pOND) } EndEnumFilters; } - SetPlaybackMode(PM_DIGITAL_CAPTURE); + SetPlaybackMode(PM_DIGITAL_TV); m_pDVBState = make_unique(); } @@ -10920,14 +11001,14 @@ HRESULT CMainFrame::OpenBDAGraph() { HRESULT hr = m_pGB->RenderFile(L"", L""); if (SUCCEEDED(hr)) { - SetPlaybackMode(PM_DIGITAL_CAPTURE); + SetPlaybackMode(PM_DIGITAL_TV); m_pDVBState = make_unique(); } return hr; } // Called from GraphThread -void CMainFrame::OpenCapture(OpenDeviceData* pODD) +void CMainFrame::OpenCapture(OpenDeviceAnalogData* pODD) { m_wndCaptureBar.InitControls(); @@ -11412,7 +11493,7 @@ void CMainFrame::OpenSetupStatsBar() } else { m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_PLAYBACK_RATE), info); } - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { m_wndStatsBar.SetLine(ResStr(IDS_STATSBAR_SIGNAL), info); } if (m_pBI) { @@ -11811,9 +11892,10 @@ bool CMainFrame::OpenMediaPrivate(CAutoPtr pOMD) OpenFileData* pFileData = dynamic_cast(pOMD.m_p); OpenDVDData* pDVDData = dynamic_cast(pOMD.m_p); - OpenDeviceData* pDeviceData = dynamic_cast(pOMD.m_p); + OpenDeviceAnalogData* pDeviceAnalogData = dynamic_cast(pOMD.m_p); + OpenDeviceDigitalData* pDeviceDigitalData = dynamic_cast(pOMD.m_p); OpenNetworkData* pNetworkData = dynamic_cast(pOMD.m_p); - ASSERT(pFileData || pDVDData || pDeviceData || pNetworkData); + ASSERT(pFileData || pDVDData || pDeviceAnalogData || pDeviceDigitalData || pNetworkData); // Clear DXVA state ... ClearDXVAState(); @@ -11852,15 +11934,13 @@ bool CMainFrame::OpenMediaPrivate(CAutoPtr pOMD) OpenDVD(pDVDData); } else if (pNetworkData) { OpenNetwork(pNetworkData); - } else if (pDeviceData) { - if (s.iDefaultCaptureDevice == 1) { - HRESULT hr = OpenBDAGraph(); - if (FAILED(hr)) { - throw (UINT)IDS_CAPTURE_ERROR_DEVICE; - } - } else { - OpenCapture(pDeviceData); + } else if (pDeviceDigitalData) { + HRESULT hr = OpenBDAGraph(); + if (FAILED(hr)) { + throw (UINT)IDS_CAPTURE_ERROR_DEVICE; } + } else if (pDeviceAnalogData) { + OpenCapture(pDeviceAnalogData); } else { throw (UINT)IDS_INVALID_PARAMS_ERROR; } @@ -11988,7 +12068,7 @@ bool CMainFrame::OpenMediaPrivate(CAutoPtr pOMD) m_closingmsg = err; auto getMessageArgs = [&]() { - WPARAM wp = pFileData ? PM_FILE : pNetworkData ? PM_DIGITAL_CAPTURE : pDVDData ? PM_DVD : pDeviceData ? (s.iDefaultCaptureDevice == 1 ? PM_DIGITAL_CAPTURE : PM_ANALOG_CAPTURE) : PM_NONE; + WPARAM wp = pFileData ? PM_FILE : pNetworkData ? PM_DIGITAL_TV : pDVDData ? PM_DVD : pDeviceAnalogData ? PM_ANALOG_CAPTURE : pDeviceDigitalData ? PM_DIGITAL_TV : PM_NONE; ASSERT(wp != PM_NONE); LPARAM lp = (LPARAM)pOMD.Detach(); ASSERT(lp); @@ -12019,6 +12099,13 @@ void CMainFrame::CloseMediaPrivate() { ASSERT(GetLoadState() == MLS::CLOSING); + // IPTV: Managing IGMPv2 multicast membership (leave group) if needed + if (m_pMulticastMembership != nullptr) { + m_pMulticastMembership->udp_multicast_leave_group(); + delete m_pMulticastMembership; + m_pMulticastMembership = nullptr; + } + if (m_pMC) { m_pMC->Stop(); // needed for StreamBufferSource, because m_iMediaLoadState is always MLS::CLOSED // TODO: fix the opening for such media } @@ -12179,7 +12266,7 @@ bool CMainFrame::SearchInDir(bool bDirForward, bool bLoop /*= false*/) void CMainFrame::DoTunerScan(TunerScanData* pTSD) { - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { CComQIPtr pTun = m_pGB; if (pTun) { BOOLEAN bPresent; @@ -12661,7 +12748,7 @@ void CMainFrame::SetupAudioSubMenu() CoTaskMemFree(pName); } VERIFY(subMenu.CheckMenuRadioItem(2, 2 + cStreams - 1, 2 + iSel, MF_BYPOSITION)); - } else if (GetPlaybackMode() == PM_FILE || GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_FILE || GetPlaybackMode() == PM_DIGITAL_TV) { SetupNavStreamSelectSubMenu(subMenu, id, 1); } } @@ -12765,7 +12852,7 @@ void CMainFrame::SetupSubtitlesSubMenu() POSITION pos = m_pSubStreams.GetHeadPosition(); - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { SetupNavStreamSelectSubMenu(subMenu, id, 2); } else if (pos) { // Internal subtitles renderer int nItemsBeforeStart = id - ID_SUBTITLES_SUBITEM_START; @@ -13116,7 +13203,7 @@ void CMainFrame::SetupJumpToSubMenus(CMenu* parentMenu /*= nullptr*/, int iInser menuEndRadioSection(m_chaptersMenu); addSubMenuIfPossible(ResStr(IDS_NAVIGATE_CHAPTERS), m_chaptersMenu); } - } else if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + } else if (GetPlaybackMode() == PM_DIGITAL_TV) { const CAppSettings& s = AfxGetAppSettings(); menuStartRadioSection(); @@ -14578,16 +14665,17 @@ void CMainFrame::OpenMedia(CAutoPtr pOMD) auto pFileData = dynamic_cast(pOMD.m_p); auto pDVDData = dynamic_cast(pOMD.m_p); - auto pDeviceData = dynamic_cast(pOMD.m_p); + auto pDeviceAnalogData = dynamic_cast(pOMD.m_p); + auto pDeviceDigitalData = dynamic_cast(pOMD.m_p); auto pNetworkData = dynamic_cast(pOMD.m_p); // if the tuner graph is already loaded, we just change its channel - if (pDeviceData) { + if (pDeviceAnalogData) { if (GetLoadState() == MLS::LOADED && m_pAMTuner - && m_VidDispName == pDeviceData->DisplayName[0] && m_AudDispName == pDeviceData->DisplayName[1]) { - m_wndCaptureBar.m_capdlg.SetVideoInput(pDeviceData->vinput); - m_wndCaptureBar.m_capdlg.SetVideoChannel(pDeviceData->vchannel); - m_wndCaptureBar.m_capdlg.SetAudioInput(pDeviceData->ainput); + && m_VidDispName == pDeviceAnalogData->DisplayName[0] && m_AudDispName == pDeviceAnalogData->DisplayName[1]) { + m_wndCaptureBar.m_capdlg.SetVideoInput(pDeviceAnalogData->vinput); + m_wndCaptureBar.m_capdlg.SetVideoChannel(pDeviceAnalogData->vchannel); + m_wndCaptureBar.m_capdlg.SetAudioInput(pDeviceAnalogData->ainput); SendNowPlayingToSkype(); return; } @@ -14650,7 +14738,7 @@ void CMainFrame::OpenMedia(CAutoPtr pOMD) // use the graph thread only for some media types bool bDirectShow = pFileData && !pFileData->fns.IsEmpty() && s.m_Formats.GetEngine(pFileData->fns.GetHead()) == DirectShow; - bool bUseThread = m_pGraphThread && s.fEnableWorkerThreadForOpening && (bDirectShow || !pFileData) && (s.iDefaultCaptureDevice == 1 || !pDeviceData); + bool bUseThread = m_pGraphThread && s.fEnableWorkerThreadForOpening && (bDirectShow || !pFileData) && (!pDeviceAnalogData); // create d3dfs window if launching in fullscreen and d3dfs is enabled if (s.IsD3DFullscreen() && m_fStartInD3DFullscreen) { @@ -14850,47 +14938,76 @@ HRESULT CMainFrame::SetChannel(int nChannel) m_nLockedZoomVideoWindow = 0; } - CDVBChannel* pChannel = s.FindChannelByPref(s.nDVBLastChannel); + CDVBChannel* pChannel = s.FindChannelByPref(nChannel); if (!pChannel) { - m_pDVBState->bSetChannelActive = false; - return E_ABORT; + if (s.bEnabledDVB) { + // Channel not found and DVB is enabled. + // Then Create an empty channel object + pChannel = new CDVBChannel; + pChannel->SetFrequency(0); + } else { + // Channel not found and DVB disabled. + // Then do nothing + m_pDVBState->bSetChannelActive = false; + return E_ABORT; + } } if (pChannel->IsDVB()) { - CComQIPtr pTun = m_pGB; - if (pTun) { - if (SUCCEEDED(hr = pTun->SetChannel(nChannel))) { - if (hr == S_FALSE) { // Re-create all - m_nLockedZoomVideoWindow = 0; - m_wndNavigationBar.m_navdlg.SetChannelInfoAvailable(FALSE); - PostMessage(WM_COMMAND, ID_FILE_OPENDIGITALTV); - return hr; + if (s.bEnabledDVB) { + // The channel is DVB and DVB is enabled + CComQIPtr pTun = m_pGB; + if (pTun) { + if (SUCCEEDED(hr = pTun->SetChannel(nChannel))) { + if (hr == S_FALSE) { // Re-create all + m_nLockedZoomVideoWindow = 0; + m_wndNavigationBar.m_navdlg.SetChannelInfoAvailable(FALSE); + PostMessage(WM_COMMAND, ID_FILE_OPENDIGITALTV); + return hr; + } } + } else { + // pTun object not created. Force rebuilding graph + hr = S_FALSE; + m_nLockedZoomVideoWindow = 0; + s.nDVBLastChannel = nChannel; + m_wndNavigationBar.m_navdlg.SetChannelInfoAvailable(FALSE); + PostMessage(WM_COMMAND, ID_FILE_OPENDIGITALTV); + return hr; } + } else { + // The channel is DVB and DVB is not enabled + hr = E_INVALIDARG; } - } else { // IsIPTV() - if (pChannel != s.FindChannelByPref(nChannel)) { + } else if (pChannel->IsIPTV() && s.bEnabledIPTV) { + // IPTV + if (pChannel != s.FindChannelByPref(s.nDVBLastChannel)) { hr = S_FALSE; // Force rebuilding graph - pChannel = s.FindChannelByPref(nChannel); m_nLockedZoomVideoWindow = 0; s.nDVBLastChannel = nChannel; m_wndNavigationBar.m_navdlg.SetChannelInfoAvailable(FALSE); PostMessage(WM_COMMAND, ID_FILE_OPENDIGITALTV); return hr; } + } else { + // The channel is IPTV and IPTV is not enabled + hr = E_INVALIDARG; } - m_pDVBState->bActive = true; - m_pDVBState->pChannel = pChannel; - m_pDVBState->sChannelName = pChannel->GetName(); + if (hr == S_OK) { + m_pDVBState->bActive = true; + m_pDVBState->pChannel = pChannel; + m_pDVBState->sChannelName = pChannel->GetName(); - m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_CHANNEL), m_pDVBState->sChannelName); - RecalcLayout(); + m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_CHANNEL), m_pDVBState->sChannelName); + RecalcLayout(); - if (s.fRememberZoomLevel && !(m_fFullScreen || IsZoomed() || IsIconic())) { - ZoomVideoWindow(); + if (s.fRememberZoomLevel && !(m_fFullScreen || IsZoomed() || IsIconic())) { + ZoomVideoWindow(); + } + MoveVideoWindow(); + UpdateCurrentChannelInfo(); } - MoveVideoWindow(); // Add temporary flag to allow EC_VIDEO_SIZE_CHANGED event to stabilize window size // for 5 seconds since playback starts @@ -14898,7 +15015,6 @@ HRESULT CMainFrame::SetChannel(int nChannel) m_timerOneTime.Subscribe(TimerOneTimeSubscriber::AUTOFIT_TIMEOUT, [this] { m_bAllowWindowZoom = false; }, 5000); - UpdateCurrentChannelInfo(); } m_pDVBState->bSetChannelActive = false; @@ -16432,7 +16548,7 @@ void CMainFrame::UpdateUILanguage() // Reload the static bars OpenSetupInfoBar(); - if (GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (GetPlaybackMode() == PM_DIGITAL_TV) { UpdateCurrentChannelInfo(false, false); } OpenSetupStatsBar(); @@ -16645,18 +16761,23 @@ CString CMainFrame::GetCaptureTitle() CString title; title.LoadString(IDS_CAPTURE_LIVE); - if (GetPlaybackMode() == PM_ANALOG_CAPTURE) { - CString devName = GetFriendlyName(m_VidDispName); - if (!devName.IsEmpty()) { - title.AppendFormat(_T(" | %s"), devName); - } - } else { - CString& eventName = m_pDVBState->NowNext.eventName; - if (m_pDVBState->bActive) { - title.AppendFormat(_T(" | %s"), m_pDVBState->sChannelName); - if (!eventName.IsEmpty()) { - title.AppendFormat(_T(" - %s"), eventName); - } + CString devName = GetFriendlyName(m_VidDispName); + if (!devName.IsEmpty()) { + title.AppendFormat(_T(" | %s"), devName); + } + return title; +} + +CString CMainFrame::GetDigitalTVTitle() +{ + CString title; + + title.LoadString(IDS_CAPTURE_LIVE); + CString& eventName = m_pDVBState->NowNext.eventName; + if (m_pDVBState->bActive) { + title.AppendFormat(_T(" | %s"), m_pDVBState->sChannelName); + if (!eventName.IsEmpty()) { + title.AppendFormat(_T(" - %s"), eventName); } else { title += _T(" | DTV"); } diff --git a/src/mpc-hc/MainFrm.h b/src/mpc-hc/MainFrm.h index 889df0c8986..83609e83b0b 100644 --- a/src/mpc-hc/MainFrm.h +++ b/src/mpc-hc/MainFrm.h @@ -71,6 +71,7 @@ #include "sizecbar/scbarg.h" #include "DSMPropertyBag.h" #include "SkypeMoodMsgHandler.h" +#include "IPTVMcastTools.h" #include #include @@ -92,7 +93,7 @@ enum { PM_FILE, PM_DVD, PM_ANALOG_CAPTURE, - PM_DIGITAL_CAPTURE + PM_DIGITAL_TV }; interface __declspec(uuid("6E8D4A21-310C-11d0-B79A-00AA003767A7")) // IID_IAMLine21Decoder @@ -127,15 +128,24 @@ class OpenDVDData : public OpenMediaData class OpenNetworkData : public OpenMediaData { public: - // OpenNetworkData() {} + OpenNetworkData() : address(_T("rtp://0.0.0.0")), err(0) {} CString address; - int err = 0; + int err; }; -class OpenDeviceData : public OpenMediaData +class OpenDeviceDigitalData : public OpenMediaData { public: - OpenDeviceData() { + OpenDeviceDigitalData() : nDVBChannel(-1), err(0) {} + CStringW DisplayName[2]; + int nDVBChannel; + int err; +}; + +class OpenDeviceAnalogData : public OpenMediaData +{ +public: + OpenDeviceAnalogData() { vinput = vchannel = ainput = -1; } CStringW DisplayName[2]; @@ -400,7 +410,7 @@ class CMainFrame : public CFrameWnd, public CDropTarget void StopWebServer(); int GetPlaybackMode() const { return m_iPlaybackMode; } - bool IsPlaybackCaptureMode() const { return GetPlaybackMode() == PM_ANALOG_CAPTURE || GetPlaybackMode() == PM_DIGITAL_CAPTURE; } + bool IsPlaybackCaptureMode() const { return GetPlaybackMode() == PM_ANALOG_CAPTURE || GetPlaybackMode() == PM_DIGITAL_TV; } void SetPlaybackMode(int iNewStatus); bool IsMuted() { return m_wndToolBar.GetVolume() == -10000; } int GetVolume() { return m_wndToolBar.m_volctrl.GetPos(); } @@ -464,7 +474,7 @@ class CMainFrame : public CFrameWnd, public CDropTarget void OpenFile(OpenFileData* pOFD); void OpenDVD(OpenDVDData* pODD); void OpenNetwork(OpenNetworkData* pOND); - void OpenCapture(OpenDeviceData* pODD); + void OpenCapture(OpenDeviceAnalogData* pODD); HRESULT OpenBDAGraph(); void OpenCustomizeGraph(); void OpenSetupVideo(); @@ -553,6 +563,7 @@ class CMainFrame : public CFrameWnd, public CDropTarget CString GetFileName(); CString GetCaptureTitle(); + CString GetDigitalTVTitle(); // shaders void SetShaders(bool bSetPreResize = true, bool bSetPostResize = true); @@ -984,6 +995,7 @@ class CMainFrame : public CFrameWnd, public CDropTarget afx_msg void OnHelpDonate(); afx_msg void OnClose(); + afx_msg void OnRefreshPlayerSettings(); CMPC_Lcd m_Lcd; @@ -1105,4 +1117,7 @@ class CMainFrame : public CFrameWnd, public CDropTarget bool GetDecoderType(CString& type) const; DPI m_dpi; + +private: + CIPTVMcastTools* m_pMulticastMembership; }; diff --git a/src/mpc-hc/MainFrmControls.cpp b/src/mpc-hc/MainFrmControls.cpp index 0aaaea205c3..00cbbd2a40d 100644 --- a/src/mpc-hc/MainFrmControls.cpp +++ b/src/mpc-hc/MainFrmControls.cpp @@ -37,7 +37,7 @@ UINT CMainFrameControls::GetEffectiveToolbarsSelection() { const auto& s = AfxGetAppSettings(); UINT ret = s.nCS; - if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_CAPTURE + if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_TV || m_pMainFrame->GetPlaybackMode() == PM_ANALOG_CAPTURE) { ret &= ~CS_SEEKBAR; } diff --git a/src/mpc-hc/PPageCapture.cpp b/src/mpc-hc/PPageCapture.cpp index c586a43f0f6..862ff7c3ae7 100644 --- a/src/mpc-hc/PPageCapture.cpp +++ b/src/mpc-hc/PPageCapture.cpp @@ -292,7 +292,6 @@ IMPLEMENT_DYNAMIC(CPPageCapture, CPPageBase) CPPageCapture::CPPageCapture() : CPPageBase(CPPageCapture::IDD, CPPageCapture::IDD) - , m_iDefaultDevice(0) { } @@ -303,15 +302,10 @@ CPPageCapture::~CPPageCapture() void CPPageCapture::DoDataExchange(CDataExchange* pDX) { CPPageBase::DoDataExchange(pDX); + DDX_Check(pDX, IDC_CHECK1, m_bEnableAnalog); DDX_Control(pDX, IDC_COMBO1, m_cbAnalogVideo); DDX_Control(pDX, IDC_COMBO2, m_cbAnalogAudio); DDX_Control(pDX, IDC_COMBO9, m_cbAnalogCountry); - DDX_Control(pDX, IDC_COMBO4, m_cbDigitalNetworkProvider); - DDX_Control(pDX, IDC_COMBO5, m_cbDigitalTuner); - DDX_Control(pDX, IDC_COMBO3, m_cbDigitalReceiver); - DDX_Radio(pDX, IDC_RADIO1, m_iDefaultDevice); - DDX_Control(pDX, IDC_COMBO6, m_cbRebuildFilterGraph); - DDX_Control(pDX, IDC_COMBO7, m_cbStopFilterGraph); } BEGIN_MESSAGE_MAP(CPPageCapture, CPPageBase) @@ -321,21 +315,7 @@ BEGIN_MESSAGE_MAP(CPPageCapture, CPPageBase) ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateAnalog) ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdateAnalog) ON_UPDATE_COMMAND_UI(IDC_STATIC3, OnUpdateAnalog) - ON_UPDATE_COMMAND_UI(IDC_COMBO4, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_COMBO5, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_STATIC4, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_STATIC5, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_COMBO3, OnUpdateDigitalReciver) - ON_UPDATE_COMMAND_UI(IDC_STATIC6, OnUpdateDigitalReciver) - ON_UPDATE_COMMAND_UI(IDC_COMBO6, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_COMBO7, OnUpdateDigitalStopFilterGraph) - ON_UPDATE_COMMAND_UI(IDC_CHECK1, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST10, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST11, OnUpdateDigital) - ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST12, OnUpdateDigitalStopFilterGraph) - ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_DESC1, OnUpdateDigital) - ON_CBN_SELCHANGE(IDC_COMBO6, OnSelChangeRebuildFilterGraph) - ON_CBN_SELCHANGE(IDC_COMBO7, OnSelChangeStopFilterGraph) + ON_UPDATE_COMMAND_UI(IDC_STATIC4, OnUpdateAnalog) ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipNotify) END_MESSAGE_MAP() @@ -349,37 +329,8 @@ BOOL CPPageCapture::OnInitDialog() const CAppSettings& s = AfxGetAppSettings(); + m_bEnableAnalog = s.bEnabledAnalogCapture; FindAnalogDevices(); - FindDigitalDevices(); - - if (m_cbAnalogVideo.GetCount() && m_cbDigitalTuner.GetCount()) { - m_iDefaultDevice = s.iDefaultCaptureDevice; - } else if (m_cbAnalogVideo.GetCount()) { - m_iDefaultDevice = 0; - GetDlgItem(IDC_RADIO2)->EnableWindow(FALSE); - } else if (m_cbDigitalTuner.GetCount()) { - m_iDefaultDevice = 1; - GetDlgItem(IDC_RADIO1)->EnableWindow(FALSE); - } else { - m_iDefaultDevice = s.iDefaultCaptureDevice; - GetDlgItem(IDC_RADIO2)->EnableWindow(FALSE); - GetDlgItem(IDC_RADIO1)->EnableWindow(FALSE); - } - - m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG0)); - m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG1)); - m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG2)); - m_cbRebuildFilterGraph.SetCurSel(s.nDVBRebuildFilterGraph); - CorrectComboListWidth(m_cbRebuildFilterGraph); - - m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG0)); - m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG1)); - m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG2)); - m_cbStopFilterGraph.SetCurSel(s.nDVBStopFilterGraph); - CorrectComboListWidth(m_cbStopFilterGraph); - - OnSelChangeRebuildFilterGraph(); - OnSelChangeStopFilterGraph(); UpdateData(FALSE); @@ -399,43 +350,7 @@ BOOL CPPageCapture::OnApply() void CPPageCapture::OnUpdateAnalog(CCmdUI* pCmdUI) { - pCmdUI->Enable(IsDlgButtonChecked(IDC_RADIO1) && m_cbAnalogVideo.GetCount()); -} - -void CPPageCapture::OnUpdateDigital(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(IsDlgButtonChecked(IDC_RADIO2) && m_cbDigitalTuner.GetCount()); -} - -void CPPageCapture::OnUpdateDigitalReciver(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(IsDlgButtonChecked(IDC_RADIO2) && m_cbDigitalReceiver.GetCount()); -} - -void CPPageCapture::OnUpdateDigitalStopFilterGraph(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(IsDlgButtonChecked(IDC_RADIO2) && m_cbDigitalTuner.GetCount() && - (m_cbRebuildFilterGraph.GetCurSel() != 2)); -} - -void CPPageCapture::OnSelChangeRebuildFilterGraph() -{ - if (m_cbRebuildFilterGraph.GetCurSel() == 0) { - GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC0)); - } else if (m_cbRebuildFilterGraph.GetCurSel() == 1) { - GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC1)); - } else if (m_cbRebuildFilterGraph.GetCurSel() == 2) { - GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC2)); - } else { - GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(_T("")); - } - SetModified(); -} - - -void CPPageCapture::OnSelChangeStopFilterGraph() -{ - SetModified(); + pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK1) && m_cbAnalogVideo.GetCount()); } BOOL CPPageCapture::OnToolTipNotify(UINT id, NMHDR* pNMH, LRESULT* pResult) @@ -459,21 +374,6 @@ BOOL CPPageCapture::OnToolTipNotify(UINT id, NMHDR* pNMH, LRESULT* pResult) case IDC_COMBO9: bRet = FillComboToolTip(m_cbAnalogCountry, pTTT); break; - case IDC_COMBO4: - bRet = FillComboToolTip(m_cbDigitalNetworkProvider, pTTT); - break; - case IDC_COMBO5: - bRet = FillComboToolTip(m_cbDigitalTuner, pTTT); - break; - case IDC_COMBO3: - bRet = FillComboToolTip(m_cbDigitalReceiver, pTTT); - break; - case IDC_COMBO6: - bRet = FillComboToolTip(m_cbRebuildFilterGraph, pTTT); - break; - case IDC_COMBO7: - bRet = FillComboToolTip(m_cbStopFilterGraph, pTTT); - break; } return bRet; @@ -626,98 +526,12 @@ void CPPageCapture::FindAnalogDevices() } } -void CPPageCapture::FindDigitalDevices() -{ - const CAppSettings& s = AfxGetAppSettings(); - int iSel = 0; - bool bFound = false; - - BeginEnumSysDev(KSCATEGORY_BDA_NETWORK_PROVIDER, pMoniker) { - CComPtr pPB; - pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); - - CComVariant var; - if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { - int i = m_cbDigitalNetworkProvider.AddString(CString(var.bstrVal)); - - LPOLESTR strName = nullptr; - if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { - m_providernames.Add(CString(strName)); - if (s.strBDANetworkProvider == CString(strName)) { - iSel = i; - bFound = true; - } else if (!bFound && CString(var.bstrVal) == _T("Microsoft Network Provider")) { - // Select Microsoft Network Provider by default, other network providers are deprecated. - iSel = i; - } - CoTaskMemFree(strName); - } - } - } - EndEnumSysDev; - if (m_cbDigitalNetworkProvider.GetCount()) { - m_cbDigitalNetworkProvider.SetCurSel(iSel); - } else { - return; - } - - - iSel = 0; - BeginEnumSysDev(KSCATEGORY_BDA_NETWORK_TUNER, pMoniker) { - CComPtr pPB; - pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); - - CComVariant var; - if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { - int i = m_cbDigitalTuner.AddString(CString(var.bstrVal)); - - LPOLESTR strName = nullptr; - if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { - m_tunernames.Add(CString(strName)); - if (s.strBDATuner == CString(strName)) { - iSel = i; - } - CoTaskMemFree(strName); - } - } - } - EndEnumSysDev; - if (m_cbDigitalTuner.GetCount()) { - m_cbDigitalTuner.SetCurSel(iSel); - } else { - return; - } - - iSel = 0; - BeginEnumSysDev(KSCATEGORY_BDA_RECEIVER_COMPONENT, pMoniker) { - CComPtr pPB; - pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); - - CComVariant var; - if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { - int i = m_cbDigitalReceiver.AddString(CString(var.bstrVal)); - - LPOLESTR strName = nullptr; - if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { - m_receivernames.Add(CString(strName)); - if (s.strBDAReceiver == CString(strName)) { - iSel = i; - } - CoTaskMemFree(strName); - } - } - } - EndEnumSysDev; - if (m_cbDigitalReceiver.GetCount()) { - m_cbDigitalReceiver.SetCurSel(iSel); - } -} void CPPageCapture::SaveFoundDevices() { CAppSettings& s = AfxGetAppSettings(); - s.iDefaultCaptureDevice = m_iDefaultDevice; + s.bEnabledAnalogCapture = !!m_bEnableAnalog; if (m_cbAnalogVideo.GetCurSel() >= 0) { s.strAnalogVideo = m_vidnames[m_cbAnalogVideo.GetCurSel()]; @@ -728,17 +542,4 @@ void CPPageCapture::SaveFoundDevices() if (m_cbAnalogCountry.GetCurSel() >= 0) { s.iAnalogCountry = ((cc_t*)m_cbAnalogCountry.GetItemDataPtr(m_cbAnalogCountry.GetCurSel()))->code; } - - if (m_cbDigitalNetworkProvider.GetCurSel() >= 0) { - s.strBDANetworkProvider = m_providernames[m_cbDigitalNetworkProvider.GetCurSel()]; - } - if (m_cbDigitalTuner.GetCurSel() >= 0) { - s.strBDATuner = m_tunernames[m_cbDigitalTuner.GetCurSel()]; - } - if (m_cbDigitalReceiver.GetCurSel() >= 0) { - s.strBDAReceiver = m_receivernames[m_cbDigitalReceiver.GetCurSel()]; - } - - s.nDVBRebuildFilterGraph = (DVB_RebuildFilterGraph)m_cbRebuildFilterGraph.GetCurSel(); - s.nDVBStopFilterGraph = (DVB_StopFilterGraph)m_cbStopFilterGraph.GetCurSel(); } diff --git a/src/mpc-hc/PPageCapture.h b/src/mpc-hc/PPageCapture.h index d8fccb63483..c1634154ed5 100644 --- a/src/mpc-hc/PPageCapture.h +++ b/src/mpc-hc/PPageCapture.h @@ -36,12 +36,6 @@ class CPPageCapture : public CPPageBase CComboBox m_cbAnalogVideo; CComboBox m_cbAnalogAudio; CComboBox m_cbAnalogCountry; - CComboBox m_cbDigitalNetworkProvider; - CComboBox m_cbDigitalTuner; - CComboBox m_cbDigitalReceiver; - int m_iDefaultDevice; - CComboBox m_cbRebuildFilterGraph; - CComboBox m_cbStopFilterGraph; void FindAnalogDevices(); void FindDigitalDevices(); @@ -60,12 +54,8 @@ class CPPageCapture : public CPPageBase virtual BOOL OnApply(); DECLARE_MESSAGE_MAP() + BOOL m_bEnableAnalog; afx_msg void OnUpdateAnalog(CCmdUI* pCmdUI); - afx_msg void OnUpdateDigital(CCmdUI* pCmdUI); - afx_msg void OnUpdateDigitalReciver(CCmdUI* pCmdUI); - afx_msg void OnUpdateDigitalStopFilterGraph(CCmdUI* pCmdUI); - afx_msg void OnSelChangeRebuildFilterGraph(); - afx_msg void OnSelChangeStopFilterGraph(); afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMH, LRESULT* pResult); }; diff --git a/src/mpc-hc/PPageDigitalTV.cpp b/src/mpc-hc/PPageDigitalTV.cpp new file mode 100644 index 00000000000..a2101455ffa --- /dev/null +++ b/src/mpc-hc/PPageDigitalTV.cpp @@ -0,0 +1,314 @@ +/* +* (C) 2009-2013 see Authors.txt +* +* This file is part of MPC-HC. +* +* MPC-HC is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* MPC-HC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +// PPageCapture.cpp : implementation file +// + +#include "stdafx.h" +#include +#include +#include +#include +#include + +#include "mplayerc.h" +#include "PPageDigitalTV.h" +#include "DSUtil.h" + + +// CPPageCapture dialog + +IMPLEMENT_DYNAMIC(CPPageDigitalTV, CPPageBase) + +CPPageDigitalTV::CPPageDigitalTV() + : CPPageBase(CPPageDigitalTV::IDD, CPPageDigitalTV::IDD) +{ +} + +CPPageDigitalTV::~CPPageDigitalTV() +{ +} + +void CPPageDigitalTV::DoDataExchange(CDataExchange* pDX) +{ + CPPageBase::DoDataExchange(pDX); + DDX_Check(pDX, IDC_CHECK1, m_bEnableDVB); + DDX_Control(pDX, IDC_COMBO4, m_cbDigitalNetworkProvider); + DDX_Control(pDX, IDC_COMBO5, m_cbDigitalTuner); + DDX_Control(pDX, IDC_COMBO3, m_cbDigitalReceiver); + DDX_Control(pDX, IDC_COMBO6, m_cbRebuildFilterGraph); + DDX_Control(pDX, IDC_COMBO7, m_cbStopFilterGraph); + DDX_Check(pDX, IDC_CHECK2, m_bEnableIPTV); + DDX_Check(pDX, IDC_CHECK3, m_bUseIGMPMembership); +} + + +BEGIN_MESSAGE_MAP(CPPageDigitalTV, CPPageBase) + ON_UPDATE_COMMAND_UI(IDC_COMBO4, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_COMBO5, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_STATIC4, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_STATIC5, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_COMBO3, OnUpdateDigitalReciver) + ON_UPDATE_COMMAND_UI(IDC_STATIC6, OnUpdateDigitalReciver) + ON_UPDATE_COMMAND_UI(IDC_COMBO6, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_COMBO7, OnUpdateDigitalStopFilterGraph) + ON_UPDATE_COMMAND_UI(IDC_STATIC, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_STATIC2, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST10, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST11, OnUpdateDVB) + ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_ST12, OnUpdateDigitalStopFilterGraph) + ON_UPDATE_COMMAND_UI(IDC_PPAGECAPTURE_DESC1, OnUpdateDVB) + ON_CBN_SELCHANGE(IDC_COMBO6, OnSelchangeRebuildFilterGraph) + ON_CBN_SELCHANGE(IDC_COMBO7, OnSelchangeStopFilterGraph) + ON_UPDATE_COMMAND_UI(IDC_STATIC1, OnUpdateIPTV) + ON_UPDATE_COMMAND_UI(IDC_STATIC3, OnUpdateIPTV) + ON_UPDATE_COMMAND_UI(IDC_CHECK3, OnUpdateIPTV) +END_MESSAGE_MAP() + + +// CPPageCapture message handlers + +BOOL CPPageDigitalTV::OnInitDialog() +{ + __super::OnInitDialog(); + + SetHandCursor(m_hWnd, IDC_COMBO4); + + const CAppSettings& s = AfxGetAppSettings(); + + FindDigitalDevices(); + + m_bEnableDVB = s.bEnabledDVB; + + m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG0)); + m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG1)); + m_cbRebuildFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_FG2)); + m_cbRebuildFilterGraph.SetCurSel(s.nDVBRebuildFilterGraph); + CorrectComboListWidth(m_cbRebuildFilterGraph); + + m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG0)); + m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG1)); + m_cbStopFilterGraph.AddString(ResStr(IDS_PPAGE_CAPTURE_SFG2)); + m_cbStopFilterGraph.SetCurSel(s.nDVBStopFilterGraph); + CorrectComboListWidth(m_cbStopFilterGraph); + OnSelchangeRebuildFilterGraph(); + OnSelchangeStopFilterGraph(); + + m_bEnableIPTV = s.bEnabledIPTV; + m_bUseIGMPMembership = s.bUseIGMPMembership; + GetDlgItem(IDC_CHECK3)->EnableWindow(FALSE); + + UpdateData(FALSE); + SaveFoundDevices(); // Save (new) devices to ensure that comboboxes reflect actual settings. + + EnableToolTips(TRUE); + + return TRUE; +} + +BOOL CPPageDigitalTV::OnApply() +{ + UpdateData(); + SaveFoundDevices(); + AfxGetMainWnd()->PostMessageW(WM_DTV_REFRESHSETTINGS); + return __super::OnApply(); +} + +void CPPageDigitalTV::OnUpdateDVB(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK1) && m_cbDigitalTuner.GetCount()); +} + +void CPPageDigitalTV::OnUpdateIPTV(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK2)); +} + +void CPPageDigitalTV::OnUpdateDigitalReciver(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK1) && m_cbDigitalReceiver.GetCount()); +} + +void CPPageDigitalTV::OnUpdateDigitalStopFilterGraph(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(IsDlgButtonChecked(IDC_CHECK1) && m_cbDigitalTuner.GetCount() && + (m_cbRebuildFilterGraph.GetCurSel() != 2)); +} + +void CPPageDigitalTV::OnSelchangeRebuildFilterGraph() +{ + if (m_cbRebuildFilterGraph.GetCurSel() == 0) { + GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC0)); + } else if (m_cbRebuildFilterGraph.GetCurSel() == 1) { + GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC1)); + } else if (m_cbRebuildFilterGraph.GetCurSel() == 2) { + GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(ResStr(IDS_PPAGE_CAPTURE_FGDESC2)); + } else { + GetDlgItem(IDC_PPAGECAPTURE_DESC1)->SetWindowText(_T("")); + } + SetModified(); +} + + +void CPPageDigitalTV::OnSelchangeStopFilterGraph() +{ + SetModified(); +} + +BOOL CPPageDigitalTV::OnToolTipNotify(UINT id, NMHDR* pNMH, LRESULT* pResult) +{ + LPTOOLTIPTEXT pTTT = reinterpret_cast(pNMH); + + UINT_PTR nID = pNMH->idFrom; + if (pTTT->uFlags & TTF_IDISHWND) { + nID = ::GetDlgCtrlID((HWND)nID); + } + + BOOL bRet = FALSE; + + switch (nID) { + case IDC_COMBO4: + bRet = FillComboToolTip(m_cbDigitalNetworkProvider, pTTT); + break; + case IDC_COMBO5: + bRet = FillComboToolTip(m_cbDigitalTuner, pTTT); + break; + case IDC_COMBO3: + bRet = FillComboToolTip(m_cbDigitalReceiver, pTTT); + break; + case IDC_COMBO6: + bRet = FillComboToolTip(m_cbRebuildFilterGraph, pTTT); + break; + case IDC_COMBO7: + bRet = FillComboToolTip(m_cbStopFilterGraph, pTTT); + break; + } + + return bRet; +} + +void CPPageDigitalTV::FindDigitalDevices() +{ + const CAppSettings& s = AfxGetAppSettings(); + int iSel = 0; + bool bFound = false; + + BeginEnumSysDev(KSCATEGORY_BDA_NETWORK_PROVIDER, pMoniker) { + CComPtr pPB; + pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); + + CComVariant var; + if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { + int i = m_cbDigitalNetworkProvider.AddString(CString(var.bstrVal)); + + LPOLESTR strName = nullptr; + if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { + m_providernames.Add(CString(strName)); + if (s.strBDANetworkProvider == CString(strName)) { + iSel = i; + bFound = true; + } else if (!bFound && CString(var.bstrVal) == _T("Microsoft Network Provider")) { + // Select Microsoft Network Provider by default, other network providers are deprecated. + iSel = i; + } + CoTaskMemFree(strName); + } + } + } + EndEnumSysDev; + if (m_cbDigitalNetworkProvider.GetCount()) { + m_cbDigitalNetworkProvider.SetCurSel(iSel); + } else { + return; + } + + + iSel = 0; + BeginEnumSysDev(KSCATEGORY_BDA_NETWORK_TUNER, pMoniker) { + CComPtr pPB; + pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); + + CComVariant var; + if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { + int i = m_cbDigitalTuner.AddString(CString(var.bstrVal)); + + LPOLESTR strName = nullptr; + if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { + m_tunernames.Add(CString(strName)); + if (s.strBDATuner == CString(strName)) { + iSel = i; + } + CoTaskMemFree(strName); + } + } + } + EndEnumSysDev; + if (m_cbDigitalTuner.GetCount()) { + m_cbDigitalTuner.SetCurSel(iSel); + } else { + return; + } + + iSel = 0; + BeginEnumSysDev(KSCATEGORY_BDA_RECEIVER_COMPONENT, pMoniker) { + CComPtr pPB; + pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPB)); + + CComVariant var; + if (SUCCEEDED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, nullptr))) { + int i = m_cbDigitalReceiver.AddString(CString(var.bstrVal)); + + LPOLESTR strName = nullptr; + if (SUCCEEDED(pMoniker->GetDisplayName(nullptr, nullptr, &strName))) { + m_receivernames.Add(CString(strName)); + if (s.strBDAReceiver == CString(strName)) { + iSel = i; + } + CoTaskMemFree(strName); + } + } + } + EndEnumSysDev; + if (m_cbDigitalReceiver.GetCount()) { + m_cbDigitalReceiver.SetCurSel(iSel); + } +} + +void CPPageDigitalTV::SaveFoundDevices() +{ + CAppSettings& s = AfxGetAppSettings(); + + s.bEnabledDVB = !!m_bEnableDVB; + if (m_cbDigitalNetworkProvider.GetCurSel() >= 0) { + s.strBDANetworkProvider = m_providernames[m_cbDigitalNetworkProvider.GetCurSel()]; + } + if (m_cbDigitalTuner.GetCurSel() >= 0) { + s.strBDATuner = m_tunernames[m_cbDigitalTuner.GetCurSel()]; + } + if (m_cbDigitalReceiver.GetCurSel() >= 0) { + s.strBDAReceiver = m_receivernames[m_cbDigitalReceiver.GetCurSel()]; + } + s.nDVBRebuildFilterGraph = (DVB_RebuildFilterGraph)m_cbRebuildFilterGraph.GetCurSel(); + s.nDVBStopFilterGraph = (DVB_StopFilterGraph)m_cbStopFilterGraph.GetCurSel(); + + s.bEnabledIPTV = !!m_bEnableIPTV; + s.bUseIGMPMembership = !!m_bUseIGMPMembership; + +} diff --git a/src/mpc-hc/PPageDigitalTV.h b/src/mpc-hc/PPageDigitalTV.h new file mode 100644 index 00000000000..23cc990520f --- /dev/null +++ b/src/mpc-hc/PPageDigitalTV.h @@ -0,0 +1,73 @@ +/* +* (C) 2009-2014 see Authors.txt +* (C) 2009-2013 see Authors.txt +* +* This file is part of MPC-HC. +* +* MPC-HC is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* MPC-HC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*/ + +#pragma once + +#include "PPageBase.h" +#include +#include + +// CPPageDigitalTV dialog + +class CPPageDigitalTV : public CPPageBase +{ + DECLARE_DYNAMIC(CPPageDigitalTV) + + CAtlArray m_vidnames, m_audnames, m_providernames, m_tunernames, m_receivernames; + +private: + BOOL m_bEnableDVB; + CComboBox m_cbDigitalNetworkProvider; + CComboBox m_cbDigitalTuner; + CComboBox m_cbDigitalReceiver; + CComboBox m_cbRebuildFilterGraph; + CComboBox m_cbStopFilterGraph; + + void FindAnalogDevices(); + void FindDigitalDevices(); + void SaveFoundDevices(); + BOOL m_bEnableIPTV; + BOOL m_bUseIGMPMembership; + +public: + CPPageDigitalTV(); // standard constructor + virtual ~CPPageDigitalTV(); + + // Dialog Data + enum { IDD = IDD_PPAGEDIGITALTV }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + virtual BOOL OnApply(); + + DECLARE_MESSAGE_MAP() + +public: + + afx_msg void OnUpdateDVB(CCmdUI* pCmdUI); + afx_msg void OnUpdateDigitalReciver(CCmdUI* pCmdUI); + afx_msg void OnUpdateDigitalStopFilterGraph(CCmdUI* pCmdUI); + afx_msg void OnSelchangeRebuildFilterGraph(); + afx_msg void OnSelchangeStopFilterGraph(); + afx_msg void OnUpdateIPTV(CCmdUI* pCmdUI); + afx_msg BOOL OnToolTipNotify(UINT id, NMHDR* pNMH, LRESULT* pResult); +}; \ No newline at end of file diff --git a/src/mpc-hc/PPageSheet.cpp b/src/mpc-hc/PPageSheet.cpp index 7a861b7dc23..72e7d1cca18 100644 --- a/src/mpc-hc/PPageSheet.cpp +++ b/src/mpc-hc/PPageSheet.cpp @@ -51,6 +51,7 @@ CPPageSheet::CPPageSheet(LPCTSTR pszCaption, IFilterGraph* pFG, CWnd* pParentWnd AddPage(&m_fullscreen); AddPage(&m_sync); AddPage(&m_tuner); + AddPage(&m_digitalTV); #ifndef MPCHC_LITE AddPage(&m_internalfilters); #endif diff --git a/src/mpc-hc/PPageSheet.h b/src/mpc-hc/PPageSheet.h index cc784f9c7f0..144ab39cb61 100644 --- a/src/mpc-hc/PPageSheet.h +++ b/src/mpc-hc/PPageSheet.h @@ -41,6 +41,7 @@ #include "PPageTweaks.h" #include "PPageMisc.h" #include "PPageCapture.h" +#include "PPageDigitalTV.h" #include "PPageShaders.h" #include "PPageAdvanced.h" #include "TreePropSheet/TreePropSheet.h" @@ -89,6 +90,7 @@ class CPPageSheet : public TreePropSheet::CTreePropSheet CPPageFullscreen m_fullscreen; CPPageSync m_sync; CPPageCapture m_tuner; + CPPageDigitalTV m_digitalTV; #ifndef MPCHC_LITE CPPageInternalFilters m_internalfilters; #endif diff --git a/src/mpc-hc/PlayerNavigationDialog.cpp b/src/mpc-hc/PlayerNavigationDialog.cpp index c61b29fef86..cd453073ef1 100644 --- a/src/mpc-hc/PlayerNavigationDialog.cpp +++ b/src/mpc-hc/PlayerNavigationDialog.cpp @@ -88,10 +88,6 @@ BOOL CPlayerNavigationDialog::OnInitDialog() { __super::OnInitDialog(); - m_tabSelChannelList.InsertItem(0, ResStr(IDS_DTV_TAB_DVBT)); - m_tabSelChannelList.InsertItem(1, ResStr(IDS_DTV_TAB_IPTV)); - m_tabSelChannelList.InsertItem(2, ResStr(IDS_DTV_TAB_RADIO)); - return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } @@ -102,6 +98,53 @@ void CPlayerNavigationDialog::OnDestroy() __super::OnDestroy(); } +void CPlayerNavigationDialog::ResetTabs() +{ + CAppSettings& s = AfxGetAppSettings(); + int i = 0; + + // relative position of each tab. -1 means not present + m_tabDVB = -1; + m_tabIPTV = -1; + m_tabRadio = -1; + m_tabSelChannelList.DeleteAllItems(); + + if (s.bEnabledDVB && (s.strBDATuner != _T(""))) { + m_tabDVB = i; + m_tabSelChannelList.InsertItem(i, ResStr(IDS_DTV_TAB_DVBT)); + i++; + } + + if (s.bEnabledIPTV) { + m_tabIPTV = i; + m_tabSelChannelList.InsertItem(i, ResStr(IDS_DTV_TAB_IPTV)); + i++; + } + + if (s.bEnabledDVB && (s.strBDATuner != _T(""))) { + m_tabRadio = i; + m_tabSelChannelList.InsertItem(i, ResStr(IDS_DTV_TAB_RADIO)); + i++; + } + + if (s.strBDATuner == _T("")) { + m_tabSelChannelList.SetCurSel(0); + } else { + // Select the tab where the current channel belongs by default + // Otherwise do nothing + CDVBChannel* pChannel = s.FindChannelByPref(s.nDVBLastChannel); + if (pChannel) { + if (pChannel->IsDVB() && pChannel->GetVideoPID() && m_tabDVB >= 0) { + m_tabSelChannelList.SetCurSel(m_tabDVB); + } else if (pChannel->IsDVB() && m_tabRadio >= 0) { + m_tabSelChannelList.SetCurSel(m_tabRadio); + } else if (pChannel->IsIPTV() && m_tabIPTV >= 0) { + m_tabSelChannelList.SetCurSel(m_tabIPTV); + } + } + } +} + void CPlayerNavigationDialog::OnChangeChannel() { int nItem = m_channelList.GetCurSel(); @@ -113,47 +156,45 @@ void CPlayerNavigationDialog::OnChangeChannel() void CPlayerNavigationDialog::UpdateElementList() { - if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_TV) { const auto& s = AfxGetAppSettings(); m_channelList.ResetContent(); for (const auto& channel : s.m_DVBChannels) { - switch (m_tabSelChannelList.GetCurSel()) { - case 0: // DVB-T - if (channel.IsDVB() && channel.GetVideoPID() && channel.GetAudioCount()) { - int nItem = m_channelList.AddString(channel.GetName()); - if (nItem != LB_ERR) { - m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); - if (s.nDVBLastChannel == channel.GetPrefNumber()) { - m_channelList.SetCurSel(nItem); - } + // Update only the active tab + if (m_tabSelChannelList.GetCurSel() == m_tabDVB) { + // DVB-T + if (channel.IsDVB() && channel.GetVideoPID() && channel.GetAudioCount()) { + int nItem = m_channelList.AddString(channel.GetName()); + if (nItem != LB_ERR) { + m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); + if (s.nDVBLastChannel == channel.GetPrefNumber()) { + m_channelList.SetCurSel(nItem); } } - break; - - case 1: // IPTV - if (channel.IsIPTV() && channel.GetVideoPID()) { - int nItem = m_channelList.AddString(channel.GetName()); - if (nItem != LB_ERR) { - m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); - if (s.nDVBLastChannel == channel.GetPrefNumber()) { - m_channelList.SetCurSel(nItem); - } + } + } else if (m_tabSelChannelList.GetCurSel() == m_tabIPTV) { + // IPTV + if (channel.IsIPTV() && channel.GetVideoPID()) { + int nItem = m_channelList.AddString(channel.GetName()); + if (nItem != LB_ERR) { + m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); + if (s.nDVBLastChannel == channel.GetPrefNumber()) { + m_channelList.SetCurSel(nItem); } } - break; - - case 2: // Radio - if ((channel.GetVideoPID() == 0) && (channel.GetAudioCount() > 0)) { - int nItem = m_channelList.AddString(channel.GetName()); - if (nItem != LB_ERR) { - m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); - if (s.nDVBLastChannel == channel.GetPrefNumber()) { - m_channelList.SetCurSel(nItem); - } + } + } else if (m_tabSelChannelList.GetCurSel() == m_tabRadio) { + // Radio + if ((channel.GetVideoPID() == 0) && (channel.GetAudioCount() > 0)) { + int nItem = m_channelList.AddString(channel.GetName()); + if (nItem != LB_ERR) { + m_channelList.SetItemData(nItem, (DWORD_PTR)channel.GetPrefNumber()); + if (s.nDVBLastChannel == channel.GetPrefNumber()) { + m_channelList.SetCurSel(nItem); } } - break; + } } } } @@ -192,13 +233,6 @@ void CPlayerNavigationDialog::OnUpdateShowChannelInfoButton(CCmdUI* pCmdUI) void CPlayerNavigationDialog::OnTcnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult) { - const CAppSettings& s = AfxGetAppSettings(); - - if (s.strBDATuner == _T("") && - (m_tabSelChannelList.GetCurSel() == 0 || m_tabSelChannelList.GetCurSel() == 2)) { - m_tabSelChannelList.SetCurSel(1); - } - UpdateElementList(); *pResult = 0; } diff --git a/src/mpc-hc/PlayerNavigationDialog.h b/src/mpc-hc/PlayerNavigationDialog.h index a887c9195b0..67423958f88 100644 --- a/src/mpc-hc/PlayerNavigationDialog.h +++ b/src/mpc-hc/PlayerNavigationDialog.h @@ -36,6 +36,9 @@ class CPlayerNavigationDialog : public CResizableDialog CMainFrame* m_pMainFrame; bool m_bChannelInfoAvailable; bool m_bTVStations; + int m_tabDVB; + int m_tabIPTV; + int m_tabRadio; public: CPlayerNavigationDialog() = delete; @@ -49,6 +52,7 @@ class CPlayerNavigationDialog : public CResizableDialog void UpdateElementList(); void UpdatePos(int nID); + void ResetTabs(); void SetChannelInfoAvailable(bool bAvailable); CTabCtrl m_tabSelChannelList; diff --git a/src/mpc-hc/PlayerPlaylistBar.cpp b/src/mpc-hc/PlayerPlaylistBar.cpp index 0226a2d40e1..f943ff9982e 100644 --- a/src/mpc-hc/PlayerPlaylistBar.cpp +++ b/src/mpc-hc/PlayerPlaylistBar.cpp @@ -790,7 +790,7 @@ OpenMediaData* CPlayerPlaylistBar::GetCurOMD(REFERENCE_TIME rtStart) } if (pli->m_type == CPlaylistItem::device) { - if (OpenDeviceData* p = DEBUG_NEW OpenDeviceData()) { + if (OpenDeviceAnalogData* p = DEBUG_NEW OpenDeviceAnalogData()) { POSITION pos = pli->m_fns.GetHeadPosition(); for (int i = 0; i < _countof(p->DisplayName) && pos; i++) { p->DisplayName[i] = pli->m_fns.GetNext(pos); diff --git a/src/mpc-hc/SettingsDefines.h b/src/mpc-hc/SettingsDefines.h index ceee6e56d2b..21e50fa1335 100644 --- a/src/mpc-hc/SettingsDefines.h +++ b/src/mpc-hc/SettingsDefines.h @@ -233,11 +233,13 @@ #define IDS_RS_DEFAULT_CAPTURE _T("DefaultCapture") #define IDS_R_CAPTURE _T("Capture") +#define IDS_RS_ENABLE_ANALOGCAPTURE _T("EnableAnalogCapture") #define IDS_RS_VIDEO_DISP_NAME _T("VidDispName") #define IDS_RS_AUDIO_DISP_NAME _T("AudDispName") #define IDS_RS_COUNTRY _T("Country") #define IDS_R_DVB _T("DVBConfiguration") +#define IDS_RS_ENABLE_DVB _T("EnableDVB") #define IDS_RS_BDA_NETWORKPROVIDER _T("BDANetworkProvider") #define IDS_RS_BDA_TUNER _T("BDATuner") #define IDS_RS_BDA_RECEIVER _T("BDAReceiver") @@ -252,6 +254,8 @@ #define IDS_RS_DVB_NEXTCHANNELCOUNT _T("NextChannelCount") #define IDS_RS_DVB_REBUILD_FG _T("RebuildFilterGraph") #define IDS_RS_DVB_STOP_FG _T("StopFilterGraph") +#define IDS_RS_ENABLE_IPTV _T("EnableIPTV") +#define IDS_RS_USE_IGMPMEMBERSHIP _T("UseIGMP_Membership") #define IDS_RS_D3D9RENDERDEVICE _T("D3D9RenderDevice") diff --git a/src/mpc-hc/TVToolsDlg.cpp b/src/mpc-hc/TVToolsDlg.cpp index 0021dd1bc4d..16748a8783a 100644 --- a/src/mpc-hc/TVToolsDlg.cpp +++ b/src/mpc-hc/TVToolsDlg.cpp @@ -45,10 +45,24 @@ CTVToolsDlg::~CTVToolsDlg() BOOL CTVToolsDlg::OnInitDialog() { + const auto& s = AfxGetAppSettings(); CDialog::OnInitDialog(); - m_TabCtrl.InsertItem(0, ResStr(IDS_DTV_DVB_SCAN)); - m_TabCtrl.InsertItem(1, ResStr(IDS_DTV_IPTV_SCAN)); + m_Tab_scan[0] = SC_NONE; + m_Tab_scan[1] = SC_NONE; + int i = 0; + + if (s.bEnabledDVB && s.strBDATuner != _T("")) { + m_TabCtrl.InsertItem(i, ResStr(IDS_DTV_DVB_SCAN)); + m_Tab_scan[i] = SC_DVB; + i++; + } + + if (s.bEnabledIPTV) { + m_TabCtrl.InsertItem(i, ResStr(IDS_DTV_IPTV_SCAN)); + m_Tab_scan[i] = SC_IPTV; + i++; + } SetTab(0); return TRUE; @@ -93,25 +107,47 @@ HRESULT CTVToolsDlg::SetTab(int iTabNumber) switch (iTabNumber) { case 0: - if (m_IPTVScanDlg) { - m_IPTVScanDlg.ShowWindow(SW_HIDE); - } - if (!m_TunerScanDlg) { - m_TunerScanDlg.Create(IDD_TUNER_SCAN, this); + if (m_Tab_scan[iTabNumber] == SC_DVB) { + if (m_IPTVScanDlg) { + m_IPTVScanDlg.ShowWindow(SW_HIDE); + } + if (!m_TunerScanDlg) { + m_TunerScanDlg.Create(IDD_TUNER_SCAN, this); + } + m_TunerScanDlg.ShowWindow(SW_SHOWNORMAL); + m_TunerScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); + } else if (m_Tab_scan[iTabNumber] == SC_IPTV) { + if (m_TunerScanDlg) { + m_TunerScanDlg.ShowWindow(SW_HIDE); + } + if (!m_IPTVScanDlg) { + m_IPTVScanDlg.Create(IDD_IPTV_SCAN, this); + } + m_IPTVScanDlg.ShowWindow(SW_SHOWNORMAL); + m_IPTVScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); } - m_TunerScanDlg.ShowWindow(SW_SHOWNORMAL); - m_TunerScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); break; case 1: - if (m_TunerScanDlg) { - m_TunerScanDlg.ShowWindow(SW_HIDE); - } - if (!m_IPTVScanDlg) { - m_IPTVScanDlg.Create(IDD_IPTV_SCAN, this); + if (m_Tab_scan[iTabNumber] == SC_IPTV) { + if (m_TunerScanDlg) { + m_TunerScanDlg.ShowWindow(SW_HIDE); + } + if (!m_IPTVScanDlg) { + m_IPTVScanDlg.Create(IDD_IPTV_SCAN, this); + } + m_IPTVScanDlg.ShowWindow(SW_SHOWNORMAL); + m_IPTVScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); + } else if (m_Tab_scan[iTabNumber] == SC_DVB) { + if (m_IPTVScanDlg) { + m_IPTVScanDlg.ShowWindow(SW_HIDE); + } + if (!m_TunerScanDlg) { + m_TunerScanDlg.Create(IDD_TUNER_SCAN, this); + } + m_TunerScanDlg.ShowWindow(SW_SHOWNORMAL); + m_TunerScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); } - m_IPTVScanDlg.ShowWindow(SW_SHOWNORMAL); - m_IPTVScanDlg.MoveWindow(iPosX0, iPosY0, iPosX1, iPosY1); break; diff --git a/src/mpc-hc/TunerScanDlg.cpp b/src/mpc-hc/TunerScanDlg.cpp index 2bcf57c3337..1b084b1b86e 100644 --- a/src/mpc-hc/TunerScanDlg.cpp +++ b/src/mpc-hc/TunerScanDlg.cpp @@ -113,11 +113,17 @@ BEGIN_MESSAGE_MAP(CTunerScanDlg, CDialog) ON_BN_CLICKED(ID_SAVE, &CTunerScanDlg::OnBnClickedSave) ON_BN_CLICKED(ID_START, &CTunerScanDlg::OnBnClickedStart) ON_BN_CLICKED(IDCANCEL, &CTunerScanDlg::OnBnClickedCancel) + ON_BN_CLICKED(IDC_CHECK_REMOVE_CHANNELS, OnUpdateData) ON_BN_CLICKED(IDC_CHECK_OFFSET, &CTunerScanDlg::OnBnClickedCheckOffset) END_MESSAGE_MAP() // CTunerScanDlg message handlers +void CTunerScanDlg::OnUpdateData() +{ + UpdateData(true); +} + void CTunerScanDlg::OnBnClickedSave() { auto& DVBChannels = AfxGetAppSettings().m_DVBChannels; @@ -125,10 +131,11 @@ void CTunerScanDlg::OnBnClickedSave() CAppSettings& s = AfxGetAppSettings(); int iChannel = 0; - UpdateData(); if (m_bRemoveChannels) { // Remove only DVB Channels - auto it = std::remove_if(std::begin(DVBChannels), std::end(DVBChannels), IsChannelDVB); + auto new_end = std::remove_if(std::begin(DVBChannels), std::end(DVBChannels), IsChannelDVB); + DVBChannels.erase(new_end, DVBChannels.end()); + s.nNextChannelCount = 0; } for (int i = 0; i < m_ChannelList.GetItemCount(); i++) { diff --git a/src/mpc-hc/TunerScanDlg.h b/src/mpc-hc/TunerScanDlg.h index 9185b772852..77991d77dd5 100644 --- a/src/mpc-hc/TunerScanDlg.h +++ b/src/mpc-hc/TunerScanDlg.h @@ -66,7 +66,7 @@ class CTunerScanDlg : public CDialog afx_msg LRESULT OnScanEnd(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnStats(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnNewChannel(WPARAM wParam, LPARAM lParam); - + afx_msg void OnUpdateData(); afx_msg void OnBnClickedCheckOffset(); afx_msg void OnBnClickedSave(); afx_msg void OnBnClickedStart(); diff --git a/src/mpc-hc/WebClientSocket.cpp b/src/mpc-hc/WebClientSocket.cpp index c7f4bf8f2ea..2140b0b5189 100644 --- a/src/mpc-hc/WebClientSocket.cpp +++ b/src/mpc-hc/WebClientSocket.cpp @@ -979,7 +979,7 @@ static CStringA GetChannelsJSON(const std::vector& channels) bool CWebClientSocket::OnDVBChannels(CStringA& hdr, CStringA& body, CStringA& mime) { - if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_TV) { mime = "application/json"; body = GetChannelsJSON(AfxGetAppSettings().m_DVBChannels); } else { @@ -996,7 +996,7 @@ bool CWebClientSocket::OnDVBSetChannel(CStringA& hdr, CStringA& body, CStringA& { CString requestParam; int channelIdx; - if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_CAPTURE) { + if (m_pMainFrame->GetPlaybackMode() == PM_DIGITAL_TV) { // the 'idx' GET parameter should contain a valid integer of the // channel to switch to. if (m_get.Lookup("idx", requestParam) diff --git a/src/mpc-hc/mpc-hc.rc b/src/mpc-hc/mpc-hc.rc index fd343b75e59..5473d5334bd 100644 --- a/src/mpc-hc/mpc-hc.rc +++ b/src/mpc-hc/mpc-hc.rc @@ -906,29 +906,41 @@ IDD_PPAGECAPTURE DIALOGEX 0, 0, 296, 241 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - GROUPBOX "Default Device",IDC_STATIC,5,5,286,24 - CONTROL "Analog",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | WS_GROUP,91,17,55,8 - CONTROL "Digital",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,150,17,55,8 - GROUPBOX "Analog settings",IDC_STATIC,5,33,286,59 + CONTROL "Enable analog capture device",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,12,280,8 + GROUPBOX "",IDC_STATIC,5,27,286,68 + LTEXT "Analog settings", IDC_STATIC4, 10, 34, 280, 8 LTEXT "Video",IDC_STATIC1,10,47,74,8 COMBOBOX IDC_COMBO1,84,45,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "Audio",IDC_STATIC2,10,62,74,8 COMBOBOX IDC_COMBO2,84,60,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP LTEXT "Country",IDC_STATIC3,10,77,74,8 COMBOBOX IDC_COMBO9,84,75,202,102,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Digital settings (BDA)",IDC_STATIC,5,96,286,141 - LTEXT "Network Provider",IDC_STATIC4,10,110,74,8 - COMBOBOX IDC_COMBO4,84,108,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Tuner",IDC_STATIC5,10,125,74,8 - COMBOBOX IDC_COMBO5,84,123,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Receiver",IDC_STATIC6,10,140,74,8 - COMBOBOX IDC_COMBO3,84,138,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel switching approach:",IDC_PPAGECAPTURE_ST10,10,158,260,8 - LTEXT "Rebuild filter graph",IDC_PPAGECAPTURE_ST11,10,172,74,8 - EDITTEXT IDC_PPAGECAPTURE_DESC1,84,184,202,20,ES_MULTILINE | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP - COMBOBOX IDC_COMBO6,84,170,201,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Stop filter graph",IDC_PPAGECAPTURE_ST12,10,206,74,8 - COMBOBOX IDC_COMBO7,84,204,201,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + END + +IDD_PPAGEDIGITALTV DIALOGEX 0, 0, 296, 241 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Enable DVB",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,12,280,8 + GROUPBOX "",IDC_STATIC,5,24,286,139 + LTEXT "DVB settings (BDA)", IDC_STATIC2, 10, 30, 280, 8 + LTEXT "Network Provider",IDC_STATIC4,10,45,74,8 + COMBOBOX IDC_COMBO4,84,43,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Tuner",IDC_STATIC5,10,60,74,8 + COMBOBOX IDC_COMBO5,84,58,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Receiver",IDC_STATIC6,10,75,74,8 + COMBOBOX IDC_COMBO3,84,73,202,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Channel switching approach:",IDC_PPAGECAPTURE_ST10,10,93,260,8 + LTEXT "Rebuild filter graph",IDC_PPAGECAPTURE_ST11,10,107,74,8 + EDITTEXT IDC_PPAGECAPTURE_DESC1,84,119,202,20,ES_MULTILINE | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP + COMBOBOX IDC_COMBO6,84,105,201,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Stop filter graph",IDC_PPAGECAPTURE_ST12,10,141,74,8 + COMBOBOX IDC_COMBO7,84,139,201,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + CONTROL "Enable IPTV",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,178,280,8 + GROUPBOX "",IDC_STATIC1,5,191,286,42 + LTEXT "IPTV settings", IDC_STATIC3, 10, 198, 280, 8 + CONTROL "Let the player manage IGMP membership (only for multicast)",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,212,280,8 END IDD_PPAGESYNC DIALOGEX 0, 0, 296, 241 @@ -990,14 +1002,14 @@ BEGIN LTEXT "s",IDC_STATIC2,267,199,19,8 END -IDD_NAVIGATION_DLG DIALOGEX 0, 0, 93, 68 +IDD_NAVIGATION_DLG DIALOGEX 0, 0, 95, 68 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LISTBOX IDC_LISTCHANNELS,3,15,87,32,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Info",IDC_NAVIGATION_INFO,3,51,40,14,WS_DISABLED - PUSHBUTTON "Tools",IDC_NAVIGATION_SCAN,51,51,40,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,3,1,87,14 + LISTBOX IDC_LISTCHANNELS,2,15,92,32,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Info",IDC_NAVIGATION_INFO,2,51,40,14,WS_DISABLED + PUSHBUTTON "Tools",IDC_NAVIGATION_SCAN,53,51,40,14 + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,2,1,93,14 END IDD_PPAGESUBMISC DIALOGEX 0, 0, 296, 241 @@ -1290,6 +1302,12 @@ BEGIN VERTGUIDE, 10 END + IDD_PPAGEDIGITALTV, DIALOG + BEGIN + VERTGUIDE, 10 + VERTGUIDE, 84 + END + IDD_PPAGEFULLSCREEN, DIALOG BEGIN VERTGUIDE, 235 @@ -2363,6 +2381,7 @@ BEGIN IDD_PPAGEMISC "Miscellaneous" IDD_FILEMEDIAINFO "MediaInfo" IDD_PPAGECAPTURE "Playback::Capture" + IDD_PPAGEDIGITALTV "Playback::Digital TV" IDD_PPAGESYNC "Playback::Sync Renderer Settings" IDD_PPAGEFULLSCREEN "Playback::Fullscreen" END @@ -2695,6 +2714,7 @@ END STRINGTABLE BEGIN IDS_AG_OPEN_DEVICE "Open Device" + IDS_AG_OPEN_DIGITALTV "Open Digital TV" IDS_AG_SAVE_AS "Save As" IDS_AG_SAVE_IMAGE "Save Image" IDS_MPLAYERC_6 "Save Image (auto)" diff --git a/src/mpc-hc/mpc-hc.vcxproj b/src/mpc-hc/mpc-hc.vcxproj index c0cfa8eb753..de459a15f21 100644 --- a/src/mpc-hc/mpc-hc.vcxproj +++ b/src/mpc-hc/mpc-hc.vcxproj @@ -338,6 +338,7 @@ + @@ -381,6 +382,7 @@ + @@ -479,6 +481,7 @@ + @@ -518,6 +521,7 @@ + diff --git a/src/mpc-hc/mpc-hc.vcxproj.filters b/src/mpc-hc/mpc-hc.vcxproj.filters index 54ab1932843..bb34a610792 100644 --- a/src/mpc-hc/mpc-hc.vcxproj.filters +++ b/src/mpc-hc/mpc-hc.vcxproj.filters @@ -399,6 +399,12 @@ Source Files + + Resource Files + + + Source Files + @@ -809,6 +815,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/src/mpc-hc/mplayerc.h b/src/mpc-hc/mplayerc.h index 7cf8918d916..32b651e9114 100644 --- a/src/mpc-hc/mplayerc.h +++ b/src/mpc-hc/mplayerc.h @@ -76,7 +76,8 @@ enum { WM_TUNER_STATS, WM_TUNER_NEW_CHANNEL, WM_DVB_EIT_DATA_READY, - WM_DTV_SETCHANNEL + WM_DTV_SETCHANNEL, + WM_DTV_REFRESHSETTINGS }; enum ControlType { diff --git a/src/mpc-hc/resource.h b/src/mpc-hc/resource.h index 9766104cadd..4e3deec9d49 100644 --- a/src/mpc-hc/resource.h +++ b/src/mpc-hc/resource.h @@ -342,6 +342,7 @@ #define IDD_PPAGESYNC 10055 #define IDD_PPAGEFULLSCREEN 10056 #define IDD_RFS_FILELIST_EXT 10057 +#define IDD_PPAGEDIGITALTV 10058 #define IDC_COMBO1 11000 #define IDC_COMBO2 11001 #define IDC_COMBO3 11002