forked from mstoykov/mp4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
header.go
82 lines (74 loc) · 1.77 KB
/
header.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package mp4
import (
"encoding/binary"
"io"
"math"
)
const (
// BoxHeaderSize the size of a box
boxHeaderSize32bit = 8
boxHeaderSize64bit = 16
)
// BoxHeader The header of a box
type BoxHeader struct {
Type string
Size uint64
}
// DecodeHeader decodes a box header (size + box type)
func DecodeHeader(r io.Reader) (BoxHeader, error) {
buf := make([]byte, boxHeaderSize32bit)
n, err := r.Read(buf)
if err != nil {
return BoxHeader{}, err
}
if n != boxHeaderSize32bit {
return BoxHeader{}, ErrTruncatedHeader
}
typeName := string(buf[4:8])
size := uint64(binary.BigEndian.Uint32(buf[0:4]))
if size == 1 { // 64 bit size
buf = make([]byte, boxHeaderSize64bit-boxHeaderSize32bit)
n, err := r.Read(buf)
if err != nil {
return BoxHeader{}, err
}
if n != 8 {
return BoxHeader{}, ErrTruncatedHeader
}
size = binary.BigEndian.Uint64(buf[0:8])
}
return BoxHeader{typeName, size}, nil
}
// EncodeHeader encodes a box header to a writer
func EncodeHeader(b Box, w io.Writer) error {
var size = b.Size()
size = AddHeaderSize(size)
if math.MaxUint32 > size {
buf := make([]byte, boxHeaderSize32bit)
binary.BigEndian.PutUint32(buf, uint32(size))
strtobuf(buf[4:], b.Type(), 4)
_, err := w.Write(buf)
return err
}
buf := make([]byte, boxHeaderSize64bit)
binary.BigEndian.PutUint32(buf, uint32(1))
strtobuf(buf[4:], b.Type(), 4)
binary.BigEndian.PutUint64(buf[8:], size)
_, err := w.Write(buf)
return err
}
func AddHeaderSize(size uint64) uint64 {
return size + HeaderSizeFor(size)
}
func RemoveHeaderSize(size uint64) uint64 {
if size > math.MaxUint32 {
return size - boxHeaderSize64bit
}
return size - boxHeaderSize32bit
}
func HeaderSizeFor(size uint64) uint64 {
if math.MaxUint32 > size+8 {
return boxHeaderSize32bit
}
return boxHeaderSize64bit
}