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
67d88374
Commit
67d88374
authored
2 years ago
by
xiongguangjie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rtp h265 packet like h264
parent
599208dd
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
122 行增加
和
45 行删除
+122
-45
src/Extension/H265Rtp.cpp
+106
-45
src/Extension/H265Rtp.h
+16
-0
没有找到文件。
src/Extension/H265Rtp.cpp
查看文件 @
67d88374
...
...
@@ -9,7 +9,7 @@
*/
#include "H265Rtp.h"
#include "Common/config.h"
namespace
mediakit
{
//https://datatracker.ietf.org/doc/rfc7798/
...
...
@@ -258,58 +258,119 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
ui8Interleaved
)
{
}
void
H265RtpEncoder
::
packRtpFu
(
const
char
*
ptr
,
size_t
len
,
uint64_t
pts
,
bool
is_mark
,
bool
gop_pos
){
auto
max_size
=
getMaxSize
()
-
3
;
auto
nal_type
=
H265_TYPE
(
ptr
[
0
]);
//获取NALU的5bit 帧类型
unsigned
char
s_e_flags
;
bool
fu_start
=
true
;
bool
mark_bit
=
false
;
size_t
offset
=
2
;
while
(
!
mark_bit
)
{
if
(
len
<=
offset
+
max_size
)
{
// FU end
mark_bit
=
true
;
max_size
=
len
-
offset
;
s_e_flags
=
(
1
<<
6
)
|
nal_type
;
}
else
if
(
fu_start
)
{
// FU start
s_e_flags
=
(
1
<<
7
)
|
nal_type
;
}
else
{
// FU mid
s_e_flags
=
nal_type
;
}
{
// 传入nullptr先不做payload的内存拷贝
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
max_size
+
3
,
mark_bit
,
pts
);
// rtp payload 负载部分
uint8_t
*
payload
=
rtp
->
getPayload
();
// FU 第1个字节,表明为FU
payload
[
0
]
=
49
<<
1
;
// FU 第2个字节貌似固定为1
payload
[
1
]
=
ptr
[
1
];
// 1;
// FU 第3个字节
payload
[
2
]
=
s_e_flags
;
// H265 数据
memcpy
(
payload
+
3
,
ptr
+
offset
,
max_size
);
// 输入到rtp环形缓存
RtpCodec
::
inputRtp
(
rtp
,
fu_start
&&
gop_pos
);
}
offset
+=
max_size
;
fu_start
=
false
;
}
}
void
H265RtpEncoder
::
packRtp
(
const
char
*
ptr
,
size_t
len
,
uint64_t
pts
,
bool
is_mark
,
bool
gop_pos
){
if
(
len
+
3
<=
getMaxSize
())
{
//signal-nalu
RtpCodec
::
inputRtp
(
makeRtp
(
getTrackType
(),
ptr
,
len
,
is_mark
,
pts
),
gop_pos
);
}
else
{
//FU-A模式
packRtpFu
(
ptr
,
len
,
pts
,
is_mark
,
gop_pos
);
}
}
void
H265RtpEncoder
::
insertConfigFrame
(
uint64_t
pts
){
if
(
!
_sps
||
!
_pps
||
!
_vps
)
{
WarnL
<<
" not ok"
;
return
;
}
//gop缓存从vps 开始,vps ,sps、pps后面还有时间戳相同的关键帧,所以mark bit为false
packRtp
(
_vps
->
data
()
+
_vps
->
prefixSize
(),
_vps
->
size
()
-
_vps
->
prefixSize
(),
pts
,
false
,
true
);
packRtp
(
_sps
->
data
()
+
_sps
->
prefixSize
(),
_sps
->
size
()
-
_sps
->
prefixSize
(),
pts
,
false
,
false
);
packRtp
(
_pps
->
data
()
+
_pps
->
prefixSize
(),
_pps
->
size
()
-
_pps
->
prefixSize
(),
pts
,
false
,
false
);
}
bool
H265RtpEncoder
::
inputFrame_l
(
const
Frame
::
Ptr
&
frame
,
bool
is_mark
){
if
(
frame
->
keyFrame
())
{
//保证每一个关键帧前都有SPS PPS VPS
insertConfigFrame
(
frame
->
pts
());
}
packRtp
(
frame
->
data
()
+
frame
->
prefixSize
(),
frame
->
size
()
-
frame
->
prefixSize
(),
frame
->
pts
(),
is_mark
,
false
);
return
true
;
}
bool
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
auto
ptr
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
auto
len
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
pts
=
frame
->
pts
();
auto
nal_type
=
H265_TYPE
(
ptr
[
0
]);
//获取NALU的5bit 帧类型
auto
max_size
=
getMaxSize
()
-
3
;
//超过MTU,按照FU方式打包
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
+
max_size
)
{
//FU end
mark_bit
=
true
;
max_size
=
len
-
offset
;
s_e_flags
=
(
1
<<
6
)
|
nal_type
;
}
else
if
(
fu_start
)
{
//FU start
s_e_flags
=
(
1
<<
7
)
|
nal_type
;
}
else
{
//FU mid
s_e_flags
=
nal_type
;
}
{
//传入nullptr先不做payload的内存拷贝
auto
rtp
=
makeRtp
(
getTrackType
(),
nullptr
,
max_size
+
3
,
mark_bit
,
pts
);
//rtp payload 负载部分
uint8_t
*
payload
=
rtp
->
getPayload
();
//FU 第1个字节,表明为FU
payload
[
0
]
=
49
<<
1
;
//FU 第2个字节貌似固定为1
payload
[
1
]
=
ptr
[
1
];
// 1;
//FU 第3个字节
payload
[
2
]
=
s_e_flags
;
//H265 数据
memcpy
(
payload
+
3
,
ptr
+
offset
,
max_size
);
//输入到rtp环形缓存
RtpCodec
::
inputRtp
(
rtp
,
fu_start
&&
frame
->
keyFrame
());
}
switch
(
nal_type
)
{
case
H265Frame
:
:
NAL_SPS
:
{
_sps
=
Frame
::
getCacheAbleFrame
(
frame
);
return
true
;
}
case
H265Frame
:
:
NAL_PPS
:
{
_pps
=
Frame
::
getCacheAbleFrame
(
frame
);
return
true
;
}
case
H265Frame
:
:
NAL_VPS
:
{
_vps
=
Frame
::
getCacheAbleFrame
(
frame
);
return
true
;
}
default
:
break
;
}
offset
+=
max_size
;
fu_start
=
false
;
GET_CONFIG
(
int
,
lowLatency
,
Rtp
::
kLowLatency
);
if
(
lowLatency
)
{
// 低延迟模式
if
(
_last_frame
)
{
flush
();
}
inputFrame_l
(
frame
,
true
);
}
else
{
RtpCodec
::
inputRtp
(
makeRtp
(
getTrackType
(),
ptr
,
len
,
false
,
pts
),
frame
->
keyFrame
());
if
(
_last_frame
)
{
//如果时间戳发生了变化,那么markbit才置true
inputFrame_l
(
_last_frame
,
_last_frame
->
pts
()
!=
frame
->
pts
());
}
_last_frame
=
Frame
::
getCacheAbleFrame
(
frame
);
}
return
true
;
}
void
H265RtpEncoder
::
flush
()
{
if
(
_last_frame
)
{
// 如果时间戳发生了变化,那么markbit才置true
inputFrame_l
(
_last_frame
,
true
);
_last_frame
=
nullptr
;
}
return
len
>
0
;
}
}
//namespace mediakit
This diff is collapsed.
Click to expand it.
src/Extension/H265Rtp.h
查看文件 @
67d88374
...
...
@@ -85,6 +85,22 @@ public:
* @param frame 帧数据,必须
*/
bool
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
/**
* 刷新输出所有frame缓存
*/
void
flush
()
override
;
private
:
void
packRtp
(
const
char
*
ptr
,
size_t
len
,
uint64_t
pts
,
bool
is_mark
,
bool
gop_pos
);
void
packRtpFu
(
const
char
*
ptr
,
size_t
len
,
uint64_t
pts
,
bool
is_mark
,
bool
gop_pos
);
void
insertConfigFrame
(
uint64_t
pts
);
bool
inputFrame_l
(
const
Frame
::
Ptr
&
frame
,
bool
is_mark
);
private
:
Frame
::
Ptr
_sps
;
Frame
::
Ptr
_pps
;
Frame
::
Ptr
_vps
;
Frame
::
Ptr
_last_frame
;
};
}
//namespace mediakit{
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论