new parser for movie header box

This commit is contained in:
Martin Riedl 2024-10-16 18:58:58 +02:00
parent 30b665e0d0
commit 199f7730fb
Signed by: martinr92
GPG key ID: FB68DA65516A804C
4 changed files with 115 additions and 1 deletions

2
Box.go
View file

@ -26,6 +26,8 @@ const (
BoxTypeMediaData = "mdat" BoxTypeMediaData = "mdat"
// BoxTypeMovie Movie Box // BoxTypeMovie Movie Box
BoxTypeMovie = "moov" BoxTypeMovie = "moov"
// BoxTypeMovieHeader Movie Header Box
BoxTypeMovieHeader = "mvhd"
// BoxTypeMovieFragment Movie Fragment Box // BoxTypeMovieFragment Movie Fragment Box
BoxTypeMovieFragment = "moof" BoxTypeMovieFragment = "moof"
// BoxTypeMovieFragmentHeader Movie Fragment Header Box // BoxTypeMovieFragmentHeader Movie Fragment Header Box

110
MovieHeaderBox.go Normal file
View file

@ -0,0 +1,110 @@
// 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"
)
// MovieHeaderBox Movie Header Box struct
//
// 8.2.2 Movie Header Box
// Box Type: mvhd
// Container: Movie Box (moov)
// Mandatory: Yes
// Quantity: Exactly one
//
// This box defines overall information which is mediaindependent, and relevant to the entire
// presentation considered as a whole.
type MovieHeaderBox struct {
*FullBox
// is an integer that declares the creation time of the presentation (in seconds
// since midnight, Jan. 1, 1904, in UTC time)
CreationTimeV0 uint32
// is an integer that declares the creation time of the presentation (in seconds
// since midnight, Jan. 1, 1904, in UTC time)
CreationTimeV1 uint64
// is an integer that declares the most recent time the presentation was
// modified (in seconds since midnight, Jan. 1, 1904, in UTC time)
ModificationTimeV0 uint32
// is an integer that declares the most recent time the presentation was
// modified (in seconds since midnight, Jan. 1, 1904, in UTC time)
ModificationTimeV1 uint64
// is an integer that specifies the timescale for the entire presentation; this is the
// number of time units that pass in one second. For example, a time coordinate system that
// measures time in sixtieths of a second has a time scale of 60.
Timescale uint32
// is an integer that declares length of the presentation (in the indicated timescale). This
// property is derived from the presentations tracks: the value of this field corresponds to the
// duration of the longest track in the presentation. If the duration cannot be determined then
// duration is set to all 1s.
DurationV0 uint32
// is an integer that declares length of the presentation (in the indicated timescale). This
// property is derived from the presentations tracks: the value of this field corresponds to the
// duration of the longest track in the presentation. If the duration cannot be determined then
// duration is set to all 1s.
DurationV1 uint64
// is a fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0
// (0x00010000) is normal forward playback
Rate int32
// is a fixed point 8.8 number that indicates the preferred playback volume. 1.0 (0x0100) is
// full volume.
Volume int16
// provides a transformation matrix for the video; (u,v,w) are restricted here to (0,0,1), hex
// values (0,0,0x40000000).
Matrix []int32
// is a nonzero integer that indicates a value to use for the track ID of the next track
// to be added to this presentation. Zero is not a valid track ID value. The value of
// next_track_ID shall be larger than the largest trackID in use. If this value is equal to all 1s
// (32bit maxint), and a new media track is to be added, then a search must be made in the file for
// an unused track identifier.
NextTrackID uint32
}
// ParseMovieHeaderBox creates a new Movie Header Box struct
func ParseMovieHeaderBox(filePosition uint64, headerSize uint32, content []byte) *MovieHeaderBox {
box := &MovieHeaderBox{
FullBox: newFullBox(&Box{filePosition, headerSize}, content[0:4]),
}
position := 4
if box.Version == 1 {
box.CreationTimeV1 = binary.BigEndian.Uint64(content[4:12])
box.ModificationTimeV1 = binary.BigEndian.Uint64(content[12:20])
box.Timescale = binary.BigEndian.Uint32(content[20:24])
box.DurationV1 = binary.BigEndian.Uint64(content[24:32])
position += 28
} else { // version == 0
box.CreationTimeV0 = binary.BigEndian.Uint32(content[4:8])
box.ModificationTimeV0 = binary.BigEndian.Uint32(content[8:12])
box.Timescale = binary.BigEndian.Uint32(content[12:16])
box.DurationV0 = binary.BigEndian.Uint32(content[16:20])
position += 16
}
box.Rate = int32(binary.BigEndian.Uint32(content[position : position+4]))
box.Volume = int16(binary.BigEndian.Uint16(content[position+4 : position+6]))
position += 4 + 2 + 2 + 8 // 4 bytes for rate, 2 bytes for volume, 2 bytes reserved and 8 bytes reserved
for i := 0; i < 9; i++ {
box.Matrix = append(box.Matrix, int32(binary.BigEndian.Uint32(content[position:position+4])))
position += 4
}
// skip 6*32 bit "pre-defined"
position += 6 * 4
box.NextTrackID = binary.BigEndian.Uint32(content[position : position+4])
return box
}

View file

@ -110,6 +110,8 @@ func parseNextBox(reader io.Reader, filePosition uint64) (box interface{}, endPo
box = ParseMediaDataBox(filePosition, boxHeaderSize, boxContentBytes) box = ParseMediaDataBox(filePosition, boxHeaderSize, boxContentBytes)
case BoxTypeMovie: case BoxTypeMovie:
box, err = ParseMovieBox(filePosition, boxHeaderSize, boxContentBytes) box, err = ParseMovieBox(filePosition, boxHeaderSize, boxContentBytes)
case BoxTypeMovieHeader:
box = ParseMovieHeaderBox(filePosition, boxHeaderSize, boxContentBytes)
case BoxTypeMovieFragment: case BoxTypeMovieFragment:
box, err = ParseMovieFragmentBox(filePosition, boxHeaderSize, boxContentBytes) box, err = ParseMovieFragmentBox(filePosition, boxHeaderSize, boxContentBytes)
case BoxTypeMovieFragmentHeader: case BoxTypeMovieFragmentHeader:

View file

@ -22,7 +22,7 @@ Implementation progress
| 8.1.2 Free Space Box | free, skip | - | | 8.1.2 Free Space Box | free, skip | - |
| 8.1.3 Progressive Download Information Box | pdin | - | | 8.1.3 Progressive Download Information Box | pdin | - |
| 8.2.1 Movie Box | moov | 100% | | 8.2.1 Movie Box | moov | 100% |
| 8.2.2 Movie Header Box | mvhd | - | | 8.2.2 Movie Header Box | mvhd | 100% |
| 8.3.1 Track Box | trak | - | | 8.3.1 Track Box | trak | - |
| 8.3.2 Track Header Box | tkhd | - | | 8.3.2 Track Header Box | tkhd | - |
| 8.3.3 Track Reference Box | tref | - | | 8.3.3 Track Reference Box | tref | - |