live555是採用c++寫的輕量級流媒體庫,我這裏僅採用此庫處理RTSP請求,發送音視頻流在庫外部做。
視頻RTP組包代碼
u_int8_t frame_header[4];
if (m_init == 0) {
srandom(time(NULL));
m_seq_no = (u_int16_t)random();
m_ssrc = (u_int32_t)random();
m_init = 1;
}
int data_len = 0;
frame_header[0] = '$';
frame_header[1] = 0;
frame_header[2] = (u_int8_t)(((segm_len + 12) & 0xFF00) >> 8);
frame_header[3] = (u_int8_t)((segm_len + 12) & 0xFF);
memcpy(pData, frame_header, 4);
data_len += 4;
u_int32_t n_rtp_header;
u_int32_t rtp_header = 0x80000000;
if (streamHead.nStreamDataLen<1444)
{
rtp_header |= (224 << 16); // marker 1
}
else
{
rtp_header |= (96 << 16);
}
rtp_header |= m_seq_no;
n_rtp_header = htonl(rtp_header);
memcpy(pData + data_len, &n_rtp_header, 4);
data_len += 4;
u_int32_t n_send_time;
u_int32_t send_time = 90000 * pack_tv.tv_sec;
send_time += (u_int32_t)(90000 * (pack_tv.tv_usec / 1000000.0) + 0.5);
n_send_time = htonl(send_time);
memcpy(pData + data_len, &n_send_time, 4);
data_len += 4;
u_int32_t n_ssrc;
n_ssrc = htonl(m_ssrc);
memcpy(pData + data_len, &n_ssrc, 4);
data_len += 4;
if (65535==m_seq_no)
{
m_seq_no=0;
}
else
{
m_seq_no++;
}
音頻 RTP 組包
pData[0] = '$';
pData[1] = 2;
pData[2] = (u_int8_t)(((streamHead.nStreamDataLen+ 12) & 0xFF00) >> 8);
pData[3] = (u_int8_t)((streamHead.nStreamDataLen + 12) & 0xFF);
RTP_FIXED_HEADER* rtp_hdr =(RTP_FIXED_HEADER*)&pData[4];
memset(rtp_hdr,0,sizeof(RTP_FIXED_HEADER)); // this is very important
rtp_hdr->payload = 0;
rtp_hdr->version = 2;
rtp_hdr->extension = 0;
rtp_hdr->marker = 1;
rtp_hdr->ssrc = htonl(10); // it's unique in a rtp session, set 10 here
if (65535==m_audioSeqNum)
{
rtp_hdr->seq_no = htons(m_audioSeqNum);
m_audioSeqNum=0;
}
else
{
rtp_hdr->seq_no = htons(m_audioSeqNum ++);
}
m_audioTsCurrent= m_audioTsCurrent+m_audioTimestamp_increse;
rtp_hdr->timestamp=htonl(m_audioTsCurrent);