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

|

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