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-10-27 11:25:42 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0ed8807727c4643d13a0bb37887d6dc1b32c0918
0ed88077
1 parent
b9ef2801
support cache last gop for video
显示空白字符变更
内嵌
并排对比
正在显示
6 个修改的文件
包含
176 行增加
和
7 行删除
README.md
trunk/src/core/srs_core_client.cpp
trunk/src/core/srs_core_codec.cpp
trunk/src/core/srs_core_codec.hpp
trunk/src/core/srs_core_source.cpp
trunk/src/core/srs_core_source.hpp
README.md
查看文件 @
0ed8807
...
...
@@ -45,7 +45,8 @@ url: rtmp://127.0.0.1:1935/live/livestream
*
nginx v1.5.0: 139524 lines
<br/>
### History
*
v0.2, 2013-10-23, v0.2 released. 10125 lines.
*
v0.3, 2013-10-27, support cache last gop for client fast startup.
*
v0.2, 2013-10-25, v0.2 released. 10125 lines.
*
v0.2, 2013-10-25, support flash publish.
*
v0.2, 2013-10-25, support h264/avc codec by rtmp complex handshake(SrsComplexHandshake).
*
v0.2, 2013-10-24, support time jitter detect and correct algorithm(SrsConsumer::jitter_correct).
...
...
trunk/src/core/srs_core_client.cpp
查看文件 @
0ed8807
...
...
@@ -145,7 +145,9 @@ int SrsClient::do_cycle()
return
ret
;
}
srs_info
(
"start to publish stream %s success"
,
req
->
stream
.
c_str
());
return
streaming_publish
(
source
,
true
);
ret
=
streaming_publish
(
source
,
true
);
source
->
on_unpublish
();
return
ret
;
}
case
SrsClientFlashPublish
:
{
srs_verbose
(
"flash start to publish stream %s."
,
req
->
stream
.
c_str
());
...
...
@@ -155,7 +157,9 @@ int SrsClient::do_cycle()
return
ret
;
}
srs_info
(
"flash start to publish stream %s success"
,
req
->
stream
.
c_str
());
return
streaming_publish
(
source
,
false
);
ret
=
streaming_publish
(
source
,
false
);
source
->
on_unpublish
();
return
ret
;
}
default
:
{
ret
=
ERROR_SYSTEM_CLIENT_INVALID
;
...
...
trunk/src/core/srs_core_codec.cpp
查看文件 @
0ed8807
...
...
@@ -31,6 +31,35 @@ SrsCodec::~SrsCodec()
{
}
bool
SrsCodec
::
video_is_keyframe
(
int8_t
*
data
,
int
size
)
{
// E.4.3.1 VIDEODATA
// Frame Type UB [4]
// Type of video frame. The following values are defined:
// 1 = key frame (for AVC, a seekable frame)
// 2 = inter frame (for AVC, a non-seekable frame)
// 3 = disposable inter frame (H.263 only)
// 4 = generated key frame (reserved for server use only)
// 5 = video info/command frame
//
// AVCPacketType IF CodecID == 7 UI8
// The following values are defined:
// 0 = AVC sequence header
// 1 = AVC NALU
// 2 = AVC end of sequence (lower level NALU sequence ender is
// not required or supported)
// 2bytes required.
if
(
size
<
1
)
{
return
false
;
}
char
frame_type
=
*
(
char
*
)
data
;
frame_type
=
(
frame_type
>>
4
)
&
0x0F
;
return
frame_type
==
1
;
}
bool
SrsCodec
::
video_is_sequence_header
(
int8_t
*
data
,
int
size
)
{
// E.4.3.1 VIDEODATA
...
...
trunk/src/core/srs_core_codec.hpp
查看文件 @
0ed8807
...
...
@@ -40,10 +40,26 @@ public:
SrsCodec
();
virtual
~
SrsCodec
();
public
:
/**
* only check the frame_type, not check the codec type.
*/
virtual
bool
video_is_keyframe
(
int8_t
*
data
,
int
size
);
/**
* check codec h264, keyframe, sequence header
*/
virtual
bool
video_is_sequence_header
(
int8_t
*
data
,
int
size
);
/**
* check codec aac, sequence header
*/
virtual
bool
audio_is_sequence_header
(
int8_t
*
data
,
int
size
);
private
:
/**
* check codec h264.
*/
virtual
bool
video_is_h264
(
int8_t
*
data
,
int
size
);
private
:
/**
* check codec aac.
*/
virtual
bool
audio_is_aac
(
int8_t
*
data
,
int
size
);
};
...
...
trunk/src/core/srs_core_source.cpp
查看文件 @
0ed8807
...
...
@@ -64,6 +64,11 @@ SrsConsumer::~SrsConsumer()
source
->
on_consumer_destroy
(
this
);
}
int
SrsConsumer
::
get_time
()
{
return
(
int
)
last_pkt_correct_time
;
}
int
SrsConsumer
::
enqueue
(
SrsSharedPtrMessage
*
msg
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -144,10 +149,12 @@ int SrsConsumer::jitter_correct(SrsSharedPtrMessage* msg)
SrsSource
::
SrsSource
(
std
::
string
_stream_url
)
{
stream_url
=
_stream_url
;
cache_metadata
=
NULL
;
cache_sh_video
=
NULL
;
cache_sh_audio
=
NULL
;
codec
=
new
SrsCodec
();
cache_metadata
=
cache_sh_video
=
cache_sh_audio
=
NULL
;
cached_video_count
=
0
;
enable_gop_cache
=
true
;
}
SrsSource
::~
SrsSource
()
...
...
@@ -159,6 +166,8 @@ SrsSource::~SrsSource()
}
consumers
.
clear
();
clear_gop_cache
();
srs_freep
(
cache_metadata
);
srs_freep
(
cache_sh_video
);
srs_freep
(
cache_sh_audio
);
...
...
@@ -246,8 +255,16 @@ int SrsSource::on_audio(SrsCommonMessage* audio)
if
(
codec
->
audio_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
srs_freep
(
cache_sh_audio
);
cache_sh_audio
=
msg
->
copy
();
return
ret
;
}
// cache the last gop packets
if
((
ret
=
cache_last_gop
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"shrink gop cache failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"cache gop success."
);
return
ret
;
}
...
...
@@ -282,7 +299,15 @@ int SrsSource::on_video(SrsCommonMessage* video)
if
(
codec
->
video_is_sequence_header
(
msg
->
payload
,
msg
->
size
))
{
srs_freep
(
cache_sh_video
);
cache_sh_video
=
msg
->
copy
();
return
ret
;
}
// cache the last gop packets
if
((
ret
=
cache_last_gop
(
msg
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"shrink gop cache failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"cache gop success."
);
return
ret
;
}
...
...
@@ -312,6 +337,16 @@ int SrsSource::on_video(SrsCommonMessage* video)
}
srs_info
(
"dispatch audio sequence header success"
);
std
::
vector
<
SrsSharedPtrMessage
*>::
iterator
it
;
for
(
it
=
gop_cache
.
begin
();
it
!=
gop_cache
.
end
();
++
it
)
{
SrsSharedPtrMessage
*
msg
=
*
it
;
if
((
ret
=
consumer
->
enqueue
(
msg
->
copy
()))
!=
ERROR_SUCCESS
)
{
srs_error
(
"dispatch cached gop failed. ret=%d"
,
ret
);
return
ret
;
}
}
srs_trace
(
"dispatch cached gop success. count=%d, duration=%d"
,
(
int
)
gop_cache
.
size
(),
consumer
->
get_time
());
return
ret
;
}
...
...
@@ -325,3 +360,58 @@ void SrsSource::on_consumer_destroy(SrsConsumer* consumer)
srs_info
(
"handle consumer destroy success."
);
}
void
SrsSource
::
on_unpublish
()
{
clear_gop_cache
();
srs_trace
(
"clear cache when unpublish."
);
}
int
SrsSource
::
cache_last_gop
(
SrsSharedPtrMessage
*
msg
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
!
enable_gop_cache
)
{
srs_verbose
(
"gop cache is disabled."
);
return
ret
;
}
// got video, update the video count if acceptable
if
(
msg
->
header
.
is_video
())
{
cached_video_count
++
;
}
// no acceptable video or pure audio, disable the cache.
if
(
cached_video_count
==
0
)
{
srs_verbose
(
"ignore any frame util got a h264 video frame."
);
return
ret
;
}
// clear gop cache when got key frame
if
(
msg
->
header
.
is_video
()
&&
codec
->
video_is_keyframe
(
msg
->
payload
,
msg
->
size
))
{
srs_info
(
"clear gop cache when got keyframe. vcount=%d, count=%d"
,
cached_video_count
,
(
int
)
gop_cache
.
size
());
clear_gop_cache
();
// curent msg is video frame, so we set to 1.
cached_video_count
=
1
;
}
// cache the frame.
gop_cache
.
push_back
(
msg
->
copy
());
return
ret
;
}
void
SrsSource
::
clear_gop_cache
()
{
std
::
vector
<
SrsSharedPtrMessage
*>::
iterator
it
;
for
(
it
=
gop_cache
.
begin
();
it
!=
gop_cache
.
end
();
++
it
)
{
SrsSharedPtrMessage
*
msg
=
*
it
;
srs_freep
(
msg
);
}
gop_cache
.
clear
();
cached_video_count
=
0
;
}
...
...
trunk/src/core/srs_core_source.hpp
查看文件 @
0ed8807
...
...
@@ -55,6 +55,10 @@ public:
virtual
~
SrsConsumer
();
public
:
/**
* get current client time, the last packet time.
*/
virtual
int
get_time
();
/**
* enqueue an shared ptr message.
*/
virtual
int
enqueue
(
SrsSharedPtrMessage
*
msg
);
...
...
@@ -92,6 +96,22 @@ private:
SrsCodec
*
codec
;
std
::
string
stream_url
;
std
::
vector
<
SrsConsumer
*>
consumers
;
// gop cache for client fast startup.
private:
/**
* if disabled the gop cache,
* the client will wait for the next keyframe for h264,
* and will be black-screen.
*/
bool
enable_gop_cache
;
/**
* the video frame count, avoid cache for pure audio stream.
*/
int
cached_video_count
;
/**
* cached gop.
*/
std
::
vector
<
SrsSharedPtrMessage
*>
gop_cache
;
private
:
SrsSharedPtrMessage
*
cache_metadata
;
// the cached video sequence header.
...
...
@@ -108,6 +128,15 @@ public:
public
:
virtual
int
create_consumer
(
SrsConsumer
*&
consumer
);
virtual
void
on_consumer_destroy
(
SrsConsumer
*
consumer
);
virtual
void
on_unpublish
();
private
:
/**
* only for h264 codec
* 1. cache the gop when got h264 video packet.
* 2. clear gop when got keyframe.
*/
virtual
int
cache_last_gop
(
SrsSharedPtrMessage
*
msg
);
virtual
void
clear_gop_cache
();
};
#endif
\ No newline at end of file
...
...
请
注册
或
登录
后发表评论