package protocol import ( "encoding/binary" "io" "github.com/niko/qcc/pkg/types" ) const MediaHeaderSize = 8 + 4 + 1 + 1 + 4 type MediaPacket struct { CallID uint64 SeqNum uint32 Codec types.CodecType Flags types.MediaFlags Timestamp uint32 Payload []byte } func MarshalMediaPacket(pkt *MediaPacket) []byte { size := MediaHeaderSize + len(pkt.Payload) buf := make([]byte, size) off := 0 binary.BigEndian.PutUint64(buf[off:], pkt.CallID) off += 8 binary.LittleEndian.PutUint32(buf[off:], pkt.SeqNum) off += 4 buf[off] = byte(pkt.Codec) off++ buf[off] = byte(pkt.Flags) off++ binary.BigEndian.PutUint32(buf[off:], pkt.Timestamp) off += 4 copy(buf[off:], pkt.Payload) return buf } func UnmarshalMediaPacket(data []byte) (*MediaPacket, bool) { if len(data) < MediaHeaderSize { return nil, false } pkt := &MediaPacket{} off := 0 pkt.CallID = binary.BigEndian.Uint64(data[off:]) off += 8 pkt.SeqNum = binary.LittleEndian.Uint32(data[off:]) off += 4 pkt.Codec = types.CodecType(data[off]) off++ pkt.Flags = types.MediaFlags(data[off]) off++ pkt.Timestamp = binary.BigEndian.Uint32(data[off:]) off += 4 pkt.Payload = make([]byte, len(data)-off) copy(pkt.Payload, data[off:]) return pkt, true } func ReadMediaPacket(r io.Reader) (*MediaPacket, error) { header := make([]byte, MediaHeaderSize) if _, err := io.ReadFull(r, header); err != nil { return nil, err } pkt := &MediaPacket{} off := 0 pkt.CallID = binary.BigEndian.Uint64(header[off:]) off += 8 pkt.SeqNum = binary.LittleEndian.Uint32(header[off:]) off += 4 pkt.Codec = types.CodecType(header[off]) off++ pkt.Flags = types.MediaFlags(header[off]) off++ pkt.Timestamp = binary.BigEndian.Uint32(header[off:]) payload, err := io.ReadAll(r) if err != nil { return nil, err } pkt.Payload = payload return pkt, nil }