Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
acbe99cb
Commit
acbe99cb
authored
Oct 12, 2021
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
整理优化webrtc ssrc与simulcast相关代码
parent
fbc53780
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
80 行增加
和
44 行删除
+80
-44
webrtc/Sdp.cpp
+76
-41
webrtc/Sdp.h
+2
-0
webrtc/WebRtcTransport.cpp
+2
-3
没有找到文件。
webrtc/Sdp.cpp
查看文件 @
acbe99cb
...
...
@@ -870,57 +870,72 @@ void RtcSession::loadFrom(const string &str, bool check) {
}
auto
ssrc_groups
=
media
.
getAllItem
<
SdpAttrSSRCGroup
>
(
'a'
,
"ssrc-group"
);
bool
have_rtx_ssrc
=
false
;
SdpAttrSSRCGroup
*
ssrc_group_sim
=
nullptr
;
SdpAttrSSRCGroup
*
ssrc_group_fid
=
nullptr
;
for
(
auto
&
group
:
ssrc_groups
)
{
if
(
group
.
isFID
())
{
ssrc_group_fid
=
&
group
;
have_rtx_ssrc
=
true
;
//ssrc-group:FID字段必须包含rtp/rtx的ssrc
CHECK
(
group
.
ssrcs
.
size
()
==
2
);
//根据rtp ssrc找到对象
auto
it
=
rtc_ssrc_map
.
find
(
group
.
ssrcs
[
0
]);
CHECK
(
it
!=
rtc_ssrc_map
.
end
());
//设置rtx ssrc
it
->
second
.
rtx_ssrc
=
group
.
ssrcs
[
1
];
rtc_media
.
rtp_rtx_ssrc
.
emplace_back
(
it
->
second
);
}
else
if
(
group
.
isSIM
())
{
CHECK
(
!
ssrc_group_sim
);
ssrc_group_sim
=
&
group
;
}
}
if
(
ssrc_group_fid
)
{
//指定了ssrc-group:FID字段
for
(
auto
ssrc
:
ssrc_group_fid
->
ssrcs
)
{
auto
it
=
rtc_ssrc_map
.
find
(
ssrc
);
if
(
it
==
rtc_ssrc_map
.
end
())
{
throw
std
::
invalid_argument
(
"a=ssrc-group:FID字段指定的ssrc未找到"
);
if
(
!
have_rtx_ssrc
)
{
//按照sdp顺序依次添加ssrc
for
(
auto
&
attr
:
ssrc_attr
)
{
if
(
attr
.
attribute
==
"cname"
)
{
rtc_media
.
rtp_rtx_ssrc
.
emplace_back
(
rtc_ssrc_map
[
attr
.
ssrc
]);
}
rtc_media
.
rtp_rtx_ssrc
.
emplace_back
(
it
->
second
);
}
CHECK
(
rtc_media
.
rtp_rtx_ssrc
.
size
()
==
2
);
}
else
{
}
auto
simulcast
=
media
.
getItemClass
<
SdpAttrSimulcast
>
(
'a'
,
"simulcast"
);
if
(
simulcast
.
empty
())
{
//没有指定ssrc-group:FID字段,也不是simulcast,那么只有1个或0个ssrc
if
(
rtc_ssrc_map
.
size
()
==
1
)
{
rtc_media
.
rtp_rtx_ssrc
.
emplace_back
(
rtc_ssrc_map
.
begin
()
->
second
);
}
else
if
(
rtc_ssrc_map
.
size
()
>
1
)
{
throw
std
::
invalid_argument
(
"sdp中不存在a=ssrc-group:FID字段,但是ssrc却大于1个"
);
if
(
!
simulcast
.
empty
())
{
// a=rid:h send
// a=rid:m send
// a=rid:l send
// a=simulcast:send h;m;l
// 风格的simulcast
unordered_set
<
string
>
rid_map
;
for
(
auto
&
rid
:
simulcast
.
rids
)
{
rid_map
.
emplace
(
rid
);
}
for
(
auto
&
rid
:
media
.
getAllItem
<
SdpAttrRid
>
(
'a'
,
"rid"
))
{
CHECK
(
rid
.
direction
==
simulcast
.
direction
);
CHECK
(
rid_map
.
find
(
rid
.
rid
)
!=
rid_map
.
end
());
}
}
else
{
//开启simulcast
rtc_media
.
rtp_rids
=
simulcast
.
rids
;
//simulcast最少要求2种方案
CHECK
(
rtc_media
.
rtp_
rids
.
size
()
>=
2
);
}
CHECK
(
simulcast
.
rids
.
size
()
>=
2
);
rtc_media
.
rtp_rids
=
simulcast
.
rids
;
}
if
(
ssrc_group_sim
)
{
//指定了a=ssrc-group:SIM
for
(
auto
ssrc
:
ssrc_group_sim
->
ssrcs
)
{
auto
it
=
rtc_ssrc_map
.
find
(
ssrc
);
if
(
it
==
rtc_ssrc_map
.
end
())
{
throw
std
::
invalid_argument
(
"a=ssrc-group:SIM字段指定的ssrc未找到"
);
}
CHECK
(
it
!=
rtc_ssrc_map
.
end
());
rtc_media
.
rtp_ssrc_sim
.
emplace_back
(
it
->
second
);
}
}
else
if
(
!
rtc_media
.
rtp_rids
.
empty
())
{
//未指定a=ssrc-group:SIM,但是指定了a=simulcast,且可能指定了ssrc
for
(
auto
&
attr
:
ssrc_attr
)
{
rtc_media
.
rtp_ssrc_sim
.
emplace_back
(
rtc_ssrc_map
[
attr
.
ssrc
]);
//未指定a=ssrc-group:SIM, 但是指定了a=simulcast, 那么只能根据ssrc顺序来对应rid顺序
rtc_media
.
rtp_ssrc_sim
=
rtc_media
.
rtp_rtx_ssrc
;
}
if
(
!
rtc_media
.
supportSimulcast
())
{
//不支持simulcast的情况下,最多一组ssrc
CHECK
(
rtc_media
.
rtp_rtx_ssrc
.
size
()
<=
1
);
}
else
{
//simulcast的情况下,要么没有指定ssrc,要么指定的ssrc个数与rid个数一致
CHECK
(
rtc_media
.
rtp_ssrc_sim
.
empty
()
||
rtc_media
.
rtp_ssrc_sim
.
size
()
==
rtc_media
.
rtp_rids
.
size
());
}
auto
rtpmap_arr
=
media
.
getAllItem
<
SdpAttrRtpMap
>
(
'a'
,
"rtpmap"
);
...
...
@@ -1161,8 +1176,10 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
static
auto
addSSRCItem
=
[](
const
RtcSSRC
&
rtp_ssrc
,
vector
<
SdpItem
::
Ptr
>
&
items
)
{
CHECK
(
!
rtp_ssrc
.
empty
());
auto
ssrc_num
=
rtp_ssrc
.
ssrc
;
for
(
auto
i
=
0
;
i
<
2
;
++
i
)
{
SdpAttrSSRC
ssrc
;
ssrc
.
ssrc
=
rtp_ssrc
.
ssrc
;
ssrc
.
ssrc
=
ssrc_num
;
ssrc
.
attribute
=
"cname"
;
ssrc
.
attribute_value
=
rtp_ssrc
.
cname
;
...
...
@@ -1185,29 +1202,38 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
ssrc
.
attribute_value
=
rtp_ssrc
.
label
;
items
.
emplace_back
(
wrapSdpAttr
(
std
::
make_shared
<
SdpAttrSSRC
>
(
ssrc
)));
}
if
(
rtp_ssrc
.
rtx_ssrc
)
{
ssrc_num
=
rtp_ssrc
.
rtx_ssrc
;
}
else
{
break
;
}
}
};
{
auto
group
=
std
::
make_shared
<
SdpAttrSSRCGroup
>
();
for
(
auto
&
ssrc
:
m
.
rtp_rtx_ssrc
)
{
//添加a=ssrc字段
addSSRCItem
(
ssrc
,
sdp_media
.
items
);
group
->
ssrcs
.
emplace_back
(
ssrc
.
ssrc
);
}
if
(
group
->
ssrcs
.
size
()
>=
2
)
{
group
->
type
=
"FID"
;
for
(
auto
&
ssrc
:
m
.
rtp_rtx_ssrc
)
{
//生成a=ssrc-group:FID字段
if
(
ssrc
.
rtx_ssrc
)
{
//有rtx ssrc
auto
group
=
std
::
make_shared
<
SdpAttrSSRCGroup
>
();
group
->
type
=
"FID"
;
group
->
ssrcs
.
emplace_back
(
ssrc
.
ssrc
);
group
->
ssrcs
.
emplace_back
(
ssrc
.
rtx_ssrc
);
sdp_media
.
items
.
emplace_back
(
wrapSdpAttr
(
std
::
move
(
group
)));
}
}
}
{
if
(
m
.
rtp_ssrc_sim
.
size
()
>=
2
)
{
//simulcast 要求 2~3路
auto
group
=
std
::
make_shared
<
SdpAttrSSRCGroup
>
();
for
(
auto
&
ssrc
:
m
.
rtp_ssrc_sim
)
{
//添加simulcast的ssrc
addSSRCItem
(
ssrc
,
sdp_media
.
items
);
group
->
ssrcs
.
emplace_back
(
ssrc
.
ssrc
);
}
//添加a=ssrc-group:SIM字段
...
...
@@ -1294,12 +1320,22 @@ uint32_t RtcMedia::getRtpSSRC() const {
}
uint32_t
RtcMedia
::
getRtxSSRC
()
const
{
if
(
rtp_rtx_ssrc
.
size
()
>
1
)
{
return
rtp_rtx_ssrc
[
1
].
ssrc
;
if
(
rtp_rtx_ssrc
.
size
())
{
return
rtp_rtx_ssrc
[
0
].
rtx_
ssrc
;
}
return
0
;
}
bool
RtcMedia
::
supportSimulcast
()
const
{
if
(
!
rtp_rids
.
empty
())
{
return
true
;
}
if
(
!
rtp_ssrc_sim
.
empty
())
{
return
true
;
}
return
false
;
}
void
RtcMedia
::
checkValid
()
const
{
CHECK
(
type
!=
TrackInvalid
);
CHECK
(
!
mid
.
empty
());
...
...
@@ -1372,15 +1408,13 @@ bool RtcSession::supportRtcpFb(const string &name, TrackType type) const {
bool
RtcSession
::
supportSimulcast
()
const
{
for
(
auto
&
m
:
media
)
{
if
(
!
m
.
rtp_rids
.
empty
())
{
return
true
;
}
if
(
!
m
.
rtp_ssrc_sim
.
empty
())
{
if
(
m
.
supportSimulcast
())
{
return
true
;
}
}
return
false
;
}
void
RtcSession
::
checkSdp
()
const
{
for
(
auto
&
m
:
media
)
{
if
(
m
.
type
!=
TrackApplication
&&
!
m
.
rtcp_mux
)
{
...
...
@@ -1636,6 +1670,7 @@ RETRY:
answer_media
.
candidate
=
configure
.
candidate
;
answer_media
.
rtp_rids
=
offer_media
.
rtp_rids
;
answer_media
.
rtp_ssrc_sim
=
offer_media
.
rtp_ssrc_sim
;
answer_media
.
rtp_rtx_ssrc
=
offer_media
.
rtp_rtx_ssrc
;
switch
(
offer_media
.
role
)
{
case
DtlsRole
:
:
actpass
:
case
DtlsRole
:
:
active
:
{
...
...
webrtc/Sdp.h
查看文件 @
acbe99cb
...
...
@@ -573,6 +573,7 @@ public:
class
RtcSSRC
{
public
:
uint32_t
ssrc
{
0
};
uint32_t
rtx_ssrc
{
0
};
string
cname
;
string
msid
;
string
mslabel
;
...
...
@@ -647,6 +648,7 @@ public:
const
RtcCodecPlan
*
getRelatedRtxPlan
(
uint8_t
pt
)
const
;
uint32_t
getRtpSSRC
()
const
;
uint32_t
getRtxSSRC
()
const
;
bool
supportSimulcast
()
const
;
};
class
RtcSession
{
...
...
webrtc/WebRtcTransport.cpp
查看文件 @
acbe99cb
...
...
@@ -539,9 +539,8 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
m
.
rtp_rtx_ssrc
[
0
].
msid
=
RTP_MSID
;
if
(
m
.
getRelatedRtxPlan
(
m
.
plan
[
0
].
pt
))
{
m
.
rtp_rtx_ssrc
.
emplace_back
();
m
.
rtp_rtx_ssrc
[
1
]
=
m
.
rtp_rtx_ssrc
[
0
];
m
.
rtp_rtx_ssrc
[
1
].
ssrc
+=
RTX_SSRC_OFFSET
;
//rtx ssrc
m
.
rtp_rtx_ssrc
[
0
].
rtx_ssrc
=
m
.
rtp_rtx_ssrc
[
0
].
ssrc
+
RTX_SSRC_OFFSET
;
}
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论