Making FakeNetworkPipe demux audio and video packets.

BUG=None

Review-Url: https://codereview.webrtc.org/2794243002
Cr-Commit-Position: refs/heads/master@{#17629}
diff --git a/webrtc/audio/test/low_bandwidth_audio_test.cc b/webrtc/audio/test/low_bandwidth_audio_test.cc
index de955f7..65f28fa 100644
--- a/webrtc/audio/test/low_bandwidth_audio_test.cc
+++ b/webrtc/audio/test/low_bandwidth_audio_test.cc
@@ -20,12 +20,9 @@
 // Wait half a second between stopping sending and stopping receiving audio.
 constexpr int kExtraRecordTimeMs = 500;
 
-// Large bitrate by default.
-const webrtc::CodecInst kDefaultCodec{120, "OPUS", 48000, 960, 2, 64000};
-
 // The best that can be done with PESQ.
 constexpr int kAudioFileBitRate = 16000;
-}
+}  // namespace
 
 namespace webrtc {
 namespace test {
@@ -79,20 +76,20 @@
     Call* sender_call) {
   return new test::PacketTransport(
       sender_call, this, test::PacketTransport::kSender,
-      MediaType::AUDIO,
-      GetNetworkPipeConfig());
+      test::CallTest::payload_type_map_, GetNetworkPipeConfig());
 }
 
 test::PacketTransport* AudioQualityTest::CreateReceiveTransport() {
-  return new test::PacketTransport(nullptr, this,
-      test::PacketTransport::kReceiver, MediaType::AUDIO,
-      GetNetworkPipeConfig());
+  return new test::PacketTransport(
+      nullptr, this, test::PacketTransport::kReceiver,
+      test::CallTest::payload_type_map_, GetNetworkPipeConfig());
 }
 
 void AudioQualityTest::ModifyAudioConfigs(
   AudioSendStream::Config* send_config,
   std::vector<AudioReceiveStream::Config>* receive_configs) {
-  send_config->send_codec_spec.codec_inst = kDefaultCodec;
+  send_config->send_codec_spec.codec_inst = webrtc::CodecInst{
+      test::CallTest::kAudioSendPayloadType, "OPUS", 48000, 960, 2, 64000};
 }
 
 void AudioQualityTest::PerformTest() {
@@ -125,12 +122,12 @@
   void ModifyAudioConfigs(AudioSendStream::Config* send_config,
       std::vector<AudioReceiveStream::Config>* receive_configs) override {
     send_config->send_codec_spec.codec_inst = CodecInst{
-        120,     // pltype
-        "OPUS",  // plname
-        48000,   // plfreq
-        2880,    // pacsize
-        1,       // channels
-        6000     // rate bits/sec
+        test::CallTest::kAudioSendPayloadType,  // pltype
+        "OPUS",                                 // plname
+        48000,                                  // plfreq
+        2880,                                   // pacsize
+        1,                                      // channels
+        6000                                    // rate bits/sec
     };
   }
 
diff --git a/webrtc/call/bitrate_estimator_tests.cc b/webrtc/call/bitrate_estimator_tests.cc
index c596ac2..ef7aba8 100644
--- a/webrtc/call/bitrate_estimator_tests.cc
+++ b/webrtc/call/bitrate_estimator_tests.cc
@@ -107,10 +107,10 @@
     sender_call_.reset(Call::Create(config));
 
     send_transport_.reset(
-        new test::DirectTransport(sender_call_.get(), MediaType::VIDEO));
+        new test::DirectTransport(sender_call_.get(), payload_type_map_));
     send_transport_->SetReceiver(receiver_call_->Receiver());
     receive_transport_.reset(
-        new test::DirectTransport(receiver_call_.get(), MediaType::VIDEO));
+        new test::DirectTransport(receiver_call_.get(), payload_type_map_));
     receive_transport_->SetReceiver(sender_call_->Receiver());
 
     video_send_config_ = VideoSendStream::Config(send_transport_.get());
diff --git a/webrtc/call/call_perf_tests.cc b/webrtc/call/call_perf_tests.cc
index bfb11d0..7ade528 100644
--- a/webrtc/call/call_perf_tests.cc
+++ b/webrtc/call/call_perf_tests.cc
@@ -191,26 +191,37 @@
   FakeNetworkPipe::Config audio_net_config;
   audio_net_config.queue_delay_ms = 500;
   audio_net_config.loss_percent = 5;
+
+  std::map<uint8_t, MediaType> audio_pt_map;
+  std::map<uint8_t, MediaType> video_pt_map;
+  std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
+               std::inserter(audio_pt_map, audio_pt_map.end()),
+               [](const std::pair<const uint8_t, MediaType>& pair) {
+                 return pair.second == MediaType::AUDIO;
+               });
+  std::copy_if(std::begin(payload_type_map_), std::end(payload_type_map_),
+               std::inserter(video_pt_map, video_pt_map.end()),
+               [](const std::pair<const uint8_t, MediaType>& pair) {
+                 return pair.second == MediaType::VIDEO;
+               });
+
   test::PacketTransport audio_send_transport(sender_call_.get(), &observer,
                                              test::PacketTransport::kSender,
-                                             MediaType::AUDIO,
-                                             audio_net_config);
+                                             audio_pt_map, audio_net_config);
   MediaTypePacketReceiver audio_receiver(receiver_call_->Receiver(),
                                          MediaType::AUDIO);
   audio_send_transport.SetReceiver(&audio_receiver);
 
-  test::PacketTransport video_send_transport(sender_call_.get(), &observer,
-                                             test::PacketTransport::kSender,
-                                             MediaType::VIDEO,
-                                             FakeNetworkPipe::Config());
+  test::PacketTransport video_send_transport(
+      sender_call_.get(), &observer, test::PacketTransport::kSender,
+      video_pt_map, FakeNetworkPipe::Config());
   MediaTypePacketReceiver video_receiver(receiver_call_->Receiver(),
                                          MediaType::VIDEO);
   video_send_transport.SetReceiver(&video_receiver);
 
   test::PacketTransport receive_transport(
       receiver_call_.get(), &observer, test::PacketTransport::kReceiver,
-      MediaType::VIDEO,
-      FakeNetworkPipe::Config());
+      payload_type_map_, FakeNetworkPipe::Config());
   receive_transport.SetReceiver(sender_call_->Receiver());
 
   test::FakeDecoder fake_decoder;
@@ -222,7 +233,7 @@
   audio_send_config.voe_channel_id = send_channel_id;
   audio_send_config.rtp.ssrc = kAudioSendSsrc;
   audio_send_config.send_codec_spec.codec_inst =
-      CodecInst{103, "ISAC", 16000, 480, 1, 32000};
+      CodecInst{kAudioSendPayloadType, "ISAC", 16000, 480, 1, 32000};
   AudioSendStream* audio_send_stream =
       sender_call_->CreateAudioSendStream(audio_send_config);
 
@@ -244,7 +255,7 @@
   audio_recv_config.voe_channel_id = recv_channel_id;
   audio_recv_config.sync_group = kSyncGroup;
   audio_recv_config.decoder_factory = decoder_factory_;
-  audio_recv_config.decoder_map = {{103, {"ISAC", 16000, 1}}};
+  audio_recv_config.decoder_map = {{kAudioSendPayloadType, {"ISAC", 16000, 1}}};
 
   AudioReceiveStream* audio_receive_stream;
 
@@ -345,15 +356,15 @@
 
    private:
     test::PacketTransport* CreateSendTransport(Call* sender_call) override {
-      return new test::PacketTransport(
-          sender_call, this, test::PacketTransport::kSender, MediaType::VIDEO,
-          net_config_);
+      return new test::PacketTransport(sender_call, this,
+                                       test::PacketTransport::kSender,
+                                       payload_type_map_, net_config_);
     }
 
     test::PacketTransport* CreateReceiveTransport() override {
-      return new test::PacketTransport(
-          nullptr, this, test::PacketTransport::kReceiver, MediaType::VIDEO,
-          net_config_);
+      return new test::PacketTransport(nullptr, this,
+                                       test::PacketTransport::kReceiver,
+                                       payload_type_map_, net_config_);
     }
 
     void OnFrame(const VideoFrame& video_frame) override {
diff --git a/webrtc/call/rampup_tests.cc b/webrtc/call/rampup_tests.cc
index b75418d..f51ab31 100644
--- a/webrtc/call/rampup_tests.cc
+++ b/webrtc/call/rampup_tests.cc
@@ -90,10 +90,9 @@
 }
 
 test::PacketTransport* RampUpTester::CreateSendTransport(Call* sender_call) {
-  send_transport_ = new test::PacketTransport(sender_call, this,
-                                              test::PacketTransport::kSender,
-                                              SelectMediaType(),
-                                              forward_transport_config_);
+  send_transport_ = new test::PacketTransport(
+      sender_call, this, test::PacketTransport::kSender,
+      test::CallTest::payload_type_map_, forward_transport_config_);
   return send_transport_;
 }
 
diff --git a/webrtc/test/call_test.cc b/webrtc/test/call_test.cc
index 5c60895..5c0b42c 100644
--- a/webrtc/test/call_test.cc
+++ b/webrtc/test/call_test.cc
@@ -26,29 +26,6 @@
 const int kVideoRotationRtpExtensionId = 4;
 }
 
-void CallTest::PayloadDemuxer::SetReceiver(PacketReceiver* receiver) {
-  receiver_ = receiver;
-}
-
-PacketReceiver::DeliveryStatus CallTest::PayloadDemuxer::DeliverPacket(
-    MediaType media_type,
-    const uint8_t* packet,
-    size_t length,
-    const PacketTime& packet_time) {
-  if (media_type == MediaType::ANY) {
-    // This simplistic demux logic will not make much sense for RTCP
-    // packets, but it seems that doesn't matter.
-    RTC_CHECK_GE(length, 2);
-    uint8_t pt = packet[1] & 0x7f;
-    if (pt == kFakeVideoSendPayloadType || pt == kFlexfecPayloadType) {
-      media_type = MediaType::VIDEO;
-    } else {
-      media_type = MediaType::AUDIO;
-    }
-  }
-  return receiver_->DeliverPacket(media_type, packet, length, packet_time);
-}
-
 CallTest::CallTest()
     : clock_(Clock::GetRealTimeClock()),
       event_log_(RtcEventLog::CreateNull()),
@@ -99,20 +76,8 @@
   send_transport_.reset(test->CreateSendTransport(sender_call_.get()));
 
   if (test->ShouldCreateReceivers()) {
-    // For tests using only video or only audio, we rely on each test
-    // configuring the underlying FakeNetworkPipe with the right media
-    // type. But for tests sending both video and audio over the same
-    // FakeNetworkPipe, we need to "demux", i.e., setting the
-    // MediaType based on RTP payload type.
-    if (num_video_streams_ > 0 && num_audio_streams_ > 0) {
-      receive_demuxer_.SetReceiver(receiver_call_->Receiver());
-      send_transport_->SetReceiver(&receive_demuxer_);
-      send_demuxer_.SetReceiver(sender_call_->Receiver());
-      receive_transport_->SetReceiver(&send_demuxer_);
-    } else {
-      send_transport_->SetReceiver(receiver_call_->Receiver());
-      receive_transport_->SetReceiver(sender_call_->Receiver());
-    }
+    send_transport_->SetReceiver(receiver_call_->Receiver());
+    receive_transport_->SetReceiver(sender_call_->Receiver());
     if (num_video_streams_ > 0)
       receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
     if (num_audio_streams_ > 0)
@@ -300,7 +265,7 @@
     audio_config.voe_channel_id = voe_recv_.channel_id;
     audio_config.rtp.remote_ssrc = audio_send_config_.rtp.ssrc;
     audio_config.decoder_factory = decoder_factory_;
-    audio_config.decoder_map = {{120, {"opus", 48000, 2}}};
+    audio_config.decoder_map = {{kAudioSendPayloadType, {"opus", 48000, 2}}};
     audio_receive_configs_.push_back(audio_config);
   }
 
@@ -462,6 +427,16 @@
 const uint32_t CallTest::kReceiverLocalAudioSsrc = 0x1234567;
 const int CallTest::kNackRtpHistoryMs = 1000;
 
+const std::map<uint8_t, MediaType> CallTest::payload_type_map_ = {
+    {CallTest::kVideoSendPayloadType, MediaType::VIDEO},
+    {CallTest::kFakeVideoSendPayloadType, MediaType::VIDEO},
+    {CallTest::kSendRtxPayloadType, MediaType::VIDEO},
+    {CallTest::kRedPayloadType, MediaType::VIDEO},
+    {CallTest::kRtxRedPayloadType, MediaType::VIDEO},
+    {CallTest::kUlpfecPayloadType, MediaType::VIDEO},
+    {CallTest::kFlexfecPayloadType, MediaType::VIDEO},
+    {CallTest::kAudioSendPayloadType, MediaType::AUDIO}};
+
 BaseTest::BaseTest() : event_log_(RtcEventLog::CreateNull()) {}
 
 BaseTest::BaseTest(unsigned int timeout_ms)
@@ -493,28 +468,15 @@
 void BaseTest::OnCallsCreated(Call* sender_call, Call* receiver_call) {
 }
 
-MediaType BaseTest::SelectMediaType() {
-  if (GetNumVideoStreams() > 0) {
-    if (GetNumAudioStreams() > 0) {
-      // Relies on PayloadDemuxer to set media type from payload type.
-      return MediaType::ANY;
-    } else {
-      return MediaType::VIDEO;
-    }
-  } else {
-    return MediaType::AUDIO;
-  }
-}
-
 test::PacketTransport* BaseTest::CreateSendTransport(Call* sender_call) {
   return new PacketTransport(sender_call, this, test::PacketTransport::kSender,
-                             SelectMediaType(),
+                             CallTest::payload_type_map_,
                              FakeNetworkPipe::Config());
 }
 
 test::PacketTransport* BaseTest::CreateReceiveTransport() {
   return new PacketTransport(nullptr, this, test::PacketTransport::kReceiver,
-                             SelectMediaType(),
+                             CallTest::payload_type_map_,
                              FakeNetworkPipe::Config());
 }
 
diff --git a/webrtc/test/call_test.h b/webrtc/test/call_test.h
index c9d7f32..b9523f5 100644
--- a/webrtc/test/call_test.h
+++ b/webrtc/test/call_test.h
@@ -57,25 +57,9 @@
   static const uint32_t kReceiverLocalVideoSsrc;
   static const uint32_t kReceiverLocalAudioSsrc;
   static const int kNackRtpHistoryMs;
+  static const std::map<uint8_t, MediaType> payload_type_map_;
 
  protected:
-  // Needed for tests sending both audio and video on the same
-  // FakeNetworkPipe. We then need to set correct MediaType based on
-  // packet payload type, before passing the packet on to Call.
-  class PayloadDemuxer : public PacketReceiver {
-   public:
-    PayloadDemuxer() = default;
-
-    void SetReceiver(PacketReceiver* receiver);
-    DeliveryStatus DeliverPacket(MediaType media_type,
-                                 const uint8_t* packet,
-                                 size_t length,
-                                 const PacketTime& packet_time) override;
-
-   private:
-    PacketReceiver* receiver_ = nullptr;
-  };
-
   // RunBaseTest overwrites the audio_state and the voice_engine of the send and
   // receive Call configs to simplify test code and avoid having old VoiceEngine
   // APIs in the tests.
@@ -141,9 +125,6 @@
   rtc::scoped_refptr<AudioDecoderFactory> decoder_factory_;
   test::FakeVideoRenderer fake_renderer_;
 
