package rtcp
import (
"encoding/binary"
"fmt"
)
type FIREntry struct {
SSRC uint32
SequenceNumber uint8
}
type FullIntraRequest struct {
SenderSSRC uint32
MediaSSRC uint32
FIR []FIREntry
}
const (
firOffset = 8
)
var _ Packet = (*FullIntraRequest )(nil )
func (p FullIntraRequest ) Marshal () ([]byte , error ) {
rawPacket := make ([]byte , firOffset +(len (p .FIR )*8 ))
binary .BigEndian .PutUint32 (rawPacket , p .SenderSSRC )
binary .BigEndian .PutUint32 (rawPacket [4 :], p .MediaSSRC )
for i , fir := range p .FIR {
binary .BigEndian .PutUint32 (rawPacket [firOffset +8 *i :], fir .SSRC )
rawPacket [firOffset +8 *i +4 ] = fir .SequenceNumber
}
h := p .Header ()
hData , err := h .Marshal ()
if err != nil {
return nil , err
}
return append (hData , rawPacket ...), nil
}
func (p *FullIntraRequest ) Unmarshal (rawPacket []byte ) error {
if len (rawPacket ) < (headerLength + ssrcLength ) {
return errPacketTooShort
}
var h Header
if err := h .Unmarshal (rawPacket ); err != nil {
return err
}
if len (rawPacket ) < (headerLength + int (4 *h .Length )) {
return errPacketTooShort
}
if h .Type != TypePayloadSpecificFeedback || h .Count != FormatFIR {
return errWrongType
}
if 4 *h .Length -firOffset <= 0 || (4 *h .Length )%8 != 0 {
return errBadLength
}
p .SenderSSRC = binary .BigEndian .Uint32 (rawPacket [headerLength :])
p .MediaSSRC = binary .BigEndian .Uint32 (rawPacket [headerLength +ssrcLength :])
for i := headerLength + firOffset ; i < (headerLength + int (h .Length *4 )); i += 8 {
p .FIR = append (p .FIR , FIREntry {
binary .BigEndian .Uint32 (rawPacket [i :]),
rawPacket [i +4 ],
})
}
return nil
}
func (p *FullIntraRequest ) Header () Header {
return Header {
Count : FormatFIR ,
Type : TypePayloadSpecificFeedback ,
Length : uint16 ((p .MarshalSize () / 4 ) - 1 ),
}
}
func (p *FullIntraRequest ) MarshalSize () int {
return headerLength + firOffset + len (p .FIR )*8
}
func (p *FullIntraRequest ) String () string {
out := fmt .Sprintf ("FullIntraRequest %x %x" ,
p .SenderSSRC , p .MediaSSRC )
for _ , e := range p .FIR {
out += fmt .Sprintf (" (%x %v)" , e .SSRC , e .SequenceNumber )
}
return out
}
func (p *FullIntraRequest ) DestinationSSRC () []uint32 {
ssrcs := make ([]uint32 , 0 , len (p .FIR ))
for _ , entry := range p .FIR {
ssrcs = append (ssrcs , entry .SSRC )
}
return ssrcs
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .