Browse Source

Implemented incoming tracks and media direction

Paul-Louis Ageneau 4 years ago
parent
commit
28e9cd5196
5 changed files with 48 additions and 18 deletions
  1. 5 4
      include/rtc/description.hpp
  2. 1 0
      include/rtc/peerconnection.hpp
  3. 6 6
      src/description.cpp
  4. 24 8
      src/peerconnection.cpp
  5. 12 0
      src/track.cpp

+ 5 - 4
include/rtc/description.hpp

@@ -63,25 +63,27 @@ public:
 
 
 	class Entry {
 	class Entry {
 	public:
 	public:
-		Entry(string mline, string mid = "", Direction dir = Direction::Unknown);
 		virtual ~Entry() = default;
 		virtual ~Entry() = default;
 
 
 		virtual string type() const { return mType; }
 		virtual string type() const { return mType; }
 		virtual string description() const { return mDescription; }
 		virtual string description() const { return mDescription; }
 		virtual string mid() const { return mMid; }
 		virtual string mid() const { return mMid; }
-		Direction direction() const;
+		Direction direction() const { return mDirection; }
+		void setDirection(Direction dir);
 
 
 		virtual void parseSdpLine(string_view line);
 		virtual void parseSdpLine(string_view line);
 		virtual string generateSdp(string_view eol) const;
 		virtual string generateSdp(string_view eol) const;
 
 
 	protected:
 	protected:
+		Entry(string mline, string mid = "", Direction dir = Direction::Unknown);
+
 		std::vector<string> mAttributes;
 		std::vector<string> mAttributes;
-		Direction mDirection;
 
 
 	private:
 	private:
 		string mType;
 		string mType;
 		string mDescription;
 		string mDescription;
 		string mMid;
 		string mMid;
+		Direction mDirection;
 	};
 	};
 
 
 	struct Application : public Entry {
 	struct Application : public Entry {
@@ -119,7 +121,6 @@ public:
 		string description() const override;
 		string description() const override;
 		Media reciprocate() const;
 		Media reciprocate() const;
 
 
-		void setDirection(Direction dir);
 		void removeFormat(const string &fmt);
 		void removeFormat(const string &fmt);
 
 
 		void addVideoCodec(int payloadType, const string &codec);
 		void addVideoCodec(int payloadType, const string &codec);

+ 1 - 0
include/rtc/peerconnection.hpp

@@ -129,6 +129,7 @@ private:
 	void closeDataChannels();
 	void closeDataChannels();
 	void remoteCloseDataChannels();
 	void remoteCloseDataChannels();
 
 
+	void incomingTrack(Description::Media description);
 	void openTracks();
 	void openTracks();
 
 
 	void processLocalDescription(Description description);
 	void processLocalDescription(Description description);

+ 6 - 6
src/description.cpp

@@ -366,7 +366,7 @@ Description::media(int index) const {
 int Description::mediaCount() const { return int(mEntries.size()); }
 int Description::mediaCount() const { return int(mEntries.size()); }
 
 
 Description::Entry::Entry(string mline, string mid, Direction dir)
 Description::Entry::Entry(string mline, string mid, Direction dir)
-    : mDirection(dir), mMid(std::move(mid)) {
+    : mMid(std::move(mid)), mDirection(dir) {
 	size_t p = mline.find(' ');
 	size_t p = mline.find(' ');
 	mType = mline.substr(0, p);
 	mType = mline.substr(0, p);
 	if (p != string::npos)
 	if (p != string::npos)
@@ -374,6 +374,8 @@ Description::Entry::Entry(string mline, string mid, Direction dir)
 			mDescription = mline.substr(q + 1, mline.find(' ', q + 1) - (q + 1));
 			mDescription = mline.substr(q + 1, mline.find(' ', q + 1) - (q + 1));
 }
 }
 
 
+void Description::Entry::setDirection(Direction dir) { mDirection = dir; }
+
 string Description::Entry::generateSdp(string_view eol) const {
 string Description::Entry::generateSdp(string_view eol) const {
 	std::ostringstream sdp;
 	std::ostringstream sdp;
 	// Port 9 is the discard protocol
 	// Port 9 is the discard protocol
@@ -490,12 +492,12 @@ Description::Media Description::Media::reciprocate() const {
 	Media reciprocated(*this);
 	Media reciprocated(*this);
 
 
 	// Invert direction
 	// Invert direction
-	switch (reciprocated.mDirection) {
+	switch (direction()) {
 	case Direction::RecvOnly:
 	case Direction::RecvOnly:
-		reciprocated.mDirection = Direction::SendOnly;
+		reciprocated.setDirection(Direction::SendOnly);
 		break;
 		break;
 	case Direction::SendOnly:
 	case Direction::SendOnly:
-		reciprocated.mDirection = Direction::RecvOnly;
+		reciprocated.setDirection(Direction::RecvOnly);
 		break;
 		break;
 	default:
 	default:
 		// We are good
 		// We are good
@@ -521,8 +523,6 @@ Description::Media::RTPMap &Description::Media::getFormat(const string &fmt) {
 	throw std::invalid_argument("format was not found");
 	throw std::invalid_argument("format was not found");
 }
 }
 
 
-void Description::Media::setDirection(Direction dir) { mDirection = dir; }
-
 void Description::Media::removeFormat(const string &fmt) {
 void Description::Media::removeFormat(const string &fmt) {
 	auto it = mRtpMap.begin();
 	auto it = mRtpMap.begin();
 	std::vector<int> remed;
 	std::vector<int> remed;

+ 24 - 8
src/peerconnection.cpp

@@ -240,6 +240,10 @@ std::shared_ptr<Track> PeerConnection::createTrack(Description::Media descriptio
 	if (localDescription())
 	if (localDescription())
 		throw std::logic_error("Tracks must be created before local description");
 		throw std::logic_error("Tracks must be created before local description");
 
 
+	if (auto it = mTracks.find(description.mid()); it != mTracks.end())
+		if (auto track = it->second.lock())
+			return track;
+
 	auto track = std::make_shared<Track>(std::move(description));
 	auto track = std::make_shared<Track>(std::move(description));
 	mTracks.emplace(std::make_pair(track->mid(), track));
 	mTracks.emplace(std::make_pair(track->mid(), track));
 	return track;
 	return track;
@@ -638,6 +642,22 @@ void PeerConnection::openDataChannels() {
 		iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->open(transport); });
 		iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->open(transport); });
 }
 }
 
 
+void PeerConnection::closeDataChannels() {
+	iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->close(); });
+}
+
+void PeerConnection::remoteCloseDataChannels() {
+	iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->remoteClose(); });
+}
+
+void PeerConnection::incomingTrack(Description::Media description) {
+	std::unique_lock lock(mTracksMutex); // we are going to emplace
+	if (mTracks.find(description.mid()) == mTracks.end()) {
+		auto track = std::make_shared<Track>(std::move(description));
+		mTracks.emplace(std::make_pair(track->mid(), track));
+	}
+}
+
 void PeerConnection::openTracks() {
 void PeerConnection::openTracks() {
 #if RTC_ENABLE_MEDIA
 #if RTC_ENABLE_MEDIA
 	if (!hasMedia())
 	if (!hasMedia())
@@ -653,13 +673,6 @@ void PeerConnection::openTracks() {
 #endif
 #endif
 }
 }
 
 
-void PeerConnection::closeDataChannels() {
-	iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->close(); });
-}
-
-void PeerConnection::remoteCloseDataChannels() {
-	iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->remoteClose(); });
-}
 
 
 void PeerConnection::processLocalDescription(Description description) {
 void PeerConnection::processLocalDescription(Description description) {
 	if (auto remote = remoteDescription()) {
 	if (auto remote = remoteDescription()) {
@@ -680,7 +693,10 @@ void PeerConnection::processLocalDescription(Description description) {
 				                   << media->mid() << "\"";
 				                   << media->mid() << "\"";
 
 
 				        auto reciprocated = media->reciprocate();
 				        auto reciprocated = media->reciprocate();
-#if !RTC_ENABLE_MEDIA
+#if RTC_ENABLE_MEDIA
+				        if (reciprocated.direction() != Description::Direction::Inactive)
+					        incomingTrack(reciprocated);
+#else
 				        // No media support, mark as inactive
 				        // No media support, mark as inactive
 				        reciprocated.setDirection(Description::Direction::Inactive);
 				        reciprocated.setDirection(Description::Direction::Inactive);
 #endif
 #endif

+ 12 - 0
src/track.cpp

@@ -74,6 +74,11 @@ void Track::open(shared_ptr<DtlsSrtpTransport> transport) { mDtlsSrtpTransport =
 #endif
 #endif
 
 
 bool Track::outgoing(message_ptr message) {
 bool Track::outgoing(message_ptr message) {
+	auto direction = mMediaDescription.direction();
+	if (direction == Description::Direction::RecvOnly ||
+	    direction == Description::Direction::Inactive)
+		throw std::runtime_error("Track media direction does not allow sending");
+
 	if (mIsClosed)
 	if (mIsClosed)
 		throw std::runtime_error("Track is closed");
 		throw std::runtime_error("Track is closed");
 
 
@@ -104,6 +109,13 @@ void Track::incoming(message_ptr message) {
 		message = *opt;
 		message = *opt;
 	}
 	}
 
 
+	auto direction = mMediaDescription.direction();
+	if ((direction == Description::Direction::SendOnly ||
+	     direction == Description::Direction::Inactive) &&
+	    message->type != Message::Control) {
+		PLOG_WARNING << "Track media direction does not allow reception, dropping";
+	}
+
 	// Tail drop if queue is full
 	// Tail drop if queue is full
 	if (mRecvQueue.full())
 	if (mRecvQueue.full())
 		return;
 		return;