-  PayloadDemuxer receive_demuxer_;
-  PayloadDemuxer send_demuxer_;
-
  private:
   // TODO(holmer): Remove once VoiceEngine is fully refactored to the new API.
   // These methods are used to set up legacy voice engines and channels which is
@@ -192,10 +173,6 @@
   virtual Call::Config GetReceiverCallConfig();
   virtual void OnCallsCreated(Call* sender_call, Call* receiver_call);
 
-  // Returns VIDEO for video-only tests, AUDIO for audio-only tests,
-  // and ANY for tests sending audio and video over the same
-  // transport.
-  virtual MediaType SelectMediaType();
   virtual test::PacketTransport* CreateSendTransport(Call* sender_call);
   virtual test::PacketTransport* CreateReceiveTransport();
 
diff --git a/webrtc/test/direct_transport.cc b/webrtc/test/direct_transport.cc
index 90531ea..370425c 100644
--- a/webrtc/test/direct_transport.cc
+++ b/webrtc/test/direct_transport.cc
@@ -15,17 +15,29 @@
 namespace webrtc {
 namespace test {
 
-DirectTransport::DirectTransport(Call* send_call, MediaType media_type)
-    : DirectTransport(FakeNetworkPipe::Config(), send_call, media_type) {}
+DirectTransport::DirectTransport(
+    Call* send_call,
+    const std::map<uint8_t, MediaType>& payload_type_map)
+    : DirectTransport(FakeNetworkPipe::Config(), send_call, payload_type_map) {}
+
+DirectTransport::DirectTransport(
+    const FakeNetworkPipe::Config& config,
+    Call* send_call,
+    const std::map<uint8_t, MediaType>& payload_type_map)
+    : DirectTransport(
+          config,
+          send_call,
+          std::unique_ptr<Demuxer>(new DemuxerImpl(payload_type_map))) {}
 
 DirectTransport::DirectTransport(const FakeNetworkPipe::Config& config,
-                                 Call* send_call, MediaType media_type)
+                                 Call* send_call,
+                                 std::unique_ptr<Demuxer> demuxer)
     : send_call_(send_call),
       packet_event_(false, false),
       thread_(NetworkProcess, this, "NetworkProcess"),
       clock_(Clock::GetRealTimeClock()),
       shutting_down_(false),
-      fake_network_(clock_, config, media_type) {
+      fake_network_(clock_, config, std::move(demuxer)) {
   thread_.Start();
   if (send_call_) {
     send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
@@ -76,6 +88,22 @@
   return fake_network_.AverageDelay();
 }
 
+DirectTransport::ForceDemuxer::ForceDemuxer(MediaType media_type)
+    : media_type_(media_type) {}
+
+void DirectTransport::ForceDemuxer::SetReceiver(PacketReceiver* receiver) {
+  packet_receiver_ = receiver;
+}
+
+void DirectTransport::ForceDemuxer::DeliverPacket(
+    const NetworkPacket* packet,
+    const PacketTime& packet_time) {
+  if (!packet_receiver_)
+    return;
+  packet_receiver_->DeliverPacket(media_type_, packet->data(),
+                                  packet->data_length(), packet_time);
+}
+
 bool DirectTransport::NetworkProcess(void* transport) {
   return static_cast<DirectTransport*>(transport)->SendPackets();
 }
diff --git a/webrtc/test/direct_transport.h b/webrtc/test/direct_transport.h
index 20a6857..a865c83 100644
--- a/webrtc/test/direct_transport.h
+++ b/webrtc/test/direct_transport.h
@@ -30,16 +30,42 @@
 
 class DirectTransport : public Transport {
  public:
-  DirectTransport(Call* send_call, MediaType media_type);
-  DirectTransport(const FakeNetworkPipe::Config& config, Call* send_call,
-                  MediaType media_type);
+  DirectTransport(Call* send_call,
+                  const std::map<uint8_t, MediaType>& payload_type_map);
+  DirectTransport(const FakeNetworkPipe::Config& config,
+                  Call* send_call,
+                  const std::map<uint8_t, MediaType>& payload_type_map);
+  DirectTransport(const FakeNetworkPipe::Config& config,
+                  Call* send_call,
+                  std::unique_ptr<Demuxer> demuxer);
+
+  // These deprecated variants always use ForceDemuxer.
+  RTC_DEPRECATED DirectTransport(Call* send_call, MediaType media_type)
+      : DirectTransport(
+            FakeNetworkPipe::Config(),
+            send_call,
+            std::unique_ptr<Demuxer>(new ForceDemuxer(media_type))) {}
+  RTC_DEPRECATED DirectTransport(const FakeNetworkPipe::Config& config,
+                                 Call* send_call,
+                                 MediaType media_type)
+      : DirectTransport(
+            config,
+            send_call,
+            std::unique_ptr<Demuxer>(new ForceDemuxer(media_type))) {}
+
   // These deprecated variants always use MediaType::VIDEO.
   RTC_DEPRECATED explicit DirectTransport(Call* send_call)
-      : DirectTransport(send_call, MediaType::VIDEO) {}
+      : DirectTransport(
+            FakeNetworkPipe::Config(),
+            send_call,
+            std::unique_ptr<Demuxer>(new ForceDemuxer(MediaType::VIDEO))) {}
 
   RTC_DEPRECATED DirectTransport(const FakeNetworkPipe::Config& config,
                                  Call* send_call)
-      : DirectTransport(config, send_call, MediaType::VIDEO) {}
+      : DirectTransport(
+            config,
+            send_call,
+            std::unique_ptr<Demuxer>(new ForceDemuxer(MediaType::VIDEO))) {}
 
   ~DirectTransport();
 
@@ -57,6 +83,21 @@
   int GetAverageDelayMs();
 
  private:
+  // TODO(minyue): remove when the deprecated ctors of DirectTransport that
+  // create ForceDemuxer are removed.
+  class ForceDemuxer : public Demuxer {
+   public:
+    explicit ForceDemuxer(MediaType media_type);
+    void SetReceiver(PacketReceiver* receiver) override;
+    void DeliverPacket(const NetworkPacket* packet,
+                       const PacketTime& packet_time) override;
+
+   private:
+    const MediaType media_type_;
+    PacketReceiver* packet_receiver_;
+    RTC_DISALLOW_COPY_AND_ASSIGN(ForceDemuxer);
+  };
+
   static bool NetworkProcess(void* transport);
   bool SendPackets();
 
diff --git a/webrtc/test/fake_network_pipe.cc b/webrtc/test/fake_network_pipe.cc
index 1034167..a614cc3 100644
--- a/webrtc/test/fake_network_pipe.cc
+++ b/webrtc/test/fake_network_pipe.cc
@@ -19,6 +19,7 @@
 
 #include "webrtc/base/logging.h"
 #include "webrtc/call/call.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
 #include "webrtc/system_wrappers/include/clock.h"
 
 namespace webrtc {
@@ -27,18 +28,46 @@
 constexpr int64_t kDefaultProcessIntervalMs = 5;
 }
 
-FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
-                                 const FakeNetworkPipe::Config& config,
-                                 MediaType media_type)
-    : FakeNetworkPipe(clock, config, media_type, 1) {}
+DemuxerImpl::DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map)
+    : packet_receiver_(nullptr), payload_type_map_(payload_type_map) {}
+
+void DemuxerImpl::SetReceiver(PacketReceiver* receiver) {
+  packet_receiver_ = receiver;
+}
+
+void DemuxerImpl::DeliverPacket(const NetworkPacket* packet,
+                                const PacketTime& packet_time) {
+  // No packet receiver means that this demuxer will terminate the flow of
+  // packets.
+  if (!packet_receiver_)
+    return;
+  const uint8_t* const packet_data = packet->data();
+  const size_t packet_length = packet->data_length();
+  MediaType media_type = MediaType::ANY;
+  if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) {
+    RTC_CHECK_GE(packet_length, 2);
+    const uint8_t payload_type = packet_data[1] & 0x7f;
+    std::map<uint8_t, MediaType>::const_iterator it =
+        payload_type_map_.find(payload_type);
+    RTC_CHECK(it != payload_type_map_.end())
+        << "payload type " << static_cast<int>(payload_type) << " unknown.";
+    media_type = it->second;
+  }
+  packet_receiver_->DeliverPacket(media_type, packet_data, packet_length,
+                                  packet_time);
+}
 
 FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
                                  const FakeNetworkPipe::Config& config,
-                                 MediaType media_type,
+                                 std::unique_ptr<Demuxer> demuxer)
+    : FakeNetworkPipe(clock, config, std::move(demuxer), 1) {}
+
+FakeNetworkPipe::FakeNetworkPipe(Clock* clock,
+                                 const FakeNetworkPipe::Config& config,
+                                 std::unique_ptr<Demuxer> demuxer,
                                  uint64_t seed)
     : clock_(clock),
-      media_type_(media_type),
-      packet_receiver_(NULL),
+      demuxer_(std::move(demuxer)),
       random_(seed),
       config_(),
       dropped_packets_(0),
@@ -62,7 +91,8 @@
 }
 
 void FakeNetworkPipe::SetReceiver(PacketReceiver* receiver) {
-  packet_receiver_ = receiver;
+  RTC_CHECK(demuxer_);
+  demuxer_->SetReceiver(receiver);
 }
 
 void FakeNetworkPipe::SetConfig(const FakeNetworkPipe::Config& config) {
@@ -89,10 +119,7 @@
 }
 
 void FakeNetworkPipe::SendPacket(const uint8_t* data, size_t data_length) {
-  // A NULL packet_receiver_ means that this pipe will terminate the flow of
-  // packets.
-  if (packet_receiver_ == NULL)
-    return;
+  RTC_CHECK(demuxer_);
   rtc::CritScope crit(&lock_);
   if (config_.queue_length_packets > 0 &&
       capacity_link_.size() >= config_.queue_length_packets) {
@@ -202,8 +229,7 @@
   while (!packets_to_deliver.empty()) {
     NetworkPacket* packet = packets_to_deliver.front();
     packets_to_deliver.pop();
-    packet_receiver_->DeliverPacket(media_type_, packet->data(),
-                                    packet->data_length(), PacketTime());
+    demuxer_->DeliverPacket(packet, PacketTime());
     delete packet;
   }
 
diff --git a/webrtc/test/fake_network_pipe.h b/webrtc/test/fake_network_pipe.h
index adf76c3..f3cd11d 100644
--- a/webrtc/test/fake_network_pipe.h
+++ b/webrtc/test/fake_network_pipe.h
@@ -11,14 +11,16 @@
 #ifndef WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
 #define WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
 
-#include <memory>
-#include <set>
 #include <string.h>
+#include <map>
+#include <memory>
 #include <queue>
+#include <set>
 
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/random.h"
+#include "webrtc/common_types.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
@@ -59,6 +61,28 @@
   int64_t arrival_time_;
 };
 
+class Demuxer {
+ public:
+  virtual ~Demuxer() = default;
+  virtual void SetReceiver(PacketReceiver* receiver) = 0;
+  virtual void DeliverPacket(const NetworkPacket* packet,
+                             const PacketTime& packet_time) = 0;
+};
+
+class DemuxerImpl final : public Demuxer {
+ public:
+  explicit DemuxerImpl(const std::map<uint8_t, MediaType>& payload_type_map);
+
+  void SetReceiver(PacketReceiver* receiver) override;
+  void DeliverPacket(const NetworkPacket* packet,
+                     const PacketTime& packet_time) override;
+
+ private:
+  PacketReceiver* packet_receiver_;
+  const std::map<uint8_t, MediaType> payload_type_map_;
+  RTC_DISALLOW_COPY_AND_ASSIGN(DemuxerImpl);
+};
+
 // Class faking a network link. This is a simple and naive solution just faking
 // capacity and adding an extra transport delay in addition to the capacity
 // introduced delay.
@@ -83,15 +107,15 @@
     int avg_burst_loss_length = -1;
   };
 
-  FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config,
-                  MediaType media_type);
   FakeNetworkPipe(Clock* clock,
-                  const FakeNetworkPipe::Config& config, MediaType media_type,
+                  const FakeNetworkPipe::Config& config,
+                  std::unique_ptr<Demuxer> demuxer);
+  FakeNetworkPipe(Clock* clock,
+                  const FakeNetworkPipe::Config& config,
+                  std::unique_ptr<Demuxer> demuxer,
                   uint64_t seed);
   ~FakeNetworkPipe();
 
-  // Must not be called in parallel with SendPacket or Process.
-  void SetReceiver(PacketReceiver* receiver);
 
   // Sets a new configuration. This won't affect packets already in the pipe.
   void SetConfig(const FakeNetworkPipe::Config& config);
@@ -99,6 +123,9 @@
   // Sends a new packet to the link.
   void SendPacket(const uint8_t* packet, size_t packet_length);
 
+  // Must not be called in parallel with SendPacket or Process.
+  void SetReceiver(PacketReceiver* receiver);
+
   // Processes the network queues and trigger PacketReceiver::IncomingPacket for
   // packets ready to be delivered.
   void Process();
@@ -112,9 +139,8 @@
 
  private:
   Clock* const clock_;
-  const MediaType media_type_;
   rtc::CriticalSection lock_;
-  PacketReceiver* packet_receiver_;
+  const std::unique_ptr<Demuxer> demuxer_;
   std::queue<NetworkPacket*> capacity_link_;
   Random random_;
 
diff --git a/webrtc/test/fake_network_pipe_unittest.cc b/webrtc/test/fake_network_pipe_unittest.cc
index c19b001..92619e1 100644
--- a/webrtc/test/fake_network_pipe_unittest.cc
+++ b/webrtc/test/fake_network_pipe_unittest.cc
@@ -11,6 +11,7 @@
 #include <memory>
 
 #include "webrtc/call/call.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
 #include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/test/fake_network_pipe.h"
 #include "webrtc/test/gmock.h"
