Skip to content

Commit 06c13d1

Browse files
committed
[patch] 重构前次提交,去掉LazyRtmpChunkDivider和LazyRtmpMsg2FlvTag的写法 #201
1 parent 8b3c65d commit 06c13d1

File tree

7 files changed

+183
-142
lines changed

7 files changed

+183
-142
lines changed

pkg/gb28181/gb28181.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ import (
1313
"github.com/q191201771/naza/pkg/nazalog"
1414
)
1515

16-
// TODO(chef): gb28181 package处于开发中阶段,请不使用
17-
// TODO(chef): [opt] rtp排序 202206
16+
// TODO(chef): [feat] http api start_rtp_pub 202207
17+
// TODO(chef): [feat] http api stop_rtp_pub 202207
18+
// TODO(chef): [feat] http api /api/stat/all_rtp_pub,不过这个可以用已有的all_group代替 202207
19+
// TODO(chef): [feat] pub接入group 202207
20+
// TODO(chef): [feat] 超时自动关闭 202207
1821
// TODO(chef): [test] 保存rtp数据,用于回放分析 202206
1922
// TODO(chef): [perf] 优化ps解析,内存块 202207
2023

pkg/logic/group__core_streaming.go

+60-24
Original file line numberDiff line numberDiff line change
@@ -151,23 +151,63 @@ func (group *Group) OnFragmentOpen() {
151151
// @param msg 调用结束后,内部不持有msg.Payload内存块
152152
//
153153
func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
154-
// TODO(chef): [refactor] 依赖lazy的out越来越多,可以考虑去掉lazy,将lazy逻辑直接写在开头处,比如if x != nil || len(y) > 0 202207
155-
156-
var (
157-
lcd remux.LazyRtmpChunkDivider
158-
lrm2ft remux.LazyRtmpMsg2FlvTag
159-
)
154+
if msg.Header.MsgLen != uint32(len(msg.Payload)) {
155+
Log.Errorf("[%s] diff. msgLen=%d, payload len=%d, %+v", group.UniqueKey, msg.Header.MsgLen, len(msg.Payload), msg.Header)
156+
}
160157

161158
if msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
162159
m, err := rtmp.ParseMetadata(msg.Payload)
163160
nazalog.Debugf("[%s] metadata. err=%+v, len=%d, value=%s", group.UniqueKey, err, len(m), m.DebugString())
164161
}
165162

163+
var (
164+
rtmpChunks4Sub []byte
165+
rtmpChunks4Push []byte
166+
167+
flv4Sub []byte
168+
)
169+
170+
needRtmp := len(group.rtmpSubSessionSet) != 0 ||
171+
group.config.RelayPushConfig.Enable ||
172+
(group.config.RtmpConfig.Enable && group.config.RtmpConfig.GopNum > 0)
173+
174+
needFlv := len(group.httpflvSubSessionSet) != 0 ||
175+
(group.config.HttpflvConfig.Enable && group.config.HttpflvConfig.GopNum > 0) ||
176+
group.config.RecordConfig.EnableFlv
177+
178+
// 目的有两个:1 rtmp按需切片 2 处理metadata的@setDataFrame
179+
if needRtmp {
180+
// 设置好用于发送的 rtmp 头部信息
181+
currHeader := remux.MakeDefaultRtmpHeader(msg.Header)
182+
183+
if msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
184+
metadataWithOutSDF, _ := rtmp.MetadataEnsureWithoutSetDataFrame(msg.Clone().Payload)
185+
rtmpChunks4Sub = rtmp.Message2Chunks(metadataWithOutSDF, &currHeader)
186+
187+
metadataWithSDF, _ := rtmp.MetadataEnsureWithSetDataFrame(msg.Clone().Payload)
188+
rtmpChunks4Push = rtmp.Message2Chunks(metadataWithSDF, &currHeader)
189+
} else {
190+
rtmpChunks4Sub = rtmp.Message2Chunks(msg.Payload, &currHeader)
191+
rtmpChunks4Push = rtmpChunks4Sub
192+
}
193+
}
194+
195+
if needFlv {
196+
if msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
197+
msg2 := msg.Clone()
198+
msg2.Payload, _ = rtmp.MetadataEnsureWithoutSetDataFrame(msg2.Payload)
199+
flv4Sub = remux.RtmpMsg2FlvTag(msg2).Raw
200+
} else {
201+
flv4Sub = remux.RtmpMsg2FlvTag(msg).Raw
202+
}
203+
}
204+
166205
// # 数据有效性检查
167206
if len(msg.Payload) == 0 {
168207
Log.Warnf("[%s] msg payload length is 0. %+v", group.UniqueKey, msg.Header)
169208
return
170209
}
210+
171211
// TODO(chef): 暂时不打开,因为过滤掉了innertest中rtmp和flv的输出和输入就不完全相同了
172212
//if msg.Header.MsgTypeId == base.RtmpTypeIdAudio {
173213
// if len(msg.Payload) <= 2 {
@@ -203,16 +243,6 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
203243
group.rtmp2RtspRemuxer.FeedRtmpMsg(msg)
204244
}
205245

206-
// # 设置好用于发送的 rtmp 头部信息
207-
currHeader := remux.MakeDefaultRtmpHeader(msg.Header)
208-
if currHeader.MsgLen != uint32(len(msg.Payload)) {
209-
Log.Errorf("[%s] diff. msgLen=%d, payload len=%d, %+v", group.UniqueKey, currHeader.MsgLen, len(msg.Payload), msg.Header)
210-
}
211-
212-
// # 懒初始化rtmp chunk切片,以及httpflv转换
213-
lcd.Init(msg.Payload, &currHeader)
214-
lrm2ft.Init(msg)
215-
216246
// # 广播。遍历所有 rtmp sub session,转发数据
217247
// ## 如果是新的 sub session,发送已缓存的信息
218248
for session := range group.rtmpSubSessionSet {
@@ -268,9 +298,9 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
268298
// ## 转发本次数据
269299
if len(group.rtmpSubSessionSet) > 0 {
270300
if group.rtmpMergeWriter == nil {
271-
group.write2RtmpSubSessions(lcd.GetEnsureWithoutSetDataFrame())
301+
group.write2RtmpSubSessions(rtmpChunks4Sub)
272302
} else {
273-
group.rtmpMergeWriter.Write(lcd.GetEnsureWithoutSetDataFrame())
303+
group.rtmpMergeWriter.Write(rtmpChunks4Sub)
274304
}
275305
}
276306

@@ -300,7 +330,7 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
300330
v.pushSession.IsFresh = false
301331
}
302332

303-
_ = v.pushSession.Write(lcd.GetEnsureWithSetDataFrame())
333+
_ = v.pushSession.Write(rtmpChunks4Push)
304334
}
305335
}
306336

@@ -333,27 +363,33 @@ func (group *Group) broadcastByRtmpMsg(msg base.RtmpMsg) {
333363
// 是否在等待关键帧
334364
if session.ShouldWaitVideoKeyFrame {
335365
if msg.IsVideoKeyNalu() {
336-
session.Write(lrm2ft.GetEnsureWithoutSetDataFrame())
366+
session.Write(flv4Sub)
337367
session.ShouldWaitVideoKeyFrame = false
338368
}
339369
} else {
340-
session.Write(lrm2ft.GetEnsureWithoutSetDataFrame())
370+
session.Write(flv4Sub)
341371
}
342372
}
343373

344374
// # 录制flv文件
345375
if group.recordFlv != nil {
346-
if err := group.recordFlv.WriteRaw(lrm2ft.GetEnsureWithoutSetDataFrame()); err != nil {
376+
if err := group.recordFlv.WriteRaw(flv4Sub); err != nil {
347377
Log.Errorf("[%s] record flv write error. err=%+v", group.UniqueKey, err)
348378
}
349379
}
350380

351381
// # 缓存关键信息,以及gop
352382
if group.config.RtmpConfig.Enable {
353-
group.rtmpGopCache.Feed(msg, lcd.GetEnsureWithSetDataFrame, lcd.GetEnsureWithoutSetDataFrame)
383+
group.rtmpGopCache.Feed(msg, rtmpChunks4Sub)
384+
if msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
385+
group.rtmpGopCache.SetMetadata(rtmpChunks4Push, rtmpChunks4Sub)
386+
}
354387
}
355388
if group.config.HttpflvConfig.Enable {
356-
group.httpflvGopCache.Feed(msg, lrm2ft.GetEnsureWithSetDataFrame, lrm2ft.GetEnsureWithoutSetDataFrame)
389+
group.httpflvGopCache.Feed(msg, flv4Sub)
390+
if msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
391+
group.httpflvGopCache.SetMetadata(flv4Sub, flv4Sub)
392+
}
357393
}
358394

359395
// # 记录stat

pkg/remux/gop_cache.go

+14-8
Original file line numberDiff line numberDiff line change
@@ -87,38 +87,44 @@ func NewGopCache(t string, uniqueKey string, gopNum int) *GopCache {
8787

8888
type LazyGet func() []byte
8989

90+
func (gc *GopCache) SetMetadata(w []byte, wo []byte) {
91+
// TODO(chef): [refactor] 将metadata等缓存逻辑从GopCache中移除 202207
92+
93+
gc.MetadataEnsureWithSetDataFrame = w
94+
gc.MetadataEnsureWithoutSetDataFrame = wo
95+
Log.Debugf("[%s] cache %s metadata. size:%d", gc.uniqueKey, gc.t, len(gc.MetadataEnsureWithSetDataFrame))
96+
}
97+
9098
// Feed
9199
//
92100
// @param lg: 内部可能持有lg返回的内存块
93101
//
94-
func (gc *GopCache) Feed(msg base.RtmpMsg, lg LazyGet, lg2 LazyGet) {
102+
func (gc *GopCache) Feed(msg base.RtmpMsg, b []byte) {
95103
// TODO(chef): [refactor] 重构lg两个参数这种方式 202207
96104

97105
switch msg.Header.MsgTypeId {
98106
case base.RtmpTypeIdMetadata:
99-
gc.MetadataEnsureWithSetDataFrame = lg()
100-
gc.MetadataEnsureWithoutSetDataFrame = lg()
101-
Log.Debugf("[%s] cache %s metadata. size:%d", gc.uniqueKey, gc.t, len(gc.MetadataEnsureWithSetDataFrame))
107+
// noop
102108
return
103109
case base.RtmpTypeIdAudio:
104110
if msg.IsAacSeqHeader() {
105-
gc.AacSeqHeader = lg()
111+
gc.AacSeqHeader = b
106112
Log.Debugf("[%s] cache %s aac seq header. size:%d", gc.uniqueKey, gc.t, len(gc.AacSeqHeader))
107113
return
108114
}
109115
case base.RtmpTypeIdVideo:
110116
if msg.IsVideoKeySeqHeader() {
111-
gc.VideoSeqHeader = lg()
117+
gc.VideoSeqHeader = b
112118
Log.Debugf("[%s] cache %s video seq header. size:%d", gc.uniqueKey, gc.t, len(gc.VideoSeqHeader))
113119
return
114120
}
115121
}
116122

117123
if gc.gopSize > 1 {
118124
if msg.IsVideoKeyNalu() {
119-
gc.feedNewGop(msg, lg())
125+
gc.feedNewGop(msg, b)
120126
} else {
121-
gc.feedLastGop(msg, lg())
127+
gc.feedLastGop(msg, b)
122128
}
123129
}
124130
}

pkg/remux/gop_cache_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -66,52 +66,52 @@ func TestGopCache_Feed(t *testing.T) {
6666
assert.Equal(t, nil, nc.GetGopDataAt(2))
6767
assert.Equal(t, nil, nc.GetGopDataAt(3))
6868

69-
nc.Feed(i1, i1f, i1f)
69+
nc.Feed(i1, i1f())
7070
assert.Equal(t, 1, nc.GetGopCount())
7171
assert.Equal(t, [][]byte{{1, 1}}, nc.GetGopDataAt(0))
7272
assert.Equal(t, nil, nc.GetGopDataAt(1))
7373
assert.Equal(t, nil, nc.GetGopDataAt(2))
7474
assert.Equal(t, nil, nc.GetGopDataAt(3))
75-
nc.Feed(p1, p1f, p1f)
75+
nc.Feed(p1, p1f())
7676
assert.Equal(t, 1, nc.GetGopCount())
7777
assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
7878
assert.Equal(t, nil, nc.GetGopDataAt(1))
7979
assert.Equal(t, nil, nc.GetGopDataAt(2))
8080
assert.Equal(t, nil, nc.GetGopDataAt(3))
8181

82-
nc.Feed(i2, i2f, i2f)
82+
nc.Feed(i2, i2f())
8383
assert.Equal(t, 2, nc.GetGopCount())
8484
assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
8585
assert.Equal(t, [][]byte{{1, 2}}, nc.GetGopDataAt(1))
8686
assert.Equal(t, nil, nc.GetGopDataAt(2))
8787
assert.Equal(t, nil, nc.GetGopDataAt(3))
88-
nc.Feed(p2, p2f, p2f)
88+
nc.Feed(p2, p2f())
8989
assert.Equal(t, 2, nc.GetGopCount())
9090
assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
9191
assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
9292
assert.Equal(t, nil, nc.GetGopDataAt(2))
9393
assert.Equal(t, nil, nc.GetGopDataAt(3))
9494

95-
nc.Feed(i3, i3f, i3f)
95+
nc.Feed(i3, i3f())
9696
assert.Equal(t, 3, nc.GetGopCount())
9797
assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
9898
assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
9999
assert.Equal(t, [][]byte{{1, 3}}, nc.GetGopDataAt(2))
100100
assert.Equal(t, nil, nc.GetGopDataAt(3))
101-
nc.Feed(p3, p3f, p3f)
101+
nc.Feed(p3, p3f())
102102
assert.Equal(t, 3, nc.GetGopCount())
103103
assert.Equal(t, [][]byte{{1, 1}, {0, 1}}, nc.GetGopDataAt(0))
104104
assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(1))
105105
assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(2))
106106
assert.Equal(t, nil, nc.GetGopDataAt(3))
107107

108-
nc.Feed(i4, i4f, i4f)
108+
nc.Feed(i4, i4f())
109109
assert.Equal(t, 3, nc.GetGopCount())
110110
assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(0))
111111
assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(1))
112112
assert.Equal(t, [][]byte{{1, 4}}, nc.GetGopDataAt(2))
113113
assert.Equal(t, nil, nc.GetGopDataAt(3))
114-
nc.Feed(p4, p4f, p4f)
114+
nc.Feed(p4, p4f())
115115
assert.Equal(t, 3, nc.GetGopCount())
116116
assert.Equal(t, [][]byte{{1, 2}, {0, 2}}, nc.GetGopDataAt(0))
117117
assert.Equal(t, [][]byte{{1, 3}, {0, 3}}, nc.GetGopDataAt(1))

pkg/remux/rtmp.go

+56-57
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ package remux
1111
import (
1212
"github.com/q191201771/lal/pkg/base"
1313
"github.com/q191201771/lal/pkg/rtmp"
14-
"github.com/q191201771/naza/pkg/nazalog"
1514
)
1615

1716
// MakeDefaultRtmpHeader
@@ -36,60 +35,60 @@ func MakeDefaultRtmpHeader(in base.RtmpHeader) (out base.RtmpHeader) {
3635
return
3736
}
3837

39-
// ---------------------------------------------------------------------------------------------------------------------
40-
41-
// LazyRtmpChunkDivider 在必要时,有且仅有一次做切分成chunk的操作
38+
//// ---------------------------------------------------------------------------------------------------------------------
4239
//
43-
type LazyRtmpChunkDivider struct {
44-
message []byte
45-
header *base.RtmpHeader
46-
chunks []byte
47-
}
48-
49-
func (lcd *LazyRtmpChunkDivider) Init(message []byte, header *base.RtmpHeader) {
50-
lcd.message = message
51-
lcd.header = header
52-
}
53-
54-
func (lcd *LazyRtmpChunkDivider) GetOriginal() []byte {
55-
if lcd.chunks == nil {
56-
lcd.chunks = rtmp.Message2Chunks(lcd.message, lcd.header)
57-
}
58-
return lcd.chunks
59-
}
60-
61-
func (lcd *LazyRtmpChunkDivider) GetEnsureWithSetDataFrame() []byte {
62-
if lcd.chunks == nil {
63-
var msg []byte
64-
var err error
65-
if lcd.header.MsgTypeId == base.RtmpTypeIdMetadata {
66-
msg, err = rtmp.MetadataEnsureWithSetDataFrame(lcd.message)
67-
if err != nil {
68-
nazalog.Errorf("[%p] rtmp.MetadataEnsureWithSetDataFrame failed. error=%+v", lcd, err)
69-
msg = lcd.message
70-
}
71-
} else {
72-
msg = lcd.message
73-
}
74-
lcd.chunks = rtmp.Message2Chunks(msg, lcd.header)
75-
}
76-
return lcd.chunks
77-
}
78-
79-
func (lcd *LazyRtmpChunkDivider) GetEnsureWithoutSetDataFrame() []byte {
80-
if lcd.chunks == nil {
81-
var msg []byte
82-
var err error
83-
if lcd.header.MsgTypeId == base.RtmpTypeIdMetadata {
84-
msg, err = rtmp.MetadataEnsureWithoutSetDataFrame(lcd.message)
85-
if err != nil {
86-
nazalog.Errorf("[%p] rtmp.MetadataEnsureWithoutSetDataFrame failed. error=%+v", lcd, err)
87-
msg = lcd.message
88-
}
89-
} else {
90-
msg = lcd.message
91-
}
92-
lcd.chunks = rtmp.Message2Chunks(msg, lcd.header)
93-
}
94-
return lcd.chunks
95-
}
40+
//// LazyRtmpChunkDivider 在必要时,有且仅有一次做切分成chunk的操作
41+
////
42+
//type LazyRtmpChunkDivider struct {
43+
// message []byte
44+
// header *base.RtmpHeader
45+
// chunks []byte
46+
//}
47+
//
48+
//func (lcd *LazyRtmpChunkDivider) Init(message []byte, header *base.RtmpHeader) {
49+
// lcd.message = message
50+
// lcd.header = header
51+
//}
52+
//
53+
//func (lcd *LazyRtmpChunkDivider) GetOriginal() []byte {
54+
// if lcd.chunks == nil {
55+
// lcd.chunks = rtmp.Message2Chunks(lcd.message, lcd.header)
56+
// }
57+
// return lcd.chunks
58+
//}
59+
//
60+
//func (lcd *LazyRtmpChunkDivider) GetEnsureWithSetDataFrame() []byte {
61+
// if lcd.chunks == nil {
62+
// var msg []byte
63+
// var err error
64+
// if lcd.header.MsgTypeId == base.RtmpTypeIdMetadata {
65+
// msg, err = rtmp.MetadataEnsureWithSetDataFrame(lcd.message)
66+
// if err != nil {
67+
// nazalog.Errorf("[%p] rtmp.MetadataEnsureWithSetDataFrame failed. error=%+v", lcd, err)
68+
// msg = lcd.message
69+
// }
70+
// } else {
71+
// msg = lcd.message
72+
// }
73+
// lcd.chunks = rtmp.Message2Chunks(msg, lcd.header)
74+
// }
75+
// return lcd.chunks
76+
//}
77+
//
78+
//func (lcd *LazyRtmpChunkDivider) GetEnsureWithoutSetDataFrame() []byte {
79+
// if lcd.chunks == nil {
80+
// var msg []byte
81+
// var err error
82+
// if lcd.header.MsgTypeId == base.RtmpTypeIdMetadata {
83+
// msg, err = rtmp.MetadataEnsureWithoutSetDataFrame(lcd.message)
84+
// if err != nil {
85+
// nazalog.Errorf("[%p] rtmp.MetadataEnsureWithoutSetDataFrame failed. error=%+v", lcd, err)
86+
// msg = lcd.message
87+
// }
88+
// } else {
89+
// msg = lcd.message
90+
// }
91+
// lcd.chunks = rtmp.Message2Chunks(msg, lcd.header)
92+
// }
93+
// return lcd.chunks
94+
//}

0 commit comments

Comments
 (0)