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
964cf391
Commit
964cf391
authored
Jun 25, 2021
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RtcpContext修改时间戳单位、整理WebRTC相关代码
parent
6c01cf33
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
49 行增加
和
52 行删除
+49
-52
src/Rtcp/RtcpContext.cpp
+2
-4
src/Rtcp/RtcpContext.h
+2
-5
src/Rtp/RtpServer.cpp
+2
-2
src/Rtsp/RtspPlayer.cpp
+2
-2
src/Rtsp/RtspPusher.cpp
+2
-2
src/Rtsp/RtspSession.cpp
+3
-3
webrtc/WebRtcTransport.cpp
+33
-31
webrtc/WebRtcTransport.h
+3
-3
没有找到文件。
src/Rtcp/RtcpContext.cpp
查看文件 @
964cf391
...
...
@@ -18,8 +18,7 @@ void RtcpContext::clear() {
memset
(
this
,
0
,
sizeof
(
RtcpContext
));
}
RtcpContext
::
RtcpContext
(
uint32_t
sample_rate
,
bool
is_receiver
)
{
_sample_rate
=
sample_rate
;
RtcpContext
::
RtcpContext
(
bool
is_receiver
)
{
_is_receiver
=
is_receiver
;
}
...
...
@@ -35,7 +34,6 @@ void RtcpContext::onRtp(uint16_t seq, uint32_t stamp, size_t bytes) {
diff
=
-
diff
;
}
//抖动单位为采样次数
diff
*=
(
_sample_rate
/
1000.0
);
_jitter
+=
(
diff
-
_jitter
)
/
16.0
;
}
else
{
_jitter
=
0
;
...
...
@@ -129,7 +127,7 @@ Buffer::Ptr RtcpContext::createRtcpSR(uint32_t rtcp_ssrc) {
rtcp
->
setNtpStamp
(
tv
);
//转换成rtp时间戳
rtcp
->
rtpts
=
htonl
(
uint32_t
(
_last_rtp_stamp
*
(
_sample_rate
/
1000.0
))
);
rtcp
->
rtpts
=
htonl
(
_last_rtp_stamp
);
rtcp
->
packet_count
=
htonl
((
uint32_t
)
_packets
);
rtcp
->
octet_count
=
htonl
((
uint32_t
)
_bytes
);
return
RtcpHeader
::
toBuffer
(
std
::
move
(
rtcp
));
...
...
src/Rtcp/RtcpContext.h
查看文件 @
964cf391
...
...
@@ -22,15 +22,14 @@ public:
using
Ptr
=
std
::
shared_ptr
<
RtcpContext
>
;
/**
* 创建rtcp上下文
* @param sample_rate 音频采用率,视频一般为90000
* @param is_receiver 是否为rtp接收者,接收者更消耗性能
*/
RtcpContext
(
uint32_t
sample_rate
,
bool
is_receiver
);
RtcpContext
(
bool
is_receiver
);
/**
* 输出或输入rtp时调用
* @param seq rtp的seq
* @param stamp rtp的时间戳,单位
毫秒
* @param stamp rtp的时间戳,单位
采样数(非毫秒)
* @param bytes rtp数据长度
*/
void
onRtp
(
uint16_t
seq
,
uint32_t
stamp
,
size_t
bytes
);
...
...
@@ -87,8 +86,6 @@ private:
bool
_is_receiver
;
//时间戳抖动值
double
_jitter
=
0
;
//视频默认90000,音频为采样率
uint32_t
_sample_rate
;
//收到或发送的rtp的字节数
size_t
_bytes
=
0
;
//收到或发送的rtp的个数
...
...
src/Rtp/RtpServer.cpp
查看文件 @
964cf391
...
...
@@ -27,7 +27,7 @@ class RtcpHelper : public RtcpContext, public std::enable_shared_from_this<RtcpH
public
:
using
Ptr
=
std
::
shared_ptr
<
RtcpHelper
>
;
RtcpHelper
(
Socket
::
Ptr
rtcp_sock
,
uint32_t
sample_rate
)
:
RtcpContext
(
sample_rate
,
true
){
RtcpHelper
(
Socket
::
Ptr
rtcp_sock
,
uint32_t
sample_rate
)
:
RtcpContext
(
true
){
_rtcp_sock
=
std
::
move
(
rtcp_sock
);
_sample_rate
=
sample_rate
;
}
...
...
@@ -35,7 +35,7 @@ public:
void
onRecvRtp
(
const
Buffer
::
Ptr
&
buf
,
struct
sockaddr
*
addr
,
int
addr_len
){
//统计rtp接受情况,用于发送rr包
auto
header
=
(
RtpHeader
*
)
buf
->
data
();
onRtp
(
ntohs
(
header
->
seq
),
ntohl
(
header
->
stamp
)
*
uint64_t
(
1000
)
/
_sample_rate
,
buf
->
size
());
onRtp
(
ntohs
(
header
->
seq
),
ntohl
(
header
->
stamp
),
buf
->
size
());
sendRtcp
(
ntohl
(
header
->
ssrc
),
addr
,
addr_len
);
}
...
...
src/Rtsp/RtspPlayer.cpp
查看文件 @
964cf391
...
...
@@ -205,7 +205,7 @@ void RtspPlayer::handleResDESCRIBE(const Parser& parser) {
}
_rtcp_context
.
clear
();
for
(
auto
&
track
:
_sdp_track
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
tr
ack
->
_samplerate
,
tr
ue
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
true
));
}
sendSetup
(
0
);
}
...
...
@@ -591,7 +591,7 @@ void RtspPlayer::sendRtspRequest(const string &cmd, const string &url,const StrC
void
RtspPlayer
::
onBeforeRtpSorted
(
const
RtpPacket
::
Ptr
&
rtp
,
int
track_idx
){
auto
&
rtcp_ctx
=
_rtcp_context
[
track_idx
];
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
ntohl
(
rtp
->
getHeader
()
->
stamp
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
auto
&
ticker
=
_rtcp_send_ticker
[
track_idx
];
if
(
ticker
.
elapsedTime
()
<
3
*
1000
)
{
...
...
src/Rtsp/RtspPusher.cpp
查看文件 @
964cf391
...
...
@@ -179,7 +179,7 @@ void RtspPusher::sendAnnounce() {
}
_rtcp_context
.
clear
();
for
(
auto
&
track
:
_track_vec
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
false
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
false
));
}
_on_res_func
=
std
::
bind
(
&
RtspPusher
::
handleResAnnounce
,
this
,
placeholders
::
_1
);
sendRtspRequest
(
"ANNOUNCE"
,
_url
,
{},
src
->
getSdp
());
...
...
@@ -360,7 +360,7 @@ void RtspPusher::updateRtcpContext(const RtpPacket::Ptr &rtp){
int
track_index
=
getTrackIndexByTrackType
(
rtp
->
type
);
auto
&
ticker
=
_rtcp_send_ticker
[
track_index
];
auto
&
rtcp_ctx
=
_rtcp_context
[
track_index
];
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
ntohl
(
rtp
->
getHeader
()
->
stamp
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
//send rtcp every 5 second
if
(
ticker
.
elapsedTime
()
>
5
*
1000
)
{
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
964cf391
...
...
@@ -252,7 +252,7 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) {
}
_rtcp_context
.
clear
();
for
(
auto
&
track
:
_sdp_track
)
{
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
tr
ack
->
_samplerate
,
tr
ue
));
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
true
));
}
_push_src
=
std
::
make_shared
<
RtspMediaSourceImp
>
(
_media_info
.
_vhost
,
_media_info
.
_app
,
_media_info
.
_streamid
);
_push_src
->
setListener
(
dynamic_pointer_cast
<
MediaSourceEvent
>
(
shared_from_this
()));
...
...
@@ -413,7 +413,7 @@ void RtspSession::onAuthSuccess() {
}
strongSelf
->
_rtcp_context
.
clear
();
for
(
auto
&
track
:
strongSelf
->
_sdp_track
)
{
strongSelf
->
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
track
->
_samplerate
,
false
));
strongSelf
->
_rtcp_context
.
emplace_back
(
std
::
make_shared
<
RtcpContext
>
(
false
));
}
strongSelf
->
_sessionid
=
makeRandStr
(
12
);
strongSelf
->
_play_src
=
rtsp_src
;
...
...
@@ -1126,7 +1126,7 @@ void RtspSession::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_index){
void
RtspSession
::
updateRtcpContext
(
const
RtpPacket
::
Ptr
&
rtp
){
int
track_index
=
getTrackIndexByTrackType
(
rtp
->
type
);
auto
&
rtcp_ctx
=
_rtcp_context
[
track_index
];
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
ntohl
(
rtp
->
getHeader
()
->
stamp
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
auto
&
ticker
=
_rtcp_send_tickers
[
track_index
];
//send rtcp every 5 second
...
...
webrtc/WebRtcTransport.cpp
查看文件 @
964cf391
...
...
@@ -408,19 +408,19 @@ void WebRtcTransportImp::onStartWebRTC() {
info
->
offer_ssrc_rtx
=
m_offer
->
getRtxSSRC
();
info
->
plan_rtp
=
&
m_answer
.
plan
[
0
];;
info
->
plan_rtx
=
m_answer
.
getRelatedRtxPlan
(
info
->
plan_rtp
->
pt
);
info
->
rtcp_context_send
=
std
::
make_shared
<
RtcpContext
>
(
info
->
plan_rtp
->
sample_rate
,
false
);
info
->
rtcp_context_send
=
std
::
make_shared
<
RtcpContext
>
(
false
);
//send ssrc --> MediaTrack
_
rtp_info_ssrc
[
info
->
answer_ssrc_rtp
]
=
info
;
_
ssrc_to_track
[
info
->
answer_ssrc_rtp
]
=
info
;
//recv ssrc --> MediaTrack
_
rtp_info_ssrc
[
info
->
offer_ssrc_rtp
]
=
info
;
_
ssrc_to_track
[
info
->
offer_ssrc_rtp
]
=
info
;
//rtp pt --> MediaTrack
_
rtp_info_pt
.
emplace
(
info
->
plan_rtp
->
pt
,
std
::
make_pair
(
false
,
info
));
_
pt_to_track
.
emplace
(
info
->
plan_rtp
->
pt
,
std
::
make_pair
(
false
,
info
));
if
(
info
->
plan_rtx
)
{
//rtx pt --> MediaTrack
_
rtp_info_pt
.
emplace
(
info
->
plan_rtx
->
pt
,
std
::
make_pair
(
true
,
info
));
_
pt_to_track
.
emplace
(
info
->
plan_rtx
->
pt
,
std
::
make_pair
(
true
,
info
));
}
if
(
m_offer
->
type
!=
TrackApplication
)
{
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
...
...
@@ -464,10 +464,10 @@ void WebRtcTransportImp::onStartWebRTC() {
}
auto
rtsp_media
=
rtsp_send_sdp
.
getMedia
(
m
.
type
);
if
(
rtsp_media
&&
getCodecId
(
rtsp_media
->
plan
[
0
].
codec
)
==
getCodecId
(
m
.
plan
[
0
].
codec
))
{
auto
it
=
_
rtp_info_pt
.
find
(
m
.
plan
[
0
].
pt
);
CHECK
(
it
!=
_
rtp_info_pt
.
end
());
auto
it
=
_
pt_to_track
.
find
(
m
.
plan
[
0
].
pt
);
CHECK
(
it
!=
_
pt_to_track
.
end
());
//记录发送rtp时约定的信息,届时发送rtp时需要修改pt和ssrc
_
send_rtp_info
[
m
.
type
]
=
it
->
second
.
second
;
_
type_to_track
[
m
.
type
]
=
it
->
second
.
second
;
}
}
}
...
...
@@ -558,8 +558,7 @@ SdpAttrCandidate::Ptr WebRtcTransportImp::getIceCandidate() const{
class
RtpChannel
:
public
RtpReceiver
{
public
:
uint32_t
ssrc
;
RtcpContext
::
Ptr
rtcp_context
;
uint32_t
rtp_ssrc
;
public
:
RtpChannel
(
function
<
void
(
RtpPacket
::
Ptr
rtp
)
>
on_rtp
,
function
<
void
(
const
FCI_NACK
&
nack
)
>
on_nack
)
{
...
...
@@ -576,11 +575,16 @@ public:
//统计rtp接受情况,便于生成nack rtcp包
nack_ctx
.
received
(
seq
);
//统计rtp收到的情况,好做rr汇报
rtcp_context
->
onRtp
(
seq
,
ntohl
(
rtp
->
stamp
)
*
uint64_t
(
1000
)
/
sample_rate
,
len
);
rtcp_context
.
onRtp
(
seq
,
ntohl
(
rtp
->
stamp
)
,
len
);
}
return
handleOneRtp
((
int
)
type
,
type
,
sample_rate
,
ptr
,
len
);
}
Buffer
::
Ptr
createRtcpRR
(
RtcpHeader
*
sr
,
uint32_t
ssrc
)
{
rtcp_context
.
onRtcp
(
sr
);
return
rtcp_context
.
createRtcpRR
(
ssrc
,
rtp_ssrc
);
}
protected
:
void
onRtpSorted
(
RtpPacket
::
Ptr
rtp
,
int
track_index
)
override
{
_on_sort
(
std
::
move
(
rtp
));
...
...
@@ -588,6 +592,7 @@ protected:
private
:
NackContext
nack_ctx
;
RtcpContext
rtcp_context
{
true
};
function
<
void
(
RtpPacket
::
Ptr
rtp
)
>
_on_sort
;
};
...
...
@@ -611,15 +616,14 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
case
RtcpType
:
:
RTCP_SR
:
{
//对方汇报rtp发送情况
RtcpSR
*
sr
=
(
RtcpSR
*
)
rtcp
;
auto
it
=
_
rtp_info_ssrc
.
find
(
sr
->
ssrc
);
if
(
it
!=
_
rtp_info_ssrc
.
end
())
{
auto
it
=
_
ssrc_to_track
.
find
(
sr
->
ssrc
);
if
(
it
!=
_
ssrc_to_track
.
end
())
{
auto
&
info
=
it
->
second
;
auto
rtp_chn
=
info
->
getRtpChannel
(
sr
->
ssrc
);
if
(
!
rtp_chn
){
WarnL
<<
"未识别的sr rtcp包:"
<<
rtcp
->
dumpString
();
}
else
{
rtp_chn
->
rtcp_context
->
onRtcp
(
sr
);
auto
rr
=
rtp_chn
->
rtcp_context
->
createRtcpRR
(
info
->
answer_ssrc_rtp
,
sr
->
ssrc
);
auto
rr
=
rtp_chn
->
createRtcpRR
(
sr
,
info
->
answer_ssrc_rtp
);
sendRtcpPacket
(
rr
->
data
(),
rr
->
size
(),
true
);
}
}
else
{
...
...
@@ -632,8 +636,8 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
//对方汇报rtp接收情况
RtcpRR
*
rr
=
(
RtcpRR
*
)
rtcp
;
for
(
auto
item
:
rr
->
getItemList
())
{
auto
it
=
_
rtp_info_ssrc
.
find
(
item
->
ssrc
);
if
(
it
!=
_
rtp_info_ssrc
.
end
())
{
auto
it
=
_
ssrc_to_track
.
find
(
item
->
ssrc
);
if
(
it
!=
_
ssrc_to_track
.
end
())
{
auto
&
info
=
it
->
second
;
auto
sr
=
info
->
rtcp_context_send
->
createRtcpSR
(
info
->
answer_ssrc_rtp
);
sendRtcpPacket
(
sr
->
data
(),
sr
->
size
(),
true
);
...
...
@@ -647,12 +651,12 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
//对方汇报停止发送rtp
RtcpBye
*
bye
=
(
RtcpBye
*
)
rtcp
;
for
(
auto
ssrc
:
bye
->
getSSRC
())
{
auto
it
=
_
rtp_info_ssrc
.
find
(
*
ssrc
);
if
(
it
==
_
rtp_info_ssrc
.
end
())
{
auto
it
=
_
ssrc_to_track
.
find
(
*
ssrc
);
if
(
it
==
_
ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的bye rtcp包:"
<<
rtcp
->
dumpString
();
continue
;
}
_
rtp_info_ssrc
.
erase
(
it
);
_
ssrc_to_track
.
erase
(
it
);
}
onShutdown
(
SockException
(
Err_eof
,
"rtcp bye message received"
));
break
;
...
...
@@ -666,8 +670,8 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
switch
((
RTPFBType
)
rtcp
->
report_count
)
{
case
RTPFBType
:
:
RTCP_RTPFB_NACK
:
{
RtcpFB
*
fb
=
(
RtcpFB
*
)
rtcp
;
auto
it
=
_
rtp_info_ssrc
.
find
(
fb
->
ssrc_media
);
if
(
it
==
_
rtp_info_ssrc
.
end
())
{
auto
it
=
_
ssrc_to_track
.
find
(
fb
->
ssrc_media
);
if
(
it
==
_
ssrc_to_track
.
end
())
{
WarnL
<<
"未识别的 rtcp包:"
<<
rtcp
->
dumpString
();
return
;
}
...
...
@@ -752,11 +756,9 @@ void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, cons
onSendNack
(
*
info
,
nack
,
ssrc
);
});
//rid --> rtp ssrc
ref
->
ssrc
=
ssrc
;
//rtp ssrc --> RtcpContext
ref
->
rtcp_context
=
std
::
make_shared
<
RtcpContext
>
(
info
->
plan_rtp
->
sample_rate
,
true
);
ref
->
rtp_ssrc
=
ssrc
;
//rtp ssrc --> MediaTrack
_
rtp_info_ssrc
[
ssrc
]
=
info
;
_
ssrc_to_track
[
ssrc
]
=
info
;
InfoL
<<
"create rtp receiver of ssrc:"
<<
ssrc
<<
", rid:"
<<
rid
<<
", codec:"
<<
info
->
plan_rtp
->
codec
;
}
...
...
@@ -766,8 +768,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) {
RtpHeader
*
rtp
=
(
RtpHeader
*
)
buf
;
//根据接收到的rtp的pt信息,找到该流的信息
auto
it
=
_
rtp_info_pt
.
find
(
rtp
->
pt
);
if
(
it
==
_
rtp_info_pt
.
end
())
{
auto
it
=
_
pt_to_track
.
find
(
rtp
->
pt
);
if
(
it
==
_
pt_to_track
.
end
())
{
WarnL
<<
"unknown rtp pt:"
<<
(
int
)
rtp
->
pt
;
return
;
}
...
...
@@ -822,7 +824,7 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) {
//rtx 转换为 rtp
rtp
->
pt
=
info
->
plan_rtp
->
pt
;
rtp
->
seq
=
htons
(
origin_seq
);
rtp
->
ssrc
=
htonl
(
ref
->
ssrc
);
rtp
->
ssrc
=
htonl
(
ref
->
rtp_
ssrc
);
memmove
((
uint8_t
*
)
buf
+
2
,
buf
,
payload
-
(
uint8_t
*
)
buf
);
buf
+=
2
;
...
...
@@ -878,14 +880,14 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &info, const string &rid, RtpPac
///////////////////////////////////////////////////////////////////
void
WebRtcTransportImp
::
onSendRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
flush
,
bool
rtx
){
auto
&
info
=
_
send_rtp_info
[
rtp
->
type
];
auto
&
info
=
_
type_to_track
[
rtp
->
type
];
if
(
!
info
)
{
//忽略,对方不支持该编码类型
return
;
}
if
(
!
rtx
)
{
//统计rtp发送情况,好做sr汇报
info
->
rtcp_context_send
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
info
->
rtcp_context_send
->
onRtp
(
rtp
->
getSeq
(),
ntohl
(
rtp
->
getHeader
()
->
stamp
),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
info
->
nack_list
.
push_back
(
rtp
);
#if 0
//此处模拟发送丢包
...
...
webrtc/WebRtcTransport.h
查看文件 @
964cf391
...
...
@@ -384,11 +384,11 @@ private:
//播放rtsp源的reader对象
RtspMediaSource
::
RingType
::
RingReader
::
Ptr
_reader
;
//根据发送rtp的track类型获取相关信息
MediaTrack
::
Ptr
_
send_rtp_info
[
2
];
MediaTrack
::
Ptr
_
type_to_track
[
2
];
//根据接收rtp的pt获取相关信息
unordered_map
<
uint8_t
/*pt*/
,
std
::
pair
<
bool
/*is rtx*/
,
MediaTrack
::
Ptr
>
>
_
rtp_info_pt
;
unordered_map
<
uint8_t
/*pt*/
,
std
::
pair
<
bool
/*is rtx*/
,
MediaTrack
::
Ptr
>
>
_
pt_to_track
;
//根据rtcp的ssrc获取相关信息,只记录rtp的ssrc,rtx的ssrc不记录
unordered_map
<
uint32_t
/*ssrc*/
,
MediaTrack
::
Ptr
>
_
rtp_info_ssrc
;
unordered_map
<
uint32_t
/*ssrc*/
,
MediaTrack
::
Ptr
>
_
ssrc_to_track
;
//发送rtp时需要修改rtp ext id
map
<
RtpExtType
,
uint8_t
>
_rtp_ext_type_to_id
;
//接收rtp时需要修改rtp ext id
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论