@@ -23,52 +24,42 @@
 
 namespace webrtc {
 
-class TestReceiver : public PacketReceiver {
+class TestDemuxer : public Demuxer {
  public:
-  TestReceiver() {}
-  virtual ~TestReceiver() {}
-
-  void IncomingPacket(const uint8_t* data, size_t length) {
-    DeliverPacket(MediaType::ANY, data, length, PacketTime());
-    delete [] data;
+  void IncomingPacket(NetworkPacket* packet) {
+    DeliverPacket(packet, PacketTime());
   }
 
-  virtual MOCK_METHOD4(
-      DeliverPacket,
-      DeliveryStatus(MediaType, const uint8_t*, size_t, const PacketTime&));
+  MOCK_METHOD1(SetReceiver, void(PacketReceiver* receiver));
+  MOCK_METHOD2(DeliverPacket,
+               void(const NetworkPacket* packet,
+                    const PacketTime& packet_time));
 };
 
-class ReorderTestReceiver : public TestReceiver {
+class ReorderTestDemuxer : public TestDemuxer {
  public:
-  ReorderTestReceiver() {}
-  virtual ~ReorderTestReceiver() {}
-
-  DeliveryStatus DeliverPacket(MediaType media_type,
-                               const uint8_t* packet,
-                               size_t length,
-                               const PacketTime& packet_time) override {
+  void DeliverPacket(const NetworkPacket* packet,
+                     const PacketTime& packet_time) override {
+    RTC_DCHECK_GE(packet->data_length(), sizeof(int));
     int seq_num;
-    memcpy(&seq_num, packet, sizeof(int));
+    memcpy(&seq_num, packet->data(), sizeof(int));
     delivered_sequence_numbers_.push_back(seq_num);
-    return PacketReceiver::DELIVERY_OK;
   }
   std::vector<int> delivered_sequence_numbers_;
 };
 
+class MockReceiver : public PacketReceiver {
+ public:
+  MOCK_METHOD4(
+      DeliverPacket,
+      DeliveryStatus(MediaType, const uint8_t*, size_t, const PacketTime&));
+};
+
 class FakeNetworkPipeTest : public ::testing::Test {
  public:
   FakeNetworkPipeTest() : fake_clock_(12345) {}
 
  protected:
-  virtual void SetUp() {
-    receiver_.reset(new TestReceiver());
-    ON_CALL(*receiver_, DeliverPacket(_, _, _, _))
-        .WillByDefault(Return(PacketReceiver::DELIVERY_OK));
-  }
-
-  virtual void TearDown() {
-  }
-
   void SendPackets(FakeNetworkPipe* pipe, int number_packets, int packet_size) {
     RTC_DCHECK_GE(packet_size, sizeof(int));
     std::unique_ptr<uint8_t[]> packet(new uint8_t[packet_size]);
@@ -85,47 +76,44 @@
   }
 
   SimulatedClock fake_clock_;
-  std::unique_ptr<TestReceiver> receiver_;
 };
 
-void DeleteMemory(uint8_t* data, int length) { delete [] data; }
-
 // Test the capacity link and verify we get as many packets as we expect.
 TEST_F(FakeNetworkPipeTest, CapacityTest) {
   FakeNetworkPipe::Config config;
   config.queue_length_packets = 20;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
   // get through the pipe.
   const int kNumPackets = 10;
   const int kPacketSize = 1000;
-  SendPackets(pipe.get(), kNumPackets , kPacketSize);
+  SendPackets(pipe.get(), kNumPackets, kPacketSize);
 
   // Time to get one packet through the link.
   const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
                                          kPacketSize);
 
   // Time haven't increased yet, so we souldn't get any packets.
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 
   // Advance enough time to release one packet.
   fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
   pipe->Process();
 
   // Release all but one packet
   fake_clock_.AdvanceTimeMilliseconds(9 * kPacketTimeMs - 1);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(8);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(8);
   pipe->Process();
 
   // And the last one.
   fake_clock_.AdvanceTimeMilliseconds(1);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
   pipe->Process();
 }
 
@@ -135,13 +123,13 @@
   config.queue_length_packets = 20;
   config.queue_delay_ms = 100;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::AUDIO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   const int kNumPackets = 2;
   const int kPacketSize = 1000;
-  SendPackets(pipe.get(), kNumPackets , kPacketSize);
+  SendPackets(pipe.get(), kNumPackets, kPacketSize);
 
   // Time to get one packet through the link.
   const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@@ -149,17 +137,17 @@
 
   // Increase more than kPacketTimeMs, but not more than the extra delay.
   fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 
   // Advance the network delay to get the first packet.
   fake_clock_.AdvanceTimeMilliseconds(config.queue_delay_ms);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
   pipe->Process();
 
   // Advance one more kPacketTimeMs to get the last packet.
   fake_clock_.AdvanceTimeMilliseconds(kPacketTimeMs);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
   pipe->Process();
 }
 
@@ -169,9 +157,9 @@
   FakeNetworkPipe::Config config;
   config.queue_length_packets = 2;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   const int kPacketSize = 1000;
   const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@@ -183,7 +171,7 @@
   // Increase time enough to deliver all three packets, verify only two are
   // delivered.
   fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs);
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(2);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2);
   pipe->Process();
 }
 
@@ -193,9 +181,9 @@
   config.queue_length_packets = 2;
   config.queue_delay_ms = 20;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   const int kPacketSize = 1000;
   const int kPacketTimeMs = PacketTimeMs(config.link_capacity_kbps,
@@ -206,7 +194,7 @@
   fake_clock_.AdvanceTimeMilliseconds(3 * kPacketTimeMs +
                                       config.queue_delay_ms);
 
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(2);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(2);
   pipe->Process();
 
   // Packet 1: kPacketTimeMs + config.queue_delay_ms,
@@ -223,9 +211,9 @@
   FakeNetworkPipe::Config config;
   config.queue_length_packets = 20;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   // Add 10 packets of 1000 bytes, = 80 kb, and verify it takes one second to
   // get through the pipe.
@@ -237,13 +225,13 @@
   int packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
 
   // Time hasn't increased yet, so we souldn't get any packets.
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 
   // Advance time in steps to release one packet at a time.
   for (int i = 0; i < kNumPackets; ++i) {
     fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
-    EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
+    EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
     pipe->Process();
   }
 
@@ -259,20 +247,20 @@
   packet_time_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
 
   // Time hasn't increased yet, so we souldn't get any packets.
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 
   // Advance time in steps to release one packet at a time.
   for (int i = 0; i < kNumPackets; ++i) {
     fake_clock_.AdvanceTimeMilliseconds(packet_time_ms);
-    EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(1);
+    EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
     pipe->Process();
   }
 
   // Check that all the packets were sent.
   EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
   fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess());
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::VIDEO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 }
 
@@ -282,9 +270,9 @@
   FakeNetworkPipe::Config config;
   config.queue_length_packets = 20;
   config.link_capacity_kbps = 80;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::AUDIO));
-  pipe->SetReceiver(receiver_.get());
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   // Add 10 packets of 1000 bytes, = 80 kb.
   const int kNumPackets = 10;
@@ -306,27 +294,27 @@
   int packet_time_2_ms = PacketTimeMs(config.link_capacity_kbps, kPacketSize);
 
   // Time hasn't increased yet, so we souldn't get any packets.
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 
   // Advance time in steps to release one packet at a time.
   for (int i = 0; i < kNumPackets; ++i) {
     fake_clock_.AdvanceTimeMilliseconds(packet_time_1_ms);
-    EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
+    EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
     pipe->Process();
   }
 
   // Advance time in steps to release one packet at a time.
   for (int i = 0; i < kNumPackets; ++i) {
     fake_clock_.AdvanceTimeMilliseconds(packet_time_2_ms);
-    EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(1);
+    EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(1);
     pipe->Process();
   }
 
   // Check that all the packets were sent.
   EXPECT_EQ(static_cast<size_t>(2 * kNumPackets), pipe->sent_packets());
   fake_clock_.AdvanceTimeMilliseconds(pipe->TimeUntilNextProcess());
-  EXPECT_CALL(*receiver_, DeliverPacket(MediaType::AUDIO, _, _, _)).Times(0);
+  EXPECT_CALL(*demuxer, DeliverPacket(_, _)).Times(0);
   pipe->Process();
 }
 
@@ -337,11 +325,9 @@
   config.link_capacity_kbps = 800;
   config.queue_delay_ms = 100;
   config.delay_standard_deviation_ms = 10;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  ReorderTestReceiver* receiver = new ReorderTestReceiver();
-  receiver_.reset(receiver);
-  pipe->SetReceiver(receiver_.get());
+  ReorderTestDemuxer* demuxer = new ReorderTestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   const uint32_t kNumPackets = 100;
   const int kPacketSize = 10;
@@ -350,9 +336,9 @@
   pipe->Process();
 
   // Confirm that all packets have been delivered in order.
-  EXPECT_EQ(kNumPackets, receiver->delivered_sequence_numbers_.size());
+  EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size());
   int last_seq_num = -1;
