blob: f2541cb8f85f3a64ae1a0f4594a42755de51cbd4 [file] [log] [blame]
deadbeefe814a0d2017-02-25 18:15:09 -08001/*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "ortc/ortcrtpsenderadapter.h"
deadbeefe814a0d2017-02-25 18:15:09 -080012
13#include <utility>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "media/base/mediaconstants.h"
16#include "ortc/rtptransportadapter.h"
17#include "rtc_base/checks.h"
deadbeefe814a0d2017-02-25 18:15:09 -080018
19namespace {
20
21void FillAudioSenderParameters(webrtc::RtpParameters* parameters) {
22 for (webrtc::RtpCodecParameters& codec : parameters->codecs) {
23 if (!codec.num_channels) {
Oskar Sundbomff610bd2017-11-16 10:57:44 +010024 codec.num_channels = 1;
deadbeefe814a0d2017-02-25 18:15:09 -080025 }
26 }
27}
28
29void FillVideoSenderParameters(webrtc::RtpParameters* parameters) {
30 for (webrtc::RtpCodecParameters& codec : parameters->codecs) {
31 if (!codec.clock_rate) {
Oskar Sundbomff610bd2017-11-16 10:57:44 +010032 codec.clock_rate = cricket::kVideoCodecClockrate;
deadbeefe814a0d2017-02-25 18:15:09 -080033 }
34 }
35}
36
37} // namespace
38
39namespace webrtc {
40
41BEGIN_OWNED_PROXY_MAP(OrtcRtpSender)
42PROXY_SIGNALING_THREAD_DESTRUCTOR()
43PROXY_METHOD1(RTCError, SetTrack, MediaStreamTrackInterface*)
44PROXY_CONSTMETHOD0(rtc::scoped_refptr<MediaStreamTrackInterface>, GetTrack)
45PROXY_METHOD1(RTCError, SetTransport, RtpTransportInterface*)
46PROXY_CONSTMETHOD0(RtpTransportInterface*, GetTransport)
47PROXY_METHOD1(RTCError, Send, const RtpParameters&)
48PROXY_CONSTMETHOD0(RtpParameters, GetParameters)
49PROXY_CONSTMETHOD0(cricket::MediaType, GetKind)
50END_PROXY_MAP()
51
52// static
53std::unique_ptr<OrtcRtpSenderInterface> OrtcRtpSenderAdapter::CreateProxy(
54 std::unique_ptr<OrtcRtpSenderAdapter> wrapped_sender) {
55 RTC_DCHECK(wrapped_sender);
56 rtc::Thread* signaling =
57 wrapped_sender->rtp_transport_controller_->signaling_thread();
58 rtc::Thread* worker =
59 wrapped_sender->rtp_transport_controller_->worker_thread();
60 return OrtcRtpSenderProxy::Create(signaling, worker,
61 std::move(wrapped_sender));
62}
63
64OrtcRtpSenderAdapter::~OrtcRtpSenderAdapter() {
65 internal_sender_ = nullptr;
66 SignalDestroyed();
67}
68
69RTCError OrtcRtpSenderAdapter::SetTrack(MediaStreamTrackInterface* track) {
70 if (track && cricket::MediaTypeFromString(track->kind()) != kind_) {
71 LOG_AND_RETURN_ERROR(
72 RTCErrorType::INVALID_PARAMETER,
73 "Track kind (audio/video) doesn't match the kind of this sender.");
74 }
75 if (internal_sender_ && !internal_sender_->SetTrack(track)) {
76 // Since we checked the track type above, this should never happen...
77 RTC_NOTREACHED();
78 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
79 "Failed to set track on RtpSender.");
80 }
81 track_ = track;
82 return RTCError::OK();
83}
84
85rtc::scoped_refptr<MediaStreamTrackInterface> OrtcRtpSenderAdapter::GetTrack()
86 const {
87 return track_;
88}
89
90RTCError OrtcRtpSenderAdapter::SetTransport(RtpTransportInterface* transport) {
91 LOG_AND_RETURN_ERROR(
92 RTCErrorType::UNSUPPORTED_OPERATION,
93 "Changing the transport of an RtpSender is not yet supported.");
94}
95
96RtpTransportInterface* OrtcRtpSenderAdapter::GetTransport() const {
97 return transport_;
98}
99
100RTCError OrtcRtpSenderAdapter::Send(const RtpParameters& parameters) {
101 RtpParameters filled_parameters = parameters;
102 RTCError err;
103 uint32_t ssrc = 0;
104 switch (kind_) {
105 case cricket::MEDIA_TYPE_AUDIO:
106 FillAudioSenderParameters(&filled_parameters);
107 err = rtp_transport_controller_->ValidateAndApplyAudioSenderParameters(
108 filled_parameters, &ssrc);
109 if (!err.ok()) {
110 return err;
111 }
112 break;
113 case cricket::MEDIA_TYPE_VIDEO:
114 FillVideoSenderParameters(&filled_parameters);
115 err = rtp_transport_controller_->ValidateAndApplyVideoSenderParameters(
116 filled_parameters, &ssrc);
117 if (!err.ok()) {
118 return err;
119 }
120 break;
121 case cricket::MEDIA_TYPE_DATA:
122 RTC_NOTREACHED();
123 return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR);
124 }
125 last_applied_parameters_ = filled_parameters;
126
127 // Now that parameters were applied, can call SetSsrc on the internal sender.
128 // This is analogous to a PeerConnection calling SetSsrc after
129 // SetLocalDescription is successful.
130 //
131 // If there were no encodings, this SSRC may be 0, which is valid.
132 if (!internal_sender_) {
133 CreateInternalSender();
134 }
135 internal_sender_->SetSsrc(ssrc);
136
137 return RTCError::OK();
138}
139
140RtpParameters OrtcRtpSenderAdapter::GetParameters() const {
141 return last_applied_parameters_;
142}
143
144cricket::MediaType OrtcRtpSenderAdapter::GetKind() const {
145 return kind_;
146}
147
148OrtcRtpSenderAdapter::OrtcRtpSenderAdapter(
149 cricket::MediaType kind,
150 RtpTransportInterface* transport,
151 RtpTransportControllerAdapter* rtp_transport_controller)
152 : kind_(kind),
153 transport_(transport),
154 rtp_transport_controller_(rtp_transport_controller) {}
155
156void OrtcRtpSenderAdapter::CreateInternalSender() {
157 switch (kind_) {
Steve Anton02ee47c2018-01-10 16:26:06 -0800158 case cricket::MEDIA_TYPE_AUDIO: {
Steve Anton47136dd2018-01-12 10:49:35 -0800159 auto* audio_sender = new AudioRtpSender(
Steve Anton111fdfd2018-06-25 13:03:36 -0700160 rtp_transport_controller_->worker_thread(), /*id=*/"", nullptr);
Steve Anton47136dd2018-01-12 10:49:35 -0800161 auto* voice_channel = rtp_transport_controller_->voice_channel();
162 RTC_DCHECK(voice_channel);
Steve Anton57858b32018-02-15 15:19:50 -0800163 audio_sender->SetVoiceMediaChannel(voice_channel->media_channel());
Steve Anton02ee47c2018-01-10 16:26:06 -0800164 internal_sender_ = audio_sender;
deadbeefe814a0d2017-02-25 18:15:09 -0800165 break;
Steve Anton02ee47c2018-01-10 16:26:06 -0800166 }
167 case cricket::MEDIA_TYPE_VIDEO: {
Steve Anton111fdfd2018-06-25 13:03:36 -0700168 auto* video_sender = new VideoRtpSender(
169 rtp_transport_controller_->worker_thread(), /*id=*/"");
Steve Anton47136dd2018-01-12 10:49:35 -0800170 auto* video_channel = rtp_transport_controller_->video_channel();
171 RTC_DCHECK(video_channel);
Steve Anton57858b32018-02-15 15:19:50 -0800172 video_sender->SetVideoMediaChannel(video_channel->media_channel());
Steve Anton02ee47c2018-01-10 16:26:06 -0800173 internal_sender_ = video_sender;
deadbeefe814a0d2017-02-25 18:15:09 -0800174 break;
Steve Anton02ee47c2018-01-10 16:26:06 -0800175 }
deadbeefe814a0d2017-02-25 18:15:09 -0800176 case cricket::MEDIA_TYPE_DATA:
177 RTC_NOTREACHED();
178 }
179 if (track_) {
180 if (!internal_sender_->SetTrack(track_)) {
181 // Since we checked the track type when it was set, this should never
182 // happen...
183 RTC_NOTREACHED();
184 }
185 }
186}
187
188} // namespace webrtc