📄 sdpparser.cpp
字号:
pLineItem = *lstIt;
if(pLineItem->GetAndSetKey() == "m")
{
pMediaItem = new CSdpMediaAnnounceItem;
if(pMediaItem ==NULL)
break;
m_vecMediaAnnounces.push_back(pMediaItem);
pMediaItem->AddALine(pLineItem);
lstSdpLines.pop_front();
// printf("M:%s\n", pLineItem->GetAndSetValue().c_str());
}
else
{
break;
}
lstIt = lstSdpLines.begin();
while(lstIt != lstSdpLines.end())
{
pLineItem = *lstIt;
if(pLineItem->GetAndSetKey() != "m")
{
pMediaItem->AddALine(pLineItem);
lstSdpLines.pop_front();
// printf("M:%s\n", pLineItem->GetAndSetValue().c_str());
}
else
{
break;
}
lstIt = lstSdpLines.begin();
}
}
// 建立具有相同PAYLOAD的流
vector<CSdpMediaAnnounceItem*>::iterator it2,it1;
CSdpMediaAnnounceItem *pItem1 = 0,*pItem2 = 0;
for(it2=m_vecMediaAnnounces.begin(); it2!=m_vecMediaAnnounces.end(); ++it2)
{
pItem2 = (*it2);
for(it1=m_vecMediaAnnounces.begin(); it1!=m_vecMediaAnnounces.end(); ++it1)
{
pItem1 = (*it1);
if( pItem1 == pItem2 ) //
{
continue;
}
else if( pItem1->GetPayload() == pItem2->GetPayload() )
{
pItem1->SetSamePayload(TRUE,pItem2->GetTrackID());
}
}
}
}
void CSdpParser::ProduceRMSdp()
{
// 针对RM的SDP的特殊性,如果是VOD,那么需要从MEDIA 域里面获取RANGE值, 并修改SESSEION 域里面有RANGE项
CSdpLineItem *pItem3 = NULL;
ITEM_LIST::iterator it3;
Float32 rangeStart = -1,rangeEnd = -1;
std::string outTime;
for(it3=m_vecGeneralLines.begin(); it3!=m_vecGeneralLines.end(); ++it3)
{
Bool bFoundRangeInMedia= FALSE;
pItem3 = *it3;
if(pItem3->GetAndSetKey() == "a" && pItem3->GetAndSetAttribute() == "range")
{
GetRange(outTime,rangeStart,rangeEnd); // 获得全局域中的RANGE
vector<CSdpMediaAnnounceItem*>::iterator itMedia;
CSdpMediaAnnounceItem *pItemMedia = 0;
for(itMedia=m_vecMediaAnnounces.begin(); itMedia!=m_vecMediaAnnounces.end(); ++itMedia)
{
pItemMedia = (*itMedia);
Float32 start=0,end=0;
Bool bFound = pItemMedia->GetRange(outTime,start,end); // 获得MEDIA域中的RANGE
if( bFound && start < rangeStart )
rangeStart = start; // 使rangeStart是所有RANGE域最小值
if( bFound && end > rangeEnd )
rangeEnd = end;
bFoundRangeInMedia= TRUE;
}
if( bFoundRangeInMedia )
{
char cRange[128];memset(cRange,0,sizeof(cRange));
sprintf( cRange,"a=range:npt=%f-%f",rangeStart,rangeEnd);
std::string strRange(cRange);
RemoveALine( "a","range");
AddALine(strRange);
}
}
}
}
string CSdpParser::GetSdp()
{
string strTmp;
ITEM_LIST::iterator itg;
CSdpLineItem *pLineItem = NULL;
for(itg=m_vecGeneralLines.begin(); itg!=m_vecGeneralLines.end(); ++itg)
{
pLineItem = *itg;
string tmp = pLineItem->GetThisLine();
strTmp += tmp;
}
// printf("GGGG:%s\n\n", strTmp.c_str());
vector<CSdpMediaAnnounceItem*>::iterator itm;
for(itm=m_vecMediaAnnounces.begin(); itm!=m_vecMediaAnnounces.end(); ++itm)
{
//get mediaAbnnouncement
strTmp += (*itm)->GetMediaAnnouce();
}
return strTmp;
}
// modify/add TrackID for Rstp protocol
void CSdpParser::ModifyTrackID()
{
CSdpMediaAnnounceItem *pItem = NULL;
UInt32 nTrackID;
char tmpBuf[8];
string strMediaType;
for(Int32 i=0; i<GetTrackNum(); i++)
{
pItem = GetMediaAnnounceItem(i);
string strMediaType = pItem->GetMediaType();
if(strMediaType == "video")
{
nTrackID = 1;
}
else if(strMediaType == "audio")
{
nTrackID = 2;
}
else
{
continue;
}
sprintf(tmpBuf, "%d", nTrackID);
string strControl = string("a=control:trackID=") + tmpBuf;
pItem->ModifyALine(strControl);
}
}
// added by samsmith --- only for ip4
// add a=control:*/r/n line to general session
Bool CSdpParser::AddGeneralControl()
{
string tmpStr;
CSdpLineItem *pItem = NULL;
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a") // find the connect data line in general session
{
if( strcmp(pItem->GetAndSetAttribute().c_str(),"control")==0 )
{
if( strcmp(pItem->GetAndSetValue().c_str(),"*" )==0 )
{
return TRUE;
}
}
}
}
CSdpLineItem *pLineItem = new CSdpLineItem;
if(pLineItem == NULL)
return FALSE;
pLineItem->GetAndSetKey("a");
pLineItem->GetAndSetAttribute("control");
pLineItem->GetAndSetValue("*");
pLineItem->SetHasAttribute(TRUE);
// m_mtxSdpParser.Lock();
m_vecGeneralLines.push_back(pLineItem);
// m_mtxSdpParser.Unlock();
return TRUE;
}
void CSdpParser::RemoveRMSdpRange()
{
RemoveALine( "a","range");
vector<CSdpMediaAnnounceItem*>::iterator itMedia;
CSdpMediaAnnounceItem *pItemMedia = 0;
for(itMedia=m_vecMediaAnnounces.begin(); itMedia!=m_vecMediaAnnounces.end(); ++itMedia)
{
pItemMedia = (*itMedia);
pItemMedia->RemoveALine("a","range");
}
}
void CSdpParser::ModifyRMSdpLenth(int len)
{
vector<CSdpMediaAnnounceItem*>::iterator itMedia;
CSdpMediaAnnounceItem *pItemMedia = 0;
std::string strLine = "a=length:0";
for(itMedia=m_vecMediaAnnounces.begin(); itMedia!=m_vecMediaAnnounces.end(); ++itMedia)
{
pItemMedia = (*itMedia);
pItemMedia->ModifyALine(strLine);
}
}
Bool CSdpParser::ModifyConnectIp(const string& nip)
{
string tmpStr;
CSdpLineItem *pItem = NULL;
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "c") // find the connect data line in general session
{
ModifySdpConnectIp(pItem,nip);
return TRUE;
}
}
return FALSE;
}
void ModifySdpConnectIp(CSdpLineItem* pItem,const string& nip)
{
char netType[32],IpType[32],ip[32];
memset(ip,0,sizeof(ip));memset(netType,0,sizeof(netType));memset(IpType,0,sizeof(IpType));
string tmpStr = pItem->GetAndSetValue().c_str();
sscanf(tmpStr.c_str(),"%s %s %s",netType,IpType,ip);
for(int i=0;i<strlen(IpType);i++)
{
IpType[i]= tolower(IpType[i]);
}
if( strcmp( IpType,"ip4")==0 ) // only for ip4
{
std::string newLine;
newLine += netType;newLine += " ";
newLine += IpType;newLine += " ";
newLine += nip;
UInt16 ttl;
ParserConnectData(pItem->GetAndSetValue().c_str(),ip,&ttl);
if( ttl != 0)
{
newLine += "/";
char cTtl[32];
int iTtl = (int)ttl;
sprintf(cTtl,"%d",iTtl);
newLine += cTtl;
}
// newLine += "\r\n";
pItem->GetAndSetValue(newLine);
}
}
void CSdpMediaAnnounceItem::RemoveALine(const string strKey, const string strAttribute)
{
int nPos = 0;
CSdpLineItem *pItem = NULL;
for(vector<CSdpLineItem*>::iterator it=m_vecLines.begin();it!=m_vecLines.end();++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == strKey && pItem->GetAndSetAttribute() == strAttribute)
{
delete pItem;
m_vecLines.erase(it);
break;
}
}
}
Bool CSdpMediaAnnounceItem::GetRange(string& outTimeType,Float32& vStart,Float32& vEnd)
{
Bool bFound = FALSE;
string tmpStr;
int nPos = 0;
CSdpLineItem *pItem = NULL;
Float32 fStart = 0;
Float32 fEnd = 0;
// ITEM_LIST::iterator it;
for(vector<CSdpLineItem*>::iterator it=m_vecLines.begin();it!=m_vecLines.end();++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "range")
{
outTimeType = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "", "=", nPos);
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "=", "-", nPos);
fStart = atof(tmpStr.c_str());
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "-", " ", nPos);
fEnd = atof(tmpStr.c_str());
bFound = TRUE;
break;
}
}
vStart = fStart;
vEnd = fEnd;
return bFound;
}
Bool CSdpMediaAnnounceItem::ModifyConnectIp(const string& nip)
{
CSdpLineItem *pItem = NULL;
for(vector<CSdpLineItem*>::iterator it=m_vecLines.begin();it!=m_vecLines.end();++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "c") // find the connect data line in general session
{
ModifySdpConnectIp(pItem,nip);
return TRUE;
}
}
return FALSE;
}
Bool CSdpMediaAnnounceItem::ModifyConnectPort(UInt16 nport)
{
CSdpLineItem *pItem = NULL;
for(vector<CSdpLineItem*>::iterator it=m_vecLines.begin();it!=m_vecLines.end();++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "m") // find the connect data line in general session
{
// m= <media> <port> <transport> <fmt list>
char media[32],port[32], transport[32],fmtlist[128];
memset(media,0,sizeof(media));memset(port,0,sizeof(port));
memset(fmtlist,0,sizeof(fmtlist));memset(transport,0,sizeof(transport));
string tmpStr = pItem->GetAndSetValue().c_str();
sscanf(tmpStr.c_str(),"%s %s %s %s",media,port,transport,fmtlist);
std::string newValue;
newValue += media;newValue += " ";
char cPort[32];
int iPort = (int)nport;
sprintf(cPort,"%d",iPort);
newValue += cPort;
newValue += " ";
newValue += transport;newValue += " ";
newValue += fmtlist;//newValue += " ";
pItem->GetAndSetValue(newValue);
//newValue += "\r\n";
return TRUE;
}
}
return FALSE;
}
// end;
Float32 CSdpParser::GetRange(string& outTimeType,Float32& vStart,Float32& vEnd)
{
string tmpStr;
int nPos = 0;
Float32 fStart = 0;
Float32 fEnd = 0;
CSdpLineItem *pItem = NULL;
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "range")
{
outTimeType = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "", "=", nPos);
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "=", "-", nPos);
fStart = atof(tmpStr.c_str());
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "-", " ", nPos);
fEnd = atof(tmpStr.c_str());
break;
}
}
vStart = fStart;
vEnd = fEnd;
return fEnd - fStart;
}
Float32 CSdpParser::GetRange(string& outTimeType)
{
string tmpStr;
int nPos = 0;
Float32 fStart = 0;
Float32 fEnd = 0;
CSdpLineItem *pItem = NULL;
ITEM_LIST::iterator it;
for(it=m_vecGeneralLines.begin(); it!=m_vecGeneralLines.end(); ++it)
{
pItem = *it;
if(pItem->GetAndSetKey() == "a" && pItem->GetAndSetAttribute() == "range")
{
outTimeType = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "", "=", nPos);
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "=", "-", nPos);
fStart = atof(tmpStr.c_str());
tmpStr = CStrOperate::GetKeyValue(pItem->GetAndSetValue(), "-", " ", nPos);
fEnd = atof(tmpStr.c_str());
break;
}
}
return fEnd - fStart;
}
Bool CSdpParser::AddALine(const string line)
{
CSdpLineItem *pLineItem = new CSdpLineItem;
pLineItem->SetAndParserALine(line);
// m_mtxSdpParser.Lock();
m_vecGeneralLines.push_back(pLineItem);
// m_mtxSdpParser.Unlock();
return TRUE;
}
void CSdpParser::RemoveALine(const string strKey, const string strAttribute/* ="" */)
{
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() == strKey && pItem->GetAndSetAttribute() == strAttribute)
{
delete pItem;
/// m_mtxSdpParser.Lock();
m_vecGeneralLines.erase(it);
// m_mtxSdpParser.Unlock();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
CSdpMediaAnnounceItem* CSdpParser::GetMediaAnnounceItem(const string& strMediaType)
{
CSdpMediaAnnounceItem *pMedia = NULL;
vector<CSdpMediaAnnounceItem*>::iterator it;
for(it=m_vecMediaAnnounces.begin(); it!=m_vecMediaAnnounces.end(); ++it)
{
pMedia = *it;
if(pMedia->GetMediaType() == strMediaType)
{
break;
}
}
return pMedia;
}
CSdpMediaAnnounceItem* CSdpParser::GetMediaAnnounceItem(UInt32 nIndex)
{
if(nIndex >= GetTrackNum())
return NULL;
return m_vecMediaAnnounces[nIndex];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -