summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/rtcp/packet.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/rtcp/packet.go')
-rw-r--r--vendor/github.com/pion/rtcp/packet.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/vendor/github.com/pion/rtcp/packet.go b/vendor/github.com/pion/rtcp/packet.go
new file mode 100644
index 0000000..de08003
--- /dev/null
+++ b/vendor/github.com/pion/rtcp/packet.go
@@ -0,0 +1,115 @@
+package rtcp
+
+// Packet represents an RTCP packet, a protocol used for out-of-band statistics and control information for an RTP session
+type Packet interface {
+ // DestinationSSRC returns an array of SSRC values that this packet refers to.
+ DestinationSSRC() []uint32
+
+ Marshal() ([]byte, error)
+ Unmarshal(rawPacket []byte) error
+}
+
+// Unmarshal takes an entire udp datagram (which may consist of multiple RTCP packets) and
+// returns the unmarshaled packets it contains.
+//
+// If this is a reduced-size RTCP packet a feedback packet (Goodbye, SliceLossIndication, etc)
+// will be returned. Otherwise, the underlying type of the returned packet will be
+// CompoundPacket.
+func Unmarshal(rawData []byte) ([]Packet, error) {
+ var packets []Packet
+ for len(rawData) != 0 {
+ p, processed, err := unmarshal(rawData)
+ if err != nil {
+ return nil, err
+ }
+
+ packets = append(packets, p)
+ rawData = rawData[processed:]
+ }
+
+ switch len(packets) {
+ // Empty packet
+ case 0:
+ return nil, errInvalidHeader
+ // Multiple Packets
+ default:
+ return packets, nil
+ }
+}
+
+// Marshal takes an array of Packets and serializes them to a single buffer
+func Marshal(packets []Packet) ([]byte, error) {
+ out := make([]byte, 0)
+ for _, p := range packets {
+ data, err := p.Marshal()
+ if err != nil {
+ return nil, err
+ }
+ out = append(out, data...)
+ }
+ return out, nil
+}
+
+// unmarshal is a factory which pulls the first RTCP packet from a bytestream,
+// and returns it's parsed representation, and the amount of data that was processed.
+func unmarshal(rawData []byte) (packet Packet, bytesprocessed int, err error) {
+ var h Header
+
+ err = h.Unmarshal(rawData)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ bytesprocessed = int(h.Length+1) * 4
+ if bytesprocessed > len(rawData) {
+ return nil, 0, errPacketTooShort
+ }
+ inPacket := rawData[:bytesprocessed]
+
+ switch h.Type {
+ case TypeSenderReport:
+ packet = new(SenderReport)
+
+ case TypeReceiverReport:
+ packet = new(ReceiverReport)
+
+ case TypeSourceDescription:
+ packet = new(SourceDescription)
+
+ case TypeGoodbye:
+ packet = new(Goodbye)
+
+ case TypeTransportSpecificFeedback:
+ switch h.Count {
+ case FormatTLN:
+ packet = new(TransportLayerNack)
+ case FormatRRR:
+ packet = new(RapidResynchronizationRequest)
+ case FormatTCC:
+ packet = new(TransportLayerCC)
+ default:
+ packet = new(RawPacket)
+ }
+
+ case TypePayloadSpecificFeedback:
+ switch h.Count {
+ case FormatPLI:
+ packet = new(PictureLossIndication)
+ case FormatSLI:
+ packet = new(SliceLossIndication)
+ case FormatREMB:
+ packet = new(ReceiverEstimatedMaximumBitrate)
+ case FormatFIR:
+ packet = new(FullIntraRequest)
+ default:
+ packet = new(RawPacket)
+ }
+
+ default:
+ packet = new(RawPacket)
+ }
+
+ err = packet.Unmarshal(inPacket)
+
+ return packet, bytesprocessed, err
+}