rtp_transmitter.cpp

来自「MPEG4音频视频压缩编码(含G.711/ACC/H.261等)」· C++ 代码 · 共 802 行 · 第 1/2 页

CPP
802
字号
		// 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 RTP_DEBUG	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;	int 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;#if RTP_DEBUG  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;    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_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 (const char *destAddr, 				  in_port_t destPort,				  in_port_t srcPort,				  uint8_t payloadNumber,				  int mcast_ttl,				  float rtcp_bandwidth){  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;  m_ref_mutex = SDL_CreateMutex();  m_reference = 1;}CRtpDestination::~CRtpDestination (void){  CHECK_AND_FREE(m_destAddr);  if (m_rtpSession != NULL) {    rtp_done(m_rtpSession);    m_rtpSession = NULL;  }  SDL_DestroyMutex(m_ref_mutex);}void CRtpDestination::start (void) {  while (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");      SDL_Delay(10);    }  }}			  			  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) {    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 + =
减小字号Ctrl + -
显示快捷键?