mirror of
https://github.com/bluenviron/mediamtx.git
synced 2026-01-10 12:22:07 -08:00
force all readers to use an asynchronous writer (#2265)
needed by #2255
This commit is contained in:
parent
30a69a7722
commit
5fb7f4e846
26 changed files with 962 additions and 938 deletions
|
|
@ -10,12 +10,15 @@ import (
|
|||
"github.com/bluenviron/gortsplib/v4/pkg/format"
|
||||
"github.com/pion/rtp"
|
||||
|
||||
"github.com/bluenviron/mediamtx/internal/asyncwriter"
|
||||
"github.com/bluenviron/mediamtx/internal/logger"
|
||||
"github.com/bluenviron/mediamtx/internal/unit"
|
||||
)
|
||||
|
||||
type readerFunc func(unit.Unit) error
|
||||
|
||||
// Stream is a media stream.
|
||||
// It stores tracks, readers and allow to write data to readers.
|
||||
// It stores tracks, readers and allows to write data to readers.
|
||||
type Stream struct {
|
||||
desc *description.Session
|
||||
bytesReceived *uint64
|
||||
|
|
@ -62,7 +65,7 @@ func (s *Stream) Close() {
|
|||
}
|
||||
}
|
||||
|
||||
// Desc returns description of the stream.
|
||||
// Desc returns the description of the stream.
|
||||
func (s *Stream) Desc() *description.Session {
|
||||
return s.desc
|
||||
}
|
||||
|
|
@ -90,7 +93,7 @@ func (s *Stream) RTSPSStream(server *gortsplib.Server) *gortsplib.ServerStream {
|
|||
}
|
||||
|
||||
// AddReader adds a reader.
|
||||
func (s *Stream) AddReader(r interface{}, medi *description.Media, forma format.Format, cb func(unit.Unit)) {
|
||||
func (s *Stream) AddReader(r *asyncwriter.Writer, medi *description.Media, forma format.Format, cb readerFunc) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
|
|
@ -100,7 +103,7 @@ func (s *Stream) AddReader(r interface{}, medi *description.Media, forma format.
|
|||
}
|
||||
|
||||
// RemoveReader removes a reader.
|
||||
func (s *Stream) RemoveReader(r interface{}) {
|
||||
func (s *Stream) RemoveReader(r *asyncwriter.Writer) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
|
|
@ -112,14 +115,14 @@ func (s *Stream) RemoveReader(r interface{}) {
|
|||
}
|
||||
|
||||
// WriteUnit writes a Unit.
|
||||
func (s *Stream) WriteUnit(medi *description.Media, forma format.Format, data unit.Unit) {
|
||||
func (s *Stream) WriteUnit(medi *description.Media, forma format.Format, u unit.Unit) {
|
||||
sm := s.smedias[medi]
|
||||
sf := sm.formats[forma]
|
||||
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
sf.writeUnit(s, medi, data)
|
||||
sf.writeUnit(s, medi, u)
|
||||
}
|
||||
|
||||
// WriteRTPPacket writes a RTP packet.
|
||||
|
|
|
|||
|
|
@ -8,15 +8,24 @@ import (
|
|||
"github.com/bluenviron/gortsplib/v4/pkg/format"
|
||||
"github.com/pion/rtp"
|
||||
|
||||
"github.com/bluenviron/mediamtx/internal/asyncwriter"
|
||||
"github.com/bluenviron/mediamtx/internal/formatprocessor"
|
||||
"github.com/bluenviron/mediamtx/internal/logger"
|
||||
"github.com/bluenviron/mediamtx/internal/unit"
|
||||
)
|
||||
|
||||
func unitSize(u unit.Unit) uint64 {
|
||||
n := uint64(0)
|
||||
for _, pkt := range u.GetRTPPackets() {
|
||||
n += uint64(pkt.MarshalSize())
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
type streamFormat struct {
|
||||
decodeErrLogger logger.Writer
|
||||
proc formatprocessor.Processor
|
||||
nonRTSPReaders map[interface{}]func(unit.Unit)
|
||||
readers map[*asyncwriter.Writer]readerFunc
|
||||
}
|
||||
|
||||
func newStreamFormat(
|
||||
|
|
@ -33,50 +42,47 @@ func newStreamFormat(
|
|||
sf := &streamFormat{
|
||||
decodeErrLogger: decodeErrLogger,
|
||||
proc: proc,
|
||||
nonRTSPReaders: make(map[interface{}]func(unit.Unit)),
|
||||
readers: make(map[*asyncwriter.Writer]readerFunc),
|
||||
}
|
||||
|
||||
return sf, nil
|
||||
}
|
||||
|
||||
func (sf *streamFormat) addReader(r interface{}, cb func(unit.Unit)) {
|
||||
sf.nonRTSPReaders[r] = cb
|
||||
func (sf *streamFormat) addReader(r *asyncwriter.Writer, cb readerFunc) {
|
||||
sf.readers[r] = cb
|
||||
}
|
||||
|
||||
func (sf *streamFormat) removeReader(r interface{}) {
|
||||
delete(sf.nonRTSPReaders, r)
|
||||
func (sf *streamFormat) removeReader(r *asyncwriter.Writer) {
|
||||
delete(sf.readers, r)
|
||||
}
|
||||
|
||||
func (sf *streamFormat) writeUnit(s *Stream, medi *description.Media, data unit.Unit) {
|
||||
hasNonRTSPReaders := len(sf.nonRTSPReaders) > 0
|
||||
func (sf *streamFormat) writeUnit(s *Stream, medi *description.Media, u unit.Unit) {
|
||||
hasNonRTSPReaders := len(sf.readers) > 0
|
||||
|
||||
err := sf.proc.Process(data, hasNonRTSPReaders)
|
||||
err := sf.proc.Process(u, hasNonRTSPReaders)
|
||||
if err != nil {
|
||||
sf.decodeErrLogger.Log(logger.Warn, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
n := uint64(0)
|
||||
for _, pkt := range data.GetRTPPackets() {
|
||||
n += uint64(pkt.MarshalSize())
|
||||
}
|
||||
atomic.AddUint64(s.bytesReceived, n)
|
||||
atomic.AddUint64(s.bytesReceived, unitSize(u))
|
||||
|
||||
if s.rtspStream != nil {
|
||||
for _, pkt := range data.GetRTPPackets() {
|
||||
s.rtspStream.WritePacketRTPWithNTP(medi, pkt, data.GetNTP()) //nolint:errcheck
|
||||
for _, pkt := range u.GetRTPPackets() {
|
||||
s.rtspStream.WritePacketRTPWithNTP(medi, pkt, u.GetNTP()) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
if s.rtspsStream != nil {
|
||||
for _, pkt := range data.GetRTPPackets() {
|
||||
s.rtspsStream.WritePacketRTPWithNTP(medi, pkt, data.GetNTP()) //nolint:errcheck
|
||||
for _, pkt := range u.GetRTPPackets() {
|
||||
s.rtspsStream.WritePacketRTPWithNTP(medi, pkt, u.GetNTP()) //nolint:errcheck
|
||||
}
|
||||
}
|
||||
|
||||
// forward decoded frames to non-RTSP readers
|
||||
for _, cb := range sf.nonRTSPReaders {
|
||||
cb(data)
|
||||
for writer, cb := range sf.readers {
|
||||
writer.Push(func() error {
|
||||
return cb(u)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue