/* 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 <saxon@ausocean.org> 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 and https://tools.ietf.org/html/rfc3550 for rtp-h264 and rtp standards. */ package rtp const ( rtpVer = 2 ) // Pkt provides fields consistent with RFC3550 definition of an rtp packet // The padding indicator does not need to be set manually, only the padding length 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 uint16 // Synch number TS uint32 // Timestamp SSRC uint32 // Synchronisation source identifier Payload []byte // H264 Payload data Padding byte // No of bytes of padding } // Bytes provides a byte slice of the packet func (p *Pkt) Bytes() []byte { if p.V == 0 { p.V = rtpVer } if p.Padding > 0 { p.p = 1 } 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.") } const headSize = 3 * 4 // bytes buf := make([]byte, headSize, headSize+len(p.Payload)+int(p.Padding)) 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) buf[4] = byte(p.TS >> 24) buf[5] = byte(p.TS >> 16) buf[6] = byte(p.TS >> 8) buf[7] = byte(p.TS) buf[8] = byte(p.SSRC >> 24) buf[9] = byte(p.SSRC >> 16) buf[10] = byte(p.SSRC >> 8) buf[11] = byte(p.SSRC) buf = append(buf, p.Payload...) // see https://tools.ietf.org/html/rfc3550 section 5.1 (padding). At end of // rtp packet, padding may exist, with the last octet being the length of the // padding including itself. if p.Padding != 0 { buf = buf[:cap(buf)] buf[len(buf)-1] = byte(p.Padding) } return buf }