From 5cc35a77a5d447a2015dccec5f9968feedfdbcb0 Mon Sep 17 00:00:00 2001 From: saxon Date: Sat, 17 Nov 2018 23:17:08 +1030 Subject: [PATCH] rtp: finished encoder file - wrote encode function, wrote timestamp function and sequence number function - need to test --- stream/rtp/encoder.go | 65 +++++++++++++++++++++---------------------- stream/rtp/rtp.go | 6 ++-- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/stream/rtp/encoder.go b/stream/rtp/encoder.go index ada69395..315f66e8 100644 --- a/stream/rtp/encoder.go +++ b/stream/rtp/encoder.go @@ -29,51 +29,52 @@ package rtp import ( "io" + "math/rand" "time" ) -// Time related constants. const ( - rtpVer = 2 - yes = 1 - no = 0 - ccCount = 0 - // pcrFreq is the base Program Clock Reference frequency. - timestampFreq = 90000 // Hz + yes = 1 + no = 0 + defaultPktType = 1 + timestampFreq = 90000 // Hz ) type Encoder struct { - dst io.Writer - + dst io.Writer + ssrc uint32 + seqNo uint16 clock time.Duration frameInterval time.Duration } -// NewEncoder returns an Encoder with the specified frame rate. +// NewEncoder returns a new Encoder type given an io.Writer - the destination +// after encoding and the desired fps func NewEncoder(dst io.Writer, fps float64) *Encoder { return &Encoder{ dst: dst, + ssrc: rand.Uint32(), frameInterval: time.Duration(float64(time.Second) / fps), } } +// Encode takes a nalu unit and encodes it into an rtp packet and +// writes to the io.Writer given in NewEncoder func (e *Encoder) Encode(nalu []byte) error { pkt := Pkt{ - Pkt{ - V: rtpVer, // version - P: no, // padding - X: no, // header extension - CC: ccCount, - M: no, // NOTE: need to check if this works (decoders should ignore this) - PT: 6, - SN: 167, - TS: 160, - SSRC: 10, - Payload: []byte{0x00, 0x01, 0x07, 0xf0, 0x56, 0x37, 0x0a, 0x0f}, - Padding: 0, - }, + V: rtpVer, // version + P: no, // padding + X: no, // header extension + CC: no, // CSRC count + M: no, // NOTE: need to check if this works (decoders should ignore this) + PT: defaultPktType, // NOTE: 1-23 according to rtp-h264 specs (don't think we need this) + SN: e.nxtSeqNo(), // sequence number + TS: e.nxtTimestamp(), // timestamp + SSRC: e.ssrc, // source identifier + Payload: nalu, + Padding: no, } - // Write rtp packet to + _, err := e.dst.Write(pkt.Bytes()) if err != nil { return err @@ -89,15 +90,13 @@ func (e *Encoder) tick() { e.clock += e.frameInterval } -// TODO: alter and make this work for rtp -func (e *Encoder) pts() uint64 { - return uint64((e.clock + e.ptsOffset).Seconds() * pcrFreq) +// nxtTimestamp gets the next timestamp +func (e *Encoder) nxtTimestamp() uint32 { + return uint32(e.clock.Seconds() * timestampFreq) } -// TODO: alter and apply this to rtp for sequence number -func (e *Encoder) ccFor(pid int) byte { - cc := e.continuity[pid] - const continuityCounterMask = 0xf - e.continuity[pid] = (cc + 1) & continuityCounterMask - return cc +// nxtSeqNo gets the next rtp packet sequence number +func (e *Encoder) nxtSeqNo() uint16 { + e.seqNo += 1 + return e.seqNo - 1 } diff --git a/stream/rtp/rtp.go b/stream/rtp/rtp.go index bdf81e93..e4f36218 100644 --- a/stream/rtp/rtp.go +++ b/stream/rtp/rtp.go @@ -41,9 +41,9 @@ type Pkt struct { CC byte // CSRC count M byte // Marker bit PT byte // Packet type - SN int16 // Synch number - TS int32 // Timestamp - SSRC int32 // Synchronisation source identifier + SN uint16 // Synch number + TS uint32 // Timestamp + SSRC uint32 // Synchronisation source identifier Payload []byte // H264 Payload data Padding int // No of bytes of padding }