Browse Source

hls muxer: fix bad computation of pts

pull/909/head
aler9 3 years ago
parent
commit
4049a01d29
  1. 20
      internal/hls/muxer_ts_generator.go
  2. 13
      internal/hls/muxer_ts_segment.go

20
internal/hls/muxer_ts_generator.go

@ -11,9 +11,6 @@ import (
) )
const ( const (
// an offset between PCR and PTS/DTS is needed to avoid PCR > PTS
pcrOffset = 500 * time.Millisecond
segmentMinAUCount = 100 segmentMinAUCount = 100
) )
@ -108,11 +105,11 @@ func (m *muxerTSGenerator) writeH264(pts time.Duration, nalus [][]byte) error {
m.startPCR = now m.startPCR = now
m.currentSegment = newMuxerTSSegment(now, m.hlsSegmentMaxSize, m.currentSegment = newMuxerTSSegment(now, m.hlsSegmentMaxSize,
m.videoTrack, m.writer.WriteData) m.videoTrack, m.writer.WriteData)
m.startPTS = pts
m.videoDTSEst = h264.NewDTSEstimator() m.videoDTSEst = h264.NewDTSEstimator()
pts = pcrOffset m.startPTS = pts
pts = 0
} else { } else {
pts = pts - m.startPTS + pcrOffset pts -= m.startPTS
// switch segment // switch segment
if idrPresent && if idrPresent &&
@ -125,7 +122,7 @@ func (m *muxerTSGenerator) writeH264(pts time.Duration, nalus [][]byte) error {
} }
} }
dts := m.videoDTSEst.Feed(pts-m.startPTS) + pcrOffset dts := m.videoDTSEst.Feed(pts)
// prepend an AUD. This is required by video.js and iOS // prepend an AUD. This is required by video.js and iOS
filteredNALUs := [][]byte{ filteredNALUs := [][]byte{
@ -156,7 +153,8 @@ func (m *muxerTSGenerator) writeH264(pts time.Duration, nalus [][]byte) error {
return err return err
} }
err = m.currentSegment.writeH264(now.Sub(m.startPCR), dts, pts, idrPresent, enc) err = m.currentSegment.writeH264(now.Sub(m.startPCR), dts,
pts, idrPresent, enc)
if err != nil { if err != nil {
if m.currentSegment.buf.Len() > 0 { if m.currentSegment.buf.Len() > 0 {
m.streamPlaylist.pushSegment(m.currentSegment) m.streamPlaylist.pushSegment(m.currentSegment)
@ -178,9 +176,9 @@ func (m *muxerTSGenerator) writeAAC(pts time.Duration, aus [][]byte) error {
m.currentSegment = newMuxerTSSegment(now, m.hlsSegmentMaxSize, m.currentSegment = newMuxerTSSegment(now, m.hlsSegmentMaxSize,
m.videoTrack, m.writer.WriteData) m.videoTrack, m.writer.WriteData)
m.startPTS = pts m.startPTS = pts
pts = pcrOffset pts = 0
} else { } else {
pts = pts - m.startPTS + pcrOffset pts -= m.startPTS
// switch segment // switch segment
if m.currentSegment.audioAUCount >= segmentMinAUCount && if m.currentSegment.audioAUCount >= segmentMinAUCount &&
@ -198,7 +196,7 @@ func (m *muxerTSGenerator) writeAAC(pts time.Duration, aus [][]byte) error {
return nil return nil
} }
pts = pts - m.startPTS + pcrOffset pts -= m.startPTS
} }
pkts := make([]*aac.ADTSPacket, len(aus)) pkts := make([]*aac.ADTSPacket, len(aus))

13
internal/hls/muxer_ts_segment.go

@ -11,6 +11,11 @@ import (
"github.com/asticode/go-astits" "github.com/asticode/go-astits"
) )
const (
// an offset between PCR and PTS/DTS is needed to avoid PCR > PTS
pcrOffset = 500 * time.Millisecond
)
type muxerTSSegment struct { type muxerTSSegment struct {
hlsSegmentMaxSize uint64 hlsSegmentMaxSize uint64
videoTrack *gortsplib.TrackH264 videoTrack *gortsplib.TrackH264
@ -93,11 +98,11 @@ func (t *muxerTSSegment) writeH264(
if dts == pts { if dts == pts {
oh.PTSDTSIndicator = astits.PTSDTSIndicatorOnlyPTS oh.PTSDTSIndicator = astits.PTSDTSIndicatorOnlyPTS
oh.PTS = &astits.ClockReference{Base: int64(pts.Seconds() * 90000)} oh.PTS = &astits.ClockReference{Base: int64((pts + pcrOffset).Seconds() * 90000)}
} else { } else {
oh.PTSDTSIndicator = astits.PTSDTSIndicatorBothPresent oh.PTSDTSIndicator = astits.PTSDTSIndicatorBothPresent
oh.DTS = &astits.ClockReference{Base: int64(dts.Seconds() * 90000)} oh.DTS = &astits.ClockReference{Base: int64((dts + pcrOffset).Seconds() * 90000)}
oh.PTS = &astits.ClockReference{Base: int64(pts.Seconds() * 90000)} oh.PTS = &astits.ClockReference{Base: int64((pts + pcrOffset).Seconds() * 90000)}
} }
_, err := t.writeData(&astits.MuxerData{ _, err := t.writeData(&astits.MuxerData{
@ -152,7 +157,7 @@ func (t *muxerTSSegment) writeAAC(
OptionalHeader: &astits.PESOptionalHeader{ OptionalHeader: &astits.PESOptionalHeader{
MarkerBits: 2, MarkerBits: 2,
PTSDTSIndicator: astits.PTSDTSIndicatorOnlyPTS, PTSDTSIndicator: astits.PTSDTSIndicatorOnlyPTS,
PTS: &astits.ClockReference{Base: int64(pts.Seconds() * 90000)}, PTS: &astits.ClockReference{Base: int64((pts + pcrOffset).Seconds() * 90000)},
}, },
PacketLength: uint16(len(enc) + 8), PacketLength: uint16(len(enc) + 8),
StreamID: 192, // audio StreamID: 192, // audio

Loading…
Cancel
Save