Wire up H264 fmtp  sprop-parameter-sets with H264SpsPpsTracker.

To avoid making this CL large unittests will be added in a followup CL.

BUG=webrtc:5948

patch from issue 2570073002 at patchset 20001 (http://crrev.com/2570073002#ps20001)

Review-Url: https://codereview.webrtc.org/2565173009
Cr-Commit-Position: refs/heads/master@{#15710}
diff --git a/webrtc/video/BUILD.gn b/webrtc/video/BUILD.gn
index 6975609..312f3f4 100644
--- a/webrtc/video/BUILD.gn
+++ b/webrtc/video/BUILD.gn
@@ -63,6 +63,7 @@
     "../base:rtc_task_queue",
     "../common_video",
     "../logging:rtc_event_log_api",
+    "../media:rtc_media_base",
     "../modules/bitrate_controller",
     "../modules/congestion_controller",
     "../modules/pacing",
diff --git a/webrtc/video/rtp_stream_receiver.cc b/webrtc/video/rtp_stream_receiver.cc
index 73ca531..d236085 100644
--- a/webrtc/video/rtp_stream_receiver.cc
+++ b/webrtc/video/rtp_stream_receiver.cc
@@ -17,6 +17,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/common_types.h"
 #include "webrtc/config.h"
+#include "webrtc/media/base/mediaconstants.h"
 #include "webrtc/modules/pacing/packet_router.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
@@ -26,6 +27,7 @@
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/include/ulpfec_receiver.h"
 #include "webrtc/modules/video_coding/frame_object.h"
+#include "webrtc/modules/video_coding/h264_sprop_parameter_sets.h"
 #include "webrtc/modules/video_coding/h264_sps_pps_tracker.h"
 #include "webrtc/modules/video_coding/packet_buffer.h"
 #include "webrtc/modules/video_coding/video_coding_impl.h"
@@ -223,13 +225,19 @@
   UpdateHistograms();
 }
 
+bool RtpStreamReceiver::AddReceiveCodec(
+    const VideoCodec& video_codec,
+    const std::map<std::string, std::string>& codec_params) {
+  pt_codec_params_.insert(make_pair(video_codec.plType, codec_params));
+  return AddReceiveCodec(video_codec);
+}
+
 bool RtpStreamReceiver::AddReceiveCodec(const VideoCodec& video_codec) {
   int8_t old_pltype = -1;
   if (rtp_payload_registry_.ReceivePayloadType(video_codec, &old_pltype) !=
       -1) {
     rtp_payload_registry_.DeRegisterReceivePayload(old_pltype);
   }
-
   return rtp_payload_registry_.RegisterReceivePayload(video_codec) == 0;
 }
 
@@ -259,6 +267,14 @@
     packet.timesNacked = nack_module_->OnReceivedPacket(packet);
 
     if (packet.codec == kVideoCodecH264) {
+      // Only when we start to receive packets will we know what payload type
+      // that will be used. When we know the payload type insert the correct
+      // sps/pps into the tracker.
+      if (packet.payloadType != last_payload_type_) {
+        last_payload_type_ = packet.payloadType;
+        InsertSpsPpsIntoTracker(packet.payloadType);
+      }
+
       switch (tracker_.CopyAndFixBitstream(&packet)) {
         case video_coding::H264SpsPpsTracker::kRequestKeyframe:
           keyframe_request_sender_->RequestKeyFrame();
@@ -650,4 +666,25 @@
       StringToRtpExtensionType(extension), id));
 }
 
+void RtpStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) {
+  auto codec_params_it = pt_codec_params_.find(payload_type);
+  if (codec_params_it == pt_codec_params_.end())
+    return;
+
+  LOG(LS_INFO) << "Found out of band supplied codec parameters for"
+               << " payload type: " << payload_type;
+
+  H264SpropParameterSets sprop_decoder;
+  auto sprop_base64_it =
+      codec_params_it->second.find(cricket::kH264FmtpSpropParameterSets);
+
+  if (sprop_base64_it == codec_params_it->second.end())
+    return;
+
+  if (!sprop_decoder.DecodeSprop(sprop_base64_it->second))
+    return;
+
+  tracker_.InsertSpsPps(sprop_decoder.sps_nalu(), sprop_decoder.pps_nalu());
+}
+
 }  // namespace webrtc
diff --git a/webrtc/video/rtp_stream_receiver.h b/webrtc/video/rtp_stream_receiver.h
index 6968cc6..b1e1db4 100644
--- a/webrtc/video/rtp_stream_receiver.h
+++ b/webrtc/video/rtp_stream_receiver.h
@@ -82,6 +82,9 @@
       VCMTiming* timing);
   ~RtpStreamReceiver();
 
+  bool AddReceiveCodec(const VideoCodec& video_codec,
+                       const std::map<std::string, std::string>& codec_params);
+
   bool AddReceiveCodec(const VideoCodec& video_codec);
 
   uint32_t GetRemoteSsrc() const;
@@ -158,6 +161,7 @@
   void UpdateHistograms();
   void EnableReceiveRtpHeaderExtension(const std::string& extension, int id);
   bool IsRedEnabled() const;
+  void InsertSpsPpsIntoTracker(uint8_t payload_type);
 
   Clock* const clock_;
   // Ownership of this object lies with VideoReceiveStream, which owns |this|.
@@ -196,6 +200,11 @@
   std::map<uint16_t, uint16_t, DescendingSeqNumComp<uint16_t>>
       last_seq_num_for_pic_id_ GUARDED_BY(last_seq_num_cs_);
   video_coding::H264SpsPpsTracker tracker_;
+  // TODO(johan): Remove pt_codec_params_ once
+  // https://bugs.chromium.org/p/webrtc/issues/detail?id=6883 is resolved.
+  // Maps a payload type to a map of out-of-band supplied codec parameters.
+  std::map<uint8_t, std::map<std::string, std::string>> pt_codec_params_;
+  int16_t last_payload_type_ = -1;
 };
 
 }  // namespace webrtc
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 0d33658..183f72b 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -315,7 +315,8 @@
   for (const Decoder& decoder : config_.decoders) {
     video_receiver_.RegisterExternalDecoder(decoder.decoder,
                                             decoder.payload_type);
-
+    // TODO(johan): make Decoder.codec_params accessible for RtpStreamReceiver
+    // which holds H264SpsPpsTracker
     VideoCodec codec = CreateDecoderVideoCodec(decoder);
     RTC_CHECK(rtp_stream_receiver_.AddReceiveCodec(codec));
     RTC_CHECK_EQ(VCM_OK, video_receiver_.RegisterReceiveCodec(