亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? rtp.c

?? MPEG-4編解碼的實現(包括MPEG4視音頻編解碼)
?? C
?? 第 1 頁 / 共 5 頁
字號:

static void process_report_blocks(struct rtp *session, rtcp_t *packet, uint32_t ssrc, rtcp_rr *rrp, struct timeval *event_ts)
{
	int i;
	rtp_event	 event;
	rtcp_rr		*rr;

	/* ...process RRs... */
	if (packet->common.count == 0) {
		if (!filter_event(session, ssrc)) {
			event.ssrc = ssrc;
			event.type = RX_RR_EMPTY;
			event.data = NULL;
			event.ts   = event_ts;
			session->callback(session, &event);
		}
	} else {
		for (i = 0; i < packet->common.count; i++, rrp++) {
			rr = (rtcp_rr *) xmalloc(sizeof(rtcp_rr));
			rr->ssrc          = ntohl(rrp->ssrc);
			rr->fract_lost    = rrp->fract_lost;	/* Endian conversion handled in the */
			rr->total_lost    = rrp->total_lost;	/* definition of the rtcp_rr type.  */
			rr->last_seq      = ntohl(rrp->last_seq);
			rr->jitter        = ntohl(rrp->jitter);
			rr->lsr           = ntohl(rrp->lsr);
			rr->dlsr          = ntohl(rrp->dlsr);

			/* Create a database entry for this SSRC, if one doesn't already exist... */
			create_source(session, rr->ssrc, FALSE);

			/* Store the RR for later use... */
			insert_rr(session, ssrc, rr, event_ts);

			/* Call the event handler... */
			if (!filter_event(session, ssrc)) {
				event.ssrc = ssrc;
				event.type = RX_RR;
				event.data = (void *) rr;
				event.ts   = event_ts;
				session->callback(session, &event);
			}
		}
	}
}

static void process_rtcp_sr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
{
	uint32_t	 ssrc;
	rtp_event	 event;
	rtcp_sr		*sr;
	source		*s;

	ssrc = ntohl(packet->r.sr.sr.ssrc);
	s = create_source(session, ssrc, FALSE);
	if (s == NULL) {
		rtp_message(LOG_WARNING, "Source 0x%08x invalid, skipping...", ssrc);
		return;
	}

	/* Mark as an active sender, if we get a sender report... */
	if (s->sender == FALSE) {
		s->sender = TRUE;
		session->sender_count++;
	}

	/* Process the SR... */
	sr = (rtcp_sr *) xmalloc(sizeof(rtcp_sr));
	sr->ssrc          = ssrc;
	sr->ntp_sec       = ntohl(packet->r.sr.sr.ntp_sec);
	sr->ntp_frac      = ntohl(packet->r.sr.sr.ntp_frac);
	sr->rtp_ts        = ntohl(packet->r.sr.sr.rtp_ts);
	sr->sender_pcount = ntohl(packet->r.sr.sr.sender_pcount);
	sr->sender_bcount = ntohl(packet->r.sr.sr.sender_bcount);

	/* Store the SR for later retrieval... */
	if (s->sr != NULL) {
		xfree(s->sr);
	}
	s->sr = sr;
	s->last_sr = *event_ts;

	/* Call the event handler... */
	if (!filter_event(session, ssrc)) {
		event.ssrc = ssrc;
		event.type = RX_SR;
		event.data = (void *) sr;
		event.ts   = event_ts;
		session->callback(session, &event);
	}

	process_report_blocks(session, packet, ssrc, packet->r.sr.rr, event_ts);

	if (((packet->common.count * 6) + 1) < (ntohs(packet->common.length) - 5)) {
		rtp_message(LOG_NOTICE, "Profile specific SR extension ignored");
	}
}

static void process_rtcp_rr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
{
	uint32_t		 ssrc;
	source		*s;

	ssrc = ntohl(packet->r.rr.ssrc);
	s = create_source(session, ssrc, FALSE);
	if (s == NULL) {
		rtp_message(LOG_WARNING, "Source 0x%08x invalid, skipping...", ssrc);
		return;
	}

	process_report_blocks(session, packet, ssrc, packet->r.rr.rr, event_ts);

	if (((packet->common.count * 6) + 1) < ntohs(packet->common.length)) {
		rtp_message(LOG_INFO, "Profile specific RR extension ignored");
	}
}

