mirror of https://bitbucket.org/ausocean/av.git
104 lines
3.0 KiB
Go
104 lines
3.0 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 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
|
|
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.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!")
|
|
}
|
|
|
|
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
|
|
}
|