@@ -40,16 +40,19 @@ type CompleteMessageCB func(stream *Stream) error
40
40
// @param cb 回调结束后,内存块会被 ChunkComposer 再次使用
41
41
func (c * ChunkComposer ) RunLoop (reader io.Reader , cb CompleteMessageCB ) error {
42
42
bootstrap := make ([]byte , 11 )
43
+ absTsFlag := false
43
44
44
45
for {
46
+ // 5.3.1.1. Chunk Basic Header
47
+ // 读取fmt和csid
45
48
if _ , err := io .ReadAtLeast (reader , bootstrap [:1 ], 1 ); err != nil {
46
49
return err
47
50
}
48
51
49
- // 5.3.1.1. Chunk Basic Header
50
52
fmt := (bootstrap [0 ] >> 6 ) & 0x03
51
53
csid := int (bootstrap [0 ] & 0x3f )
52
54
55
+ // csid可能是变长的
53
56
switch csid {
54
57
case 0 :
55
58
if _ , err := io .ReadAtLeast (reader , bootstrap [:1 ], 1 ); err != nil {
@@ -68,6 +71,7 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
68
71
stream := c .getOrCreateStream (csid )
69
72
70
73
// 5.3.1.2. Chunk Message Header
74
+ // 当前chunk的fmt不同,Message Header包含的字段也不同,是变长
71
75
switch fmt {
72
76
case 0 :
73
77
if _ , err := io .ReadAtLeast (reader , bootstrap [:11 ], 11 ); err != nil {
@@ -76,6 +80,7 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
76
80
// 包头中为绝对时间戳
77
81
stream .header .Timestamp = bele .BEUint24 (bootstrap )
78
82
stream .header .TimestampAbs = stream .header .Timestamp
83
+ absTsFlag = true
79
84
stream .header .MsgLen = bele .BEUint24 (bootstrap [3 :])
80
85
stream .header .MsgTypeID = bootstrap [6 ]
81
86
stream .header .MsgStreamID = int (bele .LEUint32 (bootstrap [7 :]))
@@ -87,7 +92,7 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
87
92
}
88
93
// 包头中为相对时间戳
89
94
stream .header .Timestamp = bele .BEUint24 (bootstrap )
90
- stream .header .TimestampAbs += stream .header .Timestamp
95
+ // stream.header.TimestampAbs += stream.header.Timestamp
91
96
stream .header .MsgLen = bele .BEUint24 (bootstrap [3 :])
92
97
stream .header .MsgTypeID = bootstrap [6 ]
93
98
@@ -98,7 +103,7 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
98
103
}
99
104
// 包头中为相对时间戳
100
105
stream .header .Timestamp = bele .BEUint24 (bootstrap )
101
- stream .header .TimestampAbs += stream .header .Timestamp
106
+ // stream.header.TimestampAbs += stream.header.Timestamp
102
107
103
108
case 3 :
104
109
// noop
@@ -107,7 +112,9 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
107
112
// 5.3.1.3 Extended Timestamp
108
113
// 使用ffmpeg推流时,发现时间戳超过3字节最大值后,即使是fmt3(即包头大小为0),依然存在ext ts字段
109
114
// 所以这里我将 `==` 的判断改成了 `>=`
110
- // TODO chef: 测试其他客户端和ext ts相关的表现
115
+ // TODO chef:
116
+ // - 测试其他客户端和ext ts相关的表现
117
+ // - 这部分可能还有问题,需要根据具体的case调整
111
118
//if stream.header.Timestamp == maxTimestampInMessageHeader {
112
119
if stream .header .Timestamp >= maxTimestampInMessageHeader {
113
120
if _ , err := io .ReadAtLeast (reader , bootstrap [:4 ], 4 ); err != nil {
@@ -126,7 +133,7 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
126
133
}
127
134
}
128
135
//stream.header.CSID = csid
129
- //log .Debugf("CHEFGREPME tag1 fmt:%d header:%+v csid:%d len:%d ts:%d", fmt, stream.header, csid, stream.header.MsgLen, stream.header.TimestampAbs)
136
+ //nazalog .Debugf("ChunkComposer chunk fmt:%d header:%+v csid:%d len:%d ts:%d", fmt, stream.header, csid, stream.header.MsgLen, stream.header.TimestampAbs)
130
137
131
138
var neededSize uint32
132
139
if stream .header .MsgLen <= c .peerChunkSize {
@@ -152,6 +159,13 @@ func (c *ChunkComposer) RunLoop(reader io.Reader, cb CompleteMessageCB) error {
152
159
}
153
160
154
161
stream .header .CSID = csid
162
+ if ! absTsFlag {
163
+ // 这么处理相当于取最后一个chunk的时间戳差值,有的协议栈是取的第一个,正常来说都可以
164
+ stream .header .TimestampAbs += stream .header .Timestamp
165
+ }
166
+ absTsFlag = false
167
+ //nazalog.Debugf("ChunkComposer message fmt:%d header:%+v csid:%d len:%d ts:%d", fmt, stream.header, csid, stream.header.MsgLen, stream.header.TimestampAbs)
168
+
155
169
if err := cb (stream ); err != nil {
156
170
return err
157
171
}
@@ -171,3 +185,14 @@ func (c *ChunkComposer) getOrCreateStream(csid int) *Stream {
171
185
}
172
186
return stream
173
187
}
188
+
189
+ // 临时存放一些rtmp推流case在这,便于理解,以及修改后,回归用
190
+ //
191
+ // 场景:ffmpeg推送test.flv至lals
192
+ // 关注点:message超过chunk时,fmt和timestamp的值
193
+ //
194
+ // ChunkComposer chunk fmt:1 header:{CSID:6 MsgLen:143 Timestamp:40 MsgTypeID:9 MsgStreamID:1 TimestampAbs:520} csid:6 len:143 ts:520
195
+ // ChunkComposer chunk fmt:1 header:{CSID:6 MsgLen:4511 Timestamp:40 MsgTypeID:9 MsgStreamID:1 TimestampAbs:560} csid:6 len:4511 ts:560
196
+ // ChunkComposer chunk fmt:3 header:{CSID:6 MsgLen:4511 Timestamp:40 MsgTypeID:9 MsgStreamID:1 TimestampAbs:560} csid:6 len:4511 ts:560
197
+ // 此处应只给上层返回一次,也即一个message,时间戳应该是560
198
+ // ChunkComposer chunk fmt:1 header:{CSID:6 MsgLen:904 Timestamp:40 MsgTypeID:9 MsgStreamID:1 TimestampAbs:600} csid:6 len:904 ts:600
0 commit comments