-  for (int seq_num : receiver->delivered_sequence_numbers_) {
+  for (int seq_num : demuxer->delivered_sequence_numbers_) {
     EXPECT_GT(seq_num, last_seq_num);
     last_seq_num = seq_num;
   }
@@ -361,15 +347,15 @@
   pipe->SetConfig(config);
   SendPackets(pipe.get(), kNumPackets, kPacketSize);
   fake_clock_.AdvanceTimeMilliseconds(1000);
-  receiver->delivered_sequence_numbers_.clear();
+  demuxer->delivered_sequence_numbers_.clear();
   pipe->Process();
 
   // Confirm that all packets have been delivered
   // and that reordering has occured.
-  EXPECT_EQ(kNumPackets, receiver->delivered_sequence_numbers_.size());
+  EXPECT_EQ(kNumPackets, demuxer->delivered_sequence_numbers_.size());
   bool reordering_has_occured = false;
   last_seq_num = -1;
-  for (int seq_num : receiver->delivered_sequence_numbers_) {
+  for (int seq_num : demuxer->delivered_sequence_numbers_) {
     if (last_seq_num > seq_num) {
       reordering_has_occured = true;
       break;
@@ -389,28 +375,26 @@
   config.queue_length_packets = kNumPackets;
   config.loss_percent = kLossPercent;
   config.avg_burst_loss_length = kAvgBurstLength;
-  std::unique_ptr<FakeNetworkPipe> pipe(
-      new FakeNetworkPipe(&fake_clock_, config, MediaType::VIDEO));
-  ReorderTestReceiver* receiver = new ReorderTestReceiver();
-  receiver_.reset(receiver);
-  pipe->SetReceiver(receiver_.get());
+  ReorderTestDemuxer* demuxer = new ReorderTestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
 
   SendPackets(pipe.get(), kNumPackets, kPacketSize);
   fake_clock_.AdvanceTimeMilliseconds(1000);
   pipe->Process();
 
   // Check that the average loss is |kLossPercent| percent.
-  int lost_packets = kNumPackets - receiver->delivered_sequence_numbers_.size();
+  int lost_packets = kNumPackets - demuxer->delivered_sequence_numbers_.size();
   double loss_fraction = lost_packets / static_cast<double>(kNumPackets);
 
   EXPECT_NEAR(kLossPercent / 100.0, loss_fraction, 0.05);
 
   // Find the number of bursts that has occurred.
-  size_t received_packets = receiver->delivered_sequence_numbers_.size();
+  size_t received_packets = demuxer->delivered_sequence_numbers_.size();
   int num_bursts = 0;
   for (size_t i = 0; i < received_packets - 1; ++i) {
-    int diff = receiver->delivered_sequence_numbers_[i + 1] -
-               receiver->delivered_sequence_numbers_[i];
+    int diff = demuxer->delivered_sequence_numbers_[i + 1] -
+               demuxer->delivered_sequence_numbers_[i];
     if (diff > 1)
       ++num_bursts;
   }
@@ -419,4 +403,43 @@
 
   EXPECT_NEAR(kAvgBurstLength, average_burst_length, 0.3);
 }
+
+TEST_F(FakeNetworkPipeTest, SetReceiver) {
+  FakeNetworkPipe::Config config;
+  TestDemuxer* demuxer = new TestDemuxer();
+  std::unique_ptr<FakeNetworkPipe> pipe(new FakeNetworkPipe(
+      &fake_clock_, config, std::unique_ptr<Demuxer>(demuxer)));
+  MockReceiver packet_receiver;
+  EXPECT_CALL(*demuxer, SetReceiver(&packet_receiver)).Times(1);
+  pipe->SetReceiver(&packet_receiver);
+}
+
+TEST(DemuxerImplTest, Demuxing) {
+  constexpr uint8_t kVideoPayloadType = 100;
+  constexpr uint8_t kAudioPayloadType = 101;
+  constexpr int64_t kTimeNow = 12345;
+  constexpr int64_t kArrivalTime = kTimeNow - 1;
+  constexpr size_t kPacketSize = 10;
+  DemuxerImpl demuxer({{kVideoPayloadType, MediaType::VIDEO},
+                       {kAudioPayloadType, MediaType::AUDIO}});
+
+  MockReceiver mock_receiver;
+  demuxer.SetReceiver(&mock_receiver);
+
+  std::vector<uint8_t> data(kPacketSize);
+  data[1] = kVideoPayloadType;
+  std::unique_ptr<NetworkPacket> packet(
+      new NetworkPacket(&data[0], kPacketSize, kTimeNow, kArrivalTime));
+  EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::VIDEO, _, _, _))
+      .WillOnce(Return(PacketReceiver::DELIVERY_OK));
+  demuxer.DeliverPacket(packet.get(), PacketTime());
+
+  data[1] = kAudioPayloadType;
+  packet.reset(
+      new NetworkPacket(&data[0], kPacketSize, kTimeNow, kArrivalTime));
+  EXPECT_CALL(mock_receiver, DeliverPacket(MediaType::AUDIO, _, _, _))
+      .WillOnce(Return(PacketReceiver::DELIVERY_OK));
+  demuxer.DeliverPacket(packet.get(), PacketTime());
+}
+
 }  // namespace webrtc
diff --git a/webrtc/test/layer_filtering_transport.cc b/webrtc/test/layer_filtering_transport.cc
index 5ae06b7..06fc71f 100644
--- a/webrtc/test/layer_filtering_transport.cc
+++ b/webrtc/test/layer_filtering_transport.cc
@@ -26,8 +26,9 @@
     uint8_t vp8_video_payload_type,
     uint8_t vp9_video_payload_type,
     int selected_tl,
-    int selected_sl)
-    : test::DirectTransport(config, send_call, MediaType::VIDEO),
+    int selected_sl,
+    const std::map<uint8_t, MediaType>& payload_type_map)
+    : test::DirectTransport(config, send_call, payload_type_map),
       vp8_video_payload_type_(vp8_video_payload_type),
       vp9_video_payload_type_(vp9_video_payload_type),
       selected_tl_(selected_tl),
diff --git a/webrtc/test/layer_filtering_transport.h b/webrtc/test/layer_filtering_transport.h
index 8f8cc2e..488f764 100644
--- a/webrtc/test/layer_filtering_transport.h
+++ b/webrtc/test/layer_filtering_transport.h
@@ -27,7 +27,8 @@
                           uint8_t vp8_video_payload_type,
                           uint8_t vp9_video_payload_type,
                           int selected_tl,
