mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge code.
Conflicts: trunk/configure trunk/src/app/srs_app_source.cpp trunk/src/kernel/srs_kernel_error.hpp
This commit is contained in:
commit
e57bda8908
90 changed files with 4584 additions and 3576 deletions
|
@ -3,18 +3,22 @@ Donations ordered by first donation.
|
||||||
===========================================================
|
===========================================================
|
||||||
2015
|
2015
|
||||||
|
|
||||||
RMB 1000+
|
RMB 10000+
|
||||||
|
* [2015-03-03 13:25] 郭强
|
||||||
|
|
||||||
|
RMB 1000-9999
|
||||||
* [2015-xx-xx xx:xx] xxx
|
* [2015-xx-xx xx:xx] xxx
|
||||||
|
|
||||||
RMB 500-999
|
RMB 500-999
|
||||||
* [2015-xx-xx xx:xx] xxx
|
* [2015-xx-xx xx:xx] xxx
|
||||||
|
|
||||||
RMB 100-499
|
RMB 100-499
|
||||||
|
* [2015-03-11 09:44] 叶发养
|
||||||
* [2015-02-08 21:10] 韩友洪
|
* [2015-02-08 21:10] 韩友洪
|
||||||
* [2015-01-09 16:08] 李理
|
* [2015-01-09 16:08] 李理
|
||||||
|
|
||||||
RMB 50-99
|
RMB 50-99
|
||||||
* [2015-xx-xx xx:xx] xxx
|
* [2015-03-03 17:30] flybird
|
||||||
|
|
||||||
RMB 0.01-49
|
RMB 0.01-49
|
||||||
* [2015-xx-xx xx:xx] xxx
|
* [2015-xx-xx xx:xx] xxx
|
||||||
|
|
41
README.md
41
README.md
|
@ -12,11 +12,32 @@ Download from ossrs.net:
|
||||||
[Centos6-x86_64](http://www.ossrs.net/srs.release/releases/files/SRS-CentOS6-x86_64-1.0.27.zip)
|
[Centos6-x86_64](http://www.ossrs.net/srs.release/releases/files/SRS-CentOS6-x86_64-1.0.27.zip)
|
||||||
[more...](http://www.ossrs.net/srs.release/releases/)
|
[more...](http://www.ossrs.net/srs.release/releases/)
|
||||||
|
|
||||||
|
## Why SRS?
|
||||||
|
|
||||||
|
1. Completely rewrite HLS following m3u8/ts spec, and HLS support h.264+aac/mp3.
|
||||||
|
1. High efficient RTMP deliverying support 7k+ concurrency, vhost based, both origin and edge.
|
||||||
|
1. Embeded simplified media HTTP server for HLS, api and HTTP flv/ts/mp3/aac streaming.
|
||||||
|
1. Variety input: RTMP, pull by ingest file or stream(HTTP/RTMP/RTSP), push by stream caster
|
||||||
|
RTSP/MPEGTS-over-UDP.
|
||||||
|
1. Popular internet delivery: RTMP for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP
|
||||||
|
flv/ts/mp3/aac streaming for user prefered.
|
||||||
|
1. Enhanced DVR: segment/session/append plan, customer path and HTTP callback.
|
||||||
|
1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming,
|
||||||
|
http api, refer, log, bandwith test and srs-librtmp.
|
||||||
|
1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process
|
||||||
|
and for linux/osx platform, common server x86-64/i386/arm/mips cpus, rich comments, strictly
|
||||||
|
follows RTMP/HLS/RTSP spec.
|
||||||
|
1. Easy to use: both English and Chinese wiki, typically config files in trunk/conf, traceable
|
||||||
|
and session based log, linux service script and install script.
|
||||||
|
1. MIT license, open source with product management and evolution.
|
||||||
|
|
||||||
|
Enjoy it!
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
SRS(SIMPLE RTMP Server) over state-threads created in 2013.10.
|
SRS(SIMPLE RTMP Server) over state-threads created in 2013.10.
|
||||||
|
|
||||||
SRS delivers rtmp/hls/http live on x86/x64/arm/mips linux,
|
SRS delivers rtmp/hls/http live on x86/x64/arm/mips linux/osx,
|
||||||
supports origin/edge/vhost and transcode/ingest and dvr/forward
|
supports origin/edge/vhost and transcode/ingest and dvr/forward
|
||||||
and http-api/http-callback/reload, introduces tracable
|
and http-api/http-callback/reload, introduces tracable
|
||||||
session-oriented log, exports client srs-librtmp,
|
session-oriented log, exports client srs-librtmp,
|
||||||
|
@ -486,14 +507,12 @@ Supported operating systems and hardware:
|
||||||
).
|
).
|
||||||
1. Support HLS(h.264+mp3) streaming, read
|
1. Support HLS(h.264+mp3) streaming, read
|
||||||
[#301](https://github.com/winlinvip/simple-rtmp-server/issues/301).
|
[#301](https://github.com/winlinvip/simple-rtmp-server/issues/301).
|
||||||
1. Support push MPEG-TS over UDP to SRS, read
|
|
||||||
[#250](https://github.com/winlinvip/simple-rtmp-server/issues/250).
|
|
||||||
1. Rewrite HLS(h.264+aac/mp3) streaming, read
|
1. Rewrite HLS(h.264+aac/mp3) streaming, read
|
||||||
[#304](https://github.com/winlinvip/simple-rtmp-server/issues/304).
|
[#304](https://github.com/winlinvip/simple-rtmp-server/issues/304).
|
||||||
1. Support push RTSP to SRS, read
|
1. [experiment] Support push MPEG-TS over UDP to SRS, read
|
||||||
|
[#250](https://github.com/winlinvip/simple-rtmp-server/issues/250).
|
||||||
|
1. [experiment] Support push RTSP to SRS, read
|
||||||
[#133](https://github.com/winlinvip/simple-rtmp-server/issues/133).
|
[#133](https://github.com/winlinvip/simple-rtmp-server/issues/133).
|
||||||
1. Support DVR http api, read
|
|
||||||
[#179](https://github.com/winlinvip/simple-rtmp-server/issues/179).
|
|
||||||
1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
|
1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
|
||||||
1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
|
1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
|
||||||
1. [no-plan] Support multiple processes, for both origin and edge
|
1. [no-plan] Support multiple processes, for both origin and edge
|
||||||
|
@ -503,7 +522,6 @@ Supported operating systems and hardware:
|
||||||
1. [no-plan] Support encryption: RTMPE/RTMPS, HLS DRM
|
1. [no-plan] Support encryption: RTMPE/RTMPS, HLS DRM
|
||||||
1. [no-plan] Support RTMPT, http to tranverse firewalls
|
1. [no-plan] Support RTMPT, http to tranverse firewalls
|
||||||
1. [no-plan] Support file source, transcoding file to live stream
|
1. [no-plan] Support file source, transcoding file to live stream
|
||||||
1. [no-plan] Support RTP/RTSP server.
|
|
||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
* 2015-02-12, [Release v1.0r2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0r2), bug fixed, 1.0.27, 59507 lines.<br/>
|
* 2015-02-12, [Release v1.0r2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/1.0r2), bug fixed, 1.0.27, 59507 lines.<br/>
|
||||||
|
@ -532,8 +550,13 @@ Supported operating systems and hardware:
|
||||||
|
|
||||||
### SRS 2.0 history
|
### SRS 2.0 history
|
||||||
|
|
||||||
* v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124.
|
* v2.0, 2015-03-10, fix [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), support osx(darwin) for mac pro. 2.0.137.
|
||||||
* v2.0, 2015-02-24, fix [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), support dvr http api. 2.0.123.
|
* v2.0, 2015-03-08, fix [#316](https://github.com/winlinvip/simple-rtmp-server/issues/316), http api provides stream/vhost/srs/server bytes, codec and count. 2.0.136.
|
||||||
|
* v2.0, 2015-03-08, fix [#310](https://github.com/winlinvip/simple-rtmp-server/issues/310), refine aac LC, support aac HE/HEv2. 2.0.134.
|
||||||
|
* v2.0, 2015-03-06, for [#322](https://github.com/winlinvip/simple-rtmp-server/issues/322), fix http-flv stream bug, support multiple streams. 2.0.133.
|
||||||
|
* v2.0, 2015-03-06, refine http request parse. 2.0.132.
|
||||||
|
* v2.0, 2015-03-01, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), revert dvr http api. 2.0.128.
|
||||||
|
* v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124
|
||||||
* v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122.
|
* v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122.
|
||||||
* v2.0, 2015-02-19, refine pithy print to more easyer to use. 2.0.121.
|
* v2.0, 2015-02-19, refine pithy print to more easyer to use. 2.0.121.
|
||||||
* v2.0, 2015-02-18, fix [#133](https://github.com/winlinvip/simple-rtmp-server/issues/133), support push rtsp to srs. 2.0.120.
|
* v2.0, 2015-02-18, fix [#133](https://github.com/winlinvip/simple-rtmp-server/issues/133), support push rtsp to srs. 2.0.120.
|
||||||
|
|
BIN
trunk/3rdparty/libaacplus-2.0.2.zip
vendored
BIN
trunk/3rdparty/libaacplus-2.0.2.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/libaacplus-patch-26410-800.zip
vendored
BIN
trunk/3rdparty/libaacplus-patch-26410-800.zip
vendored
Binary file not shown.
17
trunk/3rdparty/patches/2.http.parser.patch
vendored
Normal file
17
trunk/3rdparty/patches/2.http.parser.patch
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
diff -r -c ./Makefile ../http-parser-2.1/Makefile
|
||||||
|
*** ./Makefile Tue Mar 10 10:44:19 2015
|
||||||
|
--- ../http-parser-2.1/Makefile Wed Mar 27 06:35:20 2013
|
||||||
|
***************
|
||||||
|
*** 12,22 ****
|
||||||
|
CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA)
|
||||||
|
CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
||||||
|
|
||||||
|
- # patch by winlin
|
||||||
|
- CPPFLAGS_FAST = $(CPPFLAGS_DEBUG)
|
||||||
|
- CFLAGS_FAST = $(CFLAGS_DEBUG)
|
||||||
|
- CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
||||||
|
-
|
||||||
|
test: test_g test_fast
|
||||||
|
./test_g
|
||||||
|
./test_fast
|
||||||
|
--- 12,17 ----
|
8
trunk/3rdparty/readme.txt
vendored
8
trunk/3rdparty/readme.txt
vendored
|
@ -16,8 +16,6 @@ CherryPy-3.2.4.zip
|
||||||
ffmpeg-2.1.1.tar.gz
|
ffmpeg-2.1.1.tar.gz
|
||||||
yasm-1.2.0.tar.gz
|
yasm-1.2.0.tar.gz
|
||||||
lame-3.99.5.tar.gz
|
lame-3.99.5.tar.gz
|
||||||
libaacplus-2.0.2.tar.gz
|
|
||||||
libaacplus-patch-26410-800.zip (26410-800.zip)
|
|
||||||
speex-1.2rc1.zip
|
speex-1.2rc1.zip
|
||||||
x264-snapshot-20131129-2245-stable.tar.bz2 (core.138)
|
x264-snapshot-20131129-2245-stable.tar.bz2 (core.138)
|
||||||
for srs to support live stream transcoding.
|
for srs to support live stream transcoding.
|
||||||
|
@ -55,12 +53,6 @@ links:
|
||||||
lame:
|
lame:
|
||||||
http://sourceforge.net/projects/lame/
|
http://sourceforge.net/projects/lame/
|
||||||
http://nchc.dl.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
|
http://nchc.dl.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
|
||||||
aacplus:
|
|
||||||
http://217.20.164.161/~tipok/aacplus/
|
|
||||||
http://217.20.164.161/~tipok/aacplus/libaacplus-2.0.2.tar.gz
|
|
||||||
aacplus-patch:
|
|
||||||
http://www.3gpp.org/DynaReport/26410.htm
|
|
||||||
http://www.3gpp.org/ftp/Specs/archive/26_series/26.410/26410-800.zip
|
|
||||||
yasm:
|
yasm:
|
||||||
http://yasm.tortall.net/
|
http://yasm.tortall.net/
|
||||||
http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
|
http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
|
||||||
|
|
251
trunk/auto/auto_headers.sh
Executable file
251
trunk/auto/auto_headers.sh
Executable file
|
@ -0,0 +1,251 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# output variables:
|
||||||
|
# SRS_AUTO_HEADERS_H: the auto generated header file.
|
||||||
|
|
||||||
|
SRS_AUTO_HEADERS_H="${SRS_OBJS}/srs_auto_headers.hpp"
|
||||||
|
|
||||||
|
# write user options to headers
|
||||||
|
echo "// auto generated by configure" > $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#ifndef SRS_AUTO_HEADER_HPP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_HEADER_HPP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
echo "#define SRS_AUTO_BUILD_TS \"`date +%s`\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_BUILD_DATE \"`date \"+%Y-%m-%d %H:%M:%S\"`\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_UNAME \"`uname -a`\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_USER_CONFIGURE \"${SRS_AUTO_USER_CONFIGURE}\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_CONFIGURE \"${SRS_AUTO_CONFIGURE}\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
# export the preset.
|
||||||
|
if [ $SRS_OSX = YES ]; then
|
||||||
|
echo "#define SRS_OSX" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_X86_X64 = YES ]; then
|
||||||
|
echo "#define SRS_X86_X64" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||||
|
echo "#define SRS_ARM_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||||
|
echo "#define SRS_MIPS_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_PI = YES ]; then
|
||||||
|
echo "#define SRS_PI" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_CUBIE = YES ]; then
|
||||||
|
echo "#define SRS_CUBIE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# generate auto headers file, depends on the finished of options.sh
|
||||||
|
#####################################################################################
|
||||||
|
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||||
|
__SrsArmCC="arm-linux-gnueabi-gcc";
|
||||||
|
__SrsArmGCC="arm-linux-gnueabi-gcc";
|
||||||
|
__SrsArmCXX="arm-linux-gnueabi-g++";
|
||||||
|
__SrsArmAR="arm-linux-gnueabi-ar";
|
||||||
|
__SrsArmLD="arm-linux-gnueabi-ld";
|
||||||
|
__SrsArmRANDLIB="arm-linux-gnueabi-ranlib";
|
||||||
|
fi
|
||||||
|
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||||
|
__SrsArmCC="mipsel-openwrt-linux-gcc";
|
||||||
|
__SrsArmGCC="mipsel-openwrt-linux-gcc";
|
||||||
|
__SrsArmCXX="mipsel-openwrt-linux-g++";
|
||||||
|
__SrsArmAR="mipsel-openwrt-linux-ar";
|
||||||
|
__SrsArmLD="mipsel-openwrt-linux-ld";
|
||||||
|
__SrsArmRANDLIB="mipsel-openwrt-linux-ranlib";
|
||||||
|
fi
|
||||||
|
# the arm-ubuntu12 options for make for depends
|
||||||
|
if [[ -z $SrsArmCC ]]; then SrsArmCC=$__SrsArmCC; fi
|
||||||
|
if [[ -z $SrsArmGCC ]]; then SrsArmGCC=$__SrsArmGCC; fi
|
||||||
|
if [[ -z $SrsArmCXX ]]; then SrsArmCXX=$__SrsArmCXX; fi
|
||||||
|
if [[ -z $SrsArmAR ]]; then SrsArmAR=$__SrsArmAR; fi
|
||||||
|
if [[ -z $SrsArmLD ]]; then SrsArmLD=$__SrsArmLD; fi
|
||||||
|
if [[ -z $SrsArmRANDLIB ]]; then SrsArmRANDLIB=$__SrsArmRANDLIB; fi
|
||||||
|
# write to source file
|
||||||
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
|
echo "cc=$SrsArmCC gcc=$SrsArmGCC g++=$SrsArmCXX ar=$SrsArmAR ld=$SrsArmLD randlib=$SrsArmRANDLIB"
|
||||||
|
echo "#define SRS_AUTO_EMBEDED_TOOL_CHAIN \"cc=$SrsArmCC gcc=$SrsArmGCC g++=$SrsArmCXX ar=$SrsArmAR ld=$SrsArmLD randlib=$SrsArmRANDLIB\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#define SRS_AUTO_EMBEDED_TOOL_CHAIN \"normal x86/x64 gcc\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
# auto headers in depends.
|
||||||
|
if [ $SRS_HTTP_PARSER = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_HTTP_PARSER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_HTTP_PARSER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_HTTP_SERVER = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_HTTP_SERVER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_HTTP_SERVER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_STREAM_CASTER = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_HTTP_API = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_HTTP_API" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_HTTP_API" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_NGINX = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_NGINX" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_NGINX" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_DVR = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_DVR" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_DVR" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_HLS = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_HLS" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_HLS" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_HTTP_CALLBACK = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_HTTP_CALLBACK" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_HTTP_CALLBACK" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_SSL = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_SSL" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_SSL" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# whether compile ffmpeg tool
|
||||||
|
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_FFMPEG_TOOL" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_FFMPEG_TOOL" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# whatever the FFMPEG tools, if transcode and ingest specified,
|
||||||
|
# srs always compile the FFMPEG tool stub which used to start the FFMPEG process.
|
||||||
|
if [ $SRS_FFMPEG_STUB = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_FFMPEG_STUB" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_FFMPEG_STUB" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_TRANSCODE = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_TRANSCODE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_TRANSCODE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_INGEST = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_INGEST" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_INGEST" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# for statistic.
|
||||||
|
if [ $SRS_STAT = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_STAT" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_STAT" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_GPERF = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_GPERF" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_GPERF" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_GPERF_MC = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_GPERF_MC" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_GPERF_MC" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_GPERF_MP = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_GPERF_MP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_GPERF_MP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_GPERF_CP = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_GPERF_CP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_GPERF_CP" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# for embeded.
|
||||||
|
#####################################################################################
|
||||||
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_EMBEDED_CPU" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_EMBEDED_CPU" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# arm
|
||||||
|
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_ARM_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_ARM_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# mips
|
||||||
|
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_MIPS_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_MIPS_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
# for log level compile settings
|
||||||
|
if [ $SRS_LOG_VERBOSE = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_VERBOSE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_VERBOSE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_LOG_INFO = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_INFO" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_INFO" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
if [ $SRS_LOG_TRACE = YES ]; then
|
||||||
|
echo "#define SRS_AUTO_TRACE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
else
|
||||||
|
echo "#undef SRS_AUTO_TRACE" >> $SRS_AUTO_HEADERS_H
|
||||||
|
fi
|
||||||
|
|
||||||
|
# prefix
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_AUTO_PREFIX \"${SRS_PREFIX}\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# generated the contributors from AUTHORS.txt
|
||||||
|
#####################################################################################
|
||||||
|
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
||||||
|
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
||||||
|
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
||||||
|
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
||||||
|
done
|
||||||
|
echo "\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
# new empty line to auto headers file.
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
# auto header EOF.
|
||||||
|
echo "#endif" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
ff_src_dir="../../3rdparty"
|
ff_src_dir="../../3rdparty"
|
||||||
|
|
||||||
# the jobs to make ffmpeg
|
# the jobs to make ffmpeg
|
||||||
if [[ "" -eq SRS_JOBS ]]; then
|
if [[ "" == $SRS_JOBS ]]; then
|
||||||
export SRS_JOBS="--jobs=1"
|
export SRS_JOBS="--jobs=1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -38,9 +38,6 @@ fi
|
||||||
# ffmpeg can specifies the yasm path when configure it.
|
# ffmpeg can specifies the yasm path when configure it.
|
||||||
export PATH=${PATH}:${ff_release_dir}/bin
|
export PATH=${PATH}:${ff_release_dir}/bin
|
||||||
|
|
||||||
# the aac command for ffmepg.
|
|
||||||
AAC_FOR_FFMPEG="--enable-libfdk-aac"
|
|
||||||
|
|
||||||
# libfdk-aac
|
# libfdk-aac
|
||||||
if [[ -f ${ff_release_dir}/lib/libfdk-aac.a ]]; then
|
if [[ -f ${ff_release_dir}/lib/libfdk-aac.a ]]; then
|
||||||
echo "libfdk_aac is ok"
|
echo "libfdk_aac is ok"
|
||||||
|
@ -52,24 +49,6 @@ else
|
||||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build fdk-aac-0.1.3 failed"; exit 1; fi
|
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build fdk-aac-0.1.3 failed"; exit 1; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# libaacplus
|
|
||||||
if [ $UBUNTU14 = NO ]; then
|
|
||||||
AAC_FOR_FFMPEG="$AAC_FOR_FFMPEG --enable-libaacplus"
|
|
||||||
|
|
||||||
if [[ -f ${ff_release_dir}/lib/libaacplus.a ]]; then
|
|
||||||
echo "libaacplus is ok"
|
|
||||||
else
|
|
||||||
echo "build libaacplus-2.0.2"
|
|
||||||
cd $ff_current_dir &&
|
|
||||||
rm -rf libaacplus-2.0.2 && unzip -q ${ff_src_dir}/libaacplus-2.0.2.zip &&
|
|
||||||
cd libaacplus-2.0.2 && cp ../${ff_src_dir}/libaacplus-patch-26410-800.zip src/26410-800.zip &&
|
|
||||||
bash autogen.sh && ./configure --prefix=${ff_release_dir} --enable-static && make && make install
|
|
||||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build libaacplus-2.0.2 failed"; exit 1; fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "aac for ffmepg: $AAC_FOR_FFMPEG"
|
|
||||||
|
|
||||||
# lame-3.99
|
# lame-3.99
|
||||||
if [[ -f ${ff_release_dir}/lib/libmp3lame.a ]]; then
|
if [[ -f ${ff_release_dir}/lib/libmp3lame.a ]]; then
|
||||||
echo "libmp3lame is ok"
|
echo "libmp3lame is ok"
|
||||||
|
@ -128,7 +107,7 @@ else
|
||||||
--extra-ldflags='-L${ffmpeg_exported_release_dir}/lib -lm -ldl' \
|
--extra-ldflags='-L${ffmpeg_exported_release_dir}/lib -lm -ldl' \
|
||||||
--disable-ffplay --disable-ffprobe --disable-ffserver --disable-doc \
|
--disable-ffplay --disable-ffprobe --disable-ffserver --disable-doc \
|
||||||
--enable-postproc --enable-bzlib --enable-zlib --enable-parsers \
|
--enable-postproc --enable-bzlib --enable-zlib --enable-parsers \
|
||||||
--enable-libx264 --enable-libmp3lame $AAC_FOR_FFMPEG --enable-libspeex \
|
--enable-libx264 --enable-libmp3lame --enable-libfdk-aac --enable-libspeex \
|
||||||
--enable-pthreads --extra-libs=-lpthread \
|
--enable-pthreads --extra-libs=-lpthread \
|
||||||
--enable-encoders --enable-decoders --enable-avfilter --enable-muxers --enable-demuxers &&
|
--enable-encoders --enable-decoders --enable-avfilter --enable-muxers --enable-demuxers &&
|
||||||
make ${SRS_JOBS} && make install
|
make ${SRS_JOBS} && make install
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
# variables, parent script must set it:
|
# variables, parent script must set it:
|
||||||
# SRS_JOBS: the build jobs.
|
# SRS_JOBS: the build jobs.
|
||||||
# SrsArmMakeOptions: the arm make options for ubuntu12(armhf, v7cpu)
|
# SrsArmMakeOptions: the arm make options for ubuntu12(armhf, v7cpu)
|
||||||
# SRS_AUTO_HEADERS_H: the auto generated header file.
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
@ -42,6 +41,24 @@ function Ubuntu_prepare()
|
||||||
return 0;
|
return 0;
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# for arm, install the cross build tool chain.
|
||||||
|
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||||
|
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi"
|
||||||
|
require_sudoer "sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi"
|
||||||
|
sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi success"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# for mips, user must installed the tool chain.
|
||||||
|
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||||
|
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "user must install the tool chain: $SrsArmCC"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
OS_IS_UBUNTU=YES
|
OS_IS_UBUNTU=YES
|
||||||
echo "Ubuntu detected, install tools if needed"
|
echo "Ubuntu detected, install tools if needed"
|
||||||
|
@ -74,6 +91,13 @@ function Ubuntu_prepare()
|
||||||
echo "install patch success"
|
echo "install patch success"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
unzip --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install unzip"
|
||||||
|
require_sudoer "sudo apt-get install -y --force-yes unzip"
|
||||||
|
sudo apt-get install -y --force-yes unzip; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install unzip success"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
echo "install autoconf"
|
echo "install autoconf"
|
||||||
|
@ -104,24 +128,6 @@ function Ubuntu_prepare()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# for arm, install the cross build tool chain.
|
|
||||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
|
||||||
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
|
||||||
echo "install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi"
|
|
||||||
require_sudoer "sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi"
|
|
||||||
sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
|
||||||
echo "install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi success"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# for mips, user must installed the tool chain.
|
|
||||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
|
||||||
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
|
||||||
echo "user must install the tool chain: $SrsArmCC"
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Ubuntu install tools success"
|
echo "Ubuntu install tools success"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -138,6 +144,12 @@ function Centos_prepare()
|
||||||
if [[ ! -f /etc/redhat-release ]]; then
|
if [[ ! -f /etc/redhat-release ]]; then
|
||||||
return 0;
|
return 0;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# for arm, install the cross build tool chain.
|
||||||
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
|
echo "embeded(arm/mips) is invalid for CentOS"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
OS_IS_CENTOS=YES
|
OS_IS_CENTOS=YES
|
||||||
echo "Centos detected, install tools if needed"
|
echo "Centos detected, install tools if needed"
|
||||||
|
@ -170,6 +182,13 @@ function Centos_prepare()
|
||||||
echo "install patch success"
|
echo "install patch success"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
unzip --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install unzip"
|
||||||
|
require_sudoer "sudo yum install -y unzip"
|
||||||
|
sudo yum install -y unzip; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install unzip success"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
automake --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
automake --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
echo "install automake"
|
echo "install automake"
|
||||||
|
@ -207,12 +226,6 @@ function Centos_prepare()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# for arm, install the cross build tool chain.
|
|
||||||
if [ $SRS_EMBEDED_CPU = YES ]; then
|
|
||||||
echo "embeded(arm/mips) is invalid for CentOS"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Centos install tools success"
|
echo "Centos install tools success"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -220,13 +233,151 @@ function Centos_prepare()
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
Centos_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "CentOS prepare failed, ret=$ret"; exit $ret; fi
|
Centos_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "CentOS prepare failed, ret=$ret"; exit $ret; fi
|
||||||
fi
|
fi
|
||||||
|
#####################################################################################
|
||||||
|
# for Centos, auto install tools by yum
|
||||||
|
#####################################################################################
|
||||||
|
OS_IS_OSX=NO
|
||||||
|
function OSX_prepare()
|
||||||
|
{
|
||||||
|
uname -s|grep Darwin >/dev/null 2>&1
|
||||||
|
ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
if [ $SRS_OSX = YES ]; then
|
||||||
|
echo "OSX check failed, actual is `uname -s`"
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
return 0;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# for arm, install the cross build tool chain.
|
||||||
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
|
echo "embeded(arm/mips) is invalid for OSX"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OS_IS_OSX=YES
|
||||||
|
echo "OSX detected, install tools if needed"
|
||||||
|
|
||||||
|
brew --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install brew"
|
||||||
|
echo "ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\""
|
||||||
|
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install brew success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install gcc"
|
||||||
|
echo "brew install gcc"
|
||||||
|
brew install gcc; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install gcc success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
g++ --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install gcc-c++"
|
||||||
|
echo "brew install gcc-c++"
|
||||||
|
brew install gcc-c++; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install gcc-c++ success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
make --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install make"
|
||||||
|
echo "brew install make"
|
||||||
|
brew install make; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install make success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
patch --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install patch"
|
||||||
|
echo "brew install patch"
|
||||||
|
brew install patch; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install patch success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unzip --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install unzip"
|
||||||
|
echo "brew install unzip"
|
||||||
|
brew install unzip; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install unzip success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
|
automake --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install automake"
|
||||||
|
echo "brew install automake"
|
||||||
|
brew install automake; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install automake success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install autoconf"
|
||||||
|
echo "brew install autoconf"
|
||||||
|
brew install autoconf; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install autoconf success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
libtool --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||||
|
echo "install libtool"
|
||||||
|
echo "brew install libtool"
|
||||||
|
brew install libtool; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install libtool success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f /usr/include/pcre.h ]]; then
|
||||||
|
echo "install pcre-devel"
|
||||||
|
echo "brew install pcre-devel"
|
||||||
|
brew install pcre-devel; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install pcre-devel success"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f /usr/include/zlib.h ]]; then
|
||||||
|
echo "install zlib-devel"
|
||||||
|
echo "brew install zlib-devel"
|
||||||
|
brew install zlib-devel; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||||
|
echo "install zlib-devel success"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "OSX install tools success"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
# donot prepare tools, for srs-librtmp depends only gcc and g++.
|
||||||
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
|
OSX_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "OSX prepare failed, ret=$ret"; exit $ret; fi
|
||||||
|
fi
|
||||||
|
# requires the osx when os
|
||||||
|
if [ $OS_IS_OSX = YES ]; then
|
||||||
|
if [ $SRS_OSX = NO ]; then
|
||||||
|
echo "OSX detected, must specifies the --osx"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# TODO: FIXME: support following features.
|
||||||
|
if [ $SRS_HTTP_API = YES ]; then
|
||||||
|
echo "OSX does not support http-api, use --without-http-api"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $SRS_STAT = YES ]; then
|
||||||
|
echo "OSX does not support stat, use --without-stat"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
|
echo "OSX does not support ffmpeg, use --without-ffmpeg"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ $SRS_NGINX = YES ]; then
|
||||||
|
echo "OSX does not support nginx, use --without-nginx"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# st-1.9
|
# st-1.9
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
# check the arm flag file, if flag changed, need to rebuild the st.
|
# check the arm flag file, if flag changed, need to rebuild the st.
|
||||||
_ST_MAKE=linux-debug
|
_ST_MAKE=linux-debug && _ST_EXTRA_CFLAGS="-DMD_HAVE_EPOLL"
|
||||||
|
# for osx, use darwin for st, donot use epoll.
|
||||||
|
if [ $OS_IS_OSX = YES ]; then
|
||||||
|
_ST_MAKE=darwin-debug && _ST_EXTRA_CFLAGS=""
|
||||||
|
fi
|
||||||
# memory leak for linux-optimized
|
# memory leak for linux-optimized
|
||||||
# @see: https://github.com/winlinvip/simple-rtmp-server/issues/197
|
# @see: https://github.com/winlinvip/simple-rtmp-server/issues/197
|
||||||
if [ $SRS_EMBEDED_CPU = YES ]; then
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
|
@ -240,9 +391,9 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/st-1.9 && cd ${SRS_OBJS} &&
|
rm -rf ${SRS_OBJS}/st-1.9 && cd ${SRS_OBJS} &&
|
||||||
unzip -q ../3rdparty/st-1.9.zip && cd st-1.9 &&
|
unzip -q ../3rdparty/st-1.9.zip && cd st-1.9 &&
|
||||||
patch -p0 < ../../3rdparty/patches/1.st.arm.patch &&
|
patch -p0 -R < ../../3rdparty/patches/1.st.arm.patch &&
|
||||||
make CC=${SrsArmCC} AR=${SrsArmAR} LD=${SrsArmLD} RANDLIB=${SrsArmRANDLIB} \
|
make CC=${SrsArmCC} AR=${SrsArmAR} LD=${SrsArmLD} RANDLIB=${SrsArmRANDLIB} \
|
||||||
EXTRA_CFLAGS="-DMD_HAVE_EPOLL" ${_ST_MAKE} &&
|
EXTRA_CFLAGS=${_ST_EXTRA_CFLAGS} ${_ST_MAKE} &&
|
||||||
cd .. && rm -rf st && ln -sf st-1.9/obj st &&
|
cd .. && rm -rf st && ln -sf st-1.9/obj st &&
|
||||||
cd .. && touch ${SRS_OBJS}/_flag.st.arm.tmp
|
cd .. && touch ${SRS_OBJS}/_flag.st.arm.tmp
|
||||||
)
|
)
|
||||||
|
@ -255,7 +406,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/st-1.9 && cd ${SRS_OBJS} &&
|
rm -rf ${SRS_OBJS}/st-1.9 && cd ${SRS_OBJS} &&
|
||||||
unzip -q ../3rdparty/st-1.9.zip && cd st-1.9 &&
|
unzip -q ../3rdparty/st-1.9.zip && cd st-1.9 &&
|
||||||
make ${_ST_MAKE} EXTRA_CFLAGS="-DMD_HAVE_EPOLL" &&
|
make ${_ST_MAKE} ${_ST_EXTRA_CFLAGS} &&
|
||||||
cd .. && rm -rf st && ln -sf st-1.9/obj st &&
|
cd .. && rm -rf st && ln -sf st-1.9/obj st &&
|
||||||
cd .. && rm -f ${SRS_OBJS}/_flag.st.arm.tmp
|
cd .. && rm -f ${SRS_OBJS}/_flag.st.arm.tmp
|
||||||
)
|
)
|
||||||
|
@ -280,6 +431,7 @@ if [ $SRS_HTTP_PARSER = YES ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/http-parser-2.1 && cd ${SRS_OBJS} && unzip -q ../3rdparty/http-parser-2.1.zip &&
|
rm -rf ${SRS_OBJS}/http-parser-2.1 && cd ${SRS_OBJS} && unzip -q ../3rdparty/http-parser-2.1.zip &&
|
||||||
cd http-parser-2.1 &&
|
cd http-parser-2.1 &&
|
||||||
|
patch -p0 -R < ../../3rdparty/patches/2.http.parser.patch &&
|
||||||
sed -i "s/CPPFLAGS_FAST +=.*$/CPPFLAGS_FAST = \$\(CPPFLAGS_DEBUG\)/g" Makefile &&
|
sed -i "s/CPPFLAGS_FAST +=.*$/CPPFLAGS_FAST = \$\(CPPFLAGS_DEBUG\)/g" Makefile &&
|
||||||
sed -i "s/CFLAGS_FAST =.*$/CFLAGS_FAST = \$\(CFLAGS_DEBUG\)/g" Makefile &&
|
sed -i "s/CFLAGS_FAST =.*$/CFLAGS_FAST = \$\(CFLAGS_DEBUG\)/g" Makefile &&
|
||||||
make CC=${SrsArmCC} AR=${SrsArmAR} package &&
|
make CC=${SrsArmCC} AR=${SrsArmAR} package &&
|
||||||
|
@ -296,8 +448,7 @@ if [ $SRS_HTTP_PARSER = YES ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/http-parser-2.1 && cd ${SRS_OBJS} && unzip -q ../3rdparty/http-parser-2.1.zip &&
|
rm -rf ${SRS_OBJS}/http-parser-2.1 && cd ${SRS_OBJS} && unzip -q ../3rdparty/http-parser-2.1.zip &&
|
||||||
cd http-parser-2.1 &&
|
cd http-parser-2.1 &&
|
||||||
sed -i "s/CPPFLAGS_FAST +=.*$/CPPFLAGS_FAST = \$\(CPPFLAGS_DEBUG\)/g" Makefile &&
|
patch -p0 -R < ../../3rdparty/patches/2.http.parser.patch &&
|
||||||
sed -i "s/CFLAGS_FAST =.*$/CFLAGS_FAST = \$\(CFLAGS_DEBUG\)/g" Makefile &&
|
|
||||||
make package &&
|
make package &&
|
||||||
cd .. && rm -rf hp && ln -sf http-parser-2.1 hp &&
|
cd .. && rm -rf hp && ln -sf http-parser-2.1 hp &&
|
||||||
cd .. && rm -f ${SRS_OBJS}/_flag.st.hp.tmp
|
cd .. && rm -f ${SRS_OBJS}/_flag.st.hp.tmp
|
||||||
|
@ -311,30 +462,6 @@ if [ $SRS_HTTP_PARSER = YES ]; then
|
||||||
if [[ ! -f ${SRS_OBJS}/hp/libhttp_parser.a ]]; then echo "build http-parser-2.1 failed"; exit -1; fi
|
if [[ ! -f ${SRS_OBJS}/hp/libhttp_parser.a ]]; then echo "build http-parser-2.1 failed"; exit -1; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $SRS_HTTP_PARSER = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_HTTP_PARSER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_HTTP_PARSER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_HTTP_SERVER = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_HTTP_SERVER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_HTTP_SERVER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_STREAM_CASTER = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_HTTP_API = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_HTTP_API" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_HTTP_API" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# nginx for HLS, nginx-1.5.0
|
# nginx for HLS, nginx-1.5.0
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
@ -406,24 +533,6 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
echo "nginx is ok" > ${SRS_OBJS}/nginx/html/nginx.html
|
echo "nginx is ok" > ${SRS_OBJS}/nginx/html/nginx.html
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $SRS_NGINX = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_NGINX" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_NGINX" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_DVR = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_DVR" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_DVR" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_HLS = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_HLS" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_HLS" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# cherrypy for http hooks callback, CherryPy-3.2.4
|
# cherrypy for http hooks callback, CherryPy-3.2.4
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
@ -431,7 +540,7 @@ if [ $SRS_HTTP_CALLBACK = YES ]; then
|
||||||
if [[ -f ${SRS_OBJS}/CherryPy-3.2.4/setup.py ]]; then
|
if [[ -f ${SRS_OBJS}/CherryPy-3.2.4/setup.py ]]; then
|
||||||
echo "CherryPy-3.2.4 is ok.";
|
echo "CherryPy-3.2.4 is ok.";
|
||||||
else
|
else
|
||||||
require_sudoer "configure --with-http-callback"
|
require_sudoer "install CherryPy-3.2.4"
|
||||||
echo "install CherryPy-3.2.4";
|
echo "install CherryPy-3.2.4";
|
||||||
(
|
(
|
||||||
sudo rm -rf ${SRS_OBJS}/CherryPy-3.2.4 && cd ${SRS_OBJS} &&
|
sudo rm -rf ${SRS_OBJS}/CherryPy-3.2.4 && cd ${SRS_OBJS} &&
|
||||||
|
@ -444,12 +553,6 @@ if [ $SRS_HTTP_CALLBACK = YES ]; then
|
||||||
if [ ! -f ${SRS_OBJS}/CherryPy-3.2.4/setup.py ]; then echo "build CherryPy-3.2.4 failed."; exit -1; fi
|
if [ ! -f ${SRS_OBJS}/CherryPy-3.2.4/setup.py ]; then echo "build CherryPy-3.2.4 failed."; exit -1; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $SRS_HTTP_CALLBACK = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_HTTP_CALLBACK" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_HTTP_CALLBACK" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
echo "link players to cherrypy static-dir"
|
echo "link players to cherrypy static-dir"
|
||||||
rm -rf research/api-server/static-dir/players &&
|
rm -rf research/api-server/static-dir/players &&
|
||||||
|
@ -489,9 +592,11 @@ fi
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# extra configure options
|
# extra configure options
|
||||||
CONFIGURE_TOOL="./config"
|
CONFIGURE_TOOL="./config"
|
||||||
EXTRA_CONFIGURE=""
|
|
||||||
if [ $SRS_EMBEDED_CPU = YES ]; then
|
if [ $SRS_EMBEDED_CPU = YES ]; then
|
||||||
CONFIGURE_TOOL="./Configure"
|
CONFIGURE_TOOL="./Configure linux-armv4"
|
||||||
|
fi
|
||||||
|
if [ $SRS_OSX = YES ]; then
|
||||||
|
CONFIGURE_TOOL="./Configure darwin64-`uname -m`-cc"
|
||||||
fi
|
fi
|
||||||
# @see http://www.openssl.org/news/secadv_20140407.txt
|
# @see http://www.openssl.org/news/secadv_20140407.txt
|
||||||
# Affected users should upgrade to OpenSSL 1.0.1g. Users unable to immediately
|
# Affected users should upgrade to OpenSSL 1.0.1g. Users unable to immediately
|
||||||
|
@ -510,7 +615,7 @@ if [ $SRS_SSL = YES ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} &&
|
rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} &&
|
||||||
unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f &&
|
unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f &&
|
||||||
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared no-asm linux-armv4 -DOPENSSL_NO_HEARTBEATS ${EXTRA_CONFIGURE} &&
|
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared no-asm &&
|
||||||
make CC=${SrsArmCC} GCC=${SrsArmGCC} AR="${SrsArmAR} r" \
|
make CC=${SrsArmCC} GCC=${SrsArmGCC} AR="${SrsArmAR} r" \
|
||||||
LD=${SrsArmLD} LINK=${SrsArmGCC} RANDLIB=${SrsArmRANDLIB} &&
|
LD=${SrsArmLD} LINK=${SrsArmGCC} RANDLIB=${SrsArmRANDLIB} &&
|
||||||
make install_sw &&
|
make install_sw &&
|
||||||
|
@ -527,7 +632,7 @@ if [ $SRS_SSL = YES ]; then
|
||||||
(
|
(
|
||||||
rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} &&
|
rm -rf ${SRS_OBJS}/openssl-1.0.1f && cd ${SRS_OBJS} &&
|
||||||
unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f &&
|
unzip -q ../3rdparty/openssl-1.0.1f.zip && cd openssl-1.0.1f &&
|
||||||
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared -DOPENSSL_NO_HEARTBEATS ${EXTRA_CONFIGURE} &&
|
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared &&
|
||||||
make && make install_sw &&
|
make && make install_sw &&
|
||||||
cd .. && rm -rf openssl && ln -sf openssl-1.0.1f/_release openssl &&
|
cd .. && rm -rf openssl && ln -sf openssl-1.0.1f/_release openssl &&
|
||||||
cd .. && rm -f ${SRS_OBJS}/_flag.ssl.arm.tmp
|
cd .. && rm -f ${SRS_OBJS}/_flag.ssl.arm.tmp
|
||||||
|
@ -540,12 +645,6 @@ if [ $SRS_SSL = YES ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $SRS_SSL = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_SSL" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_SSL" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# live transcoding, ffmpeg-2.1, x264-core138, lame-3.99.5, libaacplus-2.0.2.
|
# live transcoding, ffmpeg-2.1, x264-core138, lame-3.99.5, libaacplus-2.0.2.
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
@ -566,40 +665,6 @@ if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||||
if [ ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]; then echo "build ffmpeg-2.1 failed."; exit -1; fi
|
if [ ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]; then echo "build ffmpeg-2.1 failed."; exit -1; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# whether compile ffmpeg tool
|
|
||||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_FFMPEG_TOOL" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_FFMPEG_TOOL" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
# whatever the FFMPEG tools, if transcode and ingest specified,
|
|
||||||
# srs always compile the FFMPEG tool stub which used to start the FFMPEG process.
|
|
||||||
if [ $SRS_FFMPEG_STUB = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_FFMPEG_STUB" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_FFMPEG_STUB" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_TRANSCODE = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_TRANSCODE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_TRANSCODE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $SRS_INGEST = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_INGEST" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_INGEST" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
# for statistic.
|
|
||||||
if [ $SRS_STAT = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_STAT" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_STAT" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# build research code, librtmp
|
# build research code, librtmp
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
@ -663,89 +728,8 @@ if [ $SRS_GPERF = YES ]; then
|
||||||
if [ ! -f ${SRS_OBJS}/gperf/bin/pprof ]; then echo "build gperftools-2.1 failed."; exit -1; fi
|
if [ ! -f ${SRS_OBJS}/gperf/bin/pprof ]; then echo "build gperftools-2.1 failed."; exit -1; fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $SRS_GPERF = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_GPERF" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_GPERF" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
if [ $SRS_GPERF_MC = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_GPERF_MC" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_GPERF_MC" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
if [ $SRS_GPERF_MP = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_GPERF_MP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_GPERF_MP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
if [ $SRS_GPERF_CP = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_GPERF_CP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_GPERF_CP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# for embeded.
|
|
||||||
#####################################################################################
|
|
||||||
if [ $SRS_EMBEDED_CPU = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_EMBEDED_CPU" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_EMBEDED_CPU" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
# arm
|
|
||||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_ARM_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_ARM_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
# mips
|
|
||||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_MIPS_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_MIPS_UBUNTU12" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
# for log level compile settings
|
|
||||||
if [ $SRS_LOG_VERBOSE = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_VERBOSE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_VERBOSE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
if [ $SRS_LOG_INFO = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_INFO" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_INFO" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
if [ $SRS_LOG_TRACE = YES ]; then
|
|
||||||
echo "#define SRS_AUTO_TRACE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#undef SRS_AUTO_TRACE" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
|
|
||||||
# prefix
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_PREFIX \"${SRS_PREFIX}\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# generated the contributors from AUTHORS.txt
|
|
||||||
#####################################################################################
|
|
||||||
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
|
||||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
|
||||||
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
|
||||||
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
|
||||||
done
|
|
||||||
echo "\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
# new empty line to auto headers file.
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# generated the test script
|
# generated the test script
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
rm -rf ${SRS_OBJS}/srs.test && ln -sf `pwd`/scripts/srs.test objs/srs.test
|
rm -rf ${SRS_OBJS}/srs.test && ln -sf `pwd`/scripts/srs.test objs/srs.test
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ done
|
||||||
echo "" >> ${FILE}
|
echo "" >> ${FILE}
|
||||||
|
|
||||||
# parent Makefile, to create module output dir before compile it.
|
# parent Makefile, to create module output dir before compile it.
|
||||||
echo " mkdir -p ${SRS_OBJS_DIR}/include" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
echo " @mkdir -p ${SRS_OBJS_DIR}/include" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
echo " mkdir -p ${SRS_OBJS_DIR}/lib" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
echo " @mkdir -p ${SRS_OBJS_DIR}/lib" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
|
||||||
echo -n "generate lib ${LIB_NAME} ok"; echo '!';
|
echo -n "generate lib ${LIB_NAME} ok"; echo '!';
|
||||||
|
|
|
@ -85,6 +85,6 @@ done
|
||||||
echo "" >> ${FILE}
|
echo "" >> ${FILE}
|
||||||
|
|
||||||
# parent Makefile, to create module output dir before compile it.
|
# parent Makefile, to create module output dir before compile it.
|
||||||
echo " mkdir -p ${SRS_OBJS_DIR}/${MODULE_DIR}" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
echo " @mkdir -p ${SRS_OBJS_DIR}/${MODULE_DIR}" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
|
||||||
echo -n "generate module ${MODULE_ID} ok"; echo '!';
|
echo -n "generate module ${MODULE_ID} ok"; echo '!';
|
||||||
|
|
|
@ -68,6 +68,8 @@ SRS_EXPORT_LIBRTMP_SINGLE=NO
|
||||||
# presets
|
# presets
|
||||||
# for x86/x64 pc/servers
|
# for x86/x64 pc/servers
|
||||||
SRS_X86_X64=NO
|
SRS_X86_X64=NO
|
||||||
|
# for osx system
|
||||||
|
SRS_OSX=NO
|
||||||
# armhf(v7cpu) built on ubuntu12
|
# armhf(v7cpu) built on ubuntu12
|
||||||
SRS_ARM_UBUNTU12=NO
|
SRS_ARM_UBUNTU12=NO
|
||||||
# mips built on ubuntu12
|
# mips built on ubuntu12
|
||||||
|
@ -166,6 +168,7 @@ Options:
|
||||||
|
|
||||||
Presets:
|
Presets:
|
||||||
--x86-x64 [default] for x86/x64 cpu, common pc and servers.
|
--x86-x64 [default] for x86/x64 cpu, common pc and servers.
|
||||||
|
--osx for osx(darwin) system to build SRS.
|
||||||
--pi for raspberry-pi(directly build), open features hls/ssl/static.
|
--pi for raspberry-pi(directly build), open features hls/ssl/static.
|
||||||
--cubie for cubieboard(directly build), open features except ffmpeg/nginx.
|
--cubie for cubieboard(directly build), open features except ffmpeg/nginx.
|
||||||
--arm alias for --with-arm-ubuntu12, for ubuntu12, arm crossbuild
|
--arm alias for --with-arm-ubuntu12, for ubuntu12, arm crossbuild
|
||||||
|
@ -260,6 +263,7 @@ function parse_user_option() {
|
||||||
--log-trace) SRS_LOG_TRACE=YES ;;
|
--log-trace) SRS_LOG_TRACE=YES ;;
|
||||||
|
|
||||||
--x86-x64) SRS_X86_X64=YES ;;
|
--x86-x64) SRS_X86_X64=YES ;;
|
||||||
|
--osx) SRS_OSX=YES ;;
|
||||||
--arm) SRS_ARM_UBUNTU12=YES ;;
|
--arm) SRS_ARM_UBUNTU12=YES ;;
|
||||||
--mips) SRS_MIPS_UBUNTU12=YES ;;
|
--mips) SRS_MIPS_UBUNTU12=YES ;;
|
||||||
--pi) SRS_PI=YES ;;
|
--pi) SRS_PI=YES ;;
|
||||||
|
@ -331,7 +335,9 @@ function apply_user_presets() {
|
||||||
if [ $SRS_PI = NO ]; then
|
if [ $SRS_PI = NO ]; then
|
||||||
if [ $SRS_CUBIE = NO ]; then
|
if [ $SRS_CUBIE = NO ]; then
|
||||||
if [ $SRS_X86_X64 = NO ]; then
|
if [ $SRS_X86_X64 = NO ]; then
|
||||||
SRS_X86_X64=YES; opt="--x86-x64 $opt";
|
if [ $SRS_OSX = NO ]; then
|
||||||
|
SRS_X86_X64=YES; opt="--x86-x64 $opt";
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -563,6 +569,32 @@ function apply_user_presets() {
|
||||||
SRS_STATIC=NO
|
SRS_STATIC=NO
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# for osx(darwin)
|
||||||
|
if [ $SRS_OSX = YES ]; then
|
||||||
|
SRS_HLS=YES
|
||||||
|
SRS_DVR=YES
|
||||||
|
SRS_NGINX=NO
|
||||||
|
SRS_SSL=YES
|
||||||
|
SRS_FFMPEG_TOOL=NO
|
||||||
|
SRS_TRANSCODE=YES
|
||||||
|
SRS_INGEST=YES
|
||||||
|
SRS_STAT=NO
|
||||||
|
SRS_HTTP_PARSER=YES
|
||||||
|
SRS_HTTP_CALLBACK=YES
|
||||||
|
SRS_HTTP_SERVER=YES
|
||||||
|
SRS_STREAM_CASTER=YES
|
||||||
|
SRS_HTTP_API=NO
|
||||||
|
SRS_LIBRTMP=YES
|
||||||
|
SRS_RESEARCH=NO
|
||||||
|
SRS_UTEST=NO
|
||||||
|
SRS_GPERF=NO
|
||||||
|
SRS_GPERF_MC=NO
|
||||||
|
SRS_GPERF_MP=NO
|
||||||
|
SRS_GPERF_CP=NO
|
||||||
|
SRS_GPROF=NO
|
||||||
|
SRS_STATIC=NO
|
||||||
|
fi
|
||||||
|
|
||||||
# if dev specified, open features if possible.
|
# if dev specified, open features if possible.
|
||||||
if [ $SRS_DEV = YES ]; then
|
if [ $SRS_DEV = YES ]; then
|
||||||
SRS_HLS=YES
|
SRS_HLS=YES
|
||||||
|
|
|
@ -176,6 +176,6 @@ END
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# parent Makefile, to create module output dir before compile it.
|
# parent Makefile, to create module output dir before compile it.
|
||||||
echo " mkdir -p ${SRS_OBJS_DIR}/utest" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
echo " @mkdir -p ${SRS_OBJS_DIR}/utest" >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
|
||||||
echo -n "generate utest ok"; echo '!';
|
echo -n "generate utest ok"; echo '!';
|
||||||
|
|
|
@ -82,7 +82,7 @@ vhost demo.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -105,7 +105,7 @@ vhost demo.srs.com {
|
||||||
vpreset fast;
|
vpreset fast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 40;
|
abitrate 40;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -151,7 +151,7 @@ vhost players {
|
||||||
vparams {
|
vparams {
|
||||||
g 100;
|
g 100;
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 30;
|
abitrate 30;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
|
|
@ -22,7 +22,7 @@ vhost __defaultVhost__ {
|
||||||
vpreset medium;
|
vpreset medium;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 70;
|
abitrate 70;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
|
|
@ -180,6 +180,8 @@ stream_caster {
|
||||||
caster rtsp;
|
caster rtsp;
|
||||||
output rtmp://127.0.0.1/[app]/[stream];
|
output rtmp://127.0.0.1/[app]/[stream];
|
||||||
listen 554;
|
listen 554;
|
||||||
|
rtp_port_min 57200;
|
||||||
|
rtp_port_max 57300;
|
||||||
}
|
}
|
||||||
|
|
||||||
#############################################################################################
|
#############################################################################################
|
||||||
|
@ -288,44 +290,7 @@ vhost dvr.srs.com {
|
||||||
# session reap flv when session end(unpublish).
|
# session reap flv when session end(unpublish).
|
||||||
# segment reap flv when flv duration exceed the specified dvr_duration.
|
# segment reap flv when flv duration exceed the specified dvr_duration.
|
||||||
# append always append to flv file, never reap it.
|
# append always append to flv file, never reap it.
|
||||||
# api reap flv when api required.
|
|
||||||
# about the api plan, the HTTP api to dvr,
|
|
||||||
# http url to control dvr, for example, http://dev:1985/api/v1/dvrs
|
|
||||||
# method=GET
|
|
||||||
# to query dvrs of server.
|
|
||||||
# request params, for example ?vhost=__defaultVhost__, where:
|
|
||||||
# vhost, query all dvr of this vhost.
|
|
||||||
# response in json, where:
|
|
||||||
# {code:0, dvrs: [{path_tmpl:"./[15].[04].[05].[999].flv", path_dvr:"./22.7.43.312.flv",
|
|
||||||
# wait_keyframe:true, vhost:"__defaultVhost", callback:"http://127.0.0.1:8085/api/v1/dvrs",
|
|
||||||
# status:"stop"|"start"
|
|
||||||
# }]}
|
|
||||||
# method=POST
|
|
||||||
# to start dvr of specified vhost.
|
|
||||||
# request should encode in json, specifies the dvr to create, where:
|
|
||||||
# {path_tmpl:"./[15].[04].[05].[999].flv",
|
|
||||||
# wait_keyframe:true, vhost:"__defaultVhost", callback:"http://127.0.0.1:8085/api/v1/dvrs"
|
|
||||||
# }
|
|
||||||
# response in json, where:
|
|
||||||
# {code:0}
|
|
||||||
# method=DELETE, to stop dvr
|
|
||||||
# to stop dvr of specified vhost.
|
|
||||||
# request params, for example ?vhost=__defaultVhost__, where:
|
|
||||||
# vhost, stop all dvr of this vhost.
|
|
||||||
# response in json, where:
|
|
||||||
# {code:0}
|
|
||||||
# method=PUT, use as RPC(remote process call).
|
|
||||||
# reap_segment, the request params in json, where:
|
|
||||||
# {action:"reap_segment", vhost:"__defaultVhost", path_tmpl:"./[15].[04].[05].[999].flv"}
|
|
||||||
# when reap segment, the callback POST request in json:
|
|
||||||
# {action:"on_dvr_reap_segment", client_id:100, vhost:"__defaultVhost__",
|
|
||||||
# app:"live", stream:"livestream", cwd:"/home/winlin/srs", file:"./dvr.flv"
|
|
||||||
# }
|
|
||||||
# for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com
|
|
||||||
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#http-callback
|
|
||||||
# @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#http-callback
|
|
||||||
# default: session
|
# default: session
|
||||||
# TODO: FIXME: update wiki for the api plan.
|
|
||||||
dvr_plan session;
|
dvr_plan session;
|
||||||
# the dvr output path.
|
# the dvr output path.
|
||||||
# we supports some variables to generate the filename.
|
# we supports some variables to generate the filename.
|
||||||
|
@ -361,27 +326,20 @@ vhost dvr.srs.com {
|
||||||
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#custom-path
|
||||||
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#custom-path
|
||||||
# segment,session apply it.
|
# segment,session apply it.
|
||||||
# api apply before api specified the path.
|
|
||||||
# default: ./objs/nginx/html
|
# default: ./objs/nginx/html
|
||||||
dvr_path ./objs/nginx/html;
|
dvr_path ./objs/nginx/html;
|
||||||
# the duration for dvr file, reap if exeed, in seconds.
|
# the duration for dvr file, reap if exeed, in seconds.
|
||||||
# segment apply it.
|
# segment apply it.
|
||||||
# session,api ignore.
|
# session,append ignore.
|
||||||
# default: 30
|
# default: 30
|
||||||
dvr_duration 30;
|
dvr_duration 30;
|
||||||
# whether wait keyframe to reap segment,
|
# whether wait keyframe to reap segment,
|
||||||
# if off, reap segment when duration exceed the dvr_duration,
|
# if off, reap segment when duration exceed the dvr_duration,
|
||||||
# if on, reap segment when duration exceed and got keyframe.
|
# if on, reap segment when duration exceed and got keyframe.
|
||||||
# segment apply it.
|
# segment apply it.
|
||||||
# session,api ignore.
|
# session,append ignore.
|
||||||
# default: on
|
# default: on
|
||||||
dvr_wait_keyframe on;
|
dvr_wait_keyframe on;
|
||||||
# whether dvr auto start when publish.
|
|
||||||
# if off, dvr wait for api to start it.
|
|
||||||
# api apply it.
|
|
||||||
# segment,session ignore.
|
|
||||||
# default: on
|
|
||||||
dvr_autostart on;
|
|
||||||
# about the stream monotonically increasing:
|
# about the stream monotonically increasing:
|
||||||
# 1. video timestamp is monotonically increasing,
|
# 1. video timestamp is monotonically increasing,
|
||||||
# 2. audio timestamp is monotonically increasing,
|
# 2. audio timestamp is monotonically increasing,
|
||||||
|
@ -576,7 +534,6 @@ vhost with-hls.srs.com {
|
||||||
# the available audio codec:
|
# the available audio codec:
|
||||||
# aac, mp3
|
# aac, mp3
|
||||||
# default: aac
|
# default: aac
|
||||||
# TODO: FIXME: update wiki for it.
|
|
||||||
hls_acodec aac;
|
hls_acodec aac;
|
||||||
# the default video codec of hls.
|
# the default video codec of hls.
|
||||||
# when codec changed, write the PAT/PMT table, but maybe ok util next ts.
|
# when codec changed, write the PAT/PMT table, but maybe ok util next ts.
|
||||||
|
@ -584,7 +541,6 @@ vhost with-hls.srs.com {
|
||||||
# the available video codec:
|
# the available video codec:
|
||||||
# h264, vn
|
# h264, vn
|
||||||
# default: h264
|
# default: h264
|
||||||
# TODO: FIXME: update wiki for it.
|
|
||||||
hls_vcodec h264;
|
hls_vcodec h264;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,12 +788,11 @@ vhost example.transcode.srs.com {
|
||||||
refs 10;
|
refs 10;
|
||||||
}
|
}
|
||||||
# audio encoder name. can be:
|
# audio encoder name. can be:
|
||||||
# libaacplus: use aac(libaacplus) audio encoder.
|
|
||||||
# libfdk_aac: use aac(libfdk_aac) audio encoder.
|
# libfdk_aac: use aac(libfdk_aac) audio encoder.
|
||||||
# copy: donot encoder the audio stream, copy it.
|
# copy: donot encoder the audio stream, copy it.
|
||||||
# an: disable audio output.
|
# an: disable audio output.
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
# audio bitrate, in kbps. [16, 72] for libaacplus.
|
# audio bitrate, in kbps. [16, 72] for libfdk_aac.
|
||||||
abitrate 70;
|
abitrate 70;
|
||||||
# audio sample rate. for flv/rtmp, it must be:
|
# audio sample rate. for flv/rtmp, it must be:
|
||||||
# 44100,22050,11025,5512
|
# 44100,22050,11025,5512
|
||||||
|
@ -847,6 +802,7 @@ vhost example.transcode.srs.com {
|
||||||
# other ffmpeg audio params
|
# other ffmpeg audio params
|
||||||
aparams {
|
aparams {
|
||||||
# audio params, @see: http://ffmpeg.org/ffmpeg-codecs.html#Audio-Encoders
|
# audio params, @see: http://ffmpeg.org/ffmpeg-codecs.html#Audio-Encoders
|
||||||
|
# @remark SRS supported aac profile for HLS is: aac_low, aac_he, aac_he_v2
|
||||||
profile:a aac_low;
|
profile:a aac_low;
|
||||||
}
|
}
|
||||||
# output format, can be:
|
# output format, can be:
|
||||||
|
@ -885,7 +841,7 @@ vhost mirror.transcode.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -918,7 +874,7 @@ vhost crop.transcode.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -949,7 +905,7 @@ vhost logo.transcode.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -969,7 +925,7 @@ vhost audio.transcode.srs.com {
|
||||||
engine acodec {
|
engine acodec {
|
||||||
enabled on;
|
enabled on;
|
||||||
vcodec copy;
|
vcodec copy;
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -988,7 +944,7 @@ vhost vn.transcode.srs.com {
|
||||||
engine vn {
|
engine vn {
|
||||||
enabled on;
|
enabled on;
|
||||||
vcodec vn;
|
vcodec vn;
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1040,7 +996,7 @@ vhost all.transcode.srs.com {
|
||||||
bf 3;
|
bf 3;
|
||||||
refs 10;
|
refs 10;
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 70;
|
abitrate 70;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1062,7 +1018,7 @@ vhost all.transcode.srs.com {
|
||||||
vpreset medium;
|
vpreset medium;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 70;
|
abitrate 70;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1082,7 +1038,7 @@ vhost all.transcode.srs.com {
|
||||||
vpreset fast;
|
vpreset fast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 60;
|
abitrate 60;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1102,7 +1058,7 @@ vhost all.transcode.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1113,7 +1069,7 @@ vhost all.transcode.srs.com {
|
||||||
engine vcopy {
|
engine vcopy {
|
||||||
enabled on;
|
enabled on;
|
||||||
vcodec copy;
|
vcodec copy;
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
@ -1161,7 +1117,7 @@ vhost ffempty.transcode.srs.com {
|
||||||
vpreset superfast;
|
vpreset superfast;
|
||||||
vparams {
|
vparams {
|
||||||
}
|
}
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
|
19
trunk/conf/hds.conf
Normal file
19
trunk/conf/hds.conf
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# the config for srs to delivery hds
|
||||||
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SampleHDS
|
||||||
|
# @see full.conf for detail config.
|
||||||
|
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
|
||||||
|
daemon off;
|
||||||
|
srs_log_tank console;
|
||||||
|
srs_log_level trace;
|
||||||
|
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
hds {
|
||||||
|
enabled on;
|
||||||
|
hds_fragment 10;
|
||||||
|
hds_window 60;
|
||||||
|
hds_path ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
36
trunk/conf/mac.dev.conf
Normal file
36
trunk/conf/mac.dev.conf
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# no-daemon and write log to console config for srs.
|
||||||
|
# @see full.conf for detail config.
|
||||||
|
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
daemon off;
|
||||||
|
srs_log_tank console;
|
||||||
|
http_api {
|
||||||
|
enabled on;
|
||||||
|
listen 1985;
|
||||||
|
}
|
||||||
|
http_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8080;
|
||||||
|
}
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
hls {
|
||||||
|
enabled on;
|
||||||
|
hls_fragment 10;
|
||||||
|
hls_window 60;
|
||||||
|
hls_path ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
ingest livestream {
|
||||||
|
enabled on;
|
||||||
|
input {
|
||||||
|
type file;
|
||||||
|
url ./doc/source.200kbps.768x320.flv;
|
||||||
|
}
|
||||||
|
#ffmpeg ./objs/ffmpeg/bin/ffmpeg;
|
||||||
|
ffmpeg ./objs/research/librtmp/srs_ingest_flv;
|
||||||
|
engine {
|
||||||
|
enabled off;
|
||||||
|
output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
trunk/conf/push.rtsp.conf
Normal file
17
trunk/conf/push.rtsp.conf
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# push MPEG-TS over UDP to SRS.
|
||||||
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_Streamer#push-mpeg-ts-over-udp
|
||||||
|
# @see https://github.com/winlinvip/simple-rtmp-server/issues/250#issuecomment-72321769
|
||||||
|
# @see full.conf for detail config.
|
||||||
|
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
stream_caster {
|
||||||
|
enabled on;
|
||||||
|
caster rtsp;
|
||||||
|
output rtmp://127.0.0.1/[app]/[stream];
|
||||||
|
listen 554;
|
||||||
|
rtp_port_min 57200;
|
||||||
|
rtp_port_max 57300;
|
||||||
|
}
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ vhost __defaultVhost__ {
|
||||||
engine ff {
|
engine ff {
|
||||||
enabled on;
|
enabled on;
|
||||||
vcodec copy;
|
vcodec copy;
|
||||||
acodec libaacplus;
|
acodec libfdk_aac;
|
||||||
abitrate 45;
|
abitrate 45;
|
||||||
asample_rate 44100;
|
asample_rate 44100;
|
||||||
achannels 2;
|
achannels 2;
|
||||||
|
|
505
trunk/configure
vendored
505
trunk/configure
vendored
|
@ -7,14 +7,24 @@
|
||||||
SRS_WORKDIR="."
|
SRS_WORKDIR="."
|
||||||
SRS_OBJS_DIR="objs"
|
SRS_OBJS_DIR="objs"
|
||||||
SRS_OBJS="${SRS_WORKDIR}/${SRS_OBJS_DIR}"
|
SRS_OBJS="${SRS_WORKDIR}/${SRS_OBJS_DIR}"
|
||||||
mkdir -p ${SRS_OBJS}
|
SRS_MAKEFILE="Makefile"
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# linux shell color support.
|
# linux shell color support.
|
||||||
RED="\\e[31m"
|
RED="\\033[31m"
|
||||||
GREEN="\\e[32m"
|
GREEN="\\033[32m"
|
||||||
YELLOW="\\e[33m"
|
YELLOW="\\033[33m"
|
||||||
BLACK="\\e[0m"
|
BLACK="\\033[0m"
|
||||||
|
|
||||||
|
# clean the exists, when not export srs-librtmp.
|
||||||
|
# do this only when the options is ok.
|
||||||
|
if [[ -f Makefile ]]; then
|
||||||
|
make clean
|
||||||
|
fi
|
||||||
|
# remove makefile
|
||||||
|
rm -f ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
|
||||||
|
# create objs
|
||||||
|
mkdir -p ${SRS_OBJS}
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# parse user options, set the variables like:
|
# parse user options, set the variables like:
|
||||||
|
@ -27,82 +37,18 @@ BLACK="\\e[0m"
|
||||||
# for export srs-librtmp, change target to it.
|
# for export srs-librtmp, change target to it.
|
||||||
. auto/generate-srs-librtmp-project.sh
|
. auto/generate-srs-librtmp-project.sh
|
||||||
|
|
||||||
# the auto generated variables.
|
|
||||||
SRS_AUTO_HEADERS_H="${SRS_OBJS}/srs_auto_headers.hpp"
|
|
||||||
|
|
||||||
# clean the exists, when not export srs-librtmp.
|
|
||||||
# do this only when the options is ok.
|
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|
||||||
if [[ -f Makefile ]]; then
|
|
||||||
make clean
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# write user options to headers
|
|
||||||
echo "// auto generated by configure" > $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#ifndef SRS_AUTO_HEADER_HPP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_HEADER_HPP" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
echo "#define SRS_AUTO_BUILD_TS \"`date +%s`\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_BUILD_DATE \"`date \"+%Y-%m-%d %H:%M:%S\"`\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_UNAME \"`uname -a`\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_USER_CONFIGURE \"${SRS_AUTO_USER_CONFIGURE}\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
echo "#define SRS_AUTO_CONFIGURE \"${SRS_AUTO_CONFIGURE}\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
# new empty line to auto headers file.
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# generate auto headers file, depends on the finished of options.sh
|
|
||||||
#####################################################################################
|
|
||||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
|
||||||
__SrsArmCC="arm-linux-gnueabi-gcc";
|
|
||||||
__SrsArmGCC="arm-linux-gnueabi-gcc";
|
|
||||||
__SrsArmCXX="arm-linux-gnueabi-g++";
|
|
||||||
__SrsArmAR="arm-linux-gnueabi-ar";
|
|
||||||
__SrsArmLD="arm-linux-gnueabi-ld";
|
|
||||||
__SrsArmRANDLIB="arm-linux-gnueabi-ranlib";
|
|
||||||
fi
|
|
||||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
|
||||||
__SrsArmCC="mipsel-openwrt-linux-gcc";
|
|
||||||
__SrsArmGCC="mipsel-openwrt-linux-gcc";
|
|
||||||
__SrsArmCXX="mipsel-openwrt-linux-g++";
|
|
||||||
__SrsArmAR="mipsel-openwrt-linux-ar";
|
|
||||||
__SrsArmLD="mipsel-openwrt-linux-ld";
|
|
||||||
__SrsArmRANDLIB="mipsel-openwrt-linux-ranlib";
|
|
||||||
fi
|
|
||||||
# the arm-ubuntu12 options for make for depends
|
|
||||||
if [[ -z $SrsArmCC ]]; then SrsArmCC=$__SrsArmCC; fi
|
|
||||||
if [[ -z $SrsArmGCC ]]; then SrsArmGCC=$__SrsArmGCC; fi
|
|
||||||
if [[ -z $SrsArmCXX ]]; then SrsArmCXX=$__SrsArmCXX; fi
|
|
||||||
if [[ -z $SrsArmAR ]]; then SrsArmAR=$__SrsArmAR; fi
|
|
||||||
if [[ -z $SrsArmLD ]]; then SrsArmLD=$__SrsArmLD; fi
|
|
||||||
if [[ -z $SrsArmRANDLIB ]]; then SrsArmRANDLIB=$__SrsArmRANDLIB; fi
|
|
||||||
# write to source file
|
|
||||||
if [ $SRS_EMBEDED_CPU = YES ]; then
|
|
||||||
echo "cc=$SrsArmCC gcc=$SrsArmGCC g++=$SrsArmCXX ar=$SrsArmAR ld=$SrsArmLD randlib=$SrsArmRANDLIB"
|
|
||||||
echo "#define SRS_AUTO_EMBEDED_TOOL_CHAIN \"cc=$SrsArmCC gcc=$SrsArmGCC g++=$SrsArmCXX ar=$SrsArmAR ld=$SrsArmLD randlib=$SrsArmRANDLIB\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
else
|
|
||||||
echo "#define SRS_AUTO_EMBEDED_TOOL_CHAIN \"normal x86/x64 gcc\"" >> $SRS_AUTO_HEADERS_H
|
|
||||||
fi
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
# apply user options.
|
# apply user options.
|
||||||
. auto/depends.sh
|
. auto/depends.sh
|
||||||
|
|
||||||
# auto header EOF.
|
# the auto generated variables.
|
||||||
echo "#endif" >> $SRS_AUTO_HEADERS_H
|
. auto/auto_headers.sh
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# generate Makefile.
|
# generate Makefile.
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
SRS_MAKEFILE="Makefile"
|
|
||||||
# ubuntu echo in Makefile cannot display color, use bash instead
|
# ubuntu echo in Makefile cannot display color, use bash instead
|
||||||
SRS_BUILD_SUMMARY="_srs_build_summary.sh"
|
SRS_BUILD_SUMMARY="_srs_build_summary.sh"
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# srs-librtmp sample entry
|
# srs-librtmp sample entry
|
||||||
SrsLibrtmpSampleEntry="nossl"
|
SrsLibrtmpSampleEntry="nossl"
|
||||||
if [ $SRS_SSL = YES ]; then SrsLibrtmpSampleEntry="ssl";fi
|
if [ $SRS_SSL = YES ]; then SrsLibrtmpSampleEntry="ssl";fi
|
||||||
|
@ -110,6 +56,203 @@ if [ $SRS_SSL = YES ]; then SrsLibrtmpSampleEntry="ssl";fi
|
||||||
SrsUtestMakeEntry="@echo -e \"ignore utest for it's disabled\""
|
SrsUtestMakeEntry="@echo -e \"ignore utest for it's disabled\""
|
||||||
if [ $SRS_UTEST = YES ]; then SrsUtestMakeEntry="(cd ${SRS_OBJS_DIR}/utest; \$(MAKE))"; fi
|
if [ $SRS_UTEST = YES ]; then SrsUtestMakeEntry="(cd ${SRS_OBJS_DIR}/utest; \$(MAKE))"; fi
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# finger out modules to install.
|
||||||
|
# where srs module is a dir which contains a config file.
|
||||||
|
SRS_MODULES=()
|
||||||
|
__mfiles=`find modules -name "config"` && for __mfile in $__mfiles; do
|
||||||
|
SRS_MODULES+="`dirname $__mfile`"
|
||||||
|
done
|
||||||
|
|
||||||
|
# variables for makefile for all modules.
|
||||||
|
__mphonys="" && __mdefaults="" && __mcleanups=""
|
||||||
|
# add each modules for application
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
echo "install module at: $SRS_MODULE"
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
__mphonys="$__mphonys $SRS_MODULE_NAME"
|
||||||
|
__mdefaults="$__mdefaults $SRS_MODULE_NAME"
|
||||||
|
__mcleanups="$__mcleanups $SRS_MODULE_NAME"
|
||||||
|
done
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# build tools or compiler args.
|
||||||
|
# enable gdb debug
|
||||||
|
GDBDebug=" -g -O0"
|
||||||
|
# the warning level.
|
||||||
|
WarnLevel=" -Wall"
|
||||||
|
# the compile standard.
|
||||||
|
CppStd="-ansi"
|
||||||
|
# for library compile
|
||||||
|
LibraryCompile=" -fPIC"
|
||||||
|
# performance of gprof
|
||||||
|
SrsGprof=""; SrsGprofLink=""; if [ $SRS_GPROF = YES ]; then SrsGprof=" -pg -lc_p"; SrsGprofLink=" -pg"; fi
|
||||||
|
# performance of gperf
|
||||||
|
SrsGperf=""; SrsGperfLink=""; if [ $SRS_GPERF = YES ]; then SrsGperfLink=" -lpthread"; fi
|
||||||
|
# the cxx flag generated.
|
||||||
|
CXXFLAGS="${CppStd}${WarnLevel}${GDBDebug}${LibraryCompile}${SrsGprof}"
|
||||||
|
if [ $SRS_GPERF = YES ]; then CXXFLAGS="${CXXFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"; fi
|
||||||
|
cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
|
||||||
|
GCC = gcc
|
||||||
|
CXX = g++
|
||||||
|
AR = ar
|
||||||
|
LINK = g++
|
||||||
|
CXXFLAGS = ${CXXFLAGS}
|
||||||
|
|
||||||
|
.PHONY: default srs librtmp
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Libraries, external library to build in srs,
|
||||||
|
# header(.h): add to ModuleLibIncs if need the specified library. for example, LibSTRoot
|
||||||
|
# library(.a): add to ModuleLibFiles if binary need the specifeid library. for example, LibSTfile
|
||||||
|
#
|
||||||
|
# st(state-threads) the basic network library for SRS.
|
||||||
|
LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a"
|
||||||
|
# hp(http-parser) the http request/url parser, for SRS to support HTTP callback.
|
||||||
|
LibHttpParserRoot=""; LibHttpParserfile=""
|
||||||
|
if [ $SRS_HTTP_PARSER = YES ]; then LibHttpParserRoot="${SRS_OBJS_DIR}/hp"; LibHttpParserfile="${LibHttpParserRoot}/libhttp_parser.a"; fi
|
||||||
|
# openssl-1.0.1f, for the RTMP complex handshake.
|
||||||
|
LibSSLRoot="";LibSSLfile=""
|
||||||
|
if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS_OBJS_DIR}/openssl/include"; LibSSLfile="${SRS_OBJS_DIR}/openssl/lib/libssl.a ${SRS_OBJS_DIR}/openssl/lib/libcrypto.a"; fi fi
|
||||||
|
# gperftools-2.1, for mem check and mem/cpu profile
|
||||||
|
LibGperfRoot=""; LibGperfFile=""
|
||||||
|
if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi
|
||||||
|
# the link options, always use static link
|
||||||
|
SrsLinkOptions="-ldl";
|
||||||
|
if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl"; fi fi
|
||||||
|
# if static specified, add static
|
||||||
|
# TODO: FIXME: remove static.
|
||||||
|
if [ $SRS_STATIC = YES ]; then SrsLinkOptions="${SrsLinkOptions} -static"; fi
|
||||||
|
# if mips, add -lgcc_eh, or stl compile failed.
|
||||||
|
if [ $SRS_MIPS_UBUNTU12 = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lgcc_eh"; fi
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Modules, compile each module, then link to binary
|
||||||
|
#
|
||||||
|
#Core, depends only on system apis.
|
||||||
|
MODULE_ID="CORE"
|
||||||
|
MODULE_DEPENDS=()
|
||||||
|
ModuleLibIncs=(${SRS_OBJS_DIR})
|
||||||
|
MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance")
|
||||||
|
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh
|
||||||
|
CORE_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
#
|
||||||
|
#Kernel, depends on core, provides error/log/config, nothing about stream information.
|
||||||
|
MODULE_ID="KERNEL"
|
||||||
|
MODULE_DEPENDS=("CORE")
|
||||||
|
ModuleLibIncs=(${SRS_OBJS_DIR})
|
||||||
|
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream"
|
||||||
|
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_file"
|
||||||
|
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
|
||||||
|
"srs_kernel_buffer")
|
||||||
|
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
|
||||||
|
KERNEL_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
#
|
||||||
|
#RTMP Protocol, depends on core/kernel, provides rtmp/htttp protocol features.
|
||||||
|
MODULE_ID="RTMP"
|
||||||
|
MODULE_DEPENDS=("CORE" "KERNEL")
|
||||||
|
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
||||||
|
MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk"
|
||||||
|
"srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer"
|
||||||
|
"srs_raw_avc" "srs_rtsp_stack")
|
||||||
|
RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh
|
||||||
|
RTMP_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
#
|
||||||
|
#App Module
|
||||||
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
|
MODULE_ID="APP"
|
||||||
|
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP")
|
||||||
|
ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${SRS_OBJS_DIR})
|
||||||
|
MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_st_socket" "srs_app_source"
|
||||||
|
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http"
|
||||||
|
"srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
|
||||||
|
"srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
|
||||||
|
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
|
||||||
|
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client"
|
||||||
|
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic"
|
||||||
|
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener")
|
||||||
|
# add each modules for app
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
MODULE_FILES+=($SRS_MODULE_APP)
|
||||||
|
done
|
||||||
|
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
|
||||||
|
APP_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
#LIBS Module, build libsrs.a for static link.
|
||||||
|
MODULE_ID="LIBS"
|
||||||
|
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP")
|
||||||
|
ModuleLibIncs=(${SRS_OBJS_DIR})
|
||||||
|
MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket" "srs_lib_bandwidth")
|
||||||
|
LIBS_INCS="src/libs"; MODULE_DIR=${LIBS_INCS} . auto/modules.sh
|
||||||
|
LIBS_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
#
|
||||||
|
#Main Module
|
||||||
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
|
MODULE_ID="MAIN"
|
||||||
|
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")
|
||||||
|
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibHttpParserRoot})
|
||||||
|
MODULE_FILES=("srs_main_server")
|
||||||
|
# add each modules for main
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
MODULE_FILES+=($SRS_MODULE_MAIN)
|
||||||
|
done
|
||||||
|
MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh
|
||||||
|
MAIN_OBJS="${MODULE_OBJS[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Binaries, main entrances, link the module and its depends modules,
|
||||||
|
# then link to a binary, for example, objs/srs
|
||||||
|
#
|
||||||
|
# disable all app when export librtmp
|
||||||
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
|
# all main entrances
|
||||||
|
MAIN_ENTRANCES=("srs_main_server")
|
||||||
|
# add each modules for main
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
MAIN_ENTRANCES+=($SRS_MODULE_MAIN)
|
||||||
|
done
|
||||||
|
#
|
||||||
|
# all depends libraries
|
||||||
|
ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibGperfFile})
|
||||||
|
# all depends objects
|
||||||
|
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}"
|
||||||
|
LINK_OPTIONS="${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}"
|
||||||
|
#
|
||||||
|
# srs: srs(simple rtmp server) over st(state-threads)
|
||||||
|
BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . auto/apps.sh
|
||||||
|
# add each modules for application
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
BUILD_KEY="$SRS_MODULE_NAME" APP_MAIN="$SRS_MODULE_MAIN" APP_NAME="$SRS_MODULE_NAME" . auto/apps.sh
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
# srs librtmp
|
||||||
|
if [ $SRS_LIBRTMP = YES ]; then
|
||||||
|
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${LIBS_OBJS[@]}"
|
||||||
|
BUILD_KEY="librtmp" LIB_NAME="lib/srs_librtmp" . auto/libs.sh
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# utest, the unit-test cases of srs, base on gtest1.6
|
||||||
|
if [ $SRS_UTEST = YES ]; then
|
||||||
|
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol"
|
||||||
|
"srs_utest_kernel" "srs_utest_core" "srs_utest_config"
|
||||||
|
"srs_utest_reload")
|
||||||
|
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot})
|
||||||
|
ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile})
|
||||||
|
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")
|
||||||
|
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]}"
|
||||||
|
LINK_OPTIONS="-lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . auto/utest.sh
|
||||||
|
fi
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# generate colorful summary script
|
# generate colorful summary script
|
||||||
. auto/summary.sh
|
. auto/summary.sh
|
||||||
|
@ -117,8 +260,14 @@ if [ $SRS_UTEST = YES ]; then SrsUtestMakeEntry="(cd ${SRS_OBJS_DIR}/utest; \$(M
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
# makefile
|
# makefile
|
||||||
echo "generate Makefile"
|
echo "generate Makefile"
|
||||||
|
|
||||||
|
# backup old makefile.
|
||||||
|
rm -f ${SRS_WORKDIR}/${SRS_MAKEFILE}.bk &&
|
||||||
|
mv ${SRS_WORKDIR}/${SRS_MAKEFILE} ${SRS_WORKDIR}/${SRS_MAKEFILE}.bk
|
||||||
|
|
||||||
|
# generate phony header
|
||||||
cat << END > ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
cat << END > ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
.PHONY: default _default install install-api help clean server librtmp utest _prepare_dir
|
.PHONY: default _default install install-api help clean server librtmp utest _prepare_dir $__mphonys
|
||||||
|
|
||||||
# install prefix.
|
# install prefix.
|
||||||
SRS_PREFIX=${SRS_PREFIX}
|
SRS_PREFIX=${SRS_PREFIX}
|
||||||
|
@ -146,23 +295,27 @@ fi
|
||||||
# the server, librtmp and utest
|
# the server, librtmp and utest
|
||||||
# where the bellow will check and disable some entry by only echo.
|
# where the bellow will check and disable some entry by only echo.
|
||||||
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
_default: server librtmp utest
|
_default: server librtmp utest $__mdefaults
|
||||||
@bash objs/_srs_build_summary.sh
|
@bash objs/_srs_build_summary.sh
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: make <help>|<clean>|<server>|<librtmp>|<utest>|<install>|<install-api>|<uninstall>"
|
@echo "Usage: make <help>|<clean>|<server>|<librtmp>|<utest>|<install>|<install-api>|<uninstall>"
|
||||||
@echo " help display this help menu"
|
@echo " help display this help menu"
|
||||||
@echo " clean cleanup project"
|
@echo " clean cleanup project"
|
||||||
@echo " server build the srs(simple rtmp server) over st(state-threads)"
|
@echo " server build the srs(simple rtmp server) over st(state-threads)"
|
||||||
@echo " librtmp build the client publish/play library, and samples"
|
@echo " librtmp build the client publish/play library, and samples"
|
||||||
@echo " utest build the utest for srs"
|
@echo " utest build the utest for srs"
|
||||||
@echo " install install srs to the prefix path"
|
@echo " install install srs to the prefix path"
|
||||||
@echo " install-api install srs and api-server to the prefix path"
|
@echo " install-api install srs and api-server to the prefix path"
|
||||||
@echo " uninstall uninstall srs from prefix path"
|
@echo " uninstall uninstall srs from prefix path"
|
||||||
|
@echo "@remark all modules will auto genearted and build"
|
||||||
|
@echo "For example:"
|
||||||
|
@echo " make"
|
||||||
|
@echo " make help"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
(cd ${SRS_OBJS_DIR}; rm -rf srs srs_utest)
|
(cd ${SRS_OBJS_DIR}; rm -rf srs srs_utest $__mcleanups)
|
||||||
(cd ${SRS_OBJS_DIR}; rm -rf src research include lib)
|
(cd ${SRS_OBJS_DIR}; rm -rf src include lib)
|
||||||
(cd ${SRS_OBJS_DIR}/utest; rm -rf *.o *.a)
|
(cd ${SRS_OBJS_DIR}/utest; rm -rf *.o *.a)
|
||||||
(cd research/librtmp; make clean)
|
(cd research/librtmp; make clean)
|
||||||
(cd research/api-server/static-dir; rm -rf crossdomain.xml forward live players)
|
(cd research/api-server/static-dir; rm -rf crossdomain.xml forward live players)
|
||||||
|
@ -184,6 +337,25 @@ server: _prepare_dir
|
||||||
|
|
||||||
END
|
END
|
||||||
fi
|
fi
|
||||||
|
# generate all modules entry
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
. $SRS_MODULE/config
|
||||||
|
# if export librtmp, donot build the bravo-ingest.
|
||||||
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT != NO ]; then
|
||||||
|
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
$SRS_MODULE_NAME: _prepare_dir
|
||||||
|
@echo "donot build the $SRS_MODULE_NAME for srs-librtmp"
|
||||||
|
|
||||||
|
END
|
||||||
|
else
|
||||||
|
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||||
|
$SRS_MODULE_NAME: _prepare_dir
|
||||||
|
@echo "build the $SRS_MODULE_NAME over SRS"
|
||||||
|
\$(MAKE) -f ${SRS_OBJS_DIR}/${SRS_MAKEFILE} $SRS_MODULE_NAME
|
||||||
|
|
||||||
|
END
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# disable install entry for srs-librtmp
|
# disable install entry for srs-librtmp
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT != NO ]; then
|
if [ $SRS_EXPORT_LIBRTMP_PROJECT != NO ]; then
|
||||||
|
@ -293,164 +465,9 @@ _prepare_dir:
|
||||||
@mkdir -p ${SRS_OBJS_DIR}
|
@mkdir -p ${SRS_OBJS_DIR}
|
||||||
END
|
END
|
||||||
|
|
||||||
#####################################################################################
|
# generate makefile ok, append the tails.
|
||||||
# build tools or compiler args.
|
cat ${SRS_WORKDIR}/${SRS_MAKEFILE}.bk >> ${SRS_WORKDIR}/${SRS_MAKEFILE} &&
|
||||||
# enable gdb debug
|
rm -f ${SRS_WORKDIR}/${SRS_MAKEFILE}.bk
|
||||||
GDBDebug=" -g -O0"
|
|
||||||
# the warning level.
|
|
||||||
WarnLevel=" -Wall"
|
|
||||||
# the compile standard.
|
|
||||||
CppStd="-ansi"
|
|
||||||
# for library compile
|
|
||||||
LibraryCompile=" -fPIC"
|
|
||||||
# performance of gprof
|
|
||||||
SrsGprof=""; SrsGprofLink=""; if [ $SRS_GPROF = YES ]; then SrsGprof=" -pg -lc_p"; SrsGprofLink=" -pg"; fi
|
|
||||||
# performance of gperf
|
|
||||||
SrsGperf=""; SrsGperfLink=""; if [ $SRS_GPERF = YES ]; then SrsGperfLink=" -lpthread"; fi
|
|
||||||
# the cxx flag generated.
|
|
||||||
CXXFLAGS="${CppStd}${WarnLevel}${GDBDebug}${LibraryCompile}${SrsGprof}"
|
|
||||||
if [ $SRS_GPERF = YES ]; then CXXFLAGS="${CXXFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"; fi
|
|
||||||
cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
|
|
||||||
GCC = gcc
|
|
||||||
CXX = g++
|
|
||||||
AR = ar
|
|
||||||
LINK = g++
|
|
||||||
CXXFLAGS = ${CXXFLAGS}
|
|
||||||
|
|
||||||
.PHONY: default srs librtmp
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
END
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# Libraries, external library to build in srs,
|
|
||||||
# header(.h): add to ModuleLibIncs if need the specified library. for example, LibSTRoot
|
|
||||||
# library(.a): add to ModuleLibFiles if binary need the specifeid library. for example, LibSTfile
|
|
||||||
#
|
|
||||||
# st(state-threads) the basic network library for SRS.
|
|
||||||
LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a"
|
|
||||||
# hp(http-parser) the http request/url parser, for SRS to support HTTP callback.
|
|
||||||
LibHttpParserRoot=""; LibHttpParserfile=""
|
|
||||||
if [ $SRS_HTTP_PARSER = YES ]; then LibHttpParserRoot="${SRS_OBJS_DIR}/hp"; LibHttpParserfile="${LibHttpParserRoot}/libhttp_parser.a"; fi
|
|
||||||
# openssl-1.0.1f, for the RTMP complex handshake.
|
|
||||||
LibSSLRoot="";LibSSLfile=""
|
|
||||||
if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS_OBJS_DIR}/openssl/include"; LibSSLfile="${SRS_OBJS_DIR}/openssl/lib/libssl.a ${SRS_OBJS_DIR}/openssl/lib/libcrypto.a"; fi fi
|
|
||||||
# gperftools-2.1, for mem check and mem/cpu profile
|
|
||||||
LibGperfRoot=""; LibGperfFile=""
|
|
||||||
if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi
|
|
||||||
# the link options, always use static link
|
|
||||||
SrsLinkOptions="-ldl";
|
|
||||||
if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl"; fi fi
|
|
||||||
# if static specified, add static
|
|
||||||
# TODO: FIXME: remove static.
|
|
||||||
if [ $SRS_STATIC = YES ]; then SrsLinkOptions="${SrsLinkOptions} -static"; fi
|
|
||||||
# if mips, add -lgcc_eh, or stl compile failed.
|
|
||||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lgcc_eh"; fi
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# Modules, compile each module, then link to binary
|
|
||||||
#
|
|
||||||
#Core, depends only on system apis.
|
|
||||||
MODULE_ID="CORE"
|
|
||||||
MODULE_DEPENDS=()
|
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR})
|
|
||||||
MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance")
|
|
||||||
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh
|
|
||||||
CORE_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
#
|
|
||||||
#Kernel, depends on core, provides error/log/config, nothing about stream information.
|
|
||||||
MODULE_ID="KERNEL"
|
|
||||||
MODULE_DEPENDS=("CORE")
|
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR})
|
|
||||||
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_stream"
|
|
||||||
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_file"
|
|
||||||
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
|
|
||||||
"srs_kernel_buffer")
|
|
||||||
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . auto/modules.sh
|
|
||||||
KERNEL_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
#
|
|
||||||
#RTMP Protocol, depends on core/kernel, provides rtmp/htttp protocol features.
|
|
||||||
MODULE_ID="RTMP"
|
|
||||||
MODULE_DEPENDS=("CORE" "KERNEL")
|
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
|
||||||
MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" "srs_rtmp_sdk"
|
|
||||||
"srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_rtmp_buffer"
|
|
||||||
"srs_raw_avc" "srs_rtsp_stack")
|
|
||||||
RTMP_INCS="src/protocol"; MODULE_DIR=${RTMP_INCS} . auto/modules.sh
|
|
||||||
RTMP_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
#
|
|
||||||
#App Module
|
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|
||||||
MODULE_ID="APP"
|
|
||||||
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP")
|
|
||||||
ModuleLibIncs=(${LibSTRoot} ${LibHttpParserRoot} ${SRS_OBJS_DIR})
|
|
||||||
MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_st_socket" "srs_app_source"
|
|
||||||
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http"
|
|
||||||
"srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
|
|
||||||
"srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
|
|
||||||
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
|
|
||||||
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client"
|
|
||||||
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic"
|
|
||||||
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_hds")
|
|
||||||
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . auto/modules.sh
|
|
||||||
APP_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
fi
|
|
||||||
#
|
|
||||||
#LIBS Module, build libsrs.a for static link.
|
|
||||||
MODULE_ID="LIBS"
|
|
||||||
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP")
|
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR})
|
|
||||||
MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket" "srs_lib_bandwidth")
|
|
||||||
LIBS_INCS="src/libs"; MODULE_DIR=${LIBS_INCS} . auto/modules.sh
|
|
||||||
LIBS_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
#
|
|
||||||
#Main Module
|
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|
||||||
MODULE_ID="MAIN"
|
|
||||||
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")
|
|
||||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot})
|
|
||||||
MODULE_FILES=("srs_main_server")
|
|
||||||
MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh
|
|
||||||
MAIN_OBJS="${MODULE_OBJS[@]}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#####################################################################################
|
|
||||||
# Binaries, main entrances, link the module and its depends modules,
|
|
||||||
# then link to a binary, for example, objs/srs
|
|
||||||
#
|
|
||||||
# disable all app when export librtmp
|
|
||||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|
||||||
# all main entrances
|
|
||||||
MAIN_ENTRANCES=("srs_main_server")
|
|
||||||
#
|
|
||||||
# all depends libraries
|
|
||||||
ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibGperfFile})
|
|
||||||
# all depends objects
|
|
||||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}"
|
|
||||||
LINK_OPTIONS="${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}"
|
|
||||||
#
|
|
||||||
# srs:
|
|
||||||
# srs(simple rtmp server) over st(state-threads)
|
|
||||||
BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . auto/apps.sh
|
|
||||||
fi
|
|
||||||
# srs librtmp
|
|
||||||
if [ $SRS_LIBRTMP = YES ]; then
|
|
||||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${LIBS_OBJS[@]}"
|
|
||||||
BUILD_KEY="librtmp" LIB_NAME="lib/srs_librtmp" . auto/libs.sh
|
|
||||||
fi
|
|
||||||
#
|
|
||||||
# utest, the unit-test cases of srs, base on gtest1.6
|
|
||||||
if [ $SRS_UTEST = YES ]; then
|
|
||||||
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol"
|
|
||||||
"srs_utest_kernel" "srs_utest_core" "srs_utest_config"
|
|
||||||
"srs_utest_reload")
|
|
||||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot})
|
|
||||||
ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile})
|
|
||||||
MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")
|
|
||||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]}"
|
|
||||||
LINK_OPTIONS="-lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . auto/utest.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo 'configure ok! '
|
echo 'configure ok! '
|
||||||
|
|
||||||
|
@ -571,6 +588,10 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}note: mips-ubuntu12 for srs are not builded${BLACK}"
|
echo -e "${GREEN}note: mips-ubuntu12 for srs are not builded${BLACK}"
|
||||||
fi
|
fi
|
||||||
|
# add each modules for application
|
||||||
|
for SRS_MODULE in $SRS_MODULES; do
|
||||||
|
echo -e "${GREEN}module: $SRS_MODULE${BLACK}"
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#####################################################################################
|
#####################################################################################
|
||||||
|
|
|
@ -21,11 +21,11 @@ DEFAULT_LOG_FILE='./objs/srs.log'
|
||||||
########################################################################
|
########################################################################
|
||||||
# utility functions
|
# utility functions
|
||||||
########################################################################
|
########################################################################
|
||||||
RED="\\e[31m"
|
RED="\\033[31m"
|
||||||
GREEN="\\e[32m"
|
GREEN="\\033[32m"
|
||||||
YELLOW="\\e[33m"
|
YELLOW="\\033[33m"
|
||||||
BLACK="\\e[0m"
|
BLACK="\\033[0m"
|
||||||
POS="\\e[60G"
|
POS="\\033[60G"
|
||||||
|
|
||||||
ok_msg() {
|
ok_msg() {
|
||||||
echo -e "${1}${POS}${BLACK}[${GREEN} OK ${BLACK}]"
|
echo -e "${1}${POS}${BLACK}[${GREEN} OK ${BLACK}]"
|
||||||
|
|
5
trunk/ide/readme.txt
Normal file
5
trunk/ide/readme.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
提供了各种ide。
|
||||||
|
|
||||||
|
1. UPP添加Assembly时,路径指向ide即可,譬如:\\dev\winlin\srs\ide
|
||||||
|
|
||||||
|
2015.3 winlin
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 3.1.1, 2015-01-29T11:22:06. -->
|
<!-- Written by QtCreator 3.1.1, 2015-03-05T20:44:44. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
@ -56,12 +56,12 @@
|
||||||
<valuemap type="QVariantMap">
|
<valuemap type="QVariantMap">
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fa2d28f9-85de-4a75-8e79-69d805f974bf}</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{fdda5a74-8ef6-4e67-b28c-c5be6c667578}</value>
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/src/build-qt-Desktop-Debug</value>
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/ide/build-srs-qt-Desktop-Debug</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
@ -119,7 +119,66 @@
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||||
</valuemap>
|
</valuemap>
|
||||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/winlin/git/simple-rtmp-server/trunk/ide/build-srs-qt-Desktop-Release</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
|
||||||
|
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
@ -172,13 +231,13 @@
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">srs-qt</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">srs-qt</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">srs-qt2</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/winlin/git/simple-rtmp-server/trunk/ide/srs_qt/srs-qt.pro</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/winlin/git/simple-rtmp-server/trunk/ide/srs_qt/srs-qt.pro</value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">-c console.conf</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">srs-qt.pro</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">srs-qt.pro</value>
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
|
||||||
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory">/home/winlin/srs</value>
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
|
||||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
|
4
trunk/ide/srs_upp/init
Normal file → Executable file
4
trunk/ide/srs_upp/init
Normal file → Executable file
|
@ -1,3 +1,3 @@
|
||||||
#ifndef _srs_icpp_init_stub
|
#ifndef _ide_srs_upp_icpp_init_stub
|
||||||
#define _srs_icpp_init_stub
|
#define _ide_srs_upp_icpp_init_stub
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,8 +36,8 @@ file
|
||||||
../../src/kernel/srs_kernel_log.cpp,
|
../../src/kernel/srs_kernel_log.cpp,
|
||||||
../../src/kernel/srs_kernel_mp3.hpp,
|
../../src/kernel/srs_kernel_mp3.hpp,
|
||||||
../../src/kernel/srs_kernel_mp3.cpp,
|
../../src/kernel/srs_kernel_mp3.cpp,
|
||||||
../../src/kernel/srs_rtsp_stack.hpp,
|
../../src/kernel/srs_rtsp_stack.hpp,
|
||||||
../../src/kernel/srs_rtsp_stack.cpp,
|
../../src/kernel/srs_rtsp_stack.cpp,
|
||||||
../../src/kernel/srs_kernel_stream.hpp,
|
../../src/kernel/srs_kernel_stream.hpp,
|
||||||
../../src/kernel/srs_kernel_stream.cpp,
|
../../src/kernel/srs_kernel_stream.cpp,
|
||||||
../../src/kernel/srs_kernel_ts.cpp,
|
../../src/kernel/srs_kernel_ts.cpp,
|
||||||
|
@ -45,8 +45,8 @@ file
|
||||||
../../src/kernel/srs_kernel_utility.hpp,
|
../../src/kernel/srs_kernel_utility.hpp,
|
||||||
../../src/kernel/srs_kernel_utility.cpp,
|
../../src/kernel/srs_kernel_utility.cpp,
|
||||||
protocol readonly separator,
|
protocol readonly separator,
|
||||||
../../src/protocol/srs_raw_avc.hpp,
|
../../src/protocol/srs_raw_avc.hpp,
|
||||||
../../src/protocol/srs_raw_avc.cpp,
|
../../src/protocol/srs_raw_avc.cpp,
|
||||||
../../src/protocol/srs_rtmp_amf0.hpp,
|
../../src/protocol/srs_rtmp_amf0.hpp,
|
||||||
../../src/protocol/srs_rtmp_amf0.cpp,
|
../../src/protocol/srs_rtmp_amf0.cpp,
|
||||||
../../src/protocol/srs_rtmp_buffer.hpp,
|
../../src/protocol/srs_rtmp_buffer.hpp,
|
||||||
|
@ -102,8 +102,8 @@ file
|
||||||
../../src/app/srs_app_json.cpp,
|
../../src/app/srs_app_json.cpp,
|
||||||
../../src/app/srs_app_kbps.hpp,
|
../../src/app/srs_app_kbps.hpp,
|
||||||
../../src/app/srs_app_kbps.cpp,
|
../../src/app/srs_app_kbps.cpp,
|
||||||
../../src/app/srs_app_listener.hpp,
|
../../src/app/srs_app_listener.hpp,
|
||||||
../../src/app/srs_app_listener.cpp,
|
../../src/app/srs_app_listener.cpp,
|
||||||
../../src/app/srs_app_log.hpp,
|
../../src/app/srs_app_log.hpp,
|
||||||
../../src/app/srs_app_log.cpp,
|
../../src/app/srs_app_log.cpp,
|
||||||
../../src/app/srs_app_mpegts_udp.hpp,
|
../../src/app/srs_app_mpegts_udp.hpp,
|
||||||
|
@ -116,8 +116,8 @@ file
|
||||||
../../src/app/srs_app_reload.cpp,
|
../../src/app/srs_app_reload.cpp,
|
||||||
../../src/app/srs_app_rtmp_conn.hpp,
|
../../src/app/srs_app_rtmp_conn.hpp,
|
||||||
../../src/app/srs_app_rtmp_conn.cpp,
|
../../src/app/srs_app_rtmp_conn.cpp,
|
||||||
../../src/app/srs_app_rtsp.hpp,
|
../../src/app/srs_app_rtsp.hpp,
|
||||||
../../src/app/srs_app_rtsp.cpp,
|
../../src/app/srs_app_rtsp.cpp,
|
||||||
../../src/app/srs_app_pithy_print.hpp,
|
../../src/app/srs_app_pithy_print.hpp,
|
||||||
../../src/app/srs_app_pithy_print.cpp,
|
../../src/app/srs_app_pithy_print.cpp,
|
||||||
../../src/app/srs_app_security.hpp,
|
../../src/app/srs_app_security.hpp,
|
||||||
|
|
844
trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
Normal file
844
trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
Normal file
|
@ -0,0 +1,844 @@
|
||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 46;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; };
|
||||||
|
3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; };
|
||||||
|
3C1231F81AAE652D00CE8F6C /* srs_core.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F41AAE652D00CE8F6C /* srs_core.cpp */; };
|
||||||
|
3C1232061AAE812C00CE8F6C /* srs_main_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232051AAE812C00CE8F6C /* srs_main_server.cpp */; };
|
||||||
|
3C1232201AAE814D00CE8F6C /* srs_kernel_aac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232081AAE814D00CE8F6C /* srs_kernel_aac.cpp */; };
|
||||||
|
3C1232211AAE814D00CE8F6C /* srs_kernel_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12320A1AAE814D00CE8F6C /* srs_kernel_buffer.cpp */; };
|
||||||
|
3C1232221AAE814D00CE8F6C /* srs_kernel_codec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12320C1AAE814D00CE8F6C /* srs_kernel_codec.cpp */; };
|
||||||
|
3C1232231AAE814D00CE8F6C /* srs_kernel_consts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12320E1AAE814D00CE8F6C /* srs_kernel_consts.cpp */; };
|
||||||
|
3C1232241AAE814D00CE8F6C /* srs_kernel_error.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232101AAE814D00CE8F6C /* srs_kernel_error.cpp */; };
|
||||||
|
3C1232251AAE814D00CE8F6C /* srs_kernel_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232121AAE814D00CE8F6C /* srs_kernel_file.cpp */; };
|
||||||
|
3C1232261AAE814D00CE8F6C /* srs_kernel_flv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232141AAE814D00CE8F6C /* srs_kernel_flv.cpp */; };
|
||||||
|
3C1232271AAE814D00CE8F6C /* srs_kernel_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232161AAE814D00CE8F6C /* srs_kernel_log.cpp */; };
|
||||||
|
3C1232281AAE814D00CE8F6C /* srs_kernel_mp3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232181AAE814D00CE8F6C /* srs_kernel_mp3.cpp */; };
|
||||||
|
3C1232291AAE814D00CE8F6C /* srs_kernel_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12321A1AAE814D00CE8F6C /* srs_kernel_stream.cpp */; };
|
||||||
|
3C12322A1AAE814D00CE8F6C /* srs_kernel_ts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12321C1AAE814D00CE8F6C /* srs_kernel_ts.cpp */; };
|
||||||
|
3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12321E1AAE814D00CE8F6C /* srs_kernel_utility.cpp */; };
|
||||||
|
3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */; };
|
||||||
|
3C1232421AAE81A400CE8F6C /* srs_rtmp_amf0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12322F1AAE81A400CE8F6C /* srs_rtmp_amf0.cpp */; };
|
||||||
|
3C1232431AAE81A400CE8F6C /* srs_rtmp_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232311AAE81A400CE8F6C /* srs_rtmp_buffer.cpp */; };
|
||||||
|
3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232331AAE81A400CE8F6C /* srs_rtmp_handshake.cpp */; };
|
||||||
|
3C1232451AAE81A400CE8F6C /* srs_rtmp_io.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232351AAE81A400CE8F6C /* srs_rtmp_io.cpp */; };
|
||||||
|
3C1232461AAE81A400CE8F6C /* srs_rtmp_msg_array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232371AAE81A400CE8F6C /* srs_rtmp_msg_array.cpp */; };
|
||||||
|
3C1232471AAE81A400CE8F6C /* srs_rtmp_sdk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232391AAE81A400CE8F6C /* srs_rtmp_sdk.cpp */; };
|
||||||
|
3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12323B1AAE81A400CE8F6C /* srs_rtmp_stack.cpp */; };
|
||||||
|
3C1232491AAE81A400CE8F6C /* srs_rtmp_utility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12323D1AAE81A400CE8F6C /* srs_rtmp_utility.cpp */; };
|
||||||
|
3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12323F1AAE81A400CE8F6C /* srs_rtsp_stack.cpp */; };
|
||||||
|
3C1232941AAE81D900CE8F6C /* srs_app_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */; };
|
||||||
|
3C1232951AAE81D900CE8F6C /* srs_app_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12324E1AAE81D900CE8F6C /* srs_app_config.cpp */; };
|
||||||
|
3C1232961AAE81D900CE8F6C /* srs_app_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232501AAE81D900CE8F6C /* srs_app_conn.cpp */; };
|
||||||
|
3C1232971AAE81D900CE8F6C /* srs_app_dvr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232521AAE81D900CE8F6C /* srs_app_dvr.cpp */; };
|
||||||
|
3C1232981AAE81D900CE8F6C /* srs_app_edge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232541AAE81D900CE8F6C /* srs_app_edge.cpp */; };
|
||||||
|
3C1232991AAE81D900CE8F6C /* srs_app_empty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232561AAE81D900CE8F6C /* srs_app_empty.cpp */; };
|
||||||
|
3C12329A1AAE81D900CE8F6C /* srs_app_encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232581AAE81D900CE8F6C /* srs_app_encoder.cpp */; };
|
||||||
|
3C12329B1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12325A1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp */; };
|
||||||
|
3C12329C1AAE81D900CE8F6C /* srs_app_forward.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12325C1AAE81D900CE8F6C /* srs_app_forward.cpp */; };
|
||||||
|
3C12329D1AAE81D900CE8F6C /* srs_app_heartbeat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12325E1AAE81D900CE8F6C /* srs_app_heartbeat.cpp */; };
|
||||||
|
3C12329E1AAE81D900CE8F6C /* srs_app_hls.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232601AAE81D900CE8F6C /* srs_app_hls.cpp */; };
|
||||||
|
3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232621AAE81D900CE8F6C /* srs_app_http_api.cpp */; };
|
||||||
|
3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */; };
|
||||||
|
3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; };
|
||||||
|
3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; };
|
||||||
|
3C1232A31AAE81D900CE8F6C /* srs_app_http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */; };
|
||||||
|
3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; };
|
||||||
|
3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */; };
|
||||||
|
3C1232A61AAE81D900CE8F6C /* srs_app_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232701AAE81D900CE8F6C /* srs_app_kbps.cpp */; };
|
||||||
|
3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */; };
|
||||||
|
3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */; };
|
||||||
|
3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */; };
|
||||||
|
3C1232AA1AAE81D900CE8F6C /* srs_app_pithy_print.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232781AAE81D900CE8F6C /* srs_app_pithy_print.cpp */; };
|
||||||
|
3C1232AB1AAE81D900CE8F6C /* srs_app_recv_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12327A1AAE81D900CE8F6C /* srs_app_recv_thread.cpp */; };
|
||||||
|
3C1232AC1AAE81D900CE8F6C /* srs_app_refer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12327C1AAE81D900CE8F6C /* srs_app_refer.cpp */; };
|
||||||
|
3C1232AD1AAE81D900CE8F6C /* srs_app_reload.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12327E1AAE81D900CE8F6C /* srs_app_reload.cpp */; };
|
||||||
|
3C1232AE1AAE81D900CE8F6C /* srs_app_rtmp_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232801AAE81D900CE8F6C /* srs_app_rtmp_conn.cpp */; };
|
||||||
|
3C1232AF1AAE81D900CE8F6C /* srs_app_rtsp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232821AAE81D900CE8F6C /* srs_app_rtsp.cpp */; };
|
||||||
|
3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232841AAE81D900CE8F6C /* srs_app_security.cpp */; };
|
||||||
|
3C1232B11AAE81D900CE8F6C /* srs_app_server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232861AAE81D900CE8F6C /* srs_app_server.cpp */; };
|
||||||
|
3C1232B21AAE81D900CE8F6C /* srs_app_source.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232881AAE81D900CE8F6C /* srs_app_source.cpp */; };
|
||||||
|
3C1232B31AAE81D900CE8F6C /* srs_app_st_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12328A1AAE81D900CE8F6C /* srs_app_st_socket.cpp */; };
|
||||||
|
3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12328C1AAE81D900CE8F6C /* srs_app_st.cpp */; };
|
||||||
|
3C1232B51AAE81D900CE8F6C /* srs_app_statistic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12328E1AAE81D900CE8F6C /* srs_app_statistic.cpp */; };
|
||||||
|
3C1232B61AAE81D900CE8F6C /* srs_app_thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232901AAE81D900CE8F6C /* srs_app_thread.cpp */; };
|
||||||
|
3C1232B71AAE81D900CE8F6C /* srs_app_utility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232921AAE81D900CE8F6C /* srs_app_utility.cpp */; };
|
||||||
|
3C1232D31AAEA56B00CE8F6C /* libst.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232D21AAEA56B00CE8F6C /* libst.a */; };
|
||||||
|
3C1232E91AAEA5D000CE8F6C /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232E71AAEA5D000CE8F6C /* libcrypto.a */; };
|
||||||
|
3C1232EA1AAEA5D000CE8F6C /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232E81AAEA5D000CE8F6C /* libssl.a */; };
|
||||||
|
3C1232ED1AAEA70F00CE8F6C /* libhttp_parser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */; };
|
||||||
|
3C663F0E1AB0155100286D8B /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F011AB0155100286D8B /* Makefile */; };
|
||||||
|
3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */; };
|
||||||
|
3C663F101AB0155100286D8B /* srs_audio_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */; };
|
||||||
|
3C663F111AB0155100286D8B /* srs_bandwidth_check.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F041AB0155100286D8B /* srs_bandwidth_check.c */; };
|
||||||
|
3C663F121AB0155100286D8B /* srs_detect_rtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F051AB0155100286D8B /* srs_detect_rtmp.c */; };
|
||||||
|
3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F061AB0155100286D8B /* srs_flv_injecter.c */; };
|
||||||
|
3C663F141AB0155100286D8B /* srs_flv_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F071AB0155100286D8B /* srs_flv_parser.c */; };
|
||||||
|
3C663F151AB0155100286D8B /* srs_h264_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */; };
|
||||||
|
3C663F161AB0155100286D8B /* srs_ingest_flv.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F091AB0155100286D8B /* srs_ingest_flv.c */; };
|
||||||
|
3C663F171AB0155100286D8B /* srs_ingest_rtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */; };
|
||||||
|
3C663F181AB0155100286D8B /* srs_play.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0B1AB0155100286D8B /* srs_play.c */; };
|
||||||
|
3C663F191AB0155100286D8B /* srs_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0C1AB0155100286D8B /* srs_publish.c */; };
|
||||||
|
3C663F1A1AB0155100286D8B /* srs_rtmp_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
3C1231E31AAE64A400CE8F6C /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_autofree.cpp; path = ../../../src/core/srs_core_autofree.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1231F11AAE652C00CE8F6C /* srs_core_autofree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_autofree.hpp; path = ../../../src/core/srs_core_autofree.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_performance.cpp; path = ../../../src/core/srs_core_performance.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1231F31AAE652C00CE8F6C /* srs_core_performance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_performance.hpp; path = ../../../src/core/srs_core_performance.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1231F41AAE652D00CE8F6C /* srs_core.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core.cpp; path = ../../../src/core/srs_core.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1231F51AAE652D00CE8F6C /* srs_core.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core.hpp; path = ../../../src/core/srs_core.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1231FB1AAE673100CE8F6C /* srs_auto_headers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_auto_headers.hpp; path = ../../../objs/srs_auto_headers.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232051AAE812C00CE8F6C /* srs_main_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_main_server.cpp; path = ../../../src/main/srs_main_server.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232081AAE814D00CE8F6C /* srs_kernel_aac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_aac.cpp; path = ../../../src/kernel/srs_kernel_aac.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232091AAE814D00CE8F6C /* srs_kernel_aac.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_aac.hpp; path = ../../../src/kernel/srs_kernel_aac.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12320A1AAE814D00CE8F6C /* srs_kernel_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_buffer.cpp; path = ../../../src/kernel/srs_kernel_buffer.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12320B1AAE814D00CE8F6C /* srs_kernel_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_buffer.hpp; path = ../../../src/kernel/srs_kernel_buffer.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12320C1AAE814D00CE8F6C /* srs_kernel_codec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_codec.cpp; path = ../../../src/kernel/srs_kernel_codec.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12320D1AAE814D00CE8F6C /* srs_kernel_codec.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_codec.hpp; path = ../../../src/kernel/srs_kernel_codec.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12320E1AAE814D00CE8F6C /* srs_kernel_consts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_consts.cpp; path = ../../../src/kernel/srs_kernel_consts.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12320F1AAE814D00CE8F6C /* srs_kernel_consts.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_consts.hpp; path = ../../../src/kernel/srs_kernel_consts.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232101AAE814D00CE8F6C /* srs_kernel_error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_error.cpp; path = ../../../src/kernel/srs_kernel_error.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232111AAE814D00CE8F6C /* srs_kernel_error.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_error.hpp; path = ../../../src/kernel/srs_kernel_error.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232121AAE814D00CE8F6C /* srs_kernel_file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_file.cpp; path = ../../../src/kernel/srs_kernel_file.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232131AAE814D00CE8F6C /* srs_kernel_file.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_file.hpp; path = ../../../src/kernel/srs_kernel_file.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232141AAE814D00CE8F6C /* srs_kernel_flv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_flv.cpp; path = ../../../src/kernel/srs_kernel_flv.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232151AAE814D00CE8F6C /* srs_kernel_flv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_flv.hpp; path = ../../../src/kernel/srs_kernel_flv.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232161AAE814D00CE8F6C /* srs_kernel_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_log.cpp; path = ../../../src/kernel/srs_kernel_log.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232171AAE814D00CE8F6C /* srs_kernel_log.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_log.hpp; path = ../../../src/kernel/srs_kernel_log.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232181AAE814D00CE8F6C /* srs_kernel_mp3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_mp3.cpp; path = ../../../src/kernel/srs_kernel_mp3.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232191AAE814D00CE8F6C /* srs_kernel_mp3.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_mp3.hpp; path = ../../../src/kernel/srs_kernel_mp3.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12321A1AAE814D00CE8F6C /* srs_kernel_stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_stream.cpp; path = ../../../src/kernel/srs_kernel_stream.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12321B1AAE814D00CE8F6C /* srs_kernel_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_stream.hpp; path = ../../../src/kernel/srs_kernel_stream.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12321C1AAE814D00CE8F6C /* srs_kernel_ts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_ts.cpp; path = ../../../src/kernel/srs_kernel_ts.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12321D1AAE814D00CE8F6C /* srs_kernel_ts.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_ts.hpp; path = ../../../src/kernel/srs_kernel_ts.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12321E1AAE814D00CE8F6C /* srs_kernel_utility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_utility.cpp; path = ../../../src/kernel/srs_kernel_utility.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12321F1AAE814D00CE8F6C /* srs_kernel_utility.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_utility.hpp; path = ../../../src/kernel/srs_kernel_utility.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_raw_avc.cpp; path = ../../../src/protocol/srs_raw_avc.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12322E1AAE81A400CE8F6C /* srs_raw_avc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_raw_avc.hpp; path = ../../../src/protocol/srs_raw_avc.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12322F1AAE81A400CE8F6C /* srs_rtmp_amf0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_amf0.cpp; path = ../../../src/protocol/srs_rtmp_amf0.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232301AAE81A400CE8F6C /* srs_rtmp_amf0.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_amf0.hpp; path = ../../../src/protocol/srs_rtmp_amf0.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232311AAE81A400CE8F6C /* srs_rtmp_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_buffer.cpp; path = ../../../src/protocol/srs_rtmp_buffer.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232321AAE81A400CE8F6C /* srs_rtmp_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_buffer.hpp; path = ../../../src/protocol/srs_rtmp_buffer.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232331AAE81A400CE8F6C /* srs_rtmp_handshake.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_handshake.cpp; path = ../../../src/protocol/srs_rtmp_handshake.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232341AAE81A400CE8F6C /* srs_rtmp_handshake.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_handshake.hpp; path = ../../../src/protocol/srs_rtmp_handshake.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232351AAE81A400CE8F6C /* srs_rtmp_io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_io.cpp; path = ../../../src/protocol/srs_rtmp_io.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232361AAE81A400CE8F6C /* srs_rtmp_io.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_io.hpp; path = ../../../src/protocol/srs_rtmp_io.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232371AAE81A400CE8F6C /* srs_rtmp_msg_array.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_msg_array.cpp; path = ../../../src/protocol/srs_rtmp_msg_array.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232381AAE81A400CE8F6C /* srs_rtmp_msg_array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_msg_array.hpp; path = ../../../src/protocol/srs_rtmp_msg_array.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232391AAE81A400CE8F6C /* srs_rtmp_sdk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_sdk.cpp; path = ../../../src/protocol/srs_rtmp_sdk.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12323A1AAE81A400CE8F6C /* srs_rtmp_sdk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_sdk.hpp; path = ../../../src/protocol/srs_rtmp_sdk.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12323B1AAE81A400CE8F6C /* srs_rtmp_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_stack.cpp; path = ../../../src/protocol/srs_rtmp_stack.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12323C1AAE81A400CE8F6C /* srs_rtmp_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_stack.hpp; path = ../../../src/protocol/srs_rtmp_stack.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12323D1AAE81A400CE8F6C /* srs_rtmp_utility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtmp_utility.cpp; path = ../../../src/protocol/srs_rtmp_utility.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12323E1AAE81A400CE8F6C /* srs_rtmp_utility.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtmp_utility.hpp; path = ../../../src/protocol/srs_rtmp_utility.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12323F1AAE81A400CE8F6C /* srs_rtsp_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_rtsp_stack.cpp; path = ../../../src/protocol/srs_rtsp_stack.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232401AAE81A400CE8F6C /* srs_rtsp_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_rtsp_stack.hpp; path = ../../../src/protocol/srs_rtsp_stack.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_bandwidth.cpp; path = ../../../src/app/srs_app_bandwidth.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12324D1AAE81D900CE8F6C /* srs_app_bandwidth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_bandwidth.hpp; path = ../../../src/app/srs_app_bandwidth.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12324E1AAE81D900CE8F6C /* srs_app_config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_config.cpp; path = ../../../src/app/srs_app_config.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12324F1AAE81D900CE8F6C /* srs_app_config.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_config.hpp; path = ../../../src/app/srs_app_config.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232501AAE81D900CE8F6C /* srs_app_conn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_conn.cpp; path = ../../../src/app/srs_app_conn.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232511AAE81D900CE8F6C /* srs_app_conn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_conn.hpp; path = ../../../src/app/srs_app_conn.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232521AAE81D900CE8F6C /* srs_app_dvr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_dvr.cpp; path = ../../../src/app/srs_app_dvr.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232531AAE81D900CE8F6C /* srs_app_dvr.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_dvr.hpp; path = ../../../src/app/srs_app_dvr.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232541AAE81D900CE8F6C /* srs_app_edge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_edge.cpp; path = ../../../src/app/srs_app_edge.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232551AAE81D900CE8F6C /* srs_app_edge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_edge.hpp; path = ../../../src/app/srs_app_edge.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232561AAE81D900CE8F6C /* srs_app_empty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_empty.cpp; path = ../../../src/app/srs_app_empty.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232571AAE81D900CE8F6C /* srs_app_empty.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_empty.hpp; path = ../../../src/app/srs_app_empty.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232581AAE81D900CE8F6C /* srs_app_encoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_encoder.cpp; path = ../../../src/app/srs_app_encoder.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232591AAE81D900CE8F6C /* srs_app_encoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_encoder.hpp; path = ../../../src/app/srs_app_encoder.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12325A1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ffmpeg.cpp; path = ../../../src/app/srs_app_ffmpeg.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12325B1AAE81D900CE8F6C /* srs_app_ffmpeg.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ffmpeg.hpp; path = ../../../src/app/srs_app_ffmpeg.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12325C1AAE81D900CE8F6C /* srs_app_forward.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_forward.cpp; path = ../../../src/app/srs_app_forward.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12325D1AAE81D900CE8F6C /* srs_app_forward.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_forward.hpp; path = ../../../src/app/srs_app_forward.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12325E1AAE81D900CE8F6C /* srs_app_heartbeat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_heartbeat.cpp; path = ../../../src/app/srs_app_heartbeat.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12325F1AAE81D900CE8F6C /* srs_app_heartbeat.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_heartbeat.hpp; path = ../../../src/app/srs_app_heartbeat.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232601AAE81D900CE8F6C /* srs_app_hls.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_hls.cpp; path = ../../../src/app/srs_app_hls.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232611AAE81D900CE8F6C /* srs_app_hls.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_hls.hpp; path = ../../../src/app/srs_app_hls.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232621AAE81D900CE8F6C /* srs_app_http_api.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_api.cpp; path = ../../../src/app/srs_app_http_api.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232631AAE81D900CE8F6C /* srs_app_http_api.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_api.hpp; path = ../../../src/app/srs_app_http_api.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_client.cpp; path = ../../../src/app/srs_app_http_client.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232651AAE81D900CE8F6C /* srs_app_http_client.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_client.hpp; path = ../../../src/app/srs_app_http_client.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_conn.cpp; path = ../../../src/app/srs_app_http_conn.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_conn.hpp; path = ../../../src/app/srs_app_http_conn.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http_hooks.cpp; path = ../../../src/app/srs_app_http_hooks.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_http.cpp; path = ../../../src/app/srs_app_http.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12326B1AAE81D900CE8F6C /* srs_app_http.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http.hpp; path = ../../../src/app/srs_app_http.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_json.cpp; path = ../../../src/app/srs_app_json.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_json.hpp; path = ../../../src/app/srs_app_json.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232701AAE81D900CE8F6C /* srs_app_kbps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_kbps.cpp; path = ../../../src/app/srs_app_kbps.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232711AAE81D900CE8F6C /* srs_app_kbps.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_kbps.hpp; path = ../../../src/app/srs_app_kbps.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_listener.cpp; path = ../../../src/app/srs_app_listener.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_listener.hpp; path = ../../../src/app/srs_app_listener.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_log.cpp; path = ../../../src/app/srs_app_log.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232751AAE81D900CE8F6C /* srs_app_log.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_log.hpp; path = ../../../src/app/srs_app_log.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_mpegts_udp.cpp; path = ../../../src/app/srs_app_mpegts_udp.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232771AAE81D900CE8F6C /* srs_app_mpegts_udp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_mpegts_udp.hpp; path = ../../../src/app/srs_app_mpegts_udp.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232781AAE81D900CE8F6C /* srs_app_pithy_print.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_pithy_print.cpp; path = ../../../src/app/srs_app_pithy_print.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232791AAE81D900CE8F6C /* srs_app_pithy_print.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_pithy_print.hpp; path = ../../../src/app/srs_app_pithy_print.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12327A1AAE81D900CE8F6C /* srs_app_recv_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_recv_thread.cpp; path = ../../../src/app/srs_app_recv_thread.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12327B1AAE81D900CE8F6C /* srs_app_recv_thread.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_recv_thread.hpp; path = ../../../src/app/srs_app_recv_thread.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12327C1AAE81D900CE8F6C /* srs_app_refer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_refer.cpp; path = ../../../src/app/srs_app_refer.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12327D1AAE81D900CE8F6C /* srs_app_refer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_refer.hpp; path = ../../../src/app/srs_app_refer.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12327E1AAE81D900CE8F6C /* srs_app_reload.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_reload.cpp; path = ../../../src/app/srs_app_reload.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12327F1AAE81D900CE8F6C /* srs_app_reload.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_reload.hpp; path = ../../../src/app/srs_app_reload.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232801AAE81D900CE8F6C /* srs_app_rtmp_conn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_rtmp_conn.cpp; path = ../../../src/app/srs_app_rtmp_conn.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232811AAE81D900CE8F6C /* srs_app_rtmp_conn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_rtmp_conn.hpp; path = ../../../src/app/srs_app_rtmp_conn.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232821AAE81D900CE8F6C /* srs_app_rtsp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_rtsp.cpp; path = ../../../src/app/srs_app_rtsp.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232831AAE81D900CE8F6C /* srs_app_rtsp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_rtsp.hpp; path = ../../../src/app/srs_app_rtsp.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232841AAE81D900CE8F6C /* srs_app_security.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_security.cpp; path = ../../../src/app/srs_app_security.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232851AAE81D900CE8F6C /* srs_app_security.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_security.hpp; path = ../../../src/app/srs_app_security.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232861AAE81D900CE8F6C /* srs_app_server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_server.cpp; path = ../../../src/app/srs_app_server.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232871AAE81D900CE8F6C /* srs_app_server.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_server.hpp; path = ../../../src/app/srs_app_server.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232881AAE81D900CE8F6C /* srs_app_source.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_source.cpp; path = ../../../src/app/srs_app_source.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232891AAE81D900CE8F6C /* srs_app_source.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_source.hpp; path = ../../../src/app/srs_app_source.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12328A1AAE81D900CE8F6C /* srs_app_st_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_st_socket.cpp; path = ../../../src/app/srs_app_st_socket.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12328B1AAE81D900CE8F6C /* srs_app_st_socket.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_st_socket.hpp; path = ../../../src/app/srs_app_st_socket.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12328C1AAE81D900CE8F6C /* srs_app_st.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_st.cpp; path = ../../../src/app/srs_app_st.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12328D1AAE81D900CE8F6C /* srs_app_st.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_st.hpp; path = ../../../src/app/srs_app_st.hpp; sourceTree = "<group>"; };
|
||||||
|
3C12328E1AAE81D900CE8F6C /* srs_app_statistic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_statistic.cpp; path = ../../../src/app/srs_app_statistic.cpp; sourceTree = "<group>"; };
|
||||||
|
3C12328F1AAE81D900CE8F6C /* srs_app_statistic.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_statistic.hpp; path = ../../../src/app/srs_app_statistic.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232901AAE81D900CE8F6C /* srs_app_thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_thread.cpp; path = ../../../src/app/srs_app_thread.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232911AAE81D900CE8F6C /* srs_app_thread.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_thread.hpp; path = ../../../src/app/srs_app_thread.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232921AAE81D900CE8F6C /* srs_app_utility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_utility.cpp; path = ../../../src/app/srs_app_utility.cpp; sourceTree = "<group>"; };
|
||||||
|
3C1232931AAE81D900CE8F6C /* srs_app_utility.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_utility.hpp; path = ../../../src/app/srs_app_utility.hpp; sourceTree = "<group>"; };
|
||||||
|
3C1232B81AAE824500CE8F6C /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = configure; path = ../../../configure; sourceTree = "<group>"; };
|
||||||
|
3C1232BB1AAE827E00CE8F6C /* apps.sh */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; name = apps.sh; path = ../../../auto/apps.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232BC1AAE827E00CE8F6C /* auto_headers.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = auto_headers.sh; path = ../../../auto/auto_headers.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232BD1AAE827E00CE8F6C /* build_ffmpeg.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = build_ffmpeg.sh; path = ../../../auto/build_ffmpeg.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232BE1AAE827E00CE8F6C /* depends.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = depends.sh; path = ../../../auto/depends.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232BF1AAE827E00CE8F6C /* generate_header.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = generate_header.sh; path = ../../../auto/generate_header.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C01AAE827E00CE8F6C /* generate-srs-librtmp-project.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "generate-srs-librtmp-project.sh"; path = "../../../auto/generate-srs-librtmp-project.sh"; sourceTree = "<group>"; };
|
||||||
|
3C1232C11AAE827E00CE8F6C /* generate-srs-librtmp-single.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "generate-srs-librtmp-single.sh"; path = "../../../auto/generate-srs-librtmp-single.sh"; sourceTree = "<group>"; };
|
||||||
|
3C1232C21AAE827E00CE8F6C /* libs.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = libs.sh; path = ../../../auto/libs.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C31AAE827E00CE8F6C /* local_ip.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = local_ip.sh; path = ../../../auto/local_ip.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C41AAE827E00CE8F6C /* modules.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = modules.sh; path = ../../../auto/modules.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C51AAE827E00CE8F6C /* options.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = options.sh; path = ../../../auto/options.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C61AAE827E00CE8F6C /* summary.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = summary.sh; path = ../../../auto/summary.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C71AAE827E00CE8F6C /* utest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = utest.sh; path = ../../../auto/utest.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C81AAE833300CE8F6C /* _log.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = _log.sh; path = ../../../scripts/_log.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232C91AAE833300CE8F6C /* build.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = build.sh; path = ../../../scripts/build.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CA1AAE833300CE8F6C /* git.commit.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = git.commit.sh; path = ../../../scripts/git.commit.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CB1AAE833300CE8F6C /* git2unix.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = git2unix.sh; path = ../../../scripts/git2unix.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CC1AAE833300CE8F6C /* install.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = install.sh; path = ../../../scripts/install.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CD1AAE833300CE8F6C /* package.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = package.sh; path = ../../../scripts/package.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CE1AAE833300CE8F6C /* run.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = run.sh; path = ../../../scripts/run.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232CF1AAE833300CE8F6C /* srs.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = srs.test; path = ../../../scripts/srs.test; sourceTree = "<group>"; };
|
||||||
|
3C1232D01AAE833300CE8F6C /* stop.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = stop.sh; path = ../../../scripts/stop.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232D11AAE833300CE8F6C /* test_configure.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = test_configure.sh; path = ../../../scripts/test_configure.sh; sourceTree = "<group>"; };
|
||||||
|
3C1232D21AAEA56B00CE8F6C /* libst.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libst.a; path = "../../objs/st-1.9/DARWIN_14.0.0_DBG/libst.a"; sourceTree = "<group>"; };
|
||||||
|
3C1232E71AAEA5D000CE8F6C /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = "../../objs/openssl-1.0.1f/_release/lib/libcrypto.a"; sourceTree = "<group>"; };
|
||||||
|
3C1232E81AAEA5D000CE8F6C /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = "../../objs/openssl-1.0.1f/_release/lib/libssl.a"; sourceTree = "<group>"; };
|
||||||
|
3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhttp_parser.a; path = "../../objs/http-parser-2.1/libhttp_parser.a"; sourceTree = "<group>"; };
|
||||||
|
3C1232F11AAEAC7000CE8F6C /* srs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = srs; path = ../../../etc/init.d/srs; sourceTree = "<group>"; };
|
||||||
|
3C1232F21AAEAC7000CE8F6C /* srs-api */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-api"; path = "../../../etc/init.d/srs-api"; sourceTree = "<group>"; };
|
||||||
|
3C1232F31AAEAC7000CE8F6C /* srs-demo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-demo"; path = "../../../etc/init.d/srs-demo"; sourceTree = "<group>"; };
|
||||||
|
3C1232F41AAEAC7000CE8F6C /* srs-demo-19350 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-demo-19350"; path = "../../../etc/init.d/srs-demo-19350"; sourceTree = "<group>"; };
|
||||||
|
3C663F011AB0155100286D8B /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../../research/librtmp/Makefile; sourceTree = "<group>"; };
|
||||||
|
3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_aac_raw_publish.c; path = ../../../research/librtmp/srs_aac_raw_publish.c; sourceTree = "<group>"; };
|
||||||
|
3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_audio_raw_publish.c; path = ../../../research/librtmp/srs_audio_raw_publish.c; sourceTree = "<group>"; };
|
||||||
|
3C663F041AB0155100286D8B /* srs_bandwidth_check.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_bandwidth_check.c; path = ../../../research/librtmp/srs_bandwidth_check.c; sourceTree = "<group>"; };
|
||||||
|
3C663F051AB0155100286D8B /* srs_detect_rtmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_detect_rtmp.c; path = ../../../research/librtmp/srs_detect_rtmp.c; sourceTree = "<group>"; };
|
||||||
|
3C663F061AB0155100286D8B /* srs_flv_injecter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_flv_injecter.c; path = ../../../research/librtmp/srs_flv_injecter.c; sourceTree = "<group>"; };
|
||||||
|
3C663F071AB0155100286D8B /* srs_flv_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_flv_parser.c; path = ../../../research/librtmp/srs_flv_parser.c; sourceTree = "<group>"; };
|
||||||
|
3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_h264_raw_publish.c; path = ../../../research/librtmp/srs_h264_raw_publish.c; sourceTree = "<group>"; };
|
||||||
|
3C663F091AB0155100286D8B /* srs_ingest_flv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_ingest_flv.c; path = ../../../research/librtmp/srs_ingest_flv.c; sourceTree = "<group>"; };
|
||||||
|
3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_ingest_rtmp.c; path = ../../../research/librtmp/srs_ingest_rtmp.c; sourceTree = "<group>"; };
|
||||||
|
3C663F0B1AB0155100286D8B /* srs_play.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_play.c; path = ../../../research/librtmp/srs_play.c; sourceTree = "<group>"; };
|
||||||
|
3C663F0C1AB0155100286D8B /* srs_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_publish.c; path = ../../../research/librtmp/srs_publish.c; sourceTree = "<group>"; };
|
||||||
|
3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_rtmp_dump.c; path = ../../../research/librtmp/srs_rtmp_dump.c; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
3C1231E21AAE64A400CE8F6C /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
3C1232ED1AAEA70F00CE8F6C /* libhttp_parser.a in Frameworks */,
|
||||||
|
3C1232E91AAEA5D000CE8F6C /* libcrypto.a in Frameworks */,
|
||||||
|
3C1232EA1AAEA5D000CE8F6C /* libssl.a in Frameworks */,
|
||||||
|
3C1232D31AAEA56B00CE8F6C /* libst.a in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
3C1231DC1AAE64A400CE8F6C = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1231E61AAE64A400CE8F6C /* Products */,
|
||||||
|
3C1232EE1AAEA71C00CE8F6C /* links */,
|
||||||
|
3C1231E71AAE64A400CE8F6C /* srs_xcode */,
|
||||||
|
3C663F001AB014B500286D8B /* research */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1231E61AAE64A400CE8F6C /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1231E51AAE64A400CE8F6C /* srs_xcode */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1231E71AAE64A400CE8F6C /* srs_xcode */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232B81AAE824500CE8F6C /* configure */,
|
||||||
|
3C1232EF1AAEAC5800CE8F6C /* etc */,
|
||||||
|
3C1232BA1AAE826F00CE8F6C /* auto */,
|
||||||
|
3C1232B91AAE825100CE8F6C /* scripts */,
|
||||||
|
3C12324B1AAE81CE00CE8F6C /* app */,
|
||||||
|
3C12322C1AAE819900CE8F6C /* protocol */,
|
||||||
|
3C1232071AAE814200CE8F6C /* kernel */,
|
||||||
|
3C1232041AAE80CB00CE8F6C /* main */,
|
||||||
|
3C1231F91AAE670E00CE8F6C /* objs */,
|
||||||
|
3C1231EF1AAE651100CE8F6C /* core */,
|
||||||
|
);
|
||||||
|
path = srs_xcode;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1231EF1AAE651100CE8F6C /* core */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */,
|
||||||
|
3C1231F11AAE652C00CE8F6C /* srs_core_autofree.hpp */,
|
||||||
|
3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */,
|
||||||
|
3C1231F31AAE652C00CE8F6C /* srs_core_performance.hpp */,
|
||||||
|
3C1231F41AAE652D00CE8F6C /* srs_core.cpp */,
|
||||||
|
3C1231F51AAE652D00CE8F6C /* srs_core.hpp */,
|
||||||
|
);
|
||||||
|
name = core;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1231F91AAE670E00CE8F6C /* objs */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1231FB1AAE673100CE8F6C /* srs_auto_headers.hpp */,
|
||||||
|
);
|
||||||
|
name = objs;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232041AAE80CB00CE8F6C /* main */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232051AAE812C00CE8F6C /* srs_main_server.cpp */,
|
||||||
|
);
|
||||||
|
name = main;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232071AAE814200CE8F6C /* kernel */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232081AAE814D00CE8F6C /* srs_kernel_aac.cpp */,
|
||||||
|
3C1232091AAE814D00CE8F6C /* srs_kernel_aac.hpp */,
|
||||||
|
3C12320A1AAE814D00CE8F6C /* srs_kernel_buffer.cpp */,
|
||||||
|
3C12320B1AAE814D00CE8F6C /* srs_kernel_buffer.hpp */,
|
||||||
|
3C12320C1AAE814D00CE8F6C /* srs_kernel_codec.cpp */,
|
||||||
|
3C12320D1AAE814D00CE8F6C /* srs_kernel_codec.hpp */,
|
||||||
|
3C12320E1AAE814D00CE8F6C /* srs_kernel_consts.cpp */,
|
||||||
|
3C12320F1AAE814D00CE8F6C /* srs_kernel_consts.hpp */,
|
||||||
|
3C1232101AAE814D00CE8F6C /* srs_kernel_error.cpp */,
|
||||||
|
3C1232111AAE814D00CE8F6C /* srs_kernel_error.hpp */,
|
||||||
|
3C1232121AAE814D00CE8F6C /* srs_kernel_file.cpp */,
|
||||||
|
3C1232131AAE814D00CE8F6C /* srs_kernel_file.hpp */,
|
||||||
|
3C1232141AAE814D00CE8F6C /* srs_kernel_flv.cpp */,
|
||||||
|
3C1232151AAE814D00CE8F6C /* srs_kernel_flv.hpp */,
|
||||||
|
3C1232161AAE814D00CE8F6C /* srs_kernel_log.cpp */,
|
||||||
|
3C1232171AAE814D00CE8F6C /* srs_kernel_log.hpp */,
|
||||||
|
3C1232181AAE814D00CE8F6C /* srs_kernel_mp3.cpp */,
|
||||||
|
3C1232191AAE814D00CE8F6C /* srs_kernel_mp3.hpp */,
|
||||||
|
3C12321A1AAE814D00CE8F6C /* srs_kernel_stream.cpp */,
|
||||||
|
3C12321B1AAE814D00CE8F6C /* srs_kernel_stream.hpp */,
|
||||||
|
3C12321C1AAE814D00CE8F6C /* srs_kernel_ts.cpp */,
|
||||||
|
3C12321D1AAE814D00CE8F6C /* srs_kernel_ts.hpp */,
|
||||||
|
3C12321E1AAE814D00CE8F6C /* srs_kernel_utility.cpp */,
|
||||||
|
3C12321F1AAE814D00CE8F6C /* srs_kernel_utility.hpp */,
|
||||||
|
);
|
||||||
|
name = kernel;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C12322C1AAE819900CE8F6C /* protocol */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */,
|
||||||
|
3C12322E1AAE81A400CE8F6C /* srs_raw_avc.hpp */,
|
||||||
|
3C12322F1AAE81A400CE8F6C /* srs_rtmp_amf0.cpp */,
|
||||||
|
3C1232301AAE81A400CE8F6C /* srs_rtmp_amf0.hpp */,
|
||||||
|
3C1232311AAE81A400CE8F6C /* srs_rtmp_buffer.cpp */,
|
||||||
|
3C1232321AAE81A400CE8F6C /* srs_rtmp_buffer.hpp */,
|
||||||
|
3C1232331AAE81A400CE8F6C /* srs_rtmp_handshake.cpp */,
|
||||||
|
3C1232341AAE81A400CE8F6C /* srs_rtmp_handshake.hpp */,
|
||||||
|
3C1232351AAE81A400CE8F6C /* srs_rtmp_io.cpp */,
|
||||||
|
3C1232361AAE81A400CE8F6C /* srs_rtmp_io.hpp */,
|
||||||
|
3C1232371AAE81A400CE8F6C /* srs_rtmp_msg_array.cpp */,
|
||||||
|
3C1232381AAE81A400CE8F6C /* srs_rtmp_msg_array.hpp */,
|
||||||
|
3C1232391AAE81A400CE8F6C /* srs_rtmp_sdk.cpp */,
|
||||||
|
3C12323A1AAE81A400CE8F6C /* srs_rtmp_sdk.hpp */,
|
||||||
|
3C12323B1AAE81A400CE8F6C /* srs_rtmp_stack.cpp */,
|
||||||
|
3C12323C1AAE81A400CE8F6C /* srs_rtmp_stack.hpp */,
|
||||||
|
3C12323D1AAE81A400CE8F6C /* srs_rtmp_utility.cpp */,
|
||||||
|
3C12323E1AAE81A400CE8F6C /* srs_rtmp_utility.hpp */,
|
||||||
|
3C12323F1AAE81A400CE8F6C /* srs_rtsp_stack.cpp */,
|
||||||
|
3C1232401AAE81A400CE8F6C /* srs_rtsp_stack.hpp */,
|
||||||
|
);
|
||||||
|
name = protocol;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C12324B1AAE81CE00CE8F6C /* app */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */,
|
||||||
|
3C12324D1AAE81D900CE8F6C /* srs_app_bandwidth.hpp */,
|
||||||
|
3C12324E1AAE81D900CE8F6C /* srs_app_config.cpp */,
|
||||||
|
3C12324F1AAE81D900CE8F6C /* srs_app_config.hpp */,
|
||||||
|
3C1232501AAE81D900CE8F6C /* srs_app_conn.cpp */,
|
||||||
|
3C1232511AAE81D900CE8F6C /* srs_app_conn.hpp */,
|
||||||
|
3C1232521AAE81D900CE8F6C /* srs_app_dvr.cpp */,
|
||||||
|
3C1232531AAE81D900CE8F6C /* srs_app_dvr.hpp */,
|
||||||
|
3C1232541AAE81D900CE8F6C /* srs_app_edge.cpp */,
|
||||||
|
3C1232551AAE81D900CE8F6C /* srs_app_edge.hpp */,
|
||||||
|
3C1232561AAE81D900CE8F6C /* srs_app_empty.cpp */,
|
||||||
|
3C1232571AAE81D900CE8F6C /* srs_app_empty.hpp */,
|
||||||
|
3C1232581AAE81D900CE8F6C /* srs_app_encoder.cpp */,
|
||||||
|
3C1232591AAE81D900CE8F6C /* srs_app_encoder.hpp */,
|
||||||
|
3C12325A1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp */,
|
||||||
|
3C12325B1AAE81D900CE8F6C /* srs_app_ffmpeg.hpp */,
|
||||||
|
3C12325C1AAE81D900CE8F6C /* srs_app_forward.cpp */,
|
||||||
|
3C12325D1AAE81D900CE8F6C /* srs_app_forward.hpp */,
|
||||||
|
3C12325E1AAE81D900CE8F6C /* srs_app_heartbeat.cpp */,
|
||||||
|
3C12325F1AAE81D900CE8F6C /* srs_app_heartbeat.hpp */,
|
||||||
|
3C1232601AAE81D900CE8F6C /* srs_app_hls.cpp */,
|
||||||
|
3C1232611AAE81D900CE8F6C /* srs_app_hls.hpp */,
|
||||||
|
3C1232621AAE81D900CE8F6C /* srs_app_http_api.cpp */,
|
||||||
|
3C1232631AAE81D900CE8F6C /* srs_app_http_api.hpp */,
|
||||||
|
3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */,
|
||||||
|
3C1232651AAE81D900CE8F6C /* srs_app_http_client.hpp */,
|
||||||
|
3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */,
|
||||||
|
3C1232671AAE81D900CE8F6C /* srs_app_http_conn.hpp */,
|
||||||
|
3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */,
|
||||||
|
3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */,
|
||||||
|
3C12326A1AAE81D900CE8F6C /* srs_app_http.cpp */,
|
||||||
|
3C12326B1AAE81D900CE8F6C /* srs_app_http.hpp */,
|
||||||
|
3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */,
|
||||||
|
3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */,
|
||||||
|
3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */,
|
||||||
|
3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */,
|
||||||
|
3C1232701AAE81D900CE8F6C /* srs_app_kbps.cpp */,
|
||||||
|
3C1232711AAE81D900CE8F6C /* srs_app_kbps.hpp */,
|
||||||
|
3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */,
|
||||||
|
3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */,
|
||||||
|
3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */,
|
||||||
|
3C1232751AAE81D900CE8F6C /* srs_app_log.hpp */,
|
||||||
|
3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */,
|
||||||
|
3C1232771AAE81D900CE8F6C /* srs_app_mpegts_udp.hpp */,
|
||||||
|
3C1232781AAE81D900CE8F6C /* srs_app_pithy_print.cpp */,
|
||||||
|
3C1232791AAE81D900CE8F6C /* srs_app_pithy_print.hpp */,
|
||||||
|
3C12327A1AAE81D900CE8F6C /* srs_app_recv_thread.cpp */,
|
||||||
|
3C12327B1AAE81D900CE8F6C /* srs_app_recv_thread.hpp */,
|
||||||
|
3C12327C1AAE81D900CE8F6C /* srs_app_refer.cpp */,
|
||||||
|
3C12327D1AAE81D900CE8F6C /* srs_app_refer.hpp */,
|
||||||
|
3C12327E1AAE81D900CE8F6C /* srs_app_reload.cpp */,
|
||||||
|
3C12327F1AAE81D900CE8F6C /* srs_app_reload.hpp */,
|
||||||
|
3C1232801AAE81D900CE8F6C /* srs_app_rtmp_conn.cpp */,
|
||||||
|
3C1232811AAE81D900CE8F6C /* srs_app_rtmp_conn.hpp */,
|
||||||
|
3C1232821AAE81D900CE8F6C /* srs_app_rtsp.cpp */,
|
||||||
|
3C1232831AAE81D900CE8F6C /* srs_app_rtsp.hpp */,
|
||||||
|
3C1232841AAE81D900CE8F6C /* srs_app_security.cpp */,
|
||||||
|
3C1232851AAE81D900CE8F6C /* srs_app_security.hpp */,
|
||||||
|
3C1232861AAE81D900CE8F6C /* srs_app_server.cpp */,
|
||||||
|
3C1232871AAE81D900CE8F6C /* srs_app_server.hpp */,
|
||||||
|
3C1232881AAE81D900CE8F6C /* srs_app_source.cpp */,
|
||||||
|
3C1232891AAE81D900CE8F6C /* srs_app_source.hpp */,
|
||||||
|
3C12328A1AAE81D900CE8F6C /* srs_app_st_socket.cpp */,
|
||||||
|
3C12328B1AAE81D900CE8F6C /* srs_app_st_socket.hpp */,
|
||||||
|
3C12328C1AAE81D900CE8F6C /* srs_app_st.cpp */,
|
||||||
|
3C12328D1AAE81D900CE8F6C /* srs_app_st.hpp */,
|
||||||
|
3C12328E1AAE81D900CE8F6C /* srs_app_statistic.cpp */,
|
||||||
|
3C12328F1AAE81D900CE8F6C /* srs_app_statistic.hpp */,
|
||||||
|
3C1232901AAE81D900CE8F6C /* srs_app_thread.cpp */,
|
||||||
|
3C1232911AAE81D900CE8F6C /* srs_app_thread.hpp */,
|
||||||
|
3C1232921AAE81D900CE8F6C /* srs_app_utility.cpp */,
|
||||||
|
3C1232931AAE81D900CE8F6C /* srs_app_utility.hpp */,
|
||||||
|
);
|
||||||
|
name = app;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232B91AAE825100CE8F6C /* scripts */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232C81AAE833300CE8F6C /* _log.sh */,
|
||||||
|
3C1232C91AAE833300CE8F6C /* build.sh */,
|
||||||
|
3C1232CA1AAE833300CE8F6C /* git.commit.sh */,
|
||||||
|
3C1232CB1AAE833300CE8F6C /* git2unix.sh */,
|
||||||
|
3C1232CC1AAE833300CE8F6C /* install.sh */,
|
||||||
|
3C1232CD1AAE833300CE8F6C /* package.sh */,
|
||||||
|
3C1232CE1AAE833300CE8F6C /* run.sh */,
|
||||||
|
3C1232CF1AAE833300CE8F6C /* srs.test */,
|
||||||
|
3C1232D01AAE833300CE8F6C /* stop.sh */,
|
||||||
|
3C1232D11AAE833300CE8F6C /* test_configure.sh */,
|
||||||
|
);
|
||||||
|
name = scripts;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232BA1AAE826F00CE8F6C /* auto */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232BB1AAE827E00CE8F6C /* apps.sh */,
|
||||||
|
3C1232BC1AAE827E00CE8F6C /* auto_headers.sh */,
|
||||||
|
3C1232BD1AAE827E00CE8F6C /* build_ffmpeg.sh */,
|
||||||
|
3C1232BE1AAE827E00CE8F6C /* depends.sh */,
|
||||||
|
3C1232BF1AAE827E00CE8F6C /* generate_header.sh */,
|
||||||
|
3C1232C01AAE827E00CE8F6C /* generate-srs-librtmp-project.sh */,
|
||||||
|
3C1232C11AAE827E00CE8F6C /* generate-srs-librtmp-single.sh */,
|
||||||
|
3C1232C21AAE827E00CE8F6C /* libs.sh */,
|
||||||
|
3C1232C31AAE827E00CE8F6C /* local_ip.sh */,
|
||||||
|
3C1232C41AAE827E00CE8F6C /* modules.sh */,
|
||||||
|
3C1232C51AAE827E00CE8F6C /* options.sh */,
|
||||||
|
3C1232C61AAE827E00CE8F6C /* summary.sh */,
|
||||||
|
3C1232C71AAE827E00CE8F6C /* utest.sh */,
|
||||||
|
);
|
||||||
|
name = auto;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232EE1AAEA71C00CE8F6C /* links */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */,
|
||||||
|
3C1232D21AAEA56B00CE8F6C /* libst.a */,
|
||||||
|
3C1232E81AAEA5D000CE8F6C /* libssl.a */,
|
||||||
|
3C1232E71AAEA5D000CE8F6C /* libcrypto.a */,
|
||||||
|
);
|
||||||
|
name = links;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232EF1AAEAC5800CE8F6C /* etc */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232F01AAEAC5D00CE8F6C /* init.d */,
|
||||||
|
);
|
||||||
|
name = etc;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C1232F01AAEAC5D00CE8F6C /* init.d */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C1232F11AAEAC7000CE8F6C /* srs */,
|
||||||
|
3C1232F21AAEAC7000CE8F6C /* srs-api */,
|
||||||
|
3C1232F31AAEAC7000CE8F6C /* srs-demo */,
|
||||||
|
3C1232F41AAEAC7000CE8F6C /* srs-demo-19350 */,
|
||||||
|
);
|
||||||
|
name = init.d;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
3C663F001AB014B500286D8B /* research */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
3C663F011AB0155100286D8B /* Makefile */,
|
||||||
|
3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */,
|
||||||
|
3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */,
|
||||||
|
3C663F041AB0155100286D8B /* srs_bandwidth_check.c */,
|
||||||
|
3C663F051AB0155100286D8B /* srs_detect_rtmp.c */,
|
||||||
|
3C663F061AB0155100286D8B /* srs_flv_injecter.c */,
|
||||||
|
3C663F071AB0155100286D8B /* srs_flv_parser.c */,
|
||||||
|
3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */,
|
||||||
|
3C663F091AB0155100286D8B /* srs_ingest_flv.c */,
|
||||||
|
3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */,
|
||||||
|
3C663F0B1AB0155100286D8B /* srs_play.c */,
|
||||||
|
3C663F0C1AB0155100286D8B /* srs_publish.c */,
|
||||||
|
3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */,
|
||||||
|
);
|
||||||
|
name = research;
|
||||||
|
path = srs_xcode;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
3C1231E41AAE64A400CE8F6C /* srs_xcode */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 3C1231EC1AAE64A400CE8F6C /* Build configuration list for PBXNativeTarget "srs_xcode" */;
|
||||||
|
buildPhases = (
|
||||||
|
3C1231E11AAE64A400CE8F6C /* Sources */,
|
||||||
|
3C1231E21AAE64A400CE8F6C /* Frameworks */,
|
||||||
|
3C1231E31AAE64A400CE8F6C /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = srs_xcode;
|
||||||
|
productName = srs_xcode;
|
||||||
|
productReference = 3C1231E51AAE64A400CE8F6C /* srs_xcode */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
3C1231DD1AAE64A400CE8F6C /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0610;
|
||||||
|
ORGANIZATIONNAME = winlin;
|
||||||
|
TargetAttributes = {
|
||||||
|
3C1231E41AAE64A400CE8F6C = {
|
||||||
|
CreatedOnToolsVersion = 6.1.1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 3C1231E01AAE64A400CE8F6C /* Build configuration list for PBXProject "srs_xcode" */;
|
||||||
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
developmentRegion = English;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
);
|
||||||
|
mainGroup = 3C1231DC1AAE64A400CE8F6C;
|
||||||
|
productRefGroup = 3C1231E61AAE64A400CE8F6C /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
3C1231E41AAE64A400CE8F6C /* srs_xcode */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
3C1231E11AAE64A400CE8F6C /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
3C1232951AAE81D900CE8F6C /* srs_app_config.cpp in Sources */,
|
||||||
|
3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */,
|
||||||
|
3C1232961AAE81D900CE8F6C /* srs_app_conn.cpp in Sources */,
|
||||||
|
3C12322A1AAE814D00CE8F6C /* srs_kernel_ts.cpp in Sources */,
|
||||||
|
3C12329E1AAE81D900CE8F6C /* srs_app_hls.cpp in Sources */,
|
||||||
|
3C663F171AB0155100286D8B /* srs_ingest_rtmp.c in Sources */,
|
||||||
|
3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */,
|
||||||
|
3C1232971AAE81D900CE8F6C /* srs_app_dvr.cpp in Sources */,
|
||||||
|
3C1232271AAE814D00CE8F6C /* srs_kernel_log.cpp in Sources */,
|
||||||
|
3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */,
|
||||||
|
3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */,
|
||||||
|
3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */,
|
||||||
|
3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */,
|
||||||
|
3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */,
|
||||||
|
3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */,
|
||||||
|
3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */,
|
||||||
|
3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */,
|
||||||
|
3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */,
|
||||||
|
3C663F101AB0155100286D8B /* srs_audio_raw_publish.c in Sources */,
|
||||||
|
3C663F111AB0155100286D8B /* srs_bandwidth_check.c in Sources */,
|
||||||
|
3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */,
|
||||||
|
3C1232AC1AAE81D900CE8F6C /* srs_app_refer.cpp in Sources */,
|
||||||
|
3C1232991AAE81D900CE8F6C /* srs_app_empty.cpp in Sources */,
|
||||||
|
3C1232201AAE814D00CE8F6C /* srs_kernel_aac.cpp in Sources */,
|
||||||
|
3C1232941AAE81D900CE8F6C /* srs_app_bandwidth.cpp in Sources */,
|
||||||
|
3C1232221AAE814D00CE8F6C /* srs_kernel_codec.cpp in Sources */,
|
||||||
|
3C1232B71AAE81D900CE8F6C /* srs_app_utility.cpp in Sources */,
|
||||||
|
3C1232AB1AAE81D900CE8F6C /* srs_app_recv_thread.cpp in Sources */,
|
||||||
|
3C663F151AB0155100286D8B /* srs_h264_raw_publish.c in Sources */,
|
||||||
|
3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */,
|
||||||
|
3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */,
|
||||||
|
3C1232491AAE81A400CE8F6C /* srs_rtmp_utility.cpp in Sources */,
|
||||||
|
3C663F191AB0155100286D8B /* srs_publish.c in Sources */,
|
||||||
|
3C1232A01AAE81D900CE8F6C /* srs_app_http_client.cpp in Sources */,
|
||||||
|
3C12329B1AAE81D900CE8F6C /* srs_app_ffmpeg.cpp in Sources */,
|
||||||
|
3C1232421AAE81A400CE8F6C /* srs_rtmp_amf0.cpp in Sources */,
|
||||||
|
3C1232AA1AAE81D900CE8F6C /* srs_app_pithy_print.cpp in Sources */,
|
||||||
|
3C12329C1AAE81D900CE8F6C /* srs_app_forward.cpp in Sources */,
|
||||||
|
3C1232251AAE814D00CE8F6C /* srs_kernel_file.cpp in Sources */,
|
||||||
|
3C1232AD1AAE81D900CE8F6C /* srs_app_reload.cpp in Sources */,
|
||||||
|
3C1231F81AAE652D00CE8F6C /* srs_core.cpp in Sources */,
|
||||||
|
3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */,
|
||||||
|
3C663F121AB0155100286D8B /* srs_detect_rtmp.c in Sources */,
|
||||||
|
3C1232B11AAE81D900CE8F6C /* srs_app_server.cpp in Sources */,
|
||||||
|
3C1232B31AAE81D900CE8F6C /* srs_app_st_socket.cpp in Sources */,
|
||||||
|
3C1232061AAE812C00CE8F6C /* srs_main_server.cpp in Sources */,
|
||||||
|
3C1232281AAE814D00CE8F6C /* srs_kernel_mp3.cpp in Sources */,
|
||||||
|
3C1232B21AAE81D900CE8F6C /* srs_app_source.cpp in Sources */,
|
||||||
|
3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */,
|
||||||
|
3C1232981AAE81D900CE8F6C /* srs_app_edge.cpp in Sources */,
|
||||||
|
3C1232461AAE81A400CE8F6C /* srs_rtmp_msg_array.cpp in Sources */,
|
||||||
|
3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */,
|
||||||
|
3C1232261AAE814D00CE8F6C /* srs_kernel_flv.cpp in Sources */,
|
||||||
|
3C663F1A1AB0155100286D8B /* srs_rtmp_dump.c in Sources */,
|
||||||
|
3C1232241AAE814D00CE8F6C /* srs_kernel_error.cpp in Sources */,
|
||||||
|
3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */,
|
||||||
|
3C1232291AAE814D00CE8F6C /* srs_kernel_stream.cpp in Sources */,
|
||||||
|
3C663F181AB0155100286D8B /* srs_play.c in Sources */,
|
||||||
|
3C1232B61AAE81D900CE8F6C /* srs_app_thread.cpp in Sources */,
|
||||||
|
3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */,
|
||||||
|
3C1232AE1AAE81D900CE8F6C /* srs_app_rtmp_conn.cpp in Sources */,
|
||||||
|
3C1232B51AAE81D900CE8F6C /* srs_app_statistic.cpp in Sources */,
|
||||||
|
3C663F161AB0155100286D8B /* srs_ingest_flv.c in Sources */,
|
||||||
|
3C663F141AB0155100286D8B /* srs_flv_parser.c in Sources */,
|
||||||
|
3C1232451AAE81A400CE8F6C /* srs_rtmp_io.cpp in Sources */,
|
||||||
|
3C1232431AAE81A400CE8F6C /* srs_rtmp_buffer.cpp in Sources */,
|
||||||
|
3C663F0E1AB0155100286D8B /* Makefile in Sources */,
|
||||||
|
3C1232211AAE814D00CE8F6C /* srs_kernel_buffer.cpp in Sources */,
|
||||||
|
3C1232471AAE81A400CE8F6C /* srs_rtmp_sdk.cpp in Sources */,
|
||||||
|
3C1232A61AAE81D900CE8F6C /* srs_app_kbps.cpp in Sources */,
|
||||||
|
3C12329D1AAE81D900CE8F6C /* srs_app_heartbeat.cpp in Sources */,
|
||||||
|
3C1232231AAE814D00CE8F6C /* srs_kernel_consts.cpp in Sources */,
|
||||||
|
3C1232AF1AAE81D900CE8F6C /* srs_app_rtsp.cpp in Sources */,
|
||||||
|
3C1232A31AAE81D900CE8F6C /* srs_app_http.cpp in Sources */,
|
||||||
|
3C12329A1AAE81D900CE8F6C /* srs_app_encoder.cpp in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
3C1231EA1AAE64A400CE8F6C /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
3C1231EB1AAE64A400CE8F6C /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
3C1231ED1AAE64A400CE8F6C /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "c++98";
|
||||||
|
CLANG_CXX_LIBRARY = "libstdc++";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"../../objs/**",
|
||||||
|
"/Users/winlin/Desktop/git/simple-rtmp-server/trunk/objs/http-parser-2.1",
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
"USER_HEADER_SEARCH_PATHS[arch=*]" = "../../src/** ../../objs ../../objs/st ../../objs/hp ../../objs/openssl";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
3C1231EE1AAE64A400CE8F6C /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = YES;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "c++98";
|
||||||
|
CLANG_CXX_LIBRARY = "libstdc++";
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"../../objs/**",
|
||||||
|
"/Users/winlin/Desktop/git/simple-rtmp-server/trunk/objs/http-parser-2.1",
|
||||||
|
);
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
3C1231E01AAE64A400CE8F6C /* Build configuration list for PBXProject "srs_xcode" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
3C1231EA1AAE64A400CE8F6C /* Debug */,
|
||||||
|
3C1231EB1AAE64A400CE8F6C /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
3C1231EC1AAE64A400CE8F6C /* Build configuration list for PBXNativeTarget "srs_xcode" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
3C1231ED1AAE64A400CE8F6C /* Debug */,
|
||||||
|
3C1231EE1AAE64A400CE8F6C /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 3C1231DD1AAE64A400CE8F6C /* Project object */;
|
||||||
|
}
|
7
trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:srs_xcode.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
1
trunk/ide/srs_xcode/srs_xcode/readme.txt
Normal file
1
trunk/ide/srs_xcode/srs_xcode/readme.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
the xcode project for osx.
|
11
trunk/modules/readme.txt
Normal file
11
trunk/modules/readme.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
SRS模块规则:
|
||||||
|
1. 一个模块一个目录
|
||||||
|
2. 目录下放一个config文件
|
||||||
|
3. 所有的configure中的变量模块中可以使用
|
||||||
|
|
||||||
|
模块中需要定义变量,例如:
|
||||||
|
1. SRS_MODULE_NAME:模块名称,用来做Makefile的phony以及执行binary文件名。
|
||||||
|
2. SRS_MODULE_MAIN:模块的main函数所在的cpp文件,在src/main目录。
|
||||||
|
3. SRS_MODULE_APP:模块在src/app目录的源文件列表。
|
||||||
|
|
||||||
|
winlin, 2015.3
|
|
@ -53,7 +53,8 @@ int main(int argc, char** argv)
|
||||||
// user option parse index.
|
// user option parse index.
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
// user options.
|
// user options.
|
||||||
char* in_flv_file; char* out_rtmp_url;
|
char* in_flv_file = NULL;
|
||||||
|
char* out_rtmp_url = NULL;
|
||||||
// rtmp handler
|
// rtmp handler
|
||||||
srs_rtmp_t ortmp;
|
srs_rtmp_t ortmp;
|
||||||
// flv handler
|
// flv handler
|
||||||
|
@ -75,18 +76,35 @@ int main(int argc, char** argv)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse options in FFMPEG format.
|
for (opt = 0; opt < argc; opt++) {
|
||||||
while ((opt = getopt(argc, argv, "i:y:")) != -1) {
|
srs_human_trace("argv[%d]=%s", opt, argv[opt]);
|
||||||
switch (opt) {
|
}
|
||||||
case 'i':
|
|
||||||
in_flv_file = optarg;
|
// fill the options for mac
|
||||||
break;
|
for (opt = 0; opt < argc - 1; opt++) {
|
||||||
case 'y':
|
// ignore all options except -i and -y.
|
||||||
out_rtmp_url = optarg;
|
char* p = argv[opt];
|
||||||
break;
|
|
||||||
default:
|
// only accept -x
|
||||||
break;
|
if (p[0] != '-' || p[1] == 0 || p[2] != 0) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse according the option name.
|
||||||
|
switch (p[1]) {
|
||||||
|
case 'i': in_flv_file = argv[opt + 1]; break;
|
||||||
|
case 'y': out_rtmp_url = argv[opt + 1]; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_flv_file) {
|
||||||
|
srs_human_trace("input invalid, use -i <input>");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!out_rtmp_url) {
|
||||||
|
srs_human_trace("output invalid, use -y <output>");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_human_trace("input: %s", in_flv_file);
|
srs_human_trace("input: %s", in_flv_file);
|
||||||
|
|
|
@ -41,7 +41,8 @@ int main(int argc, char** argv)
|
||||||
// user option parse index.
|
// user option parse index.
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
// user options.
|
// user options.
|
||||||
char* in_rtmp_url; char* out_rtmp_url;
|
char* in_rtmp_url = NULL;
|
||||||
|
char* out_rtmp_url = NULL;
|
||||||
// rtmp handler
|
// rtmp handler
|
||||||
srs_rtmp_t irtmp, ortmp;
|
srs_rtmp_t irtmp, ortmp;
|
||||||
|
|
||||||
|
@ -60,18 +61,31 @@ int main(int argc, char** argv)
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse options in FFMPEG format.
|
// fill the options for mac
|
||||||
while ((opt = getopt(argc, argv, "i:y:")) != -1) {
|
for (opt = 0; opt < argc - 1; opt++) {
|
||||||
switch (opt) {
|
// ignore all options except -i and -y.
|
||||||
case 'i':
|
char* p = argv[opt];
|
||||||
in_rtmp_url = optarg;
|
|
||||||
break;
|
// only accept -x
|
||||||
case 'y':
|
if (p[0] != '-' || p[1] == 0 || p[2] != 0) {
|
||||||
out_rtmp_url = optarg;
|
continue;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse according the option name.
|
||||||
|
switch (p[1]) {
|
||||||
|
case 'i': in_rtmp_url = argv[opt + 1]; break;
|
||||||
|
case 'y': out_rtmp_url = argv[opt + 1]; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_rtmp_url) {
|
||||||
|
srs_human_trace("input invalid, use -i <input>");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!out_rtmp_url) {
|
||||||
|
srs_human_trace("output invalid, use -y <output>");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_human_trace("input: %s", in_rtmp_url);
|
srs_human_trace("input: %s", in_rtmp_url);
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#######################################
|
#######################################
|
||||||
# color echo.
|
# color echo.
|
||||||
#######################################
|
#######################################
|
||||||
RED="\\e[31m"
|
RED="\\033[31m"
|
||||||
GREEN="\\e[32m"
|
GREEN="\\033[32m"
|
||||||
YELLOW="\\e[33m"
|
YELLOW="\\033[33m"
|
||||||
BLACK="\\e[0m"
|
BLACK="\\033[0m"
|
||||||
POS="\\e[103G"
|
POS="\\033[103G"
|
||||||
|
|
||||||
# if need to log to file, change the log path.
|
# if need to log to file, change the log path.
|
||||||
if [[ ! $log ]]; then
|
if [[ ! $log ]]; then
|
||||||
|
|
|
@ -1419,7 +1419,6 @@ int SrsConfig::check_config()
|
||||||
string m = conf->at(j)->name.c_str();
|
string m = conf->at(j)->name.c_str();
|
||||||
if (m != "enabled" && m != "dvr_path" && m != "dvr_plan"
|
if (m != "enabled" && m != "dvr_path" && m != "dvr_plan"
|
||||||
&& m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter"
|
&& m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter"
|
||||||
&& m != "dvr_autostart"
|
|
||||||
) {
|
) {
|
||||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret);
|
srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret);
|
||||||
|
@ -1978,38 +1977,6 @@ int SrsConfig::get_stream_caster_rtp_port_max(SrsConfDirective* sc)
|
||||||
return ::atoi(conf->arg0().c_str());
|
return ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, string sub_directive)
|
|
||||||
{
|
|
||||||
SrsConfDirective* vhost_conf = get_vhost(vhost);
|
|
||||||
|
|
||||||
if (!vhost_conf) {
|
|
||||||
vhost_conf = new SrsConfDirective();
|
|
||||||
root->directives.push_back(vhost_conf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directive.empty()) {
|
|
||||||
return vhost_conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsConfDirective* dir = vhost_conf->get(directive);
|
|
||||||
if (!dir) {
|
|
||||||
dir = new SrsConfDirective();
|
|
||||||
vhost_conf->directives.push_back(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sub_directive.empty()) {
|
|
||||||
return dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsConfDirective* sdir = dir->get(sub_directive);
|
|
||||||
if (!sdir) {
|
|
||||||
sdir = new SrsConfDirective();
|
|
||||||
dir->directives.push_back(sdir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sdir;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsConfDirective* SrsConfig::get_vhost(string vhost)
|
SrsConfDirective* SrsConfig::get_vhost(string vhost)
|
||||||
{
|
{
|
||||||
srs_assert(root);
|
srs_assert(root);
|
||||||
|
@ -3422,13 +3389,6 @@ bool SrsConfig::get_dvr_enabled(string vhost)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::set_dvr_enabled(string vhost, bool enabled)
|
|
||||||
{
|
|
||||||
SrsConfDirective* conf = create_directive(vhost, "dvr", "enabled");
|
|
||||||
conf->args.clear();
|
|
||||||
conf->args.push_back(enabled? "on":"off");
|
|
||||||
}
|
|
||||||
|
|
||||||
string SrsConfig::get_dvr_path(string vhost)
|
string SrsConfig::get_dvr_path(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* dvr = get_dvr(vhost);
|
SrsConfDirective* dvr = get_dvr(vhost);
|
||||||
|
@ -3446,13 +3406,6 @@ string SrsConfig::get_dvr_path(string vhost)
|
||||||
return conf->arg0();
|
return conf->arg0();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::set_dvr_path(string vhost, string path)
|
|
||||||
{
|
|
||||||
SrsConfDirective* conf = create_directive(vhost, "dvr", "dvr_path");
|
|
||||||
conf->args.clear();
|
|
||||||
conf->args.push_back(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
string SrsConfig::get_dvr_plan(string vhost)
|
string SrsConfig::get_dvr_plan(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* dvr = get_dvr(vhost);
|
SrsConfDirective* dvr = get_dvr(vhost);
|
||||||
|
@ -3504,30 +3457,6 @@ bool SrsConfig::get_dvr_wait_keyframe(string vhost)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsConfig::set_dvr_wait_keyframe(string vhost, bool wait_keyframe)
|
|
||||||
{
|
|
||||||
SrsConfDirective* conf = create_directive(vhost, "dvr", "dvr_wait_keyframe");
|
|
||||||
conf->args.clear();
|
|
||||||
conf->args.push_back(wait_keyframe? "on":"off");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SrsConfig::get_dvr_autostart(string vhost)
|
|
||||||
{
|
|
||||||
SrsConfDirective* dvr = get_dvr(vhost);
|
|
||||||
|
|
||||||
if (!dvr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsConfDirective* conf = dvr->get("dvr_autostart");
|
|
||||||
|
|
||||||
if (!conf || conf->arg0() != "off") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsConfig::get_dvr_time_jitter(string vhost)
|
int SrsConfig::get_dvr_time_jitter(string vhost)
|
||||||
{
|
{
|
||||||
SrsConfDirective* dvr = get_dvr(vhost);
|
SrsConfDirective* dvr = get_dvr(vhost);
|
||||||
|
|
|
@ -61,7 +61,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
|
#define SRS_CONF_DEFAULT_DVR_PLAN_SESSION "session"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
|
#define SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT "segment"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_APPEND "append"
|
#define SRS_CONF_DEFAULT_DVR_PLAN_APPEND "append"
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN_API "api"
|
|
||||||
#define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION
|
#define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION
|
||||||
#define SRS_CONF_DEFAULT_DVR_DURATION 30
|
#define SRS_CONF_DEFAULT_DVR_DURATION 30
|
||||||
#define SRS_CONF_DEFAULT_TIME_JITTER "full"
|
#define SRS_CONF_DEFAULT_TIME_JITTER "full"
|
||||||
|
@ -357,11 +356,11 @@ private:
|
||||||
* print help and exit.
|
* print help and exit.
|
||||||
*/
|
*/
|
||||||
virtual void print_help(char** argv);
|
virtual void print_help(char** argv);
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* parse the config file, which is specified by cli.
|
* parse the config file, which is specified by cli.
|
||||||
*/
|
*/
|
||||||
virtual int parse_file(const char* filename);
|
virtual int parse_file(const char* filename);
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* check the parsed config.
|
* check the parsed config.
|
||||||
*/
|
*/
|
||||||
|
@ -457,14 +456,6 @@ public:
|
||||||
* get the max udp port for rtp of stream caster rtsp.
|
* get the max udp port for rtp of stream caster rtsp.
|
||||||
*/
|
*/
|
||||||
virtual int get_stream_caster_rtp_port_max(SrsConfDirective* sc);
|
virtual int get_stream_caster_rtp_port_max(SrsConfDirective* sc);
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* create directive under vhost.
|
|
||||||
* @param directive, get the directive of vhost. get vhost if directive is empty.
|
|
||||||
* @param sub_directive, get the sub directive of vhost. get directive if sub-directive is empty.
|
|
||||||
* @return the vhost(empty directive and sub-directive); the directive(empty sub-directive); the sub-directive.
|
|
||||||
*/
|
|
||||||
virtual SrsConfDirective* create_directive(std::string vhost, std::string directive, std::string sub_directive);
|
|
||||||
// vhost specified section
|
// vhost specified section
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -954,12 +945,10 @@ public:
|
||||||
* whether dvr is enabled.
|
* whether dvr is enabled.
|
||||||
*/
|
*/
|
||||||
virtual bool get_dvr_enabled(std::string vhost);
|
virtual bool get_dvr_enabled(std::string vhost);
|
||||||
virtual void set_dvr_enabled(std::string vhost, bool enabled);
|
|
||||||
/**
|
/**
|
||||||
* get the dvr path, the flv file to save in.
|
* get the dvr path, the flv file to save in.
|
||||||
*/
|
*/
|
||||||
virtual std::string get_dvr_path(std::string vhost);
|
virtual std::string get_dvr_path(std::string vhost);
|
||||||
virtual void set_dvr_path(std::string vhost, std::string path);
|
|
||||||
/**
|
/**
|
||||||
* get the plan of dvr, how to reap the flv file.
|
* get the plan of dvr, how to reap the flv file.
|
||||||
*/
|
*/
|
||||||
|
@ -972,11 +961,6 @@ public:
|
||||||
* whether wait keyframe to reap segment.
|
* whether wait keyframe to reap segment.
|
||||||
*/
|
*/
|
||||||
virtual bool get_dvr_wait_keyframe(std::string vhost);
|
virtual bool get_dvr_wait_keyframe(std::string vhost);
|
||||||
virtual void set_dvr_wait_keyframe(std::string vhost, bool wait_keyframe);
|
|
||||||
/**
|
|
||||||
* whether autostart for dvr. wait api to start dvr if false.
|
|
||||||
*/
|
|
||||||
virtual bool get_dvr_autostart(std::string vhost);
|
|
||||||
/**
|
/**
|
||||||
* get the time_jitter algorithm for dvr.
|
* get the time_jitter algorithm for dvr.
|
||||||
*/
|
*/
|
||||||
|
@ -1148,3 +1132,4 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b);
|
||||||
extern SrsConfig* _srs_config;
|
extern SrsConfig* _srs_config;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
|
SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
|
||||||
{
|
{
|
||||||
|
id = 0;
|
||||||
server = srs_server;
|
server = srs_server;
|
||||||
stfd = client_stfd;
|
stfd = client_stfd;
|
||||||
|
|
||||||
|
@ -55,6 +56,8 @@ int SrsConnection::cycle()
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
_srs_context->generate_id();
|
_srs_context->generate_id();
|
||||||
|
id = _srs_context->get_id();
|
||||||
|
|
||||||
ip = srs_get_peer_ip(st_netfd_fileno(stfd));
|
ip = srs_get_peer_ip(st_netfd_fileno(stfd));
|
||||||
|
|
||||||
ret = do_cycle();
|
ret = do_cycle();
|
||||||
|
@ -86,6 +89,11 @@ void SrsConnection::on_thread_stop()
|
||||||
server->remove(this);
|
server->remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsConnection::srs_id()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsConnection::stop()
|
void SrsConnection::stop()
|
||||||
{
|
{
|
||||||
srs_close_stfd(stfd);
|
srs_close_stfd(stfd);
|
||||||
|
|
|
@ -51,6 +51,10 @@ private:
|
||||||
* when thread stop, the connection will be delete by server.
|
* when thread stop, the connection will be delete by server.
|
||||||
*/
|
*/
|
||||||
SrsThread* pthread;
|
SrsThread* pthread;
|
||||||
|
/**
|
||||||
|
* the id of connection.
|
||||||
|
*/
|
||||||
|
int id;
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* the server object to manage the connection.
|
* the server object to manage the connection.
|
||||||
|
@ -92,13 +96,9 @@ public:
|
||||||
virtual void on_thread_stop();
|
virtual void on_thread_stop();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* when server to get the kbps of connection,
|
* get the srs id which identify the client.
|
||||||
* it cannot wait the connection terminated then get the kbps,
|
|
||||||
* it must sample the kbps every some interval, for instance, 9s to sample all connections kbps,
|
|
||||||
* all connections will extends from IKbpsDelta which provides the bytes delta,
|
|
||||||
* while the delta must be update by the sample which invoke by the kbps_resample().
|
|
||||||
*/
|
*/
|
||||||
virtual void kbps_resample() = 0;
|
virtual int srs_id();
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* for concrete connection to do the cycle.
|
* for concrete connection to do the cycle.
|
||||||
|
|
|
@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <algorithm>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include <srs_app_config.hpp>
|
#include <srs_app_config.hpp>
|
||||||
|
@ -54,7 +55,6 @@ using namespace std;
|
||||||
SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p)
|
SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p)
|
||||||
{
|
{
|
||||||
req = NULL;
|
req = NULL;
|
||||||
source = NULL;
|
|
||||||
jitter = NULL;
|
jitter = NULL;
|
||||||
plan = p;
|
plan = p;
|
||||||
|
|
||||||
|
@ -85,11 +85,10 @@ SrsFlvSegment::~SrsFlvSegment()
|
||||||
srs_freep(enc);
|
srs_freep(enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsFlvSegment::initialize(SrsSource* s, SrsRequest* r)
|
int SrsFlvSegment::initialize(SrsRequest* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
source = s;
|
|
||||||
req = r;
|
req = r;
|
||||||
jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost);
|
jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost);
|
||||||
|
|
||||||
|
@ -308,10 +307,10 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* __video)
|
||||||
char* payload = video->payload;
|
char* payload = video->payload;
|
||||||
int size = video->size;
|
int size = video->size;
|
||||||
|
|
||||||
|
bool is_sequence_header = SrsFlvCodec::video_is_sequence_header(payload, size);
|
||||||
#ifdef SRS_AUTO_HTTP_CALLBACK
|
#ifdef SRS_AUTO_HTTP_CALLBACK
|
||||||
bool is_key_frame = SrsFlvCodec::video_is_h264(payload, size)
|
bool is_key_frame = SrsFlvCodec::video_is_h264(payload, size)
|
||||||
&& SrsFlvCodec::video_is_keyframe(payload, size)
|
&& SrsFlvCodec::video_is_keyframe(payload, size) && !is_sequence_header;
|
||||||
&& !SrsFlvCodec::video_is_sequence_header(payload, size);
|
|
||||||
if (is_key_frame) {
|
if (is_key_frame) {
|
||||||
has_keyframe = true;
|
has_keyframe = true;
|
||||||
if ((ret = plan->on_video_keyframe()) != ERROR_SUCCESS) {
|
if ((ret = plan->on_video_keyframe()) != ERROR_SUCCESS) {
|
||||||
|
@ -320,6 +319,16 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* __video)
|
||||||
}
|
}
|
||||||
srs_verbose("dvr video is key: %d", is_key_frame);
|
srs_verbose("dvr video is key: %d", is_key_frame);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// accept the sequence header here.
|
||||||
|
// when got no keyframe, ignore when should wait keyframe.
|
||||||
|
if (!has_keyframe && !is_sequence_header) {
|
||||||
|
bool wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);
|
||||||
|
if (wait_keyframe) {
|
||||||
|
srs_info("dvr: ignore when wait keyframe.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((jitter->correct(video, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
|
if ((jitter->correct(video, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -617,48 +626,6 @@ string SrsDvrAsyncCallOnDvr::to_string()
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsDvrAsyncCallOnSegment::SrsDvrAsyncCallOnSegment(SrsRequest* r, string c, string p)
|
|
||||||
{
|
|
||||||
req = r;
|
|
||||||
callback = c;
|
|
||||||
path = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsDvrAsyncCallOnSegment::~SrsDvrAsyncCallOnSegment()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrAsyncCallOnSegment::call()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HTTP_CALLBACK
|
|
||||||
// HTTP: callback
|
|
||||||
if (callback.empty()) {
|
|
||||||
srs_warn("dvr: ignore for callback empty, vhost=%s", req->vhost.c_str());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int connection_id = _srs_context->get_id();
|
|
||||||
std::string cwd = _srs_config->cwd();
|
|
||||||
std::string file = path;
|
|
||||||
std::string url = callback;
|
|
||||||
if ((ret = SrsHttpHooks::on_dvr_reap_segment(url, connection_id, req, cwd, file)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("hook client on_dvr_reap_segment failed. url=%s, ret=%d", url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
string SrsDvrAsyncCallOnSegment::to_string()
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "vhost=" << req->vhost << ", file=" << path << "callback=" << callback;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsDvrAsyncCallThread::SrsDvrAsyncCallThread()
|
SrsDvrAsyncCallThread::SrsDvrAsyncCallThread()
|
||||||
{
|
{
|
||||||
pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true);
|
pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true);
|
||||||
|
@ -717,7 +684,6 @@ int SrsDvrAsyncCallThread::cycle()
|
||||||
|
|
||||||
SrsDvrPlan::SrsDvrPlan()
|
SrsDvrPlan::SrsDvrPlan()
|
||||||
{
|
{
|
||||||
source = NULL;
|
|
||||||
req = NULL;
|
req = NULL;
|
||||||
|
|
||||||
dvr_enabled = false;
|
dvr_enabled = false;
|
||||||
|
@ -731,14 +697,13 @@ SrsDvrPlan::~SrsDvrPlan()
|
||||||
srs_freep(async);
|
srs_freep(async);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsDvrPlan::initialize(SrsSource* s, SrsRequest* r)
|
int SrsDvrPlan::initialize(SrsRequest* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
source = s;
|
|
||||||
req = r;
|
req = r;
|
||||||
|
|
||||||
if ((ret = segment->initialize(s, r)) != ERROR_SUCCESS) {
|
if ((ret = segment->initialize(r)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,18 +714,6 @@ int SrsDvrPlan::initialize(SrsSource* s, SrsRequest* r)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsDvrPlan::on_dvr_request_sh()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
// the dvr is enabled, notice the source to push the data.
|
|
||||||
if ((ret = source->on_dvr_request_sh()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrPlan::on_video_keyframe()
|
int SrsDvrPlan::on_video_keyframe()
|
||||||
{
|
{
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
@ -832,8 +785,6 @@ SrsDvrPlan* SrsDvrPlan::create_plan(string vhost)
|
||||||
return new SrsDvrSessionPlan();
|
return new SrsDvrSessionPlan();
|
||||||
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
|
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
|
||||||
return new SrsDvrAppendPlan();
|
return new SrsDvrAppendPlan();
|
||||||
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_API) {
|
|
||||||
return new SrsDvrApiPlan();
|
|
||||||
} else {
|
} else {
|
||||||
srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
|
srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
|
||||||
srs_assert(false);
|
srs_assert(false);
|
||||||
|
@ -890,320 +841,6 @@ void SrsDvrSessionPlan::on_unpublish()
|
||||||
dvr_enabled = false;
|
dvr_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsDvrApiPlan::SrsDvrApiPlan()
|
|
||||||
{
|
|
||||||
autostart = false;
|
|
||||||
started = false;
|
|
||||||
|
|
||||||
metadata = sh_audio = sh_video = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsDvrApiPlan::~SrsDvrApiPlan()
|
|
||||||
{
|
|
||||||
srs_freep(metadata);
|
|
||||||
srs_freep(sh_audio);
|
|
||||||
srs_freep(sh_video);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::initialize(SrsSource* s, SrsRequest* r)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if ((ret = SrsDvrPlan::initialize(s, r)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsApiDvrPool* pool = SrsApiDvrPool::instance();
|
|
||||||
if ((ret = pool->add_dvr(this)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
autostart = _srs_config->get_dvr_autostart(r->vhost);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::on_publish()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
// support multiple publish.
|
|
||||||
if (dvr_enabled) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_srs_config->get_dvr_enabled(req->vhost)) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// api disabled dvr when not autostart.
|
|
||||||
bool autostart = _srs_config->get_dvr_autostart(req->vhost);
|
|
||||||
if (!autostart && !started) {
|
|
||||||
srs_warn("dvr: api not start and disabled for not autostart.");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dvr_enabled = true;
|
|
||||||
|
|
||||||
if ((ret = segment->close()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = segment->open()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update sequence header
|
|
||||||
if (metadata && (ret = SrsDvrPlan::on_meta_data(metadata)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (sh_audio && (ret = SrsDvrPlan::on_audio(sh_audio)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsDvrApiPlan::on_unpublish()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::on_meta_data(SrsSharedPtrMessage* __metadata)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_freep(metadata);
|
|
||||||
metadata = __metadata->copy();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::on_audio(SrsSharedPtrMessage* __audio)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (SrsFlvCodec::audio_is_sequence_header(__audio->payload, __audio->size)) {
|
|
||||||
srs_freep(sh_audio);
|
|
||||||
sh_audio = __audio->copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = SrsDvrPlan::on_audio(__audio)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::on_video(SrsSharedPtrMessage* __video)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (SrsFlvCodec::video_is_sequence_header(__video->payload, __video->size)) {
|
|
||||||
srs_freep(sh_video);
|
|
||||||
sh_video = __video->copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = check_user_actions(__video)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = SrsDvrPlan::on_video(__video)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::set_path_tmpl(string path_tmpl)
|
|
||||||
{
|
|
||||||
_srs_config->set_dvr_path(req->vhost, path_tmpl);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::set_callback(string value)
|
|
||||||
{
|
|
||||||
callback = value;
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::set_wait_keyframe(bool wait_keyframe)
|
|
||||||
{
|
|
||||||
_srs_config->set_dvr_wait_keyframe(req->vhost, wait_keyframe);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::start()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (started) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable the config.
|
|
||||||
_srs_config->set_dvr_enabled(req->vhost, true);
|
|
||||||
|
|
||||||
// stop dvr
|
|
||||||
if (dvr_enabled) {
|
|
||||||
// ignore error.
|
|
||||||
int ret = segment->close();
|
|
||||||
if (ret != ERROR_SUCCESS) {
|
|
||||||
srs_warn("ignore flv close error. ret=%d", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
dvr_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start dvr
|
|
||||||
if ((ret = on_publish()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
started = true;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::dumps(stringstream& ss)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
bool wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);
|
|
||||||
std::string path_template = _srs_config->get_dvr_path(req->vhost);
|
|
||||||
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_STR("path_tmpl", path_template) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_STR("path_dvr", segment->get_path()) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_BOOL("wait_keyframe", wait_keyframe) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_STR("callback", callback) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_STR("status", (dvr_enabled? "start":"stop"))
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::stop()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
_srs_config->set_dvr_enabled(req->vhost, false);
|
|
||||||
started = false;
|
|
||||||
|
|
||||||
// stop dvr
|
|
||||||
if (dvr_enabled) {
|
|
||||||
// ignore error.
|
|
||||||
int ret = segment->close();
|
|
||||||
if (ret != ERROR_SUCCESS) {
|
|
||||||
srs_warn("ignore flv close error. ret=%d", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
dvr_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_trace("dvr: stop dvr of vhost=%s", req->vhost.c_str());
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::rpc(SrsJsonObject* obj)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
SrsJsonAny* prop = NULL;
|
|
||||||
if ((prop = obj->ensure_property_string("action")) == NULL) {
|
|
||||||
ret = ERROR_HTTP_DVR_REQUEST;
|
|
||||||
srs_error("dvr: rpc required action request. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
action = prop->to_str();
|
|
||||||
if (action == SRS_DVR_USER_ACTION_REAP_SEGMENT) {
|
|
||||||
if ((prop = obj->ensure_property_string("path_tmpl")) != NULL) {
|
|
||||||
path_template = prop->to_str();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = ERROR_HTTP_DVR_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::on_reap_segment()
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if ((ret = SrsDvrPlan::on_reap_segment()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = async->call(new SrsDvrAsyncCallOnSegment(req, callback, segment->get_path()))) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsDvrApiPlan::check_user_actions(SrsSharedPtrMessage* msg)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_assert(segment);
|
|
||||||
|
|
||||||
if (action == SRS_DVR_USER_ACTION_REAP_SEGMENT) {
|
|
||||||
// when wait keyframe, ignore if no frame arrived.
|
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/177
|
|
||||||
if (_srs_config->get_dvr_wait_keyframe(req->vhost)) {
|
|
||||||
if (!msg->is_video()) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* payload = msg->payload;
|
|
||||||
int size = msg->size;
|
|
||||||
bool is_key_frame = SrsFlvCodec::video_is_h264(payload, size)
|
|
||||||
&& SrsFlvCodec::video_is_keyframe(payload, size)
|
|
||||||
&& !SrsFlvCodec::video_is_sequence_header(payload, size);
|
|
||||||
if (!is_key_frame) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reap segment
|
|
||||||
if ((ret = segment->close()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use new path template if user specified.
|
|
||||||
if (!path_template.empty() && (ret = set_path_tmpl(path_template)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open new flv file
|
|
||||||
if ((ret = segment->open()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update sequence header
|
|
||||||
if (metadata && (ret = SrsDvrPlan::on_meta_data(metadata)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (sh_audio && (ret = SrsDvrPlan::on_audio(sh_audio)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset rcp params.
|
|
||||||
action = "";
|
|
||||||
path_template = "";
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsDvrAppendPlan::SrsDvrAppendPlan()
|
SrsDvrAppendPlan::SrsDvrAppendPlan()
|
||||||
{
|
{
|
||||||
last_update_time = 0;
|
last_update_time = 0;
|
||||||
|
@ -1309,11 +946,11 @@ SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
|
||||||
srs_freep(metadata);
|
srs_freep(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsDvrSegmentPlan::initialize(SrsSource* source, SrsRequest* req)
|
int SrsDvrSegmentPlan::initialize(SrsRequest* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if ((ret = SrsDvrPlan::initialize(source, req)) != ERROR_SUCCESS) {
|
if ((ret = SrsDvrPlan::initialize(req)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1460,183 +1097,9 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsApiDvrPool* SrsApiDvrPool::_instance = new SrsApiDvrPool();
|
SrsDvr::SrsDvr()
|
||||||
|
|
||||||
SrsApiDvrPool* SrsApiDvrPool::instance()
|
|
||||||
{
|
{
|
||||||
return SrsApiDvrPool::_instance;
|
source = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
SrsApiDvrPool::SrsApiDvrPool()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsApiDvrPool::~SrsApiDvrPool()
|
|
||||||
{
|
|
||||||
dvrs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsApiDvrPool::add_dvr(SrsDvrApiPlan* dvr)
|
|
||||||
{
|
|
||||||
dvrs.push_back(dvr);
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsApiDvrPool::dumps(string vhost, stringstream& ss)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
ss << __SRS_JARRAY_START;
|
|
||||||
|
|
||||||
std::vector<SrsDvrApiPlan*> plans;
|
|
||||||
for (int i = 0; i < (int)dvrs.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = dvrs.at(i);
|
|
||||||
if (!vhost.empty() && plan->req->vhost != vhost) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
plans.push_back(plan);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)plans.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = plans.at(i);
|
|
||||||
|
|
||||||
if ((ret = plan->dumps(ss)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < (int)dvrs.size() - 1) {
|
|
||||||
ss << __SRS_JFIELD_CONT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << __SRS_JARRAY_END;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsApiDvrPool::create(SrsJsonAny* json)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
srs_assert(json);
|
|
||||||
if (!json->is_object()) {
|
|
||||||
ret = ERROR_HTTP_DVR_CREATE_REQUEST;
|
|
||||||
srs_error("dvr: api create dvr request requires json object. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsJsonObject* obj = json->to_object();
|
|
||||||
SrsJsonAny* prop = NULL;
|
|
||||||
if ((prop = obj->ensure_property_string("vhost")) == NULL) {
|
|
||||||
ret = ERROR_HTTP_DVR_CREATE_REQUEST;
|
|
||||||
srs_error("dvr: api create dvr request requires vhost. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string vhost = prop->to_str();
|
|
||||||
SrsDvrApiPlan* dvr = NULL;
|
|
||||||
for (int i = 0; i < (int)dvrs.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = dvrs.at(i);
|
|
||||||
if (!vhost.empty() && plan->req->vhost != vhost) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dvr = plan;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dvr) {
|
|
||||||
ret = ERROR_HTTP_DVR_CREATE_REQUEST;
|
|
||||||
srs_error("dvr: api create dvr request vhost invalid. vhost=%s. ret=%d", vhost.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update optional parameters for plan.
|
|
||||||
if ((prop = obj->ensure_property_string("path_tmpl")) != NULL) {
|
|
||||||
if ((ret = dvr->set_path_tmpl(prop->to_str())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((prop = obj->ensure_property_boolean("wait_keyframe")) != NULL) {
|
|
||||||
if ((ret = dvr->set_wait_keyframe(prop->to_boolean())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((prop = obj->ensure_property_string("callback")) != NULL) {
|
|
||||||
if ((ret = dvr->set_callback(prop->to_str())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dvr->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsApiDvrPool::stop(string vhost)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
std::vector<SrsDvrApiPlan*> plans;
|
|
||||||
for (int i = 0; i < (int)dvrs.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = dvrs.at(i);
|
|
||||||
if (!vhost.empty() && plan->req->vhost != vhost) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
plans.push_back(plan);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)plans.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = plans.at(i);
|
|
||||||
|
|
||||||
if ((ret = plan->stop()) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsApiDvrPool::rpc(SrsJsonAny* json)
|
|
||||||
{
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (!json->is_object()) {
|
|
||||||
ret = ERROR_HTTP_DVR_REQUEST;
|
|
||||||
srs_error("dvr: rpc required object request. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsJsonObject* obj = json->to_object();
|
|
||||||
|
|
||||||
SrsJsonAny* prop = NULL;
|
|
||||||
if ((prop = obj->ensure_property_string("vhost")) == NULL) {
|
|
||||||
ret = ERROR_HTTP_DVR_REQUEST;
|
|
||||||
srs_error("dvr: rpc required vhost request. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
std::string vhost = prop->to_str();
|
|
||||||
|
|
||||||
std::vector<SrsDvrApiPlan*> plans;
|
|
||||||
for (int i = 0; i < (int)dvrs.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = dvrs.at(i);
|
|
||||||
if (!vhost.empty() && plan->req->vhost != vhost) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
plans.push_back(plan);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)plans.size(); i++) {
|
|
||||||
SrsDvrApiPlan* plan = plans.at(i);
|
|
||||||
|
|
||||||
if ((ret = plan->rpc(obj)) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsDvr::SrsDvr(SrsSource* s)
|
|
||||||
{
|
|
||||||
source = s;
|
|
||||||
plan = NULL;
|
plan = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,14 +1108,20 @@ SrsDvr::~SrsDvr()
|
||||||
srs_freep(plan);
|
srs_freep(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsDvr::initialize(SrsRequest* r)
|
int SrsDvr::initialize(SrsSource* s, SrsRequest* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
source = s;
|
||||||
|
|
||||||
srs_freep(plan);
|
srs_freep(plan);
|
||||||
plan = SrsDvrPlan::create_plan(r->vhost);
|
plan = SrsDvrPlan::create_plan(r->vhost);
|
||||||
|
|
||||||
if ((ret = plan->initialize(source, r)) != ERROR_SUCCESS) {
|
if ((ret = plan->initialize(r)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = source->on_dvr_request_sh()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1675,6 +1144,7 @@ void SrsDvr::on_unpublish()
|
||||||
plan->on_unpublish();
|
plan->on_unpublish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: FIXME: source should use shared message instead.
|
||||||
int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m)
|
int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
|
@ -58,7 +58,6 @@ class SrsThread;
|
||||||
class SrsFlvSegment : public ISrsReloadHandler
|
class SrsFlvSegment : public ISrsReloadHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsSource* source;
|
|
||||||
SrsRequest* req;
|
SrsRequest* req;
|
||||||
SrsDvrPlan* plan;
|
SrsDvrPlan* plan;
|
||||||
private:
|
private:
|
||||||
|
@ -121,7 +120,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* initialize the segment.
|
* initialize the segment.
|
||||||
*/
|
*/
|
||||||
virtual int initialize(SrsSource* s, SrsRequest* r);
|
virtual int initialize(SrsRequest* r);
|
||||||
/**
|
/**
|
||||||
* whether segment is overflow.
|
* whether segment is overflow.
|
||||||
*/
|
*/
|
||||||
|
@ -200,19 +199,6 @@ public:
|
||||||
virtual int call();
|
virtual int call();
|
||||||
virtual std::string to_string();
|
virtual std::string to_string();
|
||||||
};
|
};
|
||||||
class SrsDvrAsyncCallOnSegment : public ISrsDvrAsyncCall
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string callback;
|
|
||||||
std::string path;
|
|
||||||
SrsRequest* req;
|
|
||||||
public:
|
|
||||||
SrsDvrAsyncCallOnSegment(SrsRequest* r, std::string c, std::string p);
|
|
||||||
virtual ~SrsDvrAsyncCallOnSegment();
|
|
||||||
public:
|
|
||||||
virtual int call();
|
|
||||||
virtual std::string to_string();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the async callback for dvr.
|
* the async callback for dvr.
|
||||||
|
@ -247,7 +233,6 @@ public:
|
||||||
public:
|
public:
|
||||||
SrsRequest* req;
|
SrsRequest* req;
|
||||||
protected:
|
protected:
|
||||||
SrsSource* source;
|
|
||||||
SrsFlvSegment* segment;
|
SrsFlvSegment* segment;
|
||||||
SrsDvrAsyncCallThread* async;
|
SrsDvrAsyncCallThread* async;
|
||||||
bool dvr_enabled;
|
bool dvr_enabled;
|
||||||
|
@ -255,7 +240,7 @@ public:
|
||||||
SrsDvrPlan();
|
SrsDvrPlan();
|
||||||
virtual ~SrsDvrPlan();
|
virtual ~SrsDvrPlan();
|
||||||
public:
|
public:
|
||||||
virtual int initialize(SrsSource* s, SrsRequest* r);
|
virtual int initialize(SrsRequest* r);
|
||||||
virtual int on_publish() = 0;
|
virtual int on_publish() = 0;
|
||||||
virtual void on_unpublish() = 0;
|
virtual void on_unpublish() = 0;
|
||||||
/**
|
/**
|
||||||
|
@ -272,7 +257,6 @@ public:
|
||||||
virtual int on_video(SrsSharedPtrMessage* __video);
|
virtual int on_video(SrsSharedPtrMessage* __video);
|
||||||
protected:
|
protected:
|
||||||
virtual int on_reap_segment();
|
virtual int on_reap_segment();
|
||||||
virtual int on_dvr_request_sh();
|
|
||||||
virtual int on_video_keyframe();
|
virtual int on_video_keyframe();
|
||||||
virtual int64_t filter_timestamp(int64_t timestamp);
|
virtual int64_t filter_timestamp(int64_t timestamp);
|
||||||
public:
|
public:
|
||||||
|
@ -292,48 +276,6 @@ public:
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* api plan: reap flv by api.
|
|
||||||
*/
|
|
||||||
class SrsDvrApiPlan : public SrsDvrPlan
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
// cache the metadata and sequence header, for new segment maybe opened.
|
|
||||||
SrsSharedPtrMessage* sh_audio;
|
|
||||||
SrsSharedPtrMessage* sh_video;
|
|
||||||
SrsSharedPtrMessage* metadata;
|
|
||||||
private:
|
|
||||||
std::string callback;
|
|
||||||
bool autostart;
|
|
||||||
bool started;
|
|
||||||
private:
|
|
||||||
// user action, reap_segment.
|
|
||||||
std::string action;
|
|
||||||
std::string path_template;
|
|
||||||
public:
|
|
||||||
SrsDvrApiPlan();
|
|
||||||
virtual ~SrsDvrApiPlan();
|
|
||||||
public:
|
|
||||||
virtual int initialize(SrsSource* s, SrsRequest* r);
|
|
||||||
virtual int on_publish();
|
|
||||||
virtual void on_unpublish();
|
|
||||||
virtual int on_meta_data(SrsSharedPtrMessage* __metadata);
|
|
||||||
virtual int on_audio(SrsSharedPtrMessage* __audio);
|
|
||||||
virtual int on_video(SrsSharedPtrMessage* __video);
|
|
||||||
public:
|
|
||||||
virtual int set_path_tmpl(std::string path_tmpl);
|
|
||||||
virtual int set_callback(std::string value);
|
|
||||||
virtual int set_wait_keyframe(bool wait_keyframe);
|
|
||||||
virtual int start();
|
|
||||||
virtual int dumps(std::stringstream& ss);
|
|
||||||
virtual int stop();
|
|
||||||
virtual int rpc(SrsJsonObject* obj);
|
|
||||||
protected:
|
|
||||||
virtual int on_reap_segment();
|
|
||||||
private:
|
|
||||||
virtual int check_user_actions(SrsSharedPtrMessage* msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* always append to flv file, never reap it.
|
* always append to flv file, never reap it.
|
||||||
*/
|
*/
|
||||||
|
@ -368,7 +310,7 @@ public:
|
||||||
SrsDvrSegmentPlan();
|
SrsDvrSegmentPlan();
|
||||||
virtual ~SrsDvrSegmentPlan();
|
virtual ~SrsDvrSegmentPlan();
|
||||||
public:
|
public:
|
||||||
virtual int initialize(SrsSource* source, SrsRequest* req);
|
virtual int initialize(SrsRequest* req);
|
||||||
virtual int on_publish();
|
virtual int on_publish();
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
virtual int on_meta_data(SrsSharedPtrMessage* __metadata);
|
virtual int on_meta_data(SrsSharedPtrMessage* __metadata);
|
||||||
|
@ -378,28 +320,6 @@ private:
|
||||||
virtual int update_duration(SrsSharedPtrMessage* msg);
|
virtual int update_duration(SrsSharedPtrMessage* msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* the api dvr pool.
|
|
||||||
*/
|
|
||||||
class SrsApiDvrPool
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::vector<SrsDvrApiPlan*> dvrs;
|
|
||||||
static SrsApiDvrPool* _instance;
|
|
||||||
private:
|
|
||||||
SrsApiDvrPool();
|
|
||||||
public:
|
|
||||||
static SrsApiDvrPool* instance();
|
|
||||||
virtual ~SrsApiDvrPool();
|
|
||||||
public:
|
|
||||||
virtual int add_dvr(SrsDvrApiPlan* dvr);
|
|
||||||
public:
|
|
||||||
virtual int dumps(std::string vhost, std::stringstream& ss);
|
|
||||||
virtual int create(SrsJsonAny* json);
|
|
||||||
virtual int stop(std::string vhost);
|
|
||||||
virtual int rpc(SrsJsonAny* json);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvr(digital video recorder) to record RTMP stream to flv file.
|
* dvr(digital video recorder) to record RTMP stream to flv file.
|
||||||
* TODO: FIXME: add utest for it.
|
* TODO: FIXME: add utest for it.
|
||||||
|
@ -411,7 +331,7 @@ private:
|
||||||
private:
|
private:
|
||||||
SrsDvrPlan* plan;
|
SrsDvrPlan* plan;
|
||||||
public:
|
public:
|
||||||
SrsDvr(SrsSource* s);
|
SrsDvr();
|
||||||
virtual ~SrsDvr();
|
virtual ~SrsDvr();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -419,7 +339,7 @@ public:
|
||||||
* when system initialize(encoder publish at first time, or reload),
|
* when system initialize(encoder publish at first time, or reload),
|
||||||
* initialize the dvr will reinitialize the plan, the whole dvr framework.
|
* initialize the dvr will reinitialize the plan, the whole dvr framework.
|
||||||
*/
|
*/
|
||||||
virtual int initialize(SrsRequest* r);
|
virtual int initialize(SrsSource* s, SrsRequest* r);
|
||||||
/**
|
/**
|
||||||
* publish stream event,
|
* publish stream event,
|
||||||
* when encoder start to publish RTMP stream.
|
* when encoder start to publish RTMP stream.
|
||||||
|
|
|
@ -432,8 +432,8 @@ int SrsFFMPEG::start()
|
||||||
// memory leak in child process, it's ok.
|
// memory leak in child process, it's ok.
|
||||||
char** charpv_params = new char*[params.size() + 1];
|
char** charpv_params = new char*[params.size() + 1];
|
||||||
for (int i = 0; i < (int)params.size(); i++) {
|
for (int i = 0; i < (int)params.size(); i++) {
|
||||||
std::string p = params[i];
|
std::string& p = params[i];
|
||||||
charpv_params[i] = (char*)p.c_str();
|
charpv_params[i] = (char*)p.data();
|
||||||
}
|
}
|
||||||
// EOF: NULL
|
// EOF: NULL
|
||||||
charpv_params[params.size()] = NULL;
|
charpv_params[params.size()] = NULL;
|
||||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
#include <srs_app_json.hpp>
|
#include <srs_app_json.hpp>
|
||||||
#include <srs_app_http.hpp>
|
#include <srs_app_http.hpp>
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
|
#include <srs_core_autofree.hpp>
|
||||||
|
|
||||||
SrsHttpHeartbeat::SrsHttpHeartbeat()
|
SrsHttpHeartbeat::SrsHttpHeartbeat()
|
||||||
{
|
{
|
||||||
|
@ -73,21 +74,31 @@ void SrsHttpHeartbeat::heartbeat()
|
||||||
srs_api_dump_summaries(ss);
|
srs_api_dump_summaries(ss);
|
||||||
}
|
}
|
||||||
ss << __SRS_JOBJECT_END;
|
ss << __SRS_JOBJECT_END;
|
||||||
std::string data = ss.str();
|
|
||||||
std::string res;
|
std::string req = ss.str();
|
||||||
int status_code;
|
|
||||||
|
|
||||||
SrsHttpClient http;
|
SrsHttpClient http;
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
if ((ret = http.initialize(uri.get_host(), uri.get_port())) != ERROR_SUCCESS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpMessage* msg = NULL;
|
||||||
|
if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) {
|
||||||
srs_info("http post hartbeart uri failed. "
|
srs_info("http post hartbeart uri failed. "
|
||||||
"url=%s, request=%s, response=%s, ret=%d",
|
"url=%s, request=%s, response=%s, ret=%d",
|
||||||
url.c_str(), data.c_str(), res.c_str(), ret);
|
url.c_str(), req.c_str(), res.c_str(), ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SrsAutoFree(SrsHttpMessage, msg);
|
||||||
|
|
||||||
|
std::string res;
|
||||||
|
if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_info("http hook hartbeart success. "
|
srs_info("http hook hartbeart success. "
|
||||||
"url=%s, request=%s, status_code=%d, response=%s, ret=%d",
|
"url=%s, request=%s, status_code=%d, response=%s, ret=%d",
|
||||||
url.c_str(), data.c_str(), status_code, res.c_str(), ret);
|
url.c_str(), req.c_str(), status_code, res.c_str(), ret);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,10 +163,10 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHlsMuxer::SrsHlsMuxer(ISrsHlsHandler* h)
|
SrsHlsMuxer::SrsHlsMuxer()
|
||||||
{
|
{
|
||||||
req = NULL;
|
req = NULL;
|
||||||
handler = h;
|
handler = NULL;
|
||||||
hls_fragment = hls_window = 0;
|
hls_fragment = hls_window = 0;
|
||||||
target_duration = 0;
|
target_duration = 0;
|
||||||
_sequence_no = 0;
|
_sequence_no = 0;
|
||||||
|
@ -189,6 +189,15 @@ SrsHlsMuxer::~SrsHlsMuxer()
|
||||||
srs_freep(req);
|
srs_freep(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHlsMuxer::initialize(ISrsHlsHandler* h)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
handler = h;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHlsMuxer::sequence_no()
|
int SrsHlsMuxer::sequence_no()
|
||||||
{
|
{
|
||||||
return _sequence_no;
|
return _sequence_no;
|
||||||
|
@ -811,10 +820,10 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHls::SrsHls(SrsSource* s, ISrsHlsHandler* h)
|
SrsHls::SrsHls()
|
||||||
{
|
{
|
||||||
source = s;
|
source = NULL;
|
||||||
handler = h;
|
handler = NULL;
|
||||||
|
|
||||||
hls_enabled = false;
|
hls_enabled = false;
|
||||||
|
|
||||||
|
@ -822,7 +831,7 @@ SrsHls::SrsHls(SrsSource* s, ISrsHlsHandler* h)
|
||||||
sample = new SrsCodecSample();
|
sample = new SrsCodecSample();
|
||||||
jitter = new SrsRtmpJitter();
|
jitter = new SrsRtmpJitter();
|
||||||
|
|
||||||
muxer = new SrsHlsMuxer(h);
|
muxer = new SrsHlsMuxer();
|
||||||
hls_cache = new SrsHlsCache();
|
hls_cache = new SrsHlsCache();
|
||||||
|
|
||||||
pprint = SrsPithyPrint::create_hls();
|
pprint = SrsPithyPrint::create_hls();
|
||||||
|
@ -841,6 +850,20 @@ SrsHls::~SrsHls()
|
||||||
srs_freep(pprint);
|
srs_freep(pprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHls::initialize(SrsSource* s, ISrsHlsHandler* h)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
source = s;
|
||||||
|
handler = h;
|
||||||
|
|
||||||
|
if ((ret = muxer->initialize(h)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHls::on_publish(SrsRequest* req)
|
int SrsHls::on_publish(SrsRequest* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
|
@ -195,11 +195,15 @@ private:
|
||||||
*/
|
*/
|
||||||
SrsCodecAudio acodec;
|
SrsCodecAudio acodec;
|
||||||
public:
|
public:
|
||||||
SrsHlsMuxer(ISrsHlsHandler* h);
|
SrsHlsMuxer();
|
||||||
virtual ~SrsHlsMuxer();
|
virtual ~SrsHlsMuxer();
|
||||||
public:
|
public:
|
||||||
virtual int sequence_no();
|
virtual int sequence_no();
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* initialize the hls muxer.
|
||||||
|
*/
|
||||||
|
virtual int initialize(ISrsHlsHandler* h);
|
||||||
/**
|
/**
|
||||||
* when publish, update the config for muxer.
|
* when publish, update the config for muxer.
|
||||||
*/
|
*/
|
||||||
|
@ -325,9 +329,13 @@ private:
|
||||||
*/
|
*/
|
||||||
int64_t stream_dts;
|
int64_t stream_dts;
|
||||||
public:
|
public:
|
||||||
SrsHls(SrsSource* s, ISrsHlsHandler* h);
|
SrsHls();
|
||||||
virtual ~SrsHls();
|
virtual ~SrsHls();
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* initialize the hls by handler and source.
|
||||||
|
*/
|
||||||
|
virtual int initialize(SrsSource* s, ISrsHlsHandler* h);
|
||||||
/**
|
/**
|
||||||
* publish stream event, continue to write the m3u8,
|
* publish stream event, continue to write the m3u8,
|
||||||
* for the muxer object not destroyed.
|
* for the muxer object not destroyed.
|
||||||
|
|
|
@ -39,11 +39,10 @@ using namespace std;
|
||||||
#include <srs_rtmp_buffer.hpp>
|
#include <srs_rtmp_buffer.hpp>
|
||||||
#include <srs_kernel_file.hpp>
|
#include <srs_kernel_file.hpp>
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
|
#include <srs_rtmp_buffer.hpp>
|
||||||
|
|
||||||
#define SRS_DEFAULT_HTTP_PORT 80
|
#define SRS_DEFAULT_HTTP_PORT 80
|
||||||
|
|
||||||
#define SRS_HTTP_HEADER_BUFFER 1024
|
|
||||||
|
|
||||||
// for http parser macros
|
// for http parser macros
|
||||||
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
|
#define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS
|
||||||
#define SRS_CONSTS_HTTP_GET HTTP_GET
|
#define SRS_CONSTS_HTTP_GET HTTP_GET
|
||||||
|
@ -53,7 +52,7 @@ using namespace std;
|
||||||
|
|
||||||
#define SRS_HTTP_DEFAULT_PAGE "index.html"
|
#define SRS_HTTP_DEFAULT_PAGE "index.html"
|
||||||
|
|
||||||
int srs_go_http_response_json(ISrsGoHttpResponseWriter* w, string data)
|
int srs_go_http_response_json(ISrsHttpResponseWriter* w, string data)
|
||||||
{
|
{
|
||||||
w->header()->set_content_length(data.length());
|
w->header()->set_content_length(data.length());
|
||||||
w->header()->set_content_type("application/json");
|
w->header()->set_content_type("application/json");
|
||||||
|
@ -147,7 +146,7 @@ string srs_go_http_detect(char* data, int size)
|
||||||
|
|
||||||
// Error replies to the request with the specified error message and HTTP code.
|
// Error replies to the request with the specified error message and HTTP code.
|
||||||
// The error message should be plain text.
|
// The error message should be plain text.
|
||||||
int srs_go_http_error(ISrsGoHttpResponseWriter* w, int code, string error)
|
int srs_go_http_error(ISrsHttpResponseWriter* w, int code, string error)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -159,20 +158,20 @@ int srs_go_http_error(ISrsGoHttpResponseWriter* w, int code, string error)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpHeader::SrsGoHttpHeader()
|
SrsHttpHeader::SrsHttpHeader()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpHeader::~SrsGoHttpHeader()
|
SrsHttpHeader::~SrsHttpHeader()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsGoHttpHeader::set(string key, string value)
|
void SrsHttpHeader::set(string key, string value)
|
||||||
{
|
{
|
||||||
headers[key] = value;
|
headers[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsGoHttpHeader::get(string key)
|
string SrsHttpHeader::get(string key)
|
||||||
{
|
{
|
||||||
std::string v;
|
std::string v;
|
||||||
|
|
||||||
|
@ -183,7 +182,7 @@ string SrsGoHttpHeader::get(string key)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsGoHttpHeader::content_length()
|
int64_t SrsHttpHeader::content_length()
|
||||||
{
|
{
|
||||||
std::string cl = get("Content-Length");
|
std::string cl = get("Content-Length");
|
||||||
|
|
||||||
|
@ -194,24 +193,24 @@ int64_t SrsGoHttpHeader::content_length()
|
||||||
return (int64_t)::atof(cl.c_str());
|
return (int64_t)::atof(cl.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsGoHttpHeader::set_content_length(int64_t size)
|
void SrsHttpHeader::set_content_length(int64_t size)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof(buf), "%"PRId64, size);
|
snprintf(buf, sizeof(buf), "%"PRId64, size);
|
||||||
set("Content-Length", buf);
|
set("Content-Length", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsGoHttpHeader::content_type()
|
string SrsHttpHeader::content_type()
|
||||||
{
|
{
|
||||||
return get("Content-Type");
|
return get("Content-Type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsGoHttpHeader::set_content_type(string ct)
|
void SrsHttpHeader::set_content_type(string ct)
|
||||||
{
|
{
|
||||||
set("Content-Type", ct);
|
set("Content-Type", ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsGoHttpHeader::write(stringstream& ss)
|
void SrsHttpHeader::write(stringstream& ss)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::string>::iterator it;
|
std::map<std::string, std::string>::iterator it;
|
||||||
for (it = headers.begin(); it != headers.end(); ++it) {
|
for (it = headers.begin(); it != headers.end(); ++it) {
|
||||||
|
@ -219,64 +218,72 @@ void SrsGoHttpHeader::write(stringstream& ss)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ISrsGoHttpResponseWriter::ISrsGoHttpResponseWriter()
|
ISrsHttpResponseWriter::ISrsHttpResponseWriter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ISrsGoHttpResponseWriter::~ISrsGoHttpResponseWriter()
|
ISrsHttpResponseWriter::~ISrsHttpResponseWriter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ISrsGoHttpHandler::ISrsGoHttpHandler()
|
ISrsHttpResponseReader::ISrsHttpResponseReader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ISrsHttpResponseReader::~ISrsHttpResponseReader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ISrsHttpHandler::ISrsHttpHandler()
|
||||||
{
|
{
|
||||||
entry = NULL;
|
entry = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ISrsGoHttpHandler::~ISrsGoHttpHandler()
|
ISrsHttpHandler::~ISrsHttpHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpRedirectHandler::SrsGoHttpRedirectHandler(string u, int c)
|
SrsHttpRedirectHandler::SrsHttpRedirectHandler(string u, int c)
|
||||||
{
|
{
|
||||||
url = u;
|
url = u;
|
||||||
code = c;
|
code = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpRedirectHandler::~SrsGoHttpRedirectHandler()
|
SrsHttpRedirectHandler::~SrsHttpRedirectHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpRedirectHandler::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
// TODO: FIXME: implements it.
|
// TODO: FIXME: implements it.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpNotFoundHandler::SrsGoHttpNotFoundHandler()
|
SrsHttpNotFoundHandler::SrsHttpNotFoundHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpNotFoundHandler::~SrsGoHttpNotFoundHandler()
|
SrsHttpNotFoundHandler::~SrsHttpNotFoundHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpNotFoundHandler::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpNotFoundHandler::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
return srs_go_http_error(w,
|
return srs_go_http_error(w,
|
||||||
SRS_CONSTS_HTTP_NotFound, SRS_CONSTS_HTTP_NotFound_str);
|
SRS_CONSTS_HTTP_NotFound, SRS_CONSTS_HTTP_NotFound_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpFileServer::SrsGoHttpFileServer(string root_dir)
|
SrsHttpFileServer::SrsHttpFileServer(string root_dir)
|
||||||
{
|
{
|
||||||
dir = root_dir;
|
dir = root_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpFileServer::~SrsGoHttpFileServer()
|
SrsHttpFileServer::~SrsHttpFileServer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpFileServer::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
string upath = r->path();
|
string upath = r->path();
|
||||||
|
|
||||||
|
@ -300,7 +307,7 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
|
||||||
if (!srs_path_exists(fullpath)) {
|
if (!srs_path_exists(fullpath)) {
|
||||||
srs_warn("http miss file=%s, pattern=%s, upath=%s",
|
srs_warn("http miss file=%s, pattern=%s, upath=%s",
|
||||||
fullpath.c_str(), entry->pattern.c_str(), upath.c_str());
|
fullpath.c_str(), entry->pattern.c_str(), upath.c_str());
|
||||||
return SrsGoHttpNotFoundHandler().serve_http(w, r);
|
return SrsHttpNotFoundHandler().serve_http(w, r);
|
||||||
}
|
}
|
||||||
srs_trace("http match file=%s, pattern=%s, upath=%s",
|
srs_trace("http match file=%s, pattern=%s, upath=%s",
|
||||||
fullpath.c_str(), entry->pattern.c_str(), upath.c_str());
|
fullpath.c_str(), entry->pattern.c_str(), upath.c_str());
|
||||||
|
@ -317,7 +324,7 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
|
||||||
return serve_file(w, r, fullpath);
|
return serve_file(w, r, fullpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
int SrsHttpFileServer::serve_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -391,7 +398,7 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
|
||||||
return w->final_request();
|
return w->final_request();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_flv_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
int SrsHttpFileServer::serve_flv_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
||||||
{
|
{
|
||||||
std::string start = r->query_get("start");
|
std::string start = r->query_get("start");
|
||||||
if (start.empty()) {
|
if (start.empty()) {
|
||||||
|
@ -406,7 +413,7 @@ int SrsGoHttpFileServer::serve_flv_file(ISrsGoHttpResponseWriter* w, SrsHttpMess
|
||||||
return serve_flv_stream(w, r, fullpath, offset);
|
return serve_flv_stream(w, r, fullpath, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_mp4_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
int SrsHttpFileServer::serve_mp4_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
|
||||||
{
|
{
|
||||||
// for flash to request mp4 range in query string.
|
// for flash to request mp4 range in query string.
|
||||||
// for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd
|
// for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd
|
||||||
|
@ -443,17 +450,17 @@ int SrsGoHttpFileServer::serve_mp4_file(ISrsGoHttpResponseWriter* w, SrsHttpMess
|
||||||
return serve_mp4_stream(w, r, fullpath, start, end);
|
return serve_mp4_stream(w, r, fullpath, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
|
int SrsHttpFileServer::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
|
||||||
{
|
{
|
||||||
return serve_file(w, r, fullpath);
|
return serve_file(w, r, fullpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
|
int SrsHttpFileServer::serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
|
||||||
{
|
{
|
||||||
return serve_file(w, r, fullpath);
|
return serve_file(w, r, fullpath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpFileServer::copy(ISrsGoHttpResponseWriter* w, SrsFileReader* fs, SrsHttpMessage* r, int size)
|
int SrsHttpFileServer::copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, SrsHttpMessage* r, int size)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -476,27 +483,27 @@ int SrsGoHttpFileServer::copy(ISrsGoHttpResponseWriter* w, SrsFileReader* fs, Sr
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpMuxEntry::SrsGoHttpMuxEntry()
|
SrsHttpMuxEntry::SrsHttpMuxEntry()
|
||||||
{
|
{
|
||||||
enabled = true;
|
enabled = true;
|
||||||
explicit_match = false;
|
explicit_match = false;
|
||||||
handler = NULL;
|
handler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpMuxEntry::~SrsGoHttpMuxEntry()
|
SrsHttpMuxEntry::~SrsHttpMuxEntry()
|
||||||
{
|
{
|
||||||
srs_freep(handler);
|
srs_freep(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpServeMux::SrsGoHttpServeMux()
|
SrsHttpServeMux::SrsHttpServeMux()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpServeMux::~SrsGoHttpServeMux()
|
SrsHttpServeMux::~SrsHttpServeMux()
|
||||||
{
|
{
|
||||||
std::map<std::string, SrsGoHttpMuxEntry*>::iterator it;
|
std::map<std::string, SrsHttpMuxEntry*>::iterator it;
|
||||||
for (it = entries.begin(); it != entries.end(); ++it) {
|
for (it = entries.begin(); it != entries.end(); ++it) {
|
||||||
SrsGoHttpMuxEntry* entry = it->second;
|
SrsHttpMuxEntry* entry = it->second;
|
||||||
srs_freep(entry);
|
srs_freep(entry);
|
||||||
}
|
}
|
||||||
entries.clear();
|
entries.clear();
|
||||||
|
@ -504,14 +511,14 @@ SrsGoHttpServeMux::~SrsGoHttpServeMux()
|
||||||
vhosts.clear();
|
vhosts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpServeMux::initialize()
|
int SrsHttpServeMux::initialize()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
// TODO: FIXME: implements it.
|
// TODO: FIXME: implements it.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
int SrsHttpServeMux::handle(std::string pattern, ISrsHttpHandler* handler)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -524,7 +531,7 @@ int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entries.find(pattern) != entries.end()) {
|
if (entries.find(pattern) != entries.end()) {
|
||||||
SrsGoHttpMuxEntry* exists = entries[pattern];
|
SrsHttpMuxEntry* exists = entries[pattern];
|
||||||
if (exists->explicit_match) {
|
if (exists->explicit_match) {
|
||||||
ret = ERROR_HTTP_PATTERN_DUPLICATED;
|
ret = ERROR_HTTP_PATTERN_DUPLICATED;
|
||||||
srs_error("http: multiple registrations for %s. ret=%d", pattern.c_str(), ret);
|
srs_error("http: multiple registrations for %s. ret=%d", pattern.c_str(), ret);
|
||||||
|
@ -541,14 +548,14 @@ int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsGoHttpMuxEntry* entry = new SrsGoHttpMuxEntry();
|
SrsHttpMuxEntry* entry = new SrsHttpMuxEntry();
|
||||||
entry->explicit_match = true;
|
entry->explicit_match = true;
|
||||||
entry->handler = handler;
|
entry->handler = handler;
|
||||||
entry->pattern = pattern;
|
entry->pattern = pattern;
|
||||||
entry->handler->entry = entry;
|
entry->handler->entry = entry;
|
||||||
|
|
||||||
if (entries.find(pattern) != entries.end()) {
|
if (entries.find(pattern) != entries.end()) {
|
||||||
SrsGoHttpMuxEntry* exists = entries[pattern];
|
SrsHttpMuxEntry* exists = entries[pattern];
|
||||||
srs_freep(exists);
|
srs_freep(exists);
|
||||||
}
|
}
|
||||||
entries[pattern] = entry;
|
entries[pattern] = entry;
|
||||||
|
@ -559,11 +566,11 @@ int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
||||||
// It can be overridden by an explicit registration.
|
// It can be overridden by an explicit registration.
|
||||||
if (pattern != "/" && !pattern.empty() && pattern.at(pattern.length() - 1) == '/') {
|
if (pattern != "/" && !pattern.empty() && pattern.at(pattern.length() - 1) == '/') {
|
||||||
std::string rpattern = pattern.substr(0, pattern.length() - 1);
|
std::string rpattern = pattern.substr(0, pattern.length() - 1);
|
||||||
SrsGoHttpMuxEntry* entry = NULL;
|
SrsHttpMuxEntry* entry = NULL;
|
||||||
|
|
||||||
// free the exists not explicit entry
|
// free the exists not explicit entry
|
||||||
if (entries.find(rpattern) != entries.end()) {
|
if (entries.find(rpattern) != entries.end()) {
|
||||||
SrsGoHttpMuxEntry* exists = entries[rpattern];
|
SrsHttpMuxEntry* exists = entries[rpattern];
|
||||||
if (!exists->explicit_match) {
|
if (!exists->explicit_match) {
|
||||||
entry = exists;
|
entry = exists;
|
||||||
}
|
}
|
||||||
|
@ -573,9 +580,9 @@ int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
||||||
if (!entry || entry->explicit_match) {
|
if (!entry || entry->explicit_match) {
|
||||||
srs_freep(entry);
|
srs_freep(entry);
|
||||||
|
|
||||||
entry = new SrsGoHttpMuxEntry();
|
entry = new SrsHttpMuxEntry();
|
||||||
entry->explicit_match = false;
|
entry->explicit_match = false;
|
||||||
entry->handler = new SrsGoHttpRedirectHandler(pattern, SRS_CONSTS_HTTP_MovedPermanently);
|
entry->handler = new SrsHttpRedirectHandler(pattern, SRS_CONSTS_HTTP_MovedPermanently);
|
||||||
entry->pattern = pattern;
|
entry->pattern = pattern;
|
||||||
entry->handler->entry = entry;
|
entry->handler->entry = entry;
|
||||||
|
|
||||||
|
@ -586,11 +593,11 @@ int SrsGoHttpServeMux::handle(std::string pattern, ISrsGoHttpHandler* handler)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpServeMux::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpServeMux::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
ISrsGoHttpHandler* h = NULL;
|
ISrsHttpHandler* h = NULL;
|
||||||
if ((ret = find_handler(r, &h)) != ERROR_SUCCESS) {
|
if ((ret = find_handler(r, &h)) != ERROR_SUCCESS) {
|
||||||
srs_error("find handler failed. ret=%d", ret);
|
srs_error("find handler failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -607,7 +614,7 @@ int SrsGoHttpServeMux::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpServeMux::find_handler(SrsHttpMessage* r, ISrsGoHttpHandler** ph)
|
int SrsHttpServeMux::find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -624,13 +631,13 @@ int SrsGoHttpServeMux::find_handler(SrsHttpMessage* r, ISrsGoHttpHandler** ph)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*ph == NULL) {
|
if (*ph == NULL) {
|
||||||
*ph = new SrsGoHttpNotFoundHandler();
|
*ph = new SrsHttpNotFoundHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpServeMux::match(SrsHttpMessage* r, ISrsGoHttpHandler** ph)
|
int SrsHttpServeMux::match(SrsHttpMessage* r, ISrsHttpHandler** ph)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -642,12 +649,12 @@ int SrsGoHttpServeMux::match(SrsHttpMessage* r, ISrsGoHttpHandler** ph)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nb_matched = 0;
|
int nb_matched = 0;
|
||||||
ISrsGoHttpHandler* h = NULL;
|
ISrsHttpHandler* h = NULL;
|
||||||
|
|
||||||
std::map<std::string, SrsGoHttpMuxEntry*>::iterator it;
|
std::map<std::string, SrsHttpMuxEntry*>::iterator it;
|
||||||
for (it = entries.begin(); it != entries.end(); ++it) {
|
for (it = entries.begin(); it != entries.end(); ++it) {
|
||||||
std::string pattern = it->first;
|
std::string pattern = it->first;
|
||||||
SrsGoHttpMuxEntry* entry = it->second;
|
SrsHttpMuxEntry* entry = it->second;
|
||||||
|
|
||||||
if (!entry->enabled) {
|
if (!entry->enabled) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -668,7 +675,7 @@ int SrsGoHttpServeMux::match(SrsHttpMessage* r, ISrsGoHttpHandler** ph)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsGoHttpServeMux::path_match(string pattern, string path)
|
bool SrsHttpServeMux::path_match(string pattern, string path)
|
||||||
{
|
{
|
||||||
if (pattern.empty()) {
|
if (pattern.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -692,10 +699,10 @@ bool SrsGoHttpServeMux::path_match(string pattern, string path)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpResponseWriter::SrsGoHttpResponseWriter(SrsStSocket* io)
|
SrsHttpResponseWriter::SrsHttpResponseWriter(SrsStSocket* io)
|
||||||
{
|
{
|
||||||
skt = io;
|
skt = io;
|
||||||
hdr = new SrsGoHttpHeader();
|
hdr = new SrsHttpHeader();
|
||||||
header_wrote = false;
|
header_wrote = false;
|
||||||
status = SRS_CONSTS_HTTP_OK;
|
status = SRS_CONSTS_HTTP_OK;
|
||||||
content_length = -1;
|
content_length = -1;
|
||||||
|
@ -703,12 +710,12 @@ SrsGoHttpResponseWriter::SrsGoHttpResponseWriter(SrsStSocket* io)
|
||||||
header_sent = false;
|
header_sent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpResponseWriter::~SrsGoHttpResponseWriter()
|
SrsHttpResponseWriter::~SrsHttpResponseWriter()
|
||||||
{
|
{
|
||||||
srs_freep(hdr);
|
srs_freep(hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpResponseWriter::final_request()
|
int SrsHttpResponseWriter::final_request()
|
||||||
{
|
{
|
||||||
// complete the chunked encoding.
|
// complete the chunked encoding.
|
||||||
if (content_length == -1) {
|
if (content_length == -1) {
|
||||||
|
@ -722,12 +729,12 @@ int SrsGoHttpResponseWriter::final_request()
|
||||||
return write(NULL, 0);
|
return write(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoHttpHeader* SrsGoHttpResponseWriter::header()
|
SrsHttpHeader* SrsHttpResponseWriter::header()
|
||||||
{
|
{
|
||||||
return hdr;
|
return hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpResponseWriter::write(char* data, int size)
|
int SrsHttpResponseWriter::write(char* data, int size)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -774,7 +781,7 @@ int SrsGoHttpResponseWriter::write(char* data, int size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsGoHttpResponseWriter::write_header(int code)
|
void SrsHttpResponseWriter::write_header(int code)
|
||||||
{
|
{
|
||||||
if (header_wrote) {
|
if (header_wrote) {
|
||||||
srs_warn("http: multiple write_header calls, code=%d", code);
|
srs_warn("http: multiple write_header calls, code=%d", code);
|
||||||
|
@ -788,7 +795,7 @@ void SrsGoHttpResponseWriter::write_header(int code)
|
||||||
content_length = hdr->content_length();
|
content_length = hdr->content_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoHttpResponseWriter::send_header(char* data, int size)
|
int SrsHttpResponseWriter::send_header(char* data, int size)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -833,11 +840,166 @@ int SrsGoHttpResponseWriter::send_header(char* data, int size)
|
||||||
return skt->write((void*)buf.c_str(), buf.length(), NULL);
|
return skt->write((void*)buf.c_str(), buf.length(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpMessage::SrsHttpMessage()
|
SrsHttpResponseReader::SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io)
|
||||||
{
|
{
|
||||||
_body = new SrsSimpleBuffer();
|
skt = io;
|
||||||
_state = SrsHttpParseStateInit;
|
owner = msg;
|
||||||
|
is_eof = false;
|
||||||
|
nb_read = 0;
|
||||||
|
buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpResponseReader::~SrsHttpResponseReader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpResponseReader::initialize(SrsFastBuffer* body)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
buffer = body;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SrsHttpResponseReader::eof()
|
||||||
|
{
|
||||||
|
return is_eof;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpResponseReader::read(std::string& data)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (is_eof) {
|
||||||
|
ret = ERROR_HTTP_RESPONSE_EOF;
|
||||||
|
srs_error("http: response EOF. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// chunked encoding.
|
||||||
|
if (owner->is_chunked()) {
|
||||||
|
return read_chunked(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read by specified content-length
|
||||||
|
int max = (int)owner->content_length() - nb_read;
|
||||||
|
if (max <= 0) {
|
||||||
|
is_eof = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return read_specified(max, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpResponseReader::read_chunked(std::string& data)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
// parse the chunk length first.
|
||||||
|
char* at = NULL;
|
||||||
|
int length = 0;
|
||||||
|
while (!at) {
|
||||||
|
// find the CRLF of chunk header end.
|
||||||
|
char* start = buffer->bytes();
|
||||||
|
char* end = start + buffer->size();
|
||||||
|
for (char* p = start; p < end - 1; p++) {
|
||||||
|
if (p[0] == __SRS_HTTP_CR && p[1] == __SRS_HTTP_LF) {
|
||||||
|
// invalid chunk, ignore.
|
||||||
|
if (p == start) {
|
||||||
|
ret = ERROR_HTTP_INVALID_CHUNK_HEADER;
|
||||||
|
srs_error("chunk header start with CRLF. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
length = p - start + 2;
|
||||||
|
at = buffer->read_slice(length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// got at, ok.
|
||||||
|
if (at) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when empty, only grow 1bytes, but the buffer will cache more.
|
||||||
|
if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {
|
||||||
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
srs_error("read body from server failed. ret=%d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srs_assert(length >= 3);
|
||||||
|
|
||||||
|
// it's ok to set the pos and pos+1 to NULL.
|
||||||
|
at[length - 1] = NULL;
|
||||||
|
at[length - 2] = NULL;
|
||||||
|
|
||||||
|
// size is the bytes size, excludes the chunk header and end CRLF.
|
||||||
|
int ilength = ::strtol(at, NULL, 16);
|
||||||
|
if (ilength < 0) {
|
||||||
|
ret = ERROR_HTTP_INVALID_CHUNK_HEADER;
|
||||||
|
srs_error("chunk header negative, length=%d. ret=%d", ilength, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when empty, only grow 1bytes, but the buffer will cache more.
|
||||||
|
if ((ret = buffer->grow(skt, ilength + 2)) != ERROR_SUCCESS) {
|
||||||
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
srs_error("read body from server failed. ret=%d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_info("http: read %d chunk", ilength);
|
||||||
|
|
||||||
|
// read payload when length specifies some payload.
|
||||||
|
if (ilength <= 0) {
|
||||||
|
is_eof = true;
|
||||||
|
} else {
|
||||||
|
srs_assert(ilength);
|
||||||
|
data.append(buffer->read_slice(ilength), ilength);
|
||||||
|
nb_read += ilength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the CRLF of chunk payload end.
|
||||||
|
buffer->read_slice(2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpResponseReader::read_specified(int max, std::string& data)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (buffer->size() <= 0) {
|
||||||
|
// when empty, only grow 1bytes, but the buffer will cache more.
|
||||||
|
if ((ret = buffer->grow(skt, 1)) != ERROR_SUCCESS) {
|
||||||
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
srs_error("read body from server failed. ret=%d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int nb_bytes = srs_min(max, buffer->size());
|
||||||
|
|
||||||
|
srs_assert(nb_bytes);
|
||||||
|
data.append(buffer->read_slice(nb_bytes), nb_bytes);
|
||||||
|
nb_read += nb_bytes;
|
||||||
|
|
||||||
|
// when read completed, eof.
|
||||||
|
if (nb_read >= (int)owner->content_length()) {
|
||||||
|
is_eof = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpMessage::SrsHttpMessage(SrsStSocket* io)
|
||||||
|
{
|
||||||
|
chunked = false;
|
||||||
_uri = new SrsHttpUri();
|
_uri = new SrsHttpUri();
|
||||||
|
_body = new SrsHttpResponseReader(this, io);
|
||||||
_http_ts_send_buffer = new char[__SRS_HTTP_TS_SEND_BUFFER_SIZE];
|
_http_ts_send_buffer = new char[__SRS_HTTP_TS_SEND_BUFFER_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,10 +1010,24 @@ SrsHttpMessage::~SrsHttpMessage()
|
||||||
srs_freep(_http_ts_send_buffer);
|
srs_freep(_http_ts_send_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpMessage::initialize()
|
int SrsHttpMessage::update(string url, http_parser* header, SrsFastBuffer* body, vector<SrsHttpHeaderField>& headers)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
_url = url;
|
||||||
|
_header = *header;
|
||||||
|
_headers = headers;
|
||||||
|
|
||||||
|
// whether chunked.
|
||||||
|
std::string transfer_encoding = get_request_header("Transfer-Encoding");
|
||||||
|
chunked = (transfer_encoding == "chunked");
|
||||||
|
|
||||||
|
// set the buffer.
|
||||||
|
if ((ret = _body->initialize(body)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse uri from url.
|
||||||
std::string host = get_request_header("Host");
|
std::string host = get_request_header("Host");
|
||||||
|
|
||||||
// donot parse the empty host for uri,
|
// donot parse the empty host for uri,
|
||||||
|
@ -898,18 +1074,6 @@ char* SrsHttpMessage::http_ts_send_buffer()
|
||||||
return _http_ts_send_buffer;
|
return _http_ts_send_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::reset()
|
|
||||||
{
|
|
||||||
_state = SrsHttpParseStateInit;
|
|
||||||
_body->erase(_body->length());
|
|
||||||
_url = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SrsHttpMessage::is_complete()
|
|
||||||
{
|
|
||||||
return _state == SrsHttpParseStateComplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
u_int8_t SrsHttpMessage::method()
|
u_int8_t SrsHttpMessage::method()
|
||||||
{
|
{
|
||||||
return (u_int8_t)_header.method;
|
return (u_int8_t)_header.method;
|
||||||
|
@ -966,6 +1130,11 @@ bool SrsHttpMessage::is_http_options()
|
||||||
return _header.method == SRS_CONSTS_HTTP_OPTIONS;
|
return _header.method == SRS_CONSTS_HTTP_OPTIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsHttpMessage::is_chunked()
|
||||||
|
{
|
||||||
|
return chunked;
|
||||||
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::uri()
|
string SrsHttpMessage::uri()
|
||||||
{
|
{
|
||||||
std::string uri = _uri->get_schema();
|
std::string uri = _uri->get_schema();
|
||||||
|
@ -993,25 +1162,23 @@ string SrsHttpMessage::path()
|
||||||
return _uri->get_path();
|
return _uri->get_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::body()
|
int SrsHttpMessage::body_read_all(string& body)
|
||||||
{
|
{
|
||||||
std::string b;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (_body && _body->length() > 0) {
|
// whatever, read util EOF.
|
||||||
b.append(_body->bytes(), _body->length());
|
while (!_body->eof()) {
|
||||||
|
if ((ret = _body->read(body)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* SrsHttpMessage::body_raw()
|
ISrsHttpResponseReader* SrsHttpMessage::body_reader()
|
||||||
{
|
{
|
||||||
return _body? _body->bytes() : NULL;
|
return _body;
|
||||||
}
|
|
||||||
|
|
||||||
int64_t SrsHttpMessage::body_size()
|
|
||||||
{
|
|
||||||
return (int64_t)_body->length();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsHttpMessage::content_length()
|
int64_t SrsHttpMessage::content_length()
|
||||||
|
@ -1019,26 +1186,6 @@ int64_t SrsHttpMessage::content_length()
|
||||||
return _header.content_length;
|
return _header.content_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::set_url(string url)
|
|
||||||
{
|
|
||||||
_url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsHttpMessage::set_state(SrsHttpParseState state)
|
|
||||||
{
|
|
||||||
_state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsHttpMessage::set_header(http_parser* header)
|
|
||||||
{
|
|
||||||
memcpy(&_header, header, sizeof(http_parser));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SrsHttpMessage::append_body(const char* body, int length)
|
|
||||||
{
|
|
||||||
_body->append(body, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
string SrsHttpMessage::query_get(string key)
|
string SrsHttpMessage::query_get(string key)
|
||||||
{
|
{
|
||||||
std::string v;
|
std::string v;
|
||||||
|
@ -1052,33 +1199,28 @@ string SrsHttpMessage::query_get(string key)
|
||||||
|
|
||||||
int SrsHttpMessage::request_header_count()
|
int SrsHttpMessage::request_header_count()
|
||||||
{
|
{
|
||||||
return (int)headers.size();
|
return (int)_headers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::request_header_key_at(int index)
|
string SrsHttpMessage::request_header_key_at(int index)
|
||||||
{
|
{
|
||||||
srs_assert(index < request_header_count());
|
srs_assert(index < request_header_count());
|
||||||
SrsHttpHeaderField item = headers[index];
|
SrsHttpHeaderField item = _headers[index];
|
||||||
return item.first;
|
return item.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
string SrsHttpMessage::request_header_value_at(int index)
|
string SrsHttpMessage::request_header_value_at(int index)
|
||||||
{
|
{
|
||||||
srs_assert(index < request_header_count());
|
srs_assert(index < request_header_count());
|
||||||
SrsHttpHeaderField item = headers[index];
|
SrsHttpHeaderField item = _headers[index];
|
||||||
return item.second;
|
return item.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpMessage::set_request_header(string key, string value)
|
|
||||||
{
|
|
||||||
headers.push_back(std::make_pair(key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
string SrsHttpMessage::get_request_header(string name)
|
string SrsHttpMessage::get_request_header(string name)
|
||||||
{
|
{
|
||||||
std::vector<SrsHttpHeaderField>::iterator it;
|
std::vector<SrsHttpHeaderField>::iterator it;
|
||||||
|
|
||||||
for (it = headers.begin(); it != headers.end(); ++it) {
|
for (it = _headers.begin(); it != _headers.end(); ++it) {
|
||||||
SrsHttpHeaderField& elem = *it;
|
SrsHttpHeaderField& elem = *it;
|
||||||
std::string key = elem.first;
|
std::string key = elem.first;
|
||||||
std::string value = elem.second;
|
std::string value = elem.second;
|
||||||
|
@ -1092,12 +1234,12 @@ string SrsHttpMessage::get_request_header(string name)
|
||||||
|
|
||||||
SrsHttpParser::SrsHttpParser()
|
SrsHttpParser::SrsHttpParser()
|
||||||
{
|
{
|
||||||
msg = NULL;
|
buffer = new SrsFastBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpParser::~SrsHttpParser()
|
SrsHttpParser::~SrsHttpParser()
|
||||||
{
|
{
|
||||||
srs_freep(msg);
|
srs_freep(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpParser::initialize(enum http_parser_type type)
|
int SrsHttpParser::initialize(enum http_parser_type type)
|
||||||
|
@ -1125,28 +1267,30 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg)
|
||||||
*ppmsg = NULL;
|
*ppmsg = NULL;
|
||||||
|
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// the msg must be always NULL
|
|
||||||
srs_assert(msg == NULL);
|
|
||||||
msg = new SrsHttpMessage();
|
|
||||||
|
|
||||||
// reset request data.
|
// reset request data.
|
||||||
filed_name = "";
|
filed_name = "";
|
||||||
|
field_value = "";
|
||||||
// reset response header.
|
expect_filed_name = true;
|
||||||
msg->reset();
|
state = SrsHttpParseStateInit;
|
||||||
|
header = http_parser();
|
||||||
|
url = "";
|
||||||
|
headers.clear();
|
||||||
|
body_parsed = 0;
|
||||||
|
|
||||||
// do parse
|
// do parse
|
||||||
if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) {
|
if ((ret = parse_message_imp(skt)) != ERROR_SUCCESS) {
|
||||||
if (!srs_is_client_gracefully_close(ret)) {
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
srs_error("parse http msg failed. ret=%d", ret);
|
srs_error("parse http msg failed. ret=%d", ret);
|
||||||
}
|
}
|
||||||
srs_freep(msg);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create msg
|
||||||
|
SrsHttpMessage* msg = new SrsHttpMessage(skt);
|
||||||
|
|
||||||
// initalize http msg, parse url.
|
// initalize http msg, parse url.
|
||||||
if ((ret = msg->initialize()) != ERROR_SUCCESS) {
|
if ((ret = msg->update(url, &header, buffer, headers)) != ERROR_SUCCESS) {
|
||||||
srs_error("initialize http msg failed. ret=%d", ret);
|
srs_error("initialize http msg failed. ret=%d", ret);
|
||||||
srs_freep(msg);
|
srs_freep(msg);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1154,7 +1298,6 @@ int SrsHttpParser::parse_message(SrsStSocket* skt, SrsHttpMessage** ppmsg)
|
||||||
|
|
||||||
// parse ok, return the msg.
|
// parse ok, return the msg.
|
||||||
*ppmsg = msg;
|
*ppmsg = msg;
|
||||||
msg = NULL;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1163,42 +1306,52 @@ int SrsHttpParser::parse_message_imp(SrsStSocket* skt)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// the msg should never be NULL
|
while (true) {
|
||||||
srs_assert(msg != NULL);
|
ssize_t nparsed = 0;
|
||||||
|
|
||||||
// parser header.
|
// when buffer not empty, parse it.
|
||||||
char buf[SRS_HTTP_HEADER_BUFFER];
|
if (buffer->size() > 0) {
|
||||||
for (;;) {
|
nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
|
||||||
ssize_t nread;
|
srs_info("buffer=%d, nparsed=%d, body=%d", buffer->size(), (int)nparsed, body_parsed);
|
||||||
if ((ret = skt->read(buf, (size_t)sizeof(buf), &nread)) != ERROR_SUCCESS) {
|
|
||||||
if (!srs_is_client_gracefully_close(ret)) {
|
|
||||||
srs_error("read body from server failed. ret=%d", ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t nparsed = http_parser_execute(&parser, &settings, buf, nread);
|
// consume the parsed bytes.
|
||||||
srs_info("read_size=%d, nparsed=%d", (int)nread, (int)nparsed);
|
if (nparsed && nparsed - body_parsed > 0) {
|
||||||
|
buffer->read_slice(nparsed - body_parsed);
|
||||||
|
}
|
||||||
|
|
||||||
// check header size.
|
// ok atleast header completed,
|
||||||
if (msg->is_complete()) {
|
// never wait for body completed, for maybe chunked.
|
||||||
return ret;
|
if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nparsed != nread) {
|
// when nothing parsed, read more to parse.
|
||||||
ret = ERROR_HTTP_PARSE_HEADER;
|
if (nparsed == 0) {
|
||||||
srs_error("parse response error, parsed(%d)!=read(%d), ret=%d", (int)nparsed, (int)nread, ret);
|
// when requires more, only grow 1bytes, but the buffer will cache more.
|
||||||
return ret;
|
if ((ret = buffer->grow(skt, buffer->size() + 1)) != ERROR_SUCCESS) {
|
||||||
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
srs_error("read body from server failed. ret=%d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse last header.
|
||||||
|
if (!filed_name.empty() && !field_value.empty()) {
|
||||||
|
headers.push_back(std::make_pair(filed_name, field_value));
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpParser::on_message_begin(http_parser* parser)
|
int SrsHttpParser::on_message_begin(http_parser* parser)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
obj->msg->set_state(SrsHttpParseStateStart);
|
srs_assert(obj);
|
||||||
|
|
||||||
|
obj->state = SrsHttpParseStateStart;
|
||||||
|
|
||||||
srs_info("***MESSAGE BEGIN***");
|
srs_info("***MESSAGE BEGIN***");
|
||||||
|
|
||||||
|
@ -1208,7 +1361,11 @@ int SrsHttpParser::on_message_begin(http_parser* parser)
|
||||||
int SrsHttpParser::on_headers_complete(http_parser* parser)
|
int SrsHttpParser::on_headers_complete(http_parser* parser)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
obj->msg->set_header(parser);
|
srs_assert(obj);
|
||||||
|
|
||||||
|
obj->header = *parser;
|
||||||
|
// save the parser when header parse completed.
|
||||||
|
obj->state = SrsHttpParseStateHeaderComplete;
|
||||||
|
|
||||||
srs_info("***HEADERS COMPLETE***");
|
srs_info("***HEADERS COMPLETE***");
|
||||||
|
|
||||||
|
@ -1219,8 +1376,10 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
|
||||||
int SrsHttpParser::on_message_complete(http_parser* parser)
|
int SrsHttpParser::on_message_complete(http_parser* parser)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
// save the parser when header parse completed.
|
srs_assert(obj);
|
||||||
obj->msg->set_state(SrsHttpParseStateComplete);
|
|
||||||
|
// save the parser when body parse completed.
|
||||||
|
obj->state = SrsHttpParseStateMessageComplete;
|
||||||
|
|
||||||
srs_info("***MESSAGE COMPLETE***\n");
|
srs_info("***MESSAGE COMPLETE***\n");
|
||||||
|
|
||||||
|
@ -1230,13 +1389,10 @@ int SrsHttpParser::on_message_complete(http_parser* parser)
|
||||||
int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
|
int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
|
srs_assert(obj);
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
std::string url;
|
obj->url.append(at, (int)length);
|
||||||
|
|
||||||
url.append(at, (int)length);
|
|
||||||
|
|
||||||
obj->msg->set_url(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
|
srs_info("Method: %d, Url: %.*s", parser->method, (int)length, at);
|
||||||
|
@ -1247,45 +1403,46 @@ int SrsHttpParser::on_url(http_parser* parser, const char* at, size_t length)
|
||||||
int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length)
|
int SrsHttpParser::on_header_field(http_parser* parser, const char* at, size_t length)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
|
srs_assert(obj);
|
||||||
|
|
||||||
|
// field value=>name, reap the field.
|
||||||
|
if (!obj->expect_filed_name) {
|
||||||
|
obj->headers.push_back(std::make_pair(obj->filed_name, obj->field_value));
|
||||||
|
|
||||||
|
// reset the field name when parsed.
|
||||||
|
obj->filed_name = "";
|
||||||
|
obj->field_value = "";
|
||||||
|
}
|
||||||
|
obj->expect_filed_name = true;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
srs_assert(obj);
|
|
||||||
obj->filed_name.append(at, (int)length);
|
obj->filed_name.append(at, (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_info("Header field: %.*s", (int)length, at);
|
srs_info("Header field(%d bytes): %.*s", (int)length, (int)length, at);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length)
|
int SrsHttpParser::on_header_value(http_parser* parser, const char* at, size_t length)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
|
srs_assert(obj);
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
srs_assert(obj);
|
obj->field_value.append(at, (int)length);
|
||||||
srs_assert(obj->msg);
|
|
||||||
|
|
||||||
std::string field_value;
|
|
||||||
field_value.append(at, (int)length);
|
|
||||||
|
|
||||||
obj->msg->set_request_header(obj->filed_name, field_value);
|
|
||||||
obj->filed_name = "";
|
|
||||||
}
|
}
|
||||||
|
obj->expect_filed_name = false;
|
||||||
|
|
||||||
srs_info("Header value: %.*s", (int)length, at);
|
srs_info("Header value(%d bytes): %.*s", (int)length, (int)length, at);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
|
int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
|
||||||
{
|
{
|
||||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||||
|
srs_assert(obj);
|
||||||
|
|
||||||
if (length > 0) {
|
obj->body_parsed += length;
|
||||||
srs_assert(obj);
|
|
||||||
srs_assert(obj->msg);
|
|
||||||
|
|
||||||
obj->msg->append_body(at, (int)length);
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_info("Body: %.*s", (int)length, at);
|
srs_info("Body: %.*s", (int)length, at);
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,9 @@ class SrsHttpUri;
|
||||||
class SrsHttpMessage;
|
class SrsHttpMessage;
|
||||||
class SrsFileReader;
|
class SrsFileReader;
|
||||||
class SrsSimpleBuffer;
|
class SrsSimpleBuffer;
|
||||||
class SrsGoHttpMuxEntry;
|
class SrsHttpMuxEntry;
|
||||||
class ISrsGoHttpResponseWriter;
|
class ISrsHttpResponseWriter;
|
||||||
|
class SrsFastBuffer;
|
||||||
|
|
||||||
// http specification
|
// http specification
|
||||||
// CR = <US-ASCII CR, carriage return (13)>
|
// CR = <US-ASCII CR, carriage return (13)>
|
||||||
|
@ -70,23 +71,24 @@ class ISrsGoHttpResponseWriter;
|
||||||
#define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
|
#define __SRS_HTTP_TS_SEND_BUFFER_SIZE 4096
|
||||||
|
|
||||||
// helper function: response in json format.
|
// helper function: response in json format.
|
||||||
extern int srs_go_http_response_json(ISrsGoHttpResponseWriter* w, std::string data);
|
extern int srs_go_http_response_json(ISrsHttpResponseWriter* w, std::string data);
|
||||||
|
|
||||||
// state of message
|
// state of message
|
||||||
enum SrsHttpParseState {
|
enum SrsHttpParseState {
|
||||||
SrsHttpParseStateInit = 0,
|
SrsHttpParseStateInit = 0,
|
||||||
SrsHttpParseStateStart,
|
SrsHttpParseStateStart,
|
||||||
SrsHttpParseStateComplete
|
SrsHttpParseStateHeaderComplete,
|
||||||
|
SrsHttpParseStateMessageComplete
|
||||||
};
|
};
|
||||||
|
|
||||||
// A Header represents the key-value pairs in an HTTP header.
|
// A Header represents the key-value pairs in an HTTP header.
|
||||||
class SrsGoHttpHeader
|
class SrsHttpHeader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> headers;
|
std::map<std::string, std::string> headers;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpHeader();
|
SrsHttpHeader();
|
||||||
virtual ~SrsGoHttpHeader();
|
virtual ~SrsHttpHeader();
|
||||||
public:
|
public:
|
||||||
// Add adds the key, value pair to the header.
|
// Add adds the key, value pair to the header.
|
||||||
// It appends to any existing values associated with key.
|
// It appends to any existing values associated with key.
|
||||||
|
@ -124,7 +126,7 @@ public:
|
||||||
// A ResponseWriter interface is used by an HTTP handler to
|
// A ResponseWriter interface is used by an HTTP handler to
|
||||||
// construct an HTTP response.
|
// construct an HTTP response.
|
||||||
// Usage 1, response with specified length content:
|
// Usage 1, response with specified length content:
|
||||||
// ISrsGoHttpResponseWriter* w; // create or get response.
|
// ISrsHttpResponseWriter* w; // create or get response.
|
||||||
// std::string msg = "Hello, HTTP!";
|
// std::string msg = "Hello, HTTP!";
|
||||||
// w->header()->set_content_type("text/plain; charset=utf-8");
|
// w->header()->set_content_type("text/plain; charset=utf-8");
|
||||||
// w->header()->set_content_length(msg.length());
|
// w->header()->set_content_length(msg.length());
|
||||||
|
@ -132,12 +134,12 @@ public:
|
||||||
// w->write((char*)msg.data(), (int)msg.length());
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
// w->final_request(); // optional flush.
|
// w->final_request(); // optional flush.
|
||||||
// Usage 2, response with HTTP code only, zero content length.
|
// Usage 2, response with HTTP code only, zero content length.
|
||||||
// ISrsGoHttpResponseWriter* w; // create or get response.
|
// ISrsHttpResponseWriter* w; // create or get response.
|
||||||
// w->header()->set_content_length(0);
|
// w->header()->set_content_length(0);
|
||||||
// w->write_header(SRS_CONSTS_HTTP_OK);
|
// w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
// w->final_request();
|
// w->final_request();
|
||||||
// Usage 3, response in chunked encoding.
|
// Usage 3, response in chunked encoding.
|
||||||
// ISrsGoHttpResponseWriter* w; // create or get response.
|
// ISrsHttpResponseWriter* w; // create or get response.
|
||||||
// std::string msg = "Hello, HTTP!";
|
// std::string msg = "Hello, HTTP!";
|
||||||
// w->header()->set_content_type("application/octet-stream");
|
// w->header()->set_content_type("application/octet-stream");
|
||||||
// w->write_header(SRS_CONSTS_HTTP_OK);
|
// w->write_header(SRS_CONSTS_HTTP_OK);
|
||||||
|
@ -146,20 +148,22 @@ public:
|
||||||
// w->write((char*)msg.data(), (int)msg.length());
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
// w->write((char*)msg.data(), (int)msg.length());
|
// w->write((char*)msg.data(), (int)msg.length());
|
||||||
// w->final_request(); // required to end the chunked and flush.
|
// w->final_request(); // required to end the chunked and flush.
|
||||||
class ISrsGoHttpResponseWriter
|
class ISrsHttpResponseWriter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ISrsGoHttpResponseWriter();
|
ISrsHttpResponseWriter();
|
||||||
virtual ~ISrsGoHttpResponseWriter();
|
virtual ~ISrsHttpResponseWriter();
|
||||||
public:
|
public:
|
||||||
// when chunked mode,
|
// when chunked mode,
|
||||||
// final the request to complete the chunked encoding.
|
// final the request to complete the chunked encoding.
|
||||||
|
// for no-chunked mode,
|
||||||
|
// final to send request, for example, content-length is 0.
|
||||||
virtual int final_request() = 0;
|
virtual int final_request() = 0;
|
||||||
|
|
||||||
// Header returns the header map that will be sent by WriteHeader.
|
// Header returns the header map that will be sent by WriteHeader.
|
||||||
// Changing the header after a call to WriteHeader (or Write) has
|
// Changing the header after a call to WriteHeader (or Write) has
|
||||||
// no effect.
|
// no effect.
|
||||||
virtual SrsGoHttpHeader* header() = 0;
|
virtual SrsHttpHeader* header() = 0;
|
||||||
|
|
||||||
// Write writes the data to the connection as part of an HTTP reply.
|
// Write writes the data to the connection as part of an HTTP reply.
|
||||||
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
|
// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
|
||||||
|
@ -178,6 +182,26 @@ public:
|
||||||
virtual void write_header(int code) = 0;
|
virtual void write_header(int code) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the reader interface for http response.
|
||||||
|
*/
|
||||||
|
class ISrsHttpResponseReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISrsHttpResponseReader();
|
||||||
|
virtual ~ISrsHttpResponseReader();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* whether response read EOF.
|
||||||
|
*/
|
||||||
|
virtual bool eof() = 0;
|
||||||
|
/**
|
||||||
|
* read from the response body.
|
||||||
|
* @remark when eof(), return error.
|
||||||
|
*/
|
||||||
|
virtual int read(std::string& data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// Objects implementing the Handler interface can be
|
// Objects implementing the Handler interface can be
|
||||||
// registered to serve a particular path or subtree
|
// registered to serve a particular path or subtree
|
||||||
// in the HTTP server.
|
// in the HTTP server.
|
||||||
|
@ -186,38 +210,38 @@ public:
|
||||||
// and then return. Returning signals that the request is finished
|
// and then return. Returning signals that the request is finished
|
||||||
// and that the HTTP server can move on to the next request on
|
// and that the HTTP server can move on to the next request on
|
||||||
// the connection.
|
// the connection.
|
||||||
class ISrsGoHttpHandler
|
class ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoHttpMuxEntry* entry;
|
SrsHttpMuxEntry* entry;
|
||||||
public:
|
public:
|
||||||
ISrsGoHttpHandler();
|
ISrsHttpHandler();
|
||||||
virtual ~ISrsGoHttpHandler();
|
virtual ~ISrsHttpHandler();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r) = 0;
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Redirect to a fixed URL
|
// Redirect to a fixed URL
|
||||||
class SrsGoHttpRedirectHandler : public ISrsGoHttpHandler
|
class SrsHttpRedirectHandler : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string url;
|
std::string url;
|
||||||
int code;
|
int code;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpRedirectHandler(std::string u, int c);
|
SrsHttpRedirectHandler(std::string u, int c);
|
||||||
virtual ~SrsGoHttpRedirectHandler();
|
virtual ~SrsHttpRedirectHandler();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
// NotFound replies to the request with an HTTP 404 not found error.
|
// NotFound replies to the request with an HTTP 404 not found error.
|
||||||
class SrsGoHttpNotFoundHandler : public ISrsGoHttpHandler
|
class SrsHttpNotFoundHandler : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoHttpNotFoundHandler();
|
SrsHttpNotFoundHandler();
|
||||||
virtual ~SrsGoHttpNotFoundHandler();
|
virtual ~SrsHttpNotFoundHandler();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
// FileServer returns a handler that serves HTTP requests
|
// FileServer returns a handler that serves HTTP requests
|
||||||
|
@ -226,54 +250,54 @@ public:
|
||||||
// To use the operating system's file system implementation,
|
// To use the operating system's file system implementation,
|
||||||
// use http.Dir:
|
// use http.Dir:
|
||||||
//
|
//
|
||||||
// http.Handle("/", SrsGoHttpFileServer("/tmp"))
|
// http.Handle("/", SrsHttpFileServer("/tmp"))
|
||||||
// http.Handle("/", SrsGoHttpFileServer("static-dir"))
|
// http.Handle("/", SrsHttpFileServer("static-dir"))
|
||||||
class SrsGoHttpFileServer : public ISrsGoHttpHandler
|
class SrsHttpFileServer : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
std::string dir;
|
std::string dir;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpFileServer(std::string root_dir);
|
SrsHttpFileServer(std::string root_dir);
|
||||||
virtual ~SrsGoHttpFileServer();
|
virtual ~SrsHttpFileServer();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* serve the file by specified path
|
* serve the file by specified path
|
||||||
*/
|
*/
|
||||||
virtual int serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
virtual int serve_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
||||||
virtual int serve_flv_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
virtual int serve_flv_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
||||||
virtual int serve_mp4_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
virtual int serve_mp4_file(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* when access flv file with x.flv?start=xxx
|
* when access flv file with x.flv?start=xxx
|
||||||
*/
|
*/
|
||||||
virtual int serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
|
virtual int serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
|
||||||
/**
|
/**
|
||||||
* when access mp4 file with x.mp4?range=start-end
|
* when access mp4 file with x.mp4?range=start-end
|
||||||
* @param start the start offset in bytes.
|
* @param start the start offset in bytes.
|
||||||
* @param end the end offset in bytes. -1 to end of file.
|
* @param end the end offset in bytes. -1 to end of file.
|
||||||
* @remark response data in [start, end].
|
* @remark response data in [start, end].
|
||||||
*/
|
*/
|
||||||
virtual int serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
|
virtual int serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* copy the fs to response writer in size bytes.
|
* copy the fs to response writer in size bytes.
|
||||||
*/
|
*/
|
||||||
virtual int copy(ISrsGoHttpResponseWriter* w, SrsFileReader* fs, SrsHttpMessage* r, int size);
|
virtual int copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, SrsHttpMessage* r, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
// the mux entry for server mux.
|
// the mux entry for server mux.
|
||||||
class SrsGoHttpMuxEntry
|
class SrsHttpMuxEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool explicit_match;
|
bool explicit_match;
|
||||||
ISrsGoHttpHandler* handler;
|
ISrsHttpHandler* handler;
|
||||||
std::string pattern;
|
std::string pattern;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpMuxEntry();
|
SrsHttpMuxEntry();
|
||||||
virtual ~SrsGoHttpMuxEntry();
|
virtual ~SrsHttpMuxEntry();
|
||||||
};
|
};
|
||||||
|
|
||||||
// ServeMux is an HTTP request multiplexer.
|
// ServeMux is an HTTP request multiplexer.
|
||||||
|
@ -303,16 +327,16 @@ public:
|
||||||
// ServeMux also takes care of sanitizing the URL request path,
|
// ServeMux also takes care of sanitizing the URL request path,
|
||||||
// redirecting any request containing . or .. elements to an
|
// redirecting any request containing . or .. elements to an
|
||||||
// equivalent .- and ..-free URL.
|
// equivalent .- and ..-free URL.
|
||||||
class SrsGoHttpServeMux
|
class SrsHttpServeMux
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// the pattern handler.
|
// the pattern handler.
|
||||||
std::map<std::string, SrsGoHttpMuxEntry*> entries;
|
std::map<std::string, SrsHttpMuxEntry*> entries;
|
||||||
// the vhost handler.
|
// the vhost handler.
|
||||||
std::map<std::string, ISrsGoHttpHandler*> vhosts;
|
std::map<std::string, ISrsHttpHandler*> vhosts;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpServeMux();
|
SrsHttpServeMux();
|
||||||
virtual ~SrsGoHttpServeMux();
|
virtual ~SrsHttpServeMux();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* initialize the http serve mux.
|
* initialize the http serve mux.
|
||||||
|
@ -321,24 +345,24 @@ public:
|
||||||
public:
|
public:
|
||||||
// Handle registers the handler for the given pattern.
|
// Handle registers the handler for the given pattern.
|
||||||
// If a handler already exists for pattern, Handle panics.
|
// If a handler already exists for pattern, Handle panics.
|
||||||
virtual int handle(std::string pattern, ISrsGoHttpHandler* handler);
|
virtual int handle(std::string pattern, ISrsHttpHandler* handler);
|
||||||
// interface ISrsGoHttpHandler
|
// interface ISrsHttpHandler
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
private:
|
private:
|
||||||
virtual int find_handler(SrsHttpMessage* r, ISrsGoHttpHandler** ph);
|
virtual int find_handler(SrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||||
virtual int match(SrsHttpMessage* r, ISrsGoHttpHandler** ph);
|
virtual int match(SrsHttpMessage* r, ISrsHttpHandler** ph);
|
||||||
virtual bool path_match(std::string pattern, std::string path);
|
virtual bool path_match(std::string pattern, std::string path);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* response writer use st socket
|
* response writer use st socket
|
||||||
*/
|
*/
|
||||||
class SrsGoHttpResponseWriter : public ISrsGoHttpResponseWriter
|
class SrsHttpResponseWriter : public ISrsHttpResponseWriter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsStSocket* skt;
|
SrsStSocket* skt;
|
||||||
SrsGoHttpHeader* hdr;
|
SrsHttpHeader* hdr;
|
||||||
private:
|
private:
|
||||||
// reply header has been (logically) written
|
// reply header has been (logically) written
|
||||||
bool header_wrote;
|
bool header_wrote;
|
||||||
|
@ -356,16 +380,47 @@ private:
|
||||||
// logically written.
|
// logically written.
|
||||||
bool header_sent;
|
bool header_sent;
|
||||||
public:
|
public:
|
||||||
SrsGoHttpResponseWriter(SrsStSocket* io);
|
SrsHttpResponseWriter(SrsStSocket* io);
|
||||||
virtual ~SrsGoHttpResponseWriter();
|
virtual ~SrsHttpResponseWriter();
|
||||||
public:
|
public:
|
||||||
virtual int final_request();
|
virtual int final_request();
|
||||||
virtual SrsGoHttpHeader* header();
|
virtual SrsHttpHeader* header();
|
||||||
virtual int write(char* data, int size);
|
virtual int write(char* data, int size);
|
||||||
virtual void write_header(int code);
|
virtual void write_header(int code);
|
||||||
virtual int send_header(char* data, int size);
|
virtual int send_header(char* data, int size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* response reader use st socket.
|
||||||
|
*/
|
||||||
|
class SrsHttpResponseReader : virtual public ISrsHttpResponseReader
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SrsStSocket* skt;
|
||||||
|
SrsHttpMessage* owner;
|
||||||
|
SrsFastBuffer* buffer;
|
||||||
|
bool is_eof;
|
||||||
|
int64_t nb_read;
|
||||||
|
public:
|
||||||
|
SrsHttpResponseReader(SrsHttpMessage* msg, SrsStSocket* io);
|
||||||
|
virtual ~SrsHttpResponseReader();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* initialize the response reader with buffer.
|
||||||
|
*/
|
||||||
|
virtual int initialize(SrsFastBuffer* buffer);
|
||||||
|
// interface ISrsHttpResponseReader
|
||||||
|
public:
|
||||||
|
virtual bool eof();
|
||||||
|
virtual int read(std::string& data);
|
||||||
|
private:
|
||||||
|
virtual int read_chunked(std::string& data);
|
||||||
|
virtual int read_specified(int max, std::string& data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// for http header.
|
||||||
|
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
||||||
|
|
||||||
// A Request represents an HTTP request received by a server
|
// A Request represents an HTTP request received by a server
|
||||||
// or to be sent by a client.
|
// or to be sent by a client.
|
||||||
//
|
//
|
||||||
|
@ -387,15 +442,14 @@ private:
|
||||||
*/
|
*/
|
||||||
http_parser _header;
|
http_parser _header;
|
||||||
/**
|
/**
|
||||||
* body object, in bytes.
|
* body object, reader object.
|
||||||
* @remark, user can get body in string by get_body().
|
* @remark, user can get body in string by get_body().
|
||||||
*/
|
*/
|
||||||
SrsSimpleBuffer* _body;
|
SrsHttpResponseReader* _body;
|
||||||
/**
|
/**
|
||||||
* parser state
|
* whether the body is chunked.
|
||||||
* @remark, user can use is_complete() to determine the state.
|
|
||||||
*/
|
*/
|
||||||
SrsHttpParseState _state;
|
bool chunked;
|
||||||
/**
|
/**
|
||||||
* uri parser
|
* uri parser
|
||||||
*/
|
*/
|
||||||
|
@ -403,53 +457,77 @@ private:
|
||||||
/**
|
/**
|
||||||
* use a buffer to read and send ts file.
|
* use a buffer to read and send ts file.
|
||||||
*/
|
*/
|
||||||
|
// TODO: FIXME: remove it.
|
||||||
char* _http_ts_send_buffer;
|
char* _http_ts_send_buffer;
|
||||||
// http headers
|
// http headers
|
||||||
typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
std::vector<SrsHttpHeaderField> _headers;
|
||||||
std::vector<SrsHttpHeaderField> headers;
|
|
||||||
// the query map
|
// the query map
|
||||||
std::map<std::string, std::string> _query;
|
std::map<std::string, std::string> _query;
|
||||||
public:
|
public:
|
||||||
SrsHttpMessage();
|
SrsHttpMessage(SrsStSocket* io);
|
||||||
virtual ~SrsHttpMessage();
|
virtual ~SrsHttpMessage();
|
||||||
public:
|
public:
|
||||||
virtual int initialize();
|
/**
|
||||||
|
* set the original messages, then update the message.
|
||||||
|
*/
|
||||||
|
virtual int update(std::string url, http_parser* header,
|
||||||
|
SrsFastBuffer* body, std::vector<SrsHttpHeaderField>& headers
|
||||||
|
);
|
||||||
public:
|
public:
|
||||||
virtual char* http_ts_send_buffer();
|
virtual char* http_ts_send_buffer();
|
||||||
virtual void reset();
|
|
||||||
public:
|
public:
|
||||||
virtual bool is_complete();
|
|
||||||
virtual u_int8_t method();
|
virtual u_int8_t method();
|
||||||
virtual u_int16_t status_code();
|
virtual u_int16_t status_code();
|
||||||
|
/**
|
||||||
|
* method helpers.
|
||||||
|
*/
|
||||||
virtual std::string method_str();
|
virtual std::string method_str();
|
||||||
virtual bool is_http_get();
|
virtual bool is_http_get();
|
||||||
virtual bool is_http_put();
|
virtual bool is_http_put();
|
||||||
virtual bool is_http_post();
|
virtual bool is_http_post();
|
||||||
virtual bool is_http_delete();
|
virtual bool is_http_delete();
|
||||||
virtual bool is_http_options();
|
virtual bool is_http_options();
|
||||||
|
/**
|
||||||
|
* whether body is chunked encoding, for reader only.
|
||||||
|
*/
|
||||||
|
virtual bool is_chunked();
|
||||||
|
/**
|
||||||
|
* the uri contains the host and path.
|
||||||
|
*/
|
||||||
virtual std::string uri();
|
virtual std::string uri();
|
||||||
|
/**
|
||||||
|
* the url maybe the path.
|
||||||
|
*/
|
||||||
virtual std::string url();
|
virtual std::string url();
|
||||||
virtual std::string host();
|
virtual std::string host();
|
||||||
virtual std::string path();
|
virtual std::string path();
|
||||||
public:
|
public:
|
||||||
virtual std::string body();
|
/**
|
||||||
virtual char* body_raw();
|
* read body to string.
|
||||||
virtual int64_t body_size();
|
* @remark for small http body.
|
||||||
|
*/
|
||||||
|
virtual int body_read_all(std::string& body);
|
||||||
|
/**
|
||||||
|
* get the body reader, to read one by one.
|
||||||
|
* @remark when body is very large, or chunked, use this.
|
||||||
|
*/
|
||||||
|
virtual ISrsHttpResponseReader* body_reader();
|
||||||
|
/**
|
||||||
|
* the content length, -1 for chunked or not set.
|
||||||
|
*/
|
||||||
virtual int64_t content_length();
|
virtual int64_t content_length();
|
||||||
virtual void set_url(std::string url);
|
|
||||||
virtual void set_state(SrsHttpParseState state);
|
|
||||||
virtual void set_header(http_parser* header);
|
|
||||||
virtual void append_body(const char* body, int length);
|
|
||||||
/**
|
/**
|
||||||
* get the param in query string,
|
* get the param in query string,
|
||||||
* for instance, query is "start=100&end=200",
|
* for instance, query is "start=100&end=200",
|
||||||
* then query_get("start") is "100", and query_get("end") is "200"
|
* then query_get("start") is "100", and query_get("end") is "200"
|
||||||
*/
|
*/
|
||||||
virtual std::string query_get(std::string key);
|
virtual std::string query_get(std::string key);
|
||||||
|
/**
|
||||||
|
* get the headers.
|
||||||
|
*/
|
||||||
virtual int request_header_count();
|
virtual int request_header_count();
|
||||||
virtual std::string request_header_key_at(int index);
|
virtual std::string request_header_key_at(int index);
|
||||||
virtual std::string request_header_value_at(int index);
|
virtual std::string request_header_value_at(int index);
|
||||||
virtual void set_request_header(std::string key, std::string value);
|
|
||||||
virtual std::string get_request_header(std::string name);
|
virtual std::string get_request_header(std::string name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -462,8 +540,18 @@ class SrsHttpParser
|
||||||
private:
|
private:
|
||||||
http_parser_settings settings;
|
http_parser_settings settings;
|
||||||
http_parser parser;
|
http_parser parser;
|
||||||
SrsHttpMessage* msg;
|
// the global parse buffer.
|
||||||
|
SrsFastBuffer* buffer;
|
||||||
|
private:
|
||||||
|
// http parse data, reset before parse message.
|
||||||
|
bool expect_filed_name;
|
||||||
std::string filed_name;
|
std::string filed_name;
|
||||||
|
std::string field_value;
|
||||||
|
SrsHttpParseState state;
|
||||||
|
http_parser header;
|
||||||
|
std::string url;
|
||||||
|
std::vector<SrsHttpHeaderField> headers;
|
||||||
|
int body_parsed;
|
||||||
public:
|
public:
|
||||||
SrsHttpParser();
|
SrsHttpParser();
|
||||||
virtual ~SrsHttpParser();
|
virtual ~SrsHttpParser();
|
||||||
|
|
|
@ -48,7 +48,7 @@ SrsGoApiRoot::~SrsGoApiRoot()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiRoot::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ SrsGoApiApi::~SrsGoApiApi()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiApi::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiApi::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ SrsGoApiV1::~SrsGoApiV1()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiV1::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -108,8 +108,7 @@ int SrsGoApiV1::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
<< __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("authors", "the primary authors and contributors") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("requests", "the request itself, for http debug") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("vhosts", "dumps vhost to json") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("vhosts", "dumps vhost to json") << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("streams", "dumps streams to json") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("streams", "dumps streams to json")
|
||||||
<< __SRS_JFIELD_STR("dvrs", "query or control the dvr plan")
|
|
||||||
<< __SRS_JOBJECT_END
|
<< __SRS_JOBJECT_END
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
|
@ -124,7 +123,7 @@ SrsGoApiVersion::~SrsGoApiVersion()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiVersion::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiVersion::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ SrsGoApiSummaries::~SrsGoApiSummaries()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiSummaries::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiSummaries::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
srs_api_dump_summaries(ss);
|
srs_api_dump_summaries(ss);
|
||||||
|
@ -164,7 +163,7 @@ SrsGoApiRusages::~SrsGoApiRusages()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiRusages::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* req)
|
int SrsGoApiRusages::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* req)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -205,7 +204,7 @@ SrsGoApiSelfProcStats::~SrsGoApiSelfProcStats()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiSelfProcStats::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiSelfProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -275,7 +274,7 @@ SrsGoApiSystemProcStats::~SrsGoApiSystemProcStats()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiSystemProcStats::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiSystemProcStats::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -310,7 +309,7 @@ SrsGoApiMemInfos::~SrsGoApiMemInfos()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiMemInfos::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiMemInfos::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -346,7 +345,7 @@ SrsGoApiAuthors::~SrsGoApiAuthors()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiAuthors::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
|
@ -371,7 +370,7 @@ SrsGoApiRequests::~SrsGoApiRequests()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiRequests::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
SrsHttpMessage* req = r;
|
SrsHttpMessage* req = r;
|
||||||
|
|
||||||
|
@ -432,7 +431,7 @@ SrsGoApiVhosts::~SrsGoApiVhosts()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiVhosts::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
SrsStatistic* stat = SrsStatistic::instance();
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
|
@ -457,7 +456,7 @@ SrsGoApiStreams::~SrsGoApiStreams()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsGoApiStreams::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
std::stringstream data;
|
std::stringstream data;
|
||||||
SrsStatistic* stat = SrsStatistic::instance();
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
|
@ -474,77 +473,7 @@ int SrsGoApiStreams::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
return srs_go_http_response_json(w, ss.str());
|
return srs_go_http_response_json(w, ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsGoApiDvrs::SrsGoApiDvrs()
|
SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsGoApiDvrs::~SrsGoApiDvrs()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int SrsGoApiDvrs::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
#ifndef SRS_AUTO_DVR
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ERROR_HTTP_DVR_DISABLED)
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
#else
|
|
||||||
SrsApiDvrPool* pool = SrsApiDvrPool::instance();
|
|
||||||
if (r->is_http_get()) {
|
|
||||||
std::stringstream data;
|
|
||||||
int ret = pool->dumps(r->query_get("vhost"), data);
|
|
||||||
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_ORG("dvrs", data.str())
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
} else if (r->is_http_post()) {
|
|
||||||
std::string body = r->body();
|
|
||||||
SrsJsonAny* json = SrsJsonAny::loads((char*)body.c_str());
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
if (!json) {
|
|
||||||
ret = ERROR_HTTP_JSON_REQUIRED;
|
|
||||||
} else {
|
|
||||||
SrsAutoFree(SrsJsonAny, json);
|
|
||||||
ret = pool->create(json);
|
|
||||||
}
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ret)
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
} else if (r->is_http_delete()) {
|
|
||||||
int ret = pool->stop(r->query_get("vhost"));
|
|
||||||
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ret)
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
} else if (r->is_http_put()) {
|
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
std::string body = r->body();
|
|
||||||
SrsJsonAny* json = SrsJsonAny::loads((char*)body.c_str());
|
|
||||||
if (!json) {
|
|
||||||
ret = ERROR_HTTP_JSON_REQUIRED;
|
|
||||||
} else {
|
|
||||||
SrsAutoFree(SrsJsonAny, json);
|
|
||||||
ret = pool->rpc(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ret)
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
} else {
|
|
||||||
ss << __SRS_JOBJECT_START
|
|
||||||
<< __SRS_JFIELD_ERROR(ERROR_HTTP_DVR_REQUEST)
|
|
||||||
<< __SRS_JOBJECT_END;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return srs_go_http_response_json(w, ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m)
|
|
||||||
: SrsConnection(svr, fd)
|
: SrsConnection(svr, fd)
|
||||||
{
|
{
|
||||||
mux = m;
|
mux = m;
|
||||||
|
@ -557,7 +486,7 @@ SrsHttpApi::~SrsHttpApi()
|
||||||
srs_freep(parser);
|
srs_freep(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpApi::kbps_resample()
|
void SrsHttpApi::resample()
|
||||||
{
|
{
|
||||||
// TODO: FIXME: implements it
|
// TODO: FIXME: implements it
|
||||||
}
|
}
|
||||||
|
@ -574,6 +503,11 @@ int64_t SrsHttpApi::get_recv_bytes_delta()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsHttpApi::cleanup()
|
||||||
|
{
|
||||||
|
// TODO: FIXME: implements it
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHttpApi::do_cycle()
|
int SrsHttpApi::do_cycle()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -598,15 +532,22 @@ int SrsHttpApi::do_cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if SUCCESS, always NOT-NULL and completed message.
|
// if SUCCESS, always NOT-NULL.
|
||||||
srs_assert(req);
|
srs_assert(req);
|
||||||
srs_assert(req->is_complete());
|
|
||||||
|
|
||||||
// always free it in this scope.
|
// always free it in this scope.
|
||||||
SrsAutoFree(SrsHttpMessage, req);
|
SrsAutoFree(SrsHttpMessage, req);
|
||||||
|
|
||||||
|
// TODO: FIXME: use the post body.
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
// get response body.
|
||||||
|
if ((ret = req->body_read_all(res)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// ok, handle http request.
|
// ok, handle http request.
|
||||||
SrsGoHttpResponseWriter writer(&skt);
|
SrsHttpResponseWriter writer(&skt);
|
||||||
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
|
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -615,7 +556,7 @@ int SrsHttpApi::do_cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpApi::process_request(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -42,151 +42,142 @@ class SrsHttpHandler;
|
||||||
#include <srs_app_http.hpp>
|
#include <srs_app_http.hpp>
|
||||||
|
|
||||||
// for http root.
|
// for http root.
|
||||||
class SrsGoApiRoot : public ISrsGoHttpHandler
|
class SrsGoApiRoot : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiRoot();
|
SrsGoApiRoot();
|
||||||
virtual ~SrsGoApiRoot();
|
virtual ~SrsGoApiRoot();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiApi : public ISrsGoHttpHandler
|
class SrsGoApiApi : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiApi();
|
SrsGoApiApi();
|
||||||
virtual ~SrsGoApiApi();
|
virtual ~SrsGoApiApi();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiV1 : public ISrsGoHttpHandler
|
class SrsGoApiV1 : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiV1();
|
SrsGoApiV1();
|
||||||
virtual ~SrsGoApiV1();
|
virtual ~SrsGoApiV1();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiVersion : public ISrsGoHttpHandler
|
class SrsGoApiVersion : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiVersion();
|
SrsGoApiVersion();
|
||||||
virtual ~SrsGoApiVersion();
|
virtual ~SrsGoApiVersion();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiSummaries : public ISrsGoHttpHandler
|
class SrsGoApiSummaries : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiSummaries();
|
SrsGoApiSummaries();
|
||||||
virtual ~SrsGoApiSummaries();
|
virtual ~SrsGoApiSummaries();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiRusages : public ISrsGoHttpHandler
|
class SrsGoApiRusages : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiRusages();
|
SrsGoApiRusages();
|
||||||
virtual ~SrsGoApiRusages();
|
virtual ~SrsGoApiRusages();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiSelfProcStats : public ISrsGoHttpHandler
|
class SrsGoApiSelfProcStats : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiSelfProcStats();
|
SrsGoApiSelfProcStats();
|
||||||
virtual ~SrsGoApiSelfProcStats();
|
virtual ~SrsGoApiSelfProcStats();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiSystemProcStats : public ISrsGoHttpHandler
|
class SrsGoApiSystemProcStats : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiSystemProcStats();
|
SrsGoApiSystemProcStats();
|
||||||
virtual ~SrsGoApiSystemProcStats();
|
virtual ~SrsGoApiSystemProcStats();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiMemInfos : public ISrsGoHttpHandler
|
class SrsGoApiMemInfos : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiMemInfos();
|
SrsGoApiMemInfos();
|
||||||
virtual ~SrsGoApiMemInfos();
|
virtual ~SrsGoApiMemInfos();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiAuthors : public ISrsGoHttpHandler
|
class SrsGoApiAuthors : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiAuthors();
|
SrsGoApiAuthors();
|
||||||
virtual ~SrsGoApiAuthors();
|
virtual ~SrsGoApiAuthors();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiRequests : public ISrsGoHttpHandler
|
class SrsGoApiRequests : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiRequests();
|
SrsGoApiRequests();
|
||||||
virtual ~SrsGoApiRequests();
|
virtual ~SrsGoApiRequests();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiVhosts : public ISrsGoHttpHandler
|
class SrsGoApiVhosts : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiVhosts();
|
SrsGoApiVhosts();
|
||||||
virtual ~SrsGoApiVhosts();
|
virtual ~SrsGoApiVhosts();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsGoApiStreams : public ISrsGoHttpHandler
|
class SrsGoApiStreams : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoApiStreams();
|
SrsGoApiStreams();
|
||||||
virtual ~SrsGoApiStreams();
|
virtual ~SrsGoApiStreams();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
|
||||||
|
|
||||||
class SrsGoApiDvrs : public ISrsGoHttpHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SrsGoApiDvrs();
|
|
||||||
virtual ~SrsGoApiDvrs();
|
|
||||||
public:
|
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsHttpApi : public SrsConnection
|
class SrsHttpApi : public SrsConnection
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsHttpParser* parser;
|
SrsHttpParser* parser;
|
||||||
SrsGoHttpServeMux* mux;
|
SrsHttpServeMux* mux;
|
||||||
bool crossdomain_required;
|
bool crossdomain_required;
|
||||||
public:
|
public:
|
||||||
SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsGoHttpServeMux* m);
|
SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m);
|
||||||
virtual ~SrsHttpApi();
|
virtual ~SrsHttpApi();
|
||||||
public:
|
|
||||||
virtual void kbps_resample();
|
|
||||||
// interface IKbpsDelta
|
// interface IKbpsDelta
|
||||||
public:
|
public:
|
||||||
|
virtual void resample();
|
||||||
virtual int64_t get_send_bytes_delta();
|
virtual int64_t get_send_bytes_delta();
|
||||||
virtual int64_t get_recv_bytes_delta();
|
virtual int64_t get_recv_bytes_delta();
|
||||||
|
virtual void cleanup();
|
||||||
protected:
|
protected:
|
||||||
virtual int do_cycle();
|
virtual int do_cycle();
|
||||||
private:
|
private:
|
||||||
virtual int process_request(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
#include <srs_app_st_socket.hpp>
|
#include <srs_app_st_socket.hpp>
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
|
#include <srs_core_autofree.hpp>
|
||||||
|
|
||||||
// when error, http client sleep for a while and retry.
|
// when error, http client sleep for a while and retry.
|
||||||
#define SRS_HTTP_CLIENT_SLEEP_US (int64_t)(3*1000*1000LL)
|
#define SRS_HTTP_CLIENT_SLEEP_US (int64_t)(3*1000*1000LL)
|
||||||
|
@ -43,6 +44,7 @@ SrsHttpClient::SrsHttpClient()
|
||||||
{
|
{
|
||||||
connected = false;
|
connected = false;
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
|
skt = NULL;
|
||||||
parser = NULL;
|
parser = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,22 +54,31 @@ SrsHttpClient::~SrsHttpClient()
|
||||||
srs_freep(parser);
|
srs_freep(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& res)
|
int SrsHttpClient::initialize(string h, int p)
|
||||||
{
|
{
|
||||||
res = "";
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_freep(parser);
|
||||||
|
parser = new SrsHttpParser();
|
||||||
|
|
||||||
|
if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("initialize parser failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
host = h;
|
||||||
|
port = p;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpClient::post(string path, string req, SrsHttpMessage** ppmsg)
|
||||||
|
{
|
||||||
|
*ppmsg = NULL;
|
||||||
|
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (!parser) {
|
if ((ret = connect()) != ERROR_SUCCESS) {
|
||||||
parser = new SrsHttpParser();
|
|
||||||
|
|
||||||
if ((ret = parser->initialize(HTTP_RESPONSE)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("initialize parser failed. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = connect(uri)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http connect server failed. ret=%d", ret);
|
srs_warn("http connect server failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -75,9 +86,9 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
||||||
// send POST request to uri
|
// send POST request to uri
|
||||||
// POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
|
// POST %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "POST " << uri->get_path() << " "
|
ss << "POST " << path << " "
|
||||||
<< "HTTP/1.1" << __SRS_HTTP_CRLF
|
<< "HTTP/1.1" << __SRS_HTTP_CRLF
|
||||||
<< "Host: " << uri->get_host() << __SRS_HTTP_CRLF
|
<< "Host: " << host << __SRS_HTTP_CRLF
|
||||||
<< "Connection: Keep-Alive" << __SRS_HTTP_CRLF
|
<< "Connection: Keep-Alive" << __SRS_HTTP_CRLF
|
||||||
<< "Content-Length: " << std::dec << req.length() << __SRS_HTTP_CRLF
|
<< "Content-Length: " << std::dec << req.length() << __SRS_HTTP_CRLF
|
||||||
<< "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_HTTP_CRLF
|
<< "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_HTTP_CRLF
|
||||||
|
@ -85,10 +96,8 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
||||||
<< __SRS_HTTP_CRLF
|
<< __SRS_HTTP_CRLF
|
||||||
<< req;
|
<< req;
|
||||||
|
|
||||||
SrsStSocket skt(stfd);
|
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
if ((ret = skt.write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
||||||
// disconnect when error.
|
// disconnect when error.
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
||||||
|
@ -97,24 +106,61 @@ int SrsHttpClient::post(SrsHttpUri* uri, string req, int& status_code, string& r
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHttpMessage* msg = NULL;
|
SrsHttpMessage* msg = NULL;
|
||||||
if ((ret = parser->parse_message(&skt, &msg)) != ERROR_SUCCESS) {
|
if ((ret = parser->parse_message(skt, &msg)) != ERROR_SUCCESS) {
|
||||||
srs_error("parse http post response failed. ret=%d", ret);
|
srs_error("parse http post response failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_assert(msg);
|
srs_assert(msg);
|
||||||
srs_assert(msg->is_complete());
|
*ppmsg = msg;
|
||||||
|
|
||||||
status_code = (int)msg->status_code();
|
|
||||||
|
|
||||||
// get response body.
|
|
||||||
if (msg->body_size() > 0) {
|
|
||||||
res = msg->body();
|
|
||||||
}
|
|
||||||
srs_info("parse http post response success.");
|
srs_info("parse http post response success.");
|
||||||
|
|
||||||
srs_freep(msg);
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsHttpClient::get(string path, std::string req, SrsHttpMessage** ppmsg)
|
||||||
|
{
|
||||||
|
*ppmsg = NULL;
|
||||||
|
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if ((ret = connect()) != ERROR_SUCCESS) {
|
||||||
|
srs_warn("http connect server failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send POST request to uri
|
||||||
|
// GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "GET " << path << " "
|
||||||
|
<< "HTTP/1.1" << __SRS_HTTP_CRLF
|
||||||
|
<< "Host: " << host << __SRS_HTTP_CRLF
|
||||||
|
<< "Connection: Keep-Alive" << __SRS_HTTP_CRLF
|
||||||
|
<< "Content-Length: " << std::dec << req.length() << __SRS_HTTP_CRLF
|
||||||
|
<< "User-Agent: " << RTMP_SIG_SRS_NAME << RTMP_SIG_SRS_VERSION << __SRS_HTTP_CRLF
|
||||||
|
<< "Content-Type: application/json" << __SRS_HTTP_CRLF
|
||||||
|
<< __SRS_HTTP_CRLF
|
||||||
|
<< req;
|
||||||
|
|
||||||
|
std::string data = ss.str();
|
||||||
|
if ((ret = skt->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) {
|
||||||
|
// disconnect when error.
|
||||||
|
disconnect();
|
||||||
|
|
||||||
|
srs_error("write http get failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpMessage* msg = NULL;
|
||||||
|
if ((ret = parser->parse_message(skt, &msg)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("parse http post response failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_assert(msg);
|
||||||
|
|
||||||
|
*ppmsg = msg;
|
||||||
|
srs_info("parse http get response success.");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,9 +169,10 @@ void SrsHttpClient::disconnect()
|
||||||
connected = false;
|
connected = false;
|
||||||
|
|
||||||
srs_close_stfd(stfd);
|
srs_close_stfd(stfd);
|
||||||
|
srs_freep(skt);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpClient::connect(SrsHttpUri* uri)
|
int SrsHttpClient::connect()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -135,19 +182,17 @@ int SrsHttpClient::connect(SrsHttpUri* uri)
|
||||||
|
|
||||||
disconnect();
|
disconnect();
|
||||||
|
|
||||||
std::string server = uri->get_host();
|
|
||||||
int port = uri->get_port();
|
|
||||||
|
|
||||||
// open socket.
|
// open socket.
|
||||||
int64_t timeout = SRS_HTTP_CLIENT_SLEEP_US;
|
int64_t timeout = SRS_HTTP_CLIENT_SLEEP_US;
|
||||||
if ((ret = srs_socket_connect(server, port, timeout, &stfd)) != ERROR_SUCCESS) {
|
if ((ret = srs_socket_connect(host, port, timeout, &stfd)) != ERROR_SUCCESS) {
|
||||||
srs_warn("http client failed, server=%s, port=%d, timeout=%"PRId64", ret=%d",
|
srs_warn("http client failed, server=%s, port=%d, timeout=%"PRId64", ret=%d",
|
||||||
server.c_str(), port, timeout, ret);
|
host.c_str(), port, timeout, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_info("connect to server success. http url=%s, server=%s, port=%d",
|
srs_info("connect to server success. server=%s, port=%d", host, port);
|
||||||
uri->get_url(), uri->get_host(), uri->get_port());
|
|
||||||
|
|
||||||
|
srs_assert(!skt);
|
||||||
|
skt = new SrsStSocket(stfd);
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -37,6 +37,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
class SrsHttpUri;
|
class SrsHttpUri;
|
||||||
class SrsHttpParser;
|
class SrsHttpParser;
|
||||||
|
class SrsHttpMessage;
|
||||||
|
class SrsStSocket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* http client to GET/POST/PUT/DELETE uri
|
* http client to GET/POST/PUT/DELETE uri
|
||||||
|
@ -46,21 +48,38 @@ class SrsHttpClient
|
||||||
private:
|
private:
|
||||||
bool connected;
|
bool connected;
|
||||||
st_netfd_t stfd;
|
st_netfd_t stfd;
|
||||||
|
SrsStSocket* skt;
|
||||||
SrsHttpParser* parser;
|
SrsHttpParser* parser;
|
||||||
|
private:
|
||||||
|
// host name or ip.
|
||||||
|
std::string host;
|
||||||
|
int port;
|
||||||
public:
|
public:
|
||||||
SrsHttpClient();
|
SrsHttpClient();
|
||||||
virtual ~SrsHttpClient();
|
virtual ~SrsHttpClient();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* to post data to the uri.
|
* initialize the client, connect to host and port.
|
||||||
* @param req the data post to uri.
|
|
||||||
* @param status_code the output status code response by server.
|
|
||||||
* @param res output the response data from server.
|
|
||||||
*/
|
*/
|
||||||
virtual int post(SrsHttpUri* uri, std::string req, int& status_code, std::string& res);
|
virtual int initialize(std::string h, int p);
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* to post data to the uri.
|
||||||
|
* @param the path to request on.
|
||||||
|
* @param req the data post to uri. empty string to ignore.
|
||||||
|
* @param ppmsg output the http message to read the response.
|
||||||
|
*/
|
||||||
|
virtual int post(std::string path, std::string req, SrsHttpMessage** ppmsg);
|
||||||
|
/**
|
||||||
|
* to get data from the uri.
|
||||||
|
* @param the path to request on.
|
||||||
|
* @param req the data post to uri. empty string to ignore.
|
||||||
|
* @param ppmsg output the http message to read the response.
|
||||||
|
*/
|
||||||
|
virtual int get(std::string path, std::string req, SrsHttpMessage** ppmsg);
|
||||||
private:
|
private:
|
||||||
virtual void disconnect();
|
virtual void disconnect();
|
||||||
virtual int connect(SrsHttpUri* uri);
|
virtual int connect();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -50,7 +50,7 @@ using namespace std;
|
||||||
#include <srs_app_pithy_print.hpp>
|
#include <srs_app_pithy_print.hpp>
|
||||||
|
|
||||||
SrsVodStream::SrsVodStream(string root_dir)
|
SrsVodStream::SrsVodStream(string root_dir)
|
||||||
: SrsGoHttpFileServer(root_dir)
|
: SrsHttpFileServer(root_dir)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ SrsVodStream::~SrsVodStream()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsVodStream::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
|
int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ int SrsVodStream::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsVodStream::serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
|
int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ int SrsFlvStreamEncoder::write_video(int64_t timestamp, char* data, int size)
|
||||||
|
|
||||||
int SrsFlvStreamEncoder::write_metadata(int64_t timestamp, char* data, int size)
|
int SrsFlvStreamEncoder::write_metadata(int64_t timestamp, char* data, int size)
|
||||||
{
|
{
|
||||||
return enc->write_metadata(timestamp, data, size);
|
return enc->write_metadata(SrsCodecFlvTagScript, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsFlvStreamEncoder::has_cache()
|
bool SrsFlvStreamEncoder::has_cache()
|
||||||
|
@ -517,7 +517,7 @@ int SrsMp3StreamEncoder::dump_cache(SrsConsumer* consumer)
|
||||||
return cache->dump_cache(consumer);
|
return cache->dump_cache(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStreamWriter::SrsStreamWriter(ISrsGoHttpResponseWriter* w)
|
SrsStreamWriter::SrsStreamWriter(ISrsHttpResponseWriter* w)
|
||||||
{
|
{
|
||||||
writer = w;
|
writer = w;
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ SrsLiveStream::~SrsLiveStream()
|
||||||
srs_freep(req);
|
srs_freep(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsLiveStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -708,7 +708,7 @@ void SrsHlsM3u8Stream::set_m3u8(std::string v)
|
||||||
m3u8 = v;
|
m3u8 = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHlsM3u8Stream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHlsM3u8Stream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -740,7 +740,7 @@ void SrsHlsTsStream::set_ts(std::string v)
|
||||||
ts = v;
|
ts = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHlsTsStream::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHlsTsStream::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
@ -771,19 +771,35 @@ SrsHttpServer::~SrsHttpServer()
|
||||||
{
|
{
|
||||||
if (true) {
|
if (true) {
|
||||||
std::map<std::string, SrsLiveEntry*>::iterator it;
|
std::map<std::string, SrsLiveEntry*>::iterator it;
|
||||||
for (it = flvs.begin(); it != flvs.end(); ++it) {
|
for (it = tflvs.begin(); it != tflvs.end(); ++it) {
|
||||||
SrsLiveEntry* entry = it->second;
|
SrsLiveEntry* entry = it->second;
|
||||||
srs_freep(entry);
|
srs_freep(entry);
|
||||||
}
|
}
|
||||||
flvs.clear();
|
tflvs.clear();
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
std::map<std::string, SrsLiveEntry*>::iterator it;
|
||||||
|
for (it = sflvs.begin(); it != sflvs.end(); ++it) {
|
||||||
|
SrsLiveEntry* entry = it->second;
|
||||||
|
srs_freep(entry);
|
||||||
|
}
|
||||||
|
sflvs.clear();
|
||||||
}
|
}
|
||||||
if (true) {
|
if (true) {
|
||||||
std::map<std::string, SrsHlsEntry*>::iterator it;
|
std::map<std::string, SrsHlsEntry*>::iterator it;
|
||||||
for (it = hls.begin(); it != hls.end(); ++it) {
|
for (it = thls.begin(); it != thls.end(); ++it) {
|
||||||
SrsHlsEntry* entry = it->second;
|
SrsHlsEntry* entry = it->second;
|
||||||
srs_freep(entry);
|
srs_freep(entry);
|
||||||
}
|
}
|
||||||
hls.clear();
|
thls.clear();
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
std::map<std::string, SrsHlsEntry*>::iterator it;
|
||||||
|
for (it = shls.begin(); it != shls.end(); ++it) {
|
||||||
|
SrsHlsEntry* entry = it->second;
|
||||||
|
srs_freep(entry);
|
||||||
|
}
|
||||||
|
shls.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,56 +830,72 @@ int SrsHttpServer::mount(SrsSource* s, SrsRequest* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (flvs.find(r->vhost) == flvs.end()) {
|
// the id to identify stream.
|
||||||
srs_info("ignore mount flv stream for disabled");
|
std::string sid = r->get_stream_url();
|
||||||
return ret;
|
SrsLiveEntry* entry = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
SrsLiveEntry* entry = flvs[r->vhost];
|
// create stream from template when not found.
|
||||||
|
if (sflvs.find(sid) == sflvs.end()) {
|
||||||
|
if (tflvs.find(r->vhost) == tflvs.end()) {
|
||||||
|
srs_info("ignore mount flv stream for disabled");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsLiveEntry* tmpl = tflvs[r->vhost];
|
||||||
|
|
||||||
|
std::string mount = tmpl->mount;
|
||||||
|
|
||||||
|
// replace the vhost variable
|
||||||
|
mount = srs_string_replace(mount, "[vhost]", r->vhost);
|
||||||
|
mount = srs_string_replace(mount, "[app]", r->app);
|
||||||
|
mount = srs_string_replace(mount, "[stream]", r->stream);
|
||||||
|
|
||||||
|
// remove the default vhost mount
|
||||||
|
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
|
||||||
|
|
||||||
|
entry = new SrsLiveEntry();
|
||||||
|
entry->mount = mount;
|
||||||
|
|
||||||
|
entry->cache = new SrsStreamCache(s, r);
|
||||||
|
entry->stream = new SrsLiveStream(s, r, entry->cache);
|
||||||
|
|
||||||
|
sflvs[sid] = entry;
|
||||||
|
|
||||||
|
// start http stream cache thread
|
||||||
|
if ((ret = entry->cache->start()) != ERROR_SUCCESS) {
|
||||||
|
srs_error("http: start stream cache failed. ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mount the http flv stream.
|
||||||
|
if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("http: mount flv stream for vhost=%s failed. ret=%d", sid.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
srs_trace("http: mount flv stream for vhost=%s, mount=%s", sid.c_str(), mount.c_str());
|
||||||
|
} else {
|
||||||
|
entry = sflvs[sid];
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: FIXME: supports reload.
|
// TODO: FIXME: supports reload.
|
||||||
if (entry->stream) {
|
if (entry->stream) {
|
||||||
entry->stream->entry->enabled = true;
|
entry->stream->entry->enabled = true;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mount = entry->mount;
|
|
||||||
|
|
||||||
// replace the vhost variable
|
|
||||||
mount = srs_string_replace(mount, "[vhost]", r->vhost);
|
|
||||||
mount = srs_string_replace(mount, "[app]", r->app);
|
|
||||||
mount = srs_string_replace(mount, "[stream]", r->stream);
|
|
||||||
|
|
||||||
// remove the default vhost mount
|
|
||||||
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
|
|
||||||
|
|
||||||
entry->cache = new SrsStreamCache(s, r);
|
|
||||||
entry->stream = new SrsLiveStream(s, r, entry->cache);
|
|
||||||
|
|
||||||
// start http stream cache thread
|
|
||||||
if ((ret = entry->cache->start()) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http: start stream cache failed. ret=%d", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// mount the http flv stream.
|
|
||||||
if ((ret = mux.handle(mount, entry->stream)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http: mount flv stream for vhost=%s failed. ret=%d", r->vhost.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
srs_trace("http: mount flv stream for vhost=%s, mount=%s", r->vhost.c_str(), mount.c_str());
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r)
|
void SrsHttpServer::unmount(SrsSource* s, SrsRequest* r)
|
||||||
{
|
{
|
||||||
if (flvs.find(r->vhost) == flvs.end()) {
|
std::string sid = r->get_stream_url();
|
||||||
|
|
||||||
|
if (sflvs.find(sid) == sflvs.end()) {
|
||||||
srs_info("ignore unmount flv stream for disabled");
|
srs_info("ignore unmount flv stream for disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsLiveEntry* entry = flvs[r->vhost];
|
SrsLiveEntry* entry = sflvs[sid];
|
||||||
entry->stream->entry->enabled = false;
|
entry->stream->entry->enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -871,17 +903,19 @@ int SrsHttpServer::mount_hls(SrsRequest* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (hls.find(r->vhost) == hls.end()) {
|
std::string sid = r->get_stream_url();
|
||||||
|
|
||||||
|
if (shls.find(sid) == shls.end()) {
|
||||||
srs_info("ignore mount hls stream for disabled");
|
srs_info("ignore mount hls stream for disabled");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHlsEntry* entry = hls[r->vhost];
|
SrsHlsEntry* entry = shls[sid];
|
||||||
|
|
||||||
// TODO: FIXME: supports reload.
|
// TODO: FIXME: supports reload.
|
||||||
std::map<std::string, ISrsGoHttpHandler*>::iterator it;
|
std::map<std::string, ISrsHttpHandler*>::iterator it;
|
||||||
for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
|
for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
|
||||||
ISrsGoHttpHandler* stream = it->second;
|
ISrsHttpHandler* stream = it->second;
|
||||||
stream->entry->enabled = true;
|
stream->entry->enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,33 +925,37 @@ int SrsHttpServer::mount_hls(SrsRequest* r)
|
||||||
int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
|
int SrsHttpServer::hls_update_m3u8(SrsRequest* r, string m3u8)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
std::string mount = m3u8;
|
||||||
|
|
||||||
// when no hls mounted, ignore.
|
std::string sid = r->get_stream_url();
|
||||||
if (hls.find(r->vhost) == hls.end()) {
|
SrsHlsEntry* entry = NULL;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsHlsEntry* entry = hls[r->vhost];
|
// create stream from template when not found.
|
||||||
srs_assert(entry);
|
if (shls.find(sid) == shls.end()) {
|
||||||
|
if (thls.find(r->vhost) == thls.end()) {
|
||||||
std::string mount = entry->mount;
|
srs_info("ignore mount hls stream for disabled");
|
||||||
|
|
||||||
// replace the vhost variable
|
|
||||||
mount = srs_string_replace(mount, "[vhost]", r->vhost);
|
|
||||||
mount = srs_string_replace(mount, "[app]", r->app);
|
|
||||||
mount = srs_string_replace(mount, "[stream]", r->stream);
|
|
||||||
|
|
||||||
// remove the default vhost mount
|
|
||||||
mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/");
|
|
||||||
|
|
||||||
if (entry->streams.find(mount) == entry->streams.end()) {
|
|
||||||
ISrsGoHttpHandler* he = new SrsHlsM3u8Stream();
|
|
||||||
entry->streams[mount] = he;
|
|
||||||
|
|
||||||
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsHlsEntry* tmpl = thls[r->vhost];
|
||||||
|
|
||||||
|
entry = new SrsHlsEntry();
|
||||||
|
entry->mount = tmpl->mount;
|
||||||
|
|
||||||
|
shls[sid] = entry;
|
||||||
|
|
||||||
|
if (entry->streams.find(mount) == entry->streams.end()) {
|
||||||
|
ISrsHttpHandler* he = new SrsHlsM3u8Stream();
|
||||||
|
entry->streams[mount] = he;
|
||||||
|
|
||||||
|
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("handle mount=%s failed. ret=%d", mount.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry = shls[sid];
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the m3u8 stream.
|
// update the m3u8 stream.
|
||||||
|
@ -934,12 +972,14 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
std::string sid = r->get_stream_url();
|
||||||
|
|
||||||
// when no hls mounted, ignore.
|
// when no hls mounted, ignore.
|
||||||
if (hls.find(r->vhost) == hls.end()) {
|
if (shls.find(sid) == shls.end()) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHlsEntry* entry = hls[r->vhost];
|
SrsHlsEntry* entry = shls[sid];
|
||||||
srs_assert(entry);
|
srs_assert(entry);
|
||||||
|
|
||||||
std::string mount = entry->mount;
|
std::string mount = entry->mount;
|
||||||
|
@ -962,7 +1002,7 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
|
||||||
mount += uri;
|
mount += uri;
|
||||||
|
|
||||||
if (entry->streams.find(mount) == entry->streams.end()) {
|
if (entry->streams.find(mount) == entry->streams.end()) {
|
||||||
ISrsGoHttpHandler* he = new SrsHlsTsStream();
|
ISrsHttpHandler* he = new SrsHlsTsStream();
|
||||||
entry->streams[mount] = he;
|
entry->streams[mount] = he;
|
||||||
|
|
||||||
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
|
if ((ret = mux.handle(mount, he)) != ERROR_SUCCESS) {
|
||||||
|
@ -983,16 +1023,18 @@ int SrsHttpServer::hls_update_ts(SrsRequest* r, string uri, string ts)
|
||||||
|
|
||||||
void SrsHttpServer::unmount_hls(SrsRequest* r)
|
void SrsHttpServer::unmount_hls(SrsRequest* r)
|
||||||
{
|
{
|
||||||
if (hls.find(r->vhost) == hls.end()) {
|
std::string sid = r->get_stream_url();
|
||||||
|
|
||||||
|
if (shls.find(sid) == shls.end()) {
|
||||||
srs_info("ignore unmount hls stream for disabled");
|
srs_info("ignore unmount hls stream for disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHlsEntry* entry = hls[r->vhost];
|
SrsHlsEntry* entry = shls[sid];
|
||||||
|
|
||||||
std::map<std::string, ISrsGoHttpHandler*>::iterator it;
|
std::map<std::string, ISrsHttpHandler*>::iterator it;
|
||||||
for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
|
for (it = entry->streams.begin(); it != entry->streams.end(); ++it) {
|
||||||
ISrsGoHttpHandler* stream = it->second;
|
ISrsHttpHandler* stream = it->second;
|
||||||
stream->entry->enabled = false;
|
stream->entry->enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1097,9 +1139,8 @@ int SrsHttpServer::initialize_flv_streaming()
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsLiveEntry* entry = new SrsLiveEntry();
|
SrsLiveEntry* entry = new SrsLiveEntry();
|
||||||
entry->vhost = vhost;
|
|
||||||
entry->mount = _srs_config->get_vhost_http_remux_mount(vhost);
|
entry->mount = _srs_config->get_vhost_http_remux_mount(vhost);
|
||||||
flvs[vhost] = entry;
|
tflvs[vhost] = entry;
|
||||||
srs_trace("http flv live stream, vhost=%s, mount=%s",
|
srs_trace("http flv live stream, vhost=%s, mount=%s",
|
||||||
vhost.c_str(), entry->mount.c_str());
|
vhost.c_str(), entry->mount.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1131,9 +1172,8 @@ int SrsHttpServer::initialize_hls_streaming()
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsHlsEntry* entry = new SrsHlsEntry();
|
SrsHlsEntry* entry = new SrsHlsEntry();
|
||||||
entry->vhost = vhost;
|
|
||||||
entry->mount = _srs_config->get_hls_mount(vhost);
|
entry->mount = _srs_config->get_hls_mount(vhost);
|
||||||
hls[vhost] = entry;
|
thls[vhost] = entry;
|
||||||
srs_trace("http hls live stream, vhost=%s, mount=%s",
|
srs_trace("http hls live stream, vhost=%s, mount=%s",
|
||||||
vhost.c_str(), entry->mount.c_str());
|
vhost.c_str(), entry->mount.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1153,7 +1193,7 @@ SrsHttpConn::~SrsHttpConn()
|
||||||
srs_freep(parser);
|
srs_freep(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsHttpConn::kbps_resample()
|
void SrsHttpConn::resample()
|
||||||
{
|
{
|
||||||
// TODO: FIXME: implements it
|
// TODO: FIXME: implements it
|
||||||
}
|
}
|
||||||
|
@ -1170,6 +1210,11 @@ int64_t SrsHttpConn::get_recv_bytes_delta()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsHttpConn::cleanup()
|
||||||
|
{
|
||||||
|
// TODO: FIXME: implements it
|
||||||
|
}
|
||||||
|
|
||||||
int SrsHttpConn::do_cycle()
|
int SrsHttpConn::do_cycle()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -1194,15 +1239,22 @@ int SrsHttpConn::do_cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if SUCCESS, always NOT-NULL and completed message.
|
// if SUCCESS, always NOT-NULL.
|
||||||
srs_assert(req);
|
srs_assert(req);
|
||||||
srs_assert(req->is_complete());
|
|
||||||
|
|
||||||
// always free it in this scope.
|
// always free it in this scope.
|
||||||
SrsAutoFree(SrsHttpMessage, req);
|
SrsAutoFree(SrsHttpMessage, req);
|
||||||
|
|
||||||
|
// TODO: FIXME: use the post body.
|
||||||
|
std::string res;
|
||||||
|
|
||||||
|
// get response body.
|
||||||
|
if ((ret = req->body_read_all(res)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// ok, handle http request.
|
// ok, handle http request.
|
||||||
SrsGoHttpResponseWriter writer(&skt);
|
SrsHttpResponseWriter writer(&skt);
|
||||||
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
|
if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1263,7 @@ int SrsHttpConn::do_cycle()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsHttpConn::process_request(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
|
int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -59,14 +59,14 @@ class SrsSharedPtrMessage;
|
||||||
* server will write flv header and sequence header,
|
* server will write flv header and sequence header,
|
||||||
* then seek(10240) and response flv tag data.
|
* then seek(10240) and response flv tag data.
|
||||||
*/
|
*/
|
||||||
class SrsVodStream : public SrsGoHttpFileServer
|
class SrsVodStream : public SrsHttpFileServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsVodStream(std::string root_dir);
|
SrsVodStream(std::string root_dir);
|
||||||
virtual ~SrsVodStream();
|
virtual ~SrsVodStream();
|
||||||
protected:
|
protected:
|
||||||
virtual int serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
|
virtual int serve_flv_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
|
||||||
virtual int serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
|
virtual int serve_mp4_stream(ISrsHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,9 +214,9 @@ public:
|
||||||
class SrsStreamWriter : public SrsFileWriter
|
class SrsStreamWriter : public SrsFileWriter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
ISrsGoHttpResponseWriter* writer;
|
ISrsHttpResponseWriter* writer;
|
||||||
public:
|
public:
|
||||||
SrsStreamWriter(ISrsGoHttpResponseWriter* w);
|
SrsStreamWriter(ISrsHttpResponseWriter* w);
|
||||||
virtual ~SrsStreamWriter();
|
virtual ~SrsStreamWriter();
|
||||||
public:
|
public:
|
||||||
virtual int open(std::string file);
|
virtual int open(std::string file);
|
||||||
|
@ -232,7 +232,7 @@ public:
|
||||||
* the flv live stream supports access rtmp in flv over http.
|
* the flv live stream supports access rtmp in flv over http.
|
||||||
* srs will remux rtmp to flv streaming.
|
* srs will remux rtmp to flv streaming.
|
||||||
*/
|
*/
|
||||||
class SrsLiveStream : public ISrsGoHttpHandler
|
class SrsLiveStream : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsRequest* req;
|
SrsRequest* req;
|
||||||
|
@ -242,7 +242,7 @@ public:
|
||||||
SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c);
|
SrsLiveStream(SrsSource* s, SrsRequest* r, SrsStreamCache* c);
|
||||||
virtual ~SrsLiveStream();
|
virtual ~SrsLiveStream();
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
private:
|
private:
|
||||||
virtual int streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs);
|
virtual int streaming_send_messages(ISrsStreamEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs);
|
||||||
};
|
};
|
||||||
|
@ -252,8 +252,10 @@ private:
|
||||||
*/
|
*/
|
||||||
struct SrsLiveEntry
|
struct SrsLiveEntry
|
||||||
{
|
{
|
||||||
std::string vhost;
|
// for template, the mount contains variables.
|
||||||
|
// for concrete stream, the mount is url to access.
|
||||||
std::string mount;
|
std::string mount;
|
||||||
|
|
||||||
SrsLiveStream* stream;
|
SrsLiveStream* stream;
|
||||||
SrsStreamCache* cache;
|
SrsStreamCache* cache;
|
||||||
|
|
||||||
|
@ -263,7 +265,7 @@ struct SrsLiveEntry
|
||||||
/**
|
/**
|
||||||
* the m3u8 stream handler.
|
* the m3u8 stream handler.
|
||||||
*/
|
*/
|
||||||
class SrsHlsM3u8Stream : public ISrsGoHttpHandler
|
class SrsHlsM3u8Stream : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string m3u8;
|
std::string m3u8;
|
||||||
|
@ -273,13 +275,13 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual void set_m3u8(std::string v);
|
virtual void set_m3u8(std::string v);
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the ts stream handler.
|
* the ts stream handler.
|
||||||
*/
|
*/
|
||||||
class SrsHlsTsStream : public ISrsGoHttpHandler
|
class SrsHlsTsStream : public ISrsHttpHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string ts;
|
std::string ts;
|
||||||
|
@ -289,7 +291,7 @@ public:
|
||||||
public:
|
public:
|
||||||
virtual void set_ts(std::string v);
|
virtual void set_ts(std::string v);
|
||||||
public:
|
public:
|
||||||
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -297,12 +299,13 @@ public:
|
||||||
*/
|
*/
|
||||||
struct SrsHlsEntry
|
struct SrsHlsEntry
|
||||||
{
|
{
|
||||||
std::string vhost;
|
// for template, the mount contains variables.
|
||||||
|
// for concrete stream, the mount is url to access.
|
||||||
std::string mount;
|
std::string mount;
|
||||||
|
|
||||||
// key: the m3u8/ts file path.
|
// key: the m3u8/ts file path.
|
||||||
// value: the http handler.
|
// value: the http handler.
|
||||||
std::map<std::string, ISrsGoHttpHandler*> streams;
|
std::map<std::string, ISrsHttpHandler*> streams;
|
||||||
|
|
||||||
SrsHlsEntry();
|
SrsHlsEntry();
|
||||||
};
|
};
|
||||||
|
@ -314,11 +317,15 @@ struct SrsHlsEntry
|
||||||
class SrsHttpServer : public ISrsReloadHandler
|
class SrsHttpServer : public ISrsReloadHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsGoHttpServeMux mux;
|
SrsHttpServeMux mux;
|
||||||
// the flv live streaming template.
|
// the flv live streaming template, to create streams.
|
||||||
std::map<std::string, SrsLiveEntry*> flvs;
|
std::map<std::string, SrsLiveEntry*> tflvs;
|
||||||
// the hls live streaming template.
|
// the flv live streaming streams, crote by template.
|
||||||
std::map<std::string, SrsHlsEntry*> hls;
|
std::map<std::string, SrsLiveEntry*> sflvs;
|
||||||
|
// the hls live streaming template, to create streams.
|
||||||
|
std::map<std::string, SrsHlsEntry*> thls;
|
||||||
|
// the hls live streaming streams, crote by template.
|
||||||
|
std::map<std::string, SrsHlsEntry*> shls;
|
||||||
public:
|
public:
|
||||||
SrsHttpServer();
|
SrsHttpServer();
|
||||||
virtual ~SrsHttpServer();
|
virtual ~SrsHttpServer();
|
||||||
|
@ -353,16 +360,16 @@ private:
|
||||||
public:
|
public:
|
||||||
SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m);
|
SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m);
|
||||||
virtual ~SrsHttpConn();
|
virtual ~SrsHttpConn();
|
||||||
public:
|
|
||||||
virtual void kbps_resample();
|
|
||||||
// interface IKbpsDelta
|
// interface IKbpsDelta
|
||||||
public:
|
public:
|
||||||
|
virtual void resample();
|
||||||
virtual int64_t get_send_bytes_delta();
|
virtual int64_t get_send_bytes_delta();
|
||||||
virtual int64_t get_recv_bytes_delta();
|
virtual int64_t get_recv_bytes_delta();
|
||||||
|
virtual void cleanup();
|
||||||
protected:
|
protected:
|
||||||
virtual int do_cycle();
|
virtual int do_cycle();
|
||||||
private:
|
private:
|
||||||
virtual int process_request(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
|
virtual int process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
#include <srs_app_json.hpp>
|
#include <srs_app_json.hpp>
|
||||||
#include <srs_app_dvr.hpp>
|
#include <srs_app_dvr.hpp>
|
||||||
#include <srs_app_http_client.hpp>
|
#include <srs_app_http_client.hpp>
|
||||||
|
#include <srs_core_autofree.hpp>
|
||||||
|
|
||||||
#define SRS_HTTP_RESPONSE_OK __SRS_XSTR(ERROR_SUCCESS)
|
#define SRS_HTTP_RESPONSE_OK __SRS_XSTR(ERROR_SUCCESS)
|
||||||
|
|
||||||
|
@ -53,13 +54,6 @@ int SrsHttpHooks::on_connect(string url, int client_id, string ip, SrsRequest* r
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http uri parse on_connect url failed. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_connect") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_connect") << __SRS_JFIELD_CONT
|
||||||
|
@ -70,31 +64,14 @@ int SrsHttpHooks::on_connect(string url, int client_id, string ip, SrsRequest* r
|
||||||
<< __SRS_JFIELD_STR("tcUrl", req->tcUrl) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("tcUrl", req->tcUrl) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("pageUrl", req->pageUrl)
|
<< __SRS_JFIELD_STR("pageUrl", req->pageUrl)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http post on_connect uri failed. "
|
srs_error("http post on_connect uri failed. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_connect status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_error("http hook on_connect validate failed. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,13 +86,6 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http uri parse on_close url failed, ignored. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_close") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_close") << __SRS_JFIELD_CONT
|
||||||
|
@ -124,31 +94,14 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re
|
||||||
<< __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("app", req->app)
|
<< __SRS_JFIELD_STR("app", req->app)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http post on_close uri failed, ignored. "
|
srs_warn("http post on_close uri failed, ignored. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_close status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_warn("http hook on_close validate failed, ignored. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,13 +116,6 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http uri parse on_publish url failed. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_publish") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_publish") << __SRS_JFIELD_CONT
|
||||||
|
@ -179,31 +125,14 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r
|
||||||
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("stream", req->stream)
|
<< __SRS_JFIELD_STR("stream", req->stream)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http post on_publish uri failed. "
|
srs_error("http post on_publish uri failed. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_publish status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_error("http hook on_publish validate failed. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,13 +147,6 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http uri parse on_unpublish url failed, ignored. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_unpublish") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_unpublish") << __SRS_JFIELD_CONT
|
||||||
|
@ -234,31 +156,14 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest
|
||||||
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("stream", req->stream)
|
<< __SRS_JFIELD_STR("stream", req->stream)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http post on_unpublish uri failed, ignored. "
|
srs_warn("http post on_unpublish uri failed, ignored. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_unpublish status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_warn("http hook on_unpublish validate failed, ignored. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,13 +178,6 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http uri parse on_play url failed. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_play") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_play") << __SRS_JFIELD_CONT
|
||||||
|
@ -289,31 +187,14 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req)
|
||||||
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("stream", req->stream)
|
<< __SRS_JFIELD_STR("stream", req->stream)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http post on_play uri failed. "
|
srs_error("http post on_play uri failed. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_play status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_error("http hook on_play validate failed. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,13 +209,6 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http uri parse on_stop url failed, ignored. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_stop") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_stop") << __SRS_JFIELD_CONT
|
||||||
|
@ -344,31 +218,14 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req
|
||||||
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("stream", req->stream)
|
<< __SRS_JFIELD_STR("stream", req->stream)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_warn("http post on_stop uri failed, ignored. "
|
srs_warn("http post on_stop uri failed, ignored. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_stop status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_warn("http hook on_stop validate failed, ignored. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,13 +240,6 @@ int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req,
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http uri parse on_dvr url failed, ignored. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_dvr") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_dvr") << __SRS_JFIELD_CONT
|
||||||
|
@ -401,31 +251,14 @@ int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req,
|
||||||
<< __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("file", file)
|
<< __SRS_JFIELD_STR("file", file)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http post on_dvr uri failed, ignored. "
|
srs_error("http post on_dvr uri failed, ignored. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_dvr status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_warn("http hook on_dvr validate failed, ignored. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,13 +273,6 @@ int SrsHttpHooks::on_dvr_reap_segment(string url, int client_id, SrsRequest* req
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
SrsHttpUri uri;
|
|
||||||
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http uri parse on_dvr_reap_segment url failed, ignored. "
|
|
||||||
"client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_STR("action", "on_dvr_reap_segment") << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("action", "on_dvr_reap_segment") << __SRS_JFIELD_CONT
|
||||||
|
@ -457,31 +283,14 @@ int SrsHttpHooks::on_dvr_reap_segment(string url, int client_id, SrsRequest* req
|
||||||
<< __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("file", file)
|
<< __SRS_JFIELD_STR("file", file)
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
|
|
||||||
std::string data = ss.str();
|
std::string data = ss.str();
|
||||||
std::string res;
|
std::string res;
|
||||||
int status_code;
|
int status_code;
|
||||||
|
if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
|
||||||
SrsHttpClient http;
|
|
||||||
if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) {
|
|
||||||
srs_error("http post on_dvr_reap_segment uri failed, ignored. "
|
srs_error("http post on_dvr_reap_segment uri failed, ignored. "
|
||||||
"client_id=%d, url=%s, request=%s, response=%s, ret=%d",
|
"client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||||
client_id, url.c_str(), data.c_str(), res.c_str(), ret);
|
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure the http status is ok.
|
|
||||||
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
|
||||||
if (status_code != SRS_CONSTS_HTTP_OK) {
|
|
||||||
ret = ERROR_HTTP_STATUS_INVLIAD;
|
|
||||||
srs_error("http hook on_dvr_reap_segment status failed. "
|
|
||||||
"client_id=%d, code=%d, ret=%d", client_id, status_code, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
|
||||||
ret = ERROR_HTTP_DATA_INVLIAD;
|
|
||||||
srs_warn("http hook on_dvr_reap_segment validate failed, ignored. "
|
|
||||||
"client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,4 +301,44 @@ int SrsHttpHooks::on_dvr_reap_segment(string url, int client_id, SrsRequest* req
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsHttpHooks::do_post(std::string url, std::string req, int& code, string& res)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsHttpUri uri;
|
||||||
|
if ((ret = uri.initialize(url)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("http: post failed. url=%s, ret=%d", url.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpClient http;
|
||||||
|
if ((ret = http.initialize(uri.get_host(), uri.get_port())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsHttpMessage* msg = NULL;
|
||||||
|
if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
SrsAutoFree(SrsHttpMessage, msg);
|
||||||
|
|
||||||
|
code = msg->status_code();
|
||||||
|
if ((ret = msg->body_read_all(res)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure the http status is ok.
|
||||||
|
// https://github.com/winlinvip/simple-rtmp-server/issues/158
|
||||||
|
if (code != SRS_CONSTS_HTTP_OK) {
|
||||||
|
return ERROR_HTTP_STATUS_INVLIAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: FIXME: parse json.
|
||||||
|
if (res.empty() || res != SRS_HTTP_RESPONSE_OK) {
|
||||||
|
return ERROR_HTTP_DATA_INVLIAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -113,6 +113,8 @@ public:
|
||||||
* @param file the file path, can be relative or absolute path.
|
* @param file the file path, can be relative or absolute path.
|
||||||
*/
|
*/
|
||||||
static int on_dvr_reap_segment(std::string url, int client_id, SrsRequest* req, std::string cwd, std::string file);
|
static int on_dvr_reap_segment(std::string url, int client_id, SrsRequest* req, std::string cwd, std::string file);
|
||||||
|
private:
|
||||||
|
static int do_post(std::string url, std::string req, int& code, std::string& res);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -217,6 +217,7 @@ that is:
|
||||||
#define __SRS_JFIELD_STR(k, v) "\"" << k << "\":\"" << v << "\""
|
#define __SRS_JFIELD_STR(k, v) "\"" << k << "\":\"" << v << "\""
|
||||||
#define __SRS_JFIELD_ORG(k, v) "\"" << k << "\":" << std::dec << v
|
#define __SRS_JFIELD_ORG(k, v) "\"" << k << "\":" << std::dec << v
|
||||||
#define __SRS_JFIELD_BOOL(k, v) __SRS_JFIELD_ORG(k, (v? "true":"false"))
|
#define __SRS_JFIELD_BOOL(k, v) __SRS_JFIELD_ORG(k, (v? "true":"false"))
|
||||||
|
#define __SRS_JFIELD_NULL(k) "\"" << k << "\":null"
|
||||||
#define __SRS_JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
|
#define __SRS_JFIELD_ERROR(ret) "\"" << "code" << "\":" << ret
|
||||||
#define __SRS_JFIELD_CONT ","
|
#define __SRS_JFIELD_CONT ","
|
||||||
#define __SRS_JOBJECT_END "}"
|
#define __SRS_JOBJECT_END "}"
|
||||||
|
|
|
@ -203,20 +203,29 @@ int64_t SrsKbps::get_recv_bytes()
|
||||||
return is.get_total_bytes();
|
return is.get_total_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsKbps::resample()
|
||||||
|
{
|
||||||
|
sample();
|
||||||
|
}
|
||||||
|
|
||||||
int64_t SrsKbps::get_send_bytes_delta()
|
int64_t SrsKbps::get_send_bytes_delta()
|
||||||
{
|
{
|
||||||
int64_t delta = os.get_total_bytes() - os.delta_bytes;
|
int64_t delta = os.get_total_bytes() - os.delta_bytes;
|
||||||
os.delta_bytes = os.get_total_bytes();
|
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsKbps::get_recv_bytes_delta()
|
int64_t SrsKbps::get_recv_bytes_delta()
|
||||||
{
|
{
|
||||||
int64_t delta = is.get_total_bytes() - is.delta_bytes;
|
int64_t delta = is.get_total_bytes() - is.delta_bytes;
|
||||||
is.delta_bytes = is.get_total_bytes();
|
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsKbps::cleanup()
|
||||||
|
{
|
||||||
|
os.delta_bytes = os.get_total_bytes();
|
||||||
|
is.delta_bytes = is.get_total_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
void SrsKbps::add_delta(IKbpsDelta* delta)
|
void SrsKbps::add_delta(IKbpsDelta* delta)
|
||||||
{
|
{
|
||||||
srs_assert(delta);
|
srs_assert(delta);
|
||||||
|
|
|
@ -107,6 +107,11 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the interface which provices delta of bytes.
|
* the interface which provices delta of bytes.
|
||||||
|
* for a delta, for example, a live stream connection, we can got the delta by:
|
||||||
|
* IKbpsDelta* delta = ...;
|
||||||
|
* delta->resample();
|
||||||
|
* kbps->add_delta(delta);
|
||||||
|
* delta->cleanup();
|
||||||
*/
|
*/
|
||||||
class IKbpsDelta
|
class IKbpsDelta
|
||||||
{
|
{
|
||||||
|
@ -114,25 +119,41 @@ public:
|
||||||
IKbpsDelta();
|
IKbpsDelta();
|
||||||
virtual ~IKbpsDelta();
|
virtual ~IKbpsDelta();
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* resample to generate the value of delta bytes.
|
||||||
|
*/
|
||||||
|
virtual void resample() = 0;
|
||||||
|
/**
|
||||||
|
* get the send or recv bytes delta.
|
||||||
|
*/
|
||||||
virtual int64_t get_send_bytes_delta() = 0;
|
virtual int64_t get_send_bytes_delta() = 0;
|
||||||
virtual int64_t get_recv_bytes_delta() = 0;
|
virtual int64_t get_recv_bytes_delta() = 0;
|
||||||
|
/**
|
||||||
|
* cleanup the value of delta bytes.
|
||||||
|
*/
|
||||||
|
virtual void cleanup() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* to statistic the kbps of io.
|
* to statistic the kbps of io.
|
||||||
* itself can be a statistic source, for example, used for SRS bytes stat.
|
* itself can be a statistic source, for example, used for SRS bytes stat.
|
||||||
* there are two usage scenarios:
|
* there are two usage scenarios:
|
||||||
* 1. connections to calc kbps:
|
* 1. connections to calc kbps by sample():
|
||||||
* set_io(in, out)
|
* SrsKbps* kbps = ...;
|
||||||
* sample()
|
* kbps->set_io(in, out)
|
||||||
* get_xxx_kbps().
|
* kbps->sample()
|
||||||
|
* kbps->get_xxx_kbps().
|
||||||
* the connections know how many bytes already send/recv.
|
* the connections know how many bytes already send/recv.
|
||||||
* 2. server to calc kbps:
|
* 2. server to calc kbps by add_delta():
|
||||||
* set_io(NULL, NULL)
|
* SrsKbps* kbps = ...;
|
||||||
|
* kbps->set_io(NULL, NULL)
|
||||||
* for each connection in connections:
|
* for each connection in connections:
|
||||||
* add_delta(connections) // where connection is a IKbpsDelta*
|
* IKbpsDelta* delta = connection; // where connection implements IKbpsDelta
|
||||||
* sample()
|
* delta->resample()
|
||||||
* get_xxx_kbps().
|
* kbps->add_delta(delta)
|
||||||
|
* delta->cleanup()
|
||||||
|
* kbps->sample()
|
||||||
|
* kbps->get_xxx_kbps().
|
||||||
* the server never know how many bytes already send/recv, for the connection maybe closed.
|
* the server never know how many bytes already send/recv, for the connection maybe closed.
|
||||||
*/
|
*/
|
||||||
class SrsKbps : public virtual ISrsProtocolStatistic, public virtual IKbpsDelta
|
class SrsKbps : public virtual ISrsProtocolStatistic, public virtual IKbpsDelta
|
||||||
|
@ -174,18 +195,26 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int64_t get_send_bytes();
|
virtual int64_t get_send_bytes();
|
||||||
virtual int64_t get_recv_bytes();
|
virtual int64_t get_recv_bytes();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* resample to get the delta.
|
||||||
|
*/
|
||||||
|
virtual void resample();
|
||||||
/**
|
/**
|
||||||
* get the delta of send/recv bytes.
|
* get the delta of send/recv bytes.
|
||||||
* @remark, used for add_delta to calc the total system bytes/kbps.
|
|
||||||
*/
|
*/
|
||||||
virtual int64_t get_send_bytes_delta();
|
virtual int64_t get_send_bytes_delta();
|
||||||
virtual int64_t get_recv_bytes_delta();
|
virtual int64_t get_recv_bytes_delta();
|
||||||
|
/**
|
||||||
|
* cleanup the delta.
|
||||||
|
*/
|
||||||
|
virtual void cleanup();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* add delta to kbps clac mechenism.
|
* add delta to kbps clac mechenism.
|
||||||
* we donot know the total bytes, but know the delta, for instance,
|
* we donot know the total bytes, but know the delta, for instance,
|
||||||
* for rtmp server to calc total bytes and kbps.
|
* for rtmp server to calc total bytes and kbps.
|
||||||
* @remark user must invoke sample() when invoke this method.
|
* @remark user must invoke sample() to calc result after invoke this method.
|
||||||
* @param delta, assert should never be NULL.
|
* @param delta, assert should never be NULL.
|
||||||
*/
|
*/
|
||||||
virtual void add_delta(IKbpsDelta* delta);
|
virtual void add_delta(IKbpsDelta* delta);
|
||||||
|
|
|
@ -130,11 +130,13 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c)
|
||||||
context = new SrsTsContext();
|
context = new SrsTsContext();
|
||||||
buffer = new SrsSimpleBuffer();
|
buffer = new SrsSimpleBuffer();
|
||||||
output = _srs_config->get_stream_caster_output(c);
|
output = _srs_config->get_stream_caster_output(c);
|
||||||
|
|
||||||
req = NULL;
|
req = NULL;
|
||||||
io = NULL;
|
io = NULL;
|
||||||
client = NULL;
|
client = NULL;
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
stream_id = 0;
|
stream_id = 0;
|
||||||
|
|
||||||
avc = new SrsRawH264Stream();
|
avc = new SrsRawH264Stream();
|
||||||
aac = new SrsRawAacStream();
|
aac = new SrsRawAacStream();
|
||||||
h264_sps_changed = false;
|
h264_sps_changed = false;
|
||||||
|
@ -159,8 +161,6 @@ SrsMpegtsOverUdp::~SrsMpegtsOverUdp()
|
||||||
|
|
||||||
int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
std::string peer_ip = inet_ntoa(from->sin_addr);
|
std::string peer_ip = inet_ntoa(from->sin_addr);
|
||||||
int peer_port = ntohs(from->sin_port);
|
int peer_port = ntohs(from->sin_port);
|
||||||
|
|
||||||
|
@ -169,6 +169,13 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
||||||
|
|
||||||
srs_info("udp: got %s:%d packet %d/%d bytes",
|
srs_info("udp: got %s:%d packet %d/%d bytes",
|
||||||
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
|
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
|
||||||
|
|
||||||
|
return on_udp_bytes(peer_ip, peer_port, buf, nb_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// collect nMB data to parse in a time.
|
// collect nMB data to parse in a time.
|
||||||
// TODO: FIXME: comment the following for release.
|
// TODO: FIXME: comment the following for release.
|
||||||
|
@ -215,8 +222,7 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
||||||
|
|
||||||
// drop ts packet when size not modulus by 188
|
// drop ts packet when size not modulus by 188
|
||||||
if (buffer->length() < SRS_TS_PACKET_SIZE) {
|
if (buffer->length() < SRS_TS_PACKET_SIZE) {
|
||||||
srs_warn("udp: wait %s:%d packet %d/%d bytes",
|
srs_warn("udp: wait %s:%d packet %d/%d bytes", host.c_str(), port, nb_buf, buffer->length());
|
||||||
peer_ip.c_str(), peer_port, nb_buf, buffer->length());
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,6 +588,7 @@ int SrsMpegtsOverUdp::connect()
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// when ok, ignore.
|
// when ok, ignore.
|
||||||
|
// TODO: FIXME: should reconnect when disconnected.
|
||||||
if (io || client) {
|
if (io || client) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,6 +109,8 @@ public:
|
||||||
// interface ISrsUdpHandler
|
// interface ISrsUdpHandler
|
||||||
public:
|
public:
|
||||||
virtual int on_udp_packet(sockaddr_in* from, char* buf, int nb_buf);
|
virtual int on_udp_packet(sockaddr_in* from, char* buf, int nb_buf);
|
||||||
|
private:
|
||||||
|
virtual int on_udp_bytes(std::string host, int port, char* buf, int nb_buf);
|
||||||
// interface ISrsTsHandler
|
// interface ISrsTsHandler
|
||||||
public:
|
public:
|
||||||
virtual int on_ts_message(SrsTsMessage* msg);
|
virtual int on_ts_message(SrsTsMessage* msg);
|
||||||
|
|
|
@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -109,11 +110,6 @@ SrsRtmpConn::~SrsRtmpConn()
|
||||||
srs_freep(kbps);
|
srs_freep(kbps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsRtmpConn::kbps_resample()
|
|
||||||
{
|
|
||||||
kbps->sample();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: return detail message when error for client.
|
// TODO: return detail message when error for client.
|
||||||
int SrsRtmpConn::do_cycle()
|
int SrsRtmpConn::do_cycle()
|
||||||
{
|
{
|
||||||
|
@ -201,7 +197,7 @@ int SrsRtmpConn::do_cycle()
|
||||||
ret = service_cycle();
|
ret = service_cycle();
|
||||||
http_hooks_on_close();
|
http_hooks_on_close();
|
||||||
SrsStatistic* stat = SrsStatistic::instance();
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
stat->on_close(_srs_context->get_id());
|
stat->on_disconnect(_srs_context->get_id());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -254,6 +250,11 @@ int SrsRtmpConn::on_reload_vhost_realtime(string vhost)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsRtmpConn::resample()
|
||||||
|
{
|
||||||
|
kbps->resample();
|
||||||
|
}
|
||||||
|
|
||||||
int64_t SrsRtmpConn::get_send_bytes_delta()
|
int64_t SrsRtmpConn::get_send_bytes_delta()
|
||||||
{
|
{
|
||||||
return kbps->get_send_bytes_delta();
|
return kbps->get_send_bytes_delta();
|
||||||
|
@ -263,6 +264,11 @@ int64_t SrsRtmpConn::get_recv_bytes_delta()
|
||||||
{
|
{
|
||||||
return kbps->get_recv_bytes_delta();
|
return kbps->get_recv_bytes_delta();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsRtmpConn::cleanup()
|
||||||
|
{
|
||||||
|
kbps->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
int SrsRtmpConn::service_cycle()
|
int SrsRtmpConn::service_cycle()
|
||||||
{
|
{
|
||||||
|
@ -392,9 +398,11 @@ int SrsRtmpConn::stream_service_cycle()
|
||||||
bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost);
|
bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost);
|
||||||
|
|
||||||
// find a source to serve.
|
// find a source to serve.
|
||||||
SrsSource* source = NULL;
|
SrsSource* source = SrsSource::fetch(req);
|
||||||
if ((ret = SrsSource::find(req, server, server, &source)) != ERROR_SUCCESS) {
|
if (!source) {
|
||||||
return ret;
|
if ((ret = SrsSource::create(req, server, server, &source)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
srs_assert(source != NULL);
|
srs_assert(source != NULL);
|
||||||
|
|
||||||
|
@ -622,6 +630,9 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe
|
||||||
mw_enabled = true;
|
mw_enabled = true;
|
||||||
change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
|
change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
|
||||||
|
|
||||||
|
// set the sock options.
|
||||||
|
play_set_sock_options();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// collect elapse for pithy print.
|
// collect elapse for pithy print.
|
||||||
pprint->elapse();
|
pprint->elapse();
|
||||||
|
@ -1087,7 +1098,7 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms)
|
||||||
socklen_t sock_buf_size = sizeof(int);
|
socklen_t sock_buf_size = sizeof(int);
|
||||||
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &onb_sbuf, &sock_buf_size);
|
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &onb_sbuf, &sock_buf_size);
|
||||||
|
|
||||||
#ifdef SRS_PERF_MW_SO_SNDBUF
|
#ifdef SRS_PERF_MW_SO_SNDBUF
|
||||||
// the bytes:
|
// the bytes:
|
||||||
// 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
|
// 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
|
||||||
// 128KB=131072, 256KB=262144, 512KB=524288
|
// 128KB=131072, 256KB=262144, 512KB=524288
|
||||||
|
@ -1104,6 +1115,11 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms)
|
||||||
// socket send buffer, system will double it.
|
// socket send buffer, system will double it.
|
||||||
int nb_sbuf = socket_buffer_size / 2;
|
int nb_sbuf = socket_buffer_size / 2;
|
||||||
|
|
||||||
|
// override the send buffer by macro.
|
||||||
|
#ifdef SRS_PERF_SO_SNDBUF_SIZE
|
||||||
|
nb_sbuf = SRS_PERF_SO_SNDBUF_SIZE / 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
// set the socket send buffer when required larger buffer
|
// set the socket send buffer when required larger buffer
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, sock_buf_size) < 0) {
|
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, sock_buf_size) < 0) {
|
||||||
srs_warn("set sock SO_SENDBUF=%d failed.", nb_sbuf);
|
srs_warn("set sock SO_SENDBUF=%d failed.", nb_sbuf);
|
||||||
|
@ -1121,6 +1137,29 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms)
|
||||||
mw_sleep = sleep_ms;
|
mw_sleep = sleep_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsRtmpConn::play_set_sock_options()
|
||||||
|
{
|
||||||
|
#ifdef SRS_PERF_TCP_NODELAY
|
||||||
|
if (true) {
|
||||||
|
int fd = st_netfd_fileno(stfd);
|
||||||
|
|
||||||
|
socklen_t nb_v = sizeof(int);
|
||||||
|
|
||||||
|
int ov = 0;
|
||||||
|
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &ov, &nb_v);
|
||||||
|
|
||||||
|
int v = 1;
|
||||||
|
// set the socket send buffer when required larger buffer
|
||||||
|
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, nb_v) < 0) {
|
||||||
|
srs_warn("set sock TCP_NODELAY=%d failed.", v);
|
||||||
|
}
|
||||||
|
getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, &nb_v);
|
||||||
|
|
||||||
|
srs_trace("set TCP_NODELAY %d=>%d", ov, v);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int SrsRtmpConn::check_edge_token_traverse_auth()
|
int SrsRtmpConn::check_edge_token_traverse_auth()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
|
@ -83,8 +83,6 @@ private:
|
||||||
public:
|
public:
|
||||||
SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
|
SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
|
||||||
virtual ~SrsRtmpConn();
|
virtual ~SrsRtmpConn();
|
||||||
public:
|
|
||||||
virtual void kbps_resample();
|
|
||||||
protected:
|
protected:
|
||||||
virtual int do_cycle();
|
virtual int do_cycle();
|
||||||
// interface ISrsReloadHandler
|
// interface ISrsReloadHandler
|
||||||
|
@ -94,8 +92,10 @@ public:
|
||||||
virtual int on_reload_vhost_realtime(std::string vhost);
|
virtual int on_reload_vhost_realtime(std::string vhost);
|
||||||
// interface IKbpsDelta
|
// interface IKbpsDelta
|
||||||
public:
|
public:
|
||||||
|
virtual void resample();
|
||||||
virtual int64_t get_send_bytes_delta();
|
virtual int64_t get_send_bytes_delta();
|
||||||
virtual int64_t get_recv_bytes_delta();
|
virtual int64_t get_recv_bytes_delta();
|
||||||
|
virtual void cleanup();
|
||||||
private:
|
private:
|
||||||
// when valid and connected to vhost/app, service the client.
|
// when valid and connected to vhost/app, service the client.
|
||||||
virtual int service_cycle();
|
virtual int service_cycle();
|
||||||
|
@ -111,6 +111,7 @@ private:
|
||||||
virtual int process_publish_message(SrsSource* source, SrsCommonMessage* msg, bool vhost_is_edge);
|
virtual int process_publish_message(SrsSource* source, SrsCommonMessage* msg, bool vhost_is_edge);
|
||||||
virtual int process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg);
|
virtual int process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg);
|
||||||
virtual void change_mw_sleep(int sleep_ms);
|
virtual void change_mw_sleep(int sleep_ms);
|
||||||
|
virtual void play_set_sock_options();
|
||||||
private:
|
private:
|
||||||
virtual int check_edge_token_traverse_auth();
|
virtual int check_edge_token_traverse_auth();
|
||||||
virtual int connect_server(int origin_index, st_netfd_t* pstsock);
|
virtual int connect_server(int origin_index, st_netfd_t* pstsock);
|
||||||
|
|
|
@ -131,7 +131,7 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf)
|
||||||
|
|
||||||
SrsRtspAudioCache::SrsRtspAudioCache()
|
SrsRtspAudioCache::SrsRtspAudioCache()
|
||||||
{
|
{
|
||||||
dts = NULL;
|
dts = 0;
|
||||||
audio_samples = NULL;
|
audio_samples = NULL;
|
||||||
payload = NULL;
|
payload = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ using namespace std;
|
||||||
#include <srs_app_heartbeat.hpp>
|
#include <srs_app_heartbeat.hpp>
|
||||||
#include <srs_app_mpegts_udp.hpp>
|
#include <srs_app_mpegts_udp.hpp>
|
||||||
#include <srs_app_rtsp.hpp>
|
#include <srs_app_rtsp.hpp>
|
||||||
|
#include <srs_app_statistic.hpp>
|
||||||
|
|
||||||
// signal defines.
|
// signal defines.
|
||||||
#define SIGNAL_RELOAD SIGHUP
|
#define SIGNAL_RELOAD SIGHUP
|
||||||
|
@ -392,13 +393,12 @@ SrsServer::SrsServer()
|
||||||
pid_fd = -1;
|
pid_fd = -1;
|
||||||
|
|
||||||
signal_manager = NULL;
|
signal_manager = NULL;
|
||||||
kbps = NULL;
|
|
||||||
|
|
||||||
// donot new object in constructor,
|
// donot new object in constructor,
|
||||||
// for some global instance is not ready now,
|
// for some global instance is not ready now,
|
||||||
// new these objects in initialize instead.
|
// new these objects in initialize instead.
|
||||||
#ifdef SRS_AUTO_HTTP_API
|
#ifdef SRS_AUTO_HTTP_API
|
||||||
http_api_mux = new SrsGoHttpServeMux();
|
http_api_mux = new SrsHttpServeMux();
|
||||||
#endif
|
#endif
|
||||||
#ifdef SRS_AUTO_HTTP_SERVER
|
#ifdef SRS_AUTO_HTTP_SERVER
|
||||||
http_stream_mux = new SrsHttpServer();
|
http_stream_mux = new SrsHttpServer();
|
||||||
|
@ -452,7 +452,6 @@ void SrsServer::destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_freep(signal_manager);
|
srs_freep(signal_manager);
|
||||||
srs_freep(kbps);
|
|
||||||
|
|
||||||
// @remark never destroy the connections,
|
// @remark never destroy the connections,
|
||||||
// for it's still alive.
|
// for it's still alive.
|
||||||
|
@ -478,61 +477,11 @@ int SrsServer::initialize()
|
||||||
srs_assert(!signal_manager);
|
srs_assert(!signal_manager);
|
||||||
signal_manager = new SrsSignalManager(this);
|
signal_manager = new SrsSignalManager(this);
|
||||||
|
|
||||||
srs_assert(!kbps);
|
|
||||||
kbps = new SrsKbps();
|
|
||||||
kbps->set_io(NULL, NULL);
|
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HTTP_API
|
#ifdef SRS_AUTO_HTTP_API
|
||||||
if ((ret = http_api_mux->initialize()) != ERROR_SUCCESS) {
|
if ((ret = http_api_mux->initialize()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HTTP_API
|
|
||||||
srs_assert(http_api_mux);
|
|
||||||
if ((ret = http_api_mux->handle("/", new SrsGoApiRoot())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api", new SrsGoApiApi())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1", new SrsGoApiV1())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/summaries", new SrsGoApiSummaries())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/rusages", new SrsGoApiRusages())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/self_proc_stats", new SrsGoApiSelfProcStats())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/system_proc_stats", new SrsGoApiSystemProcStats())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/meminfos", new SrsGoApiMemInfos())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/streams", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if ((ret = http_api_mux->handle("/api/v1/dvrs", new SrsGoApiDvrs())) != ERROR_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HTTP_SERVER
|
#ifdef SRS_AUTO_HTTP_SERVER
|
||||||
srs_assert(http_stream_mux);
|
srs_assert(http_stream_mux);
|
||||||
|
@ -692,6 +641,56 @@ int SrsServer::register_signal()
|
||||||
return signal_manager->start();
|
return signal_manager->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsServer::http_handle()
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
#ifdef SRS_AUTO_HTTP_API
|
||||||
|
srs_assert(http_api_mux);
|
||||||
|
if ((ret = http_api_mux->handle("/", new SrsGoApiRoot())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api", new SrsGoApiApi())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1", new SrsGoApiV1())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/summaries", new SrsGoApiSummaries())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/rusages", new SrsGoApiRusages())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/self_proc_stats", new SrsGoApiSelfProcStats())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/system_proc_stats", new SrsGoApiSystemProcStats())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/meminfos", new SrsGoApiMemInfos())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if ((ret = http_api_mux->handle("/api/v1/streams", new SrsGoApiStreams())) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsServer::ingest()
|
int SrsServer::ingest()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
@ -741,8 +740,8 @@ void SrsServer::remove(SrsConnection* conn)
|
||||||
|
|
||||||
srs_info("conn removed. conns=%d", (int)conns.size());
|
srs_info("conn removed. conns=%d", (int)conns.size());
|
||||||
|
|
||||||
// resample the resource of specified connection.
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
resample_kbps(conn);
|
stat->kbps_add_delta(conn);
|
||||||
|
|
||||||
// all connections are created by server,
|
// all connections are created by server,
|
||||||
// so we free it here.
|
// so we free it here.
|
||||||
|
@ -858,9 +857,8 @@ int SrsServer::do_cycle()
|
||||||
srs_update_network_devices();
|
srs_update_network_devices();
|
||||||
}
|
}
|
||||||
if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
|
if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
|
||||||
srs_info("update network rtmp server info.");
|
srs_info("update network server kbps info.");
|
||||||
resample_kbps(NULL);
|
resample_kbps();
|
||||||
srs_update_rtmp_server((int)conns.size(), kbps);
|
|
||||||
}
|
}
|
||||||
#ifdef SRS_AUTO_HTTP_PARSER
|
#ifdef SRS_AUTO_HTTP_PARSER
|
||||||
if (_srs_config->get_heartbeat_enabled()) {
|
if (_srs_config->get_heartbeat_enabled()) {
|
||||||
|
@ -1009,31 +1007,25 @@ void SrsServer::close_listeners(SrsListenerType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsServer::resample_kbps(SrsConnection* conn, bool do_resample)
|
void SrsServer::resample_kbps()
|
||||||
{
|
{
|
||||||
// resample all when conn is NULL.
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
if (!conn) {
|
|
||||||
for (std::vector<SrsConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) {
|
// collect delta from all clients.
|
||||||
SrsConnection* client = *it;
|
for (std::vector<SrsConnection*>::iterator it = conns.begin(); it != conns.end(); ++it) {
|
||||||
srs_assert(client);
|
SrsConnection* conn = *it;
|
||||||
|
|
||||||
// only resample, do resample when all finished.
|
|
||||||
resample_kbps(client, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
kbps->sample();
|
// add delta of connection to server kbps.,
|
||||||
return;
|
// for next sample() of server kbps can get the stat.
|
||||||
|
stat->kbps_add_delta(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// resample for connection.
|
// TODO: FXME: support all other connections.
|
||||||
conn->kbps_resample();
|
|
||||||
|
// sample the kbps, get the stat.
|
||||||
|
SrsKbps* kbps = stat->kbps_sample();
|
||||||
|
|
||||||
kbps->add_delta(conn);
|
srs_update_rtmp_server((int)conns.size(), kbps);
|
||||||
|
|
||||||
// resample for server.
|
|
||||||
if (do_resample) {
|
|
||||||
kbps->sample();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
|
||||||
|
|
|
@ -41,7 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
class SrsServer;
|
class SrsServer;
|
||||||
class SrsConnection;
|
class SrsConnection;
|
||||||
class SrsGoHttpServeMux;
|
class SrsHttpServeMux;
|
||||||
class SrsHttpServer;
|
class SrsHttpServer;
|
||||||
class SrsIngester;
|
class SrsIngester;
|
||||||
class SrsHttpHeartbeat;
|
class SrsHttpHeartbeat;
|
||||||
|
@ -178,7 +178,7 @@ class SrsServer : virtual public ISrsReloadHandler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
#ifdef SRS_AUTO_HTTP_API
|
#ifdef SRS_AUTO_HTTP_API
|
||||||
SrsGoHttpServeMux* http_api_mux;
|
SrsHttpServeMux* http_api_mux;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SRS_AUTO_HTTP_SERVER
|
#ifdef SRS_AUTO_HTTP_SERVER
|
||||||
SrsHttpServer* http_stream_mux;
|
SrsHttpServer* http_stream_mux;
|
||||||
|
@ -210,10 +210,6 @@ private:
|
||||||
*/
|
*/
|
||||||
SrsSignalManager* signal_manager;
|
SrsSignalManager* signal_manager;
|
||||||
/**
|
/**
|
||||||
* server total kbps.
|
|
||||||
*/
|
|
||||||
SrsKbps* kbps;
|
|
||||||
/**
|
|
||||||
* user send the signal, convert to variable.
|
* user send the signal, convert to variable.
|
||||||
*/
|
*/
|
||||||
bool signal_reload;
|
bool signal_reload;
|
||||||
|
@ -236,6 +232,7 @@ public:
|
||||||
virtual int initialize_st();
|
virtual int initialize_st();
|
||||||
virtual int listen();
|
virtual int listen();
|
||||||
virtual int register_signal();
|
virtual int register_signal();
|
||||||
|
virtual int http_handle();
|
||||||
virtual int ingest();
|
virtual int ingest();
|
||||||
virtual int cycle();
|
virtual int cycle();
|
||||||
// server utility
|
// server utility
|
||||||
|
@ -277,12 +274,9 @@ private:
|
||||||
*/
|
*/
|
||||||
virtual void close_listeners(SrsListenerType type);
|
virtual void close_listeners(SrsListenerType type);
|
||||||
/**
|
/**
|
||||||
* resample the server kbps.
|
* resample the server kbs.
|
||||||
* if conn is NULL, resample all connections delta, then calc the total kbps.
|
|
||||||
* @param conn, the connection to do resample the kbps. NULL to resample all connections.
|
|
||||||
* @param do_resample, whether resample the server kbps. always false when sample a connection.
|
|
||||||
*/
|
*/
|
||||||
virtual void resample_kbps(SrsConnection* conn, bool do_resample = true);
|
virtual void resample_kbps();
|
||||||
// internal only
|
// internal only
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -316,3 +310,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ using namespace std;
|
||||||
#include <srs_kernel_codec.hpp>
|
#include <srs_kernel_codec.hpp>
|
||||||
#include <srs_rtmp_msg_array.hpp>
|
#include <srs_rtmp_msg_array.hpp>
|
||||||
#include <srs_app_hds.hpp>
|
#include <srs_app_hds.hpp>
|
||||||
|
#include <srs_app_statistic.hpp>
|
||||||
|
|
||||||
#define CONST_MAX_JITTER_MS 500
|
#define CONST_MAX_JITTER_MS 500
|
||||||
#define DEFAULT_FRAME_TIME_MS 40
|
#define DEFAULT_FRAME_TIME_MS 40
|
||||||
|
@ -714,35 +715,47 @@ ISrsSourceHandler::~ISrsSourceHandler()
|
||||||
|
|
||||||
std::map<std::string, SrsSource*> SrsSource::pool;
|
std::map<std::string, SrsSource*> SrsSource::pool;
|
||||||
|
|
||||||
int SrsSource::find(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps)
|
int SrsSource::create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
string stream_url = r->get_stream_url();
|
string stream_url = r->get_stream_url();
|
||||||
string vhost = r->vhost;
|
string vhost = r->vhost;
|
||||||
|
|
||||||
if (pool.find(stream_url) == pool.end()) {
|
// should always not exists for create a source.
|
||||||
SrsSource* source = new SrsSource(hh);
|
srs_assert (pool.find(stream_url) == pool.end());
|
||||||
if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) {
|
|
||||||
srs_freep(source);
|
SrsSource* source = new SrsSource();
|
||||||
return ret;
|
if ((ret = source->initialize(r, h, hh)) != ERROR_SUCCESS) {
|
||||||
}
|
srs_freep(source);
|
||||||
|
return ret;
|
||||||
pool[stream_url] = source;
|
|
||||||
srs_info("create new source for url=%s, vhost=%s",
|
|
||||||
stream_url.c_str(), vhost.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pool[stream_url] = source;
|
||||||
|
srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str());
|
||||||
|
|
||||||
|
*pps = source;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsSource* SrsSource::fetch(SrsRequest* r)
|
||||||
|
{
|
||||||
|
SrsSource* source = NULL;
|
||||||
|
|
||||||
|
string stream_url = r->get_stream_url();
|
||||||
|
if (pool.find(stream_url) == pool.end()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
source = pool[stream_url];
|
||||||
|
|
||||||
// we always update the request of resource,
|
// we always update the request of resource,
|
||||||
// for origin auth is on, the token in request maybe invalid,
|
// for origin auth is on, the token in request maybe invalid,
|
||||||
// and we only need to update the token of request, it's simple.
|
// and we only need to update the token of request, it's simple.
|
||||||
if (true) {
|
source->_req->update_auth(r);
|
||||||
SrsSource* source = pool[stream_url];
|
|
||||||
source->_req->update_auth(r);
|
return source;
|
||||||
*pps = source;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsSource::destroy()
|
void SrsSource::destroy()
|
||||||
|
@ -755,17 +768,16 @@ void SrsSource::destroy()
|
||||||
pool.clear();
|
pool.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsSource::SrsSource(ISrsHlsHandler* hh)
|
SrsSource::SrsSource()
|
||||||
{
|
{
|
||||||
_req = NULL;
|
_req = NULL;
|
||||||
jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
|
jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
|
||||||
|
|
||||||
#ifdef SRS_AUTO_HLS
|
#ifdef SRS_AUTO_HLS
|
||||||
// TODO: FIXME: refine code, use subscriber pattern.
|
hls = new SrsHls();
|
||||||
hls = new SrsHls(this, hh);
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef SRS_AUTO_DVR
|
#ifdef SRS_AUTO_DVR
|
||||||
dvr = new SrsDvr(this);
|
dvr = new SrsDvr();
|
||||||
#endif
|
#endif
|
||||||
#ifdef SRS_AUTO_TRANSCODE
|
#ifdef SRS_AUTO_TRANSCODE
|
||||||
encoder = new SrsEncoder();
|
encoder = new SrsEncoder();
|
||||||
|
@ -827,16 +839,26 @@ SrsSource::~SrsSource()
|
||||||
srs_freep(_req);
|
srs_freep(_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h)
|
int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
srs_assert(h);
|
||||||
|
srs_assert(hh);
|
||||||
|
srs_assert(!_req);
|
||||||
|
|
||||||
handler = h;
|
handler = h;
|
||||||
_req = r->copy();
|
_req = r->copy();
|
||||||
atc = _srs_config->get_atc(_req->vhost);
|
atc = _srs_config->get_atc(_req->vhost);
|
||||||
|
|
||||||
|
#ifdef SRS_AUTO_HLS
|
||||||
|
if ((ret = hls->initialize(this, hh)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SRS_AUTO_DVR
|
#ifdef SRS_AUTO_DVR
|
||||||
if ((ret = dvr->initialize(_req)) != ERROR_SUCCESS) {
|
if ((ret = dvr->initialize(this, _req)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1000,7 +1022,7 @@ int SrsSource::on_reload_vhost_dvr(string vhost)
|
||||||
dvr->on_unpublish();
|
dvr->on_unpublish();
|
||||||
|
|
||||||
// reinitialize the dvr, update plan.
|
// reinitialize the dvr, update plan.
|
||||||
if ((ret = dvr->initialize(_req)) != ERROR_SUCCESS) {
|
if ((ret = dvr->initialize(this, _req)) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1364,6 +1386,7 @@ int SrsSource::on_audio(SrsCommonMessage* __audio)
|
||||||
|
|
||||||
// cache the sequence header of aac, or first packet of mp3.
|
// cache the sequence header of aac, or first packet of mp3.
|
||||||
// for example, the mp3 is used for hls to write the "right" audio codec.
|
// for example, the mp3 is used for hls to write the "right" audio codec.
|
||||||
|
// TODO: FIXME: to refine the stream info system.
|
||||||
bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg.payload, msg.size);
|
bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg.payload, msg.size);
|
||||||
if (is_aac_sequence_header || !cache_sh_audio) {
|
if (is_aac_sequence_header || !cache_sh_audio) {
|
||||||
srs_freep(cache_sh_audio);
|
srs_freep(cache_sh_audio);
|
||||||
|
@ -1383,11 +1406,18 @@ int SrsSource::on_audio(SrsCommonMessage* __audio)
|
||||||
|
|
||||||
static int flv_sample_sizes[] = {8, 16, 0};
|
static int flv_sample_sizes[] = {8, 16, 0};
|
||||||
static int flv_sound_types[] = {1, 2, 0};
|
static int flv_sound_types[] = {1, 2, 0};
|
||||||
|
|
||||||
|
// when got audio stream info.
|
||||||
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
|
if ((ret = stat->on_audio_info(_req, SrsCodecAudioAAC, sample.sound_rate, sample.sound_type, codec.aac_object)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
srs_trace("%dB audio sh, "
|
srs_trace("%dB audio sh, "
|
||||||
"codec(%d, profile=%d, %dchannels, %dkbps, %dHZ), "
|
"codec(%d, profile=%s, %dchannels, %dkbps, %dHZ), "
|
||||||
"flv(%dbits, %dchannels, %dHZ)",
|
"flv(%dbits, %dchannels, %dHZ)",
|
||||||
msg.size, codec.audio_codec_id,
|
msg.size, codec.audio_codec_id,
|
||||||
codec.aac_profile, codec.aac_channels,
|
srs_codec_aac_object2str(codec.aac_object).c_str(), codec.aac_channels,
|
||||||
codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate],
|
codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate],
|
||||||
flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type],
|
flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type],
|
||||||
flv_sample_rates[sample.sound_rate]);
|
flv_sample_rates[sample.sound_rate]);
|
||||||
|
@ -1515,10 +1545,17 @@ int SrsSource::on_video(SrsCommonMessage* __video)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when got video stream info.
|
||||||
|
SrsStatistic* stat = SrsStatistic::instance();
|
||||||
|
if ((ret = stat->on_video_info(_req, SrsCodecVideoAVC, codec.avc_profile, codec.avc_level)) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
srs_trace("%dB video sh, "
|
srs_trace("%dB video sh, "
|
||||||
"codec(%d, profile=%d, level=%d, %dx%d, %dkbps, %dfps, %ds)",
|
"codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %dfps, %ds)",
|
||||||
msg.size, codec.video_codec_id,
|
msg.size, codec.video_codec_id,
|
||||||
codec.avc_profile, codec.avc_level, codec.width, codec.height,
|
srs_codec_avc_profile2str(codec.avc_profile).c_str(),
|
||||||
|
srs_codec_avc_level2str(codec.avc_level).c_str(), codec.width, codec.height,
|
||||||
codec.video_data_rate / 1000, codec.frame_rate, codec.duration);
|
codec.video_data_rate / 1000, codec.frame_rate, codec.duration);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,12 @@ public:
|
||||||
* @param hh the event handler for hls.
|
* @param hh the event handler for hls.
|
||||||
* @param pps the matched source, if success never be NULL.
|
* @param pps the matched source, if success never be NULL.
|
||||||
*/
|
*/
|
||||||
static int find(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps);
|
static int create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps);
|
||||||
|
/**
|
||||||
|
* get the exists source, NULL when not exists.
|
||||||
|
* update the request and return the exists source.
|
||||||
|
*/
|
||||||
|
static SrsSource* fetch(SrsRequest* r);
|
||||||
/**
|
/**
|
||||||
* when system exit, destroy the sources,
|
* when system exit, destroy the sources,
|
||||||
* for gmc to analysis mem leaks.
|
* for gmc to analysis mem leaks.
|
||||||
|
@ -451,15 +456,14 @@ private:
|
||||||
// the cached audio sequence header.
|
// the cached audio sequence header.
|
||||||
SrsSharedPtrMessage* cache_sh_audio;
|
SrsSharedPtrMessage* cache_sh_audio;
|
||||||
public:
|
public:
|
||||||
/**
|
SrsSource();
|
||||||
* @param _req the client request object,
|
|
||||||
* this object will deep copy it for reload.
|
|
||||||
*/
|
|
||||||
SrsSource(ISrsHlsHandler* hh);
|
|
||||||
virtual ~SrsSource();
|
virtual ~SrsSource();
|
||||||
// initialize, get and setter.
|
// initialize, get and setter.
|
||||||
public:
|
public:
|
||||||
virtual int initialize(SrsRequest* r, ISrsSourceHandler* h);
|
/**
|
||||||
|
* initialize the hls with handlers.
|
||||||
|
*/
|
||||||
|
virtual int initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh);
|
||||||
// interface ISrsReloadHandler
|
// interface ISrsReloadHandler
|
||||||
public:
|
public:
|
||||||
virtual int on_reload_vhost_atc(std::string vhost);
|
virtual int on_reload_vhost_atc(std::string vhost);
|
||||||
|
|
|
@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_kernel_log.hpp>
|
#include <srs_kernel_log.hpp>
|
||||||
|
|
||||||
|
#ifndef SRS_OSX
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
bool srs_st_epoll_is_supported(void)
|
bool srs_st_epoll_is_supported(void)
|
||||||
{
|
{
|
||||||
|
@ -38,11 +39,13 @@ bool srs_st_epoll_is_supported(void)
|
||||||
|
|
||||||
return (errno != ENOSYS);
|
return (errno != ENOSYS);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int srs_init_st()
|
int srs_init_st()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
#ifndef SRS_OSX
|
||||||
// check epoll, some old linux donot support epoll.
|
// check epoll, some old linux donot support epoll.
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/162
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/162
|
||||||
if (!srs_st_epoll_is_supported()) {
|
if (!srs_st_epoll_is_supported()) {
|
||||||
|
@ -58,6 +61,7 @@ int srs_init_st()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_verbose("st_set_eventsys use linux epoll success");
|
srs_verbose("st_set_eventsys use linux epoll success");
|
||||||
|
#endif
|
||||||
|
|
||||||
if(st_init() != 0){
|
if(st_init() != 0){
|
||||||
ret = ERROR_ST_INITIALIZE;
|
ret = ERROR_ST_INITIALIZE;
|
||||||
|
|
|
@ -29,6 +29,8 @@ using namespace std;
|
||||||
|
|
||||||
#include <srs_rtmp_sdk.hpp>
|
#include <srs_rtmp_sdk.hpp>
|
||||||
#include <srs_app_json.hpp>
|
#include <srs_app_json.hpp>
|
||||||
|
#include <srs_app_kbps.hpp>
|
||||||
|
#include <srs_app_conn.hpp>
|
||||||
|
|
||||||
int64_t __srs_gvid = getpid();
|
int64_t __srs_gvid = getpid();
|
||||||
|
|
||||||
|
@ -40,20 +42,45 @@ int64_t __srs_generate_id()
|
||||||
SrsStatisticVhost::SrsStatisticVhost()
|
SrsStatisticVhost::SrsStatisticVhost()
|
||||||
{
|
{
|
||||||
id = __srs_generate_id();
|
id = __srs_generate_id();
|
||||||
|
|
||||||
|
kbps = new SrsKbps();
|
||||||
|
kbps->set_io(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatisticVhost::~SrsStatisticVhost()
|
SrsStatisticVhost::~SrsStatisticVhost()
|
||||||
{
|
{
|
||||||
|
srs_freep(kbps);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatisticStream::SrsStatisticStream()
|
SrsStatisticStream::SrsStatisticStream()
|
||||||
{
|
{
|
||||||
id = __srs_generate_id();
|
id = __srs_generate_id();
|
||||||
vhost = NULL;
|
vhost = NULL;
|
||||||
|
|
||||||
|
has_video = false;
|
||||||
|
vcodec = SrsCodecVideoReserved;
|
||||||
|
avc_profile = SrsAvcProfileReserved;
|
||||||
|
avc_level = SrsAvcLevelReserved;
|
||||||
|
|
||||||
|
has_audio = false;
|
||||||
|
acodec = SrsCodecAudioReserved1;
|
||||||
|
asample_rate = SrsCodecAudioSampleRateReserved;
|
||||||
|
asound_type = SrsCodecAudioSoundTypeReserved;
|
||||||
|
aac_object = SrsAacObjectTypeReserved;
|
||||||
|
|
||||||
|
kbps = new SrsKbps();
|
||||||
|
kbps->set_io(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatisticStream::~SrsStatisticStream()
|
SrsStatisticStream::~SrsStatisticStream()
|
||||||
{
|
{
|
||||||
|
srs_freep(kbps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsStatisticStream::close()
|
||||||
|
{
|
||||||
|
has_video = false;
|
||||||
|
has_audio = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatistic* SrsStatistic::_instance = new SrsStatistic();
|
SrsStatistic* SrsStatistic::_instance = new SrsStatistic();
|
||||||
|
@ -61,10 +88,15 @@ SrsStatistic* SrsStatistic::_instance = new SrsStatistic();
|
||||||
SrsStatistic::SrsStatistic()
|
SrsStatistic::SrsStatistic()
|
||||||
{
|
{
|
||||||
_server_id = __srs_generate_id();
|
_server_id = __srs_generate_id();
|
||||||
|
|
||||||
|
kbps = new SrsKbps();
|
||||||
|
kbps->set_io(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatistic::~SrsStatistic()
|
SrsStatistic::~SrsStatistic()
|
||||||
{
|
{
|
||||||
|
srs_freep(kbps);
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||||
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
||||||
|
@ -93,34 +125,54 @@ SrsStatistic* SrsStatistic::instance()
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsStatistic::on_video_info(SrsRequest* req,
|
||||||
|
SrsCodecVideo vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level
|
||||||
|
) {
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsStatisticVhost* vhost = create_vhost(req);
|
||||||
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
||||||
|
|
||||||
|
stream->has_video = true;
|
||||||
|
stream->vcodec = vcodec;
|
||||||
|
stream->avc_profile = avc_profile;
|
||||||
|
stream->avc_level = avc_level;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsStatistic::on_audio_info(SrsRequest* req,
|
||||||
|
SrsCodecAudio acodec, SrsCodecAudioSampleRate asample_rate, SrsCodecAudioSoundType asound_type,
|
||||||
|
SrsAacObjectType aac_object
|
||||||
|
) {
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
SrsStatisticVhost* vhost = create_vhost(req);
|
||||||
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
||||||
|
|
||||||
|
stream->has_audio = true;
|
||||||
|
stream->acodec = acodec;
|
||||||
|
stream->asample_rate = asample_rate;
|
||||||
|
stream->asound_type = asound_type;
|
||||||
|
stream->aac_object = aac_object;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SrsStatistic::on_stream_close(SrsRequest* req)
|
||||||
|
{
|
||||||
|
SrsStatisticVhost* vhost = create_vhost(req);
|
||||||
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
||||||
|
|
||||||
|
stream->close();
|
||||||
|
}
|
||||||
|
|
||||||
int SrsStatistic::on_client(int id, SrsRequest* req)
|
int SrsStatistic::on_client(int id, SrsRequest* req)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// create vhost if not exists.
|
SrsStatisticVhost* vhost = create_vhost(req);
|
||||||
SrsStatisticVhost* vhost = NULL;
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
||||||
if (vhosts.find(req->vhost) == vhosts.end()) {
|
|
||||||
vhost = new SrsStatisticVhost();
|
|
||||||
vhost->vhost = req->vhost;
|
|
||||||
vhosts[req->vhost] = vhost;
|
|
||||||
} else {
|
|
||||||
vhost = vhosts[req->vhost];
|
|
||||||
}
|
|
||||||
|
|
||||||
// the url to identify the stream.
|
|
||||||
std::string url = req->get_stream_url();
|
|
||||||
|
|
||||||
// create stream if not exists.
|
|
||||||
SrsStatisticStream* stream = NULL;
|
|
||||||
if (streams.find(url) == streams.end()) {
|
|
||||||
stream = new SrsStatisticStream();
|
|
||||||
stream->vhost = vhost;
|
|
||||||
stream->stream = req->stream;
|
|
||||||
stream->url = url;
|
|
||||||
streams[url] = stream;
|
|
||||||
} else {
|
|
||||||
stream = streams[url];
|
|
||||||
}
|
|
||||||
|
|
||||||
// create client if not exists
|
// create client if not exists
|
||||||
SrsStatisticClient* client = NULL;
|
SrsStatisticClient* client = NULL;
|
||||||
|
@ -135,7 +187,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsStatistic::on_close(int id)
|
void SrsStatistic::on_disconnect(int id)
|
||||||
{
|
{
|
||||||
std::map<int, SrsStatisticClient*>::iterator it;
|
std::map<int, SrsStatisticClient*>::iterator it;
|
||||||
it = clients.find(id);
|
it = clients.find(id);
|
||||||
|
@ -146,6 +198,49 @@ void SrsStatistic::on_close(int id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsStatistic::kbps_add_delta(SrsConnection* conn)
|
||||||
|
{
|
||||||
|
int id = conn->srs_id();
|
||||||
|
if (clients.find(id) == clients.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsStatisticClient* client = clients[id];
|
||||||
|
|
||||||
|
// resample the kbps to collect the delta.
|
||||||
|
conn->resample();
|
||||||
|
|
||||||
|
// add delta of connection to kbps.
|
||||||
|
// for next sample() of server kbps can get the stat.
|
||||||
|
kbps->add_delta(conn);
|
||||||
|
client->stream->kbps->add_delta(conn);
|
||||||
|
client->stream->vhost->kbps->add_delta(conn);
|
||||||
|
|
||||||
|
// cleanup the delta.
|
||||||
|
conn->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsKbps* SrsStatistic::kbps_sample()
|
||||||
|
{
|
||||||
|
kbps->sample();
|
||||||
|
if (true) {
|
||||||
|
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||||
|
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
||||||
|
SrsStatisticVhost* vhost = it->second;
|
||||||
|
vhost->kbps->sample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (true) {
|
||||||
|
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||||
|
for (it = streams.begin(); it != streams.end(); it++) {
|
||||||
|
SrsStatisticStream* stream = it->second;
|
||||||
|
stream->kbps->sample();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kbps;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t SrsStatistic::server_id()
|
int64_t SrsStatistic::server_id()
|
||||||
{
|
{
|
||||||
return _server_id;
|
return _server_id;
|
||||||
|
@ -165,7 +260,9 @@ int SrsStatistic::dumps_vhosts(stringstream& ss)
|
||||||
|
|
||||||
ss << __SRS_JOBJECT_START
|
ss << __SRS_JOBJECT_START
|
||||||
<< __SRS_JFIELD_ORG("id", vhost->id) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("id", vhost->id) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("name", vhost->vhost)
|
<< __SRS_JFIELD_STR("name", vhost->vhost) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("send_bytes", vhost->kbps->get_send_bytes()) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("recv_bytes", vhost->kbps->get_recv_bytes())
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JOBJECT_END;
|
||||||
}
|
}
|
||||||
ss << __SRS_JARRAY_END;
|
ss << __SRS_JARRAY_END;
|
||||||
|
@ -198,10 +295,76 @@ int SrsStatistic::dumps_streams(stringstream& ss)
|
||||||
<< __SRS_JFIELD_ORG("id", stream->id) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("id", stream->id) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_STR("name", stream->stream) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_STR("name", stream->stream) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("vhost", stream->vhost->id) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("vhost", stream->vhost->id) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("clients", client_num)
|
<< __SRS_JFIELD_ORG("clients", client_num) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JOBJECT_END;
|
<< __SRS_JFIELD_ORG("send_bytes", stream->kbps->get_send_bytes()) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("recv_bytes", stream->kbps->get_recv_bytes()) << __SRS_JFIELD_CONT;
|
||||||
|
|
||||||
|
if (!stream->has_video) {
|
||||||
|
ss << __SRS_JFIELD_NULL("video") << __SRS_JFIELD_CONT;
|
||||||
|
} else {
|
||||||
|
ss << __SRS_JFIELD_NAME("video")
|
||||||
|
<< __SRS_JOBJECT_START
|
||||||
|
<< __SRS_JFIELD_STR("codec", srs_codec_video2str(stream->vcodec)) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_STR("profile", srs_codec_avc_profile2str(stream->avc_profile)) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("level", srs_codec_avc_level2str(stream->avc_level))
|
||||||
|
<< __SRS_JOBJECT_END
|
||||||
|
<< __SRS_JFIELD_CONT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stream->has_audio) {
|
||||||
|
ss << __SRS_JFIELD_NULL("audio");
|
||||||
|
} else {
|
||||||
|
ss << __SRS_JFIELD_NAME("audio")
|
||||||
|
<< __SRS_JOBJECT_START
|
||||||
|
<< __SRS_JFIELD_STR("codec", srs_codec_audio2str(stream->acodec)) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("sample_rate", (int)flv_sample_rates[stream->asample_rate]) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_ORG("channel", (int)stream->asound_type + 1) << __SRS_JFIELD_CONT
|
||||||
|
<< __SRS_JFIELD_STR("profile", srs_codec_aac_object2str(stream->aac_object))
|
||||||
|
<< __SRS_JOBJECT_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << __SRS_JOBJECT_END;
|
||||||
}
|
}
|
||||||
ss << __SRS_JARRAY_END;
|
ss << __SRS_JARRAY_END;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
|
||||||
|
{
|
||||||
|
SrsStatisticVhost* vhost = NULL;
|
||||||
|
|
||||||
|
// create vhost if not exists.
|
||||||
|
if (vhosts.find(req->vhost) == vhosts.end()) {
|
||||||
|
vhost = new SrsStatisticVhost();
|
||||||
|
vhost->vhost = req->vhost;
|
||||||
|
vhosts[req->vhost] = vhost;
|
||||||
|
return vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
vhost = vhosts[req->vhost];
|
||||||
|
|
||||||
|
return vhost;
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsRequest* req)
|
||||||
|
{
|
||||||
|
std::string url = req->get_stream_url();
|
||||||
|
|
||||||
|
SrsStatisticStream* stream = NULL;
|
||||||
|
|
||||||
|
// create stream if not exists.
|
||||||
|
if (streams.find(url) == streams.end()) {
|
||||||
|
stream = new SrsStatisticStream();
|
||||||
|
stream->vhost = vhost;
|
||||||
|
stream->stream = req->stream;
|
||||||
|
stream->url = url;
|
||||||
|
streams[url] = stream;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream = streams[url];
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <srs_kernel_codec.hpp>
|
||||||
|
|
||||||
|
class SrsKbps;
|
||||||
class SrsRequest;
|
class SrsRequest;
|
||||||
|
class SrsConnection;
|
||||||
|
|
||||||
struct SrsStatisticVhost
|
struct SrsStatisticVhost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int64_t id;
|
int64_t id;
|
||||||
std::string vhost;
|
std::string vhost;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* vhost total kbps.
|
||||||
|
*/
|
||||||
|
SrsKbps* kbps;
|
||||||
public:
|
public:
|
||||||
SrsStatisticVhost();
|
SrsStatisticVhost();
|
||||||
virtual ~SrsStatisticVhost();
|
virtual ~SrsStatisticVhost();
|
||||||
|
@ -53,9 +62,38 @@ public:
|
||||||
std::string app;
|
std::string app;
|
||||||
std::string stream;
|
std::string stream;
|
||||||
std::string url;
|
std::string url;
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* stream total kbps.
|
||||||
|
*/
|
||||||
|
SrsKbps* kbps;
|
||||||
|
public:
|
||||||
|
bool has_video;
|
||||||
|
SrsCodecVideo vcodec;
|
||||||
|
// profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
||||||
|
SrsAvcProfile avc_profile;
|
||||||
|
// level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
||||||
|
SrsAvcLevel avc_level;
|
||||||
|
public:
|
||||||
|
bool has_audio;
|
||||||
|
SrsCodecAudio acodec;
|
||||||
|
SrsCodecAudioSampleRate asample_rate;
|
||||||
|
SrsCodecAudioSoundType asound_type;
|
||||||
|
/**
|
||||||
|
* audio specified
|
||||||
|
* audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
|
||||||
|
* 1.5.1.1 Audio object type definition, page 23,
|
||||||
|
* in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf.
|
||||||
|
*/
|
||||||
|
SrsAacObjectType aac_object;
|
||||||
public:
|
public:
|
||||||
SrsStatisticStream();
|
SrsStatisticStream();
|
||||||
virtual ~SrsStatisticStream();
|
virtual ~SrsStatisticStream();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* close the stream.
|
||||||
|
*/
|
||||||
|
virtual void close();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SrsStatisticClient
|
struct SrsStatisticClient
|
||||||
|
@ -73,15 +111,35 @@ private:
|
||||||
int64_t _server_id;
|
int64_t _server_id;
|
||||||
// key: vhost name, value: vhost object.
|
// key: vhost name, value: vhost object.
|
||||||
std::map<std::string, SrsStatisticVhost*> vhosts;
|
std::map<std::string, SrsStatisticVhost*> vhosts;
|
||||||
// key: stream name, value: stream object.
|
// key: stream url, value: stream object.
|
||||||
std::map<std::string, SrsStatisticStream*> streams;
|
std::map<std::string, SrsStatisticStream*> streams;
|
||||||
// key: client id, value: stream object.
|
// key: client id, value: stream object.
|
||||||
std::map<int, SrsStatisticClient*> clients;
|
std::map<int, SrsStatisticClient*> clients;
|
||||||
|
// server total kbps.
|
||||||
|
SrsKbps* kbps;
|
||||||
private:
|
private:
|
||||||
SrsStatistic();
|
SrsStatistic();
|
||||||
virtual ~SrsStatistic();
|
virtual ~SrsStatistic();
|
||||||
public:
|
public:
|
||||||
static SrsStatistic* instance();
|
static SrsStatistic* instance();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* when got video info for stream.
|
||||||
|
*/
|
||||||
|
virtual int on_video_info(SrsRequest* req,
|
||||||
|
SrsCodecVideo vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* when got audio info for stream.
|
||||||
|
*/
|
||||||
|
virtual int on_audio_info(SrsRequest* req,
|
||||||
|
SrsCodecAudio acodec, SrsCodecAudioSampleRate asample_rate, SrsCodecAudioSoundType asound_type,
|
||||||
|
SrsAacObjectType aac_object
|
||||||
|
);
|
||||||
|
/**
|
||||||
|
* when close stream.
|
||||||
|
*/
|
||||||
|
virtual void on_stream_close(SrsRequest* req);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* when got a client to publish/play stream,
|
* when got a client to publish/play stream,
|
||||||
|
@ -90,9 +148,19 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int on_client(int id, SrsRequest* req);
|
virtual int on_client(int id, SrsRequest* req);
|
||||||
/**
|
/**
|
||||||
* client close
|
* client disconnect
|
||||||
*/
|
*/
|
||||||
virtual void on_close(int id);
|
virtual void on_disconnect(int id);
|
||||||
|
/**
|
||||||
|
* sample the kbps, add delta bytes of conn.
|
||||||
|
* use kbps_sample() to get all result of kbps stat.
|
||||||
|
*/
|
||||||
|
virtual void kbps_add_delta(SrsConnection* conn);
|
||||||
|
/**
|
||||||
|
* calc the result for all kbps.
|
||||||
|
* @return the server kbps.
|
||||||
|
*/
|
||||||
|
virtual SrsKbps* kbps_sample();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* get the server id, used to identify the server.
|
* get the server id, used to identify the server.
|
||||||
|
@ -107,6 +175,9 @@ public:
|
||||||
* dumps the streams to sstream in json.
|
* dumps the streams to sstream in json.
|
||||||
*/
|
*/
|
||||||
virtual int dumps_streams(std::stringstream& ss);
|
virtual int dumps_streams(std::stringstream& ss);
|
||||||
|
private:
|
||||||
|
virtual SrsStatisticVhost* create_vhost(SrsRequest* req);
|
||||||
|
virtual SrsStatisticStream* create_stream(SrsStatisticVhost* vhost, SrsRequest* req);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1119,9 +1119,7 @@ void srs_api_dump_summaries(std::stringstream& ss)
|
||||||
<< __SRS_JFIELD_ORG("net_send_bytes", ns_bytes) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("net_send_bytes", ns_bytes) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("srs_sample_time", nrs->sample_time) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("srs_sample_time", nrs->sample_time) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("srs_recv_bytes", nrs->rbytes) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("srs_recv_bytes", nrs->rbytes) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("srs_recv_kbps", nrs->rkbps) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_ORG("srs_send_bytes", nrs->sbytes) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("srs_send_bytes", nrs->sbytes) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("srs_send_kbps", nrs->skbps) << __SRS_JFIELD_CONT
|
|
||||||
<< __SRS_JFIELD_ORG("conn_sys", nrs->nb_conn_sys) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("conn_sys", nrs->nb_conn_sys) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("conn_sys_et", nrs->nb_conn_sys_et) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("conn_sys_et", nrs->nb_conn_sys_et) << __SRS_JFIELD_CONT
|
||||||
<< __SRS_JFIELD_ORG("conn_sys_tw", nrs->nb_conn_sys_tw) << __SRS_JFIELD_CONT
|
<< __SRS_JFIELD_ORG("conn_sys_tw", nrs->nb_conn_sys_tw) << __SRS_JFIELD_CONT
|
||||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// current release version
|
// current release version
|
||||||
#define VERSION_MAJOR 2
|
#define VERSION_MAJOR 2
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 124
|
#define VERSION_REVISION 137
|
||||||
|
|
||||||
// server info.
|
// server info.
|
||||||
#define RTMP_SIG_SRS_KEY "SRS"
|
#define RTMP_SIG_SRS_KEY "SRS"
|
||||||
|
@ -88,6 +88,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// generated by configure.
|
// generated by configure.
|
||||||
#include <srs_auto_headers.hpp>
|
#include <srs_auto_headers.hpp>
|
||||||
|
// important performance options.
|
||||||
|
#include <srs_core_performance.hpp>
|
||||||
|
|
||||||
// free the p and set to NULL.
|
// free the p and set to NULL.
|
||||||
// p must be a T*.
|
// p must be a T*.
|
||||||
|
|
|
@ -108,7 +108,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
* whether set the socket send buffer size.
|
* whether set the socket send buffer size.
|
||||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
||||||
*/
|
*/
|
||||||
#undef SRS_PERF_MW_SO_SNDBUF
|
#define SRS_PERF_MW_SO_SNDBUF
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether set the socket recv buffer size.
|
* whether set the socket recv buffer size.
|
||||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
||||||
|
@ -154,5 +155,31 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// in seconds, the live queue length.
|
// in seconds, the live queue length.
|
||||||
#define SRS_PERF_PLAY_QUEUE 30
|
#define SRS_PERF_PLAY_QUEUE 30
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether always use complex send algorithm.
|
||||||
|
* for some network does not support the complex send,
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/320
|
||||||
|
*/
|
||||||
|
//#undef SRS_PERF_COMPLEX_SEND
|
||||||
|
#define SRS_PERF_COMPLEX_SEND
|
||||||
|
/**
|
||||||
|
* whether enable the TCP_NODELAY
|
||||||
|
* user maybe need send small tcp packet for some network.
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/320
|
||||||
|
*/
|
||||||
|
//#define SRS_PERF_TCP_NODELAY
|
||||||
|
#undef SRS_PERF_TCP_NODELAY
|
||||||
|
/**
|
||||||
|
* set the socket send buffer,
|
||||||
|
* to force the server to send smaller tcp packet.
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/320
|
||||||
|
* @remark undef it to auto calc it by merged write sleep ms.
|
||||||
|
* @remark only apply it when SRS_PERF_MW_SO_RCVBUF is defined.
|
||||||
|
*/
|
||||||
|
#ifdef SRS_PERF_MW_SO_SNDBUF
|
||||||
|
//#define SRS_PERF_SO_SNDBUF_SIZE 1024
|
||||||
|
#undef SRS_PERF_SO_SNDBUF_SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ SrsAacEncoder::SrsAacEncoder()
|
||||||
_fs = NULL;
|
_fs = NULL;
|
||||||
got_sequence_header = false;
|
got_sequence_header = false;
|
||||||
tag_stream = new SrsStream();
|
tag_stream = new SrsStream();
|
||||||
|
aac_object = SrsAacObjectTypeReserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsAacEncoder::~SrsAacEncoder()
|
SrsAacEncoder::~SrsAacEncoder()
|
||||||
|
@ -114,7 +115,7 @@ int SrsAacEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||||
// 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33.
|
// 1.6.2.1 AudioSpecificConfig, in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33.
|
||||||
//
|
//
|
||||||
// only need to decode the first 2bytes:
|
// only need to decode the first 2bytes:
|
||||||
// audioObjectType, aac_profile, 5bits.
|
// audioObjectType, 5bits.
|
||||||
// samplingFrequencyIndex, aac_sample_rate, 4bits.
|
// samplingFrequencyIndex, aac_sample_rate, 4bits.
|
||||||
// channelConfiguration, aac_channels, 4bits
|
// channelConfiguration, aac_channels, 4bits
|
||||||
if (!stream->require(2)) {
|
if (!stream->require(2)) {
|
||||||
|
@ -123,12 +124,14 @@ int SrsAacEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
aac_profile = stream->read_1bytes();
|
int8_t audioObjectType = stream->read_1bytes();
|
||||||
aac_sample_rate = stream->read_1bytes();
|
aac_sample_rate = stream->read_1bytes();
|
||||||
|
|
||||||
aac_channels = (aac_sample_rate >> 3) & 0x0f;
|
aac_channels = (aac_sample_rate >> 3) & 0x0f;
|
||||||
aac_sample_rate = ((aac_profile << 1) & 0x0e) | ((aac_sample_rate >> 7) & 0x01);
|
aac_sample_rate = ((audioObjectType << 1) & 0x0e) | ((aac_sample_rate >> 7) & 0x01);
|
||||||
aac_profile = (aac_profile >> 3) & 0x1f;
|
|
||||||
|
audioObjectType = (audioObjectType >> 3) & 0x1f;
|
||||||
|
aac_object = (SrsAacObjectType)audioObjectType;
|
||||||
|
|
||||||
got_sequence_header = true;
|
got_sequence_header = true;
|
||||||
|
|
||||||
|
@ -177,16 +180,14 @@ int SrsAacEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||||
// protection_absent 1 bslbf
|
// protection_absent 1 bslbf
|
||||||
*pp++ = 0xf1;
|
*pp++ = 0xf1;
|
||||||
|
|
||||||
// Profile_ObjectType 2 uimsbf
|
// profile 2 uimsbf
|
||||||
// sampling_frequency_index 4 uimsbf
|
// sampling_frequency_index 4 uimsbf
|
||||||
// private_bit 1 bslbf
|
// private_bit 1 bslbf
|
||||||
// channel_configuration 3 uimsbf
|
// channel_configuration 3 uimsbf
|
||||||
// original/copy 1 bslbf
|
// original/copy 1 bslbf
|
||||||
// home 1 bslbf
|
// home 1 bslbf
|
||||||
int8_t fh_Profile_ObjectType = aac_profile - 1;
|
SrsAacProfile aac_profile = srs_codec_aac_rtmp2ts(aac_object);
|
||||||
*pp++ = ((fh_Profile_ObjectType << 6) & 0xc0) | ((aac_sample_rate << 2) & 0x3c) | ((aac_channels >> 2) & 0x01);
|
*pp++ = ((aac_profile << 6) & 0xc0) | ((aac_sample_rate << 2) & 0x3c) | ((aac_channels >> 2) & 0x01);
|
||||||
// @remark, Emphasis is removed,
|
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
|
|
||||||
// 4bits left.
|
// 4bits left.
|
||||||
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
|
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
|
||||||
// copyright_identification_bit 1 bslbf
|
// copyright_identification_bit 1 bslbf
|
||||||
|
|
|
@ -31,6 +31,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <srs_kernel_codec.hpp>
|
||||||
|
|
||||||
class SrsStream;
|
class SrsStream;
|
||||||
class SrsFileWriter;
|
class SrsFileWriter;
|
||||||
class SrsFileReader;
|
class SrsFileReader;
|
||||||
|
@ -43,7 +45,7 @@ class SrsAacEncoder
|
||||||
private:
|
private:
|
||||||
SrsFileWriter* _fs;
|
SrsFileWriter* _fs;
|
||||||
private:
|
private:
|
||||||
int8_t aac_profile;
|
SrsAacObjectType aac_object;
|
||||||
int8_t aac_sample_rate;
|
int8_t aac_sample_rate;
|
||||||
int8_t aac_channels;
|
int8_t aac_channels;
|
||||||
bool got_sequence_header;
|
bool got_sequence_header;
|
||||||
|
|
|
@ -32,6 +32,154 @@ using namespace std;
|
||||||
#include <srs_kernel_stream.hpp>
|
#include <srs_kernel_stream.hpp>
|
||||||
#include <srs_kernel_utility.hpp>
|
#include <srs_kernel_utility.hpp>
|
||||||
|
|
||||||
|
string srs_codec_video2str(SrsCodecVideo codec)
|
||||||
|
{
|
||||||
|
switch (codec) {
|
||||||
|
case SrsCodecVideoAVC:
|
||||||
|
return "H264";
|
||||||
|
case SrsCodecVideoOn2VP6:
|
||||||
|
case SrsCodecVideoOn2VP6WithAlphaChannel:
|
||||||
|
return "VP6";
|
||||||
|
case SrsCodecVideoReserved:
|
||||||
|
case SrsCodecVideoReserved1:
|
||||||
|
case SrsCodecVideoReserved2:
|
||||||
|
case SrsCodecVideoDisabled:
|
||||||
|
case SrsCodecVideoSorensonH263:
|
||||||
|
case SrsCodecVideoScreenVideo:
|
||||||
|
case SrsCodecVideoScreenVideoVersion2:
|
||||||
|
default:
|
||||||
|
return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string srs_codec_audio2str(SrsCodecAudio codec)
|
||||||
|
{
|
||||||
|
switch (codec) {
|
||||||
|
case SrsCodecAudioAAC:
|
||||||
|
return "AAC";
|
||||||
|
case SrsCodecAudioMP3:
|
||||||
|
return "MP3";
|
||||||
|
case SrsCodecAudioReserved1:
|
||||||
|
case SrsCodecAudioLinearPCMPlatformEndian:
|
||||||
|
case SrsCodecAudioADPCM:
|
||||||
|
case SrsCodecAudioLinearPCMLittleEndian:
|
||||||
|
case SrsCodecAudioNellymoser16kHzMono:
|
||||||
|
case SrsCodecAudioNellymoser8kHzMono:
|
||||||
|
case SrsCodecAudioNellymoser:
|
||||||
|
case SrsCodecAudioReservedG711AlawLogarithmicPCM:
|
||||||
|
case SrsCodecAudioReservedG711MuLawLogarithmicPCM:
|
||||||
|
case SrsCodecAudioReserved:
|
||||||
|
case SrsCodecAudioSpeex:
|
||||||
|
case SrsCodecAudioReservedMP3_8kHz:
|
||||||
|
case SrsCodecAudioReservedDeviceSpecificSound:
|
||||||
|
default:
|
||||||
|
return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string srs_codec_aac_profile2str(SrsAacProfile aac_profile)
|
||||||
|
{
|
||||||
|
switch (aac_profile) {
|
||||||
|
case SrsAacProfileMain: return "Main";
|
||||||
|
case SrsAacProfileLC: return "LC";
|
||||||
|
case SrsAacProfileSSR: return "SSR";
|
||||||
|
default: return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string srs_codec_aac_object2str(SrsAacObjectType aac_object)
|
||||||
|
{
|
||||||
|
switch (aac_object) {
|
||||||
|
case SrsAacObjectTypeAacMain: return "Main";
|
||||||
|
case SrsAacObjectTypeHE: return "HE";
|
||||||
|
case SrsAacObjectTypeHEV2: return "HEv2";
|
||||||
|
case SrsAacObjectTypeAacLC: return "LC";
|
||||||
|
case SrsAacObjectTypeAacSSR: return "SSR";
|
||||||
|
default: return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile)
|
||||||
|
{
|
||||||
|
switch (profile) {
|
||||||
|
case SrsAacProfileMain: return SrsAacObjectTypeAacMain;
|
||||||
|
case SrsAacProfileLC: return SrsAacObjectTypeAacLC;
|
||||||
|
case SrsAacProfileSSR: return SrsAacObjectTypeAacSSR;
|
||||||
|
default: return SrsAacObjectTypeReserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SrsAacProfile srs_codec_aac_rtmp2ts(SrsAacObjectType object_type)
|
||||||
|
{
|
||||||
|
switch (object_type) {
|
||||||
|
case SrsAacObjectTypeAacMain: return SrsAacProfileMain;
|
||||||
|
case SrsAacObjectTypeHE:
|
||||||
|
case SrsAacObjectTypeHEV2:
|
||||||
|
case SrsAacObjectTypeAacLC: return SrsAacProfileLC;
|
||||||
|
case SrsAacObjectTypeAacSSR: return SrsAacProfileSSR;
|
||||||
|
default: return SrsAacProfileReserved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string srs_codec_avc_profile2str(SrsAvcProfile profile)
|
||||||
|
{
|
||||||
|
switch (profile) {
|
||||||
|
case SrsAvcProfileBaseline: return "Baseline";
|
||||||
|
case SrsAvcProfileConstrainedBaseline: return "Baseline(Constrained)";
|
||||||
|
case SrsAvcProfileMain: return "Main";
|
||||||
|
case SrsAvcProfileExtended: return "Extended";
|
||||||
|
case SrsAvcProfileHigh: return "High";
|
||||||
|
case SrsAvcProfileHigh10: return "High(10)";
|
||||||
|
case SrsAvcProfileHigh10Intra: return "High(10+Intra)";
|
||||||
|
case SrsAvcProfileHigh422: return "High(422)";
|
||||||
|
case SrsAvcProfileHigh422Intra: return "High(422+Intra)";
|
||||||
|
case SrsAvcProfileHigh444: return "High(444)";
|
||||||
|
case SrsAvcProfileHigh444Predictive: return "High(444+Predictive)";
|
||||||
|
case SrsAvcProfileHigh444Intra: return "High(444+Intra)";
|
||||||
|
default: return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string srs_codec_avc_level2str(SrsAvcLevel level)
|
||||||
|
{
|
||||||
|
switch (level) {
|
||||||
|
case SrsAvcLevel_1: return "1";
|
||||||
|
case SrsAvcLevel_11: return "1.1";
|
||||||
|
case SrsAvcLevel_12: return "1.2";
|
||||||
|
case SrsAvcLevel_13: return "1.3";
|
||||||
|
case SrsAvcLevel_2: return "2";
|
||||||
|
case SrsAvcLevel_21: return "2.1";
|
||||||
|
case SrsAvcLevel_22: return "2.2";
|
||||||
|
case SrsAvcLevel_3: return "3";
|
||||||
|
case SrsAvcLevel_31: return "3.1";
|
||||||
|
case SrsAvcLevel_32: return "3.2";
|
||||||
|
case SrsAvcLevel_4: return "4";
|
||||||
|
case SrsAvcLevel_41: return "4.1";
|
||||||
|
case SrsAvcLevel_5: return "5";
|
||||||
|
case SrsAvcLevel_51: return "5.1";
|
||||||
|
default: return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the public data, event HLS disable, others can use it.
|
||||||
|
*/
|
||||||
|
// 0 = 5.5 kHz = 5512 Hz
|
||||||
|
// 1 = 11 kHz = 11025 Hz
|
||||||
|
// 2 = 22 kHz = 22050 Hz
|
||||||
|
// 3 = 44 kHz = 44100 Hz
|
||||||
|
int flv_sample_rates[] = {5512, 11025, 22050, 44100};
|
||||||
|
|
||||||
|
// the sample rates in the codec,
|
||||||
|
// in the sequence header.
|
||||||
|
int aac_sample_rates[] =
|
||||||
|
{
|
||||||
|
96000, 88200, 64000, 48000,
|
||||||
|
44100, 32000, 24000, 22050,
|
||||||
|
16000, 12000, 11025, 8000,
|
||||||
|
7350, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
SrsFlvCodec::SrsFlvCodec()
|
SrsFlvCodec::SrsFlvCodec()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -184,9 +332,9 @@ SrsAvcAacCodec::SrsAvcAacCodec()
|
||||||
audio_data_rate = 0;
|
audio_data_rate = 0;
|
||||||
audio_codec_id = 0;
|
audio_codec_id = 0;
|
||||||
|
|
||||||
avc_profile = 0;
|
avc_profile = SrsAvcProfileReserved;
|
||||||
avc_level = 0;
|
avc_level = SrsAvcLevelReserved;
|
||||||
aac_profile = 0;
|
aac_object = SrsAacObjectTypeReserved;
|
||||||
aac_sample_rate = __SRS_AAC_SAMPLE_RATE_UNSET; // sample rate ignored
|
aac_sample_rate = __SRS_AAC_SAMPLE_RATE_UNSET; // sample rate ignored
|
||||||
aac_channels = 0;
|
aac_channels = 0;
|
||||||
avc_extra_size = 0;
|
avc_extra_size = 0;
|
||||||
|
@ -384,20 +532,9 @@ int SrsAvcAacCodec::audio_aac_sequence_header_demux(char* data, int size)
|
||||||
// set the aac sample rate.
|
// set the aac sample rate.
|
||||||
aac_sample_rate = samplingFrequencyIndex;
|
aac_sample_rate = samplingFrequencyIndex;
|
||||||
|
|
||||||
// the profile = object_id + 1
|
// convert the object type in sequence header to aac profile of ADTS.
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
aac_object = (SrsAacObjectType)profile_ObjectType;
|
||||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
if (aac_object == SrsAacObjectTypeReserved) {
|
||||||
aac_profile = profile_ObjectType + 1;
|
|
||||||
|
|
||||||
// the valid aac profile:
|
|
||||||
// MPEG-2 profile
|
|
||||||
// Main profile (ID == 1)
|
|
||||||
// Low Complexity profile (LC) (ID == 2)
|
|
||||||
// Scalable Sampling Rate profile (SSR) (ID == 3)
|
|
||||||
// (reserved) (ID == 4)
|
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
|
||||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
|
||||||
if (aac_profile > 4) {
|
|
||||||
ret = ERROR_HLS_DECODE_ERROR;
|
ret = ERROR_HLS_DECODE_ERROR;
|
||||||
srs_error("audio codec decode aac sequence header failed, "
|
srs_error("audio codec decode aac sequence header failed, "
|
||||||
"adts object=%d invalid. ret=%d", profile_ObjectType, ret);
|
"adts object=%d invalid. ret=%d", profile_ObjectType, ret);
|
||||||
|
@ -554,11 +691,11 @@ int SrsAvcAacCodec::avc_demux_sps_pps(SrsStream* stream)
|
||||||
//int8_t configurationVersion = stream->read_1bytes();
|
//int8_t configurationVersion = stream->read_1bytes();
|
||||||
stream->read_1bytes();
|
stream->read_1bytes();
|
||||||
//int8_t AVCProfileIndication = stream->read_1bytes();
|
//int8_t AVCProfileIndication = stream->read_1bytes();
|
||||||
avc_profile = stream->read_1bytes();
|
avc_profile = (SrsAvcProfile)stream->read_1bytes();
|
||||||
//int8_t profile_compatibility = stream->read_1bytes();
|
//int8_t profile_compatibility = stream->read_1bytes();
|
||||||
stream->read_1bytes();
|
stream->read_1bytes();
|
||||||
//int8_t AVCLevelIndication = stream->read_1bytes();
|
//int8_t AVCLevelIndication = stream->read_1bytes();
|
||||||
avc_level = stream->read_1bytes();
|
avc_level = (SrsAvcLevel)stream->read_1bytes();
|
||||||
|
|
||||||
// parse the NALU size.
|
// parse the NALU size.
|
||||||
int8_t lengthSizeMinusOne = stream->read_1bytes();
|
int8_t lengthSizeMinusOne = stream->read_1bytes();
|
||||||
|
|
|
@ -110,6 +110,7 @@ enum SrsCodecVideo
|
||||||
SrsCodecVideoScreenVideoVersion2 = 6,
|
SrsCodecVideoScreenVideoVersion2 = 6,
|
||||||
SrsCodecVideoAVC = 7,
|
SrsCodecVideoAVC = 7,
|
||||||
};
|
};
|
||||||
|
std::string srs_codec_video2str(SrsCodecVideo codec);
|
||||||
|
|
||||||
// SoundFormat UB [4]
|
// SoundFormat UB [4]
|
||||||
// Format of SoundData. The following values are defined:
|
// Format of SoundData. The following values are defined:
|
||||||
|
@ -150,6 +151,7 @@ enum SrsCodecAudio
|
||||||
SrsCodecAudioReservedMP3_8kHz = 14,
|
SrsCodecAudioReservedMP3_8kHz = 14,
|
||||||
SrsCodecAudioReservedDeviceSpecificSound = 15,
|
SrsCodecAudioReservedDeviceSpecificSound = 15,
|
||||||
};
|
};
|
||||||
|
std::string srs_codec_audio2str(SrsCodecAudio codec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the FLV/RTMP supported audio sample rate.
|
* the FLV/RTMP supported audio sample rate.
|
||||||
|
@ -373,6 +375,98 @@ enum SrsAvcPayloadFormat
|
||||||
SrsAvcPayloadFormatIbmf,
|
SrsAvcPayloadFormatIbmf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the aac profile, for ADTS(HLS/TS)
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/310
|
||||||
|
*/
|
||||||
|
enum SrsAacProfile
|
||||||
|
{
|
||||||
|
SrsAacProfileReserved = 3,
|
||||||
|
|
||||||
|
// @see 7.1 Profiles, aac-iso-13818-7.pdf, page 40
|
||||||
|
SrsAacProfileMain = 0,
|
||||||
|
SrsAacProfileLC = 1,
|
||||||
|
SrsAacProfileSSR = 2,
|
||||||
|
};
|
||||||
|
std::string srs_codec_aac_profile2str(SrsAacProfile aac_profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the aac object type, for RTMP sequence header
|
||||||
|
* for AudioSpecificConfig, @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 33
|
||||||
|
* for audioObjectType, @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23
|
||||||
|
*/
|
||||||
|
enum SrsAacObjectType
|
||||||
|
{
|
||||||
|
SrsAacObjectTypeReserved = 0,
|
||||||
|
|
||||||
|
// Table 1.1 – Audio Object Type definition
|
||||||
|
// @see @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23
|
||||||
|
SrsAacObjectTypeAacMain = 1,
|
||||||
|
SrsAacObjectTypeAacLC = 2,
|
||||||
|
SrsAacObjectTypeAacSSR = 3,
|
||||||
|
|
||||||
|
// AAC HE = LC+SBR
|
||||||
|
SrsAacObjectTypeHE = 5,
|
||||||
|
// AAC HEv2 = LC+SBR+PS
|
||||||
|
SrsAacObjectTypeHEV2 = 29,
|
||||||
|
};
|
||||||
|
std::string srs_codec_aac_object2str(SrsAacObjectType aac_object);
|
||||||
|
// ts/hls/adts audio header profile to RTMP sequence header object type.
|
||||||
|
SrsAacObjectType srs_codec_aac_ts2rtmp(SrsAacProfile profile);
|
||||||
|
// RTMP sequence header object type to ts/hls/adts audio header profile.
|
||||||
|
SrsAacProfile srs_codec_aac_rtmp2ts(SrsAacObjectType object_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the profile for avc/h.264.
|
||||||
|
* @see Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205.
|
||||||
|
*/
|
||||||
|
enum SrsAvcProfile
|
||||||
|
{
|
||||||
|
SrsAvcProfileReserved = 0,
|
||||||
|
|
||||||
|
// @see ffmpeg, libavcodec/avcodec.h:2713
|
||||||
|
SrsAvcProfileBaseline = 66,
|
||||||
|
// FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
|
||||||
|
// FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
|
||||||
|
SrsAvcProfileConstrainedBaseline = 578,
|
||||||
|
SrsAvcProfileMain = 77,
|
||||||
|
SrsAvcProfileExtended = 88,
|
||||||
|
SrsAvcProfileHigh = 100,
|
||||||
|
SrsAvcProfileHigh10 = 110,
|
||||||
|
SrsAvcProfileHigh10Intra = 2158,
|
||||||
|
SrsAvcProfileHigh422 = 122,
|
||||||
|
SrsAvcProfileHigh422Intra = 2170,
|
||||||
|
SrsAvcProfileHigh444 = 144,
|
||||||
|
SrsAvcProfileHigh444Predictive = 244,
|
||||||
|
SrsAvcProfileHigh444Intra = 2192,
|
||||||
|
};
|
||||||
|
std::string srs_codec_avc_profile2str(SrsAvcProfile profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the level for avc/h.264.
|
||||||
|
* @see Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 207.
|
||||||
|
*/
|
||||||
|
enum SrsAvcLevel
|
||||||
|
{
|
||||||
|
SrsAvcLevelReserved = 0,
|
||||||
|
|
||||||
|
SrsAvcLevel_1 = 10,
|
||||||
|
SrsAvcLevel_11 = 11,
|
||||||
|
SrsAvcLevel_12 = 12,
|
||||||
|
SrsAvcLevel_13 = 13,
|
||||||
|
SrsAvcLevel_2 = 20,
|
||||||
|
SrsAvcLevel_21 = 21,
|
||||||
|
SrsAvcLevel_22 = 22,
|
||||||
|
SrsAvcLevel_3 = 30,
|
||||||
|
SrsAvcLevel_31 = 31,
|
||||||
|
SrsAvcLevel_32 = 32,
|
||||||
|
SrsAvcLevel_4 = 40,
|
||||||
|
SrsAvcLevel_41 = 41,
|
||||||
|
SrsAvcLevel_5 = 50,
|
||||||
|
SrsAvcLevel_51 = 51,
|
||||||
|
};
|
||||||
|
std::string srs_codec_avc_level2str(SrsAvcLevel level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the h264/avc and aac codec, for media stream.
|
* the h264/avc and aac codec, for media stream.
|
||||||
*
|
*
|
||||||
|
@ -410,9 +504,9 @@ public:
|
||||||
* video specified
|
* video specified
|
||||||
*/
|
*/
|
||||||
// profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
// profile_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
||||||
u_int8_t avc_profile;
|
SrsAvcProfile avc_profile;
|
||||||
// level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
// level_idc, H.264-AVC-ISO_IEC_14496-10.pdf, page 45.
|
||||||
u_int8_t avc_level;
|
SrsAvcLevel avc_level;
|
||||||
// lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
|
// lengthSizeMinusOne, H.264-AVC-ISO_IEC_14496-15.pdf, page 16
|
||||||
int8_t NAL_unit_length;
|
int8_t NAL_unit_length;
|
||||||
u_int16_t sequenceParameterSetLength;
|
u_int16_t sequenceParameterSetLength;
|
||||||
|
@ -429,7 +523,7 @@ public:
|
||||||
* 1.5.1.1 Audio object type definition, page 23,
|
* 1.5.1.1 Audio object type definition, page 23,
|
||||||
* in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf.
|
* in aac-mp4a-format-ISO_IEC_14496-3+2001.pdf.
|
||||||
*/
|
*/
|
||||||
u_int8_t aac_profile;
|
SrsAacObjectType aac_object;
|
||||||
/**
|
/**
|
||||||
* samplingFrequencyIndex
|
* samplingFrequencyIndex
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -213,13 +213,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define ERROR_HTTP_DVR_REQUEST 3051
|
#define ERROR_HTTP_DVR_REQUEST 3051
|
||||||
#define ERROR_HTTP_JSON_REQUIRED 3052
|
#define ERROR_HTTP_JSON_REQUIRED 3052
|
||||||
#define ERROR_HTTP_DVR_CREATE_REQUEST 3053
|
#define ERROR_HTTP_DVR_CREATE_REQUEST 3053
|
||||||
|
#define ERROR_HTTP_DVR_NO_TAEGET 3054
|
||||||
|
#define ERROR_ADTS_ID_NOT_AAC 3055
|
||||||
|
|
||||||
// HDS error code
|
// HDS error code
|
||||||
#define ERROR_HDS_OPEN_F4M_FAILED 3054
|
#define ERROR_HDS_OPEN_F4M_FAILED 3056
|
||||||
#define ERROR_HDS_WRITE_F4M_FAILED 3055
|
#define ERROR_HDS_WRITE_F4M_FAILED 3057
|
||||||
#define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3056
|
#define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3058
|
||||||
#define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3057
|
#define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3059
|
||||||
#define ERROR_HDS_OPEN_FRAGMENT_FAILED 3058
|
#define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060
|
||||||
#define ERROR_HDS_WRITE_FRAGMENT_FAILED 3059
|
#define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// HTTP/StreamCaster protocol error.
|
// HTTP/StreamCaster protocol error.
|
||||||
|
@ -249,6 +252,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define ERROR_STREAM_CASTER_AVC_SPS 4022
|
#define ERROR_STREAM_CASTER_AVC_SPS 4022
|
||||||
#define ERROR_STREAM_CASTER_AVC_PPS 4023
|
#define ERROR_STREAM_CASTER_AVC_PPS 4023
|
||||||
#define ERROR_STREAM_CASTER_FLV_TAG 4024
|
#define ERROR_STREAM_CASTER_FLV_TAG 4024
|
||||||
|
#define ERROR_HTTP_RESPONSE_EOF 4025
|
||||||
|
#define ERROR_HTTP_INVALID_CHUNK_HEADER 4026
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// user-define error.
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
#define ERROR_USER_START 9000
|
||||||
|
#define ERROR_USER_END 9999
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether the error code is an system control error.
|
* whether the error code is an system control error.
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
virtual int open(std::string file);
|
virtual int open(std::string file);
|
||||||
virtual void close();
|
virtual void close();
|
||||||
public:
|
public:
|
||||||
|
// TODO: FIXME: extract interface.
|
||||||
virtual bool is_open();
|
virtual bool is_open();
|
||||||
virtual int64_t tellg();
|
virtual int64_t tellg();
|
||||||
virtual void skip(int64_t size);
|
virtual void skip(int64_t size);
|
||||||
|
|
|
@ -36,6 +36,7 @@ using namespace std;
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_kernel_stream.hpp>
|
#include <srs_kernel_stream.hpp>
|
||||||
#include <srs_kernel_file.hpp>
|
#include <srs_kernel_file.hpp>
|
||||||
|
#include <srs_kernel_codec.hpp>
|
||||||
|
|
||||||
#define SRS_FLV_TAG_HEADER_SIZE 11
|
#define SRS_FLV_TAG_HEADER_SIZE 11
|
||||||
#define SRS_FLV_PREVIOUS_TAG_SIZE 4
|
#define SRS_FLV_PREVIOUS_TAG_SIZE 4
|
||||||
|
@ -149,7 +150,7 @@ int SrsFlvEncoder::write_audio(int64_t timestamp, char* data, int size)
|
||||||
|
|
||||||
// 11bytes tag header
|
// 11bytes tag header
|
||||||
static char tag_header[] = {
|
static char tag_header[] = {
|
||||||
(char)8, // TagType UB [5], 8 = audio
|
(char)SrsCodecFlvTagAudio, // TagType UB [5], 8 = audio
|
||||||
(char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message.
|
(char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message.
|
||||||
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
|
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
|
||||||
(char)0x00, // TimestampExtended UI8
|
(char)0x00, // TimestampExtended UI8
|
||||||
|
@ -183,7 +184,7 @@ int SrsFlvEncoder::write_video(int64_t timestamp, char* data, int size)
|
||||||
|
|
||||||
// 11bytes tag header
|
// 11bytes tag header
|
||||||
static char tag_header[] = {
|
static char tag_header[] = {
|
||||||
(char)9, // TagType UB [5], 9 = video
|
(char)SrsCodecFlvTagVideo, // TagType UB [5], 9 = video
|
||||||
(char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message.
|
(char)0x00, (char)0x00, (char)0x00, // DataSize UI24 Length of the message.
|
||||||
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
|
(char)0x00, (char)0x00, (char)0x00, // Timestamp UI24 Time in milliseconds at which the data in this tag applies.
|
||||||
(char)0x00, // TimestampExtended UI8
|
(char)0x00, // TimestampExtended UI8
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* write flv metadata.
|
* write flv metadata.
|
||||||
* @param type, the type of data, or other message type.
|
* @param type, the type of data, or other message type.
|
||||||
|
* @see SrsCodecFlvTag
|
||||||
* @param data, the amf0 metadata which serialize from:
|
* @param data, the amf0 metadata which serialize from:
|
||||||
* AMF0 string: onMetaData,
|
* AMF0 string: onMetaData,
|
||||||
* AMF0 object: the metadata object.
|
* AMF0 object: the metadata object.
|
||||||
|
|
|
@ -56,25 +56,6 @@ using namespace std;
|
||||||
#define TS_AUDIO_AAC_PID 0x102
|
#define TS_AUDIO_AAC_PID 0x102
|
||||||
#define TS_AUDIO_MP3_PID 0x103
|
#define TS_AUDIO_MP3_PID 0x103
|
||||||
|
|
||||||
/**
|
|
||||||
* the public data, event HLS disable, others can use it.
|
|
||||||
*/
|
|
||||||
// 0 = 5.5 kHz = 5512 Hz
|
|
||||||
// 1 = 11 kHz = 11025 Hz
|
|
||||||
// 2 = 22 kHz = 22050 Hz
|
|
||||||
// 3 = 44 kHz = 44100 Hz
|
|
||||||
int flv_sample_rates[] = {5512, 11025, 22050, 44100};
|
|
||||||
|
|
||||||
// the sample rates in the codec,
|
|
||||||
// in the sequence header.
|
|
||||||
int aac_sample_rates[] =
|
|
||||||
{
|
|
||||||
96000, 88200, 64000, 48000,
|
|
||||||
44100, 32000, 24000, 22050,
|
|
||||||
16000, 12000, 11025, 8000,
|
|
||||||
7350, 0, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
string srs_ts_stream2string(SrsTsStream stream)
|
string srs_ts_stream2string(SrsTsStream stream)
|
||||||
{
|
{
|
||||||
switch (stream) {
|
switch (stream) {
|
||||||
|
@ -1130,7 +1111,7 @@ int SrsTsAdaptationField::encode(SrsStream* stream)
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/250#issuecomment-71349370
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/250#issuecomment-71349370
|
||||||
int64_t pcrv = program_clock_reference_extension & 0x1ff;
|
int64_t pcrv = program_clock_reference_extension & 0x1ff;
|
||||||
pcrv |= (const1_value0 << 9) & 0x7E00;
|
pcrv |= (const1_value0 << 9) & 0x7E00;
|
||||||
pcrv |= (program_clock_reference_base << 15) & 0x1FFFFFFFF000000;
|
pcrv |= (program_clock_reference_base << 15) & 0x1FFFFFFFF000000LL;
|
||||||
|
|
||||||
pp = (char*)&pcrv;
|
pp = (char*)&pcrv;
|
||||||
*p++ = pp[5];
|
*p++ = pp[5];
|
||||||
|
@ -2783,20 +2764,6 @@ int SrsTsCache::do_cache_aac(SrsAvcAacCodec* codec, SrsCodecSample* sample)
|
||||||
srs_error("invalid aac frame length=%d, ret=%d", size, ret);
|
srs_error("invalid aac frame length=%d, ret=%d", size, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the profile = object_id + 1
|
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
|
||||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
|
||||||
// the valid object type:
|
|
||||||
// AAC Main(ID == 0)
|
|
||||||
// AAC LC(ID == 1)
|
|
||||||
// AAC SSR(ID == 2)
|
|
||||||
// AAC LTP(ID == 3)
|
|
||||||
u_int8_t profile_ObjectType = codec->aac_profile - 1;
|
|
||||||
|
|
||||||
// TODO: FIXME: only support Main or LC.
|
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/310
|
|
||||||
profile_ObjectType = srs_min(1, profile_ObjectType);
|
|
||||||
|
|
||||||
// the frame length is the AAC raw data plus the adts header size.
|
// the frame length is the AAC raw data plus the adts header size.
|
||||||
int32_t frame_length = size + 7;
|
int32_t frame_length = size + 7;
|
||||||
|
@ -2805,12 +2772,12 @@ int SrsTsCache::do_cache_aac(SrsAvcAacCodec* codec, SrsCodecSample* sample)
|
||||||
// 6.2 Audio Data Transport Stream, ADTS
|
// 6.2 Audio Data Transport Stream, ADTS
|
||||||
// in aac-iso-13818-7.pdf, page 26.
|
// in aac-iso-13818-7.pdf, page 26.
|
||||||
// fixed 7bytes header
|
// fixed 7bytes header
|
||||||
static u_int8_t adts_header[7] = {0xff, 0xf1, 0x00, 0x00, 0x00, 0x0f, 0xfc};
|
static u_int8_t adts_header[7] = {0xff, 0xf9, 0x00, 0x00, 0x00, 0x0f, 0xfc};
|
||||||
/*
|
/*
|
||||||
// adts_fixed_header
|
// adts_fixed_header
|
||||||
// 2B, 16bits
|
// 2B, 16bits
|
||||||
int16_t syncword; //12bits, '1111 1111 1111'
|
int16_t syncword; //12bits, '1111 1111 1111'
|
||||||
int8_t ID; //1bit, '0'
|
int8_t ID; //1bit, '1'
|
||||||
int8_t layer; //2bits, '00'
|
int8_t layer; //2bits, '00'
|
||||||
int8_t protection_absent; //1bit, can be '1'
|
int8_t protection_absent; //1bit, can be '1'
|
||||||
// 12bits
|
// 12bits
|
||||||
|
@ -2830,7 +2797,8 @@ int SrsTsCache::do_cache_aac(SrsAvcAacCodec* codec, SrsCodecSample* sample)
|
||||||
int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block()
|
int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block()
|
||||||
*/
|
*/
|
||||||
// profile, 2bits
|
// profile, 2bits
|
||||||
adts_header[2] = (profile_ObjectType << 6) & 0xc0;
|
SrsAacProfile aac_profile = srs_codec_aac_rtmp2ts(codec->aac_object);
|
||||||
|
adts_header[2] = (aac_profile << 6) & 0xc0;
|
||||||
// sampling_frequency_index 4bits
|
// sampling_frequency_index 4bits
|
||||||
adts_header[2] |= (codec->aac_sample_rate << 2) & 0x3c;
|
adts_header[2] |= (codec->aac_sample_rate << 2) & 0x3c;
|
||||||
// channel_configuration 3bits
|
// channel_configuration 3bits
|
||||||
|
|
|
@ -437,7 +437,9 @@ u_int32_t srs_crc32(const void* buf, int size)
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef UINT_MAX
|
||||||
#define UINT_MAX 0xffffffff
|
#define UINT_MAX 0xffffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef AV_RB32
|
#ifndef AV_RB32
|
||||||
# define AV_RB32(x) \
|
# define AV_RB32(x) \
|
||||||
|
|
|
@ -148,6 +148,24 @@ void show_macro_features()
|
||||||
srs_trace("MW(merged-write) default sleep %d", SRS_PERF_MW_SLEEP);
|
srs_trace("MW(merged-write) default sleep %d", SRS_PERF_MW_SLEEP);
|
||||||
srs_trace("read chunk stream cache cid [0, %d)", SRS_PERF_CHUNK_STREAM_CACHE);
|
srs_trace("read chunk stream cache cid [0, %d)", SRS_PERF_CHUNK_STREAM_CACHE);
|
||||||
srs_trace("default gop cache %d, play queue %ds", SRS_PERF_GOP_CACHE, SRS_PERF_PLAY_QUEUE);
|
srs_trace("default gop cache %d, play queue %ds", SRS_PERF_GOP_CACHE, SRS_PERF_PLAY_QUEUE);
|
||||||
|
|
||||||
|
#ifndef SRS_PERF_COMPLEX_SEND
|
||||||
|
srs_warn("complex send algorithm disabled.");
|
||||||
|
#else
|
||||||
|
srs_trace("complex send algorithm enabled.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SRS_PERF_TCP_NODELAY
|
||||||
|
srs_warn("TCP_NODELAY enabled, hurts performance.");
|
||||||
|
#else
|
||||||
|
srs_trace("TCP_NODELAY disabled.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SRS_PERF_SO_SNDBUF_SIZE
|
||||||
|
srs_warn("socket send buffer size %d", SRS_PERF_SO_SNDBUF_SIZE);
|
||||||
|
#else
|
||||||
|
srs_trace("auto guess socket send buffer by merged write");
|
||||||
|
#endif
|
||||||
|
|
||||||
int possible_mr_latency = 0;
|
int possible_mr_latency = 0;
|
||||||
#ifdef SRS_PERF_MERGED_READ
|
#ifdef SRS_PERF_MERGED_READ
|
||||||
|
@ -159,6 +177,23 @@ void show_macro_features()
|
||||||
|
|
||||||
void check_macro_features()
|
void check_macro_features()
|
||||||
{
|
{
|
||||||
|
// important preset.
|
||||||
|
#ifdef SRS_OSX
|
||||||
|
srs_trace("SRS for OSX");
|
||||||
|
#endif
|
||||||
|
#ifdef SRS_PI
|
||||||
|
srs_trace("SRS for pi");
|
||||||
|
#endif
|
||||||
|
#ifdef SRS_CUBIE
|
||||||
|
srs_trace("SRS for cubieboard");
|
||||||
|
#endif
|
||||||
|
#ifdef SRS_ARM_UBUNTU12
|
||||||
|
srs_trace("SRS for arm(build on ubuntu)");
|
||||||
|
#endif
|
||||||
|
#ifdef SRS_MIPS_UBUNTU12
|
||||||
|
srs_trace("SRS for mips(build on ubuntu)");
|
||||||
|
#endif
|
||||||
|
|
||||||
// for special features.
|
// for special features.
|
||||||
#ifndef SRS_PERF_MERGED_READ
|
#ifndef SRS_PERF_MERGED_READ
|
||||||
srs_warn("MR(merged-read) is disabled, hurts read performance. @see %s", RTMP_SIG_SRS_ISSUES(241));
|
srs_warn("MR(merged-read) is disabled, hurts read performance. @see %s", RTMP_SIG_SRS_ISSUES(241));
|
||||||
|
@ -170,6 +205,15 @@ void check_macro_features()
|
||||||
#warning "using develop SRS, please use release instead."
|
#warning "using develop SRS, please use release instead."
|
||||||
srs_warn("SRS %s is develop branch, please use %s instead", RTMP_SIG_SRS_VERSION, RTMP_SIG_SRS_RELEASE);
|
srs_warn("SRS %s is develop branch, please use %s instead", RTMP_SIG_SRS_VERSION, RTMP_SIG_SRS_RELEASE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SRS_AUTO_STREAM_CASTER)
|
||||||
|
#warning "stream caster is experiment feature."
|
||||||
|
srs_warn("stream caster is experiment feature.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SRS_PERF_SO_SNDBUF_SIZE) && !defined(SRS_PERF_MW_SO_SNDBUF)
|
||||||
|
#error "SRS_PERF_SO_SNDBUF_SIZE depends on SRS_PERF_MW_SO_SNDBUF"
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,8 +274,8 @@ int main(int argc, char** argv)
|
||||||
srs_trace("conf: %s, limit: %d", _srs_config->config().c_str(), _srs_config->get_max_connections());
|
srs_trace("conf: %s, limit: %d", _srs_config->config().c_str(), _srs_config->get_max_connections());
|
||||||
|
|
||||||
// features
|
// features
|
||||||
show_macro_features();
|
|
||||||
check_macro_features();
|
check_macro_features();
|
||||||
|
show_macro_features();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* we do nothing in the constructor of server,
|
* we do nothing in the constructor of server,
|
||||||
|
@ -314,6 +358,10 @@ int run_master()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret = _srs_server->http_handle()) != ERROR_SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ret = _srs_server->ingest()) != ERROR_SUCCESS) {
|
if ((ret = _srs_server->ingest()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,8 +329,8 @@ int SrsRawAacStream::adts_demux(SrsStream* stream, char** pframe, int* pnb_frame
|
||||||
int adts_header_start = stream->pos();
|
int adts_header_start = stream->pos();
|
||||||
|
|
||||||
// decode the ADTS.
|
// decode the ADTS.
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75,
|
// @see aac-iso-13818-7.pdf, page 26
|
||||||
// 1.A.2.2 Audio_Data_Transport_Stream frame, ADTS
|
// 6.2 Audio Data Transport Stream, ADTS
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885
|
||||||
// byte_alignment()
|
// byte_alignment()
|
||||||
|
|
||||||
|
@ -356,55 +356,63 @@ int SrsRawAacStream::adts_demux(SrsStream* stream, char** pframe, int* pnb_frame
|
||||||
return ERROR_AAC_REQUIRED_ADTS;
|
return ERROR_AAC_REQUIRED_ADTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syncword 12 bslbf
|
// syncword 12 bslbf
|
||||||
stream->read_1bytes();
|
stream->read_1bytes();
|
||||||
// 4bits left.
|
// 4bits left.
|
||||||
// adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS
|
// adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS
|
||||||
// ID 1 bslbf
|
// ID 1 bslbf
|
||||||
// Layer 2 uimsbf
|
// layer 2 uimsbf
|
||||||
// protection_absent 1 bslbf
|
// protection_absent 1 bslbf
|
||||||
int8_t fh0 = (stream->read_1bytes() & 0x0f);
|
int8_t pav = (stream->read_1bytes() & 0x0f);
|
||||||
/*int8_t fh_id = (fh0 >> 3) & 0x01;*/
|
int8_t id = (pav >> 3) & 0x01;
|
||||||
/*int8_t fh_layer = (fh0 >> 1) & 0x03;*/
|
/*int8_t layer = (pav >> 1) & 0x03;*/
|
||||||
int8_t fh_protection_absent = fh0 & 0x01;
|
int8_t protection_absent = pav & 0x01;
|
||||||
|
|
||||||
int16_t fh1 = stream->read_2bytes();
|
/**
|
||||||
// Profile_ObjectType 2 uimsbf
|
* ID: MPEG identifier, set to ‘1’ if the audio data in the ADTS stream are MPEG-2 AAC (See ISO/IEC 13818-7)
|
||||||
|
* and set to ‘0’ if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3.
|
||||||
|
*/
|
||||||
|
if (id != 0x01) {
|
||||||
|
ret = ERROR_ADTS_ID_NOT_AAC;
|
||||||
|
srs_warn("adts: id must be 1(aac), actual 0(mp4a). ret=%d", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t sfiv = stream->read_2bytes();
|
||||||
|
// profile 2 uimsbf
|
||||||
// sampling_frequency_index 4 uimsbf
|
// sampling_frequency_index 4 uimsbf
|
||||||
// private_bit 1 bslbf
|
// private_bit 1 bslbf
|
||||||
// channel_configuration 3 uimsbf
|
// channel_configuration 3 uimsbf
|
||||||
// original/copy 1 bslbf
|
// original/copy 1 bslbf
|
||||||
// home 1 bslbf
|
// home 1 bslbf
|
||||||
int8_t audioObjectType = (fh1 >> 14) & 0x03;
|
int8_t profile = (sfiv >> 14) & 0x03;
|
||||||
int8_t samplingFrequencyIndex = (fh1 >> 10) & 0x0f;
|
int8_t sampling_frequency_index = (sfiv >> 10) & 0x0f;
|
||||||
/*int8_t fh_private_bit = (fh1 >> 9) & 0x01;*/
|
/*int8_t private_bit = (sfiv >> 9) & 0x01;*/
|
||||||
int8_t channelConfiguration = (fh1 >> 6) & 0x07;
|
int8_t channel_configuration = (sfiv >> 6) & 0x07;
|
||||||
/*int8_t fh_original = (fh1 >> 5) & 0x01;*/
|
/*int8_t original = (sfiv >> 5) & 0x01;*/
|
||||||
/*int8_t fh_home = (fh1 >> 4) & 0x01;*/
|
/*int8_t home = (sfiv >> 4) & 0x01;*/
|
||||||
// @remark, Emphasis is removed,
|
//int8_t Emphasis; @remark, Emphasis is removed, @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736
|
|
||||||
//int8_t fh_Emphasis = (fh1 >> 2) & 0x03;
|
|
||||||
// 4bits left.
|
// 4bits left.
|
||||||
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
|
// adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS
|
||||||
// copyright_identification_bit 1 bslbf
|
// copyright_identification_bit 1 bslbf
|
||||||
// copyright_identification_start 1 bslbf
|
// copyright_identification_start 1 bslbf
|
||||||
/*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/
|
/*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/
|
||||||
/*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/
|
/*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/
|
||||||
// aac_frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.
|
// frame_length 13 bslbf: Length of the frame including headers and error_check in bytes.
|
||||||
// use the left 2bits as the 13 and 12 bit,
|
// use the left 2bits as the 13 and 12 bit,
|
||||||
// the aac_frame_length is 13bits, so we move 13-2=11.
|
// the frame_length is 13bits, so we move 13-2=11.
|
||||||
int16_t fh_aac_frame_length = (fh1 << 11) & 0x1800;
|
int16_t frame_length = (sfiv << 11) & 0x1800;
|
||||||
|
|
||||||
int32_t fh2 = stream->read_3bytes();
|
int32_t abfv = stream->read_3bytes();
|
||||||
// aac_frame_length 13 bslbf: consume the first 13-2=11bits
|
// frame_length 13 bslbf: consume the first 13-2=11bits
|
||||||
// the fh2 is 24bits, so we move right 24-11=13.
|
// the fh2 is 24bits, so we move right 24-11=13.
|
||||||
fh_aac_frame_length |= (fh2 >> 13) & 0x07ff;
|
frame_length |= (abfv >> 13) & 0x07ff;
|
||||||
// adts_buffer_fullness 11 bslbf
|
// adts_buffer_fullness 11 bslbf
|
||||||
/*int16_t fh_adts_buffer_fullness = (fh2 >> 2) & 0x7ff;*/
|
/*int16_t fh_adts_buffer_fullness = (abfv >> 2) & 0x7ff;*/
|
||||||
// no_raw_data_blocks_in_frame 2 uimsbf
|
// number_of_raw_data_blocks_in_frame 2 uimsbf
|
||||||
/*int16_t fh_no_raw_data_blocks_in_frame = fh2 & 0x03;*/
|
/*int16_t number_of_raw_data_blocks_in_frame = abfv & 0x03;*/
|
||||||
// adts_error_check(), 1.A.2.2.3 Error detection
|
// adts_error_check(), 1.A.2.2.3 Error detection
|
||||||
if (!fh_protection_absent) {
|
if (!protection_absent) {
|
||||||
if (!stream->require(2)) {
|
if (!stream->require(2)) {
|
||||||
return ERROR_AAC_ADTS_HEADER;
|
return ERROR_AAC_ADTS_HEADER;
|
||||||
}
|
}
|
||||||
|
@ -412,47 +420,38 @@ int SrsRawAacStream::adts_demux(SrsStream* stream, char** pframe, int* pnb_frame
|
||||||
/*int16_t crc_check = */stream->read_2bytes();
|
/*int16_t crc_check = */stream->read_2bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check the samplingFrequencyIndex
|
// TODO: check the sampling_frequency_index
|
||||||
// TODO: check the channelConfiguration
|
// TODO: check the channel_configuration
|
||||||
|
|
||||||
// raw_data_blocks
|
// raw_data_blocks
|
||||||
int adts_header_size = stream->pos() - adts_header_start;
|
int adts_header_size = stream->pos() - adts_header_start;
|
||||||
int raw_data_size = fh_aac_frame_length - adts_header_size;
|
int raw_data_size = frame_length - adts_header_size;
|
||||||
if (!stream->require(raw_data_size)) {
|
if (!stream->require(raw_data_size)) {
|
||||||
return ERROR_AAC_ADTS_HEADER;
|
return ERROR_AAC_ADTS_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the profile = object_id + 1
|
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
|
||||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
|
||||||
char aac_profile = audioObjectType + 1;
|
|
||||||
|
|
||||||
// the codec info.
|
// the codec info.
|
||||||
codec.protection_absent = fh_protection_absent;
|
codec.protection_absent = protection_absent;
|
||||||
codec.Profile_ObjectType = audioObjectType;
|
codec.aac_object = srs_codec_aac_ts2rtmp((SrsAacProfile)profile);
|
||||||
codec.sampling_frequency_index = samplingFrequencyIndex;
|
codec.sampling_frequency_index = sampling_frequency_index;
|
||||||
codec.channel_configuration = channelConfiguration;
|
codec.channel_configuration = channel_configuration;
|
||||||
codec.aac_frame_length = fh_aac_frame_length;
|
codec.frame_length = frame_length;
|
||||||
|
|
||||||
codec.aac_profile = aac_profile;
|
|
||||||
codec.aac_samplerate = samplingFrequencyIndex;
|
|
||||||
codec.aac_channel = channelConfiguration;
|
|
||||||
|
|
||||||
// @see srs_audio_write_raw_frame().
|
// @see srs_audio_write_raw_frame().
|
||||||
codec.sound_format = 10; // AAC
|
codec.sound_format = 10; // AAC
|
||||||
if (samplingFrequencyIndex <= 0x0c && samplingFrequencyIndex > 0x0a) {
|
if (sampling_frequency_index <= 0x0c && sampling_frequency_index > 0x0a) {
|
||||||
codec.sound_rate = SrsCodecAudioSampleRate5512;
|
codec.sound_rate = SrsCodecAudioSampleRate5512;
|
||||||
} else if (samplingFrequencyIndex <= 0x0a && samplingFrequencyIndex > 0x07) {
|
} else if (sampling_frequency_index <= 0x0a && sampling_frequency_index > 0x07) {
|
||||||
codec.sound_rate = SrsCodecAudioSampleRate11025;
|
codec.sound_rate = SrsCodecAudioSampleRate11025;
|
||||||
} else if (samplingFrequencyIndex <= 0x07 && samplingFrequencyIndex > 0x04) {
|
} else if (sampling_frequency_index <= 0x07 && sampling_frequency_index > 0x04) {
|
||||||
codec.sound_rate = SrsCodecAudioSampleRate22050;
|
codec.sound_rate = SrsCodecAudioSampleRate22050;
|
||||||
} else if (samplingFrequencyIndex <= 0x04) {
|
} else if (sampling_frequency_index <= 0x04) {
|
||||||
codec.sound_rate = SrsCodecAudioSampleRate44100;
|
codec.sound_rate = SrsCodecAudioSampleRate44100;
|
||||||
} else {
|
} else {
|
||||||
codec.sound_rate = SrsCodecAudioSampleRate44100;
|
codec.sound_rate = SrsCodecAudioSampleRate44100;
|
||||||
srs_warn("adts invalid sample rate for flv, rate=%#x", samplingFrequencyIndex);
|
srs_warn("adts invalid sample rate for flv, rate=%#x", sampling_frequency_index);
|
||||||
}
|
}
|
||||||
codec.sound_size = srs_max(0, srs_min(1, channelConfiguration - 1));
|
codec.sound_size = srs_max(0, srs_min(1, channel_configuration - 1));
|
||||||
// TODO: FIXME: finger it out the sound size by adts.
|
// TODO: FIXME: finger it out the sound size by adts.
|
||||||
codec.sound_size = 1; // 0(8bits) or 1(16bits).
|
codec.sound_size = 1; // 0(8bits) or 1(16bits).
|
||||||
|
|
||||||
|
@ -472,16 +471,13 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
// only support aac profile 1-4.
|
// only support aac profile 1-4.
|
||||||
if (codec->aac_profile < 1 || codec->aac_profile > 4) {
|
if (codec->aac_object == SrsAacObjectTypeReserved) {
|
||||||
return ERROR_AAC_DATA_INVALID;
|
return ERROR_AAC_DATA_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the profile = object_id + 1
|
SrsAacObjectType audioObjectType = codec->aac_object;
|
||||||
// @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 78,
|
char channelConfiguration = codec->channel_configuration;
|
||||||
// Table 1. A.9 ¨C MPEG-2 Audio profiles and MPEG-4 Audio object types
|
char samplingFrequencyIndex = codec->sampling_frequency_index;
|
||||||
char profile_ObjectType = codec->aac_profile - 1;
|
|
||||||
char channelConfiguration = codec->aac_channel;
|
|
||||||
char samplingFrequencyIndex = codec->aac_samplerate;
|
|
||||||
|
|
||||||
// override the aac samplerate by user specified.
|
// override the aac samplerate by user specified.
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899
|
||||||
|
@ -503,7 +499,7 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh
|
||||||
// AudioSpecificConfig (), page 33
|
// AudioSpecificConfig (), page 33
|
||||||
// 1.6.2.1 AudioSpecificConfig
|
// 1.6.2.1 AudioSpecificConfig
|
||||||
// audioObjectType; 5 bslbf
|
// audioObjectType; 5 bslbf
|
||||||
ch = (profile_ObjectType << 3) & 0xf8;
|
ch = (audioObjectType << 3) & 0xf8;
|
||||||
// 3bits left.
|
// 3bits left.
|
||||||
|
|
||||||
// samplingFrequencyIndex; 4 bslbf
|
// samplingFrequencyIndex; 4 bslbf
|
||||||
|
|
|
@ -32,6 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <srs_kernel_codec.hpp>
|
||||||
|
|
||||||
class SrsStream;
|
class SrsStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,15 +94,10 @@ public:
|
||||||
struct SrsRawAacStreamCodec
|
struct SrsRawAacStreamCodec
|
||||||
{
|
{
|
||||||
int8_t protection_absent;
|
int8_t protection_absent;
|
||||||
int8_t Profile_ObjectType;
|
SrsAacObjectType aac_object;
|
||||||
int8_t sampling_frequency_index;
|
int8_t sampling_frequency_index;
|
||||||
int8_t channel_configuration;
|
int8_t channel_configuration;
|
||||||
int16_t aac_frame_length;
|
int16_t frame_length;
|
||||||
|
|
||||||
// calc by Profile_ObjectType+1
|
|
||||||
char aac_profile;
|
|
||||||
char aac_samplerate;
|
|
||||||
char aac_channel;
|
|
||||||
|
|
||||||
char sound_format;
|
char sound_format;
|
||||||
char sound_rate;
|
char sound_rate;
|
||||||
|
|
|
@ -62,6 +62,16 @@ SrsFastBuffer::SrsFastBuffer()
|
||||||
p = end = buffer;
|
p = end = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsFastBuffer::size()
|
||||||
|
{
|
||||||
|
return end - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* SrsFastBuffer::bytes()
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsFastBuffer::set_buffer(int buffer_size)
|
void SrsFastBuffer::set_buffer(int buffer_size)
|
||||||
{
|
{
|
||||||
// the user-space buffer size limit to a max value.
|
// the user-space buffer size limit to a max value.
|
||||||
|
|
|
@ -85,6 +85,16 @@ public:
|
||||||
SrsFastBuffer();
|
SrsFastBuffer();
|
||||||
virtual ~SrsFastBuffer();
|
virtual ~SrsFastBuffer();
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* get the size of current bytes in buffer.
|
||||||
|
*/
|
||||||
|
virtual int size();
|
||||||
|
/**
|
||||||
|
* get the current bytes in buffer.
|
||||||
|
* @remark user should use read_slice() if possible,
|
||||||
|
* the bytes() is used to test bytes, for example, to detect the bytes schema.
|
||||||
|
*/
|
||||||
|
virtual char* bytes();
|
||||||
/**
|
/**
|
||||||
* create buffer with specifeid size.
|
* create buffer with specifeid size.
|
||||||
* @param buffer the size of buffer.
|
* @param buffer the size of buffer.
|
||||||
|
@ -110,6 +120,8 @@ public:
|
||||||
* skip some bytes in buffer.
|
* skip some bytes in buffer.
|
||||||
* @param size the bytes to skip. positive to next; negative to previous.
|
* @param size the bytes to skip. positive to next; negative to previous.
|
||||||
* @remark assert buffer already grow(size).
|
* @remark assert buffer already grow(size).
|
||||||
|
* @remark always use read_slice to consume bytes, which will reset for EOF.
|
||||||
|
* while skip never consume bytes.
|
||||||
*/
|
*/
|
||||||
virtual void skip(int size);
|
virtual void skip(int size);
|
||||||
public:
|
public:
|
||||||
|
@ -130,6 +142,7 @@ public:
|
||||||
* @param v true to ename merged read.
|
* @param v true to ename merged read.
|
||||||
* @param handler the handler when merge read is enabled.
|
* @param handler the handler when merge read is enabled.
|
||||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
|
||||||
|
* @remark the merged read is optional, ignore if not specifies.
|
||||||
*/
|
*/
|
||||||
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
|
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -116,7 +116,6 @@ namespace _srs_internal
|
||||||
// @remark, if no key, use EVP_Digest to digest,
|
// @remark, if no key, use EVP_Digest to digest,
|
||||||
// for instance, in python, hashlib.sha256(data).digest().
|
// for instance, in python, hashlib.sha256(data).digest().
|
||||||
HMAC_CTX_init(&ctx);
|
HMAC_CTX_init(&ctx);
|
||||||
|
|
||||||
if (HMAC_Init_ex(&ctx, __key, key_size, EVP_sha256(), NULL) < 0) {
|
if (HMAC_Init_ex(&ctx, __key, key_size, EVP_sha256(), NULL) < 0) {
|
||||||
ret = ERROR_OpenSslSha256Init;
|
ret = ERROR_OpenSslSha256Init;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -762,8 +762,9 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
#ifdef SRS_PERF_COMPLEX_SEND
|
||||||
int iov_index = 0;
|
int iov_index = 0;
|
||||||
iovec* iov = out_iovs + iov_index;
|
iovec* iovs = out_iovs + iov_index;
|
||||||
|
|
||||||
int c0c3_cache_index = 0;
|
int c0c3_cache_index = 0;
|
||||||
char* c0c3_cache = out_c0c3_caches + c0c3_cache_index;
|
char* c0c3_cache = out_c0c3_caches + c0c3_cache_index;
|
||||||
|
@ -796,13 +797,13 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
srs_assert(nbh > 0);
|
srs_assert(nbh > 0);
|
||||||
|
|
||||||
// header iov
|
// header iov
|
||||||
iov[0].iov_base = c0c3_cache;
|
iovs[0].iov_base = c0c3_cache;
|
||||||
iov[0].iov_len = nbh;
|
iovs[0].iov_len = nbh;
|
||||||
|
|
||||||
// payload iov
|
// payload iov
|
||||||
int payload_size = srs_min(out_chunk_size, pend - p);
|
int payload_size = srs_min(out_chunk_size, pend - p);
|
||||||
iov[1].iov_base = p;
|
iovs[1].iov_base = p;
|
||||||
iov[1].iov_len = payload_size;
|
iovs[1].iov_len = payload_size;
|
||||||
|
|
||||||
// consume sendout bytes.
|
// consume sendout bytes.
|
||||||
p += payload_size;
|
p += payload_size;
|
||||||
|
@ -822,7 +823,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
|
|
||||||
// to next pair of iovs
|
// to next pair of iovs
|
||||||
iov_index += 2;
|
iov_index += 2;
|
||||||
iov = out_iovs + iov_index;
|
iovs = out_iovs + iov_index;
|
||||||
|
|
||||||
// to next c0c3 header cache
|
// to next c0c3 header cache
|
||||||
c0c3_cache_index += nbh;
|
c0c3_cache_index += nbh;
|
||||||
|
@ -849,7 +850,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
// reset caches, while these cache ensure
|
// reset caches, while these cache ensure
|
||||||
// atleast we can sendout a chunk.
|
// atleast we can sendout a chunk.
|
||||||
iov_index = 0;
|
iov_index = 0;
|
||||||
iov = out_iovs + iov_index;
|
iovs = out_iovs + iov_index;
|
||||||
|
|
||||||
c0c3_cache_index = 0;
|
c0c3_cache_index = 0;
|
||||||
c0c3_cache = out_c0c3_caches + c0c3_cache_index;
|
c0c3_cache = out_c0c3_caches + c0c3_cache_index;
|
||||||
|
@ -866,6 +867,61 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
||||||
nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);
|
nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs);
|
||||||
|
|
||||||
return do_iovs_send(out_iovs, iov_index);
|
return do_iovs_send(out_iovs, iov_index);
|
||||||
|
#else
|
||||||
|
// try to send use the c0c3 header cache,
|
||||||
|
// if cache is consumed, try another loop.
|
||||||
|
for (int i = 0; i < nb_msgs; i++) {
|
||||||
|
SrsSharedPtrMessage* msg = msgs[i];
|
||||||
|
|
||||||
|
if (!msg) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore empty message.
|
||||||
|
if (!msg->payload || msg->size <= 0) {
|
||||||
|
srs_info("ignore empty message.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// p set to current write position,
|
||||||
|
// it's ok when payload is NULL and size is 0.
|
||||||
|
char* p = msg->payload;
|
||||||
|
char* pend = msg->payload + msg->size;
|
||||||
|
|
||||||
|
// always write the header event payload is empty.
|
||||||
|
while (p < pend) {
|
||||||
|
// for simple send, send each chunk one by one
|
||||||
|
iovec* iovs = out_iovs;
|
||||||
|
char* c0c3_cache = out_c0c3_caches;
|
||||||
|
int nb_cache = SRS_CONSTS_C0C3_HEADERS_MAX;
|
||||||
|
|
||||||
|
// always has header
|
||||||
|
int nbh = msg->chunk_header(c0c3_cache, nb_cache, p == msg->payload);
|
||||||
|
srs_assert(nbh > 0);
|
||||||
|
|
||||||
|
// header iov
|
||||||
|
iovs[0].iov_base = c0c3_cache;
|
||||||
|
iovs[0].iov_len = nbh;
|
||||||
|
|
||||||
|
// payload iov
|
||||||
|
int payload_size = srs_min(out_chunk_size, pend - p);
|
||||||
|
iovs[1].iov_base = p;
|
||||||
|
iovs[1].iov_len = payload_size;
|
||||||
|
|
||||||
|
// consume sendout bytes.
|
||||||
|
p += payload_size;
|
||||||
|
|
||||||
|
if ((ret = skt->writev(iovs, 2, NULL)) != ERROR_SUCCESS) {
|
||||||
|
if (!srs_is_client_gracefully_close(ret)) {
|
||||||
|
srs_error("send packet with writev failed. ret=%d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsProtocol::do_iovs_send(iovec* iovs, int size)
|
int SrsProtocol::do_iovs_send(iovec* iovs, int size)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -460,17 +460,17 @@ VOID TEST(ConfigReloadTest, ReloadPithyPrint)
|
||||||
MockSrsReloadConfig conf;
|
MockSrsReloadConfig conf;
|
||||||
|
|
||||||
conf.subscribe(&handler);
|
conf.subscribe(&handler);
|
||||||
EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"pithy_print {publish 1000;}"));
|
EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"pithy_print_ms 1000;"));
|
||||||
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print {publish 1000;}"));
|
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print_ms 1000;"));
|
||||||
EXPECT_TRUE(handler.all_false());
|
EXPECT_TRUE(handler.all_false());
|
||||||
handler.reset();
|
handler.reset();
|
||||||
|
|
||||||
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print {publish 2000;}"));
|
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print_ms 2000;"));
|
||||||
EXPECT_TRUE(handler.pithy_print_reloaded);
|
EXPECT_TRUE(handler.pithy_print_reloaded);
|
||||||
EXPECT_EQ(1, handler.count_true());
|
EXPECT_EQ(1, handler.count_true());
|
||||||
handler.reset();
|
handler.reset();
|
||||||
|
|
||||||
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print {publish 1000;}"));
|
EXPECT_TRUE(ERROR_SUCCESS == conf.reload(_MIN_OK_CONF"pithy_print_ms 1000;"));
|
||||||
EXPECT_EQ(1, handler.count_true());
|
EXPECT_EQ(1, handler.count_true());
|
||||||
handler.reset();
|
handler.reset();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue