📄 rtcpcompoundpacketbuilder.cpp
字号:
int RTCPCompoundPacketBuilder::AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength){ if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (numssrcs > 31) return ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS; size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*((size_t)numssrcs); size_t zerobytes = 0; if (reasonlength > 0) { packsize += 1; // 1 byte for the length; packsize += (size_t)reasonlength; size_t r = (packsize&0x03); if (r != 0) { zerobytes = 4-r; packsize += zerobytes; } } size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); if ((totalotherbytes + packsize) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; size_t numwords; buf = new uint8_t[packsize]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; hdr->version = 2; hdr->padding = 0; hdr->count = numssrcs; numwords = packsize/sizeof(uint32_t); hdr->length = htons((uint16_t)(numwords-1)); hdr->packettype = RTP_RTCPTYPE_BYE; uint32_t *sources = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); uint8_t srcindex; for (srcindex = 0 ; srcindex < numssrcs ; srcindex++) sources[srcindex] = htonl(ssrcs[srcindex]); if (reasonlength != 0) { size_t offset = sizeof(RTCPCommonHeader)+((size_t)numssrcs)*sizeof(uint32_t); buf[offset] = reasonlength; memcpy((buf+offset+1),reasondata,(size_t)reasonlength); for (size_t i = 0 ; i < zerobytes ; i++) buf[packsize-1-i] = 0; } byepackets.push_back(Buffer(buf,packsize)); byesize += packsize; return 0;}int RTCPCompoundPacketBuilder::AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen){ if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (subtype > 31) return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE; if ((appdatalen%4) != 0) return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH; size_t appdatawords = appdatalen/4; if ((appdatawords+2) > 65535) return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2+appdatalen; size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes(); if ((totalotherbytes + packsize) > maximumpacketsize) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; uint8_t *buf; buf = new uint8_t[packsize]; if (buf == 0) return ERR_RTP_OUTOFMEM; RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf; hdr->version = 2; hdr->padding = 0; hdr->count = subtype; hdr->length = htons((uint16_t)(appdatawords+2)); hdr->packettype = RTP_RTCPTYPE_APP; uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader)); *source = htonl(ssrc); buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+0] = name[0]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+1] = name[1]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+2] = name[2]; buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+3] = name[3]; if (appdatalen > 0) memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2),appdata,appdatalen); apppackets.push_back(Buffer(buf,packsize)); appsize += packsize; return 0;}int RTCPCompoundPacketBuilder::EndBuild(){ if (!arebuilding) return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; if (report.headerlength == 0) return ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT; uint8_t *buf; size_t len; len = appsize+byesize+report.NeededBytes()+sdes.NeededBytes(); if (!external) { buf = new uint8_t[len]; if (buf == 0) return ERR_RTP_OUTOFMEM; } else buf = buffer; uint8_t *curbuf = buf; RTCPPacket *p; // first, we'll add all report info { bool firstpacket = true; bool done = false; std::list<Buffer>::const_iterator it = report.reportblocks.begin(); do { RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; size_t offset; hdr->version = 2; hdr->padding = 0; if (firstpacket && report.isSR) { hdr->packettype = RTP_RTCPTYPE_SR; memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,report.headerlength); offset = sizeof(RTCPCommonHeader)+report.headerlength; } else { hdr->packettype = RTP_RTCPTYPE_RR; memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,sizeof(uint32_t)); offset = sizeof(RTCPCommonHeader)+sizeof(uint32_t); } firstpacket = false; uint8_t count = 0; while (it != report.reportblocks.end() && count < 31) { memcpy(curbuf+offset,(*it).packetdata,(*it).packetlength); offset += (*it).packetlength; count++; it++; } size_t numwords = offset/sizeof(uint32_t); hdr->length = htons((uint16_t)(numwords-1)); hdr->count = count; // add entry in parent's list if (hdr->packettype == RTP_RTCPTYPE_SR) p = new RTCPSRPacket(curbuf,offset); else p = new RTCPRRPacket(curbuf,offset); if (p == 0) { if (!external) delete [] buf; ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += offset; if (it == report.reportblocks.end()) done = true; } while (!done); } // then, we'll add the sdes info if (!sdes.sdessources.empty()) { bool done = false; std::list<SDESSource *>::const_iterator sourceit = sdes.sdessources.begin(); do { RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf; size_t offset = sizeof(RTCPCommonHeader); hdr->version = 2; hdr->padding = 0; hdr->packettype = RTP_RTCPTYPE_SDES; uint8_t sourcecount = 0; while (sourceit != sdes.sdessources.end() && sourcecount < 31) { uint32_t *ssrc = (uint32_t *)(curbuf+offset); *ssrc = htonl((*sourceit)->ssrc); offset += sizeof(uint32_t); std::list<Buffer>::const_iterator itemit,itemend; itemit = (*sourceit)->items.begin(); itemend = (*sourceit)->items.end(); while (itemit != itemend) { memcpy(curbuf+offset,(*itemit).packetdata,(*itemit).packetlength); offset += (*itemit).packetlength; itemit++; } curbuf[offset] = 0; // end of item list; offset++; size_t r = offset&0x03; if (r != 0) // align to 32 bit boundary { size_t num = 4-r; size_t i; for (i = 0 ; i < num ; i++) curbuf[offset+i] = 0; offset += num; } sourceit++; sourcecount++; } size_t numwords = offset/4; hdr->count = sourcecount; hdr->length = htons((uint16_t)(numwords-1)); p = new RTCPSDESPacket(curbuf,offset); if (p == 0) { if (!external) delete [] buf; ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += offset; if (sourceit == sdes.sdessources.end()) done = true; } while (!done); } // adding the app data { std::list<Buffer>::const_iterator it; for (it = apppackets.begin() ; it != apppackets.end() ; it++) { memcpy(curbuf,(*it).packetdata,(*it).packetlength); p = new RTCPAPPPacket(curbuf,(*it).packetlength); if (p == 0) { if (!external) delete [] buf; ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += (*it).packetlength; } } // adding bye packets { std::list<Buffer>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) { memcpy(curbuf,(*it).packetdata,(*it).packetlength); p = new RTCPBYEPacket(curbuf,(*it).packetlength); if (p == 0) { if (!external) delete [] buf; ClearPacketList(); return ERR_RTP_OUTOFMEM; } rtcppacklist.push_back(p); curbuf += (*it).packetlength; } } compoundpacket = buf; compoundpacketlength = len; arebuilding = false; ClearBuildBuffers(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -