分析如下RTSP函数的流程,并指明哪里实际发送了数据包
int TPSendRtpQueueCb(trans_session_desc_t *desc, trans_stream_t *stream)
{
RTPDATAFRAME *p_frame = NULL;
TPRTSPSERVERSESSION *pSession = NULL;
TPRTPPACKAGE *ptr_rtp_package = NULL;
int iSessionID = 0;
int sendmute = 0;
unsigned char mutebuf[RTP_MAX_PACKET_SIZE] = {0};
unsigned char RTPextern[RTP_MAX_EXTEN_LEN + 1] = {0};
unsigned char pucPrefix[RTP_PREFIX_SIZE] = {0};
int externtionlen = 0;
unsigned long cur_time = 0;
struct iovec iov[RTP_MAX_SEND_NUM * 3];
int ret = 0;
RETRY_INFO *p_retry_info = NULL;
RETRY_INFO tmp_retry_info = {0};
unsigned long long ullCurrentTime = 0;
RETURN_VALUE_IF(!desc || !desc->send_data || !desc->priv || !stream->package, 0); p_frame = (RTPDATAFRAME *)desc->send_data; pSession = (TPRTSPSERVERSESSION *)desc->priv; ptr_rtp_package = (TPRTPPACKAGE )stream->package; / 可能底层给的数据是错的,这里就可能出现打包异常,增加一个防护机制 */ RETURN_VALUE_IF(!p_frame->rtp_head_pos || !p_frame->rtp_payload_pos, 0); if(pSession->pRTPServer->bIsRunning != 1) { return 0; } if (pSession->iAudioVideo == RTSP_AUDIO) { pSession->getIFrame = 1; } if (pSession->iAudioVideo == RTSP_META_DATA) { pSession->getIFrame = 1; } if ( ptr_rtp_package->av_codec >= TP_ENCODE_TYPE_AUDIO_MIN && ptr_rtp_package->av_codec <= TP_ENCODE_TYPE_AUDIO_MAX) { iSessionID = RTP_SESSION_AUDIO; }
#ifdef RTSP_USE_SMART_DATA
else if (TP_ENCODE_TYPE_VIDEO_SMART == ptr_rtp_package->av_codec)
{
iSessionID = RTP_SESSION_SMART_DATA;
}
#endif
else if (TP_ENCODE_TYPE_VIDEO_META == ptr_rtp_package->av_codec)
{
iSessionID = RTP_SESSION_META_DATA;
}
else if (TP_ENCODE_TYPE_VIDEO_SMART != ptr_rtp_package->av_codec)
{
iSessionID = RTP_SESSION_VIDEO;
}
//回放数据流中同时有音频与视频数据,onvif回放会出现只拉取音频/视频的操作,此处判断过虑不需要的数据,防止空指针引用 if (pSession->pRTPServer == NULL || pSession->pRTPServer->pSessions[iSessionID] == NULL) { return 0; } if (pSession->iSessionState == TPHTTP_SESSION_STATE_PLAYING && pSession->iCurStreamID == TPRTP_STREAM_ID_ONVIF_REPLAY && ptr_rtp_package->DataFrame.iExtension && pSession->end_time > 0 && pSession->end_time <= (ptr_rtp_package->DataFrame.RTPHeaderExtension.piAddr[0] - SECS_FROM_1900_TO_1970)) { pSession->iSessionState = TPHTTP_SESSION_STATE_PAUSE; pSession->start_time = -1; trans_pause(&pSession->vedio_desc); } p_retry_info = (iSessionID == RTP_SESSION_AUDIO) ? &pSession->audio_retry_info : &pSession->video_retry_info; if (iSessionID != RTP_SESSION_AUDIO && iSessionID != RTP_SESSION_VIDEO) { p_retry_info = &tmp_retry_info; } //没收到I帧数据的话其他的数据丢掉 if ((!pSession->getIFrame && (!ptr_rtp_package->is_iframe || !ptr_rtp_package->is_first_rtp || p_retry_info->retry_flag)) && pSession->iStreamType != TPRTP_STREAM_TYPE_VIDEO_JPEG) { p_retry_info->send_pos = 0; p_retry_info->retry_flag = 0; return 0; } if (!pSession->getIFrame && pSession->ulFirstVideoRTPTS == 0) { pSession->ulFirstVideoRTPTS = (unsigned long)ptr_rtp_package->curPTS; } else if (pSession->getIFrame && pSession->ulFirstAudioRTPTS == 0 && iSessionID == RTP_SESSION_AUDIO) { pSession->ulFirstAudioRTPTS = (unsigned long)ptr_rtp_package->curPTS; }
#ifdef RTSP_USE_SMART_DATA
else if (pSession->getIFrame && pSession->ulFirstSmartRTPTS == 0 && iSessionID == RTP_SESSION_SMART_DATA)
{
pSession->ulFirstSmartRTPTS = (unsigned long)ptr_rtp_package->curPTS;
}
#endif
else if (pSession->getIFrame && pSession->ulFirstSmartRTPTS == 0 && iSessionID == RTP_SESSION_META_DATA)
{
pSession->ulFirstSmartRTPTS = (unsigned long)ptr_rtp_package->curPTS;
}
pSession->getIFrame = 1; rtsp_send_notify(pSession);
#ifdef TAPO_USE_RTSP_MULTITRANS
//流控
if (pSession->start_time != -1 && pSession->windowsize != 0 && pSession->stream_seq - pSession->recv_size > pSession->windowsize)
{
set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len);
p_retry_info->send_pos = 0;
return RTSP_SEND_RETRY;
}
#endif
/* 如果音频或视频流没有传输完,则不能交叉传输,需要将剩余数据发完,其他流走重传流程 */ if ((pSession->video_retry_info.send_pos != 0 && iSessionID != RTP_SESSION_VIDEO) || (pSession->audio_retry_info.send_pos != 0 && iSessionID != RTP_SESSION_AUDIO)) { set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len); p_retry_info->sn = p_frame->iSN;
// RTSP_ERROR(“cannot send all data send retry, client ip:%s, dump socket:%d”, pSession->pcClientIP, pSession->iSock);
// tcp_dump_info(pSession->iSock);
return RTSP_SEND_RETRY;
}
#ifdef TAPO_USE_RTSP_MULTITRANS
//半双工时有语音数据时不发送音频数据
if (RTSPGetMute() == 1 && iSessionID == RTP_SESSION_AUDIO)
{
sendmute = 1;
}
#endif
if (ptr_rtp_package->av_codec != TP_ENCODE_TYPE_UNDET && iSessionID == RTP_SESSION_VIDEO) { char codestr[TEMP_FORMAT_LEN]; if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_VIDEO_H264) snprintf(codestr, TEMP_FORMAT_LEN, “H264”); else if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_VIDEO_H265) snprintf(codestr, TEMP_FORMAT_LEN, “H265”); else if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_SNAPSHOT_JPEG) { snprintf(codestr, TEMP_FORMAT_LEN, “JPEG”); } else { return 0; } if (strcmp(pSession->SDPServer.SDPInfo.MediaInfo.pcVideoFormat, codestr) != 0) { snprintf(pSession->SDPServer.SDPInfo.MediaInfo.pcVideoFormat, 16, codestr);
#ifdef TAPO_USE_RTSP_MULTITRANS
RTSPSessionNotificationResChange(pSession, “HD”);
#endif
}
}
#ifdef TAPO_USE_RTSP_MULTITRANS
/* 仅当multitrans时 */
if (MULTITRANS_NONE != pSession->multitrans_business_type && iSessionID == RTP_SESSION_AUDIO)
{
char codestr[TEMP_FORMAT_LEN];
if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_AUDIO_G711A)
snprintf(codestr, TEMP_FORMAT_LEN, “PCMA”);
else if (ptr_rtp_package->av_codec == TP_ENCODE_TYPE_AUDIO_G711U)
snprintf(codestr, TEMP_FORMAT_LEN, “PCMU”);
else
return 0;
if (strcmp(pSession->SDPServer.SDPInfo.MediaInfo.pcAudioFormat, codestr) != 0)
{
snprintf(pSession->SDPServer.SDPInfo.MediaInfo.pcAudioFormat, 16, codestr);
RTSPSessionNotificationResChange(pSession, “HD”);
}
}
#endif
if(RTP4SIsMulticast(pSession->pRTPServer) && p_frame->multicast_send == 1) { return 0; } else if(RTP4SIsMulticast(pSession->pRTPServer)) { p_frame->multicast_send = 1; } if ((iSessionID == RTP_SESSION_AUDIO || iSessionID == RTP_SESSION_VIDEO)) { if (p_retry_info->send_pos > 0) { if (iSessionID == RTP_SESSION_AUDIO) { pSession->usCurAudioRTPSN = p_retry_info->sn; p_frame->iSN = pSession->usCurAudioRTPSN++; } else { pSession->usCurVideoRTPSN = p_retry_info->sn; p_frame->iSN = pSession->usCurVideoRTPSN++; } RtspPutUshortToBufBE((unsigned char *)p_frame->rtp_head_pos + 2, p_frame->iSN); } else { if (iSessionID == RTP_SESSION_AUDIO) { p_frame->iSN = pSession->usCurAudioRTPSN++; } else { p_frame->iSN = pSession->usCurVideoRTPSN++; } RtspPutUshortToBufBE((unsigned char *)p_frame->rtp_head_pos + 2, p_frame->iSN); } } RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 8, pSession->pRTPServer->pSessions[iSessionID]->iClientSSRC); RtspGetUintFromBufBE((unsigned char *)p_frame->rtp_head_pos + 4, (unsigned int *)&cur_time); RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4, cur_time - ((iSessionID == RTP_SESSION_VIDEO) ? pSession->ulFirstVideoRTPTS : pSession->ulFirstAudioRTPTS));
#ifdef RTSP_USE_SMART_DATA
if (RTP_SESSION_SMART_DATA == iSessionID)
{
RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4,
cur_time - pSession->ulFirstSmartRTPTS );
}
#endif
if (RTP_SESSION_META_DATA == iSessionID) { RtspPutUintToBufBE((unsigned char )p_frame->rtp_head_pos + 4, cur_time - pSession->ulFirstSmartRTPTS ); }
#ifdef TAPO_USE_RTSP_MULTITRANS
if (ptr_rtp_package->is_first_rtp && pSession->multitrans_business_type != MULTITRANS_NONE)
{
/ I帧 */
if(ptr_rtp_package->is_iframe == 1)
{
*(p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT;
/* 只解码I帧 / if (ptr_rtp_package->is_decode_only == 1) { externtionlen = RtspAddExtention(RTPextern, ptr_rtp_package->utc_time, RTP_EXTEN_DECODE_ONLY_BIT); } / 普通I帧 / else { externtionlen = RtspAddExtention(RTPextern, ptr_rtp_package->utc_time, RTP_EXTEN_I_FRAME_BIT); } } / 虚拟I帧 */ else if (ptr_rtp_package->is_virtual_iframe == 1) { *(p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT; externtionlen = RtspAddExtention(RTPextern, ptr_rtp_package->utc_time, RTP_EXTEN_VIRTUAL_FRAME_BIT); } }
#endif
/* TP NVR虚拟I帧的RTP包要包含扩展字段 */ if (pSession->bIsVirtualIFrameEnabled && ptr_rtp_package->is_virtual_iframe == 1
#ifdef TAPO_USE_RTSP_MULTITRANS
&& pSession->multitrans_business_type == MULTITRANS_NONE
#endif
)
{
*(p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT;
externtionlen = RtspAddAvbrExtention(RTPextern);
}
int need_encrypt = pSession->bIsRTPSessionCrypto[iSessionID] && (iSessionID!=RTP_SESSION_VIDEO || (ptr_rtp_package->is_iframe && pSession->rtp_send_data_index < SRTP_ENCRYPT_RTP_NUM)); // 标识加密的情况 if (pSession->bIsRTPSessionCrypto[iSessionID] == 1 && iSessionID != RTP_SESSION_SMART_DATA) { if ( (ptr_rtp_package->is_iframe && pSession->rtp_send_data_index < SRTP_ENCRYPT_RTP_NUM) || iSessionID == RTP_SESSION_AUDIO) { (p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT; externtionlen = RtspAddSrtpExtention(RTPextern); } } if (iSessionID == RTP_SESSION_SMART_DATA) { //common_version为0,表示这是不支持SRTP 2.0的NVR客户端,需要按照SRTP 1.0的方式对智能数据帧进行全部加密 //判断RTP包索引,如果相等则表示当前RTP需要加密 if(pSession->common_version == 0 || (g_smart_data_is_first_rtp_set == 1 && g_smart_data_rtp_index[smart_data_rtp_index] == pSession->rtp_send_data_index)) { (p_frame->rtp_head_pos) |= RTP_HEADER_EXTENTION_BIT; externtionlen = RtspAddSrtpExtention(RTPextern); smart_data_rtp_index = (smart_data_rtp_index + 1) % 10; need_encrypt = 1; } else { need_encrypt = 0; } } if(pSession->bRTPOverTCP) { int rtp_length = p_frame->rtp_head_len + p_frame->rtp_payload_len + externtionlen; if (need_encrypt) { rtp_length += SRTP_TAG_SIZE; } int send_count = 0; int expectlen = 0; int rtp_cur_index = pSession->rtp_send_data_index; int i = 0; pucPrefix[0] = ‘$’; pucPrefix[1] = pSession->piTCPDataID[iSessionID]; pucPrefix[2] = rtp_length >> 8; pucPrefix[3] = rtp_length & 0xff; iov[send_count].iov_base = pucPrefix; iov[send_count++].iov_len = 4; int fu_header_len = p_frame->rtp_head_len - RTP_HEADER_SIZE; if (externtionlen > 0) { iov[send_count].iov_base = p_frame->rtp_head_pos; iov[send_count++].iov_len = RTP_HEADER_SIZE; iov[send_count].iov_base = RTPextern; iov[send_count++].iov_len = externtionlen; if(fu_header_len > 0) { // 如果没有加密则把fu放在header中 if (!need_encrypt) { iov[send_count].iov_base = p_frame->rtp_head_pos + RTP_HEADER_SIZE; iov[send_count++].iov_len = fu_header_len; } } } else { iov[send_count].iov_base = p_frame->rtp_head_pos; iov[send_count++].iov_len = need_encrypt ? RTP_HEADER_SIZE : p_frame->rtp_head_len; } iov[send_count].iov_base = sendmute ? mutebuf : p_frame->rtp_payload_pos; iov[send_count++].iov_len = p_frame->rtp_payload_len; pSession->rtp_send_data[rtp_cur_index].rtp_head_size = 0; for (i = 0; i < send_count - 1; i ++) { memcpy(pSession->rtp_send_data[rtp_cur_index].rtp_header_data + pSession->rtp_send_data[rtp_cur_index].rtp_head_size, iov[i].iov_base, iov[i].iov_len); pSession->rtp_send_data[rtp_cur_index].rtp_head_size += iov[i].iov_len; } if (need_encrypt) { // 重传不需要再次分配内存加密 if (!p_retry_info->send_pos) { // 如果有fu,则需要填充到payload前面,这里把fu和payload拼起来放在加密后的地址,原地加密 unsigned char cur_encrypted_pos = pSession->encrypted_pos+rtp_cur_indexRTP_MAX_PACKET_SIZE; if (fu_header_len > 0) { memcpy(cur_encrypted_pos, p_frame->rtp_head_pos+RTP_HEADER_SIZE, fu_header_len); memcpy(cur_encrypted_pos + fu_header_len, p_frame->rtp_payload_pos, p_frame->rtp_payload_len); if (0 != SRTPEncrypt(&pSession->cryptoCtx, cur_encrypted_pos, cur_encrypted_pos, p_frame->rtp_payload_len + fu_header_len, p_frame->iSN)) { RTSP_ERROR(“SRTP encrypt failed, go to next frame”); return 0; } } else { if (0 != SRTPEncrypt(&pSession->cryptoCtx, cur_encrypted_pos, p_frame->rtp_payload_pos, p_frame->rtp_payload_len, p_frame->iSN)) { RTSP_ERROR(“SRTP encrypt failed, go to next frame”); return 0; } } pSession->rtp_send_data[rtp_cur_index].rtp_encrypted_payload_pos = cur_encrypted_pos; pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos = iov[i].iov_base; pSession->rtp_send_data[rtp_cur_index].rtp_playload_size = iov[i].iov_len; pSession->rtp_send_data[rtp_cur_index].rtp_encryped_payload_size = iov[i].iov_len + fu_header_len; //生成auth tag unsigned int total_len = pSession->rtp_send_data[rtp_cur_index].rtp_head_size + pSession->rtp_send_data[rtp_cur_index].rtp_encryped_payload_size; memset(pSession->auth_mem, 0, (RTP_MAX_PACKET_SIZE2)); memcpy(pSession->auth_mem, pSession->rtp_send_data[rtp_cur_index].rtp_header_data, pSession->rtp_send_data[rtp_cur_index].rtp_head_size); memcpy(pSession->auth_mem + pSession->rtp_send_data[rtp_cur_index].rtp_head_size, pSession->rtp_send_data[rtp_cur_index].rtp_encrypted_payload_pos, pSession->rtp_send_data[rtp_cur_index].rtp_encryped_payload_size); if (0 != SRTPAuthenticate(&pSession->cryptoCtx, p_frame->rtp_auth_tag, pSession->auth_mem, total_len, p_frame->iSN)) { RTSP_ERROR(“SRTP authenticate failed, go to next frame”); return 0; } memcpy(pSession->rtp_send_data[rtp_cur_index].rtp_auth_tag, p_frame->rtp_auth_tag, SRTP_TAG_SIZE); pSession->rtp_send_data[rtp_cur_index].rtp_tag_size = SRTP_TAG_SIZE; } } else { pSession->rtp_send_data[rtp_cur_index].rtp_playload_pos = iov[i].iov_base; pSession->rtp_send_data[rtp_cur_index].rtp_playload_size = iov[i].iov_len; } pSession->rtp_send_data_index++; /还原设置的拓展标记,避免对其他会话的影响/ if((p_frame->rtp_head_pos) & RTP_HEADER_EXTENTION_BIT) { *(p_frame->rtp_head_pos) &= ~RTP_HEADER_EXTENTION_BIT; } RtspPutUintToBufBE((unsigned char )p_frame->rtp_head_pos + 4, cur_time); if (pSession->rtp_send_data_index >= RTP_MAX_SEND_NUM || desc->frame_end
#ifdef SUPPORT_WEBSOCK_EX_HEADER
|| pSession->wsp_status != NOT_WSP_PROTO
#endif
)
{
/ 如果是重传,则他有一个起始pos,不是packet index,而是一个发送的数据量 */
int send_pos = p_retry_info->send_pos;
int iov_index = 0;
int left_size = 0;
int send_len = 0;
int rtp_index = 0;
expectlen = 0;
if (send_pos > 0) { while (send_pos >= send_len) { if (rtp_index >= RTP_MAX_SEND_NUM) { RTSP_ERROR(“invalid rtp_index, array out of bounds”); return TP_TCP_EC_FAILURE; } if (pSession->rtp_send_data[rtp_index].rtp_tag_size == SRTP_TAG_SIZE) // encrypted packet { send_len += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size + pSession->rtp_send_data[rtp_index].rtp_tag_size); rtp_index++; } else { send_len += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_playload_size); rtp_index++; } } rtp_index–; left_size = send_len - send_pos; int encrypted = pSession->rtp_send_data[rtp_index].rtp_tag_size == SRTP_TAG_SIZE; // 根据tag size判断rtp是否加密 if (encrypted == 1) { if (left_size > pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size + pSession->rtp_send_data[rtp_index].rtp_tag_size) { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data + (pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size + pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_tag_size - left_size); iov[iov_index++].iov_len = left_size - pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size - pSession->rtp_send_data[rtp_index].rtp_tag_size; expectlen += (left_size - pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size - pSession->rtp_send_data[rtp_index].rtp_tag_size); iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_encrypted_payload_pos; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size; expectlen += pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size; iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_auth_tag; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_tag_size; expectlen += pSession->rtp_send_data[rtp_index].rtp_tag_size; } else if (left_size > pSession->rtp_send_data[rtp_index].rtp_tag_size) { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_encrypted_payload_pos + (pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size + pSession->rtp_send_data[rtp_index].rtp_tag_size - left_size); iov[iov_index++].iov_len = left_size - pSession->rtp_send_data[rtp_index].rtp_tag_size; expectlen += (left_size - pSession->rtp_send_data[rtp_index].rtp_tag_size); iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_auth_tag; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_tag_size; expectlen += pSession->rtp_send_data[rtp_index].rtp_tag_size; } else { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_auth_tag + pSession->rtp_send_data[rtp_index].rtp_tag_size - left_size; iov[iov_index++].iov_len = left_size; expectlen += left_size; } rtp_index++; } else { if (left_size > pSession->rtp_send_data[rtp_index].rtp_playload_size) { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data + (pSession->rtp_send_data[rtp_index].rtp_playload_size + pSession->rtp_send_data[rtp_index].rtp_head_size - left_size); iov[iov_index++].iov_len = left_size - pSession->rtp_send_data[rtp_index].rtp_playload_size; expectlen += left_size - pSession->rtp_send_data[rtp_index].rtp_playload_size; left_size = pSession->rtp_send_data[rtp_index].rtp_playload_size; } iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_playload_pos + pSession->rtp_send_data[rtp_index].rtp_playload_size - left_size; iov[iov_index++].iov_len = left_size; expectlen += left_size; rtp_index++; } } for (; rtp_index < pSession->rtp_send_data_index; rtp_index++) { int encrypted = pSession->rtp_send_data[rtp_index].rtp_tag_size == SRTP_TAG_SIZE; if (encrypted == 1) { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_head_size; iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_encrypted_payload_pos; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size; iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_auth_tag; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_tag_size; expectlen += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_encryped_payload_size + pSession->rtp_send_data[rtp_index].rtp_tag_size); } else { iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_header_data; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_head_size; iov[iov_index].iov_base = pSession->rtp_send_data[rtp_index].rtp_playload_pos; iov[iov_index++].iov_len = pSession->rtp_send_data[rtp_index].rtp_playload_size; expectlen += (pSession->rtp_send_data[rtp_index].rtp_head_size + pSession->rtp_send_data[rtp_index].rtp_playload_size); } } if(iSessionID == RTP_SESSION_SMART_DATA) { RTSP_DEBUG(“start send smart data”); } ret = RTSPSessionSendV(pSession, iov, iov_index); if (ret == TP_TCP_EC_FAILURE && iSessionID != RTP_SESSION_SMART_DATA) { pSession->pRTPServer->iRTPStatus = RTP_STATUS_SEND_FAILURE; set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len); p_retry_info->send_pos = 0; p_retry_info->sn = p_frame->iSN; pSession->rtp_send_data_index–; return TP_TCP_EC_FAILURE; } else if(ret != expectlen && iSessionID != RTP_SESSION_SMART_DATA) // 接收方缓冲区满了,发不出去了 { set_retry_info(p_retry_info, ptr_rtp_package, p_frame->rtp_payload_len); // 会把sn记录成暂时不用的payloadCTX中的sn,下面手动更新成p_frame中的sn p_retry_info->send_pos += ret > 0 ? ret : 0; p_retry_info->sn = p_frame->iSN; pSession->rtp_send_data_index–; ullCurrentTime = tpgetboottime(); pSession->send_retry_times++; g_tel_rtsp_retry_cnt++; if (pSession->ullTimeForSendRetry == 0 || pSession->ullTimeForSendRetry + SEND_RETRY_PRINT_TIMEOUT < ullCurrentTime) { RTSP_ERROR(“cannot send all data send retry, client ip:%s, dump socket:%d, send_retry_times:%d, already send:%d, expect send:%d”, pSession->pcClientIP, pSession->iSock, pSession->send_retry_times, ret, expectlen); tcp_dump_info(pSession->iSock); pSession->ullTimeForSendRetry = ullCurrentTime; pSession->send_retry_times = 0;
#ifdef TELEMETRY_SUPPORT
TELEMETRY_RTSP telemetry_rtsp;
memset(&telemetry_rtsp, 0, sizeof(telemetry_rtsp));
ds_read(TELEMETRY_RTSP_PATH, &telemetry_rtsp, sizeof(TELEMETRY_RTSP));
telemetry_rtsp.rtsp_retry_count = g_tel_rtsp_retry_cnt;
ds_write(TELEMETRY_RTSP_PATH, &telemetry_rtsp, sizeof(TELEMETRY_RTSP));
#endif
}
return RTSP_SEND_RETRY; } if(iSessionID == RTP_SESSION_SMART_DATA) { if(ret < 0) { RTSP_DEBUG(“send smart data return error %d”,ret); } else if(ret != expectlen) { RTSP_DEBUG(“send part of smart data”); } else { RTSP_DEBUG(“send smart data successfully”); } } if (desc->frame_end) {
#ifdef TAPO_USE_RTSP_MULTITRANS
if (pSession->start_time != -1 && pSession->stream_seq % 25 == 0) //回放需要有流控
{
RTSPSendMultitransSeq(pSession); } pSession->stream_seq ++;
#endif
} if(iSessionID == RTP_SESSION_SMART_DATA) { if(desc->frame_end) { g_smart_data_is_first_rtp_set = 1; } else { g_smart_data_is_first_rtp_set = 0; } } desc->frame_end = 0; memset(pSession->rtp_send_data, 0, sizeof(RTPSENDDATA) * RTP_MAX_SEND_NUM); pSession->rtp_send_data_index = 0; smart_data_rtp_index = 0; p_retry_info->send_pos = 0; if (pSession->send_retry_times > 0) { ullCurrentTime = tpgetboottime(); if (pSession->ullTimeForSendRetry + SEND_RETRY_PRINT_TIMEOUT < ullCurrentTime) { RTSP_ERROR(“send retry %d times, client ip:%s,”, pSession->send_retry_times, pSession->pcClientIP); pSession->ullTimeForSendRetry = 0; pSession->send_retry_times = 0; } } } } else { MBUFFERByteArray mBuffer; unsigned char TXBufferMemSpace[TPRTSPSERVER_BUFFER_SIZE] = {0}; MBUFFERByteArrayInit(TXBufferMemSpace, 0, 0, TPRTSPSERVER_BUFFER_SIZE - 4, &mBuffer); MBUFFERByteArrayReset(&mBuffer); int fu_header_len = p_frame->rtp_head_len - RTP_HEADER_SIZE; if (pSession->bIsCrypto) { MBUFFERByteArrayPutMultiUCharBE((unsigned char )p_frame->rtp_head_pos, RTP_HEADER_SIZE, &mBuffer); if(externtionlen > 0) { MBUFFERByteArrayPutMultiUCharBE(RTPextern, externtionlen, &mBuffer); } if (fu_header_len > 0) { memcpy(pSession->encrypted_pos, p_frame->rtp_head_pos + RTP_HEADER_SIZE, fu_header_len); memcpy(pSession->encrypted_pos + fu_header_len, p_frame->rtp_payload_pos, p_frame->rtp_payload_len); } else { memcpy(pSession->encrypted_pos, p_frame->rtp_payload_pos, p_frame->rtp_payload_len); } if (0 != SRTPEncrypt(&pSession->cryptoCtx, pSession->encrypted_pos, pSession->encrypted_pos, p_frame->rtp_payload_len + fu_header_len, p_frame->iSN)) { RTSP_ERROR(“SRTP encrypt failed, go to next frame”); return 0; } // fu 已经考虑在内 unsigned int total_len = p_frame->rtp_head_len + externtionlen + p_frame->rtp_payload_len; memset(pSession->auth_mem, 0, (RTP_MAX_PACKET_SIZE2)); memcpy(pSession->auth_mem, p_frame->rtp_head_pos, p_frame->rtp_head_len); if(externtionlen > 0) { memcpy(pSession->auth_mem + p_frame->rtp_head_len, RTPextern, externtionlen); } // put encrypted payload and auth tag in buffer memcpy(pSession->auth_mem + p_frame->rtp_head_len + externtionlen, pSession->encrypted_pos, p_frame->rtp_payload_len); if (0 != SRTPAuthenticate(&pSession->cryptoCtx, p_frame->rtp_auth_tag, pSession->auth_mem, total_len, p_frame->iSN)) { RTSP_ERROR(“SRTP authenticate failed, go to next frame”); return 0; } MBUFFERByteArrayPutMultiUCharBE(sendmute ? mutebuf : pSession->encrypted_pos, p_frame->rtp_payload_len + fu_header_len, &mBuffer); MBUFFERByteArrayPutMultiUCharBE(p_frame->rtp_auth_tag, SRTP_TAG_SIZE, &mBuffer); } else { if(externtionlen > 0) { MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos, RTP_HEADER_SIZE, &mBuffer); MBUFFERByteArrayPutMultiUCharBE(RTPextern, externtionlen, &mBuffer); if (fu_header_len > 0) { MBUFFERByteArrayPutMultiUCharBE((unsigned char *)p_frame->rtp_head_pos + RTP_HEADER_SIZE, fu_header_len, &mBuffer); } } else { MBUFFERByteArrayPutMultiUCharBE((unsigned char )p_frame->rtp_head_pos, p_frame->rtp_head_len, &mBuffer); } MBUFFERByteArrayPutMultiUCharBE(sendmute ? mutebuf : p_frame->rtp_payload_pos, p_frame->rtp_payload_len, &mBuffer); } MBUFFERByteConvert2ReadBuff(&mBuffer); TPUdpSendByBuffer(pSession->pRTPServer->pSessions[iSessionID]->DataServer, &mBuffer); /还原设置的拓展标记,避免对其他会话的影响/ if((p_frame->rtp_head_pos) & RTP_HEADER_EXTENTION_BIT) { *(p_frame->rtp_head_pos) &= ~RTP_HEADER_EXTENTION_BIT; } RtspPutUintToBufBE((unsigned char *)p_frame->rtp_head_pos + 4, cur_time); } reset_retry_info(p_retry_info, ptr_rtp_package); p_retry_info->sn = p_frame->iSN; return 0;
}
最新发布