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
2014-03-20 18:55:45 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
e0fb1029c9359f5614fac67a3cc722099e42812d
e0fb1029
1 parent
b708f588
support pure audio hls. change to 0.9.24
隐藏空白字符变更
内嵌
并排对比
正在显示
3 个修改的文件
包含
81 行增加
和
39 行删除
trunk/src/app/srs_app_hls.cpp
trunk/src/app/srs_app_hls.hpp
trunk/src/core/srs_core.hpp
trunk/src/app/srs_app_hls.cpp
查看文件 @
e0fb102
...
...
@@ -44,7 +44,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_app_pithy_print.hpp>
// max PES packets size to flush the video.
#define SRS_HLS_AUDIO_CACHE_SIZE
512
* 1024
#define SRS_HLS_AUDIO_CACHE_SIZE
1024
* 1024
// @see: NGX_RTMP_HLS_DELAY,
// 63000: 700ms, ts_tbn=90000
...
...
@@ -481,12 +481,20 @@ SrsHlsSegment::~SrsHlsSegment()
srs_freep
(
muxer
);
}
double
SrsHlsSegment
::
update_duration
(
int64_t
current_frame_dts
)
void
SrsHlsSegment
::
update_duration
(
int64_t
current_frame_dts
)
{
// we use video/audio to update segment duration,
// so when reap segment, some previous audio frame will
// update the segment duration, which is nagetive,
// just ignore it.
if
(
current_frame_dts
<
segment_start_dts
)
{
return
;
}
duration
=
(
current_frame_dts
-
segment_start_dts
)
/
90000.0
;
srs_assert
(
duration
>=
0
);
return
duration
;
return
;
}
SrsHlsAacJitter
::
SrsHlsAacJitter
()
...
...
@@ -503,7 +511,6 @@ SrsHlsMuxer::SrsHlsMuxer()
hls_fragment
=
hls_window
=
0
;
file_index
=
0
;
current
=
NULL
;
video_count
=
0
;
}
SrsHlsMuxer
::~
SrsHlsMuxer
()
...
...
@@ -542,9 +549,6 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
return
ret
;
}
// reset video count for new publish session.
video_count
=
0
;
// TODO: create all parents dirs.
// create dir for app.
if
((
ret
=
create_dir
())
!=
ERROR_SUCCESS
)
{
...
...
@@ -605,6 +609,9 @@ int SrsHlsMuxer::flush_audio(SrsMpegtsFrame* af, SrsCodecBuffer* ab)
return
ret
;
}
// update the duration of segment.
current
->
update_duration
(
af
->
pts
);
if
((
ret
=
current
->
muxer
->
write_audio
(
af
,
ab
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -635,6 +642,9 @@ int SrsHlsMuxer::flush_video(
return
ret
;
}
// write success, clear and free the buffer
vb
->
free
();
return
ret
;
}
...
...
@@ -860,6 +870,8 @@ SrsHlsCache::SrsHlsCache()
af
=
new
SrsMpegtsFrame
();
vf
=
new
SrsMpegtsFrame
();
video_count
=
0
;
}
SrsHlsCache
::~
SrsHlsCache
()
...
...
@@ -890,6 +902,9 @@ int SrsHlsCache::on_publish(SrsHlsMuxer* muxer, SrsRequest* req, int64_t segment
// get the hls path config
std
::
string
hls_path
=
_srs_config
->
get_hls_path
(
vhost
);
// reset video count for new publish session.
video_count
=
0
;
// open muxer
if
((
ret
=
muxer
->
update_config
(
app
,
stream
,
hls_path
,
hls_fragment
,
hls_window
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer update config failed. ret=%d"
,
ret
);
...
...
@@ -956,13 +971,25 @@ int SrsHlsCache::write_audio(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t pts, S
}
}
// for pure audio
// start new segment when duration overflow.
if
(
video_count
==
0
&&
muxer
->
is_segment_overflow
())
{
srs_trace
(
"pure audio segment reap"
);
if
((
ret
=
reap_segment
(
muxer
,
af
->
pts
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
int
SrsHlsCache
::
write_video
(
SrsCodec
*
codec
,
SrsHlsMuxer
*
muxer
,
int64_t
dts
,
SrsCodecSample
*
sample
)
int
SrsHlsCache
::
write_video
(
SrsCodec
*
codec
,
SrsHlsMuxer
*
muxer
,
int64_t
dts
,
SrsCodecSample
*
sample
)
{
int
ret
=
ERROR_SUCCESS
;
video_count
++
;
// write video to cache.
if
((
ret
=
cache_video
(
codec
,
sample
))
!=
ERROR_SUCCESS
)
{
return
ret
;
...
...
@@ -974,26 +1001,11 @@ int SrsHlsCache::write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, S
vf
->
sid
=
TS_VIDEO_AVC
;
vf
->
key
=
sample
->
frame_type
==
SrsCodecVideoAVCFrameKeyFrame
;
// reopen the muxer for a gop
// close current segment, open a new segment,
// then write the key frame to the new segment.
// new segment when:
// 1. base on gop.
// 2. some gops duration overflow.
if
(
vf
->
key
&&
muxer
->
is_segment_overflow
())
{
if
((
ret
=
muxer
->
segment_close
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer close segment failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
muxer
->
segment_open
(
vf
->
dts
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer open segment failed. ret=%d"
,
ret
);
return
ret
;
}
// TODO: flush audio before or after segment?
// segment open, flush the audio.
// @see: ngx_rtmp_hls_open_fragment
/* start fragment with audio to make iPhone happy */
if
((
ret
=
muxer
->
flush_audio
(
af
,
ab
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer flush audio failed. ret=%d"
,
ret
);
if
((
ret
=
reap_segment
(
muxer
,
vf
->
dts
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
...
...
@@ -1004,8 +1016,31 @@ int SrsHlsCache::write_video(SrsCodec* codec, SrsHlsMuxer* muxer, int64_t dts, S
return
ret
;
}
// write success, clear and free the buffer
vb
->
free
();
return
ret
;
}
int
SrsHlsCache
::
reap_segment
(
SrsHlsMuxer
*
muxer
,
int64_t
segment_start_dts
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
muxer
->
segment_close
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer close segment failed. ret=%d"
,
ret
);
return
ret
;
}
if
((
ret
=
muxer
->
segment_open
(
segment_start_dts
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer open segment failed. ret=%d"
,
ret
);
return
ret
;
}
// TODO: flush audio before or after segment?
// segment open, flush the audio.
// @see: ngx_rtmp_hls_open_fragment
/* start fragment with audio to make iPhone happy */
if
((
ret
=
muxer
->
flush_audio
(
af
,
ab
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"m3u8 muxer flush audio failed. ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
...
...
trunk/src/app/srs_app_hls.hpp
查看文件 @
e0fb102
...
...
@@ -124,7 +124,7 @@ public:
* update the segment duration.
* @current_frame_dts the dts of frame, in tbn of ts.
*/
virtual
double
update_duration
(
int64_t
current_frame_dts
);
virtual
void
update_duration
(
int64_t
current_frame_dts
);
};
/**
...
...
@@ -149,14 +149,6 @@ private:
std
::
string
m3u8
;
private
:
/**
* for pure audio HLS application,
* the video count used to count the video,
* if zero and audio buffer overflow, reap the ts,
* just like we got a keyframe.
*/
u_int32_t
video_count
;
private
:
/**
* m3u8 segments.
*/
std
::
vector
<
SrsHlsSegment
*>
segments
;
...
...
@@ -219,6 +211,14 @@ private:
int64_t
audio_buffer_start_pts
;
// time jitter for aac
SrsHlsAacJitter
*
aac_jitter
;
private
:
/**
* for pure audio HLS application,
* the video count used to count the video,
* if zero and audio buffer overflow, reap the ts,
* just like we got a keyframe.
*/
u_int32_t
video_count
;
public
:
SrsHlsCache
();
virtual
~
SrsHlsCache
();
...
...
@@ -237,6 +237,13 @@ public:
*/
virtual
int
write_video
(
SrsCodec
*
codec
,
SrsHlsMuxer
*
muxer
,
int64_t
dts
,
SrsCodecSample
*
sample
);
private
:
/**
* reopen the muxer for a new hls segment,
* close current segment, open a new segment,
* then write the key frame to the new segment.
* so, user must reap_segment then flush_video to hls muxer.
*/
virtual
int
reap_segment
(
SrsHlsMuxer
*
muxer
,
int64_t
segment_start_dts
);
virtual
int
cache_audio
(
SrsCodec
*
codec
,
SrsCodecSample
*
sample
);
virtual
int
cache_video
(
SrsCodec
*
codec
,
SrsCodecSample
*
sample
);
};
...
...
trunk/src/core/srs_core.hpp
查看文件 @
e0fb102
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "2
3
"
#define VERSION_REVISION "2
4
"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "srs"
...
...
请
注册
或
登录
后发表评论