Files
srs/trunk/configure
Haibo Chen(陈海博) ef048b0d65 RTC: Fix DVR missing first 4-6 seconds by initializing rate from SDP (#4541)
for issue #4418, #4151, #4076 .DVR Missing First Few Seconds of
Audio/Video

### Root Cause
When recording WebRTC streams to FLV files using DVR, the first 4-6
seconds of audio/video are missing. This occurs because:

1. **Packets are discarded before A/V sync is available**: The
RTC-to-RTMP conversion pipeline actively discards all RTP packets when
avsync_time <= 0.
2. **Original algorithm requires 2 RTCP SR packets**: The previous
implementation needed to receive two RTCP Sender Report (SR) packets
before it could calculate the rate for audio/video synchronization
timestamp conversion.
3. **Delay causes packet loss**: Since RTCP SR packets typically arrive
every 2-3 seconds, waiting for 2 SRs means 4-6 seconds of packets are
discarded before A/V sync becomes available.
4. **Audio SR arrives slower than video SR**: As reported in the issue,
video RTCP SR packets arrive much faster than audio SR packets. This
asymmetry causes audio packets to be discarded for a longer period,
resulting in the audio loss observed in DVR recordings.

### Solution
1. **Initialize rate from SDP**: Use the sample rate from SDP (Session
Description Protocol) to calculate the initial rate immediately when the
track is created.
Audio (Opus): 48000 Hz → rate = 48 (RTP units per millisecond)
Video (H.264/H.265): 90000 Hz → rate = 90 (RTP units per millisecond)
2. **Enable immediate A/V sync:** With the SDP rate available,
cal_avsync_time() can calculate valid timestamps from the very first RTP
packet, eliminating packet loss.
3. **Smooth transition to precise rate**: After receiving the 2nd RTCP
SR, update to the precisely calculated rate based on actual RTP/NTP
timestamp mapping.

## Configuration

Added new configuration option `init_rate_from_sdp` in the RTC vhost
section:

```nginx
vhost rtc.vhost.srs.com {
    rtc {
        # Whether initialize RTP rate from SDP sample rate for immediate A/V sync.
        # When enabled, the RTP rate (units per millisecond) is initialized from the SDP
        # sample rate (e.g., 90 for video 90kHz, 48 for audio 48kHz) before receiving
        # 2 RTCP SR packets. This allows immediate audio/video synchronization.
        # The rate will be updated to a more precise value after receiving the 2nd SR.
        # Overwrite by env SRS_VHOST_RTC_INIT_RATE_FROM_SDP for all vhosts.
        # Default: off
        init_rate_from_sdp off;
    }
}
```

**⚠️ Important Note**: This config defaults to **off** because:
-  When **enabled**: Fixes the audio loss problem (no missing first 4-6
seconds)
-  When **enabled**: VLC on macOS cannot play the video properly
-  Other platforms work fine (Windows, Linux)
-  FFplay works fine on all platforms

Users experiencing audio loss in DVR recordings can enable this option
if they don't need VLC macOS compatibility. We're investigating the VLC
macOS issue to make this feature safe to enable by default in the
future.

---------

Co-authored-by: winlin <winlinvip@gmail.com>
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
2025-10-28 09:33:40 -04:00

765 lines
29 KiB
Bash
Executable File

#!/bin/bash
#####################################################################################
# the main output dir, all configure and make output are in this dir.
#####################################################################################
# Configure SRS from other directory, for example:
# env SRS_WORKDIR=~/git/srs/trunk ./configure
if [[ -z $SRS_WORKDIR ]]; then SRS_WORKDIR="."; fi
# Set the objs to other directory, for example:
# env SRS_OUTPUT=$(pwd) ./configure
if [[ -z $SRS_OUTPUT ]]; then
SRS_OBJS="${SRS_WORKDIR}/objs" && SRS_MAKEFILE=${SRS_WORKDIR}/Makefile
else
SRS_OBJS="${SRS_OUTPUT}/objs" && SRS_MAKEFILE=${SRS_OUTPUT}/Makefile
fi
# linux shell color support.
RED="\\033[31m"
GREEN="\\033[32m"
YELLOW="\\033[33m"
BLACK="\\033[0m"
#####################################################################################
# parse user options, set the variables like:
# srs features: SRS_SSL/SRS_HLS/SRS_HTTP_CALLBACK/......
# build options: SRS_JOBS
#####################################################################################
# parse options, exit with error when parse options invalid.
. $SRS_WORKDIR/auto/options.sh
# setup variables when options parsed.
. $SRS_WORKDIR/auto/setup_variables.sh
# We don't need to cleanup the exists files.
rm -f ${SRS_MAKEFILE}
# Create objs and platform directories.
mkdir -p ${SRS_OBJS}/${SRS_PLATFORM}
# If only generate objs directory, quit without error.
if [[ $SRS_GENERATE_OBJS == YES ]]; then exit 0; fi
# apply user options.
. $SRS_WORKDIR/auto/depends.sh
# the auto generated variables.
. $SRS_WORKDIR/auto/auto_headers.sh
#####################################################################################
# generate Makefile.
#####################################################################################
# ubuntu echo in Makefile cannot display color, use bash instead
SRS_BUILD_SUMMARY="_srs_build_summary.sh"
# utest make entry, (cd utest; make)
SrsUtestMakeEntry="@echo -e \"ignore utest for it's disabled\""
if [[ $SRS_UTEST == YES ]]; then SrsUtestMakeEntry="\$(MAKE)\$(JOBS) -C ${SRS_OBJS}/${SRS_PLATFORM}/utest"; fi
# generate extra phony for each modules.
cat << END > ${SRS_OBJS}/Makefile
.PHONY: $__mphonys
END
#####################################################################################
# build tools or compiler args.
# enable gdb debug
GDBDebug=" -g -O0"
# the warning level.
WarnLevel=" -Wall"
# the compile standard.
CppStd="-ansi"
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
SrsGperf=""; SrsGperfLink=""; if [[ $SRS_GPERF == YES ]]; then SrsGperfLink=" -lpthread"; fi
# the cxx flag generated.
CXXFLAGS="${CXXFLAGS} ${CppStd}${WarnLevel}${GDBDebug}${LibraryCompile}${SrsGprof}"
if [[ $SRS_GPERF == YES ]]; then
CXXFLAGS="${CXXFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free";
fi
# For coverage.
if [[ $SRS_GCOV == YES ]]; then
SrsGcov="-fprofile-arcs -ftest-coverage"
fi
if [[ $SRS_GCOV == YES ]]; then
CXXFLAGS="${CXXFLAGS} ${SrsGcov}";
fi
# User configed options.
if [[ $SRS_EXTRA_FLAGS != '' ]]; then
CXXFLAGS="${CXXFLAGS} $SRS_EXTRA_FLAGS";
fi
# For Sanitizer
# @doc: https://github.com/google/sanitizers/wiki/AddressSanitizer
if [[ $SRS_SANITIZER == YES ]]; then
CXXFLAGS="${CXXFLAGS} -fsanitize=address -fno-omit-frame-pointer";
fi
# Start to generate the Makefile.
cat << END >> ${SRS_OBJS}/Makefile
CC = ${SRS_TOOL_CC}
CXX = ${SRS_TOOL_CXX}
AR = ${SRS_TOOL_AR}
LINK = ${SRS_TOOL_CXX}
CXXFLAGS = ${CXXFLAGS}
.PHONY: default srs srs_ingest_hls
default:
END
#####################################################################################
# Libraries, external library to build in srs,
# header(.h): add to ModuleLibIncs if need the specified library. for example, LibSTRoot
# library(.a): add to ModuleLibFiles if binary need the specifeid library. for example, LibSTfile
#
# the link options, always use static link
SrsLinkOptions="-ldl -lpthread";
# st(state-threads) the basic network library for SRS.
LibSTRoot="${SRS_OBJS}/st"; LibSTfile="${LibSTRoot}/libst.a"
if [[ $SRS_SHARED_ST == YES ]]; then LibSTfile="-L${LibSTRoot} -lst"; fi
# srtp
LibSrtpRoot="${SRS_OBJS}/srtp2/include"; LibSrtpFile="${SRS_OBJS}/srtp2/lib/libsrtp2.a"
if [[ $SRS_USE_SYS_SRTP == YES ]]; then
LibSrtpRoot=""; LibSrtpFile="libsrtp2.a"
if [[ $SRS_SHARED_SRTP == YES ]]; then
LibSrtpFile="";
SrsLinkOptions="${SrsLinkOptions} -lsrtp2";
fi
fi
# FFMPEG for WebRTC transcoding, such as aac to opus.
if [[ $SRS_FFMPEG_FIT == YES ]]; then
LibFfmpegRoot="${SRS_OBJS}/ffmpeg/include"
LibFfmpegFile="${SRS_OBJS}/ffmpeg/lib/libavcodec.a ${SRS_OBJS}/ffmpeg/lib/libswresample.a ${SRS_OBJS}/ffmpeg/lib/libavutil.a"
if [[ $SRS_FFMPEG_OPUS != YES ]]; then
LibFfmpegFile="${LibFfmpegFile} ${SRS_OBJS}/opus/lib/libopus.a"
fi
if [[ $SRS_SHARED_FFMPEG == YES ]]; then
LibFfmpegFile="-L${SRS_OBJS}/ffmpeg/lib -lavcodec -lswresample -lavutil";
if [[ $SRS_FFMPEG_OPUS != YES ]]; then
LibFfmpegFile="$LibFfmpegFile -L${SRS_OBJS}/opus/lib -lopus"
fi
fi
if [[ $SRS_USE_SYS_FFMPEG == YES ]]; then
LibFfmpegRoot=""
LibFfmpegFile="libavcodec.a libswresample.a libavutil.a libopus.a";
if [[ $SRS_SHARED_FFMPEG == YES ]]; then
LibFfmpegFile=""
SrsLinkOptions="${SrsLinkOptions} -lavcodec -lswresample -lavutil -lopus";
fi
fi
fi
# openssl-1.1.0e, for the RTMP complex handshake.
LibSSLRoot="";LibSSLfile=""
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == NO ]]; then
LibSSLRoot="${SRS_OBJS}/openssl/include"; LibSSLfile="${SRS_OBJS}/openssl/lib/libssl.a ${SRS_OBJS}/openssl/lib/libcrypto.a";
fi
# gperftools-2.1, for mem check and mem/cpu profile
LibGperfRoot=""; LibGperfFile=""
if [[ $SRS_GPERF == YES ]]; then
LibGperfRoot="${SRS_OBJS}/gperf/include"; LibGperfFile="${SRS_OBJS}/gperf/lib/libtcmalloc_and_profiler.a";
fi
if [[ $SRS_GPERF_MD == YES ]]; then
LibGperfFile="${SRS_OBJS}/gperf/lib/libtcmalloc_debug.a";
fi
# srt code path - always enabled
LibSRTRoot="${SRS_OBJS}/srt/include"; LibSRTfile="${SRS_OBJS}/srt/lib/libsrt.a"
if [[ $SRS_SHARED_SRT == YES ]]; then LibSRTfile="-L${SRS_OBJS}/srt/lib -lsrt"; fi
if [[ $SRS_USE_SYS_SRT == YES ]]; then
LibSRTRoot=""; LibSRTfile="libsrt.a"
if [[ $SRS_SHARED_SRT == YES ]]; then
LibSRTfile="";
SrsLinkOptions="${SrsLinkOptions} -lsrt";
fi
fi
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto";
fi
# Static link the c++ libraries, for user who build SRS by a new version of gcc,
# so we need to link the c++ libraries staticly but not all.
# @see https://stackoverflow.com/a/26107550
if [[ $SRS_STATIC == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -static-libstdc++";
fi
# For coverage.
if [[ $SRS_GCOV == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} ${SrsGcov}";
fi
# For FFMPEG/RTC on Linux.
if [[ $SRS_OSX != YES && $SRS_FFMPEG_FIT == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -lrt";
fi
# The backtrace symbol option.
if [[ $SRS_BACKTRACE == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -rdynamic";
fi
# For address sanitizer
# @doc: https://github.com/google/sanitizers/wiki/AddressSanitizer
if [[ $SRS_SANITIZER == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -fsanitize=address -fno-omit-frame-pointer";
if [[ $SRS_SANITIZER_STATIC == YES ]]; then
SrsLinkOptions="${SrsLinkOptions} -static-libasan";
fi
fi
# User configed options.
if [[ $SRS_EXTRA_LDFLAGS != '' ]]; then
SrsLinkOptions="${SrsLinkOptions} $SRS_EXTRA_LDFLAGS";
fi
#####################################################################################
# Modules, compile each module, then link to binary
#
#Core, depends only on system apis.
MODULE_ID="CORE"
MODULE_DEPENDS=()
ModuleLibIncs=(${SRS_OBJS})
MODULE_FILES=("srs_core" "srs_core_version" "srs_core_version7" "srs_core_autofree"
"srs_core_time" "srs_core_platform" "srs_core_deprecated" "srs_core_performance")
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . $SRS_WORKDIR/auto/modules.sh
CORE_OBJS="${MODULE_OBJS[@]}"
#
#Kernel, depends on core, provides error/log/config, nothing about stream information.
MODULE_ID="KERNEL"
MODULE_DEPENDS=("CORE")
ModuleLibIncs=(${SRS_OBJS} ${LibSSLRoot})
MODULE_FILES=("srs_kernel_error" "srs_kernel_log" "srs_kernel_buffer"
"srs_kernel_utility" "srs_kernel_flv" "srs_kernel_codec" "srs_kernel_io"
"srs_kernel_consts" "srs_kernel_aac" "srs_kernel_mp3" "srs_kernel_ts"
"srs_kernel_stream" "srs_kernel_balance" "srs_kernel_mp4" "srs_kernel_file"
"srs_kernel_kbps" "srs_kernel_rtc_rtp" "srs_kernel_rtc_rtcp" "srs_kernel_packet"
"srs_kernel_st" "srs_kernel_factory" "srs_kernel_hourglass" "srs_kernel_ps"
"srs_kernel_pithy_print" "srs_kernel_rtc_queue" "srs_kernel_resource")
KERNEL_INCS="src/kernel"; MODULE_DIR=${KERNEL_INCS} . $SRS_WORKDIR/auto/modules.sh
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} ${LibSTRoot} ${LibSSLRoot})
MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_protocol_conn" "srs_protocol_rtmp_handshake"
"srs_protocol_rtmp_stack" "srs_protocol_utility" "srs_protocol_rtmp_msg_array"
"srs_protocol_raw_avc" "srs_protocol_http_stack" "srs_protocol_json" "srs_protocol_stream"
"srs_protocol_format" "srs_protocol_log" "srs_protocol_st" "srs_protocol_http_client"
"srs_protocol_http_conn" "srs_protocol_rtmp_conn" "srs_protocol_protobuf"
"srs_protocol_http_stack_llhttp" "srs_protocol_http_stack_llhttpapi"
"srs_protocol_http_stack_llhttpadapter" "srs_protocol_http_stack_llhttphttp")
# Always include SRT protocol
MODULE_FILES+=("srs_protocol_srt")
ModuleLibIncs+=(${LibSRTRoot})
MODULE_FILES+=("srs_protocol_rtc_stun" "srs_protocol_rtp" "srs_protocol_sdp")
if [[ $SRS_RTSP == YES ]]; then
MODULE_FILES+=("srs_protocol_rtsp_stack")
fi
PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . $SRS_WORKDIR/auto/modules.sh
PROTOCOL_OBJS="${MODULE_OBJS[@]}"
#
#App Module, for SRS server only.
MODULE_ID="APP"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL")
ModuleLibIncs=(${SRS_OBJS} ${LibSSLRoot} ${LibSrtpRoot})
if [[ $SRS_GPERF == YES ]]; then
ModuleLibIncs+=(${LibGperfRoot})
fi
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibIncs+=("${LibFfmpegRoot[*]}")
fi
MODULE_FILES=("srs_app_server" "srs_app_rtmp_conn" "srs_app_rtmp_source"
"srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder"
"srs_app_st" "srs_app_log" "srs_app_config" "srs_app_stream_bridge"
"srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
"srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge"
"srs_app_heartbeat" "srs_app_http_client" "srs_app_http_static"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
"srs_app_mpegts_udp" "srs_app_listener" "srs_app_async_call"
"srs_app_caster_flv" "srs_app_latest_version" "srs_app_process"
"srs_app_dash" "srs_app_fragment" "srs_app_dvr" "srs_app_ng_exec"
"srs_app_coworkers" "srs_app_circuit_breaker" "srs_app_factory"
"srs_app_stream_token" "srs_app_http_stream")
# Always include SRT app modules
MODULE_FILES+=("srs_app_srt_server" "srs_app_srt_listener" "srs_app_srt_conn" "srs_app_srt_source")
MODULE_FILES+=("srs_app_rtc_conn" "srs_app_rtc_dtls" "srs_app_rtc_network"
"srs_app_rtc_server" "srs_app_rtc_source" "srs_app_rtc_api")
if [[ $SRS_RTSP == YES ]]; then
MODULE_FILES+=("srs_app_rtsp_source" "srs_app_rtsp_conn")
fi
if [[ $SRS_FFMPEG_FIT == YES ]]; then
MODULE_FILES+=("srs_app_rtc_codec")
fi
if [[ $SRS_GB28181 == YES ]]; then
MODULE_FILES+=("srs_app_gb28181")
fi
DEFINES=""
# add each modules for app
APP_INCS="src/app"; MODULE_DIR=${APP_INCS} . $SRS_WORKDIR/auto/modules.sh
APP_OBJS="${MODULE_OBJS[@]}"
#
#Server Module, for SRS only.
MODULE_ID="SERVER"
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP")
ModuleLibIncs=(${SRS_OBJS} ${LibGperfRoot} ${LibSSLRoot} ${LibSrtpRoot})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibIncs+=("${LibFfmpegRoot[*]}")
fi
MODULE_FILES=("srs_main_server")
SERVER_INCS="src/main"; MODULE_DIR=${SERVER_INCS} . $SRS_WORKDIR/auto/modules.sh
SERVER_OBJS="${MODULE_OBJS[@]}"
#####################################################################################
# Binaries, main entrances, link the module and its depends modules,
# then link to a binary, for example, objs/srs
#
# all main entrances
MAIN_ENTRANCES=("srs_main_server")
#
# all depends libraries
ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile} ${LibSrtpFile})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibFiles+=("${LibFfmpegFile[*]}")
fi
# Always include SRT library files
ModuleLibFiles+=("${LibSRTfile[*]}")
# all depends objects
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}"
ModuleLibIncs=(${SRS_OBJS} ${LibSTRoot} ${LibGperfRoot} ${LibSSLRoot} ${LibSrtpRoot})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibIncs+=("${LibFfmpegRoot[*]}")
fi
# Always include SRT libraries
ModuleLibIncs+=(${LibSRTRoot})
MODULE_OBJS="${MODULE_OBJS} ${SRT_OBJS[@]}"
LINK_OPTIONS="${LDFLAGS} ${SrsLinkOptions}${SrsGprofLink}${SrsGperfLink}"
#
# srs: srs(simple rtmp server) over st(state-threads)
BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" . $SRS_WORKDIR/auto/apps.sh
#
# For modules, with the app module.
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}"
ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile} ${LibSrtpFile})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibFiles+=("${LibFfmpegFile[*]}")
fi
# Always include SRT library files
ModuleLibFiles+=("${LibSRTfile[*]}")
# For utest on mac.
# @see https://github.com/protocolbuffers/protobuf/issues/51#issuecomment-111044468
if [[ $SRS_OSX == YES ]]; then
UTEST_EXTRA_DEFINES="-DGTEST_USE_OWN_TR1_TUPLE=1"
fi
#
# utest, the unit-test cases of srs, base on gtest1.6
if [[ $SRS_UTEST == YES ]]; then
MODULE_FILES=("srs_utest" "srs_utest_manual_amf0" "srs_utest_manual_kernel" "srs_utest_manual_core" "srs_utest_manual_srt"
"srs_utest_manual_config" "srs_utest_manual_rtmp" "srs_utest_manual_http" "srs_utest_manual_avc" "srs_utest_manual_reload"
"srs_utest_manual_mp4" "srs_utest_manual_service" "srs_utest_manual_app_rtc2rtmp" "srs_utest_manual_rtc" "srs_utest_manual_config2"
"srs_utest_manual_protocol" "srs_utest_manual_protocol2" "srs_utest_manual_kernel2" "srs_utest_manual_st" "srs_utest_manual_fmp4"
"srs_utest_manual_source_lock" "srs_utest_manual_stream_token" "srs_utest_manual_rtc_recv_track" "srs_utest_manual_st2"
"srs_utest_manual_hevc_structs" "srs_utest_manual_coworkers" "srs_utest_manual_pithy_print" "srs_utest_manual_protocol3"
"srs_utest_manual_app" "srs_utest_manual_mock")
MODULE_FILES+=("srs_utest_workflow_rtc_playstream" "srs_utest_workflow_rtc_publishstream"
"srs_utest_workflow_rtc_conn" "srs_utest_workflow_rtmp_conn" "srs_utest_workflow_srt_conn" "srs_utest_workflow_http_conn"
"srs_utest_workflow_forward" "srs_utest_workflow_rtc2rtmp" "srs_utest_workflow_rtmp2rtc")
MODULE_FILES+=("srs_utest_ai01" "srs_utest_ai02" "srs_utest_ai03" "srs_utest_ai04" "srs_utest_ai05"
"srs_utest_ai06" "srs_utest_ai07" "srs_utest_ai08" "srs_utest_ai09" "srs_utest_ai10" "srs_utest_ai11"
"srs_utest_ai12" "srs_utest_ai13" "srs_utest_ai14" "srs_utest_ai15" "srs_utest_ai16" "srs_utest_ai17"
"srs_utest_ai18" "srs_utest_ai19" "srs_utest_ai20" "srs_utest_ai24")
if [[ $SRS_GB28181 == YES ]]; then
MODULE_FILES+=("srs_utest_manual_gb28181" "srs_utest_ai23")
fi
if [[ $SRS_RTSP == YES ]]; then
MODULE_FILES+=("srs_utest_ai21" "srs_utest_ai22")
fi
ModuleLibIncs=(${SRS_OBJS} ${LibSTRoot} ${LibSSLRoot} ${LibSrtpRoot})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibIncs+=("${LibFfmpegRoot[*]}")
fi
# Always include SRT library includes
ModuleLibIncs+=("${LibSRTRoot[*]}")
ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibSrtpFile})
if [[ $SRS_FFMPEG_FIT == YES ]]; then
ModuleLibFiles+=("${LibFfmpegFile[*]}")
fi
# Always include SRT library files
ModuleLibFiles+=("${LibSRTfile[*]}")
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "APP")
MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${APP_OBJS[@]} ${SRT_OBJS[@]}"
LINK_OPTIONS="${LDFLAGS} -lpthread ${SrsLinkOptions}" MODULE_DIR="src/utest" APP_NAME="srs_utest" . $SRS_WORKDIR/auto/utest.sh
fi
#####################################################################################
# generate colorful summary script
. $SRS_WORKDIR/auto/summary.sh
#####################################################################################
# makefile
echo "Generate Makefile"
# backup old makefile.
rm -f ${SRS_MAKEFILE}.bk &&
mv ${SRS_MAKEFILE} ${SRS_MAKEFILE}.bk
# generate phony header
cat << END > ${SRS_MAKEFILE}
.PHONY: default all _default install help clean destroy server utest _prepare_dir $__mphonys
.PHONY: clean_srs clean_openssl clean_srtp2 clean_opus clean_ffmpeg clean_st
.PHONY: st ffmpeg
CC = ${SRS_TOOL_CC}
CXX = ${SRS_TOOL_CXX}
AR = ${SRS_TOOL_AR}
LINK = ${SRS_TOOL_LD}
RANDLIB = ${SRS_TOOL_RANDLIB}
CXXFLAGS = ${CXXFLAGS}
LDFLAGS = ${LDFLAGS}
# install prefix.
SRS_PREFIX=${SRS_PREFIX}
SRS_DEFAULT_CONFIG=${SRS_DEFAULT_CONFIG}
__REAL_INSTALL=\$(DESTDIR)\$(SRS_PREFIX)
SRS_FORCE_MAKE_JOBS=${SRS_FORCE_MAKE_JOBS}
END
if [[ $SRS_FORCE_MAKE_JOBS == YES ]]; then
cat << END >> ${SRS_MAKEFILE}
JOBS=\$(shell echo \$(MAKEFLAGS)| grep -qE '\-j[0-9]+' || echo " ${SRS_JOBS}")
END
fi
# the real entry for all platform:
cat << END >> ${SRS_MAKEFILE}
default: server
all: _default
_default: server utest
help:
@echo "Usage: make <help>|<clean>|<destroy>|<server>|<utest>|<install>|<uninstall>"
@echo " help Display this help menu"
@echo " clean Cleanup project and all depends"
@echo " destroy Cleanup all files for this platform in ${SRS_OBJS}/${SRS_PLATFORM}"
@echo " server Build the srs and other modules in main"
@echo " utest Build the utest for srs"
@echo " install Install srs to the prefix path"
@echo " uninstall Uninstall srs from prefix path"
@echo "To rebuild special module:"
@echo " st Rebuild st-srs in ${SRS_OBJS}/${SRS_PLATFORM}/st-srs"
@echo " ffmpeg Rebuild ffmpeg in ${SRS_OBJS}/${SRS_PLATFORM}/ffmpeg-4.2-fit"
@echo "To reconfigure special depends:"
@echo " clean_openssl Remove the openssl cache."
@echo " clean_srtp2 Remove the libsrtp2 cache."
@echo " clean_opus Remove the opus cache."
@echo " clean_ffmpeg Remove the FFmpeg cache."
@echo " clean_st Remove the ST cache."
@echo "For example:"
@echo " make"
@echo " make help"
doclean:
(cd ${SRS_OBJS} && rm -rf srs srs_utest srs.exe srs_utest.exe $__mcleanups)
(cd ${SRS_OBJS} && rm -rf src/* include lib)
(mkdir -p ${SRS_OBJS}/utest && cd ${SRS_OBJS}/utest && rm -rf *.o *.a)
clean: clean_srs
destroy:
(cd ${SRS_OBJS} && rm -rf ${SRS_PLATFORM})
clean_srs:
@(cd ${SRS_OBJS} && rm -rf srs srs_utest src/* utest/*)
clean_openssl:
@rm -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdparty/openssl
@echo "Please rebuild openssl by: ./configure"
clean_srtp2:
@rm -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdparty/srtp2
@echo "Please rebuild libsrtp2 by: ./configure"
clean_opus:
@rm -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdparty/opus
@echo "Please rebuild opus by: ./configure"
clean_ffmpeg:
@rm -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdparty/ffmpeg
@echo "Please rebuild FFmpeg by: ./configure"
clean_st:
@rm -rf ${SRS_OBJS}/${SRS_PLATFORM}/3rdparty/st
@echo "Please rebuild ST by: ./configure"
st:
@rm -f ${SRS_OBJS}/srs srs_utest
@\$(MAKE)\$(JOBS) -C ${SRS_OBJS}/${SRS_PLATFORM}/st-srs clean
@env EXTRA_CFLAGS="${_ST_EXTRA_CFLAGS}" \$(MAKE)\$(JOBS) -C ${SRS_OBJS}/${SRS_PLATFORM}/st-srs ${_ST_MAKE_ARGS} CC=\$(CC) CXX=\$(CXX) AR=\$(AR) LD=\$(LINK) RANDLIB=\$(RANDLIB)
@echo "Please rebuild srs by: make"
ffmpeg:
@rm -f ${SRS_OBJS}/srs srs_utest
\$(MAKE)\$(JOBS) -C ${SRS_OBJS}/${SRS_PLATFORM}/ffmpeg-4.2-fit
\$(MAKE)\$(JOBS) -C ${SRS_OBJS}/${SRS_PLATFORM}/ffmpeg-4.2-fit install-libs
@echo "Please rebuild srs by: make"
END
# Generate Makefile entry for srs-server.
cat << END >> ${SRS_MAKEFILE}
server: _prepare_dir
@echo "Build the SRS server, JOBS=\${JOBS}, FORCE_MAKE_JOBS=${SRS_FORCE_MAKE_JOBS}"
\$(MAKE)\$(JOBS) -f ${SRS_OBJS}/Makefile srs
@bash objs/_srs_build_summary.sh
END
# install entry
cat << END >> ${SRS_MAKEFILE}
uninstall:
@echo "rmdir \$(SRS_PREFIX)"
@rm -rf \$(SRS_PREFIX)
install:
@echo "Now mkdir \$(__REAL_INSTALL)"
@mkdir -p \$(__REAL_INSTALL)
@echo "Now make the http root dir"
@mkdir -p \$(__REAL_INSTALL)/objs/nginx/html
@cp -f research/index.html \$(__REAL_INSTALL)/objs/nginx/html
@cp -f research/favicon.ico \$(__REAL_INSTALL)/objs/nginx/html
@cp -Rf research/players \$(__REAL_INSTALL)/objs/nginx/html/
@cp -Rf research/console \$(__REAL_INSTALL)/objs/nginx/html/
@cp -Rf 3rdparty/signaling/www/demos \$(__REAL_INSTALL)/objs/nginx/html/
@echo "Now copy binary files"
@mkdir -p \$(__REAL_INSTALL)/objs
@cp -f objs/srs \$(__REAL_INSTALL)/objs
@echo "Now copy srs conf files"
@mkdir -p \$(__REAL_INSTALL)/conf
@cp -f conf/*.conf \$(__REAL_INSTALL)/conf
@cp -f conf/server.key conf/server.crt \$(__REAL_INSTALL)/conf
@echo "Now copy init.d script files"
@mkdir -p \$(__REAL_INSTALL)/etc/init.d
@cp -f etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
@sed -i "s|^ROOT=.*|ROOT=\"\$(SRS_PREFIX)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
@sed -i "s|^CONFIG=.*|CONFIG=\"\$(SRS_DEFAULT_CONFIG)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
@echo "Now copy systemctl service files"
@mkdir -p \$(__REAL_INSTALL)/usr/lib/systemd/system
@cp -f usr/lib/systemd/system/srs.service \$(__REAL_INSTALL)/usr/lib/systemd/system/srs.service
@echo ""
@echo "@see: https://ossrs.net/lts/zh-cn/docs/v7/doc/service"
END
if [[ $SRS_UTEST == YES ]]; then
cat << END >> ${SRS_MAKEFILE}
utest: server
@echo "Building the utest for srs"
${SrsUtestMakeEntry}
@echo "The utest is built ok."
END
else
cat << END >> ${SRS_MAKEFILE}
utest: server
@echo "Ignore utest for it's disabled."
END
fi
cat << END >> ${SRS_MAKEFILE}
# the ./configure will generate it.
_prepare_dir:
@mkdir -p ${SRS_OBJS}
END
# generate makefile ok, append the tails.
cat ${SRS_MAKEFILE}.bk >> ${SRS_MAKEFILE} &&
rm -f ${SRS_MAKEFILE}.bk
echo 'Configure ok! '
#####################################################################################
# when configure success, prepare build
#####################################################################################
# create objs/logs for ffmpeg to write log.
mkdir -p ${SRS_OBJS}/logs
#####################################################################################
# configure summary
#####################################################################################
# summary
echo ""
echo "Configure summary:"
echo " ${SRS_AUTO_USER_CONFIGURE}"
echo " ${SRS_AUTO_CONFIGURE}"
if [[ $SRS_HLS == YES ]]; then
echo -e "${GREEN}HLS is enabled.${BLACK}"
else
echo -e "${YELLOW}Warning: HLS is disabled.${BLACK}"
fi
if [[ $SRS_STREAM_CASTER == YES ]]; then
echo -e "${YELLOW}Experiment: StreamConverter is enabled.${BLACK}"
else
echo -e "${GREEN}Note: StreamConverter is disabled.${BLACK}"
fi
if [[ $SRS_HDS == YES ]]; then
echo -e "${YELLOW}Experiment: HDS is enabled.${BLACK}"
else
echo -e "${GREEN}Warning: HDS is disabled.${BLACK}"
fi
if [[ $SRS_GB28181 == YES ]]; then
echo -e "${YELLOW}Experiment: GB28181 is enabled. https://github.com/ossrs/srs/issues/3176${BLACK}"
else
echo -e "${GREEN}Warning: GB28181 is disabled.${BLACK}"
fi
echo -e "${GREEN}Experiment: HEVC/H.265 is enabled. https://github.com/ossrs/srs/issues/465${BLACK}"
echo -e "${YELLOW}Experiment: SRT is enabled. https://github.com/ossrs/srs/issues/1147${BLACK}"
echo -e "${YELLOW}Experiment: RTC is enabled. https://github.com/ossrs/srs/issues/307${BLACK}"
if [[ $SRS_RTSP == YES ]]; then
echo -e "${YELLOW}Experiment: RTSP is enabled (requires RTC).${BLACK}"
else
echo -e "${GREEN}Warning: RTSP is disabled.${BLACK}"
fi
if [[ $SRS_HTTPS == YES ]]; then
echo -e "${YELLOW}Experiment: HTTPS is enabled. https://github.com/ossrs/srs/issues/1657${BLACK}"
else
echo -e "${GREEN}Warning: HTTPS is disabled.${BLACK}"
fi
if [[ $SRS_DVR == YES ]]; then
echo -e "${GREEN}DVR is enabled.${BLACK}"
else
echo -e "${YELLOW}Warning: DVR is disabled.${BLACK}"
fi
if [[ $SRS_SSL == YES ]]; then
echo -e "${GREEN}RTMP complex handshake is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: RTMP complex handshake is disabled, flash cann't play h264/aac.${BLACK}"
fi
if [[ $SRS_NASM == YES ]]; then
echo -e "${GREEN}NASM for HTTPS(openssl) and FFmepg is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: NASM for HTTPS(openssl) and FFmepg is disabled${BLACK}"
fi
if [[ $SRS_SRTP_ASM == YES ]]; then
echo -e "${GREEN}SRTP-NASM for WebRTC(openssl) is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: SRTP-NASM for WebRTC(openssl) is disabled${BLACK}"
fi
if [[ $SRS_TRANSCODE == YES ]]; then
echo -e "${GREEN}The transcoding is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: The transcoding is disabled.${BLACK}"
fi
if [[ $SRS_INGEST == YES ]]; then
echo -e "${GREEN}The ingesting is enabled.${BLACK}"
else
echo -e "${YELLOW}Warning: The ingesting is disabled.${BLACK}"
fi
if [[ $SRS_HTTP_CALLBACK == YES ]]; then
echo -e "${GREEN}The http-callback is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: The http-callback is disabled.${BLACK}"
fi
if [[ $SRS_HTTP_SERVER == YES ]]; then
echo -e "${GREEN}Embeded HTTP server for HTTP-FLV/HLS is enabled.${BLACK}"
else
echo -e "${YELLOW}Warning: Embeded HTTP server is disabled, HTTP-FLV is disabled, please use nginx to delivery HLS.${BLACK}"
fi
if [[ $SRS_HTTP_API == YES ]]; then
echo -e "${GREEN}The HTTP API is enabled${BLACK}"
else
echo -e "${YELLOW}Warning: The HTTP API is disabled.${BLACK}"
fi
if [[ $SRS_UTEST == YES ]]; then
echo -e "${GREEN}The utests are enabled.${BLACK}"
else
echo -e "${YELLOW}Note: The utests are disabled.${BLACK}"
fi
if [[ $SRS_GPERF == YES ]]; then
echo -e "${GREEN}The gperf(tcmalloc) is enabled.${BLACK}"
else
echo -e "${GREEN}Note: The gperf(tcmalloc) is disabled.${BLACK}"
fi
if [[ $SRS_GPERF_MC == YES ]]; then
echo -e "${YELLOW}The gmc(gperf memory check) is enabled, performance may suffer.${BLACK}"
else
echo -e "${GREEN}Note: The gmc(gperf memory check) is disabled.${BLACK}"
fi
if [[ $SRS_GPERF_MD == YES ]]; then
echo -e "${YELLOW}The gmd(gperf memory defense) is enabled, performance may suffer.${BLACK}"
else
echo -e "${GREEN}Note: The gmd(gperf memory defense) is disabled.${BLACK}"
fi
if [[ $SRS_GPERF_MP == YES ]]; then
echo -e "${YELLOW}The gmp(gperf memory profile) is enabled, performance may suffer.${BLACK}"
else
echo -e "${GREEN}Note: The gmp(gperf memory profile) is disabled.${BLACK}"
fi
if [[ $SRS_GPERF_CP == YES ]]; then
echo -e "${YELLOW}The gcp(gperf cpu profile) is enabled, performance may suffer.${BLACK}"
else
echo -e "${GREEN}Note: The gcp(gperf cpu profile) is disabled.${BLACK}"
fi
if [[ $SRS_GPROF == YES ]]; then
echo -e "${YELLOW}The gprof(GNU profile tool) is enabled, performance may suffer.${BLACK}"
else
echo -e "${GREEN}Note: The gprof(GNU profile tool) is disabled.${BLACK}"
fi
if [[ $SRS_CROSS_BUILD == YES ]]; then
echo -e "${YELLOW}The cross-build is enabled.${BLACK}"
else
echo -e "${GREEN}Note: The cross-build is disabled.${BLACK}"
fi
if [[ $SRS_VALGRIND == YES ]]; then
echo -e "${GREEN}The valgrind is enabled.${BLACK}"
else
echo -e "${GREEN}Note: The valgrind is disabled.${BLACK}"
fi
if [[ $SRS_SANITIZER == YES ]]; then
echo -e "${GREEN}The sanitizer is enabled.${BLACK}"
else
echo -e "${GREEN}Note: The sanitizer is disabled.${BLACK}"
fi
#####################################################################################
# Do cleanup when configure done.
#####################################################################################
if [[ $SRS_CLEAN == YES && -f Makefile ]]; then
#echo "Do full cleanup, you can disable it by: --clean=off"
make clean
fi
#####################################################################################
# next step
#####################################################################################
echo ""
echo "You can build SRS:"
echo "\" make \" to build the SRS server"
echo "\" make help \" to get some help"