mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
Merge
This commit is contained in:
commit
d2a4e08ba0
38 changed files with 24 additions and 9868 deletions
|
@ -24,14 +24,6 @@ jobs:
|
|||
- run: |
|
||||
echo "Build SRS without NASM or SRTP-NASM" &&
|
||||
cd trunk && ./configure --nasm=off --srtp-nasm=off && make
|
||||
build-c7-gb28181:
|
||||
docker:
|
||||
- image: ossrs/srs:dev
|
||||
steps:
|
||||
- checkout
|
||||
- run: |
|
||||
echo "Build SRS with GB28181" &&
|
||||
cd trunk && ./configure --gb28181=on && make
|
||||
build-c7-srt:
|
||||
docker:
|
||||
- image: ossrs/srs:dev
|
||||
|
@ -111,7 +103,7 @@ jobs:
|
|||
- checkout
|
||||
- run: |
|
||||
echo "Build and run utest for SRS" &&
|
||||
cd trunk && ./configure --gb28181=on --utest=on --gcov=on && make &&
|
||||
cd trunk && ./configure --utest=on --gcov=on && make &&
|
||||
./objs/srs_utest && bash auto/codecov.sh
|
||||
run-regression-test:
|
||||
docker:
|
||||
|
@ -140,7 +132,6 @@ workflows:
|
|||
- run-regression-test
|
||||
- build-c7-nortc
|
||||
- build-c7-noasm
|
||||
- build-c7-gb28181
|
||||
- build-c7-srt
|
||||
- build-c8-baseline
|
||||
- build-c8-srt
|
||||
|
|
|
@ -15,16 +15,14 @@ The changelog for SRS.
|
|||
|
||||
## SRS 4.0 Changelog
|
||||
|
||||
* v4.0, 2021-06-16, Change [GB28181](https://github.com/ossrs/srs/issues/1500) to [feature/gb28181](https://github.com/ossrs/srs/tree/feature/gb28181). 4.0.127
|
||||
* v4.0, 2021-06-01, Support --shared-ffmpeg to link with *.so for LGPL license. 4.0.126
|
||||
* v4.0, 2021-06-01, Support --shared-srt to link with *.so for MPL license. 4.0.125
|
||||
* v4.0, 2021-05-31, Use [SPDX-License-Identifier: MIT](https://spdx.dev/ids/). 4.0.124
|
||||
* v4.0, 2021-05-28, Fix bugs for GB28181 and RTC. 4.0.123
|
||||
* v4.0, 2021-05-21, Fix [#2370][bug #2370] bug for Firefox play stream(published by Chrome). 4.0.121
|
||||
* v4.0, 2021-05-21, RTC: Refine sdk, migrate from onaddstream to ontrack. 4.0.120
|
||||
* v4.0, 2021-05-21, Tools: Refine configure options. 4.0.119
|
||||
* v4.0, 2021-05-20, Fix build fail when disable RTC by --rtc=off. 4.0.118
|
||||
* v4.0, 2021-05-19, Fix [#2362][bug #2362]: Allow WebRTC to play before publishing, for GB28181 as such. 4.0.117
|
||||
* v4.0, 2021-05-18, Fix [#2355][bug #2355]: GB28181: Fix play by RTC bug. 4.0.116
|
||||
* v4.0, 2021-05-15, SRT: Build SRT from source by SRS. 4.0.115
|
||||
* v4.0, 2021-05-15, Rename SrsConsumer* to SrsLiveConsumer*. 4.0.114
|
||||
* v4.0, 2021-05-15, Rename SrsRtcStream* to SrsRtcSource*. 4.0.113
|
||||
|
@ -72,7 +70,6 @@ The changelog for SRS.
|
|||
* v4.0, 2021-01-08, HTML5 video tag resolution adaptive. 4.0.59
|
||||
* v4.0, 2021-01-08, Fix memory leak and bugs for RTC. 4.0.58
|
||||
* v4.0, 2021-01-06, Merge #2109, Refine srs_string_split.
|
||||
* v4.0, 2021-01-06, Merge #2109, Fix bugs for GB28181.
|
||||
* v4.0, 2020-12-24, Support disable CherryPy. 4.0.57
|
||||
* v4.0, 2020-11-12, For [#1998][bug #1998], Support Firefox, use PT in offer. 4.0.55
|
||||
* v4.0, 2020-11-11, For [#1508][bug #1508], Transform http header name to upper camel case. 4.0.54
|
||||
|
@ -90,10 +87,8 @@ The changelog for SRS.
|
|||
* v4.0, 2020-07-25, RTC: Support multiple address for client. 4.0.36
|
||||
* v4.0, 2020-07-11, Refine log context with random string. 4.0.35
|
||||
* v4.0, 2020-07-04, Fix some bugs for RTC. 4.0.34
|
||||
* v4.0, 2020-07-03, Merge [#1830][bug #1830] to fix bugs in GB28181. 4.0.33
|
||||
* v4.0, 2020-06-24, Support static link c++ libraries. 4.0.32
|
||||
* v4.0, 2020-06-23, Change log cid from int to string. 4.0.31
|
||||
* v4.0, 2020-06-13, GB28181 with JitterBuffer support. 4.0.30
|
||||
* v4.0, 2020-06-03, Support enable C++11. 4.0.29
|
||||
* v4.0, 2020-05-31, Remove [srs-librtmp](https://github.com/ossrs/srs/issues/1535#issuecomment-633907655). 4.0.28
|
||||
* v4.0, 2020-05-21, For [#307][bug #307], disable GSO and sendmmsg. 4.0.27
|
||||
|
@ -102,10 +97,8 @@ The changelog for SRS.
|
|||
* v4.0, 2020-04-30, For [#307][bug #307], support publish RTC with passing opus. 4.0.24
|
||||
* v4.0, 2020-04-14, For [#307][bug #307], support sendmmsg, GSO and reuseport. 4.0.23
|
||||
* v4.0, 2020-04-05, For [#307][bug #307], SRTP ASM only works with openssl-1.0, auto detect it. 4.0.22
|
||||
* v4.0, 2020-04-04, Merge RTC and GB28181, with bugs fixed. 4.0.21
|
||||
* v4.0, 2020-04-04, For [#307][bug #307], refine RTC latency from 600ms to 200ms. 4.0.20
|
||||
* v4.0, 2020-04-03, For [#307][bug #307], build SRTP with openssl to improve performance. 4.0.19
|
||||
* v4.0, 2020-03-31, For [#1500][bug #1500], support push stream by GB28181. 4.0.18
|
||||
* v4.0, 2020-03-31, Play stream by WebRTC on iOS/Android/PC browser. 4.0.17
|
||||
* v4.0, 2020-03-28, Support multiple OS/Platform build cache. 4.0.16
|
||||
* v4.0, 2020-03-28, For [#1250][bug #1250], support macOS, OSX, MacbookPro, Apple Darwin.
|
||||
|
|
12
README.md
12
README.md
|
@ -5,9 +5,9 @@
|
|||
[](https://codecov.io/gh/ossrs/srs/branch/develop)
|
||||
[](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
||||
|
||||
SRS/4.0,[Leo][release4],是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181。
|
||||
SRS/4.0,[Leo][release4],是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT。
|
||||
|
||||
SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181.
|
||||
SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT.
|
||||
|
||||
SRS is licenced under [MIT][LICENSE], but some depended libraries are distributed using their [own licenses][LicenseMixing].
|
||||
|
||||
|
@ -69,7 +69,6 @@ Fast index for Wikis:
|
|||
|
||||
Other important wiki:
|
||||
|
||||
* Usage: How to publish GB28181 to SRS? [#1500](https://github.com/ossrs/srs/issues/1500#issuecomment-606695679)
|
||||
* Usage: How to delivery DASH(Experimental)?([CN][v4_CN_SampleDASH], [EN][v4_EN_SampleDASH])
|
||||
* Usage: How to transode RTMP stream by FFMPEG?([CN][v4_CN_SampleFFMPEG], [EN][v4_EN_SampleFFMPEG])
|
||||
* Usage: How to delivery HTTP FLV Live Streaming Cluster?([CN][v4_CN_SampleHttpFlvCluster], [EN][v4_EN_SampleHttpFlvCluster])
|
||||
|
@ -121,9 +120,6 @@ For optional stream caster services, to push streams to SRS:
|
|||
* udp://8935, Stream Caster: [Push MPEGTS over UDP](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-mpeg-ts-over-udp) server.
|
||||
* tcp://554, Stream Caster: [Push RTSP](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-rtsp-to-srs) server.
|
||||
* tcp://8936, Stream Caster: [Push HTTP-FLV](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs) server.
|
||||
* tcp://5060, Stream Caster: [Push GB28181 SIP](https://github.com/ossrs/srs/issues/1500#issuecomment-606695679) server.
|
||||
* udp://9000, Stream Caster: [Push GB28181 Media(bundle)](https://github.com/ossrs/srs/issues/1500#issuecomment-606695679) server.
|
||||
* udp://58200-58300, Stream Caster: [Push GB28181 Media(no-bundle)](https://github.com/ossrs/srs/issues/1500#issuecomment-606695679) server.
|
||||
* udp://10080, Stream Caster: [Push SRT Media](https://github.com/ossrs/srs/issues/1147#issuecomment-577469119) server.
|
||||
|
||||
For external services to work with SRS:
|
||||
|
@ -176,7 +172,7 @@ For external services to work with SRS:
|
|||
- [x] [Experimental] Support transcode RTMP/AAC to WebRTC/Opus, [#307][bug #307].
|
||||
- [x] [Experimental] Support AV1 codec for WebRTC, [#2324][bug #2324].
|
||||
- [x] [Experimental] Enhance HTTP Stream Server for HTTP-FLV, HTTPS, HLS etc. [#1657][bug #1657].
|
||||
- [x] [Experimental] Support push stream by GB28181, [#1500][bug #1500].
|
||||
- [ ] Support push stream by GB28181, [#1500][bug #1500].
|
||||
- [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738].
|
||||
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
|
||||
- [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250].
|
||||
|
@ -307,7 +303,7 @@ The stream architecture of SRS.
|
|||
| MediaSource(2) | | |
|
||||
| (MPEGTSoverUDP | | |
|
||||
| HTTP-FLV, --push-+->- StreamCaster(4) -(rtmp)-+-> SRS |
|
||||
| GB28181,SRT, | | |
|
||||
| SRT, | | |
|
||||
| ......) | | |
|
||||
+----------------------+ | |
|
||||
| FFMPEG --push(srt)--+->- SRTModule(5) ---(rtmp)-+-> SRS |
|
||||
|
|
|
@ -85,12 +85,6 @@ else
|
|||
srs_undefine_macro "SRS_SIMULATOR" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_GB28181 = YES ]; then
|
||||
srs_define_macro "SRS_GB28181" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_GB28181" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_HTTPS = YES ]; then
|
||||
srs_define_macro "SRS_HTTPS" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
|
|
|
@ -299,15 +299,6 @@ function OSX_prepare()
|
|||
echo "Please install pkg-config"; exit -1;
|
||||
fi
|
||||
|
||||
if [[ $SRS_GB28181 == YES ]]; then
|
||||
if [[ ! -f /usr/local/opt/libiconv/lib/libiconv.a ]]; then
|
||||
echo "install libiconv"
|
||||
echo "brew install libiconv"
|
||||
brew install libiconv; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "install libiconv success"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
echo "SRT enable, install depend tools"
|
||||
tclsh <<< "exit" >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
|
|
|
@ -6,7 +6,6 @@ help=no
|
|||
SRS_HDS=NO
|
||||
SRS_SRT=NO
|
||||
SRS_RTC=RESERVED
|
||||
SRS_GB28181=NO
|
||||
SRS_CXX11=YES
|
||||
SRS_CXX14=NO
|
||||
SRS_NGINX=NO
|
||||
|
@ -115,7 +114,6 @@ Features:
|
|||
--utest=on|off Whether build the utest. Default: $(value2switch $SRS_UTEST)
|
||||
--srt=on|off Whether build the SRT. Default: $(value2switch $SRS_SRT)
|
||||
--rtc=on|off Whether build the WebRTC. Default: $(value2switch $SRS_RTC)
|
||||
--gb28181=on|off Whether build the GB28181. Default: $(value2switch $SRS_GB28181)
|
||||
--cxx11=on|off Whether enable the C++11. Default: $(value2switch $SRS_CXX11)
|
||||
--cxx14=on|off Whether enable the C++14. Default: $(value2switch $SRS_CXX14)
|
||||
--ffmpeg-fit=on|off Whether enable the FFmpeg fit(source code). Default: $(value2switch $SRS_FFMPEG_FIT)
|
||||
|
@ -265,10 +263,6 @@ function parse_user_option() {
|
|||
--simulator) SRS_SIMULATOR=$(switch2value $value) ;;
|
||||
--ffmpeg-fit) SRS_FFMPEG_FIT=$(switch2value $value) ;;
|
||||
|
||||
--with-gb28181) SRS_GB28181=YES ;;
|
||||
--without-gb28181) SRS_GB28181=NO ;;
|
||||
--gb28181) SRS_GB28181=$(switch2value $value) ;;
|
||||
|
||||
--cxx11) SRS_CXX11=$(switch2value $value) ;;
|
||||
--cxx14) SRS_CXX14=$(switch2value $value) ;;
|
||||
|
||||
|
@ -356,14 +350,18 @@ function parse_user_option_to_value_and_option() {
|
|||
esac
|
||||
}
|
||||
|
||||
# For variable values, might be three values: YES, RESERVED, NO(by default).
|
||||
function value2switch() {
|
||||
if [[ $1 == YES ]]; then
|
||||
echo on;
|
||||
else if [[ $1 == RESERVED ]]; then
|
||||
echo reserved;
|
||||
else
|
||||
echo off;
|
||||
fi
|
||||
}
|
||||
|
||||
# For user options, only off or on(by default).
|
||||
function switch2value() {
|
||||
if [[ $1 == off ]]; then
|
||||
echo NO;
|
||||
|
@ -473,7 +471,6 @@ function regenerate_options() {
|
|||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --srt=$(value2switch $SRS_SRT)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --rtc=$(value2switch $SRS_RTC)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --simulator=$(value2switch $SRS_SIMULATOR)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gb28181=$(value2switch $SRS_GB28181)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx11=$(value2switch $SRS_CXX11)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx14=$(value2switch $SRS_CXX14)"
|
||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --ffmpeg-fit=$(value2switch $SRS_FFMPEG_FIT)"
|
||||
|
|
|
@ -366,89 +366,6 @@ stream_caster {
|
|||
listen 8936;
|
||||
}
|
||||
|
||||
# GB28181
|
||||
stream_caster {
|
||||
# whether stream caster is enabled.
|
||||
# default: off
|
||||
enabled on;
|
||||
# the caster type of stream, the casters:
|
||||
# gb28181, Push GB28181 to SRS.
|
||||
caster gb28181;
|
||||
# the output rtmp url.
|
||||
# for gb28181 caster, the typically output url:
|
||||
# rtmp://127.0.0.1/live/[stream]
|
||||
# where the [stream] is the VideoChannelCodecID.
|
||||
output rtmp://127.0.0.1/live/[stream];
|
||||
# the listen port for stream caster.
|
||||
# for gb28181 caster, listen at udp port. for example, 9000.
|
||||
# @remark We can bundle all gb28181 to this port, to reuse this port.
|
||||
# User can choose to bundle port in API port_mode or SIP invite_port_fixed.
|
||||
listen 9000;
|
||||
# Listen as TCP if on; otherwise, listen as UDP.
|
||||
# default: off
|
||||
tcp_enable off;
|
||||
# If not bundle ports, use specified ports for each stream.
|
||||
rtp_port_min 58200;
|
||||
rtp_port_max 58300;
|
||||
# Whether wait for keyframe then forward to RTMP.
|
||||
# default: on
|
||||
wait_keyframe on;
|
||||
# Max timeout in seconds for RTP stream, if timeout, RTCP bye and close stream.
|
||||
# default: 30
|
||||
rtp_idle_timeout 30;
|
||||
# Whether has audio.
|
||||
# @remark Flash/RTMP only supports 11025 22050 44100 sample rate, if not the audio may corrupt.
|
||||
# default: off
|
||||
audio_enable off;
|
||||
# The exposed IP to receive media stream.
|
||||
# * Retrieve server IP automatically, from all network interfaces.
|
||||
# eth0 Retrieve server IP by specified network interface name. # TODO: Implements it.
|
||||
# $CANDIDATE Read the IP from ENV variable $EIP, use * if not set, see https://github.com/ossrs/srs/issues/307#issuecomment-599028124
|
||||
# x.x.x.x A specified IP address or DNS name, which can be access by client such as Chrome.
|
||||
# You can specific more than one interface name:
|
||||
# eth0 eth1 Use network interface eth0 and eth1. # TODO: Implements it.
|
||||
# Also by IP or DNS names:
|
||||
# 192.168.1.3 10.1.2.3 rtc.me # TODO: Implements it.
|
||||
# And by multiple ENV variables:
|
||||
# $CANDIDATE $EIP # TODO: Implements it.
|
||||
# default: *
|
||||
host *;
|
||||
#The media channel is automatically created according to the received RTP packet,
|
||||
# and the channel ID is generated according to the RTP SSRC
|
||||
# channelid format: 'chid[ssrc]' [ssrc] is rtp's ssrc
|
||||
auto_create_channel off;
|
||||
|
||||
sip {
|
||||
# Whether enable embeded SIP server.
|
||||
# default: on
|
||||
enabled on;
|
||||
# The SIP listen port.
|
||||
# default: 5060
|
||||
listen 5060;
|
||||
# The SIP server ID.
|
||||
# default: 34020000002000000001
|
||||
serial 34020000002000000001;
|
||||
# The SIP server domain.
|
||||
# default: 3402000000
|
||||
realm 3402000000;
|
||||
# The SIP ACK response timeout in seconds.
|
||||
# default: 30
|
||||
ack_timeout 30;
|
||||
# The keepalive timeout in seconds.
|
||||
# default: 120
|
||||
keepalive_timeout 120;
|
||||
# Whether play immediately after registered.
|
||||
# default: on
|
||||
auto_play on;
|
||||
# Whether bundle media stream port.
|
||||
# default: on
|
||||
invite_port_fixed on;
|
||||
# interval to query equipment list from equipment or subordinate domain, unit(s)
|
||||
# default: 60
|
||||
query_catalog_interval 60;
|
||||
}
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
# SRT server section
|
||||
#############################################################################################
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
# push gb28181 stream to SRS.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
|
||||
http_api {
|
||||
enabled on;
|
||||
listen 1985;
|
||||
}
|
||||
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 8080;
|
||||
}
|
||||
|
||||
stats {
|
||||
network 0;
|
||||
}
|
||||
|
||||
stream_caster {
|
||||
enabled on;
|
||||
caster gb28181;
|
||||
|
||||
# 转发流到rtmp服务器地址与端口
|
||||
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400875104
|
||||
# [stream] is VideoChannelCodecID(视频通道编码ID) for sip
|
||||
# 自动创建的道通[stream] 是‘chid[ssrc]’ [ssrc]是rtp的ssrc
|
||||
# [ssrc] rtp中的ssrc
|
||||
output rtmp://127.0.0.1:1935/live/[stream];
|
||||
|
||||
# 接收设备端rtp流的多路复用端口
|
||||
listen 9000;
|
||||
# 多路复用端口类型,on为tcp,off为udp
|
||||
# 默认:on
|
||||
tcp_enable on;
|
||||
|
||||
# rtp接收监听端口范围,最小值
|
||||
rtp_port_min 58200;
|
||||
# rtp接收监听端口范围,最大值
|
||||
rtp_port_max 58300;
|
||||
|
||||
# 是否等待关键帧之后,再转发,
|
||||
# off:不需等待,直接转发
|
||||
# on:等第一个关键帧后,再转发
|
||||
wait_keyframe on;
|
||||
|
||||
# rtp包空闲等待时间,如果指定时间没有收到任何包
|
||||
# rtp监听连接自动停止,发送BYE命令
|
||||
rtp_idle_timeout 30;
|
||||
|
||||
# 是否转发音频流
|
||||
# 目前只支持aac格式,所以需要设备支持aac格式
|
||||
# on:转发音频
|
||||
# off:不转发音频,只有视频
|
||||
# *注意*!!!:flv 只支持11025 22050 44100 三种
|
||||
# 如果设备端没有三种中任何一个,转发时为自动选择一种格式
|
||||
# 同时也会将adts的头封装在flv aac raw数据中
|
||||
# 这样的话播放器为自动通过adts头自动选择采样频率
|
||||
# 像ffplay, vlc都可以,但是flash是没有声音,
|
||||
# 因为flash,只支持11025 22050 44100
|
||||
audio_enable off;
|
||||
|
||||
# 是否开启rtp缓冲
|
||||
# 开启之后能有效解决rtp乱序等问题
|
||||
# tcp模式建议关闭
|
||||
jitterbuffer_enable off;
|
||||
|
||||
# 服务器主机号,可以域名或ip地址
|
||||
# 也就是设备端将媒体发送的地址,如果是服务器是内外网
|
||||
# 需要写外网地址,
|
||||
# 调用api创建stream session时返回ip地址也是host
|
||||
# $CANDIDATE 是系统环境变量,从环境变量获取地址,如果没有配置,用*
|
||||
# *代表指定stats network 的网卡号地址,如果没有配置network,默认则是第0号网卡地址
|
||||
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400917594
|
||||
host $CANDIDATE;
|
||||
|
||||
#根据收到ps rtp包自带创建rtmp媒体通道,不需要api接口创建
|
||||
#rtmp地址参数[stream] 就是通道id 格式chid[ssrc]
|
||||
auto_create_channel off;
|
||||
|
||||
sip {
|
||||
# 是否启用srs内部sip信令
|
||||
# 为on信令走srs, off 只转发ps流
|
||||
enabled on;
|
||||
|
||||
# sip监听udp端口
|
||||
listen 5060;
|
||||
|
||||
# SIP server ID(SIP服务器ID).
|
||||
# 设备端配置编号需要与该值一致,否则无法注册
|
||||
serial 34020000002000000001;
|
||||
|
||||
# SIP server domain(SIP服务器域)
|
||||
realm 3402000000;
|
||||
|
||||
# 服务端发送ack后,接收回应的超时时间,单位为秒
|
||||
# 如果指定时间没有回应,认为失败
|
||||
ack_timeout 30;
|
||||
|
||||
# 设备心跳维持时间,如果指定时间内(秒)没有接收一个心跳
|
||||
# 认为设备离线
|
||||
keepalive_timeout 120;
|
||||
|
||||
# 注册之后是否自动给设备端发送invite
|
||||
# on: 是 off 不是,需要通过api控制
|
||||
auto_play on;
|
||||
# 设备将流发送的端口,是否固定
|
||||
# on 发送流到多路复用端口 如9000
|
||||
# off 自动从rtp_mix_port - rtp_max_port 之间的值中
|
||||
# 选一个可以用的端口
|
||||
invite_port_fixed on;
|
||||
|
||||
# 向设备或下级域查询设备列表的间隔,单位(秒)
|
||||
# 默认60秒
|
||||
query_catalog_interval 60;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_server {
|
||||
enabled on;
|
||||
# Listen at udp://8000
|
||||
listen 8000;
|
||||
#
|
||||
# The $CANDIDATE means fetch from env, if not configed, use * as default.
|
||||
#
|
||||
# The * means retrieving server IP automatically, from all network interfaces,
|
||||
# @see https://github.com/ossrs/srs/issues/307#issuecomment-599028124
|
||||
candidate $CANDIDATE;
|
||||
}
|
||||
|
||||
vhost __defaultVhost__ {
|
||||
rtc {
|
||||
enabled on;
|
||||
bframe discard;
|
||||
}
|
||||
|
||||
http_remux {
|
||||
enabled on;
|
||||
mount [vhost]/[app]/[stream].flv;
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
# push gb28181 stream to SRS.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
|
||||
http_api {
|
||||
enabled on;
|
||||
listen 1985;
|
||||
}
|
||||
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 8080;
|
||||
}
|
||||
|
||||
stats {
|
||||
network 0;
|
||||
}
|
||||
|
||||
stream_caster {
|
||||
enabled on;
|
||||
caster gb28181;
|
||||
|
||||
# 转发流到rtmp服务器地址与端口
|
||||
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400875104
|
||||
# [stream] is VideoChannelCodecID(视频通道编码ID) for sip
|
||||
# 自动创建的道通[stream] 是‘chid[ssrc]’ [ssrc]是rtp的ssrc
|
||||
# [ssrc] rtp中的ssrc
|
||||
output rtmp://127.0.0.1:1935/live/[stream];
|
||||
|
||||
# 接收设备端rtp流的多路复用端口
|
||||
listen 9000;
|
||||
# 多路复用端口类型,on为tcp,off为udp
|
||||
# 默认:off
|
||||
tcp_enable on;
|
||||
|
||||
# rtp接收监听端口范围,最小值
|
||||
rtp_port_min 58200;
|
||||
# rtp接收监听端口范围,最大值
|
||||
rtp_port_max 58300;
|
||||
|
||||
# 是否等待关键帧之后,再转发,
|
||||
# off:不需等待,直接转发
|
||||
# on:等第一个关键帧后,再转发
|
||||
wait_keyframe on;
|
||||
|
||||
# rtp包空闲等待时间,如果指定时间没有收到任何包
|
||||
# rtp监听连接自动停止,发送BYE命令
|
||||
rtp_idle_timeout 30;
|
||||
|
||||
# 是否转发音频流
|
||||
# 目前只支持aac格式,所以需要设备支持aac格式
|
||||
# on:转发音频
|
||||
# off:不转发音频,只有视频
|
||||
# *注意*!!!:flv 只支持11025 22050 44100 三种
|
||||
# 如果设备端没有三种中任何一个,转发时为自动选择一种格式
|
||||
# 同时也会将adts的头封装在flv aac raw数据中
|
||||
# 这样的话播放器为自动通过adts头自动选择采样频率
|
||||
# 像ffplay, vlc都可以,但是flash是没有声音,
|
||||
# 因为flash,只支持11025 22050 44100
|
||||
audio_enable off;
|
||||
|
||||
# 是否开启rtp缓冲
|
||||
# 开启之后能有效解决rtp乱序等问题
|
||||
# tcp模式建议关闭
|
||||
jitterbuffer_enable off;
|
||||
|
||||
# 服务器主机号,可以域名或ip地址
|
||||
# 也就是设备端将媒体发送的地址,如果是服务器是内外网
|
||||
# 需要写外网地址,
|
||||
# 调用api创建stream session时返回ip地址也是host
|
||||
# $CANDIDATE 是系统环境变量,从环境变量获取地址,如果没有配置,用*
|
||||
# *代表指定stats network 的网卡号地址,如果没有配置network,默认则是第0号网卡地址
|
||||
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400917594
|
||||
host $CANDIDATE;
|
||||
|
||||
#根据收到ps rtp包自带创建rtmp媒体通道,不需要api接口创建
|
||||
#rtmp地址参数[stream] 就是通道id 格式chid[ssrc]
|
||||
auto_create_channel off;
|
||||
|
||||
sip {
|
||||
# 是否启用srs内部sip信令
|
||||
# 为on信令走srs, off 只转发ps流
|
||||
enabled on;
|
||||
|
||||
# sip监听udp端口
|
||||
listen 5060;
|
||||
|
||||
# SIP server ID(SIP服务器ID).
|
||||
# 设备端配置编号需要与该值一致,否则无法注册
|
||||
serial 34020000002000000001;
|
||||
|
||||
# SIP server domain(SIP服务器域)
|
||||
realm 3402000000;
|
||||
|
||||
# 服务端发送ack后,接收回应的超时时间,单位为秒
|
||||
# 如果指定时间没有回应,认为失败
|
||||
ack_timeout 30;
|
||||
|
||||
# 设备心跳维持时间,如果指定时间内(秒)没有接收一个心跳
|
||||
# 认为设备离线
|
||||
keepalive_timeout 120;
|
||||
|
||||
# 注册之后是否自动给设备端发送invite
|
||||
# on: 是 off 不是,需要通过api控制
|
||||
auto_play on;
|
||||
# 设备将流发送的端口,是否固定
|
||||
# on 发送流到多路复用端口 如9000
|
||||
# off 自动从rtp_mix_port - rtp_max_port 之间的值中
|
||||
# 选一个可以用的端口
|
||||
invite_port_fixed on;
|
||||
|
||||
# 向设备或下级域查询设备列表的间隔,单位(秒)
|
||||
# 默认60秒
|
||||
query_catalog_interval 60;
|
||||
}
|
||||
}
|
||||
|
||||
rtc_server {
|
||||
enabled on;
|
||||
# Listen at udp://8000
|
||||
listen 8000;
|
||||
#
|
||||
# The $CANDIDATE means fetch from env, if not configed, use * as default.
|
||||
#
|
||||
# The * means retrieving server IP automatically, from all network interfaces,
|
||||
# @see https://github.com/ossrs/srs/issues/307#issuecomment-599028124
|
||||
candidate $CANDIDATE;
|
||||
}
|
||||
|
||||
vhost __defaultVhost__ {
|
||||
rtc {
|
||||
enabled on;
|
||||
bframe discard;
|
||||
}
|
||||
|
||||
http_remux {
|
||||
enabled on;
|
||||
mount [vhost]/[app]/[stream].flv;
|
||||
}
|
||||
}
|
15
trunk/configure
vendored
15
trunk/configure
vendored
|
@ -168,11 +168,6 @@ if [[ $SRS_SRT == YES ]]; then
|
|||
if [[ $SRS_SHARED_SRT == YES ]]; then LibSRTfile="-L${SRS_OBJS_DIR}/srt/lib -lsrt"; fi
|
||||
fi
|
||||
|
||||
# For iconv on macOS only, CentOS seems ok.
|
||||
if [[ $SRS_GB28181 == YES && $SRS_OSX == YES ]]; then
|
||||
LibIconvRoot="/usr/local/opt/libiconv/include"; LibIconvfile="/usr/local/opt/libiconv/lib/libiconv.a"
|
||||
fi
|
||||
|
||||
# the link options, always use static link
|
||||
SrsLinkOptions="-ldl -lpthread";
|
||||
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then
|
||||
|
@ -284,13 +279,6 @@ fi
|
|||
if [[ $SRS_FFMPEG_FIT == YES ]]; then
|
||||
MODULE_FILES+=("srs_app_rtc_codec")
|
||||
fi
|
||||
if [[ $SRS_GB28181 == YES ]]; then
|
||||
MODULE_FILES+=("srs_app_gb28181" "srs_app_gb28181_sip" "srs_app_gb28181_jitter")
|
||||
fi
|
||||
if [[ $SRS_GB28181 == YES ]]; then
|
||||
MODULE_FILES+=("srs_app_gb28181_stack")
|
||||
ModuleLibIncs+=(${LibIconvRoot})
|
||||
fi
|
||||
|
||||
DEFINES=""
|
||||
# add each modules for app
|
||||
|
@ -370,9 +358,6 @@ fi
|
|||
if [[ $SRS_SRT == YES ]]; then
|
||||
ModuleLibFiles+=("${LibSRTfile[*]}")
|
||||
fi
|
||||
if [[ $SRS_GB28181 == YES ]]; then
|
||||
ModuleLibFiles+=("${LibIconvfile[*]}")
|
||||
fi
|
||||
# all depends objects
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}"
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibGperfRoot} ${LibSSLRoot})
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!--<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>-->
|
||||
<!--<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>-->
|
||||
<!--<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>-->
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>-->
|
||||
<li>
|
||||
<a href="https://github.com/ossrs/srs">
|
||||
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ossrs/srs?style=social">
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!--<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>-->
|
||||
<!--<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>-->
|
||||
<!--<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>-->
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>-->
|
||||
<li>
|
||||
<a href="https://github.com/ossrs/srs">
|
||||
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ossrs/srs?style=social">
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
|
||||
<li class="active"><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
|
||||
<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">SRS-GB28181</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<li class="active"><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
|
||||
<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
|
||||
<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">SRS-GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">SRS-GB28181</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<!--<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>-->
|
||||
<!--<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>-->
|
||||
<!--li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>-->
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>-->
|
||||
<li>
|
||||
<a href="https://github.com/ossrs/srs">
|
||||
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ossrs/srs?style=social">
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<!--<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>-->
|
||||
<!--<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>-->
|
||||
<!--li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>-->
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>-->
|
||||
<li>
|
||||
<a href="https://github.com/ossrs/srs">
|
||||
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ossrs/srs?style=social">
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
|
||||
<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
|
||||
<li class="active"><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
|
||||
<li><a id="nav_gb28181" href="srs_gb28181.html">SRS-GB28181</a></li>
|
||||
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">SRS-GB28181</a></li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -262,11 +262,6 @@ bool srs_stream_caster_is_flv(string caster)
|
|||
return caster == "flv";
|
||||
}
|
||||
|
||||
bool srs_stream_caster_is_gb28181(string caster)
|
||||
{
|
||||
return caster == "gb28181";
|
||||
}
|
||||
|
||||
bool srs_config_apply_filter(SrsConfDirective* dvr_apply, SrsRequest* req)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
@ -4590,302 +4585,6 @@ int SrsConfig::get_stream_caster_rtp_port_max(SrsConfDirective* conf)
|
|||
return ::atoi(conf->arg0().c_str());
|
||||
}
|
||||
|
||||
srs_utime_t SrsConfig::get_stream_caster_gb28181_rtp_idle_timeout(SrsConfDirective* conf)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("rtp_idle_timeout");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
srs_utime_t SrsConfig::get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("ack_timeout");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
srs_utime_t SrsConfig::get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 120 * SRS_UTIME_SECONDS;
|
||||
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("keepalive_timeout");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
string SrsConfig::get_stream_caster_gb28181_host(SrsConfDirective* conf)
|
||||
{
|
||||
static string DEFAULT = "*";
|
||||
|
||||
conf = conf->get("host");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
string eip = srs_getenv(conf->arg0());
|
||||
if (!eip.empty()) {
|
||||
return eip;
|
||||
}
|
||||
|
||||
// If configed as ENV, but no ENV set, use default value.
|
||||
if (srs_string_starts_with(conf->arg0(), "$")) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return conf->arg0();
|
||||
}
|
||||
|
||||
string SrsConfig::get_stream_caster_gb28181_serial(SrsConfDirective* conf)
|
||||
{
|
||||
static string DEFAULT = "34020000002000000001";
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("serial");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return conf->arg0();
|
||||
}
|
||||
|
||||
string SrsConfig::get_stream_caster_gb28181_realm(SrsConfDirective* conf)
|
||||
{
|
||||
static string DEFAULT = "3402000000";
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("realm");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return conf->arg0();
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_audio_enable(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = false;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("audio_enable");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_jitterbuffer_enable(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("jitterbuffer_enable");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_wait_keyframe(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("wait_keyframe");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_sip_enable(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("enabled");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_sip_auto_play(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("auto_play");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
|
||||
}
|
||||
|
||||
int SrsConfig::get_stream_caster_gb28181_sip_listen(SrsConfDirective* conf)
|
||||
{
|
||||
static int DEFAULT = 5060;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("listen");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return ::atoi(conf->arg0().c_str());
|
||||
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_sip_invite_port_fixed(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("invite_port_fixed");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
|
||||
}
|
||||
|
||||
bool SrsConfig::get_stream_caster_gb28181_auto_create_channel(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = false;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("auto_create_channel");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
srs_utime_t SrsConfig::get_stream_caster_gb28181_sip_query_catalog_interval(SrsConfDirective* conf)
|
||||
{
|
||||
static srs_utime_t DEFAULT = 60 * SRS_UTIME_SECONDS;
|
||||
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("sip");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("query_catalog_interval");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_server_enabled()
|
||||
{
|
||||
SrsConfDirective* conf = root->get("rtc_server");
|
||||
|
|
|
@ -102,7 +102,6 @@ extern bool srs_config_dvr_is_plan_session(std::string plan);
|
|||
extern bool srs_stream_caster_is_udp(std::string caster);
|
||||
extern bool srs_stream_caster_is_rtsp(std::string caster);
|
||||
extern bool srs_stream_caster_is_flv(std::string caster);
|
||||
extern bool srs_stream_caster_is_gb28181(std::string caster);
|
||||
// Whether the dvr_apply active the stream specified by req.
|
||||
extern bool srs_config_apply_filter(SrsConfDirective* dvr_apply, SrsRequest* req);
|
||||
|
||||
|
@ -502,22 +501,6 @@ public:
|
|||
// Get the max udp port for rtp of stream caster rtsp.
|
||||
virtual int get_stream_caster_rtp_port_max(SrsConfDirective* conf);
|
||||
|
||||
virtual srs_utime_t get_stream_caster_gb28181_rtp_idle_timeout(SrsConfDirective* conf);
|
||||
virtual srs_utime_t get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf);
|
||||
virtual srs_utime_t get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_audio_enable(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_jitterbuffer_enable(SrsConfDirective* conf);
|
||||
virtual std::string get_stream_caster_gb28181_host(SrsConfDirective* conf);
|
||||
virtual std::string get_stream_caster_gb28181_serial(SrsConfDirective* conf);
|
||||
virtual std::string get_stream_caster_gb28181_realm(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_wait_keyframe(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_sip_enable(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_sip_auto_play(SrsConfDirective* conf);
|
||||
virtual int get_stream_caster_gb28181_sip_listen(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_sip_invite_port_fixed(SrsConfDirective* conf);
|
||||
virtual bool get_stream_caster_gb28181_auto_create_channel(SrsConfDirective* conf);
|
||||
virtual srs_utime_t get_stream_caster_gb28181_sip_query_catalog_interval(SrsConfDirective* conf);
|
||||
|
||||
// rtc section
|
||||
public:
|
||||
virtual bool get_rtc_server_enabled();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,581 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2021 Lixin
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_APP_GB28181_HPP
|
||||
#define SRS_APP_GB28181_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
|
||||
#include <srs_app_st.hpp>
|
||||
#include <srs_app_listener.hpp>
|
||||
#include <srs_kernel_stream.hpp>
|
||||
#include <srs_app_log.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_protocol_json.hpp>
|
||||
#include <srs_app_gb28181_sip.hpp>
|
||||
#include <srs_app_gb28181_jitter.hpp>
|
||||
#include <srs_rtmp_stack.hpp>
|
||||
#include <srs_app_source.hpp>
|
||||
#include <srs_service_conn.hpp>
|
||||
|
||||
#define RTP_PORT_MODE_FIXED "fixed"
|
||||
#define RTP_PORT_MODE_RANDOM "random"
|
||||
|
||||
#define PS_AUDIO_ID 0xc0
|
||||
#define PS_AUDIO_ID_END 0xdf
|
||||
#define PS_VIDEO_ID 0xe0
|
||||
#define PS_VIDEO_ID_END 0xef
|
||||
|
||||
#define STREAM_TYPE_VIDEO_MPEG1 0x01
|
||||
#define STREAM_TYPE_VIDEO_MPEG2 0x02
|
||||
#define STREAM_TYPE_AUDIO_MPEG1 0x03
|
||||
#define STREAM_TYPE_AUDIO_MPEG2 0x04
|
||||
#define STREAM_TYPE_PRIVATE_SECTION 0x05
|
||||
#define STREAM_TYPE_PRIVATE_DATA 0x06
|
||||
#define STREAM_TYPE_AUDIO_AAC 0x0f
|
||||
#define STREAM_TYPE_VIDEO_MPEG4 0x10
|
||||
#define STREAM_TYPE_VIDEO_H264 0x1b
|
||||
#define STREAM_TYPE_VIDEO_HEVC 0x24
|
||||
#define STREAM_TYPE_VIDEO_CAVS 0x42
|
||||
#define STREAM_TYPE_VIDEO_SAVC 0x80
|
||||
|
||||
#define STREAM_TYPE_AUDIO_AC3 0x81
|
||||
|
||||
#define STREAM_TYPE_AUDIO_G711 0x90
|
||||
#define STREAM_TYPE_AUDIO_G711ULAW 0x91
|
||||
#define STREAM_TYPE_AUDIO_G722_1 0x92
|
||||
#define STREAM_TYPE_AUDIO_G723_1 0x93
|
||||
#define STREAM_TYPE_AUDIO_G726 0x96
|
||||
#define STREAM_TYPE_AUDIO_G729_1 0x99
|
||||
#define STREAM_TYPE_AUDIO_SVAC 0x9b
|
||||
#define STREAM_TYPE_AUDIO_PCM 0x9c
|
||||
|
||||
class SrsConfDirective;
|
||||
class SrsRtspPacket;
|
||||
class SrsRtmpClient;
|
||||
class SrsRawH264Stream;
|
||||
class SrsRawAacStream;
|
||||
struct SrsRawAacStreamCodec;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsAudioFrame;
|
||||
class SrsSimpleStream;
|
||||
class SrsPithyPrint;
|
||||
class SrsSimpleRtmpClient;
|
||||
class SrsSipStack;
|
||||
class SrsGb28181Manger;
|
||||
class SrsRtpTimeJitter;
|
||||
class SrsSipRequest;
|
||||
class SrsGb28181RtmpMuxer;
|
||||
class SrsGb28181Config;
|
||||
class SrsGb28181PsRtpProcessor;
|
||||
class SrsGb28181SipService;
|
||||
class SrsGb28181StreamChannel;
|
||||
class SrsGb28181SipSession;
|
||||
class SrsRtpJitterBuffer;
|
||||
class SrsServer;
|
||||
class SrsLiveSource;
|
||||
class SrsRequest;
|
||||
class SrsResourceManager;
|
||||
class SrsGb28181Conn;
|
||||
class SrsGb28181Caster;
|
||||
|
||||
//ps rtp header packet parse
|
||||
|
||||
class SrsPsRtpPacket: public SrsRtspPacket
|
||||
{
|
||||
public:
|
||||
SrsPsRtpPacket();
|
||||
virtual ~SrsPsRtpPacket();
|
||||
bool isFirstPacket;
|
||||
public:
|
||||
virtual srs_error_t decode(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
//randomly assigned ports receive gb28181 device streams
|
||||
class SrsPsRtpListener: public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
SrsUdpListener* listener;
|
||||
SrsGb28181PsRtpProcessor* rtp_processor;
|
||||
int _port;
|
||||
public:
|
||||
SrsPsRtpListener(SrsGb28181Config* c, int p, std::string s);
|
||||
virtual ~SrsPsRtpListener();
|
||||
public:
|
||||
virtual int port();
|
||||
virtual srs_error_t listen();
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
};
|
||||
|
||||
//multiplexing service, single port receiving all gb28181 device streams
|
||||
class SrsGb28181RtpMuxService : public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
SrsGb28181Config *config;
|
||||
SrsGb28181PsRtpProcessor *rtp_processor;
|
||||
public:
|
||||
SrsGb28181RtpMuxService(SrsConfDirective* c);
|
||||
virtual ~SrsGb28181RtpMuxService();
|
||||
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
};
|
||||
|
||||
|
||||
//process gb28181 RTP package, generate a completed PS stream data,
|
||||
//call the PS stream parser, parse the original video and audio
|
||||
class SrsGb28181PsRtpProcessor: public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
SrsPithyPrint* pprint;
|
||||
SrsGb28181Config* config;
|
||||
std::map<std::string, SrsPsRtpPacket*> cache_ps_rtp_packet;
|
||||
std::map<std::string, SrsPsRtpPacket*> pre_packet;
|
||||
std::string channel_id;
|
||||
bool auto_create_channel;
|
||||
public:
|
||||
SrsGb28181PsRtpProcessor(SrsGb28181Config* c, std::string sid);
|
||||
virtual ~SrsGb28181PsRtpProcessor();
|
||||
private:
|
||||
bool can_send_ps_av_packet();
|
||||
void dispose();
|
||||
void clear_pre_packet();
|
||||
SrsGb28181RtmpMuxer* fetch_rtmpmuxer(std::string channel_id, uint32_t ssrc);
|
||||
srs_error_t rtmpmuxer_enqueue_data(SrsGb28181RtmpMuxer *muxer, uint32_t ssrc,
|
||||
int peer_port, std::string address_string, SrsPsRtpPacket *pkt);
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
virtual srs_error_t on_tcp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
public:
|
||||
virtual srs_error_t on_rtp_packet_jitter(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
virtual srs_error_t on_rtp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
};
|
||||
|
||||
|
||||
//ps stream processing parsing interface
|
||||
class ISrsPsStreamHander
|
||||
{
|
||||
public:
|
||||
ISrsPsStreamHander();
|
||||
virtual ~ISrsPsStreamHander();
|
||||
public:
|
||||
virtual srs_error_t on_rtp_video(SrsSimpleStream* stream, int64_t dts)=0;
|
||||
virtual srs_error_t on_rtp_audio(SrsSimpleStream* stream, int64_t dts, int type)=0;
|
||||
};
|
||||
|
||||
//analysis of PS stream and
|
||||
//extraction of H264 raw data and audio data
|
||||
//then process the flow through PS stream hander,
|
||||
//such as RTMP multiplexer, and composited into RTMP av stream
|
||||
class SrsPsStreamDemixer
|
||||
{
|
||||
public:
|
||||
// gb28181 program stream struct define
|
||||
struct SrsPsPacketStartCode
|
||||
{
|
||||
uint8_t start_code[3];
|
||||
uint8_t stream_id[1];
|
||||
};
|
||||
|
||||
struct SrsPsPacketHeader
|
||||
{
|
||||
SrsPsPacketStartCode start;// 4
|
||||
uint8_t info[9];
|
||||
uint8_t stuffing_length;
|
||||
};
|
||||
|
||||
struct SrsPsPacketBBHeader
|
||||
{
|
||||
SrsPsPacketStartCode start;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
struct SrsPsePacket
|
||||
{
|
||||
SrsPsPacketStartCode start;
|
||||
uint16_t length;
|
||||
uint8_t info[2];
|
||||
uint8_t stuffing_length;
|
||||
};
|
||||
|
||||
struct SrsPsMapPacket
|
||||
{
|
||||
SrsPsPacketStartCode start;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
private:
|
||||
SrsFileWriter ps_fw;
|
||||
SrsFileWriter video_fw;
|
||||
SrsFileWriter audio_fw;
|
||||
SrsFileWriter unknow_fw;
|
||||
|
||||
bool first_keyframe_flag;
|
||||
bool wait_first_keyframe;
|
||||
bool audio_enable;
|
||||
std::string channel_id;
|
||||
|
||||
uint8_t video_es_id;
|
||||
uint8_t video_es_type;
|
||||
uint8_t audio_es_id;
|
||||
uint8_t audio_es_type;
|
||||
int audio_check_aac_try_count;
|
||||
|
||||
SrsRawAacStream *aac;
|
||||
|
||||
ISrsPsStreamHander *hander;
|
||||
public:
|
||||
SrsPsStreamDemixer(ISrsPsStreamHander *h, std::string sid, bool a, bool k);
|
||||
virtual ~SrsPsStreamDemixer();
|
||||
private:
|
||||
bool can_send_ps_av_packet();
|
||||
public:
|
||||
int64_t parse_ps_timestamp(const uint8_t* p);
|
||||
std::string get_ps_map_type_str(uint8_t);
|
||||
virtual srs_error_t on_ps_stream(char* ps_data, int ps_size, uint32_t timestamp, uint32_t ssrc);
|
||||
};
|
||||
|
||||
|
||||
//RTMP multiplexer, which processes the raw H264 / AAC,
|
||||
//then publish it to RTMP server
|
||||
class SrsGb28181RtmpMuxer : public ISrsCoroutineHandler,
|
||||
public ISrsConnection, public ISrsPsStreamHander
|
||||
{
|
||||
private:
|
||||
SrsPithyPrint* pprint;
|
||||
SrsGb28181StreamChannel *channel;
|
||||
int stream_idle_timeout;
|
||||
srs_utime_t recv_rtp_stream_time;
|
||||
srs_utime_t send_rtmp_stream_time;
|
||||
private:
|
||||
std::string channel_id;
|
||||
std::string _rtmp_url;
|
||||
std::string video_ssrc;
|
||||
std::string audio_ssrc;
|
||||
|
||||
SrsGb28181Manger* gb28181_manger;
|
||||
SrsCoroutine* trd;
|
||||
SrsPsStreamDemixer* ps_demixer;
|
||||
srs_cond_t wait_ps_queue;
|
||||
|
||||
SrsSimpleRtmpClient* sdk;
|
||||
SrsRtpTimeJitter* vjitter;
|
||||
SrsRtpTimeJitter* ajitter;
|
||||
|
||||
SrsRawH264Stream* avc;
|
||||
std::string h264_sps;
|
||||
std::string h264_pps;
|
||||
|
||||
SrsRawAacStream* aac;
|
||||
std::string aac_specific_config;
|
||||
|
||||
SrsRequest* req;
|
||||
SrsLiveSource* source;
|
||||
SrsServer* server;
|
||||
|
||||
SrsRtpJitterBuffer *jitter_buffer;
|
||||
SrsRtpJitterBuffer *jitter_buffer_audio;
|
||||
|
||||
char *ps_buffer;
|
||||
char *ps_buffer_audio;
|
||||
|
||||
int ps_buflen;
|
||||
int ps_buflen_auido;
|
||||
|
||||
uint32_t ps_rtp_video_ts;
|
||||
|
||||
bool source_publish;
|
||||
|
||||
public:
|
||||
std::queue<SrsPsRtpPacket*> ps_queue;
|
||||
|
||||
public:
|
||||
SrsGb28181RtmpMuxer(SrsGb28181Manger* m, std::string id, bool a, bool k);
|
||||
virtual ~SrsGb28181RtmpMuxer();
|
||||
|
||||
public:
|
||||
virtual srs_error_t serve();
|
||||
virtual void stop();
|
||||
srs_error_t initialize(SrsServer* s, SrsRequest* r);
|
||||
|
||||
virtual std::string get_channel_id();
|
||||
virtual void ps_packet_enqueue(SrsPsRtpPacket *pkt);
|
||||
virtual void copy_channel(SrsGb28181StreamChannel *s);
|
||||
virtual void set_channel_peer_ip(std::string ip);
|
||||
virtual void set_channel_peer_port(int port);
|
||||
virtual int channel_peer_port();
|
||||
virtual std::string channel_peer_ip();
|
||||
virtual void set_rtmp_url(std::string url);
|
||||
virtual std::string rtmp_url();
|
||||
virtual SrsGb28181StreamChannel get_channel();
|
||||
srs_utime_t get_recv_stream_time();
|
||||
|
||||
void insert_jitterbuffer(SrsPsRtpPacket *pkt);
|
||||
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
virtual void destroy();
|
||||
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
// Interface ISrsConnection.
|
||||
public:
|
||||
virtual std::string remote_ip();
|
||||
virtual const SrsContextId& get_id();
|
||||
virtual std::string desc();
|
||||
public:
|
||||
virtual srs_error_t on_rtp_video(SrsSimpleStream* stream, int64_t dts);
|
||||
virtual srs_error_t on_rtp_audio(SrsSimpleStream* stream, int64_t dts, int type);
|
||||
private:
|
||||
|
||||
srs_error_t replace_startcode_with_nalulen(char *video_data, int &size, uint32_t pts, uint32_t dts);
|
||||
srs_error_t write_h264_ipb_frame2(char *frame, int frame_size, uint32_t pts, uint32_t dts);
|
||||
virtual srs_error_t write_h264_sps_pps(uint32_t dts, uint32_t pts);
|
||||
virtual srs_error_t write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts, bool b = true);
|
||||
virtual srs_error_t write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts);
|
||||
virtual srs_error_t rtmp_write_packet(char type, uint32_t timestamp, char* data, int size);
|
||||
virtual srs_error_t rtmp_write_packet_by_source(char type, uint32_t timestamp, char* data, int size);
|
||||
private:
|
||||
// Connect to RTMP server.
|
||||
virtual srs_error_t connect();
|
||||
// Close the connection to RTMP server.
|
||||
virtual void close();
|
||||
public:
|
||||
virtual void rtmp_close();
|
||||
};
|
||||
|
||||
//system parameter configuration of gb28181 module,
|
||||
//read file from configuration file to generate
|
||||
class SrsGb28181Config
|
||||
{
|
||||
public:
|
||||
std::string host;
|
||||
srs_utime_t rtp_idle_timeout;
|
||||
bool audio_enable;
|
||||
bool wait_keyframe;
|
||||
std::string output;
|
||||
int rtp_port_min;
|
||||
int rtp_port_max;
|
||||
int rtp_mux_port;
|
||||
bool rtp_mux_tcp_enable;
|
||||
bool auto_create_channel;
|
||||
bool jitterbuffer_enable;
|
||||
|
||||
//sip config
|
||||
int sip_port;
|
||||
std::string sip_serial;
|
||||
std::string sip_realm;
|
||||
bool sip_enable;
|
||||
srs_utime_t sip_ack_timeout;
|
||||
srs_utime_t sip_keepalive_timeout;
|
||||
bool sip_auto_play;
|
||||
bool sip_invite_port_fixed;
|
||||
srs_utime_t sip_query_catalog_interval;
|
||||
|
||||
public:
|
||||
SrsGb28181Config(SrsConfDirective* c);
|
||||
virtual ~SrsGb28181Config();
|
||||
};
|
||||
|
||||
class SrsGb28181StreamChannel
|
||||
{
|
||||
private:
|
||||
std::string channel_id;
|
||||
std::string port_mode;
|
||||
std::string app;
|
||||
std::string stream;
|
||||
std::string rtmp_url;
|
||||
std::string flv_url;
|
||||
std::string hls_url;
|
||||
std::string webrtc_url;
|
||||
|
||||
std::string ip;
|
||||
int rtp_port;
|
||||
int rtmp_port;
|
||||
uint32_t ssrc;
|
||||
srs_utime_t recv_time;
|
||||
std::string recv_time_str;
|
||||
|
||||
//send rtp stream client local port
|
||||
int rtp_peer_port;
|
||||
//send rtp stream client local ip
|
||||
std::string rtp_peer_ip;
|
||||
|
||||
public:
|
||||
SrsGb28181StreamChannel();
|
||||
virtual ~SrsGb28181StreamChannel();
|
||||
|
||||
std::string get_channel_id() const { return channel_id; }
|
||||
std::string get_port_mode() const { return port_mode; }
|
||||
std::string get_app() const { return app; }
|
||||
std::string get_stream() const { return stream; }
|
||||
std::string get_ip() const { return ip; }
|
||||
int get_rtp_port() const { return rtp_port; }
|
||||
int get_rtmp_port() const { return rtmp_port; }
|
||||
uint32_t get_ssrc() const { return ssrc; }
|
||||
uint32_t get_rtp_peer_port() const { return rtp_peer_port; }
|
||||
std::string get_rtp_peer_ip() const { return rtp_peer_ip; }
|
||||
std::string get_rtmp_url() const { return rtmp_url; }
|
||||
std::string get_flv_url() const { return flv_url; }
|
||||
std::string get_hls_url() const { return hls_url; }
|
||||
std::string get_webrtc_url() const { return webrtc_url; }
|
||||
srs_utime_t get_recv_time() const { return recv_time; }
|
||||
std::string get_recv_time_str() const { return recv_time_str; }
|
||||
|
||||
void set_channel_id(const std::string &i) { channel_id = i; }
|
||||
void set_port_mode(const std::string &p) { port_mode = p; }
|
||||
void set_app(const std::string &a) { app = a; }
|
||||
void set_stream(const std::string &s) { stream = s; }
|
||||
void set_ip(const std::string &i) { ip = i; }
|
||||
void set_rtp_port( const int &p) { rtp_port = p; }
|
||||
void set_rtmp_port( const int &p) { rtmp_port = p; }
|
||||
void set_ssrc( const int &s) { ssrc = s;}
|
||||
void set_rtp_peer_ip( const std::string &p) { rtp_peer_ip = p; }
|
||||
void set_rtp_peer_port( const int &s) { rtp_peer_port = s;}
|
||||
void set_rtmp_url( const std::string &u) { rtmp_url = u; }
|
||||
void set_flv_url( const std::string &u) { flv_url = u; }
|
||||
void set_hls_url( const std::string &u) { hls_url = u; }
|
||||
void set_webrtc_url( const std::string &u) { webrtc_url = u; }
|
||||
void set_recv_time( const srs_utime_t &u) { recv_time = u; }
|
||||
void set_recv_time_str( const std::string &u) { recv_time_str = u; }
|
||||
|
||||
void copy(const SrsGb28181StreamChannel *s);
|
||||
void dumps(SrsJsonObject* obj);
|
||||
|
||||
};
|
||||
|
||||
// Global singleton instance.
|
||||
extern SrsGb28181Manger* _srs_gb28181;
|
||||
|
||||
//gb28181 module management, management of all RTMP multiplexers,
|
||||
//random assignment of RTP listeners, and external control interfaces
|
||||
class SrsGb28181Manger
|
||||
{
|
||||
private:
|
||||
SrsGb28181Config *config;
|
||||
// The key: port, value: whether used.
|
||||
std::map<int, bool> used_ports;
|
||||
std::map<uint32_t, SrsPsRtpListener*> rtp_pool;
|
||||
std::map<uint32_t, SrsGb28181RtmpMuxer*> rtmpmuxers_ssrc;
|
||||
std::map<std::string, SrsGb28181RtmpMuxer*> rtmpmuxers;
|
||||
SrsResourceManager* manager;
|
||||
SrsGb28181SipService* sip_service;
|
||||
SrsServer* server;
|
||||
public:
|
||||
SrsGb28181Manger(SrsServer* s, SrsConfDirective* c);
|
||||
virtual ~SrsGb28181Manger();
|
||||
|
||||
public:
|
||||
srs_error_t fetch_or_create_rtmpmuxer(std::string id, SrsRequest *req, SrsGb28181RtmpMuxer** gb28181);
|
||||
SrsGb28181RtmpMuxer* fetch_rtmpmuxer(std::string id);
|
||||
SrsGb28181RtmpMuxer* fetch_rtmpmuxer_by_ssrc(uint32_t ssrc);
|
||||
void update_rtmpmuxer_to_newssrc_by_id(std::string id, uint32_t ssrc);
|
||||
void rtmpmuxer_map_by_ssrc(SrsGb28181RtmpMuxer*muxer, uint32_t ssrc);
|
||||
void rtmpmuxer_unmap_by_ssrc(uint32_t ssrc);
|
||||
uint32_t generate_ssrc(std::string id);
|
||||
uint32_t hash_code(std::string str);
|
||||
|
||||
void set_sip_service(SrsGb28181SipService *s) { sip_service = s; }
|
||||
SrsGb28181SipService* get_sip_service() { return sip_service; }
|
||||
SrsGb28181Config* get_gb28181_config_ptr() { return config;}
|
||||
|
||||
public:
|
||||
//stream channel api
|
||||
srs_error_t create_stream_channel(SrsGb28181StreamChannel *channel);
|
||||
srs_error_t delete_stream_channel(std::string id, std::string chid);
|
||||
srs_error_t query_stream_channel(std::string id, SrsJsonArray* arr);
|
||||
//sip api
|
||||
srs_error_t notify_sip_invite(std::string id, std::string ip, int port, uint32_t ssrc, std::string chid);
|
||||
srs_error_t notify_sip_bye(std::string id, std::string chid);
|
||||
srs_error_t notify_sip_raw_data(std::string id, std::string data);
|
||||
srs_error_t notify_sip_unregister(std::string id);
|
||||
srs_error_t notify_sip_query_catalog(std::string id);
|
||||
srs_error_t notify_sip_ptz(std::string id, std::string chid, std::string cmd, uint8_t speed, int priority);
|
||||
srs_error_t query_sip_session(std::string id, SrsJsonArray* arr);
|
||||
srs_error_t query_device_list(std::string id, SrsJsonArray* arr);
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
|
||||
public:
|
||||
// Alloc a rtp port from local ports pool.
|
||||
// @param pport output the rtp port.
|
||||
void alloc_port(int* pport);
|
||||
// Free the alloced rtp port.
|
||||
void free_port(int lpmin, int lpmax);
|
||||
srs_error_t initialize();
|
||||
|
||||
SrsGb28181Config get_gb28181_config();
|
||||
srs_error_t start_ps_rtp_listen(std::string id, int port);
|
||||
void stop_rtp_listen(std::string id);
|
||||
|
||||
public:
|
||||
void remove(SrsGb28181RtmpMuxer* conn);
|
||||
void remove_sip_session(SrsGb28181SipSession* sess);
|
||||
};
|
||||
|
||||
// The gb28181 tcp connection serve the fd.
|
||||
class SrsGb28181Conn : public ISrsCoroutineHandler, public ISrsConnection
|
||||
{
|
||||
private:
|
||||
char* mbuffer;
|
||||
srs_netfd_t stfd;
|
||||
SrsStSocket* skt;
|
||||
SrsRtspStack* rtsp;
|
||||
SrsGb28181Caster* caster;
|
||||
SrsCoroutine* trd;
|
||||
SrsGb28181PsRtpProcessor *processor;
|
||||
public:
|
||||
SrsGb28181Conn(SrsGb28181Caster* c, srs_netfd_t fd, SrsGb28181PsRtpProcessor *rtp_processor);
|
||||
virtual ~SrsGb28181Conn();
|
||||
public:
|
||||
virtual srs_error_t serve();
|
||||
virtual std::string remote_ip();
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
virtual std::string desc();
|
||||
virtual const SrsContextId& get_id();
|
||||
};
|
||||
|
||||
// The caster for gb28181.
|
||||
class SrsGb28181Caster : public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
std::string output;
|
||||
SrsGb28181Config *config;
|
||||
SrsGb28181PsRtpProcessor *rtp_processor;
|
||||
private:
|
||||
std::vector<SrsGb28181Conn*> clients;
|
||||
SrsResourceManager* manager;
|
||||
public:
|
||||
SrsGb28181Caster(SrsConfDirective* c);
|
||||
virtual ~SrsGb28181Caster();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
// internal methods.
|
||||
public:
|
||||
virtual void remove(SrsGb28181Conn* conn);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,530 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2021 Lixin
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_APP_GB28181_RTP_JITBUFFER_HPP
|
||||
#define SRS_APP_GB28181_RTP_JITBUFFER_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
#include <srs_app_log.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_rtc_rtp.hpp>
|
||||
#include <srs_kernel_flv.hpp>
|
||||
|
||||
class SrsPsRtpPacket;
|
||||
class SrsRtpFrameBuffer;
|
||||
class SrsRtpDecodingState;
|
||||
class SrsGb28181RtmpMuxer;
|
||||
class VCMPacket;
|
||||
class SrsRtpPacket;
|
||||
|
||||
///jittbuffer
|
||||
|
||||
enum FrameType {
|
||||
kEmptyFrame = 0,
|
||||
kAudioFrameSpeech = 1,
|
||||
kAudioFrameCN = 2,
|
||||
kVideoFrameKey = 3, // independent frame
|
||||
kVideoFrameDelta = 4, // depends on the previus frame
|
||||
kVideoFrameGolden = 5, // depends on a old known previus frame
|
||||
kVideoFrameAltRef = 6
|
||||
};
|
||||
|
||||
// Used to indicate which decode with errors mode should be used.
|
||||
enum SrsRtpDecodeErrorMode {
|
||||
kNoErrors, // Never decode with errors. Video will freeze
|
||||
// if nack is disabled.
|
||||
kSelectiveErrors, // Frames that are determined decodable in
|
||||
// VCMSessionInfo may be decoded with missing
|
||||
// packets. As not all incomplete frames will be
|
||||
// decodable, video will freeze if nack is disabled.
|
||||
kWithErrors // Release frames as needed. Errors may be
|
||||
// introduced as some encoded frames may not be
|
||||
// complete.
|
||||
};
|
||||
|
||||
// Used to estimate rolling average of packets per frame.
|
||||
static const float kFastConvergeMultiplier = 0.4f;
|
||||
static const float kNormalConvergeMultiplier = 0.2f;
|
||||
|
||||
enum { kMaxNumberOfFrames = 300 };
|
||||
enum { kStartNumberOfFrames = 6 };
|
||||
enum { kMaxVideoDelayMs = 10000 };
|
||||
enum { kPacketsPerFrameMultiplier = 5 };
|
||||
enum { kFastConvergeThreshold = 5};
|
||||
|
||||
enum SrsRtpJitterBufferEnum {
|
||||
kMaxConsecutiveOldFrames = 60,
|
||||
kMaxConsecutiveOldPackets = 300,
|
||||
kMaxPacketsInSession = 800,
|
||||
kBufferIncStepSizeBytes = 30000, // >20 packets.
|
||||
kMaxJBFrameSizeBytes = 4000000 // sanity don't go above 4Mbyte.
|
||||
};
|
||||
|
||||
enum SrsRtpFrameBufferEnum {
|
||||
kOutOfBoundsPacket = -7,
|
||||
kNotInitialized = -6,
|
||||
kOldPacket = -5,
|
||||
kGeneralError = -4,
|
||||
kFlushIndicator = -3, // Indicator that a flush has occurred.
|
||||
kTimeStampError = -2,
|
||||
kSizeError = -1,
|
||||
kNoError = 0,
|
||||
kIncomplete = 1, // Frame incomplete.
|
||||
kCompleteSession = 3, // at least one layer in the frame complete.
|
||||
kDecodableSession = 4, // Frame incomplete, but ready to be decoded
|
||||
kDuplicatePacket = 5 // We're receiving a duplicate packet.
|
||||
};
|
||||
|
||||
enum SrsRtpFrameBufferStateEnum {
|
||||
kStateEmpty, // frame popped by the RTP receiver
|
||||
kStateIncomplete, // frame that have one or more packet(s) stored
|
||||
kStateComplete, // frame that have all packets
|
||||
kStateDecodable // Hybrid mode - frame can be decoded
|
||||
};
|
||||
|
||||
enum SrsRtpNackMode {
|
||||
kNack,
|
||||
kNoNack
|
||||
};
|
||||
|
||||
// Used to indicate if a received packet contain a complete NALU (or equivalent)
|
||||
enum VCMNaluCompleteness {
|
||||
kNaluUnset = 0, // Packet has not been filled.
|
||||
kNaluComplete = 1, // Packet can be decoded as is.
|
||||
kNaluStart, // Packet contain beginning of NALU
|
||||
kNaluIncomplete, // Packet is not beginning or end of NALU
|
||||
kNaluEnd, // Packet is the end of a NALU
|
||||
};
|
||||
|
||||
enum RtpVideoCodecTypes {
|
||||
kRtpVideoNone,
|
||||
kRtpVideoGeneric,
|
||||
kRtpVideoVp8,
|
||||
kRtpVideoVp9,
|
||||
kRtpVideoH264,
|
||||
kRtpVideoPS
|
||||
};
|
||||
|
||||
|
||||
// Video codec types
|
||||
enum VideoCodecType {
|
||||
kVideoCodecVP8,
|
||||
kVideoCodecVP9,
|
||||
kVideoCodecH264,
|
||||
kVideoCodecH264SVC,
|
||||
kVideoCodecI420,
|
||||
kVideoCodecRED,
|
||||
kVideoCodecULPFEC,
|
||||
kVideoCodecGeneric,
|
||||
kVideoCodecH264PS,
|
||||
kVideoCodecUnknown
|
||||
};
|
||||
|
||||
// The packetization types that we support: single, aggregated, and fragmented.
|
||||
enum H264PacketizationTypes {
|
||||
kH264SingleNalu, // This packet contains a single NAL unit.
|
||||
kH264StapA, // This packet contains STAP-A (single time
|
||||
// aggregation) packets. If this packet has an
|
||||
// associated NAL unit type, it'll be for the
|
||||
// first such aggregated packet.
|
||||
kH264FuA, // This packet contains a FU-A (fragmentation
|
||||
// unit) packet, meaning it is a part of a frame
|
||||
// that was too large to fit into a single packet.
|
||||
};
|
||||
|
||||
enum { kH264StartCodeLengthBytes = 4};
|
||||
|
||||
// Used to pass data from jitter buffer to session info.
|
||||
// This data is then used in determining whether a frame is decodable.
|
||||
struct FrameData {
|
||||
int64_t rtt_ms;
|
||||
float rolling_average_packets_per_frame;
|
||||
};
|
||||
|
||||
inline bool IsNewerSequenceNumber(uint16_t sequence_number,
|
||||
uint16_t prev_sequence_number)
|
||||
{
|
||||
return sequence_number != prev_sequence_number &&
|
||||
static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
|
||||
}
|
||||
|
||||
inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp)
|
||||
{
|
||||
return timestamp != prev_timestamp &&
|
||||
static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
|
||||
}
|
||||
|
||||
inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
|
||||
uint16_t sequence_number2)
|
||||
{
|
||||
return IsNewerSequenceNumber(sequence_number1, sequence_number2)
|
||||
? sequence_number1
|
||||
: sequence_number2;
|
||||
}
|
||||
|
||||
inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2)
|
||||
{
|
||||
return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2;
|
||||
}
|
||||
|
||||
typedef std::list<SrsRtpFrameBuffer*> UnorderedFrameList;
|
||||
|
||||
class TimestampLessThan {
|
||||
public:
|
||||
bool operator() (const uint32_t& timestamp1,
|
||||
const uint32_t& timestamp2) const
|
||||
{
|
||||
return IsNewerTimestamp(timestamp2, timestamp1);
|
||||
}
|
||||
};
|
||||
|
||||
class FrameList
|
||||
: public std::map<uint32_t, SrsRtpFrameBuffer*, TimestampLessThan> {
|
||||
public:
|
||||
void InsertFrame(SrsRtpFrameBuffer* frame);
|
||||
SrsRtpFrameBuffer* PopFrame(uint32_t timestamp);
|
||||
SrsRtpFrameBuffer* Front() const;
|
||||
SrsRtpFrameBuffer* FrontNext() const;
|
||||
SrsRtpFrameBuffer* Back() const;
|
||||
int RecycleFramesUntilKeyFrame(FrameList::iterator* key_frame_it,
|
||||
UnorderedFrameList* free_frames);
|
||||
void CleanUpOldOrEmptyFrames(SrsRtpDecodingState* decoding_state, UnorderedFrameList* free_frames);
|
||||
void Reset(UnorderedFrameList* free_frames);
|
||||
};
|
||||
|
||||
|
||||
class VCMPacket {
|
||||
public:
|
||||
VCMPacket();
|
||||
VCMPacket(const uint8_t* ptr,
|
||||
size_t size,
|
||||
uint16_t seqNum,
|
||||
uint32_t timestamp,
|
||||
bool markerBit,
|
||||
H264PacketizationTypes type,
|
||||
RtpVideoCodecTypes rtpType,
|
||||
bool singlenual,
|
||||
bool isfirst,
|
||||
FrameType ftype
|
||||
);
|
||||
|
||||
void Reset();
|
||||
|
||||
uint8_t payloadType;
|
||||
uint32_t timestamp;
|
||||
// NTP time of the capture time in local timebase in milliseconds.
|
||||
int64_t ntp_time_ms_;
|
||||
uint16_t seqNum;
|
||||
const uint8_t* dataPtr;
|
||||
size_t sizeBytes;
|
||||
bool markerBit;
|
||||
|
||||
FrameType frameType;
|
||||
VideoCodecType codec;
|
||||
|
||||
bool isFirstPacket; // Is this first packet in a frame.
|
||||
VCMNaluCompleteness completeNALU; // Default is kNaluIncomplete.
|
||||
bool insertStartCode; // True if a start code should be inserted before this
|
||||
// packet.
|
||||
int width;
|
||||
int height;
|
||||
//RTPVideoHeader codecSpecificHeader;
|
||||
|
||||
|
||||
//H264 header
|
||||
H264PacketizationTypes h264packetizationType;
|
||||
bool h264singleNalu;
|
||||
|
||||
public:
|
||||
void CopyCodecSpecifics(RtpVideoCodecTypes codecType, bool H264single_nalu, bool firstPacket);
|
||||
};
|
||||
|
||||
class SrsRtpFrameBuffer {
|
||||
public:
|
||||
SrsRtpFrameBuffer();
|
||||
virtual ~SrsRtpFrameBuffer();
|
||||
|
||||
public:
|
||||
SrsRtpFrameBufferEnum InsertPacket(const VCMPacket& packet, const FrameData& frame_data);
|
||||
void UpdateCompleteSession();
|
||||
void UpdateDecodableSession(const FrameData& frame_data);
|
||||
bool HaveFirstPacket() const;
|
||||
bool HaveLastPacket() const;
|
||||
void Reset();
|
||||
|
||||
uint32_t GetTimeStamp() const;
|
||||
FrameType GetFrameType() const;
|
||||
SrsRtpFrameBufferStateEnum GetState() const;
|
||||
|
||||
int32_t GetHighSeqNum() const;
|
||||
int32_t GetLowSeqNum() const;
|
||||
size_t Length() const;
|
||||
const uint8_t* Buffer() const;
|
||||
|
||||
int NumPackets() const;
|
||||
void InformOfEmptyPacket(uint16_t seq_num);
|
||||
|
||||
bool complete() const;
|
||||
bool decodable() const;
|
||||
|
||||
bool DeletePacket(int &count);
|
||||
void PrepareForDecode(bool continuous);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::list<VCMPacket> PacketList;
|
||||
typedef PacketList::iterator PacketIterator;
|
||||
typedef PacketList::const_iterator PacketIteratorConst;
|
||||
typedef PacketList::reverse_iterator ReversePacketIterator;
|
||||
|
||||
bool InSequence(const PacketIterator& packet_it,
|
||||
const PacketIterator& prev_packet_it);
|
||||
|
||||
size_t InsertBuffer(uint8_t* frame_buffer, PacketIterator packet_it);
|
||||
size_t Insert(const uint8_t* buffer, size_t length, bool insert_start_code, uint8_t* frame_buffer);
|
||||
void ShiftSubsequentPackets(PacketIterator it, int steps_to_shift);
|
||||
void VerifyAndAllocate(const uint32_t minimumSize);
|
||||
void UpdateDataPointers(const uint8_t* old_base_ptr, const uint8_t* new_base_ptr);
|
||||
size_t DeletePacketData(PacketIterator start, PacketIterator end);
|
||||
size_t MakeDecodable();
|
||||
|
||||
|
||||
PacketList packets_;
|
||||
int empty_seq_num_low_;
|
||||
int empty_seq_num_high_;
|
||||
|
||||
int first_packet_seq_num_;
|
||||
int last_packet_seq_num_;
|
||||
|
||||
bool complete_;
|
||||
bool decodable_;
|
||||
|
||||
uint32_t timeStamp_;
|
||||
FrameType frame_type_;
|
||||
|
||||
SrsRtpDecodeErrorMode decode_error_mode_;
|
||||
SrsRtpFrameBufferStateEnum state_;
|
||||
|
||||
//uint16_t nackCount_;
|
||||
//int64_t latestPacketTimeMs_;
|
||||
|
||||
// The payload.
|
||||
uint8_t* _buffer;
|
||||
size_t _size;
|
||||
size_t _length;
|
||||
};
|
||||
|
||||
class SrsRtpDecodingState {
|
||||
public:
|
||||
SrsRtpDecodingState();
|
||||
~SrsRtpDecodingState();
|
||||
// Check for old frame
|
||||
bool IsOldFrame(const SrsRtpFrameBuffer* frame) const;
|
||||
// Check for old packet
|
||||
bool IsOldPacket(const VCMPacket* packet);
|
||||
// Check for frame continuity based on current decoded state. Use best method
|
||||
// possible, i.e. temporal info, picture ID or sequence number.
|
||||
bool ContinuousFrame(const SrsRtpFrameBuffer* frame) const;
|
||||
void SetState(const SrsRtpFrameBuffer* frame);
|
||||
void CopyFrom(const SrsRtpDecodingState& state);
|
||||
bool UpdateEmptyFrame(const SrsRtpFrameBuffer* frame);
|
||||
// Update the sequence number if the timestamp matches current state and the
|
||||
// sequence number is higher than the current one. This accounts for packets
|
||||
// arriving late.
|
||||
void UpdateOldPacket(const VCMPacket* packet);
|
||||
void SetSeqNum(uint16_t new_seq_num);
|
||||
void Reset();
|
||||
uint32_t time_stamp() const;
|
||||
uint16_t sequence_num() const;
|
||||
// Return true if at initial state.
|
||||
bool in_initial_state() const;
|
||||
// Return true when sync is on - decode all layers.
|
||||
bool full_sync() const;
|
||||
|
||||
private:
|
||||
void UpdateSyncState(const SrsRtpFrameBuffer* frame);
|
||||
// Designated continuity functions
|
||||
//bool ContinuousPictureId(int picture_id) const;
|
||||
bool ContinuousSeqNum(uint16_t seq_num) const;
|
||||
//bool ContinuousLayer(int temporal_id, int tl0_pic_id) const;
|
||||
//bool UsingPictureId(const SrsRtpFrameBuffer* frame) const;
|
||||
|
||||
// Keep state of last decoded frame.
|
||||
// TODO(mikhal/stefan): create designated classes to handle these types.
|
||||
uint16_t sequence_num_;
|
||||
uint32_t time_stamp_;
|
||||
bool full_sync_; // Sync flag when temporal layers are used.
|
||||
bool in_initial_state_;
|
||||
|
||||
bool m_firstPacket;
|
||||
};
|
||||
|
||||
// The time jitter correct for rtp.
|
||||
class SrsRtpTimeJitter
|
||||
{
|
||||
private:
|
||||
int64_t previous_timestamp;
|
||||
int64_t pts;
|
||||
int delta;
|
||||
public:
|
||||
SrsRtpTimeJitter();
|
||||
virtual ~SrsRtpTimeJitter();
|
||||
public:
|
||||
int64_t timestamp();
|
||||
srs_error_t correct(int64_t& ts);
|
||||
void reset();
|
||||
};
|
||||
|
||||
class SrsRtpJitterBuffer
|
||||
{
|
||||
public:
|
||||
SrsRtpJitterBuffer(std::string key);
|
||||
virtual ~SrsRtpJitterBuffer();
|
||||
|
||||
public:
|
||||
srs_error_t start();
|
||||
void Reset();
|
||||
SrsRtpFrameBufferEnum InsertPacket(uint16_t seq, uint32_t ts, bool maker, char *buf, int size,
|
||||
bool* retransmitted);
|
||||
void ReleaseFrame(SrsRtpFrameBuffer* frame);
|
||||
bool FoundFrame(uint32_t& time_stamp);
|
||||
bool GetFrame(char **buffer, int &buf_len, int &size, bool &keyframe, const uint32_t time_stamp);
|
||||
void SetDecodeErrorMode(SrsRtpDecodeErrorMode error_mode);
|
||||
void SetNackMode(SrsRtpNackMode mode,int64_t low_rtt_nack_threshold_ms,
|
||||
int64_t high_rtt_nack_threshold_ms);
|
||||
void SetNackSettings(size_t max_nack_list_size,int max_packet_age_to_nack,
|
||||
int max_incomplete_time_ms);
|
||||
uint16_t* GetNackList(uint16_t* nack_list_size, bool* request_key_frame);
|
||||
void Flush();
|
||||
void ResetJittter();
|
||||
|
||||
bool isFirstKeyFrame;
|
||||
private:
|
||||
|
||||
SrsRtpFrameBufferEnum GetFrameByRtpPacket(const VCMPacket& packet, SrsRtpFrameBuffer** frame,
|
||||
FrameList** frame_list);
|
||||
SrsRtpFrameBuffer* GetEmptyFrame();
|
||||
bool NextCompleteTimestamp(uint32_t max_wait_time_ms, uint32_t* timestamp);
|
||||
bool NextMaybeIncompleteTimestamp(uint32_t* timestamp);
|
||||
SrsRtpFrameBuffer* ExtractAndSetDecode(uint32_t timestamp);
|
||||
SrsRtpFrameBuffer* NextFrame() const;
|
||||
|
||||
|
||||
bool TryToIncreaseJitterBufferSize();
|
||||
bool RecycleFramesUntilKeyFrame();
|
||||
bool IsContinuous(const SrsRtpFrameBuffer& frame) const;
|
||||
bool IsContinuousInState(const SrsRtpFrameBuffer& frame,
|
||||
const SrsRtpDecodingState& decoding_state) const;
|
||||
void FindAndInsertContinuousFrames(const SrsRtpFrameBuffer& new_frame);
|
||||
void CleanUpOldOrEmptyFrames();
|
||||
|
||||
//nack
|
||||
bool UpdateNackList(uint16_t sequence_number);
|
||||
bool TooLargeNackList() const;
|
||||
bool HandleTooLargeNackList();
|
||||
bool MissingTooOldPacket(uint16_t latest_sequence_number) const;
|
||||
bool HandleTooOldPackets(uint16_t latest_sequence_number);
|
||||
void DropPacketsFromNackList(uint16_t last_decoded_sequence_number);
|
||||
SrsRtpNackMode nack_mode() const;
|
||||
int NonContinuousOrIncompleteDuration();
|
||||
uint16_t EstimatedLowSequenceNumber(const SrsRtpFrameBuffer& frame) const;
|
||||
bool WaitForRetransmissions();
|
||||
|
||||
bool IsPacketInOrder(uint16_t sequence_number);
|
||||
bool IsFirstPacketInFrame(uint32_t ts, uint16_t seq);
|
||||
|
||||
private:
|
||||
class SequenceNumberLessThan {
|
||||
public:
|
||||
bool operator() (const uint16_t& sequence_number1,
|
||||
const uint16_t& sequence_number2) const
|
||||
{
|
||||
return IsNewerSequenceNumber(sequence_number2, sequence_number1);
|
||||
}
|
||||
};
|
||||
typedef std::set<uint16_t, SequenceNumberLessThan> SequenceNumberSet;
|
||||
|
||||
std::string key_;
|
||||
|
||||
srs_cond_t wait_cond_t;
|
||||
// If we are running (have started) or not.
|
||||
bool running_;
|
||||
// Number of allocated frames.
|
||||
int max_number_of_frames_;
|
||||
UnorderedFrameList free_frames_;
|
||||
FrameList decodable_frames_;
|
||||
FrameList incomplete_frames_;
|
||||
SrsRtpDecodingState last_decoded_state_;
|
||||
bool first_packet_since_reset_;
|
||||
|
||||
// Statistics.
|
||||
//VCMReceiveStatisticsCallback* stats_callback_ GUARDED_BY(crit_sect_);
|
||||
// Frame counts for each type (key, delta, ...)
|
||||
//FrameCounts receive_statistics_;
|
||||
// Latest calculated frame rates of incoming stream.
|
||||
unsigned int incoming_frame_rate_;
|
||||
unsigned int incoming_frame_count_;
|
||||
int64_t time_last_incoming_frame_count_;
|
||||
unsigned int incoming_bit_count_;
|
||||
unsigned int incoming_bit_rate_;
|
||||
// Number of frames in a row that have been too old.
|
||||
int num_consecutive_old_frames_;
|
||||
// Number of packets in a row that have been too old.
|
||||
int num_consecutive_old_packets_;
|
||||
// Number of packets received.
|
||||
int num_packets_;
|
||||
int num_packets_free_;
|
||||
// Number of duplicated packets received.
|
||||
int num_duplicated_packets_;
|
||||
// Number of packets discarded by the jitter buffer.
|
||||
int num_discarded_packets_;
|
||||
// Time when first packet is received.
|
||||
int64_t time_first_packet_ms_;
|
||||
|
||||
// Jitter estimation.
|
||||
// Filter for estimating jitter.
|
||||
//VCMJitterEstimator jitter_estimate_;
|
||||
// Calculates network delays used for jitter calculations.
|
||||
//VCMInterFrameDelay inter_frame_delay_;
|
||||
//VCMJitterSample waiting_for_completion_;
|
||||
int64_t rtt_ms_;
|
||||
|
||||
// NACK and retransmissions.
|
||||
SrsRtpNackMode nack_mode_;
|
||||
int64_t low_rtt_nack_threshold_ms_;
|
||||
int64_t high_rtt_nack_threshold_ms_;
|
||||
// Holds the internal NACK list (the missing sequence numbers).
|
||||
SequenceNumberSet missing_sequence_numbers_;
|
||||
uint16_t latest_received_sequence_number_;
|
||||
std::vector<uint16_t> nack_seq_nums_;
|
||||
size_t max_nack_list_size_;
|
||||
int max_packet_age_to_nack_; // Measured in sequence numbers.
|
||||
int max_incomplete_time_ms_;
|
||||
|
||||
SrsRtpDecodeErrorMode decode_error_mode_;
|
||||
// Estimated rolling average of packets per frame
|
||||
float average_packets_per_frame_;
|
||||
// average_packets_per_frame converges fast if we have fewer than this many
|
||||
// frames.
|
||||
int frame_counter_;
|
||||
|
||||
uint32_t last_received_timestamp_;
|
||||
uint16_t last_received_sequence_number_;
|
||||
bool first_packet_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,206 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2021 Lixin
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_APP_GB28181_SIP_HPP
|
||||
#define SRS_APP_GB28181_SIP_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <srs_app_log.hpp>
|
||||
#include <srs_app_gb28181_stack.hpp>
|
||||
#include <srs_app_gb28181.hpp>
|
||||
#include <srs_app_pithy_print.hpp>
|
||||
#include <srs_service_conn.hpp>
|
||||
|
||||
class SrsConfDirective;
|
||||
class SrsSipRequest;
|
||||
class SrsGb28181Config;
|
||||
class SrsSipStack;
|
||||
class SrsGb28181SipService;
|
||||
class SrsGb28181Device;
|
||||
|
||||
enum SrsGb28181SipSessionStatusType{
|
||||
SrsGb28181SipSessionUnkonw = 0,
|
||||
SrsGb28181SipSessionRegisterOk = 1,
|
||||
SrsGb28181SipSessionAliveOk = 2,
|
||||
SrsGb28181SipSessionInviteOk = 3,
|
||||
SrsGb28181SipSessionTrying = 4,
|
||||
SrsGb28181SipSessionBye = 5,
|
||||
};
|
||||
|
||||
class SrsGb28181Device
|
||||
{
|
||||
public:
|
||||
SrsGb28181Device();
|
||||
virtual ~SrsGb28181Device();
|
||||
public:
|
||||
std::string device_id;
|
||||
std::string device_name;
|
||||
std::string device_status;
|
||||
SrsGb28181SipSessionStatusType invite_status;
|
||||
srs_utime_t invite_time;
|
||||
SrsSipRequest req_inivate;
|
||||
};
|
||||
|
||||
class SrsGb28181SipSession: public ISrsCoroutineHandler, public ISrsConnection
|
||||
{
|
||||
private:
|
||||
//SrsSipRequest *req;
|
||||
SrsGb28181SipService *servcie;
|
||||
std::string _session_id;
|
||||
SrsCoroutine* trd;
|
||||
SrsPithyPrint* pprint;
|
||||
private:
|
||||
SrsGb28181SipSessionStatusType _register_status;
|
||||
SrsGb28181SipSessionStatusType _alive_status;
|
||||
SrsGb28181SipSessionStatusType _invite_status;
|
||||
srs_utime_t _register_time;
|
||||
srs_utime_t _alive_time;
|
||||
srs_utime_t _invite_time;
|
||||
srs_utime_t _reg_expires;
|
||||
srs_utime_t _query_catalog_time;
|
||||
|
||||
std::string _peer_ip;
|
||||
int _peer_port;
|
||||
|
||||
sockaddr _from;
|
||||
int _fromlen;
|
||||
SrsSipRequest *req;
|
||||
|
||||
std::map<std::string, SrsGb28181Device*> _device_list;
|
||||
//std::map<std::string, int> _device_status;
|
||||
int _sip_cseq;
|
||||
|
||||
public:
|
||||
SrsGb28181SipSession(SrsGb28181SipService *c, SrsSipRequest* r);
|
||||
virtual ~SrsGb28181SipSession();
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
|
||||
public:
|
||||
void set_register_status(SrsGb28181SipSessionStatusType s) { _register_status = s;}
|
||||
void set_alive_status(SrsGb28181SipSessionStatusType s) { _alive_status = s;}
|
||||
void set_invite_status(SrsGb28181SipSessionStatusType s) { _invite_status = s;}
|
||||
void set_register_time(srs_utime_t t) { _register_time = t;}
|
||||
void set_alive_time(srs_utime_t t) { _alive_time = t;}
|
||||
void set_invite_time(srs_utime_t t) { _invite_time = t;}
|
||||
//void set_recv_rtp_time(srs_utime_t t) { _recv_rtp_time = t;}
|
||||
void set_reg_expires(int e) { _reg_expires = e*SRS_UTIME_SECONDS;}
|
||||
void set_peer_ip(std::string i) { _peer_ip = i;}
|
||||
void set_peer_port(int o) { _peer_port = o;}
|
||||
void set_sockaddr(sockaddr f) { _from = f;}
|
||||
void set_sockaddr_len(int l) { _fromlen = l;}
|
||||
void set_request(SrsSipRequest *r) { req->copy(r);}
|
||||
|
||||
SrsGb28181SipSessionStatusType register_status() { return _register_status;}
|
||||
SrsGb28181SipSessionStatusType alive_status() { return _alive_status;}
|
||||
SrsGb28181SipSessionStatusType invite_status() { return _invite_status;}
|
||||
srs_utime_t register_time() { return _register_time;}
|
||||
srs_utime_t alive_time() { return _alive_time;}
|
||||
srs_utime_t invite_time() { return _invite_time;}
|
||||
//srs_utime_t recv_rtp_time() { return _recv_rtp_time;}
|
||||
int reg_expires() { return _reg_expires;}
|
||||
std::string peer_ip() { return _peer_ip;}
|
||||
int peer_port() { return _peer_port;}
|
||||
sockaddr sockaddr_from() { return _from;}
|
||||
int sockaddr_fromlen() { return _fromlen;}
|
||||
SrsSipRequest request() { return *req;}
|
||||
int sip_cseq(){ return _sip_cseq++;}
|
||||
|
||||
std::string session_id() { return _session_id;}
|
||||
std::map<std::string, std::map<std::string, std::string> > item_list;
|
||||
int item_list_sumnum;
|
||||
public:
|
||||
void update_device_list(std::map<std::string, std::string> devlist);
|
||||
void clear_device_list();
|
||||
SrsGb28181Device *get_device_info(std::string chid);
|
||||
void dumps(SrsJsonObject* obj);
|
||||
void dumpItemList(SrsJsonObject* obj);
|
||||
|
||||
public:
|
||||
virtual srs_error_t serve();
|
||||
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
// Interface ISrsConnection.
|
||||
public:
|
||||
virtual std::string remote_ip();
|
||||
virtual const SrsContextId& get_id();
|
||||
virtual std::string desc();
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
};
|
||||
|
||||
class SrsGb28181SipService : public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
SrsSipStack *sip;
|
||||
SrsGb28181Config *config;
|
||||
srs_netfd_t lfd;
|
||||
|
||||
std::map<std::string, SrsGb28181SipSession*> sessions;
|
||||
std::map<std::string, SrsGb28181SipSession*> sessions_by_callid;
|
||||
|
||||
srs_mutex_t lock_session;
|
||||
public:
|
||||
SrsGb28181SipService(SrsConfDirective* c);
|
||||
virtual ~SrsGb28181SipService();
|
||||
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
virtual void set_stfd(srs_netfd_t fd);
|
||||
private:
|
||||
void destroy();
|
||||
srs_error_t on_udp_sip(std::string host, int port, std::string recv_msg, sockaddr* from, int fromlen);
|
||||
public:
|
||||
int send_message(sockaddr* f, int l, std::stringstream& ss);
|
||||
|
||||
int send_ack(SrsSipRequest *req, sockaddr *f, int l);
|
||||
int send_status(SrsSipRequest *req, sockaddr *f, int l);
|
||||
|
||||
srs_error_t send_invite(SrsSipRequest *req, std::string ip, int port, uint32_t ssrc, std::string chid);
|
||||
srs_error_t send_bye(SrsSipRequest *req, std::string chid);
|
||||
srs_error_t send_query_catalog(SrsSipRequest *req);
|
||||
srs_error_t send_ptz(SrsSipRequest *req, std::string chid, std::string cmd, uint8_t speed, int priority);
|
||||
|
||||
// The SIP command is transmitted through HTTP API,
|
||||
// and the body content is transmitted to the device,
|
||||
// mainly for testing and debugging, For example, here is HTTP body:
|
||||
// BYE sip:34020000001320000003@3402000000 SIP/2.0
|
||||
// Via: SIP/2.0/UDP 39.100.155.146:15063;rport;branch=z9hG4bK34205410
|
||||
// From: <sip:34020000002000000001@3402000000>;tag=512355410
|
||||
// To: <sip:34020000001320000003@3402000000>;tag=680367414
|
||||
// Call-ID: 200003304
|
||||
// CSeq: 21 BYE
|
||||
// Max-Forwards: 70
|
||||
// User-Agent: SRS/4.0.4(Leo)
|
||||
// Content-Length: 0
|
||||
//
|
||||
//
|
||||
srs_error_t send_sip_raw_data(SrsSipRequest *req, std::string data);
|
||||
srs_error_t query_sip_session(std::string sid, SrsJsonArray* arr);
|
||||
srs_error_t query_device_list(std::string sid, SrsJsonArray* arr);
|
||||
|
||||
public:
|
||||
srs_error_t fetch_or_create_sip_session(SrsSipRequest *req, SrsGb28181SipSession** sess);
|
||||
SrsGb28181SipSession* fetch(std::string id);
|
||||
void remove_session(std::string id);
|
||||
SrsGb28181Config* get_config();
|
||||
|
||||
void sip_session_map_by_callid(SrsGb28181SipSession *sess, std::string call_id);
|
||||
void sip_session_unmap_by_callid(std::string call_id);
|
||||
SrsGb28181SipSession* fetch_session_by_callid(std::string call_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,168 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2013-2021 Lixin
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
|
||||
#ifndef SRS_APP_GB28181_STACK_HPP
|
||||
#define SRS_APP_GB28181_STACK_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <srs_kernel_consts.hpp>
|
||||
#include <srs_rtsp_stack.hpp>
|
||||
|
||||
class SrsBuffer;
|
||||
class SrsSimpleStream;
|
||||
class SrsAudioFrame;
|
||||
|
||||
// SIP methods
|
||||
#define SRS_SIP_METHOD_REGISTER "REGISTER"
|
||||
#define SRS_SIP_METHOD_MESSAGE "MESSAGE"
|
||||
#define SRS_SIP_METHOD_INVITE "INVITE"
|
||||
#define SRS_SIP_METHOD_ACK "ACK"
|
||||
#define SRS_SIP_METHOD_BYE "BYE"
|
||||
|
||||
// SIP-Version
|
||||
#define SRS_SIP_VERSION "SIP/2.0"
|
||||
#define SRS_SIP_USER_AGENT RTMP_SIG_SRS_SERVER
|
||||
|
||||
#define SRS_SIP_PTZ_START 0xA5
|
||||
|
||||
|
||||
enum SrsSipCmdType{
|
||||
SrsSipCmdRequest=0,
|
||||
SrsSipCmdRespone=1
|
||||
};
|
||||
|
||||
enum SrsSipPtzCmdType{
|
||||
SrsSipPtzCmdStop = 0x00,
|
||||
SrsSipPtzCmdRight = 0x01,
|
||||
SrsSipPtzCmdLeft = 0x02,
|
||||
SrsSipPtzCmdDown = 0x04,
|
||||
SrsSipPtzCmdUp = 0x08,
|
||||
SrsSipPtzCmdZoomIn = 0x10,
|
||||
SrsSipPtzCmdZoomOut = 0x20
|
||||
};
|
||||
|
||||
std::string srs_sip_get_utc_date();
|
||||
|
||||
class SrsSipRequest
|
||||
{
|
||||
public:
|
||||
//sip header member
|
||||
std::string method;
|
||||
std::string uri;
|
||||
std::string version;
|
||||
std::string status;
|
||||
|
||||
std::string via;
|
||||
std::string from;
|
||||
std::string to;
|
||||
std::string from_tag;
|
||||
std::string to_tag;
|
||||
std::string branch;
|
||||
|
||||
std::string call_id;
|
||||
long seq;
|
||||
|
||||
std::string contact;
|
||||
std::string user_agent;
|
||||
|
||||
std::string content_type;
|
||||
long content_length;
|
||||
|
||||
long expires;
|
||||
int max_forwards;
|
||||
|
||||
std::string www_authenticate;
|
||||
std::string authorization;
|
||||
|
||||
std::string chid;
|
||||
|
||||
std::map<std::string, std::string> xml_body_map;
|
||||
std::map<std::string, std::string> device_list_map;
|
||||
// add an item_list, you can do a lot of other things
|
||||
// used by DeviceList, Alarmstatus, RecordList in "GB/T 28181—2016"
|
||||
std::vector<std::map<std::string, std::string> > item_list;
|
||||
|
||||
public:
|
||||
std::string serial;
|
||||
std::string realm;
|
||||
std::string sip_auth_id;
|
||||
std::string sip_auth_pwd;
|
||||
std::string sip_username;
|
||||
std::string peer_ip;
|
||||
int peer_port;
|
||||
std::string host;
|
||||
int host_port;
|
||||
SrsSipCmdType cmdtype;
|
||||
|
||||
std::string from_realm;
|
||||
std::string to_realm;
|
||||
uint32_t y_ssrc;
|
||||
|
||||
public:
|
||||
SrsRtspSdp* sdp;
|
||||
SrsRtspTransport* transport;
|
||||
public:
|
||||
SrsSipRequest();
|
||||
virtual ~SrsSipRequest();
|
||||
public:
|
||||
virtual bool is_register();
|
||||
virtual bool is_invite();
|
||||
virtual bool is_message();
|
||||
virtual bool is_ack();
|
||||
virtual bool is_bye();
|
||||
|
||||
virtual void copy(SrsSipRequest* src);
|
||||
public:
|
||||
virtual std::string get_cmdtype_str();
|
||||
};
|
||||
|
||||
// The gb28181 sip protocol stack.
|
||||
class SrsSipStack
|
||||
{
|
||||
private:
|
||||
// The cached bytes buffer.
|
||||
SrsSimpleStream* buf;
|
||||
public:
|
||||
SrsSipStack();
|
||||
virtual ~SrsSipStack();
|
||||
public:
|
||||
virtual srs_error_t parse_request(SrsSipRequest** preq, const char *recv_msg, int nb_buf);
|
||||
protected:
|
||||
virtual srs_error_t do_parse_request(SrsSipRequest* req, const char *recv_msg);
|
||||
virtual srs_error_t parse_xml(std::string xml_msg, std::map<std::string, std::string> &json_map, std::vector<std::map<std::string, std::string> > &item_list);
|
||||
|
||||
private:
|
||||
//response from
|
||||
virtual std::string get_sip_from(SrsSipRequest const *req);
|
||||
//response to
|
||||
virtual std::string get_sip_to(SrsSipRequest const *req);
|
||||
//response via
|
||||
virtual std::string get_sip_via(SrsSipRequest const *req);
|
||||
|
||||
public:
|
||||
//response: request sent by the sip-agent, wait for sip-server response
|
||||
virtual void resp_status(std::stringstream& ss, SrsSipRequest *req);
|
||||
virtual void resp_keepalive(std::stringstream& ss, SrsSipRequest *req);
|
||||
|
||||
//request: request sent by the sip-server, wait for sip-agent response
|
||||
virtual void req_invite(std::stringstream& ss, SrsSipRequest *req, std::string ip,
|
||||
int port, uint32_t ssrc, bool tcpFlag);
|
||||
virtual void req_ack(std::stringstream& ss, SrsSipRequest *req);
|
||||
virtual void req_bye(std::stringstream& ss, SrsSipRequest *req);
|
||||
virtual void req_401_unauthorized(std::stringstream& ss, SrsSipRequest *req);
|
||||
virtual void req_query_catalog(std::stringstream& ss, SrsSipRequest *req);
|
||||
virtual void req_ptz(std::stringstream& ss, SrsSipRequest *req, uint8_t cmd, uint8_t speed, int priority);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1299,200 +1299,6 @@ srs_error_t SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage
|
|||
return srs_api_response_code(w, r, 100);
|
||||
}
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
SrsGoApiGb28181::SrsGoApiGb28181()
|
||||
{
|
||||
}
|
||||
|
||||
SrsGoApiGb28181::~SrsGoApiGb28181()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsGoApiGb28181::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = do_serve_http(w, r)) != srs_success) {
|
||||
srs_warn("Server GB28181 err %s", srs_error_desc(err).c_str());
|
||||
int code = srs_error_code(err); srs_error_reset(err);
|
||||
return srs_api_response_code(w, r, code);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsGoApiGb28181::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
|
||||
SrsJsonObject* data = SrsJsonAny::object();
|
||||
obj->set("data", data);
|
||||
|
||||
string id = r->query_get("id");
|
||||
string action = r->query_get("action");
|
||||
string vhost = r->query_get("vhost");
|
||||
string app = r->query_get("app");
|
||||
string stream = r->query_get("stream");
|
||||
//fixed, random
|
||||
string port_mode = r->query_get("port_mode");
|
||||
|
||||
if (!_srs_gb28181) {
|
||||
return srs_error_new(ERROR_GB28181_SERVER_NOT_RUN, "no gb28181 engine");
|
||||
}
|
||||
|
||||
if(action == "create_channel"){
|
||||
if (id.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id");
|
||||
}
|
||||
|
||||
SrsGb28181StreamChannel channel;
|
||||
channel.set_channel_id(id);
|
||||
channel.set_app(app);
|
||||
channel.set_stream(stream);
|
||||
channel.set_port_mode(port_mode);
|
||||
|
||||
if ((err = _srs_gb28181->create_stream_channel(&channel)) != srs_success) {
|
||||
return srs_error_wrap(err, "create stream channel");
|
||||
}
|
||||
|
||||
data->set("query", SrsJsonAny::object()
|
||||
->set("id", SrsJsonAny::str(channel.get_channel_id().c_str()))
|
||||
->set("ip", SrsJsonAny::str(channel.get_ip().c_str()))
|
||||
->set("rtmp_port", SrsJsonAny::integer(channel.get_rtmp_port()))
|
||||
->set("app", SrsJsonAny::str(channel.get_app().c_str()))
|
||||
->set("stream", SrsJsonAny::str(channel.get_stream().c_str()))
|
||||
->set("rtp_port", SrsJsonAny::integer(channel.get_rtp_port()))
|
||||
->set("ssrc", SrsJsonAny::integer(channel.get_ssrc())));
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
|
||||
} else if(action == "delete_channel"){
|
||||
string chid = r->query_get("chid");
|
||||
if (id.empty() || chid.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id or chid");
|
||||
}
|
||||
|
||||
if ((err = _srs_gb28181->delete_stream_channel(id, chid)) != srs_success) {
|
||||
return srs_error_wrap(err, "delete stream channel");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "query_channel") {
|
||||
SrsJsonArray* arr = SrsJsonAny::array();
|
||||
data->set("channels", arr);
|
||||
|
||||
if ((err = _srs_gb28181->query_stream_channel(id, arr)) != srs_success) {
|
||||
return srs_error_wrap(err, "query stream channel");
|
||||
}
|
||||
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
} else if(action == "sip_invite"){
|
||||
string chid = r->query_get("chid");
|
||||
if (id.empty() || chid.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id or chid");
|
||||
}
|
||||
|
||||
string ssrc = r->query_get("ssrc");
|
||||
string rtp_port = r->query_get("rtp_port");
|
||||
string ip = r->query_get("ip");
|
||||
|
||||
int _port = strtoul(rtp_port.c_str(), NULL, 10);
|
||||
uint32_t _ssrc = (uint32_t)(strtoul(ssrc.c_str(), NULL, 10));
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_invite(id, ip, _port, _ssrc, chid)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip invite");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_bye"){
|
||||
string chid = r->query_get("chid");
|
||||
if (id.empty() || chid.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id or chid");
|
||||
}
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_bye(id, chid)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip bye");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_ptz"){
|
||||
string chid = r->query_get("chid");
|
||||
string ptzcmd = r->query_get("ptzcmd");
|
||||
string speed = r->query_get("speed");
|
||||
string priority = r->query_get("priority");
|
||||
if (id.empty() || chid.empty() || ptzcmd.empty() || speed.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id or chid or ptzcmd or speed");
|
||||
}
|
||||
|
||||
uint8_t _speed = (uint8_t)(strtoul(speed.c_str(), NULL, 10));
|
||||
int _priority = (int)(strtoul(priority.c_str(), NULL, 10));
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_ptz(id, chid, ptzcmd, _speed, _priority)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip ptz");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_raw_data"){
|
||||
if (id.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id");
|
||||
}
|
||||
|
||||
std::string body;
|
||||
r->body_read_all(body);
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_raw_data(id, body)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip raw data");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_unregister"){
|
||||
if (id.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id");
|
||||
}
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_unregister(id)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip unregister");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_query_catalog"){
|
||||
if (id.empty()){
|
||||
return srs_error_new(ERROR_GB28181_VALUE_EMPTY, "no id");
|
||||
}
|
||||
|
||||
if ((err = _srs_gb28181->notify_sip_query_catalog(id)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip query catelog");
|
||||
}
|
||||
|
||||
return srs_api_response_code(w, r, 0);
|
||||
} else if(action == "sip_query_devicelist"){
|
||||
SrsJsonArray* arr = SrsJsonAny::array();
|
||||
data->set("PlatformID", SrsJsonAny::str(_srs_gb28181->get_gb28181_config_ptr()->sip_serial.c_str()));
|
||||
data->set("DeviceList", arr);
|
||||
|
||||
if ((err = _srs_gb28181->query_device_list("", arr)) != srs_success) {
|
||||
return srs_error_wrap(err, "query device list");
|
||||
}
|
||||
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
} else if(action == "sip_query_session"){
|
||||
SrsJsonArray* arr = SrsJsonAny::array();
|
||||
data->set("sessions", arr);
|
||||
|
||||
if ((err = _srs_gb28181->query_sip_session(id, arr)) != srs_success) {
|
||||
return srs_error_wrap(err, "notify sip session");
|
||||
}
|
||||
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
} else {
|
||||
return srs_error_new(ERROR_GB28181_ACTION_INVALID, "action %s", action.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SRS_GPERF
|
||||
#include <gperftools/malloc_extension.h>
|
||||
|
||||
|
|
|
@ -205,19 +205,6 @@ public:
|
|||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
class SrsGoApiGb28181 : public ISrsHttpHandler
|
||||
{
|
||||
public:
|
||||
SrsGoApiGb28181();
|
||||
virtual ~SrsGoApiGb28181();
|
||||
public:
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
private:
|
||||
virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SRS_GPERF
|
||||
class SrsGoApiTcmalloc : public ISrsHttpHandler
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@ using namespace std;
|
|||
#include <srs_app_utility.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_app_pithy_print.hpp>
|
||||
|
||||
#include <srs_protocol_kbps.hpp>
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ using namespace std;
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
|
||||
#include <srs_core_autofree.hpp>
|
||||
|
@ -41,6 +42,8 @@ using namespace std;
|
|||
#include <srs_app_rtc_source.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_app_threads.hpp>
|
||||
#include <srs_service_log.hpp>
|
||||
#include <srs_app_log.hpp>
|
||||
|
||||
#include <srs_protocol_kbps.hpp>
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ using namespace std;
|
|||
#include <srs_app_rtc_source.hpp>
|
||||
#include <srs_app_rtc_api.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_service_log.hpp>
|
||||
|
||||
extern SrsPps* _srs_pps_rpkts;
|
||||
SrsPps* _srs_pps_rstuns = NULL;
|
||||
|
|
|
@ -944,17 +944,6 @@ srs_error_t SrsRtmpConn::acquire_publish(SrsLiveSource* source)
|
|||
|
||||
SrsRequest* req = info->req;
|
||||
|
||||
// @see https://github.com/ossrs/srs/issues/2364
|
||||
// Check whether GB28181 stream is busy.
|
||||
#if defined(SRS_GB28181)
|
||||
if (_srs_gb28181 != NULL) {
|
||||
SrsGb28181RtmpMuxer* gb28181 = _srs_gb28181->fetch_rtmpmuxer(req->stream);
|
||||
if (gb28181 != NULL) {
|
||||
return srs_error_new(ERROR_SYSTEM_STREAM_BUSY, "gb28181 stream %s busy", req->get_stream_url().c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check whether RTC stream is busy.
|
||||
#ifdef SRS_RTC
|
||||
SrsRtcSource *rtc = NULL;
|
||||
|
|
|
@ -35,8 +35,7 @@ using namespace std;
|
|||
#include <srs_app_caster_flv.hpp>
|
||||
#include <srs_kernel_consts.hpp>
|
||||
#include <srs_app_coworkers.hpp>
|
||||
#include <srs_app_gb28181.hpp>
|
||||
#include <srs_app_gb28181_sip.hpp>
|
||||
#include <srs_service_log.hpp>
|
||||
|
||||
std::string srs_listener_type2string(SrsListenerType type)
|
||||
{
|
||||
|
@ -57,10 +56,6 @@ std::string srs_listener_type2string(SrsListenerType type)
|
|||
return "RTSP";
|
||||
case SrsListenerFlv:
|
||||
return "HTTP-FLV";
|
||||
case SrsListenerGb28181Sip:
|
||||
return "GB28181-SIP over UDP";
|
||||
case SrsListenerGb28181RtpMux:
|
||||
return "GB28181-Stream over RTP";
|
||||
default:
|
||||
return "UNKONWN";
|
||||
}
|
||||
|
@ -253,9 +248,7 @@ srs_error_t SrsUdpStreamListener::listen(string i, int p)
|
|||
|
||||
// the caller already ensure the type is ok,
|
||||
// we just assert here for unknown stream caster.
|
||||
srs_assert(type == SrsListenerMpegTsOverUdp
|
||||
|| type == SrsListenerGb28181Sip
|
||||
|| type == SrsListenerGb28181RtpMux);
|
||||
srs_assert(type == SrsListenerMpegTsOverUdp);
|
||||
|
||||
ip = i;
|
||||
port = p;
|
||||
|
@ -293,85 +286,6 @@ SrsUdpCasterListener::~SrsUdpCasterListener()
|
|||
srs_freep(caster);
|
||||
}
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
|
||||
SrsGb28181Listener::SrsGb28181Listener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsUdpStreamListener(svr, t, NULL)
|
||||
{
|
||||
// the caller already ensure the type is ok,
|
||||
// we just assert here for unknown stream caster.
|
||||
srs_assert(type == SrsListenerGb28181Sip
|
||||
||type == SrsListenerGb28181RtpMux);
|
||||
|
||||
if (type == SrsListenerGb28181Sip) {
|
||||
caster = new SrsGb28181SipService(c);
|
||||
}else if(type == SrsListenerGb28181RtpMux){
|
||||
caster = new SrsGb28181RtpMuxService(c);
|
||||
}
|
||||
}
|
||||
|
||||
SrsGb28181Listener::~SrsGb28181Listener()
|
||||
{
|
||||
srs_freep(caster);
|
||||
}
|
||||
|
||||
SrsGb28181TcpListener::SrsGb28181TcpListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t)
|
||||
{
|
||||
// the caller already ensure the type is ok,
|
||||
// we just assert here for unknown stream caster.
|
||||
srs_assert(type == SrsListenerGb28181RtpMux);
|
||||
|
||||
caster = new SrsGb28181Caster(c);
|
||||
listener = NULL;
|
||||
}
|
||||
|
||||
SrsGb28181TcpListener::~SrsGb28181TcpListener()
|
||||
{
|
||||
srs_freep(caster);
|
||||
srs_freep(listener);
|
||||
}
|
||||
|
||||
srs_error_t SrsGb28181TcpListener::listen(std::string i, int p)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// the caller already ensure the type is ok,
|
||||
// we just assert here for unknown stream caster.
|
||||
srs_assert(type == SrsListenerGb28181RtpMux);
|
||||
|
||||
ip = i;
|
||||
port = p;
|
||||
|
||||
if ((err = caster->initialize()) != srs_success) {
|
||||
return srs_error_wrap(err, "init caster");
|
||||
}
|
||||
|
||||
srs_freep(listener);
|
||||
listener = new SrsTcpListener(this, ip, port);
|
||||
|
||||
if ((err = listener->listen()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtsp listen %s:%d", ip.c_str(), port);
|
||||
}
|
||||
|
||||
string v = srs_listener_type2string(type);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsGb28181TcpListener::on_tcp_client(srs_netfd_t stfd)
|
||||
{
|
||||
int fd = srs_netfd_fileno(stfd);
|
||||
string ip = srs_get_peer_ip(fd);
|
||||
|
||||
srs_error_t err = caster->on_tcp_client(stfd);
|
||||
if (err != srs_success) {
|
||||
srs_warn("accept client failed, err is %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SrsSignalManager* SrsSignalManager::instance = NULL;
|
||||
|
||||
SrsSignalManager::SrsSignalManager(SrsServer* s)
|
||||
|
@ -699,11 +613,6 @@ void SrsServer::destroy()
|
|||
|
||||
srs_freep(signal_manager);
|
||||
srs_freep(conn_manager);
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
//free global gb28181 manager
|
||||
srs_freep(_srs_gb28181);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SrsServer::dispose()
|
||||
|
@ -980,11 +889,6 @@ srs_error_t SrsServer::http_handle()
|
|||
if ((err = http_api_mux->handle("/api/v1/clusters", new SrsGoApiClusters())) != srs_success) {
|
||||
return srs_error_wrap(err, "handle clusters");
|
||||
}
|
||||
#ifdef SRS_GB28181
|
||||
if ((err = http_api_mux->handle("/api/v1/gb28181", new SrsGoApiGb28181())) != srs_success) {
|
||||
return srs_error_wrap(err, "handle raw");
|
||||
}
|
||||
#endif
|
||||
|
||||
// test the request info.
|
||||
if ((err = http_api_mux->handle("/api/v1/tests/requests", new SrsGoApiRequests())) != srs_success) {
|
||||
|
@ -1411,32 +1315,6 @@ srs_error_t SrsServer::listen_https_stream()
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
srs_error_t SrsServer::listen_gb28181_sip(SrsConfDirective* stream_caster)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsListener* sip_listener = NULL;
|
||||
sip_listener = new SrsGb28181Listener(this, SrsListenerGb28181Sip, stream_caster);
|
||||
|
||||
int port = _srs_config->get_stream_caster_gb28181_sip_listen(stream_caster);
|
||||
if (port <= 0) {
|
||||
return srs_error_new(ERROR_STREAM_CASTER_PORT, "invalid sip port=%d", port);
|
||||
}
|
||||
|
||||
srs_assert(sip_listener != NULL);
|
||||
|
||||
listeners.push_back(sip_listener);
|
||||
|
||||
// TODO: support listen at <[ip:]port>
|
||||
if ((err = sip_listener->listen(srs_any_address_for_listener(), port)) != srs_success) {
|
||||
return srs_error_wrap(err, "listen at %d", port);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
srs_error_t SrsServer::listen_stream_caster()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -1462,33 +1340,6 @@ srs_error_t SrsServer::listen_stream_caster()
|
|||
listener = new SrsRtspListener(this, SrsListenerRtsp, stream_caster);
|
||||
} else if (srs_stream_caster_is_flv(caster)) {
|
||||
listener = new SrsHttpFlvListener(this, SrsListenerFlv, stream_caster);
|
||||
#ifdef SRS_GB28181
|
||||
} else if (srs_stream_caster_is_gb28181(caster)) {
|
||||
//init global gb28181 manger
|
||||
if (_srs_gb28181 == NULL){
|
||||
_srs_gb28181 = new SrsGb28181Manger(this, stream_caster);
|
||||
if ((err = _srs_gb28181->initialize()) != srs_success){
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
//sip listener
|
||||
if (_srs_config->get_stream_caster_gb28181_sip_enable(stream_caster)){
|
||||
if ((err = listen_gb28181_sip(stream_caster)) != srs_success){
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
//gb28181 stream listener
|
||||
if (!_srs_config->get_stream_caster_tcp_enable(stream_caster)) {
|
||||
listener = new SrsGb28181Listener(this, SrsListenerGb28181RtpMux, stream_caster);
|
||||
} else {
|
||||
listener = new SrsGb28181TcpListener(this, SrsListenerGb28181RtpMux, stream_caster);
|
||||
}
|
||||
#else
|
||||
srs_warn("gb28181 is disabled, please enable it by: ./configure --with-gb28181");
|
||||
continue;
|
||||
#endif
|
||||
} else {
|
||||
return srs_error_new(ERROR_STREAM_CASTER_ENGINE, "invalid caster %s", caster.c_str());
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include <srs_app_listener.hpp>
|
||||
#include <srs_app_conn.hpp>
|
||||
#include <srs_service_st.hpp>
|
||||
#include <srs_app_gb28181.hpp>
|
||||
#include <srs_app_gb28181_sip.hpp>
|
||||
#include <srs_app_hourglass.hpp>
|
||||
#include <srs_app_hybrid.hpp>
|
||||
|
||||
|
@ -38,8 +36,6 @@ class SrsTcpListener;
|
|||
class SrsAppCasterFlv;
|
||||
class SrsRtspCaster;
|
||||
class SrsResourceManager;
|
||||
class SrsGb28181Caster;
|
||||
|
||||
|
||||
// The listener type for server to identify the connection,
|
||||
// that is, use different type to process the connection.
|
||||
|
@ -57,10 +53,6 @@ enum SrsListenerType
|
|||
SrsListenerRtsp = 4,
|
||||
// TCP stream, FLV stream over HTTP.
|
||||
SrsListenerFlv = 5,
|
||||
// UDP stream, gb28181 ps stream over rtp,
|
||||
SrsListenerGb28181RtpMux = 6,
|
||||
// UDP gb28181 sip server
|
||||
SrsListenerGb28181Sip = 7,
|
||||
// HTTPS api,
|
||||
SrsListenerHttpsApi = 8,
|
||||
// HTTPS stream,
|
||||
|
@ -152,33 +144,6 @@ public:
|
|||
virtual ~SrsUdpCasterListener();
|
||||
};
|
||||
|
||||
#ifdef SRS_GB28181
|
||||
|
||||
// A UDP gb28181 listener, for sip and rtp stream mux server.
|
||||
class SrsGb28181Listener : public SrsUdpStreamListener
|
||||
{
|
||||
public:
|
||||
SrsGb28181Listener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c);
|
||||
virtual ~SrsGb28181Listener();
|
||||
};
|
||||
|
||||
class SrsGb28181TcpListener : public SrsListener, public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
SrsTcpListener* listener;
|
||||
SrsGb28181Caster* caster;
|
||||
public:
|
||||
SrsGb28181TcpListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c);
|
||||
virtual ~SrsGb28181TcpListener();
|
||||
public:
|
||||
virtual srs_error_t listen(std::string i, int p);
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Convert signal to io,
|
||||
// @see: st-1.9/docs/notes.html
|
||||
class SrsSignalManager : public ISrsCoroutineHandler
|
||||
|
@ -341,9 +306,6 @@ private:
|
|||
virtual srs_error_t listen_http_stream();
|
||||
virtual srs_error_t listen_https_stream();
|
||||
virtual srs_error_t listen_stream_caster();
|
||||
#ifdef SRS_GB28181
|
||||
virtual srs_error_t listen_gb28181_sip(SrsConfDirective* c);
|
||||
#endif
|
||||
// Close the listeners for specified type,
|
||||
// Remove the listen object from manager.
|
||||
virtual void close_listeners(SrsListenerType type);
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 126
|
||||
#define VERSION_REVISION 127
|
||||
|
||||
#endif
|
||||
|
|
|
@ -171,8 +171,6 @@
|
|||
#define SRS_CONSTS_LOG_EXEC "EXE"
|
||||
// The rtc.
|
||||
#define SRS_CONSTS_LOG_RTC "RTC"
|
||||
// The gb28181 stream log id.
|
||||
#define SRS_CONSTS_LOG_GB28181_CASTER "GBS"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
|
|
@ -351,31 +351,6 @@
|
|||
#define ERROR_RTC_NO_TRACK 5030
|
||||
#define ERROR_RTC_RTCP_EMPTY_RR 5031
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// GB28181 API error.
|
||||
///////////////////////////////////////////////////////
|
||||
#define ERROR_GB28181_SERVER_NOT_RUN 6000
|
||||
#define ERROR_GB28181_SESSION_IS_EXIST 6001
|
||||
#define ERROR_GB28181_SESSION_IS_NOTEXIST 6002
|
||||
#define ERROR_GB28181_RTP_PORT_FULL 6003
|
||||
#define ERROR_GB28181_PORT_MODE_INVALID 6004
|
||||
#define ERROR_GB28181_VALUE_EMPTY 6005
|
||||
#define ERROR_GB28181_ACTION_INVALID 6006
|
||||
#define ERROR_GB28181_SIP_NOT_RUN 6007
|
||||
#define ERROR_GB28181_SIP_INVITE_FAILED 6008
|
||||
#define ERROR_GB28181_SIP_BYE_FAILED 6009
|
||||
#define ERROR_GB28181_SIP_IS_INVITING 6010
|
||||
#define ERROR_GB28181_CREATER_RTMPMUXER_FAILED 6011
|
||||
#define ERROR_GB28181_SIP_CH_OFFLINE 6012
|
||||
#define ERROR_GB28181_SIP_CH_NOTEXIST 6013
|
||||
#define ERROR_GB28181_SIP_RAW_DATA_FAILED 6014
|
||||
#define ERROR_GB28181_SIP_PRASE_FAILED 6015
|
||||
#define ERROR_GB28181_SIP_PTZ_FAILED 6016
|
||||
#define ERROR_GB28181_SIP_NOT_INVITE 6017
|
||||
#define ERROR_GB28181_SIP_PTZ_CMD_INVALID 6018
|
||||
#define ERROR_GB28181_H264_FRAMESIZE 6019
|
||||
#define ERROR_GB28181_H264_FRAME_FULL 6020
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// HTTP API error.
|
||||
///////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in a new issue