av/stream/rtp/rtp.go

96 lines
2.8 KiB
Go

/*
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 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
}