-                          int selected_sl);
+                          int selected_sl,
+                          const std::map<uint8_t, MediaType>& payload_type_map);
   bool DiscardedLastPacket() const;
   bool SendRtp(const uint8_t* data,
                size_t length,
diff --git a/webrtc/test/rtp_rtcp_observer.h b/webrtc/test/rtp_rtcp_observer.h
index b268e4b..bb00782 100644
--- a/webrtc/test/rtp_rtcp_observer.h
+++ b/webrtc/test/rtp_rtcp_observer.h
@@ -94,9 +94,9 @@
   PacketTransport(Call* send_call,
                   RtpRtcpObserver* observer,
                   TransportType transport_type,
-                  MediaType media_type,
+                  const std::map<uint8_t, MediaType>& payload_type_map,
                   const FakeNetworkPipe::Config& configuration)
-      : test::DirectTransport(configuration, send_call, media_type),
+      : test::DirectTransport(configuration, send_call, payload_type_map),
         observer_(observer),
         transport_type_(transport_type) {}
 
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index e482246..f31a68e 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -66,7 +66,9 @@
 
 namespace webrtc {
 
-static const int kSilenceTimeoutMs = 2000;
+namespace {
+constexpr int kSilenceTimeoutMs = 2000;
+}
 
 class EndToEndTest : public test::CallTest {
  public:
@@ -210,10 +212,9 @@
 
   CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
 
-  test::DirectTransport sender_transport(
-      sender_call_.get(), MediaType::VIDEO);
-  test::DirectTransport receiver_transport(
-      receiver_call_.get(), MediaType::VIDEO);
+  test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
+  test::DirectTransport receiver_transport(receiver_call_.get(),
+                                           payload_type_map_);
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
@@ -260,10 +261,9 @@
 
   CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
 
-  test::DirectTransport sender_transport(
-      sender_call_.get(), MediaType::VIDEO);
-  test::DirectTransport receiver_transport(
-      receiver_call_.get(), MediaType::VIDEO);
+  test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
+  test::DirectTransport receiver_transport(receiver_call_.get(),
+                                           payload_type_map_);
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
@@ -323,7 +323,8 @@
       VideoEncoderConfig* encoder_config) override {
     send_config->encoder_settings.encoder = encoder_.get();
     send_config->encoder_settings.payload_name = payload_name_;
-    send_config->encoder_settings.payload_type = 126;
+    send_config->encoder_settings.payload_type =
+        test::CallTest::kVideoSendPayloadType;
 
     (*receive_configs)[0].renderer = this;
     (*receive_configs)[0].decoders.resize(1);
@@ -534,8 +535,7 @@
 
     test::PacketTransport* CreateReceiveTransport() override {
       test::PacketTransport* receive_transport = new test::PacketTransport(
-          nullptr, this, test::PacketTransport::kReceiver,
-          MediaType::AUDIO,
+          nullptr, this, test::PacketTransport::kReceiver, payload_type_map_,
           FakeNetworkPipe::Config());
       receive_transport_ = receive_transport;
       return receive_transport;
@@ -798,7 +798,7 @@
     config.queue_delay_ms = kNetworkDelayMs;
     return new test::PacketTransport(sender_call, this,
                                      test::PacketTransport::kSender,
-                                     MediaType::VIDEO, config);
+                                     test::CallTest::payload_type_map_, config);
   }
 
   void OnFrame(const VideoFrame& video_frame) override {
@@ -978,7 +978,7 @@
       config.queue_delay_ms = kNetworkDelayMs;
       return new test::PacketTransport(sender_call, this,
                                        test::PacketTransport::kSender,
-                                       MediaType::VIDEO, config);
+                                       payload_type_map_, config);
     }
 
     // TODO(holmer): Investigate why we don't send FEC packets when the bitrate
@@ -1320,10 +1320,9 @@
 
   CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
 
-  test::DirectTransport send_transport(
-      sender_call_.get(), MediaType::VIDEO);
-  test::DirectTransport receive_transport(
-      receiver_call_.get(), MediaType::VIDEO);
+  test::DirectTransport send_transport(sender_call_.get(), payload_type_map_);
+  test::DirectTransport receive_transport(receiver_call_.get(),
+                                          payload_type_map_);
   PacketInputObserver input_observer(receiver_call_->Receiver());
   send_transport.SetReceiver(&input_observer);
   receive_transport.SetReceiver(sender_call_->Receiver());
@@ -1443,7 +1442,11 @@
 // Another is set up to receive all three of these with different renderers.
 class MultiStreamTest {
  public:
-  static const size_t kNumStreams = 3;
+  static constexpr size_t kNumStreams = 3;
+  const uint8_t kVideoPayloadType = 124;
+  const std::map<uint8_t, MediaType> payload_type_map_ = {
+      {kVideoPayloadType, MediaType::VIDEO}};
+
   struct CodecSettings {
     uint32_t ssrc;
     int width;
@@ -1489,7 +1492,7 @@
       send_config.rtp.ssrcs.push_back(ssrc);
       send_config.encoder_settings.encoder = encoders[i].get();
       send_config.encoder_settings.payload_name = "VP8";
-      send_config.encoder_settings.payload_type = 124;
+      send_config.encoder_settings.payload_type = kVideoPayloadType;
       VideoEncoderConfig encoder_config;
       test::FillEncoderConfiguration(1, &encoder_config);
       encoder_config.max_bitrate_bps = 100000;
@@ -1550,10 +1553,10 @@
                                    VideoReceiveStream::Config* receive_config) {
   }
   virtual test::DirectTransport* CreateSendTransport(Call* sender_call) {
-    return new test::DirectTransport(sender_call, MediaType::VIDEO);
+    return new test::DirectTransport(sender_call, payload_type_map_);
   }
   virtual test::DirectTransport* CreateReceiveTransport(Call* receiver_call) {
-    return new test::DirectTransport(receiver_call, MediaType::VIDEO);
+    return new test::DirectTransport(receiver_call, payload_type_map_);
   }
 };
 
@@ -1629,10 +1632,12 @@
 
   class RtpExtensionHeaderObserver : public test::DirectTransport {
    public:
-    RtpExtensionHeaderObserver(Call* sender_call,
-                               const uint32_t& first_media_ssrc,
-                               const std::map<uint32_t, uint32_t>& ssrc_map)
-        : DirectTransport(sender_call, MediaType::VIDEO),
+    RtpExtensionHeaderObserver(
+        Call* sender_call,
+        const uint32_t& first_media_ssrc,
+        const std::map<uint32_t, uint32_t>& ssrc_map,
+        const std::map<uint8_t, MediaType>& payload_type_map)
+        : DirectTransport(sender_call, payload_type_map),
           done_(false, false),
           parser_(RtpHeaderParser::Create()),
           first_media_ssrc_(first_media_ssrc),
@@ -1796,8 +1801,14 @@
     }
 
     test::DirectTransport* CreateSendTransport(Call* sender_call) override {
-      observer_ = new RtpExtensionHeaderObserver(sender_call, first_media_ssrc_,
-                                                 rtx_to_media_ssrcs_);
+      std::map<uint8_t, MediaType> payload_type_map =
+          MultiStreamTest::payload_type_map_;
+      RTC_DCHECK(payload_type_map.find(kSendRtxPayloadType) ==
+                 payload_type_map.end());
+      payload_type_map[kSendRtxPayloadType] = MediaType::VIDEO;
+      observer_ =
+          new RtpExtensionHeaderObserver(sender_call, first_media_ssrc_,
+                                         rtx_to_media_ssrcs_, payload_type_map);
       return observer_;
     }
 
@@ -1948,10 +1959,9 @@
 
   CreateCalls(Call::Config(event_log_.get()), Call::Config(event_log_.get()));
 
-  test::DirectTransport sender_transport(
-      sender_call_.get(), MediaType::VIDEO);
-  test::DirectTransport receiver_transport(
-      receiver_call_.get(), MediaType::VIDEO);
+  test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
+  test::DirectTransport receiver_transport(receiver_call_.get(),
+                                           payload_type_map_);
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
@@ -2114,8 +2124,7 @@
 
     test::PacketTransport* CreateReceiveTransport() override {
       receive_transport_ = new test::PacketTransport(
-          nullptr, this, test::PacketTransport::kReceiver,
-          MediaType::VIDEO,
+          nullptr, this, test::PacketTransport::kReceiver, payload_type_map_,
           FakeNetworkPipe::Config());
       return receive_transport_;
     }
@@ -3107,9 +3116,9 @@
     test::PacketTransport* CreateSendTransport(Call* sender_call) override {
       FakeNetworkPipe::Config network_config;
       network_config.loss_percent = 5;
-      return new test::PacketTransport(
-          sender_call, this, test::PacketTransport::kSender, MediaType::VIDEO,
-          network_config);
+      return new test::PacketTransport(sender_call, this,
+                                       test::PacketTransport::kSender,
+                                       payload_type_map_, network_config);
     }
 
     Call::Config GetSenderCallConfig() override {
@@ -3661,14 +3670,12 @@
   Call::Config config(event_log_.get());
   CreateCalls(config, config);
 
-  test::PacketTransport send_transport(sender_call_.get(), &observer,
-                                       test::PacketTransport::kSender,
-                                       MediaType::VIDEO,
-                                       FakeNetworkPipe::Config());
-  test::PacketTransport receive_transport(nullptr, &observer,
-                                          test::PacketTransport::kReceiver,
-                                          MediaType::VIDEO,
-                                          FakeNetworkPipe::Config());
+  test::PacketTransport send_transport(
+      sender_call_.get(), &observer, test::PacketTransport::kSender,
+      payload_type_map_, FakeNetworkPipe::Config());
+  test::PacketTransport receive_transport(
+      nullptr, &observer, test::PacketTransport::kReceiver, payload_type_map_,
+      FakeNetworkPipe::Config());
   send_transport.SetReceiver(receiver_call_->Receiver());
   receive_transport.SetReceiver(sender_call_->Receiver());
 
@@ -3960,11 +3967,11 @@
 
   FakeNetworkPipe::Config config;
   config.queue_delay_ms = kSendDelayMs;
-  test::DirectTransport sender_transport(
-      config, sender_call_.get(), MediaType::VIDEO);
+  test::DirectTransport sender_transport(config, sender_call_.get(),
+                                         payload_type_map_);
   config.queue_delay_ms = kReceiveDelayMs;
-  test::DirectTransport receiver_transport(
-      config, receiver_call_.get(), MediaType::VIDEO);
+  test::DirectTransport receiver_transport(config, receiver_call_.get(),
+                                           payload_type_map_);
   sender_transport.SetReceiver(receiver_call_->Receiver());
   receiver_transport.SetReceiver(sender_call_->Receiver());
 
@@ -4026,7 +4033,7 @@
   CreateCalls(config, config);
   receiver_call_->SignalChannelNetworkState(network_to_bring_up, kNetworkUp);
 
-  test::DirectTransport sender_transport(sender_call_.get(), MediaType::VIDEO);
+  test::DirectTransport sender_transport(sender_call_.get(), payload_type_map_);
   sender_transport.SetReceiver(receiver_call_->Receiver());
   CreateSendConfig(1, 0, 0, &sender_transport);
   CreateMatchingReceiveConfigs(transport);
diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc
index 36c35ee..0baf42c 100644
--- a/webrtc/video/video_quality_test.cc
+++ b/webrtc/video/video_quality_test.cc
@@ -54,6 +54,7 @@
 constexpr int kPayloadTypeH264 = 122;
 constexpr int kPayloadTypeVP8 = 123;
 constexpr int kPayloadTypeVP9 = 124;
+
 constexpr size_t kMaxComparisons = 10;
 constexpr char kSyncGroup[] = "av_sync";
 constexpr int kOpusMinBitrateBps = 6000;
@@ -1030,7 +1031,18 @@
 };
 
 VideoQualityTest::VideoQualityTest()
-    : clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) {}
+    : clock_(Clock::GetRealTimeClock()), receive_logs_(0), send_logs_(0) {
+  payload_type_map_ = test::CallTest::payload_type_map_;
+  RTC_DCHECK(payload_type_map_.find(kPayloadTypeH264) ==
+             payload_type_map_.end());
+  RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP8) ==
+             payload_type_map_.end());
+  RTC_DCHECK(payload_type_map_.find(kPayloadTypeVP9) ==
+             payload_type_map_.end());
+  payload_type_map_[kPayloadTypeH264] = webrtc::MediaType::VIDEO;
+  payload_type_map_[kPayloadTypeVP8] = webrtc::MediaType::VIDEO;
+  payload_type_map_[kPayloadTypeVP9] = webrtc::MediaType::VIDEO;
+}
 
 VideoQualityTest::Params::Params()
     : call({false, Call::Config::BitrateConfig()}),
