1
1
mirror of https://github.com/wader/fq.git synced 2024-12-24 22:05:31 +03:00

mp4: Properly use trun data offset

Each trun has it's own data offset, before the last offset was wrongly used
for all truns. Could also cause sample ranges to be beyond EOF.

tenc: Decode default constant iv

Fixes #292
This commit is contained in:
Mattias Wadman 2022-06-07 15:34:09 +02:00
parent f7457ce893
commit 7d25fbfdbb
2 changed files with 66 additions and 30 deletions

View File

@ -196,8 +196,9 @@ type moofBox struct {
}
type trafBox struct {
trackID int
moof *moof
trackID int
baseDataOffset int64
moof *moof
}
func irefEntryDecode(ctx *decodeContext, d *decode.D) {
@ -777,7 +778,8 @@ func init() {
},
"moov": decodeBoxes,
"moof": func(ctx *decodeContext, d *decode.D) {
decodeBoxesWithParentData(ctx, d, &moofBox{offset: (d.Pos() / 8) - 8})
offset := (d.Pos() / 8) - 8
decodeBoxesWithParentData(ctx, d, &moofBox{offset: offset})
},
// Track Fragment
"traf": func(ctx *decodeContext, d *decode.D) {
@ -807,7 +809,6 @@ func init() {
d.FieldU1("unused2")
sampleDescriptionIndexPresent = d.FieldBool("sample_description_index_present")
baseDataOffsetPresent = d.FieldBool("base_data_offset_present")
})
trackID := int(d.FieldU32("track_id"))
@ -815,16 +816,10 @@ func init() {
if mb := ctx.currentMoofBox(); mb != nil {
m.offset = mb.offset
}
if t := ctx.currentTrafBox(); t != nil {
t.trackID = trackID
t.moof = m
}
if t := ctx.currentTrack(); t != nil {
t.moofs = append(t.moofs, m)
}
baseDataOffset := int64(0)
if baseDataOffsetPresent {
d.FieldU64("base_data_offset")
baseDataOffset = int64(d.FieldU64("base_data_offset"))
}
if sampleDescriptionIndexPresent {
m.defaultSampleDescriptionIndex = int(d.FieldU32("sample_description_index"))
@ -838,6 +833,15 @@ func init() {
if defaultSampleFlagsPresent {
d.FieldU32("default_sample_flags")
}
if t := ctx.currentTrafBox(); t != nil {
t.trackID = trackID
t.moof = m
t.baseDataOffset = baseDataOffset
}
if t := ctx.currentTrack(); t != nil {
t.moofs = append(t.moofs, m)
}
},
// Track Fragment Run
"trun": func(ctx *decodeContext, d *decode.D) {
@ -865,8 +869,9 @@ func init() {
dataOffsetPresent = d.FieldBool("data_offset_present")
})
sampleCount := d.FieldU32("sample_count")
dataOffset := int64(0)
if dataOffsetPresent {
m.dataOffset = d.FieldS32("data_offset")
dataOffset = d.FieldS32("data_offset")
}
if firstSampleFlagsPresent {
d.FieldU32("first_sample_flags")
@ -876,6 +881,9 @@ func init() {
d.Errorf("too many sample trun entries %d > %d", sampleCount, maxSampleEntryCount)
}
t := trun{
dataOffset: dataOffset,
}
d.FieldArray("samples", func(d *decode.D) {
for i := uint64(0); i < sampleCount; i++ {
sampleSize := m.defaultSampleSize
@ -894,9 +902,11 @@ func init() {
}
})
m.samplesSizes = append(m.samplesSizes, sampleSize)
t.samplesSizes = append(t.samplesSizes, sampleSize)
}
})
m.truns = append(m.truns, t)
},
"tfdt": func(_ *decodeContext, d *decode.D) {
version := d.FieldU8("version")
@ -1244,7 +1254,9 @@ func init() {
d.FieldArray("samples", func(d *decode.D) {
for i := uint64(0); i < sampleCount; i++ {
d.FieldStruct("entry", func(d *decode.D) {
d.FieldRawLen("iv", int64(t.defaultIVSize*8))
if t.defaultIVSize != 0 {
d.FieldRawLen("iv", int64(t.defaultIVSize*8))
}
if flags&0b10 != 0 {
subSampleCount := d.FieldU16("subsample_count")
d.FieldArray("subsamples", func(d *decode.D) {
@ -1278,7 +1290,8 @@ func init() {
d.FieldRawLen("default_kid", 8*16)
if defaultIsEncrypted != 0 && defaultIVSize == 0 {
d.FieldU8("default_constant_iv_size")
defaultConstantIVSize := d.FieldU8("default_constant_iv_size")
d.FieldRawLen("default_constant_iv", int64(defaultConstantIVSize)*8)
}
if t := ctx.currentTrack(); t != nil {
t.defaultIVSize = int(defaultIVSize)

View File

@ -102,8 +102,12 @@ type moof struct {
offset int64
defaultSampleSize int64
defaultSampleDescriptionIndex int
dataOffset int64
samplesSizes []int64
truns []trun
}
type trun struct {
dataOffset int64
samplesSizes []int64
}
type sampleDescription struct {
@ -339,20 +343,39 @@ func mp4Tracks(d *decode.D, ctx *decodeContext) {
}
}
sampleNr := 0
for _, m := range t.moofs {
sampleOffset := m.offset + m.dataOffset
for _, sz := range m.samplesSizes {
dataFormat := trackSDDataFormat
if m.defaultSampleDescriptionIndex != 0 && m.defaultSampleDescriptionIndex-1 < len(t.sampleDescriptions) {
sd := t.sampleDescriptions[m.defaultSampleDescriptionIndex-1]
dataFormat = sd.dataFormat
if sd.originalFormat != "" {
dataFormat = sd.originalFormat
}
}
for _, trun := range m.truns {
sampleOffset := m.offset + trun.dataOffset
decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, sz*8, t.formatInArg)
sampleOffset += sz
for _, sz := range trun.samplesSizes {
dataFormat := trackSDDataFormat
if m.defaultSampleDescriptionIndex != 0 && m.defaultSampleDescriptionIndex-1 < len(t.sampleDescriptions) {
sd := t.sampleDescriptions[m.defaultSampleDescriptionIndex-1]
dataFormat = sd.dataFormat
if sd.originalFormat != "" {
dataFormat = sd.originalFormat
}
}
// logStrFn := func() string {
// return fmt.Sprintf("%d: %s: %d: (%s): sz=%d %d+%d=%d",
// t.id,
// dataFormat,
// sampleNr,
// trackSDDataFormat,
// sz,
// m.offset,
// m.dataOffset,
// sampleOffset,
// )
// }
// log.Println(logStrFn())
decodeSampleRange(d, t, dataFormat, "sample", sampleOffset*8, sz*8, t.formatInArg)
sampleOffset += sz
sampleNr++
}
}
}
})