|
@@ -268,6 +268,21 @@ int copyAndReturn(binary b, char *buffer, int size) {
|
|
|
return int(b.size());
|
|
|
}
|
|
|
|
|
|
+template<typename T>
|
|
|
+int copyAndReturn(std::vector<T> b, T *buffer, int size) {
|
|
|
+ if (!buffer)
|
|
|
+ return int(b.size());
|
|
|
+
|
|
|
+ if (size < int(b.size()))
|
|
|
+ return RTC_ERR_TOO_SMALL;
|
|
|
+ memcpy(buffer, b.data(), size * sizeof(*buffer));
|
|
|
+ return int(b.size());
|
|
|
+}
|
|
|
+
|
|
|
+string lowercased(string str) {
|
|
|
+ std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::tolower(c); });
|
|
|
+ return str;
|
|
|
+}
|
|
|
} // namespace
|
|
|
|
|
|
void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb) {
|
|
@@ -365,6 +380,12 @@ int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+int rtcIsDataChannelOpen(int dc) {
|
|
|
+ return wrap([dc] {
|
|
|
+ return getDataChannel(dc)->isOpen() ? RTC_ERR_SUCCESS : RTC_ERR_FAILURE;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
int rtcDeleteDataChannel(int dc) {
|
|
|
return wrap([dc] {
|
|
|
auto dataChannel = getDataChannel(dc);
|
|
@@ -380,6 +401,34 @@ int rtcDeleteDataChannel(int dc) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+int rtcIsDataChannelOpen(int dc) {
|
|
|
+ return wrap([dc] {
|
|
|
+ return getDataChannel(dc)->isOpen() ? RTC_ERR_SUCCESS : RTC_ERR_FAILURE;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+#if RTC_ENABLE_MEDIA
|
|
|
+
|
|
|
+void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid, const char *_trackID) {
|
|
|
+
|
|
|
+ optional<string> name = nullopt;
|
|
|
+ if (_name) {
|
|
|
+ name = string(_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ optional<string> msid = nullopt;
|
|
|
+ if (_msid) {
|
|
|
+ msid = string(_msid);
|
|
|
+ }
|
|
|
+
|
|
|
+ optional<string> trackID = nullopt;
|
|
|
+ if (_trackID) {
|
|
|
+ trackID = string(_trackID);
|
|
|
+ }
|
|
|
+
|
|
|
+ description->addSSRC(ssrc, name, msid, trackID);
|
|
|
+}
|
|
|
+
|
|
|
int rtcAddTrack(int pc, const char *mediaDescriptionSdp) {
|
|
|
return wrap([&] {
|
|
|
if (!mediaDescriptionSdp)
|
|
@@ -503,6 +552,26 @@ int rtcGetTrackDescription(int tr, char *buffer, int size) {
|
|
|
|
|
|
#if RTC_ENABLE_MEDIA
|
|
|
|
|
|
+void setSSRC(Description::Media *description, uint32_t ssrc, const char *_name, const char *_msid, const char *_trackID) {
|
|
|
+
|
|
|
+ optional<string> name = nullopt;
|
|
|
+ if (_name) {
|
|
|
+ name = string(_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ optional<string> msid = nullopt;
|
|
|
+ if (_msid) {
|
|
|
+ msid = string(_msid);
|
|
|
+ }
|
|
|
+
|
|
|
+ optional<string> trackID = nullopt;
|
|
|
+ if (_trackID) {
|
|
|
+ trackID = string(_trackID);
|
|
|
+ }
|
|
|
+
|
|
|
+ description->addSSRC(ssrc, name, msid, trackID);
|
|
|
+}
|
|
|
+
|
|
|
int rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init) {
|
|
|
return wrap([&] {
|
|
|
auto track = getTrack(tr);
|
|
@@ -633,6 +702,23 @@ int rtcSetNeedsToSendRtcpSr(int id) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+int rtcGetTrackPayloadTypesForCodec(int tr, const char * ccodec, int * buffer, int size) {
|
|
|
+ return wrap([&] {
|
|
|
+ auto track = getTrack(tr);
|
|
|
+ auto codec = lowercased(string(ccodec));
|
|
|
+ auto description = track->description();
|
|
|
+ std::vector<int> payloadTypes{};
|
|
|
+ payloadTypes.reserve(std::max(size, 0));
|
|
|
+ for (auto it = description.beginMaps(); it != description.endMaps(); it++) {
|
|
|
+ auto element = *it;
|
|
|
+ if (lowercased(element.second.format) == codec) {
|
|
|
+ payloadTypes.push_back(element.first);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return copyAndReturn(payloadTypes, buffer, size);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
#endif // RTC_ENABLE_MEDIA
|
|
|
#if RTC_ENABLE_WEBSOCKET
|
|
|
|
|
@@ -784,6 +870,68 @@ int rtcSetLocalDescription(int pc, const char *type) {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+int rtcGetSsrcsForTrack(int tr, uint32_t * buffer, int bufferSize) {
|
|
|
+ return wrap([&] {
|
|
|
+ auto track = getTrack(tr);
|
|
|
+ auto ssrcs = track->description().getSSRCs();
|
|
|
+ return copyAndReturn(ssrcs, buffer, bufferSize);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+int rtcGetCNameForSsrc(int tr, uint32_t ssrc, char * cname, int cnameSize) {
|
|
|
+ return wrap([&] {
|
|
|
+ auto track = getTrack(tr);
|
|
|
+ auto description = track->description();
|
|
|
+ auto optCName = description.getCNameForSsrc(ssrc);
|
|
|
+ if (optCName.has_value()) {
|
|
|
+ return copyAndReturn(optCName.value(), cname, cnameSize);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+int rtcGetSsrcsForType(const char * mediaType, const char * sdp, uint32_t * buffer, int bufferSize) {
|
|
|
+ return wrap([&] {
|
|
|
+ auto type = lowercased(string(mediaType));
|
|
|
+ auto oldSDP = string(sdp);
|
|
|
+ auto description = Description(oldSDP, "unspec");
|
|
|
+ auto mediaCount = description.mediaCount();
|
|
|
+ for (auto i = 0; i < mediaCount; i++) {
|
|
|
+ if (std::holds_alternative<Description::Media *>(description.media(i))) {
|
|
|
+ auto media = std::get<Description::Media *>(description.media(i));
|
|
|
+ auto currentMediaType = lowercased(media->type());
|
|
|
+ if (currentMediaType == type) {
|
|
|
+ auto ssrcs = media->getSSRCs();
|
|
|
+ return copyAndReturn(ssrcs, buffer, bufferSize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+int rtcSetSsrcForType(const char * mediaType, const char * sdp, char * buffer, const int bufferSize,
|
|
|
+ rtcSsrcForTypeInit * init) {
|
|
|
+ return wrap([&] {
|
|
|
+ auto type = lowercased(string(mediaType));
|
|
|
+ auto prevSDP = string(sdp);
|
|
|
+ auto description = Description(prevSDP, "unspec");
|
|
|
+ auto mediaCount = description.mediaCount();
|
|
|
+ for (auto i = 0; i < mediaCount; i++) {
|
|
|
+ if (std::holds_alternative<Description::Media *>(description.media(i))) {
|
|
|
+ auto media = std::get<Description::Media *>(description.media(i));
|
|
|
+ auto currentMediaType = lowercased(media->type());
|
|
|
+ if (currentMediaType == type) {
|
|
|
+ setSSRC(media, init->ssrc, init->name, init->msid, init->trackId);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return copyAndReturn(string(description), buffer, bufferSize);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
int rtcSetRemoteDescription(int pc, const char *sdp, const char *type) {
|
|
|
return wrap([&] {
|
|
|
auto peerConnection = getPeerConnection(pc);
|