110 lines
2.5 KiB
Go
110 lines
2.5 KiB
Go
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
|
|
}
|