test hls ll
This commit is contained in:
124
codec/opusparser/opusparser.go
Normal file
124
codec/opusparser/opusparser.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package opusparser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/deepch/vdk/av"
|
||||
)
|
||||
|
||||
type CodecData struct {
|
||||
Channels int
|
||||
}
|
||||
|
||||
func NewCodecData(channels int) *CodecData {
|
||||
return &CodecData{Channels: channels}
|
||||
}
|
||||
|
||||
func (d CodecData) Type() av.CodecType {
|
||||
return av.OPUS
|
||||
}
|
||||
|
||||
func (d CodecData) SampleRate() int {
|
||||
return 48000
|
||||
}
|
||||
|
||||
func (d CodecData) ChannelLayout() av.ChannelLayout {
|
||||
switch d.Channels {
|
||||
case 1:
|
||||
return av.CH_MONO
|
||||
case 2:
|
||||
return av.CH_STEREO
|
||||
default:
|
||||
panic("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
func (d CodecData) SampleFormat() av.SampleFormat {
|
||||
return av.S16
|
||||
}
|
||||
|
||||
func (d CodecData) PacketDuration(pkt []byte) (time.Duration, error) {
|
||||
return PacketDuration(pkt)
|
||||
}
|
||||
|
||||
func Channels(pkt []byte) int {
|
||||
if len(pkt) > 0 && (pkt[0]&0x4) == 0 {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
func PacketDuration(pkt []byte) (time.Duration, error) {
|
||||
if len(pkt) < 1 {
|
||||
return 0, errors.New("empty opus packet")
|
||||
}
|
||||
toc := pkt[0]
|
||||
config := toc >> 3
|
||||
//stereo := (toc & 0x4) != 0
|
||||
code := toc & 0x3
|
||||
numFr := 0
|
||||
switch code {
|
||||
case 0:
|
||||
// one frame
|
||||
if len(pkt) > 1 {
|
||||
numFr = 1
|
||||
}
|
||||
case 1, 2:
|
||||
// two frames
|
||||
if len(pkt) > 2 {
|
||||
numFr = 2
|
||||
}
|
||||
case 3:
|
||||
// N frames
|
||||
if len(pkt) < 2 {
|
||||
return 0, errors.New("invalid opus packet")
|
||||
}
|
||||
numFr = int(pkt[1] & 0x3f)
|
||||
}
|
||||
return time.Duration(numFr) * opusFrameTimes[config], nil
|
||||
}
|
||||
|
||||
var opusFrameTimes = []time.Duration{
|
||||
// SILK NB
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
40 * time.Millisecond,
|
||||
60 * time.Millisecond,
|
||||
// SILK MB
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
40 * time.Millisecond,
|
||||
60 * time.Millisecond,
|
||||
// SILK WB
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
40 * time.Millisecond,
|
||||
60 * time.Millisecond,
|
||||
// Hybrid SWB
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
// Hybrid FB
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
// CELT NB
|
||||
2500 * time.Microsecond,
|
||||
5 * time.Millisecond,
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
// CELT WB
|
||||
2500 * time.Microsecond,
|
||||
5 * time.Millisecond,
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
// CELT SWB
|
||||
2500 * time.Microsecond,
|
||||
5 * time.Millisecond,
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
// CELT FB
|
||||
2500 * time.Microsecond,
|
||||
5 * time.Millisecond,
|
||||
10 * time.Millisecond,
|
||||
20 * time.Millisecond,
|
||||
}
|
||||
Reference in New Issue
Block a user