您好,登錄后才能下訂單哦!
場景
在建立RTSP連接之后,通過rtp over tcp接收視頻數據,在下面的例子中獲取到的數據流,還是存在相隔2個RTP負載的問題,但是從字節來看,RTP的負載非常小,應該對數據沒有任何的影響
說明
m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);第二個參數是真實讀取到的字節數,第三個參數是指定當前讀取多少個字節
代碼
struct RTPHeader
{
unsigned char szHeader[4];
};
unsigned short sRTPPayLoadLen = 0;//整個RTP報文的長度,由$ 0x00|0x01 后面的兩個字節決定
unsigned char cOneBytes = 0;//保存第一個字節,進行判斷是否是$,從而判斷是否是RTP負載包,還是RTSP指令包
char* pszOneBytes = (char*)&cOneBytes;//接收數據只能通過符號字符,因此采用強制轉換
int nRealReadLen = 0;//保存了每一次讀取的字節個數
int nRet = m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);//建立rtsp鏈接之后,開始讀取第一個字節
if (nRet <= 0)
{
exit(0);
}
while (true)
{
if ('$' == cOneBytes)
{
nRet = m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);
if ((nRet <= 0) || (nRet != 1)) break;
if ('$' == cOneBytes) continue;//兩個$$相連也是有可能的,重新循環
if (0x00 == cOneBytes || 0x01 == cOneBytes)//讀取到有效的數據
{
nRet = m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);//嘗試讀取高位的負載長度
if ((nRet <= 0) || (nRet != 1)) break;
if ('$' == cOneBytes) continue;
sRTPPayLoadLen = cOneBytes << 8;
if (sRTPPayLoadLen < -1 || sRTPPayLoadLen > 1500) continue;//高位有可能是0,因為有時候多個RTP只是攜帶格式信息,但是沒有攜帶數據負載
nRet = m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);//嘗試讀取低位的負載長度
if ((nRet <= 0) || (nRet != 1)) break;
//if ('$' == cOneBytes) continue;//有可能低位剛好就是24,所以這一點是不需要擔心的
sRTPPayLoadLen = sRTPPayLoadLen + cOneBytes;
if (sRTPPayLoadLen < 0 || sRTPPayLoadLen > 1500) continue;//數據不可能超過1500,局域網傳輸帶寬要求
char szRTPPayLoadContent[1500] = { 0 };
nRealReadLen = 0;
nRet = m_sock->RecvBuffer(szRTPPayLoadContent, nRealReadLen, sRTPPayLoadLen);
RTPHeader* pHeader = (RTPHeader*)szRTPPayLoadContent;
unsigned short sRTPSeq = (pHeader->szHeader[2] << 8) + pHeader->szHeader[3];
//std::cout << "curSeq:" << sRTPSeq << std::endl;
static int nLastSeq = sRTPSeq;
int nGap = sRTPSeq - nLastSeq;
if (nGap != 1)
{
std::cout << "rtp seq gap:" << nGap <<",lastSeq:"<<nLastSeq<<",curSeq:"<<sRTPSeq << std::endl;
}
nLastSeq = sRTPSeq;
//循環讀取負載的長度報文,一次可能讀取不了完整的一個RTP負載的報文
while (nRealReadLen < sRTPPayLoadLen)
{
memset(szRTPPayLoadContent, 0x00, 1500);
sRTPPayLoadLen = sRTPPayLoadLen - nRealReadLen;
nRealReadLen = 0;
nRet = m_sock->RecvBuffer(szRTPPayLoadContent, nRealReadLen, sRTPPayLoadLen);
}
}
}
nRet = m_sock->RecvBuffer(pszOneBytes, nRealReadLen, 1);
if ((nRet <= 0) || (nRet != 1)) break;
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。