Example #1
0
Talker::MsgType Talker::receive_msg() {
    if (!receive()) 
        return MSG_RESET;
    if (_rx_buffer[0] == '$')
        return receive_rtcp();
    return receive_rtsp();
}
uint16_t RtpSession::receive_rtp_packet(void *buf )
{
	struct timeval start_time_tv;

	if ( ! m_preceived ) {
		/* This is the 1th packet that we receive-
		 * Here we should send an RTCP SDES packet with all the 
		 * infos...
		 */
		gettimeofday(&start_time_tv, NULL);
		m_start_time = tv2dbl(start_time_tv);
#if 0		
		/*! Build the SDES CNAME packet */
		uint16_t s = 10 + strlen( m_cname );
		/* Align to 32 bit boundary .. */
		s = (uint16_t)ceil( (double)s /4 ) * 4;
		
		m_sdes_pkt = (rtcp_t *)calloc( s , 1 );
		RtcpPacket *p = new RtcpPacket( m_sdes_pkt, s );
		p->set_version( 2 );
		p->set_padding( 0 );
		p->set_count( 1 );
		p->set_type( RTCP_SDES );
		p->set_length( (uint16_t)s/4 - 1 );
		m_sdes_pkt->r.sdes.src = htonl( m_ssrc );
		m_sdes_pkt->r.sdes.item->type = RTCP_SDES_CNAME;
		m_sdes_pkt->r.sdes.item->length = strlen( m_cname );
		memcpy( m_sdes_pkt->r.sdes.item[0].data, m_cname, strlen(m_cname) );
		m_sdes_pkt_size = s;

		/*! Schedule an RTCP RR.. */
		event_t *e = (event_t*)malloc( sizeof( event_t ) );
 		e->type = RTCP_RR;
		e->time = m_start_time + 5.0;
		e->next = NULL;
		insert_event( e );
		send_rtcp();
#endif
	}
	
	int event = 0;
	int retval;
	double timeout, now;
	struct timeval timeout_tv, now_tv;
	fd_set sockets;

	/*! Here we check for events or things to do... */
	while ( 1 ) {

		gettimeofday(&now_tv, NULL);
		now = tv2dbl(now_tv);

		if (    m_event_queue != NULL ) {
			event = 1;
			timeout = m_event_queue->time - now;
		} else {
			event = 0;
			timeout = 0.5; /* Arbitrary value.. to be trimmed.. */
		}
		if ( timeout < 0 )
			timeout = 0;
		timeout_tv = dbl2tv( timeout );

		FD_ZERO( &sockets );
		FD_SET( m_rtp_sock, &sockets );
		FD_SET( m_rtcp_sock, &sockets );

		int max_fd = ((m_rtp_sock > m_rtcp_sock) ? m_rtp_sock : m_rtcp_sock ) + 1;

		retval = select(max_fd, &sockets, NULL, NULL, &timeout_tv);
		if ( retval < 0 ) {
			perror("select");
			return false;
		} else if ( retval > 0 ) { // There are some events...
			if (FD_ISSET(m_rtp_sock, &sockets)) {
				/* There's an RTP packet to be read... 
				 */
				return receive_rtp( buf );
			}
			
			if (FD_ISSET(m_rtcp_sock, &sockets)) {
				receive_rtcp();
			}
		}  else { /* retval == 0, select timed out */
			if (event) {
				gettimeofday( &now_tv, NULL );
				now = tv2dbl( now_tv );
				while ( m_event_queue != NULL &&
					m_event_queue->time <= now ) {
					/* There is a pending RTCP packet to send) */
					send_rtcp();
				}
			} 
		}
	}
}
bool RtpSession::send_rtp_packet(void *buf, uint16_t size, uint32_t ts_inc )
{
	uint32_t timestamp;
	struct timeval start_time_tv, now_tv;
	double play_time, now;
	
	timestamp = m_prev_timestamp + ts_inc;
	m_prev_timestamp = timestamp;
	
	if ( !buf || !size ) {
	  printf("Cannot send packet.\n");
	  return false;
	}
	
	if ( ! m_psent ) {
		/* This is the 1th packet that we send.
		 * Here we should send an RTCP SDES packet with all the 
		 * infos...
		 */
		gettimeofday(&start_time_tv, NULL);
		m_start_time = tv2dbl(start_time_tv);
		
		/*! Build the SDES CNAME packet */
		uint16_t s = 10 + strlen( m_cname );
		/* Align to 32 bit boundary .. */
		s = (uint16_t)ceil( (double)s /4 ) * 4;
		
		m_sdes_pkt = (rtcp_t *)calloc( s , 1 );
		RtcpPacket *p = new RtcpPacket( m_sdes_pkt, s );
		p->set_version( 2 );
		p->set_padding( 0 );
		p->set_count( 1 );
		p->set_type( RTCP_SDES );
		p->set_length( (uint16_t)s/4 - 1 );
		m_sdes_pkt->r.sdes.src = htonl( m_ssrc );
		m_sdes_pkt->r.sdes.item->type = RTCP_SDES_CNAME;
		m_sdes_pkt->r.sdes.item->length = strlen( m_cname );
		memcpy( m_sdes_pkt->r.sdes.item[0].data, m_cname, strlen(m_cname) );
		m_sdes_pkt_size = s;

		/*! Schedule an RTCP for now.. */
		event_t *e = (event_t*)malloc( sizeof( event_t ) );
 		e->type = RTCP_SR;
		e->time = 0.0;
		e->next = NULL;
		insert_event( e );
		send_rtcp();
	}

	/** OK, we build the real RTP packet... */
	RtpPacket *pkt = new RtpPacket( (uint8_t*)buf, size );
	pkt->set_ssrc( m_ssrc );
	pkt->set_payload_type( m_payload_type );
	pkt->set_sequence( m_seq++ );
	pkt->set_timestamp( timestamp );
	delete pkt;

	if ( ! send_pkt( buf, size ) ) {
		/* Problems sending packet.. probably the client closed
		 * the connection..
		 */
		return false;
	}

	/* *************************************************** */
	/*! Here we check for events or things to do... */

	/* Schedule the times to play packets as an absolute offset from
	 * our start time, rather than a relative offset from the initial
	 * packet.  (We're less vulnerable to drifting clocks that way).
	 * Alternative version based on timestamps and RTP clock..
	 */
	play_time = m_start_time + ((double)(timestamp - m_base_timestamp)/ m_rtp_clock);
	// printf("play_time: %f - difference: %f sec.\n", play_time,
	//		((double)(timestamp - m_base_timestamp)/ m_rtp_clock));

	while (gettimeofday(&now_tv, NULL), (now = tv2dbl(now_tv)) < play_time) {

		int event = 0;
		int retval;
		double timeout;
		struct timeval timeout_tv;
		fd_set sockets;

		if (	m_event_queue != NULL && 
			m_event_queue->time < play_time ) {
			event = 1;
			timeout = m_event_queue->time - now;
		} else {
			event = 0;
			timeout = play_time - now;
		}
		if ( timeout < 0 )
			timeout = 0;
		timeout_tv = dbl2tv( timeout );

		FD_ZERO( &sockets );
		FD_SET( m_rtp_sock, &sockets );
		FD_SET( m_rtcp_sock, &sockets );

		int max_fd = ((m_rtp_sock > m_rtcp_sock) ? m_rtp_sock : m_rtcp_sock ) + 1;

		retval = select(max_fd, &sockets, NULL, NULL, &timeout_tv);
		if ( retval < 0 ) {
			perror("select");
			exit(1);
		} else if ( retval > 0 ) { // There are some events...
			if (FD_ISSET(m_rtp_sock, &sockets)) {
				/* There's an RTP packet to be read... 
				 * We should receive, validate and .. trash it..
				 */
				receive_rtp( (void*)m_buf );
			}
			
			if (FD_ISSET(m_rtcp_sock, &sockets)) {
				receive_rtcp();
			}
		}  else { /* retval == 0, select timed out */
			if (event) {
				gettimeofday( &now_tv, NULL );
				now = tv2dbl( now_tv );
				while ( m_event_queue != NULL &&
					m_event_queue->time <= now ) {
					/* There is a pending RTCP packet to send) */
					send_rtcp();
				}
			} else
				break;  /* Time for the next packet */
		}
	}
	/* **************************************************** */
	return true;
}