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
cffc0743
Commit
cffc0743
authored
Jul 14, 2022
by
xiongguangjie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
format code use clang-format
parent
602b475a
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
1078 行增加
和
1049 行删除
+1078
-1049
src/Rtcp/Rtcp.cpp
+264
-264
src/Rtcp/Rtcp.h
+172
-177
src/Rtcp/RtcpContext.cpp
+79
-73
src/Rtcp/RtcpContext.h
+24
-25
src/Rtcp/RtcpFCI.cpp
+142
-136
src/Rtcp/RtcpFCI.h
+104
-103
webrtc/WebRtcTransport.cpp
+293
-271
没有找到文件。
src/Rtcp/Rtcp.cpp
查看文件 @
cffc0743
...
@@ -8,55 +8,67 @@
...
@@ -8,55 +8,67 @@
* may be found in the AUTHORS file in the root of the source tree.
* may be found in the AUTHORS file in the root of the source tree.
*/
*/
#include <stddef.h>
#include <assert.h>
#include "Rtcp.h"
#include "Rtcp.h"
#include "Util/logger.h"
#include "RtcpFCI.h"
#include "RtcpFCI.h"
#include "Util/logger.h"
#include <assert.h>
#include <stddef.h>
using
namespace
std
;
using
namespace
std
;
using
namespace
toolkit
;
using
namespace
toolkit
;
namespace
mediakit
{
namespace
mediakit
{
const
char
*
rtcpTypeToStr
(
RtcpType
type
){
const
char
*
rtcpTypeToStr
(
RtcpType
type
)
{
switch
(
type
){
switch
(
type
)
{
#define SWITCH_CASE(key, value) case RtcpType::key : return #value "(" #key ")";
#define SWITCH_CASE(key, value) \
case RtcpType::key: \
return #value "(" #key ")";
RTCP_PT_MAP
(
SWITCH_CASE
)
RTCP_PT_MAP
(
SWITCH_CASE
)
#undef SWITCH_CASE
#undef SWITCH_CASE
default
:
return
"unknown rtcp pt"
;
default
:
return
"unknown rtcp pt"
;
}
}
}
}
const
char
*
sdesTypeToStr
(
SdesType
type
){
const
char
*
sdesTypeToStr
(
SdesType
type
)
{
switch
(
type
){
switch
(
type
)
{
#define SWITCH_CASE(key, value) case SdesType::key : return #value "(" #key ")";
#define SWITCH_CASE(key, value) \
case SdesType::key: \
return #value "(" #key ")";
SDES_TYPE_MAP
(
SWITCH_CASE
)
SDES_TYPE_MAP
(
SWITCH_CASE
)
#undef SWITCH_CASE
#undef SWITCH_CASE
default
:
return
"unknown source description type"
;
default
:
return
"unknown source description type"
;
}
}
}
}
const
char
*
psfbTypeToStr
(
PSFBType
type
)
{
const
char
*
psfbTypeToStr
(
PSFBType
type
)
{
switch
(
type
){
switch
(
type
)
{
#define SWITCH_CASE(key, value) case PSFBType::key : return #value "(" #key ")";
#define SWITCH_CASE(key, value) \
case PSFBType::key: \
return #value "(" #key ")";
PSFB_TYPE_MAP
(
SWITCH_CASE
)
PSFB_TYPE_MAP
(
SWITCH_CASE
)
#undef SWITCH_CASE
#undef SWITCH_CASE
default
:
return
"unknown payload-specific fb message fmt type"
;
default
:
return
"unknown payload-specific fb message fmt type"
;
}
}
}
}
const
char
*
rtpfbTypeToStr
(
RTPFBType
type
)
{
const
char
*
rtpfbTypeToStr
(
RTPFBType
type
)
{
switch
(
type
){
switch
(
type
)
{
#define SWITCH_CASE(key, value) case RTPFBType::key : return #value "(" #key ")";
#define SWITCH_CASE(key, value) \
case RTPFBType::key: \
return #value "(" #key ")";
RTPFB_TYPE_MAP
(
SWITCH_CASE
)
RTPFB_TYPE_MAP
(
SWITCH_CASE
)
#undef SWITCH_CASE
#undef SWITCH_CASE
default
:
return
"unknown transport layer feedback messages fmt type"
;
default
:
return
"unknown transport layer feedback messages fmt type"
;
}
}
}
}
static
size_t
alignSize
(
size_t
bytes
)
{
static
size_t
alignSize
(
size_t
bytes
)
{
return
(
size_t
)
((
bytes
+
3
)
>>
2
)
<<
2
;
return
(
size_t
)((
bytes
+
3
)
>>
2
)
<<
2
;
}
}
static
void
setupHeader
(
RtcpHeader
*
rtcp
,
RtcpType
type
,
size_t
report_count
,
size_t
total_bytes
)
{
static
void
setupHeader
(
RtcpHeader
*
rtcp
,
RtcpType
type
,
size_t
report_count
,
size_t
total_bytes
)
{
...
@@ -65,16 +77,16 @@ static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, si
...
@@ -65,16 +77,16 @@ static void setupHeader(RtcpHeader *rtcp, RtcpType type, size_t report_count, si
if
(
report_count
>
0x1F
)
{
if
(
report_count
>
0x1F
)
{
throw
std
::
invalid_argument
(
StrPrinter
<<
"rtcp report_count最大赋值为31,当前为:"
<<
report_count
);
throw
std
::
invalid_argument
(
StrPrinter
<<
"rtcp report_count最大赋值为31,当前为:"
<<
report_count
);
}
}
//items总个数
//
items总个数
rtcp
->
report_count
=
report_count
;
rtcp
->
report_count
=
report_count
;
rtcp
->
pt
=
(
uint8_t
)
type
;
rtcp
->
pt
=
(
uint8_t
)
type
;
rtcp
->
setSize
(
total_bytes
);
rtcp
->
setSize
(
total_bytes
);
}
}
static
void
setupPadding
(
RtcpHeader
*
rtcp
,
size_t
padding_size
)
{
static
void
setupPadding
(
RtcpHeader
*
rtcp
,
size_t
padding_size
)
{
if
(
padding_size
)
{
if
(
padding_size
)
{
rtcp
->
padding
=
1
;
rtcp
->
padding
=
1
;
((
uint8_t
*
)
rtcp
)[
rtcp
->
getSize
()
-
1
]
=
padding_size
&
0xFF
;
((
uint8_t
*
)
rtcp
)[
rtcp
->
getSize
()
-
1
]
=
padding_size
&
0xFF
;
}
else
{
}
else
{
rtcp
->
padding
=
0
;
rtcp
->
padding
=
0
;
}
}
...
@@ -91,123 +103,125 @@ string RtcpHeader::dumpHeader() const {
...
@@ -91,123 +103,125 @@ string RtcpHeader::dumpHeader() const {
printer
<<
"padding:"
<<
padding
<<
"
\r\n
"
;
printer
<<
"padding:"
<<
padding
<<
"
\r\n
"
;
}
}
switch
((
RtcpType
)
pt
)
{
switch
((
RtcpType
)
pt
)
{
case
RtcpType
:
:
RTCP_RTPFB
:
{
case
RtcpType
:
:
RTCP_RTPFB
:
{
printer
<<
"report_count:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
"
\r\n
"
;
printer
<<
"report_count:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
"
\r\n
"
;
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_PSFB
:
{
case
RtcpType
:
:
RTCP_PSFB
:
{
printer
<<
"report_count:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
"
\r\n
"
;
printer
<<
"report_count:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
"
\r\n
"
;
break
;
break
;
}
}
default
:
{
default
:
{
printer
<<
"report_count:"
<<
report_count
<<
"
\r\n
"
;
printer
<<
"report_count:"
<<
report_count
<<
"
\r\n
"
;
break
;
break
;
}
}
}
}
printer
<<
"pt:"
<<
rtcpTypeToStr
((
RtcpType
)
pt
)
<<
"
\r\n
"
;
printer
<<
"pt:"
<<
rtcpTypeToStr
((
RtcpType
)
pt
)
<<
"
\r\n
"
;
printer
<<
"size:"
<<
getSize
()
<<
"
\r\n
"
;
printer
<<
"size:"
<<
getSize
()
<<
"
\r\n
"
;
printer
<<
"--------
\r\n
"
;
printer
<<
"--------
\r\n
"
;
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
string
RtcpHeader
::
dumpString
()
const
{
string
RtcpHeader
::
dumpString
()
const
{
switch
((
RtcpType
)
pt
)
{
switch
((
RtcpType
)
pt
)
{
case
RtcpType
:
:
RTCP_SR
:
{
case
RtcpType
:
:
RTCP_SR
:
{
RtcpSR
*
rtcp
=
(
RtcpSR
*
)
this
;
RtcpSR
*
rtcp
=
(
RtcpSR
*
)
this
;
return
rtcp
->
dumpString
();
return
rtcp
->
dumpString
();
}
}
case
RtcpType
:
:
RTCP_RR
:
{
case
RtcpType
:
:
RTCP_RR
:
{
RtcpRR
*
rtcp
=
(
RtcpRR
*
)
this
;
RtcpRR
*
rtcp
=
(
RtcpRR
*
)
this
;
return
rtcp
->
dumpString
();
return
rtcp
->
dumpString
();
}
}
case
RtcpType
:
:
RTCP_SDES
:
{
case
RtcpType
:
:
RTCP_SDES
:
{
RtcpSdes
*
rtcp
=
(
RtcpSdes
*
)
this
;
RtcpSdes
*
rtcp
=
(
RtcpSdes
*
)
this
;
return
rtcp
->
dumpString
();
return
rtcp
->
dumpString
();
}
}
case
RtcpType
:
:
RTCP_RTPFB
:
case
RtcpType
:
:
RTCP_RTPFB
:
case
RtcpType
:
:
RTCP_PSFB
:
{
case
RtcpType
:
:
RTCP_PSFB
:
{
RtcpFB
*
rtcp
=
(
RtcpFB
*
)
this
;
RtcpFB
*
rtcp
=
(
RtcpFB
*
)
this
;
return
rtcp
->
dumpString
();
return
rtcp
->
dumpString
();
}
}
case
RtcpType
:
:
RTCP_BYE
:
{
case
RtcpType
:
:
RTCP_BYE
:
{
RtcpBye
*
rtcp
=
(
RtcpBye
*
)
this
;
RtcpBye
*
rtcp
=
(
RtcpBye
*
)
this
;
return
rtcp
->
dumpString
();
return
rtcp
->
dumpString
();
}
}
default
:
return
StrPrinter
<<
dumpHeader
()
<<
hexdump
((
char
*
)
this
+
sizeof
(
*
this
),
getSize
()
-
sizeof
(
*
this
));
default
:
return
StrPrinter
<<
dumpHeader
()
<<
hexdump
((
char
*
)
this
+
sizeof
(
*
this
),
getSize
()
-
sizeof
(
*
this
));
}
}
}
}
size_t
RtcpHeader
::
getSize
()
const
{
size_t
RtcpHeader
::
getSize
()
const
{
//加上rtcp头长度
//
加上rtcp头长度
return
(
1
+
ntohs
(
length
))
<<
2
;
return
(
1
+
ntohs
(
length
))
<<
2
;
}
}
size_t
RtcpHeader
::
getPaddingSize
()
const
{
size_t
RtcpHeader
::
getPaddingSize
()
const
{
if
(
!
padding
)
{
if
(
!
padding
)
{
return
0
;
return
0
;
}
}
return
((
uint8_t
*
)
this
)[
getSize
()
-
1
];
return
((
uint8_t
*
)
this
)[
getSize
()
-
1
];
}
}
void
RtcpHeader
::
setSize
(
size_t
size
)
{
void
RtcpHeader
::
setSize
(
size_t
size
)
{
//不包含rtcp头的长度
//
不包含rtcp头的长度
length
=
htons
((
uint16_t
)
((
size
>>
2
)
-
1
));
length
=
htons
((
uint16_t
)((
size
>>
2
)
-
1
));
}
}
void
RtcpHeader
::
net2Host
(
size_t
len
)
{
void
RtcpHeader
::
net2Host
(
size_t
len
)
{
switch
((
RtcpType
)
pt
)
{
switch
((
RtcpType
)
pt
)
{
case
RtcpType
:
:
RTCP_SR
:
{
case
RtcpType
:
:
RTCP_SR
:
{
RtcpSR
*
sr
=
(
RtcpSR
*
)
this
;
RtcpSR
*
sr
=
(
RtcpSR
*
)
this
;
sr
->
net2Host
(
len
);
sr
->
net2Host
(
len
);
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_RR
:
{
case
RtcpType
:
:
RTCP_RR
:
{
RtcpRR
*
rr
=
(
RtcpRR
*
)
this
;
RtcpRR
*
rr
=
(
RtcpRR
*
)
this
;
rr
->
net2Host
(
len
);
rr
->
net2Host
(
len
);
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_SDES
:
{
case
RtcpType
:
:
RTCP_SDES
:
{
RtcpSdes
*
sdes
=
(
RtcpSdes
*
)
this
;
RtcpSdes
*
sdes
=
(
RtcpSdes
*
)
this
;
sdes
->
net2Host
(
len
);
sdes
->
net2Host
(
len
);
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_RTPFB
:
case
RtcpType
:
:
RTCP_RTPFB
:
case
RtcpType
:
:
RTCP_PSFB
:
{
case
RtcpType
:
:
RTCP_PSFB
:
{
RtcpFB
*
fb
=
(
RtcpFB
*
)
this
;
RtcpFB
*
fb
=
(
RtcpFB
*
)
this
;
fb
->
net2Host
(
len
);
fb
->
net2Host
(
len
);
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_BYE
:
{
case
RtcpType
:
:
RTCP_BYE
:
{
RtcpBye
*
bye
=
(
RtcpBye
*
)
this
;
RtcpBye
*
bye
=
(
RtcpBye
*
)
this
;
bye
->
net2Host
(
len
);
bye
->
net2Host
(
len
);
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_XR
:
{
case
RtcpType
:
:
RTCP_XR
:
{
RtcpXRRRTR
*
xr
=
(
RtcpXRRRTR
*
)
this
;
RtcpXRRRTR
*
xr
=
(
RtcpXRRRTR
*
)
this
;
if
(
xr
->
bt
==
4
){
if
(
xr
->
bt
==
4
)
{
xr
->
net2Host
(
len
);
xr
->
net2Host
(
len
);
//TraceL<<xr->dumpString();
// TraceL<<xr->dumpString();
}
else
if
(
xr
->
bt
==
5
){
}
else
if
(
xr
->
bt
==
5
)
{
RtcpXRDLRR
*
dlrr
=
(
RtcpXRDLRR
*
)
this
;
RtcpXRDLRR
*
dlrr
=
(
RtcpXRDLRR
*
)
this
;
dlrr
->
net2Host
(
len
);
dlrr
->
net2Host
(
len
);
TraceL
<<
dlrr
->
dumpString
();
TraceL
<<
dlrr
->
dumpString
();
}
else
{
}
else
{
throw
std
::
runtime_error
(
StrPrinter
<<
"rtcp xr bt "
<<
xr
->
bt
<<
" not support"
);
throw
std
::
runtime_error
(
StrPrinter
<<
"rtcp xr bt "
<<
xr
->
bt
<<
" not support"
);
}
break
;
}
}
default
:
throw
std
::
runtime_error
(
StrPrinter
<<
"未处理的rtcp包:"
<<
rtcpTypeToStr
((
RtcpType
)
this
->
pt
));
break
;
}
default
:
throw
std
::
runtime_error
(
StrPrinter
<<
"未处理的rtcp包:"
<<
rtcpTypeToStr
((
RtcpType
)
this
->
pt
));
}
}
}
}
...
@@ -215,10 +229,10 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
...
@@ -215,10 +229,10 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
vector
<
RtcpHeader
*>
ret
;
vector
<
RtcpHeader
*>
ret
;
ssize_t
remain
=
len
;
ssize_t
remain
=
len
;
char
*
ptr
=
data
;
char
*
ptr
=
data
;
while
(
remain
>
(
ssize_t
)
sizeof
(
RtcpHeader
))
{
while
(
remain
>
(
ssize_t
)
sizeof
(
RtcpHeader
))
{
RtcpHeader
*
rtcp
=
(
RtcpHeader
*
)
ptr
;
RtcpHeader
*
rtcp
=
(
RtcpHeader
*
)
ptr
;
auto
rtcp_len
=
rtcp
->
getSize
();
auto
rtcp_len
=
rtcp
->
getSize
();
if
(
remain
<
(
ssize_t
)
rtcp_len
)
{
if
(
remain
<
(
ssize_t
)
rtcp_len
)
{
WarnL
<<
"非法的rtcp包,声明的长度超过实际数据长度"
;
WarnL
<<
"非法的rtcp包,声明的长度超过实际数据长度"
;
break
;
break
;
}
}
...
@@ -226,7 +240,7 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
...
@@ -226,7 +240,7 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
rtcp
->
net2Host
(
rtcp_len
);
rtcp
->
net2Host
(
rtcp_len
);
ret
.
emplace_back
(
rtcp
);
ret
.
emplace_back
(
rtcp
);
}
catch
(
std
::
exception
&
ex
)
{
}
catch
(
std
::
exception
&
ex
)
{
//不能处理的rtcp包,或者无法解析的rtcp包,忽略掉
//
不能处理的rtcp包,或者无法解析的rtcp包,忽略掉
WarnL
<<
ex
.
what
()
<<
",长度为:"
<<
rtcp_len
;
WarnL
<<
ex
.
what
()
<<
",长度为:"
<<
rtcp_len
;
}
}
ptr
+=
rtcp_len
;
ptr
+=
rtcp_len
;
...
@@ -237,19 +251,13 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
...
@@ -237,19 +251,13 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len) {
class
BufferRtcp
:
public
Buffer
{
class
BufferRtcp
:
public
Buffer
{
public
:
public
:
BufferRtcp
(
std
::
shared_ptr
<
RtcpHeader
>
rtcp
)
{
BufferRtcp
(
std
::
shared_ptr
<
RtcpHeader
>
rtcp
)
{
_rtcp
=
std
::
move
(
rtcp
);
}
_rtcp
=
std
::
move
(
rtcp
);
}
~
BufferRtcp
()
override
{}
~
BufferRtcp
()
override
{}
char
*
data
()
const
override
{
char
*
data
()
const
override
{
return
(
char
*
)
_rtcp
.
get
();
}
return
(
char
*
)
_rtcp
.
get
();
}
size_t
size
()
const
override
{
size_t
size
()
const
override
{
return
_rtcp
->
getSize
();
}
return
_rtcp
->
getSize
();
}
private
:
private
:
std
::
shared_ptr
<
RtcpHeader
>
_rtcp
;
std
::
shared_ptr
<
RtcpHeader
>
_rtcp
;
...
@@ -264,36 +272,34 @@ Buffer::Ptr RtcpHeader::toBuffer(std::shared_ptr<RtcpHeader> rtcp) {
...
@@ -264,36 +272,34 @@ Buffer::Ptr RtcpHeader::toBuffer(std::shared_ptr<RtcpHeader> rtcp) {
std
::
shared_ptr
<
RtcpSR
>
RtcpSR
::
create
(
size_t
item_count
)
{
std
::
shared_ptr
<
RtcpSR
>
RtcpSR
::
create
(
size_t
item_count
)
{
auto
real_size
=
sizeof
(
RtcpSR
)
-
sizeof
(
ReportItem
)
+
item_count
*
sizeof
(
ReportItem
);
auto
real_size
=
sizeof
(
RtcpSR
)
-
sizeof
(
ReportItem
)
+
item_count
*
sizeof
(
ReportItem
);
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpSR
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpSR
*
)
new
char
[
bytes
];
setupHeader
(
ptr
,
RtcpType
::
RTCP_SR
,
item_count
,
bytes
);
setupHeader
(
ptr
,
RtcpType
::
RTCP_SR
,
item_count
,
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
return
std
::
shared_ptr
<
RtcpSR
>
(
ptr
,
[](
RtcpSR
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpSR
>
(
ptr
,
[](
RtcpSR
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
string
RtcpSR
::
getNtpStamp
()
const
{
string
RtcpSR
::
getNtpStamp
()
const
{
struct
timeval
tv
;
struct
timeval
tv
;
tv
.
tv_sec
=
ntpmsw
-
0x83AA7E80
;
tv
.
tv_sec
=
ntpmsw
-
0x83AA7E80
;
tv
.
tv_usec
=
(
decltype
(
tv
.
tv_usec
))
(
ntplsw
/
((
double
)
(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
tv
.
tv_usec
=
(
decltype
(
tv
.
tv_usec
))
(
ntplsw
/
((
double
)(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
return
LogChannel
::
printTime
(
tv
);
return
LogChannel
::
printTime
(
tv
);
}
}
uint64_t
RtcpSR
::
getNtpUnixStampMS
()
const
{
uint64_t
RtcpSR
::
getNtpUnixStampMS
()
const
{
if
(
ntpmsw
<
0x83AA7E80
)
{
if
(
ntpmsw
<
0x83AA7E80
)
{
//ntp时间戳起始时间为1900年,但是utc时间戳起始时间为1970年,两者相差0x83AA7E80秒
//
ntp时间戳起始时间为1900年,但是utc时间戳起始时间为1970年,两者相差0x83AA7E80秒
//ntp时间戳不得早于1970年,否则无法转换为utc时间戳
//
ntp时间戳不得早于1970年,否则无法转换为utc时间戳
return
0
;
return
0
;
}
}
struct
timeval
tv
;
struct
timeval
tv
;
tv
.
tv_sec
=
ntpmsw
-
0x83AA7E80
;
tv
.
tv_sec
=
ntpmsw
-
0x83AA7E80
;
tv
.
tv_usec
=
(
decltype
(
tv
.
tv_usec
))
(
ntplsw
/
((
double
)
(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
tv
.
tv_usec
=
(
decltype
(
tv
.
tv_usec
))
(
ntplsw
/
((
double
)(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
return
1000
*
tv
.
tv_sec
+
tv
.
tv_usec
/
1000
;
return
1000
*
tv
.
tv_sec
+
tv
.
tv_usec
/
1000
;
}
}
void
RtcpSR
::
setNtpStamp
(
struct
timeval
tv
)
{
void
RtcpSR
::
setNtpStamp
(
struct
timeval
tv
)
{
ntpmsw
=
htonl
(
tv
.
tv_sec
+
0x83AA7E80
);
/* 0x83AA7E80 is the number of seconds from 1900 to 1970 */
ntpmsw
=
htonl
(
tv
.
tv_sec
+
0x83AA7E80
);
/* 0x83AA7E80 is the number of seconds from 1900 to 1970 */
ntplsw
=
htonl
((
uint32_t
)
((
double
)
tv
.
tv_usec
*
(
double
)
(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
ntplsw
=
htonl
((
uint32_t
)
((
double
)
tv
.
tv_usec
*
(
double
)(((
uint64_t
)
1
)
<<
32
)
*
1.0e-6
));
}
}
void
RtcpSR
::
setNtpStamp
(
uint64_t
unix_stamp_ms
)
{
void
RtcpSR
::
setNtpStamp
(
uint64_t
unix_stamp_ms
)
{
...
@@ -313,7 +319,7 @@ string RtcpSR::dumpString() const {
...
@@ -313,7 +319,7 @@ string RtcpSR::dumpString() const {
printer
<<
"rtpts:"
<<
rtpts
<<
"
\r\n
"
;
printer
<<
"rtpts:"
<<
rtpts
<<
"
\r\n
"
;
printer
<<
"packet_count:"
<<
packet_count
<<
"
\r\n
"
;
printer
<<
"packet_count:"
<<
packet_count
<<
"
\r\n
"
;
printer
<<
"octet_count:"
<<
octet_count
<<
"
\r\n
"
;
printer
<<
"octet_count:"
<<
octet_count
<<
"
\r\n
"
;
auto
items
=
((
RtcpSR
*
)
this
)
->
getItemList
();
auto
items
=
((
RtcpSR
*
)
this
)
->
getItemList
();
auto
i
=
0
;
auto
i
=
0
;
for
(
auto
&
item
:
items
)
{
for
(
auto
&
item
:
items
)
{
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
...
@@ -322,17 +328,19 @@ string RtcpSR::dumpString() const {
...
@@ -322,17 +328,19 @@ string RtcpSR::dumpString() const {
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
#define CHECK_MIN_SIZE(size, kMinSize) \
#define CHECK_MIN_SIZE(size, kMinSize) \
if (size < kMinSize) { \
if (size < kMinSize) { \
throw std::out_of_range(StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \
throw std::out_of_range( \
}
StrPrinter << rtcpTypeToStr((RtcpType)pt) << " 长度不足:" << size << " < " << kMinSize); \
}
#define CHECK_REPORT_COUNT(item_count) \
#define CHECK_REPORT_COUNT(item_count) \
/*修正个数,防止getItemList时内存越界*/
\
/*修正个数,防止getItemList时内存越界*/
\
if (report_count != item_count) { \
if (report_count != item_count) { \
WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " << item_count; \
WarnL << rtcpTypeToStr((RtcpType)pt) << " report_count 字段不正确,已修正为:" << (int)report_count << " -> " \
report_count = item_count; \
<< item_count; \
}
report_count = item_count; \
}
void
RtcpSR
::
net2Host
(
size_t
size
)
{
void
RtcpSR
::
net2Host
(
size_t
size
)
{
static
const
size_t
kMinSize
=
sizeof
(
RtcpSR
)
-
sizeof
(
items
);
static
const
size_t
kMinSize
=
sizeof
(
RtcpSR
)
-
sizeof
(
items
);
...
@@ -347,7 +355,7 @@ void RtcpSR::net2Host(size_t size) {
...
@@ -347,7 +355,7 @@ void RtcpSR::net2Host(size_t size) {
ReportItem
*
ptr
=
&
items
;
ReportItem
*
ptr
=
&
items
;
int
item_count
=
0
;
int
item_count
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)
(
ptr
)
+
sizeof
(
ReportItem
)
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)(
ptr
)
+
sizeof
(
ReportItem
)
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
ptr
->
net2Host
();
ptr
->
net2Host
();
++
ptr
;
++
ptr
;
++
item_count
;
++
item_count
;
...
@@ -358,7 +366,7 @@ void RtcpSR::net2Host(size_t size) {
...
@@ -358,7 +366,7 @@ void RtcpSR::net2Host(size_t size) {
vector
<
ReportItem
*>
RtcpSR
::
getItemList
()
{
vector
<
ReportItem
*>
RtcpSR
::
getItemList
()
{
vector
<
ReportItem
*>
ret
;
vector
<
ReportItem
*>
ret
;
ReportItem
*
ptr
=
&
items
;
ReportItem
*
ptr
=
&
items
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
ret
.
emplace_back
(
ptr
);
ret
.
emplace_back
(
ptr
);
++
ptr
;
++
ptr
;
}
}
...
@@ -395,19 +403,17 @@ void ReportItem::net2Host() {
...
@@ -395,19 +403,17 @@ void ReportItem::net2Host() {
std
::
shared_ptr
<
RtcpRR
>
RtcpRR
::
create
(
size_t
item_count
)
{
std
::
shared_ptr
<
RtcpRR
>
RtcpRR
::
create
(
size_t
item_count
)
{
auto
real_size
=
sizeof
(
RtcpRR
)
-
sizeof
(
ReportItem
)
+
item_count
*
sizeof
(
ReportItem
);
auto
real_size
=
sizeof
(
RtcpRR
)
-
sizeof
(
ReportItem
)
+
item_count
*
sizeof
(
ReportItem
);
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpRR
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpRR
*
)
new
char
[
bytes
];
setupHeader
(
ptr
,
RtcpType
::
RTCP_RR
,
item_count
,
bytes
);
setupHeader
(
ptr
,
RtcpType
::
RTCP_RR
,
item_count
,
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
return
std
::
shared_ptr
<
RtcpRR
>
(
ptr
,
[](
RtcpRR
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpRR
>
(
ptr
,
[](
RtcpRR
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
string
RtcpRR
::
dumpString
()
const
{
string
RtcpRR
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
auto
items
=
((
RtcpRR
*
)
this
)
->
getItemList
();
auto
items
=
((
RtcpRR
*
)
this
)
->
getItemList
();
auto
i
=
0
;
auto
i
=
0
;
for
(
auto
&
item
:
items
)
{
for
(
auto
&
item
:
items
)
{
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
...
@@ -423,7 +429,7 @@ void RtcpRR::net2Host(size_t size) {
...
@@ -423,7 +429,7 @@ void RtcpRR::net2Host(size_t size) {
ReportItem
*
ptr
=
&
items
;
ReportItem
*
ptr
=
&
items
;
int
item_count
=
0
;
int
item_count
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)
(
ptr
)
+
sizeof
(
ReportItem
)
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)(
ptr
)
+
sizeof
(
ReportItem
)
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
ptr
->
net2Host
();
ptr
->
net2Host
();
++
ptr
;
++
ptr
;
++
item_count
;
++
item_count
;
...
@@ -434,7 +440,7 @@ void RtcpRR::net2Host(size_t size) {
...
@@ -434,7 +440,7 @@ void RtcpRR::net2Host(size_t size) {
vector
<
ReportItem
*>
RtcpRR
::
getItemList
()
{
vector
<
ReportItem
*>
RtcpRR
::
getItemList
()
{
vector
<
ReportItem
*>
ret
;
vector
<
ReportItem
*>
ret
;
ReportItem
*
ptr
=
&
items
;
ReportItem
*
ptr
=
&
items
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
ret
.
emplace_back
(
ptr
);
ret
.
emplace_back
(
ptr
);
++
ptr
;
++
ptr
;
}
}
...
@@ -458,8 +464,8 @@ size_t SdesChunk::minSize() {
...
@@ -458,8 +464,8 @@ size_t SdesChunk::minSize() {
string
SdesChunk
::
dumpString
()
const
{
string
SdesChunk
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"type:"
<<
sdesTypeToStr
((
SdesType
)
type
)
<<
"
\r\n
"
;
printer
<<
"type:"
<<
sdesTypeToStr
((
SdesType
)
type
)
<<
"
\r\n
"
;
printer
<<
"txt_len:"
<<
(
int
)
txt_len
<<
"
\r\n
"
;
printer
<<
"txt_len:"
<<
(
int
)
txt_len
<<
"
\r\n
"
;
printer
<<
"text:"
<<
(
txt_len
?
string
(
text
,
txt_len
)
:
""
)
<<
"
\r\n
"
;
printer
<<
"text:"
<<
(
txt_len
?
string
(
text
,
txt_len
)
:
""
)
<<
"
\r\n
"
;
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
...
@@ -469,32 +475,30 @@ string SdesChunk::dumpString() const {
...
@@ -469,32 +475,30 @@ string SdesChunk::dumpString() const {
std
::
shared_ptr
<
RtcpSdes
>
RtcpSdes
::
create
(
const
std
::
vector
<
string
>
&
item_text
)
{
std
::
shared_ptr
<
RtcpSdes
>
RtcpSdes
::
create
(
const
std
::
vector
<
string
>
&
item_text
)
{
size_t
item_total_size
=
0
;
size_t
item_total_size
=
0
;
for
(
auto
&
text
:
item_text
)
{
for
(
auto
&
text
:
item_text
)
{
//统计所有SdesChunk对象占用的空间
//
统计所有SdesChunk对象占用的空间
item_total_size
+=
alignSize
(
SdesChunk
::
minSize
()
+
(
0xFF
&
text
.
size
()));
item_total_size
+=
alignSize
(
SdesChunk
::
minSize
()
+
(
0xFF
&
text
.
size
()));
}
}
auto
real_size
=
sizeof
(
RtcpSdes
)
-
sizeof
(
SdesChunk
)
+
item_total_size
;
auto
real_size
=
sizeof
(
RtcpSdes
)
-
sizeof
(
SdesChunk
)
+
item_total_size
;
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpSdes
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpSdes
*
)
new
char
[
bytes
];
memset
(
ptr
,
0x00
,
bytes
);
memset
(
ptr
,
0x00
,
bytes
);
auto
item_ptr
=
&
ptr
->
chunks
;
auto
item_ptr
=
&
ptr
->
chunks
;
for
(
auto
&
text
:
item_text
)
{
for
(
auto
&
text
:
item_text
)
{
item_ptr
->
txt_len
=
(
0xFF
&
text
.
size
());
item_ptr
->
txt_len
=
(
0xFF
&
text
.
size
());
//确保赋值\0为RTCP_SDES_END
//
确保赋值\0为RTCP_SDES_END
memcpy
(
item_ptr
->
text
,
text
.
data
(),
item_ptr
->
txt_len
+
1
);
memcpy
(
item_ptr
->
text
,
text
.
data
(),
item_ptr
->
txt_len
+
1
);
item_ptr
=
(
SdesChunk
*
)
((
char
*
)
item_ptr
+
item_ptr
->
totalBytes
());
item_ptr
=
(
SdesChunk
*
)
((
char
*
)
item_ptr
+
item_ptr
->
totalBytes
());
}
}
setupHeader
(
ptr
,
RtcpType
::
RTCP_SDES
,
item_text
.
size
(),
bytes
);
setupHeader
(
ptr
,
RtcpType
::
RTCP_SDES
,
item_text
.
size
(),
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
return
std
::
shared_ptr
<
RtcpSdes
>
(
ptr
,
[](
RtcpSdes
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpSdes
>
(
ptr
,
[](
RtcpSdes
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
string
RtcpSdes
::
dumpString
()
const
{
string
RtcpSdes
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
auto
items
=
((
RtcpSdes
*
)
this
)
->
getChunkList
();
auto
items
=
((
RtcpSdes
*
)
this
)
->
getChunkList
();
auto
i
=
0
;
auto
i
=
0
;
for
(
auto
&
item
:
items
)
{
for
(
auto
&
item
:
items
)
{
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
...
@@ -508,9 +512,9 @@ void RtcpSdes::net2Host(size_t size) {
...
@@ -508,9 +512,9 @@ void RtcpSdes::net2Host(size_t size) {
CHECK_MIN_SIZE
(
size
,
kMinSize
);
CHECK_MIN_SIZE
(
size
,
kMinSize
);
SdesChunk
*
ptr
=
&
chunks
;
SdesChunk
*
ptr
=
&
chunks
;
int
item_count
=
0
;
int
item_count
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)
(
ptr
)
+
SdesChunk
::
minSize
()
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
&&
(
char
*
)(
ptr
)
+
SdesChunk
::
minSize
()
<=
(
char
*
)
(
this
)
+
size
;
++
i
)
{
ptr
->
net2Host
();
ptr
->
net2Host
();
ptr
=
(
SdesChunk
*
)
((
char
*
)
ptr
+
ptr
->
totalBytes
());
ptr
=
(
SdesChunk
*
)
((
char
*
)
ptr
+
ptr
->
totalBytes
());
++
item_count
;
++
item_count
;
}
}
CHECK_REPORT_COUNT
(
item_count
);
CHECK_REPORT_COUNT
(
item_count
);
...
@@ -519,9 +523,9 @@ void RtcpSdes::net2Host(size_t size) {
...
@@ -519,9 +523,9 @@ void RtcpSdes::net2Host(size_t size) {
vector
<
SdesChunk
*>
RtcpSdes
::
getChunkList
()
{
vector
<
SdesChunk
*>
RtcpSdes
::
getChunkList
()
{
vector
<
SdesChunk
*>
ret
;
vector
<
SdesChunk
*>
ret
;
SdesChunk
*
ptr
=
&
chunks
;
SdesChunk
*
ptr
=
&
chunks
;
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
report_count
;
++
i
)
{
ret
.
emplace_back
(
ptr
);
ret
.
emplace_back
(
ptr
);
ptr
=
(
SdesChunk
*
)
((
char
*
)
ptr
+
ptr
->
totalBytes
());
ptr
=
(
SdesChunk
*
)
((
char
*
)
ptr
+
ptr
->
totalBytes
());
}
}
return
ret
;
return
ret
;
}
}
...
@@ -534,31 +538,29 @@ std::shared_ptr<RtcpFB> RtcpFB::create_l(RtcpType type, int fmt, const void *fci
...
@@ -534,31 +538,29 @@ std::shared_ptr<RtcpFB> RtcpFB::create_l(RtcpType type, int fmt, const void *fci
}
}
auto
real_size
=
sizeof
(
RtcpFB
)
+
fci_len
;
auto
real_size
=
sizeof
(
RtcpFB
)
+
fci_len
;
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpFB
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpFB
*
)
new
char
[
bytes
];
if
(
fci
&&
fci_len
)
{
if
(
fci
&&
fci_len
)
{
memcpy
((
char
*
)
ptr
+
sizeof
(
RtcpFB
),
fci
,
fci_len
);
memcpy
((
char
*
)
ptr
+
sizeof
(
RtcpFB
),
fci
,
fci_len
);
}
}
setupHeader
(
ptr
,
type
,
fmt
,
bytes
);
setupHeader
(
ptr
,
type
,
fmt
,
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
return
std
::
shared_ptr
<
RtcpFB
>
((
RtcpFB
*
)
ptr
,
[](
RtcpFB
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpFB
>
((
RtcpFB
*
)
ptr
,
[](
RtcpFB
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
std
::
shared_ptr
<
RtcpFB
>
RtcpFB
::
create
(
PSFBType
fmt
,
const
void
*
fci
,
size_t
fci_len
)
{
std
::
shared_ptr
<
RtcpFB
>
RtcpFB
::
create
(
PSFBType
fmt
,
const
void
*
fci
,
size_t
fci_len
)
{
return
RtcpFB
::
create_l
(
RtcpType
::
RTCP_PSFB
,
(
int
)
fmt
,
fci
,
fci_len
);
return
RtcpFB
::
create_l
(
RtcpType
::
RTCP_PSFB
,
(
int
)
fmt
,
fci
,
fci_len
);
}
}
std
::
shared_ptr
<
RtcpFB
>
RtcpFB
::
create
(
RTPFBType
fmt
,
const
void
*
fci
,
size_t
fci_len
)
{
std
::
shared_ptr
<
RtcpFB
>
RtcpFB
::
create
(
RTPFBType
fmt
,
const
void
*
fci
,
size_t
fci_len
)
{
return
RtcpFB
::
create_l
(
RtcpType
::
RTCP_RTPFB
,
(
int
)
fmt
,
fci
,
fci_len
);
return
RtcpFB
::
create_l
(
RtcpType
::
RTCP_RTPFB
,
(
int
)
fmt
,
fci
,
fci_len
);
}
}
const
void
*
RtcpFB
::
getFciPtr
()
const
{
const
void
*
RtcpFB
::
getFciPtr
()
const
{
return
(
uint8_t
*
)
&
ssrc_media
+
sizeof
(
ssrc_media
);
return
(
uint8_t
*
)
&
ssrc_media
+
sizeof
(
ssrc_media
);
}
}
size_t
RtcpFB
::
getFciSize
()
const
{
size_t
RtcpFB
::
getFciSize
()
const
{
auto
fci_len
=
(
ssize_t
)
getSize
()
-
getPaddingSize
()
-
sizeof
(
RtcpFB
);
auto
fci_len
=
(
ssize_t
)
getSize
()
-
getPaddingSize
()
-
sizeof
(
RtcpFB
);
CHECK
(
fci_len
>=
0
);
CHECK
(
fci_len
>=
0
);
return
fci_len
;
return
fci_len
;
}
}
...
@@ -568,58 +570,60 @@ string RtcpFB::dumpString() const {
...
@@ -568,58 +570,60 @@ string RtcpFB::dumpString() const {
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc:"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc_media:"
<<
ssrc_media
<<
"
\r\n
"
;
printer
<<
"ssrc_media:"
<<
ssrc_media
<<
"
\r\n
"
;
switch
((
RtcpType
)
pt
)
{
switch
((
RtcpType
)
pt
)
{
case
RtcpType
:
:
RTCP_PSFB
:
{
case
RtcpType
:
:
RTCP_PSFB
:
{
switch
((
PSFBType
)
report_count
)
{
switch
((
PSFBType
)
report_count
)
{
case
PSFBType
:
:
RTCP_PSFB_SLI
:
{
case
PSFBType
:
:
RTCP_PSFB_SLI
:
{
auto
&
fci
=
getFci
<
FCI_SLI
>
();
auto
&
fci
=
getFci
<
FCI_SLI
>
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
break
;
break
;
}
}
case
PSFBType
:
:
RTCP_PSFB_PLI
:
{
case
PSFBType
:
:
RTCP_PSFB_PLI
:
{
getFciSize
();
getFciSize
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
);
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
);
break
;
break
;
}
}
case
PSFBType
:
:
RTCP_PSFB_FIR
:
{
case
PSFBType
:
:
RTCP_PSFB_FIR
:
{
auto
&
fci
=
getFci
<
FCI_FIR
>
();
auto
&
fci
=
getFci
<
FCI_FIR
>
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
break
;
}
case
PSFBType
:
:
RTCP_PSFB_REMB
:
{
auto
&
fci
=
getFci
<
FCI_REMB
>
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
break
;
}
default
:
{
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
hexdump
(
getFciPtr
(),
getFciSize
());
break
;
}
}
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_RTPFB
:
{
switch
((
RTPFBType
)
report_count
)
{
case
PSFBType
:
:
RTCP_PSFB_REMB
:
{
case
RTPFBType
:
:
RTCP_RTPFB_NACK
:
{
auto
&
fci
=
getFci
<
FCI_REMB
>
();
auto
&
fci
=
getFci
<
FCI_NACK
>
();
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
break
;
}
case
RTPFBType
:
:
RTCP_RTPFB_TWCC
:
{
auto
&
fci
=
getFci
<
FCI_TWCC
>
();
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
(
getFciSize
());
break
;
}
default
:
{
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
hexdump
(
getFciPtr
(),
getFciSize
());
break
;
}
}
break
;
break
;
}
}
default
:
/*不可达*/
assert
(
0
);
break
;
default
:
{
printer
<<
"fci:"
<<
psfbTypeToStr
((
PSFBType
)
report_count
)
<<
" "
<<
hexdump
(
getFciPtr
(),
getFciSize
());
break
;
}
}
break
;
}
case
RtcpType
:
:
RTCP_RTPFB
:
{
switch
((
RTPFBType
)
report_count
)
{
case
RTPFBType
:
:
RTCP_RTPFB_NACK
:
{
auto
&
fci
=
getFci
<
FCI_NACK
>
();
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
();
break
;
}
case
RTPFBType
:
:
RTCP_RTPFB_TWCC
:
{
auto
&
fci
=
getFci
<
FCI_TWCC
>
();
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
fci
.
dumpString
(
getFciSize
());
break
;
}
default
:
{
printer
<<
"fci:"
<<
rtpfbTypeToStr
((
RTPFBType
)
report_count
)
<<
" "
<<
hexdump
(
getFciPtr
(),
getFciSize
());
break
;
}
}
break
;
}
default
:
/*不可达*/
assert
(
0
);
break
;
}
}
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
...
@@ -637,24 +641,22 @@ std::shared_ptr<RtcpBye> RtcpBye::create(const std::vector<uint32_t> &ssrcs, con
...
@@ -637,24 +641,22 @@ std::shared_ptr<RtcpBye> RtcpBye::create(const std::vector<uint32_t> &ssrcs, con
assert
(
reason
.
size
()
<=
0xFF
);
assert
(
reason
.
size
()
<=
0xFF
);
auto
real_size
=
sizeof
(
RtcpHeader
)
+
sizeof
(
uint32_t
)
*
ssrcs
.
size
()
+
1
+
reason
.
size
();
auto
real_size
=
sizeof
(
RtcpHeader
)
+
sizeof
(
uint32_t
)
*
ssrcs
.
size
()
+
1
+
reason
.
size
();
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpBye
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpBye
*
)
new
char
[
bytes
];
setupHeader
(
ptr
,
RtcpType
::
RTCP_BYE
,
ssrcs
.
size
(),
bytes
);
setupHeader
(
ptr
,
RtcpType
::
RTCP_BYE
,
ssrcs
.
size
(),
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
int
i
=
0
;
int
i
=
0
;
for
(
auto
ssrc
:
ssrcs
)
{
for
(
auto
ssrc
:
ssrcs
)
{
((
RtcpBye
*
)
ptr
)
->
ssrc
[
i
++
]
=
htonl
(
ssrc
);
((
RtcpBye
*
)
ptr
)
->
ssrc
[
i
++
]
=
htonl
(
ssrc
);
}
}
if
(
!
reason
.
empty
())
{
if
(
!
reason
.
empty
())
{
uint8_t
*
reason_len_ptr
=
(
uint8_t
*
)
ptr
+
sizeof
(
RtcpHeader
)
+
sizeof
(
uint32_t
)
*
ssrcs
.
size
();
uint8_t
*
reason_len_ptr
=
(
uint8_t
*
)
ptr
+
sizeof
(
RtcpHeader
)
+
sizeof
(
uint32_t
)
*
ssrcs
.
size
();
*
reason_len_ptr
=
reason
.
size
()
&
0xFF
;
*
reason_len_ptr
=
reason
.
size
()
&
0xFF
;
memcpy
(
reason_len_ptr
+
1
,
reason
.
data
(),
*
reason_len_ptr
);
memcpy
(
reason_len_ptr
+
1
,
reason
.
data
(),
*
reason_len_ptr
);
}
}
return
std
::
shared_ptr
<
RtcpBye
>
(
ptr
,
[](
RtcpBye
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpBye
>
(
ptr
,
[](
RtcpBye
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
vector
<
uint32_t
*>
RtcpBye
::
getSSRC
()
{
vector
<
uint32_t
*>
RtcpBye
::
getSSRC
()
{
...
@@ -667,16 +669,16 @@ vector<uint32_t *> RtcpBye::getSSRC() {
...
@@ -667,16 +669,16 @@ vector<uint32_t *> RtcpBye::getSSRC() {
string
RtcpBye
::
getReason
()
const
{
string
RtcpBye
::
getReason
()
const
{
auto
*
reason_len_ptr
=
&
reason_len
+
sizeof
(
ssrc
)
*
(
report_count
-
1
);
auto
*
reason_len_ptr
=
&
reason_len
+
sizeof
(
ssrc
)
*
(
report_count
-
1
);
if
(
reason_len_ptr
+
1
>=
(
uint8_t
*
)
this
+
getSize
())
{
if
(
reason_len_ptr
+
1
>=
(
uint8_t
*
)
this
+
getSize
())
{
return
""
;
return
""
;
}
}
return
string
((
char
*
)
reason_len_ptr
+
1
,
*
reason_len_ptr
);
return
string
((
char
*
)
reason_len_ptr
+
1
,
*
reason_len_ptr
);
}
}
string
RtcpBye
::
dumpString
()
const
{
string
RtcpBye
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
for
(
auto
ssrc
:
((
RtcpBye
*
)
this
)
->
getSSRC
())
{
for
(
auto
ssrc
:
((
RtcpBye
*
)
this
)
->
getSSRC
())
{
printer
<<
"ssrc:"
<<
*
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc:"
<<
*
ssrc
<<
"
\r\n
"
;
}
}
printer
<<
"reason:"
<<
getReason
();
printer
<<
"reason:"
<<
getReason
();
...
@@ -692,35 +694,37 @@ void RtcpBye::net2Host(size_t size) {
...
@@ -692,35 +694,37 @@ void RtcpBye::net2Host(size_t size) {
ssrc
[
i
]
=
ntohl
(
ssrc
[
i
]);
ssrc
[
i
]
=
ntohl
(
ssrc
[
i
]);
offset
+=
sizeof
(
ssrc
);
offset
+=
sizeof
(
ssrc
);
}
}
//修正ssrc个数
//
修正ssrc个数
CHECK_REPORT_COUNT
(
i
);
CHECK_REPORT_COUNT
(
i
);
if
(
offset
<
size
)
{
if
(
offset
<
size
)
{
uint8_t
*
reason_len_ptr
=
&
reason_len
+
sizeof
(
ssrc
)
*
(
report_count
-
1
);
uint8_t
*
reason_len_ptr
=
&
reason_len
+
sizeof
(
ssrc
)
*
(
report_count
-
1
);
if
(
reason_len_ptr
+
1
+
*
reason_len_ptr
>
(
uint8_t
*
)
this
+
size
)
{
if
(
reason_len_ptr
+
1
+
*
reason_len_ptr
>
(
uint8_t
*
)
this
+
size
)
{
WarnL
<<
"invalid rtcp bye reason length"
;
WarnL
<<
"invalid rtcp bye reason length"
;
//修正reason_len长度
//
修正reason_len长度
*
reason_len_ptr
=
((
uint8_t
*
)
this
+
size
-
reason_len_ptr
-
1
)
&
0xFF
;
*
reason_len_ptr
=
((
uint8_t
*
)
this
+
size
-
reason_len_ptr
-
1
)
&
0xFF
;
}
}
}
}
}
}
////////////////////////////////////////////
////////////////////////////////////////////
string
RtcpXRRRTR
::
dumpString
()
const
{
string
RtcpXRRRTR
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"bt :"
<<
(
int
)
bt
<<
"
\r\n
"
;
printer
<<
"bt :"
<<
(
int
)
bt
<<
"
\r\n
"
;
printer
<<
"block_length : "
<<
block_length
<<
"
\r\n
"
;
printer
<<
"block_length : "
<<
block_length
<<
"
\r\n
"
;
printer
<<
"ntp msw : "
<<
ntpmsw
<<
"
\r\n
"
;
printer
<<
"ntp msw : "
<<
ntpmsw
<<
"
\r\n
"
;
printer
<<
"ntp lsw : "
<<
ntplsw
<<
"
\r\n
"
;
printer
<<
"ntp lsw : "
<<
ntplsw
<<
"
\r\n
"
;
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
void
RtcpXRRRTR
::
net2Host
(
size_t
size
)
{
void
RtcpXRRRTR
::
net2Host
(
size_t
size
)
{
static
const
size_t
kMinSize
=
sizeof
(
RtcpHeader
);
static
const
size_t
kMinSize
=
sizeof
(
RtcpHeader
);
CHECK_MIN_SIZE
(
size
,
kMinSize
);
CHECK_MIN_SIZE
(
size
,
kMinSize
);
if
(
size
!=
sizeof
(
RtcpXRRRTR
)){
if
(
size
!=
sizeof
(
RtcpXRRRTR
))
{
throw
std
::
invalid_argument
(
StrPrinter
<<
"rtcp xr Receiver Reference Time Report Block must is "
<<
sizeof
(
RtcpXRRRTR
)
<<
" actual size "
<<
size
);
throw
std
::
invalid_argument
(
StrPrinter
<<
"rtcp xr Receiver Reference Time Report Block must is "
<<
sizeof
(
RtcpXRRRTR
)
<<
" actual size "
<<
size
);
}
}
ssrc
=
ntohl
(
ssrc
);
ssrc
=
ntohl
(
ssrc
);
block_length
=
ntohs
(
block_length
);
block_length
=
ntohs
(
block_length
);
...
@@ -728,14 +732,13 @@ void RtcpXRRRTR::net2Host(size_t size) {
...
@@ -728,14 +732,13 @@ void RtcpXRRRTR::net2Host(size_t size) {
ntplsw
=
ntohl
(
ntplsw
);
ntplsw
=
ntohl
(
ntplsw
);
}
}
string
RtcpXRDLRRReportItem
::
dumpString
()
const
{
string
RtcpXRDLRRReportItem
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"last RR (lrr) :"
<<
lrr
<<
"
\r\n
"
;
printer
<<
"last RR (lrr) :"
<<
lrr
<<
"
\r\n
"
;
printer
<<
"delay since last RR (dlrr): "
<<
dlrr
<<
"
\r\n
"
;
printer
<<
"delay since last RR (dlrr): "
<<
dlrr
<<
"
\r\n
"
;
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
...
@@ -745,24 +748,23 @@ void RtcpXRDLRRReportItem::net2Host() {
...
@@ -745,24 +748,23 @@ void RtcpXRDLRRReportItem::net2Host() {
dlrr
=
ntohl
(
dlrr
);
dlrr
=
ntohl
(
dlrr
);
}
}
std
::
vector
<
RtcpXRDLRRReportItem
*>
RtcpXRDLRR
::
getItemList
()
{
std
::
vector
<
RtcpXRDLRRReportItem
*>
RtcpXRDLRR
::
getItemList
()
{
auto
count
=
block_length
/
3
;
auto
count
=
block_length
/
3
;
RtcpXRDLRRReportItem
*
ptr
=
&
items
;
RtcpXRDLRRReportItem
*
ptr
=
&
items
;
vector
<
RtcpXRDLRRReportItem
*>
ret
;
vector
<
RtcpXRDLRRReportItem
*>
ret
;
for
(
int
i
=
0
;
i
<
(
int
)
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
count
;
++
i
)
{
ret
.
emplace_back
(
ptr
);
ret
.
emplace_back
(
ptr
);
++
ptr
;
++
ptr
;
}
}
return
ret
;
return
ret
;
}
}
string
RtcpXRDLRR
::
dumpString
()
const
{
string
RtcpXRDLRR
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
RtcpHeader
::
dumpHeader
();
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"ssrc :"
<<
ssrc
<<
"
\r\n
"
;
printer
<<
"bt :"
<<
(
int
)
bt
<<
"
\r\n
"
;
printer
<<
"bt :"
<<
(
int
)
bt
<<
"
\r\n
"
;
printer
<<
"block_length : "
<<
block_length
<<
"
\r\n
"
;
printer
<<
"block_length : "
<<
block_length
<<
"
\r\n
"
;
auto
items_list
=
((
RtcpXRDLRR
*
)
this
)
->
getItemList
();
auto
items_list
=
((
RtcpXRDLRR
*
)
this
)
->
getItemList
();
auto
i
=
0
;
auto
i
=
0
;
for
(
auto
&
item
:
items_list
)
{
for
(
auto
&
item
:
items_list
)
{
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
printer
<<
"---- item:"
<<
i
++
<<
" ----
\r\n
"
;
...
@@ -778,23 +780,21 @@ void RtcpXRDLRR::net2Host(size_t size) {
...
@@ -778,23 +780,21 @@ void RtcpXRDLRR::net2Host(size_t size) {
ssrc
=
ntohl
(
ssrc
);
ssrc
=
ntohl
(
ssrc
);
block_length
=
ntohs
(
block_length
);
block_length
=
ntohs
(
block_length
);
auto
count
=
block_length
/
3
;
auto
count
=
block_length
/
3
;
for
(
int
i
=
0
;
i
<
(
int
)
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
count
;
++
i
)
{
RtcpXRDLRRReportItem
*
ptr
=
&
items
;
RtcpXRDLRRReportItem
*
ptr
=
&
items
;
ptr
->
net2Host
();
ptr
->
net2Host
();
ptr
++
;
ptr
++
;
}
}
}
}
std
::
shared_ptr
<
RtcpXRDLRR
>
RtcpXRDLRR
::
create
(
size_t
item_count
)
{
std
::
shared_ptr
<
RtcpXRDLRR
>
RtcpXRDLRR
::
create
(
size_t
item_count
)
{
auto
real_size
=
sizeof
(
RtcpXRDLRR
)
-
sizeof
(
RtcpXRDLRRReportItem
)
+
item_count
*
sizeof
(
RtcpXRDLRRReportItem
);
auto
real_size
=
sizeof
(
RtcpXRDLRR
)
-
sizeof
(
RtcpXRDLRRReportItem
)
+
item_count
*
sizeof
(
RtcpXRDLRRReportItem
);
auto
bytes
=
alignSize
(
real_size
);
auto
bytes
=
alignSize
(
real_size
);
auto
ptr
=
(
RtcpXRDLRR
*
)
new
char
[
bytes
];
auto
ptr
=
(
RtcpXRDLRR
*
)
new
char
[
bytes
];
setupHeader
(
ptr
,
RtcpType
::
RTCP_XR
,
0
,
bytes
);
setupHeader
(
ptr
,
RtcpType
::
RTCP_XR
,
0
,
bytes
);
setupPadding
(
ptr
,
bytes
-
real_size
);
setupPadding
(
ptr
,
bytes
-
real_size
);
return
std
::
shared_ptr
<
RtcpXRDLRR
>
(
ptr
,
[](
RtcpXRDLRR
*
ptr
)
{
return
std
::
shared_ptr
<
RtcpXRDLRR
>
(
ptr
,
[](
RtcpXRDLRR
*
ptr
)
{
delete
[]
(
char
*
)
ptr
;
});
delete
[]
(
char
*
)
ptr
;
});
}
}
#if 0
#if 0
...
@@ -811,4 +811,4 @@ static toolkit::onceToken token([](){
...
@@ -811,4 +811,4 @@ static toolkit::onceToken token([](){
});
});
#endif
#endif
}
//
namespace
mediakit
}
//
namespace
mediakit
\ No newline at end of file
\ No newline at end of file
src/Rtcp/Rtcp.h
查看文件 @
cffc0743
...
@@ -11,11 +11,11 @@
...
@@ -11,11 +11,11 @@
#ifndef ZLMEDIAKIT_RTCP_H
#ifndef ZLMEDIAKIT_RTCP_H
#define ZLMEDIAKIT_RTCP_H
#define ZLMEDIAKIT_RTCP_H
#include "Common/macros.h"
#include "Network/Buffer.h"
#include "Util/util.h"
#include <stdint.h>
#include <stdint.h>
#include <vector>
#include <vector>
#include "Util/util.h"
#include "Network/Buffer.h"
#include "Common/macros.h"
namespace
mediakit
{
namespace
mediakit
{
...
@@ -23,115 +23,115 @@ namespace mediakit {
...
@@ -23,115 +23,115 @@ namespace mediakit {
#pragma pack(push, 1)
#pragma pack(push, 1)
#endif // defined(_WIN32)
#endif // defined(_WIN32)
//http://www.networksorcery.com/enp/protocol/rtcp.htm
//
http://www.networksorcery.com/enp/protocol/rtcp.htm
#define RTCP_PT_MAP(XX) \
#define RTCP_PT_MAP(XX)
\
XX(RTCP_FIR, 192)
\
XX(RTCP_FIR, 192)
\
XX(RTCP_NACK, 193)
\
XX(RTCP_NACK, 193)
\
XX(RTCP_SMPTETC, 194)
\
XX(RTCP_SMPTETC, 194)
\
XX(RTCP_IJ, 195)
\
XX(RTCP_IJ, 195)
\
XX(RTCP_SR, 200)
\
XX(RTCP_SR, 200)
\
XX(RTCP_RR, 201)
\
XX(RTCP_RR, 201)
\
XX(RTCP_SDES, 202)
\
XX(RTCP_SDES, 202)
\
XX(RTCP_BYE, 203)
\
XX(RTCP_BYE, 203)
\
XX(RTCP_APP, 204)
\
XX(RTCP_APP, 204)
\
XX(RTCP_RTPFB, 205)
\
XX(RTCP_RTPFB, 205)
\
XX(RTCP_PSFB, 206)
\
XX(RTCP_PSFB, 206)
\
XX(RTCP_XR, 207)
\
XX(RTCP_XR, 207)
\
XX(RTCP_AVB, 208)
\
XX(RTCP_AVB, 208)
\
XX(RTCP_RSI, 209)
\
XX(RTCP_RSI, 209)
\
XX(RTCP_TOKEN, 210)
XX(RTCP_TOKEN, 210)
//https://tools.ietf.org/html/rfc3550#section-6.5
//
https://tools.ietf.org/html/rfc3550#section-6.5
#define SDES_TYPE_MAP(XX) \
#define SDES_TYPE_MAP(XX)
\
XX(RTCP_SDES_END, 0)
\
XX(RTCP_SDES_END, 0)
\
XX(RTCP_SDES_CNAME, 1)
\
XX(RTCP_SDES_CNAME, 1)
\
XX(RTCP_SDES_NAME, 2)
\
XX(RTCP_SDES_NAME, 2)
\
XX(RTCP_SDES_EMAIL, 3)
\
XX(RTCP_SDES_EMAIL, 3)
\
XX(RTCP_SDES_PHONE, 4)
\
XX(RTCP_SDES_PHONE, 4)
\
XX(RTCP_SDES_LOC, 5)
\
XX(RTCP_SDES_LOC, 5)
\
XX(RTCP_SDES_TOOL, 6)
\
XX(RTCP_SDES_TOOL, 6)
\
XX(RTCP_SDES_NOTE, 7)
\
XX(RTCP_SDES_NOTE, 7)
\
XX(RTCP_SDES_PRIVATE, 8)
XX(RTCP_SDES_PRIVATE, 8)
//https://datatracker.ietf.org/doc/rfc4585/?include_text=1
//
https://datatracker.ietf.org/doc/rfc4585/?include_text=1
//6.3. Payload-Specific Feedback Messages
//
6.3. Payload-Specific Feedback Messages
//
//
// Payload-Specific FB messages are identified by the value PT=PSFB as
//
Payload-Specific FB messages are identified by the value PT=PSFB as
// RTCP message type.
//
RTCP message type.
//
//
// Three payload-specific FB messages are defined so far plus an
//
Three payload-specific FB messages are defined so far plus an
// application layer FB message. They are identified by means of the
//
application layer FB message. They are identified by means of the
// FMT parameter as follows:
//
FMT parameter as follows:
//
//
// 0: unassigned
//
0: unassigned
// 1: Picture Loss Indication (PLI)
//
1: Picture Loss Indication (PLI)
// 2: Slice Loss Indication (SLI)
//
2: Slice Loss Indication (SLI)
// 3: Reference Picture Selection Indication (RPSI)
//
3: Reference Picture Selection Indication (RPSI)
// 4: FIR https://tools.ietf.org/html/rfc5104#section-4.3.1.1
//
4: FIR https://tools.ietf.org/html/rfc5104#section-4.3.1.1
// 5: TSTR https://tools.ietf.org/html/rfc5104#section-4.3.2.1
//
5: TSTR https://tools.ietf.org/html/rfc5104#section-4.3.2.1
// 6: TSTN https://tools.ietf.org/html/rfc5104#section-4.3.2.1
//
6: TSTN https://tools.ietf.org/html/rfc5104#section-4.3.2.1
// 7: VBCM https://tools.ietf.org/html/rfc5104#section-4.3.4.1
//
7: VBCM https://tools.ietf.org/html/rfc5104#section-4.3.4.1
// 8-14: unassigned
//
8-14: unassigned
// 15: REMB / Application layer FB (AFB) message, https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
//
15: REMB / Application layer FB (AFB) message, https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
// 16-30: unassigned
//
16-30: unassigned
// 31: reserved for future expansion of the sequence number space
//
31: reserved for future expansion of the sequence number space
#define PSFB_TYPE_MAP(XX) \
#define PSFB_TYPE_MAP(XX)
\
XX(RTCP_PSFB_PLI, 1)
\
XX(RTCP_PSFB_PLI, 1)
\
XX(RTCP_PSFB_SLI, 2)
\
XX(RTCP_PSFB_SLI, 2)
\
XX(RTCP_PSFB_RPSI, 3)
\
XX(RTCP_PSFB_RPSI, 3)
\
XX(RTCP_PSFB_FIR, 4)
\
XX(RTCP_PSFB_FIR, 4)
\
XX(RTCP_PSFB_TSTR, 5)
\
XX(RTCP_PSFB_TSTR, 5)
\
XX(RTCP_PSFB_TSTN, 6)
\
XX(RTCP_PSFB_TSTN, 6)
\
XX(RTCP_PSFB_VBCM, 7)
\
XX(RTCP_PSFB_VBCM, 7)
\
XX(RTCP_PSFB_REMB, 15)
XX(RTCP_PSFB_REMB, 15)
//https://tools.ietf.org/html/rfc4585#section-6.2
//
https://tools.ietf.org/html/rfc4585#section-6.2
//6.2. Transport Layer Feedback Messages
//
6.2. Transport Layer Feedback Messages
//
//
// Transport layer FB messages are identified by the value RTPFB as RTCP
//
Transport layer FB messages are identified by the value RTPFB as RTCP
// message type.
//
message type.
//
//
// A single general purpose transport layer FB message is defined in
//
A single general purpose transport layer FB message is defined in
// this document: Generic NACK. It is identified by means of the FMT
//
this document: Generic NACK. It is identified by means of the FMT
// parameter as follows:
//
parameter as follows:
//
//
// 0: unassigned
//
0: unassigned
// 1: Generic NACK
//
1: Generic NACK
// 2: reserved https://tools.ietf.org/html/rfc5104#section-4.2
//
2: reserved https://tools.ietf.org/html/rfc5104#section-4.2
// 3: TMMBR https://tools.ietf.org/html/rfc5104#section-4.2.1.1
//
3: TMMBR https://tools.ietf.org/html/rfc5104#section-4.2.1.1
// 4: TMMBN https://tools.ietf.org/html/rfc5104#section-4.2.2.1
//
4: TMMBN https://tools.ietf.org/html/rfc5104#section-4.2.2.1
// 5-14: unassigned
//
5-14: unassigned
// 15 transport-cc https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
//
15 transport-cc https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
// 16-30: unassigned
//
16-30: unassigned
// 31: reserved for future expansion of the identifier number space
//
31: reserved for future expansion of the identifier number space
#define RTPFB_TYPE_MAP(XX) \
#define RTPFB_TYPE_MAP(XX)
\
XX(RTCP_RTPFB_NACK, 1)
\
XX(RTCP_RTPFB_NACK, 1)
\
XX(RTCP_RTPFB_TMMBR, 3)
\
XX(RTCP_RTPFB_TMMBR, 3)
\
XX(RTCP_RTPFB_TMMBN, 4)
\
XX(RTCP_RTPFB_TMMBN, 4)
\
XX(RTCP_RTPFB_TWCC, 15)
XX(RTCP_RTPFB_TWCC, 15)
//rtcp类型枚举
//
rtcp类型枚举
enum
class
RtcpType
:
uint8_t
{
enum
class
RtcpType
:
uint8_t
{
#define XX(key, value) key = value,
#define XX(key, value) key = value,
RTCP_PT_MAP
(
XX
)
RTCP_PT_MAP
(
XX
)
#undef XX
#undef XX
};
};
//sdes类型枚举
//
sdes类型枚举
enum
class
SdesType
:
uint8_t
{
enum
class
SdesType
:
uint8_t
{
#define XX(key, value) key = value,
#define XX(key, value) key = value,
SDES_TYPE_MAP
(
XX
)
SDES_TYPE_MAP
(
XX
)
#undef XX
#undef XX
};
};
//psfb类型枚举
//
psfb类型枚举
enum
class
PSFBType
:
uint8_t
{
enum
class
PSFBType
:
uint8_t
{
#define XX(key, value) key = value,
#define XX(key, value) key = value,
PSFB_TYPE_MAP
(
XX
)
PSFB_TYPE_MAP
(
XX
)
#undef XX
#undef XX
};
};
//rtpfb类型枚举
//
rtpfb类型枚举
enum
class
RTPFBType
:
uint8_t
{
enum
class
RTPFBType
:
uint8_t
{
#define XX(key, value) key = value,
#define XX(key, value) key = value,
RTPFB_TYPE_MAP
(
XX
)
RTPFB_TYPE_MAP
(
XX
)
...
@@ -161,26 +161,26 @@ const char *rtpfbTypeToStr(RTPFBType type);
...
@@ -161,26 +161,26 @@ const char *rtpfbTypeToStr(RTPFBType type);
class
RtcpHeader
{
class
RtcpHeader
{
public
:
public
:
#if __BYTE_ORDER == __BIG_ENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
//版本号,固定为2
//
版本号,固定为2
uint32_t
version
:
2
;
uint32_t
version
:
2
;
//padding,固定为0
//
padding,固定为0
uint32_t
padding
:
1
;
uint32_t
padding
:
1
;
//reception report count
//
reception report count
uint32_t
report_count
:
5
;
uint32_t
report_count
:
5
;
#else
#else
//reception report count
//
reception report count
uint32_t
report_count
:
5
;
uint32_t
report_count
:
5
;
//padding,末尾是否有追加填充
//
padding,末尾是否有追加填充
uint32_t
padding
:
1
;
uint32_t
padding
:
1
;
//版本号,固定为2
//
版本号,固定为2
uint32_t
version
:
2
;
uint32_t
version
:
2
;
#endif
#endif
//rtcp类型,RtcpType
//
rtcp类型,RtcpType
uint32_t
pt
:
8
;
uint32_t
pt
:
8
;
private
:
private
:
//长度
//
长度
uint32_t
length
:
16
;
uint32_t
length
:
16
;
public
:
public
:
/**
/**
...
@@ -222,7 +222,6 @@ public:
...
@@ -222,7 +222,6 @@ public:
void
setSize
(
size_t
size
);
void
setSize
(
size_t
size
);
protected
:
protected
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
...
@@ -240,26 +239,26 @@ private:
...
@@ -240,26 +239,26 @@ private:
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//ReportBlock
//
ReportBlock
class
ReportItem
{
class
ReportItem
{
public
:
public
:
friend
class
RtcpSR
;
friend
class
RtcpSR
;
friend
class
RtcpRR
;
friend
class
RtcpRR
;
uint32_t
ssrc
;
uint32_t
ssrc
;
//Fraction lost
//
Fraction lost
uint32_t
fraction
:
8
;
uint32_t
fraction
:
8
;
//Cumulative number of packets lost
//
Cumulative number of packets lost
uint32_t
cumulative
:
24
;
uint32_t
cumulative
:
24
;
//Sequence number cycles count
//
Sequence number cycles count
uint16_t
seq_cycles
;
uint16_t
seq_cycles
;
//Highest sequence number received
//
Highest sequence number received
uint16_t
seq_max
;
uint16_t
seq_max
;
//Interarrival jitter
//
Interarrival jitter
uint32_t
jitter
;
uint32_t
jitter
;
//Last SR timestamp, NTP timestamp,(ntpmsw & 0xFFFF) << 16 | (ntplsw >> 16) & 0xFFFF)
//
Last SR timestamp, NTP timestamp,(ntpmsw & 0xFFFF) << 16 | (ntplsw >> 16) & 0xFFFF)
uint32_t
last_sr_stamp
;
uint32_t
last_sr_stamp
;
//Delay since last SR timestamp,expressed in units of 1/65536 seconds
//
Delay since last SR timestamp,expressed in units of 1/65536 seconds
uint32_t
delay_since_last_sr
;
uint32_t
delay_since_last_sr
;
private
:
private
:
...
@@ -273,7 +272,7 @@ private:
...
@@ -273,7 +272,7 @@ private:
* 网络字节序转换为主机字节序
* 网络字节序转换为主机字节序
*/
*/
void
net2Host
();
void
net2Host
();
}
PACKED
;
}
PACKED
;
/*
/*
* 6.4.1 SR: Sender Report RTCP Packet
* 6.4.1 SR: Sender Report RTCP Packet
...
@@ -329,7 +328,7 @@ public:
...
@@ -329,7 +328,7 @@ public:
uint32_t
packet_count
;
uint32_t
packet_count
;
// sender octet count
// sender octet count
uint32_t
octet_count
;
uint32_t
octet_count
;
//可能有很多个
//
可能有很多个
ReportItem
items
;
ReportItem
items
;
public
:
public
:
...
@@ -358,13 +357,13 @@ public:
...
@@ -358,13 +357,13 @@ public:
* 获取ReportItem对象指针列表
* 获取ReportItem对象指针列表
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
vector
<
ReportItem
*>
getItemList
();
std
::
vector
<
ReportItem
*>
getItemList
();
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -406,13 +405,13 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...
@@ -406,13 +405,13 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
*/
//Receiver Report
//
Receiver Report
class
RtcpRR
:
public
RtcpHeader
{
class
RtcpRR
:
public
RtcpHeader
{
public
:
public
:
friend
class
RtcpHeader
;
friend
class
RtcpHeader
;
uint32_t
ssrc
;
uint32_t
ssrc
;
//可能有很多个
//
可能有很多个
ReportItem
items
;
ReportItem
items
;
public
:
public
:
...
@@ -420,14 +419,14 @@ public:
...
@@ -420,14 +419,14 @@ public:
* 创建RR包,只赋值了RtcpHeader部分
* 创建RR包,只赋值了RtcpHeader部分
* @param item_count ReportItem对象个数
* @param item_count ReportItem对象个数
* @return RR包
* @return RR包
*/
*/
static
std
::
shared_ptr
<
RtcpRR
>
create
(
size_t
item_count
);
static
std
::
shared_ptr
<
RtcpRR
>
create
(
size_t
item_count
);
/**
/**
* 获取ReportItem对象指针列表
* 获取ReportItem对象指针列表
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
vector
<
ReportItem
*>
getItemList
();
std
::
vector
<
ReportItem
*>
getItemList
();
private
:
private
:
/**
/**
...
@@ -475,20 +474,20 @@ SDES items 定义
...
@@ -475,20 +474,20 @@ SDES items 定义
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
*/
//Source description Chunk
//
Source description Chunk
class
SdesChunk
{
class
SdesChunk
{
public
:
public
:
friend
class
RtcpSdes
;
friend
class
RtcpSdes
;
uint32_t
ssrc
;
uint32_t
ssrc
;
//SdesType
//
SdesType
uint8_t
type
;
uint8_t
type
;
//text长度股,可以为0
//
text长度股,可以为0
uint8_t
txt_len
;
uint8_t
txt_len
;
//不定长
//
不定长
char
text
[
1
];
char
text
[
1
];
//最后以RTCP_SDES_END结尾
//
最后以RTCP_SDES_END结尾
//只字段为占位字段,不代表真实位置
//
只字段为占位字段,不代表真实位置
uint8_t
end
;
uint8_t
end
;
public
:
public
:
...
@@ -511,16 +510,16 @@ private:
...
@@ -511,16 +510,16 @@ private:
/**
/**
* 网络字节序转换为主机字节序
* 网络字节序转换为主机字节序
*/
*/
void
net2Host
();
void
net2Host
();
}
PACKED
;
}
PACKED
;
//Source description
//
Source description
class
RtcpSdes
:
public
RtcpHeader
{
class
RtcpSdes
:
public
RtcpHeader
{
public
:
public
:
friend
class
RtcpHeader
;
friend
class
RtcpHeader
;
//可能有很多个
//
可能有很多个
SdesChunk
chunks
;
SdesChunk
chunks
;
public
:
public
:
...
@@ -535,13 +534,13 @@ public:
...
@@ -535,13 +534,13 @@ public:
* 获取SdesChunk对象指针列表
* 获取SdesChunk对象指针列表
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
vector
<
SdesChunk
*>
getChunkList
();
std
::
vector
<
SdesChunk
*>
getChunkList
();
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -591,11 +590,11 @@ public:
...
@@ -591,11 +590,11 @@ public:
* @tparam Type 对象类型
* @tparam Type 对象类型
* @return 对象指针
* @return 对象指针
*/
*/
template
<
typename
Type
>
template
<
typename
Type
>
const
Type
&
getFci
()
const
{
const
Type
&
getFci
()
const
{
auto
fci_data
=
getFciPtr
();
auto
fci_data
=
getFciPtr
();
auto
fci_len
=
getFciSize
();
auto
fci_len
=
getFciSize
();
Type
*
fci
=
(
Type
*
)
fci_data
;
Type
*
fci
=
(
Type
*
)
fci_data
;
fci
->
check
(
fci_len
);
fci
->
check
(
fci_len
);
return
*
fci
;
return
*
fci
;
}
}
...
@@ -612,9 +611,9 @@ public:
...
@@ -612,9 +611,9 @@ public:
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -627,7 +626,7 @@ private:
...
@@ -627,7 +626,7 @@ private:
static
std
::
shared_ptr
<
RtcpFB
>
create_l
(
RtcpType
type
,
int
fmt
,
const
void
*
fci
,
size_t
fci_len
);
static
std
::
shared_ptr
<
RtcpFB
>
create_l
(
RtcpType
type
,
int
fmt
,
const
void
*
fci
,
size_t
fci_len
);
}
PACKED
;
}
PACKED
;
//BYE
//
BYE
/*
/*
0 1 2 3
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
...
@@ -675,9 +674,9 @@ public:
...
@@ -675,9 +674,9 @@ public:
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -712,8 +711,7 @@ private:
...
@@ -712,8 +711,7 @@ private:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
*/
class
RtcpXRRRTR
:
public
RtcpHeader
class
RtcpXRRRTR
:
public
RtcpHeader
{
{
public
:
public
:
friend
class
RtcpHeader
;
friend
class
RtcpHeader
;
uint32_t
ssrc
;
uint32_t
ssrc
;
...
@@ -722,15 +720,16 @@ public:
...
@@ -722,15 +720,16 @@ public:
uint8_t
reserved
;
uint8_t
reserved
;
// 2
// 2
uint16_t
block_length
;
uint16_t
block_length
;
// ntp timestamp MSW(in second)
// ntp timestamp MSW(in second)
uint32_t
ntpmsw
;
uint32_t
ntpmsw
;
// ntp timestamp LSW(in picosecond)
// ntp timestamp LSW(in picosecond)
uint32_t
ntplsw
;
uint32_t
ntplsw
;
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -739,7 +738,7 @@ private:
...
@@ -739,7 +738,7 @@ private:
*/
*/
void
net2Host
(
size_t
size
);
void
net2Host
(
size_t
size
);
}
PACKED
;
}
PACKED
;
/*
/*
...
@@ -759,18 +758,18 @@ private:
...
@@ -759,18 +758,18 @@ private:
: ... : 2
: ... : 2
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*/
*/
class
RtcpXRDLRRReportItem
class
RtcpXRDLRRReportItem
{
{
public
:
public
:
friend
class
RtcpXRDLRR
;
friend
class
RtcpXRDLRR
;
uint32_t
ssrc
;
uint32_t
ssrc
;
uint32_t
lrr
;
uint32_t
lrr
;
uint32_t
dlrr
;
uint32_t
dlrr
;
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -778,12 +777,9 @@ private:
...
@@ -778,12 +777,9 @@ private:
* @param size 字节长度,防止内存越界
* @param size 字节长度,防止内存越界
*/
*/
void
net2Host
();
void
net2Host
();
}
PACKED
;
}
PACKED
;
class
RtcpXRDLRR
:
public
RtcpHeader
class
RtcpXRDLRR
:
public
RtcpHeader
{
{
public
:
public
:
friend
class
RtcpHeader
;
friend
class
RtcpHeader
;
uint32_t
ssrc
;
uint32_t
ssrc
;
...
@@ -799,17 +795,17 @@ public:
...
@@ -799,17 +795,17 @@ public:
*/
*/
static
std
::
shared_ptr
<
RtcpXRDLRR
>
create
(
size_t
item_count
);
static
std
::
shared_ptr
<
RtcpXRDLRR
>
create
(
size_t
item_count
);
/**
/**
* 获取RtcpXRDLRRReportItem对象指针列表
* 获取RtcpXRDLRRReportItem对象指针列表
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
vector
<
RtcpXRDLRRReportItem
*>
getItemList
();
std
::
vector
<
RtcpXRDLRRReportItem
*>
getItemList
();
private
:
private
:
/**
/**
* 打印字段详情
* 打印字段详情
* 使用net2Host转换成主机字节序后才可使用此函数
* 使用net2Host转换成主机字节序后才可使用此函数
*/
*/
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
/**
/**
...
@@ -818,12 +814,11 @@ private:
...
@@ -818,12 +814,11 @@ private:
*/
*/
void
net2Host
(
size_t
size
);
void
net2Host
(
size_t
size
);
}
PACKED
;
}
PACKED
;
#if defined(_WIN32)
#if defined(_WIN32)
#pragma pack(pop)
#pragma pack(pop)
#endif // defined(_WIN32)
#endif // defined(_WIN32)
}
//namespace mediakit
}
//
namespace mediakit
#endif //ZLMEDIAKIT_RTCP_H
#endif //
ZLMEDIAKIT_RTCP_H
src/Rtcp/RtcpContext.cpp
查看文件 @
cffc0743
...
@@ -14,7 +14,8 @@ using namespace toolkit;
...
@@ -14,7 +14,8 @@ using namespace toolkit;
namespace
mediakit
{
namespace
mediakit
{
void
RtcpContext
::
onRtp
(
uint16_t
/*seq*/
,
uint32_t
stamp
,
uint64_t
ntp_stamp_ms
,
uint32_t
/*sample_rate*/
,
size_t
bytes
)
{
void
RtcpContext
::
onRtp
(
uint16_t
/*seq*/
,
uint32_t
stamp
,
uint64_t
ntp_stamp_ms
,
uint32_t
/*sample_rate*/
,
size_t
bytes
)
{
++
_packets
;
++
_packets
;
_bytes
+=
bytes
;
_bytes
+=
bytes
;
_last_rtp_stamp
=
stamp
;
_last_rtp_stamp
=
stamp
;
...
@@ -52,43 +53,45 @@ Buffer::Ptr RtcpContext::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc)
...
@@ -52,43 +53,45 @@ Buffer::Ptr RtcpContext::createRtcpXRDLRR(uint32_t rtcp_ssrc, uint32_t rtp_ssrc)
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void
RtcpContextForSend
::
onRtcp
(
RtcpHeader
*
rtcp
)
{
void
RtcpContextForSend
::
onRtcp
(
RtcpHeader
*
rtcp
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
case
RtcpType
:
:
RTCP_RR
:
{
case
RtcpType
:
:
RTCP_RR
:
{
auto
rtcp_rr
=
(
RtcpRR
*
)
rtcp
;
auto
rtcp_rr
=
(
RtcpRR
*
)
rtcp
;
for
(
auto
item
:
rtcp_rr
->
getItemList
())
{
for
(
auto
item
:
rtcp_rr
->
getItemList
())
{
if
(
!
item
->
last_sr_stamp
)
{
if
(
!
item
->
last_sr_stamp
)
{
continue
;
continue
;
}
auto
it
=
_sender_report_ntp
.
find
(
item
->
last_sr_stamp
);
if
(
it
==
_sender_report_ntp
.
end
())
{
continue
;
}
//发送sr到收到rr之间的时间戳增量
auto
ms_inc
=
getCurrentMillisecond
()
-
it
->
second
;
//rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒
auto
delay_ms
=
(
uint64_t
)
item
->
delay_since_last_sr
*
1000
/
65536
;
auto
rtt
=
(
int
)
(
ms_inc
-
delay_ms
);
if
(
rtt
>=
0
)
{
//rtt不可能小于0
_rtt
[
item
->
ssrc
]
=
rtt
;
//InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt;
}
}
}
break
;
auto
it
=
_sender_report_ntp
.
find
(
item
->
last_sr_stamp
);
}
if
(
it
==
_sender_report_ntp
.
end
())
{
case
RtcpType
:
:
RTCP_XR
:
{
continue
;
auto
rtcp_xr
=
(
RtcpXRRRTR
*
)
rtcp
;
}
if
(
rtcp_xr
->
bt
==
4
){
// 发送sr到收到rr之间的时间戳增量
_xr_xrrtr_recv_last_rr
[
rtcp_xr
->
ssrc
]
=
((
rtcp_xr
->
ntpmsw
&
0xFFFF
)
<<
16
)
|
((
rtcp_xr
->
ntplsw
>>
16
)
&
0xFFFF
);
auto
ms_inc
=
getCurrentMillisecond
()
-
it
->
second
;
_xr_rrtr_recv_sys_stamp
[
rtcp_xr
->
ssrc
]
=
getCurrentMillisecond
();
// rtp接收端收到sr包后,回复rr包的延时,已转换为毫秒
}
else
if
(
rtcp_xr
->
bt
==
5
){
auto
delay_ms
=
(
uint64_t
)
item
->
delay_since_last_sr
*
1000
/
65536
;
TraceL
<<
"for sender not recive dlrr"
;
auto
rtt
=
(
int
)(
ms_inc
-
delay_ms
);
}
else
{
if
(
rtt
>=
0
)
{
TraceL
<<
"not support xr bt "
<<
rtcp_xr
->
bt
;
// rtt不可能小于0
_rtt
[
item
->
ssrc
]
=
rtt
;
// InfoL << "ssrc:" << item->ssrc << ",rtt:" << rtt;
}
}
break
;
}
}
default
:
break
;
break
;
}
case
RtcpType
:
:
RTCP_XR
:
{
auto
rtcp_xr
=
(
RtcpXRRRTR
*
)
rtcp
;
if
(
rtcp_xr
->
bt
==
4
)
{
_xr_xrrtr_recv_last_rr
[
rtcp_xr
->
ssrc
]
=
((
rtcp_xr
->
ntpmsw
&
0xFFFF
)
<<
16
)
|
((
rtcp_xr
->
ntplsw
>>
16
)
&
0xFFFF
);
_xr_rrtr_recv_sys_stamp
[
rtcp_xr
->
ssrc
]
=
getCurrentMillisecond
();
}
else
if
(
rtcp_xr
->
bt
==
5
)
{
TraceL
<<
"for sender not recive dlrr"
;
}
else
{
TraceL
<<
"not support xr bt "
<<
rtcp_xr
->
bt
;
}
break
;
}
default
:
break
;
}
}
}
}
...
@@ -105,21 +108,21 @@ Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) {
...
@@ -105,21 +108,21 @@ Buffer::Ptr RtcpContextForSend::createRtcpSR(uint32_t rtcp_ssrc) {
rtcp
->
setNtpStamp
(
_last_ntp_stamp_ms
);
rtcp
->
setNtpStamp
(
_last_ntp_stamp_ms
);
rtcp
->
rtpts
=
htonl
(
_last_rtp_stamp
);
rtcp
->
rtpts
=
htonl
(
_last_rtp_stamp
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
rtcp
->
packet_count
=
htonl
((
uint32_t
)
_packets
);
rtcp
->
packet_count
=
htonl
((
uint32_t
)
_packets
);
rtcp
->
octet_count
=
htonl
((
uint32_t
)
_bytes
);
rtcp
->
octet_count
=
htonl
((
uint32_t
)
_bytes
);
//记录上次发送的sender report信息,用于后续统计rtt
//
记录上次发送的sender report信息,用于后续统计rtt
auto
last_sr_lsr
=
((
ntohl
(
rtcp
->
ntpmsw
)
&
0xFFFF
)
<<
16
)
|
((
ntohl
(
rtcp
->
ntplsw
)
>>
16
)
&
0xFFFF
);
auto
last_sr_lsr
=
((
ntohl
(
rtcp
->
ntpmsw
)
&
0xFFFF
)
<<
16
)
|
((
ntohl
(
rtcp
->
ntplsw
)
>>
16
)
&
0xFFFF
);
_sender_report_ntp
[
last_sr_lsr
]
=
getCurrentMillisecond
();
_sender_report_ntp
[
last_sr_lsr
]
=
getCurrentMillisecond
();
if
(
_sender_report_ntp
.
size
()
>=
5
)
{
if
(
_sender_report_ntp
.
size
()
>=
5
)
{
//删除最早的sr rtcp
//
删除最早的sr rtcp
_sender_report_ntp
.
erase
(
_sender_report_ntp
.
begin
());
_sender_report_ntp
.
erase
(
_sender_report_ntp
.
begin
());
}
}
return
RtcpHeader
::
toBuffer
(
std
::
move
(
rtcp
));
return
RtcpHeader
::
toBuffer
(
std
::
move
(
rtcp
));
}
}
toolkit
::
Buffer
::
Ptr
RtcpContextForSend
::
createRtcpXRDLRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
){
toolkit
::
Buffer
::
Ptr
RtcpContextForSend
::
createRtcpXRDLRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
)
{
auto
rtcp
=
RtcpXRDLRR
::
create
(
1
);
auto
rtcp
=
RtcpXRDLRR
::
create
(
1
);
rtcp
->
bt
=
5
;
rtcp
->
bt
=
5
;
rtcp
->
reserved
=
0
;
rtcp
->
reserved
=
0
;
...
@@ -127,14 +130,14 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui
...
@@ -127,14 +130,14 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
rtcp
->
items
.
ssrc
=
htonl
(
rtp_ssrc
);
rtcp
->
items
.
ssrc
=
htonl
(
rtp_ssrc
);
if
(
_xr_xrrtr_recv_last_rr
.
find
(
rtp_ssrc
)
==
_xr_xrrtr_recv_last_rr
.
end
())
{
if
(
_xr_xrrtr_recv_last_rr
.
find
(
rtp_ssrc
)
==
_xr_xrrtr_recv_last_rr
.
end
())
{
rtcp
->
items
.
lrr
=
0
;
rtcp
->
items
.
lrr
=
0
;
WarnL
;
WarnL
;
}
else
{
}
else
{
rtcp
->
items
.
lrr
=
htonl
(
_xr_xrrtr_recv_last_rr
[
rtp_ssrc
]);
rtcp
->
items
.
lrr
=
htonl
(
_xr_xrrtr_recv_last_rr
[
rtp_ssrc
]);
}
}
if
(
_xr_rrtr_recv_sys_stamp
.
find
(
rtp_ssrc
)
==
_xr_rrtr_recv_sys_stamp
.
end
())
{
if
(
_xr_rrtr_recv_sys_stamp
.
find
(
rtp_ssrc
)
==
_xr_rrtr_recv_sys_stamp
.
end
())
{
rtcp
->
items
.
dlrr
=
0
;
rtcp
->
items
.
dlrr
=
0
;
WarnL
;
WarnL
;
}
else
{
}
else
{
...
@@ -149,39 +152,41 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui
...
@@ -149,39 +152,41 @@ toolkit::Buffer::Ptr RtcpContextForSend::createRtcpXRDLRR(uint32_t rtcp_ssrc, ui
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void
RtcpContextForRecv
::
onRtp
(
uint16_t
seq
,
uint32_t
stamp
,
uint64_t
ntp_stamp_ms
,
uint32_t
sample_rate
,
size_t
bytes
)
{
void
RtcpContextForRecv
::
onRtp
(
uint16_t
seq
,
uint32_t
stamp
,
uint64_t
ntp_stamp_ms
,
uint32_t
sample_rate
,
size_t
bytes
)
{
{
{
//接收者才做复杂的统计运算
//
接收者才做复杂的统计运算
auto
sys_stamp
=
getCurrentMillisecond
();
auto
sys_stamp
=
getCurrentMillisecond
();
if
(
_last_rtp_sys_stamp
)
{
if
(
_last_rtp_sys_stamp
)
{
//计算时间戳抖动值
// 计算时间戳抖动值
double
diff
=
double
((
int64_t
(
sys_stamp
)
-
int64_t
(
_last_rtp_sys_stamp
))
*
(
sample_rate
/
double
(
1000.0
))
double
diff
=
double
(
-
(
int64_t
(
stamp
)
-
int64_t
(
_last_rtp_stamp
)));
(
int64_t
(
sys_stamp
)
-
int64_t
(
_last_rtp_sys_stamp
))
*
(
sample_rate
/
double
(
1000.0
))
-
(
int64_t
(
stamp
)
-
int64_t
(
_last_rtp_stamp
)));
if
(
diff
<
0
)
{
if
(
diff
<
0
)
{
diff
=
-
diff
;
diff
=
-
diff
;
}
}
//抖动单位为采样次数
//
抖动单位为采样次数
_jitter
+=
(
diff
-
_jitter
)
/
16.0
;
_jitter
+=
(
diff
-
_jitter
)
/
16.0
;
}
else
{
}
else
{
_jitter
=
0
;
_jitter
=
0
;
}
}
if
(
_last_rtp_seq
>
0xFF00
&&
seq
<
0xFF
&&
(
!
_seq_cycles
||
_packets
-
_last_cycle_packets
>
0x1FFF
))
{
if
(
_last_rtp_seq
>
0xFF00
&&
seq
<
0xFF
&&
(
!
_seq_cycles
||
_packets
-
_last_cycle_packets
>
0x1FFF
))
{
//上次seq大于0xFF00且本次seq小于0xFF,
//
上次seq大于0xFF00且本次seq小于0xFF,
//且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环
//
且未发生回环或者距离上次回环间隔超过0x1FFF个包,则认为回环
++
_seq_cycles
;
++
_seq_cycles
;
_last_cycle_packets
=
_packets
;
_last_cycle_packets
=
_packets
;
_seq_max
=
seq
;
_seq_max
=
seq
;
}
else
if
(
seq
>
_seq_max
)
{
}
else
if
(
seq
>
_seq_max
)
{
//本次回环前最大seq
//
本次回环前最大seq
_seq_max
=
seq
;
_seq_max
=
seq
;
}
}
if
(
!
_seq_base
)
{
if
(
!
_seq_base
)
{
//记录第一个rtp的seq
//
记录第一个rtp的seq
_seq_base
=
seq
;
_seq_base
=
seq
;
}
else
if
(
!
_seq_cycles
&&
seq
<
_seq_base
)
{
}
else
if
(
!
_seq_cycles
&&
seq
<
_seq_base
)
{
//未发生回环,那么取最新的seq为基准seq
//
未发生回环,那么取最新的seq为基准seq
_seq_base
=
seq
;
_seq_base
=
seq
;
}
}
...
@@ -192,21 +197,22 @@ void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_
...
@@ -192,21 +197,22 @@ void RtcpContextForRecv::onRtp(uint16_t seq, uint32_t stamp, uint64_t ntp_stamp_
}
}
void
RtcpContextForRecv
::
onRtcp
(
RtcpHeader
*
rtcp
)
{
void
RtcpContextForRecv
::
onRtcp
(
RtcpHeader
*
rtcp
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
case
RtcpType
:
:
RTCP_SR
:
{
case
RtcpType
:
:
RTCP_SR
:
{
auto
rtcp_sr
=
(
RtcpSR
*
)
rtcp
;
auto
rtcp_sr
=
(
RtcpSR
*
)
rtcp
;
/**
/**
last SR timestamp (LSR): 32 bits
last SR timestamp (LSR): 32 bits
The middle 32 bits out of 64 in the NTP timestamp (as explained in
The middle 32 bits out of 64 in the NTP timestamp (as explained in
Section 4) received as part of the most recent RTCP sender report
Section 4) received as part of the most recent RTCP sender report
(SR) packet from source SSRC_n. If no SR has been received yet,
(SR) packet from source SSRC_n. If no SR has been received yet,
the field is set to zero.
the field is set to zero.
*/
*/
_last_sr_lsr
=
((
rtcp_sr
->
ntpmsw
&
0xFFFF
)
<<
16
)
|
((
rtcp_sr
->
ntplsw
>>
16
)
&
0xFFFF
);
_last_sr_lsr
=
((
rtcp_sr
->
ntpmsw
&
0xFFFF
)
<<
16
)
|
((
rtcp_sr
->
ntplsw
>>
16
)
&
0xFFFF
);
_last_sr_ntp_sys
=
getCurrentMillisecond
();
_last_sr_ntp_sys
=
getCurrentMillisecond
();
break
;
break
;
}
}
default
:
break
;
default
:
break
;
}
}
}
}
...
@@ -236,7 +242,7 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss
...
@@ -236,7 +242,7 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss
auto
rtcp
=
RtcpRR
::
create
(
1
);
auto
rtcp
=
RtcpRR
::
create
(
1
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
rtcp
->
ssrc
=
htonl
(
rtcp_ssrc
);
ReportItem
*
item
=
(
ReportItem
*
)
&
rtcp
->
items
;
ReportItem
*
item
=
(
ReportItem
*
)
&
rtcp
->
items
;
item
->
ssrc
=
htonl
(
rtp_ssrc
);
item
->
ssrc
=
htonl
(
rtp_ssrc
);
uint8_t
fraction
=
0
;
uint8_t
fraction
=
0
;
...
@@ -255,9 +261,9 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss
...
@@ -255,9 +261,9 @@ Buffer::Ptr RtcpContextForRecv::createRtcpRR(uint32_t rtcp_ssrc, uint32_t rtp_ss
// now - Last SR time,单位毫秒
// now - Last SR time,单位毫秒
auto
delay
=
getCurrentMillisecond
()
-
_last_sr_ntp_sys
;
auto
delay
=
getCurrentMillisecond
()
-
_last_sr_ntp_sys
;
// in units of 1/65536 seconds
// in units of 1/65536 seconds
auto
dlsr
=
(
uint32_t
)
(
delay
/
1000.0
f
*
65536
);
auto
dlsr
=
(
uint32_t
)(
delay
/
1000.0
f
*
65536
);
item
->
delay_since_last_sr
=
htonl
(
_last_sr_lsr
?
dlsr
:
0
);
item
->
delay_since_last_sr
=
htonl
(
_last_sr_lsr
?
dlsr
:
0
);
return
RtcpHeader
::
toBuffer
(
rtcp
);
return
RtcpHeader
::
toBuffer
(
rtcp
);
}
}
}
//
namespace
mediakit
}
//
namespace
mediakit
\ No newline at end of file
\ No newline at end of file
src/Rtcp/RtcpContext.h
查看文件 @
cffc0743
...
@@ -11,9 +11,9 @@
...
@@ -11,9 +11,9 @@
#ifndef ZLMEDIAKIT_RTCPCONTEXT_H
#ifndef ZLMEDIAKIT_RTCPCONTEXT_H
#define ZLMEDIAKIT_RTCPCONTEXT_H
#define ZLMEDIAKIT_RTCPCONTEXT_H
#include <stdint.h>
#include <stddef.h>
#include "Rtcp.h"
#include "Rtcp.h"
#include <stddef.h>
#include <stdint.h>
namespace
mediakit
{
namespace
mediakit
{
...
@@ -55,11 +55,10 @@ public:
...
@@ -55,11 +55,10 @@ public:
*/
*/
virtual
toolkit
::
Buffer
::
Ptr
createRtcpSR
(
uint32_t
rtcp_ssrc
);
virtual
toolkit
::
Buffer
::
Ptr
createRtcpSR
(
uint32_t
rtcp_ssrc
);
/**
/**
* @brief 创建xr的dlrr包,用于接收者估算rtt
* @brief 创建xr的dlrr包,用于接收者估算rtt
*
*
* @return toolkit::Buffer::Ptr
* @return toolkit::Buffer::Ptr
*/
*/
virtual
toolkit
::
Buffer
::
Ptr
createRtcpXRDLRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
);
virtual
toolkit
::
Buffer
::
Ptr
createRtcpXRDLRR
(
uint32_t
rtcp_ssrc
,
uint32_t
rtp_ssrc
);
...
@@ -82,11 +81,11 @@ public:
...
@@ -82,11 +81,11 @@ public:
virtual
size_t
geLostInterval
();
virtual
size_t
geLostInterval
();
protected
:
protected
:
//收到或发送的rtp的字节数
//
收到或发送的rtp的字节数
size_t
_bytes
=
0
;
size_t
_bytes
=
0
;
//收到或发送的rtp的个数
//
收到或发送的rtp的个数
size_t
_packets
=
0
;
size_t
_packets
=
0
;
//上次的rtp时间戳,毫秒
//
上次的rtp时间戳,毫秒
uint32_t
_last_rtp_stamp
=
0
;
uint32_t
_last_rtp_stamp
=
0
;
uint64_t
_last_ntp_stamp_ms
=
0
;
uint64_t
_last_ntp_stamp_ms
=
0
;
};
};
...
@@ -107,11 +106,11 @@ public:
...
@@ -107,11 +106,11 @@ public:
uint32_t
getRtt
(
uint32_t
ssrc
)
const
;
uint32_t
getRtt
(
uint32_t
ssrc
)
const
;
private
:
private
:
std
::
map
<
uint32_t
/*ssrc*/
,
uint32_t
/*rtt*/
>
_rtt
;
std
::
map
<
uint32_t
/*ssrc*/
,
uint32_t
/*rtt*/
>
_rtt
;
std
::
map
<
uint32_t
/*last_sr_lsr*/
,
uint64_t
/*ntp stamp*/
>
_sender_report_ntp
;
std
::
map
<
uint32_t
/*last_sr_lsr*/
,
uint64_t
/*ntp stamp*/
>
_sender_report_ntp
;
std
::
map
<
uint32_t
/*ssrc*/
,
uint64_t
/*xr rrtr sys stamp*/
>
_xr_rrtr_recv_sys_stamp
;
std
::
map
<
uint32_t
/*ssrc*/
,
uint64_t
/*xr rrtr sys stamp*/
>
_xr_rrtr_recv_sys_stamp
;
std
::
map
<
uint32_t
/*ssrc*/
,
uint32_t
/*last rr */
>
_xr_xrrtr_recv_last_rr
;
std
::
map
<
uint32_t
/*ssrc*/
,
uint32_t
/*last rr */
>
_xr_xrrtr_recv_last_rr
;
};
};
class
RtcpContextForRecv
:
public
RtcpContext
{
class
RtcpContextForRecv
:
public
RtcpContext
{
...
@@ -125,29 +124,29 @@ public:
...
@@ -125,29 +124,29 @@ public:
void
onRtcp
(
RtcpHeader
*
rtcp
)
override
;
void
onRtcp
(
RtcpHeader
*
rtcp
)
override
;
private
:
private
:
//时间戳抖动值
//
时间戳抖动值
double
_jitter
=
0
;
double
_jitter
=
0
;
//第一个seq的值
//
第一个seq的值
uint16_t
_seq_base
=
0
;
uint16_t
_seq_base
=
0
;
//rtp最大seq
//
rtp最大seq
uint16_t
_seq_max
=
0
;
uint16_t
_seq_max
=
0
;
//rtp回环次数
//
rtp回环次数
uint16_t
_seq_cycles
=
0
;
uint16_t
_seq_cycles
=
0
;
//上次回环发生时,记录的rtp包数
//
上次回环发生时,记录的rtp包数
size_t
_last_cycle_packets
=
0
;
size_t
_last_cycle_packets
=
0
;
//上次的seq
//
上次的seq
uint16_t
_last_rtp_seq
=
0
;
uint16_t
_last_rtp_seq
=
0
;
//上次的rtp的系统时间戳(毫秒)用于统计抖动
//
上次的rtp的系统时间戳(毫秒)用于统计抖动
uint64_t
_last_rtp_sys_stamp
=
0
;
uint64_t
_last_rtp_sys_stamp
=
0
;
//上次统计的丢包总数
//
上次统计的丢包总数
size_t
_last_lost
=
0
;
size_t
_last_lost
=
0
;
//上次统计应收rtp包总数
//
上次统计应收rtp包总数
size_t
_last_expected
=
0
;
size_t
_last_expected
=
0
;
//上次收到sr包时计算出的Last SR timestamp
//
上次收到sr包时计算出的Last SR timestamp
uint32_t
_last_sr_lsr
=
0
;
uint32_t
_last_sr_lsr
=
0
;
//上次收到sr时的系统时间戳,单位毫秒
//
上次收到sr时的系统时间戳,单位毫秒
uint64_t
_last_sr_ntp_sys
=
0
;
uint64_t
_last_sr_ntp_sys
=
0
;
};
};
}
//
namespace mediakit
}
//
namespace mediakit
#endif //ZLMEDIAKIT_RTCPCONTEXT_H
#endif //
ZLMEDIAKIT_RTCPCONTEXT_H
src/Rtcp/RtcpFCI.cpp
查看文件 @
cffc0743
...
@@ -16,16 +16,16 @@ using namespace toolkit;
...
@@ -16,16 +16,16 @@ using namespace toolkit;
namespace
mediakit
{
namespace
mediakit
{
void
FCI_SLI
::
check
(
size_t
size
){
void
FCI_SLI
::
check
(
size_t
size
)
{
CHECK
(
size
>=
kSize
);
CHECK
(
size
>=
kSize
);
}
}
FCI_SLI
::
FCI_SLI
(
uint16_t
first
,
uint16_t
number
,
uint8_t
pic_id
)
{
FCI_SLI
::
FCI_SLI
(
uint16_t
first
,
uint16_t
number
,
uint8_t
pic_id
)
{
//13 bits
//
13 bits
first
&=
0x1FFF
;
first
&=
0x1FFF
;
//13 bits
//
13 bits
number
&=
0x1FFF
;
number
&=
0x1FFF
;
//6 bits
//
6 bits
pic_id
&=
0x3F
;
pic_id
&=
0x3F
;
data
=
(
first
<<
19
)
|
(
number
<<
6
)
|
pic_id
;
data
=
(
first
<<
19
)
|
(
number
<<
6
)
|
pic_id
;
data
=
htonl
(
data
);
data
=
htonl
(
data
);
...
@@ -49,19 +49,19 @@ string FCI_SLI::dumpString() const {
...
@@ -49,19 +49,19 @@ string FCI_SLI::dumpString() const {
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
FCI_FIR
::
check
(
size_t
size
){
void
FCI_FIR
::
check
(
size_t
size
)
{
CHECK
(
size
>=
kSize
);
CHECK
(
size
>=
kSize
);
}
}
uint32_t
FCI_FIR
::
getSSRC
()
const
{
uint32_t
FCI_FIR
::
getSSRC
()
const
{
return
ntohl
(
ssrc
);
return
ntohl
(
ssrc
);
}
}
uint8_t
FCI_FIR
::
getSeq
()
const
{
uint8_t
FCI_FIR
::
getSeq
()
const
{
return
seq_number
;
return
seq_number
;
}
}
uint32_t
FCI_FIR
::
getReserved
()
const
{
uint32_t
FCI_FIR
::
getReserved
()
const
{
return
(
reserved
[
0
]
<<
16
)
|
(
reserved
[
1
]
<<
8
)
|
reserved
[
2
];
return
(
reserved
[
0
]
<<
16
)
|
(
reserved
[
1
]
<<
8
)
|
reserved
[
2
];
}
}
...
@@ -81,7 +81,7 @@ FCI_FIR::FCI_FIR(uint32_t ssrc, uint8_t seq_number, uint32_t reserved) {
...
@@ -81,7 +81,7 @@ FCI_FIR::FCI_FIR(uint32_t ssrc, uint8_t seq_number, uint32_t reserved) {
static
const
char
kRembMagic
[]
=
"REMB"
;
static
const
char
kRembMagic
[]
=
"REMB"
;
void
FCI_REMB
::
check
(
size_t
size
){
void
FCI_REMB
::
check
(
size_t
size
)
{
CHECK
(
size
>=
kSize
);
CHECK
(
size
>=
kSize
);
CHECK
(
memcmp
(
magic
,
kRembMagic
,
sizeof
(
magic
))
==
0
);
CHECK
(
memcmp
(
magic
,
kRembMagic
,
sizeof
(
magic
))
==
0
);
auto
num_ssrc
=
bitrate
[
0
];
auto
num_ssrc
=
bitrate
[
0
];
...
@@ -93,7 +93,7 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
...
@@ -93,7 +93,7 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
CHECK
(
ssrcs
.
size
()
>
0
&&
ssrcs
.
size
()
<=
0xFF
);
CHECK
(
ssrcs
.
size
()
>
0
&&
ssrcs
.
size
()
<=
0xFF
);
string
ret
;
string
ret
;
ret
.
resize
(
kSize
+
ssrcs
.
size
()
*
4
);
ret
.
resize
(
kSize
+
ssrcs
.
size
()
*
4
);
FCI_REMB
*
thiz
=
(
FCI_REMB
*
)
ret
.
data
();
FCI_REMB
*
thiz
=
(
FCI_REMB
*
)
ret
.
data
();
memcpy
(
thiz
->
magic
,
kRembMagic
,
sizeof
(
magic
));
memcpy
(
thiz
->
magic
,
kRembMagic
,
sizeof
(
magic
));
/* bitrate --> BR Exp/BR Mantissa */
/* bitrate --> BR Exp/BR Mantissa */
...
@@ -101,7 +101,7 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
...
@@ -101,7 +101,7 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
uint8_t
exp
=
0
;
uint8_t
exp
=
0
;
uint32_t
mantissa
=
0
;
uint32_t
mantissa
=
0
;
for
(
b
=
0
;
b
<
32
;
b
++
)
{
for
(
b
=
0
;
b
<
32
;
b
++
)
{
if
(
bitrate
<=
((
uint32_t
)
0x3FFFF
<<
b
))
{
if
(
bitrate
<=
((
uint32_t
)
0x3FFFF
<<
b
))
{
exp
=
b
;
exp
=
b
;
break
;
break
;
}
}
...
@@ -110,16 +110,16 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
...
@@ -110,16 +110,16 @@ string FCI_REMB::create(const vector<uint32_t> &ssrcs, uint32_t bitrate) {
b
=
31
;
b
=
31
;
}
}
mantissa
=
bitrate
>>
b
;
mantissa
=
bitrate
>>
b
;
//Num SSRC (8 bits)
//
Num SSRC (8 bits)
thiz
->
bitrate
[
0
]
=
ssrcs
.
size
()
&
0xFF
;
thiz
->
bitrate
[
0
]
=
ssrcs
.
size
()
&
0xFF
;
//BR Exp (6 bits)/BR Mantissa (18 bits)
//
BR Exp (6 bits)/BR Mantissa (18 bits)
thiz
->
bitrate
[
1
]
=
(
uint8_t
)
((
exp
<<
2
)
+
((
mantissa
>>
16
)
&
0x03
));
thiz
->
bitrate
[
1
]
=
(
uint8_t
)((
exp
<<
2
)
+
((
mantissa
>>
16
)
&
0x03
));
//BR Mantissa (18 bits)
//
BR Mantissa (18 bits)
thiz
->
bitrate
[
2
]
=
(
uint8_t
)
(
mantissa
>>
8
);
thiz
->
bitrate
[
2
]
=
(
uint8_t
)(
mantissa
>>
8
);
//BR Mantissa (18 bits)
//
BR Mantissa (18 bits)
thiz
->
bitrate
[
3
]
=
(
uint8_t
)
(
mantissa
);
thiz
->
bitrate
[
3
]
=
(
uint8_t
)(
mantissa
);
//设置ssrc列表
//
设置ssrc列表
int
i
=
0
;
int
i
=
0
;
for
(
auto
ssrc
:
ssrcs
)
{
for
(
auto
ssrc
:
ssrcs
)
{
thiz
->
ssrc_feedback
[
i
++
]
=
htonl
(
ssrc
);
thiz
->
ssrc_feedback
[
i
++
]
=
htonl
(
ssrc
);
...
@@ -149,7 +149,7 @@ vector<uint32_t> FCI_REMB::getSSRC() {
...
@@ -149,7 +149,7 @@ vector<uint32_t> FCI_REMB::getSSRC() {
string
FCI_REMB
::
dumpString
()
const
{
string
FCI_REMB
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"bitrate:"
<<
getBitRate
()
<<
", ssrc:"
;
printer
<<
"bitrate:"
<<
getBitRate
()
<<
", ssrc:"
;
for
(
auto
&
ssrc
:
((
FCI_REMB
*
)
this
)
->
getSSRC
())
{
for
(
auto
&
ssrc
:
((
FCI_REMB
*
)
this
)
->
getSSRC
())
{
printer
<<
ssrc
<<
" "
;
printer
<<
ssrc
<<
" "
;
}
}
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
...
@@ -171,7 +171,7 @@ FCI_NACK::FCI_NACK(uint16_t pid_h, const vector<bool> &type) {
...
@@ -171,7 +171,7 @@ FCI_NACK::FCI_NACK(uint16_t pid_h, const vector<bool> &type) {
pid
=
htons
(
pid_h
);
pid
=
htons
(
pid_h
);
}
}
void
FCI_NACK
::
check
(
size_t
size
){
void
FCI_NACK
::
check
(
size_t
size
)
{
CHECK
(
size
>=
kSize
);
CHECK
(
size
>=
kSize
);
}
}
...
@@ -186,7 +186,7 @@ uint16_t FCI_NACK::getBlp() const {
...
@@ -186,7 +186,7 @@ uint16_t FCI_NACK::getBlp() const {
vector
<
bool
>
FCI_NACK
::
getBitArray
()
const
{
vector
<
bool
>
FCI_NACK
::
getBitArray
()
const
{
vector
<
bool
>
ret
;
vector
<
bool
>
ret
;
ret
.
resize
(
kBitSize
+
1
);
ret
.
resize
(
kBitSize
+
1
);
//nack第一个包丢包
//
nack第一个包丢包
ret
[
0
]
=
true
;
ret
[
0
]
=
true
;
auto
blp_h
=
getBlp
();
auto
blp_h
=
getBlp
();
...
@@ -220,25 +220,25 @@ public:
...
@@ -220,25 +220,25 @@ public:
// |T| S | Run Length |
// |T| S | Run Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#if __BYTE_ORDER == __BIG_ENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
uint16_t
type
:
1
;
uint16_t
type
:
1
;
uint16_t
symbol
:
2
;
uint16_t
symbol
:
2
;
uint16_t
run_length_high
:
5
;
uint16_t
run_length_high
:
5
;
#else
#else
// Run Length 高5位
// Run Length 高5位
uint16_t
run_length_high
:
5
;
uint16_t
run_length_high
:
5
;
//参考SymbolStatus定义
//
参考SymbolStatus定义
uint16_t
symbol
:
2
;
uint16_t
symbol
:
2
;
//固定为0
//
固定为0
uint16_t
type
:
1
;
uint16_t
type
:
1
;
#endif
#endif
// Run Length 低8位
// Run Length 低8位
uint16_t
run_length_low
:
8
;
uint16_t
run_length_low
:
8
;
//获取Run Length
//
获取Run Length
uint16_t
getRunLength
()
const
;
uint16_t
getRunLength
()
const
;
//构造函数
//
构造函数
RunLengthChunk
(
SymbolStatus
status
,
uint16_t
run_length
);
RunLengthChunk
(
SymbolStatus
status
,
uint16_t
run_length
);
//打印本对象
//
打印本对象
string
dumpString
()
const
;
string
dumpString
()
const
;
}
PACKED
;
}
PACKED
;
...
@@ -254,7 +254,7 @@ uint16_t RunLengthChunk::getRunLength() const {
...
@@ -254,7 +254,7 @@ uint16_t RunLengthChunk::getRunLength() const {
return
run_length_high
<<
8
|
run_length_low
;
return
run_length_high
<<
8
|
run_length_low
;
}
}
string
RunLengthChunk
::
dumpString
()
const
{
string
RunLengthChunk
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"run length chunk, symbol:"
<<
(
int
)
symbol
<<
", run length:"
<<
getRunLength
();
printer
<<
"run length chunk, symbol:"
<<
(
int
)
symbol
<<
", run length:"
<<
getRunLength
();
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
...
@@ -271,30 +271,30 @@ public:
...
@@ -271,30 +271,30 @@ public:
// |T|S| symbol list |
// |T|S| symbol list |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#if __BYTE_ORDER == __BIG_ENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
uint16_t
type
:
1
;
uint16_t
type
:
1
;
uint16_t
symbol
:
1
;
uint16_t
symbol
:
1
;
uint16_t
symbol_list_high
:
6
;
uint16_t
symbol_list_high
:
6
;
#else
#else
// symbol_list 高6位
// symbol_list 高6位
uint16_t
symbol_list_high
:
6
;
uint16_t
symbol_list_high
:
6
;
//symbol_list中元素是1个还是2个bit
//
symbol_list中元素是1个还是2个bit
uint16_t
symbol
:
1
;
uint16_t
symbol
:
1
;
//固定为1
//
固定为1
uint16_t
type
:
1
;
uint16_t
type
:
1
;
#endif
#endif
// symbol_list 低8位
// symbol_list 低8位
uint16_t
symbol_list_low
:
8
;
uint16_t
symbol_list_low
:
8
;
//获取symbollist
//
获取symbollist
vector
<
SymbolStatus
>
getSymbolList
()
const
;
vector
<
SymbolStatus
>
getSymbolList
()
const
;
//构造函数
//
构造函数
StatusVecChunk
(
bool
symbol_bit
,
const
vector
<
SymbolStatus
>
&
status
);
StatusVecChunk
(
bool
symbol_bit
,
const
vector
<
SymbolStatus
>
&
status
);
//打印本对象
//
打印本对象
string
dumpString
()
const
;
string
dumpString
()
const
;
}
PACKED
;
}
PACKED
;
StatusVecChunk
::
StatusVecChunk
(
bool
symbol_bit
,
const
vector
<
SymbolStatus
>
&
status
)
{
StatusVecChunk
::
StatusVecChunk
(
bool
symbol_bit
,
const
vector
<
SymbolStatus
>
&
status
)
{
CHECK
(
status
.
size
()
<<
symbol_bit
<=
14
);
CHECK
(
status
.
size
()
<<
symbol_bit
<=
14
);
uint16_t
value
=
0
;
uint16_t
value
=
0
;
type
=
1
;
type
=
1
;
symbol
=
symbol_bit
;
symbol
=
symbol_bit
;
...
@@ -303,31 +303,31 @@ StatusVecChunk::StatusVecChunk(bool symbol_bit, const vector<SymbolStatus> &stat
...
@@ -303,31 +303,31 @@ StatusVecChunk::StatusVecChunk(bool symbol_bit, const vector<SymbolStatus> &stat
CHECK
(
item
<=
SymbolStatus
::
reserved
);
CHECK
(
item
<=
SymbolStatus
::
reserved
);
if
(
!
symbol
)
{
if
(
!
symbol
)
{
CHECK
(
item
<=
SymbolStatus
::
small_delta
);
CHECK
(
item
<=
SymbolStatus
::
small_delta
);
value
|=
(
int
)
item
<<
i
;
value
|=
(
int
)
item
<<
i
;
--
i
;
--
i
;
}
else
{
}
else
{
value
|=
(
int
)
item
<<
(
i
-
1
);
value
|=
(
int
)
item
<<
(
i
-
1
);
i
-=
2
;
i
-=
2
;
}
}
}
}
symbol_list_low
=
value
&
0xFF
;
symbol_list_low
=
value
&
0xFF
;
symbol_list_high
=
(
value
>>
8
)
&
0x3F
;
symbol_list_high
=
(
value
>>
8
)
&
0x3F
;
}
}
vector
<
SymbolStatus
>
StatusVecChunk
::
getSymbolList
()
const
{
vector
<
SymbolStatus
>
StatusVecChunk
::
getSymbolList
()
const
{
CHECK
(
type
==
1
);
CHECK
(
type
==
1
);
vector
<
SymbolStatus
>
ret
;
vector
<
SymbolStatus
>
ret
;
auto
thiz
=
ntohs
(
*
((
uint16_t
*
)
this
));
auto
thiz
=
ntohs
(
*
((
uint16_t
*
)
this
));
if
(
symbol
==
0
)
{
if
(
symbol
==
0
)
{
//s = 0 时,表示symbollist的每一个bit能表示一个数据包的到达状态
//
s = 0 时,表示symbollist的每一个bit能表示一个数据包的到达状态
for
(
int
i
=
13
;
i
>=
0
;
--
i
)
{
for
(
int
i
=
13
;
i
>=
0
;
--
i
)
{
SymbolStatus
status
=
(
SymbolStatus
)
((
bool
)
(
thiz
&
(
1
<<
i
)));
SymbolStatus
status
=
(
SymbolStatus
)
((
bool
)
(
thiz
&
(
1
<<
i
)));
ret
.
emplace_back
(
status
);
ret
.
emplace_back
(
status
);
}
}
}
else
{
}
else
{
//s = 1 时,表示symbollist每两个bit表示一个数据包的状态
//
s = 1 时,表示symbollist每两个bit表示一个数据包的状态
for
(
int
i
=
12
;
i
>=
0
;
i
-=
2
)
{
for
(
int
i
=
12
;
i
>=
0
;
i
-=
2
)
{
SymbolStatus
status
=
(
SymbolStatus
)
((
thiz
&
(
3
<<
i
))
>>
i
);
SymbolStatus
status
=
(
SymbolStatus
)((
thiz
&
(
3
<<
i
))
>>
i
);
ret
.
emplace_back
(
status
);
ret
.
emplace_back
(
status
);
}
}
}
}
...
@@ -336,17 +336,17 @@ vector<SymbolStatus> StatusVecChunk::getSymbolList() const {
...
@@ -336,17 +336,17 @@ vector<SymbolStatus> StatusVecChunk::getSymbolList() const {
string
StatusVecChunk
::
dumpString
()
const
{
string
StatusVecChunk
::
dumpString
()
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
printer
<<
"status vector chunk, symbol:"
<<
(
int
)
symbol
<<
", symbol list:"
;
printer
<<
"status vector chunk, symbol:"
<<
(
int
)
symbol
<<
", symbol list:"
;
auto
vec
=
getSymbolList
();
auto
vec
=
getSymbolList
();
for
(
auto
&
item
:
vec
)
{
for
(
auto
&
item
:
vec
)
{
printer
<<
(
int
)
item
<<
" "
;
printer
<<
(
int
)
item
<<
" "
;
}
}
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
void
FCI_TWCC
::
check
(
size_t
size
){
void
FCI_TWCC
::
check
(
size_t
size
)
{
CHECK
(
size
>=
kSize
);
CHECK
(
size
>=
kSize
);
}
}
...
@@ -365,87 +365,87 @@ uint32_t FCI_TWCC::getReferenceTime() const {
...
@@ -365,87 +365,87 @@ uint32_t FCI_TWCC::getReferenceTime() const {
ret
|=
ref_time
[
2
];
ret
|=
ref_time
[
2
];
return
ret
;
return
ret
;
}
}
//3.1.5. Receive Delta
//
3.1.5. Receive Delta
//
//
// Deltas are represented as multiples of 250us:
//
Deltas are represented as multiples of 250us:
//
//
// o If the "Packet received, small delta" symbol has been appended to
//
o If the "Packet received, small delta" symbol has been appended to
// the status list, an 8-bit unsigned receive delta will be appended
//
the status list, an 8-bit unsigned receive delta will be appended
// to recv delta list, representing a delta in the range [0, 63.75]
//
to recv delta list, representing a delta in the range [0, 63.75]
// ms.
//
ms.
//
//
// o If the "Packet received, large or negative delta" symbol has been
//
o If the "Packet received, large or negative delta" symbol has been
// appended to the status list, a 16-bit signed receive delta will be
//
appended to the status list, a 16-bit signed receive delta will be
// appended to recv delta list, representing a delta in the range
//
appended to recv delta list, representing a delta in the range
// [-8192.0, 8191.75] ms.
//
[-8192.0, 8191.75] ms.
//
//
// o If the delta exceeds even the larger limits, a new feedback
//
o If the delta exceeds even the larger limits, a new feedback
// message must be used, where the 24-bit base receive delta can
//
message must be used, where the 24-bit base receive delta can
// cover very large gaps.
//
cover very large gaps.
//
//
// The smaller receive delta upper bound of 63.75 ms means that this is
//
The smaller receive delta upper bound of 63.75 ms means that this is
// only viable at about 1000/25.5 ~= 16 packets per second and above.
//
only viable at about 1000/25.5 ~= 16 packets per second and above.
// With a packet size of 1200 bytes/packet that amounts to a bitrate of
//
With a packet size of 1200 bytes/packet that amounts to a bitrate of
// about 150 kbit/s.
//
about 150 kbit/s.
//
//
// The 0.25 ms resolution means that up to 4000 packets per second can
//
The 0.25 ms resolution means that up to 4000 packets per second can
// be represented. With a 1200 bytes/packet payload, that amounts to
//
be represented. With a 1200 bytes/packet payload, that amounts to
// 38.4 Mbit/s payload bandwidth.
//
38.4 Mbit/s payload bandwidth.
static
int16_t
getRecvDelta
(
SymbolStatus
status
,
uint8_t
*&
ptr
,
const
uint8_t
*
end
){
static
int16_t
getRecvDelta
(
SymbolStatus
status
,
uint8_t
*&
ptr
,
const
uint8_t
*
end
)
{
int16_t
delta
=
0
;
int16_t
delta
=
0
;
switch
(
status
)
{
switch
(
status
)
{
case
SymbolStatus
:
:
not_received
:
{
case
SymbolStatus
:
:
not_received
:
{
//
丢包, recv delta为0个字节
//
丢包, recv delta为0个字节
break
;
break
;
}
}
case
SymbolStatus
:
:
small_delta
:
{
case
SymbolStatus
:
:
small_delta
:
{
CHECK
(
ptr
+
1
<=
end
);
CHECK
(
ptr
+
1
<=
end
);
//
时间戳增量小于256, recv delta为1个字节
//
时间戳增量小于256, recv delta为1个字节
delta
=
*
ptr
;
delta
=
*
ptr
;
ptr
+=
1
;
ptr
+=
1
;
break
;
break
;
}
}
case
SymbolStatus
:
:
large_delta
:
{
case
SymbolStatus
:
:
large_delta
:
{
CHECK
(
ptr
+
2
<=
end
);
CHECK
(
ptr
+
2
<=
end
);
//
时间戳增量256~65535间,recv delta为2个字节
//
时间戳增量256~65535间,recv delta为2个字节
delta
=
*
ptr
<<
8
|
*
(
ptr
+
1
);
delta
=
*
ptr
<<
8
|
*
(
ptr
+
1
);
ptr
+=
2
;
ptr
+=
2
;
break
;
break
;
}
}
case
SymbolStatus
:
:
reserved
:
{
case
SymbolStatus
:
:
reserved
:
{
//
没有时间戳
//
没有时间戳
break
;
break
;
}
}
default
:
default
:
//
这个逻辑分支不可达到
//
这个逻辑分支不可达到
CHECK
(
0
);
CHECK
(
0
);
break
;
break
;
}
}
return
delta
;
return
delta
;
}
}
FCI_TWCC
::
TwccPacketStatus
FCI_TWCC
::
getPacketChunkList
(
size_t
total_size
)
const
{
FCI_TWCC
::
TwccPacketStatus
FCI_TWCC
::
getPacketChunkList
(
size_t
total_size
)
const
{
TwccPacketStatus
ret
;
TwccPacketStatus
ret
;
auto
ptr
=
(
uint8_t
*
)
this
+
kSize
;
auto
ptr
=
(
uint8_t
*
)
this
+
kSize
;
auto
end
=
(
uint8_t
*
)
this
+
total_size
;
auto
end
=
(
uint8_t
*
)
this
+
total_size
;
CHECK
(
ptr
<
end
);
CHECK
(
ptr
<
end
);
auto
seq
=
getBaseSeq
();
auto
seq
=
getBaseSeq
();
auto
rtp_count
=
getPacketCount
();
auto
rtp_count
=
getPacketCount
();
for
(
uint8_t
i
=
0
;
i
<
rtp_count
;)
{
for
(
uint8_t
i
=
0
;
i
<
rtp_count
;)
{
CHECK
(
ptr
+
RunLengthChunk
::
kSize
<=
end
);
CHECK
(
ptr
+
RunLengthChunk
::
kSize
<=
end
);
RunLengthChunk
*
chunk
=
(
RunLengthChunk
*
)
ptr
;
RunLengthChunk
*
chunk
=
(
RunLengthChunk
*
)
ptr
;
if
(
!
chunk
->
type
)
{
if
(
!
chunk
->
type
)
{
//RunLengthChunk
//
RunLengthChunk
for
(
auto
j
=
0
;
j
<
chunk
->
getRunLength
();
++
j
)
{
for
(
auto
j
=
0
;
j
<
chunk
->
getRunLength
();
++
j
)
{
ret
.
emplace
(
seq
++
,
std
::
make_pair
((
SymbolStatus
)
chunk
->
symbol
,
0
));
ret
.
emplace
(
seq
++
,
std
::
make_pair
((
SymbolStatus
)
chunk
->
symbol
,
0
));
if
(
++
i
>=
rtp_count
)
{
if
(
++
i
>=
rtp_count
)
{
break
;
break
;
}
}
}
}
}
else
{
}
else
{
//StatusVecChunk
//
StatusVecChunk
StatusVecChunk
*
chunk
=
(
StatusVecChunk
*
)
ptr
;
StatusVecChunk
*
chunk
=
(
StatusVecChunk
*
)
ptr
;
for
(
auto
&
symbol
:
chunk
->
getSymbolList
())
{
for
(
auto
&
symbol
:
chunk
->
getSymbolList
())
{
ret
.
emplace
(
seq
++
,
std
::
make_pair
(
symbol
,
0
));
ret
.
emplace
(
seq
++
,
std
::
make_pair
(
symbol
,
0
));
if
(
++
i
>=
rtp_count
)
{
if
(
++
i
>=
rtp_count
)
{
...
@@ -465,23 +465,29 @@ FCI_TWCC::TwccPacketStatus FCI_TWCC::getPacketChunkList(size_t total_size) const
...
@@ -465,23 +465,29 @@ FCI_TWCC::TwccPacketStatus FCI_TWCC::getPacketChunkList(size_t total_size) const
string
FCI_TWCC
::
dumpString
(
size_t
total_size
)
const
{
string
FCI_TWCC
::
dumpString
(
size_t
total_size
)
const
{
_StrPrinter
printer
;
_StrPrinter
printer
;
auto
map
=
getPacketChunkList
(
total_size
);
auto
map
=
getPacketChunkList
(
total_size
);
printer
<<
"twcc fci, base_seq:"
<<
getBaseSeq
()
<<
", pkt_status_count:"
<<
getPacketCount
()
<<
", ref time:"
<<
getReferenceTime
()
<<
", fb count:"
<<
(
int
)
fb_pkt_count
<<
"
\n
"
;
printer
<<
"twcc fci, base_seq:"
<<
getBaseSeq
()
<<
", pkt_status_count:"
<<
getPacketCount
()
<<
", ref time:"
<<
getReferenceTime
()
<<
", fb count:"
<<
(
int
)
fb_pkt_count
<<
"
\n
"
;
for
(
auto
&
pr
:
map
)
{
for
(
auto
&
pr
:
map
)
{
printer
<<
"rtp seq:"
<<
pr
.
first
<<
", packet status:"
<<
(
int
)(
pr
.
second
.
first
)
<<
", delta:"
<<
pr
.
second
.
second
<<
"
\n
"
;
printer
<<
"rtp seq:"
<<
pr
.
first
<<
", packet status:"
<<
(
int
)(
pr
.
second
.
first
)
<<
", delta:"
<<
pr
.
second
.
second
<<
"
\n
"
;
}
}
return
std
::
move
(
printer
);
return
std
::
move
(
printer
);
}
}
static
void
appendDeltaString
(
string
&
delta_str
,
FCI_TWCC
::
TwccPacketStatus
&
status
,
int
count
){
static
void
appendDeltaString
(
string
&
delta_str
,
FCI_TWCC
::
TwccPacketStatus
&
status
,
int
count
)
{
for
(
auto
it
=
status
.
begin
();
it
!=
status
.
end
()
&&
count
--
;)
{
for
(
auto
it
=
status
.
begin
();
it
!=
status
.
end
()
&&
count
--
;)
{
switch
(
it
->
second
.
first
)
{
switch
(
it
->
second
.
first
)
{
//large delta模式先写高字节,再写低字节
// large delta模式先写高字节,再写低字节
case
SymbolStatus
:
:
large_delta
:
delta_str
.
push_back
((
it
->
second
.
second
>>
8
)
&
0xFF
);
case
SymbolStatus
:
:
large_delta
:
//small delta模式只写低字节
delta_str
.
push_back
((
it
->
second
.
second
>>
8
)
&
0xFF
);
case
SymbolStatus
:
:
small_delta
:
delta_str
.
push_back
(
it
->
second
.
second
&
0xFF
);
break
;
// small delta模式只写低字节
default
:
break
;
case
SymbolStatus
:
:
small_delta
:
delta_str
.
push_back
(
it
->
second
.
second
&
0xFF
);
break
;
default
:
break
;
}
}
//移除已经处理过的数据
//
移除已经处理过的数据
it
=
status
.
erase
(
it
);
it
=
status
.
erase
(
it
);
}
}
}
}
...
@@ -489,7 +495,7 @@ static void appendDeltaString(string &delta_str, FCI_TWCC::TwccPacketStatus &sta
...
@@ -489,7 +495,7 @@ static void appendDeltaString(string &delta_str, FCI_TWCC::TwccPacketStatus &sta
string
FCI_TWCC
::
create
(
uint32_t
ref_time
,
uint8_t
fb_pkt_count
,
TwccPacketStatus
&
status
)
{
string
FCI_TWCC
::
create
(
uint32_t
ref_time
,
uint8_t
fb_pkt_count
,
TwccPacketStatus
&
status
)
{
string
fci
;
string
fci
;
fci
.
resize
(
FCI_TWCC
::
kSize
);
fci
.
resize
(
FCI_TWCC
::
kSize
);
FCI_TWCC
*
ptr
=
(
FCI_TWCC
*
)
(
fci
.
data
());
FCI_TWCC
*
ptr
=
(
FCI_TWCC
*
)(
fci
.
data
());
ptr
->
base_seq
=
htons
(
status
.
begin
()
->
first
);
ptr
->
base_seq
=
htons
(
status
.
begin
()
->
first
);
ptr
->
pkt_status_count
=
htons
(
status
.
size
());
ptr
->
pkt_status_count
=
htons
(
status
.
size
());
ptr
->
fb_pkt_count
=
fb_pkt_count
;
ptr
->
fb_pkt_count
=
fb_pkt_count
;
...
@@ -500,21 +506,21 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
...
@@ -500,21 +506,21 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
string
delta_str
;
string
delta_str
;
while
(
!
status
.
empty
())
{
while
(
!
status
.
empty
())
{
{
{
//第一个rtp的状态
//
第一个rtp的状态
auto
symbol
=
status
.
begin
()
->
second
.
first
;
auto
symbol
=
status
.
begin
()
->
second
.
first
;
int16_t
count
=
0
;
int16_t
count
=
0
;
for
(
auto
&
pr
:
status
)
{
for
(
auto
&
pr
:
status
)
{
if
(
pr
.
second
.
first
!=
symbol
)
{
if
(
pr
.
second
.
first
!=
symbol
)
{
//状态发送变更了,本chunk结束
//
状态发送变更了,本chunk结束
break
;
break
;
}
}
if
(
++
count
>=
(
0xFFFF
>>
3
))
{
if
(
++
count
>=
(
0xFFFF
>>
3
))
{
//RunLengthChunk 13个bit表明rtp个数,最多可以表述0xFFFF >> 3个rtp状态
//
RunLengthChunk 13个bit表明rtp个数,最多可以表述0xFFFF >> 3个rtp状态
break
;
break
;
}
}
}
}
if
(
count
>=
7
)
{
if
(
count
>=
7
)
{
//连续状态相同个数大于6个时,使用RunLengthChunk模式比较节省带宽
//
连续状态相同个数大于6个时,使用RunLengthChunk模式比较节省带宽
RunLengthChunk
chunk
(
symbol
,
count
);
RunLengthChunk
chunk
(
symbol
,
count
);
fci
.
append
((
char
*
)
&
chunk
,
RunLengthChunk
::
kSize
);
fci
.
append
((
char
*
)
&
chunk
,
RunLengthChunk
::
kSize
);
appendDeltaString
(
delta_str
,
status
,
count
);
appendDeltaString
(
delta_str
,
status
,
count
);
...
@@ -523,20 +529,20 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
...
@@ -523,20 +529,20 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
}
}
{
{
//StatusVecChunk模式
//
StatusVecChunk模式
//symbol_list中元素是1个bit
//
symbol_list中元素是1个bit
auto
symbol
=
0
;
auto
symbol
=
0
;
vector
<
SymbolStatus
>
vec
;
vector
<
SymbolStatus
>
vec
;
for
(
auto
&
pr
:
status
)
{
for
(
auto
&
pr
:
status
)
{
vec
.
push_back
(
pr
.
second
.
first
);
vec
.
push_back
(
pr
.
second
.
first
);
if
(
pr
.
second
.
first
>=
SymbolStatus
::
large_delta
)
{
if
(
pr
.
second
.
first
>=
SymbolStatus
::
large_delta
)
{
//symbol_list中元素是2个bit
//
symbol_list中元素是2个bit
symbol
=
1
;
symbol
=
1
;
}
}
if
(
vec
.
size
()
<<
symbol
>=
14
)
{
if
(
vec
.
size
()
<<
symbol
>=
14
)
{
//symbol为0时,最多存放14个rtp的状态
//
symbol为0时,最多存放14个rtp的状态
//symbol为1时,最多存放7个rtp的状态
//
symbol为1时,最多存放7个rtp的状态
break
;
break
;
}
}
}
}
...
@@ -547,9 +553,9 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
...
@@ -547,9 +553,9 @@ string FCI_TWCC::create(uint32_t ref_time, uint8_t fb_pkt_count, TwccPacketStatu
}
}
}
}
//recv delta部分
//
recv delta部分
fci
.
append
(
delta_str
);
fci
.
append
(
delta_str
);
return
fci
;
return
fci
;
}
}
}
//
namespace
mediakit
}
//
namespace
mediakit
\ No newline at end of file
\ No newline at end of file
src/Rtcp/RtcpFCI.h
查看文件 @
cffc0743
...
@@ -11,37 +11,37 @@
...
@@ -11,37 +11,37 @@
#ifndef ZLMEDIAKIT_RTCPFCI_H
#ifndef ZLMEDIAKIT_RTCPFCI_H
#define ZLMEDIAKIT_RTCPFCI_H
#define ZLMEDIAKIT_RTCPFCI_H
#include "Rtcp.h"
#include "Common/config.h"
#include "Common/config.h"
#include "Rtcp.h"
namespace
mediakit
{
namespace
mediakit
{
/////////////////////////////////////////// PSFB ////////////////////////////////////////////////////
/////////////////////////////////////////// PSFB ////////////////////////////////////////////////////
//PSFB fmt = 2
//
PSFB fmt = 2
//https://tools.ietf.org/html/rfc4585#section-6.3.2.2
//
https://tools.ietf.org/html/rfc4585#section-6.3.2.2
// 0 1 2 3
//
0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | First | Number | PictureID |
//
| First | Number | PictureID |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//First: 13 bits
//
First: 13 bits
// The macroblock (MB) address of the first lost macroblock. The MB
//
The macroblock (MB) address of the first lost macroblock. The MB
// numbering is done such that the macroblock in the upper left
//
numbering is done such that the macroblock in the upper left
// corner of the picture is considered macroblock number 1 and the
//
corner of the picture is considered macroblock number 1 and the
// number for each macroblock increases from left to right and then
//
number for each macroblock increases from left to right and then
// from top to bottom in raster-scan order (such that if there is a
//
from top to bottom in raster-scan order (such that if there is a
// total of N macroblocks in a picture, the bottom right macroblock
//
total of N macroblocks in a picture, the bottom right macroblock
// is considered macroblock number N).
//
is considered macroblock number N).
//
//
// Number: 13 bits
//
Number: 13 bits
// The number of lost macroblocks, in scan order as discussed above.
//
The number of lost macroblocks, in scan order as discussed above.
//
//
// PictureID: 6 bits
//
PictureID: 6 bits
// The six least significant bits of the codec-specific identifier
//
The six least significant bits of the codec-specific identifier
// that is used to reference the picture in which the loss of the
//
that is used to reference the picture in which the loss of the
// macroblock(s) has occurred. For many video codecs, the PictureID
//
macroblock(s) has occurred. For many video codecs, the PictureID
// is identical to the Temporal Reference.
//
is identical to the Temporal Reference.
class
FCI_SLI
{
class
FCI_SLI
{
public
:
public
:
static
size_t
constexpr
kSize
=
4
;
static
size_t
constexpr
kSize
=
4
;
...
@@ -101,15 +101,15 @@ public:
...
@@ -101,15 +101,15 @@ public:
}
PACKED
;
}
PACKED
;
#endif
#endif
//PSFB fmt = 4
//
PSFB fmt = 4
//https://tools.ietf.org/html/rfc5104#section-4.3.1.1
//
https://tools.ietf.org/html/rfc5104#section-4.3.1.1
// 0 1 2 3
//
0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SSRC |
//
| SSRC |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Seq nr. | Reserved |
//
| Seq nr. | Reserved |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class
FCI_FIR
{
class
FCI_FIR
{
public
:
public
:
static
size_t
constexpr
kSize
=
8
;
static
size_t
constexpr
kSize
=
8
;
...
@@ -188,34 +188,34 @@ private:
...
@@ -188,34 +188,34 @@ private:
#endif
#endif
//PSFB fmt = 15
//
PSFB fmt = 15
//https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
//
https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
// 0 1 2 3
//
0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Unique identifier 'R' 'E' 'M' 'B' |
//
| Unique identifier 'R' 'E' 'M' 'B' |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Num SSRC | BR Exp | BR Mantissa |
//
| Num SSRC | BR Exp | BR Mantissa |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | SSRC feedback |
//
| SSRC feedback |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ... |
//
| ... |
// Num SSRC (8 bits): Number of SSRCs in this message.
//
Num SSRC (8 bits): Number of SSRCs in this message.
//
//
// BR Exp (6 bits): The exponential scaling of the mantissa for the
//
BR Exp (6 bits): The exponential scaling of the mantissa for the
// maximum total media bit rate value, ignoring all packet
//
maximum total media bit rate value, ignoring all packet
// overhead. The value is an unsigned integer [0..63], as
//
overhead. The value is an unsigned integer [0..63], as
// in RFC 5104 section 4.2.2.1.
//
in RFC 5104 section 4.2.2.1.
//
//
// BR Mantissa (18 bits): The mantissa of the maximum total media bit
//
BR Mantissa (18 bits): The mantissa of the maximum total media bit
// rate (ignoring all packet overhead) that the sender of
//
rate (ignoring all packet overhead) that the sender of
// the REMB estimates. The BR is the estimate of the
//
the REMB estimates. The BR is the estimate of the
// traveled path for the SSRCs reported in this message.
//
traveled path for the SSRCs reported in this message.
// The value is an unsigned integer in number of bits per
//
The value is an unsigned integer in number of bits per
// second.
//
second.
//
//
// SSRC feedback (32 bits) Consists of one or more SSRC entries which
//
SSRC feedback (32 bits) Consists of one or more SSRC entries which
// this feedback message applies to.
//
this feedback message applies to.
class
FCI_REMB
{
class
FCI_REMB
{
public
:
public
:
static
size_t
constexpr
kSize
=
8
;
static
size_t
constexpr
kSize
=
8
;
...
@@ -227,9 +227,9 @@ public:
...
@@ -227,9 +227,9 @@ public:
std
::
vector
<
uint32_t
>
getSSRC
();
std
::
vector
<
uint32_t
>
getSSRC
();
private
:
private
:
//Unique identifier 'R' 'E' 'M' 'B'
//
Unique identifier 'R' 'E' 'M' 'B'
char
magic
[
4
];
char
magic
[
4
];
//Num SSRC (8 bits)/BR Exp (6 bits)/ BR Mantissa (18 bits)
//
Num SSRC (8 bits)/BR Exp (6 bits)/ BR Mantissa (18 bits)
uint8_t
bitrate
[
4
];
uint8_t
bitrate
[
4
];
// SSRC feedback (32 bits) Consists of one or more SSRC entries which
// SSRC feedback (32 bits) Consists of one or more SSRC entries which
// this feedback message applies to.
// this feedback message applies to.
...
@@ -238,13 +238,13 @@ private:
...
@@ -238,13 +238,13 @@ private:
/////////////////////////////////////////// RTPFB ////////////////////////////////////////////////////
/////////////////////////////////////////// RTPFB ////////////////////////////////////////////////////
//RTPFB fmt = 1
//
RTPFB fmt = 1
//https://tools.ietf.org/html/rfc4585#section-6.2.1
//
https://tools.ietf.org/html/rfc4585#section-6.2.1
// 0 1 2 3
//
0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | PID | BLP |
//
| PID | BLP |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class
FCI_NACK
{
class
FCI_NACK
{
public
:
public
:
static
constexpr
size_t
kSize
=
4
;
static
constexpr
size_t
kSize
=
4
;
...
@@ -255,8 +255,8 @@ public:
...
@@ -255,8 +255,8 @@ public:
void
check
(
size_t
size
);
void
check
(
size_t
size
);
uint16_t
getPid
()
const
;
uint16_t
getPid
()
const
;
uint16_t
getBlp
()
const
;
uint16_t
getBlp
()
const
;
//返回丢包列表,总长度17,第一个包必丢
//
返回丢包列表,总长度17,第一个包必丢
// TODO: replace std::bitset
//
TODO: replace std::bitset
std
::
vector
<
bool
>
getBitArray
()
const
;
std
::
vector
<
bool
>
getBitArray
()
const
;
std
::
string
dumpString
()
const
;
std
::
string
dumpString
()
const
;
...
@@ -318,47 +318,48 @@ public:
...
@@ -318,47 +318,48 @@ public:
} PACKED;
} PACKED;
#endif
#endif
enum
class
SymbolStatus
:
uint8_t
{
enum
class
SymbolStatus
:
uint8_t
{
//Packet not received
//
Packet not received
not_received
=
0
,
not_received
=
0
,
//Packet received, small delta (所谓small detal是指能用一个字节表示的数值)
//
Packet received, small delta (所谓small detal是指能用一个字节表示的数值)
small_delta
=
1
,
small_delta
=
1
,
// Packet received, large ornegative delta (large即是能用两个字节表示的数值)
// Packet received, large ornegative delta (large即是能用两个字节表示的数值)
large_delta
=
2
,
large_delta
=
2
,
//Reserved
//
Reserved
reserved
=
3
reserved
=
3
};
};
//RTPFB fmt = 15
//
RTPFB fmt = 15
//https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1
//
https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1
//https://zhuanlan.zhihu.com/p/206656654
//
https://zhuanlan.zhihu.com/p/206656654
// 0 1 2 3
//
0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
//
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | base sequence number | packet status count |
//
| base sequence number | packet status count |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | reference time | fb pkt. count |
//
| reference time | fb pkt. count |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | packet chunk | packet chunk |
//
| packet chunk | packet chunk |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// . .
//
. .
// . .
//
. .
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | packet chunk | recv delta | recv delta |
//
| packet chunk | recv delta | recv delta |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// . .
//
. .
// . .
//
. .
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | recv delta | recv delta | zero padding |
//
| recv delta | recv delta | zero padding |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
class
FCI_TWCC
{
class
FCI_TWCC
{
public
:
public
:
static
size_t
constexpr
kSize
=
8
;
static
size_t
constexpr
kSize
=
8
;
using
TwccPacketStatus
=
std
::
map
<
uint16_t
/*rtp ext seq*/
,
std
::
pair
<
SymbolStatus
,
int16_t
/*recv delta,单位为250us*/
>
>
;
using
TwccPacketStatus
=
std
::
map
<
uint16_t
/*rtp ext seq*/
,
std
::
pair
<
SymbolStatus
,
int16_t
/*recv delta,单位为250us*/
>>
;
void
check
(
size_t
size
);
void
check
(
size_t
size
);
std
::
string
dumpString
(
size_t
total_size
)
const
;
std
::
string
dumpString
(
size_t
total_size
)
const
;
uint16_t
getBaseSeq
()
const
;
uint16_t
getBaseSeq
()
const
;
//单位64ms
//
单位64ms
uint32_t
getReferenceTime
()
const
;
uint32_t
getReferenceTime
()
const
;
uint16_t
getPacketCount
()
const
;
uint16_t
getPacketCount
()
const
;
TwccPacketStatus
getPacketChunkList
(
size_t
total_size
)
const
;
TwccPacketStatus
getPacketChunkList
(
size_t
total_size
)
const
;
...
@@ -366,15 +367,15 @@ public:
...
@@ -366,15 +367,15 @@ public:
static
std
::
string
create
(
uint32_t
ref_time
,
uint8_t
fb_pkt_count
,
TwccPacketStatus
&
status
);
static
std
::
string
create
(
uint32_t
ref_time
,
uint8_t
fb_pkt_count
,
TwccPacketStatus
&
status
);
private
:
private
:
//base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号
//
base sequence number,基础序号,本次反馈的第一个包的序号;也就是RTP扩展头的序列号
uint16_t
base_seq
;
uint16_t
base_seq
;
//packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算
//
packet status count, 包个数,本次反馈包含多少个包的状态;从基础序号开始算
uint16_t
pkt_status_count
;
uint16_t
pkt_status_count
;
//reference time,基准时间,绝对时间;计算该包中每个媒体包的到达时间都要基于这个基准时间计算
//
reference time,基准时间,绝对时间;计算该包中每个媒体包的到达时间都要基于这个基准时间计算
uint8_t
ref_time
[
3
];
uint8_t
ref_time
[
3
];
//feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 |
//
feedback packet count,反馈包号,本包是第几个transport-cc包,每次加1 |
uint8_t
fb_pkt_count
;
uint8_t
fb_pkt_count
;
}
PACKED
;
}
PACKED
;
}
//namespace mediakit
}
//
namespace mediakit
#endif //ZLMEDIAKIT_RTCPFCI_H
#endif //
ZLMEDIAKIT_RTCPFCI_H
webrtc/WebRtcTransport.cpp
查看文件 @
cffc0743
...
@@ -9,11 +9,11 @@
...
@@ -9,11 +9,11 @@
*/
*/
#include "WebRtcTransport.h"
#include "WebRtcTransport.h"
#include <iostream>
#include "RtpExt.h"
#include "Rtcp/Rtcp.h"
#include "Rtcp/Rtcp.h"
#include "Rtcp/RtcpFCI.h"
#include "Rtcp/RtcpFCI.h"
#include "RtpExt.h"
#include "Rtsp/RtpReceiver.h"
#include "Rtsp/RtpReceiver.h"
#include <iostream>
#define RTP_SSRC_OFFSET 1
#define RTP_SSRC_OFFSET 1
#define RTX_SSRC_OFFSET 2
#define RTX_SSRC_OFFSET 2
...
@@ -25,17 +25,17 @@
...
@@ -25,17 +25,17 @@
using
namespace
std
;
using
namespace
std
;
using
namespace
mediakit
;
using
namespace
mediakit
;
//RTC配置项目
//
RTC配置项目
namespace
RTC
{
namespace
RTC
{
#define RTC_FIELD "rtc."
#define RTC_FIELD "rtc."
//rtp和rtcp接受超时时间
//
rtp和rtcp接受超时时间
const
string
kTimeOutSec
=
RTC_FIELD
"timeoutSec"
;
const
string
kTimeOutSec
=
RTC_FIELD
"timeoutSec"
;
//服务器外网ip
//
服务器外网ip
const
string
kExternIP
=
RTC_FIELD
"externIP"
;
const
string
kExternIP
=
RTC_FIELD
"externIP"
;
//设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
//
设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
const
string
kRembBitRate
=
RTC_FIELD
"rembBitRate"
;
const
string
kRembBitRate
=
RTC_FIELD
"rembBitRate"
;
//webrtc单端口udp服务器
//
webrtc单端口udp服务器
const
string
kPort
=
RTC_FIELD
"port"
;
const
string
kPort
=
RTC_FIELD
"port"
;
static
onceToken
token
([]()
{
static
onceToken
token
([]()
{
mINI
::
Instance
()[
kTimeOutSec
]
=
15
;
mINI
::
Instance
()[
kTimeOutSec
]
=
15
;
...
@@ -44,9 +44,9 @@ static onceToken token([]() {
...
@@ -44,9 +44,9 @@ static onceToken token([]() {
mINI
::
Instance
()[
kPort
]
=
8000
;
mINI
::
Instance
()[
kPort
]
=
8000
;
});
});
}
//
namespace RTC
}
//
namespace RTC
static
atomic
<
uint64_t
>
s_key
{
0
};
static
atomic
<
uint64_t
>
s_key
{
0
};
static
void
translateIPFromEnv
(
std
::
vector
<
std
::
string
>
&
v
)
{
static
void
translateIPFromEnv
(
std
::
vector
<
std
::
string
>
&
v
)
{
for
(
auto
iter
=
v
.
begin
();
iter
!=
v
.
end
();)
{
for
(
auto
iter
=
v
.
begin
();
iter
!=
v
.
end
();)
{
...
@@ -69,12 +69,12 @@ WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) {
...
@@ -69,12 +69,12 @@ WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) {
_packet_pool
.
setSize
(
64
);
_packet_pool
.
setSize
(
64
);
}
}
void
WebRtcTransport
::
onCreate
(){
void
WebRtcTransport
::
onCreate
()
{
_dtls_transport
=
std
::
make_shared
<
RTC
::
DtlsTransport
>
(
_poller
,
this
);
_dtls_transport
=
std
::
make_shared
<
RTC
::
DtlsTransport
>
(
_poller
,
this
);
_ice_server
=
std
::
make_shared
<
RTC
::
IceServer
>
(
this
,
_identifier
,
makeRandStr
(
24
));
_ice_server
=
std
::
make_shared
<
RTC
::
IceServer
>
(
this
,
_identifier
,
makeRandStr
(
24
));
}
}
void
WebRtcTransport
::
onDestory
(){
void
WebRtcTransport
::
onDestory
()
{
#ifdef ENABLE_SCTP
#ifdef ENABLE_SCTP
_sctp
=
nullptr
;
_sctp
=
nullptr
;
#endif
#endif
...
@@ -82,7 +82,7 @@ void WebRtcTransport::onDestory(){
...
@@ -82,7 +82,7 @@ void WebRtcTransport::onDestory(){
_ice_server
=
nullptr
;
_ice_server
=
nullptr
;
}
}
const
EventPoller
::
Ptr
&
WebRtcTransport
::
getPoller
()
const
{
const
EventPoller
::
Ptr
&
WebRtcTransport
::
getPoller
()
const
{
return
_poller
;
return
_poller
;
}
}
...
@@ -92,8 +92,9 @@ const string &WebRtcTransport::getIdentifier() const {
...
@@ -92,8 +92,9 @@ const string &WebRtcTransport::getIdentifier() const {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
WebRtcTransport
::
OnIceServerSendStunPacket
(
const
RTC
::
IceServer
*
iceServer
,
const
RTC
::
StunPacket
*
packet
,
RTC
::
TransportTuple
*
tuple
)
{
void
WebRtcTransport
::
OnIceServerSendStunPacket
(
sendSockData
((
char
*
)
packet
->
GetData
(),
packet
->
GetSize
(),
tuple
);
const
RTC
::
IceServer
*
iceServer
,
const
RTC
::
StunPacket
*
packet
,
RTC
::
TransportTuple
*
tuple
)
{
sendSockData
((
char
*
)
packet
->
GetData
(),
packet
->
GetSize
(),
tuple
);
}
}
void
WebRtcTransport
::
OnIceServerSelectedTuple
(
const
RTC
::
IceServer
*
iceServer
,
RTC
::
TransportTuple
*
tuple
)
{
void
WebRtcTransport
::
OnIceServerSelectedTuple
(
const
RTC
::
IceServer
*
iceServer
,
RTC
::
TransportTuple
*
tuple
)
{
...
@@ -120,16 +121,13 @@ void WebRtcTransport::OnIceServerDisconnected(const RTC::IceServer *iceServer) {
...
@@ -120,16 +121,13 @@ void WebRtcTransport::OnIceServerDisconnected(const RTC::IceServer *iceServer) {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
WebRtcTransport
::
OnDtlsTransportConnected
(
void
WebRtcTransport
::
OnDtlsTransportConnected
(
const
RTC
::
DtlsTransport
*
dtlsTransport
,
const
RTC
::
DtlsTransport
*
dtlsTransport
,
RTC
::
SrtpSession
::
CryptoSuite
srtpCryptoSuite
,
uint8_t
*
srtpLocalKey
,
RTC
::
SrtpSession
::
CryptoSuite
srtpCryptoSuite
,
size_t
srtpLocalKeyLen
,
uint8_t
*
srtpRemoteKey
,
size_t
srtpRemoteKeyLen
,
std
::
string
&
remoteCert
)
{
uint8_t
*
srtpLocalKey
,
size_t
srtpLocalKeyLen
,
uint8_t
*
srtpRemoteKey
,
size_t
srtpRemoteKeyLen
,
std
::
string
&
remoteCert
)
{
InfoL
;
InfoL
;
_srtp_session_send
=
std
::
make_shared
<
RTC
::
SrtpSession
>
(
RTC
::
SrtpSession
::
Type
::
OUTBOUND
,
srtpCryptoSuite
,
srtpLocalKey
,
srtpLocalKeyLen
);
_srtp_session_send
=
std
::
make_shared
<
RTC
::
SrtpSession
>
(
_srtp_session_recv
=
std
::
make_shared
<
RTC
::
SrtpSession
>
(
RTC
::
SrtpSession
::
Type
::
INBOUND
,
srtpCryptoSuite
,
srtpRemoteKey
,
srtpRemoteKeyLen
);
RTC
::
SrtpSession
::
Type
::
OUTBOUND
,
srtpCryptoSuite
,
srtpLocalKey
,
srtpLocalKeyLen
);
_srtp_session_recv
=
std
::
make_shared
<
RTC
::
SrtpSession
>
(
RTC
::
SrtpSession
::
Type
::
INBOUND
,
srtpCryptoSuite
,
srtpRemoteKey
,
srtpRemoteKeyLen
);
#ifdef ENABLE_SCTP
#ifdef ENABLE_SCTP
_sctp
=
std
::
make_shared
<
RTC
::
SctpAssociationImp
>
(
getPoller
(),
this
,
128
,
128
,
262144
,
true
);
_sctp
=
std
::
make_shared
<
RTC
::
SctpAssociationImp
>
(
getPoller
(),
this
,
128
,
128
,
262144
,
true
);
_sctp
->
TransportConnected
();
_sctp
->
TransportConnected
();
...
@@ -137,7 +135,8 @@ void WebRtcTransport::OnDtlsTransportConnected(
...
@@ -137,7 +135,8 @@ void WebRtcTransport::OnDtlsTransportConnected(
onStartWebRTC
();
onStartWebRTC
();
}
}
void
WebRtcTransport
::
OnDtlsTransportSendData
(
const
RTC
::
DtlsTransport
*
dtlsTransport
,
const
uint8_t
*
data
,
size_t
len
)
{
void
WebRtcTransport
::
OnDtlsTransportSendData
(
const
RTC
::
DtlsTransport
*
dtlsTransport
,
const
uint8_t
*
data
,
size_t
len
)
{
sendSockData
((
char
*
)
data
,
len
,
nullptr
);
sendSockData
((
char
*
)
data
,
len
,
nullptr
);
}
}
...
@@ -155,7 +154,8 @@ void WebRtcTransport::OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransp
...
@@ -155,7 +154,8 @@ void WebRtcTransport::OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransp
onShutdown
(
SockException
(
Err_shutdown
,
"dtls close notify received"
));
onShutdown
(
SockException
(
Err_shutdown
,
"dtls close notify received"
));
}
}
void
WebRtcTransport
::
OnDtlsTransportApplicationDataReceived
(
const
RTC
::
DtlsTransport
*
dtlsTransport
,
const
uint8_t
*
data
,
size_t
len
)
{
void
WebRtcTransport
::
OnDtlsTransportApplicationDataReceived
(
const
RTC
::
DtlsTransport
*
dtlsTransport
,
const
uint8_t
*
data
,
size_t
len
)
{
#ifdef ENABLE_SCTP
#ifdef ENABLE_SCTP
_sctp
->
ProcessSctpData
(
data
,
len
);
_sctp
->
ProcessSctpData
(
data
,
len
);
#else
#else
...
@@ -165,63 +165,64 @@ void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTran
...
@@ -165,63 +165,64 @@ void WebRtcTransport::OnDtlsTransportApplicationDataReceived(const RTC::DtlsTran
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef ENABLE_SCTP
#ifdef ENABLE_SCTP
void
WebRtcTransport
::
OnSctpAssociationConnecting
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
void
WebRtcTransport
::
OnSctpAssociationConnecting
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
TraceL
;
TraceL
;
}
}
void
WebRtcTransport
::
OnSctpAssociationConnected
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
void
WebRtcTransport
::
OnSctpAssociationConnected
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
InfoL
<<
getIdentifier
();
InfoL
<<
getIdentifier
();
}
}
void
WebRtcTransport
::
OnSctpAssociationFailed
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
void
WebRtcTransport
::
OnSctpAssociationFailed
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
WarnL
<<
getIdentifier
();
WarnL
<<
getIdentifier
();
}
}
void
WebRtcTransport
::
OnSctpAssociationClosed
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
void
WebRtcTransport
::
OnSctpAssociationClosed
(
RTC
::
SctpAssociation
*
sctpAssociation
)
{
InfoL
<<
getIdentifier
();
InfoL
<<
getIdentifier
();
}
}
void
WebRtcTransport
::
OnSctpAssociationSendData
(
RTC
::
SctpAssociation
*
sctpAssociation
,
const
uint8_t
*
data
,
size_t
len
)
{
void
WebRtcTransport
::
OnSctpAssociationSendData
(
RTC
::
SctpAssociation
*
sctpAssociation
,
const
uint8_t
*
data
,
size_t
len
)
{
_dtls_transport
->
SendApplicationData
(
data
,
len
);
_dtls_transport
->
SendApplicationData
(
data
,
len
);
}
}
void
WebRtcTransport
::
OnSctpAssociationMessageReceived
(
RTC
::
SctpAssociation
*
sctpAssociation
,
uint16_t
streamId
,
void
WebRtcTransport
::
OnSctpAssociationMessageReceived
(
uint32_t
ppid
,
const
uint8_t
*
msg
,
size_t
len
)
{
RTC
::
SctpAssociation
*
sctpAssociation
,
uint16_t
streamId
,
uint32_t
ppid
,
const
uint8_t
*
msg
,
size_t
len
)
{
InfoL
<<
getIdentifier
()
<<
" "
<<
streamId
<<
" "
<<
ppid
<<
" "
<<
len
<<
" "
<<
string
((
char
*
)
msg
,
len
);
InfoL
<<
getIdentifier
()
<<
" "
<<
streamId
<<
" "
<<
ppid
<<
" "
<<
len
<<
" "
<<
string
((
char
*
)
msg
,
len
);
RTC
::
SctpStreamParameters
params
;
RTC
::
SctpStreamParameters
params
;
params
.
streamId
=
streamId
;
params
.
streamId
=
streamId
;
//回显数据
//
回显数据
_sctp
->
SendSctpMessage
(
params
,
ppid
,
msg
,
len
);
_sctp
->
SendSctpMessage
(
params
,
ppid
,
msg
,
len
);
}
}
#endif
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
WebRtcTransport
::
sendSockData
(
const
char
*
buf
,
size_t
len
,
RTC
::
TransportTuple
*
tuple
){
void
WebRtcTransport
::
sendSockData
(
const
char
*
buf
,
size_t
len
,
RTC
::
TransportTuple
*
tuple
)
{
auto
pkt
=
_packet_pool
.
obtain2
();
auto
pkt
=
_packet_pool
.
obtain2
();
pkt
->
assign
(
buf
,
len
);
pkt
->
assign
(
buf
,
len
);
onSendSockData
(
std
::
move
(
pkt
),
true
,
tuple
?
tuple
:
_ice_server
->
GetSelectedTuple
());
onSendSockData
(
std
::
move
(
pkt
),
true
,
tuple
?
tuple
:
_ice_server
->
GetSelectedTuple
());
}
}
RTC
::
TransportTuple
*
WebRtcTransport
::
getSelectedTuple
()
const
{
RTC
::
TransportTuple
*
WebRtcTransport
::
getSelectedTuple
()
const
{
return
_ice_server
->
GetSelectedTuple
();
return
_ice_server
->
GetSelectedTuple
();
}
}
void
WebRtcTransport
::
sendRtcpRemb
(
uint32_t
ssrc
,
size_t
bit_rate
)
{
void
WebRtcTransport
::
sendRtcpRemb
(
uint32_t
ssrc
,
size_t
bit_rate
)
{
auto
remb
=
FCI_REMB
::
create
({
ssrc
},
(
uint32_t
)
bit_rate
);
auto
remb
=
FCI_REMB
::
create
({
ssrc
},
(
uint32_t
)
bit_rate
);
auto
fb
=
RtcpFB
::
create
(
PSFBType
::
RTCP_PSFB_REMB
,
remb
.
data
(),
remb
.
size
());
auto
fb
=
RtcpFB
::
create
(
PSFBType
::
RTCP_PSFB_REMB
,
remb
.
data
(),
remb
.
size
());
fb
->
ssrc
=
htonl
(
0
);
fb
->
ssrc
=
htonl
(
0
);
fb
->
ssrc_media
=
htonl
(
ssrc
);
fb
->
ssrc_media
=
htonl
(
ssrc
);
sendRtcpPacket
((
char
*
)
fb
.
get
(),
fb
->
getSize
(),
true
);
sendRtcpPacket
((
char
*
)
fb
.
get
(),
fb
->
getSize
(),
true
);
}
}
void
WebRtcTransport
::
sendRtcpPli
(
uint32_t
ssrc
)
{
void
WebRtcTransport
::
sendRtcpPli
(
uint32_t
ssrc
)
{
auto
pli
=
RtcpFB
::
create
(
PSFBType
::
RTCP_PSFB_PLI
);
auto
pli
=
RtcpFB
::
create
(
PSFBType
::
RTCP_PSFB_PLI
);
pli
->
ssrc
=
htonl
(
0
);
pli
->
ssrc
=
htonl
(
0
);
pli
->
ssrc_media
=
htonl
(
ssrc
);
pli
->
ssrc_media
=
htonl
(
ssrc
);
sendRtcpPacket
((
char
*
)
pli
.
get
(),
pli
->
getSize
(),
true
);
sendRtcpPacket
((
char
*
)
pli
.
get
(),
pli
->
getSize
(),
true
);
}
}
string
getFingerprint
(
const
string
&
algorithm_str
,
const
std
::
shared_ptr
<
RTC
::
DtlsTransport
>
&
transport
){
string
getFingerprint
(
const
string
&
algorithm_str
,
const
std
::
shared_ptr
<
RTC
::
DtlsTransport
>
&
transport
)
{
auto
algorithm
=
RTC
::
DtlsTransport
::
GetFingerprintAlgorithm
(
algorithm_str
);
auto
algorithm
=
RTC
::
DtlsTransport
::
GetFingerprintAlgorithm
(
algorithm_str
);
for
(
auto
&
finger_prints
:
transport
->
GetLocalFingerprints
())
{
for
(
auto
&
finger_prints
:
transport
->
GetLocalFingerprints
())
{
if
(
finger_prints
.
algorithm
==
algorithm
)
{
if
(
finger_prints
.
algorithm
==
algorithm
)
{
...
@@ -231,21 +232,22 @@ string getFingerprint(const string &algorithm_str, const std::shared_ptr<RTC::Dt
...
@@ -231,21 +232,22 @@ string getFingerprint(const string &algorithm_str, const std::shared_ptr<RTC::Dt
throw
std
::
invalid_argument
(
StrPrinter
<<
"不支持的加密算法:"
<<
algorithm_str
);
throw
std
::
invalid_argument
(
StrPrinter
<<
"不支持的加密算法:"
<<
algorithm_str
);
}
}
void
WebRtcTransport
::
setRemoteDtlsFingerprint
(
const
RtcSession
&
remote
){
void
WebRtcTransport
::
setRemoteDtlsFingerprint
(
const
RtcSession
&
remote
)
{
//设置远端dtls签名
//
设置远端dtls签名
RTC
::
DtlsTransport
::
Fingerprint
remote_fingerprint
;
RTC
::
DtlsTransport
::
Fingerprint
remote_fingerprint
;
remote_fingerprint
.
algorithm
=
RTC
::
DtlsTransport
::
GetFingerprintAlgorithm
(
_offer_sdp
->
media
[
0
].
fingerprint
.
algorithm
);
remote_fingerprint
.
algorithm
=
RTC
::
DtlsTransport
::
GetFingerprintAlgorithm
(
_offer_sdp
->
media
[
0
].
fingerprint
.
algorithm
);
remote_fingerprint
.
value
=
_offer_sdp
->
media
[
0
].
fingerprint
.
hash
;
remote_fingerprint
.
value
=
_offer_sdp
->
media
[
0
].
fingerprint
.
hash
;
_dtls_transport
->
SetRemoteFingerprint
(
remote_fingerprint
);
_dtls_transport
->
SetRemoteFingerprint
(
remote_fingerprint
);
}
}
void
WebRtcTransport
::
onRtcConfigure
(
RtcConfigure
&
configure
)
const
{
void
WebRtcTransport
::
onRtcConfigure
(
RtcConfigure
&
configure
)
const
{
//开启remb后关闭twcc,因为开启twcc后remb无效
//
开启remb后关闭twcc,因为开启twcc后remb无效
GET_CONFIG
(
size_t
,
remb_bit_rate
,
RTC
::
kRembBitRate
);
GET_CONFIG
(
size_t
,
remb_bit_rate
,
RTC
::
kRembBitRate
);
configure
.
enableTWCC
(
!
remb_bit_rate
);
configure
.
enableTWCC
(
!
remb_bit_rate
);
}
}
std
::
string
WebRtcTransport
::
getAnswerSdp
(
const
string
&
offer
){
std
::
string
WebRtcTransport
::
getAnswerSdp
(
const
string
&
offer
)
{
try
{
try
{
//// 解析offer sdp ////
//// 解析offer sdp ////
_offer_sdp
=
std
::
make_shared
<
RtcSession
>
();
_offer_sdp
=
std
::
make_shared
<
RtcSession
>
();
...
@@ -259,8 +261,8 @@ std::string WebRtcTransport::getAnswerSdp(const string &offer){
...
@@ -259,8 +261,8 @@ std::string WebRtcTransport::getAnswerSdp(const string &offer){
fingerprint
.
algorithm
=
_offer_sdp
->
media
[
0
].
fingerprint
.
algorithm
;
fingerprint
.
algorithm
=
_offer_sdp
->
media
[
0
].
fingerprint
.
algorithm
;
fingerprint
.
hash
=
getFingerprint
(
fingerprint
.
algorithm
,
_dtls_transport
);
fingerprint
.
hash
=
getFingerprint
(
fingerprint
.
algorithm
,
_dtls_transport
);
RtcConfigure
configure
;
RtcConfigure
configure
;
configure
.
setDefaultSetting
(
_ice_server
->
GetUsernameFragment
(),
_ice_server
->
GetPassword
(),
configure
.
setDefaultSetting
(
RtpDirection
::
sendrecv
,
fingerprint
);
_ice_server
->
GetUsernameFragment
(),
_ice_server
->
GetPassword
(),
RtpDirection
::
sendrecv
,
fingerprint
);
onRtcConfigure
(
configure
);
onRtcConfigure
(
configure
);
//// 生成answer sdp ////
//// 生成answer sdp ////
...
@@ -279,22 +281,22 @@ static bool is_dtls(char *buf) {
...
@@ -279,22 +281,22 @@ static bool is_dtls(char *buf) {
}
}
static
bool
is_rtp
(
char
*
buf
)
{
static
bool
is_rtp
(
char
*
buf
)
{
RtpHeader
*
header
=
(
RtpHeader
*
)
buf
;
RtpHeader
*
header
=
(
RtpHeader
*
)
buf
;
return
((
header
->
pt
<
64
)
||
(
header
->
pt
>=
96
));
return
((
header
->
pt
<
64
)
||
(
header
->
pt
>=
96
));
}
}
static
bool
is_rtcp
(
char
*
buf
)
{
static
bool
is_rtcp
(
char
*
buf
)
{
RtpHeader
*
header
=
(
RtpHeader
*
)
buf
;
RtpHeader
*
header
=
(
RtpHeader
*
)
buf
;
return
((
header
->
pt
>=
64
)
&&
(
header
->
pt
<
96
));
return
((
header
->
pt
>=
64
)
&&
(
header
->
pt
<
96
));
}
}
static
string
getPeerAddress
(
RTC
::
TransportTuple
*
tuple
){
static
string
getPeerAddress
(
RTC
::
TransportTuple
*
tuple
)
{
return
SockUtil
::
inet_ntoa
(
tuple
);
return
SockUtil
::
inet_ntoa
(
tuple
);
}
}
void
WebRtcTransport
::
inputSockData
(
char
*
buf
,
int
len
,
RTC
::
TransportTuple
*
tuple
)
{
void
WebRtcTransport
::
inputSockData
(
char
*
buf
,
int
len
,
RTC
::
TransportTuple
*
tuple
)
{
if
(
RTC
::
StunPacket
::
IsStun
((
const
uint8_t
*
)
buf
,
len
))
{
if
(
RTC
::
StunPacket
::
IsStun
((
const
uint8_t
*
)
buf
,
len
))
{
std
::
unique_ptr
<
RTC
::
StunPacket
>
packet
(
RTC
::
StunPacket
::
Parse
((
const
uint8_t
*
)
buf
,
len
));
std
::
unique_ptr
<
RTC
::
StunPacket
>
packet
(
RTC
::
StunPacket
::
Parse
((
const
uint8_t
*
)
buf
,
len
));
if
(
!
packet
)
{
if
(
!
packet
)
{
WarnL
<<
"parse stun error"
<<
std
::
endl
;
WarnL
<<
"parse stun error"
<<
std
::
endl
;
return
;
return
;
...
@@ -303,7 +305,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
...
@@ -303,7 +305,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
return
;
return
;
}
}
if
(
is_dtls
(
buf
))
{
if
(
is_dtls
(
buf
))
{
_dtls_transport
->
ProcessDtlsData
((
uint8_t
*
)
buf
,
len
);
_dtls_transport
->
ProcessDtlsData
((
uint8_t
*
)
buf
,
len
);
return
;
return
;
}
}
if
(
is_rtp
(
buf
))
{
if
(
is_rtp
(
buf
))
{
...
@@ -311,7 +313,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
...
@@ -311,7 +313,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
WarnL
<<
"received rtp packet when dtls not completed from:"
<<
getPeerAddress
(
tuple
);
WarnL
<<
"received rtp packet when dtls not completed from:"
<<
getPeerAddress
(
tuple
);
return
;
return
;
}
}
if
(
_srtp_session_recv
->
DecryptSrtp
((
uint8_t
*
)
buf
,
&
len
))
{
if
(
_srtp_session_recv
->
DecryptSrtp
((
uint8_t
*
)
buf
,
&
len
))
{
onRtp
(
buf
,
len
,
_ticker
.
createdTime
());
onRtp
(
buf
,
len
,
_ticker
.
createdTime
());
}
}
return
;
return
;
...
@@ -321,7 +323,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
...
@@ -321,7 +323,7 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
WarnL
<<
"received rtcp packet when dtls not completed from:"
<<
getPeerAddress
(
tuple
);
WarnL
<<
"received rtcp packet when dtls not completed from:"
<<
getPeerAddress
(
tuple
);
return
;
return
;
}
}
if
(
_srtp_session_recv
->
DecryptSrtcp
((
uint8_t
*
)
buf
,
&
len
))
{
if
(
_srtp_session_recv
->
DecryptSrtcp
((
uint8_t
*
)
buf
,
&
len
))
{
onRtcp
(
buf
,
len
);
onRtcp
(
buf
,
len
);
}
}
return
;
return
;
...
@@ -331,8 +333,8 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
...
@@ -331,8 +333,8 @@ void WebRtcTransport::inputSockData(char *buf, int len, RTC::TransportTuple *tup
void
WebRtcTransport
::
sendRtpPacket
(
const
char
*
buf
,
int
len
,
bool
flush
,
void
*
ctx
)
{
void
WebRtcTransport
::
sendRtpPacket
(
const
char
*
buf
,
int
len
,
bool
flush
,
void
*
ctx
)
{
if
(
_srtp_session_send
)
{
if
(
_srtp_session_send
)
{
auto
pkt
=
_packet_pool
.
obtain2
();
auto
pkt
=
_packet_pool
.
obtain2
();
//预留rtx加入的两个字节
//
预留rtx加入的两个字节
pkt
->
setCapacity
((
size_t
)
len
+
SRTP_MAX_TRAILER_LEN
+
2
);
pkt
->
setCapacity
((
size_t
)
len
+
SRTP_MAX_TRAILER_LEN
+
2
);
pkt
->
assign
(
buf
,
len
);
pkt
->
assign
(
buf
,
len
);
onBeforeEncryptRtp
(
pkt
->
data
(),
len
,
ctx
);
onBeforeEncryptRtp
(
pkt
->
data
(),
len
,
ctx
);
if
(
_srtp_session_send
->
EncryptRtp
(
reinterpret_cast
<
uint8_t
*>
(
pkt
->
data
()),
&
len
))
{
if
(
_srtp_session_send
->
EncryptRtp
(
reinterpret_cast
<
uint8_t
*>
(
pkt
->
data
()),
&
len
))
{
...
@@ -345,8 +347,8 @@ void WebRtcTransport::sendRtpPacket(const char *buf, int len, bool flush, void *
...
@@ -345,8 +347,8 @@ void WebRtcTransport::sendRtpPacket(const char *buf, int len, bool flush, void *
void
WebRtcTransport
::
sendRtcpPacket
(
const
char
*
buf
,
int
len
,
bool
flush
,
void
*
ctx
)
{
void
WebRtcTransport
::
sendRtcpPacket
(
const
char
*
buf
,
int
len
,
bool
flush
,
void
*
ctx
)
{
if
(
_srtp_session_send
)
{
if
(
_srtp_session_send
)
{
auto
pkt
=
_packet_pool
.
obtain2
();
auto
pkt
=
_packet_pool
.
obtain2
();
//预留rtx加入的两个字节
//
预留rtx加入的两个字节
pkt
->
setCapacity
((
size_t
)
len
+
SRTP_MAX_TRAILER_LEN
+
2
);
pkt
->
setCapacity
((
size_t
)
len
+
SRTP_MAX_TRAILER_LEN
+
2
);
pkt
->
assign
(
buf
,
len
);
pkt
->
assign
(
buf
,
len
);
onBeforeEncryptRtcp
(
pkt
->
data
(),
len
,
ctx
);
onBeforeEncryptRtcp
(
pkt
->
data
(),
len
,
ctx
);
if
(
_srtp_session_send
->
EncryptRtcp
(
reinterpret_cast
<
uint8_t
*>
(
pkt
->
data
()),
&
len
))
{
if
(
_srtp_session_send
->
EncryptRtcp
(
reinterpret_cast
<
uint8_t
*>
(
pkt
->
data
()),
&
len
))
{
...
@@ -358,29 +360,31 @@ void WebRtcTransport::sendRtcpPacket(const char *buf, int len, bool flush, void
...
@@ -358,29 +360,31 @@ void WebRtcTransport::sendRtcpPacket(const char *buf, int len, bool flush, void
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void
WebRtcTransportImp
::
onCreate
(){
void
WebRtcTransportImp
::
onCreate
()
{
WebRtcTransport
::
onCreate
();
WebRtcTransport
::
onCreate
();
registerSelf
();
registerSelf
();
weak_ptr
<
WebRtcTransportImp
>
weak_self
=
static_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
weak_ptr
<
WebRtcTransportImp
>
weak_self
=
static_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
GET_CONFIG
(
float
,
timeoutSec
,
RTC
::
kTimeOutSec
);
GET_CONFIG
(
float
,
timeoutSec
,
RTC
::
kTimeOutSec
);
_timer
=
std
::
make_shared
<
Timer
>
(
timeoutSec
/
2
,
[
weak_self
]()
{
_timer
=
std
::
make_shared
<
Timer
>
(
auto
strong_self
=
weak_self
.
lock
();
timeoutSec
/
2
,
if
(
!
strong_self
)
{
[
weak_self
]()
{
return
false
;
auto
strong_self
=
weak_self
.
lock
();
}
if
(
!
strong_self
)
{
if
(
strong_self
->
_alive_ticker
.
elapsedTime
()
>
timeoutSec
*
1000
)
{
return
false
;
strong_self
->
onShutdown
(
SockException
(
Err_timeout
,
"接受rtp和rtcp超时"
));
}
}
if
(
strong_self
->
_alive_ticker
.
elapsedTime
()
>
timeoutSec
*
1000
)
{
return
true
;
strong_self
->
onShutdown
(
SockException
(
Err_timeout
,
"接受rtp和rtcp超时"
));
},
getPoller
());
}
return
true
;
},
getPoller
());
_twcc_ctx
.
setOnSendTwccCB
([
this
](
uint32_t
ssrc
,
string
fci
)
{
_twcc_ctx
.
setOnSendTwccCB
([
this
](
uint32_t
ssrc
,
string
fci
)
{
onSendTwcc
(
ssrc
,
fci
);
});
onSendTwcc
(
ssrc
,
fci
);
});
}
}
WebRtcTransportImp
::
WebRtcTransportImp
(
const
EventPoller
::
Ptr
&
poller
)
:
WebRtcTransport
(
poller
)
{
WebRtcTransportImp
::
WebRtcTransportImp
(
const
EventPoller
::
Ptr
&
poller
)
:
WebRtcTransport
(
poller
)
{
InfoL
<<
getIdentifier
();
InfoL
<<
getIdentifier
();
}
}
...
@@ -398,14 +402,14 @@ void WebRtcTransportImp::onSendSockData(Buffer::Ptr buf, bool flush, RTC::Transp
...
@@ -398,14 +402,14 @@ void WebRtcTransportImp::onSendSockData(Buffer::Ptr buf, bool flush, RTC::Transp
WarnL
<<
"send data failed:"
<<
buf
->
size
();
WarnL
<<
"send data failed:"
<<
buf
->
size
();
return
;
return
;
}
}
//一次性发送一帧的rtp数据,提高网络io性能
//
一次性发送一帧的rtp数据,提高网络io性能
_selected_session
->
setSendFlushFlag
(
flush
);
_selected_session
->
setSendFlushFlag
(
flush
);
_selected_session
->
send
(
std
::
move
(
buf
));
_selected_session
->
send
(
std
::
move
(
buf
));
}
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
bool
WebRtcTransportImp
::
canSendRtp
()
const
{
bool
WebRtcTransportImp
::
canSendRtp
()
const
{
for
(
auto
&
m
:
_answer_sdp
->
media
)
{
for
(
auto
&
m
:
_answer_sdp
->
media
)
{
if
(
m
.
direction
==
RtpDirection
::
sendrecv
||
m
.
direction
==
RtpDirection
::
sendonly
)
{
if
(
m
.
direction
==
RtpDirection
::
sendrecv
||
m
.
direction
==
RtpDirection
::
sendonly
)
{
return
true
;
return
true
;
...
@@ -414,7 +418,7 @@ bool WebRtcTransportImp::canSendRtp() const{
...
@@ -414,7 +418,7 @@ bool WebRtcTransportImp::canSendRtp() const{
return
false
;
return
false
;
}
}
bool
WebRtcTransportImp
::
canRecvRtp
()
const
{
bool
WebRtcTransportImp
::
canRecvRtp
()
const
{
for
(
auto
&
m
:
_answer_sdp
->
media
)
{
for
(
auto
&
m
:
_answer_sdp
->
media
)
{
if
(
m
.
direction
==
RtpDirection
::
sendrecv
||
m
.
direction
==
RtpDirection
::
recvonly
)
{
if
(
m
.
direction
==
RtpDirection
::
sendrecv
||
m
.
direction
==
RtpDirection
::
recvonly
)
{
return
true
;
return
true
;
...
@@ -424,7 +428,7 @@ bool WebRtcTransportImp::canRecvRtp() const{
...
@@ -424,7 +428,7 @@ bool WebRtcTransportImp::canRecvRtp() const{
}
}
void
WebRtcTransportImp
::
onStartWebRTC
()
{
void
WebRtcTransportImp
::
onStartWebRTC
()
{
//获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息
//
获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息
for
(
auto
&
m_answer
:
_answer_sdp
->
media
)
{
for
(
auto
&
m_answer
:
_answer_sdp
->
media
)
{
if
(
m_answer
.
type
==
TrackApplication
)
{
if
(
m_answer
.
type
==
TrackApplication
)
{
continue
;
continue
;
...
@@ -441,42 +445,43 @@ void WebRtcTransportImp::onStartWebRTC() {
...
@@ -441,42 +445,43 @@ void WebRtcTransportImp::onStartWebRTC() {
track
->
plan_rtx
=
m_answer
.
getRelatedRtxPlan
(
track
->
plan_rtp
->
pt
);
track
->
plan_rtx
=
m_answer
.
getRelatedRtxPlan
(
track
->
plan_rtp
->
pt
);
track
->
rtcp_context_send
=
std
::
make_shared
<
RtcpContextForSend
>
();
track
->
rtcp_context_send
=
std
::
make_shared
<
RtcpContextForSend
>
();
//rtp track type --> MediaTrack
//
rtp track type --> MediaTrack
if
(
m_answer
.
direction
==
RtpDirection
::
sendonly
||
m_answer
.
direction
==
RtpDirection
::
sendrecv
)
{
if
(
m_answer
.
direction
==
RtpDirection
::
sendonly
||
m_answer
.
direction
==
RtpDirection
::
sendrecv
)
{
//该类型的track 才支持发送
//
该类型的track 才支持发送
_type_to_track
[
m_answer
.
type
]
=
track
;
_type_to_track
[
m_answer
.
type
]
=
track
;
}
}
//send ssrc --> MediaTrack
//
send ssrc --> MediaTrack
_ssrc_to_track
[
track
->
answer_ssrc_rtp
]
=
track
;
_ssrc_to_track
[
track
->
answer_ssrc_rtp
]
=
track
;
_ssrc_to_track
[
track
->
answer_ssrc_rtx
]
=
track
;
_ssrc_to_track
[
track
->
answer_ssrc_rtx
]
=
track
;
//recv ssrc --> MediaTrack
//
recv ssrc --> MediaTrack
_ssrc_to_track
[
track
->
offer_ssrc_rtp
]
=
track
;
_ssrc_to_track
[
track
->
offer_ssrc_rtp
]
=
track
;
_ssrc_to_track
[
track
->
offer_ssrc_rtx
]
=
track
;
_ssrc_to_track
[
track
->
offer_ssrc_rtx
]
=
track
;
//rtp pt --> MediaTrack
// rtp pt --> MediaTrack
_pt_to_track
.
emplace
(
track
->
plan_rtp
->
pt
,
std
::
unique_ptr
<
WrappedMediaTrack
>
(
new
WrappedRtpTrack
(
track
,
_twcc_ctx
,
*
this
)));
_pt_to_track
.
emplace
(
track
->
plan_rtp
->
pt
,
std
::
unique_ptr
<
WrappedMediaTrack
>
(
new
WrappedRtpTrack
(
track
,
_twcc_ctx
,
*
this
)));
if
(
track
->
plan_rtx
)
{
if
(
track
->
plan_rtx
)
{
//rtx pt --> MediaTrack
//
rtx pt --> MediaTrack
_pt_to_track
.
emplace
(
track
->
plan_rtx
->
pt
,
std
::
unique_ptr
<
WrappedMediaTrack
>
(
new
WrappedRtxTrack
(
track
)));
_pt_to_track
.
emplace
(
track
->
plan_rtx
->
pt
,
std
::
unique_ptr
<
WrappedMediaTrack
>
(
new
WrappedRtxTrack
(
track
)));
}
}
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
//
记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
track
->
rtp_ext_ctx
=
std
::
make_shared
<
RtpExtContext
>
(
*
m_offer
);
track
->
rtp_ext_ctx
=
std
::
make_shared
<
RtpExtContext
>
(
*
m_offer
);
weak_ptr
<
MediaTrack
>
weak_track
=
track
;
weak_ptr
<
MediaTrack
>
weak_track
=
track
;
track
->
rtp_ext_ctx
->
setOnGetRtp
([
this
,
weak_track
](
uint8_t
pt
,
uint32_t
ssrc
,
const
string
&
rid
)
{
track
->
rtp_ext_ctx
->
setOnGetRtp
([
this
,
weak_track
](
uint8_t
pt
,
uint32_t
ssrc
,
const
string
&
rid
)
{
//ssrc --> MediaTrack
//
ssrc --> MediaTrack
auto
track
=
weak_track
.
lock
();
auto
track
=
weak_track
.
lock
();
assert
(
track
);
assert
(
track
);
_ssrc_to_track
[
ssrc
]
=
std
::
move
(
track
);
_ssrc_to_track
[
ssrc
]
=
std
::
move
(
track
);
InfoL
<<
"get rtp, pt:"
<<
(
int
)
pt
<<
", ssrc:"
<<
ssrc
<<
", rid:"
<<
rid
;
InfoL
<<
"get rtp, pt:"
<<
(
int
)
pt
<<
", ssrc:"
<<
ssrc
<<
", rid:"
<<
rid
;
});
});
size_t
index
=
0
;
size_t
index
=
0
;
for
(
auto
&
ssrc
:
m_offer
->
rtp_ssrc_sim
)
{
for
(
auto
&
ssrc
:
m_offer
->
rtp_ssrc_sim
)
{
//记录ssrc对应的MediaTrack
//
记录ssrc对应的MediaTrack
_ssrc_to_track
[
ssrc
.
ssrc
]
=
track
;
_ssrc_to_track
[
ssrc
.
ssrc
]
=
track
;
if
(
m_offer
->
rtp_rids
.
size
()
>
index
)
{
if
(
m_offer
->
rtp_rids
.
size
()
>
index
)
{
//支持firefox的simulcast, 提前映射好ssrc和rid的关系
//
支持firefox的simulcast, 提前映射好ssrc和rid的关系
track
->
rtp_ext_ctx
->
setRid
(
ssrc
.
ssrc
,
m_offer
->
rtp_rids
[
index
]);
track
->
rtp_ext_ctx
->
setRid
(
ssrc
.
ssrc
,
m_offer
->
rtp_rids
[
index
]);
}
else
{
}
else
{
// SDP munging没有rid, 它通过group-ssrc:SIM给出ssrc列表;
// SDP munging没有rid, 它通过group-ssrc:SIM给出ssrc列表;
...
@@ -493,7 +498,7 @@ void WebRtcTransportImp::onStartWebRTC() {
...
@@ -493,7 +498,7 @@ void WebRtcTransportImp::onStartWebRTC() {
}
}
void
WebRtcTransportImp
::
onCheckAnswer
(
RtcSession
&
sdp
)
{
void
WebRtcTransportImp
::
onCheckAnswer
(
RtcSession
&
sdp
)
{
//修改answer sdp的ip、端口信息
//
修改answer sdp的ip、端口信息
GET_CONFIG_FUNC
(
std
::
vector
<
std
::
string
>
,
extern_ips
,
RTC
::
kExternIP
,
[](
string
str
)
{
GET_CONFIG_FUNC
(
std
::
vector
<
std
::
string
>
,
extern_ips
,
RTC
::
kExternIP
,
[](
string
str
)
{
std
::
vector
<
std
::
string
>
ret
;
std
::
vector
<
std
::
string
>
ret
;
if
(
str
.
length
())
{
if
(
str
.
length
())
{
...
@@ -515,7 +520,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
...
@@ -515,7 +520,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
}
}
if
(
!
canSendRtp
())
{
if
(
!
canSendRtp
())
{
//设置我们发送的rtp的ssrc
//
设置我们发送的rtp的ssrc
return
;
return
;
}
}
...
@@ -524,13 +529,13 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
...
@@ -524,13 +529,13 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
continue
;
continue
;
}
}
if
(
!
m
.
rtp_rtx_ssrc
.
empty
())
{
if
(
!
m
.
rtp_rtx_ssrc
.
empty
())
{
//已经生成了ssrc
//
已经生成了ssrc
continue
;
continue
;
}
}
//添加answer sdp的ssrc信息
//
添加answer sdp的ssrc信息
m
.
rtp_rtx_ssrc
.
emplace_back
();
m
.
rtp_rtx_ssrc
.
emplace_back
();
auto
&
ssrc
=
m
.
rtp_rtx_ssrc
.
back
();
auto
&
ssrc
=
m
.
rtp_rtx_ssrc
.
back
();
//发送的ssrc我们随便定义,因为在发送rtp时会修改为此值
//
发送的ssrc我们随便定义,因为在发送rtp时会修改为此值
ssrc
.
ssrc
=
m
.
type
+
RTP_SSRC_OFFSET
;
ssrc
.
ssrc
=
m
.
type
+
RTP_SSRC_OFFSET
;
ssrc
.
cname
=
RTP_CNAME
;
ssrc
.
cname
=
RTP_CNAME
;
ssrc
.
label
=
RTP_LABEL
;
ssrc
.
label
=
RTP_LABEL
;
...
@@ -538,7 +543,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
...
@@ -538,7 +543,7 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
ssrc
.
msid
=
RTP_MSID
;
ssrc
.
msid
=
RTP_MSID
;
if
(
m
.
getRelatedRtxPlan
(
m
.
plan
[
0
].
pt
))
{
if
(
m
.
getRelatedRtxPlan
(
m
.
plan
[
0
].
pt
))
{
//rtx ssrc
//
rtx ssrc
ssrc
.
rtx_ssrc
=
ssrc
.
ssrc
+
RTX_SSRC_OFFSET
;
ssrc
.
rtx_ssrc
=
ssrc
.
ssrc
+
RTX_SSRC_OFFSET
;
}
}
}
}
...
@@ -546,20 +551,25 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
...
@@ -546,20 +551,25 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
void
WebRtcTransportImp
::
onCheckSdp
(
SdpType
type
,
RtcSession
&
sdp
)
{
void
WebRtcTransportImp
::
onCheckSdp
(
SdpType
type
,
RtcSession
&
sdp
)
{
switch
(
type
)
{
switch
(
type
)
{
case
SdpType
:
:
answer
:
onCheckAnswer
(
sdp
);
break
;
case
SdpType
:
:
answer
:
case
SdpType
:
:
offer
:
break
;
onCheckAnswer
(
sdp
);
default
:
/*不可达*/
assert
(
0
);
break
;
break
;
case
SdpType
:
:
offer
:
break
;
default
:
/*不可达*/
assert
(
0
);
break
;
}
}
}
}
SdpAttrCandidate
::
Ptr
makeIceCandidate
(
std
::
string
ip
,
uint16_t
port
,
SdpAttrCandidate
::
Ptr
uint32_t
priority
=
100
,
std
::
string
proto
=
"udp"
)
{
makeIceCandidate
(
std
::
string
ip
,
uint16_t
port
,
uint32_t
priority
=
100
,
std
::
string
proto
=
"udp"
)
{
auto
candidate
=
std
::
make_shared
<
SdpAttrCandidate
>
();
auto
candidate
=
std
::
make_shared
<
SdpAttrCandidate
>
();
//rtp端口
//
rtp端口
candidate
->
component
=
1
;
candidate
->
component
=
1
;
candidate
->
transport
=
proto
;
candidate
->
transport
=
proto
;
candidate
->
foundation
=
proto
+
"candidate"
;
candidate
->
foundation
=
proto
+
"candidate"
;
//优先级,单candidate时随便
//
优先级,单candidate时随便
candidate
->
priority
=
priority
;
candidate
->
priority
=
priority
;
candidate
->
address
=
ip
;
candidate
->
address
=
ip
;
candidate
->
port
=
port
;
candidate
->
port
=
port
;
...
@@ -569,10 +579,10 @@ SdpAttrCandidate::Ptr makeIceCandidate(std::string ip, uint16_t port,
...
@@ -569,10 +579,10 @@ SdpAttrCandidate::Ptr makeIceCandidate(std::string ip, uint16_t port,
void
WebRtcTransportImp
::
onRtcConfigure
(
RtcConfigure
&
configure
)
const
{
void
WebRtcTransportImp
::
onRtcConfigure
(
RtcConfigure
&
configure
)
const
{
WebRtcTransport
::
onRtcConfigure
(
configure
);
WebRtcTransport
::
onRtcConfigure
(
configure
);
GET_CONFIG
(
uint16_t
,
local_port
,
RTC
::
kPort
);
GET_CONFIG
(
uint16_t
,
local_port
,
RTC
::
kPort
);
//添加接收端口candidate信息
//
添加接收端口candidate信息
GET_CONFIG_FUNC
(
std
::
vector
<
std
::
string
>
,
extern_ips
,
RTC
::
kExternIP
,
[](
string
str
){
GET_CONFIG_FUNC
(
std
::
vector
<
std
::
string
>
,
extern_ips
,
RTC
::
kExternIP
,
[](
string
str
)
{
std
::
vector
<
std
::
string
>
ret
;
std
::
vector
<
std
::
string
>
ret
;
if
(
str
.
length
())
{
if
(
str
.
length
())
{
ret
=
split
(
str
,
","
);
ret
=
split
(
str
,
","
);
...
@@ -593,19 +603,18 @@ void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const {
...
@@ -593,19 +603,18 @@ void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const {
}
}
}
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
class
RtpChannel
:
public
RtpTrackImp
,
public
std
::
enable_shared_from_this
<
RtpChannel
>
{
class
RtpChannel
:
public
RtpTrackImp
,
public
std
::
enable_shared_from_this
<
RtpChannel
>
{
public
:
public
:
RtpChannel
(
EventPoller
::
Ptr
poller
,
RtpTrackImp
::
OnSorted
cb
,
function
<
void
(
const
FCI_NACK
&
nack
)
>
on_nack
)
{
RtpChannel
(
EventPoller
::
Ptr
poller
,
RtpTrackImp
::
OnSorted
cb
,
function
<
void
(
const
FCI_NACK
&
nack
)
>
on_nack
)
{
_poller
=
std
::
move
(
poller
);
_poller
=
std
::
move
(
poller
);
_on_nack
=
std
::
move
(
on_nack
);
_on_nack
=
std
::
move
(
on_nack
);
setOnSorted
(
std
::
move
(
cb
));
setOnSorted
(
std
::
move
(
cb
));
_nack_ctx
.
setOnNack
([
this
](
const
FCI_NACK
&
nack
)
{
_nack_ctx
.
setOnNack
([
this
](
const
FCI_NACK
&
nack
)
{
onNack
(
nack
);
});
onNack
(
nack
);
});
}
}
~
RtpChannel
()
override
=
default
;
~
RtpChannel
()
override
=
default
;
...
@@ -618,7 +627,7 @@ public:
...
@@ -618,7 +627,7 @@ public:
auto
seq
=
rtp
->
getSeq
();
auto
seq
=
rtp
->
getSeq
();
_nack_ctx
.
received
(
seq
,
is_rtx
);
_nack_ctx
.
received
(
seq
,
is_rtx
);
if
(
!
is_rtx
)
{
if
(
!
is_rtx
)
{
//统计rtp接受情况,便于生成nack rtcp包
//
统计rtp接受情况,便于生成nack rtcp包
_rtcp_context
.
onRtp
(
seq
,
rtp
->
getStamp
(),
rtp
->
ntp_stamp
,
sample_rate
,
len
);
_rtcp_context
.
onRtp
(
seq
,
rtp
->
getStamp
(),
rtp
->
ntp_stamp
,
sample_rate
,
len
);
}
}
return
rtp
;
return
rtp
;
...
@@ -630,7 +639,7 @@ public:
...
@@ -630,7 +639,7 @@ public:
}
}
int
getLossRate
()
{
int
getLossRate
()
{
auto
expected
=
_rtcp_context
.
getExpectedPacketsInterval
();
auto
expected
=
_rtcp_context
.
getExpectedPacketsInterval
();
if
(
!
expected
)
{
if
(
!
expected
)
{
return
0
;
return
0
;
}
}
...
@@ -638,7 +647,7 @@ public:
...
@@ -638,7 +647,7 @@ public:
}
}
private
:
private
:
void
starNackTimer
(){
void
starNackTimer
()
{
if
(
_delay_task
)
{
if
(
_delay_task
)
{
return
;
return
;
}
}
...
@@ -669,7 +678,7 @@ private:
...
@@ -669,7 +678,7 @@ private:
function
<
void
(
const
FCI_NACK
&
nack
)
>
_on_nack
;
function
<
void
(
const
FCI_NACK
&
nack
)
>
_on_nack
;
};
};
std
::
shared_ptr
<
RtpChannel
>
MediaTrack
::
getRtpChannel
(
uint32_t
ssrc
)
const
{
std
::
shared_ptr
<
RtpChannel
>
MediaTrack
::
getRtpChannel
(
uint32_t
ssrc
)
const
{
auto
it_chn
=
rtp_channel
.
find
(
rtp_ext_ctx
->
getRid
(
ssrc
));
auto
it_chn
=
rtp_channel
.
find
(
rtp_ext_ctx
->
getRid
(
ssrc
));
if
(
it_chn
==
rtp_channel
.
end
())
{
if
(
it_chn
==
rtp_channel
.
end
())
{
return
nullptr
;
return
nullptr
;
...
@@ -693,105 +702,107 @@ int WebRtcTransportImp::getLossRate(mediakit::TrackType type) {
...
@@ -693,105 +702,107 @@ int WebRtcTransportImp::getLossRate(mediakit::TrackType type) {
void
WebRtcTransportImp
::
onRtcp
(
const
char
*
buf
,
size_t
len
)
{
void
WebRtcTransportImp
::
onRtcp
(
const
char
*
buf
,
size_t
len
)
{
_bytes_usage
+=
len
;
_bytes_usage
+=
len
;
auto
rtcps
=
RtcpHeader
::
loadFromBytes
((
char
*
)
buf
,
len
);
auto
rtcps
=
RtcpHeader
::
loadFromBytes
((
char
*
)
buf
,
len
);
for
(
auto
rtcp
:
rtcps
)
{
for
(
auto
rtcp
:
rtcps
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
switch
((
RtcpType
)
rtcp
->
pt
)
{
case
RtcpType
:
:
RTCP_SR
:
{
case
RtcpType
:
:
RTCP_SR
:
{
//对方汇报rtp发送情况
// 对方汇报rtp发送情况
RtcpSR
*
sr
=
(
RtcpSR
*
)
rtcp
;
RtcpSR
*
sr
=
(
RtcpSR
*
)
rtcp
;
auto
it
=
_ssrc_to_track
.
find
(
sr
->
ssrc
);
auto
it
=
_ssrc_to_track
.
find
(
sr
->
ssrc
);
if
(
it
!=
_ssrc_to_track
.
end
())
{
auto
&
track
=
it
->
second
;
auto
rtp_chn
=
track
->
getRtpChannel
(
sr
->
ssrc
);
if
(
!
rtp_chn
)
{
WarnL
<<
"未识别的sr rtcp包:"
<<
rtcp
->
dumpString
();
}
else
{
// InfoL << "接收丢包率,ssrc:" << sr->ssrc << ",loss rate(%):" << rtp_chn->getLossRate();
// 设置rtp时间戳与ntp时间戳的对应关系
rtp_chn
->
setNtpStamp
(
sr
->
rtpts
,
sr
->
getNtpUnixStampMS
());
auto
rr
=
rtp_chn
->
createRtcpRR
(
sr
,
track
->
answer_ssrc_rtp
);
sendRtcpPacket
(
rr
->
data
(),
rr
->
size
(),
true
);
}
}
else
{
WarnL
<<
"未识别的sr rtcp包:"
<<
rtcp
->
dumpString
();
}
break
;
}
case
RtcpType
:
:
RTCP_RR
:
{
_alive_ticker
.
resetTime
();
// 对方汇报rtp接收情况
RtcpRR
*
rr
=
(
RtcpRR
*
)
rtcp
;
for
(
auto
item
:
rr
->
getItemList
())
{
auto
it
=
_ssrc_to_track
.
find
(
item
->
ssrc
);
if
(
it
!=
_ssrc_to_track
.
end
())
{
if
(
it
!=
_ssrc_to_track
.
end
())
{
auto
&
track
=
it
->
second
;
auto
&
track
=
it
->
second
;
auto
rtp_chn
=
track
->
getRtpChannel
(
sr
->
ssrc
);
track
->
rtcp_context_send
->
onRtcp
(
rtcp
);
if
(
!
rtp_chn
)
{
auto
sr
=
track
->
rtcp_context_send
->
createRtcpSR
(
track
->
answer_ssrc_rtp
);
WarnL
<<
"未识别的sr rtcp包:"
<<
rtcp
->
dumpString
();
sendRtcpPacket
(
sr
->
data
(),
sr
->
size
(),
true
);
}
else
{
//InfoL << "接收丢包率,ssrc:" << sr->ssrc << ",loss rate(%):" << rtp_chn->getLossRate();
//设置rtp时间戳与ntp时间戳的对应关系
rtp_chn
->
setNtpStamp
(
sr
->
rtpts
,
sr
->
getNtpUnixStampMS
());
auto
rr
=
rtp_chn
->
createRtcpRR
(
sr
,
track
->
answer_ssrc_rtp
);
sendRtcpPacket
(
rr
->
data
(),
rr
->
size
(),
true
);
}
}
else
{
}
else
{
WarnL
<<
"未识别的
s
r rtcp包:"
<<
rtcp
->
dumpString
();
WarnL
<<
"未识别的
r
r rtcp包:"
<<
rtcp
->
dumpString
();
}
}
break
;
}
}
case
RtcpType
:
:
RTCP_RR
:
{
break
;
_alive_ticker
.
resetTime
();
}
//对方汇报rtp接收情况
case
RtcpType
:
:
RTCP_BYE
:
{
RtcpRR
*
rr
=
(
RtcpRR
*
)
rtcp
;
// 对方汇报停止发送rtp
for
(
auto
item
:
rr
->
getItemList
())
{
RtcpBye
*
bye
=
(
RtcpBye
*
)
rtcp
;
auto
it
=
_ssrc_to_track
.
find
(
item
->
ssrc
);
for
(
auto
ssrc
:
bye
->
getSSRC
())
{
if
(
it
!=
_ssrc_to_track
.
end
())
{
auto
it
=
_ssrc_to_track
.
find
(
*
ssrc
);
auto
&
track
=
it
->
second
;
if
(
it
==
_ssrc_to_track
.
end
())
{
track
->
rtcp_context_send
->
onRtcp
(
rtcp
);
WarnL
<<
"未识别的bye rtcp包:"
<<
rtcp
->
dumpString
();
auto
sr
=
track
->
rtcp_context_send
->
createRtcpSR
(
track
->
answer_ssrc_rtp
);
continue
;
sendRtcpPacket
(
sr
->
data
(),
sr
->
size
(),
true
);
}
else
{
WarnL
<<
"未识别的rr rtcp包:"
<<
rtcp
->
dumpString
();
}
}
}
_ssrc_to_track
.
erase
(
it
);
}
onShutdown
(
SockException
(
Err_eof
,
"rtcp bye message received"
));
break
;
}
case
RtcpType
:
:
RTCP_PSFB
:
case
RtcpType
:
:
RTCP_RTPFB
:
{
if
((
RtcpType
)
rtcp
->
pt
==
RtcpType
::
RTCP_PSFB
)
{
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_BYE
:
{
// RTPFB
//对方汇报停止发送rtp
switch
((
RTPFBType
)
rtcp
->
report_count
)
{
RtcpBye
*
bye
=
(
RtcpBye
*
)
rtcp
;
case
RTPFBType
:
:
RTCP_RTPFB_NACK
:
{
for
(
auto
ssrc
:
bye
->
getSSRC
())
{
RtcpFB
*
fb
=
(
RtcpFB
*
)
rtcp
;
auto
it
=
_ssrc_to_track
.
find
(
*
ssrc
);
auto
it
=
_ssrc_to_track
.
find
(
fb
->
ssrc_media
);
if
(
it
==
_ssrc_to_track
.
end
())
{
if
(
it
==
_ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的bye rtcp包:"
<<
rtcp
->
dumpString
();
WarnL
<<
"未识别的 rtcp包:"
<<
rtcp
->
dumpString
();
continue
;
return
;
}
_ssrc_to_track
.
erase
(
it
);
}
}
onShutdown
(
SockException
(
Err_eof
,
"rtcp bye message received"
));
auto
&
track
=
it
->
second
;
auto
&
fci
=
fb
->
getFci
<
FCI_NACK
>
();
track
->
nack_list
.
forEach
(
fci
,
[
&
](
const
RtpPacket
::
Ptr
&
rtp
)
{
// rtp重传
onSendRtp
(
rtp
,
true
,
true
);
});
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_PSFB
:
default
:
case
RtcpType
:
:
RTCP_RTPFB
:
{
if
((
RtcpType
)
rtcp
->
pt
==
RtcpType
::
RTCP_PSFB
)
{
break
;
}
//RTPFB
switch
((
RTPFBType
)
rtcp
->
report_count
)
{
case
RTPFBType
:
:
RTCP_RTPFB_NACK
:
{
RtcpFB
*
fb
=
(
RtcpFB
*
)
rtcp
;
auto
it
=
_ssrc_to_track
.
find
(
fb
->
ssrc_media
);
if
(
it
==
_ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的 rtcp包:"
<<
rtcp
->
dumpString
();
return
;
}
auto
&
track
=
it
->
second
;
auto
&
fci
=
fb
->
getFci
<
FCI_NACK
>
();
track
->
nack_list
.
forEach
(
fci
,
[
&
](
const
RtpPacket
::
Ptr
&
rtp
)
{
//rtp重传
onSendRtp
(
rtp
,
true
,
true
);
});
break
;
}
default
:
break
;
}
break
;
break
;
}
}
case
RtcpType
:
:
RTCP_XR
:
{
break
;
RtcpXRRRTR
*
xr
=
(
RtcpXRRRTR
*
)
rtcp
;
}
if
(
xr
->
bt
!=
4
){
case
RtcpType
:
:
RTCP_XR
:
{
break
;
RtcpXRRRTR
*
xr
=
(
RtcpXRRRTR
*
)
rtcp
;
}
if
(
xr
->
bt
!=
4
)
{
auto
it
=
_ssrc_to_track
.
find
(
xr
->
ssrc
);
if
(
it
==
_ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的 rtcp包:"
<<
rtcp
->
dumpString
();
return
;
}
auto
&
track
=
it
->
second
;
track
->
rtcp_context_send
->
onRtcp
(
rtcp
);
auto
xrdlrr
=
track
->
rtcp_context_send
->
createRtcpXRDLRR
(
track
->
answer_ssrc_rtp
,
track
->
answer_ssrc_rtp
);
sendRtcpPacket
(
xrdlrr
->
data
(),
xrdlrr
->
size
(),
true
);
break
;
break
;
}
}
default
:
break
;
auto
it
=
_ssrc_to_track
.
find
(
xr
->
ssrc
);
if
(
it
==
_ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的 rtcp包:"
<<
rtcp
->
dumpString
();
return
;
}
auto
&
track
=
it
->
second
;
track
->
rtcp_context_send
->
onRtcp
(
rtcp
);
auto
xrdlrr
=
track
->
rtcp_context_send
->
createRtcpXRDLRR
(
track
->
answer_ssrc_rtp
,
track
->
answer_ssrc_rtp
);
sendRtcpPacket
(
xrdlrr
->
data
(),
xrdlrr
->
size
(),
true
);
break
;
}
default
:
break
;
}
}
}
}
}
}
...
@@ -799,18 +810,18 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
...
@@ -799,18 +810,18 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
void
WebRtcTransportImp
::
createRtpChannel
(
const
string
&
rid
,
uint32_t
ssrc
,
MediaTrack
&
track
)
{
void
WebRtcTransportImp
::
createRtpChannel
(
const
string
&
rid
,
uint32_t
ssrc
,
MediaTrack
&
track
)
{
//rid --> RtpReceiverImp
//
rid --> RtpReceiverImp
auto
&
ref
=
track
.
rtp_channel
[
rid
];
auto
&
ref
=
track
.
rtp_channel
[
rid
];
weak_ptr
<
WebRtcTransportImp
>
weak_self
=
dynamic_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
weak_ptr
<
WebRtcTransportImp
>
weak_self
=
dynamic_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
ref
=
std
::
make_shared
<
RtpChannel
>
(
getPoller
(),
[
&
track
,
this
,
rid
](
RtpPacket
::
Ptr
rtp
)
mutable
{
ref
=
std
::
make_shared
<
RtpChannel
>
(
onSortedRtp
(
track
,
rid
,
std
::
move
(
rtp
));
getPoller
(),
[
&
track
,
this
,
rid
](
RtpPacket
::
Ptr
rtp
)
mutable
{
onSortedRtp
(
track
,
rid
,
std
::
move
(
rtp
));
},
},
[
&
track
,
weak_self
,
ssrc
](
const
FCI_NACK
&
nack
)
mutable
{
[
&
track
,
weak_self
,
ssrc
](
const
FCI_NACK
&
nack
)
mutable
{
//
nack发送可能由定时器异步触发
//
nack发送可能由定时器异步触发
auto
strong_self
=
weak_self
.
lock
();
auto
strong_self
=
weak_self
.
lock
();
if
(
strong_self
)
{
if
(
strong_self
)
{
strong_self
->
onSendNack
(
track
,
nack
,
ssrc
);
strong_self
->
onSendNack
(
track
,
nack
,
ssrc
);
}
}
});
});
InfoL
<<
"create rtp receiver of ssrc:"
<<
ssrc
<<
", rid:"
<<
rid
<<
", codec:"
<<
track
.
plan_rtp
->
codec
;
InfoL
<<
"create rtp receiver of ssrc:"
<<
ssrc
<<
", rid:"
<<
rid
<<
", codec:"
<<
track
.
plan_rtp
->
codec
;
}
}
...
@@ -822,8 +833,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
...
@@ -822,8 +833,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
_bytes_usage
+=
len
;
_bytes_usage
+=
len
;
_alive_ticker
.
resetTime
();
_alive_ticker
.
resetTime
();
RtpHeader
*
rtp
=
(
RtpHeader
*
)
buf
;
RtpHeader
*
rtp
=
(
RtpHeader
*
)
buf
;
//根据接收到的rtp的pt信息,找到该流的信息
//
根据接收到的rtp的pt信息,找到该流的信息
auto
it
=
_pt_to_track
.
find
(
rtp
->
pt
);
auto
it
=
_pt_to_track
.
find
(
rtp
->
pt
);
if
(
it
==
_pt_to_track
.
end
())
{
if
(
it
==
_pt_to_track
.
end
())
{
WarnL
<<
"unknown rtp pt:"
<<
(
int
)
rtp
->
pt
;
WarnL
<<
"unknown rtp pt:"
<<
(
int
)
rtp
->
pt
;
...
@@ -840,10 +851,10 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R
...
@@ -840,10 +851,10 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R
return;
return;
}
}
#endif
#endif
auto
ssrc
=
ntohl
(
rtp
->
ssrc
);
auto
ssrc
=
ntohl
(
rtp
->
ssrc
);
//修改ext id至统一
//
修改ext id至统一
string
rid
;
string
rid
;
auto
twcc_ext
=
track
->
rtp_ext_ctx
->
changeRtpExtId
(
rtp
,
true
,
&
rid
,
RtpExtType
::
transport_cc
);
auto
twcc_ext
=
track
->
rtp_ext_ctx
->
changeRtpExtId
(
rtp
,
true
,
&
rid
,
RtpExtType
::
transport_cc
);
...
@@ -856,66 +867,67 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R
...
@@ -856,66 +867,67 @@ void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, R
_transport
.
createRtpChannel
(
rid
,
ssrc
,
*
track
);
_transport
.
createRtpChannel
(
rid
,
ssrc
,
*
track
);
}
}
//解析并排序rtp
//
解析并排序rtp
ref
->
inputRtp
(
track
->
media
->
type
,
track
->
plan_rtp
->
sample_rate
,
(
uint8_t
*
)
buf
,
len
,
false
);
ref
->
inputRtp
(
track
->
media
->
type
,
track
->
plan_rtp
->
sample_rate
,
(
uint8_t
*
)
buf
,
len
,
false
);
}
}
void
WrappedRtxTrack
::
inputRtp
(
const
char
*
buf
,
size_t
len
,
uint64_t
stamp_ms
,
RtpHeader
*
rtp
)
{
void
WrappedRtxTrack
::
inputRtp
(
const
char
*
buf
,
size_t
len
,
uint64_t
stamp_ms
,
RtpHeader
*
rtp
)
{
//修改ext id至统一
//
修改ext id至统一
string
rid
;
string
rid
;
track
->
rtp_ext_ctx
->
changeRtpExtId
(
rtp
,
true
,
&
rid
,
RtpExtType
::
transport_cc
);
track
->
rtp_ext_ctx
->
changeRtpExtId
(
rtp
,
true
,
&
rid
,
RtpExtType
::
transport_cc
);
auto
&
ref
=
track
->
rtp_channel
[
rid
];
auto
&
ref
=
track
->
rtp_channel
[
rid
];
if
(
!
ref
)
{
if
(
!
ref
)
{
//再接收到对应的rtp前,丢弃rtx包
// 再接收到对应的rtp前,丢弃rtx包
WarnL
<<
"unknown rtx rtp, rid:"
<<
rid
<<
", ssrc:"
<<
ntohl
(
rtp
->
ssrc
)
<<
", codec:"
<<
track
->
plan_rtp
->
codec
<<
", seq:"
<<
ntohs
(
rtp
->
seq
);
WarnL
<<
"unknown rtx rtp, rid:"
<<
rid
<<
", ssrc:"
<<
ntohl
(
rtp
->
ssrc
)
<<
", codec:"
<<
track
->
plan_rtp
->
codec
<<
", seq:"
<<
ntohs
(
rtp
->
seq
);
return
;
return
;
}
}
//这里是rtx重传包
//
这里是rtx重传包
// https://datatracker.ietf.org/doc/html/rfc4588#section-4
//
https://datatracker.ietf.org/doc/html/rfc4588#section-4
auto
payload
=
rtp
->
getPayloadData
();
auto
payload
=
rtp
->
getPayloadData
();
auto
size
=
rtp
->
getPayloadSize
(
len
);
auto
size
=
rtp
->
getPayloadSize
(
len
);
if
(
size
<
2
)
{
if
(
size
<
2
)
{
return
;
return
;
}
}
//前两个字节是原始的rtp的seq
//
前两个字节是原始的rtp的seq
auto
origin_seq
=
payload
[
0
]
<<
8
|
payload
[
1
];
auto
origin_seq
=
payload
[
0
]
<<
8
|
payload
[
1
];
// rtx 转换为 rtp
// rtx 转换为 rtp
rtp
->
pt
=
track
->
plan_rtp
->
pt
;
rtp
->
pt
=
track
->
plan_rtp
->
pt
;
rtp
->
seq
=
htons
(
origin_seq
);
rtp
->
seq
=
htons
(
origin_seq
);
rtp
->
ssrc
=
htonl
(
ref
->
getSSRC
());
rtp
->
ssrc
=
htonl
(
ref
->
getSSRC
());
memmove
((
uint8_t
*
)
buf
+
2
,
buf
,
payload
-
(
uint8_t
*
)
buf
);
memmove
((
uint8_t
*
)
buf
+
2
,
buf
,
payload
-
(
uint8_t
*
)
buf
);
buf
+=
2
;
buf
+=
2
;
len
-=
2
;
len
-=
2
;
ref
->
inputRtp
(
track
->
media
->
type
,
track
->
plan_rtp
->
sample_rate
,
(
uint8_t
*
)
buf
,
len
,
true
);
ref
->
inputRtp
(
track
->
media
->
type
,
track
->
plan_rtp
->
sample_rate
,
(
uint8_t
*
)
buf
,
len
,
true
);
}
}
void
WebRtcTransportImp
::
onSendNack
(
MediaTrack
&
track
,
const
FCI_NACK
&
nack
,
uint32_t
ssrc
)
{
void
WebRtcTransportImp
::
onSendNack
(
MediaTrack
&
track
,
const
FCI_NACK
&
nack
,
uint32_t
ssrc
)
{
auto
rtcp
=
RtcpFB
::
create
(
RTPFBType
::
RTCP_RTPFB_NACK
,
&
nack
,
FCI_NACK
::
kSize
);
auto
rtcp
=
RtcpFB
::
create
(
RTPFBType
::
RTCP_RTPFB_NACK
,
&
nack
,
FCI_NACK
::
kSize
);
rtcp
->
ssrc
=
htonl
(
track
.
answer_ssrc_rtp
);
rtcp
->
ssrc
=
htonl
(
track
.
answer_ssrc_rtp
);
rtcp
->
ssrc_media
=
htonl
(
ssrc
);
rtcp
->
ssrc_media
=
htonl
(
ssrc
);
sendRtcpPacket
((
char
*
)
rtcp
.
get
(),
rtcp
->
getSize
(),
true
);
sendRtcpPacket
((
char
*
)
rtcp
.
get
(),
rtcp
->
getSize
(),
true
);
}
}
void
WebRtcTransportImp
::
onSendTwcc
(
uint32_t
ssrc
,
const
string
&
twcc_fci
)
{
void
WebRtcTransportImp
::
onSendTwcc
(
uint32_t
ssrc
,
const
string
&
twcc_fci
)
{
auto
rtcp
=
RtcpFB
::
create
(
RTPFBType
::
RTCP_RTPFB_TWCC
,
twcc_fci
.
data
(),
twcc_fci
.
size
());
auto
rtcp
=
RtcpFB
::
create
(
RTPFBType
::
RTCP_RTPFB_TWCC
,
twcc_fci
.
data
(),
twcc_fci
.
size
());
rtcp
->
ssrc
=
htonl
(
0
);
rtcp
->
ssrc
=
htonl
(
0
);
rtcp
->
ssrc_media
=
htonl
(
ssrc
);
rtcp
->
ssrc_media
=
htonl
(
ssrc
);
sendRtcpPacket
((
char
*
)
rtcp
.
get
(),
rtcp
->
getSize
(),
true
);
sendRtcpPacket
((
char
*
)
rtcp
.
get
(),
rtcp
->
getSize
(),
true
);
}
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
void
WebRtcTransportImp
::
onSortedRtp
(
MediaTrack
&
track
,
const
string
&
rid
,
RtpPacket
::
Ptr
rtp
)
{
void
WebRtcTransportImp
::
onSortedRtp
(
MediaTrack
&
track
,
const
string
&
rid
,
RtpPacket
::
Ptr
rtp
)
{
if
(
track
.
media
->
type
==
TrackVideo
&&
_pli_ticker
.
elapsedTime
()
>
2000
)
{
if
(
track
.
media
->
type
==
TrackVideo
&&
_pli_ticker
.
elapsedTime
()
>
2000
)
{
//定期发送pli请求关键帧,方便非rtc等协议
//
定期发送pli请求关键帧,方便非rtc等协议
_pli_ticker
.
resetTime
();
_pli_ticker
.
resetTime
();
sendRtcpPli
(
rtp
->
getSSRC
());
sendRtcpPli
(
rtp
->
getSSRC
());
//开启remb,则发送remb包调节比特率
//
开启remb,则发送remb包调节比特率
GET_CONFIG
(
size_t
,
remb_bit_rate
,
RTC
::
kRembBitRate
);
GET_CONFIG
(
size_t
,
remb_bit_rate
,
RTC
::
kRembBitRate
);
if
(
remb_bit_rate
&&
_answer_sdp
->
supportRtcpFb
(
SdpConst
::
kRembRtcpFb
))
{
if
(
remb_bit_rate
&&
_answer_sdp
->
supportRtcpFb
(
SdpConst
::
kRembRtcpFb
))
{
sendRtcpRemb
(
rtp
->
getSSRC
(),
remb_bit_rate
);
sendRtcpRemb
(
rtp
->
getSSRC
(),
remb_bit_rate
);
...
@@ -930,12 +942,14 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPa
...
@@ -930,12 +942,14 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPa
void
WebRtcTransportImp
::
onSendRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
flush
,
bool
rtx
)
{
void
WebRtcTransportImp
::
onSendRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
flush
,
bool
rtx
)
{
auto
&
track
=
_type_to_track
[
rtp
->
type
];
auto
&
track
=
_type_to_track
[
rtp
->
type
];
if
(
!
track
)
{
if
(
!
track
)
{
//忽略,对方不支持该编码类型
//
忽略,对方不支持该编码类型
return
;
return
;
}
}
if
(
!
rtx
)
{
if
(
!
rtx
)
{
//统计rtp发送情况,好做sr汇报
// 统计rtp发送情况,好做sr汇报
track
->
rtcp_context_send
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStamp
(),
rtp
->
ntp_stamp
,
rtp
->
sample_rate
,
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
track
->
rtcp_context_send
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStamp
(),
rtp
->
ntp_stamp
,
rtp
->
sample_rate
,
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
track
->
nack_list
.
pushBack
(
rtp
);
track
->
nack_list
.
pushBack
(
rtp
);
#if 0
#if 0
//此处模拟发送丢包
//此处模拟发送丢包
...
@@ -944,45 +958,45 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r
...
@@ -944,45 +958,45 @@ void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool r
}
}
#endif
#endif
}
else
{
}
else
{
//发送rtx重传包
//
发送rtx重传包
//TraceL << "send rtx rtp:" << rtp->getSeq();
//
TraceL << "send rtx rtp:" << rtp->getSeq();
}
}
pair
<
bool
/*rtx*/
,
MediaTrack
*>
ctx
{
rtx
,
track
.
get
()
};
pair
<
bool
/*rtx*/
,
MediaTrack
*>
ctx
{
rtx
,
track
.
get
()
};
sendRtpPacket
(
rtp
->
data
()
+
RtpPacket
::
kRtpTcpHeaderSize
,
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
,
flush
,
&
ctx
);
sendRtpPacket
(
rtp
->
data
()
+
RtpPacket
::
kRtpTcpHeaderSize
,
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
,
flush
,
&
ctx
);
_bytes_usage
+=
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
;
_bytes_usage
+=
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
;
}
}
void
WebRtcTransportImp
::
onBeforeEncryptRtp
(
const
char
*
buf
,
int
&
len
,
void
*
ctx
)
{
void
WebRtcTransportImp
::
onBeforeEncryptRtp
(
const
char
*
buf
,
int
&
len
,
void
*
ctx
)
{
auto
pr
=
(
pair
<
bool
/*rtx*/
,
MediaTrack
*>
*
)
ctx
;
auto
pr
=
(
pair
<
bool
/*rtx*/
,
MediaTrack
*>
*
)
ctx
;
auto
header
=
(
RtpHeader
*
)
buf
;
auto
header
=
(
RtpHeader
*
)
buf
;
if
(
!
pr
->
first
||
!
pr
->
second
->
plan_rtx
)
{
if
(
!
pr
->
first
||
!
pr
->
second
->
plan_rtx
)
{
//普通的rtp,或者不支持rtx, 修改目标pt和ssrc
//
普通的rtp,或者不支持rtx, 修改目标pt和ssrc
pr
->
second
->
rtp_ext_ctx
->
changeRtpExtId
(
header
,
false
);
pr
->
second
->
rtp_ext_ctx
->
changeRtpExtId
(
header
,
false
);
header
->
pt
=
pr
->
second
->
plan_rtp
->
pt
;
header
->
pt
=
pr
->
second
->
plan_rtp
->
pt
;
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtp
);
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtp
);
}
else
{
}
else
{
//重传的rtp, rtx
//
重传的rtp, rtx
pr
->
second
->
rtp_ext_ctx
->
changeRtpExtId
(
header
,
false
);
pr
->
second
->
rtp_ext_ctx
->
changeRtpExtId
(
header
,
false
);
header
->
pt
=
pr
->
second
->
plan_rtx
->
pt
;
header
->
pt
=
pr
->
second
->
plan_rtx
->
pt
;
if
(
pr
->
second
->
answer_ssrc_rtx
)
{
if
(
pr
->
second
->
answer_ssrc_rtx
)
{
//有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc
//
有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtx
);
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtx
);
}
else
{
}
else
{
//未单独指定rtx的ssrc,那么使用rtp的ssrc
//
未单独指定rtx的ssrc,那么使用rtp的ssrc
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtp
);
header
->
ssrc
=
htonl
(
pr
->
second
->
answer_ssrc_rtp
);
}
}
auto
origin_seq
=
ntohs
(
header
->
seq
);
auto
origin_seq
=
ntohs
(
header
->
seq
);
//seq跟原来的不一样
//
seq跟原来的不一样
header
->
seq
=
htons
(
_rtx_seq
[
pr
->
second
->
media
->
type
]);
header
->
seq
=
htons
(
_rtx_seq
[
pr
->
second
->
media
->
type
]);
++
_rtx_seq
[
pr
->
second
->
media
->
type
];
++
_rtx_seq
[
pr
->
second
->
media
->
type
];
auto
payload
=
header
->
getPayloadData
();
auto
payload
=
header
->
getPayloadData
();
auto
payload_size
=
header
->
getPayloadSize
(
len
);
auto
payload_size
=
header
->
getPayloadSize
(
len
);
if
(
payload_size
)
{
if
(
payload_size
)
{
//rtp负载后移两个字节,这两个字节用于存放osn
//
rtp负载后移两个字节,这两个字节用于存放osn
//https://datatracker.ietf.org/doc/html/rfc4588#section-4
//
https://datatracker.ietf.org/doc/html/rfc4588#section-4
memmove
(
payload
+
2
,
payload
,
payload_size
);
memmove
(
payload
+
2
,
payload
,
payload_size
);
}
}
payload
[
0
]
=
origin_seq
>>
8
;
payload
[
0
]
=
origin_seq
>>
8
;
...
@@ -991,7 +1005,7 @@ void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, int &len, void *ctx
...
@@ -991,7 +1005,7 @@ void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, int &len, void *ctx
}
}
}
}
void
WebRtcTransportImp
::
onShutdown
(
const
SockException
&
ex
){
void
WebRtcTransportImp
::
onShutdown
(
const
SockException
&
ex
)
{
WarnL
<<
ex
.
what
();
WarnL
<<
ex
.
what
();
unrefSelf
();
unrefSelf
();
for
(
auto
&
pr
:
_history_sessions
)
{
for
(
auto
&
pr
:
_history_sessions
)
{
...
@@ -1005,8 +1019,9 @@ void WebRtcTransportImp::onShutdown(const SockException &ex){
...
@@ -1005,8 +1019,9 @@ void WebRtcTransportImp::onShutdown(const SockException &ex){
void
WebRtcTransportImp
::
setSession
(
Session
::
Ptr
session
)
{
void
WebRtcTransportImp
::
setSession
(
Session
::
Ptr
session
)
{
_history_sessions
.
emplace
(
session
.
get
(),
session
);
_history_sessions
.
emplace
(
session
.
get
(),
session
);
if
(
_selected_session
)
{
if
(
_selected_session
)
{
InfoL
<<
"rtc network changed: "
<<
_selected_session
->
get_peer_ip
()
<<
":"
<<
_selected_session
->
get_peer_port
()
InfoL
<<
"rtc network changed: "
<<
_selected_session
->
get_peer_ip
()
<<
":"
<<
" -> "
<<
session
->
get_peer_ip
()
<<
":"
<<
session
->
get_peer_port
()
<<
", id:"
<<
getIdentifier
();
<<
_selected_session
->
get_peer_port
()
<<
" -> "
<<
session
->
get_peer_ip
()
<<
":"
<<
session
->
get_peer_port
()
<<
", id:"
<<
getIdentifier
();
}
}
_selected_session
=
std
::
move
(
session
);
_selected_session
=
std
::
move
(
session
);
unrefSelf
();
unrefSelf
();
...
@@ -1016,18 +1031,18 @@ const Session::Ptr &WebRtcTransportImp::getSession() const {
...
@@ -1016,18 +1031,18 @@ const Session::Ptr &WebRtcTransportImp::getSession() const {
return
_selected_session
;
return
_selected_session
;
}
}
uint64_t
WebRtcTransportImp
::
getBytesUsage
()
const
{
uint64_t
WebRtcTransportImp
::
getBytesUsage
()
const
{
return
_bytes_usage
;
return
_bytes_usage
;
}
}
uint64_t
WebRtcTransportImp
::
getDuration
()
const
{
uint64_t
WebRtcTransportImp
::
getDuration
()
const
{
return
_alive_ticker
.
createdTime
()
/
1000
;
return
_alive_ticker
.
createdTime
()
/
1000
;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void
WebRtcTransportImp
::
registerSelf
()
{
void
WebRtcTransportImp
::
registerSelf
()
{
_self
=
static_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
_self
=
static_pointer_cast
<
WebRtcTransportImp
>
(
shared_from_this
());
WebRtcTransportManager
::
Instance
().
addItem
(
getIdentifier
(),
_self
);
WebRtcTransportManager
::
Instance
().
addItem
(
getIdentifier
(),
_self
);
}
}
...
@@ -1079,8 +1094,8 @@ void WebRtcPluginManager::registerPlugin(const string &type, Plugin cb) {
...
@@ -1079,8 +1094,8 @@ void WebRtcPluginManager::registerPlugin(const string &type, Plugin cb) {
_map_creator
[
type
]
=
std
::
move
(
cb
);
_map_creator
[
type
]
=
std
::
move
(
cb
);
}
}
void
WebRtcPluginManager
::
getAnswerSdp
(
Session
&
sender
,
const
string
&
type
,
const
string
&
offer
,
const
WebRtcArgs
&
args
,
void
WebRtcPluginManager
::
getAnswerSdp
(
const
onCreateRtc
&
cb
)
{
Session
&
sender
,
const
string
&
type
,
const
string
&
offer
,
const
WebRtcArgs
&
args
,
const
onCreateRtc
&
cb
)
{
lock_guard
<
mutex
>
lck
(
_mtx_creator
);
lock_guard
<
mutex
>
lck
(
_mtx_creator
);
auto
it
=
_map_creator
.
find
(
type
);
auto
it
=
_map_creator
.
find
(
type
);
if
(
it
==
_map_creator
.
end
())
{
if
(
it
==
_map_creator
.
end
())
{
...
@@ -1090,17 +1105,20 @@ void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, cons
...
@@ -1090,17 +1105,20 @@ void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, cons
it
->
second
(
sender
,
offer
,
args
,
cb
);
it
->
second
(
sender
,
offer
,
args
,
cb
);
}
}
#include "WebRtcEchoTest.h"
#include "WebRtcPlayer.h"
#include "WebRtcPlayer.h"
#include "WebRtcPusher.h"
#include "WebRtcPusher.h"
#include "WebRtcEchoTest.h"
void
echo_plugin
(
Session
&
sender
,
const
string
&
offer
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
void
echo_plugin
(
Session
&
sender
,
const
string
&
offer
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
cb
(
*
WebRtcEchoTest
::
create
(
EventPollerPool
::
Instance
().
getPoller
()));
cb
(
*
WebRtcEchoTest
::
create
(
EventPollerPool
::
Instance
().
getPoller
()));
}
}
void
push_plugin
(
Session
&
sender
,
const
string
&
offer_sdp
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
void
push_plugin
(
Session
&
sender
,
const
string
&
offer_sdp
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
MediaInfo
info
(
args
[
"url"
]);
MediaInfo
info
(
args
[
"url"
]);
Broadcast
::
PublishAuthInvoker
invoker
=
[
cb
,
offer_sdp
,
info
](
const
string
&
err
,
const
ProtocolOption
&
option
)
mutable
{
Broadcast
::
PublishAuthInvoker
invoker
=
[
cb
,
offer_sdp
,
info
](
const
string
&
err
,
const
ProtocolOption
&
option
)
mutable
{
if
(
!
err
.
empty
())
{
if
(
!
err
.
empty
())
{
cb
(
WebRtcException
(
SockException
(
Err_other
,
err
)));
cb
(
WebRtcException
(
SockException
(
Err_other
,
err
)));
return
;
return
;
...
@@ -1112,15 +1130,15 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
...
@@ -1112,15 +1130,15 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
auto
push_failed
=
(
bool
)
src
;
auto
push_failed
=
(
bool
)
src
;
while
(
src
)
{
while
(
src
)
{
//尝试断连后继续推流
//
尝试断连后继续推流
auto
rtsp_src
=
dynamic_pointer_cast
<
RtspMediaSourceImp
>
(
src
);
auto
rtsp_src
=
dynamic_pointer_cast
<
RtspMediaSourceImp
>
(
src
);
if
(
!
rtsp_src
)
{
if
(
!
rtsp_src
)
{
//源不是rtsp推流产生的
//
源不是rtsp推流产生的
break
;
break
;
}
}
auto
ownership
=
rtsp_src
->
getOwnership
();
auto
ownership
=
rtsp_src
->
getOwnership
();
if
(
!
ownership
)
{
if
(
!
ownership
)
{
//获取推流源所有权失败
//
获取推流源所有权失败
break
;
break
;
}
}
push_src
=
std
::
move
(
rtsp_src
);
push_src
=
std
::
move
(
rtsp_src
);
...
@@ -1139,20 +1157,23 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
...
@@ -1139,20 +1157,23 @@ void push_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
push_src_ownership
=
push_src
->
getOwnership
();
push_src_ownership
=
push_src
->
getOwnership
();
push_src
->
setProtocolOption
(
option
);
push_src
->
setProtocolOption
(
option
);
}
}
auto
rtc
=
WebRtcPusher
::
create
(
EventPollerPool
::
Instance
().
getPoller
(),
push_src
,
push_src_ownership
,
info
,
option
);
auto
rtc
=
WebRtcPusher
::
create
(
EventPollerPool
::
Instance
().
getPoller
(),
push_src
,
push_src_ownership
,
info
,
option
);
push_src
->
setListener
(
rtc
);
push_src
->
setListener
(
rtc
);
cb
(
*
rtc
);
cb
(
*
rtc
);
};
};
//rtsp推流需要鉴权
// rtsp推流需要鉴权
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPublish
,
MediaOriginType
::
rtc_push
,
info
,
invoker
,
static_cast
<
SockInfo
&>
(
sender
));
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPublish
,
MediaOriginType
::
rtc_push
,
info
,
invoker
,
static_cast
<
SockInfo
&>
(
sender
));
if
(
!
flag
)
{
if
(
!
flag
)
{
//该事件无人监听,默认不鉴权
//
该事件无人监听,默认不鉴权
invoker
(
""
,
ProtocolOption
());
invoker
(
""
,
ProtocolOption
());
}
}
}
}
void
play_plugin
(
Session
&
sender
,
const
string
&
offer_sdp
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
void
play_plugin
(
Session
&
sender
,
const
string
&
offer_sdp
,
const
WebRtcArgs
&
args
,
const
WebRtcPluginManager
::
onCreateRtc
&
cb
)
{
MediaInfo
info
(
args
[
"url"
]);
MediaInfo
info
(
args
[
"url"
]);
auto
session_ptr
=
sender
.
shared_from_this
();
auto
session_ptr
=
sender
.
shared_from_this
();
Broadcast
::
AuthInvoker
invoker
=
[
cb
,
offer_sdp
,
info
,
session_ptr
](
const
string
&
err
)
mutable
{
Broadcast
::
AuthInvoker
invoker
=
[
cb
,
offer_sdp
,
info
,
session_ptr
](
const
string
&
err
)
mutable
{
...
@@ -1161,7 +1182,7 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
...
@@ -1161,7 +1182,7 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
return
;
return
;
}
}
//webrtc播放的是rtsp的源
//
webrtc播放的是rtsp的源
info
.
_schema
=
RTSP_SCHEMA
;
info
.
_schema
=
RTSP_SCHEMA
;
MediaSource
::
findAsync
(
info
,
session_ptr
,
[
=
](
const
MediaSource
::
Ptr
&
src_in
)
mutable
{
MediaSource
::
findAsync
(
info
,
session_ptr
,
[
=
](
const
MediaSource
::
Ptr
&
src_in
)
mutable
{
auto
src
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
src_in
);
auto
src
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
src_in
);
...
@@ -1169,22 +1190,23 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
...
@@ -1169,22 +1190,23 @@ void play_plugin(Session &sender, const string &offer_sdp, const WebRtcArgs &arg
cb
(
WebRtcException
(
SockException
(
Err_other
,
"stream not found"
)));
cb
(
WebRtcException
(
SockException
(
Err_other
,
"stream not found"
)));
return
;
return
;
}
}
//还原成rtc,目的是为了hook时识别哪种播放协议
//
还原成rtc,目的是为了hook时识别哪种播放协议
info
.
_schema
=
RTC_SCHEMA
;
info
.
_schema
=
RTC_SCHEMA
;
auto
rtc
=
WebRtcPlayer
::
create
(
EventPollerPool
::
Instance
().
getPoller
(),
src
,
info
);
auto
rtc
=
WebRtcPlayer
::
create
(
EventPollerPool
::
Instance
().
getPoller
(),
src
,
info
);
cb
(
*
rtc
);
cb
(
*
rtc
);
});
});
};
};
//广播通用播放url鉴权事件
// 广播通用播放url鉴权事件
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPlayed
,
info
,
invoker
,
static_cast
<
SockInfo
&>
(
sender
));
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPlayed
,
info
,
invoker
,
static_cast
<
SockInfo
&>
(
sender
));
if
(
!
flag
)
{
if
(
!
flag
)
{
//该事件无人监听,默认不鉴权
//
该事件无人监听,默认不鉴权
invoker
(
""
);
invoker
(
""
);
}
}
}
}
static
onceToken
s_rtc_auto_register
([](){
static
onceToken
s_rtc_auto_register
([]()
{
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"echo"
,
echo_plugin
);
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"echo"
,
echo_plugin
);
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"push"
,
push_plugin
);
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"push"
,
push_plugin
);
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"play"
,
play_plugin
);
WebRtcPluginManager
::
Instance
().
registerPlugin
(
"play"
,
play_plugin
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论