Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2013-11-26 11:15:44 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
326713fbed5cdfa9cf3685f64a06e658c54aadd0
326713fb
1 parent
501b182d
refine code, extract the rtmp jitter for hls
隐藏空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
99 行增加
和
62 行删除
trunk/src/core/srs_core_hls.cpp
trunk/src/core/srs_core_hls.hpp
trunk/src/core/srs_core_source.cpp
trunk/src/core/srs_core_source.hpp
trunk/src/core/srs_core_hls.cpp
查看文件 @
326713f
...
...
@@ -41,6 +41,7 @@ SrsHLS::SrsHLS()
codec
=
new
SrsCodec
();
sample
=
new
SrsCodecSample
();
muxer
=
NULL
;
jitter
=
new
SrsRtmpJitter
();
}
SrsHLS
::~
SrsHLS
()
...
...
@@ -48,6 +49,7 @@ SrsHLS::~SrsHLS()
srs_freep
(
codec
);
srs_freep
(
sample
);
srs_freep
(
muxer
);
srs_freep
(
jitter
);
}
int
SrsHLS
::
on_publish
(
std
::
string
_vhost
)
...
...
trunk/src/core/srs_core_hls.hpp
查看文件 @
326713f
...
...
@@ -38,6 +38,7 @@ class SrsCodecBuffer;
class
SrsMpegtsFrame
;
class
SrsTSMuxer
;
class
SrsCodec
;
class
SrsRtmpJitter
;
class
SrsHLS
{
...
...
@@ -47,6 +48,7 @@ private:
SrsCodec
*
codec
;
SrsCodecSample
*
sample
;
SrsTSMuxer
*
muxer
;
SrsRtmpJitter
*
jitter
;
public
:
SrsHLS
();
virtual
~
SrsHLS
();
...
...
trunk/src/core/srs_core_source.cpp
查看文件 @
326713f
...
...
@@ -36,23 +36,72 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DEFAULT_FRAME_TIME_MS 10
#define PAUSED_SHRINK_SIZE 250
std
::
map
<
std
::
string
,
SrsSource
*>
SrsSource
::
pool
;
SrsRtmpJitter
::
SrsRtmpJitter
()
{
last_pkt_correct_time
=
last_pkt_time
=
0
;
}
Srs
Source
*
SrsSource
::
find
(
std
::
string
stream_url
)
Srs
RtmpJitter
::~
SrsRtmpJitter
(
)
{
if
(
pool
.
find
(
stream_url
)
==
pool
.
end
())
{
pool
[
stream_url
]
=
new
SrsSource
(
stream_url
);
srs_verbose
(
"create new source for url=%s"
,
stream_url
.
c_str
());
}
int
SrsRtmpJitter
::
correct
(
SrsSharedPtrMessage
*
msg
,
int
audio_sample_rate
,
int
video_frame_rate
)
{
int
ret
=
ERROR_SUCCESS
;
/**
* we use a very simple time jitter detect/correct algorithm:
* 1. delta: ensure the delta is positive and valid,
* we set the delta to DEFAULT_FRAME_TIME_MS,
* if the delta of time is nagative or greater than CONST_MAX_JITTER_MS.
* 2. last_pkt_time: specifies the original packet time,
* is used to detect next jitter.
* 3. last_pkt_correct_time: simply add the positive delta,
* and enforce the time monotonically.
*/
u_int32_t
time
=
msg
->
header
.
timestamp
;
int32_t
delta
=
time
-
last_pkt_time
;
// if jitter detected, reset the delta.
if
(
delta
<
0
||
delta
>
CONST_MAX_JITTER_MS
)
{
// calc the right diff by audio sample rate
if
(
msg
->
header
.
is_audio
()
&&
audio_sample_rate
>
0
)
{
delta
=
(
int32_t
)(
delta
*
1000.0
/
audio_sample_rate
);
}
else
if
(
msg
->
header
.
is_video
()
&&
video_frame_rate
>
0
)
{
delta
=
(
int32_t
)(
delta
*
1.0
/
video_frame_rate
);
}
else
{
delta
=
DEFAULT_FRAME_TIME_MS
;
}
// sometimes, the time is absolute time, so correct it again.
if
(
delta
<
0
||
delta
>
CONST_MAX_JITTER_MS
)
{
delta
=
DEFAULT_FRAME_TIME_MS
;
}
srs_info
(
"jitter detected, last_pts=%d, pts=%d, diff=%d, last_time=%d, time=%d, diff=%d"
,
last_pkt_time
,
time
,
time
-
last_pkt_time
,
last_pkt_correct_time
,
last_pkt_correct_time
+
delta
,
delta
);
}
else
{
srs_verbose
(
"timestamp no jitter. time=%d, last_pkt=%d, correct_to=%d"
,
time
,
last_pkt_time
,
last_pkt_correct_time
+
delta
);
}
return
pool
[
stream_url
];
last_pkt_correct_time
=
srs_max
(
0
,
last_pkt_correct_time
+
delta
);
msg
->
header
.
timestamp
=
last_pkt_correct_time
;
last_pkt_time
=
time
;
return
ret
;
}
int
SrsRtmpJitter
::
get_time
()
{
return
(
int
)
last_pkt_correct_time
;
}
SrsConsumer
::
SrsConsumer
(
SrsSource
*
_source
)
{
source
=
_source
;
last_pkt_correct_time
=
last_pkt_time
=
0
;
paused
=
false
;
jitter
=
new
SrsRtmpJitter
();
}
SrsConsumer
::~
SrsConsumer
()
...
...
@@ -60,18 +109,19 @@ SrsConsumer::~SrsConsumer()
clear
();
source
->
on_consumer_destroy
(
this
);
srs_freep
(
jitter
);
}
int
SrsConsumer
::
get_time
()
{
return
(
int
)
last_pkt_correct_time
;
return
jitter
->
get_time
()
;
}
int
SrsConsumer
::
enqueue
(
SrsSharedPtrMessage
*
msg
,
int
audio_sample_rate
,
int
video_frame_rate
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
jitter
_
correct
(
msg
,
audio_sample_rate
,
video_frame_rate
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
jitter
->
correct
(
msg
,
audio_sample_rate
,
video_frame_rate
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -178,53 +228,6 @@ void SrsConsumer::shrink()
}
}
int
SrsConsumer
::
jitter_correct
(
SrsSharedPtrMessage
*
msg
,
int
audio_sample_rate
,
int
video_frame_rate
)
{
int
ret
=
ERROR_SUCCESS
;
/**
* we use a very simple time jitter detect/correct algorithm:
* 1. delta: ensure the delta is positive and valid,
* we set the delta to DEFAULT_FRAME_TIME_MS,
* if the delta of time is nagative or greater than CONST_MAX_JITTER_MS.
* 2. last_pkt_time: specifies the original packet time,
* is used to detect next jitter.
* 3. last_pkt_correct_time: simply add the positive delta,
* and enforce the time monotonically.
*/
u_int32_t
time
=
msg
->
header
.
timestamp
;
int32_t
delta
=
time
-
last_pkt_time
;
// if jitter detected, reset the delta.
if
(
delta
<
0
||
delta
>
CONST_MAX_JITTER_MS
)
{
// calc the right diff by audio sample rate
if
(
msg
->
header
.
is_audio
()
&&
audio_sample_rate
>
0
)
{
delta
=
(
int32_t
)(
delta
*
1000.0
/
audio_sample_rate
);
}
else
if
(
msg
->
header
.
is_video
()
&&
video_frame_rate
>
0
)
{
delta
=
(
int32_t
)(
delta
*
1.0
/
video_frame_rate
);
}
else
{
delta
=
DEFAULT_FRAME_TIME_MS
;
}
// sometimes, the time is absolute time, so correct it again.
if
(
delta
<
0
||
delta
>
CONST_MAX_JITTER_MS
)
{
delta
=
DEFAULT_FRAME_TIME_MS
;
}
srs_info
(
"jitter detected, last_pts=%d, pts=%d, diff=%d, last_time=%d, time=%d, diff=%d"
,
last_pkt_time
,
time
,
time
-
last_pkt_time
,
last_pkt_correct_time
,
last_pkt_correct_time
+
delta
,
delta
);
}
else
{
srs_verbose
(
"timestamp no jitter. time=%d, last_pkt=%d, correct_to=%d"
,
time
,
last_pkt_time
,
last_pkt_correct_time
+
delta
);
}
last_pkt_correct_time
=
srs_max
(
0
,
last_pkt_correct_time
+
delta
);
msg
->
header
.
timestamp
=
last_pkt_correct_time
;
last_pkt_time
=
time
;
return
ret
;
}
void
SrsConsumer
::
clear
()
{
std
::
vector
<
SrsSharedPtrMessage
*>::
iterator
it
;
...
...
@@ -235,6 +238,18 @@ void SrsConsumer::clear()
msgs
.
clear
();
}
std
::
map
<
std
::
string
,
SrsSource
*>
SrsSource
::
pool
;
SrsSource
*
SrsSource
::
find
(
std
::
string
stream_url
)
{
if
(
pool
.
find
(
stream_url
)
==
pool
.
end
())
{
pool
[
stream_url
]
=
new
SrsSource
(
stream_url
);
srs_verbose
(
"create new source for url=%s"
,
stream_url
.
c_str
());
}
return
pool
[
stream_url
];
}
SrsSource
::
SrsSource
(
std
::
string
_stream_url
)
{
stream_url
=
_stream_url
;
...
...
trunk/src/core/srs_core_source.hpp
查看文件 @
326713f
...
...
@@ -41,13 +41,35 @@ class SrsSharedPtrMessage;
class
SrsHLS
;
/**
* the consumer for SrsSource, that is a play client.
* time jitter detect and correct,
* to ensure the rtmp stream is monotonically.
*/
class
Srs
Consum
er
class
Srs
RtmpJitt
er
{
private
:
u_int32_t
last_pkt_time
;
u_int32_t
last_pkt_correct_time
;
public
:
SrsRtmpJitter
();
virtual
~
SrsRtmpJitter
();
public
:
/**
* detect the time jitter and correct it.
*/
virtual
int
correct
(
SrsSharedPtrMessage
*
msg
,
int
audio_sample_rate
,
int
video_frame_rate
);
/**
* get current client time, the last packet time.
*/
virtual
int
get_time
();
};
/**
* the consumer for SrsSource, that is a play client.
*/
class
SrsConsumer
{
private
:
SrsRtmpJitter
*
jitter
;
SrsSource
*
source
;
std
::
vector
<
SrsSharedPtrMessage
*>
msgs
;
bool
paused
;
...
...
@@ -82,10 +104,6 @@ private:
* remove to cache only one gop.
*/
virtual
void
shrink
();
/**
* detect the time jitter and correct it.
*/
virtual
int
jitter_correct
(
SrsSharedPtrMessage
*
msg
,
int
audio_sample_rate
,
int
video_frame_rate
);
virtual
void
clear
();
};
...
...
请
注册
或
登录
后发表评论