Skip to content

Commit

Permalink
fix: proper handling of add-sidx for multi-fragment segment
Browse files Browse the repository at this point in the history
  • Loading branch information
tobbee committed Apr 19, 2024
1 parent b1b0dfb commit e2dfbde
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 56 deletions.
5 changes: 0 additions & 5 deletions examples/add-sidx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,6 @@ func run(in io.Reader, out io.Writer, nonZeroEPT, removeEncBoxes, segOnMoof bool
return err
}
fmt.Printf("found %d segments\n", len(mp4Root.Segments))
for i, seg := range mp4Root.Segments {
for j, frag := range seg.Fragments {
fmt.Printf("segment: %d, fragment: %d, sequenceNr: %d\n", i, j, frag.Moof.Mfhd.SequenceNumber)
}
}

if removeEncBoxes {
removeEncryptionBoxes(mp4Root)
Expand Down
63 changes: 36 additions & 27 deletions examples/add-sidx/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,45 @@ import (
func TestAddSidx(t *testing.T) {
inPath := "testdata/clear_with_enc_boxes.mp4"
testCases := []struct {
desc string
inPath string
removeEnc bool
segOnMoof bool
wantedNrSegs uint32
wantedSize uint32
desc string
inPath string
removeEnc bool
segOnMoof bool
wantedNrSegs uint32
wantedSize uint32
wantedFirstDur uint32
}{
{
desc: "sidx, enc boxes, 1 segment",
inPath: inPath,
removeEnc: false,
segOnMoof: false,
wantedNrSegs: 1,
desc: "sidx, enc boxes, 1 segment",
inPath: inPath,
removeEnc: false,
segOnMoof: false,
wantedNrSegs: 1,
wantedFirstDur: 2 * 144144,
},
{
desc: "sidx, enc boxes, many segments",
inPath: inPath,
removeEnc: false,
segOnMoof: true,
wantedNrSegs: 2,
desc: "sidx, enc boxes, many segments",
inPath: inPath,
removeEnc: false,
segOnMoof: true,
wantedNrSegs: 2,
wantedFirstDur: 144144,
},
{
desc: "sidx, no enc boxes, many segments",
inPath: inPath,
removeEnc: true,
segOnMoof: true,
wantedNrSegs: 2,
desc: "sidx, no enc boxes, many segments",
inPath: inPath,
removeEnc: true,
segOnMoof: true,
wantedNrSegs: 2,
wantedFirstDur: 144144,
},
{
desc: "normal file with styp",
inPath: "../resegmenter/testdata/testV300.mp4",
removeEnc: false,
segOnMoof: false,
wantedNrSegs: 4,
desc: "normal file with styp",
inPath: "../resegmenter/testdata/testV300.mp4",
removeEnc: false,
segOnMoof: false,
wantedNrSegs: 4,
wantedFirstDur: 180000,
},
}

Expand All @@ -66,10 +71,14 @@ func TestAddSidx(t *testing.T) {
if decOut.Sidx == nil {
t.Error("no sidx box")
}
gotNrEntries := len(decOut.Sidx.SidxRefs)
sidxEntries := decOut.Sidx.SidxRefs
gotNrEntries := len(sidxEntries)
if gotNrEntries != int(tc.wantedNrSegs) {
t.Errorf("got %d sidx entries instead of %d", gotNrEntries, tc.wantedNrSegs)
}
if sidxEntries[0].SubSegmentDuration != tc.wantedFirstDur {
t.Errorf("got first duration %d instead of %d", sidxEntries[0].SubSegmentDuration, tc.wantedFirstDur)
}
if tc.removeEnc {
for _, seg := range decOut.Segments {
for _, frag := range seg.Fragments {
Expand Down
51 changes: 27 additions & 24 deletions mp4/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -780,38 +780,41 @@ type segData struct {
size uint32
}

// findSegmentData returns a slice of segment media data using a reference track.
func findSegmentData(segs []*MediaSegment, refTrak *TrakBox, trex *TrexBox) ([]segData, error) {
segDatas := make([]segData, 0, len(segs))
for _, seg := range segs {
frag := seg.Fragments[0]
for _, traf := range frag.Moof.Trafs {
tfhd := traf.Tfhd
if tfhd.TrackID == refTrak.Tkhd.TrackID {
// Found the track that the sidx should be based on
baseTime := traf.Tfdt.BaseMediaDecodeTime()
dur := uint32(0)
var firstCompositionTimeOffest int64
for i, trun := range traf.Truns {
trun.AddSampleDefaultValues(tfhd, trex)
samples := trun.GetSamples()
for j, sample := range samples {
if i == 0 && j == 0 {
firstCompositionTimeOffest = int64(sample.CompositionTimeOffset)
var firstCompositionTimeOffest int64
dur := uint32(0)
var baseTime uint64
for fIdx, frag := range seg.Fragments {
for _, traf := range frag.Moof.Trafs {
tfhd := traf.Tfhd
if tfhd.TrackID == refTrak.Tkhd.TrackID { // Find track that gives sidx time values
if fIdx == 0 {
baseTime = traf.Tfdt.BaseMediaDecodeTime()
}
for i, trun := range traf.Truns {
trun.AddSampleDefaultValues(tfhd, trex)
samples := trun.GetSamples()
for j, sample := range samples {
if fIdx == 0 && i == 0 && j == 0 {
firstCompositionTimeOffest = int64(sample.CompositionTimeOffset)
}
dur += sample.Dur
}
dur += sample.Dur
}
}
sd := segData{
startPos: seg.StartPos,
presentationTime: uint64(int64(baseTime) + firstCompositionTimeOffest),
baseDecodeTime: baseTime,
dur: dur,
size: uint32(seg.Size()),
}
segDatas = append(segDatas, sd)
break
}
}
sd := segData{
startPos: seg.StartPos,
presentationTime: uint64(int64(baseTime) + firstCompositionTimeOffest),
baseDecodeTime: baseTime,
dur: dur,
size: uint32(seg.Size()),
}
segDatas = append(segDatas, sd)
}
return segDatas, nil
}
Expand Down

0 comments on commit e2dfbde

Please sign in to comment.