⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdpparser.cpp

📁 跨操作系统的微型中间件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -