/* NAME rtp.go - provides a data structure intended to encapsulate the properties of an rtp packet and also functions to allow manipulation of these packets. DESCRIPTION See Readme.md AUTHOR Saxon A. Nelson-Milton LICENSE rtp.go is Copyright (C) 2018 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with revid in gpl.txt. If not, see [GNU licenses](http://www.gnu.org/licenses). */ // See https://tools.ietf.org/html/rfc6184 for rtp packet format package rtp const ( rtpVer = 2 defaultHeadSize = 3 * 4 // bytes ) type Pkt struct { V byte // Version (currently 2) P byte // Padding indicator (0 => padding, 1 => padding) X byte // Extension header indicator CC byte // CSRC count M byte // Marker bit PT byte // Packet type SN int16 // Synch number TS int32 // Timestamp SSRC int32 // Synchronisation source identifier Payload []byte // H264 Payload data Padding int // No of bytes of padding } func (p *Pkt) Bytes() []byte { if p.V == 0 { p.V = rtpVer } if p.P != 0 && p.Padding == 0 { panic("Padding bit set to something other than 1, but there is no padding size defined!") } else if p.P == 0 && p.Padding != 0 { panic("Padding bit is set to zero, but it's indicated that there is padding!") } if p.CC != 0 { panic("CC has been set to something other than 0 - this is not supported yet!") } if p.X != 0 { panic("rtp: X (extension header indicator) not 0, but extensiion headers not currently supported!") } if p.CC != 0 { panic("rtp: CC (CSRC count) not 0, but CSRC headers not yet supported!") } buf := make([]byte, defaultHeadSize, defaultHeadSize+len(p.Payload)+p.Padding) // First 4 bytes buf[0] |= p.V<<6 | p.P<<5 | p.CC buf[1] |= p.M<<7 | p.PT buf[2] |= byte(p.SN >> 8) buf[3] |= byte(p.SN) // Second lot of 4 bytes buf[4] |= byte(p.TS >> 24) buf[5] |= byte(p.TS >> 16) buf[6] |= byte(p.TS >> 8) buf[7] |= byte(p.TS) // Third lot of 4 bytes buf[8] |= byte(p.SSRC >> 24) buf[9] |= byte(p.SSRC >> 16) buf[10] |= byte(p.SSRC >> 8) buf[11] |= byte(p.SSRC) // Add payload and padding buf = append(buf, p.Payload...) buf = append(buf, append(make([]byte, p.Padding-1, p.Padding), byte(p.Padding))...) return buf }