mirror of
				https://github.com/pion/webrtc.git
				synced 2025-10-31 10:46:39 +08:00 
			
		
		
		
	Start RTCP package: add header parsing
This commit is contained in:
		 Max Hawkins
					Max Hawkins
				
			
				
					committed by
					
						 Michiel De Backker
						Michiel De Backker
					
				
			
			
				
	
			
			
			 Michiel De Backker
						Michiel De Backker
					
				
			
						parent
						
							e500917a6e
						
					
				
				
					commit
					998e370406
				
			
							
								
								
									
										106
									
								
								pkg/rtcp/packet.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								pkg/rtcp/packet.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| package rtcp | ||||
|  | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| // RTCP packet types registered with IANA. See: https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4 | ||||
| const ( | ||||
| 	TypeSR   = 200 // sender report        RFC 3550, 6.4.1 | ||||
| 	TypeRR   = 201 // receiver report      RFC 3550, 6.4.2 | ||||
| 	TypeSDES = 202 // source description   RFC 3550, 6.5 | ||||
| 	TypeBYE  = 203 // goodbye              RFC 3550, 6.6 | ||||
| 	TypeAPP  = 204 // application-defined  RFC 3550, 6.7 | ||||
| ) | ||||
|  | ||||
| // A Header is the common header shared by all RTCP packets | ||||
| type Header struct { | ||||
| 	// Identifies the version of RTP, which is the same in RTCP packets | ||||
| 	// as in RTP data packets. | ||||
| 	Version uint8 | ||||
| 	// If the padding bit is set, this individual RTCP packet contains | ||||
| 	// some additional padding octets at the end which are not part of | ||||
| 	// the control information but are included in the length field. | ||||
| 	Padding bool | ||||
| 	// The number of reception report blocks contained in this packet. | ||||
| 	ReportCount uint8 | ||||
| 	// The RTCP packet type for this packet | ||||
| 	Type uint8 | ||||
| 	// The length of this RTCP packet in 32-bit words minus one, | ||||
| 	// including the header and any padding. | ||||
| 	Length uint16 | ||||
| } | ||||
|  | ||||
| const ( | ||||
| 	headerLength     = 4 | ||||
| 	versionShift     = 6 | ||||
| 	versionMask      = 0x3 | ||||
| 	paddingShift     = 5 | ||||
| 	paddingMask      = 0x1 | ||||
| 	reportCountShift = 0 | ||||
| 	reportCountMask  = 0x1f | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errInvalidVersion     = errors.New("invalid version") | ||||
| 	errInvalidReportCount = errors.New("invalid report count") | ||||
| ) | ||||
|  | ||||
| // Marshal encodes the Header in binary | ||||
| func (h Header) Marshal() ([]byte, error) { | ||||
| 	/* | ||||
| 	 *  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 | ||||
| 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| 	 * |V=2|P|    RC   |   PT=SR=200   |             length            | | ||||
| 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| 	 */ | ||||
| 	rawPacket := make([]byte, headerLength) | ||||
|  | ||||
| 	if h.Version > 3 { | ||||
| 		return nil, errInvalidVersion | ||||
| 	} | ||||
| 	rawPacket[0] |= h.Version << versionShift | ||||
|  | ||||
| 	if h.Padding { | ||||
| 		rawPacket[0] |= 1 << paddingShift | ||||
| 	} | ||||
|  | ||||
| 	if h.ReportCount > 31 { | ||||
| 		return nil, errInvalidReportCount | ||||
| 	} | ||||
| 	rawPacket[0] |= h.ReportCount << reportCountShift | ||||
|  | ||||
| 	rawPacket[1] = h.Type | ||||
|  | ||||
| 	binary.BigEndian.PutUint16(rawPacket[2:], h.Length) | ||||
|  | ||||
| 	return rawPacket, nil | ||||
| } | ||||
|  | ||||
| // Unmarshal decodes the Header from binary | ||||
| func (h *Header) Unmarshal(rawPacket []byte) error { | ||||
| 	if len(rawPacket) < headerLength { | ||||
| 		return errors.Errorf("RTCP header size insufficient; %d < %d", len(rawPacket), headerLength) | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 *  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 | ||||
| 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| 	 * |V=2|P|    RC   |   PT=SR=200   |             length            | | ||||
| 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
| 	 */ | ||||
|  | ||||
| 	h.Version = rawPacket[0] >> versionShift & versionMask | ||||
| 	h.Padding = (rawPacket[0] >> paddingShift & paddingMask) > 0 | ||||
| 	h.ReportCount = rawPacket[0] >> reportCountShift & reportCountMask | ||||
|  | ||||
| 	h.Type = rawPacket[1] | ||||
|  | ||||
| 	h.Length = binary.BigEndian.Uint16(rawPacket[2:]) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user