Squash: Move GB28181 to feature/gb28181. 5.0.4

pull/2169/head^2
winlin 4 years ago
parent 49826081b1
commit efdbf37255

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

@ -6,6 +6,7 @@ The changelog for SRS.
## SRS 5.0 Changelog
* v5.0, 2021-06-16, Change [GB28181](https://github.com/ossrs/srs/issues/1500) to [feature/gb28181](https://github.com/ossrs/srs/tree/feature/gb28181). 5.0.4
* v5.0, 2021-05-31, Use [SPDX-License-Identifier: MIT](https://spdx.dev/ids/). 5.0.3
* v5.0, 2021-05-19, ST: Simplify it, only Linux/Darwin, epoll/kqueue, single process. 5.0.2
* v5.0, 2021-03-17, Live: Refine edge to follow client and HTTP/302. 5.0.1
@ -15,16 +16,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 +71,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 +88,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 +98,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.

@ -5,9 +5,9 @@
[![](https://codecov.io/gh/ossrs/srs/branch/develop/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/develop)
[![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
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;
elif [[ $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;
@ -384,12 +382,7 @@ do
parse_user_option
done
if [ $help = yes ]; then
show_help
exit 0
fi
function apply_detail_options() {
function apply_auto_options() {
# set default preset if not specifies
if [[ $SRS_X86_X64 == NO && $SRS_OSX == NO && $SRS_CROSS_BUILD == NO ]]; then
SRS_X86_X64=YES; opt="--x86-x64 $opt";
@ -416,6 +409,28 @@ function apply_detail_options() {
if [ $SRS_TRANSCODE = YES ]; then SRS_FFMPEG_STUB=YES; fi
if [ $SRS_INGEST = YES ]; then SRS_FFMPEG_STUB=YES; fi
if [[ $SRS_SRTP_ASM == YES && $SRS_RTC == NO ]]; then
echo "Disable SRTP-ASM, because RTC is disabled."
SRS_SRTP_ASM=NO
fi
if [[ $SRS_SRTP_ASM == YES && $SRS_NASM == NO ]]; then
echo "Disable SRTP-ASM, because NASM is disabled."
SRS_SRTP_ASM=NO
fi
}
if [ $help = yes ]; then
apply_auto_options
show_help
exit 0
fi
#####################################################################################
# apply options
#####################################################################################
function apply_detail_options() {
# Always enable HTTP utilies.
if [ $SRS_HTTP_CORE = NO ]; then SRS_HTTP_CORE=YES; echo -e "${YELLOW}[WARN] Always enable HTTP utilies.${BLACK}"; fi
if [ $SRS_STREAM_CASTER = NO ]; then SRS_STREAM_CASTER=YES; echo -e "${YELLOW}[WARN] Always enable StreamCaster.${BLACK}"; fi
@ -435,17 +450,8 @@ function apply_detail_options() {
else
export SRS_JOBS="--jobs=${SRS_JOBS}"
fi
if [[ $SRS_SRTP_ASM == YES && $SRS_RTC == NO ]]; then
echo "Disable SRTP-ASM, because RTC is disabled."
SRS_SRTP_ASM=NO
fi
if [[ $SRS_SRTP_ASM == YES && $SRS_NASM == NO ]]; then
echo "Disable SRTP-ASM, because NASM is disabled."
SRS_SRTP_ASM=NO
fi
}
apply_auto_options
apply_detail_options
function regenerate_options() {
@ -473,7 +479,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为tcpoff为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为tcpoff为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

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

@ -943,17 +943,6 @@ srs_error_t SrsRtmpConn::acquire_publish(SrsLiveSource* source)
srs_error_t err = srs_success;
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

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

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 3
#define VERSION_REVISION 4
#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…
Cancel
Save