123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- #include "../rtp_header_extension/rtp_header_extension_parser.h"
- #include <string.h>
- #include "../rtp_header_extension/rtp_header_extension_map.h"
- #include "../rtp_header_extension/byte_io.h"
- #include "../rtp_header_extension/rtp_header_extensions.h"
- class RTPHeaderExtensionParserImpl : public RTPHeaderExtensionParser {
- public:
- bool Parse(const uint8_t* packet,
- size_t length,
- RTPHeaderExtension* header,
- int *header_length);
- bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
- bool RegisterRtpHeaderExtension(RtpExtension extension) ;
- bool DeregisterRtpHeaderExtension(RTPExtensionType type) ;
- bool DeregisterRtpHeaderExtension(RtpExtension extension) ;
- private:
- RtpHeaderExtensionMap rtp_header_extension_map_;
- };
- RTPHeaderExtensionParser* RTPHeaderExtensionParser::Create() {
- return new RTPHeaderExtensionParserImpl();
- }
- bool RTPHeaderExtensionParserImpl::Parse(const uint8_t* packet,
- size_t length,
- RTPHeaderExtension* header,
- int *header_length) {
- RtpUtility::RTPHeaderExtensionParser rtp_parser(packet, length);
- *header = RTPHeaderExtension();
- RtpHeaderExtensionMap map;
- {
- map = rtp_header_extension_map_;
- }
- const bool valid_rtpheader = rtp_parser.Parse(header, &map, header_length);
- if (!valid_rtpheader) {
- return false;
- }
- return true;
- }
- bool RTPHeaderExtensionParserImpl::RegisterRtpHeaderExtension(RtpExtension extension) {
- return rtp_header_extension_map_.RegisterByUri(extension.id, extension.uri);
- }
- bool RTPHeaderExtensionParserImpl::RegisterRtpHeaderExtension(RTPExtensionType type,
- uint8_t id) {
- return rtp_header_extension_map_.RegisterByType(id, type);
- }
- bool RTPHeaderExtensionParserImpl::DeregisterRtpHeaderExtension(RtpExtension extension) {
- return rtp_header_extension_map_.Deregister(
- rtp_header_extension_map_.GetType(extension.id));
- }
- bool RTPHeaderExtensionParserImpl::DeregisterRtpHeaderExtension(RTPExtensionType type) {
- return rtp_header_extension_map_.Deregister(type) == 0;
- }
- namespace RtpUtility {
- RTPHeaderExtensionParser::RTPHeaderExtensionParser(const uint8_t* rtpData,
- const size_t rtpDataLength)
- : _ptrRTPDataBegin(rtpData),
- _ptrRTPDataEnd(rtpData ? (rtpData + rtpDataLength) : NULL) {}
- bool RTPHeaderExtensionParser::Parse(RTPHeaderExtension* header,
- const RtpHeaderExtensionMap* ptrExtensionMap,
- int *header_length) {
- const int length = _ptrRTPDataEnd - _ptrRTPDataBegin;
-
- const uint8_t* ptr = &_ptrRTPDataBegin[0];
- // If in effect, MAY be omitted for those packets for which the offset
- // is zero.
- header->hasTransmissionTimeOffset = false;
- header->transmissionTimeOffset = 0;
- // May not be present in packet.
- header->hasAbsoluteSendTime = false;
- header->absoluteSendTime = 0;
- // May not be present in packet.
- header->hasAudioLevel = false;
- header->voiceActivity = false;
- header->audioLevel = 0;
- // May not be present in packet.
- header->hasVideoRotation = false;
- header->videoRotation = kVideoRotation_0;
- // May not be present in packet.
- header->playout_delay.min_ms = -1;
- header->playout_delay.max_ms = -1;
- // May not be present in packet.
- header->hasVideoContentType = false;
- header->videoContentType = VideoContentType::UNSPECIFIED;
- *header_length = 0;
- /* RTP header extension, RFC 3550.
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | defined by profile | length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | header extension |
- | .... |
- */
- const int remain = _ptrRTPDataEnd - ptr;
- if (remain < 4) {
- return false;
- }
- *header_length += 4;
- uint16_t definedByProfile = ByteReader<uint16_t>::ReadBigEndian(ptr);
- ptr += 2;
- // in 32 bit words
- size_t XLen = ByteReader<uint16_t>::ReadBigEndian(ptr);
- ptr += 2;
- XLen *= 4; // in bytes
- if (static_cast<size_t>(remain) < (4 + XLen)) {
- return false;
- }
- static const uint16_t kRtpOneByteHeaderExtensionId = 0xBEDE;
- if (definedByProfile == kRtpOneByteHeaderExtensionId) {
- const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen;
- ParseOneByteExtensionHeader(header, ptrExtensionMap,
- ptrRTPDataExtensionEnd, ptr);
- }
- *header_length += XLen;
- if (*header_length > static_cast<size_t>(length))
- return false;
-
- return true;
- }
- void RTPHeaderExtensionParser::ParseOneByteExtensionHeader(
- RTPHeaderExtension* header,
- const RtpHeaderExtensionMap* ptrExtensionMap,
- const uint8_t* ptrRTPDataExtensionEnd,
- const uint8_t* ptr) const {
- if (!ptrExtensionMap) {
- return;
- }
- while (ptrRTPDataExtensionEnd - ptr > 0) {
- // 0
- // 0 1 2 3 4 5 6 7
- // +-+-+-+-+-+-+-+-+
- // | ID | len |
- // +-+-+-+-+-+-+-+-+
- // Note that 'len' is the header extension element length, which is the
- // number of bytes - 1.
- const int id = (*ptr & 0xf0) >> 4;
- const int len = (*ptr & 0x0f);
- ptr++;
- if (id == 0) {
- // Padding byte, skip ignoring len.
- continue;
- }
- if (id == 15) {
- return;
- }
- if (ptrRTPDataExtensionEnd - ptr < (len + 1)) {
- return;
- }
- RTPExtensionType type = ptrExtensionMap->GetType(id);
- if (type == RtpHeaderExtensionMap::kInvalidType) {
- // If we encounter an unknown extension, just skip over it.
- } else {
- switch (type) {
- case kRtpExtensionTransmissionTimeOffset: {
- if (len != 2) {
- return;
- }
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=2 | transmission offset |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header->transmissionTimeOffset =
- ByteReader<int32_t, 3>::ReadBigEndian(ptr);
- header->hasTransmissionTimeOffset = true;
- break;
- }
- case kRtpExtensionAudioLevel: {
- if (len != 0) {
- return;
- }
- // 0 1
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=0 |V| level |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
- header->audioLevel = ptr[0] & 0x7f;
- header->voiceActivity = (ptr[0] & 0x80) != 0;
- header->hasAudioLevel = true;
- break;
- }
- case kRtpExtensionAbsoluteSendTime: {
- if (len != 2) {
- return;
- }
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=2 | absolute send time |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header->absoluteSendTime =
- ByteReader<uint32_t, 3>::ReadBigEndian(ptr);
- header->hasAbsoluteSendTime = true;
- break;
- }
- case kRtpExtensionVideoRotation: {
- if (len != 0) {
- return;
- }
- // 0 1
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=0 |0 0 0 0 C F R R|
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header->hasVideoRotation = true;
- header->videoRotation =
- ConvertCVOByteToVideoRotation(ptr[0]);
- break;
- }
- case kRtpExtensionTransportSequenceNumber: {
- if (len != 1) {
- return;
- }
- // 0 1 2
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | L=1 |transport wide sequence number |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- uint16_t sequence_number = ptr[0] << 8;
- sequence_number += ptr[1];
- header->transportSequenceNumber = sequence_number;
- header->hasTransportSequenceNumber = true;
- break;
- }
- case kRtpExtensionPlayoutDelay: {
- if (len != 2) {
- return;
- }
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=2 | MIN delay | MAX delay |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- int min_playout_delay = (ptr[0] << 4) | ((ptr[1] >> 4) & 0xf);
- int max_playout_delay = ((ptr[1] & 0xf) << 8) | ptr[2];
- header->playout_delay.min_ms =
- min_playout_delay * PlayoutDelayLimits::kGranularityMs;
- header->playout_delay.max_ms =
- max_playout_delay * PlayoutDelayLimits::kGranularityMs;
- break;
- }
- case kRtpExtensionVideoContentType: {
- if (len != 0) {
- return;
- }
- // 0 1
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | ID | len=0 | Content type |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- header->hasVideoContentType = true;
- header->videoContentType =
- static_cast<VideoContentType>(ptr[0]);
-
- break;
- }
- case kRtpExtensionRtpStreamId: {
- std::string name(reinterpret_cast<const char*>(ptr), len + 1);
- header->stream_id = name;
- break;
- }
- case kRtpExtensionRepairedRtpStreamId: {
- std::string name(reinterpret_cast<const char*>(ptr), len + 1);
- header->repaired_stream_id = name;
- break;
- }
- case kRtpExtensionMid: {
- std::string name(reinterpret_cast<const char*>(ptr), len + 1);
- header->mid = name;
- break;
- }
- case kRtpExtensionNone:
- case kRtpExtensionNumberOfExtensions: {
- return;
- }
- }
- }
- ptr += (len + 1);
- }
- }
- }
|