You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/pkg/rtprtcp/rtp.go

157 lines
3.8 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package rtprtcp
import (
"errors"
"github.com/q191201771/naza/pkg/bele"
)
// -----------------------------------
// rfc3550 5.1 RTP Fixed Header Fields
// -----------------------------------
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |V=2|P|X| CC |M| PT | sequence number |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | timestamp |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | synchronization source (SSRC) identifier |
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// | contributing source (CSRC) identifiers |
// | .... |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
var ErrRTP = errors.New("lal.rtp: fxxk")
const (
RTPFixedHeaderLength = 12
)
// rfc3984 5.2. Common Structure of the RTP Payload Format
// Table 1. Summary of NAL unit types and their payload structures
//
// Type Packet Type name Section
// ---------------------------------------------------------
// 0 undefined -
// 1-23 NAL unit Single NAL unit packet per H.264 5.6
// 24 STAP-A Single-time aggregation packet 5.7.1
// 25 STAP-B Single-time aggregation packet 5.7.1
// 26 MTAP16 Multi-time aggregation packet 5.7.2
// 27 MTAP24 Multi-time aggregation packet 5.7.2
// 28 FU-A Fragmentation unit 5.8
// 29 FU-B Fragmentation unit 5.8
// 30-31 undefined -
const (
NALUTypeAVCSingleMax = 23
NALUTypeAVCSTAPA = 24 // one packet, multiple nals
NALUTypeAVCFUA = 28
)
const (
NALUTypeHEVCFUA = 49
)
const (
PositionTypeSingle uint8 = 1
PositionTypeFUAStart uint8 = 2
PositionTypeFUAMiddle uint8 = 3
PositionTypeFUAEnd uint8 = 4
PositionTypeSTAPA uint8 = 5
)
type RTPHeader struct {
Version uint8 // 2b *
Padding uint8 // 1b
Extension uint8 // 1
CsrcCount uint8 // 4b
Mark uint8 // 1b *
PacketType uint8 // 7b
Seq uint16 // 16b **
Timestamp uint32 // 32b ****
Ssrc uint32 // 32b **** Synchronization source
payloadOffset uint32
}
type RTPPacket struct {
Header RTPHeader
Raw []byte // 包含header内存
positionType uint8
}
func ParseRTPPacket(b []byte) (h RTPHeader, err error) {
if len(b) < RTPFixedHeaderLength {
err = ErrRTP
return
}
h.Version = b[0] >> 6
h.Padding = (b[0] >> 5) & 0x1
h.Extension = (b[0] >> 4) & 0x1
h.CsrcCount = b[0] & 0xF
h.Mark = b[1] >> 7
h.PacketType = b[1] & 0x7F
h.Seq = bele.BEUint16(b[2:])
h.Timestamp = bele.BEUint32(b[4:])
h.Ssrc = bele.BEUint32(b[8:])
h.payloadOffset = RTPFixedHeaderLength
return
}
// 比较序号的值,内部处理序号翻转问题,见单元测试中的例子
func CompareSeq(a, b uint16) int {
if a == b {
return 0
}
if a > b {
if a-b < 16384 {
return 1
}
return -1
}
// must be a < b
if b-a < 16384 {
return -1
}
return 1
}
// a减b的值内部处理序号翻转问题如果a小于b则返回负值见单元测试中的例子
func SubSeq(a, b uint16) int {
if a == b {
return 0
}
if a > b {
d := a - b
if d < 16384 {
return int(d)
}
return int(d) - 65536
}
// must be a < b
d := b - a
if d < 16384 {
return -int(d)
}
return 65536 - int(d)
}