-
Notifications
You must be signed in to change notification settings - Fork 3
/
media.go
109 lines (93 loc) · 3.08 KB
/
media.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
105
106
107
108
109
package main
import (
"encoding/binary"
"fmt"
flvtag "github.com/yutopp/go-flv/tag"
)
const (
headerLengthField = 4
spsId = 0x67
ppsId = 0x68
)
var (
annexBPrefix = []byte{0x00, 0x00, 0x00, 0x01}
)
func appendNALHeaderSpecial(video flvtag.VideoData, videoBuffer []byte) (sps, pps, outbuf []byte) {
hasSpsPps := false
var outBuf []byte
if video.AVCPacketType == flvtag.AVCPacketTypeNALU {
fmt.Println("video.AVCPacketType == flvtag.AVCPacketTypeNALU")
for offset := 0; offset < len(videoBuffer); {
bufferLength := int(binary.BigEndian.Uint32(videoBuffer[offset : offset+headerLengthField]))
if offset+bufferLength >= len(videoBuffer) {
break
}
offset += headerLengthField
if videoBuffer[offset] == spsId {
fmt.Println("videoBuffer at offset has spsId")
hasSpsPps = true
sps = append(annexBPrefix, videoBuffer[offset:offset+bufferLength]...)
} else if videoBuffer[offset] == ppsId {
fmt.Println("videoBuffer at offset has ppsId")
hasSpsPps = true
pps = append(annexBPrefix, videoBuffer[offset:offset+bufferLength]...)
}
outBuf = append(outBuf, annexBPrefix...)
outBuf = append(outBuf, videoBuffer[offset:offset+bufferLength]...)
offset += bufferLength
}
} else if video.AVCPacketType == flvtag.AVCPacketTypeSequenceHeader {
fmt.Println("video.AVCPacketType == flvtag.AVCPacketTypeSequenceHeader")
const spsCountOffset = 5
spsCount := videoBuffer[spsCountOffset] & 0x1F
offset := 6
sps = []byte{}
for i := 0; i < int(spsCount); i++ {
spsLen := binary.BigEndian.Uint16(videoBuffer[offset : offset+2])
offset += 2
if videoBuffer[offset] != spsId {
fmt.Println("videoBuffer does not have spsId, this would be a failure")
// panic("Failed to parse SPS")
return
}
sps = append(sps, annexBPrefix...)
sps = append(sps, videoBuffer[offset:offset+int(spsLen)]...)
offset += int(spsLen)
}
ppsCount := videoBuffer[offset]
offset++
for i := 0; i < int(ppsCount); i++ {
ppsLen := binary.BigEndian.Uint16(videoBuffer[offset : offset+2])
offset += 2
if videoBuffer[offset] != ppsId {
fmt.Println("videoBuffer does not have ppsId, this would be a failure")
// panic("Failed to parse PPS")
return
}
sps = append(sps, annexBPrefix...)
sps = append(sps, videoBuffer[offset:offset+int(ppsLen)]...)
offset += int(ppsLen)
}
return
}
// We have an unadorned keyframe, append SPS/PPS
if video.FrameType == flvtag.FrameTypeKeyFrame && !hasSpsPps {
fmt.Println("Appending sps and pps")
outBuf = append(append(sps, pps...), outBuf...)
}
return sps, pps, outBuf
}
func appendNALHeader(video flvtag.VideoData, videoBuffer []byte) (outbuf []byte) {
var outBuf []byte
for offset := 0; offset < len(videoBuffer); {
bufferLength := int(binary.BigEndian.Uint32(videoBuffer[offset : offset+headerLengthField]))
if offset+bufferLength >= len(videoBuffer) {
break
}
offset += headerLengthField
outBuf = append(outBuf, []byte{0x00, 0x00, 0x00, 0x01}...)
outBuf = append(outBuf, videoBuffer[offset:offset+bufferLength]...)
offset += bufferLength
}
return outBuf
}