diff --git a/examples/client-read-h264-convert-to-jpeg/main.go b/examples/client-read-h264-convert-to-jpeg/main.go index 04c1798d..b0f0487d 100644 --- a/examples/client-read-h264-convert-to-jpeg/main.go +++ b/examples/client-read-h264-convert-to-jpeg/main.go @@ -63,15 +63,15 @@ func main() { } // find the H264 track - h264tr, h264trID := func() (*gortsplib.TrackH264, int) { + h264TrackID, h264track := func() (int, *gortsplib.TrackH264) { for i, track := range tracks { - if h264tr, ok := track.(*gortsplib.TrackH264); ok { - return h264tr, i + if h264track, ok := track.(*gortsplib.TrackH264); ok { + return i, h264track } } - return nil, -1 + return -1, nil }() - if h264trID < 0 { + if h264TrackID < 0 { panic("H264 track not found") } @@ -86,17 +86,18 @@ func main() { } defer h264dec.close() - // send SPS and PPS to the decoder - if h264tr.SPS() == nil || h264tr.PPS() == nil { - panic("SPS or PPS not present into the SDP") + // if present, send SPS and PPS from the SDP to the decoder + if h264track.SPS() != nil { + h264dec.decode(h264track.SPS()) + } + if h264track.PPS() != nil { + h264dec.decode(h264track.PPS()) } - h264dec.decode(h264tr.SPS()) - h264dec.decode(h264tr.PPS()) // called when a RTP packet arrives saveCount := 0 c.OnPacketRTP = func(trackID int, pkt *rtp.Packet) { - if trackID != h264trID { + if trackID != h264TrackID { return } diff --git a/examples/client-read-h264-save-to-disk/main.go b/examples/client-read-h264-save-to-disk/main.go index 8c0441bf..52f26703 100644 --- a/examples/client-read-h264-save-to-disk/main.go +++ b/examples/client-read-h264-save-to-disk/main.go @@ -35,19 +35,15 @@ func main() { } // find the H264 track - var sps []byte - var pps []byte - h264Track := func() int { + h264TrackID, h264track := func() (int, *gortsplib.TrackH264) { for i, track := range tracks { - if h264t, ok := track.(*gortsplib.TrackH264); ok { - sps = h264t.SPS() - pps = h264t.PPS() - return i + if h264track, ok := track.(*gortsplib.TrackH264); ok { + return i, h264track } } - return -1 + return -1, nil }() - if h264Track < 0 { + if h264TrackID < 0 { panic("H264 track not found") } @@ -56,14 +52,14 @@ func main() { rtpDec.Init() // setup H264->MPEGTS encoder - enc, err := newMPEGTSEncoder(sps, pps) + enc, err := newMPEGTSEncoder(h264track.SPS(), h264track.PPS()) if err != nil { panic(err) } // called when a RTP packet arrives c.OnPacketRTP = func(trackID int, pkt *rtp.Packet) { - if trackID != h264Track { + if trackID != h264TrackID { return } diff --git a/examples/client-read-h264-save-to-disk/mpegtsencoder.go b/examples/client-read-h264-save-to-disk/mpegtsencoder.go index fc0b63c4..40c44043 100644 --- a/examples/client-read-h264-save-to-disk/mpegtsencoder.go +++ b/examples/client-read-h264-save-to-disk/mpegtsencoder.go @@ -3,7 +3,6 @@ package main import ( "bufio" "context" - "fmt" "log" "os" "time" @@ -27,10 +26,6 @@ type mpegtsEncoder struct { // newMPEGTSEncoder allocates a mpegtsEncoder. func newMPEGTSEncoder(sps []byte, pps []byte) (*mpegtsEncoder, error) { - if sps == nil || pps == nil { - return nil, fmt.Errorf("SPS or PPS not provided") - } - f, err := os.Create("mystream.ts") if err != nil { return nil, err @@ -84,21 +79,32 @@ func (e *mpegtsEncoder) encode(nalus [][]byte, pts time.Duration) error { } for _, nalu := range nalus { - typ := h264.NALUType(nalu[0] & 0x1F) switch typ { - case h264.NALUTypeSPS, h264.NALUTypePPS, h264.NALUTypeAccessUnitDelimiter: - // remove existing SPS, PPS, AUD + case h264.NALUTypeSPS: + e.sps = append([]byte(nil), nalu...) + + case h264.NALUTypePPS: + e.pps = append([]byte(nil), nalu...) + + case h264.NALUTypeAccessUnitDelimiter, h264.NALUTypeSEI: continue case h264.NALUTypeIDR: // add SPS and PPS before every IDR - filteredNALUs = append(filteredNALUs, e.sps, e.pps) + if e.sps != nil && e.pps != nil { + filteredNALUs = append(filteredNALUs, e.sps, e.pps) + } } filteredNALUs = append(filteredNALUs, nalu) } + // it's useless to go on if SPS or PPS have not been provided yet + if e.sps == nil || e.pps == nil { + return nil + } + // encode into Annex-B enc, err := h264.EncodeAnnexB(filteredNALUs) if err != nil { diff --git a/examples/client-read-h264/main.go b/examples/client-read-h264/main.go index 0de09ff0..ebc22ada 100644 --- a/examples/client-read-h264/main.go +++ b/examples/client-read-h264/main.go @@ -40,15 +40,15 @@ func main() { } // find the H264 track - h264tr, h264trID := func() (*gortsplib.TrackH264, int) { + h264TrackID, h264track := func() (int, *gortsplib.TrackH264) { for i, track := range tracks { - if h264tr, ok := track.(*gortsplib.TrackH264); ok { - return h264tr, i + if h264track, ok := track.(*gortsplib.TrackH264); ok { + return i, h264track } } - return nil, -1 + return -1, nil }() - if h264trID < 0 { + if h264TrackID < 0 { panic("H264 track not found") } @@ -63,16 +63,17 @@ func main() { } defer h264dec.close() - // send SPS and PPS to the decoder - if h264tr.SPS() == nil || h264tr.PPS() == nil { - panic("SPS or PPS not present into the SDP") + // if present, send SPS and PPS from the SDP to the decoder + if h264track.SPS() != nil { + h264dec.decode(h264track.SPS()) + } + if h264track.PPS() != nil { + h264dec.decode(h264track.PPS()) } - h264dec.decode(h264tr.SPS()) - h264dec.decode(h264tr.PPS()) // called when a RTP packet arrives c.OnPacketRTP = func(trackID int, pkt *rtp.Packet) { - if trackID != h264trID { + if trackID != h264TrackID { return }