mirror of
https://github.com/bluenviron/mediamtx
synced 2025-01-25 16:33:39 +00:00
3606472e82
Previously, RTP packets coming from sources other than RTSP (that actually are RTMP and HLS) were generated before the H264 remuxing, and that leaded to invalid streams, expecially when sourceOnDemand is true and the stream has invalid or dynamic SPS/PPS.
104 lines
2.0 KiB
Go
104 lines
2.0 KiB
Go
package core
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/aler9/gortsplib"
|
|
)
|
|
|
|
type streamNonRTSPReadersMap struct {
|
|
mutex sync.RWMutex
|
|
ma map[reader]struct{}
|
|
}
|
|
|
|
func newStreamNonRTSPReadersMap() *streamNonRTSPReadersMap {
|
|
return &streamNonRTSPReadersMap{
|
|
ma: make(map[reader]struct{}),
|
|
}
|
|
}
|
|
|
|
func (m *streamNonRTSPReadersMap) close() {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
m.ma = nil
|
|
}
|
|
|
|
func (m *streamNonRTSPReadersMap) add(r reader) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
m.ma[r] = struct{}{}
|
|
}
|
|
|
|
func (m *streamNonRTSPReadersMap) remove(r reader) {
|
|
m.mutex.Lock()
|
|
defer m.mutex.Unlock()
|
|
delete(m.ma, r)
|
|
}
|
|
|
|
func (m *streamNonRTSPReadersMap) writeData(data *data) {
|
|
m.mutex.RLock()
|
|
defer m.mutex.RUnlock()
|
|
|
|
for c := range m.ma {
|
|
c.onReaderData(data)
|
|
}
|
|
}
|
|
|
|
type stream struct {
|
|
nonRTSPReaders *streamNonRTSPReadersMap
|
|
rtspStream *gortsplib.ServerStream
|
|
streamTracks []streamTrack
|
|
}
|
|
|
|
func newStream(tracks gortsplib.Tracks, generateRTPPackets bool) (*stream, error) {
|
|
s := &stream{
|
|
nonRTSPReaders: newStreamNonRTSPReadersMap(),
|
|
rtspStream: gortsplib.NewServerStream(tracks),
|
|
}
|
|
|
|
s.streamTracks = make([]streamTrack, len(s.rtspStream.Tracks()))
|
|
|
|
for i, track := range s.rtspStream.Tracks() {
|
|
var err error
|
|
s.streamTracks[i], err = newStreamTrack(track, generateRTPPackets, s.writeDataInner)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
func (s *stream) close() {
|
|
s.nonRTSPReaders.close()
|
|
s.rtspStream.Close()
|
|
}
|
|
|
|
func (s *stream) tracks() gortsplib.Tracks {
|
|
return s.rtspStream.Tracks()
|
|
}
|
|
|
|
func (s *stream) readerAdd(r reader) {
|
|
if _, ok := r.(pathRTSPSession); !ok {
|
|
s.nonRTSPReaders.add(r)
|
|
}
|
|
}
|
|
|
|
func (s *stream) readerRemove(r reader) {
|
|
if _, ok := r.(pathRTSPSession); !ok {
|
|
s.nonRTSPReaders.remove(r)
|
|
}
|
|
}
|
|
|
|
func (s *stream) writeData(data *data) {
|
|
s.streamTracks[data.trackID].writeData(data)
|
|
}
|
|
|
|
func (s *stream) writeDataInner(data *data) {
|
|
// forward to RTSP readers
|
|
s.rtspStream.WritePacketRTP(data.trackID, data.rtpPacket, data.ptsEqualsDTS)
|
|
|
|
// forward to non-RTSP readers
|
|
s.nonRTSPReaders.writeData(data)
|
|
}
|