static void process_rtcp_sdes(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
{
	int 			count = packet->common.count;
	struct rtcp_sdes_t 	*sd   = &packet->r.sdes;
	rtcp_sdes_item 		*rsp; 
	rtcp_sdes_item		*rspn;
	rtcp_sdes_item 		*end  = (rtcp_sdes_item *) ((uint32_t *)packet + packet->common.length + 1);
	source 			*s;
	rtp_event		 event;

	while (--count >= 0) {
		rsp = &sd->item[0];
		if (rsp >= end) {
			break;
		}
		sd->ssrc = ntohl(sd->ssrc);
		s = create_source(session, sd->ssrc, FALSE);
		if (s == NULL) {
			rtp_message(LOG_NOTICE, "Cannot get valid source entry for 0x%08x, skipping...", sd->ssrc);
		} else {
			for (; rsp->type; rsp = rspn ) {
				rspn = (rtcp_sdes_item *)((char*)rsp+rsp->length+2);
				if (rspn >= end) {
					rsp = rspn;
					break;
				}
				if (rtp_set_sdes(session, sd->ssrc, rsp->type, rsp->data, rsp->length)) {
					if (!filter_event(session, sd->ssrc)) {
						event.ssrc = sd->ssrc;
						event.type = RX_SDES;
						event.data = (void *) rsp;
						event.ts   = event_ts;
						session->callback(session, &event);
					}
				} else {
					rtp_message(LOG_WARNING, "Invalid sdes item for source 0x%08x, skipping...", sd->ssrc);
				}
			}
		}
		sd = (struct rtcp_sdes_t *) ((uint32_t *)sd + (((char *)rsp - (char *)sd) >> 2)+1);
	}
	if (count >= 0) {
		rtp_message(LOG_INFO, "Invalid RTCP SDES packet, some items ignored.");
	}
}

static void process_rtcp_bye(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
{
	int		 i;
	uint32_t	 ssrc;
	rtp_event	 event;
	source		*s;

	for (i = 0; i < packet->common.count; i++) {
		ssrc = ntohl(packet->r.bye.ssrc[i]);
		/* This is kind-of strange, since we create a source we are about to delete. */
		/* This is done to ensure that the source mentioned in the event which is    */
		/* passed to the user of the RTP library is valid, and simplify client code. */
		create_source(session, ssrc, FALSE);
		/* Call the event handler... */
		if (!filter_event(session, ssrc)) {
			event.ssrc = ssrc;
			event.type = RX_BYE;
			event.data = NULL;
			event.ts   = event_ts;
			session->callback(session, &event);
		}
		/* Mark the source as ready for deletion. Sources are not deleted immediately */
		/* since some packets may be delayed and arrive after the BYE...              */
		s = get_source(session, ssrc);
		s->got_bye = TRUE;
		check_source(s);
		session->bye_count++;
	}
}

static void process_rtcp_app(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
{
	uint32_t         ssrc;
	rtp_event        event;
	rtcp_app        *app;
	source          *s;
	int              data_len;

	/* Update the database for this source. */
	ssrc = ntohl(packet->r.app.ssrc);
	create_source(session, ssrc, FALSE);
	s = get_source(session, ssrc);
	if (s == NULL) {
	        /* This should only occur in the event of database malfunction. */
	        rtp_message(LOG_NOTICE, "Source 0x%08x invalid, skipping...", ssrc);
	        return;
	}
	check_source(s);

	/* Copy the entire packet, converting the header (only) into host byte order. */
	app = (rtcp_app *) xmalloc(RTP_MAX_PACKET_LEN);
	app->version        = packet->common.version;
	app->p              = packet->common.p;
	app->subtype        = packet->common.count;
	app->pt             = packet->common.pt;
	app->length         = ntohs(packet->common.length);
	app->ssrc           = ssrc;
	app->name[0]        = packet->r.app.name[0];
	app->name[1]        = packet->r.app.name[1];
	app->name[2]        = packet->r.app.name[2];
	app->name[3]        = packet->r.app.name[3];
	data_len            = (app->length - 2) * 4;
	memcpy(app->data, packet->r.app.data, data_len);

	/* Callback to the application to process the app packet... */
	if (!filter_event(session, ssrc)) {
		event.ssrc = ssrc;
		event.type = RX_APP;
		event.data = (void *) app;       /* The callback function MUST free this! */
		event.ts   = event_ts;
		session->callback(session, &event);
	}
}

void rtp_process_ctrl(struct rtp *session, uint8_t *buffer, int buflen)
{
	/* This routine processes incoming RTCP packets */
	rtp_event	 event;
	struct timeval	 event_ts;
	rtcp_t		*packet;
	int		 first;
	uint32_t	 packet_ssrc = rtp_my_ssrc(session);

	gettimeofday(&event_ts, NULL);
	if (buflen > 0) {
		if (session->encryption_enabled)
		{
			/* Decrypt the packet... */
			(session->decrypt_func)(session->encrypt_userdata, buffer, &buflen);
			buffer += 4;	/* Skip the random prefix... */
			buflen -= 4;
		}
		if (validate_rtcp(buffer, buflen)) {
			first  = TRUE;
			packet = (rtcp_t *) buffer;
			while (packet < (rtcp_t *) (buffer + buflen)) {
				switch (packet->common.pt) {
					case RTCP_SR:
						if (first && !filter_event(session, ntohl(packet->r.sr.sr.ssrc))) {
							event.ssrc  = ntohl(packet->r.sr.sr.ssrc);
							event.type  = RX_RTCP_START;
							event.data  = &buflen;
							event.ts    = &event_ts;
							packet_ssrc = event.ssrc;
							session->callback(session, &event);
						}
						process_rtcp_sr(session, packet, &event_ts);
						break;
					case RTCP_RR:
						if (first && !filter_event(session, ntohl(packet->r.rr.ssrc))) {
							event.ssrc  = ntohl(packet->r.rr.ssrc);
							event.type  = RX_RTCP_START;
							event.data  = &buflen;
							event.ts    = &event_ts;
							packet_ssrc = event.ssrc;
							session->callback(session, &event);
						}
						process_rtcp_rr(session, packet, &event_ts);
						break;
					case RTCP_SDES:
						if (first && !filter_event(session, ntohl(packet->r.sdes.ssrc))) {
							event.ssrc  = ntohl(packet->r.sdes.ssrc);
							event.type  = RX_RTCP_START;
							event.data  = &buflen;
							event.ts    = &event_ts;
							packet_ssrc = event.ssrc;
							session->callback(session, &event);
						}
						process_rtcp_sdes(session, packet, &event_ts);
						break;
					case RTCP_BYE:
						if (first && !filter_event(session, ntohl(packet->r.bye.ssrc[0]))) {
							event.ssrc  = ntohl(packet->r.bye.ssrc[0]);
							event.type  = RX_RTCP_START;
							event.data  = &buflen;
							event.ts    = &event_ts;
							packet_ssrc = event.ssrc;
							session->callback(session, &event);
						}
						process_rtcp_bye(session, packet, &event_ts);
						break;
				        case RTCP_APP:
						if (first && !filter_event(session, ntohl(packet->r.app.ssrc))) {
							event.ssrc  = ntohl(packet->r.app.ssrc);
							event.type  = RX_RTCP_START;
							event.data  = &buflen;
							event.ts    = &event_ts;
							packet_ssrc = event.ssrc;
							session->callback(session, &event);
						}
					        process_rtcp_app(session, packet, &event_ts);
						break;
					default: 
						rtp_message(LOG_WARNING, "RTCP packet with unknown type (%d) ignored.", packet->common.pt);
						break;
				}
				packet = (rtcp_t *) ((uint8_t *) packet + (4 * (ntohs(packet->common.length) + 1)));
				first  = FALSE;
			}
			if (session->avg_rtcp_size < 0) {
				/* This is the first RTCP packet we've received, set our initial estimate */
				/* of the average  packet size to be the size of this packet.             */
				session->avg_rtcp_size = buflen + RTP_LOWER_LAYER_OVERHEAD;
			} else {
				/* Update our estimate of the average RTCP packet size. The constants are */
				/* 1/16 and 15/16 (section 6.3.3 of draft-ietf-avt-rtp-new-02.txt).       */
				session->avg_rtcp_size = (0.0625 * (buflen + RTP_LOWER_LAYER_OVERHEAD)) + (0.9375 * session->avg_rtcp_size);
			}
			/* Signal that we've finished processing this packet */
			if (!filter_event(session, packet_ssrc)) {
				event.ssrc = packet_ssrc;
				event.type = RX_RTCP_FINISH;
				event.data = NULL;
				event.ts   = &event_ts;
				session->callback(session, &event);
			}
		} else {
			rtp_message(LOG_INFO, "Invalid RTCP packet discarded");
			session->invalid_rtcp_count++;
		}
	}
}

/**
 * rtp_recv:
 * @session: the session pointer (returned by rtp_init())
 * @timeout: the amount of time that rtcp_recv() is allowed to block
 * @curr_rtp_ts: the current time expressed in units of the media
 * timestamp.
 *
 * Receive RTP packets and dispatch them.
 *
 * Returns: TRUE if data received, FALSE if the timeout occurred.
 */
int rtp_recv(struct rtp *session, struct timeval *timeout, uint32_t curr_rtp_ts)
{
	check_database(session);
	udp_fd_zero();
	udp_fd_set(session->rtp_socket);
	udp_fd_set(session->rtcp_socket);
	if (udp_select(timeout) > 0) {
		if (udp_fd_isset(session->rtp_socket)) {
			rtp_recv_data(session, curr_rtp_ts);
		}
		if (udp_fd_isset(session->rtcp_socket)) {
                        uint8_t		 buffer[RTP_MAX_PACKET_LEN];
                        int		 buflen;
                        buflen = udp_recv(session->rtcp_socket, buffer, RTP_MAX_PACKET_LEN);
			rtp_process_ctrl(session, buffer, buflen);
		}
		check_database(session);
                return TRUE;
	}
	check_database(session);
        return FALSE;
}



/**
 * rtp_add_csrc:
 * @session: the session pointer (returned by rtp_init()) 
 * @csrc: Const

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲午夜免费电影| 色欧美片视频在线观看在线视频| 国产精品1区二区.| 一本大道av一区二区在线播放| 欧美日韩国产电影| 国产精品久久久99| 免费不卡在线视频| 在线视频一区二区免费| 国产亚洲成年网址在线观看| 亚洲bt欧美bt精品777| www.av亚洲| 国产欧美一区二区在线观看| 日本欧美加勒比视频| 日本高清不卡在线观看| 欧美国产精品久久| 激情久久五月天| 777欧美精品| 亚洲国产cao| 91在线一区二区| 国产欧美日韩在线看| 久久精品国产色蜜蜜麻豆| 欧美亚洲动漫另类| 亚洲人一二三区| www.日韩精品| 国产精品精品国产色婷婷| 国产福利一区在线| 久久中文字幕电影| 国内精品免费在线观看| 日韩视频在线永久播放| 蜜桃一区二区三区在线| 欧美欧美午夜aⅴ在线观看| 亚洲一区在线播放| 欧美午夜精品一区| 性做久久久久久免费观看| 色婷婷av一区二区三区gif| 中文字幕一区二区三区四区不卡 | 欧美日韩一区 二区 三区 久久精品| 国产精品国产三级国产aⅴ无密码| 狠狠色丁香婷综合久久| ww久久中文字幕| 国产精品中文欧美| 欧美v亚洲v综合ⅴ国产v| 久久精品99国产精品日本| 欧美一级片在线观看| 美女性感视频久久| 国产亚洲欧美日韩日本| 成人精品gif动图一区| 中文字幕一区二区三区视频 | 日韩av不卡在线观看| 91精品国产综合久久精品app | 婷婷国产v国产偷v亚洲高清| 欧美高清视频www夜色资源网| 亚洲丰满少妇videoshd| 欧美一区二区视频免费观看| 日本不卡的三区四区五区| 久久久久9999亚洲精品| 国产成a人无v码亚洲福利| 国产精品久久久久久久久动漫| 一本久久综合亚洲鲁鲁五月天 | 亚洲色图另类专区| 欧美怡红院视频| 日韩电影网1区2区| 久久九九久精品国产免费直播| www.成人在线| 男人操女人的视频在线观看欧美| 欧美草草影院在线视频| 成人91在线观看| 丝袜美腿成人在线| 国产欧美精品在线观看| 在线视频国产一区| 紧缚捆绑精品一区二区| 亚洲色欲色欲www| 日韩精品一区二区三区蜜臀| 高清在线观看日韩| 午夜视黄欧洲亚洲| 欧美高清在线一区二区| 欧美日韩情趣电影| 丁香六月综合激情| 日韩精品福利网| 亚洲欧洲色图综合| 日韩午夜激情免费电影| 99精品一区二区三区| 久久99九九99精品| 亚洲一区二区三区四区五区黄| 精品国产一区二区三区不卡 | 欧美岛国在线观看| 99国产精品久久久久| 久久成人免费网| 夜夜爽夜夜爽精品视频| 久久免费美女视频| 在线电影国产精品| 色综合一个色综合| 国产美女精品一区二区三区| 亚洲成av人在线观看| 国产精品蜜臀av| 久久久久久久综合| 欧美一区二区在线看| 欧美伊人久久久久久久久影院 | 精品一区二区三区不卡| 亚洲国产sm捆绑调教视频| 欧美国产一区视频在线观看| 日韩欧美国产一区二区在线播放 | 精品国产三级a在线观看| 欧美三区在线观看| 日本韩国精品在线| 色婷婷久久久久swag精品| 国产成人午夜精品影院观看视频 | 日韩不卡一二三区| 亚洲一区视频在线| 亚洲国产精品一区二区www在线| 1区2区3区国产精品| 国产精品嫩草影院av蜜臀| 久久久久久夜精品精品免费| 精品久久久久一区| 精品理论电影在线| 亚洲成av人综合在线观看| 亚洲精品欧美综合四区| 日韩毛片高清在线播放| 中文字幕日本不卡| 亚洲视频电影在线| 亚洲综合丁香婷婷六月香| 亚洲精品视频一区| 五月综合激情网| 日日夜夜精品视频免费| 日韩福利视频网| 久久99久久精品欧美| 久久99蜜桃精品| 国产老肥熟一区二区三区| 国产成人免费9x9x人网站视频| 国产精品一区二区果冻传媒| 成人免费视频播放| 色婷婷精品大视频在线蜜桃视频 | 国产.欧美.日韩| 99久久伊人久久99| 欧美偷拍一区二区| 欧美一卡2卡三卡4卡5免费| 欧美va亚洲va香蕉在线| 久久精品免费在线观看| 亚洲少妇屁股交4| 首页国产丝袜综合| 国产成人av一区| 欧美中文字幕一区| 日韩午夜av一区| 国产精品国产精品国产专区不蜜| 亚洲靠逼com| 裸体在线国模精品偷拍| 成人精品小蝌蚪| 欧美日韩高清一区二区三区| 欧美sm极限捆绑bd| 中文字幕亚洲电影| 日韩在线一区二区| 国产宾馆实践打屁股91| 91在线免费视频观看| 欧美顶级少妇做爰| 中文字幕视频一区二区三区久| 亚洲www啪成人一区二区麻豆| 国产麻豆成人传媒免费观看| 97久久精品人人爽人人爽蜜臀| 欧美视频一区二区三区在线观看| 欧美电视剧免费观看| 亚洲人吸女人奶水| 韩国av一区二区三区在线观看| av资源网一区| 日韩欧美成人激情| 亚洲精品视频在线看| 蜜乳av一区二区| 91免费视频网址| 精品日韩欧美在线| 亚洲一区成人在线| 成人黄色大片在线观看| 欧美成人艳星乳罩| 亚洲线精品一区二区三区| 国产美女娇喘av呻吟久久| 欧美三级日韩三级国产三级| 国产女主播一区| 麻豆一区二区99久久久久| 色婷婷综合五月| 国产精品污污网站在线观看| 日本伊人色综合网| 欧美性色黄大片手机版| 国产精品美日韩| 国产麻豆成人精品| 日韩免费看的电影| 日韩精品一区第一页| 在线观看不卡视频| 国产精品免费视频网站| 激情六月婷婷综合| 欧美刺激午夜性久久久久久久| 亚洲影院理伦片| 色呦呦一区二区三区| 日本一区二区成人在线| 国产综合久久久久久久久久久久| 欧美一区二区三区日韩| 亚洲国产成人91porn| 日本大香伊一区二区三区| 国产精品久久久久久福利一牛影视 | 在线看不卡av| 亚洲欧美另类小说| caoporn国产精品| 国产精品久久久久影院老司|