diff --git a/protocol/rtcp/rtcp.go b/protocol/rtcp/rtcp.go index deca94fb..bf82ab80 100644 --- a/protocol/rtcp/rtcp.go +++ b/protocol/rtcp/rtcp.go @@ -10,24 +10,6 @@ const ( reportBlockSize = 6 ) -type Header struct { - Version uint8 // RTCP version. - Padding bool // Padding indicator. - ReportCount uint8 // Number of reports contained. - Type uint8 // Type of RTCP packet. - SSRC uint32 // Source identifier. -} - -type ReportBlock struct { - SSRC uint32 // Source identifier. - FractionLost uint8 // Fraction of packets lost. - PacketsLost uint32 // Cumulative number of packets lost. - HighestSequence uint32 // Extended highest sequence number received. - Jitter uint32 // Interarrival jitter. - LSR uint32 // Last sender report timestamp. - DLSR uint32 // Delay since last sender report. -} - type ReceiverReport struct { Header @@ -39,13 +21,8 @@ func (r *ReceiverReport) Bytes() []byte { l := 8 + 4*reportBlockSize*len(r.Blocks) + 4*len(r.Extensions) buf := make([]byte, l) - buf[0] = r.Version<<6 | asByte(r.Padding)<<5 | 0x1f&r.ReportCount - buf[1] = r.Type - l = 1 + reportBlockSize*len(r.Blocks) + len(r.Extensions) - binary.BigEndian.PutUint16(buf[2:], uint16(l)) - - buf[4] = byte(r.SSRC) + r.writeHeader(buf, l) idx := 8 for _, b := range r.Blocks { @@ -65,18 +42,13 @@ func (r *ReceiverReport) Bytes() []byte { } for _, e := range r.Extensions { - binary.BigEndian.PutUint32(buf[idx:], binary.BigEndian.Uint32(e[:])) + copy(buf[idx:], e[:]) idx += 4 } return buf } -type Chunk struct { - Type uint8 - Test []byte -} - type SourceDescription struct { Header @@ -84,7 +56,75 @@ type SourceDescription struct { } func (d *SourceDescription) Bytes() []byte { + bodyLen := d.bodyLen() + l := 8 + bodyLen + buf := make([]byte, l) + d.writeHeader(buf, bodyLen/4) + idx := 8 + for _, c := range d.Chunks { + binary.BigEndian.PutUint32(buf[idx:], c.SSRC) + idx += 4 + for _, i := range c.Items { + buf[idx] = i.Type + idx++ + buf[idx] = byte(len(i.Text)) + idx++ + copy(buf[idx:], i.Text) + idx += len(i.Text) + } + } + return buf +} +func (d *SourceDescription) bodyLen() int { + l := 0 + for _, c := range d.Chunks { + l += c.len() + } + return l +} + +type Header struct { + Version uint8 // RTCP version. + Padding bool // Padding indicator. + ReportCount uint8 // Number of reports contained. + Type uint8 // Type of RTCP packet. + SSRC uint32 // Source identifier. +} + +type ReportBlock struct { + SSRC uint32 // Source identifier. + FractionLost uint8 // Fraction of packets lost. + PacketsLost uint32 // Cumulative number of packets lost. + HighestSequence uint32 // Extended highest sequence number received. + Jitter uint32 // Interarrival jitter. + LSR uint32 // Last sender report timestamp. + DLSR uint32 // Delay since last sender report. +} + +type SDESItem struct { + Type uint8 + Text []byte +} + +type Chunk struct { + SSRC uint32 + Items []SDESItem +} + +func (c *Chunk) len() int { + tot := 4 + for _, i := range c.Items { + tot += 2 + len(i.Text) + } + return tot +} + +func (h Header) writeHeader(buf []byte, l int) { + buf[0] = h.Version<<6 | asByte(h.Padding)<<5 | 0x1f&h.ReportCount + buf[1] = h.Type + binary.BigEndian.PutUint16(buf[2:], uint16(l)) + buf[4] = byte(h.SSRC) } func asByte(b bool) byte {