When SRT publisher disconnects, player hangs indefinitely instead of
exiting after the configured peer_idle_timeout. This is because the
consumer wait() never checks if the publisher is still connected.
After fix, player waits for peer_idle_timeout (default 10s) then exits
gracefully when no packets arrive and publisher has disconnected.
This PR adds separate audio and video frame counting to the HTTP API
(`/api/v1/streams/`) for better stream observability. The API now
reports three frame fields:
- `frames` - Total frames (video + audio)
- `video_frames` - Video frames/packets only
- `audio_frames` - Audio frames/packets only
This enhancement provides better visibility into stream composition and
helps detect issues with CBR/VBR streams, audio/video sync problems, and
codec-specific behavior.
**Before:**
```json
{
"streams": [
{
"frames": 0, // video frames.
}
]
}
```
**After:**
```json
{
"streams": [
{
"frames": 6912, // video frames.
"audio_frames": 5678, // audio frames.
"video_frames": 1234, // video frames.
}
]
}
```
Frame Counting Strategy
- All protocols report frames every N frames to balance accuracy and
performance
- Frames are counted at the protocol-specific message/packet level:
- RTMP: Counts RTMP messages (video/audio)
- WebRTC: Counts RTP packets (video/audio)
- SRT: Counts MPEG-TS messages (H.264/HEVC/AAC)
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>
This PR refactors the stream bridge architecture in SRS to improve code
organization, type safety, and maintainability by replacing the generic
ISrsStreamBridge interface with protocol-specific bridge classes and
target interfaces.
1. New Target Interface Architecture:
- Introduces ISrsFrameTarget for AV frame consumers (RTMP sources)
- Introduces ISrsRtpTarget for RTP packet consumers (RTC sources)
- Introduces ISrsSrtTarget for SRT packet consumers (SRT sources)
2. Protocol-Specific Bridge Classes:
- SrsRtmpBridge: Converts RTMP frames to RTC/RTSP protocols
- SrsSrtBridge: Converts SRT packets to RTMP/RTC protocols
- SrsRtcBridge: Converts RTC packets to RTMP protocol
3. Simplified Bridge Management:
- Removes the generic SrsCompositeBridge chain pattern
- Each source type now uses its appropriate bridge type directly
With this improvement, you are able to implement very complex bridge and
protocol converting, for example, you can bridge RTMP to RTC with opus
audio when you support enhanced RTMP with opus.
Another plan is to support bridging RTC to RTSP, directly without
converting RTP to media frame packet, but directly deliver RTP packet
from RTC source to RTSP source.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
Move global xpps statistics variables from `srs_app_server.cpp` to
`srs_kernel_kbps.cpp`.
Extract global shared timers from `SrsServer` into new `SrsSharedTimer`
class.
Extract WebRTC session management logic from `SrsServer` into dedicated
`SrsRtcSessionManager` class.
Extract PID file handling into dedicated `SrsPidFileLocker` class.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR consolidates the SRT and RTC server functionality into the main
SrsServer class, eliminating the separate `SrsSrtServer` and
`SrsRtcServer` classes and their corresponding adapter classes. This
architectural change simplifies the codebase by removing the hybrid
server pattern and integrating all protocol handling directly into
`SrsServer`.
As unified connection manager (`_srs_conn_manager`) for all protocol
connections, all incoming connections are checked against the same
connection limit in `on_before_connection()`. This enables consistent
connection limits: `max_connections` now protects against resource
exhaustion from any protocol, not just RTMP.
Remove modules because it's not used now, so only keep the server
application module and main entry point. Remove the wait group to run
server, instead, directly run server and invoke the cycle method.
After this PR, the startup workflow and servers architecture should be
much easier to maintain.
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR introduces a comprehensive stream publish token system that
prevents race conditions when multiple publishers attempt to publish to
the same stream URL simultaneously across different protocols (RTMP,
WebRTC, SRT).
* Race Condition Issue: Multiple publishers could create duplicate
sources for the same stream when context switches occurred during source
initialization in SRS's coroutine-based architecture
* Cross-Protocol Conflicts: Different protocols (RTMP, RTC, SRT) could
simultaneously publish to the same stream URL without coordination
* Resource Management: No centralized mechanism to ensure exclusive
stream publishing access
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR fixes a critical race condition in SRS source managers where
multiple coroutines could create duplicate sources for the same stream.
- **Atomic source creation**: Source lookup, creation, and pool
insertion now happen atomically within lock scope
- **Consistent interface**: Standardize on `ISrsRequest*` interface
throughout codebase
- **Handler simplification**: Remove `ISrsLiveSourceHandler*` parameter,
obtain from global server instance
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR makes WebRTC a core feature of SRS and enforces C++98
compatibility by:
1. Always Enable WebRTC Support
- Remove `--rtc=on|off` configuration option - WebRTC is now always
enabled
- Eliminate all `#ifdef SRS_RTC` conditional compilation blocks
- Include WebRTC-related modules (RTC, SRTP, DTLS) in all builds
- Update build scripts to always link WebRTC dependencies
2. Enforce C++98 Compatibility
- Remove `--cxx11=on|off` and `--cxx14=on|off` configuration options
- Force `SRS_CXX11=NO` and `SRS_CXX14=NO` in build system
- Move these options to deprecated section with warnings
- Ensure codebase maintains C++98 standard compatibility
3. Remove Windows/Cygwin Support
- Remove all Windows and Cygwin64 conditional compilation blocks (#ifdef
_WIN32, #ifdef CYGWIN64)
- Delete Cygwin64 build configurations from build scripts (
auto/options.sh, auto/depends.sh, configure)
- Remove Cygwin64 assembly files and State Threads platform support (
md_cygwin64.S)
- Eliminate Windows-specific GitHub Actions workflows and CI/CD jobs
- Remove NSIS packaging files and Windows installer generation
- Delete Windows documentation and update feature lists to mark support
as removed in v7.0
- Simplify OS detection to only support Unix-like systems (Linux, macOS)
4. Code Cleanup
- Remove conditional WebRTC code blocks throughout the codebase
- Simplify build configuration by removing WebRTC-related conditionals
- Update constructor delegation patterns to be C++98 compatible
- Fix vector initialization to use C++98 syntax
- Eliminate Windows-specific implementations for file operations, time
handling, and networking
- Unified platform handling with consistent POSIX API usage
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This PR refactors the HTTP hooks system from static methods to a proper
interface-based architecture, improving code maintainability,
testability, and extensibility.
1. **Testability**: Interface allows easy mocking for unit tests
1. **Extensibility**: Custom hook implementations can be injected
1. **Maintainability**: Clear separation of concerns and better code
organization
1. **Documentation**: Comprehensive inline documentation for all hook
methods
1. **Future-proofing**: Enables plugin architecture and custom hook
handlers
---------
Co-authored-by: OSSRS-AI <winlinam@gmail.com>
To manage an object:
```cpp
// Before
MyClass* ptr = new MyClass();
SrsAutoFree(MyClass, ptr);
ptr->do_something();
// Now
SrsUniquePtr<MyClass> ptr(new MyClass());
ptr->do_something();
```
To manage an array of objects:
```cpp
// Before
char* ptr = new char[10];
SrsAutoFreeA(char, ptr);
ptr[0] = 0xf;
// Now
SrsUniquePtr<char[]> ptr(new char[10]);
ptr[0] = 0xf;
```
In fact, SrsUniquePtr is a limited subset of SrsAutoFree, mainly
managing pointers and arrays. SrsUniquePtr is better than SrsAutoFree
because it has the same API to standard unique ptr.
```cpp
SrsUniquePtr<MyClass> ptr(new MyClass());
ptr->do_something();
MyClass* p = ptr.get();
```
SrsAutoFree actually uses a pointer to a pointer, so it can be set to
NULL, allowing the pointer's value to be changed later (this usage is
different from SrsUniquePtr).
```cpp
// OK to free ptr correctly.
MyClass* ptr;
SrsAutoFree(MyClass, ptr);
ptr = new MyClass();
// Crash because ptr is an invalid pointer.
MyClass* ptr;
SrsUniquePtr<MyClass> ptr(ptr);
ptr = new MyClass();
```
Additionally, SrsAutoFreeH can use specific release functions, which
SrsUniquePtr does not support.
---------
Co-authored-by: Jacob Su <suzp1984@gmail.com>
Security is the built-in IP whitelist feature of SRS, which allows and
denies certain IP and IP range users. Previously, it only supported
RTMP, but this PR now supports HTTP-FLV, HLS, WebRTC, SRT, and other
protocols.
See https://ossrs.io/lts/en-us/docs/v6/doc/security as example.
---------
Co-authored-by: john <hondaxiao@tencent.com>