mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-10-04 23:32:44 +08:00
rename Data into Unit (#1556)
This commit is contained in:
@@ -355,21 +355,21 @@ func (m *hlsMuxer) setupVideoMedia(stream *stream) (*media.Media, format.Format)
|
||||
videoStartPTSFilled := false
|
||||
var videoStartPTS time.Duration
|
||||
|
||||
stream.readerAdd(m, videoMedia, videoFormatH265, func(dat formatprocessor.Data) {
|
||||
stream.readerAdd(m, videoMedia, videoFormatH265, func(unit formatprocessor.Unit) {
|
||||
m.ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataH265)
|
||||
tunit := unit.(*formatprocessor.UnitH265)
|
||||
|
||||
if tdata.AU == nil {
|
||||
if tunit.AU == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !videoStartPTSFilled {
|
||||
videoStartPTSFilled = true
|
||||
videoStartPTS = tdata.PTS
|
||||
videoStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - videoStartPTS
|
||||
pts := tunit.PTS - videoStartPTS
|
||||
|
||||
err := m.muxer.WriteH26x(tdata.NTP, pts, tdata.AU)
|
||||
err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU)
|
||||
if err != nil {
|
||||
return fmt.Errorf("muxer error: %v", err)
|
||||
}
|
||||
@@ -388,21 +388,21 @@ func (m *hlsMuxer) setupVideoMedia(stream *stream) (*media.Media, format.Format)
|
||||
videoStartPTSFilled := false
|
||||
var videoStartPTS time.Duration
|
||||
|
||||
stream.readerAdd(m, videoMedia, videoFormatH264, func(dat formatprocessor.Data) {
|
||||
stream.readerAdd(m, videoMedia, videoFormatH264, func(unit formatprocessor.Unit) {
|
||||
m.ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataH264)
|
||||
tunit := unit.(*formatprocessor.UnitH264)
|
||||
|
||||
if tdata.AU == nil {
|
||||
if tunit.AU == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !videoStartPTSFilled {
|
||||
videoStartPTSFilled = true
|
||||
videoStartPTS = tdata.PTS
|
||||
videoStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - videoStartPTS
|
||||
pts := tunit.PTS - videoStartPTS
|
||||
|
||||
err := m.muxer.WriteH26x(tdata.NTP, pts, tdata.AU)
|
||||
err := m.muxer.WriteH26x(tunit.NTP, pts, tunit.AU)
|
||||
if err != nil {
|
||||
return fmt.Errorf("muxer error: %v", err)
|
||||
}
|
||||
@@ -425,23 +425,23 @@ func (m *hlsMuxer) setupAudioMedia(stream *stream) (*media.Media, format.Format)
|
||||
audioStartPTSFilled := false
|
||||
var audioStartPTS time.Duration
|
||||
|
||||
stream.readerAdd(m, audioMedia, audioFormatMPEG4Audio, func(dat formatprocessor.Data) {
|
||||
stream.readerAdd(m, audioMedia, audioFormatMPEG4Audio, func(unit formatprocessor.Unit) {
|
||||
m.ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataMPEG4Audio)
|
||||
tunit := unit.(*formatprocessor.UnitMPEG4Audio)
|
||||
|
||||
if tdata.AUs == nil {
|
||||
if tunit.AUs == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !audioStartPTSFilled {
|
||||
audioStartPTSFilled = true
|
||||
audioStartPTS = tdata.PTS
|
||||
audioStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - audioStartPTS
|
||||
pts := tunit.PTS - audioStartPTS
|
||||
|
||||
for i, au := range tdata.AUs {
|
||||
for i, au := range tunit.AUs {
|
||||
err := m.muxer.WriteAudio(
|
||||
tdata.NTP,
|
||||
tunit.NTP,
|
||||
pts+time.Duration(i)*mpeg4audio.SamplesPerAccessUnit*
|
||||
time.Second/time.Duration(audioFormatMPEG4Audio.ClockRate()),
|
||||
au)
|
||||
@@ -464,20 +464,20 @@ func (m *hlsMuxer) setupAudioMedia(stream *stream) (*media.Media, format.Format)
|
||||
audioStartPTSFilled := false
|
||||
var audioStartPTS time.Duration
|
||||
|
||||
stream.readerAdd(m, audioMedia, audioFormatOpus, func(dat formatprocessor.Data) {
|
||||
stream.readerAdd(m, audioMedia, audioFormatOpus, func(unit formatprocessor.Unit) {
|
||||
m.ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataOpus)
|
||||
tunit := unit.(*formatprocessor.UnitOpus)
|
||||
|
||||
if !audioStartPTSFilled {
|
||||
audioStartPTSFilled = true
|
||||
audioStartPTS = tdata.PTS
|
||||
audioStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - audioStartPTS
|
||||
pts := tunit.PTS - audioStartPTS
|
||||
|
||||
err := m.muxer.WriteAudio(
|
||||
tdata.NTP,
|
||||
tunit.NTP,
|
||||
pts,
|
||||
tdata.Frame)
|
||||
tunit.Frame)
|
||||
if err != nil {
|
||||
return fmt.Errorf("muxer error: %v", err)
|
||||
}
|
||||
|
@@ -68,10 +68,10 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
|
||||
case *format.H264:
|
||||
medi.Type = media.TypeVideo
|
||||
|
||||
c.OnData(track, func(pts time.Duration, dat interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.DataH264{
|
||||
c.OnData(track, func(pts time.Duration, unit interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.UnitH264{
|
||||
PTS: pts,
|
||||
AU: dat.([][]byte),
|
||||
AU: unit.([][]byte),
|
||||
NTP: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -82,10 +82,10 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
|
||||
case *format.H265:
|
||||
medi.Type = media.TypeVideo
|
||||
|
||||
c.OnData(track, func(pts time.Duration, dat interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.DataH265{
|
||||
c.OnData(track, func(pts time.Duration, unit interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.UnitH265{
|
||||
PTS: pts,
|
||||
AU: dat.([][]byte),
|
||||
AU: unit.([][]byte),
|
||||
NTP: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -96,10 +96,10 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
|
||||
case *format.MPEG4Audio:
|
||||
medi.Type = media.TypeAudio
|
||||
|
||||
c.OnData(track, func(pts time.Duration, dat interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.DataMPEG4Audio{
|
||||
c.OnData(track, func(pts time.Duration, unit interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.UnitMPEG4Audio{
|
||||
PTS: pts,
|
||||
AUs: [][]byte{dat.([]byte)},
|
||||
AUs: [][]byte{unit.([]byte)},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
@@ -110,10 +110,10 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan
|
||||
case *format.Opus:
|
||||
medi.Type = media.TypeAudio
|
||||
|
||||
c.OnData(track, func(pts time.Duration, dat interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.DataOpus{
|
||||
c.OnData(track, func(pts time.Duration, unit interface{}) {
|
||||
err := stream.writeData(medi, ctrack, &formatprocessor.UnitOpus{
|
||||
PTS: pts,
|
||||
Frame: dat.([]byte),
|
||||
Frame: unit.([]byte),
|
||||
NTP: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
|
@@ -95,7 +95,7 @@ func (s *rpiCameraSource) run(ctx context.Context, cnf *conf.PathConf, reloadCon
|
||||
stream = res.stream
|
||||
}
|
||||
|
||||
err := stream.writeData(medi, medi.Formats[0], &formatprocessor.DataH264{
|
||||
err := stream.writeData(medi, medi.Formats[0], &formatprocessor.UnitH264{
|
||||
PTS: dts,
|
||||
AU: au,
|
||||
NTP: time.Now(),
|
||||
|
@@ -278,24 +278,24 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
var videoStartPTS time.Duration
|
||||
var videoDTSExtractor *h264.DTSExtractor
|
||||
|
||||
res.stream.readerAdd(c, videoMedia, videoFormat, func(dat formatprocessor.Data) {
|
||||
res.stream.readerAdd(c, videoMedia, videoFormat, func(unit formatprocessor.Unit) {
|
||||
ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataH264)
|
||||
tunit := unit.(*formatprocessor.UnitH264)
|
||||
|
||||
if tdata.AU == nil {
|
||||
if tunit.AU == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !videoStartPTSFilled {
|
||||
videoStartPTSFilled = true
|
||||
videoStartPTS = tdata.PTS
|
||||
videoStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - videoStartPTS
|
||||
pts := tunit.PTS - videoStartPTS
|
||||
|
||||
idrPresent := false
|
||||
nonIDRPresent := false
|
||||
|
||||
for _, nalu := range tdata.AU {
|
||||
for _, nalu := range tunit.AU {
|
||||
typ := h264.NALUType(nalu[0] & 0x1F)
|
||||
switch typ {
|
||||
case h264.NALUTypeIDR:
|
||||
@@ -318,7 +318,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
videoDTSExtractor = h264.NewDTSExtractor()
|
||||
|
||||
var err error
|
||||
dts, err = videoDTSExtractor.Extract(tdata.AU, pts)
|
||||
dts, err = videoDTSExtractor.Extract(tunit.AU, pts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -332,7 +332,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
}
|
||||
|
||||
var err error
|
||||
dts, err = videoDTSExtractor.Extract(tdata.AU, pts)
|
||||
dts, err = videoDTSExtractor.Extract(tunit.AU, pts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -341,7 +341,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
pts -= videoStartDTS
|
||||
}
|
||||
|
||||
avcc, err := h264.AVCCMarshal(tdata.AU)
|
||||
avcc, err := h264.AVCCMarshal(tunit.AU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -371,19 +371,19 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
audioStartPTSFilled := false
|
||||
var audioStartPTS time.Duration
|
||||
|
||||
res.stream.readerAdd(c, audioMedia, audioFormat, func(dat formatprocessor.Data) {
|
||||
res.stream.readerAdd(c, audioMedia, audioFormat, func(unit formatprocessor.Unit) {
|
||||
ringBuffer.Push(func() error {
|
||||
tdata := dat.(*formatprocessor.DataMPEG4Audio)
|
||||
tunit := unit.(*formatprocessor.UnitMPEG4Audio)
|
||||
|
||||
if tdata.AUs == nil {
|
||||
if tunit.AUs == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !audioStartPTSFilled {
|
||||
audioStartPTSFilled = true
|
||||
audioStartPTS = tdata.PTS
|
||||
audioStartPTS = tunit.PTS
|
||||
}
|
||||
pts := tdata.PTS - audioStartPTS
|
||||
pts := tunit.PTS - audioStartPTS
|
||||
|
||||
if videoFormat != nil {
|
||||
if !videoFirstIDRFound {
|
||||
@@ -396,7 +396,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
|
||||
}
|
||||
}
|
||||
|
||||
for i, au := range tdata.AUs {
|
||||
for i, au := range tunit.AUs {
|
||||
c.nconn.SetWriteDeadline(time.Now().Add(time.Duration(c.writeTimeout)))
|
||||
err := c.conn.WriteMessage(&message.MsgAudio{
|
||||
ChunkStreamID: message.MsgAudioChunkStreamID,
|
||||
@@ -542,7 +542,7 @@ func (c *rtmpConn) runPublish(ctx context.Context, u *url.URL) error {
|
||||
|
||||
if _, ok := videoFormat.(*format.H264); ok {
|
||||
onVideoData = func(pts time.Duration, au [][]byte) {
|
||||
err = rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.DataH264{
|
||||
err = rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.UnitH264{
|
||||
PTS: pts,
|
||||
AU: au,
|
||||
NTP: time.Now(),
|
||||
@@ -553,7 +553,7 @@ func (c *rtmpConn) runPublish(ctx context.Context, u *url.URL) error {
|
||||
}
|
||||
} else {
|
||||
onVideoData = func(pts time.Duration, au [][]byte) {
|
||||
err = rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.DataH265{
|
||||
err = rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.UnitH265{
|
||||
PTS: pts,
|
||||
AU: au,
|
||||
NTP: time.Now(),
|
||||
@@ -589,7 +589,7 @@ func (c *rtmpConn) runPublish(ctx context.Context, u *url.URL) error {
|
||||
conf.PPS,
|
||||
}
|
||||
|
||||
err := rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.DataH264{
|
||||
err := rres.stream.writeData(videoMedia, videoFormat, &formatprocessor.UnitH264{
|
||||
PTS: tmsg.DTS + tmsg.PTSDelta,
|
||||
AU: au,
|
||||
NTP: time.Now(),
|
||||
@@ -613,7 +613,7 @@ func (c *rtmpConn) runPublish(ctx context.Context, u *url.URL) error {
|
||||
}
|
||||
|
||||
if tmsg.AACType == flvio.AAC_RAW {
|
||||
err := rres.stream.writeData(audioMedia, audioFormat, &formatprocessor.DataMPEG4Audio{
|
||||
err := rres.stream.writeData(audioMedia, audioFormat, &formatprocessor.UnitMPEG4Audio{
|
||||
PTS: tmsg.DTS,
|
||||
AUs: [][]byte{tmsg.Payload},
|
||||
NTP: time.Now(),
|
||||
|
@@ -177,7 +177,7 @@ func (s *rtmpSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
continue
|
||||
}
|
||||
|
||||
err = res.stream.writeData(videoMedia, videoFormat, &formatprocessor.DataH264{
|
||||
err = res.stream.writeData(videoMedia, videoFormat, &formatprocessor.UnitH264{
|
||||
PTS: tmsg.DTS + tmsg.PTSDelta,
|
||||
AU: au,
|
||||
NTP: time.Now(),
|
||||
@@ -193,7 +193,7 @@ func (s *rtmpSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
return fmt.Errorf("received an AAC packet, but track is not set up")
|
||||
}
|
||||
|
||||
err := res.stream.writeData(audioMedia, audioFormat, &formatprocessor.DataMPEG4Audio{
|
||||
err := res.stream.writeData(audioMedia, audioFormat, &formatprocessor.UnitMPEG4Audio{
|
||||
PTS: tmsg.DTS,
|
||||
AUs: [][]byte{tmsg.Payload},
|
||||
NTP: time.Now(),
|
||||
|
@@ -327,7 +327,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
switch forma.(type) {
|
||||
case *format.H264:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataH264{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitH264{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -338,7 +338,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
case *format.H265:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataH265{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitH265{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -349,7 +349,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
case *format.VP8:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataVP8{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitVP8{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -360,7 +360,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
case *format.VP9:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataVP9{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitVP9{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -371,7 +371,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
case *format.MPEG4Audio:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataMPEG4Audio{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitMPEG4Audio{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -382,7 +382,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
case *format.Opus:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataOpus{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitOpus{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -393,7 +393,7 @@ func (s *rtspSession) onRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*base.R
|
||||
|
||||
default:
|
||||
ctx.Session.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.DataGeneric{
|
||||
err := s.stream.writeData(cmedia, cformat, &formatprocessor.UnitGeneric{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
|
@@ -139,7 +139,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
switch forma.(type) {
|
||||
case *format.H264:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataH264{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitH264{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -150,7 +150,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
case *format.H265:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataH265{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitH265{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -161,7 +161,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
case *format.VP8:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataVP8{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitVP8{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -172,7 +172,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
case *format.VP9:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataVP9{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitVP9{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -183,7 +183,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
case *format.MPEG4Audio:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataMPEG4Audio{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitMPEG4Audio{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -194,7 +194,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
case *format.Opus:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataOpus{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitOpus{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
@@ -205,7 +205,7 @@ func (s *rtspSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf cha
|
||||
|
||||
default:
|
||||
c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.DataGeneric{
|
||||
err := res.stream.writeData(cmedia, cformat, &formatprocessor.UnitGeneric{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
NTP: time.Now(),
|
||||
})
|
||||
|
@@ -45,7 +45,7 @@ func (s *stream) medias() media.Medias {
|
||||
return s.rtspStream.Medias()
|
||||
}
|
||||
|
||||
func (s *stream) readerAdd(r reader, medi *media.Media, forma format.Format, cb func(formatprocessor.Data)) {
|
||||
func (s *stream) readerAdd(r reader, medi *media.Media, forma format.Format, cb func(formatprocessor.Unit)) {
|
||||
sm := s.smedias[medi]
|
||||
sf := sm.formats[forma]
|
||||
sf.readerAdd(r, cb)
|
||||
@@ -59,7 +59,7 @@ func (s *stream) readerRemove(r reader) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stream) writeData(medi *media.Media, forma format.Format, data formatprocessor.Data) error {
|
||||
func (s *stream) writeData(medi *media.Media, forma format.Format, data formatprocessor.Unit) error {
|
||||
sm := s.smedias[medi]
|
||||
sf := sm.formats[forma]
|
||||
return sf.writeData(s, medi, data)
|
||||
|
@@ -13,7 +13,7 @@ import (
|
||||
type streamFormat struct {
|
||||
proc formatprocessor.Processor
|
||||
mutex sync.RWMutex
|
||||
nonRTSPReaders map[reader]func(formatprocessor.Data)
|
||||
nonRTSPReaders map[reader]func(formatprocessor.Unit)
|
||||
}
|
||||
|
||||
func newStreamFormat(forma format.Format, generateRTPPackets bool) (*streamFormat, error) {
|
||||
@@ -24,13 +24,13 @@ func newStreamFormat(forma format.Format, generateRTPPackets bool) (*streamForma
|
||||
|
||||
sf := &streamFormat{
|
||||
proc: proc,
|
||||
nonRTSPReaders: make(map[reader]func(formatprocessor.Data)),
|
||||
nonRTSPReaders: make(map[reader]func(formatprocessor.Unit)),
|
||||
}
|
||||
|
||||
return sf, nil
|
||||
}
|
||||
|
||||
func (sf *streamFormat) readerAdd(r reader, cb func(formatprocessor.Data)) {
|
||||
func (sf *streamFormat) readerAdd(r reader, cb func(formatprocessor.Unit)) {
|
||||
sf.mutex.Lock()
|
||||
defer sf.mutex.Unlock()
|
||||
sf.nonRTSPReaders[r] = cb
|
||||
@@ -42,7 +42,7 @@ func (sf *streamFormat) readerRemove(r reader) {
|
||||
delete(sf.nonRTSPReaders, r)
|
||||
}
|
||||
|
||||
func (sf *streamFormat) writeData(s *stream, medi *media.Media, data formatprocessor.Data) error {
|
||||
func (sf *streamFormat) writeData(s *stream, medi *media.Media, data formatprocessor.Unit) error {
|
||||
sf.mutex.RLock()
|
||||
defer sf.mutex.RUnlock()
|
||||
|
||||
|
@@ -66,7 +66,7 @@ type webRTCTrack struct {
|
||||
media *media.Media
|
||||
format format.Format
|
||||
webRTCTrack *webrtc.TrackLocalStaticRTP
|
||||
cb func(formatprocessor.Data, context.Context, chan error)
|
||||
cb func(formatprocessor.Unit, context.Context, chan error)
|
||||
}
|
||||
|
||||
func gatherMedias(tracks []*webRTCTrack) media.Medias {
|
||||
@@ -502,9 +502,9 @@ outer:
|
||||
|
||||
for _, track := range tracks {
|
||||
ctrack := track
|
||||
res.stream.readerAdd(c, track.media, track.format, func(dat formatprocessor.Data) {
|
||||
res.stream.readerAdd(c, track.media, track.format, func(unit formatprocessor.Unit) {
|
||||
ringBuffer.Push(func() {
|
||||
ctrack.cb(dat, ctx, writeError)
|
||||
ctrack.cb(unit, ctx, writeError)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -567,14 +567,14 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: vp9Media,
|
||||
format: vp9Format,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
tdata := dat.(*formatprocessor.DataVP9)
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
tunit := unit.(*formatprocessor.UnitVP9)
|
||||
|
||||
if tdata.Frame == nil {
|
||||
if tunit.Frame == nil {
|
||||
return
|
||||
}
|
||||
|
||||
packets, err := encoder.Encode(tdata.Frame, tdata.PTS)
|
||||
packets, err := encoder.Encode(tunit.Frame, tunit.PTS)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -614,14 +614,14 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: vp8Media,
|
||||
format: vp8Format,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
tdata := dat.(*formatprocessor.DataVP8)
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
tunit := unit.(*formatprocessor.UnitVP8)
|
||||
|
||||
if tdata.Frame == nil {
|
||||
if tunit.Frame == nil {
|
||||
return
|
||||
}
|
||||
|
||||
packets, err := encoder.Encode(tdata.Frame, tdata.PTS)
|
||||
packets, err := encoder.Encode(tunit.Frame, tunit.PTS)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -664,28 +664,28 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: h264Media,
|
||||
format: h264Format,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
tdata := dat.(*formatprocessor.DataH264)
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
tunit := unit.(*formatprocessor.UnitH264)
|
||||
|
||||
if tdata.AU == nil {
|
||||
if tunit.AU == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !firstNALUReceived {
|
||||
firstNALUReceived = true
|
||||
lastPTS = tdata.PTS
|
||||
lastPTS = tunit.PTS
|
||||
} else {
|
||||
if tdata.PTS < lastPTS {
|
||||
if tunit.PTS < lastPTS {
|
||||
select {
|
||||
case writeError <- fmt.Errorf("WebRTC doesn't support H264 streams with B-frames"):
|
||||
case <-ctx.Done():
|
||||
}
|
||||
return
|
||||
}
|
||||
lastPTS = tdata.PTS
|
||||
lastPTS = tunit.PTS
|
||||
}
|
||||
|
||||
packets, err := encoder.Encode(tdata.AU, tdata.PTS)
|
||||
packets, err := encoder.Encode(tunit.AU, tunit.PTS)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -718,8 +718,8 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: opusMedia,
|
||||
format: opusFormat,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range dat.GetRTPPackets() {
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range unit.GetRTPPackets() {
|
||||
webRTCTrak.WriteRTP(pkt)
|
||||
}
|
||||
},
|
||||
@@ -748,8 +748,8 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: g722Media,
|
||||
format: g722Format,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range dat.GetRTPPackets() {
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range unit.GetRTPPackets() {
|
||||
webRTCTrak.WriteRTP(pkt)
|
||||
}
|
||||
},
|
||||
@@ -786,8 +786,8 @@ func (c *webRTCConn) allocateTracks(medias media.Medias) ([]*webRTCTrack, error)
|
||||
media: g711Media,
|
||||
format: g711Format,
|
||||
webRTCTrack: webRTCTrak,
|
||||
cb: func(dat formatprocessor.Data, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range dat.GetRTPPackets() {
|
||||
cb: func(unit formatprocessor.Unit, ctx context.Context, writeError chan error) {
|
||||
for _, pkt := range unit.GetRTPPackets() {
|
||||
webRTCTrak.WriteRTP(pkt)
|
||||
}
|
||||
},
|
||||
|
@@ -13,19 +13,19 @@ const (
|
||||
maxPacketSize = 1472
|
||||
)
|
||||
|
||||
// DataGeneric is a generic data unit.
|
||||
type DataGeneric struct {
|
||||
// UnitGeneric is a generic data unit.
|
||||
type UnitGeneric struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataGeneric) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitGeneric) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataGeneric) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitGeneric) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ func newGeneric(forma format.Format, generateRTPPackets bool) (*formatProcessorG
|
||||
return &formatProcessorGeneric{}, nil
|
||||
}
|
||||
|
||||
func (t *formatProcessorGeneric) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
tdata := dat.(*DataGeneric)
|
||||
func (t *formatProcessorGeneric) Process(unit Unit, hasNonRTSPReaders bool) error {
|
||||
tunit := unit.(*UnitGeneric)
|
||||
|
||||
pkt := tdata.RTPPackets[0]
|
||||
pkt := tunit.RTPPackets[0]
|
||||
|
||||
// remove padding
|
||||
pkt.Header.Padding = false
|
||||
|
@@ -32,7 +32,7 @@ func TestGenericRemovePadding(t *testing.T) {
|
||||
PaddingSize: 20,
|
||||
}
|
||||
|
||||
err = p.Process(&DataGeneric{
|
||||
err = p.Process(&UnitGeneric{
|
||||
RTPPackets: []*rtp.Packet{pkt},
|
||||
}, false)
|
||||
require.NoError(t, err)
|
||||
|
@@ -67,21 +67,21 @@ func rtpH264ExtractSPSPPS(pkt *rtp.Packet) ([]byte, []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
// DataH264 is a H264 data unit.
|
||||
type DataH264 struct {
|
||||
// UnitH264 is a H264 data unit.
|
||||
type UnitH264 struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
AU [][]byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataH264) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitH264) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataH264) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitH264) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -198,11 +198,11 @@ func (t *formatProcessorH264) remuxAccessUnit(nalus [][]byte) [][]byte {
|
||||
return filteredNALUs
|
||||
}
|
||||
|
||||
func (t *formatProcessorH264) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataH264)
|
||||
func (t *formatProcessorH264) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitH264)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
t.updateTrackParametersFromRTPPacket(pkt)
|
||||
|
||||
if t.encoder == nil {
|
||||
@@ -233,7 +233,7 @@ func (t *formatProcessorH264) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
}
|
||||
|
||||
if t.encoder != nil {
|
||||
tdata.RTPPackets = nil
|
||||
tunit.RTPPackets = nil
|
||||
}
|
||||
|
||||
// DecodeUntilMarker() is necessary, otherwise Encode() generates partial groups
|
||||
@@ -245,9 +245,9 @@ func (t *formatProcessorH264) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.AU = au
|
||||
tdata.PTS = PTS
|
||||
tdata.AU = t.remuxAccessUnit(tdata.AU)
|
||||
tunit.AU = au
|
||||
tunit.PTS = PTS
|
||||
tunit.AU = t.remuxAccessUnit(tunit.AU)
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
@@ -255,18 +255,18 @@ func (t *formatProcessorH264) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
t.updateTrackParametersFromNALUs(tdata.AU)
|
||||
tdata.AU = t.remuxAccessUnit(tdata.AU)
|
||||
t.updateTrackParametersFromNALUs(tunit.AU)
|
||||
tunit.AU = t.remuxAccessUnit(tunit.AU)
|
||||
}
|
||||
|
||||
if len(tdata.AU) != 0 {
|
||||
pkts, err := t.encoder.Encode(tdata.AU, tdata.PTS)
|
||||
if len(tunit.AU) != 0 {
|
||||
pkts, err := t.encoder.Encode(tunit.AU, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdata.RTPPackets = pkts
|
||||
tunit.RTPPackets = pkts
|
||||
} else {
|
||||
tdata.RTPPackets = nil
|
||||
tunit.RTPPackets = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -23,7 +23,7 @@ func TestH264DynamicParams(t *testing.T) {
|
||||
|
||||
pkts, err := enc.Encode([][]byte{{byte(h264.NALUTypeIDR)}}, 0)
|
||||
require.NoError(t, err)
|
||||
data := &DataH264{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
data := &UnitH264{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
p.Process(data, true)
|
||||
|
||||
require.Equal(t, [][]byte{
|
||||
@@ -32,18 +32,18 @@ func TestH264DynamicParams(t *testing.T) {
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{7, 4, 5, 6}}, 0) // SPS
|
||||
require.NoError(t, err)
|
||||
p.Process(&DataH264{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
p.Process(&UnitH264{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{8, 1}}, 0) // PPS
|
||||
require.NoError(t, err)
|
||||
p.Process(&DataH264{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
p.Process(&UnitH264{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
|
||||
require.Equal(t, []byte{7, 4, 5, 6}, forma.SPS)
|
||||
require.Equal(t, []byte{8, 1}, forma.PPS)
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{byte(h264.NALUTypeIDR)}}, 0)
|
||||
require.NoError(t, err)
|
||||
data = &DataH264{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
data = &UnitH264{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
p.Process(data, true)
|
||||
|
||||
require.Equal(t, [][]byte{
|
||||
@@ -104,7 +104,7 @@ func TestH264OversizedPackets(t *testing.T) {
|
||||
Payload: []byte{0x1c, 0b01000000, 0x01, 0x02, 0x03, 0x04},
|
||||
},
|
||||
} {
|
||||
data := &DataH264{RTPPackets: []*rtp.Packet{pkt}}
|
||||
data := &UnitH264{RTPPackets: []*rtp.Packet{pkt}}
|
||||
p.Process(data, false)
|
||||
out = append(out, data.RTPPackets...)
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func TestH264EmptyPacket(t *testing.T) {
|
||||
p, err := New(forma, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
unit := &DataH264{
|
||||
unit := &UnitH264{
|
||||
AU: [][]byte{
|
||||
{0x07, 0x01, 0x02, 0x03}, // SPS
|
||||
{0x08, 0x01, 0x02}, // PPS
|
||||
|
@@ -74,21 +74,21 @@ func rtpH265ExtractVPSSPSPPS(pkt *rtp.Packet) ([]byte, []byte, []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
// DataH265 is a H265 data unit.
|
||||
type DataH265 struct {
|
||||
// UnitH265 is a H265 data unit.
|
||||
type UnitH265 struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
AU [][]byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataH265) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitH265) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataH265) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitH265) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -219,11 +219,11 @@ func (t *formatProcessorH265) remuxAccessUnit(nalus [][]byte) [][]byte {
|
||||
return filteredNALUs
|
||||
}
|
||||
|
||||
func (t *formatProcessorH265) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataH265)
|
||||
func (t *formatProcessorH265) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitH265)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
t.updateTrackParametersFromRTPPacket(pkt)
|
||||
|
||||
if t.encoder == nil {
|
||||
@@ -254,7 +254,7 @@ func (t *formatProcessorH265) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
}
|
||||
|
||||
if t.encoder != nil {
|
||||
tdata.RTPPackets = nil
|
||||
tunit.RTPPackets = nil
|
||||
}
|
||||
|
||||
// DecodeUntilMarker() is necessary, otherwise Encode() generates partial groups
|
||||
@@ -266,9 +266,9 @@ func (t *formatProcessorH265) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.AU = au
|
||||
tdata.PTS = PTS
|
||||
tdata.AU = t.remuxAccessUnit(tdata.AU)
|
||||
tunit.AU = au
|
||||
tunit.PTS = PTS
|
||||
tunit.AU = t.remuxAccessUnit(tunit.AU)
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
@@ -276,18 +276,18 @@ func (t *formatProcessorH265) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
t.updateTrackParametersFromNALUs(tdata.AU)
|
||||
tdata.AU = t.remuxAccessUnit(tdata.AU)
|
||||
t.updateTrackParametersFromNALUs(tunit.AU)
|
||||
tunit.AU = t.remuxAccessUnit(tunit.AU)
|
||||
}
|
||||
|
||||
if len(tdata.AU) != 0 {
|
||||
pkts, err := t.encoder.Encode(tdata.AU, tdata.PTS)
|
||||
if len(tunit.AU) != 0 {
|
||||
pkts, err := t.encoder.Encode(tunit.AU, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tdata.RTPPackets = pkts
|
||||
tunit.RTPPackets = pkts
|
||||
} else {
|
||||
tdata.RTPPackets = nil
|
||||
tunit.RTPPackets = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -22,7 +22,7 @@ func TestH265DynamicParams(t *testing.T) {
|
||||
|
||||
pkts, err := enc.Encode([][]byte{{byte(h265.NALUType_CRA_NUT) << 1, 0}}, 0)
|
||||
require.NoError(t, err)
|
||||
data := &DataH265{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
data := &UnitH265{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
p.Process(data, true)
|
||||
|
||||
require.Equal(t, [][]byte{
|
||||
@@ -31,15 +31,15 @@ func TestH265DynamicParams(t *testing.T) {
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_VPS_NUT) << 1, 1, 2, 3}}, 0)
|
||||
require.NoError(t, err)
|
||||
p.Process(&DataH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
p.Process(&UnitH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_SPS_NUT) << 1, 4, 5, 6}}, 0)
|
||||
require.NoError(t, err)
|
||||
p.Process(&DataH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
p.Process(&UnitH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_PPS_NUT) << 1, 7, 8, 9}}, 0)
|
||||
require.NoError(t, err)
|
||||
p.Process(&DataH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
p.Process(&UnitH265{RTPPackets: []*rtp.Packet{pkts[0]}}, false)
|
||||
|
||||
require.Equal(t, []byte{byte(h265.NALUType_VPS_NUT) << 1, 1, 2, 3}, forma.VPS)
|
||||
require.Equal(t, []byte{byte(h265.NALUType_SPS_NUT) << 1, 4, 5, 6}, forma.SPS)
|
||||
@@ -47,7 +47,7 @@ func TestH265DynamicParams(t *testing.T) {
|
||||
|
||||
pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_CRA_NUT) << 1, 0}}, 0)
|
||||
require.NoError(t, err)
|
||||
data = &DataH265{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
data = &UnitH265{RTPPackets: []*rtp.Packet{pkts[0]}}
|
||||
p.Process(data, true)
|
||||
|
||||
require.Equal(t, [][]byte{
|
||||
@@ -97,7 +97,7 @@ func TestH265OversizedPackets(t *testing.T) {
|
||||
Payload: bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 2000/4),
|
||||
},
|
||||
} {
|
||||
data := &DataH265{RTPPackets: []*rtp.Packet{pkt}}
|
||||
data := &UnitH265{RTPPackets: []*rtp.Packet{pkt}}
|
||||
p.Process(data, false)
|
||||
out = append(out, data.RTPPackets...)
|
||||
}
|
||||
@@ -153,7 +153,7 @@ func TestH265EmptyPacket(t *testing.T) {
|
||||
p, err := New(forma, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
unit := &DataH265{
|
||||
unit := &UnitH265{
|
||||
AU: [][]byte{
|
||||
{byte(h265.NALUType_VPS_NUT) << 1, 10, 11, 12}, // VPS
|
||||
{byte(h265.NALUType_SPS_NUT) << 1, 13, 14, 15}, // SPS
|
||||
|
@@ -9,21 +9,21 @@ import (
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// DataMPEG4Audio is a MPEG4-audio data unit.
|
||||
type DataMPEG4Audio struct {
|
||||
// UnitMPEG4Audio is a MPEG4-audio data unit.
|
||||
type UnitMPEG4Audio struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
AUs [][]byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataMPEG4Audio) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitMPEG4Audio) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataMPEG4Audio) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitMPEG4Audio) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ func newMPEG4Audio(
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *formatProcessorMPEG4Audio) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataMPEG4Audio)
|
||||
func (t *formatProcessorMPEG4Audio) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitMPEG4Audio)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
|
||||
// remove padding
|
||||
pkt.Header.Padding = false
|
||||
@@ -77,19 +77,19 @@ func (t *formatProcessorMPEG4Audio) Process(dat Data, hasNonRTSPReaders bool) er
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.AUs = aus
|
||||
tdata.PTS = PTS
|
||||
tunit.AUs = aus
|
||||
tunit.PTS = PTS
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
return nil
|
||||
}
|
||||
|
||||
pkts, err := t.encoder.Encode(tdata.AUs, tdata.PTS)
|
||||
pkts, err := t.encoder.Encode(tunit.AUs, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.RTPPackets = pkts
|
||||
tunit.RTPPackets = pkts
|
||||
return nil
|
||||
}
|
||||
|
@@ -9,21 +9,21 @@ import (
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// DataOpus is a Opus data unit.
|
||||
type DataOpus struct {
|
||||
// UnitOpus is a Opus data unit.
|
||||
type UnitOpus struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
Frame []byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataOpus) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitOpus) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataOpus) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitOpus) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ func newOpus(
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *formatProcessorOpus) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataOpus)
|
||||
func (t *formatProcessorOpus) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitOpus)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
|
||||
// remove padding
|
||||
pkt.Header.Padding = false
|
||||
@@ -74,19 +74,19 @@ func (t *formatProcessorOpus) Process(dat Data, hasNonRTSPReaders bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.Frame = frame
|
||||
tdata.PTS = PTS
|
||||
tunit.Frame = frame
|
||||
tunit.PTS = PTS
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
return nil
|
||||
}
|
||||
|
||||
pkt, err := t.encoder.Encode(tdata.Frame, tdata.PTS)
|
||||
pkt, err := t.encoder.Encode(tunit.Frame, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.RTPPackets = []*rtp.Packet{pkt}
|
||||
tunit.RTPPackets = []*rtp.Packet{pkt}
|
||||
return nil
|
||||
}
|
||||
|
@@ -2,23 +2,13 @@
|
||||
package formatprocessor
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
|
||||
"github.com/aler9/gortsplib/v2/pkg/format"
|
||||
)
|
||||
|
||||
// Data is the elementary data unit routed across the server.
|
||||
type Data interface {
|
||||
GetRTPPackets() []*rtp.Packet
|
||||
GetNTP() time.Time
|
||||
}
|
||||
|
||||
// Processor allows to cleanup and normalize streams.
|
||||
type Processor interface {
|
||||
// clears and normalizes a data unit.
|
||||
Process(Data, bool) error
|
||||
Process(Unit, bool) error
|
||||
}
|
||||
|
||||
// New allocates a Processor.
|
||||
|
13
internal/formatprocessor/unit.go
Normal file
13
internal/formatprocessor/unit.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package formatprocessor
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// Unit is the elementary data unit routed across the server.
|
||||
type Unit interface {
|
||||
GetRTPPackets() []*rtp.Packet
|
||||
GetNTP() time.Time
|
||||
}
|
@@ -9,21 +9,21 @@ import (
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// DataVP8 is a VP8 data unit.
|
||||
type DataVP8 struct {
|
||||
// UnitVP8 is a VP8 data unit.
|
||||
type UnitVP8 struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
Frame []byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataVP8) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitVP8) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataVP8) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitVP8) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ func newVP8(
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *formatProcessorVP8) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataVP8)
|
||||
func (t *formatProcessorVP8) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitVP8)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
|
||||
// remove padding
|
||||
pkt.Header.Padding = false
|
||||
@@ -77,19 +77,19 @@ func (t *formatProcessorVP8) Process(dat Data, hasNonRTSPReaders bool) error { /
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.Frame = frame
|
||||
tdata.PTS = PTS
|
||||
tunit.Frame = frame
|
||||
tunit.PTS = PTS
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
return nil
|
||||
}
|
||||
|
||||
pkts, err := t.encoder.Encode(tdata.Frame, tdata.PTS)
|
||||
pkts, err := t.encoder.Encode(tunit.Frame, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.RTPPackets = pkts
|
||||
tunit.RTPPackets = pkts
|
||||
return nil
|
||||
}
|
||||
|
@@ -9,21 +9,21 @@ import (
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
// DataVP9 is a VP9 data unit.
|
||||
type DataVP9 struct {
|
||||
// UnitVP9 is a VP9 data unit.
|
||||
type UnitVP9 struct {
|
||||
RTPPackets []*rtp.Packet
|
||||
NTP time.Time
|
||||
PTS time.Duration
|
||||
Frame []byte
|
||||
}
|
||||
|
||||
// GetRTPPackets implements Data.
|
||||
func (d *DataVP9) GetRTPPackets() []*rtp.Packet {
|
||||
// GetRTPPackets implements Unit.
|
||||
func (d *UnitVP9) GetRTPPackets() []*rtp.Packet {
|
||||
return d.RTPPackets
|
||||
}
|
||||
|
||||
// GetNTP implements Data.
|
||||
func (d *DataVP9) GetNTP() time.Time {
|
||||
// GetNTP implements Unit.
|
||||
func (d *UnitVP9) GetNTP() time.Time {
|
||||
return d.NTP
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ func newVP9(
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (t *formatProcessorVP9) Process(dat Data, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tdata := dat.(*DataVP9)
|
||||
func (t *formatProcessorVP9) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl
|
||||
tunit := unit.(*UnitVP9)
|
||||
|
||||
if tdata.RTPPackets != nil {
|
||||
pkt := tdata.RTPPackets[0]
|
||||
if tunit.RTPPackets != nil {
|
||||
pkt := tunit.RTPPackets[0]
|
||||
|
||||
// remove padding
|
||||
pkt.Header.Padding = false
|
||||
@@ -77,19 +77,19 @@ func (t *formatProcessorVP9) Process(dat Data, hasNonRTSPReaders bool) error { /
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.Frame = frame
|
||||
tdata.PTS = PTS
|
||||
tunit.Frame = frame
|
||||
tunit.PTS = PTS
|
||||
}
|
||||
|
||||
// route packet as is
|
||||
return nil
|
||||
}
|
||||
|
||||
pkts, err := t.encoder.Encode(tdata.Frame, tdata.PTS)
|
||||
pkts, err := t.encoder.Encode(tunit.Frame, tunit.PTS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tdata.RTPPackets = pkts
|
||||
tunit.RTPPackets = pkts
|
||||
return nil
|
||||
}
|
||||
|
@@ -281,13 +281,13 @@ func TestClientMPEGTS(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
onH264 := func(pts time.Duration, dat interface{}) {
|
||||
onH264 := func(pts time.Duration, unit interface{}) {
|
||||
require.Equal(t, 2*time.Second, pts)
|
||||
require.Equal(t, [][]byte{
|
||||
{7, 1, 2, 3},
|
||||
{8},
|
||||
{5},
|
||||
}, dat)
|
||||
}, unit)
|
||||
close(packetRecv)
|
||||
}
|
||||
|
||||
@@ -344,13 +344,13 @@ func TestClientFMP4(t *testing.T) {
|
||||
|
||||
packetRecv := make(chan struct{})
|
||||
|
||||
onH264 := func(pts time.Duration, dat interface{}) {
|
||||
onH264 := func(pts time.Duration, unit interface{}) {
|
||||
require.Equal(t, 2*time.Second, pts)
|
||||
require.Equal(t, [][]byte{
|
||||
{7, 1, 2, 3},
|
||||
{8},
|
||||
{5},
|
||||
}, dat)
|
||||
}, unit)
|
||||
close(packetRecv)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user