mirror of https://bitbucket.org/ausocean/av.git
protocol/rtsp: more commenting and started writing client_test.go to check the behaviour of the rtcp client
This commit is contained in:
parent
5fa0969530
commit
af664b0661
|
@ -59,14 +59,14 @@ func NewClient(clientAddress, serverAddress, name string, sendInterval time.Dura
|
|||
}
|
||||
|
||||
// Start starts the listen and send routines. This will start the process of
|
||||
// receiving and parsing SenderReports, and the process of sending receiver
|
||||
// receiving and parsing sender reports, and the process of sending receiver
|
||||
// reports to the server.
|
||||
func (c *client) Start() {
|
||||
go c.listen()
|
||||
go c.send()
|
||||
}
|
||||
|
||||
// Listen reads from the UDP connection and parses SenderReports.
|
||||
// listen reads from the UDP connection and parses SenderReports.
|
||||
func (c *client) listen() {
|
||||
conn, err := net.ListenUDP("udp", c.cAddr)
|
||||
if err != nil {
|
||||
|
@ -79,7 +79,7 @@ func (c *client) listen() {
|
|||
}
|
||||
}
|
||||
|
||||
// send write sender reports to the server.
|
||||
// send writes receiver reports to the server.
|
||||
func (c *client) send() {
|
||||
conn, err := net.DialUDP("udp", c.cAddr, c.sAddr)
|
||||
if err != nil {
|
||||
|
@ -154,12 +154,15 @@ func (c *client) parse(buf []byte) {
|
|||
c.setSenderTs(msw, lsw)
|
||||
}
|
||||
|
||||
// UpdateSequence will allow updating of the highest sequence number received
|
||||
// through an rtp stream.
|
||||
func (c *client) UpdateSequence(s uint32) {
|
||||
c.mu.Lock()
|
||||
c.sequence = s
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// highestSequence will return the highest sequence number received through rtp.
|
||||
func (c *client) highestSequence() uint32 {
|
||||
var s uint32
|
||||
c.mu.Lock()
|
||||
|
@ -168,10 +171,13 @@ func (c *client) highestSequence() uint32 {
|
|||
return s
|
||||
}
|
||||
|
||||
// jitter returns the interarrival jitter as described by RTCP specifications:
|
||||
// https://tools.ietf.org/html/rfc3550
|
||||
func (c *client) jitter() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// setSenderTs allows us to safely set the current sender report timestamp.
|
||||
func (c *client) setSenderTs(msw, lsw uint32) {
|
||||
c.mu.Lock()
|
||||
binary.BigEndian.PutUint32(c.senderTs[:], msw)
|
||||
|
@ -179,6 +185,7 @@ func (c *client) setSenderTs(msw, lsw uint32) {
|
|||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// lastSenderTs returns the timestamp of the most recent sender report.
|
||||
func (c *client) lastSenderTs() uint32 {
|
||||
var ts uint32
|
||||
c.mu.Lock()
|
||||
|
@ -187,6 +194,8 @@ func (c *client) lastSenderTs() uint32 {
|
|||
return ts
|
||||
}
|
||||
|
||||
// delay returns the duration between the receive time of the last sender report
|
||||
// and now. This is called when forming a receiver report.
|
||||
func (c *client) delay() uint32 {
|
||||
var receiveTime time.Time
|
||||
c.mu.Lock()
|
||||
|
@ -196,6 +205,7 @@ func (c *client) delay() uint32 {
|
|||
return uint32(now.Sub(receiveTime).Seconds() / delayUnit)
|
||||
}
|
||||
|
||||
// received is called when a sender report is received to mark the receive time.
|
||||
func (c *client) received() {
|
||||
c.mu.Lock()
|
||||
c.receiveTime = time.Now()
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package rtcp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReceiveAndSend(t *testing.T) {
|
||||
quit := make(chan struct{})
|
||||
go testServer(quit)
|
||||
}
|
||||
|
||||
func testServer(quit chan struct{}, t *testing.T) {
|
||||
const testServerAddr = "localhost:8000"
|
||||
sAddr, err := net.ResolveUDPAddr("udp", testServerAddr)
|
||||
if err != nil {
|
||||
t.Fatalf("could not resolve test server address, failed with error: %v", err)
|
||||
}
|
||||
|
||||
conn, err := net.DialUDP("udp", nil, sAddr)
|
||||
if err != nil {
|
||||
t.Fatalf("could not dial, failed with error: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-quit:
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
|
@ -7,14 +7,12 @@ import (
|
|||
|
||||
// Timestamp gets the timestamp from a receiver report and returns as the most
|
||||
// significant word, and the least significant word. If the given bytes do not
|
||||
// represent a valid receiver report, and error is returned.
|
||||
// represent a valid receiver report, an error is returned.
|
||||
func Timestamp(buf []byte) (msw, lsw uint32, err error) {
|
||||
// First check version of rtcp
|
||||
if (buf[0] & 0xc0 >> 6) != 2 {
|
||||
return 0, 0, errors.New("incompatible RTCP version")
|
||||
}
|
||||
|
||||
// Check type of packet
|
||||
if buf[1] != typeSenderReport {
|
||||
return 0, 0, errors.New("rtcp packet is not of sender report type")
|
||||
}
|
||||
|
|
|
@ -16,18 +16,20 @@ const (
|
|||
typeCName = 1
|
||||
)
|
||||
|
||||
// MISC.
|
||||
const (
|
||||
reportBlockSize = 6
|
||||
)
|
||||
|
||||
// ReceiverReport describes an RTCP receiver report packet.
|
||||
type ReceiverReport struct {
|
||||
Header
|
||||
|
||||
SenderSSRC uint32
|
||||
Blocks []ReportBlock
|
||||
Extensions [][4]byte
|
||||
Header // Standard RTCP packet header.
|
||||
SenderSSRC uint32 // SSRC of the sender of this report.
|
||||
Blocks []ReportBlock // Report blocks.
|
||||
Extensions [][4]byte // Contains any extensions to the packet.
|
||||
}
|
||||
|
||||
// Bytes returns a []byte of the ReceiverReport r.
|
||||
func (r *ReceiverReport) Bytes() []byte {
|
||||
l := 8 + 4*reportBlockSize*len(r.Blocks) + 4*len(r.Extensions)
|
||||
buf := make([]byte, l)
|
||||
|
@ -61,6 +63,7 @@ func (r *ReceiverReport) Bytes() []byte {
|
|||
return buf
|
||||
}
|
||||
|
||||
// ReportBlock describes an RTCP report block used in Sender/Receiver Reports.
|
||||
type ReportBlock struct {
|
||||
SSRC uint32 // Source identifier.
|
||||
FractionLost uint8 // Fraction of packets lost.
|
||||
|
@ -71,12 +74,13 @@ type ReportBlock struct {
|
|||
DLSR uint32 // Delay since last sender report.
|
||||
}
|
||||
|
||||
// SourceDescription describes a source description RTCP packet.
|
||||
type SourceDescription struct {
|
||||
Header
|
||||
|
||||
Chunks []Chunk
|
||||
Header // Standard RTCP packet header.
|
||||
Chunks []Chunk // Chunks to describe items of each SSRC.
|
||||
}
|
||||
|
||||
// Bytes returns an []byte of the SourceDescription d.
|
||||
func (d *SourceDescription) Bytes() []byte {
|
||||
bodyLen := d.bodyLen()
|
||||
rem := bodyLen % 4
|
||||
|
@ -102,6 +106,7 @@ func (d *SourceDescription) Bytes() []byte {
|
|||
return buf
|
||||
}
|
||||
|
||||
// bodyLen calculates the body length of a source description packet in bytes.
|
||||
func (d *SourceDescription) bodyLen() int {
|
||||
l := 0
|
||||
for _, c := range d.Chunks {
|
||||
|
@ -110,6 +115,7 @@ func (d *SourceDescription) bodyLen() int {
|
|||
return l
|
||||
}
|
||||
|
||||
// Header describes a standard RTCP packet header.
|
||||
type Header struct {
|
||||
Version uint8 // RTCP version.
|
||||
Padding bool // Padding indicator.
|
||||
|
@ -117,16 +123,19 @@ type Header struct {
|
|||
Type uint8 // Type of RTCP packet.
|
||||
}
|
||||
|
||||
// SDESItem describes a source description item.
|
||||
type SDESItem struct {
|
||||
Type uint8
|
||||
Text []byte
|
||||
Type uint8 // Type of item.
|
||||
Text []byte // Item text.
|
||||
}
|
||||
|
||||
// Chunk describes a source description chunk for a given SSRC.
|
||||
type Chunk struct {
|
||||
SSRC uint32
|
||||
Items []SDESItem
|
||||
SSRC uint32 // SSRC of the source being described by the below items.
|
||||
Items []SDESItem // Items describing the source.
|
||||
}
|
||||
|
||||
// len returns the len of a chunk in bytes.
|
||||
func (c *Chunk) len() int {
|
||||
tot := 4
|
||||
for _, i := range c.Items {
|
||||
|
@ -135,6 +144,8 @@ func (c *Chunk) len() int {
|
|||
return tot
|
||||
}
|
||||
|
||||
// writeHeader writes the standard RTCP header given a buffer to write to and l
|
||||
// the RTCP body length that needs to be encoded into the header.
|
||||
func (h Header) writeHeader(buf []byte, l int) {
|
||||
buf[0] = h.Version<<6 | asByte(h.Padding)<<5 | 0x1f&h.ReportCount
|
||||
buf[1] = h.Type
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// TestReceiverReportBytes checks that we can correctly obtain a []byte of an
|
||||
// RTCP receiver report from the struct representation.
|
||||
func TestReceiverReportBytes(t *testing.T) {
|
||||
expect := []byte{
|
||||
0x81, 0xc9, 0x00, 0x07,
|
||||
|
@ -48,6 +50,8 @@ func TestReceiverReportBytes(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestSourceDescriptionBytes checks that we can correctly obtain a []byte of an
|
||||
// RTCP source description from the struct representation.
|
||||
func TestSourceDescriptionBytes(t *testing.T) {
|
||||
expect := []byte{
|
||||
0x81, 0xca, 0x00, 0x04,
|
||||
|
|
Loading…
Reference in New Issue