@@ -1590,9 +1602,10 @@
 
   test::LayerFilteringTransport send_transport(
       params_.pipe, sender_call_.get(), kPayloadTypeVP8, kPayloadTypeVP9,
-      params_.video.selected_tl, params_.ss.selected_sl);
-  test::DirectTransport recv_transport(
-      params_.pipe, receiver_call_.get(), MediaType::VIDEO);
+      params_.video.selected_tl, params_.ss.selected_sl, payload_type_map_);
+
+  test::DirectTransport recv_transport(params_.pipe, receiver_call_.get(),
+                                       payload_type_map_);
 
   std::string graph_title = params_.analyzer.graph_title;
   if (graph_title.empty())
@@ -1711,7 +1724,7 @@
     audio_send_config_.max_bitrate_bps = kOpusBitrateFbBps;
   }
   audio_send_config_.send_codec_spec.codec_inst =
-      CodecInst{120, "OPUS", 48000, 960, 2, 64000};
+      CodecInst{kAudioSendPayloadType, "OPUS", 48000, 960, 2, 64000};
   audio_send_config_.send_codec_spec.enable_opus_dtx = params_.audio.dtx;
   audio_send_stream_ = call->CreateAudioSendStream(audio_send_config_);
 
@@ -1723,6 +1736,7 @@
   audio_config.rtp.transport_cc = params_.call.send_side_bwe;
   audio_config.rtp.extensions = audio_send_config_.rtp.extensions;
   audio_config.decoder_factory = decoder_factory_;
+  audio_config.decoder_map = {{kAudioSendPayloadType, {"OPUS", 48000, 2}}};
   if (params_.video.enabled && params_.audio.sync_video)
     audio_config.sync_group = kSyncGroup;
 
@@ -1753,7 +1767,8 @@
   // calls.
   test::LayerFilteringTransport transport(
       params.pipe, call.get(), kPayloadTypeVP8, kPayloadTypeVP9,
-      params.video.selected_tl, params_.ss.selected_sl);
+      params.video.selected_tl, params_.ss.selected_sl, payload_type_map_);
+
   // TODO(ivica): Use two calls to be able to merge with RunWithAnalyzer or at
   // least share as much code as possible. That way this test would also match
   // the full stack tests better.
diff --git a/webrtc/video/video_quality_test.h b/webrtc/video/video_quality_test.h
index 33a1a8a..9e851f0 100644
--- a/webrtc/video/video_quality_test.h
+++ b/webrtc/video/video_quality_test.h
@@ -10,6 +10,7 @@
 #ifndef WEBRTC_VIDEO_VIDEO_QUALITY_TEST_H_
 #define WEBRTC_VIDEO_VIDEO_QUALITY_TEST_H_
 
+#include <map>
 #include <memory>
 #include <string>
 #include <vector>
@@ -96,6 +97,8 @@
       const std::vector<std::string>& sl_descriptors);
 
  protected:
+  std::map<uint8_t, webrtc::MediaType> payload_type_map_;
+
   // No-op implementation to be able to instantiate this class from non-TEST_F
   // locations.
   void TestBody() override;
diff --git a/webrtc/video/video_send_stream_tests.cc b/webrtc/video/video_send_stream_tests.cc
index 0b991f9..894b840 100644
--- a/webrtc/video/video_send_stream_tests.cc
+++ b/webrtc/video/video_send_stream_tests.cc
@@ -438,9 +438,9 @@
     FakeNetworkPipe::Config config;
     config.loss_percent = 5;
     config.queue_delay_ms = kNetworkDelayMs;
-    return new test::PacketTransport(sender_call, this,
-                                     test::PacketTransport::kSender,
-                                     MediaType::VIDEO, config);
+    return new test::PacketTransport(
+        sender_call, this, test::PacketTransport::kSender,
+        VideoSendStreamTest::payload_type_map_, config);
   }
 
   void ModifyVideoConfigs(
@@ -594,9 +594,9 @@
     FakeNetworkPipe::Config config;
     config.loss_percent = 5;
     config.queue_delay_ms = kNetworkDelayMs;
-    return new test::PacketTransport(sender_call, this,
-                                     test::PacketTransport::kSender,
-                                     MediaType::VIDEO, config);
+    return new test::PacketTransport(
+        sender_call, this, test::PacketTransport::kSender,
+        VideoSendStreamTest::payload_type_map_, config);
   }
 
   void ModifyVideoConfigs(
@@ -1266,7 +1266,7 @@
       config.queue_delay_ms = kNetworkDelayMs;
       return new test::PacketTransport(sender_call, this,
                                        test::PacketTransport::kSender,
-                                       MediaType::VIDEO, config);
+                                       payload_type_map_, config);
     }
 
     void ModifyVideoConfigs(
@@ -2749,7 +2749,7 @@
   virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
 
  private:
-  const int kVp9PayloadType = 105;
+  const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
 
   class VideoStreamFactory
       : public VideoEncoderConfig::VideoStreamFactoryInterface {