1
0
Fork 0
forked from External/mediamtx

move aac utilities into gortsplib

This commit is contained in:
aler9 2021-09-23 20:24:10 +02:00
parent 3b0327233e
commit 68ab5c05f6
8 changed files with 9 additions and 245 deletions

View file

@ -80,7 +80,6 @@ endif
test-internal:
go test -v $(TEST_INTERNAL_OPTS) \
./internal/aac \
./internal/conf \
./internal/confenv \
./internal/confwatcher \

2
go.mod
View file

@ -5,7 +5,7 @@ go 1.16
require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/aler9/gortsplib v0.0.0-20210923180721-13c6b69d302d
github.com/aler9/gortsplib v0.0.0-20210923181911-321fe06c6dab
github.com/asticode/go-astits v1.9.0
github.com/fsnotify/fsnotify v1.4.9
github.com/gin-gonic/gin v1.7.2

4
go.sum
View file

@ -2,8 +2,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/aler9/gortsplib v0.0.0-20210923180721-13c6b69d302d h1:aiMG2qO6tpLgXYeaWH/o/RT9en/tMNco/KZ9XN+QOt0=
github.com/aler9/gortsplib v0.0.0-20210923180721-13c6b69d302d/go.mod h1:DKI+t4Wj5YjkpxmiQhmG3qRG5VMOprDQvto62wMO68c=
github.com/aler9/gortsplib v0.0.0-20210923181911-321fe06c6dab h1:Dp3zUKCN/74UdxYBvHNKJubuYZeesDDCAB4gx6wZYh4=
github.com/aler9/gortsplib v0.0.0-20210923181911-321fe06c6dab/go.mod h1:DKI+t4Wj5YjkpxmiQhmG3qRG5VMOprDQvto62wMO68c=
github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927 h1:95mXJ5fUCYpBRdSOnLAQAdJHHKxxxJrVCiaqDi965YQ=
github.com/aler9/rtmp v0.0.0-20210403095203-3be4a5535927/go.mod h1:vzuE21rowz+lT1NGsWbreIvYulgBpCGnQyeTyFblUHc=
github.com/asticode/go-astikit v0.20.0 h1:+7N+J4E4lWx2QOkRdOf6DafWJMv6O4RRfgClwQokrH8=

View file

@ -1,166 +0,0 @@
package aac
import (
"fmt"
)
const (
mpegAudioTypeAACLLC = 2
)
var sampleRates = []int{
96000,
88200,
64000,
48000,
44100,
32000,
24000,
22050,
16000,
12000,
11025,
8000,
7350,
}
var channelCounts = []int{
1,
2,
3,
4,
5,
6,
8,
}
// ADTSPacket is an ADTS packet
type ADTSPacket struct {
Type int
SampleRate int
ChannelCount int
AU []byte
}
// DecodeADTS decodes an ADTS stream into ADTS packets.
func DecodeADTS(byts []byte) ([]*ADTSPacket, error) {
// refs: https://wiki.multimedia.cx/index.php/ADTS
var ret []*ADTSPacket
for len(byts) > 0 {
syncWord := (uint16(byts[0]) << 4) | (uint16(byts[1]) >> 4)
if syncWord != 0xfff {
return nil, fmt.Errorf("invalid syncword")
}
protectionAbsent := byts[1] & 0x01
if protectionAbsent != 1 {
return nil, fmt.Errorf("CRC is not supported")
}
pkt := &ADTSPacket{}
pkt.Type = int((byts[2] >> 6) + 1)
switch pkt.Type {
case mpegAudioTypeAACLLC:
default:
return nil, fmt.Errorf("unsupported object type: %d", pkt.Type)
}
sampleRateIndex := (byts[2] >> 2) & 0x0F
switch {
case sampleRateIndex <= 12:
pkt.SampleRate = sampleRates[sampleRateIndex]
default:
return nil, fmt.Errorf("invalid sample rate index: %d", sampleRateIndex)
}
channelConfig := ((byts[2] & 0x01) << 2) | ((byts[3] >> 6) & 0x03)
switch {
case channelConfig >= 1 && channelConfig <= 7:
pkt.ChannelCount = channelCounts[channelConfig-1]
default:
return nil, fmt.Errorf("invalid channel configuration: %d", channelConfig)
}
frameLen := int(((uint16(byts[3])&0x03)<<11)|
(uint16(byts[4])<<3)|
((uint16(byts[5])>>5)&0x07)) - 7
// fullness := ((uint16(byts[5]) & 0x1F) << 6) | ((uint16(byts[6]) >> 2) & 0x3F)
frameCount := byts[6] & 0x03
if frameCount != 0 {
return nil, fmt.Errorf("multiple frame count not supported")
}
if len(byts[7:]) < frameLen {
return nil, fmt.Errorf("invalid frame length")
}
pkt.AU = byts[7 : 7+frameLen]
byts = byts[7+frameLen:]
ret = append(ret, pkt)
}
return ret, nil
}
// EncodeADTS encodes ADTS packets into an ADTS stream.
func EncodeADTS(pkts []*ADTSPacket) ([]byte, error) {
var ret []byte
for _, pkt := range pkts {
sampleRateIndex := func() int {
for i, s := range sampleRates {
if s == pkt.SampleRate {
return i
}
}
return -1
}()
if sampleRateIndex == -1 {
return nil, fmt.Errorf("invalid sample rate: %d", pkt.SampleRate)
}
channelConfig := func() int {
for i, co := range channelCounts {
if co == pkt.ChannelCount {
return i + 1
}
}
return -1
}()
if channelConfig == -1 {
return nil, fmt.Errorf("invalid channel count: %d", pkt.ChannelCount)
}
frameLen := len(pkt.AU) + 7
fullness := 0x07FF // like ffmpeg does
header := make([]byte, 7)
header[0] = 0xFF
header[1] = 0xF1
header[2] = uint8(((pkt.Type - 1) << 6) | (sampleRateIndex << 2) | ((channelConfig >> 2) & 0x01))
header[3] = uint8((channelConfig&0x03)<<6 | (frameLen>>11)&0x03)
header[4] = uint8((frameLen >> 3) & 0xFF)
header[5] = uint8((frameLen&0x07)<<5 | ((fullness >> 6) & 0x1F))
header[6] = uint8((fullness & 0x3F) << 2)
ret = append(ret, header...)
ret = append(ret, pkt.AU...)
}
return ret, nil
}

