Skip to content

Commit 6118438

Browse files
authored
Merge branch 'yapingcat:main' into main
2 parents 1f15147 + 920523f commit 6118438

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

go-mp4/mp4demuxer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ func (demuxer *MovDemuxer) ReadHead() ([]TrackInfo, error) {
231231
err = decodeTrunBox(demuxer, uint32(basebox.Size))
232232
case mov_tag([4]byte{'s', 'e', 'n', 'c'}):
233233
err = decodeSencBox(demuxer, uint32(basebox.Size))
234+
case mov_tag([4]byte{'s', 'a', 'i', 'z'}):
235+
err = decodeSaizBox(demuxer, uint32(basebox.Size))
236+
case mov_tag([4]byte{'s', 'a', 'i', 'o'}):
237+
err = decodeSaioBox(demuxer, uint32(basebox.Size))
234238
case mov_tag([4]byte{'u', 'u', 'i', 'd'}):
235239
_, err = demuxer.reader.Seek(int64(basebox.Size)-BasicBoxLen-16, io.SeekCurrent)
236240
case mov_tag([4]byte{'s', 'g', 'p', 'd'}):

go-mp4/mp4track.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ type mp4track struct {
131131
defaultConstantIV []byte
132132
defaultKID [16]byte
133133
lastSeig *SeigSampleGroupEntry
134+
lastSaiz *SaizBox
134135
subSamples []sencEntry
135136
}
136137

go-mp4/saio-box.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package mp4
2+
3+
import (
4+
"encoding/binary"
5+
"errors"
6+
"io"
7+
)
8+
9+
// SaioBox - Sample Auxiliary Information Offsets Box (saiz) (in stbl or traf box)
10+
type SaioBox struct {
11+
Box *FullBox
12+
AuxInfoType string // Used for Common Encryption Scheme (4-bytes uint32 according to spec)
13+
AuxInfoTypeParameter uint32
14+
Offset []int64
15+
}
16+
17+
func (s *SaioBox) Decode(r io.Reader, size uint32) error {
18+
if _, err := s.Box.Decode(r); err != nil {
19+
return err
20+
}
21+
buf := make([]byte, size-12)
22+
if _, err := io.ReadFull(r, buf); err != nil {
23+
return err
24+
}
25+
var n int
26+
flags := uint32(s.Box.Flags[0])<<16 | uint32(s.Box.Flags[1])<<8 | uint32(s.Box.Flags[2])
27+
if flags&0x01 != 0 {
28+
s.AuxInfoType = string(buf[n:n+4])
29+
n += 4
30+
s.AuxInfoTypeParameter = binary.BigEndian.Uint32(buf[n:])
31+
n += 4
32+
}
33+
entryCount := binary.BigEndian.Uint32(buf[n:])
34+
n += 4
35+
if s.Box.Version == 0 {
36+
for i := uint32(0); i < entryCount; i++ {
37+
s.Offset = append(s.Offset, int64(binary.BigEndian.Uint32(buf[n:])))
38+
n += 4
39+
}
40+
} else {
41+
for i := uint32(0); i < entryCount; i++ {
42+
s.Offset = append(s.Offset, int64(binary.BigEndian.Uint64(buf[n:])))
43+
n += 8
44+
}
45+
}
46+
return nil
47+
}
48+
49+
func decodeSaioBox(demuxer *MovDemuxer, size uint32) error {
50+
saio := SaioBox{Box: new(FullBox)}
51+
err := saio.Decode(demuxer.reader, size)
52+
if err != nil {
53+
return err
54+
}
55+
if demuxer.currentTrack == nil {
56+
return errors.New("current track is nil")
57+
}
58+
if len(saio.Offset) > 0 && len(demuxer.currentTrack.subSamples) == 0 {
59+
var currentOffset int64
60+
currentOffset, err = demuxer.reader.Seek(0, io.SeekCurrent)
61+
if err != nil {
62+
return err
63+
}
64+
demuxer.reader.Seek(demuxer.moofOffset+saio.Offset[0], io.SeekStart)
65+
saiz := demuxer.currentTrack.lastSaiz
66+
for i := uint32(0); i < saiz.SampleCount; i++ {
67+
sampleSize := saiz.DefaultSampleInfoSize
68+
if saiz.DefaultSampleInfoSize == 0 {
69+
sampleSize = saiz.SampleInfo[i]
70+
}
71+
buf := make([]byte, sampleSize)
72+
demuxer.reader.Read(buf)
73+
var se sencEntry
74+
se.iv = make([]byte, 16)
75+
copy(se.iv, buf[:8])
76+
if sampleSize == 8 {
77+
demuxer.currentTrack.subSamples = append(demuxer.currentTrack.subSamples, se)
78+
continue
79+
}
80+
n := 8
81+
sampleCount := binary.BigEndian.Uint16(buf[n:])
82+
n += 2
83+
84+
se.subSamples = make([]subSampleEntry, sampleCount)
85+
for j := 0; j < int(sampleCount); j++ {
86+
se.subSamples[j].bytesOfClearData = binary.BigEndian.Uint16(buf[n:])
87+
n += 2
88+
se.subSamples[j].bytesOfProtectedData = binary.BigEndian.Uint32(buf[n:])
89+
n += 4
90+
}
91+
demuxer.currentTrack.subSamples = append(demuxer.currentTrack.subSamples, se)
92+
}
93+
demuxer.reader.Seek(currentOffset, io.SeekStart)
94+
}
95+
return nil
96+
}

go-mp4/saiz-box.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package mp4
2+
3+
import (
4+
"encoding/binary"
5+
"errors"
6+
"io"
7+
)
8+
9+
// SaizBox - Sample Auxiliary Information Sizes Box (saiz) (in stbl or traf box)
10+
type SaizBox struct {
11+
Box *FullBox
12+
AuxInfoType string // Used for Common Encryption Scheme (4-bytes uint32 according to spec)
13+
AuxInfoTypeParameter uint32
14+
SampleCount uint32
15+
SampleInfo []byte
16+
DefaultSampleInfoSize uint8
17+
}
18+
19+
func (s *SaizBox) Decode(r io.Reader, size uint32) error {
20+
if _, err := s.Box.Decode(r); err != nil {
21+
return err
22+
}
23+
buf := make([]byte, size-12)
24+
if _, err := io.ReadFull(r, buf); err != nil {
25+
return err
26+
}
27+
var n int
28+
flags := uint32(s.Box.Flags[0])<<16 | uint32(s.Box.Flags[1])<<8 | uint32(s.Box.Flags[2])
29+
if flags&0x01 != 0 {
30+
s.AuxInfoType = string(buf[n:n+4])
31+
n += 4
32+
s.AuxInfoTypeParameter = binary.BigEndian.Uint32(buf[n:])
33+
n += 4
34+
}
35+
s.DefaultSampleInfoSize = buf[n]
36+
n += 1
37+
38+
s.SampleCount = binary.BigEndian.Uint32(buf[n:])
39+
n += 4
40+
41+
if s.DefaultSampleInfoSize == 0 {
42+
for i := 0; i < int(s.SampleCount); i++ {
43+
s.SampleInfo = append(s.SampleInfo, buf[n])
44+
n += 1
45+
}
46+
}
47+
return nil
48+
}
49+
50+
func decodeSaizBox(demuxer *MovDemuxer, size uint32) error {
51+
saiz := SaizBox{Box: new(FullBox)}
52+
err := saiz.Decode(demuxer.reader, size)
53+
if err != nil {
54+
return err
55+
}
56+
if demuxer.currentTrack == nil {
57+
return errors.New("current track is nil")
58+
}
59+
demuxer.currentTrack.lastSaiz = &saiz
60+
return nil
61+
}

0 commit comments

Comments
 (0)