blob: 33046925fe97d43be190c97a28525ae105ce2f3c [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 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
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000011#include "video_engine/vie_rtp_rtcp_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include "engine_configurations.h"
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000014#include "system_wrappers/interface/file_wrapper.h"
15#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000016#include "video_engine/include/vie_errors.h"
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000017#include "video_engine/vie_channel.h"
18#include "video_engine/vie_channel_manager.h"
19#include "video_engine/vie_defines.h"
20#include "video_engine/vie_encoder.h"
21#include "video_engine/vie_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000022
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000023namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000024
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000025// Helper methods for converting between module format and ViE API format.
niklase@google.com470e71d2011-07-07 08:21:25 +000026
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000027static RTCPMethod ViERTCPModeToRTCPMethod(ViERTCPMode api_mode) {
28 switch (api_mode) {
29 case kRtcpNone:
30 return kRtcpOff;
niklase@google.com470e71d2011-07-07 08:21:25 +000031
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000032 case kRtcpCompound_RFC4585:
33 return kRtcpCompound;
34
35 case kRtcpNonCompound_RFC5506:
36 return kRtcpNonCompound;
37
38 default:
39 assert(false);
40 return kRtcpOff;
41 }
42}
43
44static ViERTCPMode RTCPMethodToViERTCPMode(RTCPMethod module_method) {
45 switch (module_method) {
46 case kRtcpOff:
47 return kRtcpNone;
48
49 case kRtcpCompound:
50 return kRtcpCompound_RFC4585;
51
52 case kRtcpNonCompound:
53 return kRtcpNonCompound_RFC5506;
54
55 default:
56 assert(false);
57 return kRtcpNone;
58 }
59}
60
61static KeyFrameRequestMethod APIRequestToModuleRequest(
62 ViEKeyFrameRequestMethod api_method) {
63 switch (api_method) {
64 case kViEKeyFrameRequestNone:
65 return kKeyFrameReqFirRtp;
66
67 case kViEKeyFrameRequestPliRtcp:
68 return kKeyFrameReqPliRtcp;
69
70 case kViEKeyFrameRequestFirRtp:
71 return kKeyFrameReqFirRtp;
72
73 case kViEKeyFrameRequestFirRtcp:
74 return kKeyFrameReqFirRtcp;
75
76 default:
77 assert(false);
78 return kKeyFrameReqFirRtp;
79 }
80}
81
82ViERTP_RTCP* ViERTP_RTCP::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000083#ifdef WEBRTC_VIDEO_ENGINE_RTP_RTCP_API
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000084 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000085 return NULL;
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000086 }
87 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
88 ViERTP_RTCPImpl* vie_rtpimpl = vie_impl;
89 // Increase ref count.
90 (*vie_rtpimpl)++;
91 return vie_rtpimpl;
92#else
93 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000094#endif
95}
96
mflodman@webrtc.org8da24172011-12-19 14:18:41 +000097int ViERTP_RTCPImpl::Release() {
98 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, instance_id_,
99 "ViERTP_RTCP::Release()");
100 // Decrease ref count.
101 (*this)--;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000103 WebRtc_Word32 ref_count = GetCount();
104 if (ref_count < 0) {
105 WEBRTC_TRACE(kTraceWarning, kTraceVideo, instance_id_,
106 "ViERTP_RTCP release too many times");
107 SetLastError(kViEAPIDoesNotExist);
108 return -1;
109 }
110 WEBRTC_TRACE(kTraceInfo, kTraceVideo, instance_id_,
111 "ViERTP_RTCP reference count: %d", ref_count);
112 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +0000113}
114
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000115ViERTP_RTCPImpl::ViERTP_RTCPImpl() {
116 WEBRTC_TRACE(kTraceMemory, kTraceVideo, instance_id_,
117 "ViERTP_RTCPImpl::ViERTP_RTCPImpl() Ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +0000118}
119
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000120ViERTP_RTCPImpl::~ViERTP_RTCPImpl() {
121 WEBRTC_TRACE(kTraceMemory, kTraceVideo, instance_id_,
122 "ViERTP_RTCPImpl::~ViERTP_RTCPImpl() Dtor");
niklase@google.com470e71d2011-07-07 08:21:25 +0000123}
124
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000125int ViERTP_RTCPImpl::SetLocalSSRC(const int video_channel,
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +0000126 const unsigned int SSRC,
127 const StreamType usage,
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000128 const unsigned char simulcast_idx) {
129 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
130 "%s(channel: %d, SSRC: %d)", __FUNCTION__, video_channel, SSRC);
mflodman@webrtc.org471e83e2011-11-24 15:16:00 +0000131 ViEChannelManagerScoped cs(channel_manager_);
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000132 ViEChannel* vie_channel = cs.Channel(video_channel);
133 if (!vie_channel) {
stefan@webrtc.orgd0bdab02011-10-14 14:24:54 +0000134 // The channel doesn't exists
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000135 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
136 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
137 SetLastError(kViERtpRtcpInvalidChannelId);
138 return -1;
139 }
140 if (vie_channel->SetSSRC(SSRC, usage, simulcast_idx) != 0) {
141 SetLastError(kViERtpRtcpUnknownError);
142 return -1;
143 }
144 return 0;
145}
146
pwestin@webrtc.org8281e7d2012-01-10 14:09:18 +0000147int ViERTP_RTCPImpl::SetRemoteSSRCType(const int videoChannel,
148 const StreamType usage,
149 const unsigned int SSRC) const {
150 WEBRTC_TRACE(webrtc::kTraceApiCall, webrtc::kTraceVideo,
151 ViEId(instance_id_, videoChannel),
152 "%s(channel: %d, usage:%d SSRC: 0x%x)",
153 __FUNCTION__, usage, videoChannel, SSRC);
154
155 // Get the channel
156 ViEChannelManagerScoped cs(channel_manager_);
157 ViEChannel* ptrViEChannel = cs.Channel(videoChannel);
158 if (ptrViEChannel == NULL) {
159 // The channel doesn't exists
160 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
161 ViEId(instance_id_, videoChannel),
162 "%s: Channel %d doesn't exist",
163 __FUNCTION__, videoChannel);
164 SetLastError(kViERtpRtcpInvalidChannelId);
165 return -1;
166 }
167 if (ptrViEChannel->SetRemoteSSRCType(usage, SSRC) != 0) {
168 SetLastError(kViERtpRtcpUnknownError);
169 return -1;
170 }
171 return 0;
172}
173
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000174int ViERTP_RTCPImpl::GetLocalSSRC(const int video_channel,
175 unsigned int& SSRC) const {
176 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
177 "%s(channel: %d, SSRC: %d)", __FUNCTION__, video_channel, SSRC);
178 ViEChannelManagerScoped cs(channel_manager_);
179 ViEChannel* vie_channel = cs.Channel(video_channel);
180 if (!vie_channel) {
181 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
182 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
183 SetLastError(kViERtpRtcpInvalidChannelId);
184 return -1;
185 }
186 if (vie_channel->GetLocalSSRC((WebRtc_UWord32&) SSRC) != 0) {
187 SetLastError(kViERtpRtcpUnknownError);
188 return -1;
189 }
190 return 0;
191}
192
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000193int ViERTP_RTCPImpl::GetRemoteSSRC(const int video_channel,
194 unsigned int& SSRC) const {
195 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
196 "%s(channel: %d)", __FUNCTION__, video_channel, SSRC);
197 ViEChannelManagerScoped cs(channel_manager_);
198 ViEChannel* vie_channel = cs.Channel(video_channel);
199 if (!vie_channel) {
200 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
201 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
202 SetLastError(kViERtpRtcpInvalidChannelId);
203 return -1;
204 }
205 if (vie_channel->GetRemoteSSRC(SSRC) != 0) {
206 SetLastError(kViERtpRtcpUnknownError);
207 return -1;
208 }
209 return 0;
210}
211
212int ViERTP_RTCPImpl::GetRemoteCSRCs(const int video_channel,
213 unsigned int CSRCs[kRtpCsrcSize]) const {
214 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
215 "%s(channel: %d)", __FUNCTION__, video_channel);
216 ViEChannelManagerScoped cs(channel_manager_);
217 ViEChannel* vie_channel = cs.Channel(video_channel);
218 if (!vie_channel) {
219 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
220 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
221 SetLastError(kViERtpRtcpInvalidChannelId);
222 return -1;
223 }
224 if (vie_channel->GetRemoteCSRC(CSRCs) != 0) {
225 SetLastError(kViERtpRtcpUnknownError);
226 return -1;
227 }
228 return 0;
229}
230
231int ViERTP_RTCPImpl::SetStartSequenceNumber(const int video_channel,
232 unsigned short sequence_number) {
233 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
234 "%s(channel: %d, sequence_number: %u)", __FUNCTION__,
235 video_channel, sequence_number);
236 ViEChannelManagerScoped cs(channel_manager_);
237 ViEChannel* vie_channel = cs.Channel(video_channel);
238 if (!vie_channel) {
239 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
240 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
241 SetLastError(kViERtpRtcpInvalidChannelId);
242 return -1;
243 }
244 if (vie_channel->Sending()) {
245 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
246 "%s: Channel %d already sending.", __FUNCTION__,
247 video_channel);
248 SetLastError(kViERtpRtcpAlreadySending);
249 return -1;
250 }
251 if (vie_channel->SetStartSequenceNumber(sequence_number) != 0) {
252 SetLastError(kViERtpRtcpUnknownError);
253 return -1;
254 }
255 return 0;
256}
257
258int ViERTP_RTCPImpl::SetRTCPStatus(const int video_channel,
259 const ViERTCPMode rtcp_mode) {
260 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
261 "%s(channel: %d, mode: %d)", __FUNCTION__, video_channel,
262 rtcp_mode);
263 ViEChannelManagerScoped cs(channel_manager_);
264 ViEChannel* vie_channel = cs.Channel(video_channel);
265 if (!vie_channel) {
266 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
267 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
stefan@webrtc.orgd0bdab02011-10-14 14:24:54 +0000268 SetLastError(kViERtpRtcpInvalidChannelId);
269 return -1;
270 }
271
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000272 RTCPMethod module_mode = ViERTCPModeToRTCPMethod(rtcp_mode);
273 if (vie_channel->SetRTCPMode(module_mode) != 0) {
274 SetLastError(kViERtpRtcpUnknownError);
275 return -1;
276 }
277 return 0;
278}
279
280int ViERTP_RTCPImpl::GetRTCPStatus(const int video_channel,
281 ViERTCPMode& rtcp_mode) const {
282 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
283 "%s(channel: %d)", __FUNCTION__, video_channel, rtcp_mode);
284 ViEChannelManagerScoped cs(channel_manager_);
285 ViEChannel* vie_channel = cs.Channel(video_channel);
286 if (!vie_channel) {
287 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
288 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
289 SetLastError(kViERtpRtcpInvalidChannelId);
290 return -1;
291 }
292 RTCPMethod module_mode = kRtcpOff;
293 if (vie_channel->GetRTCPMode(module_mode) != 0) {
294 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
295 "%s: could not get current RTCP mode", __FUNCTION__);
296 SetLastError(kViERtpRtcpUnknownError);
297 return -1;
298 }
299 rtcp_mode = RTCPMethodToViERTCPMode(module_mode);
300 return 0;
301}
302
303int ViERTP_RTCPImpl::SetRTCPCName(const int video_channel,
304 const char rtcp_cname[KMaxRTCPCNameLength]) {
305 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
306 "%s(channel: %d, name: %s)", __FUNCTION__, video_channel,
307 rtcp_cname);
308 ViEChannelManagerScoped cs(channel_manager_);
309 ViEChannel* vie_channel = cs.Channel(video_channel);
310 if (!vie_channel) {
311 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
312 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
313 SetLastError(kViERtpRtcpInvalidChannelId);
314 return -1;
315 }
316 if (vie_channel->Sending()) {
317 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
318 "%s: Channel %d already sending.", __FUNCTION__,
319 video_channel);
320 SetLastError(kViERtpRtcpAlreadySending);
321 return -1;
322 }
323 if (vie_channel->SetRTCPCName(rtcp_cname) != 0) {
324 SetLastError(kViERtpRtcpUnknownError);
325 return -1;
326 }
327 return 0;
328}
329
330int ViERTP_RTCPImpl::GetRTCPCName(const int video_channel,
331 char rtcp_cname[KMaxRTCPCNameLength]) const {
332 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
333 "%s(channel: %d)", __FUNCTION__, video_channel);
334 ViEChannelManagerScoped cs(channel_manager_);
335 ViEChannel* vie_channel = cs.Channel(video_channel);
336 if (!vie_channel) {
337 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
338 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
339 SetLastError(kViERtpRtcpInvalidChannelId);
340 return -1;
341 }
342 if (vie_channel->GetRTCPCName(rtcp_cname) != 0) {
343 SetLastError(kViERtpRtcpUnknownError);
344 return -1;
345 }
346 return 0;
347}
348
349int ViERTP_RTCPImpl::GetRemoteRTCPCName(
350 const int video_channel,
351 char rtcp_cname[KMaxRTCPCNameLength]) const {
352 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
353 "%s(channel: %d)", __FUNCTION__, video_channel);
354 ViEChannelManagerScoped cs(channel_manager_);
355 ViEChannel* vie_channel = cs.Channel(video_channel);
356 if (!vie_channel) {
357 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
358 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
359 SetLastError(kViERtpRtcpInvalidChannelId);
360 return -1;
361 }
362 if (vie_channel->GetRemoteRTCPCName(rtcp_cname) != 0) {
363 SetLastError(kViERtpRtcpUnknownError);
364 return -1;
365 }
366 return 0;
367}
368
369int ViERTP_RTCPImpl::SendApplicationDefinedRTCPPacket(
370 const int video_channel,
371 const unsigned char sub_type,
372 unsigned int name,
373 const char* data,
374 unsigned short data_length_in_bytes) {
375 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
376 "%s(channel: %d, sub_type: %c, name: %d, data: x, length: %u)",
377 __FUNCTION__, video_channel, sub_type, name,
378 data_length_in_bytes);
379 ViEChannelManagerScoped cs(channel_manager_);
380 ViEChannel* vie_channel = cs.Channel(video_channel);
381 if (!vie_channel) {
382 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
383 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
384 SetLastError(kViERtpRtcpInvalidChannelId);
385 return -1;
386 }
387 if (!vie_channel->Sending()) {
388 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
389 "%s: Channel %d not sending", __FUNCTION__, video_channel);
390 SetLastError(kViERtpRtcpNotSending);
391 return -1;
392 }
393 RTCPMethod method;
394 if (vie_channel->GetRTCPMode(method) != 0 || method == kRtcpOff) {
395 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
396 "%s: RTCP disabled on channel %d.", __FUNCTION__,
397 video_channel);
398 SetLastError(kViERtpRtcpRtcpDisabled);
399 return -1;
400 }
401 if (vie_channel->SendApplicationDefinedRTCPPacket(
402 sub_type, name, reinterpret_cast<const WebRtc_UWord8*>(data),
403 data_length_in_bytes) != 0) {
404 SetLastError(kViERtpRtcpUnknownError);
405 return -1;
406 }
407 return 0;
408}
409
410int ViERTP_RTCPImpl::SetNACKStatus(const int video_channel, const bool enable) {
411 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
412 "%s(channel: %d, enable: %d)", __FUNCTION__, video_channel,
413 enable);
414 ViEChannelManagerScoped cs(channel_manager_);
415 ViEChannel* vie_channel = cs.Channel(video_channel);
416 if (!vie_channel) {
417 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
418 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
419 SetLastError(kViERtpRtcpInvalidChannelId);
420 return -1;
421 }
422 if (vie_channel->SetNACKStatus(enable) != 0) {
423 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
424 "%s: failed for channel %d", __FUNCTION__, video_channel);
425 SetLastError(kViERtpRtcpUnknownError);
426 return -1;
427 }
428
429 // Update the encoder
430 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
431 if (!vie_encoder) {
432 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
433 "%s: Could not get encoder for channel %d", __FUNCTION__,
434 video_channel);
435 SetLastError(kViERtpRtcpUnknownError);
436 return -1;
437 }
438 vie_encoder->UpdateProtectionMethod();
439 return 0;
440}
441
442int ViERTP_RTCPImpl::SetFECStatus(const int video_channel, const bool enable,
443 const unsigned char payload_typeRED,
444 const unsigned char payload_typeFEC) {
445 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
446 "%s(channel: %d, enable: %d, payload_typeRED: %u, "
447 "payloadTypeFEC: %u)",
448 __FUNCTION__, video_channel, enable, payload_typeRED,
449 payload_typeFEC);
450 ViEChannelManagerScoped cs(channel_manager_);
451 ViEChannel* vie_channel = cs.Channel(video_channel);
452 if (!vie_channel) {
453 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
454 "%s: Channel %d doesn't exist", __FUNCTION__,
455 video_channel);
456 SetLastError(kViERtpRtcpInvalidChannelId);
457 return -1;
458 }
459 if (vie_channel->SetFECStatus(enable, payload_typeRED,
460 payload_typeFEC) != 0) {
461 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
462 "%s: failed for channel %d", __FUNCTION__, video_channel);
463 SetLastError(kViERtpRtcpUnknownError);
464 return -1;
465 }
466 // Update the encoder.
467 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
468 if (!vie_encoder) {
469 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
470 "%s: Could not get encoder for channel %d", __FUNCTION__,
471 video_channel);
472 SetLastError(kViERtpRtcpUnknownError);
473 return -1;
474 }
475 vie_encoder->UpdateProtectionMethod();
476 return 0;
477}
478
479int ViERTP_RTCPImpl::SetHybridNACKFECStatus(
480 const int video_channel,
481 const bool enable,
482 const unsigned char payload_typeRED,
483 const unsigned char payload_typeFEC) {
484 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
485 "%s(channel: %d, enable: %d, payload_typeRED: %u, "
486 "payloadTypeFEC: %u)",
487 __FUNCTION__, video_channel, enable, payload_typeRED,
488 payload_typeFEC);
489 ViEChannelManagerScoped cs(channel_manager_);
490 ViEChannel* vie_channel = cs.Channel(video_channel);
491 if (!vie_channel) {
492 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
493 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
494 SetLastError(kViERtpRtcpInvalidChannelId);
495 return -1;
496 }
497
498 // Update the channel status with hybrid NACK FEC mode.
499 if (vie_channel->SetHybridNACKFECStatus(enable, payload_typeRED,
500 payload_typeFEC) != 0) {
501 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
502 "%s: failed for channel %d", __FUNCTION__, video_channel);
503 SetLastError(kViERtpRtcpUnknownError);
504 return -1;
505 }
506
507 // Update the encoder.
508 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
509 if (!vie_encoder) {
510 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
511 "%s: Could not get encoder for channel %d", __FUNCTION__,
512 video_channel);
513 SetLastError(kViERtpRtcpUnknownError);
514 return -1;
515 }
516 vie_encoder->UpdateProtectionMethod();
517 return 0;
518}
519
520int ViERTP_RTCPImpl::SetKeyFrameRequestMethod(
521 const int video_channel,
522 const ViEKeyFrameRequestMethod method) {
523 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
524 "%s(channel: %d, method: %d)", __FUNCTION__, video_channel,
525 method);
526
527 // Get the channel.
528 ViEChannelManagerScoped cs(channel_manager_);
529 ViEChannel* vie_channel = cs.Channel(video_channel);
530 if (!vie_channel) {
531 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
532 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
533 SetLastError(kViERtpRtcpInvalidChannelId);
534 return -1;
535 }
536 KeyFrameRequestMethod module_method = APIRequestToModuleRequest(method);
537 if (vie_channel->SetKeyFrameRequestMethod(module_method) != 0) {
538 SetLastError(kViERtpRtcpUnknownError);
539 return -1;
540 }
541 return 0;
542}
543
544int ViERTP_RTCPImpl::SetTMMBRStatus(const int video_channel,
545 const bool enable) {
546 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
547 "%s(channel: %d, enable: %d)", __FUNCTION__, video_channel,
548 enable);
549 ViEChannelManagerScoped cs(channel_manager_);
550 ViEChannel* vie_channel = cs.Channel(video_channel);
551 if (!vie_channel) {
552 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
553 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
554 SetLastError(kViERtpRtcpInvalidChannelId);
555 return -1;
556 }
557 if (vie_channel->EnableTMMBR(enable) != 0) {
558 SetLastError(kViERtpRtcpUnknownError);
559 return -1;
560 }
561 return 0;
562}
563
mflodman@webrtc.org6cf529d2012-01-24 06:16:16 +0000564int ViERTP_RTCPImpl::SetRembStatus(int video_channel, bool sender,
mflodman@webrtc.org84dc3d12011-12-22 10:26:13 +0000565 bool receiver) {
566 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
567 "ViERTP_RTCPImpl::SetRembStatus(%d, %d, %d)", video_channel,
568 sender, receiver);
mflodman@webrtc.org6cf529d2012-01-24 06:16:16 +0000569 if (!channel_manager_.SetRembStatus(video_channel, sender, receiver)) {
570 return -1;
571 }
572 return 0;
mflodman@webrtc.org84dc3d12011-12-22 10:26:13 +0000573}
574
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000575int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel,
576 unsigned short& fraction_lost,
577 unsigned int& cumulative_lost,
578 unsigned int& extended_max,
579 unsigned int& jitter,
580 int& rtt_ms) const {
581 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
582 "%s(channel: %d)", __FUNCTION__, video_channel);
583 ViEChannelManagerScoped cs(channel_manager_);
584 ViEChannel* vie_channel = cs.Channel(video_channel);
585 if (!vie_channel) {
586 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
587 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
588 SetLastError(kViERtpRtcpInvalidChannelId);
589 return -1;
590 }
591 if (vie_channel->GetReceivedRtcpStatistics(
592 static_cast<WebRtc_UWord16&>(fraction_lost),
593 static_cast<WebRtc_UWord32&>(cumulative_lost),
594 static_cast<WebRtc_UWord32&>(extended_max),
595 static_cast<WebRtc_UWord32&>(jitter),
596 static_cast<WebRtc_Word32&>(rtt_ms)) != 0) {
597 SetLastError(kViERtpRtcpUnknownError);
598 return -1;
599 }
600 return 0;
601}
602
603int ViERTP_RTCPImpl::GetSentRTCPStatistics(const int video_channel,
604 unsigned short& fraction_lost,
605 unsigned int& cumulative_lost,
606 unsigned int& extended_max,
607 unsigned int& jitter,
608 int& rtt_ms) const {
609 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
610 "%s(channel: %d)", __FUNCTION__, video_channel);
611 ViEChannelManagerScoped cs(channel_manager_);
612 ViEChannel* vie_channel = cs.Channel(video_channel);
613 if (!vie_channel) {
614 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
615 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
616 SetLastError(kViERtpRtcpInvalidChannelId);
617 return -1;
618 }
619
620 if (vie_channel->GetSendRtcpStatistics(
621 static_cast<WebRtc_UWord16&>(fraction_lost),
622 static_cast<WebRtc_UWord32&>(cumulative_lost),
623 static_cast<WebRtc_UWord32&>(extended_max),
624 static_cast<WebRtc_UWord32&>(jitter),
625 static_cast<WebRtc_Word32&>(rtt_ms)) != 0) {
626 SetLastError(kViERtpRtcpUnknownError);
627 return -1;
628 }
629 return 0;
630}
631
632int ViERTP_RTCPImpl::GetRTPStatistics(const int video_channel,
633 unsigned int& bytes_sent,
634 unsigned int& packets_sent,
635 unsigned int& bytes_received,
636 unsigned int& packets_received) const {
637 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
638 "%s(channel: %d)", __FUNCTION__, video_channel);
639 ViEChannelManagerScoped cs(channel_manager_);
640 ViEChannel* vie_channel = cs.Channel(video_channel);
641 if (!vie_channel) {
642 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
643 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
644 SetLastError(kViERtpRtcpInvalidChannelId);
645 return -1;
646 }
647 if (vie_channel->GetRtpStatistics(
648 static_cast<WebRtc_UWord32&>(bytes_sent),
649 static_cast<WebRtc_UWord32&>(packets_sent),
650 static_cast<WebRtc_UWord32&>(bytes_received),
651 static_cast<WebRtc_UWord32&>(packets_received)) != 0) {
652 SetLastError(kViERtpRtcpUnknownError);
653 return -1;
654 }
655 return 0;
656}
657
658int ViERTP_RTCPImpl::GetBandwidthUsage(const int video_channel,
659 unsigned int& total_bitrate_sent,
660 unsigned int& video_bitrate_sent,
661 unsigned int& fec_bitrate_sent,
662 unsigned int& nackBitrateSent) const {
663 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
664 "%s(channel: %d)", __FUNCTION__, video_channel);
665 ViEChannelManagerScoped cs(channel_manager_);
666 ViEChannel* vie_channel = cs.Channel(video_channel);
667 if (!vie_channel) {
668 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
669 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
670 SetLastError(kViERtpRtcpInvalidChannelId);
671 return -1;
672 }
673 vie_channel->GetBandwidthUsage(
674 static_cast<WebRtc_UWord32&>(total_bitrate_sent),
675 static_cast<WebRtc_UWord32&>(video_bitrate_sent),
676 static_cast<WebRtc_UWord32&>(fec_bitrate_sent),
stefan@webrtc.orgd0bdab02011-10-14 14:24:54 +0000677 static_cast<WebRtc_UWord32&>(nackBitrateSent));
678 return 0;
679}
680
niklase@google.com470e71d2011-07-07 08:21:25 +0000681int ViERTP_RTCPImpl::SetRTPKeepAliveStatus(
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000682 const int video_channel,
683 bool enable,
684 const char unknown_payload_type,
685 const unsigned int delta_transmit_time_seconds) {
686 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
687 "%s(channel: %d, enable: %d, unknown_payload_type: %d, "
688 "deltaTransmitTimeMS: %ul)",
689 __FUNCTION__, video_channel, enable,
690 static_cast<int>(unknown_payload_type),
691 delta_transmit_time_seconds);
692 ViEChannelManagerScoped cs(channel_manager_);
693 ViEChannel* vie_channel = cs.Channel(video_channel);
694 if (!vie_channel) {
695 WEBRTC_TRACE(kTraceError, kTraceVideo,
696 ViEId(instance_id_, video_channel),
697 "%s: Channel %d doesn't exist", __FUNCTION__,
698 video_channel);
699 SetLastError(kViERtpRtcpInvalidChannelId);
700 return -1;
701 }
702 WebRtc_UWord16 delta_transmit_time_ms = 1000 * delta_transmit_time_seconds;
703 if (vie_channel->SetKeepAliveStatus(enable, unknown_payload_type,
704 delta_transmit_time_ms) != 0) {
705 SetLastError(kViERtpRtcpUnknownError);
706 return -1;
707 }
708 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000709}
710
niklase@google.com470e71d2011-07-07 08:21:25 +0000711int ViERTP_RTCPImpl::GetRTPKeepAliveStatus(
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000712 const int video_channel,
713 bool& enabled,
714 char& unknown_payload_type,
715 unsigned int& delta_transmit_time_seconds) const {
716 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
717 "%s(channel: %d)", __FUNCTION__, video_channel);
718 ViEChannelManagerScoped cs(channel_manager_);
719 ViEChannel* vie_channel = cs.Channel(video_channel);
720 if (!vie_channel) {
721 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
722 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
723 SetLastError(kViERtpRtcpInvalidChannelId);
724 return -1;
725 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000726
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000727 WebRtc_UWord16 delta_time_ms = 0;
728 int ret_val = vie_channel->GetKeepAliveStatus(enabled, unknown_payload_type,
729 delta_time_ms);
730 delta_transmit_time_seconds = delta_time_ms / 1000;
731 if (ret_val != 0) {
732 SetLastError(kViERtpRtcpUnknownError);
733 }
734 return ret_val;
niklase@google.com470e71d2011-07-07 08:21:25 +0000735}
736
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000737int ViERTP_RTCPImpl::StartRTPDump(const int video_channel,
738 const char file_nameUTF8[1024],
739 RTPDirections direction) {
740 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
741 "%s(channel: %d, file_name: %s, direction: %d)", __FUNCTION__,
742 video_channel, file_nameUTF8, direction);
743 assert(FileWrapper::kMaxFileNameSize == 1024);
744 ViEChannelManagerScoped cs(channel_manager_);
745 ViEChannel* vie_channel = cs.Channel(video_channel);
746 if (!vie_channel) {
747 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
748 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
749 SetLastError(kViERtpRtcpInvalidChannelId);
750 return -1;
751 }
752 if (vie_channel->StartRTPDump(file_nameUTF8, direction) != 0) {
753 SetLastError(kViERtpRtcpUnknownError);
754 return -1;
755 }
756 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000757}
758
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000759int ViERTP_RTCPImpl::StopRTPDump(const int video_channel,
760 RTPDirections direction) {
761 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
762 "%s(channel: %d, direction: %d)", __FUNCTION__, video_channel,
763 direction);
764 ViEChannelManagerScoped cs(channel_manager_);
765 ViEChannel* vie_channel = cs.Channel(video_channel);
766 if (!vie_channel) {
767 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
768 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
769 SetLastError(kViERtpRtcpInvalidChannelId);
770 return -1;
771 }
772 if (vie_channel->StopRTPDump(direction) != 0) {
773 SetLastError(kViERtpRtcpUnknownError);
774 return -1;
775 }
776 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000777}
778
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000779int ViERTP_RTCPImpl::RegisterRTPObserver(const int video_channel,
780 ViERTPObserver& observer) {
781 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
782 "%s(channel: %d)", __FUNCTION__, video_channel);
783 ViEChannelManagerScoped cs(channel_manager_);
784 ViEChannel* vie_channel = cs.Channel(video_channel);
785 if (!vie_channel) {
786 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
787 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
788 SetLastError(kViERtpRtcpInvalidChannelId);
789 return -1;
790 }
791 if (vie_channel->RegisterRtpObserver(&observer) != 0) {
792 SetLastError(kViERtpRtcpObserverAlreadyRegistered);
793 return -1;
794 }
795 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000796}
797
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000798int ViERTP_RTCPImpl::DeregisterRTPObserver(const int video_channel) {
799 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
800 "%s(channel: %d)", __FUNCTION__, video_channel);
801 ViEChannelManagerScoped cs(channel_manager_);
802 ViEChannel* vie_channel = cs.Channel(video_channel);
803 if (!vie_channel) {
804 WEBRTC_TRACE(kTraceError, kTraceVideo,
805 ViEId(instance_id_, video_channel),
806 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
807 SetLastError(kViERtpRtcpInvalidChannelId);
808 return -1;
809 }
810 if (vie_channel->RegisterRtpObserver(NULL) != 0) {
811 SetLastError(kViERtpRtcpObserverNotRegistered);
812 return -1;
813 }
814 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000815}
816
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000817int ViERTP_RTCPImpl::RegisterRTCPObserver(const int video_channel,
818 ViERTCPObserver& observer) {
819 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
820 "%s(channel: %d)", __FUNCTION__, video_channel);
821 ViEChannelManagerScoped cs(channel_manager_);
822 ViEChannel* vie_channel = cs.Channel(video_channel);
823 if (!vie_channel) {
824 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
825 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
826 SetLastError(kViERtpRtcpInvalidChannelId);
827 return -1;
828 }
829 if (vie_channel->RegisterRtcpObserver(&observer) != 0) {
830 SetLastError(kViERtpRtcpObserverAlreadyRegistered);
831 return -1;
832 }
833 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000834}
835
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000836int ViERTP_RTCPImpl::DeregisterRTCPObserver(const int video_channel) {
837 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(instance_id_, video_channel),
838 "%s(channel: %d)", __FUNCTION__, video_channel);
839 ViEChannelManagerScoped cs(channel_manager_);
840 ViEChannel* vie_channel = cs.Channel(video_channel);
841 if (!vie_channel) {
842 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(instance_id_, video_channel),
843 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
844 SetLastError(kViERtpRtcpInvalidChannelId);
845 return -1;
846 }
847 if (vie_channel->RegisterRtcpObserver(NULL) != 0) {
848 SetLastError(kViERtpRtcpObserverNotRegistered);
849 return -1;
850 }
851 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000852}
853
mflodman@webrtc.org8da24172011-12-19 14:18:41 +0000854} // namespace webrtc