picture_loss_indication.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package rtcp
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. )
  6. // The PictureLossIndication packet informs the encoder about the loss of an undefined amount of coded video data belonging to one or more pictures
  7. type PictureLossIndication struct {
  8. // SSRC of sender
  9. SenderSSRC uint32
  10. // SSRC where the loss was experienced
  11. MediaSSRC uint32
  12. }
  13. const (
  14. pliLength = 2
  15. )
  16. // Marshal encodes the PictureLossIndication in binary
  17. func (p PictureLossIndication) Marshal() ([]byte, error) {
  18. /*
  19. * PLI does not require parameters. Therefore, the length field MUST be
  20. * 2, and there MUST NOT be any Feedback Control Information.
  21. *
  22. * The semantics of this FB message is independent of the payload type.
  23. */
  24. rawPacket := make([]byte, p.len())
  25. packetBody := rawPacket[headerLength:]
  26. binary.BigEndian.PutUint32(packetBody, p.SenderSSRC)
  27. binary.BigEndian.PutUint32(packetBody[4:], p.MediaSSRC)
  28. h := Header{
  29. Count: FormatPLI,
  30. Type: TypePayloadSpecificFeedback,
  31. Length: pliLength,
  32. }
  33. hData, err := h.Marshal()
  34. if err != nil {
  35. return nil, err
  36. }
  37. copy(rawPacket, hData)
  38. return rawPacket, nil
  39. }
  40. // Unmarshal decodes the PictureLossIndication from binary
  41. func (p *PictureLossIndication) Unmarshal(rawPacket []byte) error {
  42. if len(rawPacket) < (headerLength + (ssrcLength * 2)) {
  43. return errPacketTooShort
  44. }
  45. var h Header
  46. if err := h.Unmarshal(rawPacket); err != nil {
  47. return err
  48. }
  49. if h.Type != TypePayloadSpecificFeedback || h.Count != FormatPLI {
  50. return errWrongType
  51. }
  52. p.SenderSSRC = binary.BigEndian.Uint32(rawPacket[headerLength:])
  53. p.MediaSSRC = binary.BigEndian.Uint32(rawPacket[headerLength+ssrcLength:])
  54. return nil
  55. }
  56. // Header returns the Header associated with this packet.
  57. func (p *PictureLossIndication) Header() Header {
  58. return Header{
  59. Count: FormatPLI,
  60. Type: TypePayloadSpecificFeedback,
  61. Length: pliLength,
  62. }
  63. }
  64. func (p *PictureLossIndication) len() int {
  65. return headerLength + ssrcLength*2
  66. }
  67. func (p *PictureLossIndication) String() string {
  68. return fmt.Sprintf("PictureLossIndication %x %x", p.SenderSSRC, p.MediaSSRC)
  69. }
  70. // DestinationSSRC returns an array of SSRC values that this packet refers to.
  71. func (p *PictureLossIndication) DestinationSSRC() []uint32 {
  72. return []uint32{p.MediaSSRC}
  73. }