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
4 years ago
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
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
////////////组播配置///////////
...
...
This diff is collapsed.
Click to expand it.
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
;
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
;
...
...
This diff is collapsed.
Click to expand it.
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
{
...
...
This diff is collapsed.
Click to expand it.
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
{
...
...
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
));
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
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
{
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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循环池
...
...
This diff is collapsed.
Click to expand it.
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
This diff is collapsed.
Click to expand it.
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
);
...
...
This diff is collapsed.
Click to expand it.
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
);
}
...
...
This diff is collapsed.
Click to expand it.
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
();
...
...
This diff is collapsed.
Click to expand it.
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
));
}
...
...
This diff is collapsed.
Click to expand it.
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
));
}
...
...
This diff is collapsed.
Click to expand it.
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
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论