Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / rtp_sender_video.cc
index 5d8ae16..da58f61 100644 (file)
@@ -84,18 +84,20 @@ int32_t RTPSenderVideo::RegisterVideoPayload(
     const char payloadName[RTP_PAYLOAD_NAME_SIZE],
     const int8_t payloadType,
     const uint32_t maxBitRate,
-    ModuleRTPUtility::Payload*& payload) {
+    RtpUtility::Payload*& payload) {
   CriticalSectionScoped cs(_sendVideoCritsect);
 
   RtpVideoCodecTypes videoType = kRtpVideoGeneric;
-  if (ModuleRTPUtility::StringCompare(payloadName, "VP8",3)) {
+  if (RtpUtility::StringCompare(payloadName, "VP8", 3)) {
     videoType = kRtpVideoVp8;
-  } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
+  } else if (RtpUtility::StringCompare(payloadName, "H264", 4)) {
+    videoType = kRtpVideoH264;
+  } else if (RtpUtility::StringCompare(payloadName, "I420", 4)) {
     videoType = kRtpVideoGeneric;
   } else {
     videoType = kRtpVideoGeneric;
   }
-  payload = new ModuleRTPUtility::Payload;
+  payload = new RtpUtility::Payload;
   payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
   strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
   payload->typeSpecific.Video.videoCodecType = videoType;
@@ -211,7 +213,7 @@ RTPSenderVideo::SendRTPIntraRequest()
     data[2] = 0;
     data[3] = 1; // length
 
-    ModuleRTPUtility::AssignUWord32ToBuffer(data+4, _rtpSender.SSRC());
+    RtpUtility::AssignUWord32ToBuffer(data + 4, _rtpSender.SSRC());
 
     TRACE_EVENT_INSTANT1("webrtc_rtp",
                          "Video::IntraRequest",
@@ -273,61 +275,63 @@ int32_t RTPSenderVideo::SetFecParameters(
   return 0;
 }
 
-int32_t
-RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
-                          const FrameType frameType,
-                          const int8_t payloadType,
-                          const uint32_t captureTimeStamp,
-                          int64_t capture_time_ms,
-                          const uint8_t* payloadData,
-                          const uint32_t payloadSize,
-                          const RTPFragmentationHeader* fragmentation,
-                          VideoCodecInformation* codecInfo,
-                          const RTPVideoTypeHeader* rtpTypeHdr)
-{
-    if( payloadSize == 0)
-    {
-        return -1;
-    }
+int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType,
+                                  const FrameType frameType,
+                                  const int8_t payloadType,
+                                  const uint32_t captureTimeStamp,
+                                  int64_t capture_time_ms,
+                                  const uint8_t* payloadData,
+                                  const uint32_t payloadSize,
+                                  const RTPFragmentationHeader* fragmentation,
+                                  VideoCodecInformation* codecInfo,
+                                  const RTPVideoTypeHeader* rtpTypeHdr) {
+  if (payloadSize == 0) {
+    return -1;
+  }
 
-    if (frameType == kVideoFrameKey) {
-      producer_fec_.SetFecParameters(&key_fec_params_,
-                                     _numberFirstPartition);
-    } else {
-      producer_fec_.SetFecParameters(&delta_fec_params_,
-                                     _numberFirstPartition);
-    }
+  if (frameType == kVideoFrameKey) {
+    producer_fec_.SetFecParameters(&key_fec_params_, _numberFirstPartition);
+  } else {
+    producer_fec_.SetFecParameters(&delta_fec_params_, _numberFirstPartition);
+  }
 
-    // Default setting for number of first partition packets:
-    // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
-    _numberFirstPartition = 0;
+  // Default setting for number of first partition packets:
+  // Will be extracted in SendVP8 for VP8 codec; other codecs use 0
+  _numberFirstPartition = 0;
 
-    int32_t retVal = -1;
-    switch(videoType)
-    {
+  switch (videoType) {
     case kRtpVideoGeneric:
-        retVal = SendGeneric(frameType, payloadType, captureTimeStamp,
-                             capture_time_ms, payloadData, payloadSize);
-        break;
-    case kRtpVideoVp8:
-        retVal = SendVP8(frameType,
+      return SendGeneric(frameType,
                          payloadType,
                          captureTimeStamp,
                          capture_time_ms,
                          payloadData,
-                         payloadSize,
-                         fragmentation,
-                         rtpTypeHdr);
-        break;
+                         payloadSize);
+    case kRtpVideoVp8:
+      return SendVP8(frameType,
+                     payloadType,
+                     captureTimeStamp,
+                     capture_time_ms,
+                     payloadData,
+                     payloadSize,
+                     fragmentation,
+                     rtpTypeHdr);
+    case kRtpVideoH264:
+      return SendH264(frameType,
+                      payloadType,
+                      captureTimeStamp,
+                      capture_time_ms,
+                      payloadData,
+                      payloadSize,
+                      fragmentation,
+                      rtpTypeHdr)
+                 ? 0
+                 : -1;
     default:
-        assert(false);
-        break;
-    }
-    if(retVal <= 0)
-    {
-        return retVal;
-    }
-    return 0;
+      assert(false);
+      break;
+  }
+  return 0;
 }
 
 int32_t RTPSenderVideo::SendGeneric(const FrameType frame_type,
@@ -425,44 +429,34 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
     assert(rtpTypeHdr);
     // Initialize disregarding partition boundaries: this will use kEqualSize
     // packetization mode, which produces ~equal size packets for each frame.
-    RtpFormatVp8 packetizer(data, payloadBytesToSend, rtpTypeHdr->VP8,
-                            maxPayloadLengthVP8);
+    RtpPacketizerVp8 packetizer(rtpTypeHdr->VP8, maxPayloadLengthVP8);
+    packetizer.SetPayloadData(data, payloadBytesToSend, NULL);
 
     StorageType storage = kAllowRetransmission;
     if (rtpTypeHdr->VP8.temporalIdx == 0 &&
         !(_retransmissionSettings & kRetransmitBaseLayer)) {
       storage = kDontRetransmit;
-    }
-    if (rtpTypeHdr->VP8.temporalIdx > 0 &&
+    } else if (rtpTypeHdr->VP8.temporalIdx != kNoTemporalIdx &&
+        rtpTypeHdr->VP8.temporalIdx > 0 &&
         !(_retransmissionSettings & kRetransmitHigherLayers)) {
       storage = kDontRetransmit;
     }
 
     bool last = false;
     _numberFirstPartition = 0;
-    // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or -1 if the field
-    // isn't used. We currently only protect base layers.
-    bool protect = (rtpTypeHdr->VP8.temporalIdx < 1);
+    // |rtpTypeHdr->VP8.temporalIdx| is zero for base layers, or kNoTemporalIdx
+    // if the field isn't used (so all layers are the base layer).  We currently
+    // only protect base layers, so look for these two cases.
+    bool protect = rtpTypeHdr->VP8.temporalIdx == 0 ||
+        rtpTypeHdr->VP8.temporalIdx == kNoTemporalIdx;
     while (!last)
     {
         // Write VP8 Payload Descriptor and VP8 payload.
         uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
-        int payloadBytesInPacket = 0;
-        int packetStartPartition =
-            packetizer.NextPacket(&dataBuffer[rtpHeaderLength],
-                                  &payloadBytesInPacket, &last);
-        // TODO(holmer): Temporarily disable first partition packet counting
-        // to avoid a bug in ProducerFec which doesn't properly handle
-        // important packets.
-        // if (packetStartPartition == 0)
-        // {
-        //     ++_numberFirstPartition;
-        // }
-        // else
-        if (packetStartPartition < 0)
-        {
-            return -1;
-        }
+        size_t payloadBytesInPacket = 0;
+        if (!packetizer.NextPacket(
+                &dataBuffer[rtpHeaderLength], &payloadBytesInPacket, &last))
+          return -1;
 
         // Write RTP header.
         // Set marker bit true if this is the last packet in frame.
@@ -482,6 +476,55 @@ RTPSenderVideo::SendVP8(const FrameType frameType,
     return 0;
 }
 
+bool RTPSenderVideo::SendH264(const FrameType frameType,
+                              const int8_t payloadType,
+                              const uint32_t captureTimeStamp,
+                              int64_t capture_time_ms,
+                              const uint8_t* payloadData,
+                              const uint32_t payloadSize,
+                              const RTPFragmentationHeader* fragmentation,
+                              const RTPVideoTypeHeader* rtpTypeHdr) {
+  size_t rtp_header_length = _rtpSender.RTPHeaderLength();
+  int32_t payload_bytes_to_send = payloadSize;
+  const uint8_t* data = payloadData;
+  size_t max_payload_length = _rtpSender.MaxDataPayloadLength();
+
+  scoped_ptr<RtpPacketizer> packetizer(
+      RtpPacketizer::Create(kRtpVideoH264, max_payload_length));
+  packetizer->SetPayloadData(data, payload_bytes_to_send, fragmentation);
+
+  StorageType storage = kAllowRetransmission;
+  bool protect = (frameType == kVideoFrameKey);
+  bool last = false;
+
+  while (!last) {
+    // Write H264 payload.
+    uint8_t dataBuffer[IP_PACKET_SIZE] = {0};
+    size_t payload_bytes_in_packet = 0;
+    if (!packetizer->NextPacket(
+            &dataBuffer[rtp_header_length], &payload_bytes_in_packet, &last)) {
+      return false;
+    }
+
+    // Write RTP header.
+    // Set marker bit true if this is the last packet in frame.
+    _rtpSender.BuildRTPheader(
+        dataBuffer, payloadType, last, captureTimeStamp, capture_time_ms);
+    if (SendVideoPacket(dataBuffer,
+                        payload_bytes_in_packet,
+                        rtp_header_length,
+                        captureTimeStamp,
+                        capture_time_ms,
+                        storage,
+                        protect)) {
+      LOG(LS_WARNING)
+          << "RTPSenderVideo::SendH264 failed to send packet number "
+          << _rtpSender.SequenceNumber();
+    }
+  }
+  return true;
+}
+
 void RTPSenderVideo::ProcessBitrate() {
   _videoBitrate.Process();
   _fecOverheadRate.Process();