This repository has been archived by the owner on May 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Digital TV: new Digital TV options, split from analog capture options
1. General - Split menu entry into: Open Digital TV / Open Analog Capture. File->Open Device now only refers to analog device - Split class OpenDeviceData into OpenDeviceAnalogData and OpenDeviceDigitalData - Channel navigation panel: only enabled tabs visible (depending on Digital TV options). Set initial active tab depending on current channel type. - Add IGMP membership management: manage IGMP group join/leave for multicast IPTV streaming sources. Supports only IPv4 and IGMPv2. IPv6 and IGMPv3 could be added in the future if needed. - Add shortcut for Digital TV 2. Exception handling: - error controls (checking devices, etc.) moved from the general entry point to each channel switch operation - Change current behavior: when error switching to a channel -> show error message in info bar and then stay ready for switching to another channel - If the IPTV switching channel operation fails, we don't change the window size 3. Options & preferences: - Split Digital TV options from analog capture - New Digital TV options: DVB (BDA) and IPTV (include option: enable/disable IGMP multicast membership management)
- Loading branch information
Showing
28 changed files
with
1,174 additions
and
443 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#include "stdafx.h" | ||
#include <afxmt.h> | ||
#include "IPTVMcastTools.h" | ||
#include <winsock2.h> | ||
#include <Ws2tcpip.h> | ||
#include <mswsock.h> | ||
|
||
#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)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
#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); | ||
|
||
}; | ||
|
Oops, something went wrong.