Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / rtp_sender_video.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/modules/rtp_rtcp/source/rtp_sender_video.h"
12
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
18 #include "webrtc/modules/rtp_rtcp/source/producer_fec.h"
19 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
20 #include "webrtc/modules/rtp_rtcp/source/rtp_format_vp8.h"
21 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
22 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
23 #include "webrtc/system_wrappers/interface/logging.h"
24 #include "webrtc/system_wrappers/interface/trace_event.h"
25
26 namespace webrtc {
27 enum { REDForFECHeaderLength = 1 };
28
29 struct RtpPacket {
30   uint16_t rtpHeaderLength;
31   ForwardErrorCorrection::Packet* pkt;
32 };
33
34 RTPSenderVideo::RTPSenderVideo(Clock* clock,
35                                RTPSenderInterface* rtpSender)
36     : _rtpSender(*rtpSender),
37       _sendVideoCritsect(CriticalSectionWrapper::CreateCriticalSection()),
38       _videoType(kRtpVideoGeneric),
39       _videoCodecInformation(NULL),
40       _maxBitrate(0),
41       _retransmissionSettings(kRetransmitBaseLayer),
42
43       // Generic FEC
44       _fec(),
45       _fecEnabled(false),
46       _payloadTypeRED(-1),
47       _payloadTypeFEC(-1),
48       _numberFirstPartition(0),
49       delta_fec_params_(),
50       key_fec_params_(),
51       producer_fec_(&_fec),
52       _fecOverheadRate(clock, NULL),
53       _videoBitrate(clock, NULL) {
54   memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
55   memset(&key_fec_params_, 0, sizeof(key_fec_params_));
56   delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1;
57   delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type =
58         kFecMaskRandom;
59 }
60
61 RTPSenderVideo::~RTPSenderVideo()
62 {
63     if(_videoCodecInformation)
64     {
65         delete _videoCodecInformation;
66     }
67     delete _sendVideoCritsect;
68 }
69
70 void
71 RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes videoType)
72 {
73     CriticalSectionScoped cs(_sendVideoCritsect);
74     _videoType = videoType;
75 }
76
77 RtpVideoCodecTypes
78 RTPSenderVideo::VideoCodecType() const
79 {
80     return _videoType;
81 }
82
83 int32_t RTPSenderVideo::RegisterVideoPayload(
84     const char payloadName[RTP_PAYLOAD_NAME_SIZE],
85     const int8_t payloadType,
86     const uint32_t maxBitRate,
87     RtpUtility::Payload*& payload) {
88   CriticalSectionScoped cs(_sendVideoCritsect);
89
90   RtpVideoCodecTypes videoType = kRtpVideoGeneric;
91   if (RtpUtility::StringCompare(payloadName, "VP8", 3)) {
92     videoType = kRtpVideoVp8;
93   } else if (RtpUtility::StringCompare(payloadName, "H264", 4)) {
94     videoType = kRtpVideoH264;
95   } else if (RtpUtility::StringCompare(payloadName, "I420", 4)) {
96     videoType = kRtpVideoGeneric;
97   } else {
98     videoType = kRtpVideoGeneric;
99   }
100   payload = new RtpUtility::Payload;
101   payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
102   strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
103   payload->typeSpecific.Video.videoCodecType = videoType;
104   payload->typeSpecific.Video.maxRate = maxBitRate;
105   payload->audio = false;
106   return 0;
107 }
108
109 int32_t
110 RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer,
111                                 const uint16_t payload_length,
112                                 const uint16_t rtp_header_length,
113                                 const uint32_t capture_timestamp,
114                                 int64_t capture_time_ms,
115                                 StorageType storage,
116                                 bool protect) {
117   if(_fecEnabled) {
118     int ret = 0;
119     int fec_overhead_sent = 0;
120     int video_sent = 0;
121
122     RedPacket* red_packet = producer_fec_.BuildRedPacket(data_buffer,
123                                                          payload_length,
124                                                          rtp_header_length,
125                                                          _payloadTypeRED);
126     TRACE_EVENT_INSTANT2("webrtc_rtp", "Video::PacketRed",
127                          "timestamp", capture_timestamp,
128                          "seqnum", _rtpSender.SequenceNumber());
129     // Sending the media packet with RED header.
130     int packet_success = _rtpSender.SendToNetwork(
131         red_packet->data(),
132         red_packet->length() - rtp_header_length,
133         rtp_header_length,
134         capture_time_ms,
135         storage,
136         PacedSender::kNormalPriority);
137
138     ret |= packet_success;
139
140     if (packet_success == 0) {
141       video_sent += red_packet->length();
142     }
143     delete red_packet;
144     red_packet = NULL;
145
146     if (protect) {
147       ret = producer_fec_.AddRtpPacketAndGenerateFec(data_buffer,
148                                                      payload_length,
149                                                      rtp_header_length);
150       if (ret != 0)
151         return ret;
152     }
153
154     while (producer_fec_.FecAvailable()) {
155       red_packet = producer_fec_.GetFecPacket(
156           _payloadTypeRED,
157           _payloadTypeFEC,
158           _rtpSender.IncrementSequenceNumber(),
159           rtp_header_length);
160       StorageType storage = kDontRetransmit;
161       if (_retransmissionSettings & kRetransmitFECPackets) {
162         storage = kAllowRetransmission;
163       }
164       TRACE_EVENT_INSTANT2("webrtc_rtp", "Video::PacketFec",
165                            "timestamp", capture_timestamp,
166                            "seqnum", _rtpSender.SequenceNumber());
167       // Sending FEC packet with RED header.
168       int packet_success = _rtpSender.SendToNetwork(
169           red_packet->data(),
170           red_packet->length() - rtp_header_length,
171           rtp_header_length,
172           capture_time_ms,
173           storage,
174           PacedSender::kNormalPriority);
175
176       ret |= packet_success;
177
178       if (packet_success == 0) {
179         fec_overhead_sent += red_packet->length();
180       }
181       delete red_packet;
182       red_packet = NULL;
183     }
184     _videoBitrate.Update(video_sent);
185     _fecOverheadRate.Update(fec_overhead_sent);
186     return ret;
187   }
188   TRACE_EVENT_INSTANT2("webrtc_rtp", "Video::PacketNormal",
189                        "timestamp", capture_timestamp,
190                        "seqnum", _rtpSender.SequenceNumber());
191   int ret = _rtpSender.SendToNetwork(data_buffer,
192                                      payload_length,
193                                      rtp_header_length,
194                                      capture_time_ms,
195                                      storage,
196                                      PacedSender::kNormalPriority);
197   if (ret == 0) {
198     _videoBitrate.Update(payload_length + rtp_header_length);
199   }
200   return ret;
201 }
202
203 int32_t
204 RTPSenderVideo::SendRTPIntraRequest()
205 {
206     // RFC 2032
207     // 5.2.1.  Full intra-frame Request (FIR) packet
208
209     uint16_t length = 8;
210     uint8_t data[8];
211     data[0] = 0x80;
212     data[1] = 192;
213     data[2] = 0;
214     data[3] = 1; // length
215
216     RtpUtility::AssignUWord32ToBuffer(data + 4, _rtpSender.SSRC());
217
218     TRACE_EVENT_INSTANT1("webrtc_rtp",
219                          "Video::IntraRequest",
220                          "seqnum", _rtpSender.SequenceNumber());
221     return _rtpSender.SendToNetwork(data, 0, length, -1, kDontStore,
222                                     PacedSender::kNormalPriority);
223 }
224
225 int32_t
226 RTPSenderVideo::SetGenericFECStatus(const bool enable,
227                                     const uint8_t payloadTypeRED,
228                                     const uint8_t payloadTypeFEC)
229 {
230     _fecEnabled = enable;
231     _payloadTypeRED = payloadTypeRED;
232     _payloadTypeFEC = payloadTypeFEC;
233     memset(&delta_fec_params_, 0, sizeof(delta_fec_params_));
234     memset(&key_fec_params_, 0, sizeof(key_fec_params_));
235     delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1;
236     delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type =
237           kFecMaskRandom;
238     return 0;
239 }
240
241 int32_t
242 RTPSenderVideo::GenericFECStatus(bool& enable,
243                                  uint8_t& payloadTypeRED,
244                                  uint8_t& payloadTypeFEC) const
245 {
246     enable = _fecEnabled;
247     payloadTypeRED = _payloadTypeRED;
248     payloadTypeFEC = _payloadTypeFEC;
249     return 0;
250 }
251
252 uint16_t
253 RTPSenderVideo::FECPacketOverhead() const
254 {
255     if (_fecEnabled)
256     {
257       // Overhead is FEC headers plus RED for FEC header plus anything in RTP
258       // header beyond the 12 bytes base header (CSRC list, extensions...)
259       // This reason for the header extensions to be included here is that
260       // from an FEC viewpoint, they are part of the payload to be protected.
261       // (The base RTP header is already protected by the FEC header.)
262       return ForwardErrorCorrection::PacketOverhead() + REDForFECHeaderLength +
263              (_rtpSender.RTPHeaderLength() - kRtpHeaderSize);
264     }
265     return 0;
266 }
267
268 int32_t RTPSenderVideo::SetFecParameters(
269     const FecProtectionParams* delta_params,
270     const FecProtectionParams* key_params) {
271   assert(delta_params);
272   assert(key_params);
273   delta_fec_params_ = *delta_params;
274   key_fec_params_ = *key_params;
275   return 0;
276 }
277
278 int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
279                                   const FrameType frameType,
280                                   const int8_t payloadType,
281                                   const uint32_t captureTimeStamp,
282                                   int64_t capture_time_ms,
283                                   const uint8_t* payloadData,
284                                   const uint32_t payloadSize,
285                                   const RTPFragmentationHeader* fragmentation,
286                                   VideoCodecInformation* codecInfo,
287                                   const RTPVideoTypeHeader* rtpTypeHdr) {
288   if (payloadSize == 0) {
289     return -1;
290   }
291
292   if (frameType == kVideoFrameKey) {
293     producer_fec_.SetFecParameters(&key_fec_params_, _numberFirstPartition);
294   } else {
295     producer_fec_.SetFecParameters(&delta_fec_params_, _numberFirstPartition);
296   }
297
298   // Default setting for number of first partition packets:
299   // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
300   _numberFirstPartition = 0;
301
302   switch (videoType) {
303     case kRtpVideoGeneric:
304       return SendGeneric(frameType,
305                          payloadType,
306                          captureTimeStamp,
307                          capture_time_ms,
308                          payloadData,
309                          payloadSize);
310     case kRtpVideoVp8:
311       return SendVP8(frameType,
312                      payloadType,
313                      captureTimeStamp,
314                      capture_time_ms,
315                      payloadData,
316                      payloadSize,
317                      fragmentation,
318                      rtpTypeHdr);
319     case kRtpVideoH264:
320       return SendH264(frameType,
321                       payloadType,
322                       captureTimeStamp,
323                       capture_time_ms,
324                       payloadData,
325                       payloadSize,
326                       fragmentation,
327                       rtpTypeHdr)
328                  ? 0
329                  : -1;
330     default:
331       assert(false);
332       break;
333   }
334   return 0;
335 }
336
337 int32_t RTPSenderVideo::SendGeneric(const FrameType frame_type,
338                                     const int8_t payload_type,
339                                     const uint32_t capture_timestamp,
340                                     int64_t capture_time_ms,
341                                     const uint8_t* payload,
342                                     uint32_t size) {
343   assert(frame_type == kVideoFrameKey || frame_type == kVideoFrameDelta);
344   uint16_t rtp_header_length = _rtpSender.RTPHeaderLength();
345   uint16_t max_length = _rtpSender.MaxPayloadLength() - FECPacketOverhead() -
346                         rtp_header_length - (1 /* generic header length */);
347
348   // Fragment packets more evenly by splitting the payload up evenly.
349   uint32_t num_packets = (size + max_length - 1) / max_length;
350   uint32_t payload_length = (size + num_packets - 1) / num_packets;
351   assert(payload_length <= max_length);
352
353   // Fragment packet into packets of max MaxPayloadLength bytes payload.
354   uint8_t buffer[IP_PACKET_SIZE];
355
356   uint8_t generic_header = RtpFormatVideoGeneric::kFirstPacketBit;
357   if (frame_type == kVideoFrameKey) {
358     generic_header |= RtpFormatVideoGeneric::kKeyFrameBit;
359   }
360
361   while (size > 0) {
362     if (size < payload_length) {
363       payload_length = size;
364     }
365     size -= payload_length;
366
367     // MarkerBit is 1 on final packet (bytes_to_send == 0)
368     if (_rtpSender.BuildRTPheader(buffer, payload_type, size == 0,
369                                   capture_timestamp,
370                                   capture_time_ms) != rtp_header_length) {
371       return -1;
372     }
373
374     uint8_t* out_ptr = &buffer[rtp_header_length];
375
376     // Put generic header in packet
377     *out_ptr++ = generic_header;
378     // Remove first-packet bit, following packets are intermediate
379     generic_header &= ~RtpFormatVideoGeneric::kFirstPacketBit;
380
381     // Put payload in packet
382     memcpy(out_ptr, payload, payload_length);
383     payload += payload_length;
384
385     if (SendVideoPacket(buffer, payload_length + 1, rtp_header_length,
386                         capture_timestamp, capture_time_ms,
387                         kAllowRetransmission, true)) {
388       return -1;
389     }
390   }
391   return 0;
392 }
393
394 VideoCodecInformation*
395 RTPSenderVideo::CodecInformationVideo()
396 {
397     return _videoCodecInformation;
398 }
399
400 void
401 RTPSenderVideo::SetMaxConfiguredBitrateVideo(const uint32_t maxBitrate)
402 {
403     _maxBitrate = maxBitrate;
404 }
405
406 uint32_t
407 RTPSenderVideo::MaxConfiguredBitrateVideo() const
408 {
409     return _maxBitrate;
410 }
411
412 int32_t
413 RTPSenderVideo::SendVP8(const FrameType frameType,
414                         const int8_t payloadType,
415                         const uint32_t captureTimeStamp,
416                         int64_t capture_time_ms,
417                         const uint8_t* payloadData,
418                         const uint32_t payloadSize,
419                         const RTPFragmentationHeader* fragmentation,
420                         const RTPVideoTypeHeader* rtpTypeHdr)
421 {
422     const uint16_t rtpHeaderLength = _rtpSender.RTPHeaderLength();
423
424     int32_t payloadBytesToSend = payloadSize;
425     const uint8_t* data = payloadData;
426
427     uint16_t maxPayloadLengthVP8 = _rtpSender.MaxDataPayloadLength();
428
429     assert(rtpTypeHdr);
430     // Initialize disregarding partition boundaries: this will use kEqualSize
431     // packetization mode, which produces ~equal size packets for each frame.
432     RtpPacketizerVp8 packetizer(rtpTypeHdr->VP8, maxPayloadLengthVP8);
433     packetizer.SetPayloadData(data, payloadBytesToSend, NULL);
434
435     StorageType storage = kAllowRetransmission;
436     if (rtpTypeHdr->VP8.temporalIdx == 0 &&
437         !(_retransmissionSettings & kRetransmitBaseLayer)) {
438       storage = kDontRetransmit;
439     } else if (rtpTypeHdr->VP8.temporalIdx != kNoTemporalIdx &&
440         rtpTypeHdr->VP8.temporalIdx > 0 &&
441         !(_retransmissionSettings & kRetransmitHigherLayers)) {
442       storage = kDontRetransmit;
443     }
444
445     bool last = false;
446     _numberFirstPartition = 0;
447     // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or kNoTemporalIdx
448     // if the field isn't used (so all layers are the base layer).  We currently
449     // only protect base layers, so look for these two cases.
450     bool protect = rtpTypeHdr->VP8.temporalIdx == 0 ||
451         rtpTypeHdr->VP8.temporalIdx == kNoTemporalIdx;
452     while (!last)
453     {
454         // Write VP8 Payload Descriptor and VP8 payload.
455         uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
456         size_t payloadBytesInPacket = 0;
457         if (!packetizer.NextPacket(
458                 &dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last))
459           return -1;
460
461         // Write RTP header.
462         // Set marker bit true if this is the last packet in frame.
463         _rtpSender.BuildRTPheader(dataBuffer, payloadType, last,
464             captureTimeStamp, capture_time_ms);
465         if (-1 == SendVideoPacket(dataBuffer, payloadBytesInPacket,
466                                   rtpHeaderLength, captureTimeStamp,
467                                   capture_time_ms, storage, protect))
468         {
469           LOG(LS_WARNING)
470               << "RTPSenderVideo::SendVP8 failed to send packet number "
471               << _rtpSender.SequenceNumber();
472         }
473     }
474     TRACE_EVENT_ASYNC_END1("webrtc", "Video", capture_time_ms,
475                            "timestamp", _rtpSender.Timestamp());
476     return 0;
477 }
478
479 bool RTPSenderVideo::SendH264(const FrameType frameType,
480                               const int8_t payloadType,
481                               const uint32_t captureTimeStamp,
482                               int64_t capture_time_ms,
483                               const uint8_t* payloadData,
484                               const uint32_t payloadSize,
485                               const RTPFragmentationHeader* fragmentation,
486                               const RTPVideoTypeHeader* rtpTypeHdr) {
487   size_t rtp_header_length = _rtpSender.RTPHeaderLength();
488   int32_t payload_bytes_to_send = payloadSize;
489   const uint8_t* data = payloadData;
490   size_t max_payload_length = _rtpSender.MaxDataPayloadLength();
491
492   scoped_ptr<RtpPacketizer> packetizer(
493       RtpPacketizer::Create(kRtpVideoH264, max_payload_length));
494   packetizer->SetPayloadData(data, payload_bytes_to_send, fragmentation);
495
496   StorageType storage = kAllowRetransmission;
497   bool protect = (frameType == kVideoFrameKey);
498   bool last = false;
499
500   while (!last) {
501     // Write H264 payload.
502     uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
503     size_t payload_bytes_in_packet = 0;
504     if (!packetizer->NextPacket(
505             &dataBuffer[rtp_header_length], &payload_bytes_in_packet, &last)) {
506       return false;
507     }
508
509     // Write RTP header.
510     // Set marker bit true if this is the last packet in frame.
511     _rtpSender.BuildRTPheader(
512         dataBuffer, payloadType, last, captureTimeStamp, capture_time_ms);
513     if (SendVideoPacket(dataBuffer,
514                         payload_bytes_in_packet,
515                         rtp_header_length,
516                         captureTimeStamp,
517                         capture_time_ms,
518                         storage,
519                         protect)) {
520       LOG(LS_WARNING)
521           << "RTPSenderVideo::SendH264 failed to send packet number "
522           << _rtpSender.SequenceNumber();
523     }
524   }
525   return true;
526 }
527
528 void RTPSenderVideo::ProcessBitrate() {
529   _videoBitrate.Process();
530   _fecOverheadRate.Process();
531 }
532
533 uint32_t RTPSenderVideo::VideoBitrateSent() const {
534   return _videoBitrate.BitrateLast();
535 }
536
537 uint32_t RTPSenderVideo::FecOverheadRate() const {
538   return _fecOverheadRate.BitrateLast();
539 }
540
541 int RTPSenderVideo::SelectiveRetransmissions() const {
542   return _retransmissionSettings;
543 }
544
545 int RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) {
546   _retransmissionSettings = settings;
547   return 0;
548 }
549
550 }  // namespace webrtc