add CreateDecoder() method to all tracks that can be decoded

This commit is contained in:
aler9
2022-11-14 21:32:49 +01:00
parent 51b8063325
commit 1656e0e823
19 changed files with 222 additions and 196 deletions

View File

@@ -9,7 +9,6 @@ import (
"time"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -75,10 +74,7 @@ func main() {
}
// setup RTP/H264->H264 decoder
rtpDec := &rtph264.Decoder{
PacketizationMode: track.PacketizationMode,
}
rtpDec.Init()
rtpDec := track.CreateDecoder()
// setup H264->raw frames decoder
h264RawDec, err := newH264Decoder()

View File

@@ -2,7 +2,6 @@ package main
import (
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -47,10 +46,7 @@ func main() {
}
// setup RTP/H264->H264 decoder
rtpDec := &rtph264.Decoder{
PacketizationMode: track.PacketizationMode,
}
rtpDec.Init()
rtpDec := track.CreateDecoder()
// setup H264->MPEGTS muxer
mpegtsMuxer, err := newMPEGTSMuxer(track.SafeSPS(), track.SafePPS())

View File

@@ -4,7 +4,6 @@ import (
"log"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtph264"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -52,10 +51,7 @@ func main() {
}
// setup RTP/H264->H264 decoder
rtpDec := &rtph264.Decoder{
PacketizationMode: track.PacketizationMode,
}
rtpDec.Init()
rtpDec := track.CreateDecoder()
// setup H264->raw frames decoder
h264RawDec, err := newH264Decoder()

View File

@@ -4,7 +4,6 @@ import (
"log"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtpmpeg4audio"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -49,13 +48,7 @@ func main() {
}
// setup decoder
dec := &rtpmpeg4audio.Decoder{
SampleRate: track.Config.SampleRate,
SizeLength: track.SizeLength,
IndexLength: track.IndexLength,
IndexDeltaLength: track.IndexDeltaLength,
}
dec.Init()
dec := track.CreateDecoder()
// called when a RTP packet arrives
c.OnPacketRTP = func(ctx *gortsplib.ClientOnPacketRTPCtx) {

View File

@@ -4,7 +4,6 @@ import (
"log"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtpopus"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -49,10 +48,7 @@ func main() {
}
// setup decoder
dec := &rtpopus.Decoder{
SampleRate: track.SampleRate,
}
dec.Init()
dec := track.CreateDecoder()
// called when a RTP packet arrives
c.OnPacketRTP = func(ctx *gortsplib.ClientOnPacketRTPCtx) {

View File

@@ -4,7 +4,6 @@ import (
"log"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtpvp8"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -49,8 +48,7 @@ func main() {
}
// setup decoder
dec := &rtpvp8.Decoder{}
dec.Init()
dec := track.CreateDecoder()
// called when a RTP packet arrives
c.OnPacketRTP = func(ctx *gortsplib.ClientOnPacketRTPCtx) {

View File

@@ -4,7 +4,6 @@ import (
"log"
"github.com/aler9/gortsplib"
"github.com/aler9/gortsplib/pkg/rtpvp9"
"github.com/aler9/gortsplib/pkg/url"
)
@@ -49,8 +48,7 @@ func main() {
}
// setup decoder
dec := &rtpvp9.Decoder{}
dec.Init()
dec := track.CreateDecoder()
// called when a RTP packet arrives
c.OnPacketRTP = func(ctx *gortsplib.ClientOnPacketRTPCtx) {

View File

@@ -124,15 +124,6 @@ func (t *TrackGeneric) ClockRate() int {
return t.clockRate
}
func (t *TrackGeneric) clone() Track {
return &TrackGeneric{
Media: t.Media,
Payloads: append([]TrackGenericPayload(nil), t.Payloads...),
trackBase: t.trackBase,
clockRate: t.clockRate,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackGeneric) MediaDescription() *psdp.MediaDescription {
formats := make([]string, len(t.Payloads))
@@ -171,3 +162,12 @@ func (t *TrackGeneric) MediaDescription() *psdp.MediaDescription {
Attributes: attributes,
}
}
func (t *TrackGeneric) clone() Track {
return &TrackGeneric{
Media: t.Media,
Payloads: append([]TrackGenericPayload(nil), t.Payloads...),
trackBase: t.trackBase,
clockRate: t.clockRate,
}
}

View File

@@ -9,6 +9,8 @@ import (
"sync"
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/pkg/rtph264"
)
// TrackH264 is a H264 track.
@@ -100,44 +102,6 @@ func (t *TrackH264) ClockRate() int {
return 90000
}
func (t *TrackH264) clone() Track {
return &TrackH264{
PayloadType: t.PayloadType,
SPS: t.SPS,
PPS: t.PPS,
PacketizationMode: t.PacketizationMode,
trackBase: t.trackBase,
}
}
// SafeSPS returns the track SPS.
func (t *TrackH264) SafeSPS() []byte {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.SPS
}
// SafePPS returns the track PPS.
func (t *TrackH264) SafePPS() []byte {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.PPS
}
// SafeSetSPS sets the track SPS.
func (t *TrackH264) SafeSetSPS(v []byte) {
t.mutex.Lock()
defer t.mutex.Unlock()
t.SPS = v
}
// SafeSetPPS sets the track PPS.
func (t *TrackH264) SafeSetPPS(v []byte) {
t.mutex.Lock()
defer t.mutex.Unlock()
t.PPS = v
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackH264) MediaDescription() *psdp.MediaDescription {
t.mutex.RLock()
@@ -190,3 +154,50 @@ func (t *TrackH264) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackH264) clone() Track {
return &TrackH264{
PayloadType: t.PayloadType,
SPS: t.SPS,
PPS: t.PPS,
PacketizationMode: t.PacketizationMode,
trackBase: t.trackBase,
}
}
// CreateDecoder creates a decoder able to decode the content of the track.
func (t *TrackH264) CreateDecoder() *rtph264.Decoder {
d := &rtph264.Decoder{
PacketizationMode: t.PacketizationMode,
}
d.Init()
return d
}
// SafeSPS returns the track SPS.
func (t *TrackH264) SafeSPS() []byte {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.SPS
}
// SafePPS returns the track PPS.
func (t *TrackH264) SafePPS() []byte {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.PPS
}
// SafeSetSPS sets the track SPS.
func (t *TrackH264) SafeSetSPS(v []byte) {
t.mutex.Lock()
defer t.mutex.Unlock()
t.SPS = v
}
// SafeSetPPS sets the track PPS.
func (t *TrackH264) SafeSetPPS(v []byte) {
t.mutex.Lock()
defer t.mutex.Unlock()
t.PPS = v
}

View File

@@ -93,6 +93,52 @@ func (t *TrackH265) ClockRate() int {
return 90000
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackH265) MediaDescription() *psdp.MediaDescription {
t.mutex.RLock()
defer t.mutex.RUnlock()
typ := strconv.FormatInt(int64(t.PayloadType), 10)
fmtp := typ
var tmp []string
if t.VPS != nil {
tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.VPS))
}
if t.SPS != nil {
tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.SPS))
}
if t.PPS != nil {
tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.PPS))
}
if tmp != nil {
fmtp += " " + strings.Join(tmp, "; ")
}
return &psdp.MediaDescription{
MediaName: psdp.MediaName{
Media: "video",
Protos: []string{"RTP", "AVP"},
Formats: []string{typ},
},
Attributes: []psdp.Attribute{
{
Key: "rtpmap",
Value: typ + " H265/90000",
},
{
Key: "fmtp",
Value: fmtp,
},
{
Key: "control",
Value: t.control,
},
},
}
}
func (t *TrackH265) clone() Track {
return &TrackH265{
PayloadType: t.PayloadType,
@@ -144,49 +190,3 @@ func (t *TrackH265) SafeSetPPS(v []byte) {
defer t.mutex.Unlock()
t.PPS = v
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackH265) MediaDescription() *psdp.MediaDescription {
t.mutex.RLock()
defer t.mutex.RUnlock()
typ := strconv.FormatInt(int64(t.PayloadType), 10)
fmtp := typ
var tmp []string
if t.VPS != nil {
tmp = append(tmp, "sprop-vps="+base64.StdEncoding.EncodeToString(t.VPS))
}
if t.SPS != nil {
tmp = append(tmp, "sprop-sps="+base64.StdEncoding.EncodeToString(t.SPS))
}
if t.PPS != nil {
tmp = append(tmp, "sprop-pps="+base64.StdEncoding.EncodeToString(t.PPS))
}
if tmp != nil {
fmtp += " " + strings.Join(tmp, "; ")
}
return &psdp.MediaDescription{
MediaName: psdp.MediaName{
Media: "video",
Protos: []string{"RTP", "AVP"},
Formats: []string{typ},
},
Attributes: []psdp.Attribute{
{
Key: "rtpmap",
Value: typ + " H265/90000",
},
{
Key: "fmtp",
Value: fmtp,
},
{
Key: "control",
Value: t.control,
},
},
}
}

View File

@@ -24,12 +24,6 @@ func (t *TrackJPEG) ClockRate() int {
return 90000
}
func (t *TrackJPEG) clone() Track {
return &TrackJPEG{
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackJPEG) MediaDescription() *psdp.MediaDescription {
return &psdp.MediaDescription{
@@ -50,3 +44,9 @@ func (t *TrackJPEG) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackJPEG) clone() Track {
return &TrackJPEG{
trackBase: t.trackBase,
}
}

View File

@@ -24,12 +24,6 @@ func (t *TrackMPEG2Audio) ClockRate() int {
return 90000
}
func (t *TrackMPEG2Audio) clone() Track {
return &TrackMPEG2Audio{
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackMPEG2Audio) MediaDescription() *psdp.MediaDescription {
return &psdp.MediaDescription{
@@ -46,3 +40,9 @@ func (t *TrackMPEG2Audio) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackMPEG2Audio) clone() Track {
return &TrackMPEG2Audio{
trackBase: t.trackBase,
}
}

View File

@@ -24,12 +24,6 @@ func (t *TrackMPEG2Video) ClockRate() int {
return 90000
}
func (t *TrackMPEG2Video) clone() Track {
return &TrackMPEG2Video{
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackMPEG2Video) MediaDescription() *psdp.MediaDescription {
return &psdp.MediaDescription{
@@ -46,3 +40,9 @@ func (t *TrackMPEG2Video) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackMPEG2Video) clone() Track {
return &TrackMPEG2Video{
trackBase: t.trackBase,
}
}

View File

@@ -9,6 +9,7 @@ import (
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/pkg/mpeg4audio"
"github.com/aler9/gortsplib/pkg/rtpmpeg4audio"
)
// TrackMPEG4Audio is a MPEG-4 audio track.
@@ -108,17 +109,6 @@ func (t *TrackMPEG4Audio) ClockRate() int {
return t.Config.SampleRate
}
func (t *TrackMPEG4Audio) clone() Track {
return &TrackMPEG4Audio{
PayloadType: t.PayloadType,
Config: t.Config,
SizeLength: t.SizeLength,
IndexLength: t.IndexLength,
IndexDeltaLength: t.IndexDeltaLength,
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackMPEG4Audio) MediaDescription() *psdp.MediaDescription {
enc, err := t.Config.Marshal()
@@ -176,3 +166,26 @@ func (t *TrackMPEG4Audio) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackMPEG4Audio) clone() Track {
return &TrackMPEG4Audio{
PayloadType: t.PayloadType,
Config: t.Config,
SizeLength: t.SizeLength,
IndexLength: t.IndexLength,
IndexDeltaLength: t.IndexDeltaLength,
trackBase: t.trackBase,
}
}
// CreateDecoder creates a decoder able to decode the content of the track.
func (t *TrackMPEG4Audio) CreateDecoder() *rtpmpeg4audio.Decoder {
d := &rtpmpeg4audio.Decoder{
SampleRate: t.Config.SampleRate,
SizeLength: t.SizeLength,
IndexLength: t.IndexLength,
IndexDeltaLength: t.IndexDeltaLength,
}
d.Init()
return d
}

View File

@@ -6,6 +6,8 @@ import (
"strings"
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/pkg/rtpopus"
)
// TrackOpus is a Opus track.
@@ -53,15 +55,6 @@ func (t *TrackOpus) ClockRate() int {
return t.SampleRate
}
func (t *TrackOpus) clone() Track {
return &TrackOpus{
PayloadType: t.PayloadType,
SampleRate: t.SampleRate,
ChannelCount: t.ChannelCount,
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackOpus) MediaDescription() *psdp.MediaDescription {
typ := strconv.FormatInt(int64(t.PayloadType), 10)
@@ -94,3 +87,21 @@ func (t *TrackOpus) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackOpus) clone() Track {
return &TrackOpus{
PayloadType: t.PayloadType,
SampleRate: t.SampleRate,
ChannelCount: t.ChannelCount,
trackBase: t.trackBase,
}
}
// CreateDecoder creates a decoder able to decode the content of the track.
func (t *TrackOpus) CreateDecoder() *rtpopus.Decoder {
d := &rtpopus.Decoder{
SampleRate: t.SampleRate,
}
d.Init()
return d
}

View File

@@ -33,12 +33,6 @@ func (t *TrackPCMA) ClockRate() int {
return 8000
}
func (t *TrackPCMA) clone() Track {
return &TrackPCMA{
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackPCMA) MediaDescription() *psdp.MediaDescription {
return &psdp.MediaDescription{
@@ -59,3 +53,9 @@ func (t *TrackPCMA) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackPCMA) clone() Track {
return &TrackPCMA{
trackBase: t.trackBase,
}
}

View File

@@ -33,12 +33,6 @@ func (t *TrackPCMU) ClockRate() int {
return 8000
}
func (t *TrackPCMU) clone() Track {
return &TrackPCMU{
trackBase: t.trackBase,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackPCMU) MediaDescription() *psdp.MediaDescription {
return &psdp.MediaDescription{
@@ -59,3 +53,9 @@ func (t *TrackPCMU) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackPCMU) clone() Track {
return &TrackPCMU{
trackBase: t.trackBase,
}
}

View File

@@ -6,6 +6,8 @@ import (
"strings"
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/pkg/rtpvp8"
)
// TrackVP8 is a VP8 track.
@@ -83,15 +85,6 @@ func (t *TrackVP8) ClockRate() int {
return 90000
}
func (t *TrackVP8) clone() Track {
return &TrackVP8{
trackBase: t.trackBase,
PayloadType: t.PayloadType,
MaxFR: t.MaxFR,
MaxFS: t.MaxFS,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackVP8) MediaDescription() *psdp.MediaDescription {
typ := strconv.FormatInt(int64(t.PayloadType), 10)
@@ -131,3 +124,19 @@ func (t *TrackVP8) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackVP8) clone() Track {
return &TrackVP8{
trackBase: t.trackBase,
PayloadType: t.PayloadType,
MaxFR: t.MaxFR,
MaxFS: t.MaxFS,
}
}
// CreateDecoder creates a decoder able to decode the content of the track.
func (t *TrackVP8) CreateDecoder() *rtpvp8.Decoder {
d := &rtpvp8.Decoder{}
d.Init()
return d
}

View File

@@ -6,6 +6,8 @@ import (
"strings"
psdp "github.com/pion/sdp/v3"
"github.com/aler9/gortsplib/pkg/rtpvp9"
)
// TrackVP9 is a VP9 track.
@@ -92,16 +94,6 @@ func (t *TrackVP9) ClockRate() int {
return 90000
}
func (t *TrackVP9) clone() Track {
return &TrackVP9{
trackBase: t.trackBase,
PayloadType: t.PayloadType,
MaxFR: t.MaxFR,
MaxFS: t.MaxFS,
ProfileID: t.ProfileID,
}
}
// MediaDescription returns the track media description in SDP format.
func (t *TrackVP9) MediaDescription() *psdp.MediaDescription {
typ := strconv.FormatInt(int64(t.PayloadType), 10)
@@ -144,3 +136,20 @@ func (t *TrackVP9) MediaDescription() *psdp.MediaDescription {
},
}
}
func (t *TrackVP9) clone() Track {
return &TrackVP9{
trackBase: t.trackBase,
PayloadType: t.PayloadType,
MaxFR: t.MaxFR,
MaxFS: t.MaxFS,
ProfileID: t.ProfileID,
}
}
// CreateDecoder creates a decoder able to decode the content of the track.
func (t *TrackVP9) CreateDecoder() *rtpvp9.Decoder {
d := &rtpvp9.Decoder{}
d.Init()
return d
}