-
Notifications
You must be signed in to change notification settings - Fork 8
/
Server.cpp
159 lines (126 loc) · 4.46 KB
/
Server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <string>
#include <deque>
#include <fmt/format.h>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_sinks.h>
#include "CxxPtr/GlibPtr.h"
#include "CxxPtr/GstRtspServerPtr.h"
#include "CxxPtr/libconfigDestroy.h"
#include "ConfigHelpers.h"
#define BARS "bars"
#define WHITE "white"
#define BLACK "black"
#define RED "red"
#define GREEN "green"
#define BLUE "blue"
static std::unique_ptr<spdlog::logger> Log;
struct Config {
uint16_t port = 8554;
};
static void InitLogger() {
spdlog::sink_ptr sink = std::make_shared<spdlog::sinks::stdout_sink_st>();
Log = std::make_unique<spdlog::logger>("rtsp-test-server", sink);
Log->set_level(spdlog::level::info);
}
static void LoadConfig(Config* config)
{
const std::deque<std::string> configDirs = ::ConfigDirs();
if(configDirs.empty())
return;
Config loadedConfig = *config;
for(const std::string& configDir: configDirs) {
const std::string configFile = configDir + "/rtsp-test-server.conf";
if(!g_file_test(configFile.c_str(), G_FILE_TEST_IS_REGULAR)) {
continue;
}
config_t config;
config_init(&config);
ConfigDestroy ConfigDestroy(&config);
Log->error("Loading config \"{}\"", configFile);
if(!config_read_file(&config, configFile.c_str())) {
Log->error("Fail load config. {}. {}:{}",
config_error_text(&config),
configFile,
config_error_line(&config));
return;
}
int port = 0;
if(CONFIG_TRUE == config_lookup_int(&config, "port", &port)) {
if(port > 0 && port < 65535 ) {
loadedConfig.port = port;
} else {
Log->error("Invalid port value");
}
}
}
*config = loadedConfig;
}
int main(int argc, char *argv[])
{
InitLogger();
Config config;
LoadConfig(&config);
const std::string h264PipelineTemplate =
"( videotestsrc pattern={} ! "
"x264enc ! video/x-h264, profile=baseline ! "
"rtph264pay name=pay0 pt=96 config-interval=-1 "
"audiotestsrc ! alawenc ! rtppcmapay name=pay1 pt=8 )";
const std::string vp8PipelineTemplate =
"( videotestsrc pattern={} ! "
"vp8enc ! rtpvp8pay name=pay0 pt=96 "
"audiotestsrc ! opusenc ! rtpopuspay name=pay1 pt=97 )";
const std::deque<std::pair<std::string, std::string>> createMountPoints = {
{BARS, "smpte100"},
{WHITE, "white"},
{BLACK, "black"},
{RED, "red"},
{GREEN, "green"},
{BLUE, "blue"},
};
gst_init(&argc, &argv);
GstRTSPServerPtr staticServer(gst_rtsp_server_new());
GstRTSPServer* server = staticServer.get();
if(!server) {
Log->error("Fail to create rtsp server");
return -1;
}
GstRTSPMountPointsPtr mountPointsPtr(gst_rtsp_mount_points_new());
GstRTSPMountPoints* mountPoints = mountPointsPtr.get();
if(!server) {
Log->error("Fail to create mount points");
return -1;
}
gst_rtsp_server_set_service(server, std::to_string(config.port).c_str());
gst_rtsp_server_set_mount_points(server, mountPoints);
// h264
for(const auto& mountPoint: createMountPoints) {
GstRTSPMediaFactory* factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_transport_mode(
factory, GST_RTSP_TRANSPORT_MODE_PLAY);
gst_rtsp_media_factory_set_launch(factory,
fmt::format(h264PipelineTemplate, mountPoint.second).c_str());
gst_rtsp_media_factory_set_shared(factory, TRUE);
gst_rtsp_mount_points_add_factory(
mountPoints,
("/" + mountPoint.first).c_str(),
factory);
}
// vp8
for(const auto& mountPoint: createMountPoints) {
GstRTSPMediaFactory* factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_transport_mode(
factory, GST_RTSP_TRANSPORT_MODE_PLAY);
gst_rtsp_media_factory_set_launch(factory,
fmt::format(vp8PipelineTemplate, mountPoint.second).c_str());
gst_rtsp_media_factory_set_shared(factory, TRUE);
gst_rtsp_mount_points_add_factory(
mountPoints,
("/" + mountPoint.first + "-vp8").c_str(),
factory);
}
GMainLoopPtr loopPtr(g_main_loop_new(nullptr, FALSE));
GMainLoop* loop = loopPtr.get();
gst_rtsp_server_attach(server, nullptr);
g_main_loop_run(loop);
return 0;
}