|
|
|
@ -278,24 +278,24 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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(), |
|
|
|
|