add Speex format

This commit is contained in:
aler9
2023-08-14 18:33:09 +02:00
committed by Alessandro Ros
parent 98e6e8239e
commit abe875deb8
5 changed files with 128 additions and 1 deletions

View File

@@ -96,7 +96,7 @@ https://pkg.go.dev/github.com/bluenviron/gortsplib/v3#pkg-index
## RTP Payload Formats
In RTSP, media streams are routed between server and clients by using RTP packets. In order to decode a stream, RTP packets must be converted into codec-specific frames. This conversion happens by using a RTP payload format. This library recognizes the following formats:
In RTSP, media streams are routed between server and clients by using RTP packets. Conversion between RTP packets and codec-specific frames happens by using a payload format. This library recognizes the following payload formats:
### Video
@@ -120,6 +120,7 @@ In RTSP, media streams are routed between server and clients by using RTP packet
|MPEG-4 Audio (AAC)|Generic (RFC3640)|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4AudioGeneric)|:heavy_check_mark:|
|MPEG-4 Audio (AAC)|LATM (RFC6416)|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4AudioLATM)|:heavy_check_mark:|
|MPEG-1/2 Audio (MP3)||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG1Audio)|:heavy_check_mark:|
|Speex||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#Speex)||
|G726||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#G726)||
|G722||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#G722)|:heavy_check_mark:|
|G711 (PCMA, PCMU)||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#G711)|:heavy_check_mark:|
@@ -148,6 +149,7 @@ In RTSP, media streams are routed between server and clients by using RTP packet
* [RFC5215, RTP Payload Format for Vorbis Encoded Audio](https://datatracker.ietf.org/doc/html/rfc5215)
* [RFC7587, RTP Payload Format for the Opus Speech and Audio Codec](https://datatracker.ietf.org/doc/html/rfc7587)
* [RFC3640, RTP Payload Format for Transport of MPEG-4 Elementary Streams](https://datatracker.ietf.org/doc/html/rfc3640)
* [RFC5574, RTP Payload Format for the Speex Codec](https://datatracker.ietf.org/doc/html/rfc5574)
* [RTP Payload Format For AV1 (v1.0)](https://aomediacodec.github.io/av1-rtp-spec/)
* [Codec standards](https://github.com/bluenviron/mediacommon#standards)
* [Golang project layout](https://github.com/golang-standards/project-layout)

View File

@@ -109,6 +109,9 @@ func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[stri
case codec == "mp4a-latm":
return &MPEG4AudioLATM{}
case codec == "speex":
return &Speex{}
case codec == "vorbis":
return &Vorbis{}

View File

@@ -526,6 +526,24 @@ var casesFormat = []struct {
"config": "400023103fc0",
},
},
{
"audio speex",
"audio",
96,
"speex/16000",
map[string]string{
"vbr": "off",
},
&Speex{
PayloadTyp: 96,
SampleRate: 16000,
VBR: boolPtr(false),
},
"speex/16000",
map[string]string{
"vbr": "off",
},
},
{
"audio vorbis",
"audio",

86
pkg/formats/speex.go Normal file
View File

@@ -0,0 +1,86 @@
package formats
import (
"fmt"
"strconv"
"github.com/pion/rtp"
)
// Speex is a RTP format for the Speex codec.
// Specification: https://datatracker.ietf.org/doc/html/rfc5574
type Speex struct {
PayloadTyp uint8
SampleRate int
VBR *bool
}
func (f *Speex) unmarshal(payloadType uint8, clock string, _ string, _ string, fmtp map[string]string) error {
f.PayloadTyp = payloadType
sampleRate, err := strconv.ParseUint(clock, 10, 31)
if err != nil {
return err
}
f.SampleRate = int(sampleRate)
for key, val := range fmtp {
if key == "vbr" {
if val != "on" && val != "off" {
return fmt.Errorf("invalid vbr value: %v", val)
}
v := (val == "on")
f.VBR = &v
}
}
return nil
}
// Codec implements Format.
func (f *Speex) Codec() string {
return "Speex"
}
// String implements Format.
//
// Deprecated: replaced by Codec().
func (f *Speex) String() string {
return f.Codec()
}
// ClockRate implements Format.
func (f *Speex) ClockRate() int {
return f.SampleRate
}
// PayloadType implements Format.
func (f *Speex) PayloadType() uint8 {
return f.PayloadTyp
}
// RTPMap implements Format.
func (f *Speex) RTPMap() string {
return "speex/" + strconv.FormatInt(int64(f.SampleRate), 10)
}
// FMTP implements Format.
func (f *Speex) FMTP() map[string]string {
fmtp := make(map[string]string)
if f.VBR != nil {
if *f.VBR {
fmtp["vbr"] = "on"
} else {
fmtp["vbr"] = "off"
}
}
return fmtp
}
// PTSEqualsDTS implements Format.
func (f *Speex) PTSEqualsDTS(*rtp.Packet) bool {
return true
}

18
pkg/formats/speex_test.go Normal file
View File

@@ -0,0 +1,18 @@
package formats
import (
"testing"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)
func TestSpeexAttributes(t *testing.T) {
format := &Speex{
PayloadTyp: 96,
SampleRate: 16000,
}
require.Equal(t, "Speex", format.Codec())
require.Equal(t, 16000, format.ClockRate())
require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{}))
}