📄 sdpparser.cpp
字号:
#include "SdpParser.h"
#include "StrOperation.h"
#include <ctype.h>
#define CSDP_BUFFER_SIZE 10240
void TestSdpParser()
{
FILE *sdpFile = fopen("e:\\movies\\test01.sdp", "rb");
if(sdpFile == NULL)
return;
int nFileSize =
fseek(sdpFile,0,SEEK_END);
nFileSize = ftell(sdpFile);
char *pBuf = new char[nFileSize];
memset(pBuf, 0, nFileSize);
fseek(sdpFile, 0, SEEK_SET);
fread(pBuf, 1, nFileSize, sdpFile);
CSdpParser sdpParser;
sdpParser.SetAndParser(string(pBuf, nFileSize));
string sdp = sdpParser.GetSdp();
// printf("\n%s\n", sdp.c_str());
delete [] pBuf;
fclose(sdpFile);
}
//////////////////////////////////////////////////////////////////////////
void CSdpLineItem::SetAndParserALine(const string& strALine)
{
if(strALine.empty())
return;
m_strKey = strALine[0];
if(m_strKey == "a" ||
m_strKey == "k")
{
m_hasAttribute = TRUE;
}
else
{
m_hasAttribute = FALSE;
}
int nPos = 0;
if(m_hasAttribute)
{
m_strAttribute = CStrOperate::GetKeyValue(strALine, "=", ":", nPos);
nPos = 0;
m_strValue = CStrOperate::GetKeyValue(strALine, ":", "\r\n", nPos);
}
else
{
nPos = 0;
m_strValue = CStrOperate::GetKeyValue(strALine, "=", "\r\n", nPos);
}
}
string& CSdpLineItem::GetAndSetKey(const string strKey/*=""*/)
{
if(!strKey.empty())
m_strKey = strKey;
return m_strKey;
}
string& CSdpLineItem::GetAndSetAttribute(const string strAttr/* ="" */)
{
if(!strAttr.empty())
{
m_hasAttribute = TRUE;
m_strAttribute = strAttr;
}
return m_strAttribute;
}
string& CSdpLineItem::GetAndSetValue(const string strVal/* ="" */)
{
if(!strVal.empty())
m_strValue = strVal;
return m_strValue;
}
string CSdpLineItem::GetThisLine()
{
string tmp;
tmp = m_strKey + "=";
if(m_hasAttribute)
{
tmp += m_strAttribute + ":";
}
tmp += m_strValue + "\r\n";
return tmp;
}
Bool CSdpLineItem::operator == (const CSdpLineItem& other)
{
if(m_strKey == other.m_strKey)
{
if(m_hasAttribute == TRUE && other.m_hasAttribute == TRUE)
{
if(m_strAttribute == other.m_strAttribute)
return TRUE;
}
else if(m_hasAttribute == FALSE && other.m_hasAttribute == FALSE)
return TRUE;
else
return FALSE;
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////////
CSdpMediaAnnounceItem::~CSdpMediaAnnounceItem()
{
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
delete *it;
*it = NULL;
}
}
void CSdpMediaAnnounceItem::AddALine(CSdpLineItem* pLineItem)
{
if(pLineItem != NULL)
{
if( pLineItem->GetAndSetKey() == "m" )
{
// GET THE PAYLOAD
// m=<media> <port> <transport> <fmt list>
char cBuff1[50]; UInt32 fmt=0xFFFFFFFF;
memset(cBuff1,0,sizeof(cBuff1));
const char* pValue = pLineItem->GetAndSetValue().c_str();
sscanf(pValue,"%s %s %s %u",cBuff1,cBuff1,cBuff1,&fmt);
m_uiPayload = fmt;
}
m_vecLines.push_back(pLineItem);
}
}
void CSdpMediaAnnounceItem::AddAline(const string& strLine)
{
CSdpLineItem *pLineItem = new CSdpLineItem;
pLineItem->SetAndParserALine(strLine);
AddALine(pLineItem);
}
string CSdpMediaAnnounceItem::GetMediaAnnouce()
{
string tmp;
vector<CSdpLineItem*>::iterator it;
CSdpLineItem *pLineItem = NULL;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pLineItem = *it;
tmp += pLineItem->GetThisLine();
}
return tmp;
}
void CSdpMediaAnnounceItem::ModifyALine(const string& strLine)
{
CSdpLineItem *pNewItem = new CSdpLineItem;
pNewItem->SetAndParserALine(strLine);
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(*pItem == *pNewItem)
{
pItem->GetAndSetValue(pNewItem->GetAndSetValue());
delete pNewItem;
pNewItem = NULL;
return;
}
}
m_vecLines.push_back(pNewItem);
}
UInt32 CSdpMediaAnnounceItem::GetTrackID()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "control")
{
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "TrackID=", " ", nPos);
break;
}
}
return atol(tmpStr.c_str());
}
string CSdpMediaAnnounceItem::GetMediaType()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "m")
{
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "", " ", nPos);
break;
}
}
return tmpStr;
}
UInt32 CSdpMediaAnnounceItem::GetTimeScale()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "rtpmap")
{
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "/", "/", nPos);
break;
}
}
return atol(tmpStr.c_str());
}
UInt16 CSdpMediaAnnounceItem::GetDestPort()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "m")
{
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), " ", " ", nPos);
break;
}
}
return atol(tmpStr.c_str());
}
// added by samsmith
string CSdpParser::GetGeneralDestIP()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "c")
{
char ip[32];UInt16 ttl;
memset(ip,0,sizeof(ip));
ParserConnectData(pItem->GetAndSetValue().c_str(),ip,&ttl);
tmpStr = ip;
break;
}
}
return tmpStr;
}
string CSdpMediaAnnounceItem::GetDestIP(unsigned short *v_ttl)
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "c")
{
char ip[32];UInt16 ttl;
memset(ip,0,sizeof(ip));
ParserConnectData(pItem->GetAndSetValue().c_str(),ip,&ttl);
tmpStr = ip;
*v_ttl = ttl;
break;
}
}
return tmpStr;
}
bool ParserConnectData(const char* item,char *v_ip,unsigned short *v_ttl)
{
char cBuff1[50],cBuff2[50];
memset(cBuff1,0,sizeof(cBuff1));
memset(cBuff2,0,sizeof(cBuff2));
sscanf(item,"%s %s %s",cBuff1,cBuff1,cBuff2);
char *p;
p=::strchr(cBuff2,'/');
if( p== NULL)
{
::strcpy(v_ip,cBuff2);
*v_ttl=0;
}
else {
::strncpy(v_ip,cBuff2,p-cBuff2);
v_ip[p-cBuff2]=0;
unsigned int ttl=0;
sscanf(p+1,"%u",&ttl);
*v_ttl = (unsigned short)ttl;
}
return TRUE;
}
// end
string CSdpMediaAnnounceItem::GetDestIP()
{
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
vector<CSdpLineItem*>::iterator it;
for(it=m_vecLines.begin(); it!=m_vecLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "c")
{
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "IN IP4 ", "/", nPos);
break;
}
}
return tmpStr;
}
//////////////////////////////////////////////////////////////////////////
void CSdpParser::Reset()
{
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
// for test modify by samsmith
CSdpLineItem* pItem = *it;
delete pItem;
*it = NULL;
}
// m_mtxSdpParser.Lock();
m_vecGeneralLines.clear();
// m_mtxSdpParser.Unlock();
vector<CSdpMediaAnnounceItem*>::iterator it2;
for(it2=m_vecMediaAnnounces.begin(); it2!=m_vecMediaAnnounces.end(); ++it2)
{
delete *it2;
*it2 = NULL;
}
m_vecMediaAnnounces.clear();
}
CSdpParser::~CSdpParser()
{
Reset();
}
Bool CSdpParser::SetAndParserFromFile(const string& strFileName)
{
if(CStrOperate::GetExtName(strFileName) != "sdp")
return FALSE;
FILE *File=fopen(strFileName.c_str(),"rb");
//Assert( File > 0 );
if(File == NULL)
{
return FALSE;
}
//char cBuff[CSDP_BUFFER_SIZE];
char *pBuff = new char [CSDP_BUFFER_SIZE];
if(!pBuff)
{
fclose(File);
return FALSE;
}
memset(pBuff, 0, CSDP_BUFFER_SIZE);
UInt32 iLen=fread(pBuff,CSDP_BUFFER_SIZE,1,File);
if(iLen ==0) iLen=ftell(File);
fclose(File);
// add by samsmith
//SetAndParser(pBuff);
std::string strConvert( pBuff );
CStrOperate::ConvertUnixToDos(strConvert);
delete[] pBuff;
SetAndParser(strConvert);
// end
return TRUE;
}
void CSdpParser::SetAndParser(const string& strSdp)
{
if(strSdp.empty())
return;
list<CSdpLineItem*> lstSdpLines;
CSdpLineItem *pLineItem = NULL;
string strLine;
int nBeginPos = 0;
string strLineEndMark = "\r\n";
do
{
strLine = CStrOperate::GetKeyValue(strSdp, "", strLineEndMark, nBeginPos);
nBeginPos += strLineEndMark.size();
if(!strLine.empty())
{
pLineItem = new CSdpLineItem;
if(pLineItem == NULL)
break;
pLineItem->SetAndParserALine(strLine);
lstSdpLines.push_back(pLineItem);
}
}while (!strLine.empty());
list<CSdpLineItem*>::iterator lstIt = lstSdpLines.begin();
while(lstIt != lstSdpLines.end())
{
pLineItem = *lstIt;
if(pLineItem->GetAndSetKey() != "m")
{
// m_mtxSdpParser.Lock();
m_vecGeneralLines.push_back(pLineItem);
// m_mtxSdpParser.Unlock();
lstSdpLines.pop_front();
// printf("G:%s\n", pLineItem->GetAndSetValue().c_str());
}
else
{
break;
}
lstIt = lstSdpLines.begin();
}
CSdpMediaAnnounceItem *pMediaItem = NULL;
while(!lstSdpLines.empty())
{
lstIt = lstSdpLines.begin();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -