Implemented incoming tracks and media direction

This commit is contained in:
Paul-Louis Ageneau
2020-09-08 12:07:38 +02:00
parent cc954cc74c
commit 28e9cd5196
5 changed files with 48 additions and 18 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;