diff --git a/.circleci/config.yml b/.circleci/config.yml
index e06bed4b4..f11e26526 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -11,7 +11,7 @@ jobs:
- image: ossrs/dev
steps:
- checkout
- - run: cd trunk && ./configure && make && ./objs/srs_utest
+ - run: cd trunk && ./configure --gcov && make && ./objs/srs_utest && bash auto/coverage.sh
workflows:
version: 2
build_and_test:
diff --git a/README.md b/README.md
index c0237bff3..a7a2e7e04 100755
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
# Simple-RTMP-Server
[](https://circleci.com/gh/ossrs/srs/tree/develop)
+[](https://codecov.io/gh/ossrs/srs/branch/develop)
[](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
[
](https://github.com/ossrs/srs/wiki/v1_EN_Contact#skype-or-gitter)
SRS/3.0, [OuXuli][release3]
-SRS是一个简单的流媒体直播集群。
-SRS is a simple live streaming cluster.
+SRS是一个简单的流媒体直播集群,简单的快乐。
+SRS, created on 2013.10, a simple joy, is a simple live streaming cluster.
Download binaries from github.io: [Centos6-x86_64][centos0], [more...][more0]
Download binaries from ossrs.net: [Centos6-x86_64][centos1], [more...][more1]
@@ -14,9 +15,18 @@ About the wiki of SRS/3.0, please read [Chinese][srs_CN] or [English][srs_EN].
> Remark: SRS3 hasn't been released and it's really unstable, please use stable branches such as [SRS2](https://github.com/ossrs/srs/tree/2.0release) or [SRS1](https://github.com/ossrs/srs/tree/1.0release) instead, unless you can fix bugs and debug it.
+> Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries which are distributed using their own licenses, please read [License Mixing][LicenseMixing].
+
+> Remark: About the milestone and product plan, please read ([CN][v1_CN_Product], [EN][v1_EN_Product]) wiki.
+
+> Remark: The origin-edge cluster is released, while the origin-origin cluster is coming soon.
+
+> Remark: We are working on utest now.
+
+Enjoy it!
+
## Content
-* [About](#about)
* [Usage](#usage)
* [Wiki](#srs-30-wiki)
* [Features](#features)
@@ -34,38 +44,6 @@ About the wiki of SRS/3.0, please read [Chinese][srs_CN] or [English][srs_EN].
* [Mirrors](#mirrors)
* [System Requirements](#system-requirements)
-## About
-
-SRS's a simplest, conceptual integrated, industrial-strength live streaming origin cluster.
-
-It's created in 2013.10, by winlin, patched by many developers.
-
-> Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries
-which are distributed using their own licenses, please read [License Mixing][LicenseMixing].
-
-We always choose the best arch to write simplest code.
-It's easy to use for the English and Chinese wikis.
-The embeded HTTP API and tracable log is useful to integrate.
-
-All features are conceptual integrated.
-The live streaming features include RTMP, HTTP-FLV, HLS, HDS and MPEG-DASH, covering major protocols.
-The transform features include DVR, Transcode, Forward and Ingest, which is powerful and convenient.
-The origin-edge and origin-origin clusters provide strong fault-tolerance and load-balance feature.
-User can run SRS on LINUX and OSX, with CPUs such as X86, X64, ARM and MIPS.
-
-> Remark: The origin-edge cluster is released, while the origin-origin cluster is coming soon.
-
-The goal is industrial-strength live streaming origin cluster.
-The utests will cover full use-scenarios to avoid bugs from new code.
-Complex error logs the stack and message from each level.
-The FT and LB cluster make the servies robust.
-
-> Remark: We are working on utest now.
-
-> Remark: About the milestone and product plan, please read ([CN][v1_CN_Product], [EN][v1_EN_Product]) wiki.
-
-Enjoy it!
-
### Usage
diff --git a/trunk/.gitignore b/trunk/.gitignore
index df86e17d2..6ec2ebd1d 100644
--- a/trunk/.gitignore
+++ b/trunk/.gitignore
@@ -34,4 +34,7 @@
/test/
.DS_Store
srs
+*.dSYM/
+*.gcov
+*.ts
diff --git a/trunk/auto/coverage.sh b/trunk/auto/coverage.sh
new file mode 100644
index 000000000..79eef9dfe
--- /dev/null
+++ b/trunk/auto/coverage.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# In .circleci/config.yml, generate *.gcno with
+# ./configure --gcov --without-research --without-librtmp
+# and generate *.gcda by
+# ./objs/srs_utest
+
+# Collect all *.gcno and *.gcda to objs/cover.
+(mkdir -p objs/cover && cd objs/cover &&
+cp -R ../../src . &&
+for file in `find ../src -name "*.gcno"`; do cp $file .; done &&
+for file in `find ../src -name "*.gcda"`; do cp $file .; done)
+ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect *.gcno and *.gcda failed, ret=$ret"; exit $ret; fi
+
+# Generate *.gcov to objs/cover
+for file in `find src -name "*.cpp"`; do
+ (mkdir -p objs/cover && cd objs/cover && gcov ../../$file -o .)
+ ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect $file failed, ret=$ret"; exit $ret; fi
+done
+
+# Upload report with *.gcov
+export CODECOV_TOKEN="493bba46-c468-4e73-8b45-8cdd8ff62d96" &&
+mkdir -p objs/cover && cd objs/cover &&
+bash <(curl -s https://codecov.io/bash)
+exit 0
diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh
index e19bfc9f4..63e9f707d 100755
--- a/trunk/auto/depends.sh
+++ b/trunk/auto/depends.sh
@@ -713,11 +713,13 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
fi
fi
-if [ $SRS_LIBRTMP = YES ]; then
+if [[ $SRS_LIBRTMP == YES ]]; then
mkdir -p ${SRS_OBJS}/research
# librtmp
- (cd ${SRS_WORKDIR}/research/librtmp && mkdir -p objs && ln -sf `pwd`/objs ../../${SRS_OBJS_DIR}/research/librtmp)
+ (cd ${SRS_WORKDIR}/research/librtmp && mkdir -p objs &&
+ rm -rf ../../${SRS_OBJS_DIR}/research/librtmp &&
+ ln -sf `pwd`/objs ../../${SRS_OBJS_DIR}/research/librtmp)
ret=$?; if [[ $ret -ne 0 ]]; then echo "Link research/librtmp failed, ret=$ret"; exit $ret; fi
fi
diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh
index dd8959095..6787d89cf 100755
--- a/trunk/auto/options.sh
+++ b/trunk/auto/options.sh
@@ -43,16 +43,18 @@ SRS_DVR=YES
#
################################################################
# libraries
-SRS_FFMPEG_STUB=RESERVED
+SRS_FFMPEG_STUB=NO
# arguments
SRS_PREFIX=/usr/local/srs
SRS_JOBS=1
-SRS_STATIC=RESERVED
+SRS_STATIC=NO
+# whether enable the gcov
+SRS_GCOV=NO
# whether enable the log verbose/info/trace level.
# always enable the warn/error level.
-SRS_LOG_VERBOSE=RESERVED
-SRS_LOG_INFO=RESERVED
-SRS_LOG_TRACE=RESERVED
+SRS_LOG_VERBOSE=NO
+SRS_LOG_INFO=NO
+SRS_LOG_TRACE=NO
#
################################################################
# experts
@@ -154,7 +156,8 @@ Options:
--without-mips-ubuntu12 do not cross build srs on ubuntu12 for mips.
--prefix= The absolute installation path for srs. Default: $SRS_PREFIX
- --static whether add '-static' to link options.
+ --static Whether add '-static' to link options.
+ --gcov Whether enable the GCOV compiler options.
--jobs[=N] Allow N jobs at once; infinite jobs with no arg.
used for make in the configure, for example, to make ffmpeg.
--log-verbose whether enable the log verbose level. default: no.
@@ -267,6 +270,7 @@ function parse_user_option() {
--log-verbose) SRS_LOG_VERBOSE=YES ;;
--log-info) SRS_LOG_INFO=YES ;;
--log-trace) SRS_LOG_TRACE=YES ;;
+ --gcov) SRS_GCOV=YES ;;
--x86-x64) SRS_X86_X64=YES ;;
--x86-64) SRS_X86_X64=YES ;;
@@ -640,6 +644,7 @@ SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
if [ $SRS_LOG_VERBOSE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-verbose"; fi
if [ $SRS_LOG_INFO = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-info"; fi
if [ $SRS_LOG_TRACE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-trace"; fi
+ if [ $SRS_GCOV = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gcov"; fi
echo "User config: $SRS_AUTO_USER_CONFIGURE"
echo "Detail config: ${SRS_AUTO_CONFIGURE}"
}
diff --git a/trunk/configure b/trunk/configure
index 1f0c96d72..6971c7654 100755
--- a/trunk/configure
+++ b/trunk/configure
@@ -104,6 +104,13 @@ CXXFLAGS="${CXXFLAGS} ${CppStd}${WarnLevel}${GDBDebug}${LibraryCompile}${SrsGpro
if [ $SRS_GPERF = YES ]; then
CXXFLAGS="${CXXFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free";
fi
+# For coverage.
+if [[ $SRS_GCOV == YES ]]; then
+ SrsGcov="-fprofile-arcs -ftest-coverage"
+fi
+if [[ $SRS_GCOV == YES ]]; then
+ CXXFLAGS="${CXXFLAGS} ${SrsGcov}";
+fi
# Start to generate the Makefile.
cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
GCC = gcc
@@ -153,6 +160,10 @@ fi
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
SrsLinkOptions="${SrsLinkOptions} -lgcc_eh";
fi
+# For coverage.
+if [[ $SRS_GCOV == YES ]]; then
+ SrsLinkOptions="${SrsLinkOptions} ${SrsGcov}";
+fi
#####################################################################################
# Modules, compile each module, then link to binary
@@ -499,7 +510,7 @@ librtmp: server
@echo "Building the client publish/play library."
\$(MAKE) -f ${SRS_OBJS_DIR}/${SRS_MAKEFILE} librtmp
@echo "Building the srs-librtmp example."
- (cd research/librtmp; \$(MAKE) ${SrsLibrtmpSampleEntry})
+ (cd research/librtmp; \$(MAKE) EXTRA_CXXFLAGS="${SrsGcov}" ${SrsLibrtmpSampleEntry})
END
else
diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
index df8a6a5ff..4aa190f06 100644
--- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
+++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
@@ -303,6 +303,7 @@
3C1232F21AAEAC7000CE8F6C /* srs-api */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-api"; path = "../../../etc/init.d/srs-api"; sourceTree = ""; };
3C1232F31AAEAC7000CE8F6C /* srs-demo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-demo"; path = "../../../etc/init.d/srs-demo"; sourceTree = ""; };
3C1232F41AAEAC7000CE8F6C /* srs-demo-19350 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = "srs-demo-19350"; path = "../../../etc/init.d/srs-demo-19350"; sourceTree = ""; };
+ 3C1CDBFB2205CE0300A8C08E /* coverage.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = coverage.sh; path = ../../../auto/coverage.sh; sourceTree = ""; };
3C1EE6AC1AB1055800576EE9 /* srs_app_hds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_hds.cpp; path = ../../../src/app/srs_app_hds.cpp; sourceTree = ""; };
3C1EE6AD1AB1055800576EE9 /* srs_app_hds.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_hds.hpp; path = ../../../src/app/srs_app_hds.hpp; sourceTree = ""; };
3C1EE6B01AB1080900576EE9 /* bandwidth.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = bandwidth.conf; path = ../../../conf/bandwidth.conf; sourceTree = ""; };
@@ -446,7 +447,6 @@
3CECAF961EDC100F00C50501 /* sched.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sched.c; path = "../../../objs/state-threads-1.9.1/sched.c"; sourceTree = ""; };
3CECAF971EDC100F00C50501 /* stk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stk.c; path = "../../../objs/state-threads-1.9.1/stk.c"; sourceTree = ""; };
3CECAF981EDC100F00C50501 /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = "../../../objs/state-threads-1.9.1/sync.c"; sourceTree = ""; };
- 3CFBDA271F0338A40054D63E /* circle.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = circle.yml; path = ../../../circle.yml; sourceTree = ""; };
8C0652AF2035B5B9000B0661 /* srs_app_coworkers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_coworkers.hpp; path = ../../../src/app/srs_app_coworkers.hpp; sourceTree = ""; };
8C0652B02035B5B9000B0661 /* srs_app_coworkers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_coworkers.cpp; path = ../../../src/app/srs_app_coworkers.cpp; sourceTree = ""; };
/* End PBXFileReference section */
@@ -731,6 +731,7 @@
3C1232BB1AAE827E00CE8F6C /* apps.sh */,
3C1232BC1AAE827E00CE8F6C /* auto_headers.sh */,
3C1232BD1AAE827E00CE8F6C /* build_ffmpeg.sh */,
+ 3C1CDBFB2205CE0300A8C08E /* coverage.sh */,
3C1232BE1AAE827E00CE8F6C /* depends.sh */,
3C1232BF1AAE827E00CE8F6C /* generate_header.sh */,
3C1232C01AAE827E00CE8F6C /* generate-srs-librtmp-project.sh */,
@@ -825,7 +826,6 @@
3C1EE6D21AB1366500576EE9 /* doc */ = {
isa = PBXGroup;
children = (
- 3CFBDA271F0338A40054D63E /* circle.yml */,
3C1EE6D31AB1367D00576EE9 /* AUTHORS.txt */,
3C1EE6D51AB1367D00576EE9 /* LICENSE */,
3C1EE6D61AB1367D00576EE9 /* README.md */,
diff --git a/trunk/research/librtmp/.gitignore b/trunk/research/librtmp/.gitignore
index 26416673b..f1518d9c3 100644
--- a/trunk/research/librtmp/.gitignore
+++ b/trunk/research/librtmp/.gitignore
@@ -1 +1,3 @@
*.mp4
+*.gcno
+*.gcda
diff --git a/trunk/research/librtmp/Makefile b/trunk/research/librtmp/Makefile
index 00fad0900..0e138bb36 100755
--- a/trunk/research/librtmp/Makefile
+++ b/trunk/research/librtmp/Makefile
@@ -57,15 +57,15 @@ SRS_RESEARCH_DEPS = Makefile
# for x86/x64 platform
ifeq ($(GCC), gcc)
- EXTRA_CXX_FLAG = -g -O0 -ldl -lstdc++ -lm
+ OTHER_FLAGS += -g -O0 -ldl -lstdc++ -lm
endif
# for arm.
ifeq ($(GCC), arm-linux-gnueabi-gcc)
- EXTRA_CXX_FLAG = -g -O0 -ldl -static -lstdc++ -lm
+ OTHER_FLAGS += -g -O0 -ldl -static -lstdc++ -lm
endif
# for mips, add -lgcc_eh, or stl compile failed.
ifeq ($(GCC), mipsel-openwrt-linux-gcc)
- EXTRA_CXX_FLAG = -g -O0 -ldl -lstdc++ -lm -lgcc_eh
+ OTHER_FLAGS += -g -O0 -ldl -lstdc++ -lm -lgcc_eh
endif
# for ssl or nossl
ifeq ($(HANDSHAKE), SSL)
@@ -82,42 +82,44 @@ nossl:
@mkdir -p objs
$(MAKE) HANDSHAKE="NOSSL"
+CXXFLAGS += $(OTHER_FLAGS) $(EXTRA_CXXFLAGS)
+
objs/srs_flv_parser: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L)
- $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_flv_parser
+ $(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_flv_parser
objs/srs_flv_injecter: srs_flv_injecter.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L)
- $(GCC) srs_flv_injecter.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_flv_injecter
+ $(GCC) srs_flv_injecter.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_flv_injecter
objs/srs_publish: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_publish
+ $(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_publish
objs/srs_h264_raw_publish: srs_h264_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_h264_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_h264_raw_publish
+ $(GCC) srs_h264_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_h264_raw_publish
objs/srs_audio_raw_publish: srs_audio_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_audio_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_audio_raw_publish
+ $(GCC) srs_audio_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_audio_raw_publish
objs/srs_aac_raw_publish: srs_aac_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_aac_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_aac_raw_publish
+ $(GCC) srs_aac_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_aac_raw_publish
objs/srs_play: srs_play.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_play.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_play
+ $(GCC) srs_play.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_play
objs/srs_ingest_flv: srs_ingest_flv.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_ingest_flv.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_ingest_flv
+ $(GCC) srs_ingest_flv.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_flv
objs/srs_ingest_mp4: srs_ingest_mp4.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_ingest_mp4.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_ingest_mp4
+ $(GCC) srs_ingest_mp4.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_mp4
objs/srs_ingest_rtmp: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_ingest_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_ingest_rtmp
+ $(GCC) srs_ingest_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_rtmp
objs/srs_detect_rtmp: srs_detect_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_detect_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_detect_rtmp
+ $(GCC) srs_detect_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_detect_rtmp
objs/srs_bandwidth_check: srs_bandwidth_check.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_bandwidth_check.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_bandwidth_check
+ $(GCC) srs_bandwidth_check.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_bandwidth_check
objs/srs_rtmp_dump: srs_rtmp_dump.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
- $(GCC) srs_rtmp_dump.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_rtmp_dump
+ $(GCC) srs_rtmp_dump.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_rtmp_dump
diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp
index c058666b8..8f6451c69 100644
--- a/trunk/src/app/srs_app_hls.cpp
+++ b/trunk/src/app/srs_app_hls.cpp
@@ -458,7 +458,7 @@ srs_error_t SrsHlsMuxer::segment_open()
// open temp ts file.
std::string tmp_file = current->tmppath();
- if ((err = current->tscw->open(tmp_file.c_str())) != srs_success) {
+ if ((err = current->writer->open(tmp_file)) != srs_success) {
return srs_error_wrap(err, "open hls muxer");
}
diff --git a/trunk/src/kernel/srs_kernel_buffer.cpp b/trunk/src/kernel/srs_kernel_buffer.cpp
index 7f919c18a..80cc6055e 100644
--- a/trunk/src/kernel/srs_kernel_buffer.cpp
+++ b/trunk/src/kernel/srs_kernel_buffer.cpp
@@ -251,24 +251,17 @@ void SrsBuffer::write_bytes(char* data, int size)
p += size;
}
-SrsBitBuffer::SrsBitBuffer()
+SrsBitBuffer::SrsBitBuffer(SrsBuffer* b)
{
cb = 0;
cb_left = 0;
- stream = NULL;
+ stream = b;
}
SrsBitBuffer::~SrsBitBuffer()
{
}
-srs_error_t SrsBitBuffer::initialize(SrsBuffer* s) {
- stream = s;
- cb = 0;
- cb_left = 0;
- return srs_success;
-}
-
bool SrsBitBuffer::empty() {
if (cb_left) {
return false;
diff --git a/trunk/src/kernel/srs_kernel_buffer.hpp b/trunk/src/kernel/srs_kernel_buffer.hpp
index 7bec0b9e9..45a5542ce 100644
--- a/trunk/src/kernel/srs_kernel_buffer.hpp
+++ b/trunk/src/kernel/srs_kernel_buffer.hpp
@@ -206,10 +206,9 @@ private:
uint8_t cb_left;
SrsBuffer* stream;
public:
- SrsBitBuffer();
+ SrsBitBuffer(SrsBuffer* b);
virtual ~SrsBitBuffer();
public:
- virtual srs_error_t initialize(SrsBuffer* s);
virtual bool empty();
virtual int8_t read_bit();
};
diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp
index 40143335e..267435ca9 100644
--- a/trunk/src/kernel/srs_kernel_codec.cpp
+++ b/trunk/src/kernel/srs_kernel_codec.cpp
@@ -175,6 +175,14 @@ bool SrsFlvVideo::acceptable(char* data, int size)
return true;
}
+SrsFlvAudio::SrsFlvAudio()
+{
+}
+
+SrsFlvAudio::~SrsFlvAudio()
+{
+}
+
bool SrsFlvAudio::sh(char* data, int size)
{
// sequence header only for aac
@@ -426,7 +434,6 @@ SrsFrame::SrsFrame()
SrsFrame::~SrsFrame()
{
- srs_freep(codec);
}
srs_error_t SrsFrame::initialize(SrsCodecConfig* c)
@@ -887,10 +894,7 @@ srs_error_t SrsFormat::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
return srs_error_new(ERROR_HLS_DECODE_ERROR, "sps the level_idc invalid");
}
- SrsBitBuffer bs;
- if ((err = bs.initialize(&stream)) != srs_success) {
- return srs_error_wrap(err, "init bit buffer");
- }
+ SrsBitBuffer bs(&stream);
int32_t seq_parameter_set_id = -1;
if ((err = srs_avc_nalu_read_uev(&bs, seq_parameter_set_id)) != srs_success) {
@@ -1353,10 +1357,10 @@ srs_error_t SrsFormat::audio_aac_sequence_header_demux(char* data, int size)
// donot force to LC, @see: https://github.com/ossrs/srs/issues/81
// the source will print the sequence header info.
//if (aac_profile > 3) {
- // Mark all extended profiles as LC
- // to make Android as happy as possible.
- // @see: ngx_rtmp_hls_parse_aac_header
- //aac_profile = 1;
+ // Mark all extended profiles as LC
+ // to make Android as happy as possible.
+ // @see: ngx_rtmp_hls_parse_aac_header
+ //aac_profile = 1;
//}
return err;
diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp
index d1a0e867d..aac1c1395 100644
--- a/trunk/src/kernel/srs_kernel_codec.hpp
+++ b/trunk/src/kernel/srs_kernel_codec.hpp
@@ -704,7 +704,7 @@ public:
public:
// for sequence header, whether parse the h.264 sps.
// TODO: FIXME: Refine it.
- bool avc_parse_sps;
+ bool avc_parse_sps;
public:
SrsFormat();
virtual ~SrsFormat();
diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp
index 1f300d25e..2feb3fdf7 100644
--- a/trunk/src/kernel/srs_kernel_flv.cpp
+++ b/trunk/src/kernel/srs_kernel_flv.cpp
@@ -908,6 +908,10 @@ srs_error_t SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart
av_sequence_offset_end = reader->tellg() + data_size + SRS_FLV_PREVIOUS_TAG_SIZE;
reader->skip(data_size + SRS_FLV_PREVIOUS_TAG_SIZE);
}
+
+ if (got_audio && got_video) {
+ break;
+ }
}
// seek to the sequence header start offset.
diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp
index 26ab41841..001b03594 100644
--- a/trunk/src/kernel/srs_kernel_ts.cpp
+++ b/trunk/src/kernel/srs_kernel_ts.cpp
@@ -298,7 +298,7 @@ srs_error_t SrsTsContext::decode(SrsBuffer* stream, ISrsTsHandler* handler)
return err;
}
-srs_error_t SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac)
+srs_error_t SrsTsContext::encode(ISrsStreamWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac)
{
srs_error_t err = srs_success;
@@ -380,7 +380,7 @@ void SrsTsContext::set_sync_byte(int8_t sb)
sync_byte = sb;
}
-srs_error_t SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as)
+srs_error_t SrsTsContext::encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as)
{
srs_error_t err = srs_success;
@@ -441,7 +441,7 @@ srs_error_t SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, Sr
return err;
}
-srs_error_t SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio)
+srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio)
{
srs_error_t err = srs_success;
@@ -752,8 +752,9 @@ SrsTsPacket* SrsTsPacket::create_pat(SrsTsContext* context, int16_t pmt_number,
return pkt;
}
-SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, int16_t pmt_pid, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as)
-{
+SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context,
+ int16_t pmt_number, int16_t pmt_pid, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as
+) {
SrsTsPacket* pkt = new SrsTsPacket(context);
pkt->sync_byte = 0x47;
pkt->transport_error_indicator = 0;
@@ -800,9 +801,9 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number,
}
SrsTsPacket* SrsTsPacket::create_pes_first(SrsTsContext* context,
- int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter, bool discontinuity,
- int64_t pcr, int64_t dts, int64_t pts, int size
- ) {
+ int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter, bool discontinuity,
+ int64_t pcr, int64_t dts, int64_t pts, int size
+) {
SrsTsPacket* pkt = new SrsTsPacket(context);
pkt->sync_byte = 0x47;
pkt->transport_error_indicator = 0;
@@ -2543,7 +2544,7 @@ srs_error_t SrsTsPayloadPMT::psi_encode(SrsBuffer* stream)
return err;
}
-SrsTsContextWriter::SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc)
+SrsTsContextWriter::SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc)
{
writer = w;
context = c;
@@ -2554,25 +2555,6 @@ SrsTsContextWriter::SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAud
SrsTsContextWriter::~SrsTsContextWriter()
{
- close();
-}
-
-srs_error_t SrsTsContextWriter::open(string p)
-{
- srs_error_t err = srs_success;
-
- path = p;
-
- close();
-
- // reset the context for a new ts start.
- context->reset();
-
- if ((err = writer->open(path)) != srs_success) {
- return srs_error_wrap(err, "ts: open writer");
- }
-
- return err;
}
srs_error_t SrsTsContextWriter::write_audio(SrsTsMessage* audio)
@@ -2605,11 +2587,6 @@ srs_error_t SrsTsContextWriter::write_video(SrsTsMessage* video)
return err;
}
-void SrsTsContextWriter::close()
-{
- writer->close();
-}
-
SrsVideoCodecId SrsTsContextWriter::video_codec()
{
return vcodec;
@@ -3011,7 +2988,7 @@ SrsTsTransmuxer::~SrsTsTransmuxer()
srs_freep(context);
}
-srs_error_t SrsTsTransmuxer::initialize(SrsFileWriter* fw)
+srs_error_t SrsTsTransmuxer::initialize(ISrsStreamWriter* fw)
{
srs_error_t err = srs_success;
@@ -3021,20 +2998,12 @@ srs_error_t SrsTsTransmuxer::initialize(SrsFileWriter* fw)
srs_assert(fw);
- if (!fw->is_open()) {
- return srs_error_new(ERROR_KERNEL_FLV_STREAM_CLOSED, "ts: stream is not open");
- }
-
writer = fw;
srs_freep(tscw);
// TODO: FIXME: Support config the codec.
tscw = new SrsTsContextWriter(fw, context, SrsAudioCodecIdAAC, SrsVideoCodecIdAVC);
- if ((err = tscw->open("")) != srs_success) {
- return srs_error_wrap(err, "ts: open writer");
- }
-
return err;
}
diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp
index 3207641b3..c31dd4eb2 100644
--- a/trunk/src/kernel/srs_kernel_ts.hpp
+++ b/trunk/src/kernel/srs_kernel_ts.hpp
@@ -38,7 +38,7 @@
class SrsBuffer;
class SrsTsMessageCache;
class SrsTsContextWriter;
-class SrsFileWriter;
+class ISrsStreamWriter;
class SrsFileReader;
class SrsFormat;
class SrsSimpleStream;
@@ -131,6 +131,7 @@ enum SrsTsStream
{
// ITU-T | ISO/IEC Reserved
SrsTsStreamReserved = 0x00,
+ SrsTsStreamForbidden = 0xff,
// ISO/IEC 11172 Video
// ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
// ISO/IEC 11172 Audio
@@ -402,7 +403,7 @@ public:
* @param vc the video codec, write the PAT/PMT table when changed.
* @param ac the audio codec, write the PAT/PMT table when changed.
*/
- virtual srs_error_t encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac);
+ virtual srs_error_t encode(ISrsStreamWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac);
// drm methods
public:
/**
@@ -411,8 +412,8 @@ public:
*/
virtual void set_sync_byte(int8_t sb);
private:
- virtual srs_error_t encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as);
- virtual srs_error_t encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio);
+ virtual srs_error_t encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as);
+ virtual srs_error_t encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio);
};
/**
@@ -1542,17 +1543,12 @@ private:
SrsAudioCodecId acodec;
private:
SrsTsContext* context;
- SrsFileWriter* writer;
+ ISrsStreamWriter* writer;
std::string path;
public:
- SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc);
+ SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc);
virtual ~SrsTsContextWriter();
public:
- /**
- * open the writer, donot write the PSI of ts.
- * @param p a string indicates the path of ts file to mux to.
- */
- virtual srs_error_t open(std::string p);
/**
* write an audio frame to ts,
*/
@@ -1561,10 +1557,6 @@ public:
* write a video frame to ts,
*/
virtual srs_error_t write_video(SrsTsMessage* video);
- /**
- * close the writer.
- */
- virtual void close();
public:
/**
* get the video codec of ts muxer.
@@ -1627,7 +1619,7 @@ private:
class SrsTsTransmuxer
{
private:
- SrsFileWriter* writer;
+ ISrsStreamWriter* writer;
private:
SrsFormat* format;
SrsTsMessageCache* tsmc;
@@ -1641,7 +1633,7 @@ public:
* initialize the underlayer file stream.
* @param fw the writer to use for ts encoder, user must free it.
*/
- virtual srs_error_t initialize(SrsFileWriter* fw);
+ virtual srs_error_t initialize(ISrsStreamWriter* fw);
public:
/**
* write audio/video packet.
diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp
index ebd00af97..c0dc2bd07 100644
--- a/trunk/src/kernel/srs_kernel_utility.cpp
+++ b/trunk/src/kernel/srs_kernel_utility.cpp
@@ -77,6 +77,10 @@ srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer* stream, int32_t& v)
v = (1 << leadingZeroBits) - 1;
for (int i = 0; i < (int)leadingZeroBits; i++) {
+ if (stream->empty()) {
+ return srs_error_new(ERROR_AVC_NALU_UEV, "no bytes for leadingZeroBits=%d", leadingZeroBits);
+ }
+
int32_t b = stream->read_bit();
v += b << (leadingZeroBits - 1 - i);
}
@@ -97,8 +101,8 @@ srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v)
return err;
}
-static int64_t _srs_system_time_us_cache = 0;
-static int64_t _srs_system_time_startup_time = 0;
+int64_t _srs_system_time_us_cache = 0;
+int64_t _srs_system_time_startup_time = 0;
int64_t srs_get_system_time_ms()
{
@@ -1009,7 +1013,7 @@ uint8_t srs_from_hex_char(uint8_t c)
return -1;
}
-char *srs_data_to_hex(char *des,const u_int8_t *src,int len)
+char* srs_data_to_hex(char* des, const u_int8_t* src, int len)
{
if(src == NULL || len == 0 || des == NULL){
return NULL;
diff --git a/trunk/src/protocol/srs_rtsp_stack.cpp b/trunk/src/protocol/srs_rtsp_stack.cpp
index d10251c54..656737039 100644
--- a/trunk/src/protocol/srs_rtsp_stack.cpp
+++ b/trunk/src/protocol/srs_rtsp_stack.cpp
@@ -232,10 +232,7 @@ srs_error_t SrsRtpPacket::decode_97(SrsBuffer* stream)
int required_size = 0;
// append left bytes to payload.
- payload->append(
- stream->data() + stream->pos() + au_size,
- stream->size() - stream->pos() - au_size
- );
+ payload->append(stream->data() + stream->pos() + au_size, stream->size() - stream->pos() - au_size);
char* p = payload->bytes();
for (int i = 0; i < au_size; i += 2) {
diff --git a/trunk/src/utest/srs_utest.hpp b/trunk/src/utest/srs_utest.hpp
index 05c87996a..26691c743 100644
--- a/trunk/src/utest/srs_utest.hpp
+++ b/trunk/src/utest/srs_utest.hpp
@@ -33,36 +33,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
-#define SRS_UTEST_DEV
-#undef SRS_UTEST_DEV
-
-// enable all utest.
-#ifndef SRS_UTEST_DEV
- #define ENABLE_UTEST_AMF0
- #define ENABLE_UTEST_CONFIG
- #define ENABLE_UTEST_CORE
- #define ENABLE_UTEST_KERNEL
- #define ENABLE_UTEST_PROTOCOL
- #define ENABLE_UTEST_RELOAD
-#endif
-
-// disable some for fast dev, compile and startup.
-#ifdef SRS_UTEST_DEV
- #undef ENABLE_UTEST_AMF0
- #undef ENABLE_UTEST_CONFIG
- #undef ENABLE_UTEST_CORE
- #undef ENABLE_UTEST_KERNEL
- #undef ENABLE_UTEST_PROTOCOL
- #undef ENABLE_UTEST_RELOAD
-#endif
-
-#ifdef SRS_UTEST_DEV
- #define ENABLE_UTEST_RELOAD
-#endif
-
// we add an empty macro for upp to show the smart tips.
#define VOID
+// Public all private and protected members.
+#define private public
+#define protected public
+
// the asserts of gtest:
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp
index 1cd03ce49..f04614345 100644
--- a/trunk/src/utest/srs_utest_config.cpp
+++ b/trunk/src/utest/srs_utest_config.cpp
@@ -84,8 +84,6 @@ srs_error_t MockSrsConfig::parse(string buf)
return err;
}
-#ifdef ENABLE_UTEST_CONFIG
-
VOID TEST(ConfigTest, CheckMacros)
{
#ifndef SRS_CONSTS_LOCALHOST
@@ -1806,5 +1804,3 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_ingest_id)
EXPECT_TRUE(ERROR_SUCCESS != conf.parse(_MIN_OK_CONF"vhost v{ingest{} ingest{}}"));
}
-#endif
-
diff --git a/trunk/src/utest/srs_utest_core.cpp b/trunk/src/utest/srs_utest_core.cpp
index 47939081e..0f8b44bb1 100644
--- a/trunk/src/utest/srs_utest_core.cpp
+++ b/trunk/src/utest/srs_utest_core.cpp
@@ -22,8 +22,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include
-#ifdef ENABLE_UTEST_CORE
-
using namespace std;
#include
@@ -66,5 +64,3 @@ VOID TEST(CoreMacroseTest, Check)
#endif
}
-#endif
-
diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp
index 51fd94972..f73fc4eaa 100644
--- a/trunk/src/utest/srs_utest_kernel.cpp
+++ b/trunk/src/utest/srs_utest_kernel.cpp
@@ -30,17 +30,28 @@ using namespace std;
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#define MAX_MOCK_DATA_SIZE 1024 * 1024
MockSrsFileWriter::MockSrsFileWriter()
{
- data = new char[MAX_MOCK_DATA_SIZE];
- offset = -1;
+ size = MAX_MOCK_DATA_SIZE;
+ data = new char[size];
+ offset = 0;
+ err = srs_success;
+ error_offset = 0;
}
MockSrsFileWriter::~MockSrsFileWriter()
{
+ srs_freep(err);
srs_freep(data);
}
@@ -48,6 +59,10 @@ srs_error_t MockSrsFileWriter::open(string /*file*/)
{
offset = 0;
+ if (err != srs_success) {
+ return srs_error_copy(err);
+ }
+
return srs_success;
}
@@ -61,6 +76,11 @@ bool MockSrsFileWriter::is_open()
return offset >= 0;
}
+void MockSrsFileWriter::seek2(int64_t offset)
+{
+ this->offset = offset;
+}
+
int64_t MockSrsFileWriter::tellg()
{
return offset;
@@ -68,15 +88,43 @@ int64_t MockSrsFileWriter::tellg()
srs_error_t MockSrsFileWriter::write(void* buf, size_t count, ssize_t* pnwrite)
{
- int size = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count);
-
- memcpy(data + offset, buf, size);
-
- if (pnwrite) {
- *pnwrite = size;
+ if (err != srs_success) {
+ return srs_error_copy(err);
}
- offset += size;
+ int nwriten = srs_min(MAX_MOCK_DATA_SIZE - offset, (int)count);
+
+ memcpy(data + offset, buf, nwriten);
+
+ if (pnwrite) {
+ *pnwrite = nwriten;
+ }
+
+ offset += nwriten;
+ size = srs_max(size, offset);
+
+ if (error_offset > 0 && offset >= error_offset) {
+ return srs_error_new(-1, "exceed offset");
+ }
+
+ return srs_success;
+}
+
+srs_error_t MockSrsFileWriter::lseek(off_t _offset, int whence, off_t* seeked)
+{
+ if (whence == SEEK_SET) {
+ offset = (int)_offset;
+ }
+ if (whence == SEEK_CUR) {
+ offset += (int)_offset;
+ }
+ if (whence == SEEK_END) {
+ offset = (int)(size + _offset);
+ }
+
+ if (seeked) {
+ *seeked = (off_t)offset;
+ }
return srs_success;
}
@@ -90,7 +138,16 @@ MockSrsFileReader::MockSrsFileReader()
{
data = new char[MAX_MOCK_DATA_SIZE];
size = 0;
- offset = -1;
+ offset = 0;
+}
+
+MockSrsFileReader::MockSrsFileReader(const char* src, int nb_src)
+{
+ data = new char[nb_src];
+ memcpy(data, src, nb_src);
+
+ size = nb_src;
+ offset = 0;
}
MockSrsFileReader::~MockSrsFileReader()
@@ -141,23 +198,35 @@ srs_error_t MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
int s = srs_min(size - offset, (int)count);
if (s <= 0) {
- return srs_success;
+ return srs_error_new(ERROR_SYSTEM_FILE_EOF, "EOF left=%d", s);
}
memcpy(buf, data + offset, s);
+ offset += s;
if (pnread) {
*pnread = s;
}
- offset += s;
-
return srs_success;
}
-srs_error_t MockSrsFileReader::lseek(off_t _offset, int /*whence*/, off_t* /*seeked*/)
+srs_error_t MockSrsFileReader::lseek(off_t _offset, int whence, off_t* seeked)
{
- offset = (int)_offset;
+ if (whence == SEEK_SET) {
+ offset = (int)_offset;
+ }
+ if (whence == SEEK_CUR) {
+ offset += (int)_offset;
+ }
+ if (whence == SEEK_END) {
+ offset = (int)(size + _offset);
+ }
+
+ if (seeked) {
+ *seeked = (off_t)offset;
+ }
+
return srs_success;
}
@@ -165,9 +234,8 @@ void MockSrsFileReader::mock_append_data(const char* _data, int _size)
{
int s = srs_min(MAX_MOCK_DATA_SIZE - offset, _size);
memcpy(data + offset, _data, s);
-
- offset += s;
size += s;
+ offset += s;
}
void MockSrsFileReader::mock_reset_offset()
@@ -197,7 +265,46 @@ srs_error_t MockBufferReader::read(void* buf, size_t size, ssize_t* nread)
return srs_success;
}
-#ifdef ENABLE_UTEST_KERNEL
+MockSrsCodec::MockSrsCodec()
+{
+}
+
+MockSrsCodec::~MockSrsCodec()
+{
+}
+
+int MockSrsCodec::nb_bytes()
+{
+ return 0;
+}
+
+srs_error_t MockSrsCodec::encode(SrsBuffer* /*buf*/)
+{
+ return srs_success;
+}
+
+srs_error_t MockSrsCodec::decode(SrsBuffer* /*buf*/)
+{
+ return srs_success;
+}
+
+MockTsHandler::MockTsHandler()
+{
+ msg = NULL;
+}
+
+MockTsHandler::~MockTsHandler()
+{
+ srs_freep(msg);
+}
+
+srs_error_t MockTsHandler::on_ts_message(SrsTsMessage* m)
+{
+ srs_freep(msg);
+ msg = m->detach();
+
+ return srs_success;
+}
VOID TEST(KernelBufferTest, DefaultObject)
{
@@ -736,7 +843,7 @@ VOID TEST(KernelFlvTest, FlvVSDecoderStreamClosed)
{
MockSrsFileReader fs;
SrsFlvVodStreamDecoder dec;
- ASSERT_TRUE(ERROR_SUCCESS != dec.initialize(&fs));
+ ASSERT_TRUE(srs_success == dec.initialize(&fs));
}
/**
@@ -844,8 +951,8 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader)
int64_t start = 0;
int size = 0;
EXPECT_TRUE(ERROR_SUCCESS == dec.read_sequence_header_summary(&start, &size));
- EXPECT_TRUE(23 == start);
- EXPECT_TRUE(46 == size);
+ EXPECT_EQ(23, (int)start);
+ EXPECT_EQ(46, size);
}
/**
@@ -923,8 +1030,8 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSequenceHeader2)
int64_t start = 0;
int size = 0;
EXPECT_TRUE(ERROR_SUCCESS == dec.read_sequence_header_summary(&start, &size));
- EXPECT_TRUE(23 == start);
- EXPECT_TRUE(46 == size);
+ EXPECT_EQ(23, (int)start);
+ EXPECT_EQ(46, size);
}
/**
@@ -1350,6 +1457,26 @@ VOID TEST(KernelStreamTest, StreamWriteBytes)
EXPECT_EQ(0x19, s.read_1bytes());
}
+VOID TEST(KernelBufferTest, CoverAll)
+{
+ if (true) {
+ MockSrsCodec codec;
+ EXPECT_TRUE(0 == codec.nb_bytes());
+ EXPECT_TRUE(srs_success == codec.encode(NULL));
+ EXPECT_TRUE(srs_success == codec.decode(NULL));
+ }
+
+ if (true) {
+ SrsBuffer buf((char*)"hello", 5);
+ EXPECT_EQ(5, buf.size());
+ EXPECT_EQ(5, buf.left());
+
+ buf.read_1bytes();
+ EXPECT_EQ(5, buf.size());
+ EXPECT_EQ(4, buf.left());
+ }
+}
+
/**
* test the kernel utility, time
*/
@@ -1456,89 +1583,88 @@ VOID TEST(KernelUtilityTest, UtilityString)
VOID TEST(KernelUtility, AvcUev)
{
int32_t v;
- SrsBitBuffer bb;
char data[32];
if (true) {
data[0] = 0xff;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 1;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 1;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(0, v);
}
if (true) {
data[0] = 0x40;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(1, v);
}
if (true) {
data[0] = 0x60;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(2, v);
}
if (true) {
data[0] = 0x20;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(3, v);
}
if (true) {
data[0] = 0x28;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(4, v);
}
if (true) {
data[0] = 0x30;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(5, v);
}
if (true) {
data[0] = 0x38;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(6, v);
}
if (true) {
data[0] = 0x10;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(7, v);
}
if (true) {
data[0] = 0x12;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(8, v);
}
if (true) {
data[0] = 0x14;
- SrsBuffer buf((char*)data, 1); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 1); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(9, v);
}
if (true) {
data[0] = 0x01; data[1] = 0x12;
- SrsBuffer buf((char*)data, 2); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 2); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(128-1+9, v);
}
if (true) {
data[0] = 0x00; data[1] = 0x91; data[2] = 0x00;
- SrsBuffer buf((char*)data, 3); bb.initialize(&buf); v = 0;
+ SrsBuffer buf((char*)data, 3); SrsBitBuffer bb(&buf); v = 0;
srs_avc_nalu_read_uev(&bb, v);
EXPECT_EQ(256-1+0x22, v);
}
@@ -2124,5 +2250,1542 @@ VOID TEST(KernelUtility, RTMPUtils2)
}
}
-#endif
+VOID TEST(KernelErrorTest, CoverAll)
+{
+ if (true) {
+ EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_RTMP_CLOSE));
+ EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_REPUBLISH));
+ EXPECT_TRUE(srs_is_system_control_error(ERROR_CONTROL_REDIRECT));
+ }
+
+ if (true) {
+ srs_error_t err = srs_error_new(ERROR_CONTROL_RTMP_CLOSE, "control error");
+ EXPECT_TRUE(srs_is_system_control_error(err));
+ srs_freep(err);
+ }
+
+ if (true) {
+ EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_READ));
+ EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_READ_FULLY));
+ EXPECT_TRUE(srs_is_client_gracefully_close(ERROR_SOCKET_WRITE));
+ }
+
+ if (true) {
+ srs_error_t err = srs_error_new(ERROR_SOCKET_READ, "graceful close error");
+ EXPECT_TRUE(srs_is_client_gracefully_close(err));
+ srs_freep(err);
+ }
+
+ if (true) {
+ srs_error_t err = srs_error_wrap(srs_error_new(ERROR_CONTROL_RTMP_CLOSE, "control error"), "wrapped");
+ EXPECT_TRUE(srs_error_desc(err) != "");
+ srs_freep(err);
+ }
+
+ if (true) {
+ EXPECT_TRUE(srs_error_desc(srs_success) == "Success");
+ }
+
+ if (true) {
+ srs_error_t err = srs_success;
+ EXPECT_TRUE(srs_success == srs_error_copy(err));
+ }
+
+ if (true) {
+ srs_error_t err = srs_error_new(ERROR_SOCKET_READ, "graceful close error");
+ srs_error_t r0 = srs_error_copy(err);
+ EXPECT_TRUE(err != r0);
+ srs_freep(err);
+ srs_freep(r0);
+ }
+}
+
+VOID TEST(KernelAACTest, TransmaxRTMP2AAC)
+{
+ if (true) {
+ SrsAacTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"", 0);
+ EXPECT_EQ(ERROR_AAC_DECODE_ERROR, srs_error_code(err));
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\x0f", 1);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\xaf", 1);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsAacTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+
+ EXPECT_TRUE(!m.got_sequence_header);
+ }
+
+ if (true) {
+ SrsAacTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"\xaf\x00", 2);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\xaf\x00\x12\x10", 4);
+ EXPECT_TRUE(srs_success == err);
+ srs_freep(err);
+
+ EXPECT_TRUE(m.got_sequence_header);
+ EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
+ EXPECT_EQ(2, m.aac_channels);
+
+ err = m.write_audio(0, (char*)"\xaf\x01\xcb", 3);
+ EXPECT_TRUE(srs_success == err);
+ srs_freep(err);
+
+ EXPECT_EQ(8, f.offset);
+ EXPECT_EQ((char)0xff, f.data[0]);
+ EXPECT_EQ((char)0xf1, f.data[1]);
+ EXPECT_EQ((char)0x50, f.data[2]);
+ EXPECT_EQ((char)0x80, f.data[3]);
+ EXPECT_EQ((char)0x01, f.data[4]);
+ EXPECT_EQ((char)0x00, f.data[5]);
+ EXPECT_EQ((char)0xfc, f.data[6]);
+ EXPECT_EQ((char)0xcb, f.data[7]);
+ }
+
+ if (true) {
+ SrsAacTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"\xaf\x00", 2);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\xaf\x00\x12\x10", 4);
+ EXPECT_TRUE(srs_success == err);
+ srs_freep(err);
+
+ EXPECT_TRUE(m.got_sequence_header);
+ EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
+ EXPECT_EQ(2, m.aac_channels);
+
+ f.error_offset = 7;
+
+ err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsAacTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"\xaf\x00", 2);
+ EXPECT_TRUE(ERROR_AAC_DECODE_ERROR == srs_error_code(err));
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\xaf\x00\x12\x10", 4);
+ EXPECT_TRUE(srs_success == err);
+ srs_freep(err);
+
+ EXPECT_TRUE(m.got_sequence_header);
+ EXPECT_EQ(44100, srs_aac_srates[m.aac_sample_rate]);
+ EXPECT_EQ(2, m.aac_channels);
+
+ f.error_offset = 8;
+
+ err = m.write_audio(0, (char*)"\xaf\x01\x00", 3);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+}
+
+VOID TEST(KernelLBRRTest, CoverAll)
+{
+ if (true) {
+ SrsLbRoundRobin lb;
+ EXPECT_EQ(0, (int)lb.count);
+ EXPECT_EQ(-1, lb.index);
+ EXPECT_EQ(-1, (int)lb.current());
+ EXPECT_TRUE("" == lb.selected());
+ }
+
+ if (true) {
+ vector servers;
+ servers.push_back("s0");
+ servers.push_back("s1");
+ servers.push_back("s2");
+
+ SrsLbRoundRobin lb;
+ lb.select(servers);
+ EXPECT_EQ(0, (int)lb.current());
+ EXPECT_TRUE("s0" == lb.selected());
+
+ lb.select(servers);
+ EXPECT_EQ(1, (int)lb.current());
+ EXPECT_TRUE("s1" == lb.selected());
+
+ lb.select(servers);
+ EXPECT_EQ(2, (int)lb.current());
+ EXPECT_TRUE("s2" == lb.selected());
+
+ lb.select(servers);
+ EXPECT_EQ(0, (int)lb.current());
+ EXPECT_TRUE("s0" == lb.selected());
+ }
+}
+
+VOID TEST(KernelCodecTest, CoverAll)
+{
+ if (true) {
+ EXPECT_TRUE("H264" == srs_video_codec_id2str(SrsVideoCodecIdAVC));
+ EXPECT_TRUE("VP6" == srs_video_codec_id2str(SrsVideoCodecIdOn2VP6));
+ EXPECT_TRUE("HEVC" == srs_video_codec_id2str(SrsVideoCodecIdHEVC));
+ EXPECT_TRUE("Other" == srs_video_codec_id2str(SrsVideoCodecIdScreenVideo));
+ }
+
+ if (true) {
+ EXPECT_TRUE("AAC" == srs_audio_codec_id2str(SrsAudioCodecIdAAC));
+ EXPECT_TRUE("MP3" == srs_audio_codec_id2str(SrsAudioCodecIdMP3));
+ EXPECT_TRUE("Opus" == srs_audio_codec_id2str(SrsAudioCodecIdOpus));
+ EXPECT_TRUE("Other" == srs_audio_codec_id2str(SrsAudioCodecIdSpeex));
+ }
+
+ if (true) {
+ EXPECT_TRUE("5512" == srs_audio_sample_rate2str(SrsAudioSampleRate5512));
+ EXPECT_TRUE("11025" == srs_audio_sample_rate2str(SrsAudioSampleRate11025));
+ EXPECT_TRUE("22050" == srs_audio_sample_rate2str(SrsAudioSampleRate22050));
+ EXPECT_TRUE("44100" == srs_audio_sample_rate2str(SrsAudioSampleRate44100));
+ EXPECT_TRUE("NB8kHz" == srs_audio_sample_rate2str(SrsAudioSampleRateNB8kHz));
+ EXPECT_TRUE("MB12kHz" == srs_audio_sample_rate2str(SrsAudioSampleRateMB12kHz));
+ EXPECT_TRUE("WB16kHz" == srs_audio_sample_rate2str(SrsAudioSampleRateWB16kHz));
+ EXPECT_TRUE("SWB24kHz" == srs_audio_sample_rate2str(SrsAudioSampleRateSWB24kHz));
+ EXPECT_TRUE("FB48kHz" == srs_audio_sample_rate2str(SrsAudioSampleRateFB48kHz));
+ EXPECT_TRUE("Other" == srs_audio_sample_rate2str(SrsAudioSampleRateForbidden));
+ }
+
+ if (true) {
+ SrsFlvVideo v;
+ EXPECT_TRUE(!v.sh((char*)"\x07", 1));
+
+ EXPECT_TRUE(!v.acceptable(NULL, 0));
+ EXPECT_TRUE(!v.acceptable((char*)"\x00", 1));
+ EXPECT_TRUE(!v.acceptable((char*)"\xf0", 1));
+ EXPECT_TRUE(!v.acceptable((char*)"\x10", 1));
+ EXPECT_TRUE(!v.acceptable((char*)"\x1f", 1));
+ EXPECT_TRUE(v.acceptable((char*)"\x13", 1));
+ }
+
+ if (true) {
+ SrsFlvAudio a;
+ EXPECT_TRUE(!a.sh((char*)"\xa0", 1));
+ }
+
+ if (true) {
+ EXPECT_TRUE("16bits" == srs_audio_sample_bits2str(SrsAudioSampleBits16bit));
+ EXPECT_TRUE("8bits" == srs_audio_sample_bits2str(SrsAudioSampleBits8bit));
+ EXPECT_TRUE("Other" == srs_audio_sample_bits2str(SrsAudioSampleBitsForbidden));
+ }
+
+ if (true) {
+ EXPECT_TRUE("Stereo" == srs_audio_channels2str(SrsAudioChannelsStereo));
+ EXPECT_TRUE("Mono" == srs_audio_channels2str(SrsAudioChannelsMono));
+ EXPECT_TRUE("Other" == srs_audio_channels2str(SrsAudioChannelsForbidden));
+ }
+
+ if (true) {
+ EXPECT_TRUE("NonIDR" == srs_avc_nalu2str(SrsAvcNaluTypeNonIDR));
+ EXPECT_TRUE("DataPartitionA" == srs_avc_nalu2str(SrsAvcNaluTypeDataPartitionA));
+ EXPECT_TRUE("DataPartitionB" == srs_avc_nalu2str(SrsAvcNaluTypeDataPartitionB));
+ EXPECT_TRUE("DataPartitionC" == srs_avc_nalu2str(SrsAvcNaluTypeDataPartitionC));
+ EXPECT_TRUE("IDR" == srs_avc_nalu2str(SrsAvcNaluTypeIDR));
+ EXPECT_TRUE("SEI" == srs_avc_nalu2str(SrsAvcNaluTypeSEI));
+ EXPECT_TRUE("SPS" == srs_avc_nalu2str(SrsAvcNaluTypeSPS));
+ EXPECT_TRUE("PPS" == srs_avc_nalu2str(SrsAvcNaluTypePPS));
+ EXPECT_TRUE("AccessUnitDelimiter" == srs_avc_nalu2str(SrsAvcNaluTypeAccessUnitDelimiter));
+ EXPECT_TRUE("EOSequence" == srs_avc_nalu2str(SrsAvcNaluTypeEOSequence));
+ EXPECT_TRUE("EOStream" == srs_avc_nalu2str(SrsAvcNaluTypeEOStream));
+ EXPECT_TRUE("FilterData" == srs_avc_nalu2str(SrsAvcNaluTypeFilterData));
+ EXPECT_TRUE("SPSExt" == srs_avc_nalu2str(SrsAvcNaluTypeSPSExt));
+ EXPECT_TRUE("PrefixNALU" == srs_avc_nalu2str(SrsAvcNaluTypePrefixNALU));
+ EXPECT_TRUE("SubsetSPS" == srs_avc_nalu2str(SrsAvcNaluTypeSubsetSPS));
+ EXPECT_TRUE("LayerWithoutPartition" == srs_avc_nalu2str(SrsAvcNaluTypeLayerWithoutPartition));
+ EXPECT_TRUE("CodedSliceExt" == srs_avc_nalu2str(SrsAvcNaluTypeCodedSliceExt));
+ EXPECT_TRUE("Other" == srs_avc_nalu2str(SrsAvcNaluTypeForbidden));
+ }
+
+ if (true) {
+ EXPECT_TRUE("Main" == srs_aac_profile2str(SrsAacProfileMain));
+ EXPECT_TRUE("LC" == srs_aac_profile2str(SrsAacProfileLC));
+ EXPECT_TRUE("SSR" == srs_aac_profile2str(SrsAacProfileSSR));
+ EXPECT_TRUE("Other" == srs_aac_profile2str(SrsAacProfileReserved));
+ }
+
+ if (true) {
+ EXPECT_TRUE("Main" == srs_aac_object2str(SrsAacObjectTypeAacMain));
+ EXPECT_TRUE("LC" == srs_aac_object2str(SrsAacObjectTypeAacLC));
+ EXPECT_TRUE("SSR" == srs_aac_object2str(SrsAacObjectTypeAacSSR));
+ EXPECT_TRUE("HE" == srs_aac_object2str(SrsAacObjectTypeAacHE));
+ EXPECT_TRUE("HEv2" == srs_aac_object2str(SrsAacObjectTypeAacHEV2));
+ EXPECT_TRUE("Other" == srs_aac_object2str(SrsAacObjectTypeForbidden));
+ }
+
+ if (true) {
+ EXPECT_TRUE(SrsAacObjectTypeAacMain == srs_aac_ts2rtmp(SrsAacProfileMain));
+ EXPECT_TRUE(SrsAacObjectTypeAacLC == srs_aac_ts2rtmp(SrsAacProfileLC));
+ EXPECT_TRUE(SrsAacObjectTypeAacSSR == srs_aac_ts2rtmp(SrsAacProfileSSR));
+ EXPECT_TRUE(SrsAacObjectTypeReserved == srs_aac_ts2rtmp(SrsAacProfileReserved));
+ }
+
+ if (true) {
+ EXPECT_TRUE(SrsAacProfileMain == srs_aac_rtmp2ts(SrsAacObjectTypeAacMain));
+ EXPECT_TRUE(SrsAacProfileLC == srs_aac_rtmp2ts(SrsAacObjectTypeAacHE));
+ EXPECT_TRUE(SrsAacProfileLC == srs_aac_rtmp2ts(SrsAacObjectTypeAacHEV2));
+ EXPECT_TRUE(SrsAacProfileLC == srs_aac_rtmp2ts(SrsAacObjectTypeAacLC));
+ EXPECT_TRUE(SrsAacProfileSSR == srs_aac_rtmp2ts(SrsAacObjectTypeAacSSR));
+ EXPECT_TRUE(SrsAacProfileReserved == srs_aac_rtmp2ts(SrsAacObjectTypeReserved));
+ }
+
+ if (true) {
+ EXPECT_TRUE("Baseline" == srs_avc_profile2str(SrsAvcProfileBaseline));
+ EXPECT_TRUE("Baseline(Constrained)" == srs_avc_profile2str(SrsAvcProfileConstrainedBaseline ));
+ EXPECT_TRUE("Main" == srs_avc_profile2str(SrsAvcProfileMain));
+ EXPECT_TRUE("Extended" == srs_avc_profile2str(SrsAvcProfileExtended));
+ EXPECT_TRUE("High" == srs_avc_profile2str(SrsAvcProfileHigh ));
+ EXPECT_TRUE("High(10)" == srs_avc_profile2str(SrsAvcProfileHigh10 ));
+ EXPECT_TRUE("High(10+Intra)" == srs_avc_profile2str(SrsAvcProfileHigh10Intra));
+ EXPECT_TRUE("High(422)" == srs_avc_profile2str(SrsAvcProfileHigh422 ));
+ EXPECT_TRUE("High(422+Intra)" == srs_avc_profile2str(SrsAvcProfileHigh422Intra));
+ EXPECT_TRUE("High(444)" == srs_avc_profile2str(SrsAvcProfileHigh444 ));
+ EXPECT_TRUE("High(444+Predictive)" == srs_avc_profile2str(SrsAvcProfileHigh444Predictive));
+ EXPECT_TRUE("High(444+Intra)" == srs_avc_profile2str(SrsAvcProfileHigh444Intra));
+ EXPECT_TRUE("Other" == srs_avc_profile2str(SrsAvcProfileReserved));
+ }
+
+ if (true) {
+ EXPECT_TRUE("1" == srs_avc_level2str(SrsAvcLevel_1));
+ EXPECT_TRUE("1.1" == srs_avc_level2str(SrsAvcLevel_11));
+ EXPECT_TRUE("1.2" == srs_avc_level2str(SrsAvcLevel_12));
+ EXPECT_TRUE("1.3" == srs_avc_level2str(SrsAvcLevel_13));
+ EXPECT_TRUE("2" == srs_avc_level2str(SrsAvcLevel_2));
+ EXPECT_TRUE("2.1" == srs_avc_level2str(SrsAvcLevel_21));
+ EXPECT_TRUE("2.2" == srs_avc_level2str(SrsAvcLevel_22));
+ EXPECT_TRUE("3" == srs_avc_level2str(SrsAvcLevel_3));
+ EXPECT_TRUE("3.1" == srs_avc_level2str(SrsAvcLevel_31));
+ EXPECT_TRUE("3.2" == srs_avc_level2str(SrsAvcLevel_32));
+ EXPECT_TRUE("4" == srs_avc_level2str(SrsAvcLevel_4));
+ EXPECT_TRUE("4.1" == srs_avc_level2str(SrsAvcLevel_41));
+ EXPECT_TRUE("5" == srs_avc_level2str(SrsAvcLevel_5));
+ EXPECT_TRUE("5.1" == srs_avc_level2str(SrsAvcLevel_51));
+ EXPECT_TRUE("Other" == srs_avc_level2str(SrsAvcLevelReserved));
+ }
+
+ if (true) {
+ SrsAudioCodecConfig acc;
+ EXPECT_TRUE(!acc.is_aac_codec_ok());
+
+ acc.aac_extra_data.push_back('\xff');
+ EXPECT_TRUE(acc.is_aac_codec_ok());
+
+ SrsVideoCodecConfig vcc;
+ EXPECT_TRUE(!vcc.is_avc_codec_ok());
+
+ vcc.avc_extra_data.push_back('\xff');
+ EXPECT_TRUE(vcc.is_avc_codec_ok());
+ }
+}
+
+VOID TEST(KernelCodecTest, AVFrame)
+{
+ if (true) {
+ SrsAudioFrame f;
+ SrsAudioCodecConfig cc;
+ EXPECT_TRUE(srs_success == f.initialize(&cc));
+ EXPECT_TRUE(f.acodec() != NULL);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)1, 10));
+ EXPECT_TRUE((char*)1 == f.samples[0].bytes);
+ EXPECT_TRUE(10 == f.samples[0].size);
+ EXPECT_TRUE(1 == f.nb_samples);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)2, 20));
+ EXPECT_TRUE((char*)2 == f.samples[1].bytes);
+ EXPECT_TRUE(20 == f.samples[1].size);
+ EXPECT_TRUE(2 == f.nb_samples);
+ }
+
+ if (true) {
+ SrsAudioFrame f;
+ for (int i = 0; i < SrsMaxNbSamples; i++) {
+ EXPECT_TRUE(srs_success == f.add_sample((char*)(int64_t)i, i*10));
+ }
+
+ srs_error_t err = f.add_sample((char*)1, 1);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsVideoFrame f;
+ SrsVideoCodecConfig cc;
+ EXPECT_TRUE(srs_success == f.initialize(&cc));
+ EXPECT_TRUE(f.vcodec() != NULL);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)"\x05", 1));
+ EXPECT_TRUE(f.has_idr == true);
+ EXPECT_TRUE(f.first_nalu_type == SrsAvcNaluTypeIDR);
+ }
+
+ if (true) {
+ SrsVideoFrame f;
+ SrsVideoCodecConfig cc;
+ EXPECT_TRUE(srs_success == f.initialize(&cc));
+ EXPECT_TRUE(f.vcodec() != NULL);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)"\x07", 1));
+ EXPECT_TRUE(f.has_sps_pps == true);
+ }
+
+ if (true) {
+ SrsVideoFrame f;
+ SrsVideoCodecConfig cc;
+ EXPECT_TRUE(srs_success == f.initialize(&cc));
+ EXPECT_TRUE(f.vcodec() != NULL);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)"\x08", 1));
+ EXPECT_TRUE(f.has_sps_pps == true);
+ }
+
+ if (true) {
+ SrsVideoFrame f;
+ SrsVideoCodecConfig cc;
+ EXPECT_TRUE(srs_success == f.initialize(&cc));
+ EXPECT_TRUE(f.vcodec() != NULL);
+
+ EXPECT_TRUE(srs_success == f.add_sample((char*)"\x09", 1));
+ EXPECT_TRUE(f.has_aud == true);
+ }
+
+ if (true) {
+ SrsVideoFrame f;
+ for (int i = 0; i < SrsMaxNbSamples; i++) {
+ EXPECT_TRUE(srs_success == f.add_sample((char*)"\x05", 1));
+ }
+
+ srs_error_t err = f.add_sample((char*)"\x05", 1);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+}
+
+VOID TEST(KernelCodecTest, AudioFormat)
+{
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_audio(0, NULL, 0));
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\x00", 0));
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\x00", 1));
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\x20\x00", 2));
+ EXPECT_TRUE(1 == f.nb_raw);
+ EXPECT_TRUE(0 == f.audio->nb_samples);
+
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\x20\x00\x00", 3));
+ EXPECT_TRUE(2 == f.nb_raw);
+ EXPECT_TRUE(1 == f.audio->nb_samples);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x12\x10", 4));
+ EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, f.audio->aac_packet_type);
+ EXPECT_EQ(2, f.acodec->aac_channels);
+ EXPECT_EQ(4, f.acodec->aac_sample_rate);
+ EXPECT_EQ(2, f.acodec->aac_object);
+
+ EXPECT_EQ(SrsAudioChannelsStereo, f.acodec->sound_type);
+ EXPECT_EQ(SrsAudioSampleRate44100, f.acodec->sound_rate);
+ EXPECT_EQ(SrsAudioSampleBits16bit, f.acodec->sound_size);
+
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x01\x00", 3));
+ EXPECT_EQ(SrsAudioAacFrameTraitRawData, f.audio->aac_packet_type);
+ EXPECT_EQ(1, f.audio->nb_samples);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x13\x90", 4));
+ EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, f.audio->aac_packet_type);
+ EXPECT_EQ(7, f.acodec->aac_sample_rate);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x15\x10", 4));
+ EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, f.audio->aac_packet_type);
+ EXPECT_EQ(10, f.acodec->aac_sample_rate);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x01\x00", 3));
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x12\x10", 4));
+
+ SrsBuffer b((char*)"\x20", 1);
+ srs_error_t err = f.audio_aac_demux(&b, 0);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x12\x10", 4));
+
+ SrsBuffer b((char*)"\x30", 1);
+ srs_error_t err = f.audio_aac_demux(&b, 0);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsFormat f;
+ srs_error_t err = f.on_audio(0, (char*)"\xaf\x00\x12", 3);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsFormat f;
+ srs_error_t err = f.on_audio(0, (char*)"\xaf\x00\x02\x00", 4);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.on_aac_sequence_header((char*)"\x12\x10", 2));
+ EXPECT_EQ(2, f.acodec->aac_channels);
+ EXPECT_EQ(4, f.acodec->aac_sample_rate);
+ EXPECT_EQ(2, f.acodec->aac_object);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+ EXPECT_TRUE(srs_success == f.on_audio(0, (char*)"\xaf\x00\x12\x10", 4));
+ EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, f.audio->aac_packet_type);
+ EXPECT_TRUE(f.is_aac_sequence_header());
+ EXPECT_TRUE(!f.is_avc_sequence_header());
+ }
+}
+
+VOID TEST(KernelCodecTest, VideoFormat)
+{
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_video(0, NULL, 0));
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)"\x00", 0));
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)"\x00", 1));
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)"\x57", 1));
+
+ SrsBuffer b((char*)"\x00", 1);
+ srs_error_t err = f.video_avc_demux(&b, 0);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ uint8_t spspps[] = {
+ 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
+ 0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
+ };
+ uint8_t rawIBMF[] = {
+ 0x27,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x01, 0x9e, 0x82, 0x74, 0x43, 0xdf, 0x00, 0x16,
+ 0x02, 0x5b, 0x65, 0xa4, 0xbd, 0x42, 0x77, 0xfc, 0x23, 0x61, 0x5e, 0xc2, 0xc9, 0xe9, 0xf8, 0x50,
+ 0xd9, 0xaf, 0xc7, 0x49, 0xdc, 0xb6, 0x3a, 0xd4, 0xb5, 0x80, 0x02, 0x04, 0xac, 0xe7, 0x97, 0xc1,
+ 0xbf, 0xea, 0xf0, 0x13, 0x36, 0xd2, 0xa4, 0x0b, 0x6a, 0xc4, 0x32, 0x22, 0xe1
+ };
+ uint8_t rawAnnexb[] = {
+ 0x27,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x9e, 0x82, 0x74, 0x43, 0xdf, 0x00, 0x16,
+ 0x02, 0x5b, 0x65, 0xa4, 0xbd, 0x42, 0x77, 0xfc, 0x23, 0x61, 0x5e, 0xc2, 0xc9, 0xe9, 0xf8, 0x50,
+ 0xd9, 0xaf, 0xc7, 0x49, 0xdc, 0xb6, 0x3a, 0xd4, 0xb5, 0x80, 0x02, 0x04, 0xac, 0xe7, 0x97, 0xc1,
+ 0xbf, 0xea, 0xf0, 0x13, 0x36, 0xd2, 0xa4, 0x0b, 0x6a, 0xc4, 0x32, 0x22, 0xe1
+ };
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)spspps, sizeof(spspps)));
+ EXPECT_EQ(1, f.video->frame_type);
+ EXPECT_EQ(0, f.video->avc_packet_type);
+
+ EXPECT_EQ(768, f.vcodec->width);
+ EXPECT_EQ(320, f.vcodec->height);
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawIBMF, sizeof(rawIBMF)));
+ EXPECT_EQ(1, f.video->nb_samples);
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawIBMF, sizeof(rawIBMF)));
+ EXPECT_EQ(1, f.video->nb_samples);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)spspps, sizeof(spspps)));
+ EXPECT_EQ(1, f.video->frame_type);
+ EXPECT_EQ(0, f.video->avc_packet_type);
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawAnnexb, sizeof(rawAnnexb)));
+ EXPECT_EQ(1, f.video->nb_samples);
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawAnnexb, sizeof(rawAnnexb)));
+ EXPECT_EQ(1, f.video->nb_samples);
+
+ f.vcodec->payload_format = SrsAvcPayloadFormatAnnexb;
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawAnnexb, sizeof(rawAnnexb)));
+ EXPECT_EQ(1, f.video->nb_samples);
+ }
+
+ if (true) {
+ SrsFormat f;
+ EXPECT_TRUE(srs_success == f.initialize());
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)spspps, sizeof(spspps)));
+ EXPECT_EQ(1, f.video->frame_type);
+ EXPECT_EQ(0, f.video->avc_packet_type);
+
+ f.vcodec->payload_format = SrsAvcPayloadFormatAnnexb;
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawIBMF, sizeof(rawIBMF)));
+ EXPECT_EQ(1, f.video->nb_samples);
+
+ // If IBMF format parsed, we couldn't parse annexb anymore.
+ // Maybe FFMPEG use annexb format for some packets, then switch to IBMF.
+ srs_error_t err = f.on_video(0, (char*)rawAnnexb, sizeof(rawAnnexb));
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+
+ EXPECT_TRUE(srs_success == f.on_video(0, (char*)rawIBMF, sizeof(rawIBMF)));
+ EXPECT_EQ(1, f.video->nb_samples);
+ }
+}
+
+VOID TEST(KernelFileTest, FileWriteReader)
+{
+ if (true) {
+ SrsFileWriter f;
+ EXPECT_TRUE(!f.is_open());
+ }
+
+ if (true) {
+ SrsFileWriter f;
+ EXPECT_TRUE(srs_success == f.open("/dev/null"));
+ EXPECT_TRUE(f.is_open());
+
+ EXPECT_EQ(0, f.tellg());
+
+ ssize_t nwriten = 0;
+ EXPECT_TRUE(srs_success == f.write((void*)"Hello", 5, &nwriten));
+ EXPECT_EQ(5, nwriten);
+
+ EXPECT_TRUE(srs_success == f.lseek(0, SEEK_CUR, NULL));
+
+ f.seek2(0);
+ EXPECT_EQ(0, f.tellg());
+ }
+
+ if (true) {
+ SrsFileWriter f;
+ EXPECT_TRUE(srs_success == f.open_append("/dev/null"));
+ EXPECT_TRUE(f.is_open());
+ }
+
+ if (true) {
+ SrsFileReader f;
+ EXPECT_TRUE(!f.is_open());
+ }
+
+ if (true) {
+ SrsFileReader f;
+ EXPECT_TRUE(srs_success == f.open("/dev/null"));
+ EXPECT_TRUE(f.is_open());
+ EXPECT_EQ(0, f.tellg());
+ EXPECT_EQ(0, f.filesize());
+
+ f.skip(1);
+
+ f.seek2(0);
+ EXPECT_EQ(0, f.tellg());
+ }
+
+ if (true) {
+ SrsFileReader f;
+ EXPECT_TRUE(srs_success == f.open("/dev/null"));
+
+ char buf[16];
+ ssize_t nread = 0;
+ srs_error_t err = f.read((void*)buf, sizeof(buf), &nread);
+ EXPECT_EQ(ERROR_SYSTEM_FILE_EOF, srs_error_code(err));
+ srs_freep(err);
+
+ f.lseek(1, SEEK_CUR, NULL);
+ }
+}
+
+VOID TEST(KernelFLVTest, CoverAll)
+{
+ if (true) {
+ SrsMessageHeader h;
+ h.message_type = RTMP_MSG_SetChunkSize;
+ EXPECT_TRUE(h.is_set_chunk_size());
+
+ h.message_type = RTMP_MSG_SetPeerBandwidth;
+ EXPECT_TRUE(h.is_set_peer_bandwidth());
+
+ h.message_type = RTMP_MSG_AggregateMessage;
+ EXPECT_TRUE(h.is_aggregate());
+
+ h.initialize_amf0_script(10, 20);
+ EXPECT_EQ(RTMP_MSG_AMF0DataMessage, h.message_type);
+ EXPECT_EQ(10, h.payload_length);
+ EXPECT_EQ(20, h.stream_id);
+
+ h.initialize_audio(10, 30, 20);
+ EXPECT_EQ(RTMP_MSG_AudioMessage, h.message_type);
+ EXPECT_EQ(10, h.payload_length);
+ EXPECT_EQ(20, h.stream_id);
+ EXPECT_EQ(30, h.timestamp_delta);
+ EXPECT_EQ(30, h.timestamp);
+
+ h.initialize_video(10, 30, 20);
+ EXPECT_EQ(RTMP_MSG_VideoMessage, h.message_type);
+ EXPECT_EQ(10, h.payload_length);
+ EXPECT_EQ(20, h.stream_id);
+ EXPECT_EQ(30, h.timestamp_delta);
+ EXPECT_EQ(30, h.timestamp);
+ }
+
+ if (true) {
+ SrsMessageHeader h;
+ h.initialize_video(10, 30, 20);
+
+ SrsCommonMessage m;
+ EXPECT_TRUE(srs_success == m.create(&h, NULL, 0));
+ EXPECT_EQ(RTMP_MSG_VideoMessage, m.header.message_type);
+ EXPECT_EQ(10, m.header.payload_length);
+ EXPECT_EQ(20, m.header.stream_id);
+ EXPECT_EQ(30, m.header.timestamp_delta);
+ EXPECT_EQ(30, m.header.timestamp);
+
+ SrsSharedPtrMessage s;
+ EXPECT_TRUE(srs_success == s.create(&m));
+ EXPECT_TRUE(s.is_av());
+ EXPECT_TRUE(!s.is_audio());
+ EXPECT_TRUE(s.is_video());
+ }
+
+#ifdef SRS_PERF_FAST_FLV_ENCODER
+ if (true) {
+ MockSrsFileWriter f;
+ SrsFlvTransmuxer mux;
+ EXPECT_TRUE(srs_success == mux.initialize(&f));
+
+ SrsMessageHeader h;
+ h.initialize_video(10, 30, 20);
+
+ SrsSharedPtrMessage m;
+ EXPECT_TRUE(srs_success == m.create(&h, new char[1], 1));
+
+ SrsSharedPtrMessage* msgs = &m;
+ EXPECT_TRUE(srs_success == mux.write_tags(&msgs, 1));
+
+ EXPECT_EQ(16, f.offset);
+ }
+#endif
+}
+
+VOID TEST(KernelLogTest, CoverAll)
+{
+ if (true) {
+ ISrsLog l;
+ EXPECT_TRUE(srs_success == l.initialize());
+
+ l.reopen();
+ l.verbose("TAG", 0, "log");
+ l.info("TAG", 0, "log");
+ l.trace("TAG", 0, "log");
+ l.warn("TAG", 0, "log");
+ l.error("TAG", 0, "log");
+
+ ISrsThreadContext ctx;
+ ctx.set_id(10);
+ EXPECT_EQ(0, ctx.get_id());
+ EXPECT_EQ(0, ctx.generate_id());
+ }
+}
+
+VOID TEST(KernelMp3Test, CoverAll)
+{
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ EXPECT_TRUE(srs_success == m.write_header());
+ EXPECT_EQ((char)0x49, f.data[0]);
+ }
+
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ EXPECT_TRUE(srs_success == m.write_audio(0, (char*)"\x20\x01", 2));
+ EXPECT_EQ((char)0x01, f.data[0]);
+ }
+
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ srs_error_t err = m.write_audio(0, (char*)"\x30\x01", 2);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+
+ err = m.write_audio(0, (char*)"\x20", 1);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ f.offset = -1;
+
+ srs_error_t err = m.initialize(&f);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ f.err = srs_error_new(-1, "mock file error");
+ srs_error_t err = m.write_audio(0, (char*)"\x20\x01", 2);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsMp3Transmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ f.err = srs_error_new(-1, "mock file error");
+ srs_error_t err = m.write_header();
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+}
+
+VOID TEST(KernelUtilityTest, CoverBitsBufferAll)
+{
+ if (true) {
+ SrsBuffer b(NULL, 0);
+ SrsBitBuffer bb(&b);
+
+ int32_t v = 0;
+ srs_error_t err = srs_avc_nalu_read_uev(&bb, v);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsBuffer b((char*)"\x00", 1);
+ SrsBitBuffer bb(&b);
+
+ int32_t v = 0;
+ srs_error_t err = srs_avc_nalu_read_uev(&bb, v);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsBuffer b((char*)"\x00\x00\x00\x00", 4);
+ SrsBitBuffer bb(&b);
+
+ int32_t v = 0;
+ srs_error_t err = srs_avc_nalu_read_uev(&bb, v);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsBuffer b(NULL, 0);
+ SrsBitBuffer bb(&b);
+
+ int8_t v = 0;
+ srs_error_t err = srs_avc_nalu_read_bit(&bb, v);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+}
+
+extern int64_t _srs_system_time_startup_time;
+extern int64_t _srs_system_time_us_cache;
+extern int av_toupper(int c);
+
+VOID TEST(KernelUtilityTest, CoverTimeUtilityAll)
+{
+ _srs_system_time_us_cache = 0;
+ _srs_system_time_startup_time = 0;
+ EXPECT_TRUE(srs_get_system_startup_time_ms() > 0);
+
+ _srs_system_time_us_cache -= 300*1000 * 1000 + 1;
+ EXPECT_TRUE(srs_update_system_time_ms() > 0);
+
+ if (true) {
+ string host;
+ int port = 0;
+ srs_parse_hostport("[3ffe:dead:beef::1]:1935", host, port);
+ EXPECT_EQ(1935, port);
+ EXPECT_STREQ("3ffe:dead:beef::1", host.c_str());
+ }
+
+ if (true) {
+ string host;
+ int port = 0;
+ srs_parse_hostport("domain.com", host, port);
+ EXPECT_STREQ("domain.com", host.c_str());
+ }
+
+ if (true) {
+ string ep = srs_any_address4listener();
+ EXPECT_TRUE(ep == "0.0.0.0" || ep == "::");
+ }
+
+ if (true) {
+ string host;
+ int port = 0;
+ srs_parse_endpoint("[3ffe:dead:beef::1]:1935", host, port);
+ EXPECT_EQ(1935, port);
+ EXPECT_STREQ("3ffe:dead:beef::1", host.c_str());
+ }
+
+ if (true) {
+ string host;
+ int port = 0;
+ srs_parse_endpoint("domain.com:1935", host, port);
+ EXPECT_EQ(1935, port);
+ EXPECT_STREQ("domain.com", host.c_str());
+ }
+
+ if (true) {
+ string host;
+ int port = 0;
+ srs_parse_endpoint("1935", host, port);
+ EXPECT_EQ(1935, port);
+ EXPECT_TRUE(host == "0.0.0.0" || host == "::");
+ }
+
+ if (true) {
+ EXPECT_STREQ("1.00", srs_float2str(1).c_str());
+ EXPECT_STREQ("on", srs_bool2switch(true).c_str());
+ EXPECT_STREQ("off", srs_bool2switch(false).c_str());
+ }
+
+ if (true) {
+ vector flags;
+ flags.push_back("e");
+ flags.push_back("wo");
+ vector ss = srs_string_split("hello, world", flags);
+ EXPECT_EQ(3, (int)ss.size());
+ EXPECT_STREQ("h", ss.at(0).c_str());
+ EXPECT_STREQ("llo, ", ss.at(1).c_str());
+ EXPECT_STREQ("rld", ss.at(2).c_str());
+ }
+
+ if (true) {
+ EXPECT_EQ('H', av_toupper('h'));
+ }
+
+ if (true) {
+ int family = 0;
+ string ip = srs_dns_resolve("localhost", family);
+ EXPECT_TRUE(ip == "127.0.0.1" || ip == "::1");
+ }
+
+ if (true) {
+ EXPECT_TRUE(srs_path_exists("."));
+ EXPECT_TRUE(srs_success == srs_create_dir_recursively("."));
+ }
+
+ if (true) {
+ char buf[16] = {0};
+ EXPECT_STREQ("FE", srs_data_to_hex(buf, (const uint8_t*)"\xfe", 1));
+ }
+}
+
+VOID TEST(KernelTSTest, CoverContextUtility)
+{
+ if (true) {
+ EXPECT_STREQ("Reserved", srs_ts_stream2string(SrsTsStreamReserved).c_str());
+ EXPECT_STREQ("MP3", srs_ts_stream2string(SrsTsStreamAudioMp3).c_str());
+ EXPECT_STREQ("AAC", srs_ts_stream2string(SrsTsStreamAudioAAC).c_str());
+ EXPECT_STREQ("AC3", srs_ts_stream2string(SrsTsStreamAudioAC3).c_str());
+ EXPECT_STREQ("AudioDTS", srs_ts_stream2string(SrsTsStreamAudioDTS).c_str());
+ EXPECT_STREQ("H.264", srs_ts_stream2string(SrsTsStreamVideoH264).c_str());
+ EXPECT_STREQ("MP4", srs_ts_stream2string(SrsTsStreamVideoMpeg4).c_str());
+ EXPECT_STREQ("MP4A", srs_ts_stream2string(SrsTsStreamAudioMpeg4).c_str());
+ EXPECT_STREQ("Other", srs_ts_stream2string(SrsTsStreamForbidden).c_str());
+ }
+
+ if (true) {
+ SrsTsContext ctx;
+ SrsTsPacket p(&ctx);
+
+ SrsTsChannel c;
+ SrsTsMessage m(&c, &p);
+
+ EXPECT_TRUE(m.fresh());
+ EXPECT_TRUE(!m.is_audio());
+ EXPECT_TRUE(!m.is_video());
+ EXPECT_EQ(-1, m.stream_number());
+
+ m.sid = SrsTsPESStreamId(0x06<<5 | 0x01);
+ EXPECT_TRUE(m.is_audio());
+ EXPECT_EQ(1, m.stream_number());
+
+ m.sid = SrsTsPESStreamId(0x0e<<4 | 0x02);
+ EXPECT_TRUE(m.is_video());
+ EXPECT_EQ(2, m.stream_number());
+
+ SrsTsMessage* cp = m.detach();
+ EXPECT_TRUE(cp != NULL);
+ srs_freep(cp);
+
+ ctx.reset();
+ EXPECT_FALSE(ctx.ready);
+ }
+
+ if (true) {
+ SrsTsContext ctx;
+ SrsTsPacket p(&ctx);
+
+ SrsTsChannel c;
+ SrsTsMessage m(&c, &p);
+
+ m.PES_packet_length = 8;
+ SrsBuffer b;
+
+ int nb_bytes = 0;
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(0, nb_bytes);
+ }
+
+ if (true) {
+ SrsTsContext ctx;
+ SrsTsPacket p(&ctx);
+
+ SrsTsChannel c;
+ SrsTsMessage m(&c, &p);
+
+ m.PES_packet_length = 8;
+ SrsBuffer b((char*)"\x00\x01\x02\x03", 4);
+
+ int nb_bytes = 0;
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(4, nb_bytes);
+ }
+
+ if (true) {
+ SrsTsContext ctx;
+ SrsTsPacket p(&ctx);
+
+ SrsTsChannel c;
+ SrsTsMessage m(&c, &p);
+
+ EXPECT_TRUE(m.completed(1));
+ EXPECT_TRUE(!m.completed(0));
+
+ m.PES_packet_length = 8;
+ SrsBuffer b((char*)"\x00\x01\x02\x03", 4);
+
+ int nb_bytes = 0;
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(4, nb_bytes);
+
+ b.skip(-4);
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(4, nb_bytes);
+
+ EXPECT_TRUE(m.completed(0));
+ }
+
+ if (true) {
+ SrsTsMessage m;
+
+ EXPECT_TRUE(m.completed(1));
+ EXPECT_TRUE(!m.completed(0));
+
+ m.PES_packet_length = 8;
+ SrsBuffer b((char*)"\x00\x01\x02\x03", 4);
+
+ int nb_bytes = 0;
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(4, nb_bytes);
+
+ b.skip(-4);
+ EXPECT_TRUE(srs_success == m.dump(&b, &nb_bytes));
+ EXPECT_EQ(4, nb_bytes);
+
+ EXPECT_TRUE(m.completed(0));
+ }
+
+ if (true) {
+ MockTsHandler* h = new MockTsHandler();
+ srs_freep(h);
+
+ SrsTsContext ctx;
+ EXPECT_TRUE(!ctx.is_pure_audio());
+
+ ctx.set(100, SrsTsPidApplyPAT);
+ ctx.set(101, SrsTsPidApplyPMT);
+ ctx.set(102, SrsTsPidApplyVideo);
+ ctx.set(102, SrsTsPidApplyVideo);
+
+ ctx.on_pmt_parsed();
+ EXPECT_TRUE(!ctx.is_pure_audio());
+
+ EXPECT_EQ(100, ctx.get(100)->pid);
+ }
+
+ if (true) {
+ MockTsHandler* h = new MockTsHandler();
+ srs_freep(h);
+
+ SrsTsContext ctx;
+ EXPECT_TRUE(!ctx.is_pure_audio());
+
+ ctx.set(100, SrsTsPidApplyPAT);
+ ctx.set(101, SrsTsPidApplyPMT);
+ ctx.set(102, SrsTsPidApplyAudio);
+
+ ctx.on_pmt_parsed();
+ EXPECT_TRUE(ctx.is_pure_audio());
+
+ EXPECT_EQ(100, ctx.get(100)->pid);
+ EXPECT_TRUE(NULL == ctx.get(200));
+ }
+
+ if (true) {
+ SrsTsContext ctx;
+ EXPECT_EQ(0x47, ctx.sync_byte);
+
+ ctx.set_sync_byte(0x01);
+ EXPECT_EQ(0x01, ctx.sync_byte);
+ }
+}
+
+VOID TEST(KernelTSTest, CoverContextEncode)
+{
+ SrsTsContext ctx;
+ MockTsHandler h;
+
+ if (true) {
+ SrsBuffer b;
+ EXPECT_TRUE(srs_success == ctx.decode(&b, &h));
+ EXPECT_TRUE(NULL == h.msg);
+ }
+
+ if (true) {
+ SrsBuffer b((char*)"\x00", 1);
+
+ srs_error_t err = ctx.decode(&b, &h);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ SrsBuffer b((char*)"\x00\x00\x00\x00", 4);
+
+ srs_error_t err = ctx.decode(&b, &h);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ MockSrsFileWriter f;
+ SrsTsMessage m;
+
+ srs_error_t err = ctx.encode(&f, &m, SrsVideoCodecIdDisabled, SrsAudioCodecIdDisabled);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+
+ err = ctx.encode(&f, &m, SrsVideoCodecIdHEVC, SrsAudioCodecIdOpus);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+
+ err = ctx.encode_pat_pmt(&f, 0, SrsTsStreamReserved, 0, SrsTsStreamReserved);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+ }
+
+ if (true) {
+ MockSrsFileWriter f;
+ SrsTsMessage m;
+
+ srs_error_t err = ctx.encode_pes(&f, &m, 0x200, SrsTsStreamVideoH264, false);
+ EXPECT_TRUE(srs_success != err);
+ srs_freep(err);
+
+ EXPECT_TRUE(srs_success == ctx.encode_pat_pmt(&f, 200, SrsTsStreamVideoH264, 201, SrsTsStreamAudioAAC));
+ }
+
+ if (true) {
+ MockSrsFileWriter f;
+ SrsTsMessage m;
+
+ EXPECT_TRUE(srs_success == ctx.encode(&f, &m, SrsVideoCodecIdAVC, SrsAudioCodecIdAAC));
+
+ m.payload->append("Hello, world!", 13);
+ EXPECT_TRUE(srs_success == ctx.encode(&f, &m, SrsVideoCodecIdAVC, SrsAudioCodecIdAAC));
+ }
+}
+
+VOID TEST(KernelTSTest, CoverContextDecode)
+{
+ SrsTsContext ctx;
+ MockTsHandler h;
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x47, 0x40, 0x11, 0x10, 0x00, 0x42, 0xf0, 0x25, 0x00, 0x01, 0xc1, 0x00, 0x00, 0xff, 0x01, 0xff,
+ 0x00, 0x01, 0xfc, 0x80, 0x14, 0x48, 0x12, 0x01, 0x06, 0x46, 0x46, 0x6d, 0x70, 0x65, 0x67, 0x09,
+ 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x30, 0x31, 0x77, 0x7c, 0x43, 0xca, 0xff, 0xff, 0xff
+ };
+ SrsBuffer b((char*)raw, sizeof(raw));
+ EXPECT_TRUE(srs_success == ctx.decode(&b, &h));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x0d, 0x00, 0x01, 0xc1, 0x00, 0x00, 0x00, 0x01, 0xf0,
+ 0x00, 0x2a, 0xb1, 0x04, 0xb2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ SrsBuffer b((char*)raw, sizeof(raw));
+ EXPECT_TRUE(srs_success == ctx.decode(&b, &h));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x47, 0x50, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x17, 0x00, 0x01, 0xc1, 0x00, 0x00, 0xe1, 0x00, 0xf0,
+ 0x00, 0x1b, 0xe1, 0x00, 0xf0, 0x00, 0x0f, 0xe1, 0x01, 0xf0, 0x00, 0x2f, 0x44, 0xb9, 0x9b, 0xff
+ };
+ SrsBuffer b((char*)raw, sizeof(raw));
+ EXPECT_TRUE(srs_success == ctx.decode(&b, &h));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x47, 0x41, 0x00, 0x30, 0x07, 0x50, 0x00, 0x00, 0x7b, 0x0c, 0x7e, 0x00, 0x00, 0x00, 0x01, 0xe0,
+ 0x00, 0x00, 0x80, 0xc0, 0x0a, 0x31, 0x00, 0x09, 0x10, 0xa1, 0x11, 0x00, 0x07, 0xd8, 0x61, 0x00,
+ 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff, 0xac, 0xdc, 0x45,
+ 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32,
+ 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x33, 0x38, 0x20, 0x2d, 0x20,
+ 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43,
+ 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66,
+ 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x33, 0x20, 0x2d, 0x20, 0x68, 0x74,
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61,
+ 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
+ 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63,
+ 0x3d, 0x31, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x33, 0x20, 0x64, 0x65, 0x62
+ };
+ SrsBuffer b((char*)raw, sizeof(raw));
+ EXPECT_TRUE(srs_success == ctx.decode(&b, &h));
+ }
+}
+
+VOID TEST(KernelTSTest, CoverTransmuxer)
+{
+ SrsTsTransmuxer m;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == m.initialize(&f));
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
+ 0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
+ };
+ EXPECT_TRUE(srs_success == m.write_video(0, (char*)raw, sizeof(raw)));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf, 0x00, 0x12, 0x10
+ };
+ EXPECT_TRUE(srs_success == m.write_audio(0, (char*)raw, sizeof(raw)));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf,
+ 0x01, 0x21, 0x11, 0x45, 0x00, 0x14, 0x50, 0x01, 0x46, 0xf3, 0xf1, 0x0a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e
+ };
+ EXPECT_TRUE(srs_success == m.write_audio(34, (char*)raw, sizeof(raw)));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x27,
+ 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7b, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0x1f, 0x00, 0x00,
+ 0xf1, 0x68, 0x1a, 0x35, 0x84, 0xb3, 0xee, 0xe0, 0x61, 0xba, 0x4e, 0xa8, 0x52, 0x48, 0x50, 0x59,
+ 0x75, 0x42, 0xd9, 0x96, 0x4a, 0x51, 0x38, 0x2c, 0x63, 0x5e, 0x41, 0xc9, 0x70, 0x60, 0x9d, 0x13,
+ 0x53, 0xc2, 0xa8, 0xf5, 0x45, 0x86, 0xc5, 0x3e, 0x28, 0x1a, 0x69, 0x5f, 0x71, 0x1e, 0x51, 0x74,
+ 0x0e, 0x31, 0x47, 0x3c, 0xd3, 0xd2, 0x10, 0x25, 0x45, 0xc5, 0xb7, 0x31, 0xec, 0x7f, 0xd8, 0x02,
+ 0xae, 0xa4, 0x77, 0x6d, 0xcb, 0xc6, 0x1e, 0x2f, 0xa2, 0xd1, 0x12, 0x08, 0x34, 0x52, 0xea, 0xe8,
+ 0x0b, 0x4f, 0x81, 0x21, 0x4f, 0x71, 0x3f, 0xf2, 0xad, 0x02, 0x58, 0xdf, 0x9e, 0x31, 0x86, 0x9b,
+ 0x1b, 0x41, 0xbf, 0x2a, 0x09, 0x00, 0x43, 0x5c, 0xa1, 0x7e, 0x76, 0x59, 0xef, 0xa6, 0xfc, 0x82,
+ 0xb2, 0x72, 0x5a
+ };
+ EXPECT_TRUE(srs_success == m.write_video(40, (char*)raw, sizeof(raw)));
+ }
+}
+
+VOID TEST(KernelMP4Test, CoverMP4Codec)
+{
+ SrsMp4Encoder enc;
+ MockSrsFileWriter f;
+ SrsFormat fmt;
+ EXPECT_TRUE(srs_success == enc.initialize(&f));
+ EXPECT_TRUE(srs_success == fmt.initialize());
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
+ 0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
+ };
+ EXPECT_TRUE(srs_success == fmt.on_video(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeVIDE, fmt.video->frame_type, fmt.video->avc_packet_type, 0, 0, (uint8_t*)fmt.raw, fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf, 0x00, 0x12, 0x10
+ };
+ EXPECT_TRUE(srs_success == fmt.on_audio(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeSOUN, 0x00, fmt.audio->aac_packet_type, 0, 0, (uint8_t*)fmt.raw, fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf,
+ 0x01, 0x21, 0x11, 0x45, 0x00, 0x14, 0x50, 0x01, 0x46, 0xf3, 0xf1, 0x0a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e
+ };
+ EXPECT_TRUE(srs_success == fmt.on_audio(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeSOUN, 0x00, fmt.audio->aac_packet_type, 34, 34, (uint8_t*)fmt.raw, fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x27,
+ 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7b, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0x1f, 0x00, 0x00,
+ 0xf1, 0x68, 0x1a, 0x35, 0x84, 0xb3, 0xee, 0xe0, 0x61, 0xba, 0x4e, 0xa8, 0x52, 0x48, 0x50, 0x59,
+ 0x75, 0x42, 0xd9, 0x96, 0x4a, 0x51, 0x38, 0x2c, 0x63, 0x5e, 0x41, 0xc9, 0x70, 0x60, 0x9d, 0x13,
+ 0x53, 0xc2, 0xa8, 0xf5, 0x45, 0x86, 0xc5, 0x3e, 0x28, 0x1a, 0x69, 0x5f, 0x71, 0x1e, 0x51, 0x74,
+ 0x0e, 0x31, 0x47, 0x3c, 0xd3, 0xd2, 0x10, 0x25, 0x45, 0xc5, 0xb7, 0x31, 0xec, 0x7f, 0xd8, 0x02,
+ 0xae, 0xa4, 0x77, 0x6d, 0xcb, 0xc6, 0x1e, 0x2f, 0xa2, 0xd1, 0x12, 0x08, 0x34, 0x52, 0xea, 0xe8,
+ 0x0b, 0x4f, 0x81, 0x21, 0x4f, 0x71, 0x3f, 0xf2, 0xad, 0x02, 0x58, 0xdf, 0x9e, 0x31, 0x86, 0x9b,
+ 0x1b, 0x41, 0xbf, 0x2a, 0x09, 0x00, 0x43, 0x5c, 0xa1, 0x7e, 0x76, 0x59, 0xef, 0xa6, 0xfc, 0x82,
+ 0xb2, 0x72, 0x5a
+ };
+ EXPECT_TRUE(srs_success == fmt.on_video(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeVIDE, fmt.video->frame_type, fmt.video->avc_packet_type, 40, 40, (uint8_t*)fmt.raw, fmt.nb_raw
+ ));
+ }
+
+ EXPECT_TRUE(srs_success == enc.flush());
+
+ if (true) {
+ MockSrsFileReader fr((const char*)f.data, f.size);
+ SrsMp4Decoder dec;
+ EXPECT_TRUE(srs_success == dec.initialize(&fr));
+
+ SrsMp4HandlerType ht;
+ uint16_t ft, ct;
+ uint32_t dts, pts, nb_sample;
+ uint8_t* sample;
+ EXPECT_TRUE(srs_success == dec.read_sample(&ht, &ft, &ct, &dts, &pts, &sample, &nb_sample));
+ EXPECT_EQ(0, (int)dts);
+ }
+
+ if (true) {
+ SrsMp4BoxReader br;
+ MockSrsFileReader fr((const char*)f.data, f.size);
+ EXPECT_TRUE(srs_success == br.initialize(&fr));
+
+ SrsSimpleStream stream;
+
+ for (;;) {
+ SrsMp4Box* box = NULL;
+ srs_error_t err = br.read(&stream, &box);
+ if (err != srs_success) {
+ srs_freep(err);
+ break;
+ }
+
+ stringstream ss;
+ SrsMp4DumpContext dc;
+ dc.level = 0;
+ dc.summary = false;
+ box->dumps(ss, dc);
+
+ EXPECT_TRUE(srs_success == br.skip(box, &stream));
+
+ srs_freep(box);
+ }
+ }
+}
+
+uint8_t* mock_copy_bytes(char* data, int size)
+{
+ uint8_t* cp = new uint8_t[size];
+ memcpy(cp, data, size);
+ return cp;
+}
+
+VOID TEST(KernelMP4Test, CoverMP4M2tsSegmentEncoder)
+{
+ SrsMp4M2tsSegmentEncoder enc;
+ MockSrsFileWriter f;
+ EXPECT_TRUE(srs_success == enc.initialize(&f, 0, 0, 100));
+
+ SrsFormat fmt;
+ EXPECT_TRUE(srs_success == fmt.initialize());
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
+ 0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
+ };
+ EXPECT_TRUE(srs_success == fmt.on_video(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeVIDE, fmt.video->frame_type, 0, 0, mock_copy_bytes(fmt.raw, fmt.nb_raw), fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf, 0x00, 0x12, 0x10
+ };
+ EXPECT_TRUE(srs_success == fmt.on_audio(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeSOUN, 0x00, 0, 0, mock_copy_bytes(fmt.raw, fmt.nb_raw), fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0xaf,
+ 0x01, 0x21, 0x11, 0x45, 0x00, 0x14, 0x50, 0x01, 0x46, 0xf3, 0xf1, 0x0a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
+ 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e
+ };
+ EXPECT_TRUE(srs_success == fmt.on_audio(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeSOUN, 0x00, 34, 34, mock_copy_bytes(fmt.raw, fmt.nb_raw), fmt.nb_raw
+ ));
+ }
+
+ if (true) {
+ uint8_t raw[] = {
+ 0x27,
+ 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x7b, 0x41, 0x9a, 0x21, 0x6c, 0x42, 0x1f, 0x00, 0x00,
+ 0xf1, 0x68, 0x1a, 0x35, 0x84, 0xb3, 0xee, 0xe0, 0x61, 0xba, 0x4e, 0xa8, 0x52, 0x48, 0x50, 0x59,
+ 0x75, 0x42, 0xd9, 0x96, 0x4a, 0x51, 0x38, 0x2c, 0x63, 0x5e, 0x41, 0xc9, 0x70, 0x60, 0x9d, 0x13,
+ 0x53, 0xc2, 0xa8, 0xf5, 0x45, 0x86, 0xc5, 0x3e, 0x28, 0x1a, 0x69, 0x5f, 0x71, 0x1e, 0x51, 0x74,
+ 0x0e, 0x31, 0x47, 0x3c, 0xd3, 0xd2, 0x10, 0x25, 0x45, 0xc5, 0xb7, 0x31, 0xec, 0x7f, 0xd8, 0x02,
+ 0xae, 0xa4, 0x77, 0x6d, 0xcb, 0xc6, 0x1e, 0x2f, 0xa2, 0xd1, 0x12, 0x08, 0x34, 0x52, 0xea, 0xe8,
+ 0x0b, 0x4f, 0x81, 0x21, 0x4f, 0x71, 0x3f, 0xf2, 0xad, 0x02, 0x58, 0xdf, 0x9e, 0x31, 0x86, 0x9b,
+ 0x1b, 0x41, 0xbf, 0x2a, 0x09, 0x00, 0x43, 0x5c, 0xa1, 0x7e, 0x76, 0x59, 0xef, 0xa6, 0xfc, 0x82,
+ 0xb2, 0x72, 0x5a
+ };
+ EXPECT_TRUE(srs_success == fmt.on_video(0, (char*)raw, sizeof(raw)));
+ EXPECT_TRUE(srs_success == enc.write_sample(
+ SrsMp4HandlerTypeVIDE, fmt.video->frame_type, 40, 40, mock_copy_bytes(fmt.raw, fmt.nb_raw), fmt.nb_raw
+ ));
+ }
+
+ uint64_t dts = 0;
+ EXPECT_TRUE(srs_success == enc.flush(dts));
+}
diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp
index ad8bb197c..73eb758bd 100644
--- a/trunk/src/utest/srs_utest_kernel.hpp
+++ b/trunk/src/utest/srs_utest_kernel.hpp
@@ -31,7 +31,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
+#include
#include
+#include
class MockBufferReader: public ISrsReader
{
@@ -48,7 +50,10 @@ class MockSrsFileWriter : public SrsFileWriter
{
public:
char* data;
+ int size;
int offset;
+ srs_error_t err;
+ int error_offset;
public:
MockSrsFileWriter();
virtual ~MockSrsFileWriter();
@@ -57,9 +62,11 @@ public:
virtual void close();
public:
virtual bool is_open();
+ virtual void seek2(int64_t offset);
virtual int64_t tellg();
public:
virtual srs_error_t write(void* buf, size_t count, ssize_t* pnwrite);
+ virtual srs_error_t lseek(off_t offset, int whence, off_t* seeked);
// for mock
public:
void mock_reset_offset();
@@ -73,6 +80,7 @@ public:
int offset;
public:
MockSrsFileReader();
+ MockSrsFileReader(const char* data, int nb_data);
virtual ~MockSrsFileReader();
public:
virtual srs_error_t open(std::string file);
@@ -93,5 +101,27 @@ public:
void mock_reset_offset();
};
+class MockSrsCodec : public ISrsCodec
+{
+public:
+ MockSrsCodec();
+ virtual ~MockSrsCodec();
+public:
+ virtual int nb_bytes();
+ virtual srs_error_t encode(SrsBuffer* buf);
+ virtual srs_error_t decode(SrsBuffer* buf);
+};
+
+class MockTsHandler : public ISrsTsHandler
+{
+public:
+ SrsTsMessage* msg;
+public:
+ MockTsHandler();
+ virtual ~MockTsHandler();
+public:
+ virtual srs_error_t on_ts_message(SrsTsMessage* m);
+};
+
#endif
diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp
index 694ecbaf4..3bc35fd6b 100644
--- a/trunk/src/utest/srs_utest_protocol.cpp
+++ b/trunk/src/utest/srs_utest_protocol.cpp
@@ -275,8 +275,6 @@ MockWallClock* MockWallClock::set_clock(int64_t ms)
return this;
}
-#ifdef ENABLE_UTEST_PROTOCOL
-
// verify the sha256
VOID TEST(ProtocolHandshakeTest, OpensslSha256)
{
@@ -6004,5 +6002,3 @@ VOID TEST(ProtocolKbpsTest, RAWStatistic)
}
}
-#endif
-
diff --git a/trunk/src/utest/srs_utest_reload.cpp b/trunk/src/utest/srs_utest_reload.cpp
index 3cbdd42c2..4897b48a0 100644
--- a/trunk/src/utest/srs_utest_reload.cpp
+++ b/trunk/src/utest/srs_utest_reload.cpp
@@ -299,8 +299,6 @@ srs_error_t MockSrsReloadConfig::do_reload(string buf)
return err;
}
-#ifdef ENABLE_UTEST_RELOAD
-
VOID TEST(ConfigReloadTest, ReloadEmpty)
{
MockReloadHandler handler;
@@ -920,5 +918,3 @@ VOID TEST(ConfigReloadTest, ReloadVhostIngestUpdated)
handler.reset();
}
-#endif
-