mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
137 lines
4.0 KiB
Go
137 lines
4.0 KiB
Go
package box
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
"time"
|
|
)
|
|
|
|
// aligned(8) class MovieHeaderBox extends FullBox('mvhd', version, 0) {
|
|
// if (version==1) {
|
|
// unsigned int(64) creation_time;
|
|
// unsigned int(64) modification_time;
|
|
// unsigned int(32) timescale;
|
|
// unsigned int(64) duration;
|
|
// } else { // version==0
|
|
// unsigned int(32) creation_time;
|
|
// unsigned int(32) modification_time;
|
|
// unsigned int(32) timescale;
|
|
// unsigned int(32) duration;
|
|
// }
|
|
// template int(32) rate = 0x00010000; // typically 1.0
|
|
// template int(16) volume = 0x0100; // typically, full volume const bit(16) reserved = 0;
|
|
// const unsigned int(32)[2] reserved = 0;
|
|
// template int(32)[9] matrix =
|
|
// { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };
|
|
// // Unity matrix
|
|
// bit(32)[6] pre_defined = 0;
|
|
// unsigned int(32) next_track_ID;
|
|
// }
|
|
|
|
type MovieHeaderBox struct {
|
|
FullBox
|
|
CreationTime uint64
|
|
ModificationTime uint64
|
|
Timescale uint32
|
|
Duration uint64
|
|
Rate int32
|
|
Volume int16
|
|
Matrix [9]int32
|
|
NextTrackID uint32
|
|
}
|
|
|
|
func CreateMovieHeaderBox(nextTrackID uint32, duration uint32) *MovieHeaderBox {
|
|
now := ConvertUnixTimeToISO14496(uint64(time.Now().Unix()))
|
|
return &MovieHeaderBox{
|
|
FullBox: FullBox{
|
|
BaseBox: BaseBox{
|
|
typ: TypeMVHD,
|
|
size: uint32(FullBoxLen + 96),
|
|
},
|
|
Version: 0,
|
|
Flags: [3]byte{0, 0, 0},
|
|
},
|
|
CreationTime: now,
|
|
ModificationTime: now,
|
|
Timescale: 1000,
|
|
Duration: uint64(duration),
|
|
Rate: 0x00010000,
|
|
Volume: 0x0100,
|
|
Matrix: [9]int32{0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000},
|
|
NextTrackID: nextTrackID,
|
|
}
|
|
}
|
|
|
|
func (box *MovieHeaderBox) WriteTo(w io.Writer) (n int64, err error) {
|
|
var nn int
|
|
if box.Version == 1 {
|
|
var tmp [108]byte
|
|
binary.BigEndian.PutUint64(tmp[0:], box.CreationTime)
|
|
binary.BigEndian.PutUint64(tmp[8:], box.ModificationTime)
|
|
binary.BigEndian.PutUint32(tmp[16:], box.Timescale)
|
|
binary.BigEndian.PutUint64(tmp[20:], box.Duration)
|
|
binary.BigEndian.PutUint32(tmp[28:], uint32(box.Rate))
|
|
binary.BigEndian.PutUint16(tmp[32:], uint16(box.Volume))
|
|
offset := 44
|
|
for i := 0; i < 9; i++ {
|
|
binary.BigEndian.PutUint32(tmp[offset:], uint32(box.Matrix[i]))
|
|
offset += 4
|
|
}
|
|
binary.BigEndian.PutUint32(tmp[104:], box.NextTrackID)
|
|
nn, err = w.Write(tmp[:])
|
|
n = int64(nn)
|
|
} else {
|
|
var tmp [96]byte
|
|
binary.BigEndian.PutUint32(tmp[0:], uint32(box.CreationTime))
|
|
binary.BigEndian.PutUint32(tmp[4:], uint32(box.ModificationTime))
|
|
binary.BigEndian.PutUint32(tmp[8:], box.Timescale)
|
|
binary.BigEndian.PutUint32(tmp[12:], uint32(box.Duration))
|
|
binary.BigEndian.PutUint32(tmp[16:], uint32(box.Rate))
|
|
binary.BigEndian.PutUint16(tmp[20:], uint16(box.Volume))
|
|
offset := 32
|
|
for i := 0; i < 9; i++ {
|
|
binary.BigEndian.PutUint32(tmp[offset:], uint32(box.Matrix[i]))
|
|
offset += 4
|
|
}
|
|
binary.BigEndian.PutUint32(tmp[92:], box.NextTrackID)
|
|
nn, err = w.Write(tmp[:])
|
|
n = int64(nn)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (box *MovieHeaderBox) Unmarshal(buf []byte) (IBox, error) {
|
|
var offset int
|
|
if box.Version == 1 {
|
|
box.CreationTime = binary.BigEndian.Uint64(buf[0:])
|
|
box.ModificationTime = binary.BigEndian.Uint64(buf[8:])
|
|
box.Timescale = binary.BigEndian.Uint32(buf[16:])
|
|
box.Duration = binary.BigEndian.Uint64(buf[20:])
|
|
offset = 28
|
|
} else {
|
|
box.CreationTime = uint64(binary.BigEndian.Uint32(buf[0:]))
|
|
box.ModificationTime = uint64(binary.BigEndian.Uint32(buf[4:]))
|
|
box.Timescale = binary.BigEndian.Uint32(buf[8:])
|
|
box.Duration = uint64(binary.BigEndian.Uint32(buf[12:]))
|
|
offset = 16
|
|
}
|
|
|
|
box.Rate = int32(binary.BigEndian.Uint32(buf[offset:]))
|
|
box.Volume = int16(binary.BigEndian.Uint16(buf[offset+4:]))
|
|
// skip reserved: 2 + 8 bytes
|
|
|
|
offset += 16
|
|
for i := 0; i < 9; i++ {
|
|
box.Matrix[i] = int32(binary.BigEndian.Uint32(buf[offset:]))
|
|
offset += 4
|
|
}
|
|
// skip pre_defined: 24 bytes
|
|
box.NextTrackID = binary.BigEndian.Uint32(buf[offset+24:])
|
|
|
|
return box, nil
|
|
}
|
|
|
|
func init() {
|
|
RegisterBox[*MovieHeaderBox](TypeMVHD)
|
|
}
|