/* 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 and https://tools.ietf.org/html/rfc3550 for rtp-h264 and rtp standards. */ package rtp const ( rtpVer = 2 headLen = 3 * 4 defPayloadLen = 7 * 188 defPktLen = headLen + defPayloadLen ) // 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(buf []byte) []byte { if buf == nil || len(buf) != defPktLen { buf = make([]byte, headLen, defPktLen) } buf = buf[:headLen] 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.") } 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 }