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
84cfe66d
Commit
84cfe66d
authored
Aug 30, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修复由于音视频同步导致时间戳回退的问题
parent
29fcf3eb
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
54 行增加
和
44 行删除
+54
-44
src/Common/Stamp.cpp
+41
-39
src/Common/Stamp.h
+13
-5
没有找到文件。
src/Common/Stamp.cpp
查看文件 @
84cfe66d
...
...
@@ -44,77 +44,79 @@ void Stamp::setPlayBack(bool playback) {
void
Stamp
::
syncTo
(
Stamp
&
other
){
_sync_master
=
&
other
;
_sync_finished
=
false
;
}
//限制dts回退
void
Stamp
::
revise
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
)
{
revise_l
(
dts
,
pts
,
dts_out
,
pts_out
,
modifyStamp
);
if
(
_sync_finished
||
modifyStamp
||
_playback
){
revise_l
(
dts
,
pts
,
dts_out
,
pts_out
,
modifyStamp
);
if
(
_playback
)
{
//回放允许时间戳回退
return
;
}
if
(
dts_out
<
_last_dts_out
)
{
WarnL
<<
"dts回退:"
<<
dts_out
<<
" < "
<<
_last_dts_out
;
dts_out
=
_last_dts_out
;
pts_out
=
_last_pts_out
;
return
;
}
_last_dts_out
=
dts_out
;
_last_pts_out
=
pts_out
;
}
//音视频时间戳同步
void
Stamp
::
revise_l
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
)
{
revise_l2
(
dts
,
pts
,
dts_out
,
pts_out
,
modifyStamp
);
if
(
!
_sync_master
||
modifyStamp
||
_playback
)
{
//自动生成时间戳或回放或同步完毕
if
(
dts_out
<
0
)
{
dts_out
=
0
;
}
if
(
pts_out
<
0
)
{
pts_out
=
0
;
}
return
;
}
if
(
_sync_master
&&
_sync_master
->
_last_dts
)
{
if
(
_sync_master
&&
_sync_master
->
_last_dts_in
)
{
//音视频dts当前时间差
int64_t
dts_diff
=
_last_dts
-
_sync_master
->
_last_dts
;
if
(
ABS
(
dts_diff
)
<
5000
)
{
int64_t
dts_diff
=
_last_dts
_in
-
_sync_master
->
_last_dts_in
;
if
(
ABS
(
dts_diff
)
<
5000
)
{
//如果绝对时间戳小于5秒,那么说明他们的起始时间戳是一致的,那么强制同步
_last_relativeStamp
=
_relativeStamp
;
_relativeStamp
=
_sync_master
->
_relativeStamp
+
dts_diff
;
_relative_stamp
=
_sync_master
->
_relative_stamp
+
dts_diff
;
}
//下次不用再强制同步
_sync_master
=
nullptr
;
}
if
(
dts_out
<
0
||
dts_out
<
_last_relativeStamp
)
{
//相对时间戳小于0,或者小于上次的时间戳,
//那么说明是同步时间戳导致的,在这个过渡期内,我们一直返回上次的结果(目的是为了防止时间戳回退)
pts_out
=
_last_relativeStamp
+
(
pts_out
-
dts_out
);
dts_out
=
_last_relativeStamp
;
}
else
if
(
!
_sync_master
){
//音视频同步过渡期完毕
_sync_finished
=
true
;
}
if
(
pts_out
<
0
){
pts_out
=
dts_out
;
}
}
void
Stamp
::
revise_l
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
)
{
if
(
!
pts
){
//求取相对时间戳
void
Stamp
::
revise_l2
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
)
{
if
(
!
pts
)
{
//没有播放时间戳,使其赋值为解码时间戳
pts
=
dts
;
}
if
(
_playback
)
{
if
(
_playback
)
{
//这是点播
dts_out
=
dts
;
pts_out
=
pts
;
_relative
S
tamp
=
dts_out
;
_last_dts
=
dts
;
_relative
_s
tamp
=
dts_out
;
_last_dts
_in
=
dts
;
return
;
}
//pts和dts的差值
int
pts_dts_diff
=
pts
-
dts
;
if
(
_last_dts
!=
dts
)
{
if
(
_last_dts_in
!=
dts
)
{
//时间戳发生变更
if
(
modifyStamp
)
{
if
(
modifyStamp
)
{
//内部自己生产时间戳
_relative
S
tamp
=
_ticker
.
elapsedTime
();
}
else
{
_relative
S
tamp
+=
deltaStamp
(
dts
);
_relative
_s
tamp
=
_ticker
.
elapsedTime
();
}
else
{
_relative
_s
tamp
+=
deltaStamp
(
dts
);
}
_last_dts
=
dts
;
_last_dts
_in
=
dts
;
}
dts_out
=
_relative
S
tamp
;
dts_out
=
_relative
_s
tamp
;
//////////////以下是播放时间戳的计算//////////////////
if
(
ABS
(
pts_dts_diff
)
>
MAX_CTS
)
{
if
(
ABS
(
pts_dts_diff
)
>
MAX_CTS
)
{
//如果差值太大,则认为由于回环导致时间戳错乱了
pts_dts_diff
=
0
;
}
...
...
@@ -123,11 +125,11 @@ void Stamp::revise_l(int64_t dts, int64_t pts, int64_t &dts_out, int64_t &pts_ou
}
void
Stamp
::
setRelativeStamp
(
int64_t
relativeStamp
)
{
_relative
S
tamp
=
relativeStamp
;
_relative
_s
tamp
=
relativeStamp
;
}
int64_t
Stamp
::
getRelativeStamp
()
const
{
return
_relative
S
tamp
;
return
_relative
_s
tamp
;
}
bool
DtsGenerator
::
getDts
(
uint32_t
pts
,
uint32_t
&
dts
){
...
...
src/Common/Stamp.h
查看文件 @
84cfe66d
...
...
@@ -29,6 +29,7 @@ public:
* @return 时间戳增量
*/
int64_t
deltaStamp
(
int64_t
stamp
);
private
:
int64_t
_last_stamp
=
0
;
};
...
...
@@ -41,7 +42,7 @@ public:
~
Stamp
()
=
default
;
/**
*
修正时间戳
*
求取相对时间戳,同时实现了音视频同步、限制dts回退等功能
* @param dts 输入dts,如果为0则根据系统时间戳生成
* @param pts 输入pts,如果为0则等于dts
* @param dts_out 输出dts
...
...
@@ -75,15 +76,20 @@ public:
void
syncTo
(
Stamp
&
other
);
private
:
//主要实现音视频时间戳同步功能
void
revise_l
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
=
false
);
//主要实现获取相对时间戳功能
void
revise_l2
(
int64_t
dts
,
int64_t
pts
,
int64_t
&
dts_out
,
int64_t
&
pts_out
,
bool
modifyStamp
=
false
);
private
:
int64_t
_relativeStamp
=
0
;
int64_t
_last_relativeStamp
=
0
;
int64_t
_last_dts
=
0
;
int64_t
_relative_stamp
=
0
;
int64_t
_last_dts_in
=
0
;
int64_t
_last_dts_out
=
0
;
int64_t
_last_pts_out
=
0
;
SmoothTicker
_ticker
;
bool
_playback
=
false
;
Stamp
*
_sync_master
=
nullptr
;
bool
_sync_finished
=
true
;
};
//dts生成器,
...
...
@@ -93,8 +99,10 @@ public:
DtsGenerator
()
=
default
;
~
DtsGenerator
()
=
default
;
bool
getDts
(
uint32_t
pts
,
uint32_t
&
dts
);
private
:
bool
getDts_l
(
uint32_t
pts
,
uint32_t
&
dts
);
private
:
uint32_t
_dts_pts_offset
=
0
;
uint32_t
_last_dts
=
0
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论