Skip to content

Commit 0978dfc

Browse files
author
Thomas
committed
add h265 example
1 parent 4c01467 commit 0978dfc

File tree

9 files changed

+1765
-0
lines changed

9 files changed

+1765
-0
lines changed

examples/libdatachannel/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ FetchContent_MakeAvailable(NabtoWebrtcSignaling)
2020
add_subdirectory(src/common)
2121
add_subdirectory(src/webrtc_device)
2222
add_subdirectory(src/webrtc_device_rtsp)
23+
add_subdirectory(src/webrtc_device_rtsp_h265)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
set(src
2+
main.cpp
3+
rtsp-client/rtsp_client.cpp
4+
rtsp-client/tcp_rtp_client.cpp
5+
)
6+
7+
option(RTSP_HAS_BASIC_AUTH "disable RTSP client basic auth" ON)
8+
option(RTSP_HAS_DIGEST_AUTH "disable RTSP client digest auth" ON)
9+
10+
if (RTSP_HAS_BASIC_AUTH)
11+
add_definitions(-DNABTO_RTSP_HAS_BASIC_AUTH)
12+
endif()
13+
if (RTSP_HAS_DIGEST_AUTH)
14+
add_definitions(-DNABTO_RTSP_HAS_DIGEST_AUTH)
15+
endif()
16+
17+
add_executable(webrtc_device_rtsp_h265 "${src}")
18+
19+
find_package(plog REQUIRED)
20+
find_package(cxxopts)
21+
find_package(LibDataChannel REQUIRED)
22+
find_package(CURL REQUIRED)
23+
24+
find_package(NabtoWebrtcSignaling REQUIRED)
25+
find_package(OpenSSL REQUIRED)
26+
27+
target_link_libraries(webrtc_device_rtsp_h265
28+
webrtc_example_common
29+
cxxopts::cxxopts
30+
LibDataChannel::LibDataChannel
31+
CURL::libcurl
32+
plog::plog
33+
NabtoWebrtcSignaling::device
34+
NabtoWebrtcSignaling::util_logging
35+
NabtoWebrtcSignaling::util_curl_client
36+
NabtoWebrtcSignaling::util_token_generator
37+
OpenSSL::Crypto
38+
)
39+
40+
install(TARGETS webrtc_device_rtsp_h265
41+
RUNTIME DESTINATION bin
42+
)
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include <nabto/webrtc/util/logging.hpp>
5+
#include <rtc/rtc.hpp>
6+
#include <webrtc_connection/track_handler.hpp>
7+
8+
#include "rtsp-client/rtsp_client.hpp"
9+
10+
namespace nabto {
11+
namespace example {
12+
13+
class H265TrackHandler;
14+
typedef std::shared_ptr<H265TrackHandler> H265TrackHandlerPtr;
15+
16+
class SsrcGenerator {
17+
public:
18+
static uint32_t generateSsrc() {
19+
static std::mutex mutex;
20+
std::lock_guard<std::mutex> lock(mutex);
21+
22+
static uint32_t ssrc = 0;
23+
24+
ssrc += 1;
25+
return ssrc;
26+
}
27+
};
28+
29+
class MidGenerator {
30+
public:
31+
static std::string generateMid() {
32+
static std::mutex mutex;
33+
std::lock_guard<std::mutex> lock(mutex);
34+
static uint64_t midCounter = 0;
35+
std::stringstream ss;
36+
ss << "device-" << midCounter;
37+
midCounter += 1;
38+
return ss.str();
39+
}
40+
};
41+
42+
class HandlerTrack {
43+
public:
44+
std::shared_ptr<rtc::Track> videoTrack;
45+
std::shared_ptr<rtc::Track> audioTrack;
46+
RtspClientPtr rtp;
47+
size_t ref;
48+
};
49+
50+
class H265TrackHandler : public WebrtcTrackHandler,
51+
public std::enable_shared_from_this<H265TrackHandler> {
52+
public:
53+
static WebrtcTrackHandlerPtr create(std::string rtspUrl) {
54+
return std::make_shared<H265TrackHandler>(rtspUrl);
55+
}
56+
57+
H265TrackHandler(std::string rtspUrl)
58+
: rtspUrl_(rtspUrl),
59+
ssrc_(SsrcGenerator::generateSsrc()),
60+
audioSsrc_(SsrcGenerator::generateSsrc()) {
61+
RtspClientConf conf = {rtspUrl, nullptr, nullptr, 96,
62+
111, ssrc_, audioSsrc_};
63+
rtp_ = RtspClient::create(conf);
64+
}
65+
66+
size_t addTrack(std::shared_ptr<rtc::PeerConnection> pc) {
67+
counter_++;
68+
RtspClientConf conf = {
69+
rtspUrl_, nullptr, nullptr,
70+
96, 111, ssrc_,
71+
audioSsrc_, true, (uint16_t)(42222 + (counter_ * 4))};
72+
HandlerTrack track;
73+
74+
track.rtp = RtspClient::create(conf);
75+
track.videoTrack = pc->addTrack(createVideoDescription());
76+
track.audioTrack = pc->addTrack(createAudioDescription());
77+
track.ref = track.rtp->addConnection(track.videoTrack, track.audioTrack);
78+
return track.ref;
79+
}
80+
81+
void removeConnection(size_t ref) {
82+
auto conn = connections_.find(ref);
83+
if (conn == connections_.end()) {
84+
return;
85+
}
86+
conn->second.rtp->removeConnection(ref);
87+
connections_.erase(conn);
88+
}
89+
90+
void close() {
91+
videoTrack_ = nullptr;
92+
rtp_ = nullptr;
93+
}
94+
95+
private:
96+
std::shared_ptr<rtc::Track> videoTrack_;
97+
std::shared_ptr<rtc::Track> audioTrack_;
98+
RtspClientPtr rtp_;
99+
100+
std::map<size_t, HandlerTrack> connections_;
101+
size_t counter_ = 0;
102+
103+
std::string rtspUrl_;
104+
uint32_t ssrc_;
105+
uint32_t payloadType_ = 96;
106+
107+
uint32_t audioSsrc_;
108+
109+
rtc::Description::Video createVideoDescription() {
110+
// Create a Video media description.
111+
// We support both sending and receiving video
112+
std::string mid = MidGenerator::generateMid();
113+
rtc::Description::Video media(mid, rtc::Description::Direction::SendRecv);
114+
115+
// media.addVideoCodec(
116+
// 96,
117+
// "m=video 0 RTP/AVP 96\r\nc=IN IP4 0.0.0.0\r\na=rtpmap:96 "
118+
// "H265/90000\r\na=framerate:30\r\na=fmtp:96 "
119+
// "sprop-vps=QAEMAf//"
120+
// "BAgAAAMAmAgAAAMAAFqSgJA=;sprop-sps="
121+
// "QgEBBAgAAAMAmAgAAAMAAFqQAKBAPCKUslSSZX/"
122+
// "4AAgAC1BgYGBAAAADAEAAAAeC;sprop-pps=RAHBcoYMRiQ=\r\na=control:"
123+
// "stream=0\r\na=ts-refclk:local\r\na=mediaclk:sender\r\na=ssrc:"
124+
// "1842951636 cname:user1268947453@host-65e41dfd\r\n");
125+
126+
// Since we are creating the media track, only the supported payload
127+
// type exists, so we might as well reuse the same value for the RTP
128+
// session in WebRTC as the one we use in the RTP source (eg. Gstreamer)
129+
media.addH265Codec(payloadType_);
130+
auto r = media.rtpMap(96);
131+
// r->fmtps.push_back(
132+
// "sprop-vps=QAEMAf//"
133+
// "BAgAAAMAmAgAAAMAAFqSgJA=;sprop-sps="
134+
// "QgEBBAgAAAMAmAgAAAMAAFqQAKBAPCKUslSSZX/"
135+
// "4AAgAC1BgYGBAAAADAEAAAAeC;sprop-pps=RAHBcoYMRiQ=");
136+
137+
return media;
138+
}
139+
140+
rtc::Description::Audio createAudioDescription() {
141+
// Create an Audio media description.
142+
// We support both sending and receiving audio
143+
std::string mid = MidGenerator::generateMid();
144+
rtc::Description::Audio media(mid, rtc::Description::Direction::SendRecv);
145+
146+
media.addOpusCodec(111);
147+
auto r = media.rtpMap(111);
148+
149+
// media.addPCMUCodec(0);
150+
// auto r = media.rtpMap(0);
151+
152+
r->removeFeedback("nack");
153+
r->removeFeedback("goog-remb");
154+
return media;
155+
}
156+
};
157+
158+
} // namespace example
159+
} // namespace nabto

0 commit comments

Comments
 (0)