mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge 3.0relase.
This commit is contained in:
commit
c31c5eb05b
36 changed files with 2284 additions and 195 deletions
|
@ -18,4 +18,3 @@ workflows:
|
|||
jobs:
|
||||
- build
|
||||
- test
|
||||
|
||||
|
|
21
.github/ISSUE_TEMPLATE/---.md
vendored
21
.github/ISSUE_TEMPLATE/---.md
vendored
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
name: 提功能
|
||||
about: 提功能需求,支持新的特性。
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**你的功能是解决某个问题?**
|
||||
请详细描述你的问题,例如在使用现有功能时碰到了困难。
|
||||
|
||||
**描述你期望的解决方案**
|
||||
请详细描述你期望发生什么事情。
|
||||
|
||||
**请描述你考虑过的实现方法**
|
||||
请描述你考虑过的实现方法。
|
||||
|
||||
**环境**
|
||||
1. SRS的版本:'...'
|
||||
1. 操作系统:'...'
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -31,3 +31,5 @@
|
|||
.AppleDouble
|
||||
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
|
|
36
README.md
36
README.md
|
@ -1,6 +1,6 @@
|
|||
# SRS
|
||||
|
||||

|
||||

|
||||
[](https://circleci.com/gh/ossrs/srs/tree/develop)
|
||||
[](https://codecov.io/gh/ossrs/srs/branch/develop)
|
||||
[](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
||||
|
@ -147,7 +147,16 @@ For previous versions, please read:
|
|||
|
||||
## V3 changes
|
||||
|
||||
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.67)][r3.0a3] released. 110864 lines.</strong>
|
||||
* <strong>v3.0, 2019-12-13, [3.0 alpha4(3.0.71)][r3.0a4] released. 112928 lines.</strong>
|
||||
* v3.0, 2019-12-12, For [#547][bug #547], [#1506][bug #1506], default hls_dts_directly to on. 3.0.71
|
||||
* v3.0, 2019-12-12, SrsPacket supports converting to message, so can be sent by one API.
|
||||
* v3.0, 2019-12-11, For [#1042][bug #1042], cover RTMP client/server protocol.
|
||||
* v3.0, 2019-12-11, Fix [#1445][bug #1445], limit the createStream recursive depth. 3.0.70
|
||||
* v3.0, 2019-12-11, For [#1042][bug #1042], cover RTMP handshake protocol.
|
||||
* v3.0, 2019-12-11, Fix [#1229][bug #1229], fix the security risk in logger. 3.0.69
|
||||
* v3.0, 2019-12-11, For [#1229][bug #1229], fix the security risk in HDS. 3.0.69
|
||||
* v3.0, 2019-12-05, Fix [#1506][bug #1506], support directly turn FLV timestamp to TS DTS. 3.0.68
|
||||
* <strong>v3.0, 2019-11-30, [3.0 alpha3(3.0.67)][r3.0a3] released. 110864 lines.</strong>
|
||||
* v3.0, 2019-12-01, Fix [#1501][bug #1501], use request coworker for origin cluster. 3.0.67
|
||||
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.66)][r3.0a2] released. 110831 lines.</strong>
|
||||
* v3.0, 2019-11-30, Fix [#1501][bug #1501], use request coworker for origin cluster. 3.0.66
|
||||
|
@ -155,7 +164,7 @@ For previous versions, please read:
|
|||
* v3.0, 2019-11-30, Refine debug info for edge. 3.0.64
|
||||
* v3.0, 2019-10-30, Cover protocol stack RTMP. 3.0.63
|
||||
* v3.0, 2019-10-23, Cover JSON codec. 3.0.62
|
||||
* v3.0, 2019-10-13, Use http://ossrs.net:8000 as homepage.
|
||||
* v3.0, 2019-10-13, Use http://ossrs.net as homepage.
|
||||
* v3.0, 2019-10-10, Cover AMF0 codec. 3.0.61
|
||||
* <strong>v3.0, 2019-10-07, [3.0 alpha1(3.0.60)][r3.0a1] released. 107962 lines.</strong>
|
||||
* v3.0, 2019-10-06, Support log rotate by init.d command. 3.0.60
|
||||
|
@ -224,6 +233,7 @@ For previous versions, please read:
|
|||
|
||||
## V2 changes
|
||||
|
||||
* v2.0, 2019-12-13, Support openssl versions greater than 1.1.0. 2.0.266
|
||||
* <strong>v2.0, 2019-11-29, [2.0 release7(2.0.265)][r2.0r7] released. 86994 lines.</strong>
|
||||
* v2.0, 2019-11-29, For [srs-docker](https://github.com/ossrs/srs-docker/tree/master/2.0), install Cherrypy without sudo. 2.0.265
|
||||
* v2.0, 2019-04-06, For [#1304][bug #1304], Default HSTRS to on. 2.0.264
|
||||
|
@ -521,7 +531,7 @@ For previous versions, please read:
|
|||
* v1.0, 2014-05-27, fix [#84][bug #84], unpublish when edge disconnect. 0.9.119
|
||||
* v1.0, 2014-05-27, fix [#89][bug #89], config to /dev/null to disable ffmpeg log. 0.9.117
|
||||
* v1.0, 2014-05-25, fix [#76][bug #76], allow edge vhost to add or remove. 0.9.114
|
||||
* v1.0, 2014-05-24, Johnny contribute [ossrs.net](http://ossrs.net:8000). karthikeyan start to translate wiki to English.
|
||||
* v1.0, 2014-05-24, Johnny contribute [ossrs.net](http://ossrs.net). karthikeyan start to translate wiki to English.
|
||||
* v1.0, 2014-05-22, fix [#78][bug #78], st joinable thread must be stop by other threads, 0.9.113
|
||||
* v1.0, 2014-05-22, support amf0 StrictArray(0x0a). 0.9.111.
|
||||
* v1.0, 2014-05-22, support flv parser, add amf0 to librtmp. 0.9.110
|
||||
|
@ -655,7 +665,8 @@ For previous versions, please read:
|
|||
|
||||
## Releases
|
||||
|
||||
* 2019-11-30, [Release v3.0-a2][r3.0a3], 3.0 alpha2, 3.0.67, 110864 lines.
|
||||
* 2019-12-13, [Release v3.0-a4][r3.0a4], 3.0 alpha4, 3.0.71, 112928 lines.
|
||||
* 2019-11-30, [Release v3.0-a3][r3.0a3], 3.0 alpha3, 3.0.67, 110864 lines.
|
||||
* 2019-11-30, [Release v3.0-a2][r3.0a2], 3.0 alpha2, 3.0.66, 110831 lines.
|
||||
* 2019-10-07, [Release v3.0-a1][r3.0a1], 3.0 alpha1, 3.0.60, 107962 lines.
|
||||
* 2019-10-04, [Release v3.0-a0][r3.0a0], 3.0 alpha0, 3.0.56, 107946 lines.
|
||||
|
@ -1088,7 +1099,7 @@ Winlin
|
|||
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
|
||||
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
|
||||
[console]: http://ossrs.net:1985/console
|
||||
[player]: http://ossrs.net:8000/players/srs_player.html
|
||||
[player]: http://ossrs.net/players/srs_player.html
|
||||
[modules]: https://github.com/ossrs/srs/blob/develop/trunk/modules/readme.txt
|
||||
[docker-srs3]: https://github.com/ossrs/srs-docker#srs3
|
||||
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage
|
||||
|
@ -1140,8 +1151,8 @@ Winlin
|
|||
[v3_CN_Home]: https://github.com/ossrs/srs/wiki/v3_CN_Home
|
||||
[v3_EN_Home]: https://github.com/ossrs/srs/wiki/v3_EN_Home
|
||||
[donation0]: http://winlinvip.github.io/srs.release/donation/index.html
|
||||
[donation1]: http://ossrs.net:8000/srs.release/donation/index.html
|
||||
[donation2]: http://ossrs.net:8000/srs.release/donation/paypal.html
|
||||
[donation1]: http://ossrs.net/srs.release/donation/index.html
|
||||
[donation2]: http://ossrs.net/srs.release/donation/paypal.html
|
||||
[donations]: https://github.com/ossrs/srs/blob/develop/DONATIONS.txt
|
||||
|
||||
[v1_CN_Compare]: https://github.com/ossrs/srs/wiki/v1_CN_Compare
|
||||
|
@ -1511,6 +1522,10 @@ Winlin
|
|||
[bug #1051]: https://github.com/ossrs/srs/issues/1051
|
||||
[bug #1093]: https://github.com/ossrs/srs/issues/1093
|
||||
[bug #1501]: https://github.com/ossrs/srs/issues/1501
|
||||
[bug #1229]: https://github.com/ossrs/srs/issues/1229
|
||||
[bug #1042]: https://github.com/ossrs/srs/issues/1042
|
||||
[bug #1445]: https://github.com/ossrs/srs/issues/1445
|
||||
[bug #1506]: https://github.com/ossrs/srs/issues/1506
|
||||
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
|
||||
|
||||
[bug #1111]: https://github.com/ossrs/srs/issues/1111
|
||||
|
@ -1519,6 +1534,7 @@ Winlin
|
|||
|
||||
[exo #828]: https://github.com/google/ExoPlayer/pull/828
|
||||
|
||||
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
|
||||
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
|
||||
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
|
||||
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
|
||||
|
@ -1568,7 +1584,7 @@ Winlin
|
|||
[v1_CN_Contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
||||
[v1_EN_Contact]: https://github.com/ossrs/srs/wiki/v1_EN_Contact
|
||||
[more0]: http://winlinvip.github.io/srs.release/releases/
|
||||
[more1]: http://ossrs.net:8000/srs.release/releases/
|
||||
[more1]: http://ossrs.net/srs.release/releases/
|
||||
|
||||
[LICENSE]: https://github.com/ossrs/srs/blob/develop/LICENSE
|
||||
[LicenseMixing]: https://github.com/ossrs/srs/wiki/LicenseMixing
|
||||
|
@ -1580,5 +1596,5 @@ Winlin
|
|||
[release2]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release20
|
||||
[release3]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release30
|
||||
[centos0]: http://winlinvip.github.io/srs.release/releases/files/SRS-CentOS6-x86_64-3.0.56.zip
|
||||
[centos1]: http://ossrs.net:8000/srs.release/releases/files/SRS-CentOS6-x86_64-3.0.56.zip
|
||||
[centos1]: http://ossrs.net/srs.release/releases/files/SRS-CentOS6-x86_64-3.0.56.zip
|
||||
|
||||
|
|
1
trunk/.gitignore
vendored
1
trunk/.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
/*.conf
|
||||
/*.txt
|
||||
/*.flv
|
||||
/*.mp4
|
||||
/doc/frozen*.flv
|
||||
/doc/kungfupanda*.flv
|
||||
/doc/time*.flv
|
||||
|
|
|
@ -1,25 +1,45 @@
|
|||
#!/bin/bash
|
||||
|
||||
# In .circleci/config.yml, generate *.gcno with
|
||||
# ./configure --gcov --without-research --without-librtmp
|
||||
# ./configure --gcov --without-research --without-librtmp && make
|
||||
# and generate *.gcda by
|
||||
# ./objs/srs_utest
|
||||
|
||||
# Workdir is objs/cover.
|
||||
workdir=`pwd`/objs/cover
|
||||
|
||||
# Tool git is required to map the right path.
|
||||
git --version >/dev/null 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Tool git is required, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Create trunk under workdir.
|
||||
mkdir -p $workdir && cd $workdir
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Enter workdir failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Collect all *.gcno and *.gcda to objs/cover.
|
||||
(mkdir -p objs/cover && cd objs/cover &&
|
||||
cp -R ../../src . &&
|
||||
for file in `find ../src -name "*.gcno"`; do cp $file .; done &&
|
||||
for file in `find ../src -name "*.gcda"`; do cp $file .; done)
|
||||
cd $workdir && (rm -rf src && cp -R ../../src . && cp -R ../src .)
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect *.gcno and *.gcda failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Generate *.gcov to objs/cover
|
||||
for file in `find src -name "*.cpp"`; do
|
||||
(mkdir -p objs/cover && cd objs/cover && gcov ../../$file -o .)
|
||||
# Generate *.gcov for coverage.
|
||||
cd $workdir &&
|
||||
for file in `find src -name "*.cpp"|grep -v utest`; do
|
||||
gcov $file -o `dirname $file`
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect $file failed, ret=$ret"; exit $ret; fi
|
||||
done
|
||||
|
||||
# Cook the gcov files.
|
||||
cd $workdir &&
|
||||
find . -name "*.gcov"|grep -v srs|xargs rm -f
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Cook gcov files failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Upload report with *.gcov
|
||||
# Remark: The file codecov.yml is not neccessary. It literally depends on git.
|
||||
# Note: The right path is like:
|
||||
# https://codecov.io/gh/ossrs/srs/src/3.0release/trunk/src/protocol/srs_rtmp_stack.cpp
|
||||
# https://codecov.io/gh/ossrs/srs/src/20fbb4466fdc8ba5d810b8570df6004063212838/trunk/src/protocol/srs_rtmp_stack.cpp
|
||||
# Remark: It takes a few minutes to sync with github, so it might not available when CircleCI is done.
|
||||
# https://circleci.com/gh/ossrs/srs/tree/3.0release
|
||||
cd $workdir &&
|
||||
export CODECOV_TOKEN="493bba46-c468-4e73-8b45-8cdd8ff62d96" &&
|
||||
mkdir -p objs/cover && cd objs/cover &&
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
exit 0
|
||||
bash <(curl -s https://codecov.io/bash) &&
|
||||
echo "Done" && exit 0
|
||||
|
|
|
@ -1084,9 +1084,8 @@ vhost hls.srs.com {
|
|||
# whether cleanup the old expired ts files.
|
||||
# default: on
|
||||
hls_cleanup on;
|
||||
# the timeout in seconds to dispose the hls,
|
||||
# dispose is to remove all hls files, m3u8 and ts files.
|
||||
# when publisher timeout dispose hls.
|
||||
# If there is no incoming packets, dispose HLS in this timeout in seconds,
|
||||
# which removes all HLS files including m3u8 and ts files.
|
||||
# @remark 0 to disable dispose for publisher.
|
||||
# @remark apply for publisher timeout only, while "etc/init.d/srs stop" always dispose hls.
|
||||
# default: 0
|
||||
|
@ -1123,6 +1122,15 @@ vhost hls.srs.com {
|
|||
# @remark It's optional.
|
||||
hls_key_url https://localhost:8080;
|
||||
|
||||
# Special control controls.
|
||||
###########################################
|
||||
# Whether calculate the DTS of audio frame directly.
|
||||
# If on, guess the specific DTS by AAC samples, please read https://github.com/ossrs/srs/issues/547#issuecomment-294350544
|
||||
# If off, directly turn the FLV timestamp to DTS, which might cause corrupt audio stream.
|
||||
# @remark Recommend to set to off, unless your audio stream sample-rate and timestamp is not correct.
|
||||
# Default: on
|
||||
hls_dts_directly on;
|
||||
|
||||
# on_hls, never config in here, should config in http_hooks.
|
||||
# for the hls http callback, @see http_hooks.on_hls of vhost hooks.callback.srs.com
|
||||
# @read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS#http-callback
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/jwplayer'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/jwplayer'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/osmf'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/osmf'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/bwt'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/bwt'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/chat'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/chat'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/srsplayer'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/srsplayer'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/srspublisher'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/srspublisher'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/vlc'/>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/vlc'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -2589,6 +2589,8 @@ srs_error_t SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsJsonObject* obj
|
|||
hls->set("hls_dispose", sdir->dumps_arg0_to_number());
|
||||
} else if (sdir->name == "hls_nb_notify") {
|
||||
hls->set("hls_nb_notify", sdir->dumps_arg0_to_integer());
|
||||
} else if (sdir->name == "hls_dts_directly") {
|
||||
hls->set("hls_dts_directly", sdir->dumps_arg0_to_boolean());
|
||||
} else if (sdir->name == "hls_wait_keyframe") {
|
||||
hls->set("hls_wait_keyframe", sdir->dumps_arg0_to_boolean());
|
||||
} else if (sdir->name == "hls_keys") {
|
||||
|
@ -3751,7 +3753,7 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
&& m != "hls_storage" && m != "hls_mount" && m != "hls_td_ratio" && m != "hls_aof_ratio" && m != "hls_acodec" && m != "hls_vcodec"
|
||||
&& m != "hls_m3u8_file" && m != "hls_ts_file" && m != "hls_ts_floor" && m != "hls_cleanup" && m != "hls_nb_notify"
|
||||
&& m != "hls_wait_keyframe" && m != "hls_dispose" && m != "hls_keys" && m != "hls_fragments_per_key" && m != "hls_key_file"
|
||||
&& m != "hls_key_file_path" && m != "hls_key_url") {
|
||||
&& m != "hls_key_file_path" && m != "hls_key_url" && m != "hls_dts_directly") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.hls.%s of %s", m.c_str(), vhost->arg0().c_str());
|
||||
}
|
||||
|
||||
|
@ -6148,6 +6150,23 @@ int SrsConfig::get_vhost_hls_nb_notify(string vhost)
|
|||
return ::atoi(conf->arg0().c_str());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_vhost_hls_dts_directly(string vhost)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = get_hls(vhost);
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("hls_dts_directly");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_hls_cleanup(string vhost)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
|
|
@ -825,6 +825,8 @@ public:
|
|||
// Get the size of bytes to read from cdn network, for the on_hls_notify callback,
|
||||
// that is, to read max bytes of the bytes from the callback, or timeout or error.
|
||||
virtual int get_vhost_hls_nb_notify(std::string vhost);
|
||||
// Whether turn the FLV timestamp to TS DTS.
|
||||
virtual bool get_vhost_hls_dts_directly(std::string vhost);
|
||||
// hds section
|
||||
private:
|
||||
// Get the hds directive of vhost.
|
||||
|
|
|
@ -200,7 +200,7 @@ public:
|
|||
inline void set_index(int idx)
|
||||
{
|
||||
char file_path[1024] = {0};
|
||||
sprintf(file_path, "%s/%s/%sSeg1-Frag%d", _srs_config->get_hds_path(req->vhost).c_str()
|
||||
snprintf(file_path, 1024, "%s/%s/%sSeg1-Frag%d", _srs_config->get_hds_path(req->vhost).c_str()
|
||||
, req->app.c_str(), req->stream.c_str(), idx);
|
||||
|
||||
path = file_path;
|
||||
|
@ -428,7 +428,7 @@ srs_error_t SrsHds::flush_mainfest()
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
char buf[1024] = {0};
|
||||
sprintf(buf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
snprintf(buf, 1024, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
"<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n\t"
|
||||
"<id>%s.f4m</id>\n\t"
|
||||
"<streamType>live</streamType>\n\t"
|
||||
|
|
|
@ -910,9 +910,13 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req)
|
|||
if ((err = muxer->segment_open()) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: segment open");
|
||||
}
|
||||
srs_trace("hls: win=%dms, frag=%dms, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%dms",
|
||||
srsu2msi(hls_window), srsu2msi(hls_fragment), entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(),
|
||||
ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, srsu2msi(hls_dispose));
|
||||
|
||||
// This config item is used in SrsHls, we just log its value here.
|
||||
bool hls_dts_directly = _srs_config->get_vhost_hls_dts_directly(req->vhost);
|
||||
|
||||
srs_trace("hls: win=%dms, frag=%dms, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%dms, dts_directly=%d",
|
||||
srsu2msi(hls_window), srsu2msi(hls_fragment), entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(), ts_file.c_str(),
|
||||
hls_aof_ratio, ts_floor, cleanup, wait_keyframe, srsu2msi(hls_dispose), hls_dts_directly);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1062,6 +1066,7 @@ SrsHls::SrsHls()
|
|||
enabled = false;
|
||||
disposable = false;
|
||||
last_update_time = 0;
|
||||
hls_dts_directly = false;
|
||||
|
||||
previous_audio_dts = 0;
|
||||
aac_samples = 0;
|
||||
|
@ -1160,6 +1165,10 @@ srs_error_t SrsHls::on_publish()
|
|||
if ((err = controller->on_publish(req)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: on publish");
|
||||
}
|
||||
|
||||
// If enabled, directly turn FLV timestamp to TS DTS.
|
||||
// @remark It'll be reloaded automatically, because the origin hub will republish while reloading.
|
||||
hls_dts_directly = _srs_config->get_vhost_hls_dts_directly(req->vhost);
|
||||
|
||||
// if enabled, open the muxer.
|
||||
enabled = true;
|
||||
|
@ -1194,6 +1203,12 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
|
|||
if (!enabled) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Ignore if no format->acodec, it means the codec is not parsed, or unknown codec.
|
||||
// @issue https://github.com/ossrs/srs/issues/1506#issuecomment-562079474
|
||||
if (!format->acodec) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time();
|
||||
|
@ -1202,7 +1217,6 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
|
|||
SrsAutoFree(SrsSharedPtrMessage, audio);
|
||||
|
||||
// ts support audio codec: aac/mp3
|
||||
srs_assert(format->acodec);
|
||||
SrsAudioCodecId acodec = format->acodec->id;
|
||||
if (acodec != SrsAudioCodecIdAAC && acodec != SrsAudioCodecIdMP3) {
|
||||
return err;
|
||||
|
@ -1224,18 +1238,38 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
|
|||
previous_audio_dts = audio->timestamp;
|
||||
aac_samples = 0;
|
||||
}
|
||||
|
||||
// Use the diff to guess whether the samples is 1024 or 960.
|
||||
int nb_samples_per_frame = 1024;
|
||||
int diff = ::abs((int)(audio->timestamp - previous_audio_dts)) * srs_flv_srates[format->acodec->sound_rate];
|
||||
|
||||
// The diff duration in ms between two FLV audio packets.
|
||||
int diff = ::abs((int)(audio->timestamp - previous_audio_dts));
|
||||
previous_audio_dts = audio->timestamp;
|
||||
if (diff > 100 && diff < 950) {
|
||||
nb_samples_per_frame = 960;
|
||||
|
||||
// Guess the number of samples for each AAC frame.
|
||||
// If samples is 1024, the sample-rate is 8000HZ, the diff should be 1024/8000s=128ms.
|
||||
// If samples is 1024, the sample-rate is 44100HZ, the diff should be 1024/44100s=23ms.
|
||||
// If samples is 2048, the sample-rate is 44100HZ, the diff should be 2048/44100s=46ms.
|
||||
int nb_samples_per_frame = 0;
|
||||
int guessNumberOfSamples = diff * srs_flv_srates[format->acodec->sound_rate] / 1000;
|
||||
if (guessNumberOfSamples > 0) {
|
||||
if (guessNumberOfSamples < 960) {
|
||||
nb_samples_per_frame = 960;
|
||||
} else if (guessNumberOfSamples < 1536) {
|
||||
nb_samples_per_frame = 1024;
|
||||
} else if (guessNumberOfSamples < 3072) {
|
||||
nb_samples_per_frame = 2048;
|
||||
} else {
|
||||
nb_samples_per_frame = 4096;
|
||||
}
|
||||
}
|
||||
|
||||
// Recalc the DTS by the samples of AAC.
|
||||
int64_t dts = 90000 * aac_samples / srs_flv_srates[format->acodec->sound_rate];
|
||||
aac_samples += nb_samples_per_frame;
|
||||
int64_t dts = 90000 * aac_samples / srs_flv_srates[format->acodec->sound_rate];
|
||||
|
||||
// If directly turn FLV timestamp, overwrite the guessed DTS.
|
||||
// @doc https://github.com/ossrs/srs/issues/1506#issuecomment-562063095
|
||||
if (hls_dts_directly) {
|
||||
dts = audio->timestamp * 90;
|
||||
}
|
||||
|
||||
if ((err = controller->write_audio(format->audio, dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "hls: write audio");
|
||||
|
@ -1251,7 +1285,13 @@ srs_error_t SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* forma
|
|||
if (!enabled) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
// Ignore if no format->vcodec, it means the codec is not parsed, or unknown codec.
|
||||
// @issue https://github.com/ossrs/srs/issues/1506#issuecomment-562079474
|
||||
if (!format->vcodec) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// update the hls time, for hls_dispose.
|
||||
last_update_time = srs_get_system_time();
|
||||
|
||||
|
|
|
@ -288,6 +288,8 @@ private:
|
|||
int64_t previous_audio_dts;
|
||||
// The total aac samples.
|
||||
uint64_t aac_samples;
|
||||
// Whether directly turn FLV timestamp to TS DTS.
|
||||
bool hls_dts_directly;
|
||||
private:
|
||||
SrsOriginHub* hub;
|
||||
SrsRtmpJitter* jitter;
|
||||
|
|
|
@ -192,7 +192,8 @@ void SrsFastLog::error(const char* tag, int context_id, const char* fmt, ...)
|
|||
va_end(ap);
|
||||
|
||||
// add strerror() to error msg.
|
||||
if (errno != 0) {
|
||||
// Check size to avoid security issue https://github.com/ossrs/srs/issues/1229
|
||||
if (errno != 0 && size < LOG_MAX_SIZE) {
|
||||
size += snprintf(log_data + size, LOG_MAX_SIZE - size, "(%s)", strerror(errno));
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// The version config.
|
||||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 67
|
||||
#define VERSION_REVISION 71
|
||||
|
||||
// The macros generated by configure script.
|
||||
#include <srs_auto_headers.hpp>
|
||||
|
|
|
@ -95,6 +95,8 @@ private:
|
|||
int nb_bytes;
|
||||
public:
|
||||
SrsBuffer();
|
||||
// Initialize buffer with data b and size nb_b.
|
||||
// @remark User must free the data b.
|
||||
SrsBuffer(char* b, int nb_b);
|
||||
virtual ~SrsBuffer();
|
||||
// get the status of stream
|
||||
|
|
|
@ -177,7 +177,8 @@
|
|||
#define ERROR_HTTP_HIJACK 2052
|
||||
#define ERROR_RTMP_MESSAGE_CREATE 2053
|
||||
#define ERROR_RTMP_PROXY_EXCEED 2054
|
||||
//
|
||||
#define ERROR_RTMP_CREATE_STREAM_DEPTH 2055
|
||||
//
|
||||
// The system control message,
|
||||
// It's not an error, but special control logic.
|
||||
//
|
||||
|
|
|
@ -37,6 +37,7 @@ class SrsBuffer;
|
|||
class ISrsWriter;
|
||||
class ISrsReader;
|
||||
class SrsFileReader;
|
||||
class SrsPacket;
|
||||
|
||||
#define SRS_FLV_TAG_HEADER_SIZE 11
|
||||
#define SRS_FLV_PREVIOUS_TAG_SIZE 4
|
||||
|
@ -231,8 +232,9 @@ public:
|
|||
|
||||
// The message header for shared ptr message.
|
||||
// only the message for all msgs are same.
|
||||
struct SrsSharedMessageHeader
|
||||
class SrsSharedMessageHeader
|
||||
{
|
||||
public:
|
||||
// 3bytes.
|
||||
// Three-byte field that represents the size of the payload in bytes.
|
||||
// It is set in big-endian format.
|
||||
|
@ -245,7 +247,7 @@ struct SrsSharedMessageHeader
|
|||
// set at decoding, and canbe used for directly send message,
|
||||
// For example, dispatch to all connections.
|
||||
int perfer_cid;
|
||||
|
||||
public:
|
||||
SrsSharedMessageHeader();
|
||||
virtual ~SrsSharedMessageHeader();
|
||||
};
|
||||
|
@ -309,6 +311,7 @@ public:
|
|||
// copy header, manage the payload of msg,
|
||||
// set the payload to NULL to prevent double free.
|
||||
// @remark payload of msg set to NULL if success.
|
||||
// @remark User should free the msg.
|
||||
virtual srs_error_t create(SrsCommonMessage* msg);
|
||||
// Create shared ptr message,
|
||||
// from the header and payload.
|
||||
|
|
|
@ -64,9 +64,9 @@ void SrsSimpleStream::erase(int size)
|
|||
|
||||
void SrsSimpleStream::append(const char* bytes, int size)
|
||||
{
|
||||
srs_assert(size > 0);
|
||||
|
||||
data.insert(data.end(), bytes, bytes + size);
|
||||
if (size > 0) {
|
||||
data.insert(data.end(), bytes, bytes + size);
|
||||
}
|
||||
}
|
||||
|
||||
void SrsSimpleStream::append(SrsSimpleStream* src)
|
||||
|
|
|
@ -200,9 +200,9 @@ string srs_generate_stream_with_query(string host, string vhost, string stream,
|
|||
|
||||
// Remove the start & when param is empty.
|
||||
srs_string_trim_start(query, "&");
|
||||
|
||||
|
||||
// Prefix query with ?.
|
||||
if (!srs_string_starts_with(query, "?")) {
|
||||
if (!query.empty() && !srs_string_starts_with(query, "?")) {
|
||||
url += "?";
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace _srs_internal
|
|||
0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
|
||||
0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
|
||||
}; // 62
|
||||
|
||||
|
||||
srs_error_t do_openssl_HMACsha256(HMAC_CTX* ctx, const void* data, int data_size, void* digest, unsigned int* digest_size)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -152,6 +152,7 @@ namespace _srs_internal
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* sha256 digest algorithm.
|
||||
* @param key the sha256 key, NULL to use EVP_Digest, for instance,
|
||||
|
@ -201,24 +202,24 @@ namespace _srs_internal
|
|||
return err;
|
||||
}
|
||||
|
||||
#define RFC2409_PRIME_1024 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
|
||||
#define RFC2409_PRIME_1024 \
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
|
||||
SrsDH::SrsDH()
|
||||
{
|
||||
pdh = NULL;
|
||||
}
|
||||
|
||||
|
||||
SrsDH::~SrsDH()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void SrsDH::close()
|
||||
{
|
||||
if (pdh != NULL) {
|
||||
|
|
|
@ -137,6 +137,36 @@ SrsPacket::~SrsPacket()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsPacket::to_msg(SrsCommonMessage* msg, int stream_id)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int size = 0;
|
||||
char* payload = NULL;
|
||||
if ((err = encode(size, payload)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode packet");
|
||||
}
|
||||
|
||||
// encode packet to payload and size.
|
||||
if (size <= 0 || payload == NULL) {
|
||||
srs_warn("packet is empty, ignore empty message.");
|
||||
return err;
|
||||
}
|
||||
|
||||
// to message
|
||||
SrsMessageHeader header;
|
||||
header.payload_length = size;
|
||||
header.message_type = get_message_type();
|
||||
header.stream_id = stream_id;
|
||||
header.perfer_cid = get_prefer_cid();
|
||||
|
||||
if ((err = msg->create(&header, payload, size)) != srs_success) {
|
||||
return srs_error_wrap(err, "create %dB message", size);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsPacket::encode(int& psize, char*& ppayload)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -570,70 +600,26 @@ srs_error_t SrsProtocol::do_send_and_free_packet(SrsPacket* packet, int stream_i
|
|||
|
||||
srs_assert(packet);
|
||||
SrsAutoFree(SrsPacket, packet);
|
||||
|
||||
int size = 0;
|
||||
char* payload = NULL;
|
||||
if ((err = packet->encode(size, payload)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode packet");
|
||||
}
|
||||
|
||||
// encode packet to payload and size.
|
||||
if (size <= 0 || payload == NULL) {
|
||||
srs_warn("packet is empty, ignore empty message.");
|
||||
return err;
|
||||
}
|
||||
|
||||
// to message
|
||||
SrsMessageHeader header;
|
||||
header.payload_length = size;
|
||||
header.message_type = packet->get_message_type();
|
||||
header.stream_id = stream_id;
|
||||
header.perfer_cid = packet->get_prefer_cid();
|
||||
|
||||
err = do_simple_send(&header, payload, size);
|
||||
srs_freepa(payload);
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "simple send");
|
||||
}
|
||||
|
||||
if ((err = on_send_packet(&header, packet)) != srs_success) {
|
||||
return srs_error_wrap(err, "on send packet");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsProtocol::do_simple_send(SrsMessageHeader* mh, char* payload, int size)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
SrsCommonMessage* msg = new SrsCommonMessage();
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
|
||||
if ((err = packet->to_msg(msg, stream_id)) != srs_success) {
|
||||
return srs_error_wrap(err, "to message");
|
||||
}
|
||||
|
||||
SrsSharedPtrMessage* shared_msg = new SrsSharedPtrMessage();
|
||||
if ((err = shared_msg->create(msg)) != srs_success) {
|
||||
srs_freep(shared_msg);
|
||||
return srs_error_wrap(err, "create message");
|
||||
}
|
||||
|
||||
if ((err = send_and_free_message(shared_msg, stream_id)) != srs_success) {
|
||||
return srs_error_wrap(err, "send packet");
|
||||
}
|
||||
|
||||
// we directly send out the packet,
|
||||
// use very simple algorithm, not very fast,
|
||||
// but it's ok.
|
||||
char* p = payload;
|
||||
char* end = p + size;
|
||||
char c0c3[SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE];
|
||||
while (p < end) {
|
||||
int nbh = 0;
|
||||
if (p == payload) {
|
||||
nbh = srs_chunk_header_c0(mh->perfer_cid, (uint32_t)mh->timestamp, mh->payload_length, mh->message_type, mh->stream_id, c0c3, sizeof(c0c3));
|
||||
} else {
|
||||
nbh = srs_chunk_header_c3(mh->perfer_cid, (uint32_t)mh->timestamp, c0c3, sizeof(c0c3));
|
||||
}
|
||||
srs_assert(nbh > 0);;
|
||||
|
||||
iovec iovs[2];
|
||||
iovs[0].iov_base = c0c3;
|
||||
iovs[0].iov_len = nbh;
|
||||
|
||||
int payload_size = srs_min((int)(end - p), out_chunk_size);
|
||||
iovs[1].iov_base = p;
|
||||
iovs[1].iov_len = payload_size;
|
||||
p += payload_size;
|
||||
|
||||
if ((err = skt->writev(iovs, 2, NULL)) != srs_success) {
|
||||
return srs_error_wrap(err, "writev packet");
|
||||
}
|
||||
if ((err = on_send_packet(&msg->header, packet)) != srs_success) {
|
||||
return srs_error_wrap(err, "on send packet");
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -788,6 +774,9 @@ srs_error_t SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsBuffer*
|
|||
} else if (header.is_window_ackledgement_size()) {
|
||||
*ppacket = packet = new SrsSetWindowAckSizePacket();
|
||||
return packet->decode(stream);
|
||||
} else if (header.is_ackledgement()) {
|
||||
*ppacket = packet = new SrsAcknowledgementPacket();
|
||||
return packet->decode(stream);
|
||||
} else if (header.is_set_chunk_size()) {
|
||||
*ppacket = packet = new SrsSetChunkSizePacket();
|
||||
return packet->decode(stream);
|
||||
|
@ -1671,7 +1660,7 @@ void SrsHandshakeBytes::dispose()
|
|||
srs_freepa(c2);
|
||||
}
|
||||
|
||||
srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReadWriter* io)
|
||||
srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReader* io)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -1709,7 +1698,7 @@ srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReadWriter* io)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReadWriter* io)
|
||||
srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReader* io)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -1727,7 +1716,7 @@ srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReadWriter* io)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHandshakeBytes::read_c2(ISrsProtocolReadWriter* io)
|
||||
srs_error_t SrsHandshakeBytes::read_c2(ISrsProtocolReader* io)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -2538,7 +2527,7 @@ srs_error_t SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type,
|
|||
SrsAutoFree(SrsPacket, pkt);
|
||||
|
||||
if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
|
||||
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
|
||||
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, 3, type, stream_name, duration);
|
||||
}
|
||||
if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
|
||||
return identify_fmle_publish_client(dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
|
||||
|
@ -2546,6 +2535,7 @@ srs_error_t SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type,
|
|||
if (dynamic_cast<SrsPlayPacket*>(pkt)) {
|
||||
return identify_play_client(dynamic_cast<SrsPlayPacket*>(pkt), type, stream_name, duration);
|
||||
}
|
||||
|
||||
// call msg,
|
||||
// support response null first,
|
||||
// @see https://github.com/ossrs/srs/issues/106
|
||||
|
@ -2698,7 +2688,7 @@ srs_error_t SrsRtmpServer::on_play_client_pause(int stream_id, bool is_pause)
|
|||
return srs_error_wrap(err, "send NetStream.Unpause.Notify");
|
||||
}
|
||||
}
|
||||
// StreanBegin
|
||||
// StreamBegin
|
||||
if (true) {
|
||||
SrsUserControlPacket* pkt = new SrsUserControlPacket();
|
||||
|
||||
|
@ -2909,9 +2899,13 @@ srs_error_t SrsRtmpServer::start_flash_publish(int stream_id)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, string& stream_name, srs_utime_t& duration)
|
||||
srs_error_t SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, int depth, SrsRtmpConnType& type, string& stream_name, srs_utime_t& duration)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (depth <= 0) {
|
||||
return srs_error_new(ERROR_RTMP_CREATE_STREAM_DEPTH, "create stream recursive depth");
|
||||
}
|
||||
|
||||
if (true) {
|
||||
SrsCreateStreamResPacket* pkt = new SrsCreateStreamResPacket(req->transaction_id, stream_id);
|
||||
|
@ -2952,7 +2946,7 @@ srs_error_t SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket*
|
|||
return identify_flash_publish_client(dynamic_cast<SrsPublishPacket*>(pkt), type, stream_name);
|
||||
}
|
||||
if (dynamic_cast<SrsCreateStreamPacket*>(pkt)) {
|
||||
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, type, stream_name, duration);
|
||||
return identify_create_stream_client(dynamic_cast<SrsCreateStreamPacket*>(pkt), stream_id, depth-1, type, stream_name, duration);
|
||||
}
|
||||
if (dynamic_cast<SrsFMLEStartPacket*>(pkt)) {
|
||||
return identify_haivision_publish_client(dynamic_cast<SrsFMLEStartPacket*>(pkt), type, stream_name);
|
||||
|
|
|
@ -49,6 +49,7 @@ class SrsChunkStream;
|
|||
class SrsSharedPtrMessage;
|
||||
|
||||
class SrsProtocol;
|
||||
class ISrsProtocolReader;
|
||||
class ISrsProtocolReadWriter;
|
||||
class SrsCreateStreamPacket;
|
||||
class SrsFMLEStartPacket;
|
||||
|
@ -114,6 +115,9 @@ class SrsPacket
|
|||
public:
|
||||
SrsPacket();
|
||||
virtual ~SrsPacket();
|
||||
public:
|
||||
// Covert packet to common message.
|
||||
virtual srs_error_t to_msg(SrsCommonMessage* msg, int stream_id);
|
||||
public:
|
||||
// The subpacket can override this encode,
|
||||
// For example, video and audio will directly set the payload withou memory copy,
|
||||
|
@ -355,9 +359,6 @@ private:
|
|||
virtual srs_error_t do_iovs_send(iovec* iovs, int size);
|
||||
// The underlayer api for send and free packet.
|
||||
virtual srs_error_t do_send_and_free_packet(SrsPacket* packet, int stream_id);
|
||||
// Use simple algorithm to send the header and bytes.
|
||||
// @remark, for do_send_and_free_packet to send.
|
||||
virtual srs_error_t do_simple_send(SrsMessageHeader* mh, char* payload, int size);
|
||||
// The imp for decode_message
|
||||
virtual srs_error_t do_decode_message(SrsMessageHeader& header, SrsBuffer* stream, SrsPacket** ppacket);
|
||||
// Recv bytes oriented RTMP message from protocol stack.
|
||||
|
@ -514,9 +515,9 @@ public:
|
|||
public:
|
||||
virtual void dispose();
|
||||
public:
|
||||
virtual srs_error_t read_c0c1(ISrsProtocolReadWriter* io);
|
||||
virtual srs_error_t read_s0s1s2(ISrsProtocolReadWriter* io);
|
||||
virtual srs_error_t read_c2(ISrsProtocolReadWriter* io);
|
||||
virtual srs_error_t read_c0c1(ISrsProtocolReader* io);
|
||||
virtual srs_error_t read_s0s1s2(ISrsProtocolReader* io);
|
||||
virtual srs_error_t read_c2(ISrsProtocolReader* io);
|
||||
virtual srs_error_t create_c0c1();
|
||||
virtual srs_error_t create_s0s1s2(const char* c1 = NULL);
|
||||
virtual srs_error_t create_c2();
|
||||
|
@ -774,7 +775,7 @@ public:
|
|||
return protocol->expect_message<T>(pmsg, ppacket);
|
||||
}
|
||||
private:
|
||||
virtual srs_error_t identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, srs_utime_t& duration);
|
||||
virtual srs_error_t identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, int depth, SrsRtmpConnType& type, std::string& stream_name, srs_utime_t& duration);
|
||||
virtual srs_error_t identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
|
||||
virtual srs_error_t identify_haivision_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name);
|
||||
virtual srs_error_t identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name);
|
||||
|
|
|
@ -255,6 +255,12 @@ bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char
|
|||
level, getpid(), cid);
|
||||
}
|
||||
}
|
||||
|
||||
// Exceed the size, ignore this log.
|
||||
// Check size to avoid security issue https://github.com/ossrs/srs/issues/1229
|
||||
if (written >= size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (written == -1) {
|
||||
return false;
|
||||
|
|
|
@ -52,6 +52,15 @@ extern srs_utime_t _srs_tmp_timeout;
|
|||
#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err)
|
||||
#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err)
|
||||
|
||||
// For errors, assert.
|
||||
// @remark The err is leak when error, but it's ok in utest.
|
||||
#define HELPER_ASSERT_SUCCESS(x) ASSERT_TRUE(srs_success == (err = x)); srs_freep(err)
|
||||
#define HELPER_ASSERT_FAILED(x) ASSERT_TRUE(srs_success != (err = x)); srs_freep(err)
|
||||
|
||||
// For init array data.
|
||||
#define HELPER_ARRAY_INIT(buf, sz, val) \
|
||||
for (int i = 0; i < (int)sz; i++) (buf)[i]=val
|
||||
|
||||
// the asserts of gtest:
|
||||
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
|
||||
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
|
||||
|
|
|
@ -64,3 +64,30 @@ VOID TEST(CoreMacroseTest, Check)
|
|||
#endif
|
||||
}
|
||||
|
||||
VOID TEST(CoreLogger, CheckVsnprintf)
|
||||
{
|
||||
if (true) {
|
||||
char buf[1024];
|
||||
HELPER_ARRAY_INIT(buf, sizeof(buf), 0xf);
|
||||
|
||||
// Return the number of characters printed.
|
||||
EXPECT_EQ(6, sprintf(buf, "%s", "Hello!"));
|
||||
EXPECT_EQ('H', buf[0]);
|
||||
EXPECT_EQ('!', buf[5]);
|
||||
EXPECT_EQ(0x0, buf[6]);
|
||||
EXPECT_EQ(0xf, buf[7]);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
char buf[1024];
|
||||
HELPER_ARRAY_INIT(buf, sizeof(buf), 0xf);
|
||||
|
||||
// Return the number of characters that would have been printed if the size were unlimited.
|
||||
EXPECT_EQ(6, snprintf(buf, 3, "%s", "Hello!"));
|
||||
EXPECT_EQ('H', buf[0]);
|
||||
EXPECT_EQ('e', buf[1]);
|
||||
EXPECT_EQ(0, buf[2]);
|
||||
EXPECT_EQ(0xf, buf[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -87,7 +87,15 @@ public:
|
|||
MockBufferIO();
|
||||
virtual ~MockBufferIO();
|
||||
public:
|
||||
virtual int length();
|
||||
virtual MockBufferIO* append(std::string data);
|
||||
virtual MockBufferIO* append(MockBufferIO* data);
|
||||
virtual MockBufferIO* append(uint8_t* data, int size);
|
||||
public:
|
||||
virtual int out_length();
|
||||
virtual MockBufferIO* out_append(std::string data);
|
||||
virtual MockBufferIO* out_append(MockBufferIO* data);
|
||||
virtual MockBufferIO* out_append(uint8_t* data, int size);
|
||||
// for handshake.
|
||||
public:
|
||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue