Skip to content

Commit

Permalink
Merge branch 'yapingcat:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
timmattison authored Jun 11, 2024
2 parents 1f15147 + 920523f commit 6118438
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
4 changes: 4 additions & 0 deletions go-mp4/mp4demuxer.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@ func (demuxer *MovDemuxer) ReadHead() ([]TrackInfo, error) {
err = decodeTrunBox(demuxer, uint32(basebox.Size))
case mov_tag([4]byte{'s', 'e', 'n', 'c'}):
err = decodeSencBox(demuxer, uint32(basebox.Size))
case mov_tag([4]byte{'s', 'a', 'i', 'z'}):
err = decodeSaizBox(demuxer, uint32(basebox.Size))
case mov_tag([4]byte{'s', 'a', 'i', 'o'}):
err = decodeSaioBox(demuxer, uint32(basebox.Size))
case mov_tag([4]byte{'u', 'u', 'i', 'd'}):
_, err = demuxer.reader.Seek(int64(basebox.Size)-BasicBoxLen-16, io.SeekCurrent)
case mov_tag([4]byte{'s', 'g', 'p', 'd'}):
Expand Down
1 change: 1 addition & 0 deletions go-mp4/mp4track.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type mp4track struct {
defaultConstantIV []byte
defaultKID [16]byte
lastSeig *SeigSampleGroupEntry
lastSaiz *SaizBox
subSamples []sencEntry
}

Expand Down
96 changes: 96 additions & 0 deletions go-mp4/saio-box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package mp4

import (
"encoding/binary"
"errors"
"io"
)

// SaioBox - Sample Auxiliary Information Offsets Box (saiz) (in stbl or traf box)
type SaioBox struct {
Box *FullBox
AuxInfoType string // Used for Common Encryption Scheme (4-bytes uint32 according to spec)
AuxInfoTypeParameter uint32
Offset []int64
}

func (s *SaioBox) Decode(r io.Reader, size uint32) error {
if _, err := s.Box.Decode(r); err != nil {
return err
}
buf := make([]byte, size-12)
if _, err := io.ReadFull(r, buf); err != nil {
return err
}
var n int
flags := uint32(s.Box.Flags[0])<<16 | uint32(s.Box.Flags[1])<<8 | uint32(s.Box.Flags[2])
if flags&0x01 != 0 {
s.AuxInfoType = string(buf[n:n+4])
n += 4
s.AuxInfoTypeParameter = binary.BigEndian.Uint32(buf[n:])
n += 4
}
entryCount := binary.BigEndian.Uint32(buf[n:])
n += 4
if s.Box.Version == 0 {
for i := uint32(0); i < entryCount; i++ {
s.Offset = append(s.Offset, int64(binary.BigEndian.Uint32(buf[n:])))
n += 4
}
} else {
for i := uint32(0); i < entryCount; i++ {
s.Offset = append(s.Offset, int64(binary.BigEndian.Uint64(buf[n:])))
n += 8
}
}
return nil
}

func decodeSaioBox(demuxer *MovDemuxer, size uint32) error {
saio := SaioBox{Box: new(FullBox)}
err := saio.Decode(demuxer.reader, size)
if err != nil {
return err
}
if demuxer.currentTrack == nil {
return errors.New("current track is nil")
}
if len(saio.Offset) > 0 && len(demuxer.currentTrack.subSamples) == 0 {
var currentOffset int64
currentOffset, err = demuxer.reader.Seek(0, io.SeekCurrent)
if err != nil {
return err
}
demuxer.reader.Seek(demuxer.moofOffset+saio.Offset[0], io.SeekStart)
saiz := demuxer.currentTrack.lastSaiz
for i := uint32(0); i < saiz.SampleCount; i++ {
sampleSize := saiz.DefaultSampleInfoSize
if saiz.DefaultSampleInfoSize == 0 {
sampleSize = saiz.SampleInfo[i]
}
buf := make([]byte, sampleSize)
demuxer.reader.Read(buf)
var se sencEntry
se.iv = make([]byte, 16)
copy(se.iv, buf[:8])
if sampleSize == 8 {
demuxer.currentTrack.subSamples = append(demuxer.currentTrack.subSamples, se)
continue
}
n := 8
sampleCount := binary.BigEndian.Uint16(buf[n:])
n += 2

se.subSamples = make([]subSampleEntry, sampleCount)
for j := 0; j < int(sampleCount); j++ {
se.subSamples[j].bytesOfClearData = binary.BigEndian.Uint16(buf[n:])
n += 2
se.subSamples[j].bytesOfProtectedData = binary.BigEndian.Uint32(buf[n:])
n += 4
}
demuxer.currentTrack.subSamples = append(demuxer.currentTrack.subSamples, se)
}
demuxer.reader.Seek(currentOffset, io.SeekStart)
}
return nil
}
61 changes: 61 additions & 0 deletions go-mp4/saiz-box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package mp4

import (
"encoding/binary"
"errors"
"io"
)

// SaizBox - Sample Auxiliary Information Sizes Box (saiz) (in stbl or traf box)
type SaizBox struct {
Box *FullBox
AuxInfoType string // Used for Common Encryption Scheme (4-bytes uint32 according to spec)
AuxInfoTypeParameter uint32
SampleCount uint32
SampleInfo []byte
DefaultSampleInfoSize uint8
}

func (s *SaizBox) Decode(r io.Reader, size uint32) error {
if _, err := s.Box.Decode(r); err != nil {
return err
}
buf := make([]byte, size-12)
if _, err := io.ReadFull(r, buf); err != nil {
return err
}
var n int
flags := uint32(s.Box.Flags[0])<<16 | uint32(s.Box.Flags[1])<<8 | uint32(s.Box.Flags[2])
if flags&0x01 != 0 {
s.AuxInfoType = string(buf[n:n+4])
n += 4
s.AuxInfoTypeParameter = binary.BigEndian.Uint32(buf[n:])
n += 4
}
s.DefaultSampleInfoSize = buf[n]
n += 1

s.SampleCount = binary.BigEndian.Uint32(buf[n:])
n += 4

if s.DefaultSampleInfoSize == 0 {
for i := 0; i < int(s.SampleCount); i++ {
s.SampleInfo = append(s.SampleInfo, buf[n])
n += 1
}
}
return nil
}

func decodeSaizBox(demuxer *MovDemuxer, size uint32) error {
saiz := SaizBox{Box: new(FullBox)}
err := saiz.Decode(demuxer.reader, size)
if err != nil {
return err
}
if demuxer.currentTrack == nil {
return errors.New("current track is nil")
}
demuxer.currentTrack.lastSaiz = &saiz
return nil
}

0 comments on commit 6118438

Please sign in to comment.