Bug 985254: modify upstream h264 packetization patch to make it work r=pkerr
authorRandell Jesup <rjesup@jesup.org>
Sat, 24 May 2014 18:28:01 -0400
changeset 184844 d2c1d93b369846c6e8a51d142898eaf14ec474c1
parent 184843 5246ba3954b76a779c44a00695ddccc4913245fc
child 184845 d00df59cb452bc8761196ac61a51ac68c4fc1456
push id43947
push userrjesup@wgate.com
push dateSat, 24 May 2014 22:28:50 +0000
treeherdermozilla-inbound@e6a4624d247f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspkerr
bugs985254
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 985254: modify upstream h264 packetization patch to make it work r=pkerr
media/webrtc/trunk/webrtc/modules/interface/module_common_types.h
media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/packet.cc
media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info.cc
--- a/media/webrtc/trunk/webrtc/modules/interface/module_common_types.h
+++ b/media/webrtc/trunk/webrtc/modules/interface/module_common_types.h
@@ -1059,16 +1059,21 @@ inline bool IsNewerSequenceNumber(uint16
       static_cast<uint16_t>(sequence_number - prev_sequence_number) < 0x8000;
 }
 
 inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
   return timestamp != prev_timestamp &&
       static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
 }
 
+inline bool IsNewerOrSameTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
+  return timestamp == prev_timestamp ||
+      static_cast<uint32_t>(timestamp - prev_timestamp) < 0x80000000;
+}
+
 inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
                                      uint16_t sequence_number2) {
   return IsNewerSequenceNumber(sequence_number1, sequence_number2) ?
       sequence_number1 : sequence_number2;
 }
 
 inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) {
   return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 :
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -266,25 +266,26 @@ int32_t RTPReceiverVideo::ReceiveH264Cod
     h264_header->nalu_header        = original_nal_header;
     h264_header->single_nalu        = false;
   } else {
     // single NALU
     payload = const_cast<uint8_t*> (payload_data);
     payload_length = payload_data_length;
 
     rtp_header->type.Video.codec    = kRtpVideoH264;
-    rtp_header->type.Video.isFirstPacket = true; // First packet
+    rtp_header->type.Video.isFirstPacket = true;
     RTPVideoHeaderH264* h264_header = &rtp_header->type.Video.codecHeader.H264;
     h264_header->nalu_header        = payload_data[0];
     h264_header->single_nalu        = true;
 
     // WebRtcRTPHeader
-    if (nal_type == RtpFormatH264::kH264NALU_IDR) {
-      rtp_header->frameType = kVideoFrameKey;
-      rtp_header->type.Video.isFirstPacket = false;
+    if (nal_type == RtpFormatH264::kH264NALU_SPS ||
+        nal_type == RtpFormatH264::kH264NALU_PPS ||
+        nal_type == RtpFormatH264::kH264NALU_IDR) {
+      rtp_header->frameType = kVideoFrameKey; // not really....
     } else {
       rtp_header->frameType = kVideoFrameDelta;
     }
   }
 
   if (data_callback_->OnReceivedPayloadData(payload,
                                             payload_length,
                                             rtp_header) != 0) {
--- a/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/media/webrtc/trunk/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -523,16 +523,21 @@ int32_t RTPSenderVideo::SendH264(const F
     // 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 (-1 == SendVideoPacket(dataBuffer, payloadBytesInPacket,
                               rtpHeaderLength, captureTimeStamp,
                               capture_time_ms, storage, protect)) {
     }
+
+    if (ret_val == 0) {
+      // single NAL unit
+      last = true;
+    }
   }
   return 0;
 }
 
 void RTPSenderVideo::ProcessBitrate() {
   _videoBitrate.Process();
   _fecOverheadRate.Process();
 }
--- a/media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/main/source/decoding_state.cc
@@ -46,24 +46,24 @@ uint32_t VCMDecodingState::time_stamp() 
 uint16_t VCMDecodingState::sequence_num() const {
   return sequence_num_;
 }
 
 bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const {
   assert(frame != NULL);
   if (in_initial_state_)
     return false;
-  return !IsNewerTimestamp(frame->TimeStamp(), time_stamp_);
+  return !IsNewerOrSameTimestamp(frame->TimeStamp(), time_stamp_);
 }
 
 bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const {
   assert(packet != NULL);
   if (in_initial_state_)
     return false;
-  return !IsNewerTimestamp(packet->timestamp, time_stamp_);
+  return !IsNewerOrSameTimestamp(packet->timestamp, time_stamp_);
 }
 
 void VCMDecodingState::SetState(const VCMFrameBuffer* frame) {
   assert(frame != NULL && frame->GetHighSeqNum() >= 0);
   UpdateSyncState(frame);
   sequence_num_ = static_cast<uint16_t>(frame->GetHighSeqNum());
   time_stamp_ = frame->TimeStamp();
   picture_id_ = frame->PictureId();
--- a/media/webrtc/trunk/webrtc/modules/video_coding/main/source/packet.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/main/source/packet.cc
@@ -107,48 +107,33 @@ void VCMPacket::CopyCodecSpecifics(const
           completeNALU = kNaluIncomplete;
 
       codec = kVideoCodecVP8;
       break;
     }
     case kRtpVideoH264: {
       uint8_t nal_type = videoHeader.codecHeader.H264.nalu_header & RtpFormatH264::kH264NAL_TypeMask;
       if (videoHeader.codecHeader.H264.single_nalu) {
-        if (nal_type == RtpFormatH264::kH264NALU_SPS ||
-            nal_type == RtpFormatH264::kH264NALU_PPS) {
-          insertStartCode = true;
-          isFirstPacket   = false;
-          markerBit       = false;
-        } else {
-          isFirstPacket   = true;
-          markerBit       = true;
-          insertStartCode = true;
-        }
-      } else {
-        // Fragmented NALU
-        if (isFirstPacket) {
-          insertStartCode = true;
-          if (nal_type == RtpFormatH264::kH264NALU_IDR) {
-            // We always assume IDR is pre-leaded with a PPS or SPS/PPS.
-            isFirstPacket = false;
-          }
-        } else {
-          insertStartCode = false;
-        }
+        isFirstPacket   = true;
+        markerBit       = true;
+      }
+      if (isFirstPacket) {
+        insertStartCode = true;
       }
 
       if (isFirstPacket && markerBit)
          completeNALU = kNaluComplete;
       else if (isFirstPacket)
          completeNALU = kNaluStart;
       else if (markerBit)
          completeNALU = kNaluEnd;
       else
          completeNALU = kNaluIncomplete;
       codec = kVideoCodecH264;
+      break;
     }
     default: {
       codec = kVideoCodecUnknown;
       break;
     }
   }
 }
 
--- a/media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info.cc
+++ b/media/webrtc/trunk/webrtc/modules/video_coding/main/source/session_info.cc
@@ -418,25 +418,18 @@ int VCMSessionInfo::InsertPacket(const V
   if (rit != packets_.rend() &&
       (*rit).seqNum == packet.seqNum && (*rit).sizeBytes > 0)
     return -2;
 
   PacketIterator packet_list_it;
   if (packet.codec == kVideoCodecH264) {
     RTPVideoHeaderH264 h264 = packet.codecSpecificHeader.codecHeader.H264;
     uint8_t nal_type = h264.nalu_header & RtpFormatH264::kH264NAL_TypeMask;
-    bool potential_start = false;
-    if (nal_type == RtpFormatH264::kH264NALU_SPS ||
-        nal_type == RtpFormatH264::kH264NALU_PPS ||
-        packet.codecSpecificHeader.codecHeader.H264.single_nalu) {
-      potential_start = true;
-    } else {
-      potential_start = packet.isFirstPacket;
-    }
-    if (potential_start) {
+
+    if (packet.isFirstPacket) {
       if (HaveFirstPacket() == false ||
           IsNewerSequenceNumber(first_packet_seq_num_, packet.seqNum)) {
         first_packet_seq_num_ = packet.seqNum;
         frame_type_ = packet.frameType;
       }
     }
 
     // Track the marker bit, should only be set for one packet per session.