From 1c406419a506fe4c962874cb64b425f1372877c0 Mon Sep 17 00:00:00 2001 From: Martin Riedl Date: Sun, 8 Dec 2024 11:09:57 +0100 Subject: [PATCH] feat: new decoding time to sample box implementation --- DecodingTimeToSampleBox.go | 95 ++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 DecodingTimeToSampleBox.go diff --git a/DecodingTimeToSampleBox.go b/DecodingTimeToSampleBox.go new file mode 100644 index 0000000..3bfb3f0 --- /dev/null +++ b/DecodingTimeToSampleBox.go @@ -0,0 +1,95 @@ +// Copyright 2024 Martin Riedl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomp4 + +import ( + "encoding/binary" + "fmt" +) + +// TimeToSampleBox time to sample box struct +// +// 8.6.1.2 Decoding Time to Sample Box +// +// Box Type: ‘stts’ +// Container: Sample Table Box (‘stbl’) +// Mandatory: Yes +// Quantity: Exactly one +// +// This box contains a compact version of a table that allows indexing from decoding time to sample +// number. Other tables give sample sizes and pointers, from the sample number. Each entry in the table +// gives the number of consecutive samples with the same time delta, and the delta of those samples. By +// adding the deltas a complete time‐to‐sample map may be built. +// +// The Decoding Time to Sample Box contains decode time delta's: DT(n+1) = DT(n) + STTS(n) where +// STTS(n) is the (uncompressed) table entry for sample n. +// +// The sample entries are ordered by decoding time stamps; therefore the deltas are all non‐negative. +// +// The DT axis has a zero origin; DT(i) = SUM(for j=0 to i‐1 of delta(j)), and the sum of all deltas gives the +// length of the media in the track (not mapped to the overall timescale, and not considering any edit list). +// +// The Edit List Box provides the initial CT value if it is non‐empty (non‐zero). +type TimeToSampleBox struct { + *FullBox + // is an integer that gives the number of entries in the following table. + EntryCount uint32 + Entries []TimeToSampleBoxEntry +} + +type TimeToSampleBoxEntry struct { + // s an integer that counts the number of consecutive samples that have the given duration. + SampleCount uint32 + // is an integer that gives the delta of these samples in the time‐scale of the media. + SampleDelta uint32 +} + +// BoxTypeDecodingTimeToSample Decoding Time To Sample Box +const BoxTypeDecodingTimeToSample = "stts" + +func init() { + BoxDefinitions = append(BoxDefinitions, BoxDefinition{ + Type: BoxTypeDecodingTimeToSample, + ParentTypes: []string{BoxTypeSampleTable}, + Parser: ParseDecodingTimeToSampleBox, + }) +} + +// ParseDecodingTimeToSampleBox creates a new decoding time to sample box struct based on bytes +func ParseDecodingTimeToSampleBox(parser *Parser, filePosition uint64, headerSize uint32, content []byte) (any, error) { + box := &TimeToSampleBox{ + FullBox: newFullBox(&Box{filePosition, headerSize}, content[0:4]), + } + + // parse entry counter + box.EntryCount = binary.BigEndian.Uint32(content[4:8]) + + // parse sample entries + position := 8 + for i := 0; i < int(box.EntryCount); i++ { + newSampleEntry := TimeToSampleBoxEntry{ + SampleCount: binary.BigEndian.Uint32(content[position+(i*8) : position+4+(i*8)]), + SampleDelta: binary.BigEndian.Uint32(content[position+4+(i*8) : position+8+(i*8)]), + } + box.Entries = append(box.Entries, newSampleEntry) + } + + // validate entries amount + if len(box.Entries) != int(box.EntryCount) { + return box, fmt.Errorf("invalid amount of sample entries at %d; got %d but expected %d", filePosition, len(box.Entries), box.EntryCount) + } + + return box, nil +} diff --git a/README.md b/README.md index 7018331..b2d4c01 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Implementation progress of ISO ICE 14496-12:2015: | 8.5.1 Sample Table Box | stbl | 100% | | 8.5.2 Sample Description Box | stsd | 100% | | 8.5.3 Degradation Priority Box | stdp | - | -| 8.6.1.2 Decoding Time to Sample Box | stts | - | +| 8.6.1.2 Decoding Time to Sample Box | stts | 100% | | 8.6.1.3 Composition Time to Sample Box | ctts | - | | 8.6.1.4 Composition to Decode Box | cslg | - | | 8.6.2 Sync Sample Box | stss | - |