View file

@ -1,68 +0,0 @@
package aac
import (
"testing"
"github.com/stretchr/testify/require"
)
var casesADTS = []struct {
name string
byts []byte
pkts []*ADTSPacket
}{
{
"single",
[]byte{0xff, 0xf1, 0x4c, 0x80, 0x1, 0x3f, 0xfc, 0xaa, 0xbb},
[]*ADTSPacket{
{
Type: 2,
SampleRate: 48000,
ChannelCount: 2,
AU: []byte{0xaa, 0xbb},
},
},
},
{
"multiple",
[]byte{
0xff, 0xf1, 0x50, 0x40, 0x1, 0x3f, 0xfc, 0xaa,
0xbb, 0xff, 0xf1, 0x4c, 0x80, 0x1, 0x3f, 0xfc,
0xcc, 0xdd,
},
[]*ADTSPacket{
{
Type: 2,
SampleRate: 44100,
ChannelCount: 1,
AU: []byte{0xaa, 0xbb},
},
{
Type: 2,
SampleRate: 48000,
ChannelCount: 2,
AU: []byte{0xcc, 0xdd},
},
},
},
}
func TestDecodeADTS(t *testing.T) {
for _, ca := range casesADTS {
t.Run(ca.name, func(t *testing.T) {
pkts, err := DecodeADTS(ca.byts)
require.NoError(t, err)
require.Equal(t, ca.pkts, pkts)
})
}
}
func TestEncodeADTS(t *testing.T) {
for _, ca := range casesADTS {
t.Run(ca.name, func(t *testing.T) {
byts, err := EncodeADTS(ca.pkts)
require.NoError(t, err)
require.Equal(t, ca.byts, byts)
})
}
}

View file

@ -13,13 +13,13 @@ import (
"time"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/aac"
"github.com/aler9/gortsplib/pkg/h264"
"github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/asticode/go-astits"
"github.com/grafov/m3u8"
"github.com/aler9/rtsp-simple-server/internal/aac"
"github.com/aler9/rtsp-simple-server/internal/logger"
)

View file

@ -5,10 +5,9 @@ import (
"time"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/aac"
"github.com/aler9/gortsplib/pkg/h264"
"github.com/asticode/go-astits"
"github.com/aler9/rtsp-simple-server/internal/aac"
)
const (

View file

@ -4,7 +4,7 @@ import (
"fmt"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtpaac"
"github.com/aler9/gortsplib/pkg/aac"
"github.com/notedit/rtmp/av"
nh264 "github.com/notedit/rtmp/codec/h264"
"github.com/notedit/rtmp/format/flv/flvio"
@ -146,7 +146,7 @@ func (c *Conn) ReadMetadata() (*gortsplib.Track, *gortsplib.Track, error) {
return nil, nil, fmt.Errorf("audio track setupped twice")
}
var mpegConf rtpaac.MPEG4AudioConfig
var mpegConf aac.MPEG4AudioConfig
err := mpegConf.Decode(pkt.Data)
if err != nil {
return nil, nil, err
@ -241,8 +241,8 @@ func (c *Conn) WriteMetadata(videoTrack *gortsplib.Track, audioTrack *gortsplib.
return err
}
enc, err := rtpaac.MPEG4AudioConfig{
Type: rtpaac.MPEG4AudioType(conf.Type),
enc, err := aac.MPEG4AudioConfig{
Type: aac.MPEG4AudioType(conf.Type),
SampleRate: conf.SampleRate,
ChannelCount: conf.ChannelCount,
AOTSpecificConfig: conf.AOTSpecificConfig,