📄 rtp_transmitter.cpp
字号:
// 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 CAudioRtpTransmitter::SendQueuedAudioFrames(void){ struct iovec iov[m_audioiovMaxCount + 1]; int ix; int i = 0; CRtpDestination *rdptr; if (m_audioQueueCount == 0) { return; } u_int32_t rtpTimestamp = TimestampToRtp(m_audioQueue[0]->GetTimestamp()); u_int64_t ntpTimestamp = TimestampToNtp(m_audioQueue[0]->GetTimestamp());#ifdef DEBUG_SEND debug_message("A ts "U64" rtp %u ntp %u.%u", m_audioQueue[0]->GetTimestamp(), rtpTimestamp, (u_int32_t)(ntpTimestamp >> 32), (u_int32_t)ntpTimestamp);#endif rdptr = m_rtpDestination; 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; uint iov_add = 0; bool mbit = 1; 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, &mbit); } 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, &mbit)) { iov_start = 0; iov_add = 1; } } } // send packet rdptr = m_rtpDestination; while (rdptr != NULL) { rdptr->send_iov(&iov[iov_start], iov_add + m_audioQueueCount, rtpTimestamp, mbit ? 1 : 0); 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 CAudioRtpTransmitter::SendAudioJumboFrame(CMediaFrame* pFrame){ u_int32_t rtpTimestamp = TimestampToRtp(pFrame->GetTimestamp()); u_int64_t ntpTimestamp = TimestampToNtp(pFrame->GetTimestamp()); CRtpDestination *rdptr;#ifdef DEBUG_SEND debug_message("A ts "U64" rtp %u ntp %u.%u", pFrame->GetTimestamp(), rtpTimestamp, (u_int32_t)(ntpTimestamp >> 32), (u_int32_t)ntpTimestamp);#endif rdptr = m_rtpDestination; while (rdptr != NULL) { rdptr->send_rtcp(rtpTimestamp, ntpTimestamp); rdptr = rdptr->get_next(); } u_int32_t dataOffset = 0; u_int32_t spaceAvailable = m_mtu; struct iovec iov[2]; do { iov[1].iov_base = (u_int8_t*)pFrame->GetData() + dataOffset; uint 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_rtpDestination; 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, (int)iov[1].iov_len, pFrame->GetDataLength()); dataOffset += iov[1].iov_len; } while (dataOffset < pFrame->GetDataLength()); if (pFrame->RemoveReference()) delete pFrame;}void CRtpTransmitter::DoStartRtpDestination (const char *destAddr, in_port_t destPort){ CRtpDestination *ptr; ptr = m_rtpDestination; while (ptr != NULL) { if (ptr->Matches(destAddr, destPort)) { ptr->start(); return; } ptr = ptr->get_next(); }}void CRtpTransmitter::DoStopRtpDestination (const char *destAddr, in_port_t destPort){ CRtpDestination *ptr, *q; q = NULL; ptr = m_rtpDestination; while (ptr != NULL) { if (ptr->Matches(destAddr, destPort)) { if (ptr->remove_reference()) { if (q == NULL) { m_rtpDestination = ptr->get_next(); } else { q->set_next(ptr->get_next()); } delete ptr; } return; } q = ptr; ptr = ptr->get_next(); }}CAudioRtpTransmitter::CAudioRtpTransmitter (CAudioProfile *ap, uint16_t mtu, bool disable_ts_offset) : CRtpTransmitter(mtu){ m_audio_profile = ap; m_payloadNumber = 97; m_audioQueue = NULL; m_audio_rtp_userdata = NULL; m_audio_set_rtp_payload = NULL; // plugin function to determind how to build RTP payload m_audio_queue_frame = NULL; // plugin function to determind how to queue frames for RTP m_frameno = NULL; // plugin will allocate counter space m_audioiovMaxCount = 0; // Max number of iov segments for send_iov /* if (m_audioSrcPort == 0) { m_audioSrcPort = GetRandomPortBlock(); } if (m_pConfig->GetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT) == 0) { m_pConfig->SetIntegerValue(CONFIG_RTP_AUDIO_DEST_PORT, m_audioSrcPort + 2); } */ if (get_audio_rtp_info(ap, &m_frameType, &m_timeScale, &m_payloadNumber, &m_audioPayloadBytesPerPacket, &m_audioPayloadBytesPerFrame, &m_audioQueueMaxCount, &m_audioiovMaxCount, &m_audio_queue_frame, &m_audio_set_rtp_payload, &m_audio_set_rtp_header, &m_audio_set_rtp_jumbo_frame, &m_audio_rtp_userdata) == false) { error_message("rtp transmitter: unknown audio encoding %s", ap->GetStringValue(CFG_AUDIO_ENCODING)); } uint8_t max_queue_from_config = ap->GetIntegerValue(CFG_RTP_MAX_FRAMES_PER_PACKET); if (max_queue_from_config != 0 && max_queue_from_config < m_audioQueueMaxCount) { m_audioQueueMaxCount = max_queue_from_config; } if (m_audioiovMaxCount == 0) // This is purely for backwards compability m_audioiovMaxCount = m_audioQueueMaxCount; // Can go away when lame and faac plugin sets this#ifdef DEBUG_WRAP_TS m_audioRtpTimestampOffset = 0xffff0000;#else if (disable_ts_offset) { m_audioRtpTimestampOffset = 0; } else { m_audioRtpTimestampOffset = random(); }#endif m_audioQueueCount = 0; m_audioQueueSize = 0; m_audioQueue = (CMediaFrame**)Malloc(m_audioQueueMaxCount * sizeof(CMediaFrame*));}CAudioRtpTransmitter::~CAudioRtpTransmitter (void) { DoStopTransmit(); CHECK_AND_FREE(m_audio_rtp_userdata); CHECK_AND_FREE(m_frameno); CHECK_AND_FREE(m_audioQueue);}CVideoRtpTransmitter::CVideoRtpTransmitter (CVideoProfile *vp, uint16_t mtu, bool disable_ts_offset) : CRtpTransmitter(mtu, disable_ts_offset){ m_videoSendFunc = GetVideoRtpTransmitRoutine(vp, &m_frameType, &m_payloadNumber); m_timeScale = 90000;}CTextRtpTransmitter::CTextRtpTransmitter (CTextProfile *tp, uint16_t mtu, bool disable_ts_offset) : CRtpTransmitter(mtu, disable_ts_offset){ m_textSendFunc = GetTextRtpTransmitRoutine(tp, &m_frameType, &m_payloadNumber); m_timeScale = 90000;}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 (mp4live_rtp_params_t *rtp_params, uint8_t payloadNumber){ m_rtp_params = rtp_params; m_payloadNumber = payloadNumber; m_rtpSession = NULL; m_srtpSession = NULL; m_next = NULL; m_ref_mutex = SDL_CreateMutex(); m_reference = 1; m_destroy_rtp_session = true;}CRtpDestination::CRtpDestination (struct rtp *session, uint8_t payloadNumber){ m_rtp_params = NULL; m_payloadNumber = payloadNumber; m_rtpSession = session; m_srtpSession = NULL; m_next = NULL; m_ref_mutex = SDL_CreateMutex(); m_reference = 1; m_destroy_rtp_session = false;} CRtpDestination::~CRtpDestination (void){ if (m_rtpSession != NULL && m_destroy_rtp_session) { rtp_done(m_rtpSession); } m_rtpSession = NULL; if (m_srtpSession != NULL) { destroy_srtp(m_srtpSession); m_srtpSession = NULL; } CHECK_AND_FREE(m_rtp_params); SDL_DestroyMutex(m_ref_mutex);}void CRtpDestination::start (void) { while (m_rtpSession == NULL) { debug_message("Starting rtp dest %s %d %d", m_rtp_params->rtp_params.rtp_addr, m_rtp_params->rtp_params.rtp_tx_port, m_rtp_params->rtp_params.rtp_rx_port); if (m_rtp_params->rtp_params.rtcp_addr != NULL) { debug_message("Rtcp %s %u", m_rtp_params->rtp_params.rtcp_addr, m_rtp_params->rtp_params.rtcp_tx_port); } /* wmay - comment out for now - might have to revisit for ssm if (m_srcPort == 0) m_srcPort = m_destPort; */ m_rtp_params->rtp_params.rtp_callback = RtpCallback; m_rtp_params->rtp_params.recv_userdata = this; m_rtpSession = rtp_init_stream(&m_rtp_params->rtp_params); if (m_rtpSession == NULL) { error_message("Couldn't start rtp session"); SDL_Delay(10); } else { //srtp init //what format is the key in? if (m_rtp_params->use_srtp) { m_srtpSession = srtp_setup(m_rtpSession, &m_rtp_params->srtp_params); } } }} 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, uint iovCount, u_int32_t rtpTimestamp, int mbit){ if (m_rtpSession != NULL) { int ret = rtp_send_data_iov(m_rtpSession, rtpTimestamp, m_payloadNumber, mbit, 0, NULL, piov, iovCount, NULL, 0, 0, 0); //debug_message("sending iov %d", ret); return ret; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -