webrtc/ortc/ortcrtpsenderadapter.cc
Steve Anton 02ee47c1ae Signal track ID correctly when Unified Plan semantics selected
This change corrects PeerConnection behavior under Unified
Plan semantics to:
- Set the RtpSender id to be the track ID if created with AddTrack.
- Put the RtpSender id in the SDP as part of the MSID.
- Set the RtpReceiver id to be the track part of the MSID
    when created via SetRemoteDescription.

Also, the RtpSender constructors have been simplified to defer
mutable state (in this case, setting BaseChannels) to method calls.

Bug: webrtc:8721
Change-Id: Idc80965e2df7a803b8bbeec1d96de9ad95391cce
Reviewed-on: https://webrtc-review.googlesource.com/38480
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21563}
2018-01-11 01:11:15 +00:00

182 lines
5.6 KiB
C++

/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "ortc/ortcrtpsenderadapter.h"
#include <utility>
#include "media/base/mediaconstants.h"
#include "ortc/rtptransportadapter.h"
#include "rtc_base/checks.h"
namespace {
void FillAudioSenderParameters(webrtc::RtpParameters* parameters) {
for (webrtc::RtpCodecParameters& codec : parameters->codecs) {
if (!codec.num_channels) {
codec.num_channels = 1;
}
}
}
void FillVideoSenderParameters(webrtc::RtpParameters* parameters) {
for (webrtc::RtpCodecParameters& codec : parameters->codecs) {
if (!codec.clock_rate) {
codec.clock_rate = cricket::kVideoCodecClockrate;
}
}
}
} // namespace
namespace webrtc {
BEGIN_OWNED_PROXY_MAP(OrtcRtpSender)
PROXY_SIGNALING_THREAD_DESTRUCTOR()
PROXY_METHOD1(RTCError, SetTrack, MediaStreamTrackInterface*)
PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, GetTrack)
PROXY_METHOD1(RTCError, SetTransport, RtpTransportInterface*)
PROXY_CONSTMETHOD0(RtpTransportInterface*, GetTransport)
PROXY_METHOD1(RTCError, Send, const RtpParameters&)
PROXY_CONSTMETHOD0(RtpParameters, GetParameters)
PROXY_CONSTMETHOD0(cricket::MediaType, GetKind)
END_PROXY_MAP()
// static
std::unique_ptr<OrtcRtpSenderInterface> OrtcRtpSenderAdapter::CreateProxy(
std::unique_ptr<OrtcRtpSenderAdapter> wrapped_sender) {
RTC_DCHECK(wrapped_sender);
rtc::Thread* signaling =
wrapped_sender->rtp_transport_controller_->signaling_thread();
rtc::Thread* worker =
wrapped_sender->rtp_transport_controller_->worker_thread();
return OrtcRtpSenderProxy::Create(signaling, worker,
std::move(wrapped_sender));
}
OrtcRtpSenderAdapter::~OrtcRtpSenderAdapter() {
internal_sender_ = nullptr;
SignalDestroyed();
}
RTCError OrtcRtpSenderAdapter::SetTrack(MediaStreamTrackInterface* track) {
if (track && cricket::MediaTypeFromString(track->kind()) != kind_) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"Track kind (audio/video) doesn't match the kind of this sender.");
}
if (internal_sender_ && !internal_sender_->SetTrack(track)) {
// Since we checked the track type above, this should never happen...
RTC_NOTREACHED();
LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
"Failed to set track on RtpSender.");
}
track_ = track;
return RTCError::OK();
}
rtc::scoped_refptr<MediaStreamTrackInterface> OrtcRtpSenderAdapter::GetTrack()
const {
return track_;
}
RTCError OrtcRtpSenderAdapter::SetTransport(RtpTransportInterface* transport) {
LOG_AND_RETURN_ERROR(
RTCErrorType::UNSUPPORTED_OPERATION,
"Changing the transport of an RtpSender is not yet supported.");
}
RtpTransportInterface* OrtcRtpSenderAdapter::GetTransport() const {
return transport_;
}
RTCError OrtcRtpSenderAdapter::Send(const RtpParameters& parameters) {
RtpParameters filled_parameters = parameters;
RTCError err;
uint32_t ssrc = 0;
switch (kind_) {
case cricket::MEDIA_TYPE_AUDIO:
FillAudioSenderParameters(&filled_parameters);
err = rtp_transport_controller_->ValidateAndApplyAudioSenderParameters(
filled_parameters, &ssrc);
if (!err.ok()) {
return err;
}
break;
case cricket::MEDIA_TYPE_VIDEO:
FillVideoSenderParameters(&filled_parameters);
err = rtp_transport_controller_->ValidateAndApplyVideoSenderParameters(
filled_parameters, &ssrc);
if (!err.ok()) {
return err;
}
break;
case cricket::MEDIA_TYPE_DATA:
RTC_NOTREACHED();
return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR);
}
last_applied_parameters_ = filled_parameters;
// Now that parameters were applied, can call SetSsrc on the internal sender.
// This is analogous to a PeerConnection calling SetSsrc after
// SetLocalDescription is successful.
//
// If there were no encodings, this SSRC may be 0, which is valid.
if (!internal_sender_) {
CreateInternalSender();
}
internal_sender_->SetSsrc(ssrc);
return RTCError::OK();
}
RtpParameters OrtcRtpSenderAdapter::GetParameters() const {
return last_applied_parameters_;
}
cricket::MediaType OrtcRtpSenderAdapter::GetKind() const {
return kind_;
}
OrtcRtpSenderAdapter::OrtcRtpSenderAdapter(
cricket::MediaType kind,
RtpTransportInterface* transport,
RtpTransportControllerAdapter* rtp_transport_controller)
: kind_(kind),
transport_(transport),
rtp_transport_controller_(rtp_transport_controller) {}
void OrtcRtpSenderAdapter::CreateInternalSender() {
switch (kind_) {
case cricket::MEDIA_TYPE_AUDIO: {
auto* audio_sender = new AudioRtpSender(nullptr);
audio_sender->SetChannel(rtp_transport_controller_->voice_channel());
internal_sender_ = audio_sender;
break;
}
case cricket::MEDIA_TYPE_VIDEO: {
auto* video_sender = new VideoRtpSender();
video_sender->SetChannel(rtp_transport_controller_->video_channel());
internal_sender_ = video_sender;
break;
}
case cricket::MEDIA_TYPE_DATA:
RTC_NOTREACHED();
}
if (track_) {
if (!internal_sender_->SetTrack(track_)) {
// Since we checked the track type when it was set, this should never
// happen...
RTC_NOTREACHED();
}
}
}
} // namespace webrtc