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