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
9d9f6e30
Commit
9d9f6e30
authored
Apr 29, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善dts计算算法
parent
3630839b
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
35 行增加
和
28 行删除
+35
-28
src/Common/Stamp.cpp
+27
-3
src/Extension/H264Rtp.cpp
+4
-13
src/Extension/H265Rtp.cpp
+4
-12
没有找到文件。
src/Common/Stamp.cpp
查看文件 @
9d9f6e30
...
...
@@ -95,7 +95,7 @@ int64_t Stamp::getRelativeStamp() const {
bool
DtsGenerator
::
getDts
(
uint32_t
pts
,
uint32_t
&
dts
){
bool
ret
=
false
;
if
(
pts
==
_last_pts
){
//pts未变,
返回上次结果
//pts未变,
说明dts也不会变,返回上次dts
if
(
_last_dts
){
dts
=
_last_dts
;
ret
=
true
;
...
...
@@ -105,44 +105,68 @@ bool DtsGenerator::getDts(uint32_t pts, uint32_t &dts){
ret
=
getDts_l
(
pts
,
dts
);
if
(
ret
){
//保存本次结果
//
获取到了dts,
保存本次结果
_last_dts
=
dts
;
}
else
{
//pts排序列队长度还不知道,也就是不知道有没有B帧,
//那么先强制dts == pts,这样可能导致有B帧的情况下,起始画面有几帧回退
dts
=
pts
;
}
//记录上次pts
_last_pts
=
pts
;
return
ret
;
}
//该算法核心思想是对pts进行排序,排序好的pts就是dts。
//排序有一定的滞后性,那么需要加上排序导致的时间戳偏移量
bool
DtsGenerator
::
getDts_l
(
uint32_t
pts
,
uint32_t
&
dts
){
if
(
_sorter_max_size
==
1
){
//没有B帧
//没有B帧
,dts就等于pts
dts
=
pts
;
return
true
;
}
if
(
!
_sorter_max_size
){
//尚未计算出pts排序列队长度(也就是P帧间B帧个数)
if
(
pts
>
_last_max_pts
){
//pts时间戳增加了,那么说明这帧画面不是B帧(说明是P帧或关键帧)
if
(
_frames_since_last_max_pts
&&
_count_sorter_max_size
++
>
0
){
//已经出现多次非B帧的情况,那么我们就能知道P帧间B帧的个数
_sorter_max_size
=
_frames_since_last_max_pts
;
//我们记录P帧间时间间隔(也就是多个B帧时间戳增量累计)
_dts_pts_offset
=
(
pts
-
_last_max_pts
)
/
2
;
}
//遇到P帧或关键帧,连续B帧计数清零
_frames_since_last_max_pts
=
0
;
//记录上次非B帧的pts时间戳(同时也是dts),用于统计连续B帧时间戳增量
_last_max_pts
=
pts
;
}
//如果pts时间戳小于上一个P帧,那么断定这个是B帧,我们记录B帧连续个数
++
_frames_since_last_max_pts
;
}
//pts放入排序缓存列队,缓存列队最大等于连续B帧个数
_pts_sorter
.
emplace
(
pts
);
if
(
_sorter_max_size
&&
_pts_sorter
.
size
()
>
_sorter_max_size
){
//如果启用了pts排序(意味着存在B帧),并且pts排序缓存列队长度大于连续B帧个数,
//意味着后续的pts都会比最早的pts大,那么说明可以取出最早的pts了,这个pts将当做该帧的dts基准
auto
it
=
_pts_sorter
.
begin
();
//由于该pts是前面偏移了个_sorter_max_size帧的pts(也就是那帧画面的dts),
//那么我们加上时间戳偏移量,基本等于该帧的dts
dts
=
*
it
+
_dts_pts_offset
;
if
(
dts
>
pts
){
//dts不能大于pts(基本不可能到达这个逻辑)
dts
=
pts
;
}
//pts排序缓存出列
_pts_sorter
.
erase
(
it
);
return
true
;
}
//排序缓存尚未满
return
false
;
}
...
...
src/Extension/H264Rtp.cpp
查看文件 @
9d9f6e30
...
...
@@ -191,19 +191,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
void
H264RtpDecoder
::
onGetH264
(
const
H264Frame
::
Ptr
&
frame
)
{
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
!
flag
){
if
(
frame
->
configFrame
()
||
frame
->
keyFrame
()){
flag
=
true
;
frame
->
_dts
=
frame
->
_pts
;
}
}
//根据pts计算dts
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
//rtsp没有dts,那么根据pts排序算法生成dts
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
_h264frame
=
obtainFrame
();
}
...
...
src/Extension/H265Rtp.cpp
查看文件 @
9d9f6e30
...
...
@@ -127,18 +127,10 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) {
}
void
H265RtpDecoder
::
onGetH265
(
const
H265Frame
::
Ptr
&
frame
)
{
//计算dts
auto
flag
=
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
if
(
!
flag
){
if
(
frame
->
configFrame
()
||
frame
->
keyFrame
()){
flag
=
true
;
frame
->
_dts
=
frame
->
_pts
;
}
}
if
(
flag
){
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
}
//rtsp没有dts,那么根据pts排序算法生成dts
_dts_generator
.
getDts
(
frame
->
_pts
,
frame
->
_dts
);
//写入环形缓存
RtpCodec
::
inputFrame
(
frame
);
_h265frame
=
obtainFrame
();
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论