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-30 21:02:21 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
80a81b16618e985e676ef9a9019c0430fa952346
80a81b16
1 parent
ce15f4bc
parse ffmpeg params
隐藏空白字符变更
内嵌
并排对比
正在显示
12 个修改的文件
包含
703 行增加
和
17 行删除
trunk/conf/srs.conf
trunk/src/core/srs_core.cpp
trunk/src/core/srs_core.hpp
trunk/src/core/srs_core_client.cpp
trunk/src/core/srs_core_config.cpp
trunk/src/core/srs_core_config.hpp
trunk/src/core/srs_core_encoder.cpp
trunk/src/core/srs_core_encoder.hpp
trunk/src/core/srs_core_error.hpp
trunk/src/core/srs_core_hls.cpp
trunk/src/core/srs_core_source.cpp
trunk/src/core/srs_core_source.hpp
trunk/conf/srs.conf
查看文件 @
80a81b1
...
...
@@ -45,6 +45,7 @@ vhost all.transcode.vhost.com {
transcode
{
# whether the transcode enabled.
# if off, donot transcode.
# default: off.
enabled
on
;
# the ffmpeg
ffmpeg
./
objs
/
ffmpeg
/
bin
/
ffmpeg
;
...
...
@@ -53,6 +54,7 @@ vhost all.transcode.vhost.com {
# the transcode set name(ie. hd) is optional and not used.
engine
super
{
# whether the engine is enabled
# default: off.
enabled
on
;
# video encoder name
vcodec
libx264
;
...
...
trunk/src/core/srs_core.cpp
查看文件 @
80a81b1
...
...
@@ -43,3 +43,20 @@ void srs_update_system_time_ms()
_srs_system_time_us_cache
=
srs_max
(
0
,
_srs_system_time_us_cache
);
}
std
::
string
srs_replace
(
std
::
string
str
,
std
::
string
old_str
,
std
::
string
new_str
)
{
std
::
string
ret
=
str
;
if
(
old_str
==
new_str
)
{
return
ret
;
}
size_t
pos
=
0
;
while
((
pos
=
ret
.
find
(
old_str
,
pos
))
!=
std
::
string
::
npos
)
{
ret
=
ret
.
replace
(
pos
,
old_str
.
length
(),
new_str
);
pos
+=
new_str
.
length
();
}
return
ret
;
}
...
...
trunk/src/core/srs_core.hpp
查看文件 @
80a81b1
...
...
@@ -91,4 +91,8 @@ extern void srs_update_system_time_ms();
// signal defines.
#define SIGNAL_RELOAD SIGHUP
#include <string>
// replace utility
extern
std
::
string
srs_replace
(
std
::
string
str
,
std
::
string
old_str
,
std
::
string
new_str
);
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_client.cpp
查看文件 @
80a81b1
...
...
@@ -231,8 +231,7 @@ int SrsClient::check_vhost()
return
ret
;
}
SrsConfDirective
*
conf
=
NULL
;
if
((
conf
=
config
->
get_vhost_enabled
(
req
->
vhost
))
!=
NULL
&&
conf
->
arg0
()
!=
"on"
)
{
if
(
!
config
->
get_vhost_enabled
(
req
->
vhost
))
{
ret
=
ERROR_RTMP_VHOST_NOT_FOUND
;
srs_error
(
"vhost %s disabled. ret=%d"
,
req
->
vhost
.
c_str
(),
ret
);
return
ret
;
...
...
@@ -344,7 +343,7 @@ int SrsClient::publish(SrsSource* source, bool is_fmle)
SrsPithyPrint
pithy_print
(
SRS_STAGE_PUBLISH_USER
);
// notify the hls to prepare when publish start.
if
((
ret
=
source
->
on_publish
(
req
->
vhost
,
req
->
app
,
req
->
stream
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
source
->
on_publish
(
req
->
vhost
,
req
->
port
,
req
->
app
,
req
->
stream
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hls on_publish failed. ret=%d"
,
ret
);
return
ret
;
}
...
...
trunk/src/core/srs_core_config.cpp
查看文件 @
80a81b1
...
...
@@ -557,15 +557,24 @@ SrsConfDirective* SrsConfig::get_vhost(std::string vhost)
return
NULL
;
}
SrsConfDirective
*
SrsConfig
::
get_vhost_enabled
(
std
::
string
vhost
)
bool
SrsConfig
::
get_vhost_enabled
(
std
::
string
vhost
)
{
SrsConfDirective
*
conf
=
get_vhost
(
vhost
);
SrsConfDirective
*
vhost_
conf
=
get_vhost
(
vhost
);
if
(
!
vhost_conf
)
{
return
true
;
}
SrsConfDirective
*
conf
=
vhost_conf
->
get
(
"enabled"
);
if
(
!
conf
)
{
return
NULL
;
return
true
;
}
if
(
conf
->
arg0
()
==
"off"
)
{
return
false
;
}
return
conf
->
get
(
"enabled"
)
;
return
true
;
}
SrsConfDirective
*
SrsConfig
::
get_transcode
(
std
::
string
vhost
,
std
::
string
scope
)
...
...
@@ -588,6 +597,300 @@ SrsConfDirective* SrsConfig::get_transcode(std::string vhost, std::string scope)
return
NULL
;
}
bool
SrsConfig
::
get_transcode_enabled
(
SrsConfDirective
*
transcode
)
{
if
(
!
transcode
)
{
return
false
;
}
SrsConfDirective
*
conf
=
transcode
->
get
(
"enabled"
);
if
(
!
conf
||
conf
->
arg0
()
!=
"on"
)
{
return
false
;
}
return
true
;
}
std
::
string
SrsConfig
::
get_transcode_ffmpeg
(
SrsConfDirective
*
transcode
)
{
if
(
!
transcode
)
{
return
""
;
}
SrsConfDirective
*
conf
=
transcode
->
get
(
"ffmpeg"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
void
SrsConfig
::
get_transcode_engines
(
SrsConfDirective
*
transcode
,
std
::
vector
<
SrsConfDirective
*>&
engines
)
{
if
(
!
transcode
)
{
return
;
}
for
(
int
i
=
0
;
i
<
(
int
)
transcode
->
directives
.
size
();
i
++
)
{
SrsConfDirective
*
conf
=
transcode
->
directives
[
i
];
if
(
conf
->
name
==
"engine"
)
{
engines
.
push_back
(
conf
);
}
}
return
;
}
bool
SrsConfig
::
get_engine_enabled
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
false
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"enabled"
);
if
(
!
conf
||
conf
->
arg0
()
!=
"on"
)
{
return
false
;
}
return
true
;
}
std
::
string
SrsConfig
::
get_engine_vcodec
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vcodec"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
int
SrsConfig
::
get_engine_vbitrate
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vbitrate"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
double
SrsConfig
::
get_engine_vfps
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vfps"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atof
(
conf
->
arg0
().
c_str
());
}
int
SrsConfig
::
get_engine_vwidth
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vwidth"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
int
SrsConfig
::
get_engine_vheight
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vheight"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
int
SrsConfig
::
get_engine_vthreads
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vthreads"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
std
::
string
SrsConfig
::
get_engine_vprofile
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vprofile"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
std
::
string
SrsConfig
::
get_engine_vpreset
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vpreset"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
std
::
string
SrsConfig
::
get_engine_vparams
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"vparams"
);
if
(
!
conf
)
{
return
""
;
}
std
::
string
avparams
;
for
(
int
i
=
0
;
i
<
(
int
)
conf
->
directives
.
size
();
i
++
)
{
SrsConfDirective
*
p
=
conf
->
directives
[
i
];
if
(
!
p
)
{
continue
;
}
avparams
+=
p
->
name
;
avparams
+=
" "
;
avparams
+=
p
->
arg0
();
}
return
avparams
;
}
std
::
string
SrsConfig
::
get_engine_acodec
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"acodec"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
int
SrsConfig
::
get_engine_abitrate
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"abitrate"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
int
SrsConfig
::
get_engine_asample_rate
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"asample_rate"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
int
SrsConfig
::
get_engine_achannels
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
0
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"achannels"
);
if
(
!
conf
)
{
return
0
;
}
return
::
atoi
(
conf
->
arg0
().
c_str
());
}
std
::
string
SrsConfig
::
get_engine_aparams
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"aparams"
);
if
(
!
conf
)
{
return
""
;
}
std
::
string
avparams
;
for
(
int
i
=
0
;
i
<
(
int
)
conf
->
directives
.
size
();
i
++
)
{
SrsConfDirective
*
p
=
conf
->
directives
[
i
];
if
(
!
p
)
{
continue
;
}
avparams
+=
p
->
name
;
avparams
+=
" "
;
avparams
+=
p
->
arg0
();
}
return
avparams
;
}
std
::
string
SrsConfig
::
get_engine_output
(
SrsConfDirective
*
engine
)
{
if
(
!
engine
)
{
return
""
;
}
SrsConfDirective
*
conf
=
engine
->
get
(
"output"
);
if
(
!
conf
)
{
return
""
;
}
return
conf
->
arg0
();
}
SrsConfDirective
*
SrsConfig
::
get_gop_cache
(
std
::
string
vhost
)
{
SrsConfDirective
*
conf
=
get_vhost
(
vhost
);
...
...
@@ -621,6 +924,21 @@ SrsConfDirective* SrsConfig::get_hls(std::string vhost)
return
conf
->
get
(
"hls"
);
}
bool
SrsConfig
::
get_hls_enabled
(
std
::
string
vhost
)
{
SrsConfDirective
*
hls
=
get_hls
(
vhost
);
if
(
!
hls
)
{
return
true
;
}
if
(
hls
->
arg0
()
==
"off"
)
{
return
false
;
}
return
true
;
}
SrsConfDirective
*
SrsConfig
::
get_hls_path
(
std
::
string
vhost
)
{
SrsConfDirective
*
conf
=
get_vhost
(
vhost
);
...
...
trunk/src/core/srs_core_config.hpp
查看文件 @
80a81b1
...
...
@@ -112,12 +112,33 @@ public:
virtual
void
unsubscribe
(
SrsReloadHandler
*
handler
);
public
:
virtual
int
parse_options
(
int
argc
,
char
**
argv
);
public
:
virtual
SrsConfDirective
*
get_vhost
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_vhost_enabled
(
std
::
string
vhost
);
virtual
bool
get_vhost_enabled
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_transcode
(
std
::
string
vhost
,
std
::
string
scope
);
virtual
bool
get_transcode_enabled
(
SrsConfDirective
*
transcode
);
virtual
std
::
string
get_transcode_ffmpeg
(
SrsConfDirective
*
transcode
);
virtual
void
get_transcode_engines
(
SrsConfDirective
*
transcode
,
std
::
vector
<
SrsConfDirective
*>&
engines
);
virtual
bool
get_engine_enabled
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_vcodec
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_vbitrate
(
SrsConfDirective
*
engine
);
virtual
double
get_engine_vfps
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_vwidth
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_vheight
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_vthreads
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_vprofile
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_vpreset
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_vparams
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_acodec
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_abitrate
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_asample_rate
(
SrsConfDirective
*
engine
);
virtual
int
get_engine_achannels
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_aparams
(
SrsConfDirective
*
engine
);
virtual
std
::
string
get_engine_output
(
SrsConfDirective
*
engine
);
virtual
SrsConfDirective
*
get_gop_cache
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_forward
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_hls
(
std
::
string
vhost
);
virtual
bool
get_hls_enabled
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_hls_path
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_hls_fragment
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_hls_window
(
std
::
string
vhost
);
...
...
trunk/src/core/srs_core_encoder.cpp
查看文件 @
80a81b1
...
...
@@ -29,6 +29,154 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_ENCODER_SLEEP_MS 2000
#define SRS_ENCODER_VCODEC "libx264"
#define SRS_ENCODER_ACODEC "libaacplus"
SrsFFMPEG
::
SrsFFMPEG
(
std
::
string
ffmpeg_bin
)
{
started
=
false
;
ffmpeg
=
ffmpeg_bin
;
vbitrate
=
0
;
vfps
=
0
;
vwidth
=
0
;
vheight
=
0
;
vthreads
=
0
;
abitrate
=
0
;
asample_rate
=
0
;
achannels
=
0
;
}
SrsFFMPEG
::~
SrsFFMPEG
()
{
stop
();
}
int
SrsFFMPEG
::
initialize
(
std
::
string
vhost
,
std
::
string
port
,
std
::
string
app
,
std
::
string
stream
,
SrsConfDirective
*
engine
)
{
int
ret
=
ERROR_SUCCESS
;
vcodec
=
config
->
get_engine_vcodec
(
engine
);
vbitrate
=
config
->
get_engine_vbitrate
(
engine
);
vfps
=
config
->
get_engine_vfps
(
engine
);
vwidth
=
config
->
get_engine_vwidth
(
engine
);
vheight
=
config
->
get_engine_vheight
(
engine
);
vthreads
=
config
->
get_engine_vthreads
(
engine
);
vprofile
=
config
->
get_engine_vprofile
(
engine
);
vpreset
=
config
->
get_engine_vpreset
(
engine
);
vparams
=
config
->
get_engine_vparams
(
engine
);
acodec
=
config
->
get_engine_acodec
(
engine
);
abitrate
=
config
->
get_engine_abitrate
(
engine
);
asample_rate
=
config
->
get_engine_asample_rate
(
engine
);
achannels
=
config
->
get_engine_achannels
(
engine
);
aparams
=
config
->
get_engine_aparams
(
engine
);
output
=
config
->
get_engine_output
(
engine
);
// ensure the size is even.
vwidth
-=
vwidth
%
2
;
vheight
-=
vheight
%
2
;
if
(
vhost
==
RTMP_VHOST_DEFAULT
)
{
output
=
srs_replace
(
output
,
"[vhost]"
,
"127.0.0.1"
);
}
else
{
output
=
srs_replace
(
output
,
"[vhost]"
,
vhost
);
}
output
=
srs_replace
(
output
,
"[port]"
,
port
);
output
=
srs_replace
(
output
,
"[app]"
,
app
);
output
=
srs_replace
(
output
,
"[stream]"
,
stream
);
if
(
vcodec
!=
SRS_ENCODER_VCODEC
)
{
ret
=
ERROR_ENCODER_VCODEC
;
srs_error
(
"invalid vcodec, must be %s, actual %s, ret=%d"
,
SRS_ENCODER_VCODEC
,
vcodec
.
c_str
(),
ret
);
return
ret
;
}
if
(
vbitrate
<=
0
)
{
ret
=
ERROR_ENCODER_VBITRATE
;
srs_error
(
"invalid vbitrate: %d, ret=%d"
,
vbitrate
,
ret
);
return
ret
;
}
if
(
vfps
<=
0
)
{
ret
=
ERROR_ENCODER_VFPS
;
srs_error
(
"invalid vfps: %.2f, ret=%d"
,
vfps
,
ret
);
return
ret
;
}
if
(
vwidth
<=
0
)
{
ret
=
ERROR_ENCODER_VWIDTH
;
srs_error
(
"invalid vwidth: %d, ret=%d"
,
vwidth
,
ret
);
return
ret
;
}
if
(
vheight
<=
0
)
{
ret
=
ERROR_ENCODER_VHEIGHT
;
srs_error
(
"invalid vheight: %d, ret=%d"
,
vheight
,
ret
);
return
ret
;
}
if
(
vthreads
<
0
)
{
ret
=
ERROR_ENCODER_VTHREADS
;
srs_error
(
"invalid vthreads: %d, ret=%d"
,
vthreads
,
ret
);
return
ret
;
}
if
(
vprofile
.
empty
())
{
ret
=
ERROR_ENCODER_VPROFILE
;
srs_error
(
"invalid vprofile: %s, ret=%d"
,
vprofile
.
c_str
(),
ret
);
return
ret
;
}
if
(
vpreset
.
empty
())
{
ret
=
ERROR_ENCODER_VPRESET
;
srs_error
(
"invalid vpreset: %s, ret=%d"
,
vpreset
.
c_str
(),
ret
);
return
ret
;
}
if
(
acodec
!=
SRS_ENCODER_ACODEC
)
{
ret
=
ERROR_ENCODER_ACODEC
;
srs_error
(
"invalid acodec, must be %s, actual %s, ret=%d"
,
SRS_ENCODER_ACODEC
,
acodec
.
c_str
(),
ret
);
return
ret
;
}
if
(
abitrate
<=
0
)
{
ret
=
ERROR_ENCODER_ABITRATE
;
srs_error
(
"invalid abitrate: %d, ret=%d"
,
abitrate
,
ret
);
return
ret
;
}
if
(
asample_rate
<=
0
)
{
ret
=
ERROR_ENCODER_ASAMPLE_RATE
;
srs_error
(
"invalid sample rate: %d, ret=%d"
,
asample_rate
,
ret
);
return
ret
;
}
if
(
achannels
!=
1
&&
achannels
!=
2
)
{
ret
=
ERROR_ENCODER_ACHANNELS
;
srs_error
(
"invalid achannels, must be 1 or 2, actual %d, ret=%d"
,
achannels
,
ret
);
return
ret
;
}
if
(
output
.
empty
())
{
ret
=
ERROR_ENCODER_OUTPUT
;
srs_error
(
"invalid empty output, ret=%d"
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsFFMPEG
::
start
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
started
)
{
return
ret
;
}
return
ret
;
}
void
SrsFFMPEG
::
stop
()
{
if
(
!
started
)
{
return
;
}
}
SrsEncoder
::
SrsEncoder
()
{
tid
=
NULL
;
...
...
@@ -40,16 +188,50 @@ SrsEncoder::~SrsEncoder()
on_unpublish
();
}
int
SrsEncoder
::
on_publish
(
std
::
string
_vhost
,
std
::
string
_app
,
std
::
string
_stream
)
int
SrsEncoder
::
on_publish
(
std
::
string
_vhost
,
std
::
string
_
port
,
std
::
string
_
app
,
std
::
string
_stream
)
{
int
ret
=
ERROR_SUCCESS
;
vhost
=
_vhost
;
port
=
_port
;
app
=
_app
;
stream
=
_stream
;
// parse all transcode engines.
SrsConfDirective
*
conf
=
NULL
;
// parse vhost scope engines
std
::
string
scope
=
""
;
if
((
conf
=
config
->
get_transcode
(
vhost
,
""
))
!=
NULL
)
{
if
((
ret
=
parse_transcode
(
conf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse vhost scope=%s transcode engines failed. "
"ret=%d"
,
scope
.
c_str
(),
ret
);
return
ret
;
}
}
// parse app scope engines
scope
=
app
;
if
((
conf
=
config
->
get_transcode
(
vhost
,
app
))
!=
NULL
)
{
if
((
ret
=
parse_transcode
(
conf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse app scope=%s transcode engines failed. "
"ret=%d"
,
scope
.
c_str
(),
ret
);
return
ret
;
}
}
// parse stream scope engines
scope
+=
"/"
;
scope
+=
stream
;
if
((
conf
=
config
->
get_transcode
(
vhost
,
app
+
"/"
+
stream
))
!=
NULL
)
{
if
((
ret
=
parse_transcode
(
conf
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse stream scope=%s transcode engines failed. "
"ret=%d"
,
scope
.
c_str
(),
ret
);
return
ret
;
}
}
// start thread to run all encoding engines.
srs_assert
(
!
tid
);
if
((
tid
=
st_thread_create
(
encoder_thread
,
this
,
1
,
0
))
==
NULL
){
if
((
tid
=
st_thread_create
(
encoder_thread
,
this
,
1
,
0
))
==
NULL
)
{
ret
=
ERROR_ST_CREATE_FORWARD_THREAD
;
srs_error
(
"st_thread_create failed. ret=%d"
,
ret
);
return
ret
;
...
...
@@ -66,11 +248,89 @@ void SrsEncoder::on_unpublish()
st_thread_join
(
tid
,
NULL
);
tid
=
NULL
;
}
std
::
vector
<
SrsFFMPEG
*>::
iterator
it
;
for
(
it
=
ffmpegs
.
begin
();
it
!=
ffmpegs
.
end
();
++
it
)
{
SrsFFMPEG
*
ffmpeg
=
*
it
;
srs_freep
(
ffmpeg
);
}
ffmpegs
.
clear
();
}
SrsFFMPEG
*
SrsEncoder
::
at
(
int
index
)
{
return
ffmpegs
[
index
];
}
int
SrsEncoder
::
parse_transcode
(
SrsConfDirective
*
conf
)
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
conf
);
// enabled
if
(
!
config
->
get_transcode_enabled
(
conf
))
{
srs_trace
(
"ignore the disabled transcode: %s"
,
conf
->
arg0
().
c_str
());
return
ret
;
}
// ffmpeg
std
::
string
ffmpeg_bin
=
config
->
get_transcode_ffmpeg
(
conf
);
if
(
ffmpeg_bin
.
empty
())
{
srs_trace
(
"ignore the empty ffmpeg transcode: %s"
,
conf
->
arg0
().
c_str
());
return
ret
;
}
// get all engines.
std
::
vector
<
SrsConfDirective
*>
engines
;
config
->
get_transcode_engines
(
conf
,
engines
);
if
(
engines
.
empty
())
{
srs_trace
(
"ignore the empty transcode engine: %s"
,
conf
->
arg0
().
c_str
());
return
ret
;
}
// create engine
for
(
int
i
=
0
;
i
<
(
int
)
engines
.
size
();
i
++
)
{
SrsConfDirective
*
engine
=
engines
[
i
];
if
(
!
config
->
get_engine_enabled
(
engine
))
{
srs_trace
(
"ignore the diabled transcode engine: %s %s"
,
conf
->
arg0
().
c_str
(),
engine
->
arg0
().
c_str
());
continue
;
}
SrsFFMPEG
*
ffmpeg
=
new
SrsFFMPEG
(
ffmpeg_bin
);
if
((
ret
=
ffmpeg
->
initialize
(
vhost
,
port
,
app
,
stream
,
engine
))
!=
ERROR_SUCCESS
)
{
srs_freep
(
ffmpeg
);
srs_error
(
"invalid transcode engine: %s %s"
,
conf
->
arg0
().
c_str
(),
engine
->
arg0
().
c_str
());
return
ret
;
}
ffmpegs
.
push_back
(
ffmpeg
);
}
return
ret
;
}
int
SrsEncoder
::
cycle
()
{
int
ret
=
ERROR_SUCCESS
;
// start all ffmpegs.
std
::
vector
<
SrsFFMPEG
*>::
iterator
it
;
for
(
it
=
ffmpegs
.
begin
();
it
!=
ffmpegs
.
end
();
++
it
)
{
SrsFFMPEG
*
ffmpeg
=
*
it
;
if
((
ret
=
ffmpeg
->
start
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"ffmpeg start failed. ret=%d"
,
ret
);
return
ret
;
}
}
return
ret
;
}
...
...
@@ -95,7 +355,12 @@ void SrsEncoder::encoder_cycle()
st_usleep
(
SRS_ENCODER_SLEEP_MS
*
1000
);
}
// TODO: kill ffmpeg when finished and it alive
// kill ffmpeg when finished and it alive
std
::
vector
<
SrsFFMPEG
*>::
iterator
it
;
for
(
it
=
ffmpegs
.
begin
();
it
!=
ffmpegs
.
end
();
++
it
)
{
SrsFFMPEG
*
ffmpeg
=
*
it
;
ffmpeg
->
stop
();
}
srs_trace
(
"encoder cycle finished"
);
}
...
...
trunk/src/core/srs_core_encoder.hpp
查看文件 @
80a81b1
...
...
@@ -30,25 +30,71 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_core.hpp>
#include <string>
#include <vector>
#include <st.h>
class
SrsConfDirective
;
/**
* a transcode engine: ffmepg,
* used to transcode a stream to another.
*/
class
SrsFFMPEG
{
private
:
bool
started
;
private
:
std
::
string
ffmpeg
;
std
::
string
vcodec
;
int
vbitrate
;
double
vfps
;
int
vwidth
;
int
vheight
;
int
vthreads
;
std
::
string
vprofile
;
std
::
string
vpreset
;
std
::
string
vparams
;
std
::
string
acodec
;
int
abitrate
;
int
asample_rate
;
int
achannels
;
std
::
string
aparams
;
std
::
string
output
;
public
:
SrsFFMPEG
(
std
::
string
ffmpeg_bin
);
virtual
~
SrsFFMPEG
();
public
:
virtual
int
initialize
(
std
::
string
vhost
,
std
::
string
port
,
std
::
string
app
,
std
::
string
stream
,
SrsConfDirective
*
engine
);
virtual
int
start
();
virtual
void
stop
();
};
/**
* the encoder for a stream,
* may use multiple ffmpegs to transcode the specified stream.
*/
class
SrsEncoder
{
private
:
std
::
string
vhost
;
std
::
string
port
;
std
::
string
app
;
std
::
string
stream
;
private
:
std
::
vector
<
SrsFFMPEG
*>
ffmpegs
;
private
:
st_thread_t
tid
;
bool
loop
;
public
:
SrsEncoder
();
virtual
~
SrsEncoder
();
public
:
virtual
int
on_publish
(
std
::
string
vhost
,
std
::
string
app
,
std
::
string
stream
);
virtual
int
on_publish
(
std
::
string
vhost
,
std
::
string
port
,
std
::
string
app
,
std
::
string
stream
);
virtual
void
on_unpublish
();
private
:
virtual
SrsFFMPEG
*
at
(
int
index
);
virtual
int
parse_transcode
(
SrsConfDirective
*
conf
);
virtual
int
cycle
();
virtual
void
encoder_cycle
();
static
void
*
encoder_thread
(
void
*
arg
);
...
...
trunk/src/core/srs_core_error.hpp
查看文件 @
80a81b1
...
...
@@ -122,4 +122,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_HLS_AAC_FRAME_LENGTH 605
#define ERROR_HLS_AVC_SAMPLE_SIZE 606
#define ERROR_ENCODER_VCODEC 700
#define ERROR_ENCODER_OUTPUT 701
#define ERROR_ENCODER_ACHANNELS 702
#define ERROR_ENCODER_ASAMPLE_RATE 703
#define ERROR_ENCODER_ABITRATE 704
#define ERROR_ENCODER_ACODEC 705
#define ERROR_ENCODER_VPRESET 706
#define ERROR_ENCODER_VPROFILE 707
#define ERROR_ENCODER_VTHREADS 708
#define ERROR_ENCODER_VHEIGHT 709
#define ERROR_ENCODER_VWIDTH 710
#define ERROR_ENCODER_VFPS 711
#define ERROR_ENCODER_VBITRATE 712
#endif
\ No newline at end of file
...
...
trunk/src/core/srs_core_hls.cpp
查看文件 @
80a81b1
...
...
@@ -688,8 +688,7 @@ int SrsHls::reopen()
int
ret
=
ERROR_SUCCESS
;
// try to open the HLS muxer
SrsConfDirective
*
conf
=
config
->
get_hls
(
vhost
);
if
(
conf
&&
conf
->
arg0
()
==
"off"
)
{
if
(
!
config
->
get_hls_enabled
(
vhost
))
{
return
ret
;
}
...
...
@@ -698,6 +697,7 @@ int SrsHls::reopen()
hls_enabled
=
true
;
SrsConfDirective
*
conf
=
NULL
;
hls_path
=
SRS_CONF_DEFAULT_HLS_PATH
;
if
((
conf
=
config
->
get_hls_path
(
vhost
))
!=
NULL
)
{
hls_path
=
conf
->
arg0
();
...
...
trunk/src/core/srs_core_source.cpp
查看文件 @
80a81b1
...
...
@@ -612,7 +612,7 @@ int SrsSource::on_video(SrsCommonMessage* video)
return
ret
;
}
int
SrsSource
::
on_publish
(
std
::
string
vhost
,
std
::
string
app
,
std
::
string
stream
)
int
SrsSource
::
on_publish
(
std
::
string
vhost
,
std
::
string
port
,
std
::
string
app
,
std
::
string
stream
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -625,7 +625,7 @@ int SrsSource::on_publish(std::string vhost, std::string app, std::string stream
#endif
#ifdef SRS_FFMPEG
if
((
ret
=
encoder
->
on_publish
(
vhost
,
app
,
stream
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
encoder
->
on_publish
(
vhost
,
port
,
app
,
stream
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
#endif
...
...
trunk/src/core/srs_core_source.hpp
查看文件 @
80a81b1
...
...
@@ -210,7 +210,7 @@ public:
virtual
int
on_meta_data
(
SrsCommonMessage
*
msg
,
SrsOnMetaDataPacket
*
metadata
);
virtual
int
on_audio
(
SrsCommonMessage
*
audio
);
virtual
int
on_video
(
SrsCommonMessage
*
video
);
virtual
int
on_publish
(
std
::
string
vhost
,
std
::
string
app
,
std
::
string
stream
);
virtual
int
on_publish
(
std
::
string
vhost
,
std
::
string
port
,
std
::
string
app
,
std
::
string
stream
);
virtual
void
on_unpublish
();
public
:
virtual
int
create_consumer
(
SrsConsumer
*&
consumer
);
...
...
请
注册
或
登录
后发表评论