Re-factored error checking https://dave.cheney.net/2019/01/27/eliminate-error-handling-by-eliminating-errors
Split MPLS header into FileType and Version fixed types on AppInfoPlaylist Added STNTable to PlayItem and added STNTable parser Unexported Parse functions on most structs Combined extraneous reads Added StreamEntry parser Added StreamAttributes parser
This commit is contained in:
parent
f7141aae07
commit
8f3efef8d6
431
main.go
431
main.go
@ -145,7 +145,8 @@ const (
|
|||||||
|
|
||||||
// MPLS is a struct representing an MPLS file
|
// MPLS is a struct representing an MPLS file
|
||||||
type MPLS struct {
|
type MPLS struct {
|
||||||
Header string
|
FileType string
|
||||||
|
Version string
|
||||||
PlaylistStart int
|
PlaylistStart int
|
||||||
PlaylistMarkStart int
|
PlaylistMarkStart int
|
||||||
ExtensionDataStart int
|
ExtensionDataStart int
|
||||||
@ -156,8 +157,8 @@ type MPLS struct {
|
|||||||
// AppInfoPlaylist sucks
|
// AppInfoPlaylist sucks
|
||||||
type AppInfoPlaylist struct {
|
type AppInfoPlaylist struct {
|
||||||
Len int
|
Len int
|
||||||
PlaybackType int
|
PlaybackType byte
|
||||||
PlaybackCount int
|
PlaybackCount uint16
|
||||||
UOMask uint64
|
UOMask uint64
|
||||||
PlaylistFlags uint16
|
PlaylistFlags uint16
|
||||||
}
|
}
|
||||||
@ -184,6 +185,7 @@ type PlayItem struct {
|
|||||||
AngleCount byte
|
AngleCount byte
|
||||||
AngleFlags byte
|
AngleFlags byte
|
||||||
Angles []CLPI
|
Angles []CLPI
|
||||||
|
StreamTable STNTable
|
||||||
}
|
}
|
||||||
|
|
||||||
// STNTable STream Number Table
|
// STNTable STream Number Table
|
||||||
@ -234,37 +236,78 @@ type CLPI struct {
|
|||||||
STCID byte
|
STCID byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errReader struct {
|
||||||
|
RS *bytes.Reader
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (er *errReader) Read(p []byte) (n int, err error) {
|
||||||
|
if er.err != nil {
|
||||||
|
return 0, er.err
|
||||||
|
}
|
||||||
|
|
||||||
|
n, er.err = er.RS.Read(p)
|
||||||
|
if n != len(p) {
|
||||||
|
er.err = fmt.Errorf("%s", "Invalid read")
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, er.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (er *errReader) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
if er.err != nil {
|
||||||
|
return 0, er.err
|
||||||
|
}
|
||||||
|
|
||||||
|
var n64 int64
|
||||||
|
n64, er.err = er.Seek(offset, whence)
|
||||||
|
|
||||||
|
return n64, er.err
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
Mpls, err := Parse(os.Args[1])
|
var (
|
||||||
|
file io.Reader
|
||||||
|
Mpls MPLS
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
file, err = os.Open(filepath.Clean(os.Args[1]))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
Mpls, err = Parse(file)
|
||||||
fmt.Println(Mpls)
|
fmt.Println(Mpls)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses an MPLS file into an MPLS struct
|
// Parse parses an MPLS file into an MPLS struct
|
||||||
func Parse(fiLename string) (Mpls MPLS, err error) {
|
func Parse(reader io.Reader) (Mpls MPLS, err error) {
|
||||||
var (
|
var (
|
||||||
file *bytes.Reader
|
file []byte
|
||||||
f []byte
|
|
||||||
)
|
)
|
||||||
|
|
||||||
f, err = ioutil.ReadFile(filepath.Clean(fiLename))
|
file, err = ioutil.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MPLS{}, err
|
return MPLS{}, err
|
||||||
}
|
}
|
||||||
file = bytes.NewReader(f)
|
|
||||||
err = Mpls.Parse(file)
|
err = Mpls.Parse(file)
|
||||||
return Mpls, err
|
return Mpls, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse reads MPLS data from an io.ReadSeeker
|
// Parse reads MPLS data from an io.ReadSeeker #nosec G104
|
||||||
func (Mpls *MPLS) Parse(file io.ReadSeeker) error {
|
func (Mpls *MPLS) Parse(file []byte) error {
|
||||||
var (
|
var (
|
||||||
buf [10]byte
|
buf [10]byte
|
||||||
n int
|
n int
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
n, err = file.Read(buf[:8])
|
reader := &errReader{
|
||||||
|
RS: bytes.NewReader(file),
|
||||||
|
err: nil,
|
||||||
|
}
|
||||||
|
n, err = reader.Read(buf[:8])
|
||||||
if err != nil || n != 8 {
|
if err != nil || n != 8 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -276,139 +319,94 @@ func (Mpls *MPLS) Parse(file io.ReadSeeker) error {
|
|||||||
fmt.Fprintf(os.Stderr, "warning: mpls may not work it is version %s\n", str[4:8])
|
fmt.Fprintf(os.Stderr, "warning: mpls may not work it is version %s\n", str[4:8])
|
||||||
}
|
}
|
||||||
|
|
||||||
Mpls.Header = str
|
Mpls.FileType = str[:4]
|
||||||
|
Mpls.Version = str[4:8]
|
||||||
|
|
||||||
Mpls.PlaylistStart, err = readInt32(file, buf[:4])
|
Mpls.PlaylistStart, _ = readInt32(reader, buf[:])
|
||||||
fmt.Println("int:", Mpls.PlaylistStart, "binary:", buf[:4])
|
fmt.Println("int:", Mpls.PlaylistStart, "binary:", buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
Mpls.PlaylistMarkStart, err = readInt32(file, buf[:4])
|
Mpls.PlaylistMarkStart, _ = readInt32(reader, buf[:])
|
||||||
fmt.Println("int:", Mpls.PlaylistMarkStart, "binary:", buf[:4])
|
fmt.Println("int:", Mpls.PlaylistMarkStart, "binary:", buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
Mpls.ExtensionDataStart, err = readInt32(file, buf[:4])
|
Mpls.ExtensionDataStart, _ = readInt32(reader, buf[:])
|
||||||
fmt.Println("int:", Mpls.ExtensionDataStart, "binary:", buf[:4])
|
fmt.Println("int:", Mpls.ExtensionDataStart, "binary:", buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = file.Seek(20, io.SeekCurrent)
|
reader.Seek(20, io.SeekCurrent)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = Mpls.AppInfoPlaylist.parse(file)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = file.Seek(int64(Mpls.PlaylistStart), io.SeekStart)
|
Mpls.AppInfoPlaylist.parse(reader)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = Mpls.Playlist.Parse(file)
|
reader.Seek(int64(Mpls.PlaylistStart), io.SeekStart)
|
||||||
if err != nil {
|
|
||||||
return err
|
Mpls.Playlist.parse(reader)
|
||||||
}
|
|
||||||
return nil
|
return reader.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse reads AppInfoPlaylist data from an io.ReadSeeker
|
// parse reads AppInfoPlaylist data from an *errReader #nosec G104
|
||||||
func (aip *AppInfoPlaylist) parse(file io.ReadSeeker) error {
|
func (aip *AppInfoPlaylist) parse(reader *errReader) error {
|
||||||
var (
|
var (
|
||||||
buf [10]byte
|
buf [10]byte
|
||||||
err error
|
|
||||||
n int
|
|
||||||
)
|
)
|
||||||
aip.Len, err = readInt32(file, buf[:4])
|
aip.Len, _ = readInt32(reader, buf[:])
|
||||||
fmt.Println("int:", aip.Len, "binary:", buf[:4])
|
fmt.Println("int:", aip.Len, "binary:", buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err = file.Read(buf[:4])
|
reader.Read(buf[:1])
|
||||||
if err != nil || n != 4 {
|
|
||||||
return err
|
aip.PlaybackType = buf[1]
|
||||||
}
|
|
||||||
aip.PlaybackType = int(buf[1])
|
|
||||||
fmt.Println("int:", aip.PlaybackType, "binary:", buf[1])
|
fmt.Println("int:", aip.PlaybackType, "binary:", buf[1])
|
||||||
|
|
||||||
aip.PlaybackCount = int(binary.BigEndian.Uint16(buf[2:4]))
|
aip.PlaybackCount, _ = readUInt16(reader, buf[:])
|
||||||
fmt.Println("int:", aip.PlaybackCount, "binary:", buf[2:4])
|
fmt.Println("int:", aip.PlaybackCount, "binary:", buf[:2])
|
||||||
|
|
||||||
aip.UOMask, err = readUInt64(file, buf[:8])
|
aip.UOMask, _ = readUInt64(reader, buf[:])
|
||||||
fmt.Println("int:", aip.UOMask, "binary:", buf[:8])
|
fmt.Println("int:", aip.UOMask, "binary:", buf[:8])
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
aip.PlaylistFlags, _ = readUInt16(reader, buf[:])
|
||||||
}
|
|
||||||
aip.PlaylistFlags, err = readUInt16(file, buf[:2])
|
|
||||||
fmt.Println("int:", aip.PlaylistFlags, "binary:", buf[:2])
|
fmt.Println("int:", aip.PlaylistFlags, "binary:", buf[:2])
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
return reader.err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse reads Playlist data from an io.ReadSeeker
|
// parse reads Playlist data from an *errReader #nosec G104
|
||||||
func (p *Playlist) Parse(file io.ReadSeeker) error {
|
func (p *Playlist) parse(reader *errReader) error {
|
||||||
var (
|
var (
|
||||||
buf [10]byte
|
buf [10]byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
p.Len, err = readInt32(file, buf[:])
|
p.Len, _ = readInt32(reader, buf[:])
|
||||||
fmt.Println("int:", p.Len, "binary:", buf[:4])
|
fmt.Println("int:", p.Len, "binary:", buf[:4])
|
||||||
if err != nil {
|
|
||||||
return err
|
reader.Seek(2, io.SeekCurrent)
|
||||||
}
|
|
||||||
_, err = file.Seek(2, io.SeekCurrent)
|
p.PlayItemCount, _ = readUInt16(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.PlayItemCount, err = readUInt16(file, buf[:])
|
|
||||||
fmt.Println("int:", p.PlayItemCount, "binary:", buf[:2])
|
fmt.Println("int:", p.PlayItemCount, "binary:", buf[:2])
|
||||||
if err != nil {
|
|
||||||
return err
|
p.SubPathCount, _ = readUInt16(reader, buf[:])
|
||||||
}
|
|
||||||
p.SubPathCount, err = readUInt16(file, buf[:])
|
|
||||||
fmt.Println("int:", p.SubPathCount, "binary:", buf[:2])
|
fmt.Println("int:", p.SubPathCount, "binary:", buf[:2])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for i := 0; i < int(p.PlayItemCount); i++ {
|
for i := 0; i < int(p.PlayItemCount); i++ {
|
||||||
var item PlayItem
|
var item PlayItem
|
||||||
err = item.Parse(file)
|
err = item.parse(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.PlayItems = append(p.PlayItems, item)
|
p.PlayItems = append(p.PlayItems, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return reader.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse reads PlayItem data from an io.ReadSeeker
|
// parse reads PlayItem data from an *errReader #nosec G104
|
||||||
func (pi *PlayItem) Parse(file io.Reader) error {
|
func (pi *PlayItem) parse(reader *errReader) error {
|
||||||
var (
|
var (
|
||||||
buf [10]byte
|
buf [10]byte
|
||||||
n int
|
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
pi.Len, err = readUInt16(file, buf[:])
|
pi.Len, _ = readUInt16(reader, buf[:])
|
||||||
fmt.Println("int:", pi.Len, "binary:", buf[:2])
|
fmt.Println("int:", pi.Len, "binary:", buf[:2])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err = file.Read(buf[:9])
|
reader.Read(buf[:9])
|
||||||
if err != nil || n != 9 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
str := string(buf[:9])
|
str := string(buf[:9])
|
||||||
if str[5:9] != "M2TS" {
|
if str[5:9] != "M2TS" {
|
||||||
@ -417,121 +415,220 @@ func (pi *PlayItem) Parse(file io.Reader) error {
|
|||||||
pi.Clpi.ClipFile = str[:5]
|
pi.Clpi.ClipFile = str[:5]
|
||||||
pi.Clpi.ClipID = str[5:9]
|
pi.Clpi.ClipID = str[5:9]
|
||||||
|
|
||||||
pi.Flags, err = readUInt16(file, buf[:])
|
pi.Flags, _ = readUInt16(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
reader.Read(buf[:1])
|
||||||
}
|
|
||||||
|
|
||||||
n, err = file.Read(buf[:1])
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.Clpi.STCID = buf[0]
|
pi.Clpi.STCID = buf[0]
|
||||||
|
|
||||||
pi.InTime, err = readInt32(file, buf[:])
|
pi.InTime, _ = readInt32(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pi.OutTime, err = readInt32(file, buf[:])
|
pi.OutTime, _ = readInt32(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pi.UOMask, err = readUInt64(file, buf[:])
|
pi.UOMask, _ = readUInt64(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
reader.Read(buf[:2])
|
||||||
}
|
|
||||||
|
|
||||||
n, err = file.Read(buf[:1])
|
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.RandomAccessFlag = buf[0]
|
pi.RandomAccessFlag = buf[0]
|
||||||
|
|
||||||
n, err = file.Read(buf[:1])
|
pi.StillMode = buf[1]
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.StillMode = buf[0]
|
|
||||||
|
|
||||||
pi.StillTime, err = readUInt16(file, buf[:])
|
pi.StillTime, _ = readUInt16(reader, buf[:])
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if pi.Flags&1 == 1 {
|
if pi.Flags&1 == 1 {
|
||||||
n, err = file.Read(buf[:1])
|
reader.Read(buf[:2])
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.AngleCount = buf[0]
|
pi.AngleCount = buf[0]
|
||||||
|
|
||||||
n, err = file.Read(buf[:1])
|
pi.AngleFlags = buf[1]
|
||||||
if err != nil || n != 1 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.AngleFlags = buf[0]
|
|
||||||
|
|
||||||
for i := 0; i < int(pi.AngleCount); i++ {
|
for i := 0; i < int(pi.AngleCount); i++ {
|
||||||
var angle CLPI
|
var angle CLPI
|
||||||
err = angle.Parse(file)
|
angle.parse(reader)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pi.Angles = append(pi.Angles, angle)
|
pi.Angles = append(pi.Angles, angle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
pi.StreamTable.parse(reader)
|
||||||
|
|
||||||
|
return reader.err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse reads angle data from an io.ReadSeeker
|
// parse reads angle data from an *errReader #nosec G104
|
||||||
func (clpi *CLPI) Parse(file io.Reader) error {
|
func (clpi *CLPI) parse(reader *errReader) error {
|
||||||
var (
|
var (
|
||||||
buf [10]byte
|
buf [10]byte
|
||||||
n int
|
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
n, err = file.Read(buf[:9])
|
reader.Read(buf[:])
|
||||||
if err != nil || n != 9 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
str := string(buf[:9])
|
str := string(buf[:9])
|
||||||
clpi.ClipFile = str[:5]
|
clpi.ClipFile = str[:5]
|
||||||
clpi.ClipID = str[5:9]
|
clpi.ClipID = str[5:9]
|
||||||
|
|
||||||
n, err = file.Read(buf[:1])
|
clpi.STCID = buf[9]
|
||||||
if err != nil || n != 1 {
|
return reader.err
|
||||||
return err
|
|
||||||
}
|
|
||||||
clpi.STCID = buf[0]
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func readUInt16(file io.Reader, buf []byte) (uint16, error) {
|
// parse reads Stream data from an *errReader #nosec G104
|
||||||
n, err := file.Read(buf[:2])
|
func (stnt *STNTable) parse(reader *errReader) error {
|
||||||
|
var (
|
||||||
|
buf [10]byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
stnt.Len, _ = readUInt16(reader, buf[:])
|
||||||
|
|
||||||
|
reader.Read(buf[:9])
|
||||||
|
|
||||||
|
stnt.PrimaryVideoStreamCount = buf[2]
|
||||||
|
stnt.PrimaryAudioStreamCount = buf[3]
|
||||||
|
stnt.PrimaryPGStreamCount = buf[4]
|
||||||
|
stnt.PrimaryIGStreamCount = buf[5]
|
||||||
|
stnt.SecondaryAudioStreamCount = buf[6]
|
||||||
|
stnt.SecondaryVideoStreamCount = buf[7]
|
||||||
|
stnt.PIPPGStreamCount = buf[8]
|
||||||
|
|
||||||
|
reader.Seek(5, io.SeekCurrent)
|
||||||
|
|
||||||
|
for i := 0; i < int(stnt.PrimaryVideoStreamCount); i++ {
|
||||||
|
var stream PrimaryStream
|
||||||
|
err = stream.parse(reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stnt.PrimaryVideoStreams = append(stnt.PrimaryVideoStreams, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(stnt.PrimaryAudioStreamCount); i++ {
|
||||||
|
var stream PrimaryStream
|
||||||
|
err = stream.parse(reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stnt.PrimaryAudioStreams = append(stnt.PrimaryAudioStreams, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(stnt.PrimaryIGStreamCount); i++ {
|
||||||
|
var stream PrimaryStream
|
||||||
|
err = stream.parse(reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stnt.PrimaryIGStreams = append(stnt.PrimaryIGStreams, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < int(stnt.PrimaryAudioStreamCount); i++ {
|
||||||
|
var stream PrimaryStream
|
||||||
|
err = stream.parse(reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stnt.PrimaryAudioStreams = append(stnt.PrimaryAudioStreams, stream)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse reads Stream data from an *errReader #nosec G104
|
||||||
|
func (ps *PrimaryStream) parse(reader *errReader) error {
|
||||||
|
|
||||||
|
ps.StreamEntry.parse(reader)
|
||||||
|
|
||||||
|
ps.StreamAttributes.parse(reader)
|
||||||
|
|
||||||
|
return reader.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse reads Stream data from an *errReader #nosec G104
|
||||||
|
func (se *StreamEntry) parse(reader *errReader) error {
|
||||||
|
var (
|
||||||
|
buf [10]byte
|
||||||
|
)
|
||||||
|
|
||||||
|
reader.Read(buf[:])
|
||||||
|
|
||||||
|
se.Len = buf[0]
|
||||||
|
se.Type = buf[1]
|
||||||
|
switch se.Type {
|
||||||
|
case 1:
|
||||||
|
se.PID = binary.BigEndian.Uint16(buf[2:4])
|
||||||
|
case 2, 4:
|
||||||
|
se.SubPathID = buf[2]
|
||||||
|
se.SubClipID = buf[3]
|
||||||
|
se.PID = binary.BigEndian.Uint16(buf[4:6])
|
||||||
|
case 3:
|
||||||
|
se.SubPathID = buf[2]
|
||||||
|
se.PID = binary.BigEndian.Uint16(buf[3:5])
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse reads Stream data from an *errReader #nosec G104
|
||||||
|
func (sa *StreamAttributes) parse(reader *errReader) error {
|
||||||
|
var (
|
||||||
|
buf [10]byte
|
||||||
|
)
|
||||||
|
reader.Read(buf[:2])
|
||||||
|
|
||||||
|
sa.Len = buf[0]
|
||||||
|
sa.Encoding = buf[1]
|
||||||
|
|
||||||
|
switch sa.Encoding {
|
||||||
|
case VTMPEG1Video, VTMPEG2Video, VTVC1, VTH264:
|
||||||
|
reader.Read(buf[:1])
|
||||||
|
|
||||||
|
sa.Format = buf[0] & 0xf0 >> 4
|
||||||
|
sa.Rate = buf[0] & 0x0F
|
||||||
|
|
||||||
|
case ATMPEG1Audio, ATMPEG2Audio, ATLPCM, ATAC3, ATDTS, ATTRUEHD, ATAC3Plus, ATDTSHD, ATDTSHDMaster:
|
||||||
|
reader.Read(buf[:4])
|
||||||
|
|
||||||
|
sa.Format = buf[0] & 0xf0 >> 4
|
||||||
|
sa.Rate = buf[0] & 0x0F
|
||||||
|
sa.Language = string(buf[1:4])
|
||||||
|
|
||||||
|
case PresentationGraphics, InteractiveGraphics:
|
||||||
|
reader.Read(buf[:3])
|
||||||
|
|
||||||
|
sa.Language = string(buf[:3])
|
||||||
|
|
||||||
|
case TextSubtitle:
|
||||||
|
reader.Read(buf[:4])
|
||||||
|
|
||||||
|
sa.CharacterCode = buf[0]
|
||||||
|
sa.Language = string(buf[1:4])
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "warning: unrecognized encoding: '%02X'", sa.Encoding)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reader.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func readUInt16(reader io.Reader, buf []byte) (uint16, error) {
|
||||||
|
n, err := reader.Read(buf[:2])
|
||||||
if err != nil || n != 2 {
|
if err != nil || n != 2 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return binary.BigEndian.Uint16(buf[:2]), nil
|
return binary.BigEndian.Uint16(buf[:2]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readInt32(file io.Reader, buf []byte) (int, error) {
|
func readInt32(reader io.Reader, buf []byte) (int, error) {
|
||||||
n, err := readUInt32(file, buf)
|
n, err := readUInt32(reader, buf)
|
||||||
return int(n), err
|
return int(n), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func readUInt32(file io.Reader, buf []byte) (uint32, error) {
|
func readUInt32(reader io.Reader, buf []byte) (uint32, error) {
|
||||||
n, err := file.Read(buf[:4])
|
n, err := reader.Read(buf[:4])
|
||||||
if err != nil || n != 4 {
|
if err != nil || n != 4 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return binary.BigEndian.Uint32(buf[:4]), nil
|
return binary.BigEndian.Uint32(buf[:4]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readUInt64(file io.Reader, buf []byte) (uint64, error) {
|
func readUInt64(reader io.Reader, buf []byte) (uint64, error) {
|
||||||
n, err := file.Read(buf[:8])
|
n, err := reader.Read(buf[:8])
|
||||||
if err != nil || n != 8 {
|
if err != nil || n != 8 {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user