Exemple #1
0
static int rtp_ps_unpack_input(void* p, const void* packet, size_t bytes, int64_t time)
{
	rtp_packet_t pkt;
	struct rtp_ps_unpack_t *unpacker;

	unpacker = (struct rtp_ps_unpack_t *)p;
	if(0 != rtp_packet_deserialize(&pkt, packet, bytes) || pkt.payloadlen < 1)
		return -1;

	if((uint16_t)pkt.rtp.seq != unpacker->seq+1 && 0!=unpacker->seq)
	{
		// packet lost
		unpacker->size = 0; // clear flags
		unpacker->flag = 1;
	}

	unpacker->seq = (uint16_t)pkt.rtp.seq;

	assert(pkt.payloadlen > 0);
	if(pkt.payloadlen > 0 && 0 == unpacker->flag)
	{
		if(pkt.payloadlen > 0 && unpacker->size + pkt.payloadlen > unpacker->capacity)
		{
			uint8_t *ptr = (uint8_t*)realloc(unpacker->ptr, unpacker->capacity + pkt.payloadlen + 2048);
			if(!p)
			{
				unpacker->flag = 1;
				return ENOMEM;
			}

			unpacker->ptr = ptr;
			unpacker->capacity += pkt.payloadlen + 2048;
		}

		memcpy(unpacker->ptr + unpacker->size, pkt.payload, pkt.payloadlen);
		unpacker->size += pkt.payloadlen;
	}

	// RTP marker bit
	if(pkt.rtp.m)
	{
		if(unpacker->size > 0 && 0==unpacker->flag)
			unpacker->func.packet(unpacker->cbparam, (uint8_t)pkt.rtp.pt, unpacker->ptr, unpacker->size, time);
		unpacker->flag = 0;
		unpacker->size = 0;
	}

	return 0;
}
Exemple #2
0
int rtp_onsend(void* rtp, const void* data, int bytes)
{
//	time64_t ntp;
	struct rtp_packet_t pkt;
	struct rtp_context *ctx = (struct rtp_context *)rtp;

	ctx->role = RTP_SENDER;
	// don't need add self to sender list
	// rtp_member_list_add(ctx->senders, ctx->self);

	if(0 != rtp_packet_deserialize(&pkt, data, bytes))
		return -1; // packet error

	ctx->self->rtp_clock = rtpclock();
	ctx->self->rtp_timestamp = pkt.rtp.timestamp; // RTP timestamp
	ctx->self->rtp_bytes += pkt.payloadlen;
	ctx->self->rtp_packets += 1;
	return 0;
}
Exemple #3
0
int rtcp_input_rtp(struct rtp_context *ctx, const void* data, size_t bytes, time64_t *time)
{
	time64_t clock;
	rtp_packet_t pkt;
	struct rtp_member *sender;

	if(0 != rtp_packet_deserialize(&pkt, data, bytes))
		return -1; // packet error

	assert(2 == pkt.rtp.v);
	sender = rtp_sender_fetch(ctx, pkt.rtp.ssrc);
	if(!sender)
		return -1;

	clock = time64_now();
	// RFC3550 A.8 Estimating the Interarrival Jitter
	// the jitter estimate is updated:
	if(0 != sender->rtp_clock)
	{
		int D;
		D = (int)((unsigned int)((clock - sender->rtp_clock)*ctx->frequence/1000) - (pkt.rtp.timestamp - sender->rtp_timestamp));
		if(D < 0) D = -D;
		sender->jitter += (D - sender->jitter)/16.0;
	}

	sender->rtp_clock = clock;
	sender->rtp_timestamp = pkt.rtp.timestamp;
	sender->rtp_octets += pkt.payloadlen;
	++sender->rtp_packets;

	// RFC3550 A.1 RTP Data Header Validity Checks
	if(0 == sender->seq_max && 0 == sender->seq_cycles)
	{
		sender->seq_probation = 0;
		sender->seq_max = (uint16_t)pkt.rtp.seq;
		sender->seq_base = (uint16_t)pkt.rtp.seq;
	}
	else if( RTP_SEQ_DIFF(pkt.rtp.seq, sender->seq_max) < RTP_MISORDER)
	{
		if(pkt.rtp.seq < 0x1000 && sender->seq_max > 0x8000)
		{
			sender->seq_cycles += 1;
			sender->seq_max = (uint16_t)pkt.rtp.seq;
		}
		else
		{
			sender->seq_max = (uint16_t)MAX(pkt.rtp.seq, sender->seq_max);
		}
	}
	else
	{
		if(++sender->seq_probation > RTP_MINISEQ)
		{
			sender->seq_cycles = 0;
			sender->seq_probation = 0;
			sender->seq_max = (uint16_t)pkt.rtp.seq;
			sender->seq_base = (uint16_t)pkt.rtp.seq;
		}
	}

	// calculate wallclock from RTP timestamp
	if(0 != sender->rtcp_sr.ntpmsw)
	{
		*time = (uint64_t)ntp2clock((((uint64_t)sender->rtcp_sr.ntpmsw) << 32) | sender->rtcp_sr.ntplsw);
		*time += ((uint64_t)(uint32_t)(sender->rtp_timestamp - sender->rtcp_sr.rtpts)) * 1000 / ctx->frequence;

		// rtp timestamp round per 13-hours(0xFFFFFFFF / 90000 / 3600)
		// update wall-clock per hour
		if(clock - sender->rtcp_sr_clock > 1 * 3600 * 1000 
			|| (uint32_t)RTP_ABS((int32_t)(sender->rtp_timestamp - sender->rtcp_sr.rtpts)) > 0x10000000)
		{
			time64_t ltnow;
			ltnow = clock2ntp(*time);
			sender->rtcp_sr_clock = clock;
			sender->rtcp_sr.rtpts = sender->rtp_timestamp;
			sender->rtcp_sr.ntpmsw = (uint32_t)((ltnow >> 32) & 0xFFFFFFFF);
			sender->rtcp_sr.ntplsw = (uint32_t)ltnow;
		}