mp4/ChunkOffsetBox.go

87 lines
3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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"
)
// ChunkOffsetBox chunk offset box struct
//
// 8.7.5 Chunk Offset Box
//
// Box Type: stco, co64
// Container: Sample Table Box (stbl)
// Mandatory: Yes
// Quantity: Exactly one variant must be present
//
// The chunk offset table gives the index of each chunk into the containing file. There are two variants,
// permitting the use of 32bit or 64bit offsets. The latter is useful when managing very large
// presentations. At most one of these variants will occur in any single instance of a sample table.
//
// Offsets are file offsets, not the offset into any box within the file (e.g. Media Data Box). This permits
// referring to media data in files without any box structure. It does also mean that care must be taken
// when constructing a selfcontained ISO file with its metadata (Movie Box) at the front, as the size of the
// Movie Box will affect the chunk offsets to the media data.
type ChunkOffsetBox struct {
*FullBox
// is an integer that gives the number of entries in the following table
EntryCount uint32
EntryList []ChunkOffsetEntry
}
type ChunkOffsetEntry struct {
// is a 32 or 64 bit integer that gives the offset of the start of a chunk into its
// containing media file.
ChunkOffset uint32
}
// BoxTypeChunkOffset Chunk Offset Box
const BoxTypeChunkOffset = "stco"
func init() {
BoxDefinitions = append(BoxDefinitions, BoxDefinition{
Type: BoxTypeChunkOffset,
ParentTypes: []string{BoxTypeSampleTable},
Parser: ParseChunkOffsetBox,
})
}
// ParseChunkOffsetBox creates a new chunk offset box struct based on bytes
func ParseChunkOffsetBox(parser *Parser, filePosition uint64, headerSize uint32, content []byte) (any, error) {
box := &ChunkOffsetBox{
FullBox: newFullBox(&Box{filePosition, headerSize}, content[0:4]),
}
// parse entry counter
box.EntryCount = binary.BigEndian.Uint32(content[4:8])
// parse offset entries
position := 8
for i := 0; i < int(box.EntryCount); i++ {
newOffsetEntry := ChunkOffsetEntry{
ChunkOffset: binary.BigEndian.Uint32(content[position+(i*4) : position+4+(i*4)]),
}
box.EntryList = append(box.EntryList, newOffsetEntry)
}
// validate entries amount
if len(box.EntryList) != int(box.EntryCount) {
return box, fmt.Errorf("invalid amount of offset entries at %d; got %d but expected %d", filePosition, len(box.EntryList), box.EntryCount)
}
return box, nil
}