1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

solve merge confict

This commit is contained in:
runner365 2020-02-12 10:19:30 +08:00
commit 6f4c124f58
78 changed files with 794 additions and 67361 deletions

View file

@ -153,10 +153,26 @@ For previous versions, please read:
## V4 changes
* v4.0, 2020-02-04, Update project code. 4.0.3
* v4.0, 2020-01-26, Allow use libsrt.so for SRT is MPL license. 4.0.2
* v4.0, 2020-01-24, Fix [#1147][bug #1147], support SRT(Secure Reliable Transport). 4.0.1
## V3 changes
* v3.0, 2020-02-05, For [#665][bug #665], fix HTTP-FLV reloading bug. 3.0.116
* v3.0, 2020-02-05, For [#1592][bug #1592], fix terminal echo off by redirect process stdin. 3.0.115
* v3.0, 2020-02-04, For [#1186][bug #1186], refactor security check. 3.0.114
* v3.0, 2020-02-04, Fix [#939][bug #939], response right A/V flag in FLV header. 3.0.113
* v3.0, 2020-02-04, For [#939][bug #939], always enable fast FLV streaming.
* <strong>v3.0, 2020-02-02, [3.0 beta0(3.0.112)][r3.0b0] released. 121709 lines.</strong>
* v3.0, 2020-01-29, Support isolate version file. 3.0.112
* v3.0, 2020-01-29, Fix [#1206][bug #1206], dispose ingester while server quiting. 3.0.111
* v3.0, 2020-01-28, Fix [#1230][bug #1230], racing condition in source fetch or create. 3.0.110
* v3.0, 2020-01-27, Fix [#1303][bug #1303], do not dispatch previous meta when not publishing. 3.0.109
* v3.0, 2020-01-26, Allow use libst.so for ST is MPL license.
* v3.0, 2020-01-26, Fix [#607][bug #607], set RTMP identifying recursive depth to 3.
* v3.0, 2020-01-25, Fix [#878][bug #878], remove deprecated #EXT-X-ALLOW-CACHE for HLS. 3.0.108
* v3.0, 2020-01-25, Fix [#703][bug #703], drop video data util sps/pps. 3.0.107
* v3.0, 2020-01-25, Fix [#1108][bug #1108], reap DVR tmp file when unpublish. 3.0.106
* <strong>v3.0, 2020-01-21, [3.0 alpha9(3.0.105)][r3.0a9] released. 121577 lines.</strong>
* v3.0, 2020-01-21, Fix [#1221][bug #1221], remove complex configure options. 3.0.104
@ -734,6 +750,7 @@ For previous versions, please read:
## Releases
* 2020-02-02, [Release v3.0-b0][r3.0b0], 3.0 beta0, 3.0.112, 121709 lines.
* 2020-01-21, [Release v3.0-a9][r3.0a9], 3.0 alpha9, 3.0.105, 121577 lines.
* 2020-01-10, [Release v3.0-a8][r3.0a8], 3.0 alpha8, 3.0.97, 121555 lines.
* 2019-12-29, [Release v3.0-a7][r3.0a7], 3.0 alpha7, 3.0.90, 116356 lines.
@ -784,7 +801,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="stream-delivery"></a>
**Stream Delivery**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| RTMP | Stable | Stable | Stable | Stable | Stable |
| HLS | Stable | Stable | X | Stable | Stable |
@ -792,12 +809,13 @@ Comparing with other media servers, SRS is much better and stronger, for details
| HLS(aonly) | Stable | X | X | Stable | Stable |
| HDS | Experiment| X | X | Stable | Stable |
| MPEG-DASH | Experiment| X | X | X | X |
| SRT | Experiment| X | X | X | Stable |
| HTTP Server | Stable | Stable | X | X | Stable |
<a name="cluster"></a>
**Cluster**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| RTMP Edge | Stable | X | X | Stable | X |
| RTMP Backup | Stable | X | X | X | X |
@ -810,7 +828,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="stream-service"></a>
**Stream Service**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| DVR | Stable | Stable | X | X | Stable |
| DVR API | Stable | Stable | X | X | X |
@ -827,7 +845,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="efficiency"></a>
**Efficiency**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| Concurrency | 7.5k | 3k | 2k | 2k | 3k |
|MultipleProcess| Experiment| Stable | X | X | X |
@ -837,7 +855,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="stream-caster"></a>
**Stream Caster**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| Ingest | Stable | X | X | X | X |
| Push MPEGTS | Experiment| X | X | X | Stable |
@ -847,7 +865,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="debug-system"></a>
**Debug System**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| BW check | Stable | X | X | X | X |
| Tracable Log | Stable | X | X | X | X |
@ -855,7 +873,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="docs"></a>
**Docs**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| Demos | Stable | X | X | X | X |
| WIKI(EN+CN) | Stable | EN only | X | X | Stable |
@ -863,7 +881,7 @@ Comparing with other media servers, SRS is much better and stronger, for details
<a name="others"></a>
**Others**
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
| ----------- | ------- | ----- | --------- | -------- | ------ |
| ARM/MIPS | Stable | Stable | X | X | X |
| Client Library| Stable | X | X | X | X |
@ -1119,6 +1137,15 @@ Gitlab: [https://gitlab.com/winlinvip/srs-gitlab][gitlab], the GIT usage([CN][v1
git clone https://gitlab.com/winlinvip/srs-gitlab.git
```
| Branch | Cost | Size | CMD |
| --- | --- | --- | --- |
| 3.0release | 2m19.931s | 262MB | git clone -b 3.0release https://gitee.com/winlinvip/srs.oschina.git |
| 3.0release | 0m56.515s | 95MB | git clone -b 3.0release --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
| develop | 2m22.430s | 234MB | git clone -b develop https://gitee.com/winlinvip/srs.oschina.git |
| develop | 0m46.421s | 42MB | git clone -b develop --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
| min | 2m22.865s | 217MB | git clone -b min https://gitee.com/winlinvip/srs.oschina.git |
| min | 0m36.472s | 11MB | git clone -b min --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
## System Requirements
Supported operating systems and hardware:
@ -1631,10 +1658,21 @@ Winlin
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #1108]: https://github.com/ossrs/srs/issues/1108
[bug #703]: https://github.com/ossrs/srs/issues/703
[bug #878]: https://github.com/ossrs/srs/issues/878
[bug #607]: https://github.com/ossrs/srs/issues/607
[bug #1303]: https://github.com/ossrs/srs/issues/1303
[bug #1230]: https://github.com/ossrs/srs/issues/1230
[bug #1206]: https://github.com/ossrs/srs/issues/1206
[bug #939]: https://github.com/ossrs/srs/issues/939
[bug #1186]: https://github.com/ossrs/srs/issues/1186
[bug #1592]: https://github.com/ossrs/srs/issues/1592
[bug #665]: https://github.com/ossrs/srs/issues/665
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
[exo #828]: https://github.com/google/ExoPlayer/pull/828
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7

View file

@ -329,7 +329,7 @@ fi
# Affected users should upgrade to OpenSSL 1.1.0e. Users unable to immediately
# upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS.
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL != YES ]]; then
OPENSSL_HOTFIX="-DOPENSSL_NO_HEARTBEATS"
OPENSSL_OPTIONS="-no-shared -no-threads -no-asm -DOPENSSL_NO_HEARTBEATS"
OPENSSL_CONFIG="./config"
# https://stackoverflow.com/questions/15539062/cross-compiling-of-openssl-for-linux-arm-v5te-linux-gnueabi-toolchain
if [[ $SRS_CROSS_BUILD == YES ]]; then
@ -351,7 +351,7 @@ if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL != YES ]]; then
(
rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} &&
unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e &&
${OPENSSL_CONFIG} --prefix=`pwd`/_release -no-shared -no-threads -no-asm $OPENSSL_HOTFIX &&
${OPENSSL_CONFIG} --prefix=`pwd`/_release $OPENSSL_OPTIONS &&
make CC=${SRS_TOOL_CC} AR="${SRS_TOOL_AR} -rs" LD=${SRS_TOOL_LD} RANDLIB=${SRS_TOOL_RANDLIB} && make install_sw &&
cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl
)

View file

@ -48,6 +48,10 @@ SRS_FFMPEG_STUB=NO
SRS_PREFIX=/usr/local/srs
SRS_JOBS=1
SRS_STATIC=NO
# If enabled, link shared libraries for libst.so which uses MPL license.
SRS_SHARED_ST=NO
# If enabled, link shared libraries for libsrt.so which uses MPL license.
SRS_SHARED_SRT=NO
# whether enable the gcov
SRS_GCOV=NO
# whether enable the log verbose/info/trace level.
@ -183,6 +187,8 @@ Conflicts:
Experts:
--use-sys-ssl Do not compile ssl, use system ssl(-lssl) if required.
--use-shared-st Use link shared libraries for ST which uses MPL license.
--use-shared-srt Use link shared libraries for SRT which uses MPL license.
--export-librtmp-project=<path> Export srs-librtmp to specified project in path.
--export-librtmp-single=<path> Export srs-librtmp to a single file(.h+.cpp) in path.
@ -272,6 +278,9 @@ function parse_user_option() {
--full) SRS_ENABLE_ALL=YES ;;
--use-sys-ssl) SRS_USE_SYS_SSL=YES ;;
--use-shared-st) SRS_SHARED_ST=YES ;;
--use-shared-srt) SRS_SHARED_SRT=YES ;;
--memory-watch) SRS_MEM_WATCH=YES ;;
--export-librtmp-project) SRS_EXPORT_LIBRTMP_PROJECT=${value} ;;
--export-librtmp-single) SRS_EXPORT_LIBRTMP_SINGLE=${value} ;;
@ -535,6 +544,8 @@ function regenerate_options() {
if [ $SRS_GPERF_CP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gcp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gcp"; fi
if [ $SRS_GPROF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gprof"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gprof"; fi
if [ $SRS_STATIC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --static"; fi
if [ $SRS_SHARED_ST = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --use-shared-st"; fi
if [ $SRS_SHARED_SRT = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --use-shared-srt"; fi
if [ $SRS_LOG_VERBOSE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-verbose"; fi
if [ $SRS_LOG_INFO = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-info"; fi
if [ $SRS_LOG_TRACE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-trace"; fi

View file

@ -167,7 +167,11 @@ echo "" >> ${FILE}
echo "# link all depends libraries" >> ${FILE}
echo -n "DEPS_LIBRARIES_FILES = " >> ${FILE}
for item in ${ModuleLibFiles[*]}; do
echo -n "${SRS_TRUNK_PREFIX}/${item} " >> ${FILE}
if [[ -f ${item} ]]; then
echo -n "${SRS_TRUNK_PREFIX}/${item} " >> ${FILE}
else
echo -n "${item} " >> ${FILE}
fi
done
echo "" >> ${FILE}; echo "" >> ${FILE}
#

View file

@ -19,11 +19,16 @@ pid ./objs/srs.pid;
# performance about 10%.
# default: 60000
chunk_size 60000;
# the logs dir.
# the log dir for FFMPEG.
# if enabled ffmpeg, each transcoding stream will create a log file.
# /dev/null to disable the log.
# default: ./objs
ff_log_dir ./objs;
# the log level for FFMPEG.
# info warning error fatal panic quiet
# trace debug verbose
# default: info
ff_log_level info;
# the log tank, console or file.
# if console, print log to console.
# if file, write log to file. requires srs_log_file if log to file.
@ -196,7 +201,7 @@ stream_caster {
# the caster type of stream, the casters:
# mpegts_over_udp, MPEG-TS over UDP caster.
# rtsp, Real Time Streaming Protocol (RTSP).
# flv, FLV over HTTP POST.
# flv, FLV over HTTP by POST.
caster mpegts_over_udp;
# the output rtmp url.
# for mpegts_over_udp caster, the typically output url:

4
trunk/configure vendored
View file

@ -147,6 +147,7 @@ END
#
# st(state-threads) the basic network library for SRS.
LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a"
if [[ $SRS_SHARED_ST == YES ]]; then LibSTfile="-lst"; fi
# openssl-1.1.0e, for the RTMP complex handshake.
LibSSLRoot="";LibSSLfile=""
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == NO ]]; then
@ -163,6 +164,7 @@ fi
# srt code path
if [[ $SRS_SRT == YES ]]; then
LibSRTRoot="${SRS_WORKDIR}/src/srt"; LibSRTfile="${SRS_OBJS_DIR}/srt/lib/libsrt.a"
if [[ $SRS_SHARED_SRT == YES ]]; then LibSRTfile="-lsrt"; fi
fi
# the link options, always use static link
SrsLinkOptions="-ldl";
@ -189,7 +191,7 @@ fi
MODULE_ID="CORE"
MODULE_DEPENDS=()
ModuleLibIncs=(${SRS_OBJS_DIR})
MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance"
MODULE_FILES=("srs_core" "srs_core_version4" "srs_core_autofree" "srs_core_performance"
"srs_core_mem_watch" "srs_core_time")
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh
CORE_OBJS="${MODULE_OBJS[@]}"

File diff suppressed because one or more lines are too long

65
trunk/doc/README.md Normal file
View file

@ -0,0 +1,65 @@
# Doc
## Live Streaming
1. [amf0_spec_121207.pdf](http://github.com/ossrs/srs/wiki/doc/amf0_spec_121207.pdf), adobe amf0标准
1. [amf3_spec_121207.pdf](http://github.com/ossrs/srs/wiki/doc/amf3_spec_121207.pdf), adobe amf3标准。
1. [hls-m3u8-draft-pantos-http-live-streaming-12.txt](http://github.com/ossrs/srs/wiki/doc/hls-m3u8-draft-pantos-http-live-streaming-12.txt), [hls-m3u8-draft-pantos-http-live-streaming-12.pdf](http://github.com/ossrs/srs/wiki/doc/hls-m3u8-draft-pantos-http-live-streaming-12.pdf), m3u8标准。
1. [hls-mpeg-ts-iso13818-1.pdf](http://github.com/ossrs/srs/wiki/doc/hls-mpeg-ts-iso13818-1.pdf), ts标准。
1. [hls-mpeg-ts-VB_WhitePaper_TransportStreamVSProgramStream_rd2.pdf](http://github.com/ossrs/srs/wiki/doc/hls-mpeg-ts-VB_WhitePaper_TransportStreamVSProgramStream_rd2.pdf), ts的介绍。
1. [rtmp.part1.Chunk-Stream.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part1.Chunk-Stream.pdf), [rtmp.part2.Message-Formats.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part2.Message-Formats.pdf), [rtmp.part3.Commands-Messages.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part3.Commands-Messages.pdf), [rtmp_specification_1.0.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp_specification_1.0.pdf), adobe rtmp标准。
1. [flv_v10_1.pdf](http://github.com/ossrs/srs/wiki/doc/flv_v10_1.pdf), adobe flv。
1. [video_file_format_spec_v10_1.pdf](http://github.com/ossrs/srs/wiki/doc/video_file_format_spec_v10_1.pdf) flv/f4v.
## Codec
1. [mp3.id3v2.3.0.pdf](http://github.com/ossrs/srs/wiki/doc/mp3.id3v2.3.0.pdf), http://id3.org/id3v2.3.0
1. [aac-iso-13818-7.pdf, ISO_IEC_13818-7-AAC-2004.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_13818-7-AAC-2004.pdf), aac标准aac的编码等。
1. [aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, ISO_IEC_14496-3-AAC-2001.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-3-AAC-2001.pdf), aac的封装标准即ts/flv里面的aac raw data标准。
1. [ISO_IEC_14496-1-System-2010.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-1-System-2010.pdf) mp4 base box.
1. [H.264-AVC-ISO_IEC_14496-10.pdf, ISO_IEC_14496-10-AVC-2003.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-10-AVC-2003.pdf), avc标准编码部分。
1. [H.264-AVC-ISO_IEC_14496-12_2012-mp4.pdf, ISO_IEC_14496-12-base-format-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-12-base-format-2012.pdf), mp4标准。
1. [ISO_14496-14_2003_mp4-file-format.pdf, ISO_IEC_14496-14-MP4-2003.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-14-MP4-2003.pdf), mp4文件格式。
1. [H.264-AVC-ISO_IEC_14496-10-2012.pdf, ISO_IEC_14496-10-AVC-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-10-AVC-2012.pdf), avc标准编码部分。上面的标准是2003年的和下面的15是2010年的对不上。http://www.itu.int/ITU-T/recommendations/rec.aspx?rec=11466
1. [H.264-AVC-ISO_IEC_14496-15.pdf, ISO_IEC_14496-15-AVC-format-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-15-AVC-format-2012.pdf), avc标准封装部分。
1. [H.264_MPEG-4-Part-10-White-Paper.pdf](http://github.com/ossrs/srs/wiki/doc/H.264_MPEG-4-Part-10-White-Paper.pdf), h264简介。
## HTTP
1. [http1.0-rfc1945.txt, rfc1945-1996-http1.0.txt](http://github.com/ossrs/srs/wiki/doc/rfc1945-1996-http1.0.txt), http://www.rfc-editor.org/rfc/rfc1945.txt
1. [http1.1-rfc2616.txt, rfc2616-1999-http1.1.txt](http://github.com/ossrs/srs/wiki/doc/rfc2616-1999-http1.1.txt), http://www.rfc-editor.org/rfc/rfc2616.txt
1. [arpa-internet-text-messages-rfc822.txt, rfc822-1982-arpa-internet-text-messages.txt](http://github.com/ossrs/srs/wiki/doc/rfc822-1982-arpa-internet-text-messages.txt), http://www.rfc-editor.org/rfc/rfc822.txt
## RTC
1. [STUN, rfc5389-2008-stun.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5389-2008-stun.pdf): https://tools.ietf.org/html/rfc5389
1. [TURN, rfc5766-2010-turn.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5766-2010-turn.pdf): https://tools.ietf.org/html/rfc5766
1. [ICE, rfc5245-2010-ice.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5245-2010-ice.pdf): https://tools.ietf.org/html/rfc5245
1. [SIP, rfc3261-2002-sip.pdf](http://github.com/ossrs/srs/wiki/doc/rfc3261-2002-sip.pdf): https://tools.ietf.org/html/rfc3261
## SRT
1. [Haivision_SRT_Open_Source_White_Paper.pdf](http://github.com/ossrs/srs/wiki/doc/Haivision_SRT_Open_Source_White_Paper.pdf)
1. [SRT_Alliance_Deployment_Guide.pdf](http://github.com/ossrs/srs/wiki/doc/SRT_Alliance_Deployment_Guide.pdf)
1. [SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf](http://github.com/ossrs/srs/wiki/doc/SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf)
## Others
1. [kafka-160915-0553-82964.pdf](http://github.com/ossrs/srs/wiki/doc/kafka-160915-0553-82964.pdf), https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol
1. [rtmfp-rfc7016.pdf, rfc7016-2013-rtmfp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc7016-2013-rtmfp.pdf), adobe RTMFP, http://tools.ietf.org/html/rfc7016.
1. [rtmfp-tsvarea-1.pdf](http://github.com/ossrs/srs/wiki/doc/rtmfp-tsvarea-1.pdf), http://www.ietf.org/proceedings/10mar/slides/tsvarea-1.pdf
1. [MPEG-DASH-ISO_IEC_23009-1_2012.pdf, ISO_IEC_23009-1-DASH-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_23009-1-DASH-2012.pdf), MPEG-DASH标准。
1. [rfc2326-1998-rtsp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc2326-1998-rtsp.pdf)
1. [rfc3550-2003-rtp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc3550-2003-rtp.pdf)
1. [adobe-hds-specification.pdf](http://github.com/ossrs/srs/wiki/doc/adobe-hds-specification.pdf)
1. [adobe-media-manifest-specification.pdf](http://github.com/ossrs/srs/wiki/doc/adobe-media-manifest-specification.pdf)
1. [HTTPDynamicStreamingSpecificationErrataMay2014.pdf](http://github.com/ossrs/srs/wiki/doc/HTTPDynamicStreamingSpecificationErrataMay2014.pdf)
1. [FlashMediaManifestFormatSpecificationErrataMay2014.pdf](http://github.com/ossrs/srs/wiki/doc/FlashMediaManifestFormatSpecificationErrataMay2014.pdf)
## Files
1. ffmpeg-logo.png, ffmpeg-min.png, ffmpeg的logo。
1. source.flv, source.200kbps.768x320.flv, avatar预告片400kbps。
Winlin

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

View file

@ -1,89 +1 @@
ffmpeg-logo.png
ffmpeg-min.png
ffmpeg的logo。
source.flv
avatar预告片400kbps。
aac-iso-13818-7.pdf
aac标准aac的编码等。
aac-mp4a-format-ISO_IEC_14496-3+2001.pdf
aac的封装标准即ts/flv里面的aac raw data标准。
amf0_spec_121207.pdf
adobe amf0标准
amf3_spec_121207.pdf
adobe amf3标准。
H.264-AVC-ISO_IEC_14496-10.pdf
avc标准编码部分。
H.264-AVC-ISO_IEC_14496-12_2012-mp4.pdf
mp4标准。
ISO_14496-14_2003_mp4-file-format.pdf
mp4文件格式。
MPEG-DASH-ISO_IEC_23009-1_2012.pdf
MPEG-DASH标准。
H.264-AVC-ISO_IEC_14496-10-2012.pdf
avc标准编码部分。
上面的标准是2003年的和下面的15是2010年的对不上。
http://www.itu.int/ITU-T/recommendations/rec.aspx?rec=11466
H.264-AVC-ISO_IEC_14496-15.pdf
avc标准封装部分。
H.264_MPEG-4-Part-10-White-Paper.pdf
h264简介。
hls-m3u8-draft-pantos-http-live-streaming-12.txt
m3u8标准。
hls-mpeg-ts-iso13818-1.pdf
ts标准。
hls-mpeg-ts-VB_WhitePaper_TransportStreamVSProgramStream_rd2.pdf
ts的介绍。
rtmp.part1.Chunk-Stream.pdf
rtmp.part2.Message-Formats.pdf
rtmp.part3.Commands-Messages.pdf
rtmp_specification_1.0.pdf
adobe rtmp标准。
rtmfp-rfc7016.pdf
adobe RTMFP, http://tools.ietf.org/html/rfc7016.
rtmfp-tsvarea-1.pdf
http://www.ietf.org/proceedings/10mar/slides/tsvarea-1.pdf
flv_v10_1.pdf
video_file_format_spec_v10_1.pdf
adobe f4v/flv标准。
HTTP协议
http1.0-rfc1945.txt
http://www.rfc-editor.org/rfc/rfc1945.txt
http1.1-rfc2616.txt
http://www.rfc-editor.org/rfc/rfc2616.txt
arpa-internet-text-messages-rfc822.txt
http://www.rfc-editor.org/rfc/rfc822.txt
mp3规范
mp3.id3v2.3.0.pdf
http://id3.org/id3v2.3.0
kafka协议:
kafka-160915-0553-82964.pdf
https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol
STUN: https://tools.ietf.org/html/rfc5389
TURN: https://tools.ietf.org/html/rfc5766
ICE: https://tools.ietf.org/html/rfc5245
SIP: https://tools.ietf.org/html/rfc3261
Winlin
Moved to https://github.com/ossrs/srs/blob/develop/trunk/doc/README.md

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

View file

@ -735,13 +735,28 @@ SrsConfDirective* SrsConfDirective::get_or_create(string n, string a0)
if (!conf) {
conf = new SrsConfDirective();
conf->name = n;
conf->set_arg0(a0);
conf->args.push_back(a0);
directives.push_back(conf);
}
return conf;
}
SrsConfDirective* SrsConfDirective::get_or_create(string n, string a0, string a1)
{
SrsConfDirective* conf = get(n, a0);
if (!conf) {
conf = new SrsConfDirective();
conf->name = n;
conf->args.push_back(a0);
conf->args.push_back(a1);
directives.push_back(conf);
}
return conf;
}
SrsConfDirective* SrsConfDirective::set_arg0(string a0)
{
if (arg0() == a0) {
@ -3473,6 +3488,7 @@ srs_error_t SrsConfig::check_normal_config()
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms"
&& n != "http_server" && n != "stream_caster" && n != "srt_server"
&& n != "utc_time" && n != "work_dir" && n != "asprocess"
&& n != "ff_log_level"
) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal directive %s", n.c_str());
}
@ -5760,13 +5776,13 @@ string SrsConfig::get_log_file()
return conf->arg0();
}
bool SrsConfig::get_ffmpeg_log_enabled()
bool SrsConfig::get_ff_log_enabled()
{
string log = get_ffmpeg_log_dir();
string log = get_ff_log_dir();
return log != SRS_CONSTS_NULL_FILE;
}
string SrsConfig::get_ffmpeg_log_dir()
string SrsConfig::get_ff_log_dir()
{
static string DEFAULT = "./objs";
@ -5778,6 +5794,18 @@ string SrsConfig::get_ffmpeg_log_dir()
return conf->arg0();
}
string SrsConfig::get_ff_log_level()
{
static string DEFAULT = "info";
SrsConfDirective* conf = root->get("ff_log_level");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return conf->arg0();
}
SrsConfDirective* SrsConfig::get_dash(string vhost)
{
SrsConfDirective* conf = get_vhost(vhost);

View file

@ -215,6 +215,7 @@ public:
public:
virtual SrsConfDirective* get_or_create(std::string n);
virtual SrsConfDirective* get_or_create(std::string n, std::string a0);
virtual SrsConfDirective* get_or_create(std::string n, std::string a0, std::string a1);
virtual SrsConfDirective* set_arg0(std::string a0);
// Remove the v from sub directives, user must free the v.
virtual void remove(SrsConfDirective* v);
@ -785,10 +786,12 @@ public:
// Get the log file path.
virtual std::string get_log_file();
// Whether ffmpeg log enabled
virtual bool get_ffmpeg_log_enabled();
virtual bool get_ff_log_enabled();
// The ffmpeg log dir.
// @remark, /dev/null to disable it.
virtual std::string get_ffmpeg_log_dir();
virtual std::string get_ff_log_dir();
// The ffmpeg log level.
virtual std::string get_ff_log_level();
// The MPEG-DASH section.
private:
virtual SrsConfDirective* get_dash(std::string vhost);

View file

@ -285,8 +285,8 @@ srs_error_t SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, Sr
std::string log_file = SRS_CONSTS_NULL_FILE; // disabled
// write ffmpeg info to log file.
if (_srs_config->get_ffmpeg_log_enabled()) {
log_file = _srs_config->get_ffmpeg_log_dir();
if (_srs_config->get_ff_log_enabled()) {
log_file = _srs_config->get_ff_log_dir();
log_file += "/";
log_file += "ffmpeg-encoder";
log_file += "-";

View file

@ -82,9 +82,9 @@ SrsFFMPEG::~SrsFFMPEG()
srs_freep(process);
}
void SrsFFMPEG::set_iparams(string iparams)
void SrsFFMPEG::append_iparam(string iparam)
{
_iparams = iparams;
iparams.push_back(iparam);
}
void SrsFFMPEG::set_oformat(string format)
@ -230,8 +230,11 @@ srs_error_t SrsFFMPEG::start()
params.push_back(ffmpeg);
// input params
if (!_iparams.empty()) {
params.push_back(_iparams);
for (int i = 0; i < iparams.size(); i++) {
string iparam = iparams.at(i);
if (!iparam.empty()) {
params.push_back(iparam);
}
}
// build the perfile
@ -418,6 +421,11 @@ void SrsFFMPEG::fast_stop()
process->fast_stop();
}
void SrsFFMPEG::fast_kill()
{
process->fast_kill();
}
#endif

View file

@ -45,7 +45,7 @@ private:
std::string log_file;
private:
std::string ffmpeg;
std::string _iparams;
std::vector<std::string> iparams;
std::vector<std::string> perfile;
std::string iformat;
std::string input;
@ -70,7 +70,7 @@ public:
SrsFFMPEG(std::string ffmpeg_bin);
virtual ~SrsFFMPEG();
public:
virtual void set_iparams(std::string iparams);
virtual void append_iparam(std::string iparam);
virtual void set_oformat(std::string format);
virtual std::string output();
public:
@ -83,6 +83,7 @@ public:
virtual void stop();
public:
virtual void fast_stop();
virtual void fast_kill();
};
#endif

View file

@ -751,11 +751,9 @@ srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
// #EXTM3U\n
// #EXT-X-VERSION:3\n
// #EXT-X-ALLOW-CACHE:YES\n
std::stringstream ss;
ss << "#EXTM3U" << SRS_CONSTS_LF
<< "#EXT-X-VERSION:3" << SRS_CONSTS_LF
<< "#EXT-X-ALLOW-CACHE:YES" << SRS_CONSTS_LF;
ss << "#EXTM3U" << SRS_CONSTS_LF;
ss << "#EXT-X-VERSION:3" << SRS_CONSTS_LF;
// #EXT-X-MEDIA-SEQUENCE:4294967295\n
SrsHlsSegment* first = dynamic_cast<SrsHlsSegment*>(segments->first());

View file

@ -249,6 +249,7 @@ srs_error_t SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJit
SrsFlvStreamEncoder::SrsFlvStreamEncoder()
{
header_written = false;
enc = new SrsFlvTransmuxer();
}
@ -265,26 +266,39 @@ srs_error_t SrsFlvStreamEncoder::initialize(SrsFileWriter* w, SrsBufferCache* /*
return srs_error_wrap(err, "init encoder");
}
// write flv header.
if ((err = enc->write_header()) != srs_success) {
return srs_error_wrap(err, "write header");
}
return err;
}
srs_error_t SrsFlvStreamEncoder::write_audio(int64_t timestamp, char* data, int size)
{
srs_error_t err = srs_success;
if ((err = write_header()) != srs_success) {
return srs_error_wrap(err, "write header");
}
return enc->write_audio(timestamp, data, size);
}
srs_error_t SrsFlvStreamEncoder::write_video(int64_t timestamp, char* data, int size)
{
srs_error_t err = srs_success;
if ((err = write_header()) != srs_success) {
return srs_error_wrap(err, "write header");
}
return enc->write_video(timestamp, data, size);
}
srs_error_t SrsFlvStreamEncoder::write_metadata(int64_t timestamp, char* data, int size)
{
srs_error_t err = srs_success;
if ((err = write_header()) != srs_success) {
return srs_error_wrap(err, "write header");
}
return enc->write_metadata(SrsFrameTypeScript, data, size);
}
@ -300,20 +314,53 @@ srs_error_t SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJi
return srs_success;
}
#ifdef SRS_PERF_FAST_FLV_ENCODER
SrsFastFlvStreamEncoder::SrsFastFlvStreamEncoder()
srs_error_t SrsFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int count)
{
}
srs_error_t err = srs_success;
SrsFastFlvStreamEncoder::~SrsFastFlvStreamEncoder()
{
}
// For https://github.com/ossrs/srs/issues/939
if (!header_written) {
bool has_video = false;
bool has_audio = false;
for (int i = 0; i < count && (!has_video || !has_audio); i++) {
SrsSharedPtrMessage* msg = msgs[i];
if (msg->is_video()) {
has_video = true;
} else if (msg->is_audio()) {
has_audio = true;
}
}
// Drop data if no A+V.
if (!has_video && !has_audio) {
return err;
}
if ((err = write_header(has_video, has_audio)) != srs_success) {
return srs_error_wrap(err, "write header");
}
}
srs_error_t SrsFastFlvStreamEncoder::write_tags(SrsSharedPtrMessage** msgs, int count)
{
return enc->write_tags(msgs, count);
}
#endif
srs_error_t SrsFlvStreamEncoder::write_header(bool has_video, bool has_audio)
{
srs_error_t err = srs_success;
if (!header_written) {
header_written = true;
if ((err = enc->write_header(has_video, has_audio)) != srs_success) {
return srs_error_wrap(err, "write header");
}
srs_trace("FLV: write header audio=%d, video=%d", has_audio, has_video);
}
return err;
}
SrsAacStreamEncoder::SrsAacStreamEncoder()
{
@ -511,19 +558,8 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
srs_assert(entry);
if (srs_string_ends_with(entry->pattern, ".flv")) {
w->header()->set_content_type("video/x-flv");
#ifdef SRS_PERF_FAST_FLV_ENCODER
bool realtime = _srs_config->get_realtime_enabled(req->vhost);
if (realtime) {
enc_desc = "FLV";
enc = new SrsFlvStreamEncoder();
} else {
enc_desc = "FastFLV";
enc = new SrsFastFlvStreamEncoder();
}
#else
enc_desc = "FLV";
enc = new SrsFlvStreamEncoder();
#endif
} else if (srs_string_ends_with(entry->pattern, ".aac")) {
w->header()->set_content_type("audio/x-aac");
enc_desc = "AAC";
@ -576,10 +612,8 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
}
}
#ifdef SRS_PERF_FAST_FLV_ENCODER
SrsFastFlvStreamEncoder* ffe = dynamic_cast<SrsFastFlvStreamEncoder*>(enc);
#endif
SrsFlvStreamEncoder* ffe = dynamic_cast<SrsFlvStreamEncoder*>(enc);
// Use receive thread to accept the close event to avoid FD leak.
// @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
SrsHttpMessage* hr = dynamic_cast<SrsHttpMessage*>(r);
@ -639,16 +673,12 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
}
// sendout all messages.
#ifdef SRS_PERF_FAST_FLV_ENCODER
if (ffe) {
err = ffe->write_tags(msgs.msgs, count);
} else {
err = streaming_send_messages(enc, msgs.msgs, count);
}
#else
err = streaming_send_messages(enc, msgs.msgs, count);
#endif
// free the messages.
for (int i = 0; i < count; i++) {
SrsSharedPtrMessage* msg = msgs.msgs[i];
@ -779,6 +809,11 @@ SrsLiveEntry::SrsLiveEntry(std::string m)
_is_aac = (ext == ".aac");
}
SrsLiveEntry::~SrsLiveEntry()
{
srs_freep(req);
}
bool SrsLiveEntry::is_flv()
{
return _is_flv;
@ -816,7 +851,6 @@ SrsHttpStreamServer::~SrsHttpStreamServer()
std::map<std::string, SrsLiveEntry*>::iterator it;
for (it = tflvs.begin(); it != tflvs.end(); ++it) {
SrsLiveEntry* entry = it->second;
srs_freep(entry->req);
srs_freep(entry);
}
tflvs.clear();
@ -871,7 +905,9 @@ srs_error_t SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r)
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
entry = new SrsLiveEntry(mount);
entry->source = s;
entry->req = r->copy()->as_http();
entry->cache = new SrsBufferCache(s, r);
entry->stream = new SrsLiveStream(s, r, entry->cache);
@ -941,7 +977,8 @@ srs_error_t SrsHttpStreamServer::on_reload_vhost_added(string vhost)
srs_error_t SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost)
{
srs_error_t err = srs_success;
// Create new vhost.
if (tflvs.find(vhost) == tflvs.end()) {
if ((err = initialize_flv_entry(vhost)) != srs_success) {
return srs_error_wrap(err, "init flv entry");
@ -951,41 +988,27 @@ srs_error_t SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost
// and do mount automatically on playing http flv if this stream is a new http_remux stream.
return err;
}
SrsLiveEntry* tmpl = tflvs[vhost];
SrsRequest* req = tmpl->req;
SrsSource* source = tmpl->source;
if (source && req) {
// cleanup the exists http remux.
http_unmount(source, req);
}
if (!_srs_config->get_vhost_http_remux_enabled(vhost)) {
return err;
}
string old_tmpl_mount = tmpl->mount;
string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost);
/**
* TODO: not support to reload different mount url for the time being.
* if the mount is change, need more logical thing to deal with.
* such as erase stream from sflvs and free all related resource.
*/
srs_assert(old_tmpl_mount == new_tmpl_mount);
// do http mount directly with SrsRequest and SrsSource if stream is played already.
if (req) {
std::string sid = req->get_stream_url();
// remount stream.
if ((err = http_mount(source, req)) != srs_success) {
return srs_error_wrap(err, "vhost %s http_remux reload failed", vhost.c_str());
// Update all streams for exists vhost.
// TODO: FIMXE: If url changed, needs more things to deal with.
std::map<std::string, SrsLiveEntry*>::iterator it;
for (it = sflvs.begin(); it != sflvs.end(); ++it) {
SrsLiveEntry* entry = it->second;
if (!entry || !entry->req || !entry->source) {
continue;
}
SrsRequest* req = entry->req;
if (!req || req->vhost != vhost) {
continue;
}
SrsSource* source = entry->source;
if (_srs_config->get_vhost_http_remux_enabled(vhost)) {
http_mount(source, req);
} else {
http_unmount(source, req);
}
} else {
// for without SrsRequest and SrsSource if stream is not played yet, do http mount automatically
// when start play this http flv stream.
}
srs_trace("vhost %s http_remux reload success", vhost.c_str());

View file

@ -82,8 +82,9 @@ public:
// Transmux RTMP to HTTP Live Streaming.
class SrsFlvStreamEncoder : public ISrsBufferEncoder
{
protected:
private:
SrsFlvTransmuxer* enc;
bool header_written;
public:
SrsFlvStreamEncoder();
virtual ~SrsFlvStreamEncoder();
@ -95,21 +96,12 @@ public:
public:
virtual bool has_cache();
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
};
#ifdef SRS_PERF_FAST_FLV_ENCODER
// A Fast HTTP FLV Live Streaming, to write multiple tags by writev.
// @see https://github.com/ossrs/srs/issues/405
class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder
{
public:
SrsFastFlvStreamEncoder();
virtual ~SrsFastFlvStreamEncoder();
public:
// Write the tags in a time.
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
private:
virtual srs_error_t write_header(bool has_video = true, bool has_audio = true);
};
#endif
// Transmux RTMP to HTTP TS Streaming.
class SrsTsStreamEncoder : public ISrsBufferEncoder
@ -215,7 +207,9 @@ private:
bool _is_aac;
bool _is_mp3;
public:
// We will free the request.
SrsRequest* req;
// Shared source.
SrsSource* source;
public:
// For template, the mount contains variables.
@ -226,6 +220,7 @@ public:
SrsBufferCache* cache;
SrsLiveEntry(std::string m);
virtual ~SrsLiveEntry();
bool is_flv();
bool is_ts();

View file

@ -97,11 +97,17 @@ void SrsIngesterFFMPEG::fast_stop()
ffmpeg->fast_stop();
}
void SrsIngesterFFMPEG::fast_kill()
{
ffmpeg->fast_kill();
}
SrsIngester::SrsIngester()
{
_srs_config->subscribe(this);
expired = false;
disposed = false;
trd = new SrsDummyCoroutine();
pprint = SrsPithyPrint::create_ingester();
@ -117,11 +123,18 @@ SrsIngester::~SrsIngester()
void SrsIngester::dispose()
{
if (disposed) {
return;
}
disposed = true;
// first, use fast stop to notice all FFMPEG to quit gracefully.
fast_stop();
srs_usleep(100 * SRS_UTIME_MILLISECONDS);
// then, use stop to wait FFMPEG quit one by one and send SIGKILL if needed.
stop();
// then, use fast kill to ensure FFMPEG quit.
fast_kill();
}
srs_error_t SrsIngester::start()
@ -166,6 +179,19 @@ void SrsIngester::fast_stop()
}
}
void SrsIngester::fast_kill()
{
std::vector<SrsIngesterFFMPEG*>::iterator it;
for (it = ingesters.begin(); it != ingesters.end(); ++it) {
SrsIngesterFFMPEG* ingester = *it;
ingester->fast_kill();
}
if (!ingesters.empty()) {
srs_trace("fast kill all ingesters ok.");
}
}
// when error, ingester sleep for a while and retry.
// ingest never sleep a long time, for we must start the stream ASAP.
#define SRS_AUTO_INGESTER_CIMS (3 * SRS_UTIME_SECONDS)
@ -174,7 +200,7 @@ srs_error_t SrsIngester::cycle()
{
srs_error_t err = srs_success;
while (true) {
while (!disposed) {
if ((err = do_cycle()) != srs_success) {
srs_warn("Ingester: Ignore error, %s", srs_error_desc(err).c_str());
srs_freep(err);
@ -371,8 +397,8 @@ srs_error_t SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective*
std::string log_file = SRS_CONSTS_NULL_FILE; // disabled
// write ffmpeg info to log file.
if (_srs_config->get_ffmpeg_log_enabled()) {
log_file = _srs_config->get_ffmpeg_log_dir();
if (_srs_config->get_ff_log_enabled()) {
log_file = _srs_config->get_ff_log_dir();
log_file += "/";
log_file += "ffmpeg-ingest";
log_file += "-";
@ -383,7 +409,13 @@ srs_error_t SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective*
log_file += stream;
log_file += ".log";
}
std::string log_level = _srs_config->get_ff_log_level();
if (!log_level.empty()) {
ffmpeg->append_iparam("-loglevel");
ffmpeg->append_iparam(log_level);
}
// input
std::string input_type = _srs_config->get_ingest_input_type(ingest);
if (input_type.empty()) {
@ -397,7 +429,7 @@ srs_error_t SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective*
}
// for file, set re.
ffmpeg->set_iparams("-re");
ffmpeg->append_iparam("-re");
if ((err = ffmpeg->initialize(input_url, output, log_file)) != srs_success) {
return srs_error_wrap(err, "init ffmpeg");
@ -409,7 +441,7 @@ srs_error_t SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective*
}
// for stream, no re.
ffmpeg->set_iparams("");
ffmpeg->append_iparam("");
if ((err = ffmpeg->initialize(input_url, output, log_file)) != srs_success) {
return srs_error_wrap(err, "init ffmpeg");

View file

@ -60,6 +60,7 @@ public:
virtual srs_error_t cycle();
// @see SrsFFMPEG.fast_stop().
virtual void fast_stop();
virtual void fast_kill();
};
// Ingest file/stream/device,
@ -75,6 +76,8 @@ private:
// Whether the ingesters are expired, for example, the listen port changed,
// all ingesters must be restart.
bool expired;
// Whether already disposed.
bool disposed;
public:
SrsIngester();
virtual ~SrsIngester();
@ -84,7 +87,10 @@ public:
virtual srs_error_t start();
virtual void stop();
private:
// Notify FFMPEG to fast stop.
virtual void fast_stop();
// When SRS quit, directly kill FFMPEG after fast stop.
virtual void fast_kill();
// Interface ISrsReusableThreadHandler.
public:
virtual srs_error_t cycle();

View file

@ -152,7 +152,7 @@ srs_error_t srs_redirect_output(string from_file, int to_fd)
// redirect the fd to file.
int fd = -1;
int flags = O_CREAT|O_WRONLY|O_APPEND;
int flags = O_CREAT|O_RDWR|O_APPEND;
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
if ((fd = ::open(from_file.c_str(), flags, mode)) < 0) {
@ -197,10 +197,7 @@ srs_error_t SrsProcess::start()
// ignore the SIGINT and SIGTERM
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
// for the stdin,
// should never close it or ffmpeg will error.
// for the stdout, ignore when not specified.
// redirect stdout to file if possible.
if ((err = srs_redirect_output(stdout_file, STDOUT_FILENO)) != srs_success) {
@ -212,16 +209,22 @@ srs_error_t SrsProcess::start()
if ((err = srs_redirect_output(stderr_file, STDERR_FILENO)) != srs_success) {
return srs_error_wrap(err, "redirect output");
}
// No stdin for process, @bug https://github.com/ossrs/srs/issues/1592
if ((err = srs_redirect_output("/dev/null", STDIN_FILENO)) != srs_success) {
return srs_error_wrap(err, "redirect input");
}
// should never close the fd 3+, for it myabe used.
// for fd should close at exec, use fnctl to set it.
// log basic info to stderr.
if (true) {
fprintf(stderr, "\n");
fprintf(stderr, "process ppid=%d, cid=%d, pid=%d\n", ppid, cid, getpid());
fprintf(stderr, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
fprintf(stderr, "process actual cli: %s\n", actual_cli.c_str());
fprintf(stdout, "\n");
fprintf(stdout, "process ppid=%d, cid=%d, pid=%d, in=%d, out=%d, err=%d\n",
ppid, cid, getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
}
// memory leak in child process, it's ok.
@ -327,3 +330,28 @@ void SrsProcess::fast_stop()
return;
}
void SrsProcess::fast_kill()
{
int ret = ERROR_SUCCESS;
if (!is_started) {
return;
}
if (pid <= 0) {
return;
}
if (kill(pid, SIGKILL) < 0) {
ret = ERROR_SYSTEM_KILL;
srs_warn("ignore fast kill process failed, pid=%d. ret=%d", pid, ret);
return;
}
// Try to wait pid to avoid zombie FFMEPG.
int status = 0;
waitpid(pid, &status, WNOHANG);
return;
}

View file

@ -91,6 +91,8 @@ public:
// when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N]
// but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
virtual void fast_stop();
// Directly kill process, never use it except server quiting.
virtual void fast_kill();
};
#endif

View file

@ -39,54 +39,61 @@ SrsSecurity::~SrsSecurity()
srs_error_t SrsSecurity::check(SrsRtmpConnType type, string ip, SrsRequest* req)
{
srs_error_t err = srs_success;
// allow all if security disabled.
if (!_srs_config->get_security_enabled(req->vhost)) {
return err;
return err; // OK
}
// default to deny all when security enabled.
err = srs_error_new(ERROR_SYSTEM_SECURITY, "allowed");
// rules to apply
SrsConfDirective* rules = _srs_config->get_security_rules(req->vhost);
return do_check(rules, type, ip, req);
}
srs_error_t SrsSecurity::do_check(SrsConfDirective* rules, SrsRtmpConnType type, string ip, SrsRequest* req)
{
srs_error_t err = srs_success;
if (!rules) {
return err;
return srs_error_new(ERROR_SYSTEM_SECURITY, "default deny for %s", ip.c_str());
}
// deny if matches deny strategy.
if ((err = deny_check(rules, type, ip)) != srs_success) {
return srs_error_wrap(err, "for %s", ip.c_str());
}
// allow if matches allow strategy.
if (allow_check(rules, type, ip) == ERROR_SYSTEM_SECURITY_ALLOW) {
srs_error_reset(err);
if ((err = allow_check(rules, type, ip)) != srs_success) {
return srs_error_wrap(err, "for %s", ip.c_str());
}
// deny if matches deny strategy.
if (deny_check(rules, type, ip) == ERROR_SYSTEM_SECURITY_DENY) {
srs_error_reset(err);
return srs_error_new(ERROR_SYSTEM_SECURITY_DENY, "denied");
}
return err;
}
int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip)
srs_error_t SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip)
{
int ret = ERROR_SUCCESS;
int allow_rules = 0;
int deny_rules = 0;
for (int i = 0; i < (int)rules->directives.size(); i++) {
SrsConfDirective* rule = rules->at(i);
if (rule->name != "allow") {
if (rule->name == "deny") {
deny_rules++;
}
continue;
}
allow_rules++;
switch (type) {
case SrsRtmpConnPlay:
if (rule->arg0() != "play") {
break;
}
if (rule->arg1() == "all" || rule->arg1() == ip) {
ret = ERROR_SYSTEM_SECURITY_ALLOW;
break;
return srs_success; // OK
}
break;
case SrsRtmpConnFMLEPublish:
@ -96,28 +103,23 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
break;
}
if (rule->arg1() == "all" || rule->arg1() == ip) {
ret = ERROR_SYSTEM_SECURITY_ALLOW;
break;
return srs_success; // OK
}
break;
case SrsRtmpConnUnknown:
default:
break;
}
// when matched, donot search more.
if (ret == ERROR_SYSTEM_SECURITY_ALLOW) {
break;
}
}
return ret;
if (allow_rules > 0 || (deny_rules + allow_rules) == 0) {
return srs_error_new(ERROR_SYSTEM_SECURITY_ALLOW, "not allowed by any of %d/%d rules", allow_rules, deny_rules);
}
return srs_success; // OK
}
int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip)
srs_error_t SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip)
{
int ret = ERROR_SUCCESS;
for (int i = 0; i < (int)rules->directives.size(); i++) {
SrsConfDirective* rule = rules->at(i);
@ -131,8 +133,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
break;
}
if (rule->arg1() == "all" || rule->arg1() == ip) {
ret = ERROR_SYSTEM_SECURITY_DENY;
break;
return srs_error_new(ERROR_SYSTEM_SECURITY_DENY, "deny by rule<%s>", rule->arg1().c_str());
}
break;
case SrsRtmpConnFMLEPublish:
@ -142,21 +143,15 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
break;
}
if (rule->arg1() == "all" || rule->arg1() == ip) {
ret = ERROR_SYSTEM_SECURITY_DENY;
break;
return srs_error_new(ERROR_SYSTEM_SECURITY_DENY, "deny by rule<%s>", rule->arg1().c_str());
}
break;
case SrsRtmpConnUnknown:
default:
break;
}
// when matched, donot search more.
if (ret == ERROR_SYSTEM_SECURITY_DENY) {
break;
}
}
return ret;
return srs_success; // OK
}

View file

@ -46,12 +46,9 @@ public:
// @param req the request object of client.
virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest* req);
private:
// Security check the allow,
// @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
// Security check the deny,
// @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
virtual srs_error_t do_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip, SrsRequest* req);
virtual srs_error_t allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
virtual srs_error_t deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
};
#endif

View file

@ -520,7 +520,8 @@ void SrsServer::dispose()
close_listeners(SrsListenerRtsp);
close_listeners(SrsListenerFlv);
// @remark don't dispose ingesters, for too slow.
// Fast stop to notify FFMPEG to quit, wait for a while then fast kill.
ingester->dispose();
// dispose the source for hls and dvr.
_srs_sources->dispose();
@ -851,17 +852,14 @@ void SrsServer::on_signal(int signo)
srs_trace("gmc is on, main cycle will terminate normally.");
signal_gmc_stop = true;
#else
srs_trace("user terminate program");
#ifdef SRS_AUTO_MEM_WATCH
#ifdef SRS_AUTO_MEM_WATCH
srs_memory_report();
#endif
#endif
exit(0);
#endif
return;
}
if (signo == SRS_SIGNAL_GRACEFULLY_QUIT && !signal_gracefully_quit) {
srs_trace("user terminate program, gracefully quit.");
if ((signo == SIGINT || signo == SRS_SIGNAL_GRACEFULLY_QUIT) && !signal_gracefully_quit) {
srs_trace("sig=%d, user terminate program, gracefully quit", signo);
signal_gracefully_quit = true;
return;
}

View file

@ -903,6 +903,11 @@ srs_error_t SrsOriginHub::cycle()
return err;
}
bool SrsOriginHub::active()
{
return is_active;
}
srs_error_t SrsOriginHub::on_meta_data(SrsSharedPtrMessage* shared_metadata, SrsOnMetaDataPacket* packet)
{
srs_error_t err = srs_success;
@ -1047,6 +1052,12 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se
srs_avc_level2str(c->avc_level).c_str(), c->width, c->height,
c->video_data_rate / 1000, c->frame_rate, c->duration);
}
// Ignore video data when no sps/pps
// @bug https://github.com/ossrs/srs/issues/703#issuecomment-578393155
if (format->vcodec && !format->vcodec->is_avc_codec_ok()) {
return err;
}
if ((err = hls->on_video(msg, format)) != srs_success) {
// apply the error strategy for hls.
@ -1639,15 +1650,26 @@ SrsSourceManager* _srs_sources = new SrsSourceManager();
SrsSourceManager::SrsSourceManager()
{
lock = NULL;
}
SrsSourceManager::~SrsSourceManager()
{
srs_mutex_destroy(lock);
}
srs_error_t SrsSourceManager::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps)
{
srs_error_t err = srs_success;
// Lazy create lock, because ST is not ready in SrsSourceManager constructor.
if (!lock) {
lock = srs_mutex_new();
}
// Use lock to protect coroutine switch.
// @bug https://github.com/ossrs/srs/issues/1230
SrsLocker(lock);
SrsSource* source = NULL;
if ((source = fetch(r)) != NULL) {
@ -2452,10 +2474,10 @@ srs_error_t SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consum
consumer = new SrsConsumer(this, conn);
consumers.push_back(consumer);
srs_utime_t queue_size = _srs_config->get_queue_length(req->vhost);
consumer->set_queue_size(queue_size);
// if atc, update the sequence header to gop cache time.
if (atc && !gop_cache->empty()) {
if (meta->data()) {
@ -2468,22 +2490,25 @@ srs_error_t SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consum
meta->ash()->timestamp = srsu2ms(gop_cache->start_time());
}
}
// Copy metadata and sequence header to consumer.
if ((err = meta->dumps(consumer, atc, jitter_algorithm, dm, ds)) != srs_success) {
return srs_error_wrap(err, "meta dumps");
// If stream is publishing, dumps the sequence header and gop cache.
if (hub->active()) {
// Copy metadata and sequence header to consumer.
if ((err = meta->dumps(consumer, atc, jitter_algorithm, dm, ds)) != srs_success) {
return srs_error_wrap(err, "meta dumps");
}
// copy gop cache to client.
if (dg && (err = gop_cache->dump(consumer, atc, jitter_algorithm)) != srs_success) {
return srs_error_wrap(err, "gop cache dumps");
}
}
// copy gop cache to client.
if (dg && (err = gop_cache->dump(consumer, atc, jitter_algorithm)) != srs_success) {
return srs_error_wrap(err, "gop cache dumps");
}
// print status.
if (dg) {
srs_trace("create consumer, queue_size=%.2f, jitter=%d", queue_size, jitter_algorithm);
srs_trace("create consumer, active=%d, queue_size=%.2f, jitter=%d", hub->active(), queue_size, jitter_algorithm);
} else {
srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm);
srs_trace("create consumer, active=%d, ignore gop cache, jitter=%d", hub->active(), jitter_algorithm);
}
// for edge, when play edge stream, check the state

View file

@ -33,6 +33,7 @@
#include <srs_app_st.hpp>
#include <srs_app_reload.hpp>
#include <srs_core_performance.hpp>
#include <srs_service_st.hpp>
class SrsFormat;
class SrsRtmpFormat;
@ -330,7 +331,6 @@ class SrsOriginHub : public ISrsReloadHandler
private:
SrsSource* source;
SrsRequest* req;
// Whether the stream hub is active, or stream is publishing.
bool is_active;
private:
// The format, codec information.
@ -364,6 +364,8 @@ public:
// Cycle the hub, process some regular events,
// For example, dispose hls in cycle.
virtual srs_error_t cycle();
// Whether the stream hub is active, or stream is publishing.
virtual bool active();
public:
// When got a parsed metadata.
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata, SrsOnMetaDataPacket* packet);
@ -376,7 +378,7 @@ public:
virtual srs_error_t on_publish();
// When stop publish stream.
virtual void on_unpublish();
// Internal callback.
// Internal callback.
public:
// For the SrsForwarder to callback to request the sequence headers.
virtual srs_error_t on_forwarder_start(SrsForwarder* forwarder);
@ -442,6 +444,7 @@ public:
class SrsSourceManager
{
private:
srs_mutex_t lock;
std::map<std::string, SrsSource*> pool;
public:
SrsSourceManager();

View file

@ -27,7 +27,8 @@
// The version config.
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_REVISION 1
#include <srs_core_version4.hpp>
#define VERSION_REVISION SRS_VERSION4_REVISION
// The macros generated by configure script.
#include <srs_auto_headers.hpp>
@ -39,7 +40,7 @@
// The project informations, may sent to client in HTTP header or RTMP metadata.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_CODE "OuXuli"
#define RTMP_SIG_SRS_CODE "Leo"
#define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs"
#define RTMP_SIG_SRS_LICENSE "MIT"
#define RTMP_SIG_SRS_AUTHORS "winlin,wenjie,runner365"

View file

@ -177,13 +177,6 @@
#undef SRS_PERF_SO_SNDBUF_SIZE
#endif
/**
* define the following macro to enable the fast flv encoder.
* @see https://github.com/ossrs/srs/issues/405
*/
#undef SRS_PERF_FAST_FLV_ENCODER
#define SRS_PERF_FAST_FLV_ENCODER
/**
* whether ensure glibc memory check.
*/

View file

@ -0,0 +1,24 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core_version3.hpp>

View file

@ -0,0 +1,29 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_CORE_VERSION3_HPP
#define SRS_CORE_VERSION3_HPP
#define SRS_VERSION3_REVISION 116
#endif

View file

@ -0,0 +1,24 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_core_version4.hpp>

View file

@ -0,0 +1,29 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP
#define SRS_VERSION4_REVISION 3
#endif

View file

@ -353,23 +353,19 @@ SrsFlvTransmuxer::SrsFlvTransmuxer()
{
writer = NULL;
#ifdef SRS_PERF_FAST_FLV_ENCODER
nb_tag_headers = 0;
tag_headers = NULL;
nb_iovss_cache = 0;
iovss_cache = NULL;
nb_ppts = 0;
ppts = NULL;
#endif
}
SrsFlvTransmuxer::~SrsFlvTransmuxer()
{
#ifdef SRS_PERF_FAST_FLV_ENCODER
srs_freepa(tag_headers);
srs_freepa(iovss_cache);
srs_freepa(ppts);
#endif
}
srs_error_t SrsFlvTransmuxer::initialize(ISrsWriter* fw)
@ -379,15 +375,19 @@ srs_error_t SrsFlvTransmuxer::initialize(ISrsWriter* fw)
return srs_success;
}
srs_error_t SrsFlvTransmuxer::write_header()
srs_error_t SrsFlvTransmuxer::write_header(bool has_video, bool has_audio)
{
srs_error_t err = srs_success;
uint8_t av_flag = 0;
av_flag += (has_audio? 4:0);
av_flag += (has_video? 1:0);
// 9bytes header and 4bytes first previous-tag-size
char flv_header[] = {
'F', 'L', 'V', // Signatures "FLV"
(char)0x01, // File version (for example, 0x01 for FLV version 1)
(char)0x05, // 4, audio; 1, video; 5 audio+video.
(char)av_flag, // 4, audio; 1, video; 5 audio+video.
(char)0x00, (char)0x00, (char)0x00, (char)0x09 // DataOffset UI32 The length of this header in bytes
};
@ -472,7 +472,6 @@ int SrsFlvTransmuxer::size_tag(int data_size)
return SRS_FLV_TAG_HEADER_SIZE + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
}
#ifdef SRS_PERF_FAST_FLV_ENCODER
srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count)
{
srs_error_t err = srs_success;
@ -542,7 +541,6 @@ srs_error_t SrsFlvTransmuxer::write_tags(SrsSharedPtrMessage** msgs, int count)
return err;
}
#endif
void SrsFlvTransmuxer::cache_metadata(char type, char* data, int size, char* cache)
{

View file

@ -362,7 +362,7 @@ public:
// 1. E.2 The FLV header
// 2. PreviousTagSize0 UI32 Always 0
// that is, 9+4=13bytes.
virtual srs_error_t write_header();
virtual srs_error_t write_header(bool has_video = true, bool has_audio = true);
virtual srs_error_t write_header(char flv_header[9]);
// Write flv metadata.
// @param type, the type of data, or other message type.
@ -381,7 +381,6 @@ public:
// including the tag header, body, and 4bytes previous tag size.
// @remark assert data_size is not negative.
static int size_tag(int data_size);
#ifdef SRS_PERF_FAST_FLV_ENCODER
private:
// The cache tag header.
int nb_tag_headers;
@ -395,7 +394,6 @@ private:
public:
// Write the tags in a time.
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
#endif
private:
virtual void cache_metadata(char type, char* data, int size, char* cache);
virtual void cache_audio(int64_t timestamp, char* data, int size, char* cache);

View file

@ -356,6 +356,9 @@ srs_mutex_t srs_mutex_new()
int srs_mutex_destroy(srs_mutex_t mutex)
{
if (!mutex) {
return 0;
}
return st_mutex_destroy((st_mutex_t)mutex);
}

View file

@ -104,12 +104,13 @@ class impl__SrsLocker
private:
srs_mutex_t* lock;
public:
impl__SrsLocker(srs_mutex_t* l) : lock(l) {
int r0 = srs_mutex_lock(lock);
impl__SrsLocker(srs_mutex_t* l) {
lock = l;
int r0 = srs_mutex_lock(*lock);
srs_assert(!r0);
}
virtual ~impl__SrsLocker() {
int r0 = srs_mutex_unlock(lock);
int r0 = srs_mutex_unlock(*lock);
srs_assert(!r0);
}
};

View file

@ -26,6 +26,8 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_app_fragment.hpp>
#include <srs_app_security.hpp>
#include <srs_app_config.hpp>
#include <srs_app_st.hpp>
@ -372,3 +374,186 @@ VOID TEST(AppFragmentTest, CheckDuration)
}
}
VOID TEST(AppSecurity, CheckSecurity)
{
srs_error_t err;
// Deny if no rules.
if (true) {
SrsSecurity sec; SrsRequest rr;
HELPER_EXPECT_FAILED(sec.do_check(NULL, SrsRtmpConnUnknown, "", &rr));
}
// Deny if not allowed.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnUnknown, "", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("others"); rules.get_or_create("any");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnUnknown, "", &rr));
}
// Deny by rule.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "all");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "12.13.14.15");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "11.12.13.14");
if (true) {
SrsConfDirective* d = new SrsConfDirective();
d->name = "deny";
d->args.push_back("play");
d->args.push_back("12.13.14.15");
rules.directives.push_back(d);
}
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnFlashPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "all");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnFlashPublish, "11.12.13.14", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnHaivisionPublish, "12.13.14.15", &rr));
}
// Allowed if not denied.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnPlay, "11.12.13.14", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnUnknown, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "publish", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFlashPublish, "11.12.13.14", &rr));
}
// Allowed by rule.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "play", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "play", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFlashPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnHaivisionPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnHaivisionPublish, "12.13.14.15", &rr));
}
// Allowed if not denied.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "12.13.14.15");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("deny", "play", "all");
HELPER_EXPECT_SUCCESS(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
// Denied if not allowd.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "play", "11.12.13.14");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnFMLEPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "play", "11.12.13.14");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "12.13.14.15");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "11.12.13.14");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnHaivisionPublish, "12.13.14.15", &rr));
}
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "publish", "11.12.13.14");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnUnknown, "11.12.13.14", &rr));
}
// Denied if dup.
if (true) {
SrsSecurity sec; SrsRequest rr; SrsConfDirective rules;
rules.get_or_create("allow", "play", "11.12.13.14");
rules.get_or_create("deny", "play", "11.12.13.14");
HELPER_EXPECT_FAILED(sec.do_check(&rules, SrsRtmpConnPlay, "11.12.13.14", &rr));
}
// SRS apply the following simple strategies one by one:
// 1. allow all if security disabled.
// 2. default to deny all when security enabled.
// 3. allow if matches allow strategy.
// 4. deny if matches deny strategy.
}

View file

@ -888,6 +888,11 @@ VOID TEST(ConfigMainTest, CheckConf_ff_log_dir)
MockSrsConfig conf;
HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "ff_log_dirs ./objs;"));
}
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_FAILED(conf.parse(_MIN_OK_CONF "ff_log_levels info;"));
}
}
VOID TEST(ConfigMainTest, CheckConf_srs_log_level)
@ -3503,12 +3508,13 @@ VOID TEST(ConfigMainTest, CheckVhostConfig5)
if (true) {
MockSrsConfig conf;
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_tank xxx;srs_log_level xxx2;srs_log_file xxx3;ff_log_dir xxx4;"));
HELPER_ASSERT_SUCCESS(conf.parse(_MIN_OK_CONF "srs_log_tank xxx;srs_log_level xxx2;srs_log_file xxx3;ff_log_dir xxx4; ff_log_level xxx5;"));
EXPECT_TRUE(conf.get_log_tank_file());
EXPECT_STREQ("xxx2", conf.get_log_level().c_str());
EXPECT_STREQ("xxx3", conf.get_log_file().c_str());
EXPECT_STREQ("xxx4", conf.get_ffmpeg_log_dir().c_str());
EXPECT_TRUE(conf.get_ffmpeg_log_enabled());
EXPECT_STREQ("xxx4", conf.get_ff_log_dir().c_str());
EXPECT_STREQ("xxx5", conf.get_ff_log_level().c_str());
EXPECT_TRUE(conf.get_ff_log_enabled());
}
if (true) {

View file

@ -912,7 +912,6 @@ VOID TEST(KernelFLVTest, CoverWriterErrorCase)
HELPER_EXPECT_FAILED(m.write_video(0, NULL, 0));
}
#ifdef SRS_PERF_FAST_FLV_ENCODER
if (true) {
MockSrsFileWriter w;
HELPER_EXPECT_SUCCESS(w.open(""));
@ -963,7 +962,6 @@ VOID TEST(KernelFLVTest, CoverWriterErrorCase)
SrsSharedPtrMessage* msgs = &msg;
HELPER_EXPECT_FAILED(m.write_tags(&msgs, 1));
}
#endif
}
VOID TEST(KernelFLVTest, CoverReaderErrorCase)
@ -4028,7 +4026,6 @@ VOID TEST(KernelFLVTest, CoverAll)
EXPECT_TRUE(s.is_video());
}
#ifdef SRS_PERF_FAST_FLV_ENCODER
if (true) {
MockSrsFileWriter f;
SrsFlvTransmuxer mux;
@ -4045,7 +4042,6 @@ VOID TEST(KernelFLVTest, CoverAll)
EXPECT_EQ(16, f.tellg());
}
#endif
}
VOID TEST(KernelFLVTest, CoverSharedPtrMessage)