Пример #1
0
int rtp_queue_unlock(void* queue, void* ptr, int size)
{
	unsigned int v;
	struct rtp_queue *q;
	struct rtp_frame *frame;
	time64_t tnow =  time64_now();

	q = (struct rtp_queue *)queue;
	frame = (struct rtp_frame *)ptr - 1;
	assert(frame->ptr == (unsigned char *)ptr);

	v = ntohl(((const unsigned int *)ptr)[0]);
	frame->seq = RTP_SEQ(v);
//	frame->timestamp = ntohl(((const unsigned int *)ptr)[1]);
//	frame->ssrc = ntohl(((const unsigned int *)ptr)[2]);
	frame->clock = time64_now();
	frame->len = size;
	assert(!frame->next);

	locker_lock(&q->locker);
	rtp_queue_push(q, frame);
//	rtp_queue_dump(q);
	locker_unlock(&q->locker);
	return 0;
}
Пример #2
0
void time64_test(void)
{
    time_t t;
    time64_t t64, _t64;
    struct tm *tm;
	struct tm64 tm64;
    char gmt[64];
    char utc[64];

    t64 = time64_now();
	time64_utc(t64, &tm64);

    t = time64_to_gmtime(t64);
	_t64 = time64_from_gmtime(t);
	assert(_t64/1000 == t64 / 1000);

	tm = gmtime(&t);
	assert(tm64.year==tm->tm_year && tm64.month==tm->tm_mon && tm64.day==tm->tm_mday && tm64.wday==tm->tm_wday && tm64.hour==tm->tm_hour && tm64.minute==tm->tm_min && tm64.second==tm->tm_sec);

	sprintf(gmt, "%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    time64_format(t64, "%04Y-%02M-%02D %02h:%02m:%02s", utc);
    assert(0 == strcmp(utc, gmt));

    _t64 = time64_from("%04Y-%02M-%02D %02h:%02m:%02s", utc);
    assert(t64/1000 == _t64/1000);
}
Пример #3
0
static struct rtp_frame* rtp_queue_pop(struct rtp_queue* q)
{
	struct rtp_frame* frame = NULL;
	if(q->head && (q->head->seq == q->expected || time64_now() - q->head->clock > q->threshold))
	{
		frame = q->head;

		q->head = frame->next;
		if(q->tail == frame)
		{
			assert(!q->head);
			assert(!q->tail->next);
			q->tail = NULL;
		}
	}
	return frame;
}
Пример #4
0
int H264FileSource::Play()
{
	m_status = 1;

	time64_t clock = time64_now();
	if(0 == m_rtp_clock || m_rtp_clock + 40 < clock)
	{
		void* ptr = NULL;
		size_t bytes = 0;
		if(0 == m_reader.GetNextFrame(m_pos, ptr, bytes))
		{
			rtp_h264_packer()->input(m_rtppacker, ptr, bytes, clock);
			m_rtp_clock = clock;

			SendRTCP();
			return 1;
		}
	}

	return 0;
}
Пример #5
0
int H264FileSource::SendRTCP()
{
	// make sure have sent RTP packet

	time64_t clock = time64_now();
	int interval = rtp_rtcp_interval(m_rtp);
	if(0 == m_rtcp_clock || m_rtcp_clock + interval < clock)
	{
		char rtcp[1024] = {0};
		size_t n = rtp_rtcp_report(m_rtp, rtcp, sizeof(rtcp));

		// send RTCP packet
		struct sockaddr_in addrin;
		socket_addr_ipv4(&addrin, m_ip.c_str(), m_port[1]);
		socket_sendto(m_socket[1], rtcp, n, 0, (struct sockaddr*)&addrin, sizeof(addrin));

		m_rtcp_clock = clock;
	}
	
	return 0;
}
Пример #6
0
int rtp_queue_lock(void* queue, void** ptr, int size)
{
	struct rtp_queue *q;
	struct rtp_frame* frame;
	q = (struct rtp_queue *)queue;

	if(size < 0 || size > MAX_SIZE)
		return -1; // invalid size

	frame = (struct rtp_frame*)malloc(sizeof(struct rtp_frame) + size);
	if(!frame)
		return -1; // alloc memory error

	memset(frame, 0, sizeof(*frame));
	frame->capacity = size;
	frame->ptr = (unsigned char*)(frame+1);
	frame->clock = time64_now();

	*ptr = frame->ptr;
	return 0;
}
Пример #7
0
static int STDCALL hls_server_worker(void* param)
{
	int r, type;
	time64_t clock;
	uint32_t timestamp;
	hls_playlist_t* playlist = (hls_playlist_t*)param;
	std::string file = playlist->file + ".flv";

	while (1)
	{
		void* flv = flv_reader_create(file.c_str());
		void* demuxer = flv_demuxer_create(flv_handler, playlist->hls);

		clock = 0;
		static unsigned char packet[2 * 1024 * 1024];
		while ((r = flv_reader_read(flv, &type, &timestamp, packet, sizeof(packet))) > 0)
		{
			time64_t now = time64_now();
			if (0 == clock)
			{
				clock = now;
			}
			else
			{
				if (timestamp > now - clock)
					system_sleep(timestamp - (now - clock));
			}

			assert(0 == flv_demuxer_input(demuxer, type, packet, r, timestamp));
		}

		flv_demuxer_destroy(demuxer);
		flv_reader_destroy(flv);
	}
	hls_media_destroy(playlist->hls);
	//hls_m3u8_destroy(playlist->m3u8);
	//s_playlists.erase();
	//delete playlist;
	return thread_destroy(playlist->t);
}
Пример #8
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;
		}