📄 rtprtcpmodule.cpp
字号:
hdr = (RTCPHeader *)packetbuffer; hdr->version = RTP_VERSION; hdr->packettype = TYPE_RTCP_RR; hdr->padding = 0; hdr->blockcount = 0; hdr->length = htons((sizeof(RTCPHeader)+sizeof(SSRCPrefix))/sizeof(RTPuint32)-1); ssrcpref = (SSRCPrefix *)(packetbuffer+sizeof(RTCPHeader)); ssrcpref->ssrc = contribsrcs->localinfo.src; // already in network byte order packetoffset = sizeof(RTCPHeader)+sizeof(SSRCPrefix); } if (needrtcphdr) { needrtcphdr = false; hdr = (RTCPHeader *)(packetbuffer + packetoffset); hdr->version = RTP_VERSION; hdr->packettype = TYPE_RTCP_SDES; hdr->padding = 0; blockcount = 0; length = sizeof(RTCPHeader); packetoffset += sizeof(RTCPHeader); haveheader = true; } if (needsrchdr) { needsrchdr = false; ssrcpref = (SSRCPrefix *)(packetbuffer + packetoffset); ssrcpref->ssrc = cursrc->src; // already in network byte order packetoffset += sizeof(SSRCPrefix); length += sizeof(SSRCPrefix); blockcount++; } sdespref = (SDESPrefix *)(packetbuffer + packetoffset); sdespref->sdestype = sdespos+1; sdespref->length = sdeslen; length += sizeof(SDESPrefix); packetoffset += sizeof(SDESPrefix); if (sdeslen > 0) { memcpy(packetbuffer+packetoffset,cursrc->sdesinfo[sdespos],sdeslen); length += sdeslen; packetoffset += sdeslen; } } } if (increment) { sdespos++; if (sdespos == RTP_NUM_SDES_INDICES) { sdespos = 0; cursrc = cursrc->next; needsrchdr = true; packetbuffer[packetoffset++] = 0; // end of chunk length++; // fill till 32 bit boundary if ((mod = (length%sizeof(RTPuint32))) != 0) { while (mod != sizeof(RTPuint32)) { packetbuffer[packetoffset++] = 0; length++; mod++; } } if (blockcount == 31) // max number of chunks in a block { hdr->length = htons(length/sizeof(RTPuint32)-1); hdr->blockcount = blockcount; needrtcphdr = true; } } } } if (haveheader) { // fill till 32 bit boundary if ((mod = (length%sizeof(RTPuint32))) != 0) { while (mod != sizeof(RTPuint32)) { packetbuffer[packetoffset++] = 0; length++; mod++; } } hdr->length = htons(length/sizeof(RTPuint32)-1); hdr->blockcount = blockcount; } return 0;}int RTPRTCPModule::ProcessAPPData(){ RTPExceptionHandler apphandler; RTCPAPPPrefix *apppref; RTCPHeader *hdr; SSRCPrefix *ssrcpref; void *usrdata; bool done,gotdata; int prevreturn,size,status; if ((apphandler = handlers->handlers[RTP_EXCEPTION_TRANSMITRTCPAPPDATA].handler) == NULL) return 0; usrdata = handlers->handlers[RTP_EXCEPTION_TRANSMITRTCPAPPDATA].usrdata; done = false; gotdata = false; prevreturn = 0; size = 0; while (!done) { if (!gotdata) { ex_appdata.subtype = 0; // by default: use local ssrc ex_appdata.src = ntohl(contribsrcs->localinfo.src); ex_appdata.name[0] = ' '; ex_appdata.name[1] = ' '; ex_appdata.name[2] = ' '; ex_appdata.name[3] = ' '; ex_appdata.data = NULL; ex_appdata.numwords = 0; ex_appdata.validdata = false; ex_appdata.prevreturnval = prevreturn; apphandler(RTP_EXCEPTION_TRANSMITRTCPAPPDATA,&ex_appdata,usrdata); if (!ex_appdata.validdata) done = true; else if (ex_appdata.subtype > 31) prevreturn = ERR_RTP_SUBTYPETOOLARGE; else // check if the data can possibly fit { if (ex_appdata.numwords < 0) ex_appdata.numwords = 0; // first take an empty RR packet size = sizeof(RTCPHeader)+sizeof(SSRCPrefix); // add the APP packet size += sizeof(RTCPHeader)+sizeof(RTCPAPPPrefix); size += ex_appdata.numwords*sizeof(RTPuint32); if (size > maxpacksize) prevreturn = ERR_RTP_PACKETTOOLARGE; else { gotdata = true; prevreturn = 0; } } } else // try to put the data in a packet { if ((packetoffset + size) > maxpacksize) { if ((status = SendPacketData()) < 0) return status; } else { if (packetoffset == 0) { hdr = (RTCPHeader *)packetbuffer; hdr->version = RTP_VERSION; hdr->padding = 0; hdr->blockcount = 0; hdr->length = htons(((sizeof(RTCPHeader)+sizeof(SSRCPrefix))/sizeof(RTPuint32))-1); hdr->packettype = TYPE_RTCP_RR; ssrcpref = (SSRCPrefix *)(packetbuffer+sizeof(RTCPHeader)); ssrcpref->ssrc = contribsrcs->localinfo.src; // already in network byte order packetoffset = sizeof(RTCPHeader)+sizeof(SSRCPrefix); } hdr = (RTCPHeader *)(packetbuffer+packetoffset); hdr->version = RTP_VERSION; hdr->padding = 0; hdr->blockcount = ex_appdata.subtype; hdr->packettype = TYPE_RTCP_APP; hdr->length = htons(ex_appdata.numwords+(sizeof(RTCPHeader)+sizeof(RTCPAPPPrefix))/sizeof(RTPuint32)-1); packetoffset += sizeof(RTCPHeader); apppref = (RTCPAPPPrefix *)(packetbuffer+packetoffset); apppref->src = htonl(ex_appdata.src); apppref->name[0] = ex_appdata.name[0]; apppref->name[1] = ex_appdata.name[1]; apppref->name[2] = ex_appdata.name[2]; apppref->name[3] = ex_appdata.name[3]; packetoffset += sizeof(RTCPAPPPrefix); if (ex_appdata.numwords > 0) { memcpy(packetbuffer+packetoffset,ex_appdata.data,ex_appdata.numwords*sizeof(RTPuint32)); packetoffset += ex_appdata.numwords*sizeof(RTPuint32); } gotdata = false; } } } return 0;}int RTPRTCPModule::ProcessBYEMessage(){ bool needbyehdr,mustsetfields; int length,status,blockcount,add; RTPSourceDescription *cursrc; RTCPHeader *hdr; SSRCPrefix *ssrcpref; length = 0; blockcount = 0; hdr = NULL; cursrc = &(contribsrcs->localinfo); mustsetfields = false; needbyehdr = true; while (cursrc != NULL) { if (packetoffset == 0) { hdr = (RTCPHeader *)packetbuffer; hdr->blockcount = 0; hdr->padding = 0; hdr->version = RTP_VERSION; hdr->packettype = TYPE_RTCP_RR; hdr->length = htons(((sizeof(RTCPHeader)+sizeof(SSRCPrefix))/sizeof(RTPuint32))-1); ssrcpref = (SSRCPrefix *)(packetbuffer+sizeof(RTCPHeader)); ssrcpref->ssrc = contribsrcs->localinfo.src; // already in network byte order packetoffset = sizeof(RTCPHeader)+sizeof(SSRCPrefix); needbyehdr = true; mustsetfields = false; } else { if (needbyehdr) add = sizeof(RTCPHeader); else add = 0; if ((int)(packetoffset+add+sizeof(SSRCPrefix)) > maxpacksize) { if (mustsetfields) { hdr->length = htons(length); hdr->blockcount = blockcount; } if ((status = SendPacketData()) < 0) return status; needbyehdr = true; mustsetfields = false; } else { if (needbyehdr) { hdr = (RTCPHeader *)(packetbuffer+packetoffset); hdr->version = RTP_VERSION; hdr->padding = 0; hdr->packettype = TYPE_RTCP_BYE; mustsetfields = true; length = sizeof(RTCPHeader)/sizeof(RTPuint32)-1; blockcount = 0; packetoffset += sizeof(RTCPHeader); needbyehdr = false; } ssrcpref = (SSRCPrefix *)(packetbuffer + packetoffset); ssrcpref->ssrc = cursrc->src; // already in network byte order packetoffset += sizeof(SSRCPrefix); length += sizeof(SSRCPrefix)/sizeof(RTPuint32); blockcount++; if (blockcount == 31) { hdr->length = htons(length); hdr->blockcount = blockcount; needbyehdr = true; mustsetfields = false; } cursrc = cursrc->next; } } } if (mustsetfields) { hdr->blockcount = blockcount; hdr->length = htons(length); } return 0;}inline int RTPRTCPModule::SendPacketData(){ int status; status = rtpconn->SendRTCPCompoundData(packetbuffer,packetoffset); if (status < 0) return status; sendcount += packetoffset; packetoffset = 0; return 0;}void RTPRTCPModule::GetRRParams(RTPSourceData *src,RTCPReportBlock *rr){ struct timeval tv; long diffsec,diffusec; double diff,f,f2; RTPuint32 ext,prevext; long packlost; RTPuint32 lsr; // source rr->ssrc = htonl(src->ssrc); // dlsr & lsr if (src->sr.srreceived) { // dlsr gettimeofday(&tv,NULL); diffsec = tv.tv_sec-src->sr.srtime.tv_sec; diffusec = tv.tv_usec-src->sr.srtime.tv_usec; while (diffusec < 0) { diffsec--; diffusec += 1000000; } diff = (double)diffsec+(((double)diffusec)/1000000.0); diff *= 65536; rr->dlsr = htonl((RTPuint32)diff); // lsr lsr = ((src->sr.ntpmsw&65535)<<16)|((src->sr.ntplsw>>16)&65535); rr->lsr = htonl(lsr); } else { rr->dlsr = htonl(0); rr->lsr = htonl(0); } // ext highest seqnum ext = src->stats.maxseq; rr->exthsnr = htonl(ext); // fraction lost prevext = src->stats.prevmaxseq; f = (double)(ext-prevext); f2 = f-(double)src->stats.numnewpackets; f = f2/f; if (f < 0) f = 0; rr->fractionlost = (unsigned char)(f*256.0); // jitter rr->jitter = htonl(src->stats.jitter); // packets lost packlost = (long)(ext-src->stats.seqbase); packlost -= src->stats.numpacketsreceived; rr->packetslost[2] = packlost&255; rr->packetslost[1] = (packlost>>8)&255; rr->packetslost[0] = (packlost>>16)&255;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -