📄 rtp_transmitter.cpp
字号:
if (check_frame == 0 || !((check_frame & DROP_IT) || (check_frame & IS_JUMBO))) fprintf(stderr," QUEUE"); if (check_frame & SEND_NOW) fprintf(stderr," NOW"); fprintf(stderr,"\n");#endif // RTP_DEBUG // Check and see if we should send it or drop it if (check_frame & DROP_IT) return; // Check and see if we should send the queue first if (m_audioQueueCount > 0 && (check_frame & SEND_FIRST)) { // send anything that's pending SendQueuedAudioFrames(); } // See if we have a jumbo frame if (check_frame & IS_JUMBO) { SendAudioJumboFrame(pFrame); return; } // Add frame to queue m_audioQueue[m_audioQueueCount++] = pFrame; m_audioQueueSize += pFrame->GetDataLength(); // and check to see if we want ot send it now if (check_frame & SEND_NOW) { // send anything that's pending SendQueuedAudioFrames(); } } else { // B & D 's original CRtpTransmitter::SendAudioFrame OldSendAudioFrame(pFrame); }}void CRtpTransmitter::SendQueuedAudioFrames(void){ struct iovec iov[m_audioiovMaxCount + 1]; int ix; int i = 0; CRtpDestination *rdptr; if (m_audioQueueCount == 0) { return; } u_int32_t rtpTimestamp = AudioTimestampToRtp(m_audioQueue[0]->GetTimestamp()); u_int64_t ntpTimestamp = TimestampToNtp(m_audioQueue[0]->GetTimestamp());#if RTP_DEBUG debug_message("A ts %llu rtp %u ntp %u.%u", m_audioQueue[0]->GetTimestamp(), rtpTimestamp, (u_int32_t)(ntpTimestamp >> 32), (u_int32_t)ntpTimestamp);#endif rdptr = m_audioRtpDestination; while (rdptr != NULL) { rdptr->send_rtcp(rtpTimestamp, ntpTimestamp); rdptr = rdptr->get_next(); } // moved this from below // See if we need to add the header. int iov_start = 1; int iov_add = 0; if (m_audio_set_rtp_payload != NULL) { iov_start = 0; iov_add = m_audio_set_rtp_payload(m_audioQueue, m_audioQueueCount, iov, m_audio_rtp_userdata); } else { // audio payload data for (i = 0; i < m_audioQueueCount; i++) { iov[i + 1].iov_base = m_audioQueue[i]->GetData(); iov[i + 1].iov_len = m_audioQueue[i]->GetDataLength(); } if (m_audio_set_rtp_header != NULL) { if ((m_audio_set_rtp_header)(iov, m_audioQueueCount, m_audio_rtp_userdata)) { iov_start = 0; iov_add = 1; } } } // send packet rdptr = m_audioRtpDestination; while (rdptr != NULL) { rdptr->send_iov(&iov[iov_start], iov_add + m_audioQueueCount, rtpTimestamp, 1); rdptr = rdptr->get_next(); } // delete all the pending media frames for (ix = 0; ix < m_audioQueueCount; ix++) { if (m_audioQueue[ix]->RemoveReference()) delete m_audioQueue[ix]; m_audioQueue[ix] = NULL; } m_audioQueueCount = 0; m_audioQueueSize = 0;}void CRtpTransmitter::SendAudioJumboFrame(CMediaFrame* pFrame){ u_int32_t rtpTimestamp = AudioTimestampToRtp(pFrame->GetTimestamp()); u_int64_t ntpTimestamp = TimestampToNtp(pFrame->GetTimestamp()); CRtpDestination *rdptr;#if RTP_DEBUG debug_message("A ts %llu rtp %u ntp %u.%u", pFrame->GetTimestamp(), rtpTimestamp, (u_int32_t)(ntpTimestamp >> 32), (u_int32_t)ntpTimestamp);#endif rdptr = m_audioRtpDestination; while (rdptr != NULL) { rdptr->send_rtcp(rtpTimestamp, ntpTimestamp); rdptr = rdptr->get_next(); } u_int32_t dataOffset = 0; u_int32_t spaceAvailable = m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE); struct iovec iov[2]; do { iov[1].iov_base = (u_int8_t*)pFrame->GetData() + dataOffset; int iov_start = 1, iov_hdr = 0; bool mbit; if (m_audio_set_rtp_jumbo_frame(iov, dataOffset, pFrame->GetDataLength(), spaceAvailable, mbit, m_audio_rtp_userdata)) { iov_start = 0; iov_hdr = 1; } // send packet rdptr = m_audioRtpDestination; while (rdptr != NULL) { rdptr->send_iov(&iov[iov_start], 1 + iov_hdr, rtpTimestamp, mbit); rdptr = rdptr->get_next(); } error_message("data offset %d len %d max %d", dataOffset, iov[1].iov_len, pFrame->GetDataLength()); dataOffset += iov[1].iov_len; } while (dataOffset < pFrame->GetDataLength()); if (pFrame->RemoveReference()) delete pFrame;}void CRtpTransmitter::SendMpeg4VideoWith3016(CMediaFrame* pFrame){ u_int32_t rtpTimestamp = VideoTimestampToRtp(pFrame->GetTimestamp()); u_int64_t ntpTimestamp = TimestampToNtp(pFrame->GetTimestamp()); CRtpDestination *rdptr;#if RTP_DEBUG debug_message("V ts %llu rtp %u ntp %u.%u", pFrame->GetTimestamp(), rtpTimestamp, (u_int32_t)(ntpTimestamp >> 32), (u_int32_t)ntpTimestamp);#endif // check if RTCP SR needs to be sent rdptr = m_videoRtpDestination; while (rdptr != NULL) { rdptr->send_rtcp(rtpTimestamp, ntpTimestamp); rdptr = rdptr->get_next(); } u_int8_t* pData = (u_int8_t*)pFrame->GetData(); u_int32_t bytesToSend = pFrame->GetDataLength(); struct iovec iov; while (bytesToSend) { u_int32_t payloadLength; bool lastPacket; if (bytesToSend <= m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE)) { payloadLength = bytesToSend; lastPacket = true; } else { payloadLength = m_pConfig->GetIntegerValue(CONFIG_RTP_PAYLOAD_SIZE); lastPacket = false; } iov.iov_base = pData; iov.iov_len = payloadLength; rdptr = m_videoRtpDestination; while (rdptr != NULL) { rdptr->send_iov(&iov, 1, rtpTimestamp, lastPacket); rdptr = rdptr->get_next(); } pData += payloadLength; bytesToSend -= payloadLength; } if (pFrame->RemoveReference()) delete pFrame;}void CRtpTransmitter::DoStartRtpDestination (uint32_t handle){ CRtpDestination *ptr; ptr = m_videoRtpDestination; while (ptr != NULL) { if (ptr->get_ref_num() == handle) { ptr->start(); return; } ptr = ptr->get_next(); } ptr = m_audioRtpDestination; while (ptr != NULL) { if (ptr->get_ref_num() == handle) { ptr->start(); debug_message("Starting rtp handle %d", handle); return; } ptr = ptr->get_next(); }}void CRtpTransmitter::DoStopRtpDestination (uint32_t handle){ CRtpDestination *ptr, *q; q = NULL; ptr = m_videoRtpDestination; while (ptr != NULL) { if (ptr->get_ref_num() == handle) { if (q == NULL) { m_videoRtpDestination = ptr->get_next(); } else { q->set_next(ptr->get_next()); } delete ptr; return; } q = ptr; ptr = ptr->get_next(); } q = NULL; ptr = m_audioRtpDestination; while (ptr != NULL) { if (ptr->get_ref_num() == handle) { if (q == NULL) { m_audioRtpDestination = ptr->get_next(); } else { q->set_next(ptr->get_next()); } debug_message("Stopping rtp handle %d", handle); delete ptr; return; } q = ptr; ptr = ptr->get_next(); }}static void RtpCallback (struct rtp *session, rtp_event *e) { // Currently we ignore RTCP packets // Just do our required housekeeping if (e && (e->type == RX_RTP || e->type == RX_APP)) { free(e->data); }}CRtpDestination::CRtpDestination (uint32_t ref_number, char *destAddr, in_port_t destPort, in_port_t srcPort, uint8_t payloadNumber, int mcast_ttl, float rtcp_bandwidth){ m_refNum = ref_number; m_destAddr = strdup(destAddr); m_destPort = destPort; m_srcPort = srcPort; m_payloadNumber = payloadNumber; m_mcast_ttl = mcast_ttl; m_rtcp_bandwidth = rtcp_bandwidth; m_rtpSession = NULL; m_next = NULL;}void CRtpDestination::start (void) { if (m_rtpSession == NULL) { debug_message("Starting rtp dest %s %d %d", m_destAddr, m_destPort, m_srcPort); if (m_srcPort == 0) m_srcPort = m_destPort; m_rtpSession = rtp_init_xmitter(m_destAddr, m_srcPort, m_destPort, m_mcast_ttl, m_rtcp_bandwidth, RtpCallback, (uint8_t *)this); if (m_rtpSession == NULL) { error_message("Couldn't start rtp session"); } }} CRtpDestination::~CRtpDestination (void){ CHECK_AND_FREE(m_destAddr); if (m_rtpSession != NULL) { rtp_done(m_rtpSession); m_rtpSession = NULL; }}void CRtpDestination::send_rtcp (u_int32_t rtpTimestamp, u_int64_t ntpTimestamp){ if (m_rtpSession != NULL) { rtp_send_ctrl_2(m_rtpSession, rtpTimestamp, ntpTimestamp, NULL); rtp_update(m_rtpSession); }}int CRtpDestination::send_iov (struct iovec *piov, int iovCount, u_int32_t rtpTimestamp, int mbit){ if (m_rtpSession != NULL) { return rtp_send_data_iov(m_rtpSession, rtpTimestamp, m_payloadNumber, mbit, 0, NULL, piov, iovCount, NULL, 0, 0); } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -