Skip to content

Commit

Permalink
add G726 format (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 authored Jul 25, 2023
1 parent 2575dba commit d3def0e
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 23 deletions.
47 changes: 24 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,35 +100,36 @@ In RTSP, media streams are routed between server and clients by using RTP packet

### Video

|codec|rtp format|documentation|encoder and decoder available|
|-----|----------|-------------|-----------------------------|
|AV1|AV1|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#AV1)|:heavy_check_mark:|
|VP9|VP9|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#VP9)|:heavy_check_mark:|
|VP8|VP8|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#VP8)|:heavy_check_mark:|
|H265|H265|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#H265)|:heavy_check_mark:|
|H264|H264|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#H264)|:heavy_check_mark:|
|MPEG-2 Video|unnamed|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG2Video)||
|MPEG-4 Video (H263, Xvid)|MP4V-ES|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4VideoES)|:heavy_check_mark:|
|M-JPEG|JPEG|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MJPEG)|:heavy_check_mark:|
|format / codec|variant|documentation|encoder and decoder available|
|--------------|-------|-------------|-----------------------------|
|AV1||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#AV1)|:heavy_check_mark:|
|VP9||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#VP9)|:heavy_check_mark:|
|VP8||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#VP8)|:heavy_check_mark:|
|H265||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#H265)|:heavy_check_mark:|
|H264||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#H264)|:heavy_check_mark:|
|MPEG-4 Video (H263, Xvid)||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4VideoES)|:heavy_check_mark:|
|MPEG-2 Video||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG2Video)||
|M-JPEG||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MJPEG)|:heavy_check_mark:|

### Audio

|codec|rtp format|documentation|encoder and decoder available|
|-----|----------|-------------|-----------------------------|
|Opus|opus|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#Opus)|:heavy_check_mark:|
|Vorbis|VORBIS|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#Vorbis)||
|MPEG-4 Audio (AAC)|mpeg4-generic|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4AudioGeneric)|:heavy_check_mark:|
|MPEG-4 Audio (AAC)|MP4A-LATM|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG4AudioLATM)|:heavy_check_mark:|
|MPEG-1/2 Audio (MP3)|unnamed|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEG2Audio)|:heavy_check_mark:|
|G722|unnamed|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#G722)|:heavy_check_mark:|
|G711 (PCMA, PCMU)|unnamed|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#G711)|:heavy_check_mark:|
|LPCM|L8/L16/L24|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#LPCM)|:heavy_check_mark:|
|format / codec|variant|documentation|encoder and decoder available|
|--------------|-------|-------------|-----------------------------|
|Opus||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#Opus)|:heavy_check_mark:|
|Vorbis||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#Vorbis)||
|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#MPEG2Audio)|:heavy_check_mark:|
|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:|
|LPCM||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#LPCM)|:heavy_check_mark:|

### Mixed

|codec|rtp format|documentation|encoder and decoder available|
|-----|----------|-------------|-----------------------------|
|MPEG-TS|MP2T|[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEGTS)||
|format / codec|variant|documentation|encoder and decoder available|
|--------------|-------|-------------|-----------------------------|
|MPEG-TS||[link](https://pkg.go.dev/github.com/bluenviron/gortsplib/v3/pkg/formats#MPEGTS)||

## Standards

Expand Down
10 changes: 10 additions & 0 deletions pkg/formats/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ func Unmarshal(mediaType string, payloadType uint8, rtpMap string, fmtp map[stri
case payloadType == 9:
return &G722{}

case (codec == "g726-16" ||
codec == "g726-24" ||
codec == "g726-32" ||
codec == "g726-40" ||
codec == "aal2-g726-16" ||
codec == "aal2-g726-24" ||
codec == "aal2-g726-32" ||
codec == "aal2-g726-40") && clock == "8000":
return &G726{}

case payloadType == 14:
return &MPEG2Audio{}

Expand Down
66 changes: 66 additions & 0 deletions pkg/formats/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,72 @@ var casesFormat = []struct {
"G722/8000",
nil,
},
{
"audio g726 le 1",
"audio",
97,
"G726-16/8000",
nil,
&G726{
PayloadTyp: 97,
BitRate: 16,
},
"G726-16/8000",
nil,
},
{
"audio g726 le 2",
"audio",
97,
"G726-24/8000",
nil,
&G726{
PayloadTyp: 97,
BitRate: 24,
},
"G726-24/8000",
nil,
},
{
"audio g726 le 3",
"audio",
97,
"G726-32/8000",
nil,
&G726{
PayloadTyp: 97,
BitRate: 32,
},
"G726-32/8000",
nil,
},
{
"audio g726 le 4",
"audio",
97,
"G726-40/8000",
nil,
&G726{
PayloadTyp: 97,
BitRate: 40,
},
"G726-40/8000",
nil,
},
{
"audio g726 be",
"audio",
97,
"AAL2-G726-32/8000",
nil,
&G726{
PayloadTyp: 97,
BitRate: 32,
BigEndian: true,
},
"AAL2-G726-32/8000",
nil,
},
{
"audio lpcm 8",
"audio",
Expand Down
80 changes: 80 additions & 0 deletions pkg/formats/g726.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package formats

import (
"strconv"
"strings"

"github.com/pion/rtp"
)

// G726 is a RTP format for the G726 codec.
// Specification: https://datatracker.ietf.org/doc/html/rfc3551
type G726 struct {
PayloadTyp uint8
BitRate int
BigEndian bool
}

func (f *G726) unmarshal(payloadType uint8, _ string, codec string, _ string, _ map[string]string) error {
f.PayloadTyp = payloadType

if strings.HasPrefix(codec, "aal2-") {
f.BigEndian = true
}

switch {
case strings.HasSuffix(codec, "-16"):
f.BitRate = 16
case strings.HasSuffix(codec, "-24"):
f.BitRate = 24
case strings.HasSuffix(codec, "-32"):
f.BitRate = 32
default:
f.BitRate = 40
}

return nil
}

// Codec implements Format.
func (f *G726) Codec() string {
return "G726"
}

// String implements Format.
//
// Deprecated: replaced by Codec().
func (f *G726) String() string {
return f.Codec()
}

// ClockRate implements Format.
func (f *G726) ClockRate() int {
return 8000
}

// PayloadType implements Format.
func (f *G726) PayloadType() uint8 {
return f.PayloadTyp
}

// RTPMap implements Format.
func (f *G726) RTPMap() string {
codec := ""

if f.BigEndian {
codec += "AAL2-"
}

return codec + "G726-" + strconv.FormatInt(int64(f.BitRate), 10) + "/8000"
}

// FMTP implements Format.
func (f *G726) FMTP() map[string]string {
return nil
}

// PTSEqualsDTS implements Format.
func (f *G726) PTSEqualsDTS(*rtp.Packet) bool {
return true
}
15 changes: 15 additions & 0 deletions pkg/formats/g726_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package formats

import (
"testing"

"github.com/pion/rtp"
"github.com/stretchr/testify/require"
)

func TestG726Attributes(t *testing.T) {
format := &G726{}
require.Equal(t, "G726", format.Codec())
require.Equal(t, 8000, format.ClockRate())
require.Equal(t, true, format.PTSEqualsDTS(&rtp.Packet{}))
}

0 comments on commit d3def0e

Please sign in to comment.