?? hust_rtcpcycle_qiu_5.20.c
字號:
/*------------------------------------------------------------------------- * rtcpcycle.c - rtcpcycle, rtcpcycleupdate *------------------------------------------------------------------------- */#include <ipOS.h>#include <ipHAL.h>#include <ipStack.h>#include <ipEthernet.h>#include "hust_rtp.h"#include "hust_rtplibcommon.h"#include "hust_rtcp.h"#include "hust_event.h"#include "hust_hash.h"#include "hust_util.h"///#include <time.h>///#include <util.h>///#include <rtp.h>///#include <hash.h>///#include <rtcp.h>///#include <unistd.h>///#include <stdlib.h>/*------------------------------------------------------------------------ * rtcpcycle - do cyclic update on streams and genereate receiver reports. * Rtcycle returns seconds to wait until next rtcpcycle. *------------------------------------------------------------------------ */doublertcpcycle(struct session *psn){ struct rtcp *prtcp, *ppacket; struct rr *prr; struct rblock *prb; int i, count, packets, bytes, active; int streamcount; ssrc_t *sources; struct stream **pstreams; /* * Get pointers to pre-allocated (in rtpopen) memory. */ ////sources = psn->sn_cyclesources; sources=(ssrc_t*)heap_alloc(sizeof(ssrc_t)*RTCP_RRMAXRBLOCKS); pstreams = (struct stream **) sources; /* * Get list of sources in session. */ streamcount = rtpsources(psn, sources, RTCP_RRMAXRBLOCKS); if (streamcount <= 0) return rtcpinterval(1, 0, psn->sn_bw * RTCP_BWFRAC, FALSE, 0, &psn->sn_avgrtcp, FALSE); /* * Iterate over SSRC list. Lookup each stream and * determins if stream was active in previous RTCP * cycle. */ for (i = 0, active = 0; i < streamcount; i++) { /* * Hold on to the 32-bit pointers that will be returned * by rtpgetstream in the space previously used by the * 32-bit SSRC ID. The pointer is needed to release the * stream structure later by calling rtpreleasestream. */ pstreams[i] = rtpgetstream(psn, sources[i]); if (pstreams[i] == NULL) continue; if (!RTP_INACTIVE(pstreams[i]->stm_inactive) && RTP_DATASEEN(pstreams[i])) { active++; /* * Mark this stream for rblock generation. */ pstreams[i]->stm_mark = TRUE; } } /* * Determine how many RTCP packets (within a compund packet * must be sent. Each RTCP receiver report packet can hold only * 31 reveiver report blocks (rblocks). */ packets = active / RTCP_MAXRBLOCKS + ((active % RTCP_MAXRBLOCKS) != 0); bytes = active * sizeof(struct rblock) + packets * (RTCP_HEADERSZ + sizeof(ssrc_t)); ////ppacket = (struct rtcp *) psn->sn_cyclebuf; ppacket=(struct rtcp*)heap_alloc(packets*(sizeof(struct rr)+sizeof(struct rtcp))+active*sizeof(struct rblock)); prtcp = ppacket; prr = (struct rr *) prtcp->rtcp_data; prb = (struct rblock *) prr->rr_rb; /* * Iterate over the list of streams again, calling * rtcpcycleupdate on each to update its statistics * and generate an rblock if the streams stm_mark * flag is set. */ for (i = 0, count = 0; i < streamcount; i++) { if (pstreams[i] == NULL) continue; if (rtcpcycleupdate(psn, pstreams[i], prb) == FALSE) continue; count++; prb++; if (count == RTCP_MAXRBLOCKS || i + 1 == streamcount) { /* * An RTCP receiver report can only hold 31 report blocks. * When the maximum is reached *or* the last source in * the list of SSRCs is processed, generate an RTCP header. */ rtcpheader(prtcp, count, RTCP_RR, sizeof(struct rblock) * count + RTCP_HEADERSZ + sizeof(ssrc_t)); ///prtcp->rtcp_length = htons(prtcp->rtcp_length); ///prr->rr_ssrc = htonl(psn->sn_ssrc); /* * If there are streams remaining in the list, * advance the pointers to the next rtcp packet. */ if (i + 1 != streamcount) { prtcp = (struct rtcp *) (prb + 1); prr = (struct rr *) prtcp->rtcp_data; prb = (struct rblock *) prr->rr_rb; count = 0; } } } /* * Send the compound RTCP packet. *///// rtcpsend(psn, ppacket, bytes); rtcpsend(psn,ppacket,bytes); /* * Release all the streams. */ for (i = 0; i < streamcount; i++) if (pstreams[i] != NULL) rtpreleasestream(psn, pstreams[i]); /* * Return the number of seconds to wait before invoking * rtcpcycle again. */ return rtcpinterval(streamcount + 1, active, psn->sn_bw * RTCP_BWFRAC, FALSE, bytes + 28, &psn->sn_avgrtcp, FALSE);}/*------------------------------------------------------------------------ * rtcpcycleupdate - update stream stats and generate an rblock if * requested. Rtcpcycleupdate returns TRUE if an rblock is generated. *------------------------------------------------------------------------ */boolrtcpcycleupdate(struct session *psn, struct stream *pstm, struct rblock *prb){ int exthiseq, cumexpected, lostcycle, expcycle, reccycle; int cumlost; u32_t now;/// pthread_mutex_lock(&pstm->stm_mutex); /* * Determine if the participant has timed out. */ if (RTP_DATASEEN(pstm) == FALSE && !RTP_INACTIVE(pstm->stm_inactive)) if (++pstm->stm_inactive >= pstm->stm_inactthresh && pstm->stm_inactthresh != RTP_INFINITEINACTIVETHRESH) { pstm->stm_inactive = RTP_TIMEDOUT;/// pthread_mutex_unlock(&pstm->stm_mutex); rtpstreamcleanup(psn, pstm); rtppostevent(psn, EVENT_PARTICIPANT_TIMEOUT, pstm->stm_ssrc, NULL, 0); return FALSE; } /* * Update statistics that must be updated once per * RTCP cycle. */ exthiseq = (pstm->stm_roll << 16) | pstm->stm_hiseq; /////擴(kuò)展的最大序列號 cumexpected = exthiseq - pstm->stm_firstseq + 1; /////期望收到的包數(shù) cumlost = cumexpected - pstm->stm_packets; ///丟失的包數(shù) /* * If the stream is marked for rblock generation * write the rblock in the area pointed to by prb. */ if (pstm->stm_mark == TRUE && prb != NULL) {/// prb->rb_ssrc = htonl(pstm->stm_ssrc);/// prb->rb_hiseq = htonl(exthiseq);/// prb->rb_jitter = htonl((unsigned int) pstm->stm_jitter); prb->rb_ssrc = pstm->stm_ssrc; prb->rb_hiseq =exthiseq; prb->rb_jitter =(unsigned long int) pstm->stm_jitter; /* * Cap cumlost to appropriate max/min values for * a 24-bit signed integer. *///// prb->rb_cumlost = hton24(max(min(cumexpected - (int) pstm->stm_packets, 0x7fffff), -(1 << 23))); prb->rb_cumlost = min(cumlost, 0x7fffff); expcycle = cumexpected - pstm->stm_expprior; reccycle = pstm->stm_packets - pstm->stm_recprior; lostcycle = max(expcycle - reccycle, 0); prb->rb_fraclost = (expcycle == 0 ? 0 : (lostcycle << 8) / expcycle); /* * Extract middle 32 bits of last sender * report NTP timestamp. *//// prb->rb_lastsrts = htonl(((pstm->stm_lastntp[1] & 0x0000ffff) << 16) |/// ((pstm->stm_lastntp[0] & 0xffff0000) >> 16)); prb->rb_lastsrts =((pstm->stm_lastntp[1] & 0x0000ffff) << 16)|((pstm->stm_lastntp[0] & 0xffff0000) >> 16); /* * Compute the delay since last sender * report, if one has been received. */ if (pstm->stm_lastsr!= 0) { now=timer_get_ticks();/// prb->rb_delay = htonl(timeflatten(timesub(now, pstm->stm_lastsr), 65536)); prb->rb_delay = timeflatten((now-pstm->stm_lastsr),65536);//////時間的最小精度由time_init設(shè)定,這里不是標(biāo)準(zhǔn)的做法 //////標(biāo)準(zhǔn):delay的單位為1/65536秒 } } pstm->stm_expprior = cumexpected; pstm->stm_recprior = pstm->stm_packets;/// pthread_mutex_unlock(&pstm->stm_mutex); if (pstm->stm_mark == TRUE) { pstm->stm_mark = FALSE; return TRUE; } else return FALSE;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -