forked from sony/nmos-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdp_utils.h
251 lines (214 loc) · 10.2 KB
/
sdp_utils.h
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#ifndef NMOS_SDP_UTILS_H
#define NMOS_SDP_UTILS_H
#include "cpprest/basic_utils.h"
#include "sdp/json.h"
#include "sdp/ntp.h"
#include "nmos/rational.h"
namespace nmos
{
struct sdp_parameters;
// Sender helper functions
sdp_parameters make_sdp_parameters(const web::json::value& source, const web::json::value& flow, const web::json::value& sender, const std::vector<utility::string_t>& media_stream_ids);
web::json::value make_session_description(const sdp_parameters& sdp_params, const web::json::value& transport_params);
// Receiver helper functions
// Get transport parameters from the parsed SDP file
web::json::value get_session_description_transport_params(const web::json::value& session_description);
// Get other SDP parameters from the parsed SDP file
sdp_parameters get_session_description_sdp_parameters(const web::json::value& session_description);
std::pair<sdp_parameters, web::json::value> parse_session_description(const web::json::value& session_description);
void validate_sdp_parameters(const web::json::value& receiver, const sdp_parameters& sdp_params);
struct sdp_parameters
{
struct origin_t
{
utility::string_t user_name;
uint64_t session_id;
uint64_t session_version;
origin_t() : session_id(), session_version() {}
origin_t(const utility::string_t& user_name, uint64_t session_id, uint64_t session_version)
: user_name(user_name)
, session_id(session_id)
, session_version(session_version)
{}
origin_t(const utility::string_t& user_name, uint64_t session_id_version)
: user_name(user_name)
, session_id(session_id_version)
, session_version(session_id_version)
{}
} origin;
utility::string_t session_name;
struct connection_data_t
{
uint32_t ttl;
connection_data_t() : ttl() {}
connection_data_t(uint32_t ttl) : ttl(ttl) {}
} connection_data;
struct timing_t
{
uint64_t start_time;
uint64_t stop_time;
timing_t() : start_time(), stop_time() {}
timing_t(uint64_t start_time, uint64_t stop_time) : start_time(start_time), stop_time(stop_time) {}
} timing;
struct group_t
{
sdp::group_semantics_type semantics;
// stream identifiers for each leg when redundancy is being used, in the appropriate order
std::vector<utility::string_t> media_stream_ids;
group_t() {}
group_t(const sdp::group_semantics_type& semantics, const std::vector<utility::string_t>& media_stream_ids) : semantics(semantics), media_stream_ids(media_stream_ids) {}
} group;
sdp::media_type media_type;
sdp::protocol protocol;
struct rtpmap_t
{
uint64_t payload_type;
// encoding-name is "raw" for video, "L24" or "L16" for audio, "smpte291" for data
utility::string_t encoding_name;
uint64_t clock_rate;
rtpmap_t() : payload_type(), clock_rate() {}
rtpmap_t(uint64_t payload_type, const utility::string_t& encoding_name, uint64_t clock_rate)
: payload_type(payload_type)
, encoding_name(encoding_name)
, clock_rate(clock_rate)
{}
} rtpmap;
// additional "video/raw" parameters (video only)
struct video_t
{
// fmtp indicates format
uint32_t width;
uint32_t height;
nmos::rational exactframerate;
bool interlace;
sdp::sampling sampling;
uint32_t depth;
sdp::transfer_characteristic_system tcs; // nmos::transfer_characteristic is a subset
sdp::colorimetry colorimetry; // nmos::colorspace is a subset
sdp::type_parameter tp;
video_t() : width(), height(), depth() {}
video_t(uint32_t width, uint32_t height, const nmos::rational& exactframerate, bool interlace, const sdp::sampling& sampling, uint32_t depth, const sdp::transfer_characteristic_system& tcs, const sdp::colorimetry& colorimetry, const sdp::type_parameter& tp)
: width(width)
, height(height)
, exactframerate(exactframerate)
, interlace(interlace)
, sampling(sampling)
, depth(depth)
, tcs(tcs)
, colorimetry(colorimetry)
, tp(tp)
{}
} video;
// additional "audio/L" parameters (audio only)
struct audio_t
{
// rtpmap encoding-parameters indicates channel_count
uint32_t channel_count;
// rtpmap encoding-name (e.g. "L24") indicates bit_depth
uint32_t bit_depth;
// rtpmap clock-rate indicates sample_rate
nmos::rational sample_rate;
// fmtp indicates channel-order (e.g. "SMPTE2110.(ST)")
utility::string_t channel_order;
// ptime
double packet_time;
audio_t() : channel_count(), bit_depth(), packet_time() {}
audio_t(uint32_t channel_count, uint32_t bit_depth, const nmos::rational& sample_rate, const utility::string_t& channel_order, double packet_time)
: channel_count(channel_count)
, bit_depth(bit_depth)
, sample_rate(sample_rate)
, channel_order(channel_order)
, packet_time(packet_time)
{}
} audio;
// additional "video/smpte291" data parameters (data only)
struct data_t
{
} data;
struct ts_refclk_t
{
sdp::ts_refclk_source clock_source;
// for sdp::ts_refclk_sources::ptp
sdp::ptp_version ptp_version;
utility::string_t ptp_server;
// for sdp::ts_refclk_sources::local_mac
utility::string_t mac_address;
static ts_refclk_t ptp(const sdp::ptp_version& ptp_version, const utility::string_t& ptp_server)
{
return{ sdp::ts_refclk_sources::ptp, ptp_version, ptp_server, {} };
}
static ts_refclk_t local_mac(const utility::string_t& mac_address)
{
return{ sdp::ts_refclk_sources::local_mac, {}, {}, mac_address };
}
ts_refclk_t() {}
ts_refclk_t(const sdp::ts_refclk_source& clock_source, const sdp::ptp_version& ptp_version, const utility::string_t& ptp_server, const utility::string_t& mac_address)
: clock_source(clock_source)
, ptp_version(ptp_version)
, ptp_server(ptp_server)
, mac_address(mac_address)
{}
} ts_refclk;
struct mediaclk_t
{
sdp::mediaclk_source clock_source;
utility::string_t clock_parameters;
mediaclk_t() {}
mediaclk_t(const sdp::mediaclk_source& clock_source, const utility::string_t& clock_parameters)
: clock_source(clock_source)
, clock_parameters(clock_parameters)
{}
} mediaclk;
// construct null SDP parameters
sdp_parameters() {}
// construct "video/raw" SDP parameters with sensible defaults for unspecified fields
sdp_parameters(const utility::string_t& session_name, const video_t& video, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {})
: origin(U("-"), sdp::ntp_now() >> 32)
, session_name(session_name)
, connection_data(32)
, timing()
, group(!media_stream_ids.empty() ? group_t{ sdp::group_semantics::duplication, media_stream_ids } : group_t{})
, media_type(sdp::media_types::video)
, protocol(sdp::protocols::RTP_AVP)
, rtpmap(payload_type, U("raw"), 90000)
, video(video)
, audio()
, data()
, ts_refclk(ts_refclk_t::ptp(sdp::ptp_versions::IEEE1588_2008, U("traceable")))
, mediaclk(sdp::mediaclk_sources::direct, U("0"))
{}
// construct "audio/L" SDP parameters with sensible defaults for unspecified fields
sdp_parameters(const utility::string_t& session_name, const audio_t& audio, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {})
: origin(U("-"), sdp::ntp_now() >> 32)
, session_name(session_name)
, connection_data(32)
, timing()
, group(!media_stream_ids.empty() ? group_t{ sdp::group_semantics::duplication, media_stream_ids } : group_t{})
, media_type(sdp::media_types::audio)
, protocol(sdp::protocols::RTP_AVP)
, rtpmap(payload_type, U("L") + utility::ostringstreamed(audio.bit_depth), uint64_t(double(audio.sample_rate.numerator()) / double(audio.sample_rate.denominator()) + 0.5))
, video()
, audio(audio)
, data()
, ts_refclk(ts_refclk_t::ptp(sdp::ptp_versions::IEEE1588_2008, U("traceable")))
, mediaclk(sdp::mediaclk_sources::direct, U("0"))
{}
// construct "video/smpte291" SDP parameters with sensible defaults for unspecified fields
sdp_parameters(const utility::string_t& session_name, const data_t& data, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {})
: origin(U("-"), sdp::ntp_now() >> 32)
, session_name(session_name)
, connection_data(32)
, timing()
, group(!media_stream_ids.empty() ? group_t{ sdp::group_semantics::duplication, media_stream_ids } : group_t{})
, media_type(sdp::media_types::video)
, protocol(sdp::protocols::RTP_AVP)
, rtpmap(payload_type, U("smpte291"), 90000)
, video()
, audio()
, data(data)
, ts_refclk(ts_refclk_t::ptp(sdp::ptp_versions::IEEE1588_2008, U("traceable")))
, mediaclk(sdp::mediaclk_sources::direct, U("0"))
{}
};
}
#endif