//---------------------------------------------------------------------------
#include <stdio.h>
#include "rtspLinker.h"
//---------------------------------------------------------------------------
int GetHostByNameFuc(char *pcDDNS, char *pcIP);
//---------------------------------------------------------------------------
const unsigned long RECV_BUF_SIZE = 204800;
const unsigned long UNIT_TIMEOUT_MSEC = 100;
rtspLinker::rtspLinker()
:m_sRtspSkt(INVALID_SOCKET), m_sVideoSkt(INVALID_SOCKET), m_sAudioSkt(INVALID_SOCKET),
m_ulPort(0), m_ulVideoPort(0), m_ulAudioPort(0),
m_eProtoType(ptTCP), m_bAudioEnabled(true),
m_ulTimeOut(3000), m_ulReconnectInter(5000), m_ulFrameBufSize(10),
m_usSeqNum(0), m_bStartup(true), m_bTerminate(false),
m_hProcHandle(NULL), m_hAudioProcHandle(NULL)
{
m_hHeap = GetProcessHeap();
*m_pcIP = '\0';
*m_pcUrlPath = '\0';
*m_pcSession = '\0';
*m_pcVideoTrack = '\0';
*m_pcAudioTrack = '\0';
InitializeCriticalSection(&m_csVideoListLock);
InitializeCriticalSection(&m_csAudioListLock);
InitializeCriticalSection(&m_csBufferPoolLock);
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR)
MessageBox(NULL, "WSAStartup() failed !", "rtspLinker::Error", MB_OK);
GetHostByNameFuc("ddns.camddns.com", m_pcSelfDDNSServerIP);
GetHostByNameFuc("ddns2.ydsdvr.com", m_pcSelfDDNSServerIP2);
}
rtspLinker::~rtspLinker()
{
WSACleanup();
DeleteCriticalSection(&m_csVideoListLock);
DeleteCriticalSection(&m_csAudioListLock);
DeleteCriticalSection(&m_csBufferPoolLock);
}
void rtspLinker::SetLinker(char *pcIP, unsigned long ulPort)
{
strcpy(m_pcIP, pcIP);
m_ulPort = ulPort;
char pcRealIP[64];
if(GetHostByNameFuc(m_pcIP, pcRealIP) == NO_ANY_ERROR)
{
//若是公司的 DDNS,要用網頁的方式,取得 IP 及 port 值
if(strcmp(pcRealIP, m_pcSelfDDNSServerIP) == 0 || strcmp(pcRealIP, m_pcSelfDDNSServerIP2) == 0)
{
SOCKET sSocket = socket(AF_INET,SOCK_STREAM,0);
if(sSocket != INVALID_SOCKET)
{
struct sockaddr_in siServerSockaddr;
memset(&siServerSockaddr,0,sizeof(sockaddr_in));
siServerSockaddr.sin_family = AF_INET;
siServerSockaddr.sin_addr.s_addr = inet_addr(pcRealIP);
siServerSockaddr.sin_port = htons(m_ulPort);
if(connect(sSocket, (const struct sockaddr *)&siServerSockaddr, sizeof(sockaddr_in)) == 0)
{
char pcCmd[1024];
sprintf(pcCmd, "GET / HTTP/1.1\r\nHost:%s\r\n\r\n", m_pcIP);
if( send(sSocket, pcCmd, strlen(pcCmd), 0) > 0 )
{
memset(pcCmd, 0, 1024);
if( recv(sSocket, pcCmd, 1024, 0) > 0 )
{
//檢查是否已取得真實的 IP,是則離開
char *pcFind = strstr(pcCmd, "Location: http://");
if(pcFind != NULL)
{
char *pcFindEnd = strstr(pcFind, "/\r\n");
if(pcFindEnd != NULL)
{
memcpy(pcIP, pcFind+17, pcFindEnd-pcFind-17);
*(m_pcIP+(pcFindEnd-pcFind-17)) = '\0';
pcFindEnd = strstr(m_pcIP, ":");
if(pcFindEnd != NULL)
{
m_ulPort = atoi(pcFindEnd+1);
*pcFindEnd = '\0';
}
}
}
}
}
CloseSocket(&sSocket);
}
}
}
else
{
strcpy(m_pcIP, pcRealIP);
}
}
}
void rtspLinker::SetProtocol(enum PROTOCOL_TYPE eType)
{
m_eProtoType = eType;
}
void rtspLinker::SetUrlPath(char *pcUrl)
{
sprintf(m_pcUrlPath, "%s%s", (*pcUrl=='/')?"":"/", pcUrl);
}
void rtspLinker::SetAudioEnabled(bool bEnabled)
{
m_bAudioEnabled = bEnabled;
}
void rtspLinker::SetTimeOut(unsigned long ulTimeOut)
{
m_ulTimeOut = ulTimeOut;
}
void rtspLinker::SetReconnectInterval(unsigned long ulInterval)
{
m_ulReconnectInter = ulInterval;
}
void rtspLinker::SetFrameBufferSize(unsigned long ulSize)
{
m_ulFrameBufSize = ulSize;
}
void rtspLinker::Connect()
{
if(m_hProcHandle || m_hAudioProcHandle)
{
Disconnect();
}
m_bStartup = true;
m_bTerminate = false;
*m_pcSession = '\0';
*m_pcVideoTrack = '\0';
*m_pcAudioTrack = '\0';
m_DataQueue.Resize(0);
m_usSeqNum = 0;
m_hProcHandle = CreateThread(NULL, 0, MainProc, this, 0, NULL);
if(m_bAudioEnabled && m_eProtoType == ptUDP)
m_hAudioProcHandle = CreateThread(NULL, 0, AudioProc, this, 0, NULL);
}
void rtspLinker::Disconnect()
{
m_bTerminate = true;
if(m_sRtspSkt != INVALID_SOCKET)
{
char pcCmd[1024];
memset(pcCmd, 0, 1024);
sprintf(pcCmd, "TEARDOWN rtsp://%s%s RTSP/1.0\r\nSession: %s\r\nCSeq: %d\r\n\r\n",
m_pcIP, m_pcUrlPath, m_pcSession, m_usSeqNum++);
send(m_sRtspSkt,pcCmd,strlen(pcCmd),0);
memset(pcCmd, 0, 1024);
RecvResponse(m_sRtspSkt, (unsigned char *)pcCmd, 1024, m_ulTimeOut);
}
CloseSocket(&m_sRtspSkt);
CloseSocket(&m_sVideoSkt);
CloseSocket(&m_sAudioSkt);
if(m_hProcHandle)
{
DWORD dwRetValue = 0;
do
{
Sleep(3);
GetExitCodeThread(m_hProcHandle, &dwRetValue);
}while(dwRetValue != ERR_TERMINATED);
CloseHandle(m_hProcHandle);
m_hProcHandle = NULL;
}
if(m_hAudioProcHandle)
{
DWORD dwRetValue = 0;
do
{
Sleep(3);
GetExitCodeThread(m_hAudioProcHandle, &dwRetValue);
}while(dwRetValue != ERR_TERMINATED);
CloseHandle(m_hAudioProcHandle);
m_hAudioProcHandle = NULL;
}
EnterCriticalSection(&m_csVideoListLock);
while(!m_VideoList.empty())
{
ReturnFrame(&m_VideoList.front()->m_pBufPtr);
m_VideoList.pop_front();
}
LeaveCriticalSection(&m_csVideoListLock);
EnterCriticalSection(&m_csAudioListLock);
while(!m_AudioList.empty())
{
ReturnFrame(&m_AudioList.front()->m_pBufPtr);
m_AudioList.pop_front();
}
LeaveCriticalSection(&m_csAudioListLock);
std::set<void*>::iterator itPos;
EnterCriticalSection(&m_csBufferPoolLock);
bool bEmpty = m_BufferPool.empty();
LeaveCriticalSection(&m_csBufferPoolLock);
while(!bEmpty)
{
EnterCriticalSection(&m_csBufferPoolLock);
void *pVoid = *m_BufferPool.begin();
LeaveCriticalSection(&m_c
评论3
最新资源