-
Notifications
You must be signed in to change notification settings - Fork 83
/
annexb.go
104 lines (101 loc) · 2.8 KB
/
annexb.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package hevc
// GetParameterSetsFromByteStream gets SPS and PPS nalus from bytestream
func GetParameterSetsFromByteStream(data []byte) (vpss [][]byte, spss [][]byte, ppss [][]byte) {
n := len(data)
currNaluStart := -1
totSize := 0
for i := 0; i < n-4; i++ {
if data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 {
if currNaluStart > 0 {
currNaluEnd := i
for j := i - 1; j > currNaluStart; j-- {
// Remove zeros from end of NAL unit
if data[j] == 0 {
currNaluEnd = j
} else {
break
}
}
switch naluType := GetNaluType(data[currNaluStart]); naluType {
case NALU_VPS:
vpss = append(vpss, data[currNaluStart:currNaluEnd])
totSize += currNaluEnd - currNaluStart
case NALU_SPS:
spss = append(spss, data[currNaluStart:currNaluEnd])
totSize += currNaluEnd - currNaluStart
case NALU_PPS:
ppss = append(ppss, data[currNaluStart:currNaluEnd])
totSize += currNaluEnd - currNaluStart
}
}
currNaluStart = i + 3
nextNaluType := GetNaluType(data[currNaluStart])
if nextNaluType < 32 { // Video NALU types are below 32
break
}
}
}
psData := make([]byte, totSize)
pos := 0
for i := range vpss {
copy(psData[pos:], vpss[i])
vpss[i] = psData[pos : pos+len(vpss[i])]
pos += len(vpss[i])
}
for i := range spss {
copy(psData[pos:], spss[i])
spss[i] = psData[pos : pos+len(spss[i])]
pos += len(spss[i])
}
for i := range ppss {
copy(psData[pos:], ppss[i])
ppss[i] = psData[pos : pos+len(ppss[i])]
pos += len(ppss[i])
}
return vpss, spss, ppss
}
// ExtractNalusOfTypeFromByteStream returns all HEVC nalus of wanted type from bytestream.
// If stopAtVideo, the stream is not scanned beyond the first video NAL unit.
func ExtractNalusOfTypeFromByteStream(nType NaluType, data []byte, stopAtVideo bool) [][]byte {
currNaluStart := -1
n := len(data)
var nalus [][]byte
for i := 0; i < n-3; i++ {
if data[i] == 0 && data[i+1] == 0 && data[i+2] == 1 {
if currNaluStart > 0 {
currNaluEnd := i
for j := i - 1; j > currNaluStart; j-- {
// Remove zeros from end of NAL unit
if data[j] == 0 {
currNaluEnd = j
} else {
break
}
}
naluType := GetNaluType(data[currNaluStart])
if naluType == nType {
nalus = append(nalus, extractSlice(data, currNaluStart, currNaluEnd))
}
}
currNaluStart = i + 3
if currNaluStart < n-1 {
nextNaluType := GetNaluType(data[currNaluStart])
if stopAtVideo && nextNaluType < 32 { // Video nal unit type
return nalus
}
}
}
}
if currNaluStart < 0 {
return nil
}
if GetNaluType(data[currNaluStart]) == nType {
nalus = append(nalus, extractSlice(data, currNaluStart, n))
}
return nalus
}
func extractSlice(data []byte, start, stop int) []byte {
sl := make([]byte, stop-start)
_ = copy(sl, data[start:stop])
return sl
}