예제 #1
0
static APR_INLINE apt_bool_t mpf_rtp_data_send(mpf_rtp_stream_t *rtp_stream, rtp_transmitter_t *transmitter, const mpf_frame_t *frame)
{
	apt_bool_t status = TRUE;
	memcpy(
		transmitter->packet_data + transmitter->packet_size,
		frame->codec_frame.buffer,
		frame->codec_frame.size);
	transmitter->packet_size += frame->codec_frame.size;

	if(++transmitter->current_frames == transmitter->packet_frames) {
		rtp_header_t *header = (rtp_header_t*)transmitter->packet_data;
		header->sequence = htons(++transmitter->last_seq_num);
		RTP_TRACE("> RTP time=%6u ssrc=%8x pt=%3u %cts=%9u seq=%5hu\n",
			(apr_uint32_t)apr_time_usec(apr_time_now()),
			transmitter->sr_stat.ssrc, header->type, 
			(header->marker == 1) ? '*' : ' ',
			header->timestamp, transmitter->last_seq_num);
		header->timestamp = htonl(header->timestamp);
		if(apr_socket_sendto(
					rtp_stream->rtp_socket,
					rtp_stream->rtp_r_sockaddr,
					0,
					transmitter->packet_data,
					&transmitter->packet_size) == APR_SUCCESS) {
			transmitter->sr_stat.sent_packets++;
			transmitter->sr_stat.sent_octets += (apr_uint32_t)transmitter->packet_size - sizeof(rtp_header_t);
		}
		else {
			status = FALSE;
		}
		transmitter->current_frames = 0;
	}
	return status;
}
예제 #2
0
static APR_INLINE rtp_ts_result_e rtp_rx_ts_update(rtp_receiver_t *receiver, mpf_codec_descriptor_t *descriptor, apr_time_t *time, apr_uint32_t ts)
{
	apr_int32_t deviation;

	/* arrival time diff in samples */
	deviation = (apr_int32_t)apr_time_as_msec(*time - receiver->history.time_last) * 
		descriptor->channel_count * descriptor->sampling_rate / 1000;
	/* arrival timestamp diff */
	deviation -= ts - receiver->history.ts_last;

	if(deviation < 0) {
		deviation = -deviation;
	}

	if(deviation > DEVIATION_THRESHOLD) {
		return RTP_TS_DRIFT;
	}

	receiver->rr_stat.jitter += deviation - ((receiver->rr_stat.jitter + 8) >> 4);
	RTP_TRACE("jitter=%d deviation=%d\n",receiver->rr_stat.jitter,deviation);
	receiver->history.time_last = *time;
	receiver->history.ts_last = ts;

	if(receiver->rr_stat.jitter < receiver->periodic_history.jitter_min) {
		receiver->periodic_history.jitter_min = receiver->rr_stat.jitter;
	}
	if(receiver->rr_stat.jitter > receiver->periodic_history.jitter_max) {
		receiver->periodic_history.jitter_max = receiver->rr_stat.jitter;
	}
	return RTP_TS_UPDATE;
}
예제 #3
0
static APR_INLINE rtp_ts_result_e rtp_rx_ts_update(rtp_receiver_t *receiver, mpf_codec_descriptor_t *descriptor, apr_time_t *time, apr_uint32_t ts, apr_byte_t *marker)
{
	apr_int32_t deviation;
	apr_int32_t time_diff;

	/* arrival time diff in msec */
	time_diff = (apr_int32_t)apr_time_as_msec(*time - receiver->history.time_last);

	/* if the time difference is more than the threshold (INTER_TALKSPURT_GAP),
	   and the marker is not set, then this might be a beginning of a 
	   new malformed talkspurt */
	if(!*marker && time_diff > INTER_TALKSPURT_GAP) {
		/* set the missing marker */
		*marker = 1;
	}

	/* arrival time diff in samples */
	deviation = time_diff * descriptor->channel_count * descriptor->sampling_rate / 1000;
	/* arrival timestamp diff */
	deviation -= ts - receiver->history.ts_last;

	if(deviation < 0) {
		deviation = -deviation;
	}

	if(deviation > DEVIATION_THRESHOLD) {
		return RTP_TS_DRIFT;
	}

	receiver->rr_stat.jitter += deviation - ((receiver->rr_stat.jitter + 8) >> 4);
	RTP_TRACE("jitter=%u deviation=%d\n",receiver->rr_stat.jitter,deviation);
	receiver->history.time_last = *time;
	receiver->history.ts_last = ts;

	if(receiver->rr_stat.jitter < receiver->periodic_history.jitter_min) {
		receiver->periodic_history.jitter_min = receiver->rr_stat.jitter;
	}
	if(receiver->rr_stat.jitter > receiver->periodic_history.jitter_max) {
		receiver->periodic_history.jitter_max = receiver->rr_stat.jitter;
	}
	return RTP_TS_UPDATE;
}
예제 #4
0
static APR_INLINE apt_bool_t mpf_rtp_event_send(mpf_rtp_stream_t *rtp_stream, rtp_transmitter_t *transmitter, const mpf_frame_t *frame)
{
	char packet_data[20];
	apr_size_t packet_size = sizeof(rtp_header_t) + sizeof(mpf_named_event_frame_t);
	rtp_header_t *header = (rtp_header_t*) packet_data;
	mpf_named_event_frame_t *named_event = (mpf_named_event_frame_t*)(header+1);
	rtp_header_prepare(
		transmitter,
		header,
		rtp_stream->base->tx_event_descriptor->payload_type,
		(frame->marker == MPF_MARKER_START_OF_EVENT) ? 1 : 0,
		transmitter->timestamp_base);

	*named_event = frame->event_frame;
	named_event->edge = (frame->marker == MPF_MARKER_END_OF_EVENT) ? 1 : 0;
	
	header->sequence = htons(++transmitter->last_seq_num);
	RTP_TRACE("> RTP time=%6lu ssrc=%8lx pt=%3u %cts=%9lu seq=%5u event=%2u dur=%3u %c\n",
		(apr_uint32_t)apr_time_usec(apr_time_now()),
		transmitter->sr_stat.ssrc, 
		header->type, (header->marker == 1) ? '*' : ' ',
		header->timestamp, transmitter->last_seq_num,
		named_event->event_id, named_event->duration,
		(named_event->edge == 1) ? '*' : ' ');

	header->timestamp = htonl(header->timestamp);
	named_event->duration = htons((apr_uint16_t)named_event->duration);
	if(apr_socket_sendto(
				rtp_stream->rtp_socket,
				rtp_stream->rtp_r_sockaddr,
				0,
				packet_data,
				&packet_size) != APR_SUCCESS) {
		return FALSE;
	}
	transmitter->sr_stat.sent_packets++;
	transmitter->sr_stat.sent_octets += sizeof(mpf_named_event_frame_t);
	return TRUE;
}
예제 #5
0
static apt_bool_t rtp_rx_packet_receive(mpf_rtp_stream_t *rtp_stream, void *buffer, apr_size_t size)
{
	rtp_receiver_t *receiver = &rtp_stream->receiver;
	mpf_codec_descriptor_t *descriptor = rtp_stream->base->rx_descriptor;
	apr_time_t time;
	rtp_ssrc_result_e ssrc_result;
	rtp_header_t *header = rtp_rx_header_skip(&buffer,&size);
	if(!header) {
		/* invalid RTP packet */
		receiver->stat.invalid_packets++;
		return FALSE;
	}

	header->sequence = ntohs((apr_uint16_t)header->sequence);
	header->timestamp = ntohl(header->timestamp);
	header->ssrc = ntohl(header->ssrc);

	time = apr_time_now();

	RTP_TRACE("RTP time=%6u ssrc=%8x pt=%3u %cts=%9u seq=%5u size=%"APR_SIZE_T_FMT"\n",
					(apr_uint32_t)apr_time_usec(time),
					header->ssrc, header->type, (header->marker == 1) ? '*' : ' ',
					header->timestamp, header->sequence, size);
	if(!receiver->stat.received_packets) {
		/* initialization */
		rtp_rx_stat_init(receiver,header,&time);
	}

	ssrc_result = rtp_rx_ssrc_update(receiver,header->ssrc);
	if(ssrc_result == RTP_SSRC_PROBATION) {
		receiver->stat.invalid_packets++;
		return FALSE;
	}
	else if(ssrc_result == RTP_SSRC_RESTART) {
		rtp_rx_restart(receiver);
		rtp_rx_stat_init(receiver,header,&time);
	}

	rtp_rx_seq_update(receiver,(apr_uint16_t)header->sequence);
	
	if(header->type == descriptor->payload_type) {
		/* codec */
		apr_byte_t marker = (apr_byte_t)header->marker;
		if(rtp_rx_ts_update(receiver,descriptor,&time,header->timestamp,&marker) == RTP_TS_DRIFT) {
			rtp_rx_restart(receiver);
			return FALSE;
		}
	
		if(mpf_jitter_buffer_write(receiver->jb,buffer,size,header->timestamp,marker) != JB_OK) {
			receiver->stat.discarded_packets++;
			rtp_rx_failure_threshold_check(receiver);
		}
	}
	else if(rtp_stream->base->rx_event_descriptor && 
		header->type == rtp_stream->base->rx_event_descriptor->payload_type) {
		/* named event */
		mpf_named_event_frame_t *named_event = (mpf_named_event_frame_t *)buffer;
		named_event->duration = ntohs((apr_uint16_t)named_event->duration);
		if(mpf_jitter_buffer_event_write(receiver->jb,named_event,header->timestamp,(apr_byte_t)header->marker) != JB_OK) {
			receiver->stat.discarded_packets++;
		}
	}
	else if(header->type == RTP_PT_CN) {
		/* CN packet */
		receiver->stat.ignored_packets++;
	}
	else {
		/* invalid payload type */
		receiver->stat.ignored_packets++;
	}
	
	return TRUE;
}