Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / video_engine / vie_receiver.cc
1 /*
2  *  Copyright (c) 2012 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
11 #include "webrtc/video_engine/vie_receiver.h"
12
13 #include <vector>
14
15 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
16 #include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
17 #include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
18 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
19 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
21 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
22 #include "webrtc/modules/utility/interface/rtp_dump.h"
23 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
24 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
25 #include "webrtc/system_wrappers/interface/logging.h"
26 #include "webrtc/system_wrappers/interface/tick_util.h"
27 #include "webrtc/system_wrappers/interface/timestamp_extrapolator.h"
28 #include "webrtc/system_wrappers/interface/trace.h"
29
30 namespace webrtc {
31
32 ViEReceiver::ViEReceiver(const int32_t channel_id,
33                          VideoCodingModule* module_vcm,
34                          RemoteBitrateEstimator* remote_bitrate_estimator,
35                          RtpFeedback* rtp_feedback)
36     : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
37       channel_id_(channel_id),
38       rtp_header_parser_(RtpHeaderParser::Create()),
39       rtp_payload_registry_(new RTPPayloadRegistry(
40           RTPPayloadStrategy::CreateStrategy(false))),
41       rtp_receiver_(RtpReceiver::CreateVideoReceiver(
42           channel_id, Clock::GetRealTimeClock(), this, rtp_feedback,
43           rtp_payload_registry_.get())),
44       rtp_receive_statistics_(ReceiveStatistics::Create(
45           Clock::GetRealTimeClock())),
46       fec_receiver_(FecReceiver::Create(this)),
47       rtp_rtcp_(NULL),
48       vcm_(module_vcm),
49       remote_bitrate_estimator_(remote_bitrate_estimator),
50       clock_(Clock::GetRealTimeClock()),
51       ts_extrapolator_(
52           new TimestampExtrapolator(clock_->TimeInMilliseconds())),
53       rtp_dump_(NULL),
54       receiving_(false),
55       restored_packet_in_use_(false),
56       receiving_ast_enabled_(false) {
57   assert(remote_bitrate_estimator);
58 }
59
60 ViEReceiver::~ViEReceiver() {
61   if (rtp_dump_) {
62     rtp_dump_->Stop();
63     RtpDump::DestroyRtpDump(rtp_dump_);
64     rtp_dump_ = NULL;
65   }
66 }
67
68 bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
69   int8_t old_pltype = -1;
70   if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName,
71                                                 kVideoPayloadTypeFrequency,
72                                                 0,
73                                                 video_codec.maxBitrate,
74                                                 &old_pltype) != -1) {
75     rtp_payload_registry_->DeRegisterReceivePayload(old_pltype);
76   }
77
78   return RegisterPayload(video_codec);
79 }
80
81 bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) {
82   return rtp_receiver_->RegisterReceivePayload(video_codec.plName,
83                                                video_codec.plType,
84                                                kVideoPayloadTypeFrequency,
85                                                0,
86                                                video_codec.maxBitrate) == 0;
87 }
88
89 void ViEReceiver::SetNackStatus(bool enable,
90                                 int max_nack_reordering_threshold) {
91   if (!enable) {
92     // Reset the threshold back to the lower default threshold when NACK is
93     // disabled since we no longer will be receiving retransmissions.
94     max_nack_reordering_threshold = kDefaultMaxReorderingThreshold;
95   }
96   rtp_receive_statistics_->SetMaxReorderingThreshold(
97       max_nack_reordering_threshold);
98   rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff);
99 }
100
101 void ViEReceiver::SetRtxStatus(bool enable, uint32_t ssrc) {
102   rtp_payload_registry_->SetRtxStatus(enable, ssrc);
103 }
104
105 void ViEReceiver::SetRtxPayloadType(uint32_t payload_type) {
106   rtp_payload_registry_->SetRtxPayloadType(payload_type);
107 }
108
109 uint32_t ViEReceiver::GetRemoteSsrc() const {
110   return rtp_receiver_->SSRC();
111 }
112
113 int ViEReceiver::GetCsrcs(uint32_t* csrcs) const {
114   return rtp_receiver_->CSRCs(csrcs);
115 }
116
117 void ViEReceiver::SetRtpRtcpModule(RtpRtcp* module) {
118   rtp_rtcp_ = module;
119 }
120
121 RtpReceiver* ViEReceiver::GetRtpReceiver() const {
122   return rtp_receiver_.get();
123 }
124
125 void ViEReceiver::RegisterSimulcastRtpRtcpModules(
126     const std::list<RtpRtcp*>& rtp_modules) {
127   CriticalSectionScoped cs(receive_cs_.get());
128   rtp_rtcp_simulcast_.clear();
129
130   if (!rtp_modules.empty()) {
131     rtp_rtcp_simulcast_.insert(rtp_rtcp_simulcast_.begin(),
132                                rtp_modules.begin(),
133                                rtp_modules.end());
134   }
135 }
136
137 bool ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) {
138   if (enable) {
139     return rtp_header_parser_->RegisterRtpHeaderExtension(
140         kRtpExtensionTransmissionTimeOffset, id);
141   } else {
142     return rtp_header_parser_->DeregisterRtpHeaderExtension(
143         kRtpExtensionTransmissionTimeOffset);
144   }
145 }
146
147 bool ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
148   if (enable) {
149     if (rtp_header_parser_->RegisterRtpHeaderExtension(
150         kRtpExtensionAbsoluteSendTime, id)) {
151       receiving_ast_enabled_ = true;
152       return true;
153     } else {
154       return false;
155     }
156   } else {
157     receiving_ast_enabled_ = false;
158     return rtp_header_parser_->DeregisterRtpHeaderExtension(
159         kRtpExtensionAbsoluteSendTime);
160   }
161 }
162
163 int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
164                                    int rtp_packet_length,
165                                    const PacketTime& packet_time) {
166   return InsertRTPPacket(static_cast<const uint8_t*>(rtp_packet),
167                          rtp_packet_length, packet_time);
168 }
169
170 int ViEReceiver::ReceivedRTCPPacket(const void* rtcp_packet,
171                                     int rtcp_packet_length) {
172   return InsertRTCPPacket(static_cast<const uint8_t*>(rtcp_packet),
173                           rtcp_packet_length);
174 }
175
176 int32_t ViEReceiver::OnReceivedPayloadData(
177     const uint8_t* payload_data, const uint16_t payload_size,
178     const WebRtcRTPHeader* rtp_header) {
179   WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
180   CalculateCaptureNtpTime(&rtp_header_with_ntp);
181   if (vcm_->IncomingPacket(payload_data,
182                            payload_size,
183                            rtp_header_with_ntp) != 0) {
184     // Check this...
185     return -1;
186   }
187   return 0;
188 }
189
190 void ViEReceiver::CalculateCaptureNtpTime(WebRtcRTPHeader* rtp_header) {
191   if (rtcp_list_.size() < 2) {
192     // We need two RTCP SR reports to calculate NTP.
193     return;
194   }
195
196   int64_t sender_capture_ntp_ms = 0;
197   if (!RtpToNtpMs(rtp_header->header.timestamp,
198                   rtcp_list_,
199                   &sender_capture_ntp_ms)) {
200     return;
201   }
202   uint32_t timestamp = sender_capture_ntp_ms * 90;
203   int64_t receiver_capture_ms =
204       ts_extrapolator_->ExtrapolateLocalTime(timestamp);
205   int64_t ntp_offset =
206       clock_->CurrentNtpInMilliseconds() - clock_->TimeInMilliseconds();
207   rtp_header->ntp_time_ms = receiver_capture_ms + ntp_offset;
208 }
209
210 bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
211                                     int rtp_packet_length) {
212   RTPHeader header;
213   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
214     WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVideo, channel_id_,
215                  "IncomingPacket invalid RTP header");
216     return false;
217   }
218   header.payload_type_frequency = kVideoPayloadTypeFrequency;
219   return ReceivePacket(rtp_packet, rtp_packet_length, header, false);
220 }
221
222 void ViEReceiver::ReceivedBWEPacket(
223     int64_t arrival_time_ms, int payload_size, const RTPHeader& header) {
224   // Only forward if the incoming packet *and* the channel are both configured
225   // to receive absolute sender time. RTP time stamps may have different rates
226   // for audio and video and shouldn't be mixed.
227   if (header.extension.hasAbsoluteSendTime && receiving_ast_enabled_) {
228     remote_bitrate_estimator_->IncomingPacket(arrival_time_ms, payload_size,
229                                               header);
230   }
231 }
232
233 int ViEReceiver::InsertRTPPacket(const uint8_t* rtp_packet,
234                                  int rtp_packet_length,
235                                  const PacketTime& packet_time) {
236   {
237     CriticalSectionScoped cs(receive_cs_.get());
238     if (!receiving_) {
239       return -1;
240     }
241     if (rtp_dump_) {
242       rtp_dump_->DumpPacket(rtp_packet,
243                             static_cast<uint16_t>(rtp_packet_length));
244     }
245   }
246
247   RTPHeader header;
248   if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length,
249                                  &header)) {
250     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, channel_id_,
251                  "Incoming packet: Invalid RTP header");
252     return -1;
253   }
254   int payload_length = rtp_packet_length - header.headerLength;
255   int64_t arrival_time_ms;
256   if (packet_time.timestamp != -1)
257     arrival_time_ms = (packet_time.timestamp + 500) / 1000;
258   else
259     arrival_time_ms = TickTime::MillisecondTimestamp();
260
261   remote_bitrate_estimator_->IncomingPacket(arrival_time_ms,
262                                             payload_length, header);
263   header.payload_type_frequency = kVideoPayloadTypeFrequency;
264
265   bool in_order = IsPacketInOrder(header);
266   rtp_receive_statistics_->IncomingPacket(
267       header, rtp_packet_length, IsPacketRetransmitted(header, in_order));
268   rtp_payload_registry_->SetIncomingPayloadType(header);
269   return ReceivePacket(rtp_packet, rtp_packet_length, header, in_order)
270       ? 0
271       : -1;
272 }
273
274 bool ViEReceiver::ReceivePacket(const uint8_t* packet,
275                                 int packet_length,
276                                 const RTPHeader& header,
277                                 bool in_order) {
278   if (rtp_payload_registry_->IsEncapsulated(header)) {
279     return ParseAndHandleEncapsulatingHeader(packet, packet_length, header);
280   }
281   const uint8_t* payload = packet + header.headerLength;
282   int payload_length = packet_length - header.headerLength;
283   assert(payload_length >= 0);
284   PayloadUnion payload_specific;
285   if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
286                                                   &payload_specific)) {
287     return false;
288   }
289   return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
290                                           payload_specific, in_order);
291 }
292
293 bool ViEReceiver::ParseAndHandleEncapsulatingHeader(const uint8_t* packet,
294                                                     int packet_length,
295                                                     const RTPHeader& header) {
296   if (rtp_payload_registry_->IsRed(header)) {
297     int8_t ulpfec_pt = rtp_payload_registry_->ulpfec_payload_type();
298     if (packet[header.headerLength] == ulpfec_pt)
299       rtp_receive_statistics_->FecPacketReceived(header.ssrc);
300     if (fec_receiver_->AddReceivedRedPacket(
301             header, packet, packet_length, ulpfec_pt) != 0) {
302       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, channel_id_,
303                    "Incoming RED packet error");
304       return false;
305     }
306     return fec_receiver_->ProcessReceivedFec() == 0;
307   } else if (rtp_payload_registry_->IsRtx(header)) {
308     if (header.headerLength + header.paddingLength == packet_length) {
309       // This is an empty packet and should be silently dropped before trying to
310       // parse the RTX header.
311       return true;
312     }
313     // Remove the RTX header and parse the original RTP header.
314     if (packet_length < header.headerLength)
315       return false;
316     if (packet_length > static_cast<int>(sizeof(restored_packet_)))
317       return false;
318     CriticalSectionScoped cs(receive_cs_.get());
319     if (restored_packet_in_use_) {
320       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, channel_id_,
321                    "Multiple RTX headers detected, dropping packet");
322       return false;
323     }
324     uint8_t* restored_packet_ptr = restored_packet_;
325     if (!rtp_payload_registry_->RestoreOriginalPacket(
326         &restored_packet_ptr, packet, &packet_length, rtp_receiver_->SSRC(),
327         header)) {
328       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, channel_id_,
329                    "Incoming RTX packet: invalid RTP header");
330       return false;
331     }
332     restored_packet_in_use_ = true;
333     bool ret = OnRecoveredPacket(restored_packet_ptr, packet_length);
334     restored_packet_in_use_ = false;
335     return ret;
336   }
337   return false;
338 }
339
340 int ViEReceiver::InsertRTCPPacket(const uint8_t* rtcp_packet,
341                                   int rtcp_packet_length) {
342   {
343     CriticalSectionScoped cs(receive_cs_.get());
344     if (!receiving_) {
345       return -1;
346     }
347
348     if (rtp_dump_) {
349       rtp_dump_->DumpPacket(
350           rtcp_packet, static_cast<uint16_t>(rtcp_packet_length));
351     }
352
353     std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin();
354     while (it != rtp_rtcp_simulcast_.end()) {
355       RtpRtcp* rtp_rtcp = *it++;
356       rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
357     }
358   }
359   assert(rtp_rtcp_);  // Should be set by owner at construction time.
360   int ret = rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
361   if (ret != 0) {
362     return ret;
363   }
364
365   if (!GetRtcpTimestamp()) {
366     LOG(LS_WARNING) << "Failed to retrieve timestamp information from RTCP SR.";
367   }
368
369   return 0;
370 }
371
372 bool ViEReceiver::GetRtcpTimestamp() {
373   uint16_t rtt = 0;
374   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, NULL, NULL, NULL);
375   if (rtt == 0) {
376     // Waiting for valid rtt.
377     return true;
378   }
379
380   // Update RTCP list
381   uint32_t ntp_secs = 0;
382   uint32_t ntp_frac = 0;
383   uint32_t rtp_timestamp = 0;
384   if (0 != rtp_rtcp_->RemoteNTP(&ntp_secs,
385                                 &ntp_frac,
386                                 NULL,
387                                 NULL,
388                                 &rtp_timestamp)) {
389     return false;
390   }
391
392   bool new_rtcp_sr = false;
393   if (!UpdateRtcpList(ntp_secs,
394                       ntp_frac,
395                       rtp_timestamp,
396                       &rtcp_list_,
397                       &new_rtcp_sr)) {
398     return false;
399   }
400
401   if (!new_rtcp_sr) {
402     // No new RTCP SR since last time this function was called.
403     return true;
404   }
405
406   // Update extrapolator with the new arrival time.
407   // The extrapolator assumes the TimeInMilliseconds time.
408   int64_t receiver_arrival_time = clock_->TimeInMilliseconds();
409   int64_t sender_send_time_ms = Clock::NtpToMs(ntp_secs, ntp_frac);
410   int64_t sender_arrival_time_90k = (sender_send_time_ms + rtt / 2) * 90;
411   ts_extrapolator_->Update(receiver_arrival_time, sender_arrival_time_90k);
412   return true;
413 }
414
415 void ViEReceiver::StartReceive() {
416   CriticalSectionScoped cs(receive_cs_.get());
417   receiving_ = true;
418 }
419
420 void ViEReceiver::StopReceive() {
421   CriticalSectionScoped cs(receive_cs_.get());
422   receiving_ = false;
423 }
424
425 int ViEReceiver::StartRTPDump(const char file_nameUTF8[1024]) {
426   CriticalSectionScoped cs(receive_cs_.get());
427   if (rtp_dump_) {
428     // Restart it if it already exists and is started
429     rtp_dump_->Stop();
430   } else {
431     rtp_dump_ = RtpDump::CreateRtpDump();
432     if (rtp_dump_ == NULL) {
433       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_,
434                    "StartRTPDump: Failed to create RTP dump");
435       return -1;
436     }
437   }
438   if (rtp_dump_->Start(file_nameUTF8) != 0) {
439     RtpDump::DestroyRtpDump(rtp_dump_);
440     rtp_dump_ = NULL;
441     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_,
442                  "StartRTPDump: Failed to start RTP dump");
443     return -1;
444   }
445   return 0;
446 }
447
448 int ViEReceiver::StopRTPDump() {
449   CriticalSectionScoped cs(receive_cs_.get());
450   if (rtp_dump_) {
451     if (rtp_dump_->IsActive()) {
452       rtp_dump_->Stop();
453     } else {
454       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_,
455                    "StopRTPDump: Dump not active");
456     }
457     RtpDump::DestroyRtpDump(rtp_dump_);
458     rtp_dump_ = NULL;
459   } else {
460     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, channel_id_,
461                  "StopRTPDump: RTP dump not started");
462     return -1;
463   }
464   return 0;
465 }
466
467 void ViEReceiver::GetReceiveBandwidthEstimatorStats(
468     ReceiveBandwidthEstimatorStats* output) const {
469   remote_bitrate_estimator_->GetStats(output);
470 }
471
472 ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
473   return rtp_receive_statistics_.get();
474 }
475
476 bool ViEReceiver::IsPacketInOrder(const RTPHeader& header) const {
477   StreamStatistician* statistician =
478       rtp_receive_statistics_->GetStatistician(header.ssrc);
479   if (!statistician)
480     return false;
481   return statistician->IsPacketInOrder(header.sequenceNumber);
482 }
483
484 bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header,
485                                         bool in_order) const {
486   // Retransmissions are handled separately if RTX is enabled.
487   if (rtp_payload_registry_->RtxEnabled())
488     return false;
489   StreamStatistician* statistician =
490       rtp_receive_statistics_->GetStatistician(header.ssrc);
491   if (!statistician)
492     return false;
493   // Check if this is a retransmission.
494   uint16_t min_rtt = 0;
495   rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
496   return !in_order &&
497       statistician->IsRetransmitOfOldPacket(header, min_rtt);
498 }
499 }  // namespace webrtc