Rewrite HomeKit client
This commit is contained in:
+57
-7
@@ -10,16 +10,18 @@ import (
|
||||
|
||||
const (
|
||||
TypeAACMain = 1
|
||||
TypeAACLC = 2
|
||||
TypeAACLC = 2 // Low Complexity
|
||||
TypeAACLD = 23 // Low Delay (48000, 44100, 32000, 24000, 22050)
|
||||
TypeESCAPE = 31
|
||||
TypeAACELD = 39 // Enhanced Low Delay
|
||||
|
||||
AUTime = 1024
|
||||
|
||||
// FMTP streamtype=5 - audio stream
|
||||
FMTP = "streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config="
|
||||
)
|
||||
|
||||
// streamtype=5 - audio stream
|
||||
const fmtp = "streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config="
|
||||
|
||||
var sampleRates = []uint32{
|
||||
var sampleRates = [16]uint32{
|
||||
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350,
|
||||
0, 0, 0, // protection from request sampleRates[15]
|
||||
}
|
||||
@@ -29,7 +31,7 @@ func ConfigToCodec(conf []byte) *core.Codec {
|
||||
rd := bits.NewReader(conf)
|
||||
|
||||
codec := &core.Codec{
|
||||
FmtpLine: fmtp + hex.EncodeToString(conf),
|
||||
FmtpLine: FMTP + hex.EncodeToString(conf),
|
||||
PayloadType: core.PayloadTypeRAW,
|
||||
}
|
||||
|
||||
@@ -39,7 +41,7 @@ func ConfigToCodec(conf []byte) *core.Codec {
|
||||
}
|
||||
|
||||
switch objType {
|
||||
case TypeAACLC:
|
||||
case TypeAACLC, TypeAACLD, TypeAACELD:
|
||||
codec.Name = core.CodecAAC
|
||||
default:
|
||||
codec.Name = fmt.Sprintf("AAC-%X", objType)
|
||||
@@ -72,3 +74,51 @@ func DecodeConfig(b []byte) (objType, sampleFreqIdx, channels byte, sampleRate u
|
||||
channels = rd.ReadBits8(4)
|
||||
return
|
||||
}
|
||||
|
||||
func EncodeConfig(objType byte, sampleRate uint32, channels byte, shortFrame bool) []byte {
|
||||
wr := bits.NewWriter(nil)
|
||||
|
||||
if objType < TypeESCAPE {
|
||||
wr.WriteBits8(objType, 5)
|
||||
} else {
|
||||
wr.WriteBits8(TypeESCAPE, 5)
|
||||
wr.WriteBits8(objType-32, 6)
|
||||
}
|
||||
|
||||
i := indexUint32(sampleRates[:], sampleRate)
|
||||
if i >= 0 {
|
||||
wr.WriteBits8(byte(i), 4)
|
||||
} else {
|
||||
wr.WriteBits8(0xF, 4)
|
||||
wr.WriteBits(sampleRate, 24)
|
||||
}
|
||||
|
||||
wr.WriteBits8(channels, 4)
|
||||
|
||||
switch objType {
|
||||
case TypeAACLD:
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/67d392b97941bb51fb7af3a3c9387f5ab895fa46/libavcodec/aacdec_template.c#L841
|
||||
wr.WriteBool(shortFrame)
|
||||
wr.WriteBit(0) // dependsOnCoreCoder
|
||||
wr.WriteBit(0) // extension_flag
|
||||
wr.WriteBits8(0, 2) // ep_config
|
||||
case TypeAACELD:
|
||||
// https://github.com/FFmpeg/FFmpeg/blob/67d392b97941bb51fb7af3a3c9387f5ab895fa46/libavcodec/aacdec_template.c#L922
|
||||
wr.WriteBool(shortFrame)
|
||||
wr.WriteBits8(0, 3) // res_flags
|
||||
wr.WriteBit(0) // ldSbrPresentFlag
|
||||
wr.WriteBits8(0, 4) // ELDEXT_TERM
|
||||
wr.WriteBits8(0, 2) // ep_config
|
||||
}
|
||||
|
||||
return wr.Bytes()
|
||||
}
|
||||
|
||||
func indexUint32(s []uint32, v uint32) int {
|
||||
for i := range s {
|
||||
if v == s[i] {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
@@ -4,9 +4,25 @@ import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestConfigToCodec(t *testing.T) {
|
||||
s := "profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=F8EC3000"
|
||||
s = core.Between(s, "config=", ";")
|
||||
src, err := hex.DecodeString(s)
|
||||
require.Nil(t, err)
|
||||
|
||||
codec := ConfigToCodec(src)
|
||||
require.Equal(t, core.CodecAAC, codec.Name)
|
||||
require.Equal(t, uint32(24000), codec.ClockRate)
|
||||
require.Equal(t, uint16(1), codec.Channels)
|
||||
|
||||
dst := EncodeConfig(TypeAACELD, 24000, 1, true)
|
||||
require.Equal(t, src, dst)
|
||||
}
|
||||
|
||||
func TestADTS(t *testing.T) {
|
||||
// FFmpeg MPEG-TS AAC (one packet)
|
||||
s := "fff15080021ffc210049900219002380fff15080021ffc212049900219002380" //...
|
||||
+1
-1
@@ -51,7 +51,7 @@ func ADTSToCodec(b []byte) *core.Codec {
|
||||
Name: core.CodecAAC,
|
||||
ClockRate: sampleRates[sampleRateIdx],
|
||||
Channels: channels,
|
||||
FmtpLine: fmtp + hex.EncodeToString(conf),
|
||||
FmtpLine: FMTP + hex.EncodeToString(conf),
|
||||
}
|
||||
return codec
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user