diff --git a/LICENSE b/LICENSE index 98ce277c..bfbf85aa 100644 --- a/LICENSE +++ b/LICENSE @@ -20,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -src/internal/hls.min.js is Copyright (c) Dailymotion and is protected by +internal/core/hls.min.js is Copyright (c) Dailymotion and is protected by its own license (Apache License, Version 2.0) available at https://github.com/video-dev/hls.js/blob/master/LICENSE diff --git a/README.md b/README.md index c494da50..d1683918 100644 --- a/README.md +++ b/README.md @@ -565,7 +565,7 @@ srt://localhost:8890?streamid=publish:mystream:user:pass&pkt_size=1316 If you want to publish a stream by using a client in listening mode (i.e. with `mode=listener` appended to the URL), read the next section. -Known clients that can publish with SRT are [FFmpeg](#ffmpeg), [Gstreamer](#gstreamer), [OBS Studio](#obs-studio). +Known clients that can publish with SRT are [FFmpeg](#ffmpeg), [GStreamer](#gstreamer), [OBS Studio](#obs-studio). #### SRT servers @@ -596,7 +596,7 @@ http://localhost:8889/mystream/whip Depending on the network it may be difficult to establish a connection between server and clients, see [WebRTC-specific features](#webrtc-specific-features) for remediations. -Known clients that can publish with WebRTC and WHIP are [FFmpeg](#ffmpeg), [Gstreamer](#gstreamer), [OBS Studio](#obs-studio). +Known clients that can publish with WebRTC and WHIP are [FFmpeg](#ffmpeg), [GStreamer](#gstreamer), [OBS Studio](#obs-studio). #### WebRTC servers @@ -619,7 +619,7 @@ rtsp://localhost:8554/mystream The resulting stream will be available in path `/mystream`. -Known clients that can publish with RTSP are [FFmpeg](#ffmpeg), [Gstreamer](#gstreamer), [OBS Studio](#obs-studio). +Known clients that can publish with RTSP are [FFmpeg](#ffmpeg), [GStreamer](#gstreamer), [OBS Studio](#obs-studio). #### RTSP cameras and servers @@ -661,7 +661,7 @@ In case authentication is enabled, credentials can be passed to the server by us rtmp://localhost/mystream?user=myuser&pass=mypass ``` -Known clients that can publish with RTMP are [FFmpeg](#ffmpeg), [Gstreamer](#gstreamer), [OBS Studio](#obs-studio). +Known clients that can publish with RTMP are [FFmpeg](#ffmpeg), [GStreamer](#gstreamer), [OBS Studio](#obs-studio). #### RTMP cameras and servers @@ -717,7 +717,7 @@ paths: The resulting stream will be available in path `/mypath`. -Known clients that can publish with WebRTC and WHIP are [FFmpeg](#ffmpeg) and [Gstreamer](#gstreamer). +Known clients that can publish with WebRTC and WHIP are [FFmpeg](#ffmpeg) and [GStreamer](#gstreamer). ## Read from the server @@ -842,7 +842,7 @@ If credentials are enabled, append username and password to `streamid`; srt://localhost:8890?streamid=publish:mystream:user:pass ``` -Known clients that can read with SRT are [FFmpeg](#ffmpeg-1), [Gstreamer](#gstreamer-1) and [VLC](#vlc). +Known clients that can read with SRT are [FFmpeg](#ffmpeg-1), [GStreamer](#gstreamer-1) and [VLC](#vlc). #### WebRTC @@ -860,7 +860,7 @@ http://localhost:8889/mystream/whep Depending on the network it may be difficult to establish a connection between server and clients, see [WebRTC-specific features](#webrtc-specific-features) for remediations. -Known clients that can read with WebRTC and WHEP are [FFmpeg](#ffmpeg-1), [Gstreamer](#gstreamer-1) and [web browsers](#web-browsers-1). +Known clients that can read with WebRTC and WHEP are [FFmpeg](#ffmpeg-1), [GStreamer](#gstreamer-1) and [web browsers](#web-browsers-1). #### RTSP @@ -870,7 +870,7 @@ RTSP is a protocol that allows to publish and read streams. It supports differen rtsp://localhost:8554/mystream ``` -Known clients that can read with RTSP are [FFmpeg](#ffmpeg-1), [Gstreamer](#gstreamer-1) and [VLC](#vlc). +Known clients that can read with RTSP are [FFmpeg](#ffmpeg-1), [GStreamer](#gstreamer-1) and [VLC](#vlc). ##### Latency @@ -894,7 +894,7 @@ In case authentication is enabled, credentials can be passed to the server by us rtmp://localhost/mystream?user=myuser&pass=mypass ``` -Known clients that can read with RTMP are [FFmpeg](#ffmpeg-1), [Gstreamer](#gstreamer-1) and [VLC](#vlc). +Known clients that can read with RTMP are [FFmpeg](#ffmpeg-1), [GStreamer](#gstreamer-1) and [VLC](#vlc). #### HLS @@ -923,7 +923,7 @@ ffmpeg -i rtsp://original-source \ -f rtsp rtsp://localhost:8554/mystream ``` -Known clients that can read with HLS are [FFmpeg](#ffmpeg-1), [Gstreamer](#gstreamer-1), [VLC](#vlc) and [web browsers](#web-browsers-1). +Known clients that can read with HLS are [FFmpeg](#ffmpeg-1), [GStreamer](#gstreamer-1), [VLC](#vlc) and [web browsers](#web-browsers-1). ##### LL-HLS diff --git a/internal/core/hls_muxer.go b/internal/core/hls_muxer.go index c1975efc..dcaf2bd4 100644 --- a/internal/core/hls_muxer.go +++ b/internal/core/hls_muxer.go @@ -19,9 +19,9 @@ import ( "github.com/gin-gonic/gin" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) const ( @@ -343,9 +343,9 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls startPTSFilled := false var startPTS time.Duration - stream.AddReader(m, videoMedia, videoFormatAV1, func(unit formatprocessor.Unit) { + stream.AddReader(m, videoMedia, videoFormatAV1, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitAV1) + tunit := u.(*unit.AV1) if tunit.TU == nil { return nil @@ -378,9 +378,9 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls startPTSFilled := false var startPTS time.Duration - stream.AddReader(m, videoMedia, videoFormatVP9, func(unit formatprocessor.Unit) { + stream.AddReader(m, videoMedia, videoFormatVP9, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitVP9) + tunit := u.(*unit.VP9) if tunit.Frame == nil { return nil @@ -413,9 +413,9 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls startPTSFilled := false var startPTS time.Duration - stream.AddReader(m, videoMedia, videoFormatH265, func(unit formatprocessor.Unit) { + stream.AddReader(m, videoMedia, videoFormatH265, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitH265) + tunit := u.(*unit.H265) if tunit.AU == nil { return nil @@ -454,9 +454,9 @@ func (m *hlsMuxer) createVideoTrack(stream *stream.Stream) (*media.Media, *gohls startPTSFilled := false var startPTS time.Duration - stream.AddReader(m, videoMedia, videoFormatH264, func(unit formatprocessor.Unit) { + stream.AddReader(m, videoMedia, videoFormatH264, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitH264) + tunit := u.(*unit.H264) if tunit.AU == nil { return nil @@ -498,9 +498,9 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls audioStartPTSFilled := false var audioStartPTS time.Duration - stream.AddReader(m, audioMedia, audioFormatOpus, func(unit formatprocessor.Unit) { + stream.AddReader(m, audioMedia, audioFormatOpus, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitOpus) + tunit := u.(*unit.Opus) if !audioStartPTSFilled { audioStartPTSFilled = true @@ -539,9 +539,9 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls audioStartPTSFilled := false var audioStartPTS time.Duration - stream.AddReader(m, audioMedia, audioFormatMPEG4AudioGeneric, func(unit formatprocessor.Unit) { + stream.AddReader(m, audioMedia, audioFormatMPEG4AudioGeneric, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioGeneric) + tunit := u.(*unit.MPEG4AudioGeneric) if tunit.AUs == nil { return nil @@ -582,9 +582,9 @@ func (m *hlsMuxer) createAudioTrack(stream *stream.Stream) (*media.Media, *gohls audioStartPTSFilled := false var audioStartPTS time.Duration - stream.AddReader(m, audioMedia, audioFormatMPEG4AudioLATM, func(unit formatprocessor.Unit) { + stream.AddReader(m, audioMedia, audioFormatMPEG4AudioLATM, func(u unit.Unit) { m.ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioLATM) + tunit := u.(*unit.MPEG4AudioLATM) if tunit.AU == nil { return nil diff --git a/internal/core/hls_source.go b/internal/core/hls_source.go index f79ccba0..0029eb5c 100644 --- a/internal/core/hls_source.go +++ b/internal/core/hls_source.go @@ -11,9 +11,9 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/media" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) type hlsSourceParent interface { @@ -82,8 +82,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataAV1(track, func(pts time.Duration, tu [][]byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitAV1{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.AV1{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -98,8 +98,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataVP9(track, func(pts time.Duration, frame []byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitVP9{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.VP9{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -119,8 +119,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataH26x(track, func(pts time.Duration, dts time.Duration, au [][]byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -140,8 +140,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataH26x(track, func(pts time.Duration, dts time.Duration, au [][]byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH265{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H265{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -162,8 +162,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataMPEG4Audio(track, func(pts time.Duration, aus [][]byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -181,8 +181,8 @@ func (s *hlsSource) run(ctx context.Context, cnf *conf.PathConf, reloadConf chan } c.OnDataOpus(track, func(pts time.Duration, packets [][]byte) { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitOpus{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.Opus{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, diff --git a/internal/core/rpicamera_source.go b/internal/core/rpicamera_source.go index aff203f0..7c754d77 100644 --- a/internal/core/rpicamera_source.go +++ b/internal/core/rpicamera_source.go @@ -8,10 +8,10 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/media" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/rpicamera" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) func paramsFromConf(cnf *conf.PathConf) rpicamera.Params { @@ -98,8 +98,8 @@ func (s *rpiCameraSource) run(ctx context.Context, cnf *conf.PathConf, reloadCon stream = res.stream } - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: dts, diff --git a/internal/core/rtmp_conn.go b/internal/core/rtmp_conn.go index 65fb6e42..220257ae 100644 --- a/internal/core/rtmp_conn.go +++ b/internal/core/rtmp_conn.go @@ -20,10 +20,10 @@ import ( "github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/externalcmd" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/rtmp" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) const ( @@ -338,9 +338,9 @@ func (c *rtmpConn) setupVideo( var startPTS time.Duration var videoDTSExtractor *h264.DTSExtractor - stream.AddReader(c, videoMedia, videoFormatH264, func(unit formatprocessor.Unit) { + stream.AddReader(c, videoMedia, videoFormatH264, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitH264) + tunit := u.(*unit.H264) if tunit.AU == nil { return nil @@ -427,9 +427,9 @@ func (c *rtmpConn) setupAudio( startPTSFilled := false var startPTS time.Duration - stream.AddReader(c, audioMedia, audioFormatMPEG4Generic, func(unit formatprocessor.Unit) { + stream.AddReader(c, audioMedia, audioFormatMPEG4Generic, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioGeneric) + tunit := u.(*unit.MPEG4AudioGeneric) if tunit.AUs == nil { return nil @@ -481,9 +481,9 @@ func (c *rtmpConn) setupAudio( startPTSFilled := false var startPTS time.Duration - stream.AddReader(c, audioMedia, audioFormatMPEG4AudioLATM, func(unit formatprocessor.Unit) { + stream.AddReader(c, audioMedia, audioFormatMPEG4AudioLATM, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioLATM) + tunit := u.(*unit.MPEG4AudioLATM) if tunit.AU == nil { return nil @@ -521,9 +521,9 @@ func (c *rtmpConn) setupAudio( startPTSFilled := false var startPTS time.Duration - stream.AddReader(c, audioMedia, audioFormatMPEG1, func(unit formatprocessor.Unit) { + stream.AddReader(c, audioMedia, audioFormatMPEG1, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG1Audio) + tunit := u.(*unit.MPEG1Audio) if !startPTSFilled { startPTSFilled = true @@ -624,8 +624,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { switch videoFormat.(type) { case *formats.AV1: r.OnDataAV1(func(pts time.Duration, tu [][]byte) { - stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitAV1{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(videoMedia, videoFormat, &unit.AV1{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -635,8 +635,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { case *formats.VP9: r.OnDataVP9(func(pts time.Duration, frame []byte) { - stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitVP9{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(videoMedia, videoFormat, &unit.VP9{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -646,8 +646,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { case *formats.H265: r.OnDataH265(func(pts time.Duration, au [][]byte) { - stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitH265{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(videoMedia, videoFormat, &unit.H265{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -657,8 +657,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { case *formats.H264: r.OnDataH264(func(pts time.Duration, au [][]byte) { - stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(videoMedia, videoFormat, &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -681,8 +681,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { switch audioFormat.(type) { case *formats.MPEG4AudioGeneric: r.OnDataMPEG4Audio(func(pts time.Duration, au []byte) { - stream.WriteUnit(audioMedia, audioFormat, &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(audioMedia, audioFormat, &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -692,8 +692,8 @@ func (c *rtmpConn) runPublish(conn *rtmp.Conn, u *url.URL) error { case *formats.MPEG1Audio: r.OnDataMPEG1Audio(func(pts time.Duration, frame []byte) { - stream.WriteUnit(audioMedia, audioFormat, &formatprocessor.UnitMPEG1Audio{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(audioMedia, audioFormat, &unit.MPEG1Audio{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, diff --git a/internal/core/rtmp_source.go b/internal/core/rtmp_source.go index 66cd22a7..0f0cf382 100644 --- a/internal/core/rtmp_source.go +++ b/internal/core/rtmp_source.go @@ -12,10 +12,10 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/media" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/rtmp" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) type rtmpSourceParent interface { @@ -126,8 +126,8 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error { switch videoFormat.(type) { case *formats.H264: mc.OnDataH264(func(pts time.Duration, au [][]byte) { - stream.WriteUnit(videoMedia, videoFormat, &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(videoMedia, videoFormat, &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -150,8 +150,8 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error { switch audioFormat.(type) { case *formats.MPEG4AudioGeneric: mc.OnDataMPEG4Audio(func(pts time.Duration, au []byte) { - stream.WriteUnit(audioMedia, audioFormat, &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(audioMedia, audioFormat, &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, @@ -161,8 +161,8 @@ func (s *rtmpSource) runReader(u *url.URL, nconn net.Conn) error { case *formats.MPEG1Audio: mc.OnDataMPEG1Audio(func(pts time.Duration, frame []byte) { - stream.WriteUnit(audioMedia, audioFormat, &formatprocessor.UnitMPEG1Audio{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(audioMedia, audioFormat, &unit.MPEG1Audio{ + Base: unit.Base{ NTP: time.Now(), }, PTS: pts, diff --git a/internal/core/srt_conn.go b/internal/core/srt_conn.go index 7986517a..4e8c1ee1 100644 --- a/internal/core/srt_conn.go +++ b/internal/core/srt_conn.go @@ -21,9 +21,9 @@ import ( "github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/externalcmd" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) func durationGoToMPEGTS(v time.Duration) int64 { @@ -260,8 +260,8 @@ func (c *srtConn) runPublishReader(sconn srt.Conn, path *path) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -279,8 +279,8 @@ func (c *srtConn) runPublishReader(sconn srt.Conn, path *path) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH265{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H265{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -302,8 +302,8 @@ func (c *srtConn) runPublishReader(sconn srt.Conn, path *path) error { } r.OnDataMPEG4Audio(track, func(pts int64, aus [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -322,8 +322,8 @@ func (c *srtConn) runPublishReader(sconn srt.Conn, path *path) error { } r.OnDataOpus(track, func(pts int64, packets [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitOpus{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.Opus{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -339,8 +339,8 @@ func (c *srtConn) runPublishReader(sconn srt.Conn, path *path) error { } r.OnDataMPEG1Audio(track, func(pts int64, frames [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG1Audio{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG1Audio{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -459,9 +459,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass randomAccessReceived := false dtsExtractor := h265.NewDTSExtractor() - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitH265) + tunit := u.(*unit.H265) if tunit.AU == nil { return nil } @@ -523,9 +523,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass firstIDRReceived := false dtsExtractor := h264.NewDTSExtractor() - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitH264) + tunit := u.(*unit.H264) if tunit.AU == nil { return nil } @@ -579,9 +579,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass var startPTS time.Duration startPTSFilled := false - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioGeneric) + tunit := u.(*unit.MPEG4AudioGeneric) if tunit.AUs == nil { return nil } @@ -619,9 +619,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass var startPTS time.Duration startPTSFilled := false - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG4AudioLATM) + tunit := u.(*unit.MPEG4AudioLATM) if tunit.AU == nil { return nil } @@ -662,9 +662,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass var startPTS time.Duration startPTSFilled := false - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitOpus) + tunit := u.(*unit.Opus) if tunit.Packets == nil { return nil } @@ -697,9 +697,9 @@ func (c *srtConn) runRead(req srtNewConnReq, pathName string, user string, pass var startPTS time.Duration startPTSFilled := false - res.stream.AddReader(c, medi, format, func(unit formatprocessor.Unit) { + res.stream.AddReader(c, medi, format, func(u unit.Unit) { ringBuffer.Push(func() error { - tunit := unit.(*formatprocessor.UnitMPEG1Audio) + tunit := u.(*unit.MPEG1Audio) if tunit.Frames == nil { return nil } diff --git a/internal/core/srt_source.go b/internal/core/srt_source.go index 4391bf2c..7d67b080 100644 --- a/internal/core/srt_source.go +++ b/internal/core/srt_source.go @@ -11,9 +11,9 @@ import ( "github.com/datarhei/gosrt" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) type srtSourceParent interface { @@ -116,8 +116,8 @@ func (s *srtSource) runReader(sconn srt.Conn) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -135,8 +135,8 @@ func (s *srtSource) runReader(sconn srt.Conn) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH265{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H265{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -158,8 +158,8 @@ func (s *srtSource) runReader(sconn srt.Conn) error { } r.OnDataMPEG4Audio(track, func(pts int64, aus [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -178,8 +178,8 @@ func (s *srtSource) runReader(sconn srt.Conn) error { } r.OnDataOpus(track, func(pts int64, packets [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitOpus{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.Opus{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -195,8 +195,8 @@ func (s *srtSource) runReader(sconn srt.Conn) error { } r.OnDataMPEG1Audio(track, func(pts int64, frames [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG1Audio{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG1Audio{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), diff --git a/internal/core/udp_source.go b/internal/core/udp_source.go index 9a81c36f..399249aa 100644 --- a/internal/core/udp_source.go +++ b/internal/core/udp_source.go @@ -12,9 +12,9 @@ import ( "golang.org/x/net/ipv4" "github.com/bluenviron/mediamtx/internal/conf" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) const ( @@ -165,8 +165,8 @@ func (s *udpSource) runReader(pc net.PacketConn) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH264{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H264{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -184,8 +184,8 @@ func (s *udpSource) runReader(pc net.PacketConn) error { } r.OnDataH26x(track, func(pts int64, _ int64, au [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitH265{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.H265{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -207,8 +207,8 @@ func (s *udpSource) runReader(pc net.PacketConn) error { } r.OnDataMPEG4Audio(track, func(pts int64, aus [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG4AudioGeneric{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG4AudioGeneric{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -227,8 +227,8 @@ func (s *udpSource) runReader(pc net.PacketConn) error { } r.OnDataOpus(track, func(pts int64, packets [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitOpus{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.Opus{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), @@ -244,8 +244,8 @@ func (s *udpSource) runReader(pc net.PacketConn) error { } r.OnDataMPEG1Audio(track, func(pts int64, frames [][]byte) error { - stream.WriteUnit(medi, medi.Formats[0], &formatprocessor.UnitMPEG1Audio{ - BaseUnit: formatprocessor.BaseUnit{ + stream.WriteUnit(medi, medi.Formats[0], &unit.MPEG1Audio{ + Base: unit.Base{ NTP: time.Now(), }, PTS: decodeTime(pts), diff --git a/internal/core/webrtc_outgoing_track.go b/internal/core/webrtc_outgoing_track.go index db177114..4cfdf462 100644 --- a/internal/core/webrtc_outgoing_track.go +++ b/internal/core/webrtc_outgoing_track.go @@ -14,8 +14,8 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/ringbuffer" "github.com/pion/webrtc/v3" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/stream" + "github.com/bluenviron/mediamtx/internal/unit" ) type webRTCOutgoingTrack struct { @@ -23,7 +23,7 @@ type webRTCOutgoingTrack struct { media *media.Media format formats.Format track *webrtc.TrackLocalStaticRTP - cb func(formatprocessor.Unit) error + cb func(unit.Unit) error } func newWebRTCOutgoingTrackVideo(medias media.Medias) (*webRTCOutgoingTrack, error) { @@ -56,8 +56,8 @@ func newWebRTCOutgoingTrackVideo(medias media.Medias) (*webRTCOutgoingTrack, err media: videoMedia, format: av1Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - tunit := unit.(*formatprocessor.UnitAV1) + cb: func(u unit.Unit) error { + tunit := u.(*unit.AV1) if tunit.TU == nil { return nil @@ -106,8 +106,8 @@ func newWebRTCOutgoingTrackVideo(medias media.Medias) (*webRTCOutgoingTrack, err media: videoMedia, format: vp9Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - tunit := unit.(*formatprocessor.UnitVP9) + cb: func(u unit.Unit) error { + tunit := u.(*unit.VP9) if tunit.Frame == nil { return nil @@ -156,8 +156,8 @@ func newWebRTCOutgoingTrackVideo(medias media.Medias) (*webRTCOutgoingTrack, err media: videoMedia, format: vp8Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - tunit := unit.(*formatprocessor.UnitVP8) + cb: func(u unit.Unit) error { + tunit := u.(*unit.VP8) if tunit.Frame == nil { return nil @@ -209,8 +209,8 @@ func newWebRTCOutgoingTrackVideo(medias media.Medias) (*webRTCOutgoingTrack, err media: videoMedia, format: h264Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - tunit := unit.(*formatprocessor.UnitH264) + cb: func(u unit.Unit) error { + tunit := u.(*unit.H264) if tunit.AU == nil { return nil @@ -265,8 +265,8 @@ func newWebRTCOutgoingTrackAudio(medias media.Medias) (*webRTCOutgoingTrack, err media: audioMedia, format: opusFormat, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - for _, pkt := range unit.GetRTPPackets() { + cb: func(u unit.Unit) error { + for _, pkt := range u.GetRTPPackets() { webRTCTrak.WriteRTP(pkt) //nolint:errcheck } @@ -295,8 +295,8 @@ func newWebRTCOutgoingTrackAudio(medias media.Medias) (*webRTCOutgoingTrack, err media: audioMedia, format: g722Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - for _, pkt := range unit.GetRTPPackets() { + cb: func(u unit.Unit) error { + for _, pkt := range u.GetRTPPackets() { webRTCTrak.WriteRTP(pkt) //nolint:errcheck } @@ -332,8 +332,8 @@ func newWebRTCOutgoingTrackAudio(medias media.Medias) (*webRTCOutgoingTrack, err media: audioMedia, format: g711Format, track: webRTCTrak, - cb: func(unit formatprocessor.Unit) error { - for _, pkt := range unit.GetRTPPackets() { + cb: func(u unit.Unit) error { + for _, pkt := range u.GetRTPPackets() { webRTCTrak.WriteRTP(pkt) //nolint:errcheck } @@ -363,9 +363,9 @@ func (t *webRTCOutgoingTrack) start( } }() - stream.AddReader(r, t.media, t.format, func(unit formatprocessor.Unit) { + stream.AddReader(r, t.media, t.format, func(u unit.Unit) { ringBuffer.Push(func() { - err := t.cb(unit) + err := t.cb(u) if err != nil { select { case writeError <- err: diff --git a/internal/formatprocessor/av1.go b/internal/formatprocessor/av1.go index c1414ce3..70d8efe8 100644 --- a/internal/formatprocessor/av1.go +++ b/internal/formatprocessor/av1.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitAV1 is an AV1 data unit. -type UnitAV1 struct { - BaseUnit - PTS time.Duration - TU [][]byte -} - type formatProcessorAV1 struct { udpMaxPayloadSize int format *formats.AV1 @@ -56,8 +50,8 @@ func (t *formatProcessorAV1) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorAV1) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitAV1) +func (t *formatProcessorAV1) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.AV1) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -108,9 +102,9 @@ func (t *formatProcessorAV1) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorAV1) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitAV1{ - BaseUnit: BaseUnit{ +func (t *formatProcessorAV1) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.AV1{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/generic.go b/internal/formatprocessor/generic.go index a8f5bea4..2d52fca8 100644 --- a/internal/formatprocessor/generic.go +++ b/internal/formatprocessor/generic.go @@ -8,13 +8,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitGeneric is a generic data unit. -type UnitGeneric struct { - BaseUnit -} - type formatProcessorGeneric struct { udpMaxPayloadSize int } @@ -34,8 +30,8 @@ func newGeneric( }, nil } -func (t *formatProcessorGeneric) Process(unit Unit, _ bool) error { - tunit := unit.(*UnitGeneric) +func (t *formatProcessorGeneric) Process(u unit.Unit, _ bool) error { + tunit := u.(*unit.Generic) pkt := tunit.RTPPackets[0] @@ -51,9 +47,9 @@ func (t *formatProcessorGeneric) Process(unit Unit, _ bool) error { return nil } -func (t *formatProcessorGeneric) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitGeneric{ - BaseUnit: BaseUnit{ +func (t *formatProcessorGeneric) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.Generic{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/generic_test.go b/internal/formatprocessor/generic_test.go index 41c3c7aa..d9c83044 100644 --- a/internal/formatprocessor/generic_test.go +++ b/internal/formatprocessor/generic_test.go @@ -6,6 +6,8 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/formats" "github.com/pion/rtp" "github.com/stretchr/testify/require" + + "github.com/bluenviron/mediamtx/internal/unit" ) func TestGenericRemovePadding(t *testing.T) { @@ -33,8 +35,8 @@ func TestGenericRemovePadding(t *testing.T) { PaddingSize: 20, } - err = p.Process(&UnitGeneric{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.Generic{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, }, }, false) diff --git a/internal/formatprocessor/h264.go b/internal/formatprocessor/h264.go index b6ee5bed..c383c4a1 100644 --- a/internal/formatprocessor/h264.go +++ b/internal/formatprocessor/h264.go @@ -10,6 +10,7 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) // extract SPS and PPS without decoding RTP packets @@ -69,13 +70,6 @@ func rtpH264ExtractSPSPPS(pkt *rtp.Packet) ([]byte, []byte) { } } -// UnitH264 is a H264 data unit. -type UnitH264 struct { - BaseUnit - PTS time.Duration - AU [][]byte -} - type formatProcessorH264 struct { udpMaxPayloadSize int format *formats.H264 @@ -230,8 +224,8 @@ func (t *formatProcessorH264) remuxAccessUnit(au [][]byte) [][]byte { return filteredNALUs } -func (t *formatProcessorH264) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitH264) +func (t *formatProcessorH264) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.H264) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -304,9 +298,9 @@ func (t *formatProcessorH264) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorH264) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitH264{ - BaseUnit: BaseUnit{ +func (t *formatProcessorH264) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/h264_test.go b/internal/formatprocessor/h264_test.go index 72e588c2..44ce749e 100644 --- a/internal/formatprocessor/h264_test.go +++ b/internal/formatprocessor/h264_test.go @@ -8,6 +8,8 @@ import ( "github.com/bluenviron/mediacommon/pkg/codecs/h264" "github.com/pion/rtp" "github.com/stretchr/testify/require" + + "github.com/bluenviron/mediamtx/internal/unit" ) func TestH264DynamicParams(t *testing.T) { @@ -25,8 +27,8 @@ func TestH264DynamicParams(t *testing.T) { pkts, err := enc.Encode([][]byte{{byte(h264.NALUTypeIDR)}}, 0) require.NoError(t, err) - data := &UnitH264{ - BaseUnit: BaseUnit{ + data := &unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, } @@ -40,8 +42,8 @@ func TestH264DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{7, 4, 5, 6}}, 0) // SPS require.NoError(t, err) - err = p.Process(&UnitH264{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, }, false) @@ -50,8 +52,8 @@ func TestH264DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{8, 1}}, 0) // PPS require.NoError(t, err) - err = p.Process(&UnitH264{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, }, false) @@ -63,8 +65,8 @@ func TestH264DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{byte(h264.NALUTypeIDR)}}, 0) require.NoError(t, err) - data = &UnitH264{ - BaseUnit: BaseUnit{ + data = &unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, } @@ -129,8 +131,8 @@ func TestH264OversizedPackets(t *testing.T) { Payload: []byte{0x1c, 0b01000000, 0x01, 0x02, 0x03, 0x04}, }, } { - data := &UnitH264{ - BaseUnit: BaseUnit{ + data := &unit.H264{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, }, } @@ -192,7 +194,7 @@ func TestH264EmptyPacket(t *testing.T) { p, err := New(1472, forma, true, nil) require.NoError(t, err) - unit := &UnitH264{ + unit := &unit.H264{ AU: [][]byte{ {0x07, 0x01, 0x02, 0x03}, // SPS {0x08, 0x01, 0x02}, // PPS diff --git a/internal/formatprocessor/h265.go b/internal/formatprocessor/h265.go index 4027ca85..8b44cbb4 100644 --- a/internal/formatprocessor/h265.go +++ b/internal/formatprocessor/h265.go @@ -10,6 +10,7 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) // extract VPS, SPS and PPS without decoding RTP packets @@ -76,13 +77,6 @@ func rtpH265ExtractVPSSPSPPS(pkt *rtp.Packet) ([]byte, []byte, []byte) { } } -// UnitH265 is a H265 data unit. -type UnitH265 struct { - BaseUnit - PTS time.Duration - AU [][]byte -} - type formatProcessorH265 struct { udpMaxPayloadSize int format *formats.H265 @@ -252,8 +246,8 @@ func (t *formatProcessorH265) remuxAccessUnit(au [][]byte) [][]byte { return filteredNALUs } -func (t *formatProcessorH265) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitH265) +func (t *formatProcessorH265) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.H265) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -326,9 +320,9 @@ func (t *formatProcessorH265) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorH265) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitH265{ - BaseUnit: BaseUnit{ +func (t *formatProcessorH265) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/h265_test.go b/internal/formatprocessor/h265_test.go index 3fdea293..196a6813 100644 --- a/internal/formatprocessor/h265_test.go +++ b/internal/formatprocessor/h265_test.go @@ -8,6 +8,8 @@ import ( "github.com/bluenviron/mediacommon/pkg/codecs/h265" "github.com/pion/rtp" "github.com/stretchr/testify/require" + + "github.com/bluenviron/mediamtx/internal/unit" ) func TestH265DynamicParams(t *testing.T) { @@ -24,8 +26,8 @@ func TestH265DynamicParams(t *testing.T) { pkts, err := enc.Encode([][]byte{{byte(h265.NALUType_CRA_NUT) << 1, 0}}, 0) require.NoError(t, err) - data := &UnitH265{ - BaseUnit: BaseUnit{ + data := &unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, } @@ -39,8 +41,8 @@ func TestH265DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_VPS_NUT) << 1, 1, 2, 3}}, 0) require.NoError(t, err) - err = p.Process(&UnitH265{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, }, false) @@ -49,8 +51,8 @@ func TestH265DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_SPS_NUT) << 1, 4, 5, 6}}, 0) require.NoError(t, err) - err = p.Process(&UnitH265{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, }, false) @@ -59,8 +61,8 @@ func TestH265DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_PPS_NUT) << 1, 7, 8, 9}}, 0) require.NoError(t, err) - err = p.Process(&UnitH265{ - BaseUnit: BaseUnit{ + err = p.Process(&unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, }, false) @@ -73,8 +75,8 @@ func TestH265DynamicParams(t *testing.T) { pkts, err = enc.Encode([][]byte{{byte(h265.NALUType_CRA_NUT) << 1, 0}}, 0) require.NoError(t, err) - data = &UnitH265{ - BaseUnit: BaseUnit{ + data = &unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkts[0]}, }, } @@ -128,8 +130,8 @@ func TestH265OversizedPackets(t *testing.T) { Payload: bytes.Repeat([]byte{0x01, 0x02, 0x03, 0x04}, 2000/4), }, } { - data := &UnitH265{ - BaseUnit: BaseUnit{ + data := &unit.H265{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, }, } @@ -190,7 +192,7 @@ func TestH265EmptyPacket(t *testing.T) { p, err := New(1472, forma, true, nil) require.NoError(t, err) - unit := &UnitH265{ + unit := &unit.H265{ AU: [][]byte{ {byte(h265.NALUType_VPS_NUT) << 1, 10, 11, 12}, // VPS {byte(h265.NALUType_SPS_NUT) << 1, 13, 14, 15}, // SPS diff --git a/internal/formatprocessor/mpeg1audio.go b/internal/formatprocessor/mpeg1audio.go index 09d51afd..db5457c1 100644 --- a/internal/formatprocessor/mpeg1audio.go +++ b/internal/formatprocessor/mpeg1audio.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitMPEG1Audio is a MPEG-1/2 Audio data unit. -type UnitMPEG1Audio struct { - BaseUnit - PTS time.Duration - Frames [][]byte -} - type formatProcessorMPEG1Audio struct { udpMaxPayloadSize int format *formats.MPEG1Audio @@ -53,8 +47,8 @@ func (t *formatProcessorMPEG1Audio) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorMPEG1Audio) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitMPEG1Audio) +func (t *formatProcessorMPEG1Audio) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.MPEG1Audio) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -104,9 +98,9 @@ func (t *formatProcessorMPEG1Audio) Process(unit Unit, hasNonRTSPReaders bool) e return nil } -func (t *formatProcessorMPEG1Audio) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitMPEG1Audio{ - BaseUnit: BaseUnit{ +func (t *formatProcessorMPEG1Audio) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.MPEG1Audio{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/mpeg4audio_generic.go b/internal/formatprocessor/mpeg4audio_generic.go index 044b362d..7d2ca990 100644 --- a/internal/formatprocessor/mpeg4audio_generic.go +++ b/internal/formatprocessor/mpeg4audio_generic.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitMPEG4AudioGeneric is a MPEG-4 Audio data unit. -type UnitMPEG4AudioGeneric struct { - BaseUnit - PTS time.Duration - AUs [][]byte -} - type formatProcessorMPEG4AudioGeneric struct { udpMaxPayloadSize int format *formats.MPEG4Audio @@ -58,8 +52,8 @@ func (t *formatProcessorMPEG4AudioGeneric) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorMPEG4AudioGeneric) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitMPEG4AudioGeneric) +func (t *formatProcessorMPEG4AudioGeneric) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.MPEG4AudioGeneric) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -109,9 +103,9 @@ func (t *formatProcessorMPEG4AudioGeneric) Process(unit Unit, hasNonRTSPReaders return nil } -func (t *formatProcessorMPEG4AudioGeneric) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitMPEG4AudioGeneric{ - BaseUnit: BaseUnit{ +func (t *formatProcessorMPEG4AudioGeneric) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.MPEG4AudioGeneric{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/mpeg4audio_latm.go b/internal/formatprocessor/mpeg4audio_latm.go index 9e51a73b..bb1855c8 100644 --- a/internal/formatprocessor/mpeg4audio_latm.go +++ b/internal/formatprocessor/mpeg4audio_latm.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitMPEG4AudioLATM is a MPEG-4 Audio data unit. -type UnitMPEG4AudioLATM struct { - BaseUnit - PTS time.Duration - AU []byte -} - type formatProcessorMPEG4AudioLATM struct { udpMaxPayloadSize int format *formats.MPEG4AudioLATM @@ -54,8 +48,8 @@ func (t *formatProcessorMPEG4AudioLATM) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorMPEG4AudioLATM) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitMPEG4AudioLATM) +func (t *formatProcessorMPEG4AudioLATM) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.MPEG4AudioLATM) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -105,9 +99,9 @@ func (t *formatProcessorMPEG4AudioLATM) Process(unit Unit, hasNonRTSPReaders boo return nil } -func (t *formatProcessorMPEG4AudioLATM) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitMPEG4AudioLATM{ - BaseUnit: BaseUnit{ +func (t *formatProcessorMPEG4AudioLATM) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.MPEG4AudioLATM{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/opus.go b/internal/formatprocessor/opus.go index dfb610e0..ddf1a39e 100644 --- a/internal/formatprocessor/opus.go +++ b/internal/formatprocessor/opus.go @@ -10,15 +10,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitOpus is a Opus data unit. -type UnitOpus struct { - BaseUnit - PTS time.Duration - Packets [][]byte -} - type formatProcessorOpus struct { udpMaxPayloadSize int format *formats.Opus @@ -56,8 +50,8 @@ func (t *formatProcessorOpus) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorOpus) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitOpus) +func (t *formatProcessorOpus) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.Opus) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -111,9 +105,9 @@ func (t *formatProcessorOpus) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorOpus) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitOpus{ - BaseUnit: BaseUnit{ +func (t *formatProcessorOpus) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.Opus{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/processor.go b/internal/formatprocessor/processor.go index 753b7691..a9239476 100644 --- a/internal/formatprocessor/processor.go +++ b/internal/formatprocessor/processor.go @@ -8,15 +8,16 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) // Processor cleans and normalizes streams. type Processor interface { // cleans and normalizes a data unit. - Process(Unit, bool) error + Process(unit.Unit, bool) error // wraps a RTP packet into a Unit. - UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit + UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit } // New allocates a Processor. diff --git a/internal/formatprocessor/unit.go b/internal/formatprocessor/unit.go deleted file mode 100644 index ceca4800..00000000 --- a/internal/formatprocessor/unit.go +++ /dev/null @@ -1,32 +0,0 @@ -package formatprocessor - -import ( - "time" - - "github.com/pion/rtp" -) - -// BaseUnit contains fields shared across all units. -type BaseUnit struct { - RTPPackets []*rtp.Packet - NTP time.Time -} - -// GetRTPPackets implements Unit. -func (u *BaseUnit) GetRTPPackets() []*rtp.Packet { - return u.RTPPackets -} - -// GetNTP implements Unit. -func (u *BaseUnit) GetNTP() time.Time { - return u.NTP -} - -// Unit is the elementary data unit routed across the server. -type Unit interface { - // returns RTP packets contained into the unit. - GetRTPPackets() []*rtp.Packet - - // returns the NTP timestamp of the unit. - GetNTP() time.Time -} diff --git a/internal/formatprocessor/vp8.go b/internal/formatprocessor/vp8.go index 29600911..47044191 100644 --- a/internal/formatprocessor/vp8.go +++ b/internal/formatprocessor/vp8.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitVP8 is a VP8 data unit. -type UnitVP8 struct { - BaseUnit - PTS time.Duration - Frame []byte -} - type formatProcessorVP8 struct { udpMaxPayloadSize int format *formats.VP8 @@ -54,8 +48,8 @@ func (t *formatProcessorVP8) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorVP8) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitVP8) +func (t *formatProcessorVP8) Process(y unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := y.(*unit.VP8) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -105,9 +99,9 @@ func (t *formatProcessorVP8) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorVP8) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitVP8{ - BaseUnit: BaseUnit{ +func (t *formatProcessorVP8) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.VP8{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/formatprocessor/vp9.go b/internal/formatprocessor/vp9.go index 601ee7a1..293e3cc4 100644 --- a/internal/formatprocessor/vp9.go +++ b/internal/formatprocessor/vp9.go @@ -9,15 +9,9 @@ import ( "github.com/pion/rtp" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) -// UnitVP9 is a VP9 data unit. -type UnitVP9 struct { - BaseUnit - PTS time.Duration - Frame []byte -} - type formatProcessorVP9 struct { udpMaxPayloadSize int format *formats.VP9 @@ -54,8 +48,8 @@ func (t *formatProcessorVP9) createEncoder() error { return t.encoder.Init() } -func (t *formatProcessorVP9) Process(unit Unit, hasNonRTSPReaders bool) error { //nolint:dupl - tunit := unit.(*UnitVP9) +func (t *formatProcessorVP9) Process(u unit.Unit, hasNonRTSPReaders bool) error { //nolint:dupl + tunit := u.(*unit.VP9) if tunit.RTPPackets != nil { pkt := tunit.RTPPackets[0] @@ -105,9 +99,9 @@ func (t *formatProcessorVP9) Process(unit Unit, hasNonRTSPReaders bool) error { return nil } -func (t *formatProcessorVP9) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) Unit { - return &UnitVP9{ - BaseUnit: BaseUnit{ +func (t *formatProcessorVP9) UnitForRTPPacket(pkt *rtp.Packet, ntp time.Time) unit.Unit { + return &unit.VP9{ + Base: unit.Base{ RTPPackets: []*rtp.Packet{pkt}, NTP: ntp, }, diff --git a/internal/stream/stream.go b/internal/stream/stream.go index 40bc2727..dac6a455 100644 --- a/internal/stream/stream.go +++ b/internal/stream/stream.go @@ -9,8 +9,8 @@ import ( "github.com/bluenviron/gortsplib/v3/pkg/media" "github.com/pion/rtp" - "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) // Stream is a media stream. @@ -64,7 +64,7 @@ func (s *Stream) RTSPStream() *gortsplib.ServerStream { } // AddReader adds a reader. -func (s *Stream) AddReader(r interface{}, medi *media.Media, forma formats.Format, cb func(formatprocessor.Unit)) { +func (s *Stream) AddReader(r interface{}, medi *media.Media, forma formats.Format, cb func(unit.Unit)) { sm := s.smedias[medi] sf := sm.formats[forma] sf.addReader(r, cb) @@ -80,7 +80,7 @@ func (s *Stream) RemoveReader(r interface{}) { } // WriteUnit writes a Unit. -func (s *Stream) WriteUnit(medi *media.Media, forma formats.Format, data formatprocessor.Unit) { +func (s *Stream) WriteUnit(medi *media.Media, forma formats.Format, data unit.Unit) { sm := s.smedias[medi] sf := sm.formats[forma] sf.writeUnit(s, medi, data) diff --git a/internal/stream/stream_format.go b/internal/stream/stream_format.go index a6bf032b..e63a617a 100644 --- a/internal/stream/stream_format.go +++ b/internal/stream/stream_format.go @@ -11,13 +11,14 @@ import ( "github.com/bluenviron/mediamtx/internal/formatprocessor" "github.com/bluenviron/mediamtx/internal/logger" + "github.com/bluenviron/mediamtx/internal/unit" ) type streamFormat struct { source logger.Writer proc formatprocessor.Processor mutex sync.RWMutex - nonRTSPReaders map[interface{}]func(formatprocessor.Unit) + nonRTSPReaders map[interface{}]func(unit.Unit) } func newStreamFormat( @@ -34,13 +35,13 @@ func newStreamFormat( sf := &streamFormat{ source: source, proc: proc, - nonRTSPReaders: make(map[interface{}]func(formatprocessor.Unit)), + nonRTSPReaders: make(map[interface{}]func(unit.Unit)), } return sf, nil } -func (sf *streamFormat) addReader(r interface{}, cb func(formatprocessor.Unit)) { +func (sf *streamFormat) addReader(r interface{}, cb func(unit.Unit)) { sf.mutex.Lock() defer sf.mutex.Unlock() sf.nonRTSPReaders[r] = cb @@ -52,7 +53,7 @@ func (sf *streamFormat) removeReader(r interface{}) { delete(sf.nonRTSPReaders, r) } -func (sf *streamFormat) writeUnit(s *Stream, medi *media.Media, data formatprocessor.Unit) { +func (sf *streamFormat) writeUnit(s *Stream, medi *media.Media, data unit.Unit) { sf.mutex.RLock() defer sf.mutex.RUnlock() diff --git a/internal/unit/av1.go b/internal/unit/av1.go new file mode 100644 index 00000000..6f8c2463 --- /dev/null +++ b/internal/unit/av1.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// AV1 is an AV1 data unit. +type AV1 struct { + Base + PTS time.Duration + TU [][]byte +} diff --git a/internal/unit/base.go b/internal/unit/base.go new file mode 100644 index 00000000..868a779e --- /dev/null +++ b/internal/unit/base.go @@ -0,0 +1,23 @@ +package unit + +import ( + "time" + + "github.com/pion/rtp" +) + +// Base contains fields shared across all units. +type Base struct { + RTPPackets []*rtp.Packet + NTP time.Time +} + +// GetRTPPackets implements Unit. +func (u *Base) GetRTPPackets() []*rtp.Packet { + return u.RTPPackets +} + +// GetNTP implements Unit. +func (u *Base) GetNTP() time.Time { + return u.NTP +} diff --git a/internal/unit/generic.go b/internal/unit/generic.go new file mode 100644 index 00000000..a953bd3b --- /dev/null +++ b/internal/unit/generic.go @@ -0,0 +1,6 @@ +package unit + +// Generic is a generic data unit. +type Generic struct { + Base +} diff --git a/internal/unit/h264.go b/internal/unit/h264.go new file mode 100644 index 00000000..ae7e8b08 --- /dev/null +++ b/internal/unit/h264.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// H264 is a H264 data unit. +type H264 struct { + Base + PTS time.Duration + AU [][]byte +} diff --git a/internal/unit/h265.go b/internal/unit/h265.go new file mode 100644 index 00000000..57fe267d --- /dev/null +++ b/internal/unit/h265.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// H265 is a H265 data unit. +type H265 struct { + Base + PTS time.Duration + AU [][]byte +} diff --git a/internal/unit/mpeg1audio.go b/internal/unit/mpeg1audio.go new file mode 100644 index 00000000..902ba8d1 --- /dev/null +++ b/internal/unit/mpeg1audio.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// MPEG1Audio is a MPEG-1/2 Audio data unit. +type MPEG1Audio struct { + Base + PTS time.Duration + Frames [][]byte +} diff --git a/internal/unit/mpeg4audio_generic.go b/internal/unit/mpeg4audio_generic.go new file mode 100644 index 00000000..c1cf2823 --- /dev/null +++ b/internal/unit/mpeg4audio_generic.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// MPEG4AudioGeneric is a MPEG-4 Audio data unit. +type MPEG4AudioGeneric struct { + Base + PTS time.Duration + AUs [][]byte +} diff --git a/internal/unit/mpeg4audio_latm.go b/internal/unit/mpeg4audio_latm.go new file mode 100644 index 00000000..b2cca8e6 --- /dev/null +++ b/internal/unit/mpeg4audio_latm.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// MPEG4AudioLATM is a MPEG-4 Audio data unit. +type MPEG4AudioLATM struct { + Base + PTS time.Duration + AU []byte +} diff --git a/internal/unit/opus.go b/internal/unit/opus.go new file mode 100644 index 00000000..e975c330 --- /dev/null +++ b/internal/unit/opus.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// Opus is a Opus data unit. +type Opus struct { + Base + PTS time.Duration + Packets [][]byte +} diff --git a/internal/unit/unit.go b/internal/unit/unit.go new file mode 100644 index 00000000..055fdead --- /dev/null +++ b/internal/unit/unit.go @@ -0,0 +1,17 @@ +// Package unit contains the Unit definition. +package unit + +import ( + "time" + + "github.com/pion/rtp" +) + +// Unit is the elementary data unit routed across the server. +type Unit interface { + // returns RTP packets contained into the unit. + GetRTPPackets() []*rtp.Packet + + // returns the NTP timestamp of the unit. + GetNTP() time.Time +} diff --git a/internal/unit/vp8.go b/internal/unit/vp8.go new file mode 100644 index 00000000..75c6fbf7 --- /dev/null +++ b/internal/unit/vp8.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// VP8 is a VP8 data unit. +type VP8 struct { + Base + PTS time.Duration + Frame []byte +} diff --git a/internal/unit/vp9.go b/internal/unit/vp9.go new file mode 100644 index 00000000..0ea9e000 --- /dev/null +++ b/internal/unit/vp9.go @@ -0,0 +1,12 @@ +package unit + +import ( + "time" +) + +// VP9 is a VP9 data unit. +type VP9 struct { + Base + PTS time.Duration + Frame []byte +}