srs/trunk/src/app/srs_app_stream_bridge.hpp
Haibo Chen(陈海博) 64bbb5adcc
rtmp2rtc: Support HEVC. v7.0.33 (#4289)
## 1. Usage
### Launch Chrome with H.265 enabled: 
```bash
# Windows: 
C:\Program Files\Google\Chrome\Application>"C:\Program Files\Google\Chrome\Application\chrome.exe" --enable-features=WebRtcAllowH265Receive --force-fieldtrials=WebRTC-Video-H26xPacketBuffer/Enabled

# macOS:
open -a "Google Chrome" --args --enable-features=WebRtcAllowH265Receive --force-fieldtrials=WebRTC-Video-H26xPacketBuffer/Enabled
```

> Note: The latest Chrome browser (version 136) fully enables this by
default, so there's no need to launch it with any extra parameters.

### Launch SRS with `rtmp2rtc.conf`
```bash
./objs/srs -c conf/rtmp2rtc.conf
```

### Push H.265 with RTMP
```bash
ffmpeg -stream_loop -1 -re -i input.mp4 -c:v libx265 -preset fast -b:v 2000k -maxrate 2000k -bufsize 4000k -bf 0 -c:a aac -b:a 128k -ar 44100 -ac 2 -f flv rtmp://localhost/live/livestream
```

### Play with WebRTC
```bash
http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream
```


![image](https://github.com/user-attachments/assets/bdbf4c67-b7e2-4dc6-92a1-93e2c78e00fe)


## 2. Parameter Combinations for SDP
sendrecv offer
```bash
--enable-features=WebRtcAllowH265Send,PlatformHEVCEncoderSupport,WebRtcAllowH265Receive --force-fieldtrials=WebRTC-Video-H26xPacketBuffer/Enabled
```

sendonly offer
```bash
--enable-features=WebRtcAllowH265Send,PlatformHEVCEncoderSupport
```

recvonly offer
```bash
--enable-features=WebRtcAllowH265Receive --force-fieldtrials=WebRTC-Video-H26xPacketBuffer/Enabled
```

## 3. How to test if H.265 is working
* Browser Test for supporting H265


https://webrtc.github.io/samples/src/content/peerconnection/change-codecs/


![image](https://github.com/user-attachments/assets/174476df-a7aa-4951-9880-56328ec75065)

* How to test Safari: https://github.com/ossrs/srs/pull/3441
* Debug in Safari

![image](https://github.com/user-attachments/assets/6cf94fca-e3ed-46d2-a102-a472f1699b4e)


---------

Co-authored-by: chundonglinlin <chundonglinlin@163.com>
Co-authored-by: winlin <winlinvip@gmail.com>
Co-authored-by: john <hondaxiao@tencent.com>

---------

Co-authored-by: chundonglinlin <chundonglinlin@163.com>
Co-authored-by: john <hondaxiao@tencent.com>
2025-05-13 14:55:52 +08:00

104 lines
2.6 KiB
C++

//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_APP_STREAM_BRIDGE_HPP
#define SRS_APP_STREAM_BRIDGE_HPP
#include <srs_core.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_core_autofree.hpp>
#include <vector>
class SrsRequest;
class SrsSharedPtrMessage;
class SrsLiveSource;
class SrsRtcSource;
class SrsRtmpFormat;
class SrsMetaCache;
class SrsRtpPacket;
class SrsRtcRtpBuilder;
// A stream bridge is used to convert stream via different protocols, such as bridge for RTMP and RTC. Generally, we use
// frame as message for bridge. A frame is a audio or video frame, such as an I/B/P frame, a general frame for decoder.
// So you must assemble RTP or TS packets to a video frame if WebRTC or SRT.
class ISrsStreamBridge
{
public:
ISrsStreamBridge();
virtual ~ISrsStreamBridge();
public:
virtual srs_error_t initialize(SrsRequest* r) = 0;
virtual srs_error_t on_publish() = 0;
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame) = 0;
virtual void on_unpublish() = 0;
};
// A bridge to feed AV frame to RTMP stream.
class SrsFrameToRtmpBridge : public ISrsStreamBridge
{
private:
SrsSharedPtr<SrsLiveSource> source_;
public:
SrsFrameToRtmpBridge(SrsSharedPtr<SrsLiveSource> source);
virtual ~SrsFrameToRtmpBridge();
public:
srs_error_t initialize(SrsRequest* r);
public:
virtual srs_error_t on_publish();
virtual void on_unpublish();
public:
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
};
#ifdef SRS_RTC
// A bridge to covert AV frame to WebRTC stream.
class SrsFrameToRtcBridge : public ISrsStreamBridge
{
private:
SrsSharedPtr<SrsRtcSource> source_;
private:
#if defined(SRS_FFMPEG_FIT)
SrsRtcRtpBuilder* rtp_builder_;
#endif
private:
SrsVideoCodecId video_codec_id_;
public:
SrsFrameToRtcBridge(SrsSharedPtr<SrsRtcSource> source);
virtual ~SrsFrameToRtcBridge();
public:
virtual srs_error_t initialize(SrsRequest* r);
virtual srs_error_t on_publish();
virtual void on_unpublish();
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
srs_error_t on_rtp(SrsRtpPacket* pkt);
srs_error_t update_codec(SrsVideoCodecId id);
};
#endif
// A bridge chain, a set of bridges.
class SrsCompositeBridge : public ISrsStreamBridge
{
public:
SrsCompositeBridge();
virtual ~SrsCompositeBridge();
public:
srs_error_t initialize(SrsRequest* r);
public:
virtual srs_error_t on_publish();
virtual void on_unpublish();
public:
virtual srs_error_t on_frame(SrsSharedPtrMessage* frame);
public:
SrsCompositeBridge* append(ISrsStreamBridge* bridge);
private:
std::vector<ISrsStreamBridge*> bridges_;
};
#endif