1
0
Fork 0
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:
winlin 2019-12-13 11:20:26 +08:00
commit c31c5eb05b
36 changed files with 2284 additions and 195 deletions

View file

@ -18,4 +18,3 @@ workflows:
jobs: jobs:
- build - build
- test - test

View file

@ -1,21 +0,0 @@
---
name: 提功能
about: 提功能需求,支持新的特性。
title: ''
labels: ''
assignees: ''
---
**你的功能是解决某个问题?**
请详细描述你的问题,例如在使用现有功能时碰到了困难。
**描述你期望的解决方案**
请详细描述你期望发生什么事情。
**请描述你考虑过的实现方法**
请描述你考虑过的实现方法。
**环境**
1. SRS的版本'...'
1. 操作系统:'...'

2
.gitignore vendored
View file

@ -31,3 +31,5 @@
.AppleDouble .AppleDouble
.idea .idea
.DS_Store

View file

@ -1,6 +1,6 @@
# SRS # SRS
![](http://ossrs.net:8000/gif/v1/sls.gif?site=github.com&path=/srs/develop) ![](http://ossrs.net/gif/v1/sls.gif?site=github.com&path=/srs/develop)
[![](https://circleci.com/gh/ossrs/srs/tree/develop.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/srs/tree/develop) [![](https://circleci.com/gh/ossrs/srs/tree/develop.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/srs/tree/develop)
[![](https://codecov.io/gh/ossrs/srs/branch/develop/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/develop) [![](https://codecov.io/gh/ossrs/srs/branch/develop/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/develop)
[![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat) [![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](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
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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">

View file

@ -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;

View file

@ -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.

View file

@ -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"

View file

@ -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;
@ -1160,6 +1165,10 @@ srs_error_t SrsHls::on_publish()
if ((err = controller->on_publish(req)) != srs_success) { if ((err = controller->on_publish(req)) != srs_success) {
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;
@ -1194,6 +1203,12 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
if (!enabled) { if (!enabled) {
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;
@ -1224,18 +1238,38 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma
previous_audio_dts = audio->timestamp; previous_audio_dts = audio->timestamp;
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) {
nb_samples_per_frame = 960; // 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;
} 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");
@ -1251,7 +1285,13 @@ srs_error_t SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* forma
if (!enabled) { if (!enabled) {
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();

View file

@ -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;

View file

@ -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));
} }

View file

@ -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>

View file

@ -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

View file

@ -177,7 +177,8 @@
#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.
// //

View file

@ -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.

View file

@ -64,9 +64,9 @@ 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)

View file

@ -200,9 +200,9 @@ string srs_generate_stream_with_query(string host, string vhost, string stream,
// Remove the start & when param is empty. // Remove the start & when param is empty.
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 += "?";
} }

View file

@ -137,7 +137,7 @@ namespace _srs_internal
0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
}; // 62 }; // 62
srs_error_t do_openssl_HMACsha256(HMAC_CTX* ctx, const void* data, int data_size, void* digest, unsigned int* digest_size) srs_error_t do_openssl_HMACsha256(HMAC_CTX* ctx, const void* data, int data_size, void* digest, unsigned int* digest_size)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
@ -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,
@ -201,24 +202,24 @@ namespace _srs_internal
return err; return err;
} }
#define RFC2409_PRIME_1024 \ #define RFC2409_PRIME_1024 \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
"FFFFFFFFFFFFFFFF" "FFFFFFFFFFFFFFFF"
SrsDH::SrsDH() SrsDH::SrsDH()
{ {
pdh = NULL; pdh = NULL;
} }
SrsDH::~SrsDH() SrsDH::~SrsDH()
{ {
close(); close();
} }
void SrsDH::close() void SrsDH::close()
{ {
if (pdh != NULL) { if (pdh != NULL) {

View file

@ -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;
@ -570,70 +600,26 @@ 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;
char* payload = NULL;
if ((err = packet->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 = 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) {
return srs_error_wrap(err, "on send packet");
}
return err;
}
srs_error_t SrsProtocol::do_simple_send(SrsMessageHeader* mh, char* payload, int size) SrsCommonMessage* msg = new SrsCommonMessage();
{ SrsAutoFree(SrsCommonMessage, msg);
srs_error_t err = srs_success;
if ((err = packet->to_msg(msg, stream_id)) != srs_success) {
return srs_error_wrap(err, "to message");
}
SrsSharedPtrMessage* shared_msg = new SrsSharedPtrMessage();
if ((err = shared_msg->create(msg)) != srs_success) {
srs_freep(shared_msg);
return srs_error_wrap(err, "create message");
}
if ((err = send_and_free_message(shared_msg, stream_id)) != srs_success) {
return srs_error_wrap(err, "send packet");
}
// we directly send out the packet, if ((err = on_send_packet(&msg->header, packet)) != srs_success) {
// use very simple algorithm, not very fast, return srs_error_wrap(err, "on send packet");
// 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; return err;
@ -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,9 +2899,13 @@ 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);
@ -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);

View file

@ -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);

View file

@ -255,6 +255,12 @@ bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char
level, getpid(), cid); level, getpid(), cid);
} }
} }
// 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;

View file

@ -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

View file

@ -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

View file

@ -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