diff --git a/README.md b/README.md
index 9a351fc50..614804898 100755
--- a/README.md
+++ b/README.md
@@ -13,22 +13,22 @@ SRS is a RTMP/HLS/WebRTC/SRT/GB28181 streaming cluster, high efficiency, stable
## Usage
-**Step 1:** Get SRS.
+**>>> Step 1:** Get SRS.
```
git clone https://gitee.com/winlinvip/srs.oschina.git srs &&
cd srs/trunk && git remote set-url origin https://github.com/ossrs/srs.git && git pull
```
-> Note: Repository too large? Please clone from these [mirrors](#mirrors) instead.
+> Note: We use [mirrors(gitee)](#mirrors) here, but it's also ok to directly clone by `git clone https://github.com/ossrs/srs.git && cd srs/trunk`
-**Step 2:** Build SRS.
+**>>> Step 2:** Build SRS.
```
./configure && make
```
-> Remark: Recommend Centos6 64bits, please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
+> Remark: Recommend to use Centos7 64bits, please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
> Note: You can also build SRS in docker, please read [docker][docker-dev].
@@ -38,13 +38,16 @@ cd srs/trunk && git remote set-url origin https://github.com/ossrs/srs.git && gi
./objs/srs -c conf/srs.conf
```
-**Whatever**, you can also directly run SRS in [docker][docker-srs3]:
+**>>> Whatever**, you can also directly run SRS in [docker][docker-srs3]:
```
-docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:3
+docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 \
+ registry.cn-hangzhou.aliyuncs.com/ossrs/srs:3
```
-**From here,** strongly recommend to read bellow wikis:
+> Note: Again, we use [ACR](https://cr.console.aliyun.com/) here, you can directly run in docker hub by `docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:3`
+
+**>>> From here,** strongly recommend to read bellow wikis:
* Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP])
* Usage: How to delivery RTMP-Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster])
@@ -169,6 +172,7 @@ For previous versions, please read:
## V3 changes
+* v3.0, 2020-03-28, For [#1250][bug #1250], support macOS, OSX, MacbookPro, Apple Darwin. 3.0.138
* v3.0, 2020-03-21, For [#1629][bug #1629], fix kickoff FLV client bug. 3.0.137
* v3.0, 2020-03-21, For [#1619][bug #1619], configure without utest by default. 3.0.136
* v3.0, 2020-03-21, For [#1651][bug #1651], fix return pnwrite of srs_write_large_iovs. 3.0.135
diff --git a/trunk/.gitignore b/trunk/.gitignore
index 4e90c9b49..4431df72c 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -40,3 +40,4 @@ srs
*.ts
*.h264
*.264
+3rdparty/ffmpeg-4.2-fit
diff --git a/trunk/3rdparty/st-srs/Makefile b/trunk/3rdparty/st-srs/Makefile
index 304d44377..601d3e507 100644
--- a/trunk/3rdparty/st-srs/Makefile
+++ b/trunk/3rdparty/st-srs/Makefile
@@ -128,6 +128,7 @@ OTHER_FLAGS = -Wall
endif
ifeq ($(OS), DARWIN)
+EXTRA_OBJS = $(TARGETDIR)/md_darwin.o
LD = cc
SFLAGS = -fPIC -fno-common
DSO_SUFFIX = dylib
@@ -139,8 +140,8 @@ CFLAGS += -arch ppc
LDFLAGS += -arch ppc
endif
ifeq ($(INTEL), yes)
-CFLAGS += -arch i386 -arch x86_64
-LDFLAGS += -arch i386 -arch x86_64
+CFLAGS += -arch x86_64
+LDFLAGS += -arch x86_64
endif
LDFLAGS += -dynamiclib -install_name /sw/lib/libst.$(MAJOR).$(DSO_SUFFIX) -compatibility_version $(MAJOR) -current_version $(VERSION)
OTHER_FLAGS = -Wall
@@ -313,7 +314,9 @@ endif
# for SRS
# disable examples for ubuntu crossbuild failed.
# @see https://github.com/winlinvip/simple-rtmp-server/issues/308
+ifeq ($(OS), LINUX)
EXAMPLES =
+endif
ifeq ($(OS), DARWIN)
LINKNAME = libst.$(DSO_SUFFIX)
@@ -369,10 +372,13 @@ $(HEADER): public.h
$(TARGETDIR)/md.o: md.S
$(CC) $(CFLAGS) -c $< -o $@
+$(TARGETDIR)/md_darwin.o: md_darwin.S
+ $(CC) $(CFLAGS) -c $< -o $@
+
$(TARGETDIR)/%.o: %.c common.h md.h
$(CC) $(CFLAGS) -c $< -o $@
-examples::
+examples: $(SLIBRARY)
@echo Making $@
@cd $@; $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" OS="$(OS)" TARGETDIR="$(TARGETDIR)"
diff --git a/trunk/3rdparty/st-srs/md.h b/trunk/3rdparty/st-srs/md.h
index dc4ef54c9..8c0a222d6 100644
--- a/trunk/3rdparty/st-srs/md.h
+++ b/trunk/3rdparty/st-srs/md.h
@@ -120,26 +120,30 @@
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
#define MD_HAVE_SOCKLEN_T
- #define MD_SETJMP(env) _setjmp(env)
- #define MD_LONGJMP(env, val) _longjmp(env, val)
+ #define MD_USE_BUILTIN_SETJMP
- #if defined(__ppc__)
- #define MD_JB_SP 0
- #elif defined(__i386__)
- #define MD_JB_SP 9
- #elif defined(__x86_64__)
- #define MD_JB_SP 4
+ #if defined(__amd64__) || defined(__x86_64__)
+ #define JB_SP 12
+ #define MD_GET_SP(_t) *((long *)&((_t)->context[JB_SP]))
#else
#error Unknown CPU architecture
#endif
-
- #define MD_INIT_CONTEXT(_thread, _sp, _main) \
- ST_BEGIN_MACRO \
- if (MD_SETJMP((_thread)->context)) \
- _main(); \
- *((long *)&((_thread)->context[MD_JB_SP])) = (long) (_sp); \
+
+ #define MD_INIT_CONTEXT(_thread, _sp, _main) \
+ ST_BEGIN_MACRO \
+ if (MD_SETJMP((_thread)->context)) \
+ _main(); \
+ MD_GET_SP(_thread) = (long) (_sp); \
ST_END_MACRO
+ #if defined(MD_USE_BUILTIN_SETJMP)
+ #define MD_SETJMP(env) _st_md_cxt_save(env)
+ #define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
+
+ extern int _st_md_cxt_save(jmp_buf env);
+ extern void _st_md_cxt_restore(jmp_buf env, int val);
+ #endif
+
#define MD_GET_UTIME() \
struct timeval tv; \
(void) gettimeofday(&tv, NULL); \
diff --git a/trunk/3rdparty/st-srs/md_darwin.S b/trunk/3rdparty/st-srs/md_darwin.S
new file mode 100644
index 000000000..6cd163d44
--- /dev/null
+++ b/trunk/3rdparty/st-srs/md_darwin.S
@@ -0,0 +1,76 @@
+
+/* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */
+#if !defined(MD_ST_NO_ASM)
+
+#if defined(__amd64__) || defined(__x86_64__)
+
+ /****************************************************************/
+
+ /*
+ * Internal __jmp_buf layout
+ */
+ #define JB_RBX 0
+ #define JB_RBP 1
+ #define JB_R12 2 /* Backup IP, https://www.cnblogs.com/Five100Miles/p/8458561.html */
+ #define JB_R13 3 /* Backup SP, https://www.cnblogs.com/Five100Miles/p/8458561.html */
+ #define JB_R14 4 /* Backup LR, https://www.cnblogs.com/Five100Miles/p/8458561.html */
+ #define JB_R15 5 /* Backup PC, https://www.cnblogs.com/Five100Miles/p/8458561.html */
+ #define JB_RSP 6
+ #define JB_PC 7
+
+ .file "md_darwin.S"
+ .text
+
+ /* _st_md_cxt_save(__jmp_buf env) */ /* The env is rdi, http://blog.chinaunix.net/uid-20157960-id-1974354.html */
+ .globl __st_md_cxt_save
+ .align 16
+ __st_md_cxt_save:
+ /*
+ * Save registers.
+ */
+ movq %rbx, (JB_RBX*8)(%rdi) /* Save rbx to env[0], *(int64_t*)(rdi+0)=rbx */
+ movq %rbp, (JB_RBP*8)(%rdi) /* Save rbp to env[1], *(int64_t*)(rdi+1)=rbp */
+ movq %r12, (JB_R12*8)(%rdi) /* Save r12 to env[2], *(int64_t*)(rdi+2)=r12 */
+ movq %r13, (JB_R13*8)(%rdi) /* Save r13 to env[3], *(int64_t*)(rdi+3)=r13 */
+ movq %r14, (JB_R14*8)(%rdi) /* Save r14 to env[4], *(int64_t*)(rdi+4)=r14 */
+ movq %r15, (JB_R15*8)(%rdi) /* Save r15 to env[5], *(int64_t*)(rdi+5)=r15 */
+ /* Save SP */
+ leaq 8(%rsp), %rdx /* Save *(int64_t*)(rsp+8) to rdx, https://my.oschina.net/guonaihong/blog/508907 */
+ movq %rdx, (JB_RSP*8)(%rdi) /* Save rdx(rsp) to env[6], *(int64_t*)(rdi+6)=rdx */
+ /* Save PC we are returning to */
+ movq (%rsp), %rax /* Save PC(parent function address) %(rsp) to rax */
+ movq %rax, (JB_PC*8)(%rdi) /* Save rax(PC) to env[7], *(int64_t*)(rdi+7)=rax */
+ xorq %rax, %rax /* Reset rax to 0 */
+ ret
+
+
+ /****************************************************************/
+
+ /* _st_md_cxt_restore(__jmp_buf env, int val) */ /* The env is rdi, val is esi/rsi, http://blog.chinaunix.net/uid-20157960-id-1974354.html */
+ .globl __st_md_cxt_restore
+ .align 16
+ __st_md_cxt_restore:
+ /*
+ * Restore registers.
+ */
+ movq (JB_RBX*8)(%rdi), %rbx /* Load rbx from env[0] */
+ movq (JB_RBP*8)(%rdi), %rbp /* Load rbp from env[1] */
+ movq (JB_R12*8)(%rdi), %r12 /* Load r12 from env[2] */
+ movq (JB_R13*8)(%rdi), %r13 /* Load r13 from env[3] */
+ movq (JB_R14*8)(%rdi), %r14 /* Load r14 from env[4] */
+ movq (JB_R15*8)(%rdi), %r15 /* Load r15 from env[5] */
+ /* Set return value */ /* The esi is param1 val, the eax is return value */
+ test %esi, %esi /* if (!val) { */
+ mov $01, %eax /* val=1; */
+ cmove %eax, %esi /* } */
+ mov %esi, %eax /* return val; */
+ movq (JB_PC*8)(%rdi), %rdx /* Load rdx(PC) from env[7] */
+ movq (JB_RSP*8)(%rdi), %rsp /* Load rsp from env[6] */
+ /* Jump to saved PC */
+ jmpq *%rdx /* Jump to rdx(PC) */
+
+ /****************************************************************/
+
+#endif
+
+#endif
diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh
index b4c04545c..73afc2196 100755
--- a/trunk/auto/auto_headers.sh
+++ b/trunk/auto/auto_headers.sh
@@ -143,6 +143,11 @@ if [ $SRS_CROSS_BUILD = YES ]; then
else
srs_undefine_macro "SRS_AUTO_CROSSBUILD" $SRS_AUTO_HEADERS_H
fi
+if [ $SRS_OSX = YES ]; then
+ srs_define_macro "SRS_AUTO_OSX" $SRS_AUTO_HEADERS_H
+else
+ srs_undefine_macro "SRS_AUTO_OSX" $SRS_AUTO_HEADERS_H
+fi
# prefix
echo "" >> $SRS_AUTO_HEADERS_H
diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh
index a4c8730df..c5248539d 100755
--- a/trunk/auto/depends.sh
+++ b/trunk/auto/depends.sh
@@ -109,6 +109,7 @@ function Ubuntu_prepare()
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
Ubuntu_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "Install tools for ubuntu failed, ret=$ret"; exit $ret; fi
fi
+
#####################################################################################
# for Centos, auto install tools by yum
#####################################################################################
@@ -182,14 +183,105 @@ function Centos_prepare()
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
Centos_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "Install tools for CentOS failed, ret=$ret"; exit $ret; fi
fi
+
+#####################################################################################
+# For OSX, auto install tools by brew
+#####################################################################################
+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
+
+ # cross build for arm, install the cross build tool chain.
+ if [ $SRS_CROSS_BUILD = YES ]; then
+ echo "embeded(arm/mips) is invalid for OSX"
+ return 1
+ fi
+
+ OS_IS_OSX=YES
+ echo "OSX detected, install tools if needed"
+ # 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
+ fi
+
+ 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
+
+ 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
+
#####################################################################################
# for Centos, auto install tools by yum
#####################################################################################
# We must use a bash function instead of variable.
function sed_utility() {
- sed -i "$@"
+ if [ $OS_IS_OSX = YES ]; then
+ sed -i '' "$@"
+ else
+ sed -i "$@"
+ fi
+
ret=$?; if [[ $ret -ne 0 ]]; then
- echo "sed -i \"$@\""
+ if [ $OS_IS_OSX = YES ]; then
+ echo "sed -i '' \"$@\""
+ else
+ echo "sed -i \"$@\""
+ fi
return $ret
fi
}
@@ -204,7 +296,7 @@ SED="sed_utility" && echo "SED is $SED"
# directly build on arm/mips, for example, pi or cubie,
# export srs-librtmp
# others is invalid.
-if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then
+if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $OS_IS_OSX = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then
if [[ $SRS_PI = NO && $SRS_CUBIE = NO && $SRS_CROSS_BUILD = NO ]]; then
echo "Your OS `uname -s` is not supported."
exit 1
diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh
index 4548d819e..bf4ec0ed9 100755
--- a/trunk/auto/options.sh
+++ b/trunk/auto/options.sh
@@ -204,10 +204,6 @@ Remark:
END
}
-function ignore_option() {
- echo "ignore option \"$option\""
-}
-
function parse_user_option() {
case "$option" in
-h) help=yes ;;
@@ -297,16 +293,16 @@ function parse_user_option() {
--with-hls) SRS_HLS=YES ;;
--with-dvr) SRS_DVR=YES ;;
- --without-stream-caster) ignore_option ;;
- --without-ingest) ignore_option ;;
- --without-ssl) ignore_option ;;
- --without-stat) ignore_option ;;
- --without-transcode) ignore_option ;;
- --without-http-callback) ignore_option ;;
- --without-http-server) ignore_option ;;
- --without-http-api) ignore_option ;;
- --without-hls) ignore_option ;;
- --without-dvr) ignore_option ;;
+ --without-stream-caster) echo "ignore option \"$option\"" ;;
+ --without-ingest) echo "ignore option \"$option\"" ;;
+ --without-ssl) echo "ignore option \"$option\"" ;;
+ --without-stat) echo "ignore option \"$option\"" ;;
+ --without-transcode) echo "ignore option \"$option\"" ;;
+ --without-http-callback) echo "ignore option \"$option\"" ;;
+ --without-http-server) echo "ignore option \"$option\"" ;;
+ --without-http-api) echo "ignore option \"$option\"" ;;
+ --without-hls) echo "ignore option \"$option\"" ;;
+ --without-dvr) echo "ignore option \"$option\"" ;;
*)
echo "$0: error: invalid option \"$option\""
@@ -575,16 +571,16 @@ function check_option_conflicts() {
echo "For crossbuild, must not use default toolchain, cc: $SRS_TOOL_CC, cxx: $SRS_TOOL_CXX, ar: $SRS_TOOL_AR"; exit -1
fi
- if [ $SRS_OSX = YES ]; then
- echo "We don't support OSX, please use docker https://github.com/ossrs/srs-docker"; exit -1
- fi
-
if [[ $SRS_NGINX == YES ]]; then
- echo "Don't support building NGINX, please use docker https://github.com/ossrs/srs-docker"; exit -1
+ echo "Don't support building NGINX, please use docker https://github.com/ossrs/srs-docker"; exit -1;
fi
if [[ $SRS_FFMPEG_TOOL == YES ]]; then
- echo "Don't support building FFMPEG, please use docker https://github.com/ossrs/srs-docker"; exit -1
+ echo "Don't support building FFMPEG, please use docker https://github.com/ossrs/srs-docker"; exit -1;
+ fi
+
+ if [[ $SRS_OSX == YES && $SRS_UTEST == YES ]]; then
+ echo "Mac does not support utest."; exit -1;
fi
# TODO: FIXME: check more os.
diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp
index e4fdf4db2..4c80d5b22 100644
--- a/trunk/src/app/srs_app_server.cpp
+++ b/trunk/src/app/srs_app_server.cpp
@@ -30,7 +30,9 @@
#include
#include
#include
+#ifndef SRS_AUTO_OSX
#include
+#endif
using namespace std;
#include
@@ -481,6 +483,7 @@ srs_error_t SrsInotifyWorker::start()
{
srs_error_t err = srs_success;
+#ifndef SRS_AUTO_OSX
// Whether enable auto reload config.
bool auto_reload = _srs_config->inotify_auto_reload();
if (!auto_reload && _srs_in_docker && _srs_config->auto_reload_for_docker()) {
@@ -551,6 +554,7 @@ srs_error_t SrsInotifyWorker::start()
if ((err = trd->start()) != srs_success) {
return srs_error_wrap(err, "inotify");
}
+#endif
return err;
}
@@ -559,6 +563,7 @@ srs_error_t SrsInotifyWorker::cycle()
{
srs_error_t err = srs_success;
+#ifndef SRS_AUTO_OSX
string config_path = _srs_config->config();
string config_file = srs_path_basename(config_path);
string k8s_file = "..data";
@@ -598,6 +603,7 @@ srs_error_t SrsInotifyWorker::cycle()
srs_usleep(3000 * SRS_UTIME_MILLISECONDS);
}
+#endif
return err;
}
@@ -761,7 +767,7 @@ srs_error_t SrsServer::initialize(ISrsServerCycle* ch)
srs_error_t SrsServer::initialize_st()
{
srs_error_t err = srs_success;
-
+
// @remark, st alloc segment use mmap, which only support 32757 threads,
// if need to support more, for instance, 100k threads, define the macro MALLOC_STACK.
// TODO: FIXME: maybe can use "sysctl vm.max_map_count" to refine.
diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp
index 04ece7184..3a7ab640d 100644
--- a/trunk/src/app/srs_app_utility.cpp
+++ b/trunk/src/app/srs_app_utility.cpp
@@ -35,6 +35,9 @@
#include
#include
#include