package unpacker import ( "encoding/binary" "fmt" "git.insit.tech/psa/rtsp_reader-writer/writer/pkg/storage" "io" ) // readString reads string length and then reads string data. func readString(r io.Reader) (string, error) { var length int32 if err := binary.Read(r, binary.LittleEndian, &length); err != nil { return "", err } buf := make([]byte, length) if _, err := io.ReadFull(r, buf); err != nil { return "", err } return string(buf), nil } // readHeaderSegment reads header of the segment. func readHeaderSegment(r io.Reader) (storage.Segment, error) { var seg storage.Segment date, err := readString(r) if err != nil { return seg, err } seg.Date = date duration, err := readString(r) if err != nil { return seg, err } seg.Duration = duration return seg, nil } // readPacket reads one interleaved packet. func readPacket(r io.Reader) (storage.InterleavedPacket, error) { var pkt storage.InterleavedPacket // Read type of the packet. typeByte := make([]byte, 1) if _, err := io.ReadFull(r, typeByte); err != nil { return pkt, err } pkt.Type = typeByte[0] // Read PTS (int64). if err := binary.Read(r, binary.LittleEndian, &pkt.Pts); err != nil { return pkt, err } // Read data of the segment. if pkt.Type == storage.PacketTypeH264 { var numAUs int32 if err := binary.Read(r, binary.LittleEndian, &numAUs); err != nil { return pkt, err } var auList [][]byte for i := 0; i < int(numAUs); i++ { var auLen int32 if err := binary.Read(r, binary.LittleEndian, &auLen); err != nil { return pkt, err } auData := make([]byte, auLen) if _, err := io.ReadFull(r, auData); err != nil { return pkt, err } auList = append(auList, auData) } pkt.H264AUs = auList } else if pkt.Type == storage.PacketTypeLPCM { var auLen int32 if err := binary.Read(r, binary.LittleEndian, &auLen); err != nil { return pkt, err } auData := make([]byte, auLen) if _, err := io.ReadFull(r, auData); err != nil { return pkt, err } pkt.LPCMSamples = auData } else { return pkt, fmt.Errorf("unknown type of the packet: %d", pkt.Type) } return pkt, nil } // readPacketSegment reads segment packets. func readPacketSegment(r io.Reader) ([]storage.InterleavedPacket, error) { var numPackets int32 if err := binary.Read(r, binary.LittleEndian, &numPackets); err != nil { return nil, err } var packets []storage.InterleavedPacket for i := 0; i < int(numPackets); i++ { pkt, err := readPacket(r) if err != nil { return nil, err } packets = append(packets, pkt) } return packets, nil }