mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge branch 'feature/rtc' into develop
This commit is contained in:
commit
1c72a89fca
97 changed files with 654 additions and 9368 deletions
17
README.md
17
README.md
|
@ -159,7 +159,8 @@ For previous versions, please read:
|
|||
|
||||
## V4 changes
|
||||
|
||||
* v4.0, 2020-06-13, GB28181 with JitterBuffer support. 4.0.29
|
||||
* 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
|
||||
* v4.0, 2020-05-14, For [#307][bug #307], refine core structure, RTMP base on frame, RTC base on RTP. 4.0.26
|
||||
|
@ -1091,14 +1092,12 @@ SRS always use the simplest architecture to solve complex domain problems.
|
|||
## Modularity Architecture
|
||||
|
||||
```
|
||||
+----------------+-------------------------------------+
|
||||
| SRS/SRT server | Programs in Main or Research |
|
||||
+----------------+--+------------+---------------------+
|
||||
| App(For SRS) | Modules(1) | research/librtmp |
|
||||
+-------------------+------------+---------------------+
|
||||
| Service(C/S apps over ST) | srs-librtmp |
|
||||
+--------------------------------+---------------------+
|
||||
| Protocol Stack(RTMP/HTTP/RTSP/JSON/AMF/Format) |
|
||||
+--------------------+---------------------------------+
|
||||
| SRS/SRT server | Programs in Main |
|
||||
+--------------------+-------+-------------------------+
|
||||
| App(For SRS) | Modules(1) |
|
||||
+----------------------------+-------------------------+
|
||||
| Protocol Stack(RTMP/HTTP/RTSP/JSON/AMF/Service) |
|
||||
+------------------------------------------------------+
|
||||
| Kernel(File, Codec, Stream, LB services) |
|
||||
+------------------------------------------------------+
|
||||
|
|
4
trunk/.gitignore
vendored
4
trunk/.gitignore
vendored
|
@ -40,3 +40,7 @@ srs
|
|||
*.ts
|
||||
*.h264
|
||||
*.264
|
||||
/webrtc
|
||||
/configure.sh
|
||||
/janus
|
||||
|
||||
|
|
|
@ -69,6 +69,18 @@ else
|
|||
srs_undefine_macro "SRS_SRT" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_CXX11 = YES ]; then
|
||||
srs_define_macro "SRS_CXX11" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_CXX11" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_CXX14 = YES ]; then
|
||||
srs_define_macro "SRS_CXX14" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_CXX14" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_RTC = YES ]; then
|
||||
srs_define_macro "SRS_RTC" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
ff_src_dir="../../3rdparty"
|
||||
|
||||
# the jobs to make ffmpeg
|
||||
if [[ "" == $SRS_JOBS ]]; then
|
||||
export SRS_JOBS="--jobs=1"
|
||||
fi
|
||||
|
||||
ff_current_dir=$(pwd -P)
|
||||
ff_build_dir="${ff_current_dir}/_build"
|
||||
ff_release_dir="${ff_current_dir}/_release"
|
||||
echo "start to build the tools for transcode system:"
|
||||
echo "current_dir: ${ff_current_dir}"
|
||||
echo "build_dir: ${ff_build_dir}"
|
||||
echo "release_dir: ${ff_release_dir}"
|
||||
echo "SRS_JOBS: ${SRS_JOBS}"
|
||||
|
||||
mkdir -p ${ff_build_dir}
|
||||
mkdir -p ${ff_release_dir}
|
||||
|
||||
# yasm for libx264
|
||||
ff_yasm_bin=${ff_release_dir}/bin/yasm
|
||||
if [[ -f ${ff_yasm_bin} ]]; then
|
||||
echo "yasm is ok"
|
||||
else
|
||||
echo "build yasm-1.2.0"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf yasm-1.2.0 && unzip -q ${ff_src_dir}/yasm-1.2.0.zip &&
|
||||
cd yasm-1.2.0 && ./configure --prefix=${ff_release_dir} &&
|
||||
make && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build yasm-1.2.0 failed"; exit 1; fi
|
||||
fi
|
||||
# add yasm to path, for x264 to use yasm directly.
|
||||
# ffmpeg can specifies the yasm path when configure it.
|
||||
export PATH=${PATH}:${ff_release_dir}/bin
|
||||
|
||||
# libfdk-aac
|
||||
if [[ -f ${ff_release_dir}/lib/libfdk-aac.a ]]; then
|
||||
echo "libfdk_aac is ok"
|
||||
else
|
||||
echo "build fdk-aac-0.1.3"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf fdk-aac-0.1.3 && unzip -q ${ff_src_dir}/fdk-aac-0.1.3.zip &&
|
||||
cd fdk-aac-0.1.3 && bash autogen.sh && ./configure --prefix=${ff_release_dir} --enable-static && make ${SRS_JOBS} && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build fdk-aac-0.1.3 failed"; exit 1; fi
|
||||
fi
|
||||
|
||||
# lame-3.99
|
||||
if [[ -f ${ff_release_dir}/lib/libmp3lame.a ]]; then
|
||||
echo "libmp3lame is ok"
|
||||
else
|
||||
echo "build lame-3.99.5"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf lame-3.99.5 && unzip -q ${ff_src_dir}/lame-3.99.5.zip &&
|
||||
cd lame-3.99.5 && ./configure --prefix=${ff_release_dir} --enable-static && make ${SRS_JOBS} && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build lame-3.99.5 failed"; exit 1; fi
|
||||
fi
|
||||
|
||||
# speex-1.2rc1
|
||||
if [[ -f ${ff_release_dir}/lib/libspeex.a ]]; then
|
||||
echo "libspeex is ok"
|
||||
else
|
||||
echo "build speex-1.2rc1"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf speex-1.2rc1 && unzip -q ${ff_src_dir}/speex-1.2rc1.zip &&
|
||||
cd speex-1.2rc1 && ./configure --prefix=${ff_release_dir} --enable-static && make ${SRS_JOBS} && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build speex-1.2rc1 failed"; exit 1; fi
|
||||
fi
|
||||
|
||||
# x264 core.157
|
||||
if [[ -f ${ff_release_dir}/lib/libx264.a ]]; then
|
||||
echo "x264 is ok"
|
||||
else
|
||||
echo "build x264"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf x264-snapshot-20181116-2245 && unzip -q ${ff_src_dir}/x264-snapshot-20181116-2245.zip &&
|
||||
cd x264-snapshot-20181116-2245 &&
|
||||
./configure --prefix=${ff_release_dir} --disable-opencl --bit-depth=all \
|
||||
--enable-static --disable-avs --disable-swscale --disable-lavf \
|
||||
--disable-ffms --disable-gpac --disable-cli &&
|
||||
make ${SRS_JOBS} && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build x264 failed"; exit 1; fi
|
||||
fi
|
||||
|
||||
# ffmpeg-4.1
|
||||
if [[ -f ${ff_release_dir}/bin/ffmpeg ]]; then
|
||||
echo "ffmpeg-4.1 is ok"
|
||||
else
|
||||
echo "build ffmpeg-4.1"
|
||||
cd $ff_current_dir &&
|
||||
rm -rf ffmpeg-4.1 && unzip -q ${ff_src_dir}/ffmpeg-4.1.zip &&
|
||||
echo "remove all so to force the ffmpeg to build in static" &&
|
||||
rm -f ${ff_release_dir}/lib/*.so* &&
|
||||
echo "export the dir to enable the build command canbe use." &&
|
||||
export ffmpeg_exported_release_dir=${ff_release_dir} &&
|
||||
cd ffmpeg-4.1 &&
|
||||
./configure \
|
||||
--enable-gpl --enable-nonfree \
|
||||
--yasmexe=${ff_yasm_bin} \
|
||||
--prefix=${ff_release_dir} --cc= \
|
||||
--enable-static --disable-shared --disable-debug \
|
||||
--extra-cflags='-I${ffmpeg_exported_release_dir}/include' \
|
||||
--extra-ldflags='-L${ffmpeg_exported_release_dir}/lib -lm -ldl' \
|
||||
--disable-ffplay --disable-ffprobe --disable-doc \
|
||||
--enable-postproc --enable-bzlib --enable-zlib --enable-parsers \
|
||||
--enable-libx264 --enable-libmp3lame --enable-libfdk-aac --enable-libspeex \
|
||||
--enable-pthreads --extra-libs=-lpthread \
|
||||
--enable-encoders --enable-decoders --enable-avfilter --enable-muxers --enable-demuxers &&
|
||||
make ${SRS_JOBS} && make install
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "build ffmpeg failed"; exit 1; fi
|
||||
fi
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
# genereate the library header file.
|
||||
|
||||
objs=$1
|
||||
|
||||
rm -f $objs/include/srs_librtmp.h &&
|
||||
cp $objs/../src/libs/srs_librtmp.hpp $objs/include/srs_librtmp.h
|
||||
echo "genereate srs-librtmp headers success"
|
|
@ -29,8 +29,8 @@ echo "# INCS for ${MODULE_ID}, headers of module and its depends to compile" >>
|
|||
echo "${MODULE_ID}_MODULE_INCS = -I${MODULE_DIR} " >> ${FILE}
|
||||
#
|
||||
# the private include files, for example:
|
||||
# CORE_INCS = -Isrc/core -Iobjs/st -Iobjs -Iobjs/hp -Iobjs
|
||||
# MAIN_INCS = -Isrc/main $(CORE_MODULE_INCS) -Iobjs/st -Iobjs
|
||||
# CORE_INCS = -Isrc/core -Iobjs
|
||||
# CORE_LIBS_INCS = -Iobjs/st -Iobjs/ffmpeg/include
|
||||
# where the public will be used for other modules which depends on it.
|
||||
INCS_NAME="${MODULE_ID}_INCS"
|
||||
#
|
||||
|
@ -39,12 +39,14 @@ echo -n "${INCS_NAME} = -I${MODULE_DIR} " >> ${FILE}
|
|||
#
|
||||
# depends module header files
|
||||
for item in ${MODULE_DEPENDS[*]}; do
|
||||
DEP_INCS_NAME="${item}_INCS"do
|
||||
DEP_INCS_NAME="${item}_MODULE_INCS"
|
||||
echo -n "\$(${DEP_INCS_NAME})" >> ${FILE}
|
||||
done
|
||||
echo "" >> ${FILE}
|
||||
#
|
||||
# depends library header files
|
||||
INCS_LIBS_NAME="${MODULE_ID}_LIBS_INCS"
|
||||
echo -n "${INCS_LIBS_NAME} = " >> ${FILE}
|
||||
for item in ${ModuleLibIncs[*]}; do
|
||||
echo -n "-I${item} " >> ${FILE}
|
||||
done
|
||||
|
@ -58,6 +60,7 @@ DEPS_NAME="${MODULE_ID}_DEPS"
|
|||
echo -n "${DEPS_NAME} = " >> ${FILE}
|
||||
for item in ${MODULE_FILES[*]}; do
|
||||
HEADER_FILE="${MODULE_DIR}/${item}.hpp"
|
||||
if [[ ! -f ${HEADER_FILE} ]]; then HEADER_FILE="${MODULE_DIR}/${item}.h"; fi
|
||||
if [ -f ${HEADER_FILE} ]; then
|
||||
echo -n " ${HEADER_FILE}" >> ${FILE}
|
||||
fi
|
||||
|
@ -75,13 +78,16 @@ echo "# OBJ for ${MODULE_ID}, each object file" >> ${FILE}
|
|||
MODULE_OBJS=()
|
||||
for item in ${MODULE_FILES[*]}; do
|
||||
CPP_FILE="${MODULE_DIR}/${item}.cpp"
|
||||
if [[ ! -f ${CPP_FILE} ]]; then CPP_FILE="${MODULE_DIR}/${item}.cc"; fi
|
||||
OBJ_FILE="${SRS_OBJS_DIR}/${MODULE_DIR}/${item}.o"
|
||||
MODULE_OBJS="${MODULE_OBJS[@]} ${CPP_FILE}"
|
||||
if [ -f ${CPP_FILE} ]; then
|
||||
echo "${OBJ_FILE}: \$(${DEPS_NAME}) ${CPP_FILE} " >> ${FILE}
|
||||
echo " \$(CXX) -c \$(CXXFLAGS) ${DEFINES}\\" >> ${FILE}
|
||||
echo " \$(${INCS_NAME})\\" >> ${FILE}
|
||||
echo " -o ${OBJ_FILE} ${CPP_FILE}" >> ${FILE}
|
||||
echo " \$(${INCS_NAME})\\" >> ${FILE}
|
||||
echo " \$(${INCS_LIBS_NAME})\\" >> ${FILE}
|
||||
echo " -o ${OBJ_FILE} \\" >> ${FILE}
|
||||
echo " ${CPP_FILE}" >> ${FILE}
|
||||
fi
|
||||
done
|
||||
echo "" >> ${FILE}
|
||||
|
|
|
@ -19,6 +19,8 @@ SRS_HDS=NO
|
|||
SRS_SRT=NO
|
||||
SRS_RTC=YES
|
||||
SRS_GB28181=NO
|
||||
SRS_CXX11=NO
|
||||
SRS_CXX14=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_LIBRTMP=NO
|
||||
|
@ -149,6 +151,8 @@ Features:
|
|||
--srt=on|off Whether build the SRT support for SRS.
|
||||
--rtc=on|off Whether build the WebRTC support for SRS.
|
||||
--gb28181=on|off Whether build the GB28181 support for SRS.
|
||||
--cxx11=on|off Whether enable the C++11 support for SRS.
|
||||
--cxx14=on|off Whether enable the C++14 support for SRS.
|
||||
|
||||
--prefix=<path> The absolute installation path for srs. Default: $SRS_PREFIX
|
||||
--gcov=on|off Whether enable the GCOV compiler options.
|
||||
|
@ -321,6 +325,9 @@ function parse_user_option() {
|
|||
--without-gb28181) SRS_GB28181=NO ;;
|
||||
--gb28181) if [[ $value == off ]]; then SRS_GB28181=NO; else SRS_GB28181=YES; fi ;;
|
||||
|
||||
--cxx11) if [[ $value == off ]]; then SRS_CXX11=NO; else SRS_CXX11=YES; fi ;;
|
||||
--cxx14) if [[ $value == off ]]; then SRS_CXX14=NO; else SRS_CXX14=YES; fi ;;
|
||||
|
||||
--with-clean) SRS_CLEAN=YES ;;
|
||||
--without-clean) SRS_CLEAN=NO ;;
|
||||
--clean) if [[ $value == off ]]; then SRS_CLEAN=NO; else SRS_CLEAN=YES; fi ;;
|
||||
|
@ -514,6 +521,11 @@ function apply_user_presets() {
|
|||
SRS_UTEST=NO
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
|
||||
# Enable c++11 for SRT.
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
SRS_CXX11=YES
|
||||
fi
|
||||
}
|
||||
apply_user_presets
|
||||
|
||||
|
@ -613,6 +625,8 @@ function regenerate_options() {
|
|||
if [ $SRS_RTC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --rtc=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --rtc=off"; fi
|
||||
if [ $SRS_SIMULATOR = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --simulator=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --simulator=off"; fi
|
||||
if [ $SRS_GB28181 = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gb28181=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gb28181=off"; fi
|
||||
if [ $SRS_CXX11 = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx11=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx11=off"; fi
|
||||
if [ $SRS_CXX14 = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx14=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx14=off"; fi
|
||||
if [ $SRS_NASM = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --nasm=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --nasm=off"; fi
|
||||
if [ $SRS_SRTP_ASM = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --srtp-nasm=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --srtp-nasm=off"; fi
|
||||
if [ $SRS_SENDMMSG = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sendmmsg=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sendmmsg=off"; fi
|
||||
|
|
|
@ -491,6 +491,10 @@ vhost rtc.vhost.srs.com {
|
|||
# The strick check when process stun.
|
||||
# default: off
|
||||
stun_strict_check on;
|
||||
# Whether keep original sequence number.
|
||||
# If off, we will regenerate the sequence number for RTP packet.
|
||||
# default: off
|
||||
keep_sequence off;
|
||||
}
|
||||
# whether enable min delay mode for vhost.
|
||||
# default: on, for RTC.
|
||||
|
@ -511,6 +515,12 @@ vhost rtc.vhost.srs.com {
|
|||
# default: on
|
||||
enabled on;
|
||||
}
|
||||
# For TWCC.
|
||||
twcc {
|
||||
# Whether support TWCC.
|
||||
# default: on
|
||||
enabled on;
|
||||
}
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
|
@ -2065,33 +2075,6 @@ vhost all.transcode.srs.com {
|
|||
}
|
||||
}
|
||||
}
|
||||
# transcode all stream using the empty ffmpeg demo, do nothing.
|
||||
vhost ffempty.transcode.srs.com {
|
||||
transcode {
|
||||
enabled on;
|
||||
ffmpeg ./objs/research/ffempty;
|
||||
engine empty {
|
||||
enabled on;
|
||||
vcodec libx264;
|
||||
vbitrate 300;
|
||||
vfps 20;
|
||||
vwidth 768;
|
||||
vheight 320;
|
||||
vthreads 2;
|
||||
vprofile baseline;
|
||||
vpreset superfast;
|
||||
vparams {
|
||||
}
|
||||
acodec libfdk_aac;
|
||||
abitrate 45;
|
||||
asample_rate 44100;
|
||||
achannels 2;
|
||||
aparams {
|
||||
}
|
||||
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
|
||||
}
|
||||
}
|
||||
}
|
||||
# transcode all app and stream of app
|
||||
vhost app.transcode.srs.com {
|
||||
# the streaming transcode configs.
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
# no-daemon and write log to console config for srs.
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
http_api {
|
||||
enabled on;
|
||||
listen 1985;
|
||||
}
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 8080;
|
||||
}
|
||||
vhost __defaultVhost__ {
|
||||
hls {
|
||||
enabled on;
|
||||
hls_fragment 10;
|
||||
hls_window 60;
|
||||
hls_path ./objs/nginx/html;
|
||||
}
|
||||
ingest livestream {
|
||||
enabled on;
|
||||
input {
|
||||
type file;
|
||||
url ./doc/source.200kbps.768x320.flv;
|
||||
}
|
||||
#ffmpeg ./objs/ffmpeg/bin/ffmpeg;
|
||||
ffmpeg ./objs/research/librtmp/srs_ingest_flv;
|
||||
engine {
|
||||
enabled off;
|
||||
output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
|
||||
}
|
||||
}
|
||||
}
|
53
trunk/configure
vendored
53
trunk/configure
vendored
|
@ -87,9 +87,12 @@ GDBDebug=" -g -O0"
|
|||
WarnLevel=" -Wall"
|
||||
# the compile standard.
|
||||
CppStd="-ansi"
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
if [[ $SRS_CXX11 == YES ]]; then
|
||||
CppStd="-std=c++11"
|
||||
fi
|
||||
if [[ $SRS_CXX14 == YES ]]; then
|
||||
CppStd="-std=c++14"
|
||||
fi
|
||||
# performance of gprof
|
||||
SrsGprof=""; SrsGprofLink=""; if [ $SRS_GPROF = YES ]; then SrsGprof=" -pg -lc_p"; SrsGprofLink=" -pg"; fi
|
||||
# performance of gperf
|
||||
|
@ -211,13 +214,15 @@ KERNEL_OBJS="${MODULE_OBJS[@]}"
|
|||
#RTMP/HTTP/Raw Protocol, depends on core/kernel, provides rtmp/htttp protocol features.
|
||||
MODULE_ID="PROTOCOL"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL")
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot})
|
||||
MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_rtmp_stack"
|
||||
"srs_rtmp_handshake" "srs_protocol_utility" "srs_rtmp_msg_array" "srs_protocol_stream"
|
||||
"srs_raw_avc" "srs_rtsp_stack" "srs_sip_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json"
|
||||
"srs_protocol_format")
|
||||
"srs_protocol_format" "srs_service_log" "srs_service_st" "srs_service_http_client" "srs_service_http_conn"
|
||||
"srs_service_rtmp_conn" "srs_service_utility" "srs_service_conn")
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
MODULE_FILES+=("srs_rtc_stun_stack")
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh
|
||||
PROTOCOL_OBJS="${MODULE_OBJS[@]}"
|
||||
|
@ -225,33 +230,21 @@ PROTOCOL_OBJS="${MODULE_OBJS[@]}"
|
|||
#srt protocol features.
|
||||
if [ $SRS_SRT = YES ]; then
|
||||
MODULE_ID="SRT"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP")
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP")
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR})
|
||||
MODULE_FILES=("srt_server" "srt_handle" "srt_conn" "srt_to_rtmp" "ts_demux" "srt_data")
|
||||
SRT_INCS=${LibSRTRoot}; MODULE_DIR=${LibSRTRoot} . auto/modules.sh
|
||||
SRT_OBJS="${MODULE_OBJS[@]}"
|
||||
fi
|
||||
|
||||
#
|
||||
#Service Module, for both Server and Client Modules.
|
||||
# TODO: FIXME: Remove service module, https://github.com/ossrs/srs/issues/1535#issuecomment-633907655
|
||||
MODULE_ID="SERVICE"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL")
|
||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot})
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
MODULE_FILES=("srs_service_log" "srs_service_st" "srs_service_http_client"
|
||||
"srs_service_http_conn" "srs_service_rtmp_conn" "srs_service_utility"
|
||||
"srs_service_conn")
|
||||
DEFINES=""
|
||||
SERVICE_INCS="src/service"; MODULE_DIR=${SERVICE_INCS} . auto/modules.sh
|
||||
SERVICE_OBJS="${MODULE_OBJS[@]}"
|
||||
#
|
||||
#App Module, for SRS server only.
|
||||
MODULE_ID="APP"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE")
|
||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot} ${LibGperfRoot})
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL")
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot})
|
||||
if [ $SRS_GPERF = YES ]; then
|
||||
ModuleLibIncs+=(${LibGperfRoot})
|
||||
fi
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
|
@ -285,11 +278,11 @@ APP_OBJS="${MODULE_OBJS[@]}"
|
|||
#
|
||||
#Server Module, for SRS only.
|
||||
MODULE_ID="SERVER"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP")
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP")
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
MODULE_DEPENDS+=("SRT")
|
||||
fi
|
||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot})
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibGperfRoot} ${LibSSLRoot})
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
|
@ -302,8 +295,8 @@ SERVER_OBJS="${MODULE_OBJS[@]}"
|
|||
#
|
||||
#Main Module, for app from modules.
|
||||
MODULE_ID="MAIN"
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE")
|
||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot})
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL")
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibGperfRoot} ${LibSSLRoot})
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
|
@ -338,8 +331,8 @@ if [[ $SRS_SRT == YES ]]; then
|
|||
ModuleLibFiles+=("${LibSRTfile[*]}")
|
||||
fi
|
||||
# all depends objects
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}"
|
||||
ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot})
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}"
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibGperfRoot} ${LibSSLRoot})
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibIncs+=("${LibFfmpegRoot[*]}" ${LibSrtpRoot})
|
||||
fi
|
||||
|
@ -352,7 +345,7 @@ LINK_OPTIONS="${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}"
|
|||
BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . auto/apps.sh
|
||||
#
|
||||
# For modules, without the app module.
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${MAIN_OBJS[@]}"
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${MAIN_OBJS[@]}"
|
||||
ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile})
|
||||
if [[ $SRS_RTC == YES ]]; then
|
||||
ModuleLibFiles+=("${LibFfmpegFile[*]}" ${LibSrtpFile})
|
||||
|
@ -389,11 +382,11 @@ if [ $SRS_UTEST = YES ]; then
|
|||
if [[ $SRS_SRT == YES ]]; then
|
||||
ModuleLibFiles+=("${LibSRTfile[*]}")
|
||||
fi
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP")
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP")
|
||||
if [[ $SRS_SRT == YES ]]; then
|
||||
MODULE_DEPENDS+=("SRT")
|
||||
fi
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${APP_OBJS[@]} ${SRT_OBJS[@]}"
|
||||
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SRT_OBJS[@]}"
|
||||
LINK_OPTIONS="-lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . auto/utest.sh
|
||||
fi
|
||||
|
||||
|
|
|
@ -4,13 +4,6 @@ file
|
|||
../../src/main/srs_main_ingest_hls.cpp,
|
||||
auto readonly separator,
|
||||
../../objs/srs_auto_headers.hpp,
|
||||
libs readonly separator,
|
||||
../../src/libs/srs_librtmp.hpp,
|
||||
../../src/libs/srs_librtmp.cpp,
|
||||
../../src/libs/srs_lib_bandwidth.hpp,
|
||||
../../src/libs/srs_lib_bandwidth.cpp,
|
||||
../../src/libs/srs_lib_simple_socket.hpp,
|
||||
../../src/libs/srs_lib_simple_socket.cpp,
|
||||
core readonly separator,
|
||||
../../src/core/srs_core.hpp,
|
||||
../../src/core/srs_core.cpp,
|
||||
|
@ -167,21 +160,7 @@ file
|
|||
../../src/utest/srs_utest_protocol.hpp,
|
||||
../../src/utest/srs_utest_protocol.cpp,
|
||||
../../src/utest/srs_utest_reload.hpp,
|
||||
../../src/utest/srs_utest_reload.cpp,
|
||||
research readonly separator,
|
||||
../../research/librtmp/srs_aac_raw_publish.c,
|
||||
../../research/librtmp/srs_audio_raw_publish.c,
|
||||
../../research/librtmp/srs_bandwidth_check.c,
|
||||
../../research/librtmp/srs_detect_rtmp.c,
|
||||
../../research/librtmp/srs_flv_injecter.c,
|
||||
../../research/librtmp/srs_flv_parser.c,
|
||||
../../research/librtmp/srs_h264_raw_publish.c,
|
||||
../../research/librtmp/srs_ingest_flv.c,
|
||||
../../research/librtmp/srs_ingest_rtmp.c,
|
||||
../../research/librtmp/srs_play.c,
|
||||
../../research/librtmp/srs_publish.c,
|
||||
../../research/librtmp/srs_rtmp_dump.c,
|
||||
../../research/hls/ts_info.cc;
|
||||
../../src/utest/srs_utest_reload.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "MAIN";
|
||||
|
|
|
@ -116,9 +116,6 @@
|
|||
<ClInclude Include="..\..\src\kernel\srs_kernel_buffer.hpp" />
|
||||
<ClInclude Include="..\..\src\kernel\srs_kernel_ts.hpp" />
|
||||
<ClInclude Include="..\..\src\kernel\srs_kernel_utility.hpp" />
|
||||
<ClInclude Include="..\..\src\libs\srs_librtmp.hpp" />
|
||||
<ClInclude Include="..\..\src\libs\srs_lib_bandwidth.hpp" />
|
||||
<ClInclude Include="..\..\src\libs\srs_lib_simple_socket.hpp" />
|
||||
<ClInclude Include="..\..\src\protocol\srs_http_stack.hpp" />
|
||||
<ClInclude Include="..\..\src\protocol\srs_raw_avc.hpp" />
|
||||
<ClInclude Include="..\..\src\protocol\srs_protocol_amf0.hpp" />
|
||||
|
@ -132,19 +129,6 @@
|
|||
<ClInclude Include="..\..\src\protocol\srs_protocol_kbps.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\research\hls\ts_info.cc" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_aac_raw_publish.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_audio_raw_publish.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_bandwidth_check.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_detect_rtmp.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_flv_injecter.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_flv_parser.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_h264_raw_publish.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_ingest_flv.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_ingest_rtmp.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_play.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_publish.c" />
|
||||
<ClCompile Include="..\..\research\librtmp\srs_rtmp_dump.c" />
|
||||
<ClCompile Include="..\..\src\app\srs_app_bandwidth.cpp" />
|
||||
<ClCompile Include="..\..\src\app\srs_app_config.cpp" />
|
||||
<ClCompile Include="..\..\src\app\srs_app_conn.cpp" />
|
||||
|
@ -198,9 +182,6 @@
|
|||
<ClCompile Include="..\..\src\kernel\srs_kernel_buffer.cpp" />
|
||||
<ClCompile Include="..\..\src\kernel\srs_kernel_ts.cpp" />
|
||||
<ClCompile Include="..\..\src\kernel\srs_kernel_utility.cpp" />
|
||||
<ClCompile Include="..\..\src\libs\srs_librtmp.cpp" />
|
||||
<ClCompile Include="..\..\src\libs\srs_lib_bandwidth.cpp" />
|
||||
<ClCompile Include="..\..\src\libs\srs_lib_simple_socket.cpp" />
|
||||
<ClCompile Include="..\..\src\main\srs_main_server.cpp" />
|
||||
<ClCompile Include="..\..\src\protocol\srs_http_stack.cpp" />
|
||||
<ClCompile Include="..\..\src\protocol\srs_raw_avc.cpp" />
|
||||
|
|
|
@ -1,21 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_detect_rtmp.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_flv_injecter.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_flv_parser.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_ingest_flv.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_ingest_rtmp.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\app\srs_app_http.cpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClCompile>
|
||||
|
@ -127,9 +112,6 @@
|
|||
<ClCompile Include="..\..\src\core\srs_core_performance.cpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_h264_raw_publish.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kernel\srs_kernel_aac.cpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClCompile>
|
||||
|
@ -163,36 +145,6 @@
|
|||
<ClCompile Include="..\..\src\kernel\srs_kernel_utility.cpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_play.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_publish.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_rtmp_dump.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\hls\ts_info.cc">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_audio_raw_publish.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_bandwidth_check.c">
|
||||
<Filter>research</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\libs\srs_lib_bandwidth.cpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\libs\srs_lib_simple_socket.cpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\libs\srs_librtmp.cpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\research\librtmp\srs_aac_raw_publish.c">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\kernel\srs_kernel_ts.cpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClCompile>
|
||||
|
@ -378,15 +330,6 @@
|
|||
<ClInclude Include="..\..\src\kernel\srs_kernel_utility.hpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\libs\srs_librtmp.hpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\libs\srs_lib_bandwidth.hpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\libs\srs_lib_simple_socket.hpp">
|
||||
<Filter>librtmp</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kernel\srs_kernel_ts.hpp">
|
||||
<Filter>srs</Filter>
|
||||
</ClInclude>
|
||||
|
@ -434,14 +377,8 @@
|
|||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="research">
|
||||
<UniqueIdentifier>{7e9069c1-f19c-4ab0-b47f-36d7903cfa8b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="srs">
|
||||
<UniqueIdentifier>{0919b792-be75-49ed-b15a-2dc521e8394f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="librtmp">
|
||||
<UniqueIdentifier>{d45a9ecb-fcbe-4400-abe3-792cddecb47e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -77,9 +77,6 @@
|
|||
3C24ECCE1C3B824800460622 /* memory.error.tcmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */; };
|
||||
3C26E3C61BB146FF00D0F9DB /* srs_app_kafka.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C26E3C41BB146FF00D0F9DB /* srs_app_kafka.cpp */; };
|
||||
3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */; };
|
||||
3C36DB5B1ABD1CB90066CCAF /* srs_lib_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */; };
|
||||
3C36DB5C1ABD1CB90066CCAF /* srs_lib_simple_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */; };
|
||||
3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */; };
|
||||
3C44AACF1E3AF50200D4ABC3 /* srs_kernel_mp4.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C44AACD1E3AF50200D4ABC3 /* srs_kernel_mp4.cpp */; };
|
||||
3C4AB9331B8C9148006627D3 /* srs_app_ng_exec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C4AB9311B8C9148006627D3 /* srs_app_ng_exec.cpp */; };
|
||||
3C4D184C1E73F133008806F7 /* srs_app_fragment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D184A1E73F133008806F7 /* srs_app_fragment.cpp */; };
|
||||
|
@ -87,16 +84,6 @@
|
|||
3C5265B41B241BF0009CA186 /* srs_core_mem_watch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C5265B21B241BF0009CA186 /* srs_core_mem_watch.cpp */; };
|
||||
3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */; };
|
||||
3C663F101AB0155100286D8B /* srs_audio_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */; };
|
||||
3C663F111AB0155100286D8B /* srs_bandwidth_check.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F041AB0155100286D8B /* srs_bandwidth_check.c */; };
|
||||
3C663F121AB0155100286D8B /* srs_detect_rtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F051AB0155100286D8B /* srs_detect_rtmp.c */; };
|
||||
3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F061AB0155100286D8B /* srs_flv_injecter.c */; };
|
||||
3C663F141AB0155100286D8B /* srs_flv_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F071AB0155100286D8B /* srs_flv_parser.c */; };
|
||||
3C663F151AB0155100286D8B /* srs_h264_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */; };
|
||||
3C663F161AB0155100286D8B /* srs_ingest_flv.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F091AB0155100286D8B /* srs_ingest_flv.c */; };
|
||||
3C663F171AB0155100286D8B /* srs_ingest_rtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */; };
|
||||
3C663F181AB0155100286D8B /* srs_play.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0B1AB0155100286D8B /* srs_play.c */; };
|
||||
3C663F191AB0155100286D8B /* srs_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0C1AB0155100286D8B /* srs_publish.c */; };
|
||||
3C663F1A1AB0155100286D8B /* srs_rtmp_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */; };
|
||||
3C6F2D751E8653BF003D0805 /* srs_main_mp4_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C6F2D741E8653BF003D0805 /* srs_main_mp4_parser.cpp */; };
|
||||
3C82802C1BAFF8CC004A1794 /* srs_kafka_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C82802A1BAFF8CC004A1794 /* srs_kafka_stack.cpp */; };
|
||||
3C8CE01E1C3F482100548CC6 /* srs_app_hourglass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */; };
|
||||
|
@ -342,18 +329,10 @@
|
|||
3C1EE6D31AB1367D00576EE9 /* AUTHORS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = AUTHORS.txt; path = ../../../AUTHORS.txt; sourceTree = "<group>"; };
|
||||
3C1EE6D51AB1367D00576EE9 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../../LICENSE; sourceTree = "<group>"; };
|
||||
3C1EE6D61AB1367D00576EE9 /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; name = README.md; path = ../../../README.md; sourceTree = "<group>"; wrapsLines = 0; };
|
||||
3C24ECCB1C3B824800460622 /* memory.error.notcmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.error.notcmalloc.cpp; path = ../../../research/gperftools/memory.error.notcmalloc.cpp; sourceTree = "<group>"; };
|
||||
3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.error.tcmalloc.cpp; path = ../../../research/gperftools/memory.error.tcmalloc.cpp; sourceTree = "<group>"; };
|
||||
3C26E3C41BB146FF00D0F9DB /* srs_app_kafka.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_kafka.cpp; path = ../../../src/app/srs_app_kafka.cpp; sourceTree = "<group>"; };
|
||||
3C26E3C51BB146FF00D0F9DB /* srs_app_kafka.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_kafka.hpp; path = ../../../src/app/srs_app_kafka.hpp; sourceTree = "<group>"; };
|
||||
3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_caster_flv.cpp; path = ../../../src/app/srs_app_caster_flv.cpp; sourceTree = "<group>"; };
|
||||
3C28EDDE1AF5C43F00A3AEAC /* srs_app_caster_flv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_caster_flv.hpp; path = ../../../src/app/srs_app_caster_flv.hpp; sourceTree = "<group>"; };
|
||||
3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_bandwidth.cpp; path = ../../../src/libs/srs_lib_bandwidth.cpp; sourceTree = "<group>"; };
|
||||
3C36DB561ABD1CB90066CCAF /* srs_lib_bandwidth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_lib_bandwidth.hpp; path = ../../../src/libs/srs_lib_bandwidth.hpp; sourceTree = "<group>"; };
|
||||
3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_simple_socket.cpp; path = ../../../src/libs/srs_lib_simple_socket.cpp; sourceTree = "<group>"; };
|
||||
3C36DB581ABD1CB90066CCAF /* srs_lib_simple_socket.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_lib_simple_socket.hpp; path = ../../../src/libs/srs_lib_simple_socket.hpp; sourceTree = "<group>"; };
|
||||
3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_librtmp.cpp; path = ../../../src/libs/srs_librtmp.cpp; sourceTree = "<group>"; };
|
||||
3C36DB5A1ABD1CB90066CCAF /* srs_librtmp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_librtmp.hpp; path = ../../../src/libs/srs_librtmp.hpp; sourceTree = "<group>"; };
|
||||
3C4468E81BB0E31300589C9D /* sources_replace.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = sources_replace.sh; path = ../../../scripts/sources_replace.sh; sourceTree = "<group>"; };
|
||||
3C44AACD1E3AF50200D4ABC3 /* srs_kernel_mp4.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_mp4.cpp; path = ../../../src/kernel/srs_kernel_mp4.cpp; sourceTree = "<group>"; };
|
||||
3C44AACE1E3AF50200D4ABC3 /* srs_kernel_mp4.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_mp4.hpp; path = ../../../src/kernel/srs_kernel_mp4.hpp; sourceTree = "<group>"; };
|
||||
|
@ -365,19 +344,6 @@
|
|||
3C4F97101B8B466D00FF0E46 /* srs_app_process.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_process.cpp; path = ../../../src/app/srs_app_process.cpp; sourceTree = "<group>"; };
|
||||
3C4F97111B8B466D00FF0E46 /* srs_app_process.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_process.hpp; path = ../../../src/app/srs_app_process.hpp; sourceTree = "<group>"; };
|
||||
3C5265B21B241BF0009CA186 /* srs_core_mem_watch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_mem_watch.cpp; path = ../../../src/core/srs_core_mem_watch.cpp; sourceTree = "<group>"; };
|
||||
3C5265B31B241BF0009CA186 /* srs_core_mem_watch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_mem_watch.hpp; path = ../../../src/core/srs_core_mem_watch.hpp; sourceTree = "<group>"; };
|
||||
3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_aac_raw_publish.c; path = ../../../research/librtmp/srs_aac_raw_publish.c; sourceTree = "<group>"; };
|
||||
3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_audio_raw_publish.c; path = ../../../research/librtmp/srs_audio_raw_publish.c; sourceTree = "<group>"; };
|
||||
3C663F041AB0155100286D8B /* srs_bandwidth_check.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_bandwidth_check.c; path = ../../../research/librtmp/srs_bandwidth_check.c; sourceTree = "<group>"; };
|
||||
3C663F051AB0155100286D8B /* srs_detect_rtmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_detect_rtmp.c; path = ../../../research/librtmp/srs_detect_rtmp.c; sourceTree = "<group>"; };
|
||||
3C663F061AB0155100286D8B /* srs_flv_injecter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_flv_injecter.c; path = ../../../research/librtmp/srs_flv_injecter.c; sourceTree = "<group>"; };
|
||||
3C663F071AB0155100286D8B /* srs_flv_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_flv_parser.c; path = ../../../research/librtmp/srs_flv_parser.c; sourceTree = "<group>"; };
|
||||
3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_h264_raw_publish.c; path = ../../../research/librtmp/srs_h264_raw_publish.c; sourceTree = "<group>"; };
|
||||
3C663F091AB0155100286D8B /* srs_ingest_flv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_ingest_flv.c; path = ../../../research/librtmp/srs_ingest_flv.c; sourceTree = "<group>"; };
|
||||
3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_ingest_rtmp.c; path = ../../../research/librtmp/srs_ingest_rtmp.c; sourceTree = "<group>"; };
|
||||
3C663F0B1AB0155100286D8B /* srs_play.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_play.c; path = ../../../research/librtmp/srs_play.c; sourceTree = "<group>"; };
|
||||
3C663F0C1AB0155100286D8B /* srs_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_publish.c; path = ../../../research/librtmp/srs_publish.c; sourceTree = "<group>"; };
|
||||
3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_rtmp_dump.c; path = ../../../research/librtmp/srs_rtmp_dump.c; sourceTree = "<group>"; };
|
||||
3C6673CF1DF7B93200A6DF57 /* readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = readme.txt; path = ../../../modules/readme.txt; sourceTree = "<group>"; };
|
||||
3C6673D11DF7B95E00A6DF57 /* config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = config; path = "../../../modules/hls-ingester/config"; sourceTree = "<group>"; };
|
||||
3C6F2D731E86536B003D0805 /* config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = config; path = "../../../modules/mp4-parser/config"; sourceTree = "<group>"; };
|
||||
|
@ -397,10 +363,7 @@
|
|||
3C9F82241E4F5D2A00F5B2D2 /* srs_protocol_format.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_format.hpp; path = ../../../src/protocol/srs_protocol_format.hpp; sourceTree = "<group>"; };
|
||||
3CA432A61E3F46DD001DA0C6 /* srs_kernel_io.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kernel_io.cpp; path = ../../../src/kernel/srs_kernel_io.cpp; sourceTree = "<group>"; };
|
||||
3CA432A71E3F46DD001DA0C6 /* srs_kernel_io.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kernel_io.hpp; path = ../../../src/kernel/srs_kernel_io.hpp; sourceTree = "<group>"; };
|
||||
3CA432A91E40AEBC001DA0C6 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../../research/librtmp/Makefile; sourceTree = "<group>"; };
|
||||
3CA432AA1E40AEBC001DA0C6 /* srs_ingest_mp4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_ingest_mp4.c; path = ../../../research/librtmp/srs_ingest_mp4.c; sourceTree = "<group>"; };
|
||||
3CB25C281BB2596300C97A63 /* setup_variables.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = setup_variables.sh; path = ../../../auto/setup_variables.sh; sourceTree = "<group>"; };
|
||||
3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jmp_sp.cpp; path = ../../../research/arm/jmp_sp.cpp; sourceTree = "<group>"; };
|
||||
3CC52DCA1ACE4023006FEB01 /* srs_utest_amf0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_utest_amf0.cpp; path = ../../src/utest/srs_utest_amf0.cpp; sourceTree = "<group>"; };
|
||||
3CC52DCB1ACE4023006FEB01 /* srs_utest_amf0.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_utest_amf0.hpp; path = ../../src/utest/srs_utest_amf0.hpp; sourceTree = "<group>"; };
|
||||
3CC52DCC1ACE4023006FEB01 /* srs_utest_config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_utest_config.cpp; path = ../../src/utest/srs_utest_config.cpp; sourceTree = "<group>"; };
|
||||
|
@ -473,7 +436,6 @@
|
|||
3C1232EE1AAEA71C00CE8F6C /* links */,
|
||||
3C1231E71AAE64A400CE8F6C /* srs_xcode */,
|
||||
3CC52DC91ACE4006006FEB01 /* utest */,
|
||||
3C663F001AB014B500286D8B /* research */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -497,7 +459,6 @@
|
|||
3C12324B1AAE81CE00CE8F6C /* app */,
|
||||
3C96ADC41B00A71000885304 /* modules */,
|
||||
3C1232041AAE80CB00CE8F6C /* main */,
|
||||
3C36DB541ABD1CA70066CCAF /* libs */,
|
||||
3C1231F91AAE670E00CE8F6C /* objs */,
|
||||
3C1EE6AF1AB107EE00576EE9 /* conf */,
|
||||
3C1232EF1AAEAC5800CE8F6C /* etc */,
|
||||
|
@ -833,44 +794,6 @@
|
|||
name = doc;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3C36DB541ABD1CA70066CCAF /* libs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */,
|
||||
3C36DB561ABD1CB90066CCAF /* srs_lib_bandwidth.hpp */,
|
||||
3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */,
|
||||
3C36DB581ABD1CB90066CCAF /* srs_lib_simple_socket.hpp */,
|
||||
3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */,
|
||||
3C36DB5A1ABD1CB90066CCAF /* srs_librtmp.hpp */,
|
||||
);
|
||||
name = libs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3C663F001AB014B500286D8B /* research */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */,
|
||||
3CA432A91E40AEBC001DA0C6 /* Makefile */,
|
||||
3C24ECCB1C3B824800460622 /* memory.error.notcmalloc.cpp */,
|
||||
3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */,
|
||||
3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */,
|
||||
3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */,
|
||||
3C663F041AB0155100286D8B /* srs_bandwidth_check.c */,
|
||||
3C663F051AB0155100286D8B /* srs_detect_rtmp.c */,
|
||||
3C663F061AB0155100286D8B /* srs_flv_injecter.c */,
|
||||
3C663F071AB0155100286D8B /* srs_flv_parser.c */,
|
||||
3C663F081AB0155100286D8B /* srs_h264_raw_publish.c */,
|
||||
3C663F091AB0155100286D8B /* srs_ingest_flv.c */,
|
||||
3CA432AA1E40AEBC001DA0C6 /* srs_ingest_mp4.c */,
|
||||
3C663F0A1AB0155100286D8B /* srs_ingest_rtmp.c */,
|
||||
3C663F0B1AB0155100286D8B /* srs_play.c */,
|
||||
3C663F0C1AB0155100286D8B /* srs_publish.c */,
|
||||
3C663F0D1AB0155100286D8B /* srs_rtmp_dump.c */,
|
||||
);
|
||||
name = research;
|
||||
path = srs_xcode;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3C6673D01DF7B95000A6DF57 /* hls-ingester */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1038,7 +961,6 @@
|
|||
3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */,
|
||||
3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */,
|
||||
3CE893BF1E876A97000B742D /* srs_service_http_client.cpp in Sources */,
|
||||
3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */,
|
||||
3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */,
|
||||
3CECAF991EDC100F00C50501 /* event.c in Sources */,
|
||||
3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */,
|
||||
|
|
3
trunk/research/librtmp/.gitignore
vendored
3
trunk/research/librtmp/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
*.mp4
|
||||
*.gcno
|
||||
*.gcda
|
|
@ -1,125 +0,0 @@
|
|||
GCC = gcc
|
||||
|
||||
ifeq ($(HANDSHAKE),)
|
||||
ST_ALL = help
|
||||
else
|
||||
ST_ALL = objs/srs_flv_parser \
|
||||
objs/srs_flv_injecter objs/srs_publish objs/srs_play \
|
||||
objs/srs_ingest_flv objs/srs_ingest_rtmp objs/srs_detect_rtmp \
|
||||
objs/srs_bandwidth_check objs/srs_h264_raw_publish \
|
||||
objs/srs_audio_raw_publish objs/srs_aac_raw_publish \
|
||||
objs/srs_rtmp_dump objs/srs_ingest_mp4
|
||||
endif
|
||||
|
||||
.PHONY: default clean help ssl nossl
|
||||
|
||||
default: $(ST_ALL)
|
||||
|
||||
help:
|
||||
@echo "Usage: make <help>|<clean>|<ssl>|<nossl>"
|
||||
@echo " help display this help"
|
||||
@echo " clean cleanup build"
|
||||
@echo " ssl all tools link ssl"
|
||||
@echo " nossl all tools never link ssl"
|
||||
@echo "ssl/nossl will build the following tools:"
|
||||
@echo " srs_flv_parser parse flv file, print detail info."
|
||||
@echo " srs_flv_injecter inject keyframes information to metadata."
|
||||
@echo " srs_publish publish program using srs-librtmp"
|
||||
@echo " srs_h264_raw_publish publish raw h.264 stream to SSR by srs-librtmp"
|
||||
@echo " srs_audio_raw_publish publish raw audio stream to SSR by srs-librtmp"
|
||||
@echo " srs_aac_raw_publish publish raw aac stream to SSR by srs-librtmp"
|
||||
@echo " srs_play play program using srs-librtmp"
|
||||
@echo " srs_ingest_flv ingest flv file and publish to RTMP server."
|
||||
@echo " srs_ingest_mp4 ingest mp4 file and publish to RTMP server."
|
||||
@echo " srs_ingest_rtmp ingest RTMP and publish to RTMP server."
|
||||
@echo " srs_detect_rtmp detect RTMP stream info."
|
||||
@echo " srs_bandwidth_check bandwidth check/test tool."
|
||||
@echo " srs_rtmp_dump dump rtmp stream to flv file."
|
||||
@echo "Remark: about simple/complex handshake, see: http://blog.csdn.net/win_lin/article/details/13006803"
|
||||
@echo "Remark: srs Makefile will auto invoke this by --with/without-ssl, "
|
||||
@echo " that is, if user specified ssl(by --with-ssl), srs will make this by 'make ssl'"
|
||||
@echo " that is, if user not use ssl(by --without-ssl), use 'make nossl'"
|
||||
@echo " see: https://github.com/ossrs/srs/wiki/v1_CN_v1_Build"
|
||||
@echo "Remark: before make this sample, user must make the srs, with/without ssl"
|
||||
|
||||
clean:
|
||||
@rm -rf objs
|
||||
|
||||
# srs library root
|
||||
SRS_OBJS = ../../objs
|
||||
# srs-librtmp for publish/play, built by srs.
|
||||
SRS_LIBRTMP_I = $(SRS_OBJS)/include/srs_librtmp.h
|
||||
SRS_LIBRTMP_L = $(SRS_OBJS)/lib/srs_librtmp.a
|
||||
# openssl for complex handshake, built by srs.
|
||||
SRS_LIBSSL_L =
|
||||
# public depends, the Makefile or public headers.
|
||||
SRS_RESEARCH_DEPS = Makefile
|
||||
|
||||
# for x86/x64 platform
|
||||
ifeq ($(GCC), gcc)
|
||||
OTHER_FLAGS += -g -O0 -ldl -lstdc++ -lm
|
||||
endif
|
||||
# for arm.
|
||||
ifeq ($(GCC), arm-linux-gnueabi-gcc)
|
||||
OTHER_FLAGS += -g -O0 -ldl -static -lstdc++ -lm
|
||||
endif
|
||||
# for mips, add -lgcc_eh, or stl compile failed.
|
||||
ifeq ($(GCC), mipsel-openwrt-linux-gcc)
|
||||
OTHER_FLAGS += -g -O0 -ldl -lstdc++ -lm -lgcc_eh
|
||||
endif
|
||||
# for ssl or nossl
|
||||
ifeq ($(HANDSHAKE), SSL)
|
||||
SRS_LIBSSL_L = $(SRS_OBJS)/openssl/lib/libssl.a $(SRS_OBJS)/openssl/lib/libcrypto.a
|
||||
ifneq ($(shell test -f $(SRS_OBJS)/openssl/lib/libssl.a && echo yes), yes)
|
||||
SRS_LIBSSL_L = -lssl -lcrypto
|
||||
endif
|
||||
endif
|
||||
|
||||
ssl:
|
||||
@mkdir -p objs
|
||||
$(MAKE) HANDSHAKE="SSL"
|
||||
nossl:
|
||||
@mkdir -p objs
|
||||
$(MAKE) HANDSHAKE="NOSSL"
|
||||
|
||||
CXXFLAGS += $(OTHER_FLAGS) $(EXTRA_CXXFLAGS)
|
||||
|
||||
objs/srs_flv_parser: srs_flv_parser.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L)
|
||||
$(GCC) srs_flv_parser.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_flv_parser
|
||||
|
||||
objs/srs_flv_injecter: srs_flv_injecter.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L)
|
||||
$(GCC) srs_flv_injecter.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_flv_injecter
|
||||
|
||||
objs/srs_publish: srs_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_publish
|
||||
|
||||
objs/srs_h264_raw_publish: srs_h264_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_h264_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_h264_raw_publish
|
||||
|
||||
objs/srs_audio_raw_publish: srs_audio_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_audio_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_audio_raw_publish
|
||||
|
||||
objs/srs_aac_raw_publish: srs_aac_raw_publish.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_aac_raw_publish.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_aac_raw_publish
|
||||
|
||||
objs/srs_play: srs_play.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_play.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_play
|
||||
|
||||
objs/srs_ingest_flv: srs_ingest_flv.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_ingest_flv.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_flv
|
||||
|
||||
objs/srs_ingest_mp4: srs_ingest_mp4.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_ingest_mp4.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_mp4
|
||||
|
||||
objs/srs_ingest_rtmp: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_ingest_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_ingest_rtmp
|
||||
|
||||
objs/srs_detect_rtmp: srs_detect_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_detect_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_detect_rtmp
|
||||
|
||||
objs/srs_bandwidth_check: srs_bandwidth_check.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_bandwidth_check.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_bandwidth_check
|
||||
|
||||
objs/srs_rtmp_dump: srs_rtmp_dump.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L)
|
||||
$(GCC) srs_rtmp_dump.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(CXXFLAGS) -o objs/srs_rtmp_dump
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// for open audio raw file.
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
// https://github.com/ossrs/srs/issues/212#issuecomment-64145910
|
||||
int read_audio_frame(char* data, int size, char** pp, char** frame, int* frame_size)
|
||||
{
|
||||
char* p = *pp;
|
||||
|
||||
// @remark, for this demo, to publish aac raw file to SRS,
|
||||
// we search the adts frame from the buffer which cached the aac data.
|
||||
// please get aac adts raw data from device, it always a encoded frame.
|
||||
if (!srs_aac_is_adts(p, size - (p - data))) {
|
||||
srs_human_trace("aac adts raw data invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @see srs_audio_write_raw_frame
|
||||
// each frame prefixed aac adts header, '1111 1111 1111'B, that is 0xFFF.,
|
||||
// for instance, frame = FF F1 5C 80 13 A0 FC 00 D0 33 83 E8 5B
|
||||
*frame = p;
|
||||
// skip some data.
|
||||
// @remark, user donot need to do this.
|
||||
p += srs_aac_adts_frame_size(p, size - (p - data));
|
||||
|
||||
*pp = p;
|
||||
*frame_size = p - *frame;
|
||||
if (*frame_size <= 0) {
|
||||
srs_human_trace("aac adts raw data invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("publish raw audio as rtmp stream to server like FMLE/FFMPEG/Encoder\n");
|
||||
printf("SRS(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("Usage: %s <audio_raw_file> <rtmp_publish_url>\n", argv[0]);
|
||||
printf(" audio_raw_file: the audio raw steam file.\n");
|
||||
printf(" rtmp_publish_url: the rtmp publish url.\n");
|
||||
printf("For example:\n");
|
||||
printf(" %s ./audio.raw.aac rtmp://127.0.0.1:1935/live/livestream\n", argv[0]);
|
||||
printf("Where the file: http://winlinvip.github.io/srs.release/3rdparty/audio.raw.aac\n");
|
||||
printf("See: https://github.com/ossrs/srs/issues/212\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const char* raw_file = argv[1];
|
||||
const char* rtmp_url = argv[2];
|
||||
srs_human_trace("raw_file=%s, rtmp_url=%s", raw_file, rtmp_url);
|
||||
|
||||
// open file
|
||||
int raw_fd = open(raw_file, O_RDONLY);
|
||||
if (raw_fd < 0) {
|
||||
srs_human_trace("open audio raw file %s failed.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
off_t file_size = lseek(raw_fd, 0, SEEK_END);
|
||||
if (file_size <= 0) {
|
||||
srs_human_trace("audio raw file %s empty.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("read entirely audio raw file, size=%dKB", (int)(file_size / 1024));
|
||||
|
||||
char* audio_raw = (char*)malloc(file_size);
|
||||
if (!audio_raw) {
|
||||
srs_human_trace("alloc raw buffer failed for file %s.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
lseek(raw_fd, 0, SEEK_SET);
|
||||
ssize_t nb_read = 0;
|
||||
if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) {
|
||||
srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.",
|
||||
raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// connect rtmp context
|
||||
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
|
||||
|
||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if (srs_rtmp_publish_stream(rtmp) != 0) {
|
||||
srs_human_trace("publish stream failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("publish stream success");
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
uint32_t time_delta = 45;
|
||||
// @remark, to decode the file.
|
||||
char* p = audio_raw;
|
||||
for (;p < audio_raw + file_size;) {
|
||||
// @remark, read a frame from file buffer.
|
||||
char* data = NULL;
|
||||
int size = 0;
|
||||
if (read_audio_frame(audio_raw, file_size, &p, &data, &size) < 0) {
|
||||
srs_human_trace("read a frame from file buffer failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// 0 = Linear PCM, platform endian
|
||||
// 1 = ADPCM
|
||||
// 2 = MP3
|
||||
// 7 = G.711 A-law logarithmic PCM
|
||||
// 8 = G.711 mu-law logarithmic PCM
|
||||
// 10 = AAC
|
||||
// 11 = Speex
|
||||
char sound_format = 10;
|
||||
// 2 = 22 kHz
|
||||
char sound_rate = 2;
|
||||
// 1 = 16-bit samples
|
||||
char sound_size = 1;
|
||||
// 1 = Stereo sound
|
||||
char sound_type = 1;
|
||||
|
||||
timestamp += time_delta;
|
||||
|
||||
int ret = 0;
|
||||
if ((ret = srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp)) != 0) {
|
||||
srs_human_trace("send audio raw data failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d",
|
||||
srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size,
|
||||
sound_type);
|
||||
|
||||
// @remark, when use encode device, it not need to sleep.
|
||||
usleep(1000 * time_delta);
|
||||
}
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
close(raw_fd);
|
||||
free(audio_raw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// for open audio raw file.
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
// https://github.com/ossrs/srs/issues/212#issuecomment-63648892
|
||||
// allspace:
|
||||
// Take this file as an example: https://github.com/allspace/files/blob/master/srs.pcm
|
||||
// It's captured using SDK callback method. I have filtered out h264 video, so it's audio only now.
|
||||
// For every frame, it's a 8 bytes vendor specific header, following 160 bytes audio frame.
|
||||
// The header part can be ignored.
|
||||
int read_audio_frame(char* audio_raw, int file_size, char** pp, char** pdata, int* psize)
|
||||
{
|
||||
char* p = *pp;
|
||||
|
||||
if (file_size - (p - audio_raw) < 168) {
|
||||
srs_human_trace("audio must be 160+8 bytes. left %d bytes.", (int)(file_size - (p - audio_raw)));
|
||||
return - 1;
|
||||
}
|
||||
|
||||
// ignore 8bytes vendor specific header.
|
||||
p += 8;
|
||||
|
||||
// 160 bytes audio frame
|
||||
*pdata = p;
|
||||
*psize = 160;
|
||||
|
||||
// next frame.
|
||||
*pp = p + *psize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("publish raw audio as rtmp stream to server like FMLE/FFMPEG/Encoder\n");
|
||||
printf("SRS(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("Usage: %s <audio_raw_file> <rtmp_publish_url>\n", argv[0]);
|
||||
printf(" audio_raw_file: the audio raw steam file.\n");
|
||||
printf(" rtmp_publish_url: the rtmp publish url.\n");
|
||||
printf("For example:\n");
|
||||
printf(" %s ./audio.raw.pcm rtmp://127.0.0.1:1935/live/livestream\n", argv[0]);
|
||||
printf("Where the file: http://winlinvip.github.io/srs.release/3rdparty/audio.raw.pcm\n");
|
||||
printf("See: https://github.com/ossrs/srs/issues/212\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const char* raw_file = argv[1];
|
||||
const char* rtmp_url = argv[2];
|
||||
srs_human_trace("raw_file=%s, rtmp_url=%s", raw_file, rtmp_url);
|
||||
|
||||
// open file
|
||||
int raw_fd = open(raw_file, O_RDONLY);
|
||||
if (raw_fd < 0) {
|
||||
srs_human_trace("open audio raw file %s failed.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
off_t file_size = lseek(raw_fd, 0, SEEK_END);
|
||||
if (file_size <= 0) {
|
||||
srs_human_trace("audio raw file %s empty.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("read entirely audio raw file, size=%dKB", (int)(file_size / 1024));
|
||||
|
||||
char* audio_raw = (char*)malloc(file_size);
|
||||
if (!audio_raw) {
|
||||
srs_human_trace("alloc raw buffer failed for file %s.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
lseek(raw_fd, 0, SEEK_SET);
|
||||
ssize_t nb_read = 0;
|
||||
if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) {
|
||||
srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.",
|
||||
raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// connect rtmp context
|
||||
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
|
||||
|
||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if (srs_rtmp_publish_stream(rtmp) != 0) {
|
||||
srs_human_trace("publish stream failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("publish stream success");
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
uint32_t time_delta = 17;
|
||||
// @remark, to decode the file.
|
||||
char* p = audio_raw;
|
||||
for (;p < audio_raw + file_size;) {
|
||||
// @remark, read a frame from file buffer.
|
||||
char* data = NULL;
|
||||
int size = 0;
|
||||
if (read_audio_frame(audio_raw, file_size, &p, &data, &size) < 0) {
|
||||
srs_human_trace("read a frame from file buffer failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// 0 = Linear PCM, platform endian
|
||||
// 1 = ADPCM
|
||||
// 2 = MP3
|
||||
// 7 = G.711 A-law logarithmic PCM
|
||||
// 8 = G.711 mu-law logarithmic PCM
|
||||
// 10 = AAC
|
||||
// 11 = Speex
|
||||
char sound_format = 1;
|
||||
// 3 = 44 kHz
|
||||
char sound_rate = 3;
|
||||
// 1 = 16-bit samples
|
||||
char sound_size = 1;
|
||||
// 1 = Stereo sound
|
||||
char sound_type = 1;
|
||||
|
||||
timestamp += time_delta;
|
||||
|
||||
if (srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp) != 0) {
|
||||
srs_human_trace("send audio raw data failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d",
|
||||
srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size,
|
||||
sound_type);
|
||||
|
||||
// @remark, when use encode device, it not need to sleep.
|
||||
usleep(1000 * time_delta);
|
||||
}
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
close(raw_fd);
|
||||
free(audio_raw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
// srs debug info.
|
||||
char* ip = NULL;
|
||||
char* sig = NULL;
|
||||
int pid = 0, cid = 0;
|
||||
int major = 0, minor = 0, revision= 0, build = 0;
|
||||
// bandwidth test data.
|
||||
int64_t start_time = 0;
|
||||
int64_t end_time = 0;
|
||||
int play_kbps = 0;
|
||||
int publish_kbps = 0;
|
||||
int play_bytes = 0;
|
||||
int publish_bytes = 0;
|
||||
int play_duration = 0;
|
||||
int publish_duration = 0;
|
||||
|
||||
int do_check(srs_rtmp_t rtmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = srs_rtmp_handshake(rtmp)) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if ((ret = srs_rtmp_connect_app(rtmp)) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if ((ret = srs_rtmp_get_server_sig(rtmp, &sig)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_id(rtmp, &ip, &pid, &cid)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_version(rtmp, &major, &minor, &revision, &build)) != 0) {
|
||||
srs_human_trace("Retrieve server version failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_bandwidth_check(rtmp,
|
||||
&start_time, &end_time, &play_kbps, &publish_kbps, &play_bytes, &publish_bytes,
|
||||
&play_duration, &publish_duration)) != 0
|
||||
) {
|
||||
srs_human_trace("bandwidth check/test failed.");
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("bandwidth check/test success");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
srs_rtmp_t rtmp;
|
||||
|
||||
printf("RTMP bandwidth check/test with server.\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("RTMP bandwidth check/test with server.\n"
|
||||
"Usage: %s <rtmp_url>\n"
|
||||
" rtmp_url RTMP bandwidth url to check. format: rtmp://server:port/app?key=xxx,vhost=xxx\n"
|
||||
"For example:\n"
|
||||
" %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com\n"
|
||||
" %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com>/dev/null\n"
|
||||
"@remark, output text to stdout, while json to stderr.\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
char url[512];
|
||||
snprintf(url, sizeof(url), "%s/%s", argv[1], "livestream");
|
||||
rtmp = srs_rtmp_create((const char*)url);
|
||||
srs_human_trace("bandwidth check/test url: %s", argv[1]);
|
||||
|
||||
if ((ret = do_check(rtmp)) != 0) {
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
srs_human_trace("\n%s, %s, %d.%d.%d.%d, srs_pid=%d, srs_id=%d\n"
|
||||
"duration: %dms(%d+%d), play: %dkbps, publish: %dkbps",
|
||||
(char*)sig, (char*)ip, major, minor, revision, build, pid, cid,
|
||||
(int)(end_time - start_time), play_duration, publish_duration, play_kbps, publish_kbps);
|
||||
|
||||
rtmp_destroy:
|
||||
fprintf(stderr, "{\"code\":%d,"
|
||||
"\"srs_server\":\"%s\", \"srs_primary\":\"\", \"srs_authors\":\"\", \"srs_server_ip\":\"%s\", "
|
||||
"\"srs_version\":\"%d.%d.%d.%d\", "
|
||||
"\"srs_pid\":%d, "
|
||||
"\"srs_id\":%d, "
|
||||
"\"duration\":%d, "
|
||||
"\"play_duration\":%d, "
|
||||
"\"publish_duration\":%d,"
|
||||
"\"play_kbps\":%d, "
|
||||
"\"publish_kbps\":%d"
|
||||
"}",
|
||||
ret,
|
||||
(char*)sig, (char*)ip,
|
||||
major, minor, revision, build, pid, cid,
|
||||
(int)(end_time - start_time), play_duration, publish_duration,
|
||||
play_kbps, publish_kbps);
|
||||
srs_rtmp_destroy(rtmp);
|
||||
|
||||
srs_human_trace(" ");
|
||||
srs_human_trace("completed");
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,239 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
srs_rtmp_t rtmp;
|
||||
|
||||
// time
|
||||
int64_t time_startup = srs_utils_time_ms();
|
||||
int64_t time_dns_resolve = 0;
|
||||
int64_t time_socket_connect = 0;
|
||||
int64_t time_play_stream = 0;
|
||||
int64_t time_first_packet = 0;
|
||||
int64_t time_cleanup = 0;
|
||||
// bytes
|
||||
int64_t bytes_nsend = 0;
|
||||
int time_duration = 0;
|
||||
int64_t bytes_nrecv = 0;
|
||||
|
||||
// packet data
|
||||
int size;
|
||||
char type;
|
||||
char* data;
|
||||
uint32_t timestamp;
|
||||
uint32_t basetime = 0;
|
||||
|
||||
// user options
|
||||
const char* rtmp_url = NULL;
|
||||
int duration = 0;
|
||||
int timeout = 0;
|
||||
enum srs_url_schema sus;
|
||||
|
||||
printf("detect rtmp stream\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 3) {
|
||||
printf("detect stream on RTMP server, print result to stderr.\n"
|
||||
"Usage: %s <rtmp_url> <duration> <timeout> [url_schema]\n"
|
||||
" rtmp_url RTMP stream url to play\n"
|
||||
" duration how long to play, in seconds, stream time.\n"
|
||||
" timeout how long to timeout, in seconds, system time.\n"
|
||||
" url_schema the schema of url, default to vis, can be:\n"
|
||||
" normal: rtmp://vhost:port/app/stream\n"
|
||||
" via : rtmp://ip:port/vhost/app/stream\n"
|
||||
" vis : rtmp://ip:port/app/stream?vhost=xxx\n"
|
||||
" vis2 : rtmp://ip:port/app/stream?domain=xxx\n"
|
||||
"For example:\n"
|
||||
" %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n",
|
||||
argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
rtmp_url = argv[1];
|
||||
duration = atoi(argv[2]);
|
||||
timeout = atoi(argv[3]);
|
||||
|
||||
if (1) {
|
||||
char *p = "vis";
|
||||
if (argc > 4) {
|
||||
p = argv[4];
|
||||
}
|
||||
|
||||
if (strcmp(p, "normal") == 0) {
|
||||
sus = srs_url_schema_normal;
|
||||
} else if (strcmp(p, "via") == 0) {
|
||||
sus = srs_url_schema_via;
|
||||
} else if (strcmp(p, "vis") == 0) {
|
||||
sus = srs_url_schema_vis;
|
||||
} else if (strcmp(p, "vis2") == 0){
|
||||
sus = srs_url_schema_vis2;
|
||||
} else {
|
||||
srs_human_trace("url_schema must be normal/via/vis/vis2");
|
||||
exit(-2);
|
||||
}
|
||||
srs_human_trace("url schema: %s", p);
|
||||
}
|
||||
|
||||
srs_human_trace("rtmp url: %s", rtmp_url);
|
||||
srs_human_trace("duration: %ds, timeout:%ds", duration, timeout);
|
||||
|
||||
if (duration <= 0 || timeout <= 0) {
|
||||
srs_human_trace("duration and timeout must be positive.");
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
if ((rtmp = srs_rtmp_create(rtmp_url)) == NULL) {
|
||||
srs_human_trace("create rtmp failed");
|
||||
ret = -1;
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
if ((ret = srs_rtmp_set_timeout(rtmp, timeout * 1000, timeout * 1000)) != 0) {
|
||||
srs_human_trace("set timeout for rtmp failed. errno=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_dns_resolve(rtmp)) != 0) {
|
||||
srs_human_trace("dns resolve failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("dns resolve success");
|
||||
time_dns_resolve = srs_utils_time_ms();
|
||||
|
||||
if ((ret = srs_rtmp_connect_server(rtmp)) != 0) {
|
||||
srs_human_trace("socket connect failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("socket connect success");
|
||||
time_socket_connect = srs_utils_time_ms();
|
||||
|
||||
if ((ret = srs_rtmp_do_simple_handshake(rtmp)) != 0) {
|
||||
srs_human_trace("do simple handshake failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("do simple handshake success");
|
||||
|
||||
if ((ret = srs_rtmp_set_schema(rtmp, sus)) != 0) {
|
||||
srs_human_trace("set url schema=%d failed, ret=%d", sus, ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_connect_app(rtmp)) != 0) {
|
||||
srs_human_trace("connect vhost/app failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if ((ret = srs_rtmp_play_stream(rtmp)) != 0) {
|
||||
srs_human_trace("play stream failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("play stream success");
|
||||
time_play_stream = srs_utils_time_ms();
|
||||
|
||||
for (;;) {
|
||||
if ((ret = srs_rtmp_read_packet(rtmp, &type, ×tamp, &data, &size)) != 0) {
|
||||
srs_human_trace("read packet failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("got packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size);
|
||||
|
||||
if (SRS_RTMP_TYPE_VIDEO == type || SRS_RTMP_TYPE_AUDIO == type) {
|
||||
if (time_first_packet <= 0) {
|
||||
time_first_packet = srs_utils_time_ms();
|
||||
}
|
||||
if (basetime <= 0) {
|
||||
basetime = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
if (srs_utils_time_ms() - time_startup > timeout * 1000) {
|
||||
srs_human_trace("timeout, terminate.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
if (timestamp > basetime && (timestamp - basetime) > duration * 1000) {
|
||||
srs_human_trace("duration exceed, terminate.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
rtmp_destroy:
|
||||
bytes_nsend = srs_utils_send_bytes(rtmp);
|
||||
bytes_nrecv = srs_utils_recv_bytes(rtmp);
|
||||
|
||||
srs_rtmp_destroy(rtmp);
|
||||
time_cleanup = srs_utils_time_ms();
|
||||
time_duration = (int)(time_cleanup - time_startup);
|
||||
|
||||
// print result to stderr.
|
||||
fprintf(stderr, "{"
|
||||
"\"%s\":%d, " //#0
|
||||
"\"%s\":%d, " //#1
|
||||
"\"%s\":%d, " // #2
|
||||
"\"%s\":%d, " // #3
|
||||
"\"%s\":%d, " // #4
|
||||
"\"%s\":%d, " // #5
|
||||
"\"%s\":%d, " // #6
|
||||
"\"%s\":%d, " // #7
|
||||
"\"%s\":%d, " // #8
|
||||
"\"%s\":%d, " // #9
|
||||
"\"%s\":%d, " // #10
|
||||
"%s,%s,%s,%s}",
|
||||
"code", ret, //#0
|
||||
// total = dns + tcp_connect + start_play + first_packet + last_packet
|
||||
"total", time_duration, //#1
|
||||
"dns", (int)(time_dns_resolve - time_startup), //#2
|
||||
"tcp_connect", (int)(time_socket_connect - time_dns_resolve), //#3
|
||||
"start_play", (int)(time_play_stream - time_socket_connect), //#4
|
||||
"first_packet", (int)(time_first_packet - time_play_stream), //#5
|
||||
"last_packet", (int)(time_cleanup - time_first_packet), //#6
|
||||
"stream", (int)(timestamp - basetime), //#7
|
||||
// expect = time_cleanup - time_first_packet
|
||||
// actual = stream
|
||||
// delay = actual - expect
|
||||
"delay", (int)(timestamp - basetime - (time_cleanup - time_first_packet)), //#8
|
||||
"publish_kbps", (int)((time_duration <= 0)? 0:(bytes_nsend * 8 / time_duration)), //#9
|
||||
"play_kbps", (int)((time_duration <= 0)? 0:(bytes_nrecv * 8 / time_duration)), //#10
|
||||
// unit in ms.
|
||||
"\"unit\": \"ms\"",
|
||||
"\"remark0\": \"total = dns + tcp_connect + start_play + first_packet + last_packet\"",
|
||||
"\"remark1\": \"delay = stream - (time_cleanup - time_first_packet)\"",
|
||||
"\"remark2\": \"if code is not 0, user must ignore all data\""
|
||||
);
|
||||
|
||||
srs_human_trace(" ");
|
||||
srs_human_trace("completed");
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,383 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
#define ERROR_INJECTED 10000
|
||||
|
||||
int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc);
|
||||
int build_keyframes(srs_flv_t ic, srs_amf0_t *pname, srs_amf0_t* pdata, srs_amf0_t* pfilepositions, int64_t* pmetadata_end_offset);
|
||||
int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t amf0_data, srs_amf0_t filepositions, int64_t metadata_end_offset);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// user options.
|
||||
char* in_flv_file;
|
||||
char* out_flv_file;
|
||||
// flv handler
|
||||
srs_flv_t ic = NULL;
|
||||
srs_flv_t oc = NULL;
|
||||
|
||||
// temp variables.
|
||||
int tmp_file_size = 0;
|
||||
char* tmp_file;
|
||||
|
||||
printf("inject flv file keyframes to metadata.\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("inject flv file keyframes to metadata\n"
|
||||
"Usage: %s in_flv_file out_flv_file\n"
|
||||
" in_flv_file input flv file to inject.\n"
|
||||
" out_flv_file the inject output file, can be in_flv_file.\n"
|
||||
"For example:\n"
|
||||
" %s doc/source.200kbps.768x320.flv injected.flv\n"
|
||||
" %s ../../doc/source.200kbps.768x320.flv injected.flv\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in_flv_file = argv[1];
|
||||
out_flv_file = argv[2];
|
||||
|
||||
tmp_file_size = strlen(out_flv_file) + strlen(".tmp") + 1;
|
||||
tmp_file = (char*)malloc(tmp_file_size);
|
||||
snprintf(tmp_file, tmp_file_size, "%s.tmp", out_flv_file);
|
||||
|
||||
srs_human_trace("input: %s", in_flv_file);
|
||||
srs_human_trace("output: %s", out_flv_file);
|
||||
srs_human_trace("tmp_file: %s", tmp_file);
|
||||
|
||||
ret = process(in_flv_file, tmp_file, &ic, &oc);
|
||||
|
||||
srs_flv_close(ic);
|
||||
srs_flv_close(oc);
|
||||
|
||||
if (ret != 0) {
|
||||
unlink(tmp_file);
|
||||
if (ret == ERROR_INJECTED) {
|
||||
ret = 0;
|
||||
srs_human_trace("file already injected.");
|
||||
} else {
|
||||
srs_human_trace("error, remove tmp file.");
|
||||
}
|
||||
} else {
|
||||
rename(tmp_file, out_flv_file);
|
||||
srs_human_trace("completed, rename to %s", out_flv_file);
|
||||
}
|
||||
|
||||
free(tmp_file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, srs_flv_t* poc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
srs_flv_t ic;
|
||||
srs_flv_t oc;
|
||||
|
||||
// to adjust metadata.
|
||||
// the ic metadata end offset, the next tag start offset.
|
||||
// all oc metadata must adjust according to:
|
||||
// adjust = new_metadata_end_offset - metadata_end_offset
|
||||
int64_t metadata_end_offset = 0;
|
||||
|
||||
// metadata
|
||||
srs_amf0_t amf0_name = NULL;
|
||||
srs_amf0_t amf0_data = NULL;
|
||||
srs_amf0_t filepositions = NULL;
|
||||
|
||||
if ((ic = srs_flv_open_read(in_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
srs_human_trace("open input flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
*pic = ic;
|
||||
|
||||
if ((oc = srs_flv_open_write(out_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
srs_human_trace("open output flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
*poc = oc;
|
||||
|
||||
/**
|
||||
* we use two roundtrip to avoid the paddings of metadata,
|
||||
* to support large keyframes videos without padding fields.
|
||||
*/
|
||||
// build keyframes offset to metadata.
|
||||
if ((ret = build_keyframes(ic, &amf0_name, &amf0_data, &filepositions, &metadata_end_offset)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// inject the metadata to oc.
|
||||
if ((ret = do_inject_flv(ic, oc, amf0_name, amf0_data, filepositions, metadata_end_offset)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
srs_amf0_free(amf0_name);
|
||||
srs_amf0_free(amf0_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parse_metadata(char* data, int size, srs_amf0_t* pname, srs_amf0_t* pdata)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
int nparsed = 0;
|
||||
*pname = srs_amf0_parse(data, size, &nparsed);
|
||||
|
||||
if (*pname == NULL || nparsed >= size) {
|
||||
srs_human_trace("invalid amf0 name data.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pdata = srs_amf0_parse(data + nparsed, size - nparsed, &nparsed);
|
||||
if (*pdata == NULL || nparsed > size) {
|
||||
srs_human_trace("invalid amf0 value data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int build_keyframes(srs_flv_t ic, srs_amf0_t *pname, srs_amf0_t* pdata, srs_amf0_t* pfilepositions, int64_t* pmetadata_end_offset)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// flv header
|
||||
char header[13];
|
||||
|
||||
// packet data
|
||||
char type;
|
||||
uint32_t timestamp = 0;
|
||||
char* data = NULL;
|
||||
int32_t size;
|
||||
int64_t offset = 0;
|
||||
|
||||
// metadata
|
||||
srs_amf0_t amf0_name = NULL;
|
||||
srs_amf0_t amf0_data = NULL;
|
||||
|
||||
srs_amf0_t keyframes = NULL;
|
||||
srs_amf0_t filepositions = NULL;
|
||||
srs_amf0_t times = NULL;
|
||||
|
||||
// reset to generate metadata
|
||||
srs_flv_lseek(ic, 0);
|
||||
|
||||
if ((ret = srs_flv_read_header(ic, header)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_human_trace("build keyframe infos from flv");
|
||||
for (;;) {
|
||||
offset = srs_flv_tellg(ic);
|
||||
|
||||
// tag header
|
||||
if ((ret = srs_flv_read_tag_header(ic, &type, &size, ×tamp)) != 0) {
|
||||
if (srs_flv_is_eof(ret)) {
|
||||
srs_human_trace("parse completed.");
|
||||
return 0;
|
||||
}
|
||||
srs_human_trace("flv get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
srs_human_trace("invalid size=%d", size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
data = (char*)malloc(size);
|
||||
if ((ret = srs_flv_read_tag_data(ic, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// data tag
|
||||
if (type == SRS_RTMP_TYPE_VIDEO) {
|
||||
if (!srs_flv_is_sequence_header(data, size) && srs_flv_is_keyframe(data, size)) {
|
||||
srs_amf0_strict_array_append(filepositions, srs_amf0_create_number(offset));
|
||||
srs_amf0_strict_array_append(times, srs_amf0_create_number(((double)timestamp)/ 1000));
|
||||
}
|
||||
} else if (type == SRS_RTMP_TYPE_SCRIPT) {
|
||||
*pmetadata_end_offset = srs_flv_tellg(ic);
|
||||
if ((ret = parse_metadata(data, size, &amf0_name, &amf0_data)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pname = amf0_name;
|
||||
*pdata = amf0_data;
|
||||
|
||||
if (srs_amf0_is_object(amf0_data)) {
|
||||
keyframes = srs_amf0_object_property(amf0_data, "keyframes");
|
||||
if (keyframes == NULL) {
|
||||
keyframes = srs_amf0_create_object();
|
||||
srs_amf0_object_property_set(amf0_data, "keyframes", keyframes);
|
||||
}
|
||||
// always clear the old keyframes.
|
||||
srs_amf0_object_clear(keyframes);
|
||||
|
||||
*pfilepositions = filepositions = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "filepositions", filepositions);
|
||||
|
||||
times = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "times", times);
|
||||
} else if (srs_amf0_is_ecma_array(amf0_data)) {
|
||||
keyframes = srs_amf0_ecma_array_property(amf0_data, "keyframes");
|
||||
if (keyframes == NULL) {
|
||||
keyframes = srs_amf0_create_object();
|
||||
srs_amf0_ecma_array_property_set(amf0_data, "keyframes", keyframes);
|
||||
}
|
||||
// always clear the old keyframes.
|
||||
srs_amf0_object_clear(keyframes);
|
||||
|
||||
*pfilepositions = filepositions = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "filepositions", filepositions);
|
||||
|
||||
times = srs_amf0_create_strict_array();
|
||||
srs_amf0_object_property_set(keyframes, "times", times);
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t amf0_data, srs_amf0_t filepositions, int64_t metadata_end_offset)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// flv header
|
||||
char header[13];
|
||||
// packet data
|
||||
char type;
|
||||
uint32_t timestamp = 0;
|
||||
char* data = NULL;
|
||||
int32_t size;
|
||||
|
||||
// metadata
|
||||
srs_amf0_t fileposition = NULL;
|
||||
int amf0_name_size = 0;
|
||||
int i;
|
||||
|
||||
// the metadata end offset, the next tag start offset.
|
||||
int64_t new_metadata_end_offset = 0;
|
||||
int offset_adjust = 0;
|
||||
|
||||
// reset to write injected file
|
||||
srs_flv_lseek(ic, 0);
|
||||
|
||||
if ((ret = srs_flv_read_header(ic, header)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_flv_write_header(oc, header)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// write metadata
|
||||
if (amf0_name != NULL && amf0_data != NULL) {
|
||||
amf0_name_size = srs_amf0_size(amf0_name);
|
||||
size = amf0_name_size + srs_amf0_size(amf0_data);
|
||||
|
||||
// adjust all offset of keyframes.
|
||||
new_metadata_end_offset = srs_flv_tellg(oc) + srs_flv_size_tag(size);
|
||||
// the adjust is new offset sub the old offset of metadata end.
|
||||
offset_adjust = new_metadata_end_offset - metadata_end_offset;
|
||||
for (i = 0; i < srs_amf0_strict_array_property_count(filepositions); i++) {
|
||||
fileposition = srs_amf0_strict_array_property_at(filepositions, i);
|
||||
srs_amf0_set_number(fileposition, srs_amf0_to_number(fileposition) + offset_adjust);
|
||||
}
|
||||
|
||||
data = (char*)malloc(size);
|
||||
memset(data, 0, size);
|
||||
if ((ret = srs_amf0_serialize(amf0_name, data, amf0_name_size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_amf0_serialize(amf0_data, data + amf0_name_size, size - amf0_name_size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_flv_write_tag(oc, SRS_RTMP_TYPE_SCRIPT, 0, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
srs_human_trace("build keyframe infos from flv");
|
||||
for (;;) {
|
||||
// tag header
|
||||
if ((ret = srs_flv_read_tag_header(ic, &type, &size, ×tamp)) != 0) {
|
||||
if (srs_flv_is_eof(ret)) {
|
||||
srs_human_trace("parse completed.");
|
||||
return 0;
|
||||
}
|
||||
srs_human_trace("flv get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
srs_human_trace("invalid size=%d", size);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
data = (char*)malloc(size);
|
||||
if ((ret = srs_flv_read_tag_data(ic, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// data tag
|
||||
if (type == SRS_RTMP_TYPE_SCRIPT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// copy
|
||||
if ((ret = srs_flv_write_tag(oc, type, timestamp, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int parse_flv(srs_flv_t flv);
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// user options.
|
||||
char* in_flv_file;
|
||||
// flv handler
|
||||
srs_flv_t flv;
|
||||
|
||||
printf("parse and show flv file detail.\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("parse and show flv file detail\n"
|
||||
"Usage: %s in_flv_file\n"
|
||||
" in_flv_file flv file to parse and show.\n"
|
||||
"For example:\n"
|
||||
" %s doc/source.200kbps.768x320.flv\n"
|
||||
" %s ../../doc/source.200kbps.768x320.flv\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
in_flv_file = argv[1];
|
||||
srs_human_trace("input: %s", in_flv_file);
|
||||
|
||||
if ((flv = srs_flv_open_read(in_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
srs_human_trace("open flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = parse_flv(flv);
|
||||
srs_flv_close(flv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void digit_to_char(char* src, int ssize, char* dst, int dsize)
|
||||
{
|
||||
int i, j;
|
||||
char v;
|
||||
|
||||
for (i = 0, j = 0; i < ssize && j < dsize; i++) {
|
||||
if (j >= dsize) {
|
||||
break;
|
||||
}
|
||||
v = (src[i] >> 4) & 0x0F;
|
||||
if (v < 10) {
|
||||
dst[j++] = '0' + v;
|
||||
} else {
|
||||
dst[j++] = 'A' + (v - 10);
|
||||
}
|
||||
|
||||
if (j >= dsize) {
|
||||
break;
|
||||
}
|
||||
v = src[i] & 0x0F;
|
||||
if (v < 10) {
|
||||
dst[j++] = '0' + v;
|
||||
} else {
|
||||
dst[j++] = 'A' + (v - 10);
|
||||
}
|
||||
|
||||
if (j >= dsize) {
|
||||
break;
|
||||
}
|
||||
if (i < ssize - 1) {
|
||||
dst[j++] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsize, int print_size)
|
||||
{
|
||||
memset(hbuf, 0, hsize);
|
||||
memset(tbuf, 0, tsize);
|
||||
|
||||
if (size > 0) {
|
||||
digit_to_char(data, size, hbuf, hsize - 1);
|
||||
}
|
||||
|
||||
if (size > print_size * 2) {
|
||||
digit_to_char(data + size - print_size, size, tbuf, tsize - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_flv(srs_flv_t flv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// flv header
|
||||
char header[13];
|
||||
// packet data
|
||||
char type;
|
||||
uint32_t timestamp = 0;
|
||||
char* data = NULL;
|
||||
int32_t size;
|
||||
int64_t offset = 0;
|
||||
|
||||
if ((ret = srs_flv_read_header(flv, header)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_human_trace("start parse flv");
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
offset = srs_flv_tellg(flv);
|
||||
|
||||
// tag header
|
||||
if ((ret = srs_flv_read_tag_header(flv, &type, &size, ×tamp)) != 0) {
|
||||
if (srs_flv_is_eof(ret)) {
|
||||
srs_human_trace("parse completed.");
|
||||
return 0;
|
||||
}
|
||||
srs_human_trace("flv get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
srs_human_trace("invalid size=%d", size);
|
||||
break;
|
||||
}
|
||||
|
||||
data = (char*)malloc(size);
|
||||
|
||||
if ((ret = srs_flv_read_tag_data(flv, data, size)) == 0) {
|
||||
if ((ret = srs_human_format_rtmp_packet(buffer, sizeof(buffer), type, timestamp, data, size)) == 0) {
|
||||
srs_human_trace("%s", buffer);
|
||||
|
||||
char hbuf[48]; char tbuf[48];
|
||||
parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16);
|
||||
srs_human_raw("offset=%d, first and last 16 bytes:\n[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf);
|
||||
} else {
|
||||
srs_human_trace("print packet failed. ret=%d", ret);
|
||||
}
|
||||
} else {
|
||||
srs_human_trace("read flv failed. ret=%d", ret);
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
if (ret != 0) {
|
||||
srs_human_trace("parse failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// for open h264 raw file.
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps,
|
||||
char** frame, int* frame_size, int* dts, int* pts)
|
||||
{
|
||||
char* p = *pp;
|
||||
|
||||
// @remark, for this demo, to publish h264 raw file to SRS,
|
||||
// we search the h264 frame from the buffer which cached the h264 data.
|
||||
// please get h264 raw data from device, it always a encoded frame.
|
||||
if (!srs_h264_startswith_annexb(p, size - (p - data), pnb_start_code)) {
|
||||
srs_human_trace("h264 raw data invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @see srs_write_h264_raw_frames
|
||||
// each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0,
|
||||
// for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40)
|
||||
*frame = p;
|
||||
p += *pnb_start_code;
|
||||
|
||||
for (;p < data + size; p++) {
|
||||
if (srs_h264_startswith_annexb(p, size - (p - data), NULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*pp = p;
|
||||
*frame_size = p - *frame;
|
||||
if (*frame_size <= 0) {
|
||||
srs_human_trace("h264 raw data invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// @remark, please get the dts and pts from device,
|
||||
// we assume there is no B frame, and the fps can guess the fps and dts,
|
||||
// while the dts and pts must read from encode lib or device.
|
||||
*dts += 1000 / fps;
|
||||
*pts = *dts;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("publish raw h.264 as rtmp stream to server like FMLE/FFMPEG/Encoder\n");
|
||||
printf("SRS(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 3) {
|
||||
printf("Usage: %s <h264_raw_file> <rtmp_publish_url> <fps>\n", argv[0]);
|
||||
printf(" h264_raw_file: the h264 raw steam file.\n");
|
||||
printf(" rtmp_publish_url: the rtmp publish url.\n");
|
||||
printf(" fps: the video average fps, for example, 25.\n");
|
||||
printf("For example:\n");
|
||||
printf(" %s ./720p.h264.raw rtmp://127.0.0.1:1935/live/livestream 25\n", argv[0]);
|
||||
printf("Where the file: http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw\n");
|
||||
printf(" See: https://github.com/ossrs/srs/issues/66\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const char* raw_file = argv[1];
|
||||
const char* rtmp_url = argv[2];
|
||||
// @remark, the dts and pts if read from device, for instance, the encode lib,
|
||||
// so we assume the fps is 25, and each h264 frame is 1000ms/25fps=40ms/f.
|
||||
double fps = atof(argv[3]);
|
||||
srs_human_trace("raw_file=%s, rtmp_url=%s, fps=%.2f", raw_file, rtmp_url, fps);
|
||||
|
||||
// open file
|
||||
int raw_fd = open(raw_file, O_RDONLY);
|
||||
if (raw_fd < 0) {
|
||||
srs_human_trace("open h264 raw file %s failed.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
off_t file_size = lseek(raw_fd, 0, SEEK_END);
|
||||
if (file_size <= 0) {
|
||||
srs_human_trace("h264 raw file %s empty.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("read entirely h264 raw file, size=%dKB", (int)(file_size / 1024));
|
||||
|
||||
char* h264_raw = (char*)malloc(file_size);
|
||||
if (!h264_raw) {
|
||||
srs_human_trace("alloc raw buffer failed for file %s.", raw_file);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
lseek(raw_fd, 0, SEEK_SET);
|
||||
ssize_t nb_read = 0;
|
||||
if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) {
|
||||
srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.",
|
||||
raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// connect rtmp context
|
||||
srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url);
|
||||
|
||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if (srs_rtmp_publish_stream(rtmp) != 0) {
|
||||
srs_human_trace("publish stream failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("publish stream success");
|
||||
|
||||
int dts = 0;
|
||||
int pts = 0;
|
||||
// @remark, to decode the file.
|
||||
char* p = h264_raw;
|
||||
int count = 0;
|
||||
for (; p < h264_raw + file_size;) {
|
||||
// @remark, read a frame from file buffer.
|
||||
char* data = NULL;
|
||||
int size = 0;
|
||||
int nb_start_code = 0;
|
||||
if (read_h264_frame(h264_raw, (int)file_size, &p, &nb_start_code, fps, &data, &size, &dts, &pts) < 0) {
|
||||
srs_human_trace("read a frame from file buffer failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
// send out the h264 packet over RTMP
|
||||
int ret = srs_h264_write_raw_frames(rtmp, data, size, dts, pts);
|
||||
if (ret != 0) {
|
||||
if (srs_h264_is_dvbsp_error(ret)) {
|
||||
srs_human_trace("ignore drop video error, code=%d", ret);
|
||||
} else if (srs_h264_is_duplicated_sps_error(ret)) {
|
||||
srs_human_trace("ignore duplicated sps, code=%d", ret);
|
||||
} else if (srs_h264_is_duplicated_pps_error(ret)) {
|
||||
srs_human_trace("ignore duplicated pps, code=%d", ret);
|
||||
} else {
|
||||
srs_human_trace("send h264 raw data failed. ret=%d", ret);
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
// 5bits, 7.3.1 NAL unit syntax,
|
||||
// ISO_IEC_14496-10-AVC-2003.pdf, page 44.
|
||||
// 7: SPS, 8: PPS, 5: I Frame, 1: P Frame, 9: AUD, 6: SEI
|
||||
uint8_t nut = (char)data[nb_start_code] & 0x1f;
|
||||
srs_human_trace("sent packet: type=%s, time=%d, size=%d, fps=%.2f, b[%d]=%#x(%s)",
|
||||
srs_human_flv_tag_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, nb_start_code, (char)data[nb_start_code],
|
||||
(nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":(nut == 9? "AUD":(nut == 6? "SEI":"Unknown")))))));
|
||||
|
||||
// @remark, when use encode device, it not need to sleep.
|
||||
if (count++ == 9) {
|
||||
usleep(1000 * 1000 * count / fps);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
srs_human_trace("h264 raw data completed");
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
close(raw_fd);
|
||||
free(h264_raw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,273 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int proxy(srs_flv_t flv, srs_rtmp_t ortmp);
|
||||
int connect_oc(srs_rtmp_t ortmp);
|
||||
|
||||
#define RE_PULSE_MS 300
|
||||
#define RE_PULSE_JITTER_MS 3000
|
||||
int64_t re_create();
|
||||
void re_update(int64_t re, int32_t starttime, uint32_t time);
|
||||
void re_cleanup(int64_t re, int32_t starttime, uint32_t time);
|
||||
|
||||
int64_t tools_main_entrance_startup_time;
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// main function
|
||||
tools_main_entrance_startup_time = srs_utils_time_ms();
|
||||
|
||||
// user option parse index.
|
||||
int opt = 0;
|
||||
// user options.
|
||||
char* in_flv_file = NULL;
|
||||
char* out_rtmp_url = NULL;
|
||||
// rtmp handler
|
||||
srs_rtmp_t ortmp;
|
||||
// flv handler
|
||||
srs_flv_t flv;
|
||||
|
||||
printf("ingest flv file and publish to RTMP server like FFMPEG.\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("ingest flv file and publish to RTMP server\n"
|
||||
"Usage: %s <-i in_flv_file> <-y out_rtmp_url>\n"
|
||||
" in_flv_file input flv file, ingest from this file.\n"
|
||||
" out_rtmp_url output rtmp url, publish to this url.\n"
|
||||
"For example:\n"
|
||||
" %s -i doc/source.200kbps.768x320.flv -y rtmp://127.0.0.1/live/livestream\n"
|
||||
" %s -i ../../doc/source.200kbps.768x320.flv -y rtmp://127.0.0.1/live/livestream\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
for (opt = 0; opt < argc; opt++) {
|
||||
srs_human_trace("argv[%d]=%s", opt, argv[opt]);
|
||||
}
|
||||
|
||||
// fill the options for mac
|
||||
for (opt = 0; opt < argc - 1; opt++) {
|
||||
// ignore all options except -i and -y.
|
||||
char* p = argv[opt];
|
||||
|
||||
// only accept -x
|
||||
if (p[0] != '-' || p[1] == 0 || p[2] != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse according the option name.
|
||||
switch (p[1]) {
|
||||
case 'i': in_flv_file = argv[opt + 1]; break;
|
||||
case 'y': out_rtmp_url = argv[opt + 1]; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_flv_file) {
|
||||
srs_human_trace("input invalid, use -i <input>");
|
||||
return -1;
|
||||
}
|
||||
if (!out_rtmp_url) {
|
||||
srs_human_trace("output invalid, use -y <output>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
srs_human_trace("input: %s", in_flv_file);
|
||||
srs_human_trace("output: %s", out_rtmp_url);
|
||||
|
||||
if ((flv = srs_flv_open_read(in_flv_file)) == NULL) {
|
||||
ret = 2;
|
||||
srs_human_trace("open flv file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ortmp = srs_rtmp_create(out_rtmp_url);
|
||||
|
||||
ret = proxy(flv, ortmp);
|
||||
srs_human_trace("ingest flv to RTMP completed");
|
||||
|
||||
srs_rtmp_destroy(ortmp);
|
||||
srs_flv_close(flv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, uint32_t* ptimestamp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// packet data
|
||||
char type;
|
||||
int size;
|
||||
char* data = NULL;
|
||||
|
||||
srs_human_trace("start ingest flv to RTMP stream");
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
// tag header
|
||||
if ((ret = srs_flv_read_tag_header(flv, &type, &size, ptimestamp)) != 0) {
|
||||
if (srs_flv_is_eof(ret)) {
|
||||
srs_human_trace("parse completed.");
|
||||
return 0;
|
||||
}
|
||||
srs_human_trace("flv get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
srs_human_trace("invalid size=%d", size);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: FIXME: mem leak when error.
|
||||
data = (char*)malloc(size);
|
||||
if ((ret = srs_flv_read_tag_data(flv, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t timestamp = *ptimestamp;
|
||||
|
||||
if ((ret = srs_human_format_rtmp_packet(buffer, sizeof(buffer), type, timestamp, data, size)) != 0) {
|
||||
srs_human_trace("print packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("%s", buffer);
|
||||
|
||||
if ((ret = srs_rtmp_write_packet(ortmp, type, *ptimestamp, data, size)) != 0) {
|
||||
srs_human_trace("irtmp get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) {
|
||||
*pstarttime = *ptimestamp;
|
||||
}
|
||||
|
||||
re_update(re, *pstarttime, *ptimestamp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int proxy(srs_flv_t flv, srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t timestamp = 0;
|
||||
int32_t starttime = -1;
|
||||
|
||||
char header[13];
|
||||
if ((ret = srs_flv_read_header(flv, header)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = connect_oc(ortmp)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t re = re_create();
|
||||
|
||||
ret = do_proxy(flv, ortmp, re, &starttime, ×tamp);
|
||||
|
||||
// for the last pulse, always sleep.
|
||||
re_cleanup(re, starttime, timestamp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int connect_oc(srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = srs_rtmp_handshake(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp simple handshake failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp simple handshake success");
|
||||
|
||||
if ((ret = srs_rtmp_connect_app(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp connect vhost/app failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp connect vhost/app success");
|
||||
|
||||
if ((ret = srs_rtmp_publish_stream(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp publish stream failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp publish stream success");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t re_create()
|
||||
{
|
||||
// if not very precise, we can directly use this as re.
|
||||
int64_t re = srs_utils_time_ms();
|
||||
|
||||
// use the starttime to get the deviation
|
||||
int64_t deviation = re - tools_main_entrance_startup_time;
|
||||
srs_human_trace("deviation is %d ms, pulse is %d ms", (int)(deviation), (int)(RE_PULSE_MS));
|
||||
|
||||
// so, we adjust time to max(0, deviation)
|
||||
// because the last pulse, we already sleeped
|
||||
int adjust = (int)(deviation);
|
||||
if (adjust > 0) {
|
||||
srs_human_trace("adjust re time for %d ms", adjust);
|
||||
re -= adjust;
|
||||
} else {
|
||||
srs_human_trace("no need to adjust re time");
|
||||
}
|
||||
|
||||
return re;
|
||||
}
|
||||
void re_update(int64_t re, int32_t starttime, uint32_t time)
|
||||
{
|
||||
// send by pulse algorithm.
|
||||
int64_t now = srs_utils_time_ms();
|
||||
int64_t diff = time - starttime - (now -re);
|
||||
if (diff > RE_PULSE_MS && diff < RE_PULSE_JITTER_MS) {
|
||||
usleep((useconds_t)(diff * 1000));
|
||||
}
|
||||
}
|
||||
void re_cleanup(int64_t re, int32_t starttime, uint32_t time)
|
||||
{
|
||||
// for the last pulse, always sleep.
|
||||
// for the virtual live encoder long time publishing.
|
||||
int64_t now = srs_utils_time_ms();
|
||||
int64_t diff = time - starttime - (now -re);
|
||||
if (diff > 0) {
|
||||
srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", (int)diff, starttime, time);
|
||||
usleep((useconds_t)(diff * 1000));
|
||||
}
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int64_t tools_main_entrance_startup_time;
|
||||
int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp);
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// main function
|
||||
tools_main_entrance_startup_time = srs_utils_time_ms();
|
||||
|
||||
printf("Ingest mp4 file and publish to RTMP server like FFMPEG.\n");
|
||||
printf("SRS(OSSRS) client librtmp library.\n");
|
||||
printf("Version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("Ingest mp4 file and publish to RTMP server\n"
|
||||
"Usage: %s <-i in_mp4_file> <-y out_rtmp_url>\n"
|
||||
" in_mp4_file input mp4 file, ingest from this file.\n"
|
||||
" out_rtmp_url output rtmp url, publish to this url.\n"
|
||||
"@remark Only support non-seek mp4, see https://github.com/ossrs/srs/issues/738#issuecomment-276343669\n"
|
||||
"For example:\n"
|
||||
" %s -i avatar.mp4 -y rtmp://127.0.0.1/live/livestream\n",
|
||||
argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int opt;
|
||||
for (opt = 0; opt < argc; opt++) {
|
||||
srs_human_trace("The argv[%d]=%s", opt, argv[opt]);
|
||||
}
|
||||
|
||||
// fill the options for mac
|
||||
char* in_file = NULL;
|
||||
char* out_rtmp_url = NULL;
|
||||
for (opt = 0; opt < argc - 1; opt++) {
|
||||
// ignore all options except -i and -y.
|
||||
char* p = argv[opt];
|
||||
|
||||
// only accept -x
|
||||
if (p[0] != '-' || p[1] == 0 || p[2] != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse according the option name.
|
||||
switch (p[1]) {
|
||||
case 'i': in_file = argv[opt + 1]; break;
|
||||
case 'y': out_rtmp_url = argv[opt + 1]; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_file) {
|
||||
srs_human_trace("Invalid input file, use -i <input>");
|
||||
return -1;
|
||||
}
|
||||
if (!out_rtmp_url) {
|
||||
srs_human_trace("Invalid output url, use -y <output>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
srs_human_trace("Input file: %s", in_file);
|
||||
srs_human_trace("Output url: %s", out_rtmp_url);
|
||||
|
||||
int ret = 0;
|
||||
|
||||
srs_mp4_t mp4 = NULL;
|
||||
if ((mp4 = srs_mp4_open_read(in_file)) == NULL) {
|
||||
ret = 2;
|
||||
srs_human_trace("open mp4 file failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_rtmp_t ortmp = srs_rtmp_create(out_rtmp_url);
|
||||
|
||||
ret = proxy(mp4, ortmp);
|
||||
srs_human_trace("Ingest mp4 to RTMP ok.");
|
||||
|
||||
srs_rtmp_destroy(ortmp);
|
||||
srs_mp4_close(mp4);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int connect_oc(srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = srs_rtmp_handshake(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp simple handshake failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp simple handshake success");
|
||||
|
||||
if ((ret = srs_rtmp_connect_app(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp connect vhost/app failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp connect vhost/app success");
|
||||
|
||||
if ((ret = srs_rtmp_publish_stream(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp publish stream failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp publish stream success");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RE_PULSE_MS 300
|
||||
#define RE_PULSE_JITTER_MS 3000
|
||||
|
||||
int64_t re_create()
|
||||
{
|
||||
// if not very precise, we can directly use this as re.
|
||||
int64_t re = srs_utils_time_ms();
|
||||
|
||||
// use the starttime to get the deviation
|
||||
int64_t deviation = re - tools_main_entrance_startup_time;
|
||||
srs_human_trace("deviation is %d ms, pulse is %d ms", (int)(deviation), (int)(RE_PULSE_MS));
|
||||
|
||||
// so, we adjust time to max(0, deviation)
|
||||
// because the last pulse, we already sleeped
|
||||
int adjust = (int)(deviation);
|
||||
if (adjust > 0) {
|
||||
srs_human_trace("adjust re time for %d ms", adjust);
|
||||
re -= adjust;
|
||||
} else {
|
||||
srs_human_trace("no need to adjust re time");
|
||||
}
|
||||
|
||||
return re;
|
||||
}
|
||||
|
||||
void re_update(int64_t re, int32_t starttime, uint32_t time)
|
||||
{
|
||||
// send by pulse algorithm.
|
||||
int64_t now = srs_utils_time_ms();
|
||||
int64_t diff = time - starttime - (now -re);
|
||||
if (diff > RE_PULSE_MS && diff < RE_PULSE_JITTER_MS) {
|
||||
usleep((useconds_t)(diff * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
void re_cleanup(int64_t re, int32_t starttime, uint32_t time)
|
||||
{
|
||||
// for the last pulse, always sleep.
|
||||
// for the virtual live encoder long time publishing.
|
||||
int64_t now = srs_utils_time_ms();
|
||||
int64_t diff = time - starttime - (now -re);
|
||||
if (diff > 0) {
|
||||
srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms",
|
||||
(int)diff, starttime, time);
|
||||
usleep((useconds_t)(diff * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
int do_proxy(srs_mp4_t mp4, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, uint32_t* ptimestamp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
srs_human_trace("start ingest mp4 to RTMP stream");
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
// packet data
|
||||
char type;
|
||||
int32_t size;
|
||||
char* data = NULL;
|
||||
|
||||
// Read a mp4 sample and convert to flv tag.
|
||||
if (1) {
|
||||
srs_mp4_sample_t sample;
|
||||
if ((ret = srs_mp4_read_sample(mp4, &sample)) != 0) {
|
||||
if (srs_mp4_is_eof(ret)) {
|
||||
srs_human_trace("parse completed.");
|
||||
return 0;
|
||||
}
|
||||
srs_human_trace("mp4 get sample failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size = srs_mp4_sizeof(mp4, &sample);
|
||||
data = (char*)malloc(size);
|
||||
|
||||
if ((ret = srs_mp4_to_flv_tag(mp4, &sample, &type, ptimestamp, data, size)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_mp4_free_sample(&sample);
|
||||
}
|
||||
uint32_t timestamp = *ptimestamp;
|
||||
|
||||
if ((ret = srs_human_format_rtmp_packet(buffer, sizeof(buffer), type, timestamp, data, size)) != 0) {
|
||||
srs_human_trace("print packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("%s", buffer);
|
||||
|
||||
if ((ret = srs_rtmp_write_packet(ortmp, type, *ptimestamp, data, size)) != 0) {
|
||||
srs_human_trace("irtmp get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) {
|
||||
*pstarttime = *ptimestamp;
|
||||
}
|
||||
|
||||
re_update(re, *pstarttime, *ptimestamp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int proxy(srs_mp4_t mp4, srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = srs_mp4_init_demuxer(mp4)) != 0) {
|
||||
srs_human_trace("init demuxer failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = connect_oc(ortmp)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t re = re_create();
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
int32_t starttime = -1;
|
||||
ret = do_proxy(mp4, ortmp, re, &starttime, ×tamp);
|
||||
|
||||
// for the last pulse, always sleep.
|
||||
re_cleanup(re, starttime, timestamp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,279 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int connect_ic(srs_rtmp_t irtmp);
|
||||
int connect_oc(srs_rtmp_t ortmp);
|
||||
int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp);
|
||||
|
||||
// whether use verbose log.
|
||||
int verbose = 0;
|
||||
// 2000 is about 30s.
|
||||
#define PITHY_PRINT_EVERY_MSGS 2000
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// user option parse index.
|
||||
int opt = 0;
|
||||
// user options.
|
||||
char* in_rtmp_url = NULL;
|
||||
char* out_rtmp_url = NULL;
|
||||
// rtmp handler
|
||||
srs_rtmp_t irtmp, ortmp;
|
||||
|
||||
printf("Ingest RTMP to server like FFMPEG over srs-librtmp %d.%d.%d\n",
|
||||
srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 2) {
|
||||
printf("ingest RTMP and publish to RTMP server\n"
|
||||
"Usage: %s <-i in_rtmp_url> <-y out_rtmp_url> [-v verbose]\n"
|
||||
" in_rtmp_url input rtmp url, ingest from this url.\n"
|
||||
" out_rtmp_url output rtmp url, publish to this url.\n"
|
||||
" verbose output verbose log.\n"
|
||||
"For example:\n"
|
||||
" %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo\n"
|
||||
" %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo -v verbose\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// fill the options for mac
|
||||
for (opt = 0; opt < argc - 1; opt++) {
|
||||
// ignore all options except -i and -y.
|
||||
char* p = argv[opt];
|
||||
|
||||
// only accept -x
|
||||
if (p[0] != '-' || p[1] == 0 || p[2] != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse according the option name.
|
||||
switch (p[1]) {
|
||||
case 'i': in_rtmp_url = argv[++opt]; break;
|
||||
case 'y': out_rtmp_url = argv[++opt]; break;
|
||||
case 'v': verbose=1; opt++; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_rtmp_url) {
|
||||
srs_human_trace("input invalid, use -i <input>");
|
||||
return -1;
|
||||
}
|
||||
if (!out_rtmp_url) {
|
||||
srs_human_trace("output invalid, use -y <output>");
|
||||
return -1;
|
||||
}
|
||||
|
||||
srs_human_trace("ingest %s to %s, verbose=%d", in_rtmp_url, out_rtmp_url, verbose);
|
||||
|
||||
irtmp = srs_rtmp_create(in_rtmp_url);
|
||||
ortmp = srs_rtmp_create(out_rtmp_url);
|
||||
|
||||
ret = proxy(irtmp, ortmp);
|
||||
srs_human_trace("proxy completed");
|
||||
|
||||
srs_rtmp_destroy(irtmp);
|
||||
srs_rtmp_destroy(ortmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// packet data
|
||||
int size;
|
||||
char type;
|
||||
char* data;
|
||||
uint32_t timestamp;
|
||||
uint64_t nb_msgs = 0;
|
||||
|
||||
if ((ret = connect_ic(irtmp)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = connect_oc(ortmp)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
srs_human_trace("start proxy RTMP stream");
|
||||
} else {
|
||||
srs_human_verbose("start proxy RTMP stream");
|
||||
}
|
||||
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
if ((ret = srs_rtmp_read_packet(irtmp, &type, ×tamp, &data, &size)) != 0) {
|
||||
srs_human_trace("irtmp get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!srs_utils_flv_tag_is_ok(type)) {
|
||||
if (verbose) {
|
||||
srs_human_trace("ignore invalid flv tag=%d, dts=%d, %d bytes", type, timestamp, size);
|
||||
} else {
|
||||
srs_human_verbose("ignore invalid flv tag=%d, dts=%d, %d bytes", type, timestamp, size);
|
||||
}
|
||||
free(data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose || ((nb_msgs++ % PITHY_PRINT_EVERY_MSGS) == 0 && nb_msgs > 10)) {
|
||||
if ((ret = srs_human_format_rtmp_packet(buffer, sizeof(buffer), type, timestamp, data, size)) != 0) {
|
||||
srs_human_trace("print packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("%s", buffer);
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_write_packet(ortmp, type, timestamp, data, size)) != 0) {
|
||||
srs_human_trace("irtmp get packet failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
srs_human_trace("ortmp sent packet: type=%s, time=%d, size=%d",
|
||||
srs_human_flv_tag_type2string(type), timestamp, size);
|
||||
} else {
|
||||
srs_human_verbose("ortmp sent packet: type=%s, time=%d, size=%d",
|
||||
srs_human_flv_tag_type2string(type), timestamp, size);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int connect_ic(srs_rtmp_t irtmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// srs debug info.
|
||||
char* ip = NULL;
|
||||
char* sig = NULL;
|
||||
int pid = 0, cid = 0;
|
||||
int major = 0, minor = 0, revision= 0, build = 0;
|
||||
|
||||
if ((ret = srs_rtmp_handshake(irtmp)) != 0) {
|
||||
srs_human_trace("irtmp simple handshake failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (verbose) {
|
||||
srs_human_trace("irtmp simple handshake success");
|
||||
} else {
|
||||
srs_human_verbose("irtmp simple handshake success");
|
||||
}
|
||||
|
||||
if (srs_rtmp_connect_app(irtmp) != 0) {
|
||||
srs_human_trace("irtmp connect vhost/app failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_get_server_sig(irtmp, &sig)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_id(irtmp, &ip, &pid, &cid)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_version(irtmp, &major, &minor, &revision, &build)) != 0) {
|
||||
srs_human_trace("Retrieve server version failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("irtmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d",
|
||||
ip, sig, major, minor, revision, build, pid, cid);
|
||||
|
||||
if ((ret = srs_rtmp_play_stream(irtmp)) != 0) {
|
||||
srs_human_trace("irtmp play stream failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (verbose) {
|
||||
srs_human_trace("irtmp play stream success");
|
||||
} else {
|
||||
srs_human_verbose("irtmp play stream success");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int connect_oc(srs_rtmp_t ortmp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// srs debug info.
|
||||
char* ip = NULL;
|
||||
char* sig = NULL;
|
||||
int pid = 0, cid = 0;
|
||||
int major = 0, minor = 0, revision= 0, build = 0;
|
||||
|
||||
if ((ret = srs_rtmp_handshake(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp simple handshake failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (verbose) {
|
||||
srs_human_trace("ortmp simple handshake success");
|
||||
} else {
|
||||
srs_human_verbose("ortmp simple handshake success");
|
||||
}
|
||||
|
||||
if (srs_rtmp_connect_app(ortmp) != 0) {
|
||||
srs_human_trace("ortmp connect vhost/app failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_get_server_sig(ortmp, &sig)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_id(ortmp, &ip, &pid, &cid)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_version(ortmp, &major, &minor, &revision, &build)) != 0) {
|
||||
srs_human_trace("Retrieve server version failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("ortmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d",
|
||||
ip, sig, major, minor, revision, build, pid, cid);
|
||||
|
||||
if ((ret = srs_rtmp_publish_stream(ortmp)) != 0) {
|
||||
srs_human_trace("ortmp publish stream failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (verbose) {
|
||||
srs_human_trace("ortmp publish stream success");
|
||||
} else {
|
||||
srs_human_verbose("ortmp publish stream success");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("suck rtmp stream like rtmpdump\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("Usage: %s <rtmp_url>\n"
|
||||
" rtmp_url RTMP stream url to play\n"
|
||||
"For example:\n"
|
||||
" %s rtmp://127.0.0.1:1935/live/livestream\n",
|
||||
argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
srs_human_trace("rtmp url: %s", argv[1]);
|
||||
srs_rtmp_t rtmp = srs_rtmp_create(argv[1]);
|
||||
|
||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if (srs_rtmp_play_stream(rtmp) != 0) {
|
||||
srs_human_trace("play stream failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("play stream success");
|
||||
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
int size;
|
||||
char type;
|
||||
char* data;
|
||||
uint32_t timestamp;
|
||||
|
||||
if (srs_rtmp_read_packet(rtmp, &type, ×tamp, &data, &size) != 0) {
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
|
||||
if (srs_human_format_rtmp_packet(buffer, sizeof(buffer), type, timestamp, data, size) != 0) {
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("%s", buffer);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("publish rtmp stream to server like FMLE/FFMPEG/Encoder\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("Usage: %s <rtmp_url>\n"
|
||||
" rtmp_url RTMP stream url to publish\n"
|
||||
"For example:\n"
|
||||
" %s rtmp://127.0.0.1:1935/live/livestream\n",
|
||||
argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// warn it .
|
||||
// @see: https://github.com/ossrs/srs/issues/126
|
||||
srs_human_trace("\033[33m%s\033[0m",
|
||||
"[warning] it's only a sample to use librtmp. "
|
||||
"please never use it to publish and test forward/transcode/edge/HLS whatever. "
|
||||
"you should refer to this tool to use the srs-librtmp to publish the real media stream."
|
||||
"read about: https://github.com/ossrs/srs/issues/126");
|
||||
srs_human_trace("rtmp url: %s", argv[1]);
|
||||
srs_rtmp_t rtmp = srs_rtmp_create(argv[1]);
|
||||
|
||||
if (srs_rtmp_handshake(rtmp) != 0) {
|
||||
srs_human_trace("simple handshake failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("simple handshake success");
|
||||
|
||||
if (srs_rtmp_connect_app(rtmp) != 0) {
|
||||
srs_human_trace("connect vhost/app failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("connect vhost/app success");
|
||||
|
||||
if (srs_rtmp_publish_stream(rtmp) != 0) {
|
||||
srs_human_trace("publish stream failed.");
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("publish stream success");
|
||||
|
||||
uint32_t timestamp = 0;
|
||||
for (;;) {
|
||||
char type = SRS_RTMP_TYPE_VIDEO;
|
||||
int size = 4096;
|
||||
char* data = (char*)malloc(4096);
|
||||
|
||||
timestamp += 40;
|
||||
|
||||
if (srs_rtmp_write_packet(rtmp, type, timestamp, data, size) != 0) {
|
||||
goto rtmp_destroy;
|
||||
}
|
||||
srs_human_trace("sent packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size);
|
||||
|
||||
usleep(40 * 1000);
|
||||
}
|
||||
|
||||
rtmp_destroy:
|
||||
srs_rtmp_destroy(rtmp);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,350 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2018 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../../objs/include/srs_librtmp.h"
|
||||
|
||||
void parse_amf0_object(char* p, srs_amf0_t args)
|
||||
{
|
||||
char opvt = 0; // object property value type.
|
||||
const char* opnp = NULL; // object property name ptr.
|
||||
const char* opvp = NULL; // object property value ptr.
|
||||
|
||||
while (*p) {
|
||||
switch (*p++) {
|
||||
case 'O':
|
||||
while (*p && *p++ != ':') {
|
||||
}
|
||||
if (*p++ == '1') {
|
||||
printf("amf0 object start\n");
|
||||
} else {
|
||||
printf("amf0 object end\n");
|
||||
}
|
||||
break;
|
||||
case 'N':
|
||||
opvt = *p++;
|
||||
if (*p++ != ':') {
|
||||
printf("object property must split by :.\n");
|
||||
exit(-1);
|
||||
}
|
||||
opnp = p++;
|
||||
while (*p && *p++ != ':') {
|
||||
}
|
||||
p[-1] = 0;
|
||||
opvp = p;
|
||||
printf("amf0 %c property[%s]=%s\n", opvt, opnp, opvp);
|
||||
switch(opvt) {
|
||||
case 'S':
|
||||
srs_amf0_object_property_set(args, opnp, srs_amf0_create_string(opvp));
|
||||
break;
|
||||
default:
|
||||
printf("unsupported object property.\n");
|
||||
exit(-1);
|
||||
}
|
||||
*p=0;
|
||||
break;
|
||||
default:
|
||||
printf("only supports an object arg.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// srs debug info.
|
||||
char* ip = NULL;
|
||||
char* sig = NULL;
|
||||
int pid = 0, cid = 0;
|
||||
int major = 0, minor = 0, revision= 0, build = 0;
|
||||
// User options.
|
||||
int complex_handshake = 0;
|
||||
const char* rtmp_url = NULL;
|
||||
const char* output_flv = NULL;
|
||||
const char* swfUrl = NULL;
|
||||
const char* tcUrl = NULL;
|
||||
const char* pageUrl = NULL;
|
||||
srs_amf0_t args = NULL;
|
||||
|
||||
int do_proxy(srs_rtmp_t rtmp, srs_flv_t flv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = srs_rtmp_dns_resolve(rtmp)) != 0) {
|
||||
srs_human_trace("dns resolve failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_connect_server(rtmp)) != 0) {
|
||||
srs_human_trace("connect to server failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (complex_handshake) {
|
||||
if ((ret = srs_rtmp_do_complex_handshake(rtmp)) != 0) {
|
||||
srs_human_trace("complex handshake failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("do complex handshake success");
|
||||
} else {
|
||||
if ((ret = srs_rtmp_do_simple_handshake(rtmp)) != 0) {
|
||||
srs_human_trace("simple handshake failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("do simple handshake success");
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_set_connect_args(rtmp, tcUrl, swfUrl, pageUrl, args)) != 0) {
|
||||
srs_human_trace("set connect args failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_connect_app(rtmp)) != 0) {
|
||||
srs_human_trace("connect vhost/app failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_rtmp_get_server_sig(rtmp, &sig)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_id(rtmp, &ip, &pid, &cid)) != 0) {
|
||||
srs_human_trace("Retrieve server ID failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = srs_rtmp_get_server_version(rtmp, &major, &minor, &revision, &build)) != 0) {
|
||||
srs_human_trace("Retrieve server version failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d",
|
||||
ip, sig, major, minor, revision, build, pid, cid);
|
||||
|
||||
if ((ret = srs_rtmp_play_stream(rtmp)) != 0) {
|
||||
srs_human_trace("play stream failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("play stream success");
|
||||
|
||||
if (flv) {
|
||||
// flv header
|
||||
char header[9];
|
||||
// 3bytes, signature, "FLV",
|
||||
header[0] = 'F';
|
||||
header[1] = 'L';
|
||||
header[2] = 'V';
|
||||
// 1bytes, version, 0x01,
|
||||
header[3] = 0x01;
|
||||
// 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present.
|
||||
header[4] = 0x03; // audio + video.
|
||||
// 4bytes, dataoffset
|
||||
header[5] = 0x00;
|
||||
header[6] = 0x00;
|
||||
header[7] = 0x00;
|
||||
header[8] = 0x09;
|
||||
if ((ret = srs_flv_write_header(flv, header)) != 0) {
|
||||
srs_human_trace("write flv header failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nb_packets = 0;
|
||||
uint32_t pre_timestamp = 0;
|
||||
int64_t pre_now = -1;
|
||||
int64_t start_time = -1;
|
||||
char buffer[1024];
|
||||
for (;;) {
|
||||
int size;
|
||||
char type;
|
||||
char* data;
|
||||
uint32_t timestamp;
|
||||
|
||||
if ((ret = srs_rtmp_read_packet(rtmp, &type, ×tamp, &data, &size)) != 0) {
|
||||
srs_human_trace("read rtmp packet failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pre_now == -1) {
|
||||
pre_now = srs_utils_time_ms();
|
||||
}
|
||||
if (start_time == -1) {
|
||||
start_time = srs_utils_time_ms();
|
||||
}
|
||||
|
||||
if ((ret = srs_human_format_rtmp_packet2(buffer, sizeof(buffer), type, timestamp, data, size, pre_timestamp, pre_now, start_time, nb_packets++)) != 0) {
|
||||
srs_human_trace("print rtmp packet failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_human_trace("%s", buffer);
|
||||
|
||||
pre_timestamp = timestamp;
|
||||
pre_now = srs_utils_time_ms();
|
||||
|
||||
// we only write some types of messages to flv file.
|
||||
int is_flv_msg = type == SRS_RTMP_TYPE_AUDIO
|
||||
|| type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT;
|
||||
|
||||
// for script data, ignore except onMetaData
|
||||
if (type == SRS_RTMP_TYPE_SCRIPT) {
|
||||
if (!srs_rtmp_is_onMetaData(type, data, size)) {
|
||||
is_flv_msg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (flv) {
|
||||
if (is_flv_msg) {
|
||||
if ((ret = srs_flv_write_tag(flv, type, timestamp, data, size)) != 0) {
|
||||
srs_human_trace("dump rtmp packet failed, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
srs_human_trace("drop message type=%#x, size=%dB", type, size);
|
||||
}
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
srs_flv_t flv = NULL;
|
||||
srs_rtmp_t rtmp = NULL;
|
||||
|
||||
printf("dump rtmp stream to flv file\n");
|
||||
printf("srs(ossrs) client librtmp library.\n");
|
||||
printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision());
|
||||
printf("@refer to http://rtmpdump.mplayerhq.hu/rtmpdump.1.html\n");
|
||||
|
||||
int show_help = 0;
|
||||
const char* short_options = "hxr:o:s:t:p:C:";
|
||||
struct option long_options[] = {
|
||||
{"rtmp", required_argument, 0, 'r'},
|
||||
{"flv", required_argument, 0, 'o'},
|
||||
{"swfUrl", required_argument, 0, 's'},
|
||||
{"tcUrl", required_argument, 0, 't'},
|
||||
{"pageUrl", required_argument, 0, 'p'},
|
||||
{"conn", required_argument, 0, 'C'},
|
||||
{"complex", no_argument, 0, 'x'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int opt = 0;
|
||||
int option_index = 0;
|
||||
while((opt = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1){
|
||||
switch(opt){
|
||||
case 'r':
|
||||
rtmp_url = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
output_flv = optarg;
|
||||
break;
|
||||
case 's':
|
||||
swfUrl = optarg;
|
||||
break;
|
||||
case 't':
|
||||
tcUrl = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
pageUrl = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
if (!args) {
|
||||
args = srs_amf0_create_object();
|
||||
}
|
||||
char* p = (char*)optarg;
|
||||
parse_amf0_object(p, args);
|
||||
break;
|
||||
case 'x':
|
||||
complex_handshake = 1;
|
||||
break;
|
||||
case 'h':
|
||||
show_help = 1;
|
||||
break;
|
||||
default:
|
||||
printf("unsupported opt.\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rtmp_url || show_help) {
|
||||
printf("Usage: %s -r url [-o output] [-s swfUrl] [-t tcUrl] [-p pageUrl] [-C conndata] [--complex] [-h]\n"
|
||||
"Options:\n"
|
||||
" --rtmp -r url\n"
|
||||
" URL of the server and media content.\n"
|
||||
" --flv -o output\n"
|
||||
" Specify the output file name. If the name is − or is omitted, the stream is written to stdout.\n"
|
||||
" --complex\n"
|
||||
" Whether use complex handshake(srs-librtmp with ssl required).\n"
|
||||
" --swfUrl -s url\n"
|
||||
" URL of the SWF player for the media. By default no value will be sent.\n"
|
||||
" --tcUrl -t url\n"
|
||||
" URL of the target stream. Defaults to rtmp[e]://host[:port]/app/playpath.\n"
|
||||
" --pageUrl -p url\n"
|
||||
" URL of the web page in which the media was embedded. By default no value will be sent.\n"
|
||||
" −−conn −C type:data\n"
|
||||
" Append arbitrary AMF data to the Connect message. The type must be B for Boolean, N for number, S for string, O for object, or Z for null. For Booleans the data must be either 0 or 1 for FALSE or TRUE, respectively. Likewise for Objects the data must be 0 or 1 to end or begin an object, respectively. Data items in subobjects may be named, by prefixing the type with 'N' and specifying the name before the value, e.g. NB:myFlag:1. This option may be used multiple times to construct arbitrary AMF sequences. E.g.\n"
|
||||
" −C B:1 −C S:authMe −C O:1 −C NN:code:1.23 −C NS:flag:ok −C O:0\n"
|
||||
" -C O:1 -C NS:CONN:\" -C B:4Rg9vr0\" -C O:0\n"
|
||||
" @remark, support a object args only.\n"
|
||||
" --help -h\n"
|
||||
" Print a summary of command options.\n"
|
||||
"For example:\n"
|
||||
" %s -r rtmp://127.0.0.1:1935/live/livestream -o output.flv\n"
|
||||
" %s -h\n",
|
||||
argv[0], argv[0], argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
srs_human_trace("rtmp url: %s", rtmp_url);
|
||||
srs_human_trace("handshake: %s", (complex_handshake? "complex" : "simple"));
|
||||
srs_human_trace("swfUrl: %s", swfUrl);
|
||||
srs_human_trace("pageUrl: %s", pageUrl);
|
||||
srs_human_trace("tcUrl: %s", tcUrl);
|
||||
if (output_flv) {
|
||||
srs_human_trace("flv output path: %s", output_flv);
|
||||
} else {
|
||||
srs_human_trace("output to console");
|
||||
}
|
||||
|
||||
rtmp = srs_rtmp_create(rtmp_url);
|
||||
if (output_flv) {
|
||||
flv = srs_flv_open_write(output_flv);
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if ((ret = do_proxy(rtmp, flv)) != 0) {
|
||||
srs_human_trace("Dump RTMP failed, ret=%d", ret);
|
||||
}
|
||||
|
||||
srs_rtmp_destroy(rtmp);
|
||||
srs_flv_close(flv);
|
||||
srs_human_trace("completed");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
params="$@"
|
||||
echo "params is: $params"
|
||||
|
||||
# discover the current work dir, the log and access.
|
||||
echo "argv[0]=$0"
|
||||
if [[ ! -f $0 ]]; then
|
||||
echo "directly execute the scripts on shell.";
|
||||
work_dir=`pwd`
|
||||
else
|
||||
echo "execute scripts in file: $0";
|
||||
work_dir=`dirname $0`; work_dir=`(cd ${work_dir} && pwd)`
|
||||
fi
|
||||
work_dir=`(cd ${work_dir}/.. && pwd)`
|
||||
product_dir=$work_dir
|
||||
build_objs=${work_dir}/objs
|
||||
package_dir=${build_objs}/package
|
||||
|
||||
log="${build_objs}/test.`date +%s`.log" && . ${product_dir}/scripts/_log.sh && check_log
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then exit $ret; fi
|
||||
|
||||
item="./configure"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --x86-x64"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --pure-rtmp"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-ssl"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-hls"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-dvr"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-nginx"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-http-callback"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-http-server"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-http-api"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-ffmpeg"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-transcode"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-ingest"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-librtmp"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-research"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-stream-caster --with-http-api"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-utest"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-ssl --with-utest"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-gperf"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-gperf --with-gmc"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-gperf --with-gmp"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-gperf --with-gcp"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --with-gprof"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --log-verbose"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --log-info"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --log-trace"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast --log-info --log-verbose --log-trace"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
#######################################################################################################
|
||||
#######################################################################################################
|
||||
#######################################################################################################
|
||||
item="./configure --dev"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --fast-dev"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --demo"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --full"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
#######################################################################################################
|
||||
#######################################################################################################
|
||||
#######################################################################################################
|
||||
item="./configure --disable-all --with-ssl"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-hls --with-ssl --with-http-server --with-http-api"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-ssl --with-hls --with-nginx"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-ssl --with-hls --with-nginx --with-ffmpeg --with-transcode"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-ssl --with-ffmpeg --with-transcode"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-ssl --with-ffmpeg --with-ingest"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
item="./configure --disable-all --with-hls --with-ssl --with-http-server"
|
||||
ok_msg "test \" ${item} \""
|
||||
($item && make $params) >>$log 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then failed_msg "test \" ${item} \" failed. ret=$ret"; exit $ret; fi
|
||||
ok_msg "test \" ${item} \" success"
|
||||
|
||||
echo "success"
|
|
@ -1468,9 +1468,6 @@ srs_error_t SrsConfig::reload_conf(SrsConfig* conf)
|
|||
root = conf->root;
|
||||
conf->root = NULL;
|
||||
|
||||
// merge config.
|
||||
std::vector<ISrsReloadHandler*>::iterator it;
|
||||
|
||||
// never support reload:
|
||||
// daemon
|
||||
//
|
||||
|
@ -2246,7 +2243,7 @@ srs_error_t SrsConfig::global_to_json(SrsJsonObject* obj)
|
|||
sobjs->set(dir->arg0(), sobj);
|
||||
|
||||
SrsStatisticVhost* svhost = stat->find_vhost(dir->arg0());
|
||||
sobj->set("id", SrsJsonAny::integer(svhost? (double)svhost->id : 0));
|
||||
sobj->set("id", SrsJsonAny::str(svhost? svhost->id.c_str() : ""));
|
||||
sobj->set("name", dir->dumps_arg0_to_str());
|
||||
sobj->set("enabled", SrsJsonAny::boolean(get_vhost_enabled(dir->arg0())));
|
||||
|
||||
|
@ -2371,7 +2368,7 @@ srs_error_t SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsJsonObject* obj
|
|||
SrsStatistic* stat = SrsStatistic::instance();
|
||||
|
||||
SrsStatisticVhost* svhost = stat->find_vhost(vhost->arg0());
|
||||
obj->set("id", SrsJsonAny::integer(svhost? (double)svhost->id : 0));
|
||||
obj->set("id", SrsJsonAny::str(svhost? svhost->id.c_str() : ""));
|
||||
|
||||
obj->set("name", vhost->dumps_arg0_to_str());
|
||||
obj->set("enabled", SrsJsonAny::boolean(get_vhost_enabled(vhost)));
|
||||
|
@ -3937,7 +3934,8 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
} else if (n == "rtc") {
|
||||
for (int j = 0; j < (int)conf->directives.size(); j++) {
|
||||
string m = conf->at(j)->name;
|
||||
if (m != "enabled" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check") {
|
||||
if (m != "enabled" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check"
|
||||
&& m != "keep_sequence") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.rtc.%s of %s", m.c_str(), vhost->arg0().c_str());
|
||||
}
|
||||
}
|
||||
|
@ -5020,6 +5018,24 @@ bool SrsConfig::get_rtc_stun_strict_check(string vhost)
|
|||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_keep_sequence(string vhost)
|
||||
{
|
||||
static bool DEFAULT = false;
|
||||
|
||||
SrsConfDirective* conf = get_rtc(vhost);
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("keep_sequence");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_nack_enabled(string vhost)
|
||||
{
|
||||
static bool DEFAULT = true;
|
||||
|
|
|
@ -544,6 +544,7 @@ public:
|
|||
bool get_rtc_aac_discard(std::string vhost);
|
||||
srs_utime_t get_rtc_stun_timeout(std::string vhost);
|
||||
bool get_rtc_stun_strict_check(std::string vhost);
|
||||
bool get_rtc_keep_sequence(std::string vhost);
|
||||
bool get_rtc_nack_enabled(std::string vhost);
|
||||
bool get_rtc_twcc_enabled(std::string vhost);
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ srs_error_t SrsConnection::cycle()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
int SrsConnection::srs_id()
|
||||
string SrsConnection::srs_id()
|
||||
{
|
||||
return trd->cid();
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
virtual srs_error_t cycle();
|
||||
public:
|
||||
// Get the srs id which identify the client.
|
||||
virtual int srs_id();
|
||||
virtual std::string srs_id();
|
||||
// Get the remote ip of peer.
|
||||
virtual std::string remote_ip();
|
||||
// Set connection to expired.
|
||||
|
|
|
@ -533,7 +533,7 @@ srs_error_t SrsDvrMp4Segmenter::close_encoder()
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(int c, SrsRequest* r, string p)
|
||||
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(std::string c, SrsRequest* r, string p)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
@ -673,7 +673,7 @@ srs_error_t SrsDvrPlan::on_reap_segment()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int cid = _srs_context->get_id();
|
||||
std::string cid = _srs_context->get_id();
|
||||
|
||||
SrsFragment* fragment = segment->current();
|
||||
string fullpath = fragment->fullpath();
|
||||
|
|
|
@ -159,11 +159,11 @@ protected:
|
|||
class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
int cid;
|
||||
std::string cid;
|
||||
std::string path;
|
||||
SrsRequest* req;
|
||||
public:
|
||||
SrsDvrAsyncCallOnDvr(int c, SrsRequest* r, std::string p);
|
||||
SrsDvrAsyncCallOnDvr(std::string c, SrsRequest* r, std::string p);
|
||||
virtual ~SrsDvrAsyncCallOnDvr();
|
||||
public:
|
||||
virtual srs_error_t call();
|
||||
|
|
|
@ -82,7 +82,7 @@ void SrsHlsSegment::config_cipher(unsigned char* key,unsigned char* iv)
|
|||
fw->config_cipher(key, iv);
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(int c, SrsRequest* r, string p, string t, string m, string mu, int s, srs_utime_t d)
|
||||
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(string c, SrsRequest* r, string p, string t, string m, string mu, int s, srs_utime_t d)
|
||||
{
|
||||
req = r->copy();
|
||||
cid = c;
|
||||
|
@ -137,7 +137,7 @@ string SrsDvrAsyncCallOnHls::to_string()
|
|||
return "on_hls: " + path;
|
||||
}
|
||||
|
||||
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(int c, SrsRequest* r, string u)
|
||||
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(string c, SrsRequest* r, string u)
|
||||
{
|
||||
cid = c;
|
||||
req = r->copy();
|
||||
|
@ -759,9 +759,6 @@ srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
|
|||
SrsHlsSegment* first = dynamic_cast<SrsHlsSegment*>(segments->first());
|
||||
ss << "#EXT-X-MEDIA-SEQUENCE:" << first->sequence_no << SRS_CONSTS_LF;
|
||||
|
||||
// iterator shared for td generation and segemnts wrote.
|
||||
std::vector<SrsHlsSegment*>::iterator it;
|
||||
|
||||
// #EXT-X-TARGETDURATION:4294967295\n
|
||||
/**
|
||||
* @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
int cid;
|
||||
std::string cid;
|
||||
std::string path;
|
||||
std::string ts_url;
|
||||
std::string m3u8;
|
||||
|
@ -90,7 +90,7 @@ private:
|
|||
srs_utime_t duration;
|
||||
public:
|
||||
// TODO: FIXME: Use TBN 1000.
|
||||
SrsDvrAsyncCallOnHls(int c, SrsRequest* r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
|
||||
SrsDvrAsyncCallOnHls(std::string c, SrsRequest* r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
|
||||
virtual ~SrsDvrAsyncCallOnHls();
|
||||
public:
|
||||
virtual srs_error_t call();
|
||||
|
@ -101,11 +101,11 @@ public:
|
|||
class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
int cid;
|
||||
std::string cid;
|
||||
std::string ts_url;
|
||||
SrsRequest* req;
|
||||
public:
|
||||
SrsDvrAsyncCallOnHlsNotify(int c, SrsRequest* r, std::string u);
|
||||
SrsDvrAsyncCallOnHlsNotify(std::string c, SrsRequest* r, std::string u);
|
||||
virtual ~SrsDvrAsyncCallOnHlsNotify();
|
||||
public:
|
||||
virtual srs_error_t call();
|
||||
|
|
|
@ -699,10 +699,10 @@ srs_error_t SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessag
|
|||
|
||||
// path: {pattern}{vhost_id}
|
||||
// e.g. /api/v1/vhosts/100 pattern= /api/v1/vhosts/, vhost_id=100
|
||||
int vid = r->parse_rest_id(entry->pattern);
|
||||
std::string vid = r->parse_rest_id(entry->pattern);
|
||||
SrsStatisticVhost* vhost = NULL;
|
||||
|
||||
if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) {
|
||||
if (vid != "" && (vhost = stat->find_vhost(vid)) == NULL) {
|
||||
return srs_api_response_code(w, r, ERROR_RTMP_VHOST_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -755,10 +755,10 @@ srs_error_t SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
|
|||
|
||||
// path: {pattern}{stream_id}
|
||||
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
|
||||
int sid = r->parse_rest_id(entry->pattern);
|
||||
std::string sid = r->parse_rest_id(entry->pattern);
|
||||
|
||||
SrsStatisticStream* stream = NULL;
|
||||
if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
|
||||
if (sid != "" && (stream = stat->find_stream(sid)) == NULL) {
|
||||
return srs_api_response_code(w, r, ERROR_RTMP_STREAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -811,10 +811,10 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
|
|||
|
||||
// path: {pattern}{client_id}
|
||||
// e.g. /api/v1/clients/100 pattern= /api/v1/clients/, client_id=100
|
||||
int cid = r->parse_rest_id(entry->pattern);
|
||||
std::string cid = r->parse_rest_id(entry->pattern);
|
||||
|
||||
SrsStatisticClient* client = NULL;
|
||||
if (cid >= 0 && (client = stat->find_client(cid)) == NULL) {
|
||||
if (cid != "" && (client = stat->find_client(cid)) == NULL) {
|
||||
return srs_api_response_code(w, r, ERROR_RTMP_CLIENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -854,7 +854,7 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
|
|||
}
|
||||
|
||||
client->conn->expire();
|
||||
srs_warn("kickoff client id=%d ok", cid);
|
||||
srs_warn("kickoff client id=%s ok", cid.c_str());
|
||||
} else {
|
||||
return srs_go_http_error(w, SRS_CONSTS_HTTP_MethodNotAllowed);
|
||||
}
|
||||
|
|
|
@ -60,13 +60,15 @@ srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest* req)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
// TODO: FIXME: check client_id must be int?
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_connect"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
// obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -79,12 +81,12 @@ srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest* req)
|
|||
|
||||
SrsHttpClient http;
|
||||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
return srs_error_wrap(err, "http: on_connect failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
return srs_error_wrap(err, "http: on_connect failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
}
|
||||
|
||||
srs_trace("http: on_connect ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_connect ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -93,13 +95,13 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_close"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -114,13 +116,13 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int
|
|||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
int ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_warn("http: ignore on_close failed, client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
srs_warn("http: ignore on_close failed, client_id=%s, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
srs_trace("http: on_close ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_close ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -129,13 +131,13 @@ srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest* req)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_publish"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -149,12 +151,12 @@ srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest* req)
|
|||
|
||||
SrsHttpClient http;
|
||||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
return srs_error_wrap(err, "http: on_publish failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
return srs_error_wrap(err, "http: on_publish failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
}
|
||||
|
||||
srs_trace("http: on_publish ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_publish ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -163,13 +165,13 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_unpublish"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -184,13 +186,13 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
|
|||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
int ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_warn("http: ignore on_unpublish failed, client_id=%d, url=%s, request=%s, response=%s, status=%d, ret=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
srs_warn("http: ignore on_unpublish failed, client_id=%s, url=%s, request=%s, response=%s, status=%d, ret=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
srs_trace("http: on_unpublish ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_unpublish ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -199,13 +201,13 @@ srs_error_t SrsHttpHooks::on_play(string url, SrsRequest* req)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_play"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -219,12 +221,12 @@ srs_error_t SrsHttpHooks::on_play(string url, SrsRequest* req)
|
|||
|
||||
SrsHttpClient http;
|
||||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
return srs_error_wrap(err, "http: on_play failed, client_id=%d, url=%s, request=%s, response=%s, status=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
return srs_error_wrap(err, "http: on_play failed, client_id=%s, url=%s, request=%s, response=%s, status=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
}
|
||||
|
||||
srs_trace("http: on_play ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_play ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -233,13 +235,13 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = _srs_context->get_id();
|
||||
std::string client_id = _srs_context->get_id();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_stop"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -254,29 +256,29 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req)
|
|||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
int ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_warn("http: ignore on_stop failed, client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
srs_warn("http: ignore on_stop failed, client_id=%s, url=%s, request=%s, response=%s, code=%d, ret=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
srs_trace("http: on_stop ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_stop ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string file)
|
||||
srs_error_t SrsHttpHooks::on_dvr(std::string cid, string url, SrsRequest* req, string file)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = cid;
|
||||
std::string client_id = cid;
|
||||
std::string cwd = _srs_config->cwd();
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_dvr"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -291,21 +293,21 @@ srs_error_t SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string fi
|
|||
|
||||
SrsHttpClient http;
|
||||
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
|
||||
return srs_error_wrap(err, "http post on_dvr uri failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
return srs_error_wrap(err, "http post on_dvr uri failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
|
||||
}
|
||||
|
||||
srs_trace("http hook on_dvr success. client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http hook on_dvr success. client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
|
||||
srs_error_t SrsHttpHooks::on_hls(std::string cid, string url, SrsRequest* req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = cid;
|
||||
std::string client_id = cid;
|
||||
std::string cwd = _srs_config->cwd();
|
||||
|
||||
// the ts_url is under the same dir of m3u8_url.
|
||||
|
@ -318,7 +320,7 @@ srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string fi
|
|||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("action", SrsJsonAny::str("on_hls"));
|
||||
obj->set("client_id", SrsJsonAny::integer(client_id));
|
||||
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(req->app.c_str()));
|
||||
|
@ -341,17 +343,17 @@ srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string fi
|
|||
return srs_error_wrap(err, "http: post %s with %s, status=%d, res=%s", url.c_str(), data.c_str(), status_code, res.c_str());
|
||||
}
|
||||
|
||||
srs_trace("http: on_hls ok, client_id=%d, url=%s, request=%s, response=%s",
|
||||
client_id, url.c_str(), data.c_str(), res.c_str());
|
||||
srs_trace("http: on_hls ok, client_id=%s, url=%s, request=%s, response=%s",
|
||||
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify)
|
||||
srs_error_t SrsHttpHooks::on_hls_notify(std::string cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
int client_id = cid;
|
||||
std::string client_id = cid;
|
||||
std::string cwd = _srs_config->cwd();
|
||||
|
||||
if (srs_string_is_http(ts_url)) {
|
||||
|
@ -406,8 +408,8 @@ srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* re
|
|||
}
|
||||
|
||||
int spenttime = (int)(srsu2ms(srs_update_system_time()) - starttime);
|
||||
srs_trace("http hook on_hls_notify success. client_id=%d, url=%s, code=%d, spent=%dms, read=%dB, err=%s",
|
||||
client_id, url.c_str(), msg->status_code(), spenttime, nb_read, srs_error_desc(err).c_str());
|
||||
srs_trace("http hook on_hls_notify success. client_id=%s, url=%s, code=%d, spent=%dms, read=%dB, err=%s",
|
||||
client_id.c_str(), url.c_str(), msg->status_code(), spenttime, nb_read, srs_error_desc(err).c_str());
|
||||
|
||||
// ignore any error for on_hls_notify.
|
||||
srs_error_reset(err);
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
// ignore if empty.
|
||||
// @param file the file path, can be relative or absolute path.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file);
|
||||
static srs_error_t on_dvr(std::string cid, std::string url, SrsRequest* req, std::string file);
|
||||
// When hls reap segment, callback.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
// @param sn the seq_no, the sequence number of ts in hls/m3u8.
|
||||
// @param duration the segment duration in srs_utime_t.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
|
||||
static srs_error_t on_hls(std::string cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
|
||||
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration);
|
||||
// When hls reap segment, callback.
|
||||
// @param url the api server url, to process the event.
|
||||
|
@ -93,7 +93,7 @@ public:
|
|||
// @param ts_url the ts uri, used to replace the variable [ts_url] in url.
|
||||
// @param nb_notify the max bytes to read from notify server.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
|
||||
static srs_error_t on_hls_notify(std::string cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
|
||||
// Discover co-workers for origin cluster.
|
||||
static srs_error_t discover_co_workers(std::string url, std::string& host, int& port);
|
||||
private:
|
||||
|
|
|
@ -1141,8 +1141,8 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandle
|
|||
|
||||
// trigger edge to fetch from origin.
|
||||
bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost);
|
||||
srs_trace("flv: source url=%s, is_edge=%d, source_id=[%d][%d]",
|
||||
r->get_stream_url().c_str(), vhost_is_edge, ::getpid(), s->source_id());
|
||||
srs_trace("flv: source url=%s, is_edge=%d, source_id=[%d][%s]",
|
||||
r->get_stream_url().c_str(), vhost_is_edge, ::getpid(), s->source_id().c_str());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ srs_error_t SrsUdpListener::listen()
|
|||
handler->set_stfd(lfd);
|
||||
|
||||
srs_freep(trd);
|
||||
trd = new SrsSTCoroutine("udp", this);
|
||||
trd = new SrsSTCoroutine("udp", this, _srs_context->get_id());
|
||||
if ((err = trd->start()) != srs_success) {
|
||||
return srs_error_wrap(err, "start thread");
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ void SrsFastLog::reopen()
|
|||
open_log_file();
|
||||
}
|
||||
|
||||
void SrsFastLog::verbose(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsFastLog::verbose(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelVerbose) {
|
||||
return;
|
||||
|
@ -114,7 +114,7 @@ void SrsFastLog::verbose(const char* tag, int context_id, const char* fmt, ...)
|
|||
write_log(fd, log_data, size, SrsLogLevelVerbose);
|
||||
}
|
||||
|
||||
void SrsFastLog::info(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsFastLog::info(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelInfo) {
|
||||
return;
|
||||
|
@ -134,7 +134,7 @@ void SrsFastLog::info(const char* tag, int context_id, const char* fmt, ...)
|
|||
write_log(fd, log_data, size, SrsLogLevelInfo);
|
||||
}
|
||||
|
||||
void SrsFastLog::trace(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsFastLog::trace(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelTrace) {
|
||||
return;
|
||||
|
@ -154,7 +154,7 @@ void SrsFastLog::trace(const char* tag, int context_id, const char* fmt, ...)
|
|||
write_log(fd, log_data, size, SrsLogLevelTrace);
|
||||
}
|
||||
|
||||
void SrsFastLog::warn(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsFastLog::warn(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelWarn) {
|
||||
return;
|
||||
|
@ -174,7 +174,7 @@ void SrsFastLog::warn(const char* tag, int context_id, const char* fmt, ...)
|
|||
write_log(fd, log_data, size, SrsLogLevelWarn);
|
||||
}
|
||||
|
||||
void SrsFastLog::error(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsFastLog::error(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelError) {
|
||||
return;
|
||||
|
|
|
@ -55,11 +55,11 @@ public:
|
|||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual void reopen();
|
||||
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void info(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_utc_time();
|
||||
|
|
|
@ -180,7 +180,7 @@ srs_error_t SrsProcess::start()
|
|||
srs_info("fork process: %s", cli.c_str());
|
||||
|
||||
// for log
|
||||
int cid = _srs_context->get_id();
|
||||
std::string cid = _srs_context->get_id();
|
||||
int ppid = getpid();
|
||||
|
||||
// TODO: fork or vfork?
|
||||
|
@ -221,8 +221,8 @@ srs_error_t SrsProcess::start()
|
|||
// log basic info to stderr.
|
||||
if (true) {
|
||||
fprintf(stdout, "\n");
|
||||
fprintf(stdout, "process ppid=%d, cid=%d, pid=%d, in=%d, out=%d, err=%d\n",
|
||||
ppid, cid, getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
|
||||
fprintf(stdout, "process ppid=%d, cid=%s, pid=%d, in=%d, out=%d, err=%d\n",
|
||||
ppid, cid.c_str(), getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
|
||||
fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
|
||||
fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ ISrsMessagePumper::~ISrsMessagePumper()
|
|||
{
|
||||
}
|
||||
|
||||
SrsRecvThread::SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, int parent_cid)
|
||||
SrsRecvThread::SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, std::string parent_cid)
|
||||
{
|
||||
rtmp = r;
|
||||
pumper = p;
|
||||
|
@ -71,7 +71,7 @@ SrsRecvThread::~SrsRecvThread()
|
|||
srs_freep(trd);
|
||||
}
|
||||
|
||||
int SrsRecvThread::cid()
|
||||
std::string SrsRecvThread::cid()
|
||||
{
|
||||
return trd->cid();
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ srs_error_t SrsRecvThread::do_cycle()
|
|||
return err;
|
||||
}
|
||||
|
||||
SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, int parent_cid)
|
||||
SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, std::string parent_cid)
|
||||
: trd(this, rtmp_sdk, tm, parent_cid)
|
||||
{
|
||||
_consumer = consumer;
|
||||
|
@ -278,7 +278,7 @@ void SrsQueueRecvThread::on_stop()
|
|||
}
|
||||
|
||||
SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req,
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid)
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, std::string parent_cid)
|
||||
: trd(this, rtmp_sdk, tm, parent_cid)
|
||||
{
|
||||
rtmp = rtmp_sdk;
|
||||
|
@ -290,7 +290,7 @@ SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest*
|
|||
_nb_msgs = 0;
|
||||
video_frames = 0;
|
||||
error = srs_cond_new();
|
||||
ncid = cid = 0;
|
||||
ncid = cid = "";
|
||||
|
||||
req = _req;
|
||||
mr_fd = mr_sock_fd;
|
||||
|
@ -341,12 +341,12 @@ srs_error_t SrsPublishRecvThread::error_code()
|
|||
return srs_error_copy(recv_error);
|
||||
}
|
||||
|
||||
void SrsPublishRecvThread::set_cid(int v)
|
||||
void SrsPublishRecvThread::set_cid(std::string v)
|
||||
{
|
||||
ncid = v;
|
||||
}
|
||||
|
||||
int SrsPublishRecvThread::get_cid()
|
||||
std::string SrsPublishRecvThread::get_cid()
|
||||
{
|
||||
return ncid;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <srs_core.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <srs_app_thread.hpp>
|
||||
#include <srs_protocol_stream.hpp>
|
||||
|
@ -80,16 +81,16 @@ protected:
|
|||
SrsCoroutine* trd;
|
||||
ISrsMessagePumper* pumper;
|
||||
SrsRtmpServer* rtmp;
|
||||
int _parent_cid;
|
||||
std::string _parent_cid;
|
||||
// The recv timeout in srs_utime_t.
|
||||
srs_utime_t timeout;
|
||||
public:
|
||||
// Constructor.
|
||||
// @param tm The receive timeout in srs_utime_t.
|
||||
SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, int parent_cid);
|
||||
SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, std::string parent_cid);
|
||||
virtual ~SrsRecvThread();
|
||||
public:
|
||||
virtual int cid();
|
||||
virtual std::string cid();
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
|
@ -116,7 +117,7 @@ private:
|
|||
SrsConsumer* _consumer;
|
||||
public:
|
||||
// TODO: FIXME: Refine timeout in time unit.
|
||||
SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, int parent_cid);
|
||||
SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, std::string parent_cid);
|
||||
virtual ~SrsQueueRecvThread();
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
|
@ -167,11 +168,11 @@ private:
|
|||
// @see https://github.com/ossrs/srs/issues/244
|
||||
srs_cond_t error;
|
||||
// The merged context id.
|
||||
int cid;
|
||||
int ncid;
|
||||
std::string cid;
|
||||
std::string ncid;
|
||||
public:
|
||||
SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req,
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid);
|
||||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, std::string parent_cid);
|
||||
virtual ~SrsPublishRecvThread();
|
||||
public:
|
||||
// Wait for error for some timeout.
|
||||
|
@ -179,8 +180,8 @@ public:
|
|||
virtual int64_t nb_msgs();
|
||||
virtual uint64_t nb_video_frames();
|
||||
virtual srs_error_t error_code();
|
||||
virtual void set_cid(int v);
|
||||
virtual int get_cid();
|
||||
virtual void set_cid(std::string v);
|
||||
virtual std::string get_cid();
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
|
|
|
@ -136,10 +136,16 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
string eip = r->query_get("eip");
|
||||
// For client to specifies whether encrypt by SRTP.
|
||||
string encrypt = r->query_get("encrypt");
|
||||
// If keep_sequence is off, for client to specifies the startup sequence.
|
||||
string sequence_startup = r->query_get("sequence_startup");
|
||||
// If keep_sequence is on, for client to specifies the delta value for sequence.
|
||||
string sequence_delta = r->query_get("sequence_delta");
|
||||
// Whether keep sequence, overwrite the config for debugging each session.
|
||||
string sequence_keep = r->query_get("sequence_keep");
|
||||
|
||||
srs_trace("RTC play %s, api=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, encrypt=%s",
|
||||
streamurl.c_str(), api.c_str(), clientip.c_str(), app.c_str(), stream_name.c_str(), remote_sdp_str.length(),
|
||||
eip.c_str(), encrypt.c_str());
|
||||
srs_trace("RTC play %s, api=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, encrypt=%s, sequence(startup=%s,delta=%s,keep=%s)",
|
||||
streamurl.c_str(), api.c_str(), clientip.c_str(), app.c_str(), stream_name.c_str(), remote_sdp_str.length(), eip.c_str(), encrypt.c_str(),
|
||||
sequence_startup.c_str(), sequence_delta.c_str(), sequence_keep.c_str());
|
||||
|
||||
// TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information.
|
||||
SrsSdp remote_sdp;
|
||||
|
@ -189,6 +195,11 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
|
|||
session->set_encrypt(encrypt != "false");
|
||||
}
|
||||
|
||||
// Set the optional parameters from client.
|
||||
session->sequence_startup = sequence_startup;
|
||||
session->sequence_delta = sequence_delta;
|
||||
session->sequence_keep = sequence_keep;
|
||||
|
||||
ostringstream os;
|
||||
if ((err = local_sdp.encode(os)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode sdp");
|
||||
|
|
|
@ -487,18 +487,16 @@ SrsRtcOutgoingInfo::~SrsRtcOutgoingInfo()
|
|||
{
|
||||
}
|
||||
|
||||
SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid)
|
||||
SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, string parent_cid)
|
||||
{
|
||||
_parent_cid = parent_cid;
|
||||
trd = new SrsDummyCoroutine();
|
||||
|
||||
session_ = s;
|
||||
|
||||
audio_timestamp = 0;
|
||||
audio_sequence = 0;
|
||||
|
||||
video_sequence = 0;
|
||||
|
||||
sequence_delta = 0;
|
||||
mw_msgs = 0;
|
||||
realtime = true;
|
||||
|
||||
|
@ -508,6 +506,7 @@ SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid)
|
|||
|
||||
nn_simulate_nack_drop = 0;
|
||||
nack_enabled_ = false;
|
||||
keep_sequence_ = false;
|
||||
|
||||
_srs_config->subscribe(this);
|
||||
}
|
||||
|
@ -533,8 +532,18 @@ srs_error_t SrsRtcPlayer::initialize(const uint32_t& vssrc, const uint32_t& assr
|
|||
|
||||
// TODO: FIXME: Support reload.
|
||||
nack_enabled_ = _srs_config->get_rtc_nack_enabled(session_->req->vhost);
|
||||
srs_trace("RTC publisher video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), nack=%d",
|
||||
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, nack_enabled_);
|
||||
keep_sequence_ = _srs_config->get_rtc_keep_sequence(session_->req->vhost);
|
||||
if (!session_->sequence_startup.empty()) {
|
||||
audio_sequence = video_sequence = uint16_t(::atoi(session_->sequence_startup.c_str()));
|
||||
}
|
||||
if (!session_->sequence_delta.empty()) {
|
||||
sequence_delta = uint16_t(::atoi(session_->sequence_delta.c_str()));
|
||||
}
|
||||
if (!session_->sequence_keep.empty()) {
|
||||
keep_sequence_ = (session_->sequence_keep == "true");
|
||||
}
|
||||
srs_trace("RTC player video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), nack=%d, keep-seq=%d, sequence(audio=%u,video=%u,delta=%u)",
|
||||
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, nack_enabled_, keep_sequence_, audio_sequence, video_sequence, sequence_delta);
|
||||
|
||||
if (_srs_rtc_hijacker) {
|
||||
if ((err = _srs_rtc_hijacker->on_start_play(session_, this, session_->req)) != srs_success) {
|
||||
|
@ -566,7 +575,7 @@ srs_error_t SrsRtcPlayer::on_reload_vhost_realtime(string vhost)
|
|||
return on_reload_vhost_play(vhost);
|
||||
}
|
||||
|
||||
int SrsRtcPlayer::cid()
|
||||
std::string SrsRtcPlayer::cid()
|
||||
{
|
||||
return trd->cid();
|
||||
}
|
||||
|
@ -620,8 +629,8 @@ srs_error_t SrsRtcPlayer::cycle()
|
|||
realtime = _srs_config->get_realtime_enabled(req->vhost, true);
|
||||
mw_msgs = _srs_config->get_mw_msgs(req->vhost, realtime, true);
|
||||
|
||||
srs_trace("RTC source url=%s, source_id=[%d][%d], encrypt=%d, realtime=%d, mw_msgs=%d", req->get_stream_url().c_str(),
|
||||
::getpid(), source->source_id(), session_->encrypt, realtime, mw_msgs);
|
||||
srs_trace("RTC source url=%s, source_id=[%d][%s], encrypt=%d, realtime=%d, mw_msgs=%d", req->get_stream_url().c_str(),
|
||||
::getpid(), source->source_id().c_str(), session_->encrypt, realtime, mw_msgs);
|
||||
|
||||
SrsPithyPrint* pprint = SrsPithyPrint::create_rtc_play();
|
||||
SrsAutoFree(SrsPithyPrint, pprint);
|
||||
|
@ -707,29 +716,36 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcSource* source, const vector<SrsRtp
|
|||
// Update stats.
|
||||
info.nn_bytes += pkt->nb_bytes();
|
||||
|
||||
// For audio, we transcoded AAC to opus in extra payloads.
|
||||
uint16_t oseq = pkt->header.get_sequence();
|
||||
if (pkt->is_audio()) {
|
||||
info.nn_audios++;
|
||||
|
||||
pkt->header.set_timestamp(audio_timestamp);
|
||||
pkt->header.set_sequence(audio_sequence++);
|
||||
if (!keep_sequence_) {
|
||||
// TODO: FIXME: Should keep the order by original sequence.
|
||||
pkt->header.set_sequence(sequence_delta + audio_sequence++);
|
||||
} else {
|
||||
pkt->header.set_sequence(sequence_delta + oseq);
|
||||
}
|
||||
pkt->header.set_ssrc(audio_ssrc);
|
||||
pkt->header.set_payload_type(audio_payload_type);
|
||||
|
||||
// TODO: FIXME: Padding audio to the max payload in RTP packets.
|
||||
} else {
|
||||
info.nn_videos++;
|
||||
|
||||
// TODO: FIXME: Why 960? Need Refactoring?
|
||||
audio_timestamp += 960;
|
||||
continue;
|
||||
if (!keep_sequence_) {
|
||||
// TODO: FIXME: Should keep the order by original sequence.
|
||||
pkt->header.set_sequence(sequence_delta + video_sequence++);
|
||||
} else {
|
||||
pkt->header.set_sequence(sequence_delta + oseq);
|
||||
}
|
||||
pkt->header.set_ssrc(video_ssrc);
|
||||
pkt->header.set_payload_type(video_payload_type);
|
||||
}
|
||||
|
||||
// For video, we should process all NALUs in samples.
|
||||
info.nn_videos++;
|
||||
|
||||
// For video, we should set the RTP packet informations about this consumer.
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_ssrc(video_ssrc);
|
||||
pkt->header.set_payload_type(video_payload_type);
|
||||
// Detail log, should disable it in release version.
|
||||
srs_info("RTC: Update PT=%u, SSRC=%#x, OSEQ=%u, SEQ=%u, Time=%u, %u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(),
|
||||
oseq, pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes());
|
||||
}
|
||||
|
||||
// By default, we send packets by sendmmsg.
|
||||
|
@ -815,6 +831,10 @@ srs_error_t SrsRtcPlayer::do_send_packets(const std::vector<SrsRtpPacket2*>& pkt
|
|||
|
||||
// TODO: FIXME: Handle error.
|
||||
session_->sendonly_skt->sendto(iov->iov_base, iov->iov_len, 0);
|
||||
|
||||
// Detail log, should disable it in release version.
|
||||
srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(),
|
||||
pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes(), iov->iov_len);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -978,6 +998,12 @@ srs_error_t SrsRtcPlayer::on_rtcp_feedback(char* buf, int nb_buf)
|
|||
vector<SrsRtpPacket2*> resend_pkts;
|
||||
nack_fetch(resend_pkts, ssrc_of_media_source, pid);
|
||||
|
||||
// If NACK disabled, print a log.
|
||||
if (!nack_enabled_) {
|
||||
srs_trace("RTC NACK seq=%u, ignored", pid);
|
||||
return err;
|
||||
}
|
||||
|
||||
uint16_t mask = 0x01;
|
||||
for (int i = 1; i < 16 && blp; ++i, mask <<= 1) {
|
||||
if (!(blp & mask)) {
|
||||
|
@ -1031,7 +1057,7 @@ srs_error_t SrsRtcPlayer::on_rtcp_ps_feedback(char* buf, int nb_buf)
|
|||
|
||||
switch (fmt) {
|
||||
case kPLI: {
|
||||
SrsRtcPublisher* publisher = session_->source_->rtc_publisher();
|
||||
ISrsRtcPublisher* publisher = session_->source_->rtc_publisher();
|
||||
if (publisher) {
|
||||
publisher->request_keyframe();
|
||||
srs_trace("RTC request PLI");
|
||||
|
@ -1088,10 +1114,9 @@ SrsRtcPublisher::SrsRtcPublisher(SrsRtcSession* session)
|
|||
|
||||
SrsRtcPublisher::~SrsRtcPublisher()
|
||||
{
|
||||
source->set_rtc_publisher(NULL);
|
||||
|
||||
// TODO: FIXME: Do unpublish when session timeout.
|
||||
if (source) {
|
||||
source->set_rtc_publisher(NULL);
|
||||
source->on_unpublish();
|
||||
}
|
||||
|
||||
|
@ -1420,11 +1445,12 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
|
|||
|
||||
if (true) {
|
||||
pkt->set_decode_handler(this);
|
||||
pkt->set_rtp_header_extensions(&extension_map_);
|
||||
pkt->shared_msg = new SrsSharedPtrMessage();
|
||||
pkt->shared_msg->wrap(buf, nb_buf);
|
||||
|
||||
SrsBuffer b(buf, nb_buf);
|
||||
if ((err = pkt->decode(&b, &extension_map_)) != srs_success) {
|
||||
if ((err = pkt->decode(&b)) != srs_success) {
|
||||
return srs_error_wrap(err, "decode rtp packet");
|
||||
}
|
||||
|
||||
|
@ -1434,6 +1460,9 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
|
|||
if((err = on_twcc(twcc_sn))) {
|
||||
return srs_error_wrap(err, "fail to process twcc packet");
|
||||
}
|
||||
} else {
|
||||
// TODO: FIXME: process no twcc seq number for audio ssrc
|
||||
srs_error_reset(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1910,9 +1939,9 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|||
|
||||
void SrsRtcPublisher::request_keyframe()
|
||||
{
|
||||
int scid = _srs_context->get_id();
|
||||
int pcid = session_->context_id();
|
||||
srs_trace("RTC play=[%d][%d] request keyframe from publish=[%d][%d]", ::getpid(), scid, ::getpid(), pcid);
|
||||
std::string scid = _srs_context->get_id();
|
||||
std::string pcid = session_->context_id();
|
||||
srs_trace("RTC play=[%d][%s] request keyframe from publish=[%d][%s]", ::getpid(), scid.c_str(), ::getpid(), pcid.c_str());
|
||||
|
||||
request_keyframe_ = true;
|
||||
}
|
||||
|
@ -1946,7 +1975,7 @@ void SrsRtcPublisher::simulate_drop_packet(SrsRtpHeader* h, int nn_bytes)
|
|||
SrsRtcSession::SrsRtcSession(SrsRtcServer* s)
|
||||
{
|
||||
req = NULL;
|
||||
cid = 0;
|
||||
cid = "";
|
||||
is_publisher_ = false;
|
||||
encrypt = true;
|
||||
|
||||
|
@ -2039,12 +2068,12 @@ void SrsRtcSession::switch_to_context()
|
|||
_srs_context->set_id(cid);
|
||||
}
|
||||
|
||||
int SrsRtcSession::context_id()
|
||||
std::string SrsRtcSession::context_id()
|
||||
{
|
||||
return cid;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcSession::initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, string username, int context_id)
|
||||
srs_error_t SrsRtcSession::initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, string username, std::string context_id)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <srs_kernel_rtc_rtp.hpp>
|
||||
#include <srs_kernel_rtc_rtcp.hpp>
|
||||
#include <srs_app_rtc_queue.hpp>
|
||||
#include <srs_app_rtc_source.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
@ -188,13 +189,12 @@ public:
|
|||
class SrsRtcPlayer : virtual public ISrsCoroutineHandler, virtual public ISrsReloadHandler
|
||||
{
|
||||
protected:
|
||||
int _parent_cid;
|
||||
std::string _parent_cid;
|
||||
SrsCoroutine* trd;
|
||||
SrsRtcSession* session_;
|
||||
private:
|
||||
// TODO: FIXME: How to handle timestamp overflow?
|
||||
// Information for audio.
|
||||
uint32_t audio_timestamp;
|
||||
uint16_t audio_sequence;
|
||||
uint32_t audio_ssrc;
|
||||
uint16_t audio_payload_type;
|
||||
|
@ -206,6 +206,7 @@ private:
|
|||
SrsRtpRingBuffer* audio_queue_;
|
||||
SrsRtpRingBuffer* video_queue_;
|
||||
// Simulators.
|
||||
uint16_t sequence_delta;
|
||||
int nn_simulate_nack_drop;
|
||||
private:
|
||||
// For merged-write messages.
|
||||
|
@ -213,8 +214,10 @@ private:
|
|||
bool realtime;
|
||||
// Whether enabled nack.
|
||||
bool nack_enabled_;
|
||||
// Whether keep original sequence number.
|
||||
bool keep_sequence_;
|
||||
public:
|
||||
SrsRtcPlayer(SrsRtcSession* s, int parent_cid);
|
||||
SrsRtcPlayer(SrsRtcSession* s, std::string parent_cid);
|
||||
virtual ~SrsRtcPlayer();
|
||||
public:
|
||||
srs_error_t initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt);
|
||||
|
@ -223,7 +226,7 @@ public:
|
|||
virtual srs_error_t on_reload_vhost_play(std::string vhost);
|
||||
virtual srs_error_t on_reload_vhost_realtime(std::string vhost);
|
||||
public:
|
||||
virtual int cid();
|
||||
virtual std::string cid();
|
||||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
|
@ -248,7 +251,7 @@ private:
|
|||
srs_error_t on_rtcp_rr(char* data, int nb_data);
|
||||
};
|
||||
|
||||
class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler
|
||||
class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler, virtual public ISrsRtcPublisher
|
||||
{
|
||||
private:
|
||||
SrsHourGlass* report_timer;
|
||||
|
@ -341,7 +344,7 @@ private:
|
|||
srs_utime_t last_stun_time;
|
||||
private:
|
||||
// For each RTC session, we use a specified cid for debugging logs.
|
||||
int cid;
|
||||
std::string cid;
|
||||
// For each RTC session, whether requires encrypt.
|
||||
// Read config value, rtc_server.encrypt, default to on.
|
||||
// Sepcifies by HTTP API, query encrypt, optional.
|
||||
|
@ -351,6 +354,11 @@ private:
|
|||
SrsRtcSource* source_;
|
||||
SrsSdp remote_sdp;
|
||||
SrsSdp local_sdp;
|
||||
public:
|
||||
// User debugging parameters, overwrite config.
|
||||
std::string sequence_startup;
|
||||
std::string sequence_delta;
|
||||
std::string sequence_keep;
|
||||
private:
|
||||
bool blackhole;
|
||||
sockaddr_in* blackhole_addr;
|
||||
|
@ -371,9 +379,9 @@ public:
|
|||
std::string username();
|
||||
void set_encrypt(bool v);
|
||||
void switch_to_context();
|
||||
int context_id();
|
||||
std::string context_id();
|
||||
public:
|
||||
srs_error_t initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, std::string username, int context_id);
|
||||
srs_error_t initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, std::string username, std::string context_id);
|
||||
// The peer address may change, we can identify that by STUN messages.
|
||||
srs_error_t on_stun(SrsUdpMuxSocket* skt, SrsStunPacket* r);
|
||||
srs_error_t on_dtls(char* data, int nb_data);
|
||||
|
|
|
@ -320,7 +320,7 @@ srs_error_t SrsRtcServer::create_session(
|
|||
}
|
||||
}
|
||||
|
||||
int cid = _srs_context->get_id();
|
||||
std::string cid = _srs_context->get_id();
|
||||
SrsRtcSession* session = new SrsRtcSession(this);
|
||||
if ((err = session->initialize(source, req, publish, username, cid)) != srs_success) {
|
||||
srs_freep(session);
|
||||
|
@ -396,7 +396,7 @@ srs_error_t SrsRtcServer::setup_session2(SrsRtcSession* session, SrsRequest* req
|
|||
// TODO: FIXME: Collision detect.
|
||||
string username = session->get_local_sdp()->get_ice_ufrag() + ":" + remote_sdp.get_ice_ufrag();
|
||||
|
||||
int cid = _srs_context->get_id();
|
||||
std::string cid = _srs_context->get_id();
|
||||
if ((err = session->initialize(source, req, false, username, cid)) != srs_success) {
|
||||
return srs_error_wrap(err, "init");
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ srs_error_t SrsRtcConsumer::dump_packets(std::vector<SrsRtpPacket2*>& pkts)
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
if (should_update_source_id) {
|
||||
srs_trace("update source_id=%d[%d]", source->source_id(), source->source_id());
|
||||
srs_trace("update source_id=%d[%d]", source->source_id().c_str(), source->source_id().c_str());
|
||||
should_update_source_id = false;
|
||||
}
|
||||
|
||||
|
@ -232,9 +232,17 @@ SrsRtcSource* SrsRtcSourceManager::fetch(SrsRequest* r)
|
|||
|
||||
SrsRtcSourceManager* _srs_rtc_sources = new SrsRtcSourceManager();
|
||||
|
||||
ISrsRtcPublisher::ISrsRtcPublisher()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsRtcPublisher::~ISrsRtcPublisher()
|
||||
{
|
||||
}
|
||||
|
||||
SrsRtcSource::SrsRtcSource()
|
||||
{
|
||||
_source_id = _pre_source_id = -1;
|
||||
_source_id = _pre_source_id = "";
|
||||
_can_publish = true;
|
||||
rtc_publisher_ = NULL;
|
||||
|
||||
|
@ -270,7 +278,7 @@ void SrsRtcSource::update_auth(SrsRequest* r)
|
|||
req->update_auth(r);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcSource::on_source_id_changed(int id)
|
||||
srs_error_t SrsRtcSource::on_source_id_changed(std::string id)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -278,7 +286,7 @@ srs_error_t SrsRtcSource::on_source_id_changed(int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (_pre_source_id == -1) {
|
||||
if (_pre_source_id == "") {
|
||||
_pre_source_id = id;
|
||||
} else if (_pre_source_id != _source_id) {
|
||||
_pre_source_id = _source_id;
|
||||
|
@ -296,12 +304,12 @@ srs_error_t SrsRtcSource::on_source_id_changed(int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
int SrsRtcSource::source_id()
|
||||
std::string SrsRtcSource::source_id()
|
||||
{
|
||||
return _source_id;
|
||||
}
|
||||
|
||||
int SrsRtcSource::pre_source_id()
|
||||
std::string SrsRtcSource::pre_source_id()
|
||||
{
|
||||
return _pre_source_id;
|
||||
}
|
||||
|
@ -382,12 +390,12 @@ void SrsRtcSource::on_unpublish()
|
|||
// TODO: FIXME: Handle by statistic.
|
||||
}
|
||||
|
||||
SrsRtcPublisher* SrsRtcSource::rtc_publisher()
|
||||
ISrsRtcPublisher* SrsRtcSource::rtc_publisher()
|
||||
{
|
||||
return rtc_publisher_;
|
||||
}
|
||||
|
||||
void SrsRtcSource::set_rtc_publisher(SrsRtcPublisher* v)
|
||||
void SrsRtcSource::set_rtc_publisher(ISrsRtcPublisher* v)
|
||||
{
|
||||
rtc_publisher_ = v;
|
||||
}
|
||||
|
@ -416,6 +424,9 @@ SrsRtcFromRtmpBridger::SrsRtcFromRtmpBridger(SrsRtcSource* source)
|
|||
discard_bframe = false;
|
||||
merge_nalus = false;
|
||||
meta = new SrsMetaCache();
|
||||
audio_timestamp = 0;
|
||||
audio_sequence = 0;
|
||||
video_sequence = 0;
|
||||
}
|
||||
|
||||
SrsRtcFromRtmpBridger::~SrsRtcFromRtmpBridger()
|
||||
|
@ -584,6 +595,11 @@ srs_error_t SrsRtcFromRtmpBridger::package_opus(char* data, int size, SrsRtpPack
|
|||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeAudio;
|
||||
pkt->header.set_marker(true);
|
||||
pkt->header.set_sequence(audio_sequence++);
|
||||
pkt->header.set_timestamp(audio_timestamp);
|
||||
|
||||
// TODO: FIXME: Why 960? Need Refactoring?
|
||||
audio_timestamp += 960;
|
||||
|
||||
SrsRtpRawPayload* raw = new SrsRtpRawPayload();
|
||||
pkt->payload = raw;
|
||||
|
@ -641,25 +657,25 @@ srs_error_t SrsRtcFromRtmpBridger::on_video(SrsSharedPtrMessage* msg)
|
|||
if ((err = package_nalus(msg, samples, pkts)) != srs_success) {
|
||||
return srs_error_wrap(err, "package nalus as one");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// By default, we package each NALU(sample) to a RTP or FUA packet.
|
||||
for (int i = 0; i < nn_samples; i++) {
|
||||
SrsSample* sample = samples[i];
|
||||
|
||||
// By default, we package each NALU(sample) to a RTP or FUA packet.
|
||||
for (int i = 0; i < nn_samples; i++) {
|
||||
SrsSample* sample = samples[i];
|
||||
|
||||
// We always ignore bframe here, if config to discard bframe,
|
||||
// the bframe flag will not be set.
|
||||
if (sample->bframe) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sample->size <= kRtpMaxPayloadSize) {
|
||||
if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) {
|
||||
return srs_error_wrap(err, "package single nalu");
|
||||
// We always ignore bframe here, if config to discard bframe,
|
||||
// the bframe flag will not be set.
|
||||
if (sample->bframe) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((err = package_fu_a(msg, sample, kRtpMaxPayloadSize, pkts)) != srs_success) {
|
||||
return srs_error_wrap(err, "package fu-a");
|
||||
|
||||
if (sample->size <= kRtpMaxPayloadSize) {
|
||||
if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) {
|
||||
return srs_error_wrap(err, "package single nalu");
|
||||
}
|
||||
} else {
|
||||
if ((err = package_fu_a(msg, sample, kRtpMaxPayloadSize, pkts)) != srs_success) {
|
||||
return srs_error_wrap(err, "package fu-a");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -720,6 +736,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcSource* source, SrsShare
|
|||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
pkt->header.set_marker(false);
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_timestamp(msg->timestamp * 90);
|
||||
|
||||
SrsRtpSTAPPayload* stap = new SrsRtpSTAPPayload();
|
||||
|
@ -755,7 +772,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcSource* source, SrsShare
|
|||
}
|
||||
|
||||
*ppkt = pkt;
|
||||
srs_trace("RTC STAP-A seq=%u, sps %d, pps %d bytes", pkt->header.get_sequence(), sps.size(), pps.size());
|
||||
srs_info("RTC STAP-A seq=%u, sps %d, pps %d bytes", pkt->header.get_sequence(), sps.size(), pps.size());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -789,6 +806,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
|
|||
// Package NALUs in a single RTP packet.
|
||||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_timestamp(msg->timestamp * 90);
|
||||
pkt->payload = raw;
|
||||
pkt->shared_msg = msg->copy();
|
||||
|
@ -818,6 +836,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
|
|||
|
||||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_timestamp(msg->timestamp * 90);
|
||||
|
||||
fua->nri = (SrsAvcNaluType)header;
|
||||
|
@ -843,6 +862,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_single_nalu(SrsSharedPtrMessage* msg,
|
|||
|
||||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_timestamp(msg->timestamp * 90);
|
||||
|
||||
SrsRtpRawPayload* raw = new SrsRtpRawPayload();
|
||||
|
@ -872,6 +892,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_fu_a(SrsSharedPtrMessage* msg, SrsSam
|
|||
|
||||
SrsRtpPacket2* pkt = new SrsRtpPacket2();
|
||||
pkt->frame_type = SrsFrameTypeVideo;
|
||||
pkt->header.set_sequence(video_sequence++);
|
||||
pkt->header.set_timestamp(msg->timestamp * 90);
|
||||
|
||||
SrsRtpFUAPayload2* fua = new SrsRtpFUAPayload2();
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
class SrsRequest;
|
||||
class SrsConnection;
|
||||
class SrsMetaCache;
|
||||
class SrsRtcPublisher;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsCommonMessage;
|
||||
class SrsMessageArray;
|
||||
|
@ -94,6 +93,15 @@ private:
|
|||
// Global singleton instance.
|
||||
extern SrsRtcSourceManager* _srs_rtc_sources;
|
||||
|
||||
class ISrsRtcPublisher
|
||||
{
|
||||
public:
|
||||
ISrsRtcPublisher();
|
||||
virtual ~ISrsRtcPublisher();
|
||||
public:
|
||||
virtual void request_keyframe() = 0;
|
||||
};
|
||||
|
||||
class SrsRtcSource
|
||||
{
|
||||
private:
|
||||
|
@ -101,11 +109,11 @@ private:
|
|||
// For edge, it's the edge ingest id.
|
||||
// when source id changed, for example, the edge reconnect,
|
||||
// invoke the on_source_id_changed() to let all clients know.
|
||||
int _source_id;
|
||||
std::string _source_id;
|
||||
// previous source id.
|
||||
int _pre_source_id;
|
||||
std::string _pre_source_id;
|
||||
SrsRequest* req;
|
||||
SrsRtcPublisher* rtc_publisher_;
|
||||
ISrsRtcPublisher* rtc_publisher_;
|
||||
// Transmux RTMP to RTC.
|
||||
SrsRtcFromRtmpBridger* bridger_;
|
||||
private:
|
||||
|
@ -121,10 +129,10 @@ public:
|
|||
// Update the authentication information in request.
|
||||
virtual void update_auth(SrsRequest* r);
|
||||
// The source id changed.
|
||||
virtual srs_error_t on_source_id_changed(int id);
|
||||
virtual srs_error_t on_source_id_changed(std::string id);
|
||||
// Get current source id.
|
||||
virtual int source_id();
|
||||
virtual int pre_source_id();
|
||||
virtual std::string source_id();
|
||||
virtual std::string pre_source_id();
|
||||
// Get the bridger.
|
||||
ISrsSourceBridger* bridger();
|
||||
public:
|
||||
|
@ -145,8 +153,8 @@ public:
|
|||
virtual void on_unpublish();
|
||||
public:
|
||||
// Get and set the publisher, passed to consumer to process requests such as PLI.
|
||||
SrsRtcPublisher* rtc_publisher();
|
||||
void set_rtc_publisher(SrsRtcPublisher* v);
|
||||
ISrsRtcPublisher* rtc_publisher();
|
||||
void set_rtc_publisher(ISrsRtcPublisher* v);
|
||||
// Consume the shared RTP packet, user must free it.
|
||||
srs_error_t on_rtp(SrsRtpPacket2* pkt);
|
||||
};
|
||||
|
@ -165,6 +173,9 @@ private:
|
|||
SrsAudioRecode* codec;
|
||||
bool discard_bframe;
|
||||
bool merge_nalus;
|
||||
uint32_t audio_timestamp;
|
||||
uint16_t audio_sequence;
|
||||
uint16_t video_sequence;
|
||||
public:
|
||||
SrsRtcFromRtmpBridger(SrsRtcSource* source);
|
||||
virtual ~SrsRtcFromRtmpBridger();
|
||||
|
|
|
@ -515,8 +515,8 @@ srs_error_t SrsRtmpConn::stream_service_cycle()
|
|||
}
|
||||
|
||||
bool enabled_cache = _srs_config->get_gop_cache(req->vhost);
|
||||
srs_trace("source url=%s, ip=%s, cache=%d, is_edge=%d, source_id=[%d][%d]",
|
||||
req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, ::getpid(), source->source_id());
|
||||
srs_trace("source url=%s, ip=%s, cache=%d, is_edge=%d, source_id=[%d][%s]",
|
||||
req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, ::getpid(), source->source_id().c_str());
|
||||
source->set_cache(enabled_cache);
|
||||
|
||||
switch (info->type) {
|
||||
|
|
|
@ -120,9 +120,11 @@ srs_error_t SrsRtpConn::on_udp_packet(const sockaddr* from, const int fromlen, c
|
|||
|
||||
// always free it.
|
||||
SrsAutoFree(SrsRtpPacket, cache);
|
||||
|
||||
if ((err = rtsp->on_rtp_packet(cache, stream_id)) != srs_success) {
|
||||
return srs_error_wrap(err, "process rtp packet");
|
||||
|
||||
err = rtsp->on_rtp_packet(cache, stream_id);
|
||||
if (err != srs_success) {
|
||||
srs_warn("ignore RTP packet err %s", srs_error_desc(err).c_str());
|
||||
srs_freep(err);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -495,54 +497,62 @@ srs_error_t SrsRtspConn::write_sequence_header()
|
|||
}
|
||||
|
||||
// generate audio sh by audio specific config.
|
||||
if (true) {
|
||||
std::string sh = aac_specific_config;
|
||||
|
||||
SrsFormat* format = new SrsFormat();
|
||||
SrsAutoFree(SrsFormat, format);
|
||||
|
||||
if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) {
|
||||
return srs_error_wrap(err, "on aac sequence header");
|
||||
}
|
||||
|
||||
SrsAudioCodecConfig* dec = format->acodec;
|
||||
|
||||
acodec->sound_format = SrsAudioCodecIdAAC;
|
||||
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
|
||||
acodec->sound_size = SrsAudioSampleBits16bit;
|
||||
acodec->aac_packet_type = 0;
|
||||
|
||||
static int srs_aac_srates[] = {
|
||||
96000, 88200, 64000, 48000,
|
||||
44100, 32000, 24000, 22050,
|
||||
16000, 12000, 11025, 8000,
|
||||
7350, 0, 0, 0
|
||||
};
|
||||
switch (srs_aac_srates[dec->aac_sample_rate]) {
|
||||
case 11025:
|
||||
acodec->sound_rate = SrsAudioSampleRate11025;
|
||||
break;
|
||||
case 22050:
|
||||
acodec->sound_rate = SrsAudioSampleRate22050;
|
||||
break;
|
||||
case 44100:
|
||||
acodec->sound_rate = SrsAudioSampleRate44100;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "write audio raw frame");
|
||||
}
|
||||
if (aac_specific_config.empty()) {
|
||||
srs_warn("no audio asc");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
std::string sh = aac_specific_config;
|
||||
|
||||
SrsFormat* format = new SrsFormat();
|
||||
SrsAutoFree(SrsFormat, format);
|
||||
|
||||
if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) {
|
||||
return srs_error_wrap(err, "on aac sequence header");
|
||||
}
|
||||
|
||||
SrsAudioCodecConfig* dec = format->acodec;
|
||||
|
||||
acodec->sound_format = SrsAudioCodecIdAAC;
|
||||
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
|
||||
acodec->sound_size = SrsAudioSampleBits16bit;
|
||||
acodec->aac_packet_type = 0;
|
||||
|
||||
static int srs_aac_srates[] = {
|
||||
96000, 88200, 64000, 48000,
|
||||
44100, 32000, 24000, 22050,
|
||||
16000, 12000, 11025, 8000,
|
||||
7350, 0, 0, 0
|
||||
};
|
||||
switch (srs_aac_srates[dec->aac_sample_rate]) {
|
||||
case 11025:
|
||||
acodec->sound_rate = SrsAudioSampleRate11025;
|
||||
break;
|
||||
case 22050:
|
||||
acodec->sound_rate = SrsAudioSampleRate22050;
|
||||
break;
|
||||
case 44100:
|
||||
acodec->sound_rate = SrsAudioSampleRate44100;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) {
|
||||
return srs_error_wrap(err, "write audio raw frame");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspConn::write_h264_sps_pps(uint32_t dts, uint32_t pts)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (h264_sps.empty() || h264_pps.empty()) {
|
||||
srs_warn("no sps=%dB or pps=%dB", (int)h264_sps.size(), (int)h264_pps.size());
|
||||
return err;
|
||||
}
|
||||
|
||||
// h264 raw to h264 packet.
|
||||
std::string sh;
|
||||
|
@ -687,6 +697,7 @@ void SrsRtspConn::close()
|
|||
SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
|
||||
{
|
||||
// TODO: FIXME: support reload.
|
||||
engine = _srs_config->get_stream_caster_engine(c);
|
||||
output = _srs_config->get_stream_caster_output(c);
|
||||
local_port_min = _srs_config->get_stream_caster_rtp_port_min(c);
|
||||
local_port_max = _srs_config->get_stream_caster_rtp_port_max(c);
|
||||
|
@ -728,7 +739,7 @@ srs_error_t SrsRtspCaster::alloc_port(int* pport)
|
|||
break;
|
||||
}
|
||||
}
|
||||
srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1);
|
||||
srs_trace("rtsp: %s alloc port=%d-%d", engine.c_str(), *pport, *pport + 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -738,7 +749,7 @@ void SrsRtspCaster::free_port(int lpmin, int lpmax)
|
|||
for (int i = lpmin; i < lpmax; i++) {
|
||||
used_ports[i] = false;
|
||||
}
|
||||
srs_trace("rtsp: free rtp port=%d-%d", lpmin, lpmax);
|
||||
srs_trace("rtsp: %s free rtp port=%d-%d", engine.c_str(), lpmin, lpmax);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtspCaster::on_tcp_client(srs_netfd_t stfd)
|
||||
|
|
|
@ -173,6 +173,7 @@ private:
|
|||
class SrsRtspCaster : public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
std::string engine;
|
||||
std::string output;
|
||||
int local_port_min;
|
||||
int local_port_max;
|
||||
|
|
|
@ -825,8 +825,8 @@ srs_error_t SrsServer::initialize_st()
|
|||
return srs_error_new(ERROR_SYSTEM_ASSERT_FAILED, "ppid=%d illegal for asprocess", ppid);
|
||||
}
|
||||
|
||||
srs_trace("server main cid=%d, pid=%d, ppid=%d, asprocess=%d",
|
||||
_srs_context->get_id(), ::getpid(), ppid, asprocess);
|
||||
srs_trace("server main cid=%s, pid=%d, ppid=%d, asprocess=%d",
|
||||
_srs_context->get_id().c_str(), ::getpid(), ppid, asprocess);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@ srs_error_t SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count)
|
|||
count = 0;
|
||||
|
||||
if (should_update_source_id) {
|
||||
srs_trace("update source_id=%d[%d]", source->source_id(), source->source_id());
|
||||
srs_trace("update source_id=%s[%s]", source->source_id().c_str(), source->source_id().c_str());
|
||||
should_update_source_id = false;
|
||||
}
|
||||
|
||||
|
@ -1792,7 +1792,7 @@ void SrsSourceManager::dispose()
|
|||
|
||||
srs_error_t SrsSourceManager::cycle()
|
||||
{
|
||||
int cid = _srs_context->get_id();
|
||||
std::string cid = _srs_context->get_id();
|
||||
srs_error_t err = do_cycle();
|
||||
_srs_context->set_id(cid);
|
||||
|
||||
|
@ -1809,7 +1809,7 @@ srs_error_t SrsSourceManager::do_cycle()
|
|||
|
||||
// Do cycle source to cleanup components, such as hls dispose.
|
||||
if ((err = source->cycle()) != srs_success) {
|
||||
return srs_error_wrap(err, "source=%d/%d cycle", source->source_id(), source->pre_source_id());
|
||||
return srs_error_wrap(err, "source=%s/%s cycle", source->source_id().c_str(), source->pre_source_id().c_str());
|
||||
}
|
||||
|
||||
// TODO: FIXME: support source cleanup.
|
||||
|
@ -1866,7 +1866,7 @@ SrsSource::SrsSource()
|
|||
mix_queue = new SrsMixQueue();
|
||||
|
||||
_can_publish = true;
|
||||
_pre_source_id = _source_id = -1;
|
||||
_pre_source_id = _source_id = "";
|
||||
die_at = 0;
|
||||
|
||||
handler = NULL;
|
||||
|
@ -2065,7 +2065,7 @@ srs_error_t SrsSource::on_reload_vhost_play(string vhost)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsSource::on_source_id_changed(int id)
|
||||
srs_error_t SrsSource::on_source_id_changed(string id)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -2073,7 +2073,7 @@ srs_error_t SrsSource::on_source_id_changed(int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (_pre_source_id == -1) {
|
||||
if (_pre_source_id == "") {
|
||||
_pre_source_id = id;
|
||||
} else if (_pre_source_id != _source_id) {
|
||||
_pre_source_id = _source_id;
|
||||
|
@ -2091,12 +2091,12 @@ srs_error_t SrsSource::on_source_id_changed(int id)
|
|||
return err;
|
||||
}
|
||||
|
||||
int SrsSource::source_id()
|
||||
string SrsSource::source_id()
|
||||
{
|
||||
return _source_id;
|
||||
}
|
||||
|
||||
int SrsSource::pre_source_id()
|
||||
string SrsSource::pre_source_id()
|
||||
{
|
||||
return _pre_source_id;
|
||||
}
|
||||
|
|
|
@ -508,9 +508,9 @@ private:
|
|||
// For edge, it's the edge ingest id.
|
||||
// when source id changed, for example, the edge reconnect,
|
||||
// invoke the on_source_id_changed() to let all clients know.
|
||||
int _source_id;
|
||||
std::string _source_id;
|
||||
// previous source id.
|
||||
int _pre_source_id;
|
||||
std::string _pre_source_id;
|
||||
// deep copy of client request.
|
||||
SrsRequest* req;
|
||||
// To delivery stream to clients.
|
||||
|
@ -567,10 +567,10 @@ public:
|
|||
virtual srs_error_t on_reload_vhost_play(std::string vhost);
|
||||
public:
|
||||
// The source id changed.
|
||||
virtual srs_error_t on_source_id_changed(int id);
|
||||
virtual srs_error_t on_source_id_changed(std::string id);
|
||||
// Get current source id.
|
||||
virtual int source_id();
|
||||
virtual int pre_source_id();
|
||||
virtual std::string source_id();
|
||||
virtual std::string pre_source_id();
|
||||
// Whether source is inactive, which means there is no publishing stream source.
|
||||
// @remark For edge, it's inactive util stream has been pulled from origin.
|
||||
virtual bool inactive();
|
||||
|
|
|
@ -74,14 +74,14 @@ srs_error_t SrsDummyCoroutine::pull()
|
|||
return srs_error_new(ERROR_THREAD_DUMMY, "dummy pull");
|
||||
}
|
||||
|
||||
int SrsDummyCoroutine::cid()
|
||||
string SrsDummyCoroutine::cid()
|
||||
{
|
||||
return 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
_ST_THREAD_CREATE_PFN _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)st_thread_create;
|
||||
|
||||
SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h, int cid)
|
||||
SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h, std::string cid)
|
||||
{
|
||||
name = n;
|
||||
handler = h;
|
||||
|
@ -180,7 +180,7 @@ srs_error_t SrsSTCoroutine::pull()
|
|||
return srs_error_copy(trd_err);
|
||||
}
|
||||
|
||||
int SrsSTCoroutine::cid()
|
||||
string SrsSTCoroutine::cid()
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ int SrsSTCoroutine::cid()
|
|||
srs_error_t SrsSTCoroutine::cycle()
|
||||
{
|
||||
if (_srs_context) {
|
||||
if (context) {
|
||||
if (!context.empty()) {
|
||||
_srs_context->set_id(context);
|
||||
} else {
|
||||
context = _srs_context->generate_id();
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
// @return a copy of error, which should be freed by user.
|
||||
// NULL if not terminated and user should pull again.
|
||||
virtual srs_error_t pull() = 0;
|
||||
virtual int cid() = 0;
|
||||
virtual std::string cid() = 0;
|
||||
};
|
||||
|
||||
// An empty coroutine, user can default to this object before create any real coroutine.
|
||||
|
@ -95,7 +95,7 @@ public:
|
|||
virtual void stop();
|
||||
virtual void interrupt();
|
||||
virtual srs_error_t pull();
|
||||
virtual int cid();
|
||||
virtual std::string cid();
|
||||
};
|
||||
|
||||
// For utest to mock the thread create.
|
||||
|
@ -121,7 +121,7 @@ private:
|
|||
ISrsCoroutineHandler* handler;
|
||||
private:
|
||||
srs_thread_t trd;
|
||||
int context;
|
||||
std::string context;
|
||||
srs_error_t trd_err;
|
||||
private:
|
||||
bool started;
|
||||
|
@ -132,7 +132,7 @@ private:
|
|||
public:
|
||||
// Create a thread with name n and handler h.
|
||||
// @remark User can specify a cid for thread to use, or we will allocate a new one.
|
||||
SrsSTCoroutine(std::string n, ISrsCoroutineHandler* h, int cid = 0);
|
||||
SrsSTCoroutine(std::string n, ISrsCoroutineHandler* h, std::string cid = "");
|
||||
virtual ~SrsSTCoroutine();
|
||||
public:
|
||||
// Start the thread.
|
||||
|
@ -154,7 +154,7 @@ public:
|
|||
// @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
|
||||
virtual srs_error_t pull();
|
||||
// Get the context id of thread.
|
||||
virtual int cid();
|
||||
virtual std::string cid();
|
||||
private:
|
||||
virtual srs_error_t cycle();
|
||||
static void* pfn(void* arg);
|
||||
|
|
|
@ -71,7 +71,7 @@ srs_error_t SrsStatisticVhost::dumps(SrsJsonObject* obj)
|
|||
bool hls_enabled = _srs_config->get_hls_enabled(vhost);
|
||||
bool enabled = _srs_config->get_vhost_enabled(vhost);
|
||||
|
||||
obj->set("id", SrsJsonAny::integer(id));
|
||||
obj->set("id", SrsJsonAny::str(id.c_str()));
|
||||
obj->set("name", SrsJsonAny::str(vhost.c_str()));
|
||||
obj->set("enabled", SrsJsonAny::boolean(enabled));
|
||||
obj->set("clients", SrsJsonAny::integer(nb_clients));
|
||||
|
@ -134,9 +134,9 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
obj->set("id", SrsJsonAny::integer(id));
|
||||
obj->set("id", SrsJsonAny::str(id.c_str()));
|
||||
obj->set("name", SrsJsonAny::str(stream.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::integer(vhost->id));
|
||||
obj->set("vhost", SrsJsonAny::str(vhost->id.c_str()));
|
||||
obj->set("app", SrsJsonAny::str(app.c_str()));
|
||||
obj->set("live_ms", SrsJsonAny::integer(srsu2ms(srs_get_system_time())));
|
||||
obj->set("clients", SrsJsonAny::integer(nb_clients));
|
||||
|
@ -154,7 +154,7 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
|
|||
obj->set("publish", publish);
|
||||
|
||||
publish->set("active", SrsJsonAny::boolean(active));
|
||||
publish->set("cid", SrsJsonAny::integer(connection_cid));
|
||||
publish->set("cid", SrsJsonAny::str(connection_cid.c_str()));
|
||||
|
||||
if (!has_video) {
|
||||
obj->set("video", SrsJsonAny::null());
|
||||
|
@ -184,7 +184,7 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsStatisticStream::publish(int cid)
|
||||
void SrsStatisticStream::publish(string cid)
|
||||
{
|
||||
connection_cid = cid;
|
||||
active = true;
|
||||
|
@ -203,7 +203,7 @@ void SrsStatisticStream::close()
|
|||
|
||||
SrsStatisticClient::SrsStatisticClient()
|
||||
{
|
||||
id = 0;
|
||||
id = "";
|
||||
stream = NULL;
|
||||
conn = NULL;
|
||||
req = NULL;
|
||||
|
@ -219,9 +219,9 @@ srs_error_t SrsStatisticClient::dumps(SrsJsonObject* obj)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
obj->set("id", SrsJsonAny::integer(id));
|
||||
obj->set("vhost", SrsJsonAny::integer(stream->vhost->id));
|
||||
obj->set("stream", SrsJsonAny::integer(stream->id));
|
||||
obj->set("id", SrsJsonAny::str(id.c_str()));
|
||||
obj->set("vhost", SrsJsonAny::str(stream->vhost->id.c_str()));
|
||||
obj->set("stream", SrsJsonAny::str(stream->id.c_str()));
|
||||
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
||||
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
|
||||
obj->set("swfUrl", SrsJsonAny::str(req->swfUrl.c_str()));
|
||||
|
@ -278,21 +278,21 @@ SrsStatistic::~SrsStatistic()
|
|||
srs_freep(clk);
|
||||
|
||||
if (true) {
|
||||
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
||||
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
||||
SrsStatisticVhost* vhost = it->second;
|
||||
srs_freep(vhost);
|
||||
}
|
||||
}
|
||||
if (true) {
|
||||
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
||||
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||
for (it = streams.begin(); it != streams.end(); it++) {
|
||||
SrsStatisticStream* stream = it->second;
|
||||
srs_freep(stream);
|
||||
}
|
||||
}
|
||||
if (true) {
|
||||
std::map<int, SrsStatisticClient*>::iterator it;
|
||||
std::map<std::string, SrsStatisticClient*>::iterator it;
|
||||
for (it = clients.begin(); it != clients.end(); it++) {
|
||||
SrsStatisticClient* client = it->second;
|
||||
srs_freep(client);
|
||||
|
@ -319,40 +319,27 @@ SrsStatistic* SrsStatistic::instance()
|
|||
return _instance;
|
||||
}
|
||||
|
||||
SrsStatisticVhost* SrsStatistic::find_vhost(int vid)
|
||||
SrsStatisticVhost* SrsStatistic::find_vhost(string vid)
|
||||
{
|
||||
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
||||
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||
if ((it = vhosts.find(vid)) != vhosts.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SrsStatisticVhost* SrsStatistic::find_vhost(string name)
|
||||
SrsStatisticStream* SrsStatistic::find_stream(string sid)
|
||||
{
|
||||
if (rvhosts.empty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::map<string, SrsStatisticVhost*>::iterator it;
|
||||
if ((it = rvhosts.find(name)) != rvhosts.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SrsStatisticStream* SrsStatistic::find_stream(int sid)
|
||||
{
|
||||
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
||||
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||
if ((it = streams.find(sid)) != streams.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SrsStatisticClient* SrsStatistic::find_client(int cid)
|
||||
SrsStatisticClient* SrsStatistic::find_client(string cid)
|
||||
{
|
||||
std::map<int, SrsStatisticClient*>::iterator it;
|
||||
std::map<std::string, SrsStatisticClient*>::iterator it;
|
||||
if ((it = clients.find(cid)) != clients.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
@ -405,7 +392,7 @@ srs_error_t SrsStatistic::on_video_frames(SrsRequest* req, int nb_frames)
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsStatistic::on_stream_publish(SrsRequest* req, int cid)
|
||||
void SrsStatistic::on_stream_publish(SrsRequest* req, string cid)
|
||||
{
|
||||
SrsStatisticVhost* vhost = create_vhost(req);
|
||||
SrsStatisticStream* stream = create_stream(vhost, req);
|
||||
|
@ -421,7 +408,7 @@ void SrsStatistic::on_stream_close(SrsRequest* req)
|
|||
|
||||
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
|
||||
if (true) {
|
||||
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
||||
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||
if ((it=streams.find(stream->id)) != streams.end()) {
|
||||
streams.erase(it);
|
||||
}
|
||||
|
@ -436,7 +423,7 @@ void SrsStatistic::on_stream_close(SrsRequest* req)
|
|||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
|
||||
srs_error_t SrsStatistic::on_client(std::string id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -464,9 +451,9 @@ srs_error_t SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn
|
|||
return err;
|
||||
}
|
||||
|
||||
void SrsStatistic::on_disconnect(int id)
|
||||
void SrsStatistic::on_disconnect(std::string id)
|
||||
{
|
||||
std::map<int, SrsStatisticClient*>::iterator it;
|
||||
std::map<std::string, SrsStatisticClient*>::iterator it;
|
||||
if ((it = clients.find(id)) == clients.end()) {
|
||||
return;
|
||||
}
|
||||
|
@ -484,7 +471,7 @@ void SrsStatistic::on_disconnect(int id)
|
|||
|
||||
void SrsStatistic::kbps_add_delta(SrsConnection* conn)
|
||||
{
|
||||
int id = conn->srs_id();
|
||||
std::string id = conn->srs_id();
|
||||
if (clients.find(id) == clients.end()) {
|
||||
return;
|
||||
}
|
||||
|
@ -506,14 +493,14 @@ SrsKbps* SrsStatistic::kbps_sample()
|
|||
{
|
||||
kbps->sample();
|
||||
if (true) {
|
||||
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
||||
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
||||
SrsStatisticVhost* vhost = it->second;
|
||||
vhost->kbps->sample();
|
||||
}
|
||||
}
|
||||
if (true) {
|
||||
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
||||
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||
for (it = streams.begin(); it != streams.end(); it++) {
|
||||
SrsStatisticStream* stream = it->second;
|
||||
stream->kbps->sample();
|
||||
|
@ -532,7 +519,7 @@ srs_error_t SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
||||
std::map<std::string, SrsStatisticVhost*>::iterator it;
|
||||
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
||||
SrsStatisticVhost* vhost = it->second;
|
||||
|
||||
|
@ -551,7 +538,7 @@ srs_error_t SrsStatistic::dumps_streams(SrsJsonArray* arr)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
||||
std::map<std::string, SrsStatisticStream*>::iterator it;
|
||||
for (it = streams.begin(); it != streams.end(); it++) {
|
||||
SrsStatisticStream* stream = it->second;
|
||||
|
||||
|
@ -570,7 +557,7 @@ srs_error_t SrsStatistic::dumps_clients(SrsJsonArray* arr, int start, int count)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
std::map<int, SrsStatisticClient*>::iterator it = clients.begin();
|
||||
std::map<std::string, SrsStatisticClient*>::iterator it = clients.begin();
|
||||
for (int i = 0; i < start + count && it != clients.end(); it++, i++) {
|
||||
if (i < start) {
|
||||
continue;
|
||||
|
|
|
@ -43,7 +43,7 @@ class SrsJsonArray;
|
|||
struct SrsStatisticVhost
|
||||
{
|
||||
public:
|
||||
int64_t id;
|
||||
std::string id;
|
||||
std::string vhost;
|
||||
int nb_streams;
|
||||
int nb_clients;
|
||||
|
@ -61,13 +61,13 @@ public:
|
|||
struct SrsStatisticStream
|
||||
{
|
||||
public:
|
||||
int64_t id;
|
||||
std::string id;
|
||||
SrsStatisticVhost* vhost;
|
||||
std::string app;
|
||||
std::string stream;
|
||||
std::string url;
|
||||
bool active;
|
||||
int connection_cid;
|
||||
std::string connection_cid;
|
||||
int nb_clients;
|
||||
uint64_t nb_frames;
|
||||
public:
|
||||
|
@ -101,7 +101,7 @@ public:
|
|||
virtual srs_error_t dumps(SrsJsonObject* obj);
|
||||
public:
|
||||
// Publish the stream.
|
||||
virtual void publish(int cid);
|
||||
virtual void publish(std::string cid);
|
||||
// Close the stream.
|
||||
virtual void close();
|
||||
};
|
||||
|
@ -113,7 +113,7 @@ public:
|
|||
SrsConnection* conn;
|
||||
SrsRequest* req;
|
||||
SrsRtmpConnType type;
|
||||
int id;
|
||||
std::string id;
|
||||
srs_utime_t create;
|
||||
public:
|
||||
SrsStatisticClient();
|
||||
|
@ -151,19 +151,19 @@ private:
|
|||
int64_t _server_id;
|
||||
private:
|
||||
// The key: vhost id, value: vhost object.
|
||||
std::map<int64_t, SrsStatisticVhost*> vhosts;
|
||||
std::map<std::string, SrsStatisticVhost*> vhosts;
|
||||
// The key: vhost url, value: vhost Object.
|
||||
// @remark a fast index for vhosts.
|
||||
std::map<std::string, SrsStatisticVhost*> rvhosts;
|
||||
private:
|
||||
// The key: stream id, value: stream Object.
|
||||
std::map<int64_t, SrsStatisticStream*> streams;
|
||||
std::map<std::string, SrsStatisticStream*> streams;
|
||||
// The key: stream url, value: stream Object.
|
||||
// @remark a fast index for streams.
|
||||
std::map<std::string, SrsStatisticStream*> rstreams;
|
||||
private:
|
||||
// The key: client id, value: stream object.
|
||||
std::map<int, SrsStatisticClient*> clients;
|
||||
std::map<std::string, SrsStatisticClient*> clients;
|
||||
// The server total kbps.
|
||||
SrsKbps* kbps;
|
||||
SrsWallClock* clk;
|
||||
|
@ -179,10 +179,9 @@ private:
|
|||
public:
|
||||
static SrsStatistic* instance();
|
||||
public:
|
||||
virtual SrsStatisticVhost* find_vhost(int vid);
|
||||
virtual SrsStatisticVhost* find_vhost(std::string name);
|
||||
virtual SrsStatisticStream* find_stream(int sid);
|
||||
virtual SrsStatisticClient* find_client(int cid);
|
||||
virtual SrsStatisticVhost* find_vhost(std::string vid);
|
||||
virtual SrsStatisticStream* find_stream(std::string sid);
|
||||
virtual SrsStatisticClient* find_client(std::string cid);
|
||||
public:
|
||||
// When got video info for stream.
|
||||
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile,
|
||||
|
@ -196,7 +195,7 @@ public:
|
|||
// When publish stream.
|
||||
// @param req the request object of publish connection.
|
||||
// @param cid the cid of publish connection.
|
||||
virtual void on_stream_publish(SrsRequest* req, int cid);
|
||||
virtual void on_stream_publish(SrsRequest* req, std::string cid);
|
||||
// When close stream.
|
||||
virtual void on_stream_close(SrsRequest* req);
|
||||
public:
|
||||
|
@ -205,12 +204,12 @@ public:
|
|||
// @param req, the client request object.
|
||||
// @param conn, the physical absract connection object.
|
||||
// @param type, the type of connection.
|
||||
virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
|
||||
virtual srs_error_t on_client(std::string id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
|
||||
// Client disconnect
|
||||
// @remark the on_disconnect always call, while the on_client is call when
|
||||
// only got the request object, so the client specified by id maybe not
|
||||
// exists in stat.
|
||||
virtual void on_disconnect(int id);
|
||||
virtual void on_disconnect(std::string id);
|
||||
// Sample the kbps, add delta bytes of conn.
|
||||
// Use kbps_sample() to get all result of kbps stat.
|
||||
// TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead.
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <srs_kernel_log.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
SrsCoroutineManager::SrsCoroutineManager()
|
||||
|
@ -72,7 +73,9 @@ srs_error_t SrsCoroutineManager::cycle()
|
|||
|
||||
void SrsCoroutineManager::remove(ISrsConnection* c)
|
||||
{
|
||||
conns.push_back(c);
|
||||
if (::find(conns.begin(), conns.end(), c) == conns.end()) {
|
||||
conns.push_back(c);
|
||||
}
|
||||
srs_cond_signal(cond);
|
||||
}
|
||||
|
||||
|
@ -80,8 +83,8 @@ void SrsCoroutineManager::clear()
|
|||
{
|
||||
// To prevent thread switch when delete connection,
|
||||
// we copy all connections then free one by one.
|
||||
vector<ISrsConnection*> copy = conns;
|
||||
conns.clear();
|
||||
vector<ISrsConnection*> copy;
|
||||
copy.swap(conns);
|
||||
|
||||
vector<ISrsConnection*>::iterator it;
|
||||
for (it = copy.begin(); it != copy.end(); ++it) {
|
||||
|
|
|
@ -24,6 +24,6 @@
|
|||
#ifndef SRS_CORE_VERSION4_HPP
|
||||
#define SRS_CORE_VERSION4_HPP
|
||||
|
||||
#define SRS_VERSION4_REVISION 29
|
||||
#define SRS_VERSION4_REVISION 30
|
||||
|
||||
#endif
|
||||
|
|
|
@ -411,7 +411,7 @@ private:
|
|||
std::string file;
|
||||
int line;
|
||||
|
||||
int cid;
|
||||
std::string cid;
|
||||
int rerrno;
|
||||
|
||||
std::string desc;
|
||||
|
|
|
@ -42,23 +42,23 @@ void ISrsLog::reopen()
|
|||
{
|
||||
}
|
||||
|
||||
void ISrsLog::verbose(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
|
||||
void ISrsLog::verbose(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void ISrsLog::info(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
|
||||
void ISrsLog::info(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void ISrsLog::trace(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
|
||||
void ISrsLog::trace(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void ISrsLog::warn(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
|
||||
void ISrsLog::warn(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
|
||||
{
|
||||
}
|
||||
|
||||
void ISrsLog::error(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
|
||||
void ISrsLog::error(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,19 +70,19 @@ ISrsThreadContext::~ISrsThreadContext()
|
|||
{
|
||||
}
|
||||
|
||||
int ISrsThreadContext::generate_id()
|
||||
std::string ISrsThreadContext::generate_id()
|
||||
{
|
||||
return 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
int ISrsThreadContext::get_id()
|
||||
std::string ISrsThreadContext::get_id()
|
||||
{
|
||||
return 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
int ISrsThreadContext::set_id(int /*v*/)
|
||||
std::string ISrsThreadContext::set_id(std::string /*v*/)
|
||||
{
|
||||
return 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include <srs_kernel_consts.hpp>
|
||||
|
||||
|
@ -64,16 +65,16 @@ public:
|
|||
virtual void reopen();
|
||||
public:
|
||||
// The log for verbose, very verbose information.
|
||||
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
// The log for debug, detail information.
|
||||
virtual void info(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
// The log for trace, important information.
|
||||
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
// The log for warn, warn is something should take attention, but not a error.
|
||||
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
// The log for error, something error occur, do something about the error, ie. close the connection,
|
||||
// but we will donot abort the program.
|
||||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
};
|
||||
|
||||
// The context id manager to identify context, for instance, the green-thread.
|
||||
|
@ -89,12 +90,12 @@ public:
|
|||
virtual ~ISrsThreadContext();
|
||||
public:
|
||||
// Generate the id for current context.
|
||||
virtual int generate_id();
|
||||
virtual std::string generate_id();
|
||||
// Get the generated id of current context.
|
||||
virtual int get_id();
|
||||
virtual std::string get_id();
|
||||
// Set the id of current context.
|
||||
// @return the previous id value; 0 if no context.
|
||||
virtual int set_id(int v);
|
||||
virtual std::string set_id(std::string v);
|
||||
};
|
||||
|
||||
// @global User must provides a log object
|
||||
|
@ -107,25 +108,25 @@ extern ISrsThreadContext* _srs_context;
|
|||
// Use __FUNCTION__ to print c method
|
||||
// Use __PRETTY_FUNCTION__ to print c++ class:method
|
||||
#if 1
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
#if 0
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
#if 0
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_warn(msg, ...) _srs_log->warn(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// TODO: FIXME: Add more verbose and info logs.
|
||||
|
|
|
@ -119,17 +119,11 @@ SrsRtpHeader::~SrsRtpHeader()
|
|||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap *extension_map)
|
||||
{
|
||||
srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf) {
|
||||
srs_error_t err = srs_success;
|
||||
uint16_t profile_id = buf->read_2bytes();
|
||||
extension_length = buf->read_2bytes();
|
||||
|
||||
if (!extension_map) {
|
||||
buf->skip(extension_length * 4);
|
||||
return err;
|
||||
}
|
||||
|
||||
// @see: https://tools.ietf.org/html/rfc5285#section-4.2
|
||||
if (profile_id == 0xBEDE) {
|
||||
uint32_t xlen = extension_length * 4;
|
||||
|
@ -151,7 +145,7 @@ srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExte
|
|||
uint8_t id = (id_len & 0xF0) >> 4;
|
||||
uint8_t len = (id_len & 0x0F);
|
||||
|
||||
SrsRtpExtensionType xtype = extension_map->get_type(id);
|
||||
SrsRtpExtensionType xtype = extension_map_.get_type(id);
|
||||
if (xtype == kRtpExtensionTransportSequenceNumber) {
|
||||
// 0 1 2
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
|
||||
|
@ -176,7 +170,7 @@ srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExte
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
|
||||
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
@ -231,7 +225,7 @@ srs_error_t SrsRtpHeader::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap*
|
|||
| header extension |
|
||||
| .... |
|
||||
*/
|
||||
if ((err = parse_extension(buf, extmap)) != srs_success) {
|
||||
if ((err = parse_extension(buf)) != srs_success) {
|
||||
return srs_error_wrap(err, "fail to parse extension");
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +292,12 @@ srs_error_t SrsRtpHeader::encode(SrsBuffer* buf)
|
|||
|
||||
return err;
|
||||
}
|
||||
void SrsRtpHeader::set_extensions(const SrsRtpHeaderExtensionMap* extmap)
|
||||
{
|
||||
if (extmap) {
|
||||
extension_map_ = *extmap;
|
||||
}
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpHeader::get_twcc_sequence_number(uint16_t& twcc_sn)
|
||||
{
|
||||
|
@ -449,6 +449,11 @@ SrsRtpPacket2* SrsRtpPacket2::copy()
|
|||
return cp;
|
||||
}
|
||||
|
||||
void SrsRtpPacket2::set_rtp_header_extensions(const SrsRtpHeaderExtensionMap* extmap)
|
||||
{
|
||||
return header.set_extensions(extmap);
|
||||
}
|
||||
|
||||
int SrsRtpPacket2::nb_bytes()
|
||||
{
|
||||
if (!cached_payload_size) {
|
||||
|
@ -482,11 +487,11 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
|
||||
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = header.decode(buf, extmap)) != srs_success) {
|
||||
if ((err = header.decode(buf)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtp header");
|
||||
}
|
||||
|
||||
|
|
|
@ -140,14 +140,15 @@ private:
|
|||
uint32_t ssrc;
|
||||
uint32_t csrc[15];
|
||||
uint16_t extension_length;
|
||||
SrsRtpHeaderExtensionMap extension_map_;
|
||||
SrsRtpHeaderExtension header_extension;
|
||||
public:
|
||||
SrsRtpHeader();
|
||||
virtual ~SrsRtpHeader();
|
||||
private:
|
||||
srs_error_t parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extension_map);
|
||||
srs_error_t parse_extension(SrsBuffer* buf);
|
||||
public:
|
||||
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
|
||||
virtual srs_error_t decode(SrsBuffer* buf);
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
virtual int nb_bytes();
|
||||
public:
|
||||
|
@ -163,6 +164,7 @@ public:
|
|||
uint32_t get_ssrc() const;
|
||||
void set_padding(uint8_t v);
|
||||
uint8_t get_padding() const;
|
||||
void set_extensions(const SrsRtpHeaderExtensionMap* extmap);
|
||||
srs_error_t get_twcc_sequence_number(uint16_t& twcc_sn);
|
||||
};
|
||||
|
||||
|
@ -219,12 +221,13 @@ public:
|
|||
bool is_audio();
|
||||
// Copy the RTP packet.
|
||||
SrsRtpPacket2* copy();
|
||||
// Set RTP header extensions for encoding or decoding header extension
|
||||
void set_rtp_header_extensions(const SrsRtpHeaderExtensionMap* extmap);
|
||||
// interface ISrsEncoder
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
// TODO: FIXME: Should follow interface ISrsEncoder.
|
||||
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
|
||||
virtual srs_error_t decode(SrsBuffer* buf);
|
||||
};
|
||||
|
||||
// Single payload data.
|
||||
|
|
|
@ -1,416 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
|
||||
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_rtmp_stack.hpp>
|
||||
#include <srs_rtmp_stack.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_protocol_amf0.hpp>
|
||||
|
||||
/**
|
||||
* recv bandwidth helper.
|
||||
*/
|
||||
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
|
||||
bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_start_play();
|
||||
}
|
||||
bool _bandwidth_is_stop_play(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_stop_play();
|
||||
}
|
||||
bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_start_publish();
|
||||
}
|
||||
bool _bandwidth_is_stop_publish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_stop_publish();
|
||||
}
|
||||
bool _bandwidth_is_finish(SrsBandwidthPacket* pkt)
|
||||
{
|
||||
return pkt->is_finish();
|
||||
}
|
||||
int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((err = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
srs_info("get final message success.");
|
||||
|
||||
if (pfn(pkt)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int _srs_expect_bandwidth_packet2(SrsRtmpClient* rtmp, _CheckPacketType pfn, SrsBandwidthPacket** ppkt)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
SrsCommonMessage* msg = NULL;
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((err = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsCommonMessage, msg);
|
||||
srs_info("get final message success.");
|
||||
|
||||
if (pfn(pkt)) {
|
||||
*ppkt = pkt;
|
||||
return ret;
|
||||
}
|
||||
|
||||
srs_freep(pkt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsBandwidthClient::SrsBandwidthClient()
|
||||
{
|
||||
_rtmp = NULL;
|
||||
}
|
||||
|
||||
SrsBandwidthClient::~SrsBandwidthClient()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp)
|
||||
{
|
||||
_rtmp = rtmp;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::bandwidth_check(
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration
|
||||
) {
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
*start_time = srsu2ms(srs_update_system_time());
|
||||
|
||||
// play
|
||||
if ((ret = play_start()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = play_checking()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = play_stop()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// publish
|
||||
int duration_ms = 0;
|
||||
int actual_play_kbps = 0;
|
||||
if ((ret = publish_start(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = publish_checking(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
if ((ret = publish_stop()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((ret = do_final(&pkt)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
|
||||
// get data
|
||||
if (true ) {
|
||||
SrsAmf0Any* prop = NULL;
|
||||
if ((prop = pkt->data->ensure_property_number("play_kbps")) != NULL) {
|
||||
*play_kbps = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("publish_kbps")) != NULL) {
|
||||
*publish_kbps = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("play_bytes")) != NULL) {
|
||||
*play_bytes = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("publish_bytes")) != NULL) {
|
||||
*publish_bytes = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("play_time")) != NULL) {
|
||||
*play_duration = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("publish_time")) != NULL) {
|
||||
*publish_duration = (int)prop->to_number();
|
||||
}
|
||||
}
|
||||
|
||||
*end_time = srsu2ms(srs_update_system_time());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_start()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv play begin request.");
|
||||
|
||||
if (true) {
|
||||
// send start play response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check start play message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check play begin.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_checking()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::play_stop()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv play stop request.");
|
||||
|
||||
if (true) {
|
||||
// send stop play response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check stop play message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check play stop.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_start(int& duration_ms, int& play_kbps)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
SrsBandwidthPacket* pkt = NULL;
|
||||
if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SrsAutoFree(SrsBandwidthPacket, pkt);
|
||||
|
||||
SrsAmf0Any* prop = NULL;
|
||||
if ((prop = pkt->data->ensure_property_number("duration_ms")) != NULL) {
|
||||
duration_ms = (int)prop->to_number();
|
||||
}
|
||||
if ((prop = pkt->data->ensure_property_number("limit_kbps")) != NULL) {
|
||||
play_kbps = (int)prop->to_number();
|
||||
}
|
||||
}
|
||||
srs_info("BW check recv publish begin request.");
|
||||
|
||||
if (true) {
|
||||
// send start publish response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check start publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check publish begin.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (duration_ms <= 0) {
|
||||
ret = ERROR_RTMP_BWTC_DATA;
|
||||
srs_error("server must specifies the duration, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (play_kbps <= 0) {
|
||||
ret = ERROR_RTMP_BWTC_DATA;
|
||||
srs_error("server must specifies the play kbp, ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int data_count = 1;
|
||||
int64_t starttime = srsu2ms(srs_update_system_time());
|
||||
while (int64_t(srsu2ms(srs_get_system_time()) - starttime) < duration_ms) {
|
||||
// TODO: FIXME: use shared ptr message.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing();
|
||||
|
||||
// TODO: FIXME: magic number
|
||||
for (int i = 0; i < data_count; ++i) {
|
||||
std::stringstream seq;
|
||||
seq << i;
|
||||
std::string play_data = "SRS band check data from server's publishing......";
|
||||
pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
|
||||
}
|
||||
data_count += 2;
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check publish messages failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// use the play kbps to control the publish
|
||||
int elaps = (int)(srsu2ms(srs_update_system_time()) - starttime);
|
||||
if (elaps > 0) {
|
||||
int current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps);
|
||||
while (current_kbps > play_kbps) {
|
||||
srs_update_system_time();
|
||||
elaps = (int)(srsu2ms(srs_get_system_time()) - starttime);
|
||||
current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps);
|
||||
usleep(100 * 1000); // TODO: FIXME: magic number.
|
||||
}
|
||||
}
|
||||
}
|
||||
srs_info("BW check send publish bytes over.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::publish_stop()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if (true) {
|
||||
// send start publish response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW client stop publish request.");
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv publish stop request.");
|
||||
|
||||
if (true) {
|
||||
// send start publish response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check publish stop.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsBandwidthClient::do_final(SrsBandwidthPacket** ppkt)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
srs_info("BW check recv finish/report request.");
|
||||
|
||||
if (true) {
|
||||
// send final response to server.
|
||||
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final();
|
||||
|
||||
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
ret = srs_error_code(err);
|
||||
srs_freep(err);
|
||||
srs_error("send bandwidth check final message failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
srs_info("BW check final.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRS_LIB_BANDWIDTH_HPP
|
||||
#define SRS_LIB_BANDWIDTH_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
class SrsRtmpClient;
|
||||
class SrsBandwidthPacket;
|
||||
|
||||
/**
|
||||
* bandwith client library for srs-librtmp.
|
||||
*/
|
||||
class SrsBandwidthClient
|
||||
{
|
||||
private:
|
||||
SrsRtmpClient* _rtmp;
|
||||
public:
|
||||
SrsBandwidthClient();
|
||||
virtual ~SrsBandwidthClient();
|
||||
public:
|
||||
/**
|
||||
* initialize the bandwidth check client.
|
||||
*/
|
||||
virtual int initialize(SrsRtmpClient* rtmp);
|
||||
/**
|
||||
* do bandwidth check.
|
||||
*
|
||||
* bandwidth info:
|
||||
* @param start_time, output the start time, in ms.
|
||||
* @param end_time, output the end time, in ms.
|
||||
* @param play_kbps, output the play/download kbps.
|
||||
* @param publish_kbps, output the publish/upload kbps.
|
||||
* @param play_bytes, output the play/download bytes.
|
||||
* @param publish_bytes, output the publish/upload bytes.
|
||||
* @param play_duration, output the play/download test duration, in ms.
|
||||
* @param publish_duration, output the publish/upload test duration, in ms.
|
||||
*/
|
||||
virtual int bandwidth_check(
|
||||
int64_t* start_time, int64_t* end_time,
|
||||
int* play_kbps, int* publish_kbps,
|
||||
int* play_bytes, int* publish_bytes,
|
||||
int* play_duration, int* publish_duration);
|
||||
private:
|
||||
/**
|
||||
* play check/test, downloading bandwidth kbps.
|
||||
*/
|
||||
virtual int play_start();
|
||||
virtual int play_checking();
|
||||
virtual int play_stop();
|
||||
/**
|
||||
* publish check/test, publishing bandwidth kbps.
|
||||
*/
|
||||
virtual int publish_start(int& duration_ms, int& play_kbps);
|
||||
virtual int publish_checking(int duration_ms, int play_kbps);
|
||||
virtual int publish_stop();
|
||||
/**
|
||||
* report and final packet
|
||||
*/
|
||||
virtual int do_final(SrsBandwidthPacket** ppkt);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,486 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <srs_lib_simple_socket.hpp>
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
|
||||
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
||||
#ifndef _WIN32
|
||||
#define SOCKET_ETIME EWOULDBLOCK
|
||||
#define SOCKET_ECONNRESET ECONNRESET
|
||||
|
||||
#define SOCKET_ERRNO() errno
|
||||
#define SOCKET_RESET(fd) fd = -1; (void)0
|
||||
#define SOCKET_CLOSE(fd) \
|
||||
if (fd > 0) {\
|
||||
::close(fd); \
|
||||
fd = -1; \
|
||||
} \
|
||||
(void)0
|
||||
#define SOCKET_VALID(x) (x > 0)
|
||||
#define SOCKET_SETUP() (void)0
|
||||
#define SOCKET_CLEANUP() (void)0
|
||||
#else
|
||||
#define SOCKET_ETIME WSAETIMEDOUT
|
||||
#define SOCKET_ECONNRESET WSAECONNRESET
|
||||
#define SOCKET_ERRNO() WSAGetLastError()
|
||||
#define SOCKET_RESET(x) x=INVALID_SOCKET
|
||||
#define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;}
|
||||
#define SOCKET_VALID(x) (x!=INVALID_SOCKET)
|
||||
#define SOCKET_BUFF(x) ((char*)x)
|
||||
#define SOCKET_SETUP() socket_setup()
|
||||
#define SOCKET_CLEANUP() socket_cleanup()
|
||||
#endif
|
||||
|
||||
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_kernel_consts.hpp>
|
||||
|
||||
// when io not hijacked, use simple socket, the block sync stream.
|
||||
#ifndef SRS_HIJACK_IO
|
||||
struct SrsBlockSyncSocket
|
||||
{
|
||||
int family;
|
||||
SOCKET fd;
|
||||
SOCKET fdv4;
|
||||
SOCKET fdv6;
|
||||
// Bytes transmit.
|
||||
int64_t rbytes;
|
||||
int64_t sbytes;
|
||||
// The send/recv timeout in ms.
|
||||
int64_t rtm;
|
||||
int64_t stm;
|
||||
|
||||
SrsBlockSyncSocket() {
|
||||
family = AF_UNSPEC;
|
||||
stm = rtm = SRS_UTIME_NO_TIMEOUT;
|
||||
rbytes = sbytes = 0;
|
||||
|
||||
SOCKET_RESET(fd);
|
||||
SOCKET_RESET(fdv4);
|
||||
SOCKET_RESET(fdv6);
|
||||
SOCKET_SETUP();
|
||||
}
|
||||
|
||||
virtual ~SrsBlockSyncSocket() {
|
||||
if (SOCKET_VALID(fd)) {
|
||||
SOCKET_CLOSE(fd);
|
||||
}
|
||||
if (SOCKET_VALID(fdv4)) {
|
||||
SOCKET_CLOSE(fdv4);
|
||||
}
|
||||
if (SOCKET_VALID(fdv6)) {
|
||||
SOCKET_CLOSE(fdv6);
|
||||
}
|
||||
SOCKET_CLEANUP();
|
||||
}
|
||||
};
|
||||
srs_hijack_io_t srs_hijack_io_create()
|
||||
{
|
||||
SrsBlockSyncSocket* skt = new SrsBlockSyncSocket();
|
||||
return skt;
|
||||
}
|
||||
void srs_hijack_io_destroy(srs_hijack_io_t ctx)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
srs_freep(skt);
|
||||
}
|
||||
int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
skt->family = AF_UNSPEC;
|
||||
skt->fdv4 = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
skt->fdv6 = ::socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (!SOCKET_VALID(skt->fdv4) && !SOCKET_VALID(skt->fdv4)) {
|
||||
return ERROR_SOCKET_CREATE;
|
||||
}
|
||||
|
||||
// No TCP cache.
|
||||
int v = 1;
|
||||
setsockopt(skt->fdv4, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
|
||||
setsockopt(skt->fdv6, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
char sport[8];
|
||||
snprintf(sport, sizeof(sport), "%d", port);
|
||||
|
||||
addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
addrinfo* r = NULL;
|
||||
SrsAutoFree(addrinfo, r);
|
||||
if(getaddrinfo(server_ip, sport, (const addrinfo*)&hints, &r)) {
|
||||
return ERROR_SOCKET_CONNECT;
|
||||
}
|
||||
|
||||
skt->family = r->ai_family;
|
||||
if (r->ai_family == AF_INET6) {
|
||||
skt->fd = skt->fdv6;
|
||||
SOCKET_RESET(skt->fdv6);
|
||||
} else {
|
||||
skt->fd = skt->fdv4;
|
||||
SOCKET_RESET(skt->fdv4);
|
||||
}
|
||||
|
||||
if(::connect(skt->fd, r->ai_addr, r->ai_addrlen) < 0){
|
||||
return ERROR_SOCKET_CONNECT;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0);
|
||||
|
||||
if (nread) {
|
||||
*nread = nb_read;
|
||||
}
|
||||
|
||||
// On success a non-negative integer indicating the number of bytes actually read is returned
|
||||
// (a value of 0 means the network connection is closed or end of file is reached).
|
||||
if (nb_read <= 0) {
|
||||
if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
|
||||
return ERROR_SOCKET_TIMEOUT;
|
||||
}
|
||||
|
||||
if (nb_read == 0) {
|
||||
errno = SOCKET_ECONNRESET;
|
||||
}
|
||||
|
||||
return ERROR_SOCKET_READ;
|
||||
}
|
||||
|
||||
skt->rbytes += nb_read;
|
||||
|
||||
return ret;
|
||||
}
|
||||
int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD tv = (DWORD)(tm);
|
||||
|
||||
// To convert tv to const char* to make VS2015 happy.
|
||||
if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
|
||||
return SOCKET_ERRNO();
|
||||
}
|
||||
#else
|
||||
// The default for this option is zero,
|
||||
// which indicates that a receive operation shall not time out.
|
||||
int32_t sec = 0;
|
||||
int32_t usec = 0;
|
||||
|
||||
if (tm != SRS_UTIME_NO_TIMEOUT) {
|
||||
sec = (int32_t)(tm / 1000);
|
||||
usec = (int32_t)((tm % 1000)*1000);
|
||||
}
|
||||
|
||||
struct timeval tv = { sec , usec };
|
||||
if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
|
||||
return SOCKET_ERRNO();
|
||||
}
|
||||
#endif
|
||||
|
||||
skt->rtm = tm;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
return skt->rtm;
|
||||
}
|
||||
int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
return skt->rbytes;
|
||||
}
|
||||
int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD tv = (DWORD)(tm);
|
||||
|
||||
// To convert tv to const char* to make VS2015 happy.
|
||||
if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
|
||||
return SOCKET_ERRNO();
|
||||
}
|
||||
#else
|
||||
// The default for this option is zero,
|
||||
// which indicates that a receive operation shall not time out.
|
||||
int32_t sec = 0;
|
||||
int32_t usec = 0;
|
||||
|
||||
if (tm != SRS_UTIME_NO_TIMEOUT) {
|
||||
sec = (int32_t)(tm / 1000);
|
||||
usec = (int32_t)((tm % 1000)*1000);
|
||||
}
|
||||
|
||||
struct timeval tv = { sec , usec };
|
||||
if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
|
||||
return SOCKET_ERRNO();
|
||||
}
|
||||
#endif
|
||||
|
||||
skt->stm = tm;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
return skt->stm;
|
||||
}
|
||||
int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
return skt->sbytes;
|
||||
}
|
||||
int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ssize_t nb_write = ::writev(skt->fd, iov, iov_size);
|
||||
|
||||
if (nwrite) {
|
||||
*nwrite = nb_write;
|
||||
}
|
||||
|
||||
// On success, the readv() function returns the number of bytes read;
|
||||
// the writev() function returns the number of bytes written. On error, -1 is
|
||||
// returned, and errno is set appropriately.
|
||||
if (nb_write <= 0) {
|
||||
// @see https://github.com/ossrs/srs/issues/200
|
||||
if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
|
||||
return ERROR_SOCKET_TIMEOUT;
|
||||
}
|
||||
|
||||
return ERROR_SOCKET_WRITE;
|
||||
}
|
||||
|
||||
skt->sbytes += nb_write;
|
||||
|
||||
return ret;
|
||||
}
|
||||
int srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t tm)
|
||||
{
|
||||
return tm == SRS_UTIME_NO_TIMEOUT;
|
||||
}
|
||||
int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
size_t left = size;
|
||||
ssize_t nb_read = 0;
|
||||
|
||||
while (left > 0) {
|
||||
char* this_buf = (char*)buf + nb_read;
|
||||
ssize_t this_nread;
|
||||
|
||||
if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
nb_read += this_nread;
|
||||
left -= (size_t)this_nread;
|
||||
}
|
||||
|
||||
if (nread) {
|
||||
*nread = nb_read;
|
||||
}
|
||||
skt->rbytes += nb_read;
|
||||
|
||||
return ret;
|
||||
}
|
||||
int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite)
|
||||
{
|
||||
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
|
||||
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0);
|
||||
|
||||
if (nwrite) {
|
||||
*nwrite = nb_write;
|
||||
}
|
||||
|
||||
if (nb_write <= 0) {
|
||||
// @see https://github.com/ossrs/srs/issues/200
|
||||
if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
|
||||
return ERROR_SOCKET_TIMEOUT;
|
||||
}
|
||||
|
||||
return ERROR_SOCKET_WRITE;
|
||||
}
|
||||
|
||||
skt->sbytes += nb_write;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
SimpleSocketStream::SimpleSocketStream()
|
||||
{
|
||||
io = srs_hijack_io_create();
|
||||
}
|
||||
|
||||
SimpleSocketStream::~SimpleSocketStream()
|
||||
{
|
||||
if (io) {
|
||||
srs_hijack_io_destroy(io);
|
||||
io = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
srs_hijack_io_t SimpleSocketStream::hijack_io()
|
||||
{
|
||||
return io;
|
||||
}
|
||||
|
||||
int SimpleSocketStream::create_socket(srs_rtmp_t owner)
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_create_socket(io, owner);
|
||||
}
|
||||
|
||||
int SimpleSocketStream::connect(const char* server_ip, int port)
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_connect(io, server_ip, port);
|
||||
}
|
||||
|
||||
// Interface ISrsReader
|
||||
srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
|
||||
{
|
||||
srs_assert(io);
|
||||
int ret = srs_hijack_io_read(io, buf, size, nread);
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "read");
|
||||
}
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
// Interface ISrsProtocolReader
|
||||
void SimpleSocketStream::set_recv_timeout(srs_utime_t tm)
|
||||
{
|
||||
srs_assert(io);
|
||||
srs_hijack_io_set_recv_timeout(io, srsu2ms(tm));
|
||||
}
|
||||
|
||||
srs_utime_t SimpleSocketStream::get_recv_timeout()
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_get_recv_timeout(io) * SRS_UTIME_MILLISECONDS;
|
||||
}
|
||||
|
||||
int64_t SimpleSocketStream::get_recv_bytes()
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_get_recv_bytes(io);
|
||||
}
|
||||
|
||||
// Interface ISrsProtocolWriter
|
||||
void SimpleSocketStream::set_send_timeout(srs_utime_t tm)
|
||||
{
|
||||
srs_assert(io);
|
||||
srs_hijack_io_set_send_timeout(io, srsu2ms(tm));
|
||||
}
|
||||
|
||||
srs_utime_t SimpleSocketStream::get_send_timeout()
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_get_send_timeout(io) * SRS_UTIME_MILLISECONDS;
|
||||
}
|
||||
|
||||
int64_t SimpleSocketStream::get_send_bytes()
|
||||
{
|
||||
srs_assert(io);
|
||||
return srs_hijack_io_get_send_bytes(io);
|
||||
}
|
||||
|
||||
srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
|
||||
{
|
||||
srs_assert(io);
|
||||
int ret = srs_hijack_io_writev(io, iov, iov_size, nwrite);
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "read");
|
||||
}
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread)
|
||||
{
|
||||
srs_assert(io);
|
||||
int ret = srs_hijack_io_read_fully(io, buf, size, nread);
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "read");
|
||||
}
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
srs_error_t SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite)
|
||||
{
|
||||
srs_assert(io);
|
||||
int ret = srs_hijack_io_write(io, buf, size, nwrite);
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
return srs_error_new(ret, "read");
|
||||
}
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2020 Winlin
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SRS_LIB_SIMPLE_SOCKET_HPP
|
||||
#define SRS_LIB_SIMPLE_SOCKET_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <srs_protocol_io.hpp>
|
||||
#include <srs_librtmp.hpp>
|
||||
|
||||
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
|
||||
#ifndef _WIN32
|
||||
#define SOCKET int
|
||||
#endif
|
||||
|
||||
/**
|
||||
* simple socket stream,
|
||||
* use tcp socket, sync block mode, for client like srs-librtmp.
|
||||
*/
|
||||
class SimpleSocketStream : public ISrsProtocolReadWriter
|
||||
{
|
||||
private:
|
||||
srs_hijack_io_t io;
|
||||
public:
|
||||
SimpleSocketStream();
|
||||
virtual ~SimpleSocketStream();
|
||||
public:
|
||||
virtual srs_hijack_io_t hijack_io();
|
||||
virtual int create_socket(srs_rtmp_t owner);
|
||||
virtual int connect(const char* server, int port);
|
||||
// Interface ISrsReader
|
||||
public:
|
||||
virtual srs_error_t read(void* buf, size_t size, ssize_t* nread);
|
||||
// Interface ISrsProtocolReader
|
||||
public:
|
||||
virtual void set_recv_timeout(srs_utime_t tm);
|
||||
virtual srs_utime_t get_recv_timeout();
|
||||
virtual int64_t get_recv_bytes();
|
||||
// Interface ISrsProtocolWriter
|
||||
public:
|
||||
virtual void set_send_timeout(srs_utime_t tm);
|
||||
virtual srs_utime_t get_send_timeout();
|
||||
virtual int64_t get_send_bytes();
|
||||
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
|
||||
// Interface ISrsProtocolReadWriter
|
||||
public:
|
||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||
virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -490,7 +490,7 @@ public:
|
|||
// then the rest id is 100.
|
||||
// @param pattern the handler pattern which will serve the request.
|
||||
// @return the REST id; -1 if not matched.
|
||||
virtual int parse_rest_id(std::string pattern) = 0;
|
||||
virtual std::string parse_rest_id(std::string pattern) = 0;
|
||||
public:
|
||||
// The left all data is chunked body, the infinite chunked mode,
|
||||
// which is chunked encoding without chunked header.
|
||||
|
|
|
@ -2453,7 +2453,7 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser
|
|||
}
|
||||
// for edge to directly get the id of client.
|
||||
data->set("srs_pid", SrsAmf0Any::number(getpid()));
|
||||
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
|
||||
data->set("srs_id", SrsAmf0Any::str(_srs_context->get_id().c_str()));
|
||||
|
||||
if ((err = protocol->send_and_free_packet(pkt, 0)) != srs_success) {
|
||||
return srs_error_wrap(err, "send connect app response");
|
||||
|
|
|
@ -535,19 +535,19 @@ string SrsHttpMessage::ext()
|
|||
return _ext;
|
||||
}
|
||||
|
||||
int SrsHttpMessage::parse_rest_id(string pattern)
|
||||
std::string SrsHttpMessage::parse_rest_id(string pattern)
|
||||
{
|
||||
string p = _uri->get_path();
|
||||
if (p.length() <= pattern.length()) {
|
||||
return -1;
|
||||
return "";
|
||||
}
|
||||
|
||||
string id = p.substr((int)pattern.length());
|
||||
if (!id.empty()) {
|
||||
return ::atoi(id.c_str());
|
||||
return id;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return "";
|
||||
}
|
||||
|
||||
srs_error_t SrsHttpMessage::enter_infinite_chunked()
|
|
@ -172,7 +172,7 @@ public:
|
|||
virtual std::string query();
|
||||
virtual std::string ext();
|
||||
// Get the RESTful matched id.
|
||||
virtual int parse_rest_id(std::string pattern);
|
||||
virtual std::string parse_rest_id(std::string pattern);
|
||||
public:
|
||||
virtual srs_error_t enter_infinite_chunked();
|
||||
public:
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
|
@ -41,29 +42,31 @@ SrsThreadContext::~SrsThreadContext()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsThreadContext::generate_id()
|
||||
string SrsThreadContext::generate_id()
|
||||
{
|
||||
static int id = 0;
|
||||
|
||||
if (id == 0) {
|
||||
id = (100 + ((uint32_t)(int64_t)this)%1000);
|
||||
}
|
||||
|
||||
int gid = id++;
|
||||
cache[srs_thread_self()] = gid;
|
||||
return gid;
|
||||
|
||||
stringstream ss;
|
||||
ss << gid;
|
||||
cache[srs_thread_self()] = ss.str();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int SrsThreadContext::get_id()
|
||||
string SrsThreadContext::get_id()
|
||||
{
|
||||
return cache[srs_thread_self()];
|
||||
}
|
||||
|
||||
int SrsThreadContext::set_id(int v)
|
||||
string SrsThreadContext::set_id(string v)
|
||||
{
|
||||
srs_thread_t self = srs_thread_self();
|
||||
|
||||
int ov = 0;
|
||||
string ov;
|
||||
if (cache.find(self) != cache.end()) {
|
||||
ov = cache[self];
|
||||
}
|
||||
|
@ -76,7 +79,7 @@ int SrsThreadContext::set_id(int v)
|
|||
void SrsThreadContext::clear_cid()
|
||||
{
|
||||
srs_thread_t self = srs_thread_self();
|
||||
std::map<srs_thread_t, int>::iterator it = cache.find(self);
|
||||
std::map<srs_thread_t, string>::iterator it = cache.find(self);
|
||||
if (it != cache.end()) {
|
||||
cache.erase(it);
|
||||
}
|
||||
|
@ -105,7 +108,7 @@ void SrsConsoleLog::reopen()
|
|||
{
|
||||
}
|
||||
|
||||
void SrsConsoleLog::verbose(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsConsoleLog::verbose(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelVerbose) {
|
||||
return;
|
||||
|
@ -125,7 +128,7 @@ void SrsConsoleLog::verbose(const char* tag, int context_id, const char* fmt, ..
|
|||
fprintf(stdout, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void SrsConsoleLog::info(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsConsoleLog::info(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelInfo) {
|
||||
return;
|
||||
|
@ -145,7 +148,7 @@ void SrsConsoleLog::info(const char* tag, int context_id, const char* fmt, ...)
|
|||
fprintf(stdout, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void SrsConsoleLog::trace(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsConsoleLog::trace(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelTrace) {
|
||||
return;
|
||||
|
@ -165,7 +168,7 @@ void SrsConsoleLog::trace(const char* tag, int context_id, const char* fmt, ...)
|
|||
fprintf(stdout, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void SrsConsoleLog::warn(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsConsoleLog::warn(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelWarn) {
|
||||
return;
|
||||
|
@ -185,7 +188,7 @@ void SrsConsoleLog::warn(const char* tag, int context_id, const char* fmt, ...)
|
|||
fprintf(stderr, "%s\n", buffer);
|
||||
}
|
||||
|
||||
void SrsConsoleLog::error(const char* tag, int context_id, const char* fmt, ...)
|
||||
void SrsConsoleLog::error(const char* tag, const char* context_id, const char* fmt, ...)
|
||||
{
|
||||
if (level > SrsLogLevelError) {
|
||||
return;
|
||||
|
@ -211,7 +214,7 @@ void SrsConsoleLog::error(const char* tag, int context_id, const char* fmt, ...)
|
|||
}
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize)
|
||||
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, const char* cid, const char* level, int* psize)
|
||||
{
|
||||
// clock time
|
||||
timeval tv;
|
||||
|
@ -235,24 +238,24 @@ bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char
|
|||
if (dangerous) {
|
||||
if (tag) {
|
||||
written = snprintf(buffer, size,
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ",
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%s][%d] ",
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
|
||||
level, tag, getpid(), cid, errno);
|
||||
} else {
|
||||
written = snprintf(buffer, size,
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ",
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%s][%d] ",
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
|
||||
level, getpid(), cid, errno);
|
||||
}
|
||||
} else {
|
||||
if (tag) {
|
||||
written = snprintf(buffer, size,
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ",
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%s] ",
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
|
||||
level, tag, getpid(), cid);
|
||||
} else {
|
||||
written = snprintf(buffer, size,
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ",
|
||||
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%s] ",
|
||||
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
|
||||
level, getpid(), cid);
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
#include <srs_core.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <srs_service_st.hpp>
|
||||
#include <srs_kernel_log.hpp>
|
||||
|
@ -36,14 +37,14 @@
|
|||
class SrsThreadContext : public ISrsThreadContext
|
||||
{
|
||||
private:
|
||||
std::map<srs_thread_t, int> cache;
|
||||
std::map<srs_thread_t, std::string> cache;
|
||||
public:
|
||||
SrsThreadContext();
|
||||
virtual ~SrsThreadContext();
|
||||
public:
|
||||
virtual int generate_id();
|
||||
virtual int get_id();
|
||||
virtual int set_id(int v);
|
||||
virtual std::string generate_id();
|
||||
virtual std::string get_id();
|
||||
virtual std::string set_id(std::string v);
|
||||
public:
|
||||
virtual void clear_cid();
|
||||
};
|
||||
|
@ -63,11 +64,11 @@ public:
|
|||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual void reopen();
|
||||
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void info(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
|
||||
};
|
||||
|
||||
// Generate the log header.
|
||||
|
@ -75,6 +76,6 @@ public:
|
|||
// @param utc Whether use UTC time format in the log header.
|
||||
// @param psize Output the actual header size.
|
||||
// @remark It's a internal API.
|
||||
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize);
|
||||
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, const char* cid, const char* level, int* psize);
|
||||
|
||||
#endif
|
|
@ -122,7 +122,7 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
|
|||
data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
|
||||
// for edge to directly get the id of client.
|
||||
data->set("srs_pid", SrsAmf0Any::number(getpid()));
|
||||
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
|
||||
data->set("srs_id", SrsAmf0Any::str(_srs_context->get_id().c_str()));
|
||||
|
||||
// local ip of edge
|
||||
data->set("srs_server_ip", SrsAmf0Any::str(local_ip.c_str()));
|
|
@ -214,7 +214,7 @@ srs_error_t do_srs_tcp_listen(int fd, addrinfo* r, srs_netfd_t* pfd)
|
|||
return srs_error_wrap(err, "set reuseport");
|
||||
}
|
||||
|
||||
if (bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
|
||||
if (::bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
|
||||
return srs_error_new(ERROR_SOCKET_BIND, "bind");
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ srs_error_t do_srs_udp_listen(int fd, addrinfo* r, srs_netfd_t* pfd)
|
|||
return srs_error_wrap(err, "set reuseport");
|
||||
}
|
||||
|
||||
if (bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
|
||||
if (::bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
|
||||
return srs_error_new(ERROR_SOCKET_BIND, "bind");
|
||||
}
|
||||
|
|
@ -129,3 +129,11 @@ VOID TEST(SampleTest, FastSampleMacrosTest)
|
|||
EXPECT_NEAR(10, 15, 5);
|
||||
}
|
||||
|
||||
VOID TEST(SampleTest, StringEQTest)
|
||||
{
|
||||
string str = "100";
|
||||
EXPECT_TRUE("100" == str);
|
||||
EXPECT_EQ("100", str);
|
||||
EXPECT_STREQ("100", str.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
SrsDummyCoroutine dc;
|
||||
|
||||
if (true) {
|
||||
EXPECT_EQ(0, dc.cid());
|
||||
EXPECT_EQ("", dc.cid());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -52,7 +52,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
if (true) {
|
||||
dc.stop();
|
||||
|
||||
EXPECT_EQ(0, dc.cid());
|
||||
EXPECT_EQ("", dc.cid());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -68,7 +68,7 @@ VOID TEST(AppCoroutineTest, Dummy)
|
|||
if (true) {
|
||||
dc.interrupt();
|
||||
|
||||
EXPECT_EQ(0, dc.cid());
|
||||
EXPECT_EQ("", dc.cid());
|
||||
|
||||
srs_error_t err = dc.pull();
|
||||
EXPECT_TRUE(err != srs_success);
|
||||
|
@ -88,11 +88,11 @@ public:
|
|||
srs_error_t err;
|
||||
srs_cond_t running;
|
||||
srs_cond_t exited;
|
||||
int cid;
|
||||
std::string cid;
|
||||
// Quit without error.
|
||||
bool quit;
|
||||
public:
|
||||
MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0), quit(false) {
|
||||
MockCoroutineHandler() : trd(NULL), err(srs_success), cid("0"), quit(false) {
|
||||
running = srs_cond_new();
|
||||
exited = srs_cond_new();
|
||||
}
|
||||
|
@ -128,12 +128,12 @@ VOID TEST(AppCoroutineTest, StartStop)
|
|||
MockCoroutineHandler ch;
|
||||
SrsSTCoroutine sc("test", &ch);
|
||||
ch.trd = ≻
|
||||
EXPECT_EQ(0, sc.cid());
|
||||
EXPECT_EQ("", sc.cid());
|
||||
|
||||
// Thread stop after created.
|
||||
sc.stop();
|
||||
|
||||
EXPECT_EQ(0, sc.cid());
|
||||
EXPECT_EQ("", sc.cid());
|
||||
|
||||
srs_error_t err = sc.pull();
|
||||
EXPECT_TRUE(srs_success != err);
|
||||
|
@ -151,13 +151,13 @@ VOID TEST(AppCoroutineTest, StartStop)
|
|||
MockCoroutineHandler ch;
|
||||
SrsSTCoroutine sc("test", &ch);
|
||||
ch.trd = ≻
|
||||
EXPECT_EQ(0, sc.cid());
|
||||
EXPECT_EQ("", sc.cid());
|
||||
|
||||
EXPECT_TRUE(srs_success == sc.start());
|
||||
EXPECT_TRUE(srs_success == sc.pull());
|
||||
|
||||
srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_TRUE(sc.cid() > 0);
|
||||
EXPECT_TRUE(!sc.cid().empty());
|
||||
|
||||
// Thread stop after started.
|
||||
sc.stop();
|
||||
|
@ -178,7 +178,7 @@ VOID TEST(AppCoroutineTest, StartStop)
|
|||
MockCoroutineHandler ch;
|
||||
SrsSTCoroutine sc("test", &ch);
|
||||
ch.trd = ≻
|
||||
EXPECT_EQ(0, sc.cid());
|
||||
EXPECT_EQ("", sc.cid());
|
||||
|
||||
EXPECT_TRUE(srs_success == sc.start());
|
||||
EXPECT_TRUE(srs_success == sc.pull());
|
||||
|
@ -220,16 +220,16 @@ VOID TEST(AppCoroutineTest, Cycle)
|
|||
|
||||
if (true) {
|
||||
MockCoroutineHandler ch;
|
||||
SrsSTCoroutine sc("test", &ch, 250);
|
||||
SrsSTCoroutine sc("test", &ch, "250");
|
||||
ch.trd = ≻
|
||||
EXPECT_EQ(250, sc.cid());
|
||||
EXPECT_TRUE("250" == sc.cid());
|
||||
|
||||
EXPECT_TRUE(srs_success == sc.start());
|
||||
EXPECT_TRUE(srs_success == sc.pull());
|
||||
|
||||
// After running, the cid in cycle should equal to the thread.
|
||||
srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS);
|
||||
EXPECT_EQ(250, ch.cid);
|
||||
EXPECT_TRUE("250" == ch.cid);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
|
|
|
@ -4099,16 +4099,16 @@ VOID TEST(KernelLogTest, CoverAll)
|
|||
HELPER_EXPECT_SUCCESS(l.initialize());
|
||||
|
||||
l.reopen();
|
||||
l.verbose("TAG", 0, "log");
|
||||
l.info("TAG", 0, "log");
|
||||
l.trace("TAG", 0, "log");
|
||||
l.warn("TAG", 0, "log");
|
||||
l.error("TAG", 0, "log");
|
||||
l.verbose("TAG", "0", "log");
|
||||
l.info("TAG", "0", "log");
|
||||
l.trace("TAG", "0", "log");
|
||||
l.warn("TAG", "0", "log");
|
||||
l.error("TAG", "0", "log");
|
||||
|
||||
ISrsThreadContext ctx;
|
||||
ctx.set_id(10);
|
||||
EXPECT_EQ(0, ctx.get_id());
|
||||
EXPECT_EQ(0, ctx.generate_id());
|
||||
ctx.set_id("10");
|
||||
EXPECT_EQ("", ctx.get_id());
|
||||
EXPECT_EQ("", ctx.generate_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ VOID TEST(TCPServerTest, MessageConnection)
|
|||
if (true) {
|
||||
SrsHttpMessage m;
|
||||
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/v1/streams/100", false));
|
||||
EXPECT_EQ(100, m.parse_rest_id("/v1/streams/")); EXPECT_FALSE(m.is_jsonp());
|
||||
EXPECT_EQ("100", m.parse_rest_id("/v1/streams/")); EXPECT_FALSE(m.is_jsonp());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,7 @@ class MockOnCycleThread : public ISrsCoroutineHandler
|
|||
public:
|
||||
SrsSTCoroutine trd;
|
||||
srs_cond_t cond;
|
||||
MockOnCycleThread() : trd("mock", this, 0) {
|
||||
MockOnCycleThread() : trd("mock", this, "0") {
|
||||
cond = srs_cond_new();
|
||||
};
|
||||
virtual ~MockOnCycleThread() {
|
||||
|
@ -822,7 +822,7 @@ class MockOnCycleThread2 : public ISrsCoroutineHandler
|
|||
public:
|
||||
SrsSTCoroutine trd;
|
||||
srs_mutex_t lock;
|
||||
MockOnCycleThread2() : trd("mock", this, 0) {
|
||||
MockOnCycleThread2() : trd("mock", this, "0") {
|
||||
lock = srs_mutex_new();
|
||||
};
|
||||
virtual ~MockOnCycleThread2() {
|
||||
|
@ -863,7 +863,7 @@ class MockOnCycleThread3 : public ISrsCoroutineHandler
|
|||
public:
|
||||
SrsSTCoroutine trd;
|
||||
srs_netfd_t fd;
|
||||
MockOnCycleThread3() : trd("mock", this, 0) {
|
||||
MockOnCycleThread3() : trd("mock", this, "0") {
|
||||
fd = NULL;
|
||||
};
|
||||
virtual ~MockOnCycleThread3() {
|
||||
|
@ -1116,7 +1116,7 @@ class MockOnCycleThread4 : public ISrsCoroutineHandler
|
|||
public:
|
||||
SrsSTCoroutine trd;
|
||||
srs_netfd_t fd;
|
||||
MockOnCycleThread4() : trd("mock", this, 0) {
|
||||
MockOnCycleThread4() : trd("mock", this, "0") {
|
||||
fd = NULL;
|
||||
};
|
||||
virtual ~MockOnCycleThread4() {
|
||||
|
@ -1268,38 +1268,38 @@ VOID TEST(TCPServerTest, ContextUtility)
|
|||
if (true) {
|
||||
SrsThreadContext ctx;
|
||||
|
||||
EXPECT_EQ(0, ctx.set_id(100));
|
||||
EXPECT_EQ(100, ctx.set_id(1000));
|
||||
EXPECT_EQ(1000, ctx.get_id());
|
||||
EXPECT_TRUE("" == ctx.set_id("100"));
|
||||
EXPECT_TRUE("100" == ctx.set_id("1000"));
|
||||
EXPECT_TRUE("1000" == ctx.get_id());
|
||||
|
||||
ctx.clear_cid();
|
||||
EXPECT_EQ(0, ctx.set_id(100));
|
||||
EXPECT_TRUE("" == ctx.set_id("100"));
|
||||
}
|
||||
|
||||
int base_size = 0;
|
||||
if (true) {
|
||||
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", 100, "Trace", &size));
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", "100", "Trace", &size));
|
||||
base_size = size;
|
||||
EXPECT_TRUE(base_size > 0);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, "SRS", 100, "Trace", &size));
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, "SRS", "100", "Trace", &size));
|
||||
EXPECT_EQ(base_size, size);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
errno = 0;
|
||||
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, NULL, 100, "Trace", &size));
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, NULL, "100", "Trace", &size));
|
||||
EXPECT_EQ(base_size - 5, size);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, false, NULL, 100, "Trace", &size));
|
||||
ASSERT_TRUE(srs_log_header(buf, 1024, false, false, NULL, "100", "Trace", &size));
|
||||
EXPECT_EQ(base_size - 8, size);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue