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
070bf19c
Commit
070bf19c
authored
Jan 31, 2021
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重写rtp框架
parent
5175c52a
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
399 行增加
和
325 行删除
+399
-325
conf/config.ini
+0
-2
src/Common/config.cpp
+0
-3
src/Common/config.h
+0
-2
src/Extension/AACRtp.cpp
+31
-32
src/Extension/AACRtp.h
+1
-1
src/Extension/CommonRtp.cpp
+14
-13
src/Extension/H264Rtp.cpp
+24
-22
src/Extension/H265Rtp.cpp
+17
-16
src/Rtp/GB28181Process.cpp
+4
-3
src/Rtp/RtpCache.cpp
+1
-1
src/Rtsp/RtpCodec.cpp
+30
-36
src/Rtsp/RtpCodec.h
+21
-43
src/Rtsp/RtpReceiver.cpp
+46
-105
src/Rtsp/RtpReceiver.h
+4
-6
src/Rtsp/Rtsp.cpp
+90
-2
src/Rtsp/Rtsp.h
+94
-10
src/Rtsp/RtspMediaSource.h
+4
-4
src/Rtsp/RtspPlayer.cpp
+7
-6
src/Rtsp/RtspPusher.cpp
+5
-4
src/Rtsp/RtspSession.cpp
+6
-12
src/Rtsp/RtspSession.h
+0
-2
没有找到文件。
conf/config.ini
查看文件 @
070bf19c
...
...
@@ -195,8 +195,6 @@ sslport=19350
#音频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
#加大该值会明显增加直播延时
audioMtuSize
=
600
#rtp时间戳回环时间,单位毫秒
cycleMS
=
46800000
#视频mtu大小,该参数限制rtp最大字节数,推荐不要超过1400
videoMtuSize
=
1400
...
...
src/Common/config.cpp
查看文件 @
070bf19c
...
...
@@ -194,15 +194,12 @@ const string kAudioMtuSize = RTP_FIELD"audioMtuSize";
const
string
kMaxRtpCount
=
RTP_FIELD
"maxRtpCount"
;
//如果RTP序列正确次数累计达到该数字就启动清空排序缓存
const
string
kClearCount
=
RTP_FIELD
"clearCount"
;
//最大RTP时间为13个小时,每13小时回环一次
const
string
kCycleMS
=
RTP_FIELD
"cycleMS"
;
onceToken
token
([](){
mINI
::
Instance
()[
kVideoMtuSize
]
=
1400
;
mINI
::
Instance
()[
kAudioMtuSize
]
=
600
;
mINI
::
Instance
()[
kMaxRtpCount
]
=
50
;
mINI
::
Instance
()[
kClearCount
]
=
10
;
mINI
::
Instance
()[
kCycleMS
]
=
13
*
60
*
60
*
1000
;
},
nullptr
);
}
//namespace Rtsp
...
...
src/Common/config.h
查看文件 @
070bf19c
...
...
@@ -251,8 +251,6 @@ extern const string kAudioMtuSize;
extern
const
string
kMaxRtpCount
;
//如果RTP序列正确次数累计达到该数字就启动清空排序缓存
extern
const
string
kClearCount
;
//最大RTP时间为13个小时,每13小时回环一次
extern
const
string
kCycleMS
;
}
//namespace Rtsp
////////////组播配置///////////
...
...
src/Extension/AACRtp.cpp
查看文件 @
070bf19c
...
...
@@ -25,32 +25,30 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
}
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
uiStamp
=
frame
->
dts
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
uiStamp
%=
cycleMS
;
auto
*
ptr
=
(
char
*
)
pcData
;
auto
iSize
=
iLen
;
while
(
iSize
>
0
)
{
if
(
iSize
<=
_ui32MtuSize
-
20
)
{
_aucSectionBuf
[
0
]
=
0
;
_aucSectionBuf
[
1
]
=
16
;
_aucSectionBuf
[
2
]
=
(
iLen
>>
5
)
&
0xFF
;
_aucSectionBuf
[
3
]
=
((
iLen
&
0x1F
)
<<
3
)
&
0xFF
;
memcpy
(
_aucSectionBuf
+
4
,
ptr
,
iSize
);
makeAACRtp
(
_aucSectionBuf
,
iSize
+
4
,
true
,
uiStamp
);
auto
stamp
=
frame
->
dts
();
auto
data
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
len
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
ptr
=
(
char
*
)
data
;
auto
remain_size
=
len
;
auto
max_size
=
getMaxSize
()
-
4
;
while
(
remain_size
>
0
)
{
if
(
remain_size
<=
max_size
)
{
_section_buf
[
0
]
=
0
;
_section_buf
[
1
]
=
16
;
_section_buf
[
2
]
=
(
len
>>
5
)
&
0xFF
;
_section_buf
[
3
]
=
((
len
&
0x1F
)
<<
3
)
&
0xFF
;
memcpy
(
_section_buf
+
4
,
ptr
,
remain_size
);
makeAACRtp
(
_section_buf
,
remain_size
+
4
,
true
,
stamp
);
break
;
}
_
aucSectionB
uf
[
0
]
=
0
;
_
aucSectionB
uf
[
1
]
=
16
;
_
aucSectionBuf
[
2
]
=
((
iL
en
)
>>
5
)
&
0xFF
;
_
aucSectionBuf
[
3
]
=
((
iL
en
&
0x1F
)
<<
3
)
&
0xFF
;
memcpy
(
_
aucSectionBuf
+
4
,
ptr
,
_ui32MtuSize
-
20
);
makeAACRtp
(
_
aucSectionBuf
,
_ui32MtuSize
-
16
,
false
,
uiS
tamp
);
ptr
+=
(
_ui32MtuSize
-
20
)
;
iSize
-=
(
_ui32MtuSize
-
20
)
;
_
section_b
uf
[
0
]
=
0
;
_
section_b
uf
[
1
]
=
16
;
_
section_buf
[
2
]
=
((
l
en
)
>>
5
)
&
0xFF
;
_
section_buf
[
3
]
=
((
l
en
&
0x1F
)
<<
3
)
&
0xFF
;
memcpy
(
_
section_buf
+
4
,
ptr
,
max_size
);
makeAACRtp
(
_
section_buf
,
max_size
+
4
,
false
,
s
tamp
);
ptr
+=
max_size
;
remain_size
-=
max_size
;
}
}
...
...
@@ -82,15 +80,16 @@ void AACRtpDecoder::obtainFrame() {
_frame
->
_codec_id
=
CodecAAC
;
}
bool
AACRtpDecoder
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtppack
,
bool
key_pos
)
{
bool
AACRtpDecoder
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
key_pos
)
{
auto
stamp
=
rtp
->
getStampMS
();
//rtp数据开始部分
uint8_t
*
ptr
=
(
uint8_t
*
)
rtppack
->
data
()
+
rtppack
->
offset
;
auto
ptr
=
rtp
->
getPayload
()
;
//rtp数据末尾
uint8_t
*
end
=
(
uint8_t
*
)
rtppack
->
data
()
+
rtppack
->
s
ize
();
auto
end
=
ptr
+
rtp
->
getPayloadS
ize
();
//首2字节表示Au-Header的个数,单位bit,所以除以16得到Au-Header个数
uint16_t
au_header_count
=
((
ptr
[
0
]
<<
8
)
|
ptr
[
1
])
>>
4
;
auto
au_header_count
=
((
ptr
[
0
]
<<
8
)
|
ptr
[
1
])
>>
4
;
//记录au_header起始指针
uint8_t
*
au_header_ptr
=
ptr
+
2
;
auto
au_header_ptr
=
ptr
+
2
;
ptr
=
au_header_ptr
+
au_header_count
*
2
;
if
(
end
<
ptr
)
{
...
...
@@ -100,11 +99,11 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
if
(
!
_last_dts
)
{
//记录第一个时间戳
_last_dts
=
rtppack
->
timeS
tamp
;
_last_dts
=
s
tamp
;
}
//每个audio unit时间戳增量
auto
dts_inc
=
(
rtppack
->
timeS
tamp
-
_last_dts
)
/
au_header_count
;
auto
dts_inc
=
(
s
tamp
-
_last_dts
)
/
au_header_count
;
if
(
dts_inc
<
0
&&
dts_inc
>
100
)
{
//时间戳增量异常,忽略
dts_inc
=
0
;
...
...
@@ -129,7 +128,7 @@ bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
}
}
//记录上次时间戳
_last_dts
=
rtppack
->
timeS
tamp
;
_last_dts
=
s
tamp
;
return
false
;
}
...
...
src/Extension/AACRtp.h
查看文件 @
070bf19c
...
...
@@ -80,7 +80,7 @@ private:
void
makeAACRtp
(
const
void
*
pData
,
size_t
uiLen
,
bool
bMark
,
uint32_t
uiStamp
);
private
:
unsigned
char
_
aucSectionB
uf
[
1600
];
unsigned
char
_
section_b
uf
[
1600
];
};
}
//namespace mediakit
...
...
src/Extension/CommonRtp.cpp
查看文件 @
070bf19c
...
...
@@ -29,14 +29,16 @@ void CommonRtpDecoder::obtainFrame() {
}
bool
CommonRtpDecoder
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
){
auto
payload
=
rtp
->
data
()
+
rtp
->
offset
;
auto
size
=
rtp
->
size
()
-
rtp
->
offset
;
auto
payload
=
rtp
->
getPayload
();
auto
size
=
rtp
->
getPayloadSize
();
auto
stamp
=
rtp
->
getStampMS
();
auto
seq
=
rtp
->
getSeq
();
if
(
size
<=
0
)
{
//无实际负载
return
false
;
}
if
(
_frame
->
_dts
!=
rtp
->
timeS
tamp
||
_frame
->
_buffer
.
size
()
>
_max_frame_size
)
{
if
(
_frame
->
_dts
!=
s
tamp
||
_frame
->
_buffer
.
size
()
>
_max_frame_size
)
{
//时间戳发生变化或者缓存超过MAX_FRAME_SIZE,则清空上帧数据
if
(
!
_frame
->
_buffer
.
empty
())
{
//有有效帧,则输出
...
...
@@ -45,20 +47,20 @@ bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
//新的一帧数据
obtainFrame
();
_frame
->
_dts
=
rtp
->
timeS
tamp
;
_frame
->
_dts
=
s
tamp
;
_drop_flag
=
false
;
}
else
if
(
_last_seq
!=
0
&&
(
uint16_t
)(
_last_seq
+
1
)
!=
rtp
->
sequence
)
{
}
else
if
(
_last_seq
!=
0
&&
(
uint16_t
)(
_last_seq
+
1
)
!=
seq
)
{
//时间戳未发生变化,但是seq却不连续,说明中间rtp丢包了,那么整帧应该废弃
WarnL
<<
"rtp丢包:"
<<
_last_seq
<<
" -> "
<<
rtp
->
sequence
;
WarnL
<<
"rtp丢包:"
<<
_last_seq
<<
" -> "
<<
seq
;
_drop_flag
=
true
;
_frame
->
_buffer
.
clear
();
}
if
(
!
_drop_flag
)
{
_frame
->
_buffer
.
append
(
payload
,
size
);
_frame
->
_buffer
.
append
(
(
char
*
)
payload
,
size
);
}
_last_seq
=
rtp
->
sequence
;
_last_seq
=
seq
;
return
false
;
}
...
...
@@ -70,18 +72,17 @@ CommonRtpEncoder::CommonRtpEncoder(CodecId codec, uint32_t ssrc, uint32_t mtu_si
}
void
CommonRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
){
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
stamp
=
frame
->
dts
()
%
cycleMS
;
auto
stamp
=
frame
->
dts
();
auto
ptr
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
len
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
remain_size
=
len
;
const
auto
max_rtp_size
=
_ui32MtuSize
-
20
;
auto
max_size
=
getMaxSize
()
;
bool
mark
=
false
;
while
(
remain_size
>
0
)
{
size_t
rtp_size
;
if
(
remain_size
>
max_
rtp_
size
)
{
rtp_size
=
max_
rtp_
size
;
if
(
remain_size
>
max_size
)
{
rtp_size
=
max_size
;
}
else
{
rtp_size
=
remain_size
;
mark
=
true
;
...
...
src/Extension/H264Rtp.cpp
查看文件 @
070bf19c
...
...
@@ -46,7 +46,7 @@ bool H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
return
decodeRtp
(
rtp
);
}
bool
H264RtpDecoder
::
decodeRtp
(
const
RtpPacket
::
Ptr
&
rtp
pack
)
{
bool
H264RtpDecoder
::
decodeRtp
(
const
RtpPacket
::
Ptr
&
rtp
)
{
/**
* h264帧类型
* Type==1:P/B frame
...
...
@@ -71,8 +71,11 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
29 FU-B Fragmentation unit 5.8
30-31 undefined -
*/
const
uint8_t
*
frame
=
(
uint8_t
*
)
rtppack
->
data
()
+
rtppack
->
offset
;
auto
length
=
rtppack
->
size
()
-
rtppack
->
offset
;
auto
frame
=
rtp
->
getPayload
();
auto
length
=
rtp
->
getPayloadSize
();
auto
stamp
=
rtp
->
getStampMS
();
auto
seq
=
rtp
->
getSeq
();
int
nal_type
=
*
frame
&
0x1F
;
int
nal_suffix
=
*
frame
&
(
~
0x1F
);
...
...
@@ -80,7 +83,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
//a full frame
_h264frame
->
_buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_buffer
.
append
((
char
*
)
frame
,
length
);
_h264frame
->
_pts
=
rtppack
->
timeS
tamp
;
_h264frame
->
_pts
=
s
tamp
;
auto
key
=
_h264frame
->
keyFrame
();
onGetH264
(
_h264frame
);
return
(
key
);
//i frame
...
...
@@ -107,7 +110,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
//有有效数据
_h264frame
->
_buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_buffer
.
append
((
char
*
)
ptr
,
len
);
_h264frame
->
_pts
=
rtppack
->
timeS
tamp
;
_h264frame
->
_pts
=
s
tamp
;
if
((
ptr
[
0
]
&
0x1F
)
==
H264Frame
::
NAL_IDR
)
{
haveIDR
=
true
;
}
...
...
@@ -127,16 +130,16 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
_h264frame
->
_buffer
.
assign
(
"\x0\x0\x0\x1"
,
4
);
_h264frame
->
_buffer
.
push_back
(
nal_suffix
|
fu
.
type
);
_h264frame
->
_buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_pts
=
rtppack
->
timeS
tamp
;
_h264frame
->
_pts
=
s
tamp
;
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
seq
;
return
_h264frame
->
keyFrame
();
}
if
(
rtppack
->
sequence
!=
(
uint16_t
)(
_lastSeq
+
1
)
&&
rtppack
->
sequence
!=
0
)
{
if
(
seq
!=
(
uint16_t
)(
_lastSeq
+
1
)
&&
seq
!=
0
)
{
//中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃
_h264frame
->
_buffer
.
clear
();
WarnL
<<
"rtp丢包: "
<<
rtppack
->
sequence
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
WarnL
<<
"rtp丢包: "
<<
seq
<<
" != "
<<
_lastSeq
<<
" + 1,该帧被废弃"
;
return
false
;
}
...
...
@@ -144,13 +147,13 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
//该帧的中间rtp包 FU-A mid
_h264frame
->
_buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
//该函数return时,保存下当前sequence,以便下次对比seq是否连续
_lastSeq
=
rtppack
->
sequence
;
_lastSeq
=
seq
;
return
false
;
}
//该帧最后一个rtp包 FU-A end
_h264frame
->
_buffer
.
append
((
char
*
)
frame
+
2
,
length
-
2
);
_h264frame
->
_pts
=
rtppack
->
timeS
tamp
;
_h264frame
->
_pts
=
s
tamp
;
onGetH264
(
_h264frame
);
return
false
;
}
...
...
@@ -163,7 +166,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
// 0 udef
// 30 udef
// 31 udef
WarnL
<<
"不支持的rtp类型:"
<<
(
int
)
nal_type
<<
" "
<<
rtppack
->
sequence
;
WarnL
<<
"不支持的rtp类型:"
<<
(
int
)
nal_type
<<
" "
<<
seq
;
return
false
;
}
}
...
...
@@ -193,15 +196,14 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
}
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
ptr
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
len
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
pts
=
frame
->
pts
()
%
cycleMS
;
auto
pts
=
frame
->
pts
();
auto
nal_type
=
H264_TYPE
(
ptr
[
0
]);
size_t
payload_size
=
_ui32MtuSize
-
2
;
auto
max_size
=
getMaxSize
()
-
2
;
//超过MTU则按照FU-A模式打包
if
(
len
>
payload
_size
+
1
)
{
if
(
len
>
max
_size
+
1
)
{
//最高位bit为forbidden_zero_bit,
//后面2bit为nal_ref_idc(帧重要程度),00:可以丢,11:不能丢
//末尾5bit为nalu type,固定为28(FU-A)
...
...
@@ -211,10 +213,10 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
bool
mark_bit
=
false
;
size_t
offset
=
1
;
while
(
!
mark_bit
)
{
if
(
len
<=
offset
+
payload
_size
)
{
if
(
len
<=
offset
+
max
_size
)
{
//FU-A end
mark_bit
=
true
;
payload
_size
=
len
-
offset
;
max
_size
=
len
-
offset
;
s_e_r_flags
=
(
1
<<
6
)
|
nal_type
;
}
else
if
(
fu_a_start
)
{
//FU-A start
...
...
@@ -226,19 +228,19 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
{
//传入nullptr先不做payload的内存拷贝
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
payload
_size
+
2
,
mark_bit
,
pts
);
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
max
_size
+
2
,
mark_bit
,
pts
);
//rtp payload 负载部分
uint8_t
*
payload
=
(
uint8_t
*
)
rtp
->
data
()
+
rtp
->
offset
;
uint8_t
*
payload
=
rtp
->
getPayload
()
;
//FU-A 第1个字节
payload
[
0
]
=
nal_fu_a
;
//FU-A 第2个字节
payload
[
1
]
=
s_e_r_flags
;
//H264 数据
memcpy
(
payload
+
2
,
(
unsigned
char
*
)
ptr
+
offset
,
payload
_size
);
memcpy
(
payload
+
2
,
(
unsigned
char
*
)
ptr
+
offset
,
max
_size
);
//输入到rtp环形缓存
RtpCodec
::
inputRtp
(
rtp
,
fu_a_start
&&
nal_type
==
H264Frame
::
NAL_IDR
);
}
offset
+=
payload
_size
;
offset
+=
max
_size
;
fu_a_start
=
false
;
}
}
else
{
...
...
src/Extension/H265Rtp.cpp
查看文件 @
070bf19c
...
...
@@ -168,9 +168,11 @@ bool H265RtpDecoder::mergeFu(const uint8_t *ptr, ssize_t size, uint16_t seq, uin
return
false
;
}
bool
H265RtpDecoder
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtppack
,
bool
)
{
const
uint8_t
*
frame
=
(
uint8_t
*
)
rtppack
->
data
()
+
rtppack
->
offset
;
auto
length
=
rtppack
->
size
()
-
rtppack
->
offset
;
bool
H265RtpDecoder
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
,
bool
)
{
auto
frame
=
rtp
->
getPayload
();
auto
length
=
rtp
->
getPayloadSize
();
auto
stamp
=
rtp
->
getStampMS
();
auto
seq
=
rtp
->
getSeq
();
int
nal
=
H265_TYPE
(
frame
[
0
]);
if
(
nal
>
50
){
...
...
@@ -185,13 +187,13 @@ bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool ) {
return
false
;
case
48
:
// aggregated packet (AP) - with two or more NAL units
return
unpackAp
(
frame
,
length
,
rtppack
->
timeS
tamp
);
return
unpackAp
(
frame
,
length
,
s
tamp
);
case
49
:
// fragmentation unit (FU)
return
mergeFu
(
frame
,
length
,
rtppack
->
sequence
,
rtppack
->
timeS
tamp
);
return
mergeFu
(
frame
,
length
,
seq
,
s
tamp
);
default
:
// 4.4.1. Single NAL Unit Packets (p24)
return
singleFrame
(
frame
,
length
,
rtppack
->
timeS
tamp
);
return
singleFrame
(
frame
,
length
,
s
tamp
);
}
}
...
...
@@ -228,25 +230,24 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
}
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
uint32_t
,
cycleMS
,
Rtp
::
kCycleMS
);
auto
ptr
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
auto
len
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
pts
=
frame
->
pts
()
%
cycleMS
;
auto
pts
=
frame
->
pts
();
auto
nal_type
=
H265_TYPE
(
ptr
[
0
]);
//获取NALU的5bit 帧类型
size_t
payload_size
=
_ui32MtuSize
-
3
;
auto
max_size
=
getMaxSize
()
-
3
;
//超过MTU,按照FU方式打包
if
(
len
>
payload
_size
+
2
)
{
if
(
len
>
max
_size
+
2
)
{
//获取帧头数据,1byte
unsigned
char
s_e_flags
;
bool
fu_start
=
true
;
bool
mark_bit
=
false
;
size_t
offset
=
2
;
while
(
!
mark_bit
)
{
if
(
len
<=
offset
+
payload
_size
)
{
if
(
len
<=
offset
+
max
_size
)
{
//FU end
mark_bit
=
true
;
payload
_size
=
len
-
offset
;
max
_size
=
len
-
offset
;
s_e_flags
=
(
1
<<
6
)
|
nal_type
;
}
else
if
(
fu_start
)
{
//FU start
...
...
@@ -258,9 +259,9 @@ void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) {
{
//传入nullptr先不做payload的内存拷贝
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
payload
_size
+
3
,
mark_bit
,
pts
);
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
max
_size
+
3
,
mark_bit
,
pts
);
//rtp payload 负载部分
uint8_t
*
payload
=
(
uint8_t
*
)
rtp
->
data
()
+
rtp
->
offset
;
uint8_t
*
payload
=
rtp
->
getPayload
()
;
//FU 第1个字节,表明为FU
payload
[
0
]
=
49
<<
1
;
//FU 第2个字节貌似固定为1
...
...
@@ -268,12 +269,12 @@ void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) {
//FU 第3个字节
payload
[
2
]
=
s_e_flags
;
//H265 数据
memcpy
(
payload
+
3
,
ptr
+
offset
,
payload
_size
);
memcpy
(
payload
+
3
,
ptr
+
offset
,
max
_size
);
//输入到rtp环形缓存
RtpCodec
::
inputRtp
(
rtp
,
fu_start
&&
H265Frame
::
isKeyFrame
(
nal_type
));
}
offset
+=
payload
_size
;
offset
+=
max
_size
;
fu_start
=
false
;
}
}
else
{
...
...
src/Rtp/GB28181Process.cpp
查看文件 @
070bf19c
...
...
@@ -35,8 +35,9 @@ bool GB28181Process::inputRtp(bool, const char *data, size_t data_len) {
}
void
GB28181Process
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtp
,
int
)
{
auto
pt
=
rtp
->
getHeader
()
->
pt
;
if
(
!
_rtp_decoder
)
{
switch
(
rtp
->
PT
)
{
switch
(
pt
)
{
case
98
:
{
//H264负载
_rtp_decoder
=
std
::
make_shared
<
H264RtpDecoder
>
();
...
...
@@ -44,8 +45,8 @@ void GB28181Process::onRtpSorted(const RtpPacket::Ptr &rtp, int) {
break
;
}
default
:
{
if
(
rtp
->
PT
!=
33
&&
rtp
->
PT
!=
96
)
{
WarnL
<<
"rtp payload type未识别("
<<
(
int
)
rtp
->
PT
<<
"),已按ts或ps负载处理"
;
if
(
pt
!=
33
&&
pt
!=
96
)
{
WarnL
<<
"rtp payload type未识别("
<<
(
int
)
pt
<<
"),已按ts或ps负载处理"
;
}
//ts或ps负载
_rtp_decoder
=
std
::
make_shared
<
CommonRtpDecoder
>
(
CodecInvalid
,
32
*
1024
);
...
...
src/Rtp/RtpCache.cpp
查看文件 @
070bf19c
...
...
@@ -28,7 +28,7 @@ void RtpCache::input(uint64_t stamp, Buffer::Ptr buffer) {
void
RtpCachePS
::
onRTP
(
Buffer
::
Ptr
buffer
)
{
auto
rtp
=
static_pointer_cast
<
RtpPacket
>
(
buffer
);
auto
stamp
=
rtp
->
timeStamp
;
auto
stamp
=
rtp
->
getStampMS
()
;
input
(
stamp
,
std
::
move
(
buffer
));
}
...
...
src/Rtsp/RtpCodec.cpp
查看文件 @
070bf19c
...
...
@@ -13,43 +13,37 @@
namespace
mediakit
{
RtpPacket
::
Ptr
RtpInfo
::
makeRtp
(
TrackType
type
,
const
void
*
data
,
size_t
len
,
bool
mark
,
uint32_t
stamp
)
{
uint16_t
payload_len
=
(
uint16_t
)(
len
+
12
);
uint32_t
ts
=
htonl
((
_ui32SampleRate
/
1000
)
*
stamp
);
uint16_t
sq
=
htons
(
_ui16Sequence
);
uint32_t
sc
=
htonl
(
_ui32Ssrc
);
auto
rtp_ptr
=
ResourcePoolHelper
<
RtpPacket
>::
obtainObj
();
rtp_ptr
->
setCapacity
(
len
+
16
);
rtp_ptr
->
setSize
(
len
+
16
);
auto
*
rtp
=
(
unsigned
char
*
)
rtp_ptr
->
data
();
rtp
[
0
]
=
'$'
;
rtp
[
1
]
=
_ui8Interleaved
;
rtp
[
2
]
=
payload_len
>>
8
;
rtp
[
3
]
=
payload_len
&
0xFF
;
rtp
[
4
]
=
0x80
;
rtp
[
5
]
=
(
mark
<<
7
)
|
_ui8PayloadType
;
memcpy
(
&
rtp
[
6
],
&
sq
,
2
);
memcpy
(
&
rtp
[
8
],
&
ts
,
4
);
//ssrc
memcpy
(
&
rtp
[
12
],
&
sc
,
4
);
if
(
data
){
//payload
memcpy
(
&
rtp
[
16
],
data
,
len
);
uint16_t
payload_len
=
(
uint16_t
)
(
len
+
RtpPacket
::
kRtpHeaderSize
);
auto
rtp
=
ResourcePoolHelper
<
RtpPacket
>::
obtainObj
();
rtp
->
setCapacity
(
payload_len
+
RtpPacket
::
kRtpTcpHeaderSize
);
rtp
->
setSize
(
payload_len
+
RtpPacket
::
kRtpTcpHeaderSize
);
rtp
->
sample_rate
=
_sample_rate
;
rtp
->
type
=
type
;
//rtsp over tcp 头
auto
ptr
=
(
uint8_t
*
)
rtp
->
data
();
ptr
[
0
]
=
'$'
;
ptr
[
1
]
=
_interleaved
;
ptr
[
2
]
=
payload_len
>>
8
;
ptr
[
3
]
=
payload_len
&
0xFF
;
//rtp头
auto
header
=
rtp
->
getHeader
();
header
->
version
=
RtpPacket
::
kRtpVersion
;
header
->
padding
=
0
;
header
->
ext
=
0
;
header
->
csrc
=
0
;
header
->
mark
=
mark
;
header
->
pt
=
_pt
;
header
->
seq
=
htons
(
_seq
++
);
header
->
stamp
=
htonl
(
uint64_t
(
stamp
)
*
_sample_rate
/
1000
);
header
->
ssrc
=
htonl
(
_ssrc
);
//有效负载
if
(
data
)
{
memcpy
(
&
ptr
[
RtpPacket
::
kRtpHeaderSize
+
RtpPacket
::
kRtpTcpHeaderSize
],
data
,
len
);
}
rtp_ptr
->
PT
=
_ui8PayloadType
;
rtp_ptr
->
interleaved
=
_ui8Interleaved
;
rtp_ptr
->
mark
=
mark
;
rtp_ptr
->
sequence
=
_ui16Sequence
;
rtp_ptr
->
timeStamp
=
stamp
;
rtp_ptr
->
ssrc
=
_ui32Ssrc
;
rtp_ptr
->
type
=
type
;
rtp_ptr
->
offset
=
16
;
_ui16Sequence
++
;
_ui32TimeStamp
=
stamp
;
return
rtp_ptr
;
return
rtp
;
}
}
//namespace mediakit
...
...
src/Rtsp/RtpCodec.h
查看文件 @
070bf19c
...
...
@@ -58,63 +58,41 @@ protected:
RingType
::
Ptr
_rtpRing
;
};
class
RtpInfo
:
public
ResourcePoolHelper
<
RtpPacket
>
{
class
RtpInfo
:
public
ResourcePoolHelper
<
RtpPacket
>
{
public
:
typedef
std
::
shared_ptr
<
RtpInfo
>
Ptr
;
RtpInfo
(
uint32_t
ui32Ssrc
,
uint32_t
ui32MtuSize
,
uint32_t
ui32SampleRate
,
uint8_t
ui8PayloadType
,
uint8_t
ui8Interleaved
)
{
if
(
ui32Ssrc
==
0
){
ui32Ssrc
=
((
uint64_t
)
this
)
&
0xFFFFFFFF
;
RtpInfo
(
uint32_t
ssrc
,
size_t
mtu_size
,
uint32_t
sample_rate
,
uint8_t
pt
,
uint8_t
interleaved
)
{
if
(
ssrc
==
0
)
{
ssrc
=
((
uint64_t
)
this
)
&
0xFFFFFFFF
;
}
_
ui32Ssrc
=
ui32Ssrc
;
_
ui32SampleRate
=
ui32SampleRate
;
_
ui32MtuSize
=
ui32MtuS
ize
;
_
ui8PayloadType
=
ui8PayloadTyp
e
;
_
ui8Interleaved
=
ui8I
nterleaved
;
_
pt
=
pt
;
_
ssrc
=
ssrc
;
_
mtu_size
=
mtu_s
ize
;
_
sample_rate
=
sample_rat
e
;
_
interleaved
=
i
nterleaved
;
}
virtual
~
RtpInfo
(){}
int
getInterleaved
()
const
{
return
_ui8Interleaved
;
}
int
getPayloadType
()
const
{
return
_ui8PayloadType
;
}
~
RtpInfo
()
override
{}
int
getSampleRate
()
const
{
return
_ui32SampleRate
;
//返回rtp负载最大长度
size_t
getMaxSize
()
const
{
return
_mtu_size
-
RtpPacket
::
kRtpHeaderSize
;
}
uint32_t
getSsrc
()
const
{
return
_
ui32S
src
;
return
_
s
src
;
}
uint16_t
getSeqence
()
const
{
return
_ui16Sequence
;
}
uint32_t
getTimestamp
()
const
{
return
_ui32TimeStamp
;
}
uint32_t
getMtuSize
()
const
{
return
_ui32MtuSize
;
}
RtpPacket
::
Ptr
makeRtp
(
TrackType
type
,
const
void
*
data
,
size_t
len
,
bool
mark
,
uint32_t
stamp
);
protected
:
uint32_t
_ui32Ssrc
;
uint32_t
_ui32SampleRate
;
uint32_t
_ui32MtuSize
;
uint8_t
_ui8PayloadType
;
uint8_t
_ui8Interleaved
;
uint16_t
_ui16Sequence
=
0
;
uint32_t
_ui32TimeStamp
=
0
;
private
:
uint8_t
_pt
;
uint8_t
_interleaved
;
uint16_t
_seq
=
0
;
uint32_t
_ssrc
;
uint32_t
_sample_rate
;
size_t
_mtu_size
;
};
class
RtpCodec
:
public
RtpRing
,
public
FrameDispatcher
,
public
CodecInfo
{
...
...
src/Rtsp/RtpReceiver.cpp
查看文件 @
070bf19c
...
...
@@ -11,10 +11,6 @@
#include "Common/config.h"
#include "RtpReceiver.h"
#define AV_RB16(x) \
((((const uint8_t*)(x))[0] << 8) | \
((const uint8_t*)(x))[1])
#define RTP_MAX_SIZE (10 * 1024)
namespace
mediakit
{
...
...
@@ -28,122 +24,67 @@ RtpReceiver::RtpReceiver() {
++
index
;
}
}
RtpReceiver
::~
RtpReceiver
()
{}
bool
RtpReceiver
::
handleOneRtp
(
int
track_index
,
TrackType
type
,
int
samplerate
,
uint8_t
*
rtp_raw_ptr
,
size_t
rtp_raw_
len
)
{
if
(
rtp_raw_len
<
12
)
{
WarnL
<<
"rtp包太小:"
<<
rtp_raw_
len
;
bool
RtpReceiver
::
handleOneRtp
(
int
index
,
TrackType
type
,
int
sample_rate
,
uint8_t
*
ptr
,
size_t
len
)
{
if
(
len
<
RtpPacket
::
kRtpHeaderSize
)
{
WarnL
<<
"rtp包太小:"
<<
len
;
return
false
;
}
uint32_t
version
=
rtp_raw_ptr
[
0
]
>>
6
;
uint8_t
padding
=
0
;
uint8_t
ext
=
rtp_raw_ptr
[
0
]
&
0x10
;
uint8_t
csrc
=
rtp_raw_ptr
[
0
]
&
0x0f
;
if
(
rtp_raw_ptr
[
0
]
&
0x20
)
{
//获取padding大小
padding
=
rtp_raw_ptr
[
rtp_raw_len
-
1
];
//移除padding flag
rtp_raw_ptr
[
0
]
&=
~
0x20
;
//移除padding字节
rtp_raw_len
-=
padding
;
}
if
(
version
!=
2
)
{
throw
std
::
invalid_argument
(
"非法的rtp,version != 2"
);
if
(
len
>
RTP_MAX_SIZE
)
{
WarnL
<<
"超大的rtp包:"
<<
len
<<
" > "
<<
RTP_MAX_SIZE
;
return
false
;
}
auto
rtp_ptr
=
_rtp_pool
.
obtain
();
auto
&
rtp
=
*
rtp_ptr
;
rtp
.
type
=
type
;
rtp
.
interleaved
=
2
*
type
;
rtp
.
mark
=
rtp_raw_ptr
[
1
]
>>
7
;
rtp
.
PT
=
rtp_raw_ptr
[
1
]
&
0x7F
;
//序列号,内存对齐
memcpy
(
&
rtp
.
sequence
,
rtp_raw_ptr
+
2
,
2
);
rtp
.
sequence
=
ntohs
(
rtp
.
sequence
);
//时间戳,内存对齐
memcpy
(
&
rtp
.
timeStamp
,
rtp_raw_ptr
+
4
,
4
);
rtp
.
timeStamp
=
ntohl
(
rtp
.
timeStamp
);
if
(
!
samplerate
)
{
if
(
!
sample_rate
)
{
//无法把时间戳转换成毫秒
return
false
;
}
//时间戳转换成毫秒
rtp
.
timeStamp
=
rtp
.
timeStamp
*
1000LL
/
samplerate
;
//ssrc,内存对齐
memcpy
(
&
rtp
.
ssrc
,
rtp_raw_ptr
+
8
,
4
);
rtp
.
ssrc
=
ntohl
(
rtp
.
ssrc
);
if
(
_ssrc
[
track_index
]
!=
rtp
.
ssrc
)
{
if
(
_ssrc
[
track_index
]
==
0
)
{
//保存SSRC至track对象
_ssrc
[
track_index
]
=
rtp
.
ssrc
;
}
else
{
//ssrc错误
WarnL
<<
"ssrc错误:"
<<
rtp
.
ssrc
<<
" != "
<<
_ssrc
[
track_index
];
if
(
_ssrc_err_count
[
track_index
]
++
>
10
)
{
//ssrc切换后清除老数据
WarnL
<<
"ssrc更换:"
<<
_ssrc
[
track_index
]
<<
" -> "
<<
rtp
.
ssrc
;
_rtp_sortor
[
track_index
].
clear
();
_ssrc
[
track_index
]
=
rtp
.
ssrc
;
}
return
false
;
}
RtpHeader
*
header
=
(
RtpHeader
*
)
ptr
;
if
(
header
->
version
!=
RtpPacket
::
kRtpVersion
)
{
throw
std
::
invalid_argument
(
"非法的rtp,version字段非法"
);
}
//ssrc匹配正确,不匹配计数清零
_ssrc_err_count
[
track_index
]
=
0
;
//rtp 12个固定字节头
rtp
.
offset
=
12
;
//rtp有csrc
rtp
.
offset
+=
4
*
csrc
;
if
(
ext
)
{
//rtp有ext
uint16_t
reserved
=
AV_RB16
(
rtp_raw_ptr
+
rtp
.
offset
);
uint16_t
extlen
=
AV_RB16
(
rtp_raw_ptr
+
rtp
.
offset
+
2
)
<<
2
;
rtp
.
offset
+=
extlen
+
4
;
}
if
(
rtp_raw_len
<=
rtp
.
offset
)
{
if
(
!
header
->
getPayloadSize
(
len
))
{
//无有效负载的rtp包
return
false
;
}
if
(
rtp_raw_len
>
RTP_MAX_SIZE
)
{
WarnL
<<
"超大的rtp包:"
<<
rtp_raw_len
<<
" > "
<<
RTP_MAX_SIZE
;
//比对缓存ssrc
auto
ssrc
=
ntohl
(
header
->
ssrc
);
if
(
!
_ssrc
[
index
])
{
//保存SSRC至track对象
_ssrc
[
index
]
=
ssrc
;
}
else
if
(
_ssrc
[
index
]
!=
ssrc
)
{
//ssrc错误
WarnL
<<
"ssrc错误:"
<<
ssrc
<<
" != "
<<
_ssrc
[
index
];
return
false
;
}
//设置rtp负载长度
rtp
.
setCapacity
(
rtp_raw_len
+
4
);
rtp
.
setSize
(
rtp_raw_len
+
4
);
uint8_t
*
payload_ptr
=
(
uint8_t
*
)
rtp
.
data
();
payload_ptr
[
0
]
=
'$'
;
payload_ptr
[
1
]
=
rtp
.
interleaved
;
payload_ptr
[
2
]
=
(
rtp_raw_len
>>
8
)
&
0xFF
;
payload_ptr
[
3
]
=
rtp_raw_len
&
0xFF
;
//添加rtp over tcp前4个字节的偏移量
rtp
.
offset
+=
4
;
//拷贝rtp负载
memcpy
(
payload_ptr
+
4
,
rtp_raw_ptr
,
rtp_raw_len
);
//排序rtp
auto
seq
=
rtp_ptr
->
sequence
;
onBeforeRtpSorted
(
rtp_ptr
,
track_index
);
_rtp_sortor
[
track_index
].
sortPacket
(
seq
,
std
::
move
(
rtp_ptr
));
auto
rtp
=
_rtp_pool
.
obtain
();
//需要添加4个字节的rtp over tcp头
rtp
->
setCapacity
(
RtpPacket
::
kRtpTcpHeaderSize
+
len
);
rtp
->
setSize
(
RtpPacket
::
kRtpTcpHeaderSize
+
len
);
rtp
->
sample_rate
=
sample_rate
;
rtp
->
type
=
type
;
//赋值4个字节的rtp over tcp头
uint8_t
*
data
=
(
uint8_t
*
)
rtp
->
data
();
data
[
0
]
=
'$'
;
data
[
1
]
=
2
*
type
;
data
[
2
]
=
(
len
>>
8
)
&
0xFF
;
data
[
3
]
=
len
&
0xFF
;
//拷贝rtp
memcpy
(
&
data
[
4
],
ptr
,
len
);
onBeforeRtpSorted
(
rtp
,
index
);
auto
seq
=
rtp
->
getSeq
();
_rtp_sortor
[
index
].
sortPacket
(
seq
,
std
::
move
(
rtp
));
return
true
;
}
void
RtpReceiver
::
clear
()
{
CLEAR_ARR
(
_ssrc
);
CLEAR_ARR
(
_ssrc_err_count
);
for
(
auto
&
sortor
:
_rtp_sortor
)
{
sortor
.
clear
();
}
...
...
@@ -153,16 +94,16 @@ void RtpReceiver::setPoolSize(size_t size) {
_rtp_pool
.
setSize
(
size
);
}
size_t
RtpReceiver
::
getJitterSize
(
int
track_
index
)
const
{
return
_rtp_sortor
[
track_
index
].
getJitterSize
();
size_t
RtpReceiver
::
getJitterSize
(
int
index
)
const
{
return
_rtp_sortor
[
index
].
getJitterSize
();
}
size_t
RtpReceiver
::
getCycleCount
(
int
track_
index
)
const
{
return
_rtp_sortor
[
track_
index
].
getCycleCount
();
size_t
RtpReceiver
::
getCycleCount
(
int
index
)
const
{
return
_rtp_sortor
[
index
].
getCycleCount
();
}
uint32_t
RtpReceiver
::
getSSRC
(
int
track_
index
)
const
{
return
_ssrc
[
track_
index
];
uint32_t
RtpReceiver
::
getSSRC
(
int
index
)
const
{
return
_ssrc
[
index
];
}
}
//namespace mediakit
src/Rtsp/RtpReceiver.h
查看文件 @
070bf19c
...
...
@@ -168,14 +168,14 @@ public:
protected
:
/**
* 输入数据指针生成并排序rtp包
* @param
track_
index track下标索引
* @param index track下标索引
* @param type track类型
* @param samplerate rtp时间戳基准时钟,视频为90000,音频为采样率
* @param
rtp_raw_
ptr rtp数据指针
* @param
rtp_raw_
len rtp数据指针长度
* @param ptr rtp数据指针
* @param len rtp数据指针长度
* @return 解析成功返回true
*/
bool
handleOneRtp
(
int
track_index
,
TrackType
type
,
int
samplerate
,
uint8_t
*
rtp_raw_ptr
,
size_t
rtp_raw_
len
);
bool
handleOneRtp
(
int
index
,
TrackType
type
,
int
samplerate
,
uint8_t
*
ptr
,
size_t
len
);
/**
* rtp数据包排序后输出
...
...
@@ -199,8 +199,6 @@ protected:
private
:
uint32_t
_ssrc
[
2
]
=
{
0
,
0
};
//ssrc不匹配计数
size_t
_ssrc_err_count
[
2
]
=
{
0
,
0
};
//rtp排序缓存,根据seq排序
PacketSortor
<
RtpPacket
::
Ptr
>
_rtp_sortor
[
2
];
//rtp循环池
...
...
src/Rtsp/Rtsp.cpp
查看文件 @
070bf19c
...
...
@@ -415,14 +415,101 @@ string printSSRC(uint32_t ui32Ssrc) {
}
Buffer
::
Ptr
makeRtpOverTcpPrefix
(
uint16_t
size
,
uint8_t
interleaved
){
auto
rtp_tcp
=
std
::
make_shared
<
BufferRaw
>
(
4
);
auto
rtp_tcp
=
std
::
make_shared
<
BufferRaw
>
(
RtpPacket
::
kRtpTcpHeaderSize
);
rtp_tcp
->
setSize
(
RtpPacket
::
kRtpTcpHeaderSize
);
auto
ptr
=
rtp_tcp
->
data
();
ptr
[
0
]
=
'$'
;
ptr
[
1
]
=
interleaved
;
ptr
[
2
]
=
(
size
>>
8
)
&
0xFF
;
ptr
[
3
]
=
size
&
0xFF
;
rtp_tcp
->
setSize
(
4
);
return
rtp_tcp
;
}
#define AV_RB16(x) \
((((const uint8_t*)(x))[0] << 8) | \
((const uint8_t*)(x))[1])
size_t
RtpHeader
::
getCsrcSize
()
const
{
//每个csrc占用4字节
return
csrc
<<
2
;
}
uint8_t
*
RtpHeader
::
getCsrcData
()
{
if
(
!
csrc
)
{
return
nullptr
;
}
return
&
payload
;
}
size_t
RtpHeader
::
getExtSize
()
const
{
//rtp有ext
if
(
!
ext
)
{
return
0
;
}
auto
ext_ptr
=
&
payload
+
getCsrcSize
();
uint16_t
reserved
=
AV_RB16
(
ext_ptr
);
//每个ext占用4字节
return
AV_RB16
(
ext_ptr
+
2
)
<<
2
;
}
uint8_t
*
RtpHeader
::
getExtData
()
{
if
(
!
ext
)
{
return
nullptr
;
}
auto
ext_ptr
=
&
payload
+
getCsrcSize
();
//多出的4个字节分别为reserved、ext_len
return
ext_ptr
+
4
+
getExtSize
();
}
size_t
RtpHeader
::
getPayloadOffset
()
const
{
//有ext时,还需要忽略reserved、ext_len 4个字节
return
getCsrcSize
()
+
(
ext
?
(
4
+
getExtSize
())
:
0
);
}
uint8_t
*
RtpHeader
::
getPayloadData
()
{
return
&
payload
+
getPayloadOffset
();
}
size_t
RtpHeader
::
getPaddingSize
(
size_t
rtp_size
)
const
{
if
(
!
padding
)
{
return
0
;
}
auto
end
=
(
uint8_t
*
)
this
+
rtp_size
;
return
*
end
;
}
size_t
RtpHeader
::
getPayloadSize
(
size_t
rtp_size
){
auto
invalid_size
=
getPayloadOffset
()
+
getPaddingSize
(
rtp_size
);
if
(
invalid_size
+
RtpPacket
::
kRtpHeaderSize
>=
rtp_size
)
{
return
0
;
}
return
rtp_size
-
invalid_size
-
RtpPacket
::
kRtpHeaderSize
;
}
RtpHeader
*
RtpPacket
::
getHeader
(){
//需除去rtcp over tcp 4个字节长度
return
(
RtpHeader
*
)(
data
()
+
RtpPacket
::
kRtpTcpHeaderSize
);
}
uint16_t
RtpPacket
::
getSeq
(){
return
ntohs
(
getHeader
()
->
seq
);
}
uint32_t
RtpPacket
::
getStampMS
(){
return
ntohl
(
getHeader
()
->
stamp
)
*
uint64_t
(
1000
)
/
sample_rate
;
}
uint32_t
RtpPacket
::
getSSRC
(){
return
ntohl
(
getHeader
()
->
ssrc
);
}
uint8_t
*
RtpPacket
::
getPayload
(){
return
getHeader
()
->
getPayloadData
();
}
size_t
RtpPacket
::
getPayloadSize
(){
//需除去rtcp over tcp 4个字节长度
return
getHeader
()
->
getPayloadSize
(
size
()
-
kRtpTcpHeaderSize
);
}
}
//
namespace
mediakit
\ No newline at end of file
src/Rtsp/Rtsp.h
查看文件 @
070bf19c
...
...
@@ -15,8 +15,9 @@
#include <string>
#include <memory>
#include <unordered_map>
#include "Common/config.h"
#include "Util/util.h"
#include "Common/config.h"
#include "Common/macros.h"
#include "Extension/Frame.h"
using
namespace
std
;
...
...
@@ -68,18 +69,101 @@ typedef enum {
};
#if defined(_WIN32)
#pragma pack(push, 1)
#endif // defined(_WIN32)
class
RtpHeader
{
public
:
#if __BYTE_ORDER == __BIG_ENDIAN
//版本号,固定为2
uint32_t
version
:
2
;
//padding
uint32_t
padding
:
1
;
//扩展
uint32_t
ext
:
1
;
//csrc
uint32_t
csrc
:
4
;
//mark
uint32_t
mark
:
1
;
//负载类型
uint32_t
pt
:
7
;
#else
//csrc
uint32_t
csrc
:
4
;
//扩展
uint32_t
ext
:
1
;
//padding
uint32_t
padding
:
1
;
//版本号,固定为2
uint32_t
version
:
2
;
//负载类型
uint32_t
pt
:
7
;
//mark
uint32_t
mark
:
1
;
#endif
//序列号
uint32_t
seq
:
16
;
//时间戳
uint32_t
stamp
;
//ssrc
uint32_t
ssrc
;
//负载,如果有csrc和ext,前面为 4 * csrc + (4 + 4 * ext_len)
uint8_t
payload
;
public
:
//返回csrc字段字节长度
size_t
getCsrcSize
()
const
;
//返回csrc字段首地址,不存在时返回nullptr
uint8_t
*
getCsrcData
();
//返回ext字段字节长度
size_t
getExtSize
()
const
;
//返回ext段首地址,不存在时返回nullptr
uint8_t
*
getExtData
();
//返回有效负载指针,跳过csrc、ext
uint8_t
*
getPayloadData
();
//返回有效负载总长度,不包括csrc、ext、padding
size_t
getPayloadSize
(
size_t
rtp_size
);
private
:
//返回有效负载偏移量
size_t
getPayloadOffset
()
const
;
//返回padding长度
size_t
getPaddingSize
(
size_t
rtp_size
)
const
;
}
PACKED
;
#if defined(_WIN32)
#pragma pack(pop)
#endif // defined(_WIN32)
//此rtp为rtp over tcp形式,需要忽略前4个字节
class
RtpPacket
:
public
BufferRaw
{
public
:
typedef
std
::
shared_ptr
<
RtpPacket
>
Ptr
;
bool
mark
;
uint8_t
interleaved
;
uint8_t
PT
;
using
Ptr
=
std
::
shared_ptr
<
RtpPacket
>
;
enum
{
kRtpVersion
=
2
,
kRtpHeaderSize
=
12
,
kRtpTcpHeaderSize
=
4
};
RtpHeader
*
getHeader
();
//主机字节序的seq
uint16_t
getSeq
();
//主机字节序的时间戳,已经转换为毫秒
uint32_t
getStampMS
();
//主机字节序的ssrc
uint32_t
getSSRC
();
//有效负载,跳过csrc、ext
uint8_t
*
getPayload
();
//有效负载长度,不包括csrc、ext、padding
size_t
getPayloadSize
();
//音视频类型
TrackType
type
;
uint16_t
sequence
;
//时间戳,单位毫秒
uint32_t
timeStamp
;
uint32_t
ssrc
;
size_t
offset
;
//音频为采样率,视频一般为90000
uint32_t
sample_rate
;
};
Buffer
::
Ptr
makeRtpOverTcpPrefix
(
uint16_t
size
,
uint8_t
interleaved
);
...
...
src/Rtsp/RtspMediaSource.h
查看文件 @
070bf19c
...
...
@@ -160,10 +160,11 @@ public:
_speed
[
rtp
->
type
]
+=
rtp
->
size
();
assert
(
rtp
->
type
>=
0
&&
rtp
->
type
<
TrackMax
);
auto
&
track
=
_tracks
[
rtp
->
type
];
auto
stamp
=
rtp
->
getStampMS
();
if
(
track
)
{
track
->
_seq
=
rtp
->
sequence
;
track
->
_time_stamp
=
rtp
->
timeS
tamp
;
track
->
_ssrc
=
rtp
->
ssrc
;
track
->
_seq
=
rtp
->
getSeq
()
;
track
->
_time_stamp
=
s
tamp
;
track
->
_ssrc
=
rtp
->
getSSRC
()
;
}
if
(
!
_ring
)
{
weak_ptr
<
RtspMediaSource
>
weakSelf
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
shared_from_this
());
...
...
@@ -183,7 +184,6 @@ public:
}
}
bool
is_video
=
rtp
->
type
==
TrackVideo
;
auto
stamp
=
rtp
->
timeStamp
;
PacketCache
<
RtpPacket
>::
inputPacket
(
stamp
,
is_video
,
std
::
move
(
rtp
),
keyPos
);
}
...
...
src/Rtsp/RtspPlayer.cpp
查看文件 @
070bf19c
...
...
@@ -478,10 +478,10 @@ void RtspPlayer::onRtpPacket(const char *data, size_t len) {
uint8_t
interleaved
=
data
[
1
];
if
(
interleaved
%
2
==
0
){
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
);
handleOneRtp
(
trackIdx
,
_sdp_track
[
trackIdx
]
->
_type
,
_sdp_track
[
trackIdx
]
->
_samplerate
,
(
uint8_t
*
)
data
+
4
,
len
-
4
);
handleOneRtp
(
trackIdx
,
_sdp_track
[
trackIdx
]
->
_type
,
_sdp_track
[
trackIdx
]
->
_samplerate
,
(
uint8_t
*
)
data
+
RtpPacket
::
kRtpTcpHeaderSize
,
len
-
RtpPacket
::
kRtpTcpHeaderSize
);
}
else
{
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
-
1
);
onRtcpPacket
(
trackIdx
,
_sdp_track
[
trackIdx
],
(
uint8_t
*
)
data
+
4
,
len
-
4
);
onRtcpPacket
(
trackIdx
,
_sdp_track
[
trackIdx
],
(
uint8_t
*
)
data
+
RtpPacket
::
kRtpTcpHeaderSize
,
len
-
RtpPacket
::
kRtpTcpHeaderSize
);
}
}
...
...
@@ -494,7 +494,7 @@ void RtspPlayer::onRtcpPacket(int track_idx, SdpTrack::Ptr &track, uint8_t *data
}
void
RtspPlayer
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
){
_stamp
[
trackidx
]
=
rtppt
->
timeStamp
;
_stamp
[
trackidx
]
=
rtppt
->
getStampMS
()
;
_rtp_recv_ticker
.
resetTime
();
onRecvRTP
(
rtppt
,
_sdp_track
[
trackidx
]);
}
...
...
@@ -593,7 +593,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
->
sequence
,
rtp
->
timeStamp
,
rtp
->
size
()
-
4
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
auto
&
ticker
=
_rtcp_send_ticker
[
track_idx
];
if
(
ticker
.
elapsedTime
()
<
3
*
1000
)
{
...
...
@@ -627,10 +627,11 @@ void RtspPlayer::onBeforeRtpSorted(const RtpPacket::Ptr &rtp, int track_idx){
}
};
auto
rtcp
=
rtcp_ctx
->
createRtcpRR
(
rtp
->
ssrc
+
1
,
rtp
->
ssrc
);
auto
ssrc
=
rtp
->
getSSRC
();
auto
rtcp
=
rtcp_ctx
->
createRtcpRR
(
ssrc
+
1
,
ssrc
);
auto
rtcp_sdes
=
RtcpSdes
::
create
({
SERVER_NAME
});
rtcp_sdes
->
items
.
type
=
(
uint8_t
)
SdesType
::
RTCP_SDES_CNAME
;
rtcp_sdes
->
items
.
ssrc
=
htonl
(
rtp
->
ssrc
);
rtcp_sdes
->
items
.
ssrc
=
htonl
(
ssrc
);
send_rtcp
(
this
,
track_idx
,
std
::
move
(
rtcp
));
send_rtcp
(
this
,
track_idx
,
RtcpHeader
::
toBuffer
(
rtcp_sdes
));
ticker
.
resetTime
();
...
...
src/Rtsp/RtspPusher.cpp
查看文件 @
070bf19c
...
...
@@ -154,7 +154,7 @@ void RtspPusher::onRtpPacket(const char *data, size_t len) {
uint8_t
interleaved
=
data
[
1
];
if
(
interleaved
%
2
!=
0
)
{
trackIdx
=
getTrackIndexByInterleaved
(
interleaved
-
1
);
onRtcpPacket
(
trackIdx
,
_track_vec
[
trackIdx
],
(
uint8_t
*
)
data
+
4
,
len
-
4
);
onRtcpPacket
(
trackIdx
,
_track_vec
[
trackIdx
],
(
uint8_t
*
)
data
+
RtpPacket
::
kRtpTcpHeaderSize
,
len
-
RtpPacket
::
kRtpTcpHeaderSize
);
}
}
...
...
@@ -361,7 +361,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
->
sequence
,
rtp
->
timeStamp
,
rtp
->
size
()
-
4
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
//send rtcp every 5 second
if
(
ticker
.
elapsedTime
()
>
5
*
1000
)
{
...
...
@@ -376,10 +376,11 @@ void RtspPusher::updateRtcpContext(const RtpPacket::Ptr &rtp){
}
};
auto
rtcp
=
rtcp_ctx
->
createRtcpSR
(
rtp
->
ssrc
+
1
);
auto
ssrc
=
rtp
->
getSSRC
();
auto
rtcp
=
rtcp_ctx
->
createRtcpSR
(
ssrc
+
1
);
auto
rtcp_sdes
=
RtcpSdes
::
create
({
SERVER_NAME
});
rtcp_sdes
->
items
.
type
=
(
uint8_t
)
SdesType
::
RTCP_SDES_CNAME
;
rtcp_sdes
->
items
.
ssrc
=
htonl
(
rtp
->
ssrc
);
rtcp_sdes
->
items
.
ssrc
=
htonl
(
ssrc
);
send_rtcp
(
this
,
track_index
,
std
::
move
(
rtcp
));
send_rtcp
(
this
,
track_index
,
RtcpHeader
::
toBuffer
(
rtcp_sdes
));
}
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
070bf19c
...
...
@@ -15,7 +15,6 @@
#include "RtspSession.h"
#include "Util/MD5.h"
#include "Util/base64.h"
#include "Rtcp/Rtcp.h"
using
namespace
std
;
using
namespace
toolkit
;
...
...
@@ -171,10 +170,10 @@ void RtspSession::onRtpPacket(const char *data, size_t len) {
return
;
}
auto
track_idx
=
getTrackIndexByInterleaved
(
interleaved
);
handleOneRtp
(
track_idx
,
_sdp_track
[
track_idx
]
->
_type
,
_sdp_track
[
track_idx
]
->
_samplerate
,
(
uint8_t
*
)
data
+
4
,
len
-
4
);
handleOneRtp
(
track_idx
,
_sdp_track
[
track_idx
]
->
_type
,
_sdp_track
[
track_idx
]
->
_samplerate
,
(
uint8_t
*
)
data
+
RtpPacket
::
kRtpTcpHeaderSize
,
len
-
RtpPacket
::
kRtpTcpHeaderSize
);
}
else
{
auto
track_idx
=
getTrackIndexByInterleaved
(
interleaved
-
1
);
onRtcpPacket
(
track_idx
,
_sdp_track
[
track_idx
],
data
+
4
,
len
-
4
);
onRtcpPacket
(
track_idx
,
_sdp_track
[
track_idx
],
data
+
RtpPacket
::
kRtpTcpHeaderSize
,
len
-
RtpPacket
::
kRtpTcpHeaderSize
);
}
}
...
...
@@ -913,12 +912,6 @@ void RtspSession::send_NotAcceptable() {
}
void
RtspSession
::
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtp
,
int
track_idx
)
{
if
(
_start_stamp
[
track_idx
]
==
-
1
)
{
//记录起始时间戳
_start_stamp
[
track_idx
]
=
rtp
->
timeStamp
;
}
//时间戳增量
rtp
->
timeStamp
-=
_start_stamp
[
track_idx
];
_push_src
->
onWrite
(
rtp
,
false
);
}
...
...
@@ -1130,7 +1123,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
->
sequence
,
rtp
->
timeStamp
,
rtp
->
size
()
-
4
);
rtcp_ctx
->
onRtp
(
rtp
->
getSeq
(),
rtp
->
getStampMS
(),
rtp
->
size
()
-
RtpPacket
::
kRtpTcpHeaderSize
);
auto
&
ticker
=
_rtcp_send_tickers
[
track_index
];
//send rtcp every 5 second
...
...
@@ -1147,10 +1140,11 @@ void RtspSession::updateRtcpContext(const RtpPacket::Ptr &rtp){
}
};
auto
rtcp
=
_push_src
?
rtcp_ctx
->
createRtcpRR
(
rtp
->
ssrc
+
1
,
rtp
->
ssrc
)
:
rtcp_ctx
->
createRtcpSR
(
rtp
->
ssrc
+
1
);
auto
ssrc
=
rtp
->
getSSRC
();
auto
rtcp
=
_push_src
?
rtcp_ctx
->
createRtcpRR
(
ssrc
+
1
,
ssrc
)
:
rtcp_ctx
->
createRtcpSR
(
ssrc
+
1
);
auto
rtcp_sdes
=
RtcpSdes
::
create
({
SERVER_NAME
});
rtcp_sdes
->
items
.
type
=
(
uint8_t
)
SdesType
::
RTCP_SDES_CNAME
;
rtcp_sdes
->
items
.
ssrc
=
htonl
(
rtp
->
ssrc
);
rtcp_sdes
->
items
.
ssrc
=
htonl
(
ssrc
);
send_rtcp
(
this
,
track_index
,
std
::
move
(
rtcp
));
send_rtcp
(
this
,
track_index
,
RtcpHeader
::
toBuffer
(
rtcp_sdes
));
}
...
...
src/Rtsp/RtspSession.h
查看文件 @
070bf19c
...
...
@@ -171,8 +171,6 @@ private:
Rtsp
::
eRtpType
_rtp_type
=
Rtsp
::
RTP_Invalid
;
//收到的seq,回复时一致
int
_cseq
=
0
;
//rtsp推流起始时间戳,目的是为了同步
int32_t
_start_stamp
[
2
]
=
{
-
1
,
-
1
};
//消耗的总流量
uint64_t
_bytes_usage
=
0
;
//ContentBase
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论