Breaking out receive-stats, rtp-payload-registry and rtp-receiver from the
rtp_rtcp implementation.

This refactoring significantly reduces the receive-side RTP parser and receiver
complexity, and makes it possible to implement RTX correctly by having two
instances of receive-statistics.

With this change the dead-or-alive and packet timeout APIs are removed.

TEST=trybots, vie_auto_test, voe_auto_test
BUG=1811
R=mflodman@webrtc.org, pbos@webrtc.org, xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1745004

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@4301 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/interface/module_common_types.h b/modules/interface/module_common_types.h
index 57a1dfb..48b0323 100644
--- a/modules/interface/module_common_types.h
+++ b/modules/interface/module_common_types.h
@@ -44,6 +44,7 @@
     uint32_t arrOfCSRCs[kRtpCsrcSize];
     uint8_t paddingLength;
     uint16_t headerLength;
+    int payload_type_frequency;
     RTPHeaderExtension extension;
 };
 
@@ -93,13 +94,13 @@
     RTPVideoHeaderVP8       VP8;
 };
 
-enum RTPVideoCodecTypes
+enum RtpVideoCodecTypes
 {
-    kRTPVideoGeneric  = 0,
-    kRTPVideoVP8      = 8,
-    kRTPVideoNoVideo  = 10,
-    kRTPVideoFEC      = 11,
-    kRTPVideoI420     = 12
+    kRtpVideoNone,
+    kRtpVideoGeneric,
+    kRtpVideoVp8,
+    kRtpVideoFec,
+    kRtpVideoI420
 };
 struct RTPVideoHeader
 {
@@ -109,7 +110,7 @@
     bool                    isFirstPacket;   // first packet in frame
     uint8_t           simulcastIdx;    // Index if the simulcast encoder creating
                                              // this frame, 0 if not using simulcast.
-    RTPVideoCodecTypes      codec;
+    RtpVideoCodecTypes      codec;
     RTPVideoTypeHeader      codecHeader;
 };
 union RTPTypeHeader
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 4e9c808..523a14e 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -168,7 +168,6 @@
             'remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h',
             'remote_bitrate_estimator/rtp_to_ntp_unittest.cc',
             'rtp_rtcp/source/mock/mock_rtp_payload_strategy.h',
-            'rtp_rtcp/source/mock/mock_rtp_receiver_video.h',
             'rtp_rtcp/source/fec_test_helper.cc',
             'rtp_rtcp/source/fec_test_helper.h',
             'rtp_rtcp/source/nack_rtx_unittest.cc',
diff --git a/modules/rtp_rtcp/interface/receive_statistics.h b/modules/rtp_rtcp/interface/receive_statistics.h
new file mode 100644
index 0000000..fc47bf8
--- /dev/null
+++ b/modules/rtp_rtcp/interface/receive_statistics.h
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
+#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
+
+#include "webrtc/modules/interface/module.h"
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class Clock;
+
+class ReceiveStatistics : public Module {
+ public:
+  struct RtpReceiveStatistics {
+    uint8_t fraction_lost;
+    uint32_t cumulative_lost;
+    uint32_t extended_max_sequence_number;
+    uint32_t jitter;
+    uint32_t max_jitter;
+  };
+
+  virtual ~ReceiveStatistics() {}
+
+  static ReceiveStatistics* Create(Clock* clock);
+
+  virtual void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
+                              bool retransmitted, bool in_order) = 0;
+
+  virtual bool Statistics(RtpReceiveStatistics* statistics, bool reset) = 0;
+
+  virtual bool Statistics(RtpReceiveStatistics* statistics, int32_t* missing,
+                          bool reset) = 0;
+
+  virtual void GetDataCounters(uint32_t* bytes_received,
+                               uint32_t* packets_received) const = 0;
+
+  virtual uint32_t BitrateReceived() = 0;
+
+  virtual void ResetStatistics() = 0;
+
+  virtual void ResetDataCounters() = 0;
+};
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry.h b/modules/rtp_rtcp/interface/rtp_payload_registry.h
similarity index 86%
rename from modules/rtp_rtcp/source/rtp_payload_registry.h
rename to modules/rtp_rtcp/interface/rtp_payload_registry.h
index 465a4ed..f5aca81 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry.h
+++ b/modules/rtp_rtcp/interface/rtp_payload_registry.h
@@ -8,8 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PAYLOAD_REGISTRY_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PAYLOAD_REGISTRY_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
+#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
 
 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -21,7 +21,7 @@
 // of payload handling.
 class RTPPayloadStrategy {
  public:
-  virtual ~RTPPayloadStrategy() {};
+  virtual ~RTPPayloadStrategy() {}
 
   virtual bool CodecsMustBeUnique() const = 0;
 
@@ -42,10 +42,13 @@
       const uint8_t channels,
       const uint32_t rate) const = 0;
 
+  virtual int GetPayloadTypeFrequency(
+      const ModuleRTPUtility::Payload& payload) const = 0;
+
   static RTPPayloadStrategy* CreateStrategy(const bool handling_audio);
 
  protected:
-   RTPPayloadStrategy() {};
+  RTPPayloadStrategy() {}
 };
 
 class RTPPayloadRegistry {
@@ -73,7 +76,11 @@
       const uint32_t rate,
       int8_t* payload_type) const;
 
-  int32_t PayloadTypeToPayload(
+  bool GetPayloadSpecifics(uint8_t payload_type, PayloadUnion* payload) const;
+
+  int GetPayloadTypeFrequency(uint8_t payload_type) const;
+
+  bool PayloadTypeToPayload(
     const uint8_t payload_type,
     ModuleRTPUtility::Payload*& payload) const;
 
@@ -116,4 +123,4 @@
 
 }  // namespace webrtc
 
-#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_PAYLOAD_REGISTRY_H_
+#endif  // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_PAYLOAD_REGISTRY_H_
diff --git a/modules/rtp_rtcp/interface/rtp_receiver.h b/modules/rtp_rtcp/interface/rtp_receiver.h
new file mode 100644
index 0000000..0e47d01
--- /dev/null
+++ b/modules/rtp_rtcp/interface/rtp_receiver.h
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
+#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
+
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class RTPPayloadRegistry;
+
+class TelephoneEventHandler {
+ public:
+  virtual ~TelephoneEventHandler() {}
+
+  // The following three methods implement the TelephoneEventHandler interface.
+  // Forward DTMFs to decoder for playout.
+  virtual void SetTelephoneEventForwardToDecoder(bool forward_to_decoder) = 0;
+
+  // Is forwarding of outband telephone events turned on/off?
+  virtual bool TelephoneEventForwardToDecoder() const = 0;
+
+  // Is TelephoneEvent configured with payload type payload_type
+  virtual bool TelephoneEventPayloadType(const int8_t payload_type) const = 0;
+};
+
+class RtpReceiver {
+ public:
+  // Creates a video-enabled RTP receiver.
+  static RtpReceiver* CreateVideoReceiver(
+      int id, Clock* clock,
+      RtpData* incoming_payload_callback,
+      RtpFeedback* incoming_messages_callback,
+      RTPPayloadRegistry* rtp_payload_registry);
+
+  // Creates an audio-enabled RTP receiver.
+  static RtpReceiver* CreateAudioReceiver(
+      int id, Clock* clock,
+      RtpAudioFeedback* incoming_audio_feedback,
+      RtpData* incoming_payload_callback,
+      RtpFeedback* incoming_messages_callback,
+      RTPPayloadRegistry* rtp_payload_registry);
+
+  virtual ~RtpReceiver() {}
+
+  // Returns a TelephoneEventHandler if available.
+  virtual TelephoneEventHandler* GetTelephoneEventHandler() = 0;
+
+  // Registers a receive payload in the payload registry and notifies the media
+  // receiver strategy.
+  virtual int32_t RegisterReceivePayload(
+      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
+      const int8_t payload_type,
+      const uint32_t frequency,
+      const uint8_t channels,
+      const uint32_t rate) = 0;
+
+  // De-registers |payload_type| from the payload registry.
+  virtual int32_t DeRegisterReceivePayload(const int8_t payload_type) = 0;
+
+  // Parses the media specific parts of an RTP packet and updates the receiver
+  // state. This for instance means that any changes in SSRC and payload type is
+  // detected and acted upon.
+  virtual bool IncomingRtpPacket(RTPHeader* rtp_header,
+                                 const uint8_t* incoming_rtp_packet,
+                                 int incoming_rtp_packet_length,
+                                 PayloadUnion payload_specific,
+                                 bool in_order) = 0;
+
+  // Returns the currently configured NACK method.
+  virtual NACKMethod NACK() const = 0;
+
+  // Turn negative acknowledgement (NACK) requests on/off.
+  virtual int32_t SetNACKStatus(const NACKMethod method,
+                                int max_reordering_threshold) = 0;
+
+  // Returns the last received timestamp.
+  virtual uint32_t TimeStamp() const = 0;
+  // Returns the time in milliseconds when the last timestamp was received.
+  virtual int32_t LastReceivedTimeMs() const = 0;
+
+  // Returns the remote SSRC of the currently received RTP stream.
+  virtual uint32_t SSRC() const = 0;
+
+  // Returns the current remote CSRCs.
+  virtual int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const = 0;
+
+  // Returns the current energy of the RTP stream received.
+  virtual int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const = 0;
+
+  // Enable/disable RTX and set the SSRC to be used.
+  virtual void SetRTXStatus(bool enable, uint32_t ssrc) = 0;
+
+  // Returns the current RTX status and the SSRC and payload type used.
+  virtual void RTXStatus(bool* enable, uint32_t* ssrc,
+                         int* payload_type) const = 0;
+
+  // Sets the RTX payload type.
+  virtual void SetRtxPayloadType(int payload_type) = 0;
+
+  // Returns true if the packet with RTP header |header| is likely to be a
+  // retransmitted packet, false otherwise.
+  virtual bool RetransmitOfOldPacket(const RTPHeader& header, int jitter,
+                                     int min_rtt) const = 0;
+
+  // Returns true if |sequence_number| is received in order, false otherwise.
+  virtual bool InOrderPacket(const uint16_t sequence_number) const = 0;
+};
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RECEIVER_H_
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp.h b/modules/rtp_rtcp/interface/rtp_rtcp.h
index 5c25fbe..2171d48 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -19,8 +19,9 @@
 namespace webrtc {
 // Forward declarations.
 class PacedSender;
+class ReceiveStatistics;
 class RemoteBitrateEstimator;
-class RemoteBitrateObserver;
+class RtpReceiver;
 class Transport;
 
 class RtpRtcp : public Module {
@@ -57,8 +58,7 @@
     bool audio;
     Clock* clock;
     RtpRtcp* default_module;
-    RtpData* incoming_data;
-    RtpFeedback* incoming_messages;
+    ReceiveStatistics* receive_statistics;
     Transport* outgoing_transport;
     RtcpFeedback* rtcp_feedback;
     RtcpIntraFrameObserver* intra_frame_callback;
@@ -68,6 +68,7 @@
     RemoteBitrateEstimator* remote_bitrate_estimator;
     PacedSender* paced_sender;
   };
+
   /*
    *   Create a RTP/RTCP module object using the system clock.
    *
@@ -81,174 +82,11 @@
    *
    ***************************************************************************/
 
-    /*
-    *   configure a RTP packet timeout value
-    *
-    *   RTPtimeoutMS   - time in milliseconds after last received RTP packet
-    *   RTCPtimeoutMS  - time in milliseconds after last received RTCP packet
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SetPacketTimeout(
-        const uint32_t RTPtimeoutMS,
-        const uint32_t RTCPtimeoutMS) = 0;
-
-    /*
-    *   Set periodic dead or alive notification
-    *
-    *   enable              - turn periodic dead or alive notification on/off
-    *   sampleTimeSeconds   - sample interval in seconds for dead or alive
-    *                         notifications
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SetPeriodicDeadOrAliveStatus(
-        const bool enable,
-        const uint8_t sampleTimeSeconds) = 0;
-
-    /*
-    *   Get periodic dead or alive notification status
-    *
-    *   enable              - periodic dead or alive notification on/off
-    *   sampleTimeSeconds   - sample interval in seconds for dead or alive
-    *                         notifications
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t PeriodicDeadOrAliveStatus(
-        bool& enable,
-        uint8_t& sampleTimeSeconds) = 0;
-
-    /*
-    *   set voice codec name and payload type
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t RegisterReceivePayload(
-        const CodecInst& voiceCodec) = 0;
-
-    /*
-    *   set video codec name and payload type
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t RegisterReceivePayload(
-        const VideoCodec& videoCodec) = 0;
-
-    /*
-    *   get payload type for a voice codec
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t ReceivePayloadType(
-        const CodecInst& voiceCodec,
-        int8_t* plType) = 0;
-
-    /*
-    *   get payload type for a video codec
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t ReceivePayloadType(
-        const VideoCodec& videoCodec,
-        int8_t* plType) = 0;
-
-    /*
-    *   Remove a registered payload type from list of accepted payloads
-    *
-    *   payloadType - payload type of codec
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t DeRegisterReceivePayload(
-        const int8_t payloadType) = 0;
-
-    /*
-    *   Get last received remote timestamp
-    */
-    virtual uint32_t RemoteTimestamp() const = 0;
-
-    /*
-    *   Get the local time of the last received remote timestamp
-    */
-    virtual int64_t LocalTimeOfRemoteTimeStamp() const = 0;
-
-    /*
-    *   Get the current estimated remote timestamp
-    *
-    *   timestamp   - estimated timestamp
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t EstimatedRemoteTimeStamp(
-        uint32_t& timestamp) const = 0;
-
-    /*
-    *   Get incoming SSRC
-    */
-    virtual uint32_t RemoteSSRC() const = 0;
-
-    /*
-    *   Get remote CSRC
-    *
-    *   arrOfCSRC   - array that will receive the CSRCs
-    *
-    *   return -1 on failure else the number of valid entries in the list
-    */
-    virtual int32_t RemoteCSRCs(
-        uint32_t arrOfCSRC[kRtpCsrcSize]) const  = 0;
-
-    /*
-    *   get the currently configured SSRC filter
-    *
-    *   allowedSSRC - SSRC that will be allowed through
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SSRCFilter(uint32_t& allowedSSRC) const = 0;
-
-    /*
-    *   set a SSRC to be used as a filter for incoming RTP streams
-    *
-    *   allowedSSRC - SSRC that will be allowed through
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SetSSRCFilter(const bool enable,
-                                  const uint32_t allowedSSRC) = 0;
-
-    /*
-    * Turn on/off receiving RTX (RFC 4588) on a specific SSRC.
-    */
-    virtual int32_t SetRTXReceiveStatus(bool enable, uint32_t SSRC) = 0;
-
-    // Sets the payload type to expected for received RTX packets. Note
-    // that this doesn't enable RTX, only the payload type is set.
-    virtual void SetRtxReceivePayloadType(int payload_type) = 0;
-
-    /*
-    * Get status of receiving RTX (RFC 4588) on a specific SSRC.
-    */
-    virtual int32_t RTXReceiveStatus(bool* enable,
-                                     uint32_t* SSRC,
-                                     int* payloadType) const = 0;
-
-    /*
-    *   called by the network module when we receive a packet
-    *
-    *   incomingPacket - incoming packet buffer
-    *   packetLength   - length of incoming buffer
-    *   parsed_rtp_header - the parsed RTP header
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t IncomingRtpPacket(const uint8_t* incomingPacket,
-                                      const uint16_t packetLength,
-                                      const RTPHeader& parsed_rtp_header) = 0;
-
     virtual int32_t IncomingRtcpPacket(const uint8_t* incoming_packet,
                                        uint16_t incoming_packet_length) = 0;
 
+    virtual void SetRemoteSSRC(const uint32_t ssrc) = 0;
+
     /**************************************************************************
     *
     *   Sender
@@ -609,32 +447,6 @@
         const uint8_t pictureID) = 0;
 
     /*
-    *   Reset RTP statistics
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t ResetStatisticsRTP() = 0;
-
-    /*
-    *   statistics of our localy created statistics of the received RTP stream
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t StatisticsRTP(
-        uint8_t* fraction_lost,  // scale 0 to 255
-        uint32_t* cum_lost,      // number of lost packets
-        uint32_t* ext_max,       // highest sequence number received
-        uint32_t* jitter,
-        uint32_t* max_jitter = NULL) const = 0;
-
-    /*
-    *   Reset RTP data counters for the receiving side
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t ResetReceiveDataCountersRTP() = 0;
-
-    /*
     *   Reset RTP data counters for the sending side
     *
     *   return -1 on failure else 0
@@ -648,9 +460,7 @@
     */
     virtual int32_t DataCountersRTP(
         uint32_t* bytesSent,
-        uint32_t* packetsSent,
-        uint32_t* bytesReceived,
-        uint32_t* packetsReceived) const = 0;
+        uint32_t* packetsSent) const = 0;
     /*
     *   Get received RTCP sender info
     *
@@ -731,18 +541,6 @@
     /*
     *   (NACK)
     */
-    virtual NACKMethod NACK() const  = 0;
-
-    /*
-    *   Turn negative acknowledgement requests on/off
-    *   |max_reordering_threshold| should be set to how much a retransmitted
-    *   packet can be expected to be reordered (in sequence numbers) compared to
-    *   a packet which has not been retransmitted.
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int32_t SetNACKStatus(const NACKMethod method,
-                                  int max_reordering_threshold) = 0;
 
     /*
      *  TODO(holmer): Propagate this API to VideoEngine.
@@ -798,19 +596,6 @@
         const uint16_t packetSizeSamples) = 0;
 
     /*
-    *   Forward DTMF to decoder for playout.
-    *
-    *   return -1 on failure else 0
-    */
-    virtual int SetTelephoneEventForwardToDecoder(bool forwardToDecoder) = 0;
-
-    /*
-    *   Returns true if received DTMF events are forwarded to the decoder using
-    *    the OnPlayTelephoneEvent callback.
-    */
-    virtual bool TelephoneEventForwardToDecoder() const = 0;
-
-    /*
     *   SendTelephoneEventActive
     *
     *   return true if we currently send a telephone event and 100 ms after an
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
index 500ab53..9754203 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
@@ -11,22 +11,39 @@
 #ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
 #define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
 
+#include <stddef.h>
+
 #include "webrtc/modules/interface/module_common_types.h"
 #include "webrtc/system_wrappers/interface/clock.h"
 #include "webrtc/typedefs.h"
 
-#ifndef NULL
-    #define NULL    0
-#endif
-
 #define RTCP_CNAME_SIZE 256    // RFC 3550 page 44, including null termination
 #define IP_PACKET_SIZE 1500    // we assume ethernet
 #define MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS 10
 #define TIMEOUT_SEI_MESSAGES_MS 30000   // in milliseconds
 
-namespace webrtc{
+namespace webrtc {
 
-const int32_t kDefaultVideoFrequency = 90000;
+const int kVideoPayloadTypeFrequency = 90000;
+
+struct AudioPayload
+{
+    uint32_t    frequency;
+    uint8_t     channels;
+    uint32_t    rate;
+};
+
+struct VideoPayload
+{
+    RtpVideoCodecTypes   videoCodecType;
+    uint32_t       maxRate;
+};
+
+union PayloadUnion
+{
+    AudioPayload Audio;
+    VideoPayload Video;
+};
 
 enum RTCPMethod
 {
@@ -145,6 +162,9 @@
         const uint8_t* payloadData,
         const uint16_t payloadSize,
         const WebRtcRTPHeader* rtpHeader) = 0;
+
+    virtual bool OnRecoveredPacket(const uint8_t* packet,
+                                   int packet_length) = 0;
 protected:
     virtual ~RtpData() {}
 };
@@ -162,8 +182,6 @@
         const int32_t /*id*/,
         const RTCPVoIPMetric* /*metric*/)  {};
 
-    virtual void OnRTCPPacketTimeout(const int32_t /*id*/)  {};
-
     virtual void OnReceiveReportReceived(const int32_t id,
                                          const uint32_t senderSSRC)  {};
 
@@ -186,14 +204,6 @@
         const uint8_t channels,
         const uint32_t rate) = 0;
 
-    virtual void OnPacketTimeout(const int32_t id) = 0;
-
-    virtual void OnReceivedPacket(const int32_t id,
-                                  const RtpRtcpPacketType packetType) = 0;
-
-    virtual void OnPeriodicDeadOrAlive(const int32_t id,
-                                       const RTPAliveType alive) = 0;
-
     virtual void OnIncomingSSRCChanged( const int32_t id,
                                         const uint32_t SSRC) = 0;
 
@@ -201,6 +211,8 @@
                                         const uint32_t CSRC,
                                         const bool added) = 0;
 
+    virtual void OnResetStatistics() = 0;
+
 protected:
     virtual ~RtpFeedback() {}
 };
@@ -268,32 +280,32 @@
    return 0;
  }
 
- virtual void OnPacketTimeout(const int32_t id) {}
-
- virtual void OnReceivedPacket(const int32_t id,
-                               const RtpRtcpPacketType packetType) {}
-
- virtual void OnPeriodicDeadOrAlive(const int32_t id,
-                                    const RTPAliveType alive) {}
-
- virtual void OnIncomingSSRCChanged(const int32_t id,
+  virtual void OnIncomingSSRCChanged(const int32_t id,
                                     const uint32_t SSRC) {}
 
  virtual void OnIncomingCSRCChanged(const int32_t id,
                                     const uint32_t CSRC,
                                     const bool added) {}
+
+ virtual void OnResetStatistics() {}
 };
 
 // Null object version of RtpData.
 class NullRtpData : public RtpData {
  public:
   virtual ~NullRtpData() {}
+
   virtual int32_t OnReceivedPayloadData(
       const uint8_t* payloadData,
       const uint16_t payloadSize,
       const WebRtcRTPHeader* rtpHeader) {
-   return 0;
- }
+    return 0;
+  }
+
+  virtual bool OnRecoveredPacket(const uint8_t* packet,
+                                 int packet_length) {
+    return true;
+  }
 };
 
 // Null object version of RtpAudioFeedback.
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 0d39f8b..674a5b5 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -35,53 +35,9 @@
       int32_t(RtpRtcp* module));
   MOCK_METHOD0(DeRegisterSyncModule,
       int32_t());
-  MOCK_METHOD0(InitReceiver,
-      int32_t());
-  MOCK_METHOD1(RegisterIncomingDataCallback,
-      int32_t(RtpData* incomingDataCallback));
-  MOCK_METHOD1(RegisterIncomingRTPCallback,
-      int32_t(RtpFeedback* incomingMessagesCallback));
-  MOCK_METHOD2(SetPacketTimeout,
-      int32_t(const uint32_t RTPtimeoutMS, const uint32_t RTCPtimeoutMS));
-  MOCK_METHOD2(SetPeriodicDeadOrAliveStatus,
-      int32_t(const bool enable, const uint8_t sampleTimeSeconds));
-  MOCK_METHOD2(PeriodicDeadOrAliveStatus,
-      int32_t(bool &enable, uint8_t &sampleTimeSeconds));
-  MOCK_METHOD1(RegisterReceivePayload,
-      int32_t(const CodecInst& voiceCodec));
-  MOCK_METHOD1(RegisterReceivePayload,
-      int32_t(const VideoCodec& videoCodec));
-  MOCK_METHOD2(ReceivePayloadType,
-      int32_t(const CodecInst& voiceCodec, int8_t* plType));
-  MOCK_METHOD2(ReceivePayloadType,
-      int32_t(const VideoCodec& videoCodec, int8_t* plType));
-  MOCK_METHOD1(DeRegisterReceivePayload,
-      int32_t(const int8_t payloadType));
-  MOCK_CONST_METHOD0(RemoteTimestamp,
-      uint32_t());
-  MOCK_CONST_METHOD0(LocalTimeOfRemoteTimeStamp,
-        int64_t());
-  MOCK_CONST_METHOD1(EstimatedRemoteTimeStamp,
-      int32_t(uint32_t& timestamp));
-  MOCK_CONST_METHOD0(RemoteSSRC,
-      uint32_t());
-  MOCK_CONST_METHOD1(RemoteCSRCs,
-      int32_t(uint32_t arrOfCSRC[kRtpCsrcSize]));
-  MOCK_CONST_METHOD1(SSRCFilter,
-      int32_t(uint32_t& allowedSSRC));
-  MOCK_METHOD2(SetSSRCFilter,
-      int32_t(const bool enable, const uint32_t allowedSSRC));
-  MOCK_METHOD2(SetRTXReceiveStatus,
-      int32_t(bool enable, uint32_t ssrc));
-  MOCK_CONST_METHOD3(RTXReceiveStatus,
-      int32_t(bool* enable, uint32_t* ssrc, int* payload_type));
-  MOCK_METHOD1(SetRtxReceivePayloadType,
-      void(int));
-  MOCK_METHOD3(IncomingRtpPacket,
-      int32_t(const uint8_t* incomingPacket, const uint16_t packetLength,
-              const webrtc::RTPHeader& header));
   MOCK_METHOD2(IncomingRtcpPacket,
       int32_t(const uint8_t* incomingPacket, uint16_t packetLength));
+  MOCK_METHOD1(SetRemoteSSRC, void(const uint32_t ssrc));
   MOCK_METHOD4(IncomingAudioNTP,
       int32_t(const uint32_t audioReceivedNTPsecs,
               const uint32_t audioReceivedNTPfrac,
@@ -196,16 +152,10 @@
       int32_t(const uint64_t pictureID));
   MOCK_METHOD1(SendRTCPSliceLossIndication,
       int32_t(const uint8_t pictureID));
-  MOCK_METHOD0(ResetStatisticsRTP,
-      int32_t());
-  MOCK_CONST_METHOD5(StatisticsRTP,
-      int32_t(uint8_t *fraction_lost, uint32_t *cum_lost, uint32_t *ext_max, uint32_t *jitter, uint32_t *max_jitter));
-  MOCK_METHOD0(ResetReceiveDataCountersRTP,
-      int32_t());
   MOCK_METHOD0(ResetSendDataCountersRTP,
       int32_t());
-  MOCK_CONST_METHOD4(DataCountersRTP,
-      int32_t(uint32_t *bytesSent, uint32_t *packetsSent, uint32_t *bytesReceived, uint32_t *packetsReceived));
+  MOCK_CONST_METHOD2(DataCountersRTP,
+      int32_t(uint32_t *bytesSent, uint32_t *packetsSent));
   MOCK_METHOD1(RemoteRTCPStat,
       int32_t(RTCPSenderInfo* senderInfo));
   MOCK_CONST_METHOD1(RemoteRTCPStat,
@@ -224,8 +174,6 @@
       int32_t(const bool enable));
   MOCK_METHOD3(SetREMBData,
       int32_t(const uint32_t bitrate, const uint8_t numberOfSSRC, const uint32_t* SSRC));
-  MOCK_METHOD1(SetRemoteBitrateObserver,
-      bool(RemoteBitrateObserver*));
   MOCK_CONST_METHOD0(IJ,
       bool());
   MOCK_METHOD1(SetIJStatus,
@@ -252,9 +200,6 @@
       int32_t(RtpAudioFeedback* messagesCallback));
   MOCK_METHOD1(SetAudioPacketSize,
       int32_t(const uint16_t packetSizeSamples));
-  MOCK_METHOD1(SetTelephoneEventForwardToDecoder, int(bool forwardToDecoder));
-  MOCK_CONST_METHOD0(TelephoneEventForwardToDecoder,
-      bool());
   MOCK_CONST_METHOD1(SendTelephoneEventActive,
       bool(int8_t& telephoneEvent));
   MOCK_METHOD3(SendTelephoneEventOutband,
diff --git a/modules/rtp_rtcp/source/bitrate.cc b/modules/rtp_rtcp/source/bitrate.cc
index e3995ad..1dc314f 100644
--- a/modules/rtp_rtcp/source/bitrate.cc
+++ b/modules/rtp_rtcp/source/bitrate.cc
@@ -57,6 +57,10 @@
   return static_cast<uint32_t>(bitrate);
 }
 
+int64_t Bitrate::time_last_rate_update() const {
+  return time_last_rate_update_;
+}
+
 void Bitrate::Process() {
   // Triggered by timer.
   int64_t now = clock_->TimeInMilliseconds();
diff --git a/modules/rtp_rtcp/source/bitrate.h b/modules/rtp_rtcp/source/bitrate.h
index 49a857c..7599684 100644
--- a/modules/rtp_rtcp/source/bitrate.h
+++ b/modules/rtp_rtcp/source/bitrate.h
@@ -42,6 +42,8 @@
   // Bitrate last second, updated now.
   uint32_t BitrateNow() const;
 
+  int64_t time_last_rate_update() const;
+
  protected:
   Clock* clock_;
 
diff --git a/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h b/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
index 6e1cf93..ccf82e5 100644
--- a/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
+++ b/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h
@@ -12,7 +12,7 @@
 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_PAYLOAD_REGISTRY_H_
 
 #include "testing/gmock/include/gmock/gmock.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
 
 namespace webrtc {
 
@@ -27,6 +27,8 @@
            const uint32_t rate));
   MOCK_CONST_METHOD2(UpdatePayloadRate,
       void(ModuleRTPUtility::Payload* payload, const uint32_t rate));
+  MOCK_CONST_METHOD1(GetPayloadTypeFrequency, int(
+      const ModuleRTPUtility::Payload& payload));
   MOCK_CONST_METHOD5(CreatePayloadType,
       ModuleRTPUtility::Payload*(
           const char payloadName[RTP_PAYLOAD_NAME_SIZE],
diff --git a/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h b/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h
deleted file mode 100644
index ea533ff..0000000
--- a/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_RECEIVER_VIDEO_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_RECEIVER_VIDEO_H_
-
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
-
-namespace webrtc {
-
-class MockRTPReceiverVideo : public RTPReceiverVideo {
- public:
-  MockRTPReceiverVideo() : RTPReceiverVideo(0, NULL, NULL) {}
-  MOCK_METHOD1(ChangeUniqueId,
-      void(const int32_t id));
-  MOCK_METHOD3(ReceiveRecoveredPacketCallback,
-      int32_t(WebRtcRTPHeader* rtpHeader,
-              const uint8_t* payloadData,
-              const uint16_t payloadDataLength));
-  MOCK_METHOD3(CallbackOfReceivedPayloadData,
-      int32_t(const uint8_t* payloadData,
-              const uint16_t payloadSize,
-              const WebRtcRTPHeader* rtpHeader));
-  MOCK_CONST_METHOD0(TimeStamp,
-      uint32_t());
-  MOCK_CONST_METHOD0(SequenceNumber,
-      uint16_t());
-  MOCK_CONST_METHOD2(PayloadTypeToPayload,
-      uint32_t(const uint8_t payloadType,
-               ModuleRTPUtility::Payload*& payload));
-  MOCK_CONST_METHOD2(RetransmitOfOldPacket,
-      bool(const uint16_t sequenceNumber,
-           const uint32_t rtpTimeStamp));
-  MOCK_CONST_METHOD0(REDPayloadType,
-      int8_t());
-  MOCK_CONST_METHOD0(HaveNotReceivedPackets,
-        bool());
-};
-
-}  // namespace webrtc
-
-#endif  //WEBRTC_MODULES_RTP_RTCP_SOURCE_MOCK_MOCK_RTP_RECEIVER_VIDEO_H_
diff --git a/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index e780f5f..ecf4a07 100644
--- a/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -15,7 +15,10 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -30,7 +33,7 @@
 const int kTestNumberOfRtxPackets = 149;
 const int kNumFrames = 30;
 
-class VerifyingRtxReceiver : public RtpData
+class VerifyingRtxReceiver : public NullRtpData
 {
  public:
   VerifyingRtxReceiver() {}
@@ -47,6 +50,20 @@
   std::list<uint16_t> sequence_numbers_;
 };
 
+class TestRtpFeedback : public NullRtpFeedback {
+ public:
+  TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
+  virtual ~TestRtpFeedback() {}
+
+  virtual void OnIncomingSSRCChanged(const int32_t id,
+                                     const uint32_t SSRC) {
+    rtp_rtcp_->SetRemoteSSRC(SSRC);
+  }
+
+ private:
+  RtpRtcp* rtp_rtcp_;
+};
+
 class RtxLoopBackTransport : public webrtc::Transport {
  public:
   explicit RtxLoopBackTransport(uint32_t rtx_ssrc)
@@ -56,11 +73,17 @@
         consecutive_drop_end_(0),
         rtx_ssrc_(rtx_ssrc),
         count_rtx_ssrc_(0),
+        rtp_payload_registry_(NULL),
+        rtp_receiver_(NULL),
         module_(NULL) {
   }
 
-  void SetSendModule(RtpRtcp* rtpRtcpModule) {
+  void SetSendModule(RtpRtcp* rtpRtcpModule,
+                     RTPPayloadRegistry* rtp_payload_registry,
+                     RtpReceiver* receiver) {
     module_ = rtpRtcpModule;
+    rtp_payload_registry_ = rtp_payload_registry;
+    rtp_receiver_ = receiver;
   }
 
   void DropEveryNthPacket(int n) {
@@ -94,8 +117,14 @@
     if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
       return -1;
     }
-    if (module_->IncomingRtpPacket(static_cast<const uint8_t*>(data), len,
-                                   header) < 0) {
+    PayloadUnion payload_specific;
+    if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
+                                                   &payload_specific)) {
+      return -1;
+    }
+    if (!rtp_receiver_->IncomingRtpPacket(&header,
+                                          static_cast<const uint8_t*>(data),
+                                          len, payload_specific, true)) {
       return -1;
     }
     return len;
@@ -113,6 +142,8 @@
   int consecutive_drop_end_;
   uint32_t rtx_ssrc_;
   int count_rtx_ssrc_;
+  RTPPayloadRegistry* rtp_payload_registry_;
+  RtpReceiver* rtp_receiver_;
   RtpRtcp* module_;
   std::set<uint16_t> expected_sequence_numbers_;
 };
@@ -120,7 +151,8 @@
 class RtpRtcpRtxNackTest : public ::testing::Test {
  protected:
   RtpRtcpRtxNackTest()
-      : rtp_rtcp_module_(NULL),
+      : rtp_payload_registry_(0, RTPPayloadStrategy::CreateStrategy(false)),
+        rtp_rtcp_module_(NULL),
         transport_(kTestSsrc + 1),
         receiver_(),
         payload_data_length(sizeof(payload_data)),
@@ -132,19 +164,27 @@
     configuration.id = kTestId;
     configuration.audio = false;
     configuration.clock = &fake_clock;
-    configuration.incoming_data = &receiver_;
+    receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
+    configuration.receive_statistics = receive_statistics_.get();
     configuration.outgoing_transport = &transport_;
     rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration);
 
+    rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
+
+    rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
+        kTestId, &fake_clock, &receiver_, rtp_feedback_.get(),
+        &rtp_payload_registry_));
+
     EXPECT_EQ(0, rtp_rtcp_module_->SetSSRC(kTestSsrc));
     EXPECT_EQ(0, rtp_rtcp_module_->SetRTCPStatus(kRtcpCompound));
-    EXPECT_EQ(0, rtp_rtcp_module_->SetNACKStatus(kNackRtcp, 450));
+    EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
     EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 600));
     EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true));
     EXPECT_EQ(0, rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber));
     EXPECT_EQ(0, rtp_rtcp_module_->SetStartTimestamp(111111));
 
-    transport_.SetSendModule(rtp_rtcp_module_);
+    transport_.SetSendModule(rtp_rtcp_module_, &rtp_payload_registry_,
+                             rtp_receiver_.get());
 
     VideoCodec video_codec;
     memset(&video_codec, 0, sizeof(video_codec));
@@ -152,7 +192,11 @@
     memcpy(video_codec.plName, "I420", 5);
 
     EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec));
-    EXPECT_EQ(0, rtp_rtcp_module_->RegisterReceivePayload(video_codec));
+    EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                                       video_codec.plType,
+                                                       90000,
+                                                       0,
+                                                       video_codec.maxBitrate));
 
     for (int n = 0; n < payload_data_length; n++) {
       payload_data[n] = n % 10;
@@ -196,7 +240,7 @@
   }
 
   void RunRtxTest(RtxMode rtx_method, int loss) {
-    EXPECT_EQ(0, rtp_rtcp_module_->SetRTXReceiveStatus(true, kTestSsrc + 1));
+    rtp_receiver_->SetRTXStatus(true, kTestSsrc + 1);
     EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(rtx_method, true,
         kTestSsrc + 1));
     transport_.DropEveryNthPacket(loss);
@@ -224,7 +268,11 @@
     delete rtp_rtcp_module_;
   }
 
+  scoped_ptr<ReceiveStatistics> receive_statistics_;
+  RTPPayloadRegistry rtp_payload_registry_;
+  scoped_ptr<RtpReceiver> rtp_receiver_;
   RtpRtcp* rtp_rtcp_module_;
+  scoped_ptr<TestRtpFeedback> rtp_feedback_;
   RtxLoopBackTransport transport_;
   VerifyingRtxReceiver receiver_;
   uint8_t  payload_data[65000];
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
new file mode 100644
index 0000000..10be3c5
--- /dev/null
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -0,0 +1,294 @@
+/*
+ *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h"
+
+#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/trace_event.h"
+
+namespace webrtc {
+
+enum { kRateUpdateIntervalMs = 1000 };
+
+ReceiveStatistics* ReceiveStatistics::Create(Clock* clock) {
+  return new ReceiveStatisticsImpl(clock);
+}
+
+ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
+    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+      clock_(clock),
+      incoming_bitrate_(clock),
+      ssrc_(0),
+      jitter_q4_(0),
+      jitter_max_q4_(0),
+      cumulative_loss_(0),
+      jitter_q4_transmission_time_offset_(0),
+      local_time_last_received_timestamp_(0),
+      last_received_timestamp_(0),
+      last_received_transmission_time_offset_(0),
+
+      received_seq_first_(0),
+      received_seq_max_(0),
+      received_seq_wraps_(0),
+
+      received_packet_oh_(12),  // RTP header.
+      received_byte_count_(0),
+      received_retransmitted_packets_(0),
+      received_inorder_packet_count_(0),
+
+      last_report_inorder_packets_(0),
+      last_report_old_packets_(0),
+      last_report_seq_max_(0),
+      last_reported_statistics_() {}
+
+void ReceiveStatisticsImpl::ResetStatistics() {
+  CriticalSectionScoped lock(crit_sect_.get());
+  last_report_inorder_packets_ = 0;
+  last_report_old_packets_ = 0;
+  last_report_seq_max_ = 0;
+  memset(&last_reported_statistics_, 0, sizeof(last_reported_statistics_));
+  jitter_q4_ = 0;
+  jitter_max_q4_ = 0;
+  cumulative_loss_ = 0;
+  jitter_q4_transmission_time_offset_ = 0;
+  received_seq_wraps_ = 0;
+  received_seq_max_ = 0;
+  received_seq_first_ = 0;
+  received_byte_count_ = 0;
+  received_retransmitted_packets_ = 0;
+  received_inorder_packet_count_ = 0;
+}
+
+void ReceiveStatisticsImpl::ResetDataCounters() {
+  CriticalSectionScoped lock(crit_sect_.get());
+  received_byte_count_ = 0;
+  received_retransmitted_packets_ = 0;
+  received_inorder_packet_count_ = 0;
+  last_report_inorder_packets_ = 0;
+}
+
+void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
+                                           size_t bytes,
+                                           bool retransmitted,
+                                           bool in_order) {
+  ssrc_ = header.ssrc;
+  incoming_bitrate_.Update(bytes);
+
+  received_byte_count_ += bytes;
+
+  if (received_seq_max_ == 0 && received_seq_wraps_ == 0) {
+    // This is the first received report.
+    received_seq_first_ = header.sequenceNumber;
+    received_seq_max_ = header.sequenceNumber;
+    received_inorder_packet_count_ = 1;
+    // Current time in samples.
+    local_time_last_received_timestamp_ =
+        ModuleRTPUtility::GetCurrentRTP(clock_, header.payload_type_frequency);
+    return;
+  }
+
+  // Count only the new packets received. That is, if packets 1, 2, 3, 5, 4, 6
+  // are received, 4 will be ignored.
+  if (in_order) {
+    // Current time in samples.
+    const uint32_t RTPtime =
+        ModuleRTPUtility::GetCurrentRTP(clock_, header.payload_type_frequency);
+    received_inorder_packet_count_++;
+
+    // Wrong if we use RetransmitOfOldPacket.
+    int32_t seq_diff =
+        header.sequenceNumber - received_seq_max_;
+    if (seq_diff < 0) {
+      // Wrap around detected.
+      received_seq_wraps_++;
+    }
+    // New max.
+    received_seq_max_ = header.sequenceNumber;
+
+    if (header.timestamp != last_received_timestamp_ &&
+        received_inorder_packet_count_ > 1) {
+      int32_t time_diff_samples =
+          (RTPtime - local_time_last_received_timestamp_) -
+          (header.timestamp - last_received_timestamp_);
+
+      time_diff_samples = abs(time_diff_samples);
+
+      // lib_jingle sometimes deliver crazy jumps in TS for the same stream.
+      // If this happens, don't update jitter value. Use 5 secs video frequency
+      // as the threshold.
+      if (time_diff_samples < 450000) {
+        // Note we calculate in Q4 to avoid using float.
+        int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_;
+        jitter_q4_ += ((jitter_diff_q4 + 8) >> 4);
+      }
+
+      // Extended jitter report, RFC 5450.
+      // Actual network jitter, excluding the source-introduced jitter.
+      int32_t time_diff_samples_ext =
+        (RTPtime - local_time_last_received_timestamp_) -
+        ((header.timestamp +
+          header.extension.transmissionTimeOffset) -
+         (last_received_timestamp_ +
+          last_received_transmission_time_offset_));
+
+      time_diff_samples_ext = abs(time_diff_samples_ext);
+
+      if (time_diff_samples_ext < 450000) {
+        int32_t jitter_diffQ4TransmissionTimeOffset =
+          (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
+        jitter_q4_transmission_time_offset_ +=
+          ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
+      }
+    }
+    last_received_timestamp_ = header.timestamp;
+    local_time_last_received_timestamp_ = RTPtime;
+  } else {
+    if (retransmitted) {
+      received_retransmitted_packets_++;
+    } else {
+      received_inorder_packet_count_++;
+    }
+  }
+
+  uint16_t packet_oh = header.headerLength + header.paddingLength;
+
+  // Our measured overhead. Filter from RFC 5104 4.2.1.2:
+  // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
+  received_packet_oh_ = (15 * received_packet_oh_ + packet_oh) >> 4;
+}
+
+bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
+                                       bool reset) {
+  int32_t missing;
+  return Statistics(statistics, &missing, reset);
+}
+
+bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
+                                       int32_t*  missing, bool reset) {
+  CriticalSectionScoped lock(crit_sect_.get());
+
+  if (missing == NULL) {
+    return false;
+  }
+  if (received_seq_first_ == 0 && received_byte_count_ == 0) {
+    // We have not received anything.
+    return false;
+  }
+  if (!reset) {
+    if (last_report_inorder_packets_ == 0) {
+      // No report.
+      return false;
+    }
+    // Just get last report.
+    *statistics = last_reported_statistics_;
+    return true;
+  }
+
+  if (last_report_inorder_packets_ == 0) {
+    // First time we send a report.
+    last_report_seq_max_ = received_seq_first_ - 1;
+  }
+  // Calculate fraction lost.
+  uint16_t exp_since_last = (received_seq_max_ - last_report_seq_max_);
+
+  if (last_report_seq_max_ > received_seq_max_) {
+    // Can we assume that the seq_num can't go decrease over a full RTCP period?
+    exp_since_last = 0;
+  }
+
+  // Number of received RTP packets since last report, counts all packets but
+  // not re-transmissions.
+  uint32_t rec_since_last =
+      received_inorder_packet_count_ - last_report_inorder_packets_;
+
+  // With NACK we don't know the expected retransmissions during the last
+  // second. We know how many "old" packets we have received. We just count
+  // the number of old received to estimate the loss, but it still does not
+  // guarantee an exact number since we run this based on time triggered by
+  // sending of an RTP packet. This should have a minimum effect.
+
+  // With NACK we don't count old packets as received since they are
+  // re-transmitted. We use RTT to decide if a packet is re-ordered or
+  // re-transmitted.
+  uint32_t retransmitted_packets =
+      received_retransmitted_packets_ - last_report_old_packets_;
+  rec_since_last += retransmitted_packets;
+
+  *missing = 0;
+  if (exp_since_last > rec_since_last) {
+    *missing = (exp_since_last - rec_since_last);
+  }
+  uint8_t local_fraction_lost = 0;
+  if (exp_since_last) {
+    // Scale 0 to 255, where 255 is 100% loss.
+    local_fraction_lost = (uint8_t)((255 * (*missing)) / exp_since_last);
+  }
+  statistics->fraction_lost = local_fraction_lost;
+
+  // We need a counter for cumulative loss too.
+  cumulative_loss_ += *missing;
+
+  if (jitter_q4_ > jitter_max_q4_) {
+    jitter_max_q4_ = jitter_q4_;
+  }
+  statistics->cumulative_lost = cumulative_loss_;
+  statistics->extended_max_sequence_number = (received_seq_wraps_ << 16) +
+      received_seq_max_;
+  // Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
+  statistics->jitter = jitter_q4_ >> 4;
+  statistics->max_jitter = jitter_max_q4_ >> 4;
+  if (reset) {
+    // Store this report.
+    last_reported_statistics_ = *statistics;
+
+    // Only for report blocks in RTCP SR and RR.
+    last_report_inorder_packets_ = received_inorder_packet_count_;
+    last_report_old_packets_ = received_retransmitted_packets_;
+    last_report_seq_max_ = received_seq_max_;
+  }
+  return true;
+}
+
+void ReceiveStatisticsImpl::GetDataCounters(
+    uint32_t* bytes_received, uint32_t* packets_received) const {
+  CriticalSectionScoped lock(crit_sect_.get());
+
+  if (bytes_received) {
+    *bytes_received = received_byte_count_;
+  }
+  if (packets_received) {
+    *packets_received =
+        received_retransmitted_packets_ + received_inorder_packet_count_;
+  }
+}
+
+uint32_t ReceiveStatisticsImpl::BitrateReceived() {
+  return incoming_bitrate_.BitrateNow();
+}
+
+int32_t ReceiveStatisticsImpl::TimeUntilNextProcess() {
+  int time_since_last_update = clock_->TimeInMilliseconds() -
+      incoming_bitrate_.time_last_rate_update();
+  return std::max(kRateUpdateIntervalMs - time_since_last_update, 0);
+}
+
+int32_t ReceiveStatisticsImpl::Process() {
+  incoming_bitrate_.Process();
+  TRACE_COUNTER_ID1("webrtc_rtp", "RTPReceiverBitrate", ssrc_,
+                    incoming_bitrate_.BitrateLast());
+  TRACE_COUNTER_ID1("webrtc_rtp", "RTPReceiverPacketRate", ssrc_,
+                    incoming_bitrate_.PacketRate());
+  return 0;
+}
+
+}  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h
new file mode 100644
index 0000000..1207606
--- /dev/null
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -0,0 +1,77 @@
+/*
+ *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
+
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
+
+#include <algorithm>
+
+#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+class CriticalSectionWrapper;
+
+class ReceiveStatisticsImpl : public ReceiveStatistics {
+ public:
+  explicit ReceiveStatisticsImpl(Clock* clock);
+
+  // Implements ReceiveStatistics.
+  void IncomingPacket(const RTPHeader& header, size_t bytes,
+                      bool old_packet, bool in_order);
+  bool Statistics(RtpReceiveStatistics* statistics, bool reset);
+  bool Statistics(RtpReceiveStatistics* statistics, int32_t* missing,
+                  bool reset);
+  void GetDataCounters(uint32_t* bytes_received,
+                       uint32_t* packets_received) const;
+  uint32_t BitrateReceived();
+  void ResetStatistics();
+  void ResetDataCounters();
+
+  // Implements Module.
+  int32_t TimeUntilNextProcess();
+  int32_t Process();
+
+ private:
+  scoped_ptr<CriticalSectionWrapper> crit_sect_;
+  Clock* clock_;
+  Bitrate incoming_bitrate_;
+  uint32_t ssrc_;
+  // Stats on received RTP packets.
+  uint32_t jitter_q4_;
+  uint32_t jitter_max_q4_;
+  uint32_t cumulative_loss_;
+  uint32_t jitter_q4_transmission_time_offset_;
+
+  uint32_t local_time_last_received_timestamp_;
+  uint32_t last_received_timestamp_;
+  int32_t last_received_transmission_time_offset_;
+  uint16_t received_seq_first_;
+  uint16_t received_seq_max_;
+  uint16_t received_seq_wraps_;
+
+  // Current counter values.
+  uint16_t received_packet_oh_;
+  uint32_t received_byte_count_;
+  uint32_t received_retransmitted_packets_;
+  uint32_t received_inorder_packet_count_;
+
+  // Counter values when we sent the last report.
+  uint32_t last_report_inorder_packets_;
+  uint32_t last_report_old_packets_;
+  uint16_t last_report_seq_max_;
+  RtpReceiveStatistics last_reported_statistics_;
+};
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
diff --git a/modules/rtp_rtcp/source/receiver_fec.cc b/modules/rtp_rtcp/source/receiver_fec.cc
index e99cd4d..aa90702 100644
--- a/modules/rtp_rtcp/source/receiver_fec.cc
+++ b/modules/rtp_rtcp/source/receiver_fec.cc
@@ -14,14 +14,16 @@
 
 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
 // RFC 5109
 namespace webrtc {
-ReceiverFEC::ReceiverFEC(const int32_t id, RTPReceiverVideo* owner)
+ReceiverFEC::ReceiverFEC(const int32_t id, RtpData* callback)
     : id_(id),
-      owner_(owner),
+      crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+      recovered_packet_callback_(callback),
       fec_(new ForwardErrorCorrection(id)),
       payload_type_fec_(-1) {}
 
@@ -42,6 +44,7 @@
 }
 
 void ReceiverFEC::SetPayloadTypeFEC(const int8_t payload_type) {
+  CriticalSectionScoped cs(crit_sect_.get());
   payload_type_fec_ = payload_type;
 }
 //     0                   1                    2                   3
@@ -76,6 +79,8 @@
                                           const uint8_t* incoming_rtp_packet,
                                           const uint16_t payload_data_length,
                                           bool& FECpacket) {
+  CriticalSectionScoped cs(crit_sect_.get());
+
   if (payload_type_fec_ == -1) {
     return -1;
   }
@@ -221,12 +226,18 @@
 }
 
 int32_t ReceiverFEC::ProcessReceivedFEC() {
+  crit_sect_->Enter();
   if (!received_packet_list_.empty()) {
     // Send received media packet to VCM.
     if (!received_packet_list_.front()->is_fec) {
-      if (ParseAndReceivePacket(received_packet_list_.front()->pkt) != 0) {
+      ForwardErrorCorrection::Packet* packet =
+          received_packet_list_.front()->pkt;
+      crit_sect_->Leave();
+      if (!recovered_packet_callback_->OnRecoveredPacket(packet->data,
+                                                         packet->length)) {
         return -1;
       }
+      crit_sect_->Enter();
     }
     if (fec_->DecodeFEC(&received_packet_list_, &recovered_packet_list_) != 0) {
       return -1;
@@ -239,27 +250,16 @@
   for (; it != recovered_packet_list_.end(); ++it) {
     if ((*it)->returned)  // Already sent to the VCM and the jitter buffer.
       continue;
-    if (ParseAndReceivePacket((*it)->pkt) != 0) {
+    ForwardErrorCorrection::Packet* packet = (*it)->pkt;
+    crit_sect_->Leave();
+    if (!recovered_packet_callback_->OnRecoveredPacket(packet->data,
+                                                       packet->length)) {
       return -1;
     }
+    crit_sect_->Enter();
     (*it)->returned = true;
   }
-  return 0;
-}
-
-int ReceiverFEC::ParseAndReceivePacket(
-    const ForwardErrorCorrection::Packet* packet) {
-  WebRtcRTPHeader header;
-  memset(&header, 0, sizeof(header));
-  ModuleRTPUtility::RTPHeaderParser parser(packet->data, packet->length);
-  if (!parser.Parse(header.header)) {
-    return -1;
-  }
-  if (owner_->ReceiveRecoveredPacketCallback(
-          &header, &packet->data[header.header.headerLength],
-          packet->length - header.header.headerLength) != 0) {
-    return -1;
-  }
+  crit_sect_->Leave();
   return 0;
 }
 
diff --git a/modules/rtp_rtcp/source/receiver_fec.h b/modules/rtp_rtcp/source/receiver_fec.h
index 2a13975..653a93e 100644
--- a/modules/rtp_rtcp/source/receiver_fec.h
+++ b/modules/rtp_rtcp/source/receiver_fec.h
@@ -15,14 +15,16 @@
 
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
-class RTPReceiverVideo;
+
+class CriticalSectionWrapper;
 
 class ReceiverFEC {
  public:
-  ReceiverFEC(const int32_t id, RTPReceiverVideo* owner);
+  ReceiverFEC(const int32_t id, RtpData* callback);
   virtual ~ReceiverFEC();
 
   int32_t AddReceivedFECPacket(const WebRtcRTPHeader* rtp_header,
@@ -35,10 +37,9 @@
   void SetPayloadTypeFEC(const int8_t payload_type);
 
  private:
-  int ParseAndReceivePacket(const ForwardErrorCorrection::Packet* packet);
-
   int id_;
-  RTPReceiverVideo* owner_;
+  scoped_ptr<CriticalSectionWrapper> crit_sect_;
+  RtpData* recovered_packet_callback_;
   ForwardErrorCorrection* fec_;
   // TODO(holmer): In the current version received_packet_list_ is never more
   // than one packet, since we process FEC every time a new packet
diff --git a/modules/rtp_rtcp/source/receiver_fec_unittest.cc b/modules/rtp_rtcp/source/receiver_fec_unittest.cc
index 46b8eb4..981f237 100644
--- a/modules/rtp_rtcp/source/receiver_fec_unittest.cc
+++ b/modules/rtp_rtcp/source/receiver_fec_unittest.cc
@@ -16,20 +16,31 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
-#include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h"
 #include "webrtc/modules/rtp_rtcp/source/receiver_fec.h"
 
 using ::testing::_;
 using ::testing::Args;
 using ::testing::ElementsAreArray;
+using ::testing::Return;
 
 namespace webrtc {
 
+class MockRtpData : public RtpData {
+ public:
+  MOCK_METHOD3(OnReceivedPayloadData,
+      int32_t(const uint8_t* payloadData,
+              const uint16_t payloadSize,
+              const WebRtcRTPHeader* rtpHeader));
+
+  MOCK_METHOD2(OnRecoveredPacket,
+      bool(const uint8_t* packet, int packet_length));
+};
+
 class ReceiverFecTest : public ::testing::Test {
  protected:
   virtual void SetUp() {
     fec_ = new ForwardErrorCorrection(0);
-    receiver_fec_ = new ReceiverFEC(0, &rtp_receiver_video_);
+    receiver_fec_ = new ReceiverFEC(0, &rtp_data_callback_);
     generator_ = new FrameGenerator();
     receiver_fec_->SetPayloadTypeFEC(kFecPayloadType);
   }
@@ -64,11 +75,10 @@
     // Verify that the content of the reconstructed packet is equal to the
     // content of |packet|, and that the same content is received |times| number
     // of times in a row.
-    EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(
-                                         _, _, packet->length - kRtpHeaderSize))
-        .With(Args<1, 2>(ElementsAreArray(packet->data + kRtpHeaderSize,
-                                          packet->length - kRtpHeaderSize)))
-        .Times(times);
+    EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, packet->length))
+        .With(Args<0, 1>(ElementsAreArray(packet->data,
+                                          packet->length)))
+        .Times(times).WillRepeatedly(Return(true));
   }
 
   void BuildAndAddRedMediaPacket(RtpPacket* packet) {
@@ -92,7 +102,7 @@
   }
 
   ForwardErrorCorrection* fec_;
-  MockRTPReceiverVideo rtp_receiver_video_;
+  MockRtpData rtp_data_callback_;
   ReceiverFEC* receiver_fec_;
   FrameGenerator* generator_;
 };
@@ -255,8 +265,8 @@
   GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1);
 
   BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
-  EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-      .Times(1);
+  EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+      .Times(1).WillRepeatedly(Return(true));
   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
   delayed_fec = fec_packets.front();
 
@@ -270,15 +280,15 @@
   for (std::list<RtpPacket*>::iterator it = media_rtp_packets_batch2.begin();
        it != media_rtp_packets_batch2.end(); ++it) {
     BuildAndAddRedMediaPacket(*it);
-    EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-        .Times(1);
+    EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+        .Times(1).WillRepeatedly(Return(true));
     EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
   }
 
   // Add the delayed FEC packet. One packet should be reconstructed.
   BuildAndAddRedFecPacket(delayed_fec);
-  EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-      .Times(1);
+  EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+      .Times(1).WillRepeatedly(Return(true));
   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
 
   DeletePackets(&media_packets_batch1);
@@ -299,8 +309,8 @@
   GenerateFEC(&media_packets_batch1, &fec_packets, kNumFecPacketsBatch1);
 
   BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
-  EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-      .Times(1);
+  EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+      .Times(1).WillRepeatedly(Return(true));
   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
   delayed_fec = fec_packets.front();
 
@@ -314,15 +324,15 @@
   for (std::list<RtpPacket*>::iterator it = media_rtp_packets_batch2.begin();
        it != media_rtp_packets_batch2.end(); ++it) {
     BuildAndAddRedMediaPacket(*it);
-    EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-        .Times(1);
+    EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+        .Times(1).WillRepeatedly(Return(true));
     EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
   }
 
   // Add the delayed FEC packet. No packet should be reconstructed since the
   // first media packet of that frame has been dropped due to being too old.
   BuildAndAddRedFecPacket(delayed_fec);
-  EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
+  EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
       .Times(0);
   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
 
@@ -346,7 +356,7 @@
          it != fec_packets.end(); ++it) {
       // Only FEC packets inserted. No packets recoverable at this time.
       BuildAndAddRedFecPacket(*it);
-      EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
+      EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
           .Times(0);
       EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
     }
@@ -360,8 +370,8 @@
   // and should've been dropped. Only the media packet we inserted will be
   // returned.
   BuildAndAddRedMediaPacket(media_rtp_packets.front());
-  EXPECT_CALL(rtp_receiver_video_, ReceiveRecoveredPacketCallback(_, _, _))
-      .Times(1);
+  EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+      .Times(1).WillRepeatedly(Return(true));
   EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
 
   DeletePackets(&media_packets);
diff --git a/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc b/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
index 10566d6..e7c7bcb 100644
--- a/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_format_remb_unittest.cc
@@ -115,13 +115,15 @@
   uint32_t SSRC = 456789;
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpNonCompound));
   EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 1, &SSRC));
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb));
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb, NULL));
 }
 
 TEST_F(RtcpFormatRembTest, TestCompund) {
   uint32_t SSRCs[2] = {456789, 98765};
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
   EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 2, SSRCs));
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb));
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  memset(&receive_stats, 0, sizeof(receive_stats));
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb, &receive_stats));
 }
 }  // namespace
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index b86728a..698325c 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -141,6 +141,11 @@
     return 0;
 }
 
+uint32_t RTCPReceiver::RemoteSSRC() const {
+  CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
+  return _remoteSSRC;
+}
+
 void RTCPReceiver::RegisterRtcpObservers(
     RtcpIntraFrameObserver* intra_frame_callback,
     RtcpBandwidthObserver* bandwidth_callback,
@@ -183,7 +188,7 @@
   return 0;
 }
 
-int32_t RTCPReceiver::RTT(const uint32_t remoteSSRC,
+int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
                           uint16_t* RTT,
                           uint16_t* avgRTT,
                           uint16_t* minRTT,
@@ -1410,43 +1415,4 @@
   return num;
 }
 
-int32_t
-RTCPReceiver::SetPacketTimeout(const uint32_t timeoutMS)
-{
-    CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
-    _packetTimeOutMS = timeoutMS;
-    return 0;
-}
-
-void RTCPReceiver::PacketTimeout()
-{
-    if(_packetTimeOutMS == 0)
-    {
-        // not configured
-        return;
-    }
-
-    bool packetTimeOut = false;
-    {
-        CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
-        if(_lastReceived == 0)
-        {
-            // not active
-            return;
-        }
-
-        int64_t now = _clock->TimeInMilliseconds();
-        if(now - _lastReceived > _packetTimeOutMS)
-        {
-            packetTimeOut = true;
-            _lastReceived = 0;  // only one callback
-        }
-    }
-    CriticalSectionScoped lock(_criticalSectionFeedbacks);
-    if(packetTimeOut && _cbRtcpFeedback)
-    {
-        _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
-    }
-}
-
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index a86eef4..45e3b68 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -42,6 +42,7 @@
     void SetSSRC( const uint32_t ssrc);
     void SetRelaySSRC( const uint32_t ssrc);
     int32_t SetRemoteSSRC( const uint32_t ssrc);
+    uint32_t RemoteSSRC() const;
 
     uint32_t RelaySSRC() const;
 
@@ -67,7 +68,7 @@
                 uint32_t *rtcp_timestamp) const;
 
     // get rtt
-    int32_t RTT(const uint32_t remoteSSRC,
+    int32_t RTT(uint32_t remoteSSRC,
                 uint16_t* RTT,
                 uint16_t* avgRTT,
                 uint16_t* minRTT,
@@ -106,9 +107,6 @@
 
     int32_t UpdateTMMBR();
 
-    int32_t SetPacketTimeout(const uint32_t timeoutMS);
-    void PacketTimeout();
-
 protected:
     RTCPHelp::RTCPReportBlockInformation* CreateReportBlockInformation(const uint32_t remoteSSRC);
     RTCPHelp::RTCPReportBlockInformation* GetReportBlockInformation(const uint32_t remoteSSRC) const;
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 445c553..d5c1120 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -136,7 +136,7 @@
 
 // This test transport verifies that no functions get called.
 class TestTransport : public Transport,
-                      public RtpData {
+                      public NullRtpData {
  public:
   explicit TestTransport()
       : rtcp_receiver_(NULL) {
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 2905737..ff9190d 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -268,7 +268,7 @@
     }
     if(sendRTCPBye)
     {
-        return SendRTCP(kRtcpBye);
+        return SendRTCP(kRtcpBye, NULL);
     }
     return 0;
 }
@@ -373,12 +373,10 @@
     _SSRC = ssrc;
 }
 
-int32_t
-RTCPSender::SetRemoteSSRC( const uint32_t ssrc)
+void RTCPSender::SetRemoteSSRC(uint32_t ssrc)
 {
     CriticalSectionScoped lock(_criticalSectionRTCPSender);
     _remoteSSRC = ssrc;
-    return 0;
 }
 
 int32_t
@@ -1534,11 +1532,13 @@
 }
 
 int32_t
-RTCPSender::SendRTCP(const uint32_t packetTypeFlags,
-                     const int32_t nackSize,       // NACK
-                     const uint16_t* nackList,     // NACK
-                     const bool repeat,                  // FIR
-                     const uint64_t pictureID)     // SLI & RPSI
+RTCPSender::SendRTCP(
+    uint32_t packetTypeFlags,
+    const ReceiveStatistics::RtpReceiveStatistics* receive_stats,
+    int32_t nackSize,
+    const uint16_t* nackList,
+    bool repeat,
+    uint64_t pictureID)
 {
     uint32_t rtcpPacketTypeFlags = packetTypeFlags;
     uint32_t pos = 0;
@@ -1570,13 +1570,15 @@
             rtcpPacketTypeFlags & kRtcpSr ||
             rtcpPacketTypeFlags & kRtcpRr)
         {
-            // get statistics from our RTPreceiver outside critsect
-            if(_rtpRtcp.ReportBlockStatistics(&received.fractionLost,
-                                              &received.cumulativeLost,
-                                              &received.extendedHighSeqNum,
-                                              &received.jitter,
-                                              &jitterTransmissionOffset) == 0)
+            // Do we have receive statistics to send?
+            if (receive_stats)
             {
+                received.fractionLost = receive_stats->fraction_lost;
+                received.cumulativeLost = receive_stats->cumulative_lost;
+                received.extendedHighSeqNum =
+                    receive_stats->extended_max_sequence_number;
+                received.jitter = receive_stats->jitter;
+                jitterTransmissionOffset = 0;
                 hasReceived = true;
 
                 uint32_t lastReceivedRRNTPsecs = 0;
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index 9be2f3f..06c07f4 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -17,6 +17,7 @@
 
 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -26,7 +27,7 @@
 
 namespace webrtc {
 
-class ModuleRtpRtcpImpl; 
+class ModuleRtpRtcpImpl;
 
 class NACKStringBuilder
 {
@@ -70,7 +71,7 @@
 
     void SetSSRC( const uint32_t ssrc);
 
-    int32_t SetRemoteSSRC( const uint32_t ssrc);
+    void SetRemoteSSRC(uint32_t ssrc);
 
     int32_t SetCameraDelay(const int32_t delayMS);
 
@@ -88,11 +89,13 @@
 
     uint32_t LastSendReport(uint32_t& lastRTCPTime);
 
-    int32_t SendRTCP(const uint32_t rtcpPacketTypeFlags,
-                     const int32_t nackSize = 0,
-                     const uint16_t* nackList = 0,
-                     const bool repeat = false,
-                     const uint64_t pictureID = 0);
+    int32_t SendRTCP(
+        uint32_t rtcpPacketTypeFlags,
+        const ReceiveStatistics::RtpReceiveStatistics* receive_stats,
+        int32_t nackSize = 0,
+        const uint16_t* nackList = 0,
+        bool repeat = false,
+        uint64_t pictureID = 0);
 
     int32_t AddReportBlock(const uint32_t SSRC,
                            const RTCPReportBlock* receiveBlock);
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 9b1d15c..3c0681d 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -20,9 +20,12 @@
 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
 
 namespace webrtc {
@@ -216,7 +219,7 @@
 }
 
 class TestTransport : public Transport,
-                      public RtpData {
+                      public NullRtpData {
  public:
   TestTransport()
       : rtcp_receiver_(NULL) {
@@ -276,6 +279,8 @@
   RtcpSenderTest()
       : over_use_detector_options_(),
         system_clock_(Clock::GetRealTimeClock()),
+        rtp_payload_registry_(new RTPPayloadRegistry(
+            0, RTPPayloadStrategy::CreateStrategy(false))),
         remote_bitrate_observer_(),
         remote_bitrate_estimator_(
             RemoteBitrateEstimatorFactory().Create(
@@ -287,11 +292,12 @@
     configuration.id = 0;
     configuration.audio = false;
     configuration.clock = system_clock_;
-    configuration.incoming_data = test_transport_;
     configuration.outgoing_transport = test_transport_;
     configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
 
     rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
+    rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
+        0, system_clock_, test_transport_, NULL, rtp_payload_registry_.get()));
     rtcp_sender_ = new RTCPSender(0, false, system_clock_, rtp_rtcp_impl_);
     rtcp_receiver_ = new RTCPReceiver(0, system_clock_, rtp_rtcp_impl_);
     test_transport_->SetRTCPReceiver(rtcp_receiver_);
@@ -314,6 +320,8 @@
 
   OverUseDetectorOptions over_use_detector_options_;
   Clock* system_clock_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+  scoped_ptr<RtpReceiver> rtp_receiver_;
   ModuleRtpRtcpImpl* rtp_rtcp_impl_;
   RTCPSender* rtcp_sender_;
   RTCPReceiver* rtcp_receiver_;
@@ -327,7 +335,7 @@
 
 TEST_F(RtcpSenderTest, RtcpOff) {
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpOff));
-  EXPECT_EQ(-1, rtcp_sender_->SendRTCP(kRtcpSr));
+  EXPECT_EQ(-1, rtcp_sender_->SendRTCP(kRtcpSr, NULL));
 }
 
 TEST_F(RtcpSenderTest, IJStatus) {
@@ -351,18 +359,27 @@
   strncpy(codec_inst.plName, "VP8", webrtc::kPayloadNameSize - 1);
   codec_inst.codecType = webrtc::kVideoCodecVP8;
   codec_inst.plType = payload;
-  EXPECT_EQ(0, rtp_rtcp_impl_->RegisterReceivePayload(codec_inst));
+  EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec_inst.plName,
+                                                     codec_inst.plType,
+                                                     90000,
+                                                     0,
+                                                     codec_inst.maxBitrate));
 
   // Make sure RTP packet has been received.
   scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
   RTPHeader header;
   EXPECT_TRUE(parser->Parse(packet_, packet_length, &header));
-  EXPECT_EQ(0, rtp_rtcp_impl_->IncomingRtpPacket(packet_, packet_length,
-                                                 header));
+  PayloadUnion payload_specific;
+  EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
+                                                        &payload_specific));
+  EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(&header, packet_, packet_length,
+                                               payload_specific, true));
 
   EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr));
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  memset(&receive_stats, 0, sizeof(receive_stats));
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr, &receive_stats));
 
   // Transmission time offset packet should be received.
   ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
@@ -372,7 +389,9 @@
 TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) {
   EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
   EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr));
+  // |receive_stats| is NULL since no data has been received.
+  ReceiveStatistics::RtpReceiveStatistics* receive_stats = NULL;
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr, receive_stats));
 
   // Transmission time offset packet should not be received.
   ASSERT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
@@ -390,7 +409,9 @@
   TMMBRSet bounding_set;
   EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
   ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr));
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  memset(&receive_stats, 0, sizeof(receive_stats));
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr, &receive_stats));
   // We now expect the packet to show up in the rtcp_packet_info_ of
   // test_transport_.
   ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
@@ -412,7 +433,9 @@
 
   EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
   ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
-  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr));
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  memset(&receive_stats, 0, sizeof(receive_stats));
+  EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr, &receive_stats));
   // We now expect the packet to show up in the rtcp_packet_info_ of
   // test_transport_.
   ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry.cc b/modules/rtp_rtcp/source/rtp_payload_registry.cc
index cb689ee..dee05fe 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
 
 #include "webrtc/system_wrappers/interface/trace.h"
 
@@ -21,8 +21,7 @@
       rtp_payload_strategy_(rtp_payload_strategy),
       red_payload_type_(-1),
       last_received_payload_type_(-1),
-      last_received_media_payload_type_(-1) {
-}
+      last_received_media_payload_type_(-1) {}
 
 RTPPayloadRegistry::~RTPPayloadRegistry() {
   while (!payload_type_map_.empty()) {
@@ -226,7 +225,29 @@
   return -1;
 }
 
-int32_t RTPPayloadRegistry::PayloadTypeToPayload(
+bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type,
+                                             PayloadUnion* payload) const {
+  ModuleRTPUtility::PayloadTypeMap::const_iterator it =
+    payload_type_map_.find(payload_type);
+
+  // Check that this is a registered payload type.
+  if (it == payload_type_map_.end()) {
+    return false;
+  }
+  *payload = it->second->typeSpecific;
+  return true;
+}
+
+int RTPPayloadRegistry::GetPayloadTypeFrequency(
+    uint8_t payload_type) const {
+  ModuleRTPUtility::Payload* payload;
+  if (!PayloadTypeToPayload(payload_type, payload)) {
+    return -1;
+  }
+  return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload);
+}
+
+bool RTPPayloadRegistry::PayloadTypeToPayload(
   const uint8_t payload_type,
   ModuleRTPUtility::Payload*& payload) const {
 
@@ -235,10 +256,10 @@
 
   // Check that this is a registered payload type.
   if (it == payload_type_map_.end()) {
-    return -1;
+    return false;
   }
   payload = it->second;
-  return 0;
+  return true;
 }
 
 bool RTPPayloadRegistry::ReportMediaPayloadType(
@@ -289,6 +310,11 @@
     payload->audio = true;
     return payload;
   }
+
+  int GetPayloadTypeFrequency(
+      const ModuleRTPUtility::Payload& payload) const {
+    return payload.typeSpecific.Audio.frequency;
+  }
 };
 
 class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
@@ -315,15 +341,15 @@
       const uint32_t frequency,
       const uint8_t channels,
       const uint32_t rate) const {
-    RtpVideoCodecTypes videoType = kRtpGenericVideo;
+    RtpVideoCodecTypes videoType = kRtpVideoGeneric;
     if (ModuleRTPUtility::StringCompare(payloadName, "VP8", 3)) {
-      videoType = kRtpVp8Video;
+      videoType = kRtpVideoVp8;
     } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
-      videoType = kRtpGenericVideo;
+      videoType = kRtpVideoGeneric;
     } else if (ModuleRTPUtility::StringCompare(payloadName, "ULPFEC", 6)) {
-      videoType = kRtpFecVideo;
+      videoType = kRtpVideoFec;
     } else {
-      videoType = kRtpGenericVideo;
+      videoType = kRtpVideoGeneric;
     }
     ModuleRTPUtility::Payload* payload = new ModuleRTPUtility::Payload;
 
@@ -334,6 +360,11 @@
     payload->audio = false;
     return payload;
   }
+
+  int GetPayloadTypeFrequency(
+      const ModuleRTPUtility::Payload& payload) const {
+    return kVideoPayloadTypeFrequency;
+  }
 };
 
 RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy(
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc b/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
index 2f1e916..8ef1074 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -74,8 +74,8 @@
   EXPECT_TRUE(new_payload_created) << "A new payload WAS created.";
 
   ModuleRTPUtility::Payload* retrieved_payload = NULL;
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(payload_type,
-                                                           retrieved_payload));
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
+                                                          retrieved_payload));
 
   // We should get back the exact pointer to the payload returned by the
   // payload strategy.
@@ -83,7 +83,7 @@
 
   // Now forget about it and verify it's gone.
   EXPECT_EQ(0, rtp_payload_registry_->DeRegisterReceivePayload(payload_type));
-  EXPECT_EQ(-1, rtp_payload_registry_->PayloadTypeToPayload(
+  EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
       payload_type, retrieved_payload));
 }
 
@@ -101,8 +101,8 @@
   ASSERT_EQ(red_type_of_the_day, rtp_payload_registry_->red_payload_type());
 
   ModuleRTPUtility::Payload* retrieved_payload = NULL;
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(red_type_of_the_day,
-                                                           retrieved_payload));
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(red_type_of_the_day,
+                                                          retrieved_payload));
   EXPECT_FALSE(retrieved_payload->audio);
   EXPECT_STRCASEEQ("red", retrieved_payload->name);
 }
@@ -131,11 +131,11 @@
 
   // Ensure both payloads are preserved.
   ModuleRTPUtility::Payload* retrieved_payload = NULL;
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(payload_type,
-                                                           retrieved_payload));
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
+                                                          retrieved_payload));
   EXPECT_EQ(first_payload_on_heap, retrieved_payload);
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
-                                                           retrieved_payload));
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
+                                                          retrieved_payload));
   EXPECT_EQ(second_payload_on_heap, retrieved_payload);
 
   // Ok, update the rate for one of the codecs. If either the incoming rate or
@@ -170,10 +170,10 @@
       kTypicalChannels, kTypicalRate, &ignored));
 
   ModuleRTPUtility::Payload* retrieved_payload = NULL;
-  EXPECT_EQ(-1, rtp_payload_registry_->PayloadTypeToPayload(
+  EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
       payload_type, retrieved_payload)) << "The first payload should be "
           "deregistered because the only thing that differs is payload type.";
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
       payload_type - 1, retrieved_payload)) <<
           "The second payload should still be registered though.";
 
@@ -185,10 +185,10 @@
       kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
       kTypicalChannels, kTypicalRate, &ignored));
 
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
       payload_type - 1, retrieved_payload)) <<
           "Not compatible; both payloads should be kept.";
-  EXPECT_EQ(0, rtp_payload_registry_->PayloadTypeToPayload(
+  EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
       payload_type + 1, retrieved_payload)) <<
           "Not compatible; both payloads should be kept.";
 }
diff --git a/modules/rtp_rtcp/source/rtp_receiver.cc b/modules/rtp_rtcp/source/rtp_receiver.cc
deleted file mode 100644
index 4fc557f..0000000
--- a/modules/rtp_rtcp/source/rtp_receiver.cc
+++ /dev/null
@@ -1,1140 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver.h"
-
-#include <cassert>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
-#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/interface/trace.h"
-#include "webrtc/system_wrappers/interface/trace_event.h"
-
-namespace webrtc {
-
-using ModuleRTPUtility::AudioPayload;
-using ModuleRTPUtility::GetCurrentRTP;
-using ModuleRTPUtility::Payload;
-using ModuleRTPUtility::RTPPayloadParser;
-using ModuleRTPUtility::StringCompare;
-using ModuleRTPUtility::VideoPayload;
-
-RTPReceiver::RTPReceiver(const int32_t id,
-                         Clock* clock,
-                         ModuleRtpRtcpImpl* owner,
-                         RtpAudioFeedback* incoming_audio_messages_callback,
-                         RtpData* incoming_payload_callback,
-                         RtpFeedback* incoming_messages_callback,
-                         RTPReceiverStrategy* rtp_media_receiver,
-                         RTPPayloadRegistry* rtp_payload_registry)
-    : Bitrate(clock),
-      rtp_payload_registry_(rtp_payload_registry),
-      rtp_media_receiver_(rtp_media_receiver),
-      id_(id),
-      rtp_rtcp_(*owner),
-      cb_rtp_feedback_(incoming_messages_callback),
-
-      critical_section_rtp_receiver_(
-        CriticalSectionWrapper::CreateCriticalSection()),
-      last_receive_time_(0),
-      last_received_payload_length_(0),
-
-      packet_timeout_ms_(0),
-
-      ssrc_(0),
-      num_csrcs_(0),
-      current_remote_csrc_(),
-      num_energy_(0),
-      current_remote_energy_(),
-      use_ssrc_filter_(false),
-      ssrc_filter_(0),
-
-      jitter_q4_(0),
-      jitter_max_q4_(0),
-      cumulative_loss_(0),
-      jitter_q4_transmission_time_offset_(0),
-      local_time_last_received_timestamp_(0),
-      last_received_frame_time_ms_(0),
-      last_received_timestamp_(0),
-      last_received_sequence_number_(0),
-      last_received_transmission_time_offset_(0),
-
-      received_seq_first_(0),
-      received_seq_max_(0),
-      received_seq_wraps_(0),
-
-      received_packet_oh_(12),  // RTP header.
-      received_byte_count_(0),
-      received_old_packet_count_(0),
-      received_inorder_packet_count_(0),
-
-      last_report_inorder_packets_(0),
-      last_report_old_packets_(0),
-      last_report_seq_max_(0),
-      last_report_fraction_lost_(0),
-      last_report_cumulative_lost_(0),
-      last_report_extended_high_seq_num_(0),
-      last_report_jitter_(0),
-      last_report_jitter_transmission_time_offset_(0),
-
-      nack_method_(kNackOff),
-      max_reordering_threshold_(kDefaultMaxReorderingThreshold),
-      rtx_(false),
-      ssrc_rtx_(0),
-      payload_type_rtx_(-1) {
-  assert(incoming_audio_messages_callback &&
-         incoming_messages_callback &&
-         incoming_payload_callback);
-
-  memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_));
-  memset(current_remote_energy_, 0, sizeof(current_remote_energy_));
-
-  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
-}
-
-RTPReceiver::~RTPReceiver() {
-  for (int i = 0; i < num_csrcs_; ++i) {
-    cb_rtp_feedback_->OnIncomingCSRCChanged(id_, current_remote_csrc_[i],
-                                            false);
-  }
-  delete critical_section_rtp_receiver_;
-  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id_, "%s deleted", __FUNCTION__);
-}
-
-RtpVideoCodecTypes RTPReceiver::VideoCodecType() const {
-  ModuleRTPUtility::PayloadUnion media_specific;
-  rtp_media_receiver_->GetLastMediaSpecificPayload(&media_specific);
-  return media_specific.Video.videoCodecType;
-}
-
-uint32_t RTPReceiver::MaxConfiguredBitrate() const {
-  ModuleRTPUtility::PayloadUnion media_specific;
-  rtp_media_receiver_->GetLastMediaSpecificPayload(&media_specific);
-  return media_specific.Video.maxRate;
-}
-
-bool RTPReceiver::REDPayloadType(const int8_t payload_type) const {
-  return rtp_payload_registry_->red_payload_type() == payload_type;
-}
-
-int8_t RTPReceiver::REDPayloadType() const {
-  return rtp_payload_registry_->red_payload_type();
-}
-
-int32_t RTPReceiver::SetPacketTimeout(const uint32_t timeout_ms) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  packet_timeout_ms_ = timeout_ms;
-  return 0;
-}
-
-bool RTPReceiver::HaveNotReceivedPackets() const {
-  return last_receive_time_ == 0;
-}
-
-void RTPReceiver::PacketTimeout() {
-  bool packet_time_out = false;
-  {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_);
-    if (packet_timeout_ms_ == 0) {
-      // Not configured.
-      return;
-    }
-
-    if (HaveNotReceivedPackets()) {
-      // Not active.
-      return;
-    }
-
-    int64_t now = clock_->TimeInMilliseconds();
-
-    if (now - last_receive_time_ > packet_timeout_ms_) {
-      packet_time_out = true;
-      last_receive_time_ = 0;            // Only one callback.
-      rtp_payload_registry_->ResetLastReceivedPayloadTypes();
-    }
-  }
-  if (packet_time_out) {
-    cb_rtp_feedback_->OnPacketTimeout(id_);
-  }
-}
-
-void RTPReceiver::ProcessDeadOrAlive(const bool rtcp_alive,
-                                     const int64_t now) {
-  RTPAliveType alive = kRtpDead;
-
-  if (last_receive_time_ + 1000 > now) {
-    // Always alive if we have received a RTP packet the last second.
-    alive = kRtpAlive;
-
-  } else {
-    if (rtcp_alive) {
-      alive = rtp_media_receiver_->ProcessDeadOrAlive(
-          last_received_payload_length_);
-    } else {
-      // No RTP packet for 1 sec and no RTCP: dead.
-    }
-  }
-
-  cb_rtp_feedback_->OnPeriodicDeadOrAlive(id_, alive);
-}
-
-uint16_t RTPReceiver::PacketOHReceived() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return received_packet_oh_;
-}
-
-uint32_t RTPReceiver::PacketCountReceived() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return received_inorder_packet_count_;
-}
-
-uint32_t RTPReceiver::ByteCountReceived() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return received_byte_count_;
-}
-
-int32_t RTPReceiver::RegisterReceivePayload(
-    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const int8_t payload_type,
-    const uint32_t frequency,
-    const uint8_t channels,
-    const uint32_t rate) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  // TODO(phoglund): Try to streamline handling of the RED codec and some other
-  // cases which makes it necessary to keep track of whether we created a
-  // payload or not.
-  bool created_new_payload = false;
-  int32_t result = rtp_payload_registry_->RegisterReceivePayload(
-      payload_name, payload_type, frequency, channels, rate,
-      &created_new_payload);
-  if (created_new_payload) {
-    if (rtp_media_receiver_->OnNewPayloadTypeCreated(payload_name, payload_type,
-                                                     frequency) != 0) {
-      WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
-                   "%s failed to register payload",
-                   __FUNCTION__);
-      return -1;
-    }
-  }
-  return result;
-}
-
-int32_t RTPReceiver::DeRegisterReceivePayload(
-    const int8_t payload_type) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return rtp_payload_registry_->DeRegisterReceivePayload(payload_type);
-}
-
-int32_t RTPReceiver::ReceivePayloadType(
-    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const uint32_t frequency,
-    const uint8_t channels,
-    const uint32_t rate,
-    int8_t* payload_type) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return rtp_payload_registry_->ReceivePayloadType(
-      payload_name, frequency, channels, rate, payload_type);
-}
-
-NACKMethod RTPReceiver::NACK() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return nack_method_;
-}
-
-// Turn negative acknowledgment requests on/off.
-int32_t RTPReceiver::SetNACKStatus(const NACKMethod method,
-                                   int max_reordering_threshold) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  if (max_reordering_threshold < 0) {
-    return -1;
-  } else if (method == kNackRtcp) {
-    max_reordering_threshold_ = max_reordering_threshold;
-  } else {
-    max_reordering_threshold_ = kDefaultMaxReorderingThreshold;
-  }
-  nack_method_ = method;
-  return 0;
-}
-
-void RTPReceiver::SetRTXStatus(bool enable, uint32_t ssrc) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  rtx_ = enable;
-  ssrc_rtx_ = ssrc;
-}
-
-void RTPReceiver::RTXStatus(bool* enable, uint32_t* ssrc,
-                            int* payload_type) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  *enable = rtx_;
-  *ssrc = ssrc_rtx_;
-  *payload_type = payload_type_rtx_;
-}
-
-void RTPReceiver::SetRtxPayloadType(int payload_type) {
-  CriticalSectionScoped cs(critical_section_rtp_receiver_);
-  payload_type_rtx_ = payload_type;
-}
-
-uint32_t RTPReceiver::SSRC() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return ssrc_;
-}
-
-// Get remote CSRC.
-int32_t RTPReceiver::CSRCs(
-    uint32_t array_of_csrcs[kRtpCsrcSize]) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  assert(num_csrcs_ <= kRtpCsrcSize);
-
-  if (num_csrcs_ > 0) {
-    memcpy(array_of_csrcs, current_remote_csrc_,
-           sizeof(uint32_t)*num_csrcs_);
-  }
-  return num_csrcs_;
-}
-
-int32_t RTPReceiver::Energy(
-    uint8_t array_of_energy[kRtpCsrcSize]) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  assert(num_energy_ <= kRtpCsrcSize);
-
-  if (num_energy_ > 0) {
-    memcpy(array_of_energy, current_remote_energy_,
-           sizeof(uint8_t)*num_csrcs_);
-  }
-  return num_energy_;
-}
-
-int32_t RTPReceiver::IncomingRTPPacket(
-  RTPHeader* rtp_header,
-  const uint8_t* packet,
-  const uint16_t packet_length) {
-  TRACE_EVENT0("webrtc_rtp", "RTPRecv::Packet");
-  // The rtp_header argument contains the parsed RTP header.
-  int length = packet_length - rtp_header->paddingLength;
-
-  // Sanity check.
-  if ((length - rtp_header->headerLength) < 0) {
-    WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
-                 "%s invalid argument",
-                 __FUNCTION__);
-    return -1;
-  }
-  if (rtx_) {
-    if (ssrc_rtx_ == rtp_header->ssrc) {
-      // Sanity check, RTX packets has 2 extra header bytes.
-      if (rtp_header->headerLength + kRtxHeaderSize > packet_length) {
-        return -1;
-      }
-      // If a specific RTX payload type is negotiated, set back to the media
-      // payload type and treat it like a media packet from here.
-      if (payload_type_rtx_ != -1) {
-        if (payload_type_rtx_ == rtp_header->payloadType &&
-            rtp_payload_registry_->last_received_media_payload_type() != -1) {
-          rtp_header->payloadType =
-              rtp_payload_registry_->last_received_media_payload_type();
-        } else {
-          WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-                       "Incorrect RTX configuration, dropping packet.");
-          return -1;
-        }
-      }
-      rtp_header->ssrc = ssrc_;
-      rtp_header->sequenceNumber =
-        (packet[rtp_header->headerLength] << 8) +
-        packet[1 + rtp_header->headerLength];
-      // Count the RTX header as part of the RTP
-      rtp_header->headerLength += 2;
-    }
-  }
-  if (use_ssrc_filter_) {
-    if (rtp_header->ssrc != ssrc_filter_) {
-      WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-                   "%s drop packet due to SSRC filter",
-                   __FUNCTION__);
-      return -1;
-    }
-  }
-  if (last_receive_time_ == 0) {
-    // Trigger only once.
-    if (length - rtp_header->headerLength == 0) {
-      // Keep-alive packet.
-      cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive);
-    } else {
-      cb_rtp_feedback_->OnReceivedPacket(id_, kPacketRtp);
-    }
-  }
-  int8_t first_payload_byte = 0;
-  if (length > 0) {
-    first_payload_byte = packet[rtp_header->headerLength];
-  }
-  // Trigger our callbacks.
-  CheckSSRCChanged(rtp_header);
-
-  bool is_red = false;
-  ModuleRTPUtility::PayloadUnion specific_payload = {};
-
-  if (CheckPayloadChanged(rtp_header,
-                          first_payload_byte,
-                          is_red,
-                          &specific_payload) == -1) {
-    if (length - rtp_header->headerLength == 0) {
-      // OK, keep-alive packet.
-      WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
-                   "%s received keepalive",
-                   __FUNCTION__);
-      return 0;
-    }
-    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-                 "%s received invalid payloadtype",
-                 __FUNCTION__);
-    return -1;
-  }
-  WebRtcRTPHeader webrtc_rtp_header;
-  memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
-  webrtc_rtp_header.header = *rtp_header;
-  CheckCSRC(&webrtc_rtp_header);
-
-  uint16_t payload_data_length =
-    ModuleRTPUtility::GetPayloadDataLength(*rtp_header, packet_length);
-
-  bool is_first_packet_in_frame =
-      SequenceNumber() + 1 == rtp_header->sequenceNumber &&
-      TimeStamp() != rtp_header->timestamp;
-  bool is_first_packet = is_first_packet_in_frame || HaveNotReceivedPackets();
-
-  int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
-      &webrtc_rtp_header, specific_payload, is_red, packet, packet_length,
-      clock_->TimeInMilliseconds(), is_first_packet);
-
-  if (ret_val < 0) {
-    return ret_val;
-  }
-
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  // This compares to received_seq_max_. We store the last received after we
-  // have done the callback.
-  bool old_packet = RetransmitOfOldPacket(rtp_header->sequenceNumber,
-                                          rtp_header->timestamp);
-
-  // This updates received_seq_max_ and other members.
-  UpdateStatistics(rtp_header, payload_data_length, old_packet);
-
-  // Need to be updated after RetransmitOfOldPacket and
-  // RetransmitOfOldPacketUpdateStatistics.
-  last_receive_time_ = clock_->TimeInMilliseconds();
-  last_received_payload_length_ = payload_data_length;
-
-  if (!old_packet) {
-    if (last_received_timestamp_ != rtp_header->timestamp) {
-      last_received_timestamp_ = rtp_header->timestamp;
-      last_received_frame_time_ms_ = clock_->TimeInMilliseconds();
-    }
-    last_received_sequence_number_ = rtp_header->sequenceNumber;
-    last_received_transmission_time_offset_ =
-      rtp_header->extension.transmissionTimeOffset;
-  }
-  return ret_val;
-}
-
-// Implementation note: we expect to have the critical_section_rtp_receiver_
-// critsect when we call this.
-void RTPReceiver::UpdateStatistics(const RTPHeader* rtp_header,
-                                   const uint16_t bytes,
-                                   const bool old_packet) {
-  uint32_t frequency_hz = rtp_media_receiver_->GetFrequencyHz();
-
-  Bitrate::Update(bytes);
-
-  received_byte_count_ += bytes;
-
-  if (received_seq_max_ == 0 && received_seq_wraps_ == 0) {
-    // This is the first received report.
-    received_seq_first_ = rtp_header->sequenceNumber;
-    received_seq_max_ = rtp_header->sequenceNumber;
-    received_inorder_packet_count_ = 1;
-    local_time_last_received_timestamp_ =
-      GetCurrentRTP(clock_, frequency_hz);  // Time in samples.
-    return;
-  }
-
-  // Count only the new packets received.
-  if (InOrderPacket(rtp_header->sequenceNumber)) {
-    const uint32_t RTPtime =
-      GetCurrentRTP(clock_, frequency_hz);  // Time in samples.
-    received_inorder_packet_count_++;
-
-    // Wrong if we use RetransmitOfOldPacket.
-    int32_t seq_diff =
-        rtp_header->sequenceNumber - received_seq_max_;
-    if (seq_diff < 0) {
-      // Wrap around detected.
-      received_seq_wraps_++;
-    }
-    // new max
-    received_seq_max_ = rtp_header->sequenceNumber;
-
-    if (rtp_header->timestamp != last_received_timestamp_ &&
-        received_inorder_packet_count_ > 1) {
-      int32_t time_diff_samples =
-          (RTPtime - local_time_last_received_timestamp_) -
-          (rtp_header->timestamp - last_received_timestamp_);
-
-      time_diff_samples = abs(time_diff_samples);
-
-      // lib_jingle sometimes deliver crazy jumps in TS for the same stream.
-      // If this happens, don't update jitter value. Use 5 secs video frequency
-      // as the treshold.
-      if (time_diff_samples < 450000) {
-        // Note we calculate in Q4 to avoid using float.
-        int32_t jitter_diff_q4 = (time_diff_samples << 4) - jitter_q4_;
-        jitter_q4_ += ((jitter_diff_q4 + 8) >> 4);
-      }
-
-      // Extended jitter report, RFC 5450.
-      // Actual network jitter, excluding the source-introduced jitter.
-      int32_t time_diff_samples_ext =
-        (RTPtime - local_time_last_received_timestamp_) -
-        ((rtp_header->timestamp +
-          rtp_header->extension.transmissionTimeOffset) -
-         (last_received_timestamp_ +
-          last_received_transmission_time_offset_));
-
-      time_diff_samples_ext = abs(time_diff_samples_ext);
-
-      if (time_diff_samples_ext < 450000) {
-        int32_t jitter_diffQ4TransmissionTimeOffset =
-          (time_diff_samples_ext << 4) - jitter_q4_transmission_time_offset_;
-        jitter_q4_transmission_time_offset_ +=
-          ((jitter_diffQ4TransmissionTimeOffset + 8) >> 4);
-      }
-    }
-    local_time_last_received_timestamp_ = RTPtime;
-  } else {
-    if (old_packet) {
-      received_old_packet_count_++;
-    } else {
-      received_inorder_packet_count_++;
-    }
-  }
-
-  uint16_t packet_oh =
-      rtp_header->headerLength + rtp_header->paddingLength;
-
-  // Our measured overhead. Filter from RFC 5104 4.2.1.2:
-  // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
-  received_packet_oh_ = (15 * received_packet_oh_ + packet_oh) >> 4;
-}
-
-// Implementation note: we expect to have the critical_section_rtp_receiver_
-// critsect when we call this.
-bool RTPReceiver::RetransmitOfOldPacket(
-    const uint16_t sequence_number,
-    const uint32_t rtp_time_stamp) const {
-  if (InOrderPacket(sequence_number)) {
-    return false;
-  }
-
-  uint32_t frequency_khz = rtp_media_receiver_->GetFrequencyHz() / 1000;
-  int64_t time_diff_ms = clock_->TimeInMilliseconds() -
-      last_receive_time_;
-
-  // Diff in time stamp since last received in order.
-  int32_t rtp_time_stamp_diff_ms =
-      static_cast<int32_t>(rtp_time_stamp - last_received_timestamp_) /
-      frequency_khz;
-
-  uint16_t min_rtt = 0;
-  int32_t max_delay_ms = 0;
-  rtp_rtcp_.RTT(ssrc_, NULL, NULL, &min_rtt, NULL);
-  if (min_rtt == 0) {
-    // Jitter variance in samples.
-    float jitter = jitter_q4_ >> 4;
-
-    // Jitter standard deviation in samples.
-    float jitter_std = sqrt(jitter);
-
-    // 2 times the standard deviation => 95% confidence.
-    // And transform to milliseconds by dividing by the frequency in kHz.
-    max_delay_ms = static_cast<int32_t>((2 * jitter_std) / frequency_khz);
-
-    // Min max_delay_ms is 1.
-    if (max_delay_ms == 0) {
-      max_delay_ms = 1;
-    }
-  } else {
-    max_delay_ms = (min_rtt / 3) + 1;
-  }
-  if (time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms) {
-    return true;
-  }
-  return false;
-}
-
-bool RTPReceiver::InOrderPacket(const uint16_t sequence_number) const {
-  if (IsNewerSequenceNumber(sequence_number, received_seq_max_)) {
-    return true;
-  } else {
-    // If we have a restart of the remote side this packet is still in order.
-    return !IsNewerSequenceNumber(sequence_number, received_seq_max_ -
-                                  max_reordering_threshold_);
-  }
-}
-
-uint16_t RTPReceiver::SequenceNumber() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return last_received_sequence_number_;
-}
-
-uint32_t RTPReceiver::TimeStamp() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return last_received_timestamp_;
-}
-
-int32_t RTPReceiver::LastReceivedTimeMs() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  return last_received_frame_time_ms_;
-}
-
-// Compute time stamp of the last incoming packet that is the first packet of
-// its frame.
-int32_t RTPReceiver::EstimatedRemoteTimeStamp(
-    uint32_t& timestamp) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  uint32_t frequency_hz = rtp_media_receiver_->GetFrequencyHz();
-
-  if (local_time_last_received_timestamp_ == 0) {
-    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-                 "%s invalid state", __FUNCTION__);
-    return -1;
-  }
-  // Time in samples.
-  uint32_t diff = GetCurrentRTP(clock_, frequency_hz) -
-                        local_time_last_received_timestamp_;
-
-  timestamp = last_received_timestamp_ + diff;
-  return 0;
-}
-
-// Get the currently configured SSRC filter.
-int32_t RTPReceiver::SSRCFilter(uint32_t& allowed_ssrc) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-  if (use_ssrc_filter_) {
-    allowed_ssrc = ssrc_filter_;
-    return 0;
-  }
-  WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-               "%s invalid state", __FUNCTION__);
-  return -1;
-}
-
-// Set a SSRC to be used as a filter for incoming RTP streams.
-int32_t RTPReceiver::SetSSRCFilter(
-    const bool enable, const uint32_t allowed_ssrc) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  use_ssrc_filter_ = enable;
-  if (enable) {
-    ssrc_filter_ = allowed_ssrc;
-  } else {
-    ssrc_filter_ = 0;
-  }
-  return 0;
-}
-
-// Implementation note: must not hold critsect when called.
-void RTPReceiver::CheckSSRCChanged(const RTPHeader* rtp_header) {
-  bool new_ssrc = false;
-  bool re_initialize_decoder = false;
-  char payload_name[RTP_PAYLOAD_NAME_SIZE];
-  uint32_t frequency = kDefaultVideoFrequency;
-  uint8_t channels = 1;
-  uint32_t rate = 0;
-
-  {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-    int8_t last_received_payload_type =
-        rtp_payload_registry_->last_received_payload_type();
-    if (ssrc_ != rtp_header->ssrc ||
-        (last_received_payload_type == -1 && ssrc_ == 0)) {
-      // We need the payload_type_ to make the call if the remote SSRC is 0.
-      new_ssrc = true;
-
-      ResetStatistics();
-
-      last_received_timestamp_      = 0;
-      last_received_sequence_number_ = 0;
-      last_received_transmission_time_offset_ = 0;
-      last_received_frame_time_ms_ = 0;
-
-      // Do we have a SSRC? Then the stream is restarted.
-      if (ssrc_) {
-        // Do we have the same codec? Then re-initialize coder.
-        if (rtp_header->payloadType == last_received_payload_type) {
-          re_initialize_decoder = true;
-
-          Payload* payload;
-          if (rtp_payload_registry_->PayloadTypeToPayload(
-              rtp_header->payloadType, payload) != 0) {
-            return;
-          }
-          assert(payload);
-          payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
-          strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
-          if (payload->audio) {
-            frequency = payload->typeSpecific.Audio.frequency;
-            channels = payload->typeSpecific.Audio.channels;
-            rate = payload->typeSpecific.Audio.rate;
-          } else {
-            frequency = kDefaultVideoFrequency;
-          }
-        }
-      }
-      ssrc_ = rtp_header->ssrc;
-    }
-  }
-  if (new_ssrc) {
-    // We need to get this to our RTCP sender and receiver.
-    // We need to do this outside critical section.
-    rtp_rtcp_.SetRemoteSSRC(rtp_header->ssrc);
-    cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->ssrc);
-  }
-  if (re_initialize_decoder) {
-    if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
-        id_, rtp_header->payloadType, payload_name, frequency,
-        channels, rate)) {
-      // New stream, same codec.
-      WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
-                   "Failed to create decoder for payload type:%d",
-                   rtp_header->payloadType);
-    }
-  }
-}
-
-// Implementation note: must not hold critsect when called.
-// TODO(phoglund): Move as much as possible of this code path into the media
-// specific receivers. Basically this method goes through a lot of trouble to
-// compute something which is only used by the media specific parts later. If
-// this code path moves we can get rid of some of the rtp_receiver ->
-// media_specific interface (such as CheckPayloadChange, possibly get/set
-// last known payload).
-int32_t RTPReceiver::CheckPayloadChanged(
-  const RTPHeader* rtp_header,
-  const int8_t first_payload_byte,
-  bool& is_red,
-  ModuleRTPUtility::PayloadUnion* specific_payload) {
-  bool re_initialize_decoder = false;
-
-  char payload_name[RTP_PAYLOAD_NAME_SIZE];
-  int8_t payload_type = rtp_header->payloadType;
-
-  {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-    int8_t last_received_payload_type =
-        rtp_payload_registry_->last_received_payload_type();
-    if (payload_type != last_received_payload_type) {
-      if (REDPayloadType(payload_type)) {
-        // Get the real codec payload type.
-        payload_type = first_payload_byte & 0x7f;
-        is_red = true;
-
-        if (REDPayloadType(payload_type)) {
-          // Invalid payload type, traced by caller. If we proceeded here,
-          // this would be set as |_last_received_payload_type|, and we would no
-          // longer catch corrupt packets at this level.
-          return -1;
-        }
-
-        // When we receive RED we need to check the real payload type.
-        if (payload_type == last_received_payload_type) {
-          rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
-          return 0;
-        }
-      }
-      bool should_reset_statistics = false;
-      bool should_discard_changes = false;
-
-      rtp_media_receiver_->CheckPayloadChanged(
-        payload_type, specific_payload, &should_reset_statistics,
-        &should_discard_changes);
-
-      if (should_reset_statistics) {
-        ResetStatistics();
-      }
-      if (should_discard_changes) {
-        is_red = false;
-        return 0;
-      }
-
-      Payload* payload;
-      if (rtp_payload_registry_->PayloadTypeToPayload(payload_type,
-                                                      payload) != 0) {
-        // Not a registered payload type.
-        return -1;
-      }
-      assert(payload);
-      payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
-      strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
-
-      rtp_payload_registry_->set_last_received_payload_type(payload_type);
-
-      re_initialize_decoder = true;
-
-      rtp_media_receiver_->SetLastMediaSpecificPayload(payload->typeSpecific);
-      rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
-
-      if (!payload->audio) {
-        if (VideoCodecType() == kRtpFecVideo) {
-          // Only reset the decoder on media packets.
-          re_initialize_decoder = false;
-        } else {
-          bool media_type_unchanged =
-              rtp_payload_registry_->ReportMediaPayloadType(payload_type);
-          if (media_type_unchanged) {
-            // Only reset the decoder if the media codec type has changed.
-            re_initialize_decoder = false;
-          }
-        }
-      }
-      if (re_initialize_decoder) {
-        ResetStatistics();
-      }
-    } else {
-      rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
-      is_red = false;
-    }
-  }  // End critsect.
-
-  if (re_initialize_decoder) {
-    if (-1 == rtp_media_receiver_->InvokeOnInitializeDecoder(
-        cb_rtp_feedback_, id_, payload_type, payload_name,
-        *specific_payload)) {
-      return -1;  // Wrong payload type.
-    }
-  }
-  return 0;
-}
-
-// Implementation note: must not hold critsect when called.
-void RTPReceiver::CheckCSRC(const WebRtcRTPHeader* rtp_header) {
-  int32_t num_csrcs_diff = 0;
-  uint32_t old_remote_csrc[kRtpCsrcSize];
-  uint8_t old_num_csrcs = 0;
-
-  {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-    if (!rtp_media_receiver_->ShouldReportCsrcChanges(
-        rtp_header->header.payloadType)) {
-      return;
-    }
-    num_energy_ = rtp_header->type.Audio.numEnergy;
-    if (rtp_header->type.Audio.numEnergy > 0 &&
-        rtp_header->type.Audio.numEnergy <= kRtpCsrcSize) {
-      memcpy(current_remote_energy_,
-             rtp_header->type.Audio.arrOfEnergy,
-             rtp_header->type.Audio.numEnergy);
-    }
-    old_num_csrcs  = num_csrcs_;
-    if (old_num_csrcs > 0) {
-      // Make a copy of old.
-      memcpy(old_remote_csrc, current_remote_csrc_,
-             num_csrcs_ * sizeof(uint32_t));
-    }
-    const uint8_t num_csrcs = rtp_header->header.numCSRCs;
-    if ((num_csrcs > 0) && (num_csrcs <= kRtpCsrcSize)) {
-      // Copy new.
-      memcpy(current_remote_csrc_,
-             rtp_header->header.arrOfCSRCs,
-             num_csrcs * sizeof(uint32_t));
-    }
-    if (num_csrcs > 0 || old_num_csrcs > 0) {
-      num_csrcs_diff = num_csrcs - old_num_csrcs;
-      num_csrcs_ = num_csrcs;  // Update stored CSRCs.
-    } else {
-      // No change.
-      return;
-    }
-  }  // End critsect.
-
-  bool have_called_callback = false;
-  // Search for new CSRC in old array.
-  for (uint8_t i = 0; i < rtp_header->header.numCSRCs; ++i) {
-    const uint32_t csrc = rtp_header->header.arrOfCSRCs[i];
-
-    bool found_match = false;
-    for (uint8_t j = 0; j < old_num_csrcs; ++j) {
-      if (csrc == old_remote_csrc[j]) {  // old list
-        found_match = true;
-        break;
-      }
-    }
-    if (!found_match && csrc) {
-      // Didn't find it, report it as new.
-      have_called_callback = true;
-      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, true);
-    }
-  }
-  // Search for old CSRC in new array.
-  for (uint8_t i = 0; i < old_num_csrcs; ++i) {
-    const uint32_t csrc = old_remote_csrc[i];
-
-    bool found_match = false;
-    for (uint8_t j = 0; j < rtp_header->header.numCSRCs; ++j) {
-      if (csrc == rtp_header->header.arrOfCSRCs[j]) {
-        found_match = true;
-        break;
-      }
-    }
-    if (!found_match && csrc) {
-      // Did not find it, report as removed.
-      have_called_callback = true;
-      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, false);
-    }
-  }
-  if (!have_called_callback) {
-    // If the CSRC list contain non-unique entries we will end up here.
-    // Using CSRC 0 to signal this event, not interop safe, other
-    // implementations might have CSRC 0 as a valid value.
-    if (num_csrcs_diff > 0) {
-      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, true);
-    } else if (num_csrcs_diff < 0) {
-      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, false);
-    }
-  }
-}
-
-int32_t RTPReceiver::ResetStatistics() {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  last_report_inorder_packets_ = 0;
-  last_report_old_packets_ = 0;
-  last_report_seq_max_ = 0;
-  last_report_fraction_lost_ = 0;
-  last_report_cumulative_lost_ = 0;
-  last_report_extended_high_seq_num_ = 0;
-  last_report_jitter_ = 0;
-  last_report_jitter_transmission_time_offset_ = 0;
-  jitter_q4_ = 0;
-  jitter_max_q4_ = 0;
-  cumulative_loss_ = 0;
-  jitter_q4_transmission_time_offset_ = 0;
-  received_seq_wraps_ = 0;
-  received_seq_max_ = 0;
-  received_seq_first_ = 0;
-  received_byte_count_ = 0;
-  received_old_packet_count_ = 0;
-  received_inorder_packet_count_ = 0;
-  return 0;
-}
-
-int32_t RTPReceiver::ResetDataCounters() {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  received_byte_count_ = 0;
-  received_old_packet_count_ = 0;
-  received_inorder_packet_count_ = 0;
-  last_report_inorder_packets_ = 0;
-
-  return 0;
-}
-
-int32_t RTPReceiver::Statistics(
-    uint8_t*  fraction_lost,
-    uint32_t* cum_lost,
-    uint32_t* ext_max,
-    uint32_t* jitter,
-    uint32_t* max_jitter,
-    uint32_t* jitter_transmission_time_offset,
-    bool reset) const {
-  int32_t missing;
-  return Statistics(fraction_lost,
-                    cum_lost,
-                    ext_max,
-                    jitter,
-                    max_jitter,
-                    jitter_transmission_time_offset,
-                    &missing,
-                    reset);
-}
-
-int32_t RTPReceiver::Statistics(
-    uint8_t*  fraction_lost,
-    uint32_t* cum_lost,
-    uint32_t* ext_max,
-    uint32_t* jitter,
-    uint32_t* max_jitter,
-    uint32_t* jitter_transmission_time_offset,
-    int32_t*  missing,
-    bool reset) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  if (missing == NULL) {
-    return -1;
-  }
-  if (received_seq_first_ == 0 && received_byte_count_ == 0) {
-    // We have not received anything. -1 required by RTCP sender.
-    return -1;
-  }
-  if (!reset) {
-    if (last_report_inorder_packets_ == 0) {
-      // No report.
-      return -1;
-    }
-    // Just get last report.
-    if (fraction_lost) {
-      *fraction_lost = last_report_fraction_lost_;
-    }
-    if (cum_lost) {
-      *cum_lost = last_report_cumulative_lost_;  // 24 bits valid.
-    }
-    if (ext_max) {
-      *ext_max = last_report_extended_high_seq_num_;
-    }
-    if (jitter) {
-      *jitter = last_report_jitter_;
-    }
-    if (max_jitter) {
-      // Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
-      *max_jitter = (jitter_max_q4_ >> 4);
-    }
-    if (jitter_transmission_time_offset) {
-      *jitter_transmission_time_offset =
-        last_report_jitter_transmission_time_offset_;
-    }
-    return 0;
-  }
-
-  if (last_report_inorder_packets_ == 0) {
-    // First time we send a report.
-    last_report_seq_max_ = received_seq_first_ - 1;
-  }
-  // Calculate fraction lost.
-  uint16_t exp_since_last = (received_seq_max_ - last_report_seq_max_);
-
-  if (last_report_seq_max_ > received_seq_max_) {
-    // Can we assume that the seq_num can't go decrease over a full RTCP period?
-    exp_since_last = 0;
-  }
-
-  // Number of received RTP packets since last report, counts all packets but
-  // not re-transmissions.
-  uint32_t rec_since_last =
-      received_inorder_packet_count_ - last_report_inorder_packets_;
-
-  if (nack_method_ == kNackOff) {
-    // This is needed for re-ordered packets.
-    uint32_t old_packets =
-        received_old_packet_count_ - last_report_old_packets_;
-    rec_since_last += old_packets;
-  } else {
-    // With NACK we don't know the expected retransmitions during the last
-    // second. We know how many "old" packets we have received. We just count
-    // the number of old received to estimate the loss, but it still does not
-    // guarantee an exact number since we run this based on time triggered by
-    // sending of a RTP packet. This should have a minimum effect.
-
-    // With NACK we don't count old packets as received since they are
-    // re-transmitted. We use RTT to decide if a packet is re-ordered or
-    // re-transmitted.
-  }
-
-  *missing = 0;
-  if (exp_since_last > rec_since_last) {
-    *missing = (exp_since_last - rec_since_last);
-  }
-  uint8_t local_fraction_lost = 0;
-  if (exp_since_last) {
-    // Scale 0 to 255, where 255 is 100% loss.
-    local_fraction_lost = (uint8_t)((255 * (*missing)) / exp_since_last);
-  }
-  if (fraction_lost) {
-    *fraction_lost = local_fraction_lost;
-  }
-
-  // We need a counter for cumulative loss too.
-  cumulative_loss_ += *missing;
-
-  if (jitter_q4_ > jitter_max_q4_) {
-    jitter_max_q4_ = jitter_q4_;
-  }
-  if (cum_lost) {
-    *cum_lost =  cumulative_loss_;
-  }
-  if (ext_max) {
-    *ext_max = (received_seq_wraps_ << 16) + received_seq_max_;
-  }
-  // Note: internal jitter value is in Q4 and needs to be scaled by 1/16.
-  if (jitter) {
-    *jitter = (jitter_q4_ >> 4);
-  }
-  if (max_jitter) {
-    *max_jitter = (jitter_max_q4_ >> 4);
-  }
-  if (jitter_transmission_time_offset) {
-    *jitter_transmission_time_offset =
-      (jitter_q4_transmission_time_offset_ >> 4);
-  }
-  if (reset) {
-    // Store this report.
-    last_report_fraction_lost_ = local_fraction_lost;
-    last_report_cumulative_lost_ = cumulative_loss_;  // 24 bits valid.
-    last_report_extended_high_seq_num_ =
-        (received_seq_wraps_ << 16) + received_seq_max_;
-    last_report_jitter_  = (jitter_q4_ >> 4);
-    last_report_jitter_transmission_time_offset_ =
-      (jitter_q4_transmission_time_offset_ >> 4);
-
-    // Only for report blocks in RTCP SR and RR.
-    last_report_inorder_packets_ = received_inorder_packet_count_;
-    last_report_old_packets_ = received_old_packet_count_;
-    last_report_seq_max_ = received_seq_max_;
-  }
-  return 0;
-}
-
-int32_t RTPReceiver::DataCounters(
-    uint32_t* bytes_received,
-    uint32_t* packets_received) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_);
-
-  if (bytes_received) {
-    *bytes_received = received_byte_count_;
-  }
-  if (packets_received) {
-    *packets_received =
-        received_old_packet_count_ + received_inorder_packet_count_;
-  }
-  return 0;
-}
-
-void RTPReceiver::ProcessBitrate() {
-  CriticalSectionScoped cs(critical_section_rtp_receiver_);
-
-  Bitrate::Process();
-  TRACE_COUNTER_ID1("webrtc_rtp",
-                    "RTPReceiverBitrate", ssrc_, BitrateLast());
-  TRACE_COUNTER_ID1("webrtc_rtp",
-                    "RTPReceiverPacketRate", ssrc_, PacketRate());
-}
-
-}  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver.h b/modules/rtp_rtcp/source/rtp_receiver.h
deleted file mode 100644
index ce7e0a2..0000000
--- a/modules/rtp_rtcp/source/rtp_receiver.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
-
-#include <map>
-
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
-#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
-#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver_help.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/typedefs.h"
-
-namespace webrtc {
-
-class RtpRtcpFeedback;
-class ModuleRtpRtcpImpl;
-class Trace;
-class RTPReceiverAudio;
-class RTPReceiverVideo;
-class RTPReceiverStrategy;
-
-class RTPReceiver : public Bitrate {
- public:
-  // Callbacks passed in here may not be NULL (use Null Object callbacks if you
-  // want callbacks to do nothing). This class takes ownership of the media
-  // receiver but nothing else.
-  RTPReceiver(const int32_t id,
-              Clock* clock,
-              ModuleRtpRtcpImpl* owner,
-              RtpAudioFeedback* incoming_audio_messages_callback,
-              RtpData* incoming_payload_callback,
-              RtpFeedback* incoming_messages_callback,
-              RTPReceiverStrategy* rtp_media_receiver,
-              RTPPayloadRegistry* rtp_payload_registry);
-
-  virtual ~RTPReceiver();
-
-  RtpVideoCodecTypes VideoCodecType() const;
-  uint32_t MaxConfiguredBitrate() const;
-
-  int32_t SetPacketTimeout(const uint32_t timeout_ms);
-  void PacketTimeout();
-
-  void ProcessDeadOrAlive(const bool RTCPalive, const int64_t now);
-
-  void ProcessBitrate();
-
-  int32_t RegisterReceivePayload(
-      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const int8_t payload_type,
-      const uint32_t frequency,
-      const uint8_t channels,
-      const uint32_t rate);
-
-  int32_t DeRegisterReceivePayload(const int8_t payload_type);
-
-  int32_t ReceivePayloadType(
-      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const uint32_t frequency,
-      const uint8_t channels,
-      const uint32_t rate,
-      int8_t* payload_type) const;
-
-  int32_t IncomingRTPPacket(
-      RTPHeader* rtpheader,
-      const uint8_t* incoming_rtp_packet,
-      const uint16_t incoming_rtp_packet_length);
-
-  NACKMethod NACK() const ;
-
-  // Turn negative acknowledgement requests on/off.
-  int32_t SetNACKStatus(const NACKMethod method, int max_reordering_threshold);
-
-  // Returns the last received timestamp.
-  virtual uint32_t TimeStamp() const;
-  int32_t LastReceivedTimeMs() const;
-  virtual uint16_t SequenceNumber() const;
-
-  int32_t EstimatedRemoteTimeStamp(uint32_t& timestamp) const;
-
-  uint32_t SSRC() const;
-
-  int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const;
-
-  int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const;
-
-  // Get the currently configured SSRC filter.
-  int32_t SSRCFilter(uint32_t& allowed_ssrc) const;
-
-  // Set a SSRC to be used as a filter for incoming RTP streams.
-  int32_t SetSSRCFilter(const bool enable, const uint32_t allowed_ssrc);
-
-  int32_t Statistics(uint8_t*  fraction_lost,
-                     uint32_t* cum_lost,
-                     uint32_t* ext_max,
-                     uint32_t* jitter,  // Will be moved from JB.
-                     uint32_t* max_jitter,
-                     uint32_t* jitter_transmission_time_offset,
-                     bool reset) const;
-
-  int32_t Statistics(uint8_t*  fraction_lost,
-                     uint32_t* cum_lost,
-                     uint32_t* ext_max,
-                     uint32_t* jitter,  // Will be moved from JB.
-                     uint32_t* max_jitter,
-                     uint32_t* jitter_transmission_time_offset,
-                     int32_t* missing,
-                     bool reset) const;
-
-  int32_t DataCounters(uint32_t* bytes_received,
-                       uint32_t* packets_received) const;
-
-  int32_t ResetStatistics();
-
-  int32_t ResetDataCounters();
-
-  uint16_t PacketOHReceived() const;
-
-  uint32_t PacketCountReceived() const;
-
-  uint32_t ByteCountReceived() const;
-
-  int32_t RegisterRtpHeaderExtension(const RTPExtensionType type,
-                                     const uint8_t id);
-
-  int32_t DeregisterRtpHeaderExtension(const RTPExtensionType type);
-
-  void GetHeaderExtensionMapCopy(RtpHeaderExtensionMap* map) const;
-
-  // RTX.
-  void SetRTXStatus(bool enable, uint32_t ssrc);
-
-  void RTXStatus(bool* enable, uint32_t* ssrc, int* payload_type) const;
-
-  void SetRtxPayloadType(int payload_type);
-
-  virtual int8_t REDPayloadType() const;
-
-  bool HaveNotReceivedPackets() const;
-
-  virtual bool RetransmitOfOldPacket(const uint16_t sequence_number,
-                                     const uint32_t rtp_time_stamp) const;
-
-  void UpdateStatistics(const RTPHeader* rtp_header,
-                        const uint16_t bytes,
-                        const bool old_packet);
-
- private:
-  // Returns whether RED is configured with payload_type.
-  bool REDPayloadType(const int8_t payload_type) const;
-
-  bool InOrderPacket(const uint16_t sequence_number) const;
-
-  void CheckSSRCChanged(const RTPHeader* rtp_header);
-  void CheckCSRC(const WebRtcRTPHeader* rtp_header);
-  int32_t CheckPayloadChanged(const RTPHeader* rtp_header,
-                              const int8_t first_payload_byte,
-                              bool& isRED,
-                              ModuleRTPUtility::PayloadUnion* payload);
-
-  void UpdateNACKBitRate(int32_t bytes, uint32_t now);
-  bool ProcessNACKBitRate(uint32_t now);
-
-  RTPPayloadRegistry*             rtp_payload_registry_;
-  scoped_ptr<RTPReceiverStrategy> rtp_media_receiver_;
-
-  int32_t           id_;
-  ModuleRtpRtcpImpl&      rtp_rtcp_;
-
-  RtpFeedback*            cb_rtp_feedback_;
-
-  CriticalSectionWrapper* critical_section_rtp_receiver_;
-  mutable int64_t   last_receive_time_;
-  uint16_t          last_received_payload_length_;
-
-  uint32_t          packet_timeout_ms_;
-
-  // SSRCs.
-  uint32_t            ssrc_;
-  uint8_t             num_csrcs_;
-  uint32_t            current_remote_csrc_[kRtpCsrcSize];
-  uint8_t             num_energy_;
-  uint8_t             current_remote_energy_[kRtpCsrcSize];
-
-  bool                      use_ssrc_filter_;
-  uint32_t            ssrc_filter_;
-
-  // Stats on received RTP packets.
-  uint32_t            jitter_q4_;
-  mutable uint32_t    jitter_max_q4_;
-  mutable uint32_t    cumulative_loss_;
-  uint32_t            jitter_q4_transmission_time_offset_;
-
-  uint32_t            local_time_last_received_timestamp_;
-  int64_t                   last_received_frame_time_ms_;
-  uint32_t            last_received_timestamp_;
-  uint16_t            last_received_sequence_number_;
-  int32_t             last_received_transmission_time_offset_;
-  uint16_t            received_seq_first_;
-  uint16_t            received_seq_max_;
-  uint16_t            received_seq_wraps_;
-
-  // Current counter values.
-  uint16_t            received_packet_oh_;
-  uint32_t            received_byte_count_;
-  uint32_t            received_old_packet_count_;
-  uint32_t            received_inorder_packet_count_;
-
-  // Counter values when we sent the last report.
-  mutable uint32_t    last_report_inorder_packets_;
-  mutable uint32_t    last_report_old_packets_;
-  mutable uint16_t    last_report_seq_max_;
-  mutable uint8_t     last_report_fraction_lost_;
-  mutable uint32_t    last_report_cumulative_lost_;  // 24 bits valid.
-  mutable uint32_t    last_report_extended_high_seq_num_;
-  mutable uint32_t    last_report_jitter_;
-  mutable uint32_t    last_report_jitter_transmission_time_offset_;
-
-  NACKMethod nack_method_;
-  int max_reordering_threshold_;
-
-  bool rtx_;
-  uint32_t ssrc_rtx_;
-  int payload_type_rtx_;
-};
-
-}  // namespace webrtc
-
-#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_H_
diff --git a/modules/rtp_rtcp/source/rtp_receiver_audio.cc b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
index dd49ec5..fc8a748 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_audio.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
@@ -20,13 +20,18 @@
 #include "webrtc/system_wrappers/interface/trace_event.h"
 
 namespace webrtc {
+RTPReceiverStrategy* RTPReceiverStrategy::CreateAudioStrategy(
+    int32_t id, RtpData* data_callback,
+    RtpAudioFeedback* incoming_messages_callback) {
+  return new RTPReceiverAudio(id, data_callback, incoming_messages_callback);
+}
+
 RTPReceiverAudio::RTPReceiverAudio(const int32_t id,
                                    RtpData* data_callback,
                                    RtpAudioFeedback* incoming_messages_callback)
     : RTPReceiverStrategy(data_callback),
+      TelephoneEventHandler(),
       id_(id),
-      critical_section_rtp_receiver_audio_(
-          CriticalSectionWrapper::CreateCriticalSection()),
       last_received_frequency_(8000),
       telephone_event_forward_to_decoder_(false),
       telephone_event_payload_type_(-1),
@@ -37,42 +42,36 @@
       cng_payload_type_(-1),
       g722_payload_type_(-1),
       last_received_g722_(false),
+      num_energy_(0),
+      current_remote_energy_(),
       cb_audio_feedback_(incoming_messages_callback) {
   last_payload_.Audio.channels = 1;
-}
-
-uint32_t RTPReceiverAudio::AudioFrequency() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
-  if (last_received_g722_) {
-    return 8000;
-  }
-  return last_received_frequency_;
+  memset(current_remote_energy_, 0, sizeof(current_remote_energy_));
 }
 
 // Outband TelephoneEvent(DTMF) detection
-int RTPReceiverAudio::SetTelephoneEventForwardToDecoder(
+void RTPReceiverAudio::SetTelephoneEventForwardToDecoder(
     bool forward_to_decoder) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+  CriticalSectionScoped lock(crit_sect_.get());
   telephone_event_forward_to_decoder_ = forward_to_decoder;
-  return 0;
 }
 
 // Is forwarding of outband telephone events turned on/off?
 bool RTPReceiverAudio::TelephoneEventForwardToDecoder() const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+  CriticalSectionScoped lock(crit_sect_.get());
   return telephone_event_forward_to_decoder_;
 }
 
 bool RTPReceiverAudio::TelephoneEventPayloadType(
-    const int8_t payload_type) const {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+    int8_t payload_type) const {
+  CriticalSectionScoped lock(crit_sect_.get());
   return (telephone_event_payload_type_ == payload_type) ? true : false;
 }
 
-bool RTPReceiverAudio::CNGPayloadType(const int8_t payload_type,
+bool RTPReceiverAudio::CNGPayloadType(int8_t payload_type,
                                       uint32_t* frequency,
                                       bool* cng_payload_type_has_changed) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+  CriticalSectionScoped lock(crit_sect_.get());
   *cng_payload_type_has_changed = false;
 
   //  We can have four CNG on 8000Hz, 16000Hz, 32000Hz and 48000Hz.
@@ -118,8 +117,7 @@
   return false;
 }
 
-bool RTPReceiverAudio::ShouldReportCsrcChanges(
-    uint8_t payload_type) const {
+bool RTPReceiverAudio::ShouldReportCsrcChanges(uint8_t payload_type) const {
   // Don't do this for DTMF packets, otherwise it's fine.
   return !TelephoneEventPayloadType(payload_type);
 }
@@ -158,9 +156,9 @@
 // -   G7221     frame         N/A
 int32_t RTPReceiverAudio::OnNewPayloadTypeCreated(
     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const int8_t payload_type,
-    const uint32_t frequency) {
-  CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+    int8_t payload_type,
+    uint32_t frequency) {
+  CriticalSectionScoped lock(crit_sect_.get());
 
   if (ModuleRTPUtility::StringCompare(payload_name, "telephone-event", 15)) {
     telephone_event_payload_type_ = payload_type;
@@ -183,18 +181,24 @@
   return 0;
 }
 
-int32_t RTPReceiverAudio::ParseRtpPacket(
-    WebRtcRTPHeader* rtp_header,
-    const ModuleRTPUtility::PayloadUnion& specific_payload,
-    const bool is_red,
-    const uint8_t* packet,
-    const uint16_t packet_length,
-    const int64_t timestamp_ms,
-    const bool is_first_packet) {
+int32_t RTPReceiverAudio::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
+                                         const PayloadUnion& specific_payload,
+                                         bool is_red,
+                                         const uint8_t* packet,
+                                         uint16_t packet_length,
+                                         int64_t timestamp_ms,
+                                         bool is_first_packet) {
   TRACE_EVENT2("webrtc_rtp", "Audio::ParseRtp",
                "seqnum", rtp_header->header.sequenceNumber,
                "timestamp", rtp_header->header.timestamp);
   rtp_header->type.Audio.numEnergy = rtp_header->header.numCSRCs;
+  num_energy_ = rtp_header->type.Audio.numEnergy;
+  if (rtp_header->type.Audio.numEnergy > 0 &&
+      rtp_header->type.Audio.numEnergy <= kRtpCsrcSize) {
+    memcpy(current_remote_energy_,
+           rtp_header->type.Audio.arrOfEnergy,
+           rtp_header->type.Audio.numEnergy);
+  }
   const uint8_t* payload_data =
       ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
   const uint16_t payload_data_length =
@@ -207,8 +211,12 @@
                                  is_red);
 }
 
-int32_t RTPReceiverAudio::GetFrequencyHz() const {
-  return AudioFrequency();
+int RTPReceiverAudio::GetPayloadTypeFrequency() const {
+  CriticalSectionScoped lock(crit_sect_.get());
+  if (last_received_g722_) {
+    return 8000;
+  }
+  return last_received_frequency_;
 }
 
 RTPAliveType RTPReceiverAudio::ProcessDeadOrAlive(
@@ -223,11 +231,10 @@
   }
 }
 
-void RTPReceiverAudio::CheckPayloadChanged(
-    const int8_t payload_type,
-    ModuleRTPUtility::PayloadUnion* specific_payload,
-    bool* should_reset_statistics,
-    bool* should_discard_changes) {
+void RTPReceiverAudio::CheckPayloadChanged(int8_t payload_type,
+                                           PayloadUnion* specific_payload,
+                                           bool* should_reset_statistics,
+                                           bool* should_discard_changes) {
   *should_discard_changes = false;
   *should_reset_statistics = false;
 
@@ -251,12 +258,24 @@
   }
 }
 
+int RTPReceiverAudio::Energy(uint8_t array_of_energy[kRtpCsrcSize]) const {
+  CriticalSectionScoped cs(crit_sect_.get());
+
+  assert(num_energy_ <= kRtpCsrcSize);
+
+  if (num_energy_ > 0) {
+    memcpy(array_of_energy, current_remote_energy_,
+           sizeof(uint8_t) * num_energy_);
+  }
+  return num_energy_;
+}
+
 int32_t RTPReceiverAudio::InvokeOnInitializeDecoder(
     RtpFeedback* callback,
-    const int32_t id,
-    const int8_t payload_type,
+    int32_t id,
+    int8_t payload_type,
     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const ModuleRTPUtility::PayloadUnion& specific_payload) const {
+    const PayloadUnion& specific_payload) const {
   if (-1 == callback->OnInitializeDecoder(id,
                                           payload_type,
                                           payload_name,
@@ -277,9 +296,9 @@
 int32_t RTPReceiverAudio::ParseAudioCodecSpecific(
     WebRtcRTPHeader* rtp_header,
     const uint8_t* payload_data,
-    const uint16_t payload_length,
-    const ModuleRTPUtility::AudioPayload& audio_specific,
-    const bool is_red) {
+    uint16_t payload_length,
+    const AudioPayload& audio_specific,
+    bool is_red) {
 
   if (payload_length == 0) {
     return 0;
@@ -288,7 +307,7 @@
   bool telephone_event_packet =
       TelephoneEventPayloadType(rtp_header->header.payloadType);
   if (telephone_event_packet) {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+    CriticalSectionScoped lock(crit_sect_.get());
 
     // RFC 4733 2.3
     // 0                   1                   2                   3
@@ -333,7 +352,7 @@
   }
 
   {
-    CriticalSectionScoped lock(critical_section_rtp_receiver_audio_.get());
+    CriticalSectionScoped lock(crit_sect_.get());
 
     if (!telephone_event_packet) {
       last_received_frequency_ = audio_specific.frequency;
diff --git a/modules/rtp_rtcp/source/rtp_receiver_audio.h b/modules/rtp_rtcp/source/rtp_receiver_audio.h
index 67b30c0..5a52629 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_audio.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_audio.h
@@ -13,8 +13,8 @@
 
 #include <set>
 
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -25,16 +25,16 @@
 class CriticalSectionWrapper;
 
 // Handles audio RTP packets. This class is thread-safe.
-class RTPReceiverAudio : public RTPReceiverStrategy {
+class RTPReceiverAudio : public RTPReceiverStrategy,
+                         public TelephoneEventHandler {
  public:
   RTPReceiverAudio(const int32_t id,
                    RtpData* data_callback,
                    RtpAudioFeedback* incoming_messages_callback);
 
-  uint32_t AudioFrequency() const;
-
+  // The following three methods implement the TelephoneEventHandler interface.
   // Forward DTMFs to decoder for playout.
-  int SetTelephoneEventForwardToDecoder(bool forward_to_decoder);
+  void SetTelephoneEventForwardToDecoder(bool forward_to_decoder);
 
   // Is forwarding of outband telephone events turned on/off?
   bool TelephoneEventForwardToDecoder() const;
@@ -42,22 +42,25 @@
   // Is TelephoneEvent configured with payload type payload_type
   bool TelephoneEventPayloadType(const int8_t payload_type) const;
 
+  TelephoneEventHandler* GetTelephoneEventHandler() {
+    return this;
+  }
+
   // Returns true if CNG is configured with payload type payload_type. If so,
   // the frequency and cng_payload_type_has_changed are filled in.
   bool CNGPayloadType(const int8_t payload_type,
                       uint32_t* frequency,
                       bool* cng_payload_type_has_changed);
 
-  int32_t ParseRtpPacket(
-      WebRtcRTPHeader* rtp_header,
-      const ModuleRTPUtility::PayloadUnion& specific_payload,
-      const bool is_red,
-      const uint8_t* packet,
-      const uint16_t packet_length,
-      const int64_t timestamp_ms,
-      const bool is_first_packet);
+  int32_t ParseRtpPacket(WebRtcRTPHeader* rtp_header,
+                         const PayloadUnion& specific_payload,
+                         bool is_red,
+                         const uint8_t* packet,
+                         uint16_t packet_length,
+                         int64_t timestamp_ms,
+                         bool is_first_packet);
 
-  int32_t GetFrequencyHz() const;
+  int GetPayloadTypeFrequency() const;
 
   RTPAliveType ProcessDeadOrAlive(uint16_t last_payload_length) const;
 
@@ -65,44 +68,45 @@
 
   int32_t OnNewPayloadTypeCreated(
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const int8_t payload_type,
-      const uint32_t frequency);
+      int8_t payload_type,
+      uint32_t frequency);
 
   int32_t InvokeOnInitializeDecoder(
       RtpFeedback* callback,
-      const int32_t id,
-      const int8_t payload_type,
+      int32_t id,
+      int8_t payload_type,
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const ModuleRTPUtility::PayloadUnion& specific_payload) const;
+      const PayloadUnion& specific_payload) const;
 
   // We do not allow codecs to have multiple payload types for audio, so we
   // need to override the default behavior (which is to do nothing).
   void PossiblyRemoveExistingPayloadType(
       ModuleRTPUtility::PayloadTypeMap* payload_type_map,
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const size_t payload_name_length,
-      const uint32_t frequency,
-      const uint8_t channels,
-      const uint32_t rate) const;
+      size_t payload_name_length,
+      uint32_t frequency,
+      uint8_t channels,
+      uint32_t rate) const;
 
   // We need to look out for special payload types here and sometimes reset
   // statistics. In addition we sometimes need to tweak the frequency.
-  void CheckPayloadChanged(const int8_t payload_type,
-                           ModuleRTPUtility::PayloadUnion* specific_payload,
+  void CheckPayloadChanged(int8_t payload_type,
+                           PayloadUnion* specific_payload,
                            bool* should_reset_statistics,
                            bool* should_discard_changes);
 
+  int Energy(uint8_t array_of_energy[kRtpCsrcSize]) const;
+
  private:
 
   int32_t ParseAudioCodecSpecific(
       WebRtcRTPHeader* rtp_header,
       const uint8_t* payload_data,
-      const uint16_t payload_length,
-      const ModuleRTPUtility::AudioPayload& audio_specific,
-      const bool is_red);
+      uint16_t payload_length,
+      const AudioPayload& audio_specific,
+      bool is_red);
 
   int32_t id_;
-  scoped_ptr<CriticalSectionWrapper> critical_section_rtp_receiver_audio_;
 
   uint32_t last_received_frequency_;
 
@@ -121,6 +125,9 @@
   int8_t g722_payload_type_;
   bool last_received_g722_;
 
+  uint8_t num_energy_;
+  uint8_t current_remote_energy_[kRtpCsrcSize];
+
   RtpAudioFeedback* cb_audio_feedback_;
 };
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
new file mode 100644
index 0000000..7037957
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
@@ -0,0 +1,643 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cassert>
+
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+#include "webrtc/system_wrappers/interface/trace_event.h"
+
+namespace webrtc {
+
+using ModuleRTPUtility::GetCurrentRTP;
+using ModuleRTPUtility::Payload;
+using ModuleRTPUtility::RTPPayloadParser;
+using ModuleRTPUtility::StringCompare;
+
+RtpReceiver* RtpReceiver::CreateVideoReceiver(
+    int id, Clock* clock,
+    RtpData* incoming_payload_callback,
+    RtpFeedback* incoming_messages_callback,
+    RTPPayloadRegistry* rtp_payload_registry) {
+  if (!incoming_payload_callback)
+    incoming_payload_callback = NullObjectRtpData();
+  if (!incoming_messages_callback)
+    incoming_messages_callback = NullObjectRtpFeedback();
+  return new RtpReceiverImpl(
+      id, clock, NullObjectRtpAudioFeedback(), incoming_messages_callback,
+      rtp_payload_registry,
+      RTPReceiverStrategy::CreateVideoStrategy(id, incoming_payload_callback));
+}
+
+RtpReceiver* RtpReceiver::CreateAudioReceiver(
+    int id, Clock* clock,
+    RtpAudioFeedback* incoming_audio_feedback,
+    RtpData* incoming_payload_callback,
+    RtpFeedback* incoming_messages_callback,
+    RTPPayloadRegistry* rtp_payload_registry) {
+  if (!incoming_audio_feedback)
+    incoming_audio_feedback = NullObjectRtpAudioFeedback();
+  if (!incoming_payload_callback)
+    incoming_payload_callback = NullObjectRtpData();
+  if (!incoming_messages_callback)
+    incoming_messages_callback = NullObjectRtpFeedback();
+  return new RtpReceiverImpl(
+      id, clock, incoming_audio_feedback, incoming_messages_callback,
+      rtp_payload_registry,
+      RTPReceiverStrategy::CreateAudioStrategy(id, incoming_payload_callback,
+                                               incoming_audio_feedback));
+}
+
+RtpReceiverImpl::RtpReceiverImpl(int32_t id,
+                         Clock* clock,
+                         RtpAudioFeedback* incoming_audio_messages_callback,
+                         RtpFeedback* incoming_messages_callback,
+                         RTPPayloadRegistry* rtp_payload_registry,
+                         RTPReceiverStrategy* rtp_media_receiver)
+    : clock_(clock),
+      rtp_payload_registry_(rtp_payload_registry),
+      rtp_media_receiver_(rtp_media_receiver),
+      id_(id),
+      cb_rtp_feedback_(incoming_messages_callback),
+      critical_section_rtp_receiver_(
+        CriticalSectionWrapper::CreateCriticalSection()),
+      last_receive_time_(0),
+      last_received_payload_length_(0),
+      ssrc_(0),
+      num_csrcs_(0),
+      current_remote_csrc_(),
+      nack_method_(kNackOff),
+      max_reordering_threshold_(kDefaultMaxReorderingThreshold),
+      rtx_(false),
+      ssrc_rtx_(0),
+      payload_type_rtx_(-1) {
+  assert(incoming_audio_messages_callback && incoming_messages_callback);
+
+  memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_));
+
+  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
+}
+
+RtpReceiverImpl::~RtpReceiverImpl() {
+  for (int i = 0; i < num_csrcs_; ++i) {
+    cb_rtp_feedback_->OnIncomingCSRCChanged(id_, current_remote_csrc_[i],
+                                            false);
+  }
+  delete critical_section_rtp_receiver_;
+  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id_, "%s deleted", __FUNCTION__);
+}
+
+RTPReceiverStrategy* RtpReceiverImpl::GetMediaReceiver() const {
+  return rtp_media_receiver_.get();
+}
+
+RtpVideoCodecTypes RtpReceiverImpl::VideoCodecType() const {
+  PayloadUnion media_specific;
+  rtp_media_receiver_->GetLastMediaSpecificPayload(&media_specific);
+  return media_specific.Video.videoCodecType;
+}
+
+int32_t RtpReceiverImpl::RegisterReceivePayload(
+    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
+    const int8_t payload_type,
+    const uint32_t frequency,
+    const uint8_t channels,
+    const uint32_t rate) {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+  // TODO(phoglund): Try to streamline handling of the RED codec and some other
+  // cases which makes it necessary to keep track of whether we created a
+  // payload or not.
+  bool created_new_payload = false;
+  int32_t result = rtp_payload_registry_->RegisterReceivePayload(
+      payload_name, payload_type, frequency, channels, rate,
+      &created_new_payload);
+  if (created_new_payload) {
+    if (rtp_media_receiver_->OnNewPayloadTypeCreated(payload_name, payload_type,
+                                                     frequency) != 0) {
+      WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
+                   "%s failed to register payload",
+                   __FUNCTION__);
+      return -1;
+    }
+  }
+  return result;
+}
+
+int32_t RtpReceiverImpl::DeRegisterReceivePayload(
+    const int8_t payload_type) {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  return rtp_payload_registry_->DeRegisterReceivePayload(payload_type);
+}
+
+NACKMethod RtpReceiverImpl::NACK() const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  return nack_method_;
+}
+
+// Turn negative acknowledgment requests on/off.
+int32_t RtpReceiverImpl::SetNACKStatus(const NACKMethod method,
+                                   int max_reordering_threshold) {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  if (max_reordering_threshold < 0) {
+    return -1;
+  } else if (method == kNackRtcp) {
+    max_reordering_threshold_ = max_reordering_threshold;
+  } else {
+    max_reordering_threshold_ = kDefaultMaxReorderingThreshold;
+  }
+  nack_method_ = method;
+  return 0;
+}
+
+void RtpReceiverImpl::SetRTXStatus(bool enable, uint32_t ssrc) {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  rtx_ = enable;
+  ssrc_rtx_ = ssrc;
+}
+
+void RtpReceiverImpl::RTXStatus(bool* enable, uint32_t* ssrc,
+                            int* payload_type) const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  *enable = rtx_;
+  *ssrc = ssrc_rtx_;
+  *payload_type = payload_type_rtx_;
+}
+
+void RtpReceiverImpl::SetRtxPayloadType(int payload_type) {
+  CriticalSectionScoped cs(critical_section_rtp_receiver_);
+  payload_type_rtx_ = payload_type;
+}
+
+uint32_t RtpReceiverImpl::SSRC() const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  return ssrc_;
+}
+
+// Get remote CSRC.
+int32_t RtpReceiverImpl::CSRCs(uint32_t array_of_csrcs[kRtpCsrcSize]) const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+  assert(num_csrcs_ <= kRtpCsrcSize);
+
+  if (num_csrcs_ > 0) {
+    memcpy(array_of_csrcs, current_remote_csrc_, sizeof(uint32_t)*num_csrcs_);
+  }
+  return num_csrcs_;
+}
+
+int32_t RtpReceiverImpl::Energy(
+    uint8_t array_of_energy[kRtpCsrcSize]) const {
+  return rtp_media_receiver_->Energy(array_of_energy);
+}
+
+bool RtpReceiverImpl::IncomingRtpPacket(
+  RTPHeader* rtp_header,
+  const uint8_t* packet,
+  int packet_length,
+  PayloadUnion payload_specific,
+  bool in_order) {
+  TRACE_EVENT0("webrtc_rtp", "RTPRecv::Packet");
+  // The rtp_header argument contains the parsed RTP header.
+  int length = packet_length - rtp_header->paddingLength;
+
+  // Sanity check.
+  if ((length - rtp_header->headerLength) < 0) {
+    WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
+                 "%s invalid argument",
+                 __FUNCTION__);
+    return false;
+  }
+  {
+    CriticalSectionScoped cs(critical_section_rtp_receiver_);
+    // TODO(holmer): Make rtp_header const after RTX has been broken out.
+    if (rtx_) {
+      if (ssrc_rtx_ == rtp_header->ssrc) {
+        // Sanity check, RTX packets has 2 extra header bytes.
+        if (rtp_header->headerLength + kRtxHeaderSize > packet_length) {
+          return false;
+        }
+        // If a specific RTX payload type is negotiated, set back to the media
+        // payload type and treat it like a media packet from here.
+        if (payload_type_rtx_ != -1) {
+          if (payload_type_rtx_ == rtp_header->payloadType &&
+              rtp_payload_registry_->last_received_media_payload_type() != -1) {
+            rtp_header->payloadType =
+                rtp_payload_registry_->last_received_media_payload_type();
+          } else {
+            WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
+                         "Incorrect RTX configuration, dropping packet.");
+            return false;
+          }
+        }
+        rtp_header->ssrc = ssrc_;
+        rtp_header->sequenceNumber =
+          (packet[rtp_header->headerLength] << 8) +
+          packet[1 + rtp_header->headerLength];
+        // Count the RTX header as part of the RTP
+        rtp_header->headerLength += 2;
+      }
+    }
+  }
+  int8_t first_payload_byte = 0;
+  if (length > 0) {
+    first_payload_byte = packet[rtp_header->headerLength];
+  }
+  // Trigger our callbacks.
+  CheckSSRCChanged(rtp_header);
+
+  bool is_red = false;
+  bool should_reset_statistics = false;
+
+  if (CheckPayloadChanged(rtp_header,
+                          first_payload_byte,
+                          is_red,
+                          &payload_specific,
+                          &should_reset_statistics) == -1) {
+    if (length - rtp_header->headerLength == 0) {
+      // OK, keep-alive packet.
+      WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
+                   "%s received keepalive",
+                   __FUNCTION__);
+      return true;
+    }
+    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
+                 "%s received invalid payloadtype",
+                 __FUNCTION__);
+    return false;
+  }
+  if (should_reset_statistics) {
+    cb_rtp_feedback_->OnResetStatistics();
+  }
+  WebRtcRTPHeader webrtc_rtp_header;
+  memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
+  webrtc_rtp_header.header = *rtp_header;
+  CheckCSRC(&webrtc_rtp_header);
+
+  uint16_t payload_data_length =
+    ModuleRTPUtility::GetPayloadDataLength(*rtp_header, packet_length);
+
+  bool is_first_packet_in_frame = false;
+  bool is_first_packet = false;
+  {
+    CriticalSectionScoped lock(critical_section_rtp_receiver_);
+    is_first_packet_in_frame =
+          last_received_sequence_number_ + 1 == rtp_header->sequenceNumber &&
+          TimeStamp() != rtp_header->timestamp;
+    is_first_packet = is_first_packet_in_frame || last_receive_time_ == 0;
+  }
+
+  int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
+      &webrtc_rtp_header, payload_specific, is_red, packet, packet_length,
+      clock_->TimeInMilliseconds(), is_first_packet);
+
+  if (ret_val < 0) {
+    return false;
+  }
+
+  {
+    CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+    last_receive_time_ = clock_->TimeInMilliseconds();
+    last_received_payload_length_ = payload_data_length;
+
+    if (in_order) {
+      if (last_received_timestamp_ != rtp_header->timestamp) {
+        last_received_timestamp_ = rtp_header->timestamp;
+        last_received_frame_time_ms_ = clock_->TimeInMilliseconds();
+      }
+      last_received_sequence_number_ = rtp_header->sequenceNumber;
+    }
+  }
+  return true;
+}
+
+// Implementation note: we expect to have the critical_section_rtp_receiver_
+// critsect when we call this.
+bool RtpReceiverImpl::RetransmitOfOldPacket(const RTPHeader& header,
+                                        int jitter, int min_rtt) const {
+  if (InOrderPacket(header.sequenceNumber)) {
+    return false;
+  }
+
+  CriticalSectionScoped cs(critical_section_rtp_receiver_);
+  uint32_t frequency_khz = header.payload_type_frequency / 1000;
+  int64_t time_diff_ms = clock_->TimeInMilliseconds() -
+      last_receive_time_;
+
+  // Diff in time stamp since last received in order.
+  int32_t rtp_time_stamp_diff_ms =
+      static_cast<int32_t>(header.timestamp - last_received_timestamp_) /
+      frequency_khz;
+
+  int32_t max_delay_ms = 0;
+  if (min_rtt == 0) {
+    // Jitter standard deviation in samples.
+    float jitter_std = sqrt(static_cast<float>(jitter));
+
+    // 2 times the standard deviation => 95% confidence.
+    // And transform to milliseconds by dividing by the frequency in kHz.
+    max_delay_ms = static_cast<int32_t>((2 * jitter_std) / frequency_khz);
+
+    // Min max_delay_ms is 1.
+    if (max_delay_ms == 0) {
+      max_delay_ms = 1;
+    }
+  } else {
+    max_delay_ms = (min_rtt / 3) + 1;
+  }
+  if (time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms) {
+    return true;
+  }
+  return false;
+}
+
+bool RtpReceiverImpl::InOrderPacket(const uint16_t sequence_number) const {
+  CriticalSectionScoped cs(critical_section_rtp_receiver_);
+  if (IsNewerSequenceNumber(sequence_number, last_received_sequence_number_)) {
+    return true;
+  } else {
+    // If we have a restart of the remote side this packet is still in order.
+    return !IsNewerSequenceNumber(sequence_number,
+                                  last_received_sequence_number_ -
+                                  max_reordering_threshold_);
+  }
+}
+
+TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
+  return rtp_media_receiver_->GetTelephoneEventHandler();
+}
+
+uint32_t RtpReceiverImpl::TimeStamp() const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  return last_received_timestamp_;
+}
+
+int32_t RtpReceiverImpl::LastReceivedTimeMs() const {
+  CriticalSectionScoped lock(critical_section_rtp_receiver_);
+  return last_received_frame_time_ms_;
+}
+
+// Implementation note: must not hold critsect when called.
+void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader* rtp_header) {
+  bool new_ssrc = false;
+  bool re_initialize_decoder = false;
+  char payload_name[RTP_PAYLOAD_NAME_SIZE];
+  uint8_t channels = 1;
+  uint32_t rate = 0;
+
+  {
+    CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+    int8_t last_received_payload_type =
+        rtp_payload_registry_->last_received_payload_type();
+    if (ssrc_ != rtp_header->ssrc ||
+        (last_received_payload_type == -1 && ssrc_ == 0)) {
+      // We need the payload_type_ to make the call if the remote SSRC is 0.
+      new_ssrc = true;
+
+      cb_rtp_feedback_->OnResetStatistics();
+
+      last_received_timestamp_      = 0;
+      last_received_sequence_number_ = 0;
+      last_received_frame_time_ms_ = 0;
+
+      // Do we have a SSRC? Then the stream is restarted.
+      if (ssrc_) {
+        // Do we have the same codec? Then re-initialize coder.
+        if (rtp_header->payloadType == last_received_payload_type) {
+          re_initialize_decoder = true;
+
+          Payload* payload;
+          if (!rtp_payload_registry_->PayloadTypeToPayload(
+              rtp_header->payloadType, payload)) {
+            return;
+          }
+          assert(payload);
+          payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
+          strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
+          if (payload->audio) {
+            channels = payload->typeSpecific.Audio.channels;
+            rate = payload->typeSpecific.Audio.rate;
+          }
+        }
+      }
+      ssrc_ = rtp_header->ssrc;
+    }
+  }
+  if (new_ssrc) {
+    // We need to get this to our RTCP sender and receiver.
+    // We need to do this outside critical section.
+    cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->ssrc);
+  }
+  if (re_initialize_decoder) {
+    if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
+        id_, rtp_header->payloadType, payload_name,
+        rtp_header->payload_type_frequency, channels, rate)) {
+      // New stream, same codec.
+      WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
+                   "Failed to create decoder for payload type:%d",
+                   rtp_header->payloadType);
+    }
+  }
+}
+
+// Implementation note: must not hold critsect when called.
+// TODO(phoglund): Move as much as possible of this code path into the media
+// specific receivers. Basically this method goes through a lot of trouble to
+// compute something which is only used by the media specific parts later. If
+// this code path moves we can get rid of some of the rtp_receiver ->
+// media_specific interface (such as CheckPayloadChange, possibly get/set
+// last known payload).
+int32_t RtpReceiverImpl::CheckPayloadChanged(
+  const RTPHeader* rtp_header,
+  const int8_t first_payload_byte,
+  bool& is_red,
+  PayloadUnion* specific_payload,
+  bool* should_reset_statistics) {
+  bool re_initialize_decoder = false;
+
+  char payload_name[RTP_PAYLOAD_NAME_SIZE];
+  int8_t payload_type = rtp_header->payloadType;
+
+  {
+    CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+    int8_t last_received_payload_type =
+        rtp_payload_registry_->last_received_payload_type();
+    if (payload_type != last_received_payload_type) {
+      if (rtp_payload_registry_->red_payload_type() == payload_type) {
+        // Get the real codec payload type.
+        payload_type = first_payload_byte & 0x7f;
+        is_red = true;
+
+        if (rtp_payload_registry_->red_payload_type() == payload_type) {
+          // Invalid payload type, traced by caller. If we proceeded here,
+          // this would be set as |_last_received_payload_type|, and we would no
+          // longer catch corrupt packets at this level.
+          return -1;
+        }
+
+        // When we receive RED we need to check the real payload type.
+        if (payload_type == last_received_payload_type) {
+          rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
+          return 0;
+        }
+      }
+      *should_reset_statistics = false;
+      bool should_discard_changes = false;
+
+      rtp_media_receiver_->CheckPayloadChanged(
+        payload_type, specific_payload, should_reset_statistics,
+        &should_discard_changes);
+
+      if (should_discard_changes) {
+        is_red = false;
+        return 0;
+      }
+
+      Payload* payload;
+      if (!rtp_payload_registry_->PayloadTypeToPayload(payload_type, payload)) {
+        // Not a registered payload type.
+        return -1;
+      }
+      assert(payload);
+      payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
+      strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
+
+      rtp_payload_registry_->set_last_received_payload_type(payload_type);
+
+      re_initialize_decoder = true;
+
+      rtp_media_receiver_->SetLastMediaSpecificPayload(payload->typeSpecific);
+      rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
+
+      if (!payload->audio) {
+        if (VideoCodecType() == kRtpVideoFec) {
+          // Only reset the decoder on media packets.
+          re_initialize_decoder = false;
+        } else {
+          bool media_type_unchanged =
+              rtp_payload_registry_->ReportMediaPayloadType(payload_type);
+          if (media_type_unchanged) {
+            // Only reset the decoder if the media codec type has changed.
+            re_initialize_decoder = false;
+          }
+        }
+      }
+      if (re_initialize_decoder) {
+        *should_reset_statistics = true;
+      }
+    } else {
+      rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
+      is_red = false;
+    }
+  }  // End critsect.
+
+  if (re_initialize_decoder) {
+    if (-1 == rtp_media_receiver_->InvokeOnInitializeDecoder(
+        cb_rtp_feedback_, id_, payload_type, payload_name,
+        *specific_payload)) {
+      return -1;  // Wrong payload type.
+    }
+  }
+  return 0;
+}
+
+// Implementation note: must not hold critsect when called.
+void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader* rtp_header) {
+  int32_t num_csrcs_diff = 0;
+  uint32_t old_remote_csrc[kRtpCsrcSize];
+  uint8_t old_num_csrcs = 0;
+
+  {
+    CriticalSectionScoped lock(critical_section_rtp_receiver_);
+
+    if (!rtp_media_receiver_->ShouldReportCsrcChanges(
+        rtp_header->header.payloadType)) {
+      return;
+    }
+    old_num_csrcs  = num_csrcs_;
+    if (old_num_csrcs > 0) {
+      // Make a copy of old.
+      memcpy(old_remote_csrc, current_remote_csrc_,
+             num_csrcs_ * sizeof(uint32_t));
+    }
+    const uint8_t num_csrcs = rtp_header->header.numCSRCs;
+    if ((num_csrcs > 0) && (num_csrcs <= kRtpCsrcSize)) {
+      // Copy new.
+      memcpy(current_remote_csrc_,
+             rtp_header->header.arrOfCSRCs,
+             num_csrcs * sizeof(uint32_t));
+    }
+    if (num_csrcs > 0 || old_num_csrcs > 0) {
+      num_csrcs_diff = num_csrcs - old_num_csrcs;
+      num_csrcs_ = num_csrcs;  // Update stored CSRCs.
+    } else {
+      // No change.
+      return;
+    }
+  }  // End critsect.
+
+  bool have_called_callback = false;
+  // Search for new CSRC in old array.
+  for (uint8_t i = 0; i < rtp_header->header.numCSRCs; ++i) {
+    const uint32_t csrc = rtp_header->header.arrOfCSRCs[i];
+
+    bool found_match = false;
+    for (uint8_t j = 0; j < old_num_csrcs; ++j) {
+      if (csrc == old_remote_csrc[j]) {  // old list
+        found_match = true;
+        break;
+      }
+    }
+    if (!found_match && csrc) {
+      // Didn't find it, report it as new.
+      have_called_callback = true;
+      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, true);
+    }
+  }
+  // Search for old CSRC in new array.
+  for (uint8_t i = 0; i < old_num_csrcs; ++i) {
+    const uint32_t csrc = old_remote_csrc[i];
+
+    bool found_match = false;
+    for (uint8_t j = 0; j < rtp_header->header.numCSRCs; ++j) {
+      if (csrc == rtp_header->header.arrOfCSRCs[j]) {
+        found_match = true;
+        break;
+      }
+    }
+    if (!found_match && csrc) {
+      // Did not find it, report as removed.
+      have_called_callback = true;
+      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, csrc, false);
+    }
+  }
+  if (!have_called_callback) {
+    // If the CSRC list contain non-unique entries we will end up here.
+    // Using CSRC 0 to signal this event, not interop safe, other
+    // implementations might have CSRC 0 as a valid value.
+    if (num_csrcs_diff > 0) {
+      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, true);
+    } else if (num_csrcs_diff < 0) {
+      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, 0, false);
+    }
+  }
+}
+
+}  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.h b/modules/rtp_rtcp/source/rtp_receiver_impl.h
new file mode 100644
index 0000000..2bf332b
--- /dev/null
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.h
@@ -0,0 +1,122 @@
+/*
+ *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
+
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class RtpReceiverImpl : public RtpReceiver {
+ public:
+  // Callbacks passed in here may not be NULL (use Null Object callbacks if you
+  // want callbacks to do nothing). This class takes ownership of the media
+  // receiver but nothing else.
+  RtpReceiverImpl(int32_t id,
+                  Clock* clock,
+                  RtpAudioFeedback* incoming_audio_messages_callback,
+                  RtpFeedback* incoming_messages_callback,
+                  RTPPayloadRegistry* rtp_payload_registry,
+                  RTPReceiverStrategy* rtp_media_receiver);
+
+  virtual ~RtpReceiverImpl();
+
+  RTPReceiverStrategy* GetMediaReceiver() const;
+
+  int32_t RegisterReceivePayload(
+      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
+      const int8_t payload_type,
+      const uint32_t frequency,
+      const uint8_t channels,
+      const uint32_t rate);
+
+  int32_t DeRegisterReceivePayload(const int8_t payload_type);
+
+  bool IncomingRtpPacket(
+      RTPHeader* rtp_header,
+      const uint8_t* incoming_rtp_packet,
+      int incoming_rtp_packet_length,
+      PayloadUnion payload_specific,
+      bool in_order);
+
+  NACKMethod NACK() const;
+
+  // Turn negative acknowledgement requests on/off.
+  int32_t SetNACKStatus(const NACKMethod method, int max_reordering_threshold);
+
+  // Returns the last received timestamp.
+  virtual uint32_t TimeStamp() const;
+  int32_t LastReceivedTimeMs() const;
+
+  uint32_t SSRC() const;
+
+  int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const;
+
+  int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const;
+
+  // RTX.
+  void SetRTXStatus(bool enable, uint32_t ssrc);
+
+  void RTXStatus(bool* enable, uint32_t* ssrc, int* payload_type) const;
+
+  void SetRtxPayloadType(int payload_type);
+
+  virtual bool RetransmitOfOldPacket(const RTPHeader& header,
+                                     int jitter, int min_rtt) const;
+  bool InOrderPacket(const uint16_t sequence_number) const;
+  TelephoneEventHandler* GetTelephoneEventHandler();
+
+ private:
+  RtpVideoCodecTypes VideoCodecType() const;
+
+  void CheckSSRCChanged(const RTPHeader* rtp_header);
+  void CheckCSRC(const WebRtcRTPHeader* rtp_header);
+  int32_t CheckPayloadChanged(const RTPHeader* rtp_header,
+                              const int8_t first_payload_byte,
+                              bool& isRED,
+                              PayloadUnion* payload,
+                              bool* should_reset_statistics);
+
+  Clock* clock_;
+  RTPPayloadRegistry* rtp_payload_registry_;
+  scoped_ptr<RTPReceiverStrategy> rtp_media_receiver_;
+
+  int32_t id_;
+
+  RtpFeedback* cb_rtp_feedback_;
+
+  CriticalSectionWrapper* critical_section_rtp_receiver_;
+  int64_t last_receive_time_;
+  uint16_t last_received_payload_length_;
+
+  // SSRCs.
+  uint32_t ssrc_;
+  uint8_t num_csrcs_;
+  uint32_t current_remote_csrc_[kRtpCsrcSize];
+
+  uint32_t last_received_timestamp_;
+  int64_t last_received_frame_time_ms_;
+  uint16_t last_received_sequence_number_;
+
+  NACKMethod nack_method_;
+  int max_reordering_threshold_;
+
+  bool rtx_;
+  uint32_t ssrc_rtx_;
+  int payload_type_rtx_;
+};
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
diff --git a/modules/rtp_rtcp/source/rtp_receiver_strategy.cc b/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
index 8831e12..14763ba 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
@@ -12,21 +12,30 @@
 
 #include <cstdlib>
 
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+
 namespace webrtc {
 
 RTPReceiverStrategy::RTPReceiverStrategy(RtpData* data_callback)
-    : data_callback_(data_callback) {
+    : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+      data_callback_(data_callback) {
   memset(&last_payload_, 0, sizeof(last_payload_));
 }
 
 void RTPReceiverStrategy::GetLastMediaSpecificPayload(
-  ModuleRTPUtility::PayloadUnion* payload) const {
+    PayloadUnion* payload) const {
+  CriticalSectionScoped cs(crit_sect_.get());
   memcpy(payload, &last_payload_, sizeof(*payload));
 }
 
 void RTPReceiverStrategy::SetLastMediaSpecificPayload(
-  const ModuleRTPUtility::PayloadUnion& payload) {
+    const PayloadUnion& payload) {
+  CriticalSectionScoped cs(crit_sect_.get());
   memcpy(&last_payload_, &payload, sizeof(last_payload_));
 }
 
+int RTPReceiverStrategy::Energy(uint8_t array_of_energy[kRtpCsrcSize]) const {
+  return 0;
+}
+
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_strategy.h b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
index 8e8fa1d..69be56f 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_strategy.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
@@ -14,23 +14,24 @@
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
 
+class TelephoneEventHandler;
+
 // This strategy deals with media-specific RTP packet processing.
 // This class is not thread-safe and must be protected by its caller.
 class RTPReceiverStrategy {
  public:
-  // The data callback is where we should send received payload data.
-  // See ParseRtpPacket. This class does not claim ownership of the callback.
-  // Implementations must NOT hold any critical sections while calling the
-  // callback.
-  //
-  // Note: Implementations may call the callback for other reasons than calls
-  // to ParseRtpPacket, for instance if the implementation somehow recovers a
-  // packet.
-  RTPReceiverStrategy(RtpData* data_callback);
+  static RTPReceiverStrategy* CreateVideoStrategy(int32_t id,
+                                                  RtpData* data_callback);
+  static RTPReceiverStrategy* CreateAudioStrategy(
+      int32_t id, RtpData* data_callback,
+      RtpAudioFeedback* incoming_messages_callback);
+
   virtual ~RTPReceiverStrategy() {}
 
   // Parses the RTP packet and calls the data callback with the payload data.
@@ -39,21 +40,22 @@
   // make changes in the data as necessary. The specific_payload argument
   // provides audio or video-specific data. The is_first_packet argument is true
   // if this packet is either the first packet ever or the first in its frame.
-  virtual int32_t ParseRtpPacket(
-    WebRtcRTPHeader* rtp_header,
-    const ModuleRTPUtility::PayloadUnion& specific_payload,
-    const bool is_red,
-    const uint8_t* packet,
-    const uint16_t packet_length,
-    const int64_t timestamp_ms,
-    const bool is_first_packet) = 0;
+  virtual int32_t ParseRtpPacket(WebRtcRTPHeader* rtp_header,
+                                 const PayloadUnion& specific_payload,
+                                 bool is_red,
+                                 const uint8_t* packet,
+                                 uint16_t packet_length,
+                                 int64_t timestamp_ms,
+                                 bool is_first_packet) = 0;
+
+  virtual TelephoneEventHandler* GetTelephoneEventHandler() = 0;
 
   // Retrieves the last known applicable frequency.
-  virtual int32_t GetFrequencyHz() const = 0;
+  virtual int GetPayloadTypeFrequency() const = 0;
 
   // Computes the current dead-or-alive state.
   virtual RTPAliveType ProcessDeadOrAlive(
-    uint16_t last_payload_length) const = 0;
+      uint16_t last_payload_length) const = 0;
 
   // Returns true if we should report CSRC changes for this payload type.
   // TODO(phoglund): should move out of here along with other payload stuff.
@@ -63,40 +65,49 @@
   // the payload registry.
   virtual int32_t OnNewPayloadTypeCreated(
       const char payloadName[RTP_PAYLOAD_NAME_SIZE],
-      const int8_t payloadType,
-      const uint32_t frequency) = 0;
+      int8_t payloadType,
+      uint32_t frequency) = 0;
 
   // Invokes the OnInitializeDecoder callback in a media-specific way.
   virtual int32_t InvokeOnInitializeDecoder(
-    RtpFeedback* callback,
-    const int32_t id,
-    const int8_t payload_type,
-    const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const ModuleRTPUtility::PayloadUnion& specific_payload) const = 0;
+      RtpFeedback* callback,
+      int32_t id,
+      int8_t payload_type,
+      const char payload_name[RTP_PAYLOAD_NAME_SIZE],
+      const PayloadUnion& specific_payload) const = 0;
 
   // Checks if the payload type has changed, and returns whether we should
   // reset statistics and/or discard this packet.
-  virtual void CheckPayloadChanged(
-    const int8_t payload_type,
-    ModuleRTPUtility::PayloadUnion* specific_payload,
-    bool* should_reset_statistics,
-    bool* should_discard_changes) {
+  virtual void CheckPayloadChanged(int8_t payload_type,
+                                   PayloadUnion* specific_payload,
+                                   bool* should_reset_statistics,
+                                   bool* should_discard_changes) {
     // Default: Keep changes and don't reset statistics.
     *should_discard_changes = false;
     *should_reset_statistics = false;
   }
 
   // Stores / retrieves the last media specific payload for later reference.
-  void GetLastMediaSpecificPayload(
-    ModuleRTPUtility::PayloadUnion* payload) const;
-  void SetLastMediaSpecificPayload(
-    const ModuleRTPUtility::PayloadUnion& payload);
+  void GetLastMediaSpecificPayload(PayloadUnion* payload) const;
+  void SetLastMediaSpecificPayload(const PayloadUnion& payload);
+
+  int Energy(uint8_t array_of_energy[kRtpCsrcSize]) const;
 
  protected:
-  ModuleRTPUtility::PayloadUnion last_payload_;
+  // The data callback is where we should send received payload data.
+  // See ParseRtpPacket. This class does not claim ownership of the callback.
+  // Implementations must NOT hold any critical sections while calling the
+  // callback.
+  //
+  // Note: Implementations may call the callback for other reasons than calls
+  // to ParseRtpPacket, for instance if the implementation somehow recovers a
+  // packet.
+  RTPReceiverStrategy(RtpData* data_callback);
+
+  scoped_ptr<CriticalSectionWrapper> crit_sect_;
+  PayloadUnion last_payload_;
   RtpData* data_callback_;
 };
-
 }  // namespace webrtc
 
 #endif  // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_STRATEGY_H_
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.cc b/modules/rtp_rtcp/source/rtp_receiver_video.cc
index b5e8662..62fcdb1 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -15,9 +15,9 @@
 #include <cassert>  // assert
 #include <cstring>  // memcpy()
 
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
 #include "webrtc/modules/rtp_rtcp/source/receiver_fec.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
@@ -29,21 +29,18 @@
   return (x & 0x3fff) * uint32_t(pow(10.0f, (2 + (x >> 14))));
 }
 
-RTPReceiverVideo::RTPReceiverVideo(
-    const int32_t id,
-    const RTPPayloadRegistry* rtp_rtp_payload_registry,
-    RtpData* data_callback)
+RTPReceiverStrategy* RTPReceiverStrategy::CreateVideoStrategy(
+    int32_t id, RtpData* data_callback) {
+  return new RTPReceiverVideo(id, data_callback);
+}
+
+RTPReceiverVideo::RTPReceiverVideo(int32_t id, RtpData* data_callback)
     : RTPReceiverStrategy(data_callback),
       id_(id),
-      rtp_rtp_payload_registry_(rtp_rtp_payload_registry),
-      critical_section_receiver_video_(
-          CriticalSectionWrapper::CreateCriticalSection()),
-      current_fec_frame_decoded_(false),
       receive_fec_(NULL) {
 }
 
 RTPReceiverVideo::~RTPReceiverVideo() {
-  delete critical_section_receiver_video_;
   delete receive_fec_;
 }
 
@@ -55,12 +52,12 @@
 
 int32_t RTPReceiverVideo::OnNewPayloadTypeCreated(
     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const int8_t payload_type,
-    const uint32_t frequency) {
+    int8_t payload_type,
+    uint32_t frequency) {
   if (ModuleRTPUtility::StringCompare(payload_name, "ULPFEC", 6)) {
     // Enable FEC if not enabled.
     if (receive_fec_ == NULL) {
-      receive_fec_ = new ReceiverFEC(id_, this);
+      receive_fec_ = new ReceiverFEC(id_, data_callback_);
     }
     receive_fec_->SetPayloadTypeFEC(payload_type);
   }
@@ -69,15 +66,16 @@
 
 int32_t RTPReceiverVideo::ParseRtpPacket(
     WebRtcRTPHeader* rtp_header,
-    const ModuleRTPUtility::PayloadUnion& specific_payload,
-    const bool is_red,
+    const PayloadUnion& specific_payload,
+    bool is_red,
     const uint8_t* packet,
-    const uint16_t packet_length,
-    const int64_t timestamp_ms,
-    const bool is_first_packet) {
+    uint16_t packet_length,
+    int64_t timestamp_ms,
+    bool is_first_packet) {
   TRACE_EVENT2("webrtc_rtp", "Video::ParseRtp",
                "seqnum", rtp_header->header.sequenceNumber,
                "timestamp", rtp_header->header.timestamp);
+  rtp_header->type.Video.codec = specific_payload.Video.videoCodecType;
   const uint8_t* payload_data =
       ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
   const uint16_t payload_data_length =
@@ -93,8 +91,8 @@
                                  is_first_packet);
 }
 
-int32_t RTPReceiverVideo::GetFrequencyHz() const {
-  return kDefaultVideoFrequency;
+int RTPReceiverVideo::GetPayloadTypeFrequency() const {
+  return kVideoPayloadTypeFrequency;
 }
 
 RTPAliveType RTPReceiverVideo::ProcessDeadOrAlive(
@@ -104,13 +102,13 @@
 
 int32_t RTPReceiverVideo::InvokeOnInitializeDecoder(
     RtpFeedback* callback,
-    const int32_t id,
-    const int8_t payload_type,
+    int32_t id,
+    int8_t payload_type,
     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-    const ModuleRTPUtility::PayloadUnion& specific_payload) const {
+    const PayloadUnion& specific_payload) const {
   // For video we just go with default values.
   if (-1 == callback->OnInitializeDecoder(
-      id, payload_type, payload_name, kDefaultVideoFrequency, 1, 0)) {
+      id, payload_type, payload_name, kVideoPayloadTypeFrequency, 1, 0)) {
     WEBRTC_TRACE(kTraceError,
                  kTraceRtpRtcp,
                  id,
@@ -127,29 +125,29 @@
 int32_t RTPReceiverVideo::ParseVideoCodecSpecific(
     WebRtcRTPHeader* rtp_header,
     const uint8_t* payload_data,
-    const uint16_t payload_data_length,
-    const RtpVideoCodecTypes video_type,
-    const bool is_red,
+    uint16_t payload_data_length,
+    RtpVideoCodecTypes video_type,
+    bool is_red,
     const uint8_t* incoming_rtp_packet,
-    const uint16_t incoming_rtp_packet_size,
-    const int64_t now_ms,
-    const bool is_first_packet) {
+    uint16_t incoming_rtp_packet_size,
+    int64_t now_ms,
+    bool is_first_packet) {
   int32_t ret_val = 0;
 
-  critical_section_receiver_video_->Enter();
+  crit_sect_->Enter();
 
   if (is_red) {
     if (receive_fec_ == NULL) {
-      critical_section_receiver_video_->Leave();
+      crit_sect_->Leave();
       return -1;
     }
+    crit_sect_->Leave();
     bool FECpacket = false;
     ret_val = receive_fec_->AddReceivedFECPacket(
         rtp_header, incoming_rtp_packet, payload_data_length, FECpacket);
     if (ret_val != -1) {
       ret_val = receive_fec_->ProcessReceivedFEC();
     }
-    critical_section_receiver_video_->Leave();
 
     if (ret_val == 0 && FECpacket) {
       // Callback with the received FEC packet.
@@ -158,21 +156,17 @@
       // empty payload and data length.
       rtp_header->frameType = kFrameEmpty;
       // We need this for the routing.
-      int32_t ret_val = SetCodecType(video_type, rtp_header);
-      if (ret_val != 0) {
-        return ret_val;
-      }
+      rtp_header->type.Video.codec = video_type;
       // Pass the length of FEC packets so that they can be accounted for in
       // the bandwidth estimator.
       ret_val = data_callback_->OnReceivedPayloadData(
           NULL, payload_data_length, rtp_header);
     }
   } else {
-    // will leave the critical_section_receiver_video_ critsect
+    // will leave the crit_sect_ critsect
     ret_val = ParseVideoCodecSpecificSwitch(rtp_header,
                                             payload_data,
                                             payload_data_length,
-                                            video_type,
                                             is_first_packet);
   }
   return ret_val;
@@ -214,82 +208,11 @@
   return rtp_header_length;
 }
 
-int32_t RTPReceiverVideo::ReceiveRecoveredPacketCallback(
-    WebRtcRTPHeader* rtp_header,
-    const uint8_t* payload_data,
-    const uint16_t payload_data_length) {
-  // TODO(pwestin) Re-factor this to avoid the messy critsect handling.
-  critical_section_receiver_video_->Enter();
-
-  current_fec_frame_decoded_ = true;
-
-  ModuleRTPUtility::Payload* payload = NULL;
-  if (rtp_rtp_payload_registry_->PayloadTypeToPayload(
-          rtp_header->header.payloadType, payload) != 0) {
-    critical_section_receiver_video_->Leave();
-    return -1;
-  }
-  // here we can re-create the original lost packet so that we can use it for
-  // the relay we need to re-create the RED header too
-  uint8_t recovered_packet[IP_PACKET_SIZE];
-  uint16_t rtp_header_length =
-      (uint16_t) BuildRTPheader(rtp_header, recovered_packet);
-
-  const uint8_t kREDForFECHeaderLength = 1;
-
-  // replace pltype
-  recovered_packet[1] &= 0x80;  // Reset.
-  recovered_packet[1] += rtp_rtp_payload_registry_->red_payload_type();
-
-  // add RED header
-  recovered_packet[rtp_header_length] = rtp_header->header.payloadType;
-  // f-bit always 0
-
-  memcpy(recovered_packet + rtp_header_length + kREDForFECHeaderLength,
-         payload_data,
-         payload_data_length);
-
-  // A recovered packet can be the first packet, but we lack the ability to
-  // detect it at the moment since we do not store the history of recently
-  // received packets. Most codecs like VP8 deal with this in other ways.
-  bool is_first_packet = false;
-
-  return ParseVideoCodecSpecificSwitch(
-      rtp_header,
-      payload_data,
-      payload_data_length,
-      payload->typeSpecific.Video.videoCodecType,
-      is_first_packet);
-}
-
-int32_t RTPReceiverVideo::SetCodecType(
-    const RtpVideoCodecTypes video_type,
-    WebRtcRTPHeader* rtp_header) const {
-  switch (video_type) {
-    case kRtpGenericVideo:
-      rtp_header->type.Video.codec = kRTPVideoGeneric;
-      break;
-    case kRtpVp8Video:
-      rtp_header->type.Video.codec = kRTPVideoVP8;
-      break;
-    case kRtpFecVideo:
-      rtp_header->type.Video.codec = kRTPVideoFEC;
-      break;
-  }
-  return 0;
-}
-
 int32_t RTPReceiverVideo::ParseVideoCodecSpecificSwitch(
     WebRtcRTPHeader* rtp_header,
     const uint8_t* payload_data,
-    const uint16_t payload_data_length,
-    const RtpVideoCodecTypes video_type,
-    const bool is_first_packet) {
-  int32_t ret_val = SetCodecType(video_type, rtp_header);
-  if (ret_val != 0) {
-    critical_section_receiver_video_->Leave();
-    return ret_val;
-  }
+    uint16_t payload_data_length,
+    bool is_first_packet) {
   WEBRTC_TRACE(kTraceStream,
                kTraceRtpRtcp,
                id_,
@@ -297,25 +220,26 @@
                __FUNCTION__,
                rtp_header->header.timestamp);
 
-  // All receive functions release critical_section_receiver_video_ before
-  // returning.
-  switch (video_type) {
-    case kRtpGenericVideo:
+  // Critical section has already been taken.
+  switch (rtp_header->type.Video.codec) {
+    case kRtpVideoGeneric:
       rtp_header->type.Video.isFirstPacket = is_first_packet;
       return ReceiveGenericCodec(rtp_header, payload_data, payload_data_length);
-    case kRtpVp8Video:
+    case kRtpVideoVp8:
       return ReceiveVp8Codec(rtp_header, payload_data, payload_data_length);
-    case kRtpFecVideo:
+    case kRtpVideoFec:
       break;
+    default:
+      assert(false);
   }
-  critical_section_receiver_video_->Leave();
+  // Releasing the already taken critical section here.
+  crit_sect_->Leave();
   return -1;
 }
 
-int32_t RTPReceiverVideo::ReceiveVp8Codec(
-    WebRtcRTPHeader* rtp_header,
-    const uint8_t* payload_data,
-    const uint16_t payload_data_length) {
+int32_t RTPReceiverVideo::ReceiveVp8Codec(WebRtcRTPHeader* rtp_header,
+                                          const uint8_t* payload_data,
+                                          uint16_t payload_data_length) {
   bool success;
   ModuleRTPUtility::RTPPayload parsed_packet;
   if (payload_data_length == 0) {
@@ -323,12 +247,12 @@
     parsed_packet.info.VP8.dataLength = 0;
   } else {
     ModuleRTPUtility::RTPPayloadParser rtp_payload_parser(
-        kRtpVp8Video, payload_data, payload_data_length, id_);
+        kRtpVideoVp8, payload_data, payload_data_length, id_);
 
     success = rtp_payload_parser.Parse(parsed_packet);
   }
   // from here down we only work on local data
-  critical_section_receiver_video_->Leave();
+  crit_sect_->Leave();
 
   if (!success) {
     return -1;
@@ -391,7 +315,7 @@
   rtp_header->type.Video.isFirstPacket =
       (generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0;
 
-  critical_section_receiver_video_->Leave();
+  crit_sect_->Leave();
 
   if (data_callback_->OnReceivedPayloadData(
           payload_data, payload_data_length, rtp_header) != 0) {
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.h b/modules/rtp_rtcp/source/rtp_receiver_video.h
index 520e201..cd5286b 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.h
@@ -22,27 +22,28 @@
 class CriticalSectionWrapper;
 class ModuleRtpRtcpImpl;
 class ReceiverFEC;
-class RTPReceiver;
-class RTPPayloadRegistry;
+class RtpReceiver;
 
 class RTPReceiverVideo : public RTPReceiverStrategy {
  public:
-  RTPReceiverVideo(const int32_t id,
-                   const RTPPayloadRegistry* rtp_payload_registry,
-                   RtpData* data_callback);
+  RTPReceiverVideo(const int32_t id, RtpData* data_callback);
 
   virtual ~RTPReceiverVideo();
 
   int32_t ParseRtpPacket(
       WebRtcRTPHeader* rtp_header,
-      const ModuleRTPUtility::PayloadUnion& specific_payload,
-      const bool is_red,
+      const PayloadUnion& specific_payload,
+      bool is_red,
       const uint8_t* packet,
-      const uint16_t packet_length,
-      const int64_t timestamp,
-      const bool is_first_packet);
+      uint16_t packet_length,
+      int64_t timestamp,
+      bool is_first_packet);
 
-  int32_t GetFrequencyHz() const;
+  TelephoneEventHandler* GetTelephoneEventHandler() {
+    return NULL;
+  }
+
+  int GetPayloadTypeFrequency() const;
 
   RTPAliveType ProcessDeadOrAlive(uint16_t last_payload_length) const;
 
@@ -50,41 +51,32 @@
 
   int32_t OnNewPayloadTypeCreated(
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const int8_t payload_type,
-      const uint32_t frequency);
+      int8_t payload_type,
+      uint32_t frequency);
 
   int32_t InvokeOnInitializeDecoder(
       RtpFeedback* callback,
-      const int32_t id,
-      const int8_t payload_type,
+      int32_t id,
+      int8_t payload_type,
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
-      const ModuleRTPUtility::PayloadUnion& specific_payload) const;
-
-  virtual int32_t ReceiveRecoveredPacketCallback(
-      WebRtcRTPHeader* rtp_header,
-      const uint8_t* payload_data,
-      const uint16_t payload_data_length);
+      const PayloadUnion& specific_payload) const;
 
   void SetPacketOverHead(uint16_t packet_over_head);
 
  protected:
-  int32_t SetCodecType(const RtpVideoCodecTypes video_type,
-                       WebRtcRTPHeader* rtp_header) const;
-
   int32_t ParseVideoCodecSpecificSwitch(
       WebRtcRTPHeader* rtp_header,
       const uint8_t* payload_data,
-      const uint16_t payload_data_length,
-      const RtpVideoCodecTypes video_type,
-      const bool is_first_packet);
+      uint16_t payload_data_length,
+      bool is_first_packet);
 
   int32_t ReceiveGenericCodec(WebRtcRTPHeader* rtp_header,
                               const uint8_t* payload_data,
-                              const uint16_t payload_data_length);
+                              uint16_t payload_data_length);
 
   int32_t ReceiveVp8Codec(WebRtcRTPHeader* rtp_header,
                           const uint8_t* payload_data,
-                          const uint16_t payload_data_length);
+                          uint16_t payload_data_length);
 
   int32_t BuildRTPheader(const WebRtcRTPHeader* rtp_header,
                          uint8_t* data_buffer) const;
@@ -93,21 +85,17 @@
   int32_t ParseVideoCodecSpecific(
       WebRtcRTPHeader* rtp_header,
       const uint8_t* payload_data,
-      const uint16_t payload_data_length,
-      const RtpVideoCodecTypes video_type,
-      const bool is_red,
+      uint16_t payload_data_length,
+      RtpVideoCodecTypes video_type,
+      bool is_red,
       const uint8_t* incoming_rtp_packet,
-      const uint16_t incoming_rtp_packet_size,
-      const int64_t now_ms,
-      const bool is_first_packet);
+      uint16_t incoming_rtp_packet_size,
+      int64_t now_ms,
+      bool is_first_packet);
 
   int32_t id_;
-  const RTPPayloadRegistry* rtp_rtp_payload_registry_;
-
-  CriticalSectionWrapper* critical_section_receiver_video_;
 
   // FEC
-  bool current_fec_frame_decoded_;
   ReceiverFEC* receive_fec_;
 };
 }  // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_rtcp.gypi b/modules/rtp_rtcp/source/rtp_rtcp.gypi
index bc3320b..8c4f366 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp.gypi
+++ b/modules/rtp_rtcp/source/rtp_rtcp.gypi
@@ -28,11 +28,16 @@
       },
       'sources': [
         # Common
+        '../interface/receive_statistics.h',
         '../interface/rtp_header_parser.h',
+        '../interface/rtp_payload_registry.h',
+        '../interface/rtp_receiver.h',
         '../interface/rtp_rtcp.h',
         '../interface/rtp_rtcp_defines.h',
         'bitrate.cc',
         'bitrate.h',
+        'receive_statistics_impl.cc',
+        'receive_statistics_impl.h',
         'rtp_header_parser.cc',
         'rtp_rtcp_config.h',
         'rtp_rtcp_impl.cc',
@@ -47,8 +52,8 @@
         'rtcp_utility.h',
         'rtp_header_extension.cc',
         'rtp_header_extension.h',
-        'rtp_receiver.cc',
-        'rtp_receiver.h',
+        'rtp_receiver_impl.cc',
+        'rtp_receiver_impl.h',
         'rtp_sender.cc',
         'rtp_sender.h',
         'rtp_utility.cc',
@@ -75,7 +80,6 @@
         'producer_fec.h',
         'rtp_packet_history.cc',
         'rtp_packet_history.h',
-        'rtp_payload_registry.h',
         'rtp_payload_registry.cc',
         'rtp_receiver_strategy.cc',
         'rtp_receiver_strategy.h',
@@ -93,6 +97,7 @@
         'vp8_partition_aggregator.h',
         # Mocks
         '../mocks/mock_rtp_rtcp.h',
+        'mock/mock_rtp_payload_strategy.h',
       ], # source
       # TODO(jschuh): Bug 1348: fix size_t to int truncations.
       'msvs_disabled_warnings': [ 4267, ],
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 99cadf2..6d6c520 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -14,8 +14,6 @@
 #include <string.h>
 
 #include "webrtc/common_types.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
 #include "webrtc/system_wrappers/interface/logging.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 
@@ -38,28 +36,12 @@
 
 namespace webrtc {
 
-static RtpData* NullObjectRtpData() {
-  static NullRtpData null_rtp_data;
-  return &null_rtp_data;
-}
-
-static RtpFeedback* NullObjectRtpFeedback() {
-  static NullRtpFeedback null_rtp_feedback;
-  return &null_rtp_feedback;
-}
-
-static RtpAudioFeedback* NullObjectRtpAudioFeedback() {
-  static NullRtpAudioFeedback null_rtp_audio_feedback;
-  return &null_rtp_audio_feedback;
-}
-
 RtpRtcp::Configuration::Configuration()
     : id(-1),
       audio(false),
       clock(NULL),
       default_module(NULL),
-      incoming_data(NullObjectRtpData()),
-      incoming_messages(NullObjectRtpFeedback()),
+      receive_statistics(NULL),
       outgoing_transport(NULL),
       rtcp_feedback(NULL),
       intra_frame_callback(NULL),
@@ -85,10 +67,7 @@
 }
 
 ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
-    : rtp_payload_registry_(
-          configuration.id,
-          RTPPayloadStrategy::CreateStrategy(configuration.audio)),
-      rtp_sender_(configuration.id,
+    : rtp_sender_(configuration.id,
                   configuration.audio,
                   configuration.clock,
                   configuration.outgoing_transport,
@@ -98,14 +77,12 @@
                    this),
       rtcp_receiver_(configuration.id, configuration.clock, this),
       clock_(configuration.clock),
-      rtp_telephone_event_handler_(NULL),
+      receive_statistics_(configuration.receive_statistics),
       id_(configuration.id),
       audio_(configuration.audio),
       collision_detected_(false),
       last_process_time_(configuration.clock->TimeInMilliseconds()),
       last_bitrate_process_time_(configuration.clock->TimeInMilliseconds()),
-      last_packet_timeout_process_time_(
-          configuration.clock->TimeInMilliseconds()),
       last_rtt_process_time_(configuration.clock->TimeInMilliseconds()),
       packet_overhead_(28),  // IPV4 UDP.
       critical_section_module_ptrs_(
@@ -114,9 +91,6 @@
           CriticalSectionWrapper::CreateCriticalSection()),
       default_module_(
           static_cast<ModuleRtpRtcpImpl*>(configuration.default_module)),
-      dead_or_alive_active_(false),
-      dead_or_alive_timeout_ms_(0),
-      dead_or_alive_last_timer_(0),
       nack_method_(kNackOff),
       nack_last_time_sent_full_(0),
       nack_last_seq_number_sent_(0),
@@ -127,26 +101,6 @@
       , plot1_(NULL),
 #endif
       rtt_observer_(configuration.rtt_observer) {
-  RTPReceiverStrategy* rtp_receiver_strategy;
-  if (configuration.audio) {
-    // If audio, we need to be able to handle telephone events too, so stash
-    // away the audio receiver for those situations.
-    rtp_telephone_event_handler_ =
-        new RTPReceiverAudio(configuration.id, configuration.incoming_data,
-                             configuration.audio_messages);
-    rtp_receiver_strategy = rtp_telephone_event_handler_;
-  } else {
-    rtp_receiver_strategy =
-        new RTPReceiverVideo(configuration.id, &rtp_payload_registry_,
-                             configuration.incoming_data);
-  }
-  rtp_receiver_.reset(new RTPReceiver(
-      configuration.id, configuration.clock, this,
-      configuration.audio_messages, configuration.incoming_data,
-      configuration.incoming_messages, rtp_receiver_strategy,
-      &rtp_payload_registry_));
-
-
   send_video_codec_.codecType = kVideoCodecUnknown;
 
   if (default_module_) {
@@ -235,24 +189,14 @@
 
 // Process any pending tasks such as timeouts (non time critical events).
 int32_t ModuleRtpRtcpImpl::Process() {
-    const int64_t now = clock_->TimeInMilliseconds();
+  const int64_t now = clock_->TimeInMilliseconds();
   last_process_time_ = now;
 
-  if (now >=
-      last_packet_timeout_process_time_ + kRtpRtcpPacketTimeoutProcessTimeMs) {
-    rtp_receiver_->PacketTimeout();
-    rtcp_receiver_.PacketTimeout();
-    last_packet_timeout_process_time_ = now;
-  }
-
   if (now >= last_bitrate_process_time_ + kRtpRtcpBitrateProcessTimeMs) {
     rtp_sender_.ProcessBitrate();
-    rtp_receiver_->ProcessBitrate();
     last_bitrate_process_time_ = now;
   }
 
-  ProcessDeadOrAliveTimer();
-
   const bool default_instance(child_modules_.empty() ? false : true);
   if (!default_instance) {
     if (rtcp_sender_.Sending()) {
@@ -297,8 +241,14 @@
         }
       }
     }
-    if (rtcp_sender_.TimeToSendRTCPReport())
-      rtcp_sender_.SendRTCP(kRtcpReport);
+    if (rtcp_sender_.TimeToSendRTCPReport()) {
+      ReceiveStatistics::RtpReceiveStatistics receive_stats;
+      if (receive_statistics_->Statistics(&receive_stats, true)) {
+        rtcp_sender_.SendRTCP(kRtcpReport, &receive_stats);
+      } else {
+        rtcp_sender_.SendRTCP(kRtcpReport, NULL);
+      }
+    }
   }
 
   if (UpdateRTCPReceiveInformationTimers()) {
@@ -308,230 +258,6 @@
   return 0;
 }
 
-void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
-  bool RTCPalive = false;
-  int64_t now = 0;
-  bool do_callback = false;
-
-  // Do operations on members under lock but avoid making the
-  // ProcessDeadOrAlive() callback under the same lock.
-  {
-    CriticalSectionScoped lock(critical_section_module_ptrs_.get());
-    if (dead_or_alive_active_) {
-      now = clock_->TimeInMilliseconds();
-      if (now > dead_or_alive_timeout_ms_ + dead_or_alive_last_timer_) {
-        // RTCP is alive if we have received a report the last 12 seconds.
-        dead_or_alive_last_timer_ += dead_or_alive_timeout_ms_;
-
-        if (rtcp_receiver_.LastReceived() + 12000 > now)
-          RTCPalive = true;
-
-        do_callback = true;
-      }
-    }
-  }
-
-  if (do_callback)
-    rtp_receiver_->ProcessDeadOrAlive(RTCPalive, now);
-}
-
-int32_t ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
-    const bool enable,
-    const uint8_t sample_time_seconds) {
-  if (enable) {
-    WEBRTC_TRACE(kTraceModuleCall,
-                 kTraceRtpRtcp,
-                 id_,
-                 "SetPeriodicDeadOrAliveStatus(enable, %d)",
-                 sample_time_seconds);
-  } else {
-    WEBRTC_TRACE(kTraceModuleCall,
-                 kTraceRtpRtcp,
-                 id_,
-                 "SetPeriodicDeadOrAliveStatus(disable)");
-  }
-  if (sample_time_seconds == 0) {
-    return -1;
-  }
-  {
-    CriticalSectionScoped lock(critical_section_module_ptrs_.get());
-    dead_or_alive_active_ = enable;
-    dead_or_alive_timeout_ms_ = sample_time_seconds * 1000;
-    // Trigger the first after one period.
-    dead_or_alive_last_timer_ = clock_->TimeInMilliseconds();
-  }
-  return 0;
-}
-
-int32_t ModuleRtpRtcpImpl::PeriodicDeadOrAliveStatus(
-    bool& enable,
-    uint8_t& sample_time_seconds) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "PeriodicDeadOrAliveStatus()");
-
-  enable = dead_or_alive_active_;
-  sample_time_seconds =
-      static_cast<uint8_t>(dead_or_alive_timeout_ms_ / 1000);
-  return 0;
-}
-
-int32_t ModuleRtpRtcpImpl::SetPacketTimeout(
-    const uint32_t rtp_timeout_ms,
-    const uint32_t rtcp_timeout_ms) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "SetPacketTimeout(%u,%u)",
-               rtp_timeout_ms,
-               rtcp_timeout_ms);
-
-  if (rtp_receiver_->SetPacketTimeout(rtp_timeout_ms) == 0) {
-    return rtcp_receiver_.SetPacketTimeout(rtcp_timeout_ms);
-  }
-  return -1;
-}
-
-int32_t ModuleRtpRtcpImpl::RegisterReceivePayload(
-    const CodecInst& voice_codec) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "RegisterReceivePayload(voice_codec)");
-
-  return rtp_receiver_->RegisterReceivePayload(
-      voice_codec.plname,
-      voice_codec.pltype,
-      voice_codec.plfreq,
-      voice_codec.channels,
-      (voice_codec.rate < 0) ? 0 : voice_codec.rate);
-}
-
-int32_t ModuleRtpRtcpImpl::RegisterReceivePayload(
-    const VideoCodec& video_codec) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "RegisterReceivePayload(video_codec)");
-
-  return rtp_receiver_->RegisterReceivePayload(video_codec.plName,
-                                               video_codec.plType,
-                                               90000,
-                                               0,
-                                               video_codec.maxBitrate);
-}
-
-int32_t ModuleRtpRtcpImpl::ReceivePayloadType(
-    const CodecInst& voice_codec,
-  int8_t* pl_type) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "ReceivePayloadType(voice_codec)");
-
-  return rtp_receiver_->ReceivePayloadType(
-           voice_codec.plname,
-           voice_codec.plfreq,
-           voice_codec.channels,
-           (voice_codec.rate < 0) ? 0 : voice_codec.rate,
-           pl_type);
-}
-
-int32_t ModuleRtpRtcpImpl::ReceivePayloadType(
-    const VideoCodec& video_codec,
-  int8_t* pl_type) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "ReceivePayloadType(video_codec)");
-
-  return rtp_receiver_->ReceivePayloadType(video_codec.plName,
-                                           90000,
-                                           0,
-                                           video_codec.maxBitrate,
-                                           pl_type);
-}
-
-int32_t ModuleRtpRtcpImpl::DeRegisterReceivePayload(
-    const int8_t payload_type) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "DeRegisterReceivePayload(%d)",
-               payload_type);
-
-  return rtp_receiver_->DeRegisterReceivePayload(payload_type);
-}
-
-// Get the currently configured SSRC filter.
-int32_t ModuleRtpRtcpImpl::SSRCFilter(
-    uint32_t& allowed_ssrc) const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SSRCFilter()");
-
-  return rtp_receiver_->SSRCFilter(allowed_ssrc);
-}
-
-// Set a SSRC to be used as a filter for incoming RTP streams.
-int32_t ModuleRtpRtcpImpl::SetSSRCFilter(
-    const bool enable,
-    const uint32_t allowed_ssrc) {
-  if (enable) {
-    WEBRTC_TRACE(kTraceModuleCall,
-                 kTraceRtpRtcp,
-                 id_,
-                 "SetSSRCFilter(enable, 0x%x)",
-                 allowed_ssrc);
-  } else {
-    WEBRTC_TRACE(kTraceModuleCall,
-                 kTraceRtpRtcp,
-                 id_,
-                 "SetSSRCFilter(disable)");
-  }
-
-  return rtp_receiver_->SetSSRCFilter(enable, allowed_ssrc);
-}
-
-// Get last received remote timestamp.
-uint32_t ModuleRtpRtcpImpl::RemoteTimestamp() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteTimestamp()");
-
-  return rtp_receiver_->TimeStamp();
-}
-
-int64_t ModuleRtpRtcpImpl::LocalTimeOfRemoteTimeStamp() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
-               "LocalTimeOfRemoteTimeStamp()");
-
-  return rtp_receiver_->LastReceivedTimeMs();
-}
-
-// Get the current estimated remote timestamp.
-int32_t ModuleRtpRtcpImpl::EstimatedRemoteTimeStamp(
-    uint32_t& timestamp) const {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "EstimatedRemoteTimeStamp()");
-
-  return rtp_receiver_->EstimatedRemoteTimeStamp(timestamp);
-}
-
-// Get incoming SSRC.
-uint32_t ModuleRtpRtcpImpl::RemoteSSRC() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteSSRC()");
-
-  return rtp_receiver_->SSRC();
-}
-
-// Get remote CSRC
-int32_t ModuleRtpRtcpImpl::RemoteCSRCs(
-    uint32_t arr_of_csrc[kRtpCsrcSize]) const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteCSRCs()");
-
-  return rtp_receiver_->CSRCs(arr_of_csrc);
-}
-
 int32_t ModuleRtpRtcpImpl::SetRTXSendStatus(RtxMode mode, bool set_ssrc,
                                             uint32_t ssrc) {
   rtp_sender_.SetRTXStatus(mode, set_ssrc, ssrc);
@@ -544,42 +270,10 @@
   return 0;
 }
 
-int32_t ModuleRtpRtcpImpl::SetRTXReceiveStatus(bool enable,
-                                               uint32_t ssrc) {
-  rtp_receiver_->SetRTXStatus(enable, ssrc);
-  return 0;
-}
-
-int32_t ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable, uint32_t* ssrc,
-                                            int* payload_type) const {
-  rtp_receiver_->RTXStatus(enable, ssrc, payload_type);
-  return 0;
-}
-
 void ModuleRtpRtcpImpl::SetRtxSendPayloadType(int payload_type) {
   rtp_sender_.SetRtxPayloadType(payload_type);
 }
 
-void ModuleRtpRtcpImpl::SetRtxReceivePayloadType(int payload_type) {
-  rtp_receiver_->SetRtxPayloadType(payload_type);
-}
-
-// Called by the network module when we receive a packet.
-int32_t ModuleRtpRtcpImpl::IncomingRtpPacket(
-    const uint8_t* incoming_packet,
-    const uint16_t incoming_packet_length,
-    const RTPHeader& parsed_rtp_header) {
-  WEBRTC_TRACE(kTraceStream,
-               kTraceRtpRtcp,
-               id_,
-               "IncomingRtpPacket(packet_length:%u)",
-               incoming_packet_length);
-  RTPHeader rtp_header_copy = parsed_rtp_header;
-  return rtp_receiver_->IncomingRTPPacket(&rtp_header_copy,
-                                          incoming_packet,
-                                          incoming_packet_length);
-}
-
 int32_t ModuleRtpRtcpImpl::IncomingRtcpPacket(
     const uint8_t* rtcp_packet,
     const uint16_t length) {
@@ -882,7 +576,12 @@
   if (!have_child_modules) {
     // Don't send RTCP from default module.
     if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
-      rtcp_sender_.SendRTCP(kRtcpReport);
+      ReceiveStatistics::RtpReceiveStatistics receive_stats;
+      if (receive_statistics_->Statistics(&receive_stats, true)) {
+        rtcp_sender_.SendRTCP(kRtcpReport, &receive_stats);
+      } else {
+        rtcp_sender_.SendRTCP(kRtcpReport, NULL);
+      }
     }
     return rtp_sender_.SendOutgoingData(frame_type,
                                         payload_type,
@@ -1185,12 +884,6 @@
   return rtcp_receiver_.CNAME(remote_ssrc, c_name);
 }
 
-uint16_t ModuleRtpRtcpImpl::RemoteSequenceNumber() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoteSequenceNumber()");
-
-  return rtp_receiver_->SequenceNumber();
-}
-
 int32_t ModuleRtpRtcpImpl::RemoteNTP(
     uint32_t* received_ntpsecs,
     uint32_t* received_ntpfrac,
@@ -1230,21 +923,6 @@
   rtcp_receiver_.SetRTT(static_cast<uint16_t>(rtt));
 }
 
-// Reset RTP statistics.
-int32_t ModuleRtpRtcpImpl::ResetStatisticsRTP() {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "ResetStatisticsRTP()");
-
-  return rtp_receiver_->ResetStatistics();
-}
-
-// Reset RTP data counters for the receiving side.
-int32_t ModuleRtpRtcpImpl::ResetReceiveDataCountersRTP() {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
-               "ResetReceiveDataCountersRTP()");
-
-  return rtp_receiver_->ResetDataCounters();
-}
-
 // Reset RTP data counters for the sending side.
 int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
   WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
@@ -1259,8 +937,18 @@
 int32_t ModuleRtpRtcpImpl::SendRTCP(uint32_t rtcp_packet_type) {
   WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SendRTCP(0x%x)",
                rtcp_packet_type);
-
-  return  rtcp_sender_.SendRTCP(rtcp_packet_type);
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  if (rtcp_sender_.Status() == kRtcpCompound ||
+      (rtcp_packet_type & kRtcpReport) ||
+      (rtcp_packet_type & kRtcpSr) ||
+      (rtcp_packet_type & kRtcpRr)) {
+    if (receive_statistics_->Statistics(&receive_stats, true)) {
+      return rtcp_sender_.SendRTCP(rtcp_packet_type, &receive_stats);
+    } else {
+      return rtcp_sender_.SendRTCP(rtcp_packet_type, NULL);
+    }
+  }
+  return rtcp_sender_.SendRTCP(rtcp_packet_type, NULL);
 }
 
 int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
@@ -1283,32 +971,9 @@
   return  rtcp_sender_.SetRTCPVoIPMetrics(voip_metric);
 }
 
-// Our locally created statistics of the received RTP stream.
-int32_t ModuleRtpRtcpImpl::StatisticsRTP(
-    uint8_t*  fraction_lost,
-    uint32_t* cum_lost,
-    uint32_t* ext_max,
-    uint32_t* jitter,
-    uint32_t* max_jitter) const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "StatisticsRTP()");
-
-  uint32_t jitter_transmission_time_offset = 0;
-
-  int32_t ret_val = rtp_receiver_->Statistics(
-      fraction_lost, cum_lost, ext_max, jitter, max_jitter,
-      &jitter_transmission_time_offset, (rtcp_sender_.Status() == kRtcpOff));
-  if (ret_val == -1) {
-    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
-                 "StatisticsRTP() no statistics available");
-  }
-  return ret_val;
-}
-
 int32_t ModuleRtpRtcpImpl::DataCountersRTP(
     uint32_t* bytes_sent,
-    uint32_t* packets_sent,
-    uint32_t* bytes_received,
-    uint32_t* packets_received) const {
+    uint32_t* packets_sent) const {
   WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, "DataCountersRTP()");
 
   if (bytes_sent) {
@@ -1317,36 +982,7 @@
   if (packets_sent) {
     *packets_sent = rtp_sender_.Packets();
   }
-  return rtp_receiver_->DataCounters(bytes_received, packets_received);
-}
-
-int32_t ModuleRtpRtcpImpl::ReportBlockStatistics(
-    uint8_t* fraction_lost,
-    uint32_t* cum_lost,
-    uint32_t* ext_max,
-    uint32_t* jitter,
-    uint32_t* jitter_transmission_time_offset) {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "ReportBlockStatistics()");
-  int32_t missing = 0;
-  int32_t ret = rtp_receiver_->Statistics(fraction_lost,
-                                          cum_lost,
-                                          ext_max,
-                                          jitter,
-                                          NULL,
-                                          jitter_transmission_time_offset,
-                                          &missing,
-                                                true);
-
-#ifdef MATLAB
-  if (plot1_ == NULL) {
-    plot1_ = eng.NewPlot(new MatlabPlot());
-    plot1_->AddTimeLine(30, "b", "lost", clock_->TimeInMilliseconds());
-  }
-  plot1_->Append("lost", missing);
-  plot1_->Plot();
-#endif
-
-  return ret;
+  return 0;
 }
 
 int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* sender_info) {
@@ -1461,52 +1097,6 @@
   return rtcp_sender_.SetTMMBN(bounding_set, max_bitrate_kbit);
 }
 
-// (NACK) Negative acknowledgment.
-
-// Is Negative acknowledgment requests on/off?
-NACKMethod ModuleRtpRtcpImpl::NACK() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "NACK()");
-
-  NACKMethod child_method = kNackOff;
-  const bool default_instance(child_modules_.empty() ? false : true);
-  if (default_instance) {
-    // For default we need to check all child modules too.
-    CriticalSectionScoped lock(critical_section_module_ptrs_.get());
-    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
-      child_modules_.begin();
-    while (it != child_modules_.end()) {
-      RtpRtcp* module = *it;
-      if (module) {
-        NACKMethod nackMethod = module->NACK();
-        if (nackMethod != kNackOff) {
-          child_method = nackMethod;
-          break;
-        }
-      }
-      it++;
-    }
-  }
-
-  NACKMethod method = nack_method_;
-  if (child_method != kNackOff) {
-    method = child_method;
-  }
-  return method;
-}
-
-// Turn negative acknowledgment requests on/off.
-int32_t ModuleRtpRtcpImpl::SetNACKStatus(
-    NACKMethod method, int max_reordering_threshold) {
-  WEBRTC_TRACE(kTraceModuleCall,
-               kTraceRtpRtcp,
-               id_,
-               "SetNACKStatus(%u)", method);
-
-  nack_method_ = method;
-  rtp_receiver_->SetNACKStatus(method, max_reordering_threshold);
-  return 0;
-}
-
 // Returns the currently configured retransmission mode.
 int ModuleRtpRtcpImpl::SelectiveRetransmissions() const {
   WEBRTC_TRACE(kTraceModuleCall,
@@ -1536,7 +1126,7 @@
                "SendNACK(size:%u)", size);
 
   uint16_t avg_rtt = 0;
-  rtcp_receiver_.RTT(rtp_receiver_->SSRC(), NULL, &avg_rtt, NULL, NULL);
+  rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &avg_rtt, NULL, NULL);
 
   int64_t wait_time = 5 + ((avg_rtt * 3) >> 1);  // 5 + RTT * 1.5.
   if (wait_time == 5) {
@@ -1575,13 +1165,15 @@
   }
   nack_last_seq_number_sent_ = nack_list[start_id + nackLength - 1];
 
-  switch (nack_method_) {
-    case kNackRtcp:
-      return rtcp_sender_.SendRTCP(kRtcpNack, nackLength, &nack_list[start_id]);
-    case kNackOff:
-      return -1;
-  };
-  return -1;
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  if (rtcp_sender_.Status() == kRtcpCompound &&
+      receive_statistics_->Statistics(&receive_stats, true)) {
+    return rtcp_sender_.SendRTCP(kRtcpNack, &receive_stats, nackLength,
+                                 &nack_list[start_id]);
+  } else {
+    return rtcp_sender_.SendRTCP(kRtcpNack, NULL, nackLength,
+                                 &nack_list[start_id]);
+  }
 }
 
 // Store the sent packets, needed to answer to a Negative acknowledgment
@@ -1601,29 +1193,6 @@
   return 0;  // TODO(pwestin): change to void.
 }
 
-// Forward DTMFs to decoder for playout.
-int ModuleRtpRtcpImpl::SetTelephoneEventForwardToDecoder(
-    bool forward_to_decoder) {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
-               "SetTelephoneEventForwardToDecoder(forward_to_decoder:%d)",
-               forward_to_decoder);
-
-  assert(audio_);
-  assert(rtp_telephone_event_handler_);
-  return rtp_telephone_event_handler_->SetTelephoneEventForwardToDecoder(
-      forward_to_decoder);
-}
-
-// Is forwarding of out-band telephone events turned on/off?
-bool ModuleRtpRtcpImpl::TelephoneEventForwardToDecoder() const {
-  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_,
-               "TelephoneEventForwardToDecoder()");
-
-  assert(audio_);
-  assert(rtp_telephone_event_handler_);
-  return rtp_telephone_event_handler_->TelephoneEventForwardToDecoder();
-}
-
 // Send a TelephoneEvent tone using RFC 2833 (4733).
 int32_t ModuleRtpRtcpImpl::SendTelephoneEventOutband(
     const uint8_t key,
@@ -1716,10 +1285,6 @@
   return rtp_sender_.RED(&payload_type);
 }
 
-RtpVideoCodecTypes ModuleRtpRtcpImpl::ReceivedVideoCodec() const {
-  return rtp_receiver_->VideoCodecType();
-}
-
 RtpVideoCodecTypes ModuleRtpRtcpImpl::SendVideoCodec() const {
   return rtp_sender_.VideoCodecType();
 }
@@ -1785,9 +1350,9 @@
     case kKeyFrameReqFirRtp:
       return rtp_sender_.SendRTPIntraRequest();
     case kKeyFrameReqPliRtcp:
-      return rtcp_sender_.SendRTCP(kRtcpPli);
+      return SendRTCP(kRtcpPli);
     case kKeyFrameReqFirRtcp:
-      return rtcp_sender_.SendRTCP(kRtcpFir);
+      return SendRTCP(kRtcpFir);
   }
   return -1;
 }
@@ -1799,7 +1364,14 @@
                id_,
                "SendRTCPSliceLossIndication (picture_id:%d)",
                picture_id);
-  return rtcp_sender_.SendRTCP(kRtcpSli, 0, 0, false, picture_id);
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  if (rtcp_sender_.Status() == kRtcpCompound &&
+      receive_statistics_->Statistics(&receive_stats, true)) {
+    return rtcp_sender_.SendRTCP(kRtcpSli, &receive_stats, 0, 0, false,
+                                 picture_id);
+  } else {
+    return rtcp_sender_.SendRTCP(kRtcpSli, NULL, 0, 0, false, picture_id);
+  }
 }
 
 int32_t ModuleRtpRtcpImpl::SetCameraDelay(const int32_t delay_ms) {
@@ -1923,7 +1495,7 @@
     }
     if (kRtcpOff != rtcp_sender_.Status()) {
       // Send RTCP bye on the current SSRC.
-      rtcp_sender_.SendRTCP(kRtcpBye);
+      SendRTCP(kRtcpBye);
     }
     // Change local SSRC and inform all objects about the new SSRC.
     rtcp_sender_.SetSSRC(new_ssrc);
@@ -1931,10 +1503,6 @@
   }
 }
 
-uint32_t ModuleRtpRtcpImpl::BitrateReceivedNow() const {
-  return rtp_receiver_->BitrateNow();
-}
-
 void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate,
                                     uint32_t* video_rate,
                                     uint32_t* fec_rate,
@@ -1996,12 +1564,19 @@
 }
 
 void ModuleRtpRtcpImpl::OnRequestSendReport() {
-  rtcp_sender_.SendRTCP(kRtcpSr);
+  SendRTCP(kRtcpSr);
 }
 
 int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
     const uint64_t picture_id) {
-  return rtcp_sender_.SendRTCP(kRtcpRpsi, 0, 0, false, picture_id);
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  if (rtcp_sender_.Status() == kRtcpCompound &&
+      receive_statistics_->Statistics(&receive_stats, true)) {
+    return rtcp_sender_.SendRTCP(kRtcpRpsi, &receive_stats, 0, 0, false,
+                                 picture_id);
+  } else {
+    return rtcp_sender_.SendRTCP(kRtcpRpsi, NULL, 0, 0, false, picture_id);
+  }
 }
 
 uint32_t ModuleRtpRtcpImpl::SendTimeOfSendReport(
@@ -2016,7 +1591,7 @@
     return;
   }
   uint16_t avg_rtt = 0;
-  rtcp_receiver_.RTT(rtp_receiver_->SSRC(), NULL, &avg_rtt, NULL, NULL);
+  rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &avg_rtt, NULL, NULL);
   rtp_sender_.OnReceivedNACK(nack_sequence_numbers, avg_rtt);
 }
 
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index c70f7cb..fd70751 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -17,8 +17,6 @@
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 
@@ -43,72 +41,12 @@
 
   // Receiver part.
 
-  // Configure a timeout value.
-  virtual int32_t SetPacketTimeout(const uint32_t rtp_timeout_ms,
-                                   const uint32_t rtcp_timeout_ms);
-
-  // Set periodic dead or alive notification.
-  virtual int32_t SetPeriodicDeadOrAliveStatus(
-      const bool enable,
-      const uint8_t sample_time_seconds);
-
-  // Get periodic dead or alive notification status.
-  virtual int32_t PeriodicDeadOrAliveStatus(
-      bool& enable,
-      uint8_t& sample_time_seconds);
-
-  virtual int32_t RegisterReceivePayload(const CodecInst& voice_codec);
-
-  virtual int32_t RegisterReceivePayload(const VideoCodec& video_codec);
-
-  virtual int32_t ReceivePayloadType(const CodecInst& voice_codec,
-                                     int8_t* pl_type);
-
-  virtual int32_t ReceivePayloadType(const VideoCodec& video_codec,
-                                     int8_t* pl_type);
-
-  virtual int32_t DeRegisterReceivePayload(
-      const int8_t payload_type);
-
-  // Get the currently configured SSRC filter.
-  virtual int32_t SSRCFilter(uint32_t& allowed_ssrc) const;
-
-  // Set a SSRC to be used as a filter for incoming RTP streams.
-  virtual int32_t SetSSRCFilter(const bool enable,
-                                const uint32_t allowed_ssrc);
-
-  // Get last received remote timestamp.
-  virtual uint32_t RemoteTimestamp() const;
-
-  // Get the local time of the last received remote timestamp.
-  virtual int64_t LocalTimeOfRemoteTimeStamp() const;
-
-  // Get the current estimated remote timestamp.
-  virtual int32_t EstimatedRemoteTimeStamp(
-      uint32_t& timestamp) const;
-
-  virtual uint32_t RemoteSSRC() const;
-
-  virtual int32_t RemoteCSRCs(
-      uint32_t arr_of_csrc[kRtpCsrcSize]) const;
-
-  virtual int32_t SetRTXReceiveStatus(const bool enable,
-                                      const uint32_t ssrc);
-
-  virtual int32_t RTXReceiveStatus(bool* enable, uint32_t* ssrc,
-                                   int* payloadType) const;
-
-  virtual void SetRtxReceivePayloadType(int payload_type);
-
-  // Called when we receive an RTP packet.
-  virtual int32_t IncomingRtpPacket(const uint8_t* incoming_packet,
-                                    const uint16_t packet_length,
-                                    const RTPHeader& parsed_rtp_header);
-
   // Called when we receive an RTCP packet.
   virtual int32_t IncomingRtcpPacket(const uint8_t* incoming_packet,
                                      uint16_t incoming_packet_length);
 
+  virtual void SetRemoteSSRC(const uint32_t ssrc);
+
   // Sender part.
 
   virtual int32_t RegisterSendPayload(const CodecInst& voice_codec);
@@ -239,32 +177,11 @@
   // Normal SR and RR are triggered via the process function.
   virtual int32_t SendRTCP(uint32_t rtcp_packet_type = kRtcpReport);
 
-  // Statistics of our locally created statistics of the received RTP stream.
-  virtual int32_t StatisticsRTP(uint8_t*  fraction_lost,
-                                uint32_t* cum_lost,
-                                uint32_t* ext_max,
-                                uint32_t* jitter,
-                                uint32_t* max_jitter = NULL) const;
-
-  // Reset RTP statistics.
-  virtual int32_t ResetStatisticsRTP();
-
-  virtual int32_t ResetReceiveDataCountersRTP();
-
   virtual int32_t ResetSendDataCountersRTP();
 
   // Statistics of the amount of data sent and received.
   virtual int32_t DataCountersRTP(uint32_t* bytes_sent,
-                                  uint32_t* packets_sent,
-                                  uint32_t* bytes_received,
-                                  uint32_t* packets_received) const;
-
-  virtual int32_t ReportBlockStatistics(
-      uint8_t* fraction_lost,
-      uint32_t* cum_lost,
-      uint32_t* ext_max,
-      uint32_t* jitter,
-      uint32_t* jitter_transmission_time_offset);
+                                  uint32_t* packets_sent) const;
 
   // Get received RTCP report, sender info.
   virtual int32_t RemoteRTCPStat(RTCPSenderInfo* sender_info);
@@ -313,13 +230,6 @@
 
   // (NACK) Negative acknowledgment part.
 
-  // Is Negative acknowledgment requests on/off?
-  virtual NACKMethod NACK() const;
-
-  // Turn negative acknowledgment requests on/off.
-  virtual int32_t SetNACKStatus(const NACKMethod method,
-                                int max_reordering_threshold);
-
   virtual int SelectiveRetransmissions() const;
 
   virtual int SetSelectiveRetransmissions(uint8_t settings);
@@ -349,12 +259,6 @@
   virtual int32_t SetAudioPacketSize(
       const uint16_t packet_size_samples);
 
-  // Forward DTMFs to decoder for playout.
-  virtual int SetTelephoneEventForwardToDecoder(bool forward_to_decoder);
-
-  // Is forwarding of outband telephone events turned on/off?
-  virtual bool TelephoneEventForwardToDecoder() const;
-
   virtual bool SendTelephoneEventActive(int8_t& telephone_event) const;
 
   // Send a TelephoneEvent tone using RFC 2833 (4733).
@@ -382,8 +286,6 @@
 
   // Video part.
 
-  virtual RtpVideoCodecTypes ReceivedVideoCodec() const;
-
   virtual RtpVideoCodecTypes SendVideoCodec() const;
 
   virtual int32_t SendRTCPSliceLossIndication(
@@ -425,8 +327,6 @@
                            uint32_t* fec_rate,
                            uint32_t* nackRate) const;
 
-  virtual void SetRemoteSSRC(const uint32_t ssrc);
-
   virtual uint32_t SendTimeOfSendReport(const uint32_t send_report);
 
   // Good state of RTP receiver inform sender.
@@ -456,8 +356,6 @@
 
   bool UpdateRTCPReceiveInformationTimers();
 
-  void ProcessDeadOrAliveTimer();
-
   uint32_t BitrateReceivedNow() const;
 
   // Get remote SequenceNumber.
@@ -466,10 +364,7 @@
   // Only for internal testing.
   uint32_t LastSendReport(uint32_t& last_rtcptime);
 
-  RTPPayloadRegistry        rtp_payload_registry_;
-
   RTPSender                 rtp_sender_;
-  scoped_ptr<RTPReceiver>   rtp_receiver_;
 
   RTCPSender                rtcp_sender_;
   RTCPReceiver              rtcp_receiver_;
@@ -479,14 +374,13 @@
  private:
   int64_t RtcpReportInterval();
 
-  RTPReceiverAudio*         rtp_telephone_event_handler_;
+  ReceiveStatistics* receive_statistics_;
 
   int32_t             id_;
   const bool                audio_;
   bool                      collision_detected_;
   int64_t             last_process_time_;
   int64_t             last_bitrate_process_time_;
-  int64_t             last_packet_timeout_process_time_;
   int64_t             last_rtt_process_time_;
   uint16_t            packet_overhead_;
 
@@ -495,10 +389,6 @@
   ModuleRtpRtcpImpl*            default_module_;
   std::list<ModuleRtpRtcpImpl*> child_modules_;
 
-  // Dead or alive.
-  bool                  dead_or_alive_active_;
-  uint32_t        dead_or_alive_timeout_ms_;
-  int64_t         dead_or_alive_last_timer_;
   // Send side
   NACKMethod            nack_method_;
   uint32_t        nack_last_time_sent_full_;
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index b72aa35..278cada 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -350,7 +350,7 @@
       return 0;
     }
   }
-  RtpVideoCodecTypes video_type = kRtpGenericVideo;
+  RtpVideoCodecTypes video_type = kRtpVideoGeneric;
   if (CheckPayloadType(payload_type, &video_type) != 0) {
     WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
                  "%s invalid argument failed to find payload_type:%d",
@@ -1183,7 +1183,7 @@
       }
       frequency_hz = frequency;
     } else {
-      frequency_hz = kDefaultVideoFrequency;
+      frequency_hz = kVideoPayloadTypeFrequency;
     }
     uint32_t RTPtime = ModuleRTPUtility::GetCurrentRTP(clock_, frequency_hz);
 
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 1db4377..2d2c8d9 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -37,7 +37,7 @@
     _rtpSender(*rtpSender),
     _sendVideoCritsect(CriticalSectionWrapper::CreateCriticalSection()),
 
-    _videoType(kRtpGenericVideo),
+    _videoType(kRtpVideoGeneric),
     _videoCodecInformation(NULL),
     _maxBitrate(0),
     _retransmissionSettings(kRetransmitBaseLayer),
@@ -89,13 +89,13 @@
     ModuleRTPUtility::Payload*& payload) {
   CriticalSectionScoped cs(_sendVideoCritsect);
 
-  RtpVideoCodecTypes videoType = kRtpGenericVideo;
+  RtpVideoCodecTypes videoType = kRtpVideoGeneric;
   if (ModuleRTPUtility::StringCompare(payloadName, "VP8",3)) {
-    videoType = kRtpVp8Video;
+    videoType = kRtpVideoVp8;
   } else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
-    videoType = kRtpGenericVideo;
+    videoType = kRtpVideoGeneric;
   } else {
-    videoType = kRtpGenericVideo;
+    videoType = kRtpVideoGeneric;
   }
   payload = new ModuleRTPUtility::Payload;
   payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
@@ -302,11 +302,11 @@
     int32_t retVal = -1;
     switch(videoType)
     {
-    case kRtpGenericVideo:
+    case kRtpVideoGeneric:
         retVal = SendGeneric(frameType, payloadType, captureTimeStamp,
                              capture_time_ms, payloadData, payloadSize);
         break;
-    case kRtpVp8Video:
+    case kRtpVideoVp8:
         retVal = SendVP8(frameType,
                          payloadType,
                          captureTimeStamp,
diff --git a/modules/rtp_rtcp/source/rtp_utility.cc b/modules/rtp_rtcp/source/rtp_utility.cc
index 4a3a143..25afd73 100644
--- a/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/modules/rtp_rtcp/source/rtp_utility.cc
@@ -46,6 +46,21 @@
 
 namespace webrtc {
 
+RtpData* NullObjectRtpData() {
+  static NullRtpData null_rtp_data;
+  return &null_rtp_data;
+}
+
+RtpFeedback* NullObjectRtpFeedback() {
+  static NullRtpFeedback null_rtp_feedback;
+  return &null_rtp_feedback;
+}
+
+RtpAudioFeedback* NullObjectRtpAudioFeedback() {
+  static NullRtpAudioFeedback null_rtp_audio_feedback;
+  return &null_rtp_audio_feedback;
+}
+
 namespace ModuleRTPUtility {
 
 enum {
@@ -188,9 +203,9 @@
   type = videoType;
 
   switch (type) {
-    case kRtpGenericVideo:
+    case kRtpVideoGeneric:
       break;
-    case kRtpVp8Video: {
+    case kRtpVideoVp8: {
       info.VP8.nonReferenceFrame = false;
       info.VP8.beginningOfPartition = false;
       info.VP8.partitionID = 0;
@@ -567,9 +582,9 @@
   parsedPacket.SetType(_videoType);
 
   switch (_videoType) {
-    case kRtpGenericVideo:
+    case kRtpVideoGeneric:
       return ParseGeneric(parsedPacket);
-    case kRtpVp8Video:
+    case kRtpVideoVp8:
       return ParseVP8(parsedPacket);
     default:
       return false;
diff --git a/modules/rtp_rtcp/source/rtp_utility.h b/modules/rtp_rtcp/source/rtp_utility.h
index 3bae732..e95830e 100644
--- a/modules/rtp_rtcp/source/rtp_utility.h
+++ b/modules/rtp_rtcp/source/rtp_utility.h
@@ -19,15 +19,13 @@
 #include "webrtc/typedefs.h"
 
 namespace webrtc {
-enum RtpVideoCodecTypes
-{
-    kRtpGenericVideo  = 0,
-    kRtpFecVideo      = 10,
-    kRtpVp8Video      = 11
-};
 
 const uint8_t kRtpMarkerBitMask = 0x80;
 
+RtpData* NullObjectRtpData();
+RtpFeedback* NullObjectRtpFeedback();
+RtpAudioFeedback* NullObjectRtpAudioFeedback();
+
 namespace ModuleRTPUtility
 {
     // January 1970, in NTP seconds.
@@ -36,22 +34,6 @@
     // Magic NTP fractional unit.
     const double NTP_FRAC = 4.294967296E+9;
 
-    struct AudioPayload
-    {
-        uint32_t    frequency;
-        uint8_t     channels;
-        uint32_t    rate;
-    };
-    struct VideoPayload
-    {
-        RtpVideoCodecTypes   videoCodecType;
-        uint32_t       maxRate;
-    };
-    union PayloadUnion
-    {
-        AudioPayload Audio;
-        VideoPayload Video;
-    };
     struct Payload
     {
         char name[RTP_PAYLOAD_NAME_SIZE];
diff --git a/modules/rtp_rtcp/source/rtp_utility_unittest.cc b/modules/rtp_rtcp/source/rtp_utility_unittest.cc
index b7b3db8..02a89fc 100644
--- a/modules/rtp_rtcp/source/rtp_utility_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_utility_unittest.cc
@@ -76,13 +76,13 @@
   payload[0] = 0x14;  // Binary 0001 0100; S = 1, PartID = 4.
   payload[1] = 0x01;  // P frame.
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 4, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 4 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
@@ -97,13 +97,13 @@
   payload[1] = 0x80;
   payload[2] = 17;
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 1 /*N*/, 0 /*S*/, 0 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 0 /*L*/, 0 /*T*/, 0 /*K*/);
@@ -117,7 +117,7 @@
   // Re-use payload, but change to long PictureID.
   payload[2] = 0x80 | 17;
   payload[3] = 17;
-  RTPPayloadParser rtpPayloadParser2(kRtpVp8Video, payload, 10, 0);
+  RTPPayloadParser rtpPayloadParser2(kRtpVideoVp8, payload, 10, 0);
 
   ASSERT_TRUE(rtpPayloadParser2.Parse(parsedPacket));
 
@@ -136,13 +136,13 @@
   payload[1] = 0x40;
   payload[2] = 17;
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 13, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 13, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 1 /*S*/, 0 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 1 /*L*/, 0 /*T*/, 0 /*K*/);
@@ -159,13 +159,13 @@
   payload[1] = 0x20;
   payload[2] = 0x80;  // TID(2) + LayerSync(false)
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 1 /*T*/, 0 /*K*/);
@@ -183,13 +183,13 @@
   payload[1] = 0x10;  // K = 1.
   payload[2] = 0x11;  // KEYIDX = 17 decimal.
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 0 /*I*/, 0 /*L*/, 0 /*T*/, 1 /*K*/);
@@ -209,13 +209,13 @@
   payload[4] = 42;           // Tl0PicIdx.
   payload[5] = 0x40 | 0x20 | 0x11;  // TID(1) + LayerSync(true) + KEYIDX(17).
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 10, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 10, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kPFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8, 0 /*N*/, 0 /*S*/, 8 /*PartID*/);
   VerifyExtensions(parsedPacket.info.VP8, 1 /*I*/, 1 /*L*/, 1 /*T*/, 1 /*K*/);
@@ -236,7 +236,7 @@
   payload[2] = 0x80 | 17;  // ... but only 2 bytes PictureID is provided.
   payload[3] = 17;  // PictureID, low 8 bits.
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, payload, 4, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, payload, 4, 0);
 
   RTPPayload parsedPacket;
   EXPECT_FALSE(rtpPayloadParser.Parse(parsedPacket));
@@ -258,13 +258,13 @@
   ASSERT_EQ(0, packetizer.NextPacket(packet, &send_bytes, &last));
   ASSERT_TRUE(last);
 
-  RTPPayloadParser rtpPayloadParser(kRtpVp8Video, packet, send_bytes, 0);
+  RTPPayloadParser rtpPayloadParser(kRtpVideoVp8, packet, send_bytes, 0);
 
   RTPPayload parsedPacket;
   ASSERT_TRUE(rtpPayloadParser.Parse(parsedPacket));
 
   EXPECT_EQ(ModuleRTPUtility::kIFrame, parsedPacket.frameType);
-  EXPECT_EQ(kRtpVp8Video, parsedPacket.type);
+  EXPECT_EQ(kRtpVideoVp8, parsedPacket.type);
 
   VerifyBasicHeader(parsedPacket.info.VP8,
                     inputHeader.nonReference /*N*/,
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc
index 1eaf0f0..6789e04 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -33,6 +33,10 @@
     configuration.audio = true;
     configuration.clock = &fake_clock;
     module = RtpRtcp::CreateRtpRtcp(configuration);
+    rtp_payload_registry_.reset(new RTPPayloadRegistry(
+            test_id, RTPPayloadStrategy::CreateStrategy(true)));
+    rtp_receiver_.reset(RtpReceiver::CreateAudioReceiver(
+        test_id, &fake_clock, NULL, NULL, NULL, rtp_payload_registry_.get()));
   }
 
   virtual void TearDown() {
@@ -40,6 +44,8 @@
   }
 
   int test_id;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+  scoped_ptr<RtpReceiver> rtp_receiver_;
   RtpRtcp* module;
   uint32_t test_ssrc;
   uint32_t test_timestamp;
@@ -103,9 +109,9 @@
   EXPECT_EQ(0, module->SetTMMBRStatus(false));
   EXPECT_FALSE(module->TMMBR());
 
-  EXPECT_EQ(kNackOff, module->NACK());
-  EXPECT_EQ(0, module->SetNACKStatus(kNackRtcp, 450));
-  EXPECT_EQ(kNackRtcp, module->NACK());
+  EXPECT_EQ(kNackOff, rtp_receiver_->NACK());
+  EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
+  EXPECT_EQ(kNackRtcp, rtp_receiver_->NACK());
 }
 
 TEST_F(RtpRtcpAPITest, RTXSender) {
@@ -129,7 +135,7 @@
   EXPECT_EQ(0, module->SetRTXSendStatus(kRtxRetransmitted, false, 1));
   EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc, &payload_type));
   EXPECT_EQ(kRtxRetransmitted, rtx_mode);
-  EXPECT_EQ(kRtxPayloadType ,payload_type);
+  EXPECT_EQ(kRtxPayloadType, payload_type);
 }
 
 TEST_F(RtpRtcpAPITest, RTXReceiver) {
@@ -137,14 +143,14 @@
   unsigned int ssrc = 0;
   const int kRtxPayloadType = 119;
   int payload_type = -1;
-  EXPECT_EQ(0, module->SetRTXReceiveStatus(true, 1));
-  module->SetRtxReceivePayloadType(kRtxPayloadType);
-  EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc, &payload_type));
+  rtp_receiver_->SetRTXStatus(true, 1);
+  rtp_receiver_->SetRtxPayloadType(kRtxPayloadType);
+  rtp_receiver_->RTXStatus(&enable, &ssrc, &payload_type);
   EXPECT_TRUE(enable);
   EXPECT_EQ(1u, ssrc);
   EXPECT_EQ(kRtxPayloadType ,payload_type);
-  EXPECT_EQ(0, module->SetRTXReceiveStatus(false, 0));
-  EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc, &payload_type));
+  rtp_receiver_->SetRTXStatus(false, 0);
+  rtp_receiver_->RTXStatus(&enable, &ssrc, &payload_type);
   EXPECT_FALSE(enable);
   EXPECT_EQ(kRtxPayloadType ,payload_type);
 }
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.h b/modules/rtp_rtcp/test/testAPI/test_api.h
index 7cce3c8..1a13ab9 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -10,7 +10,10 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -24,10 +27,18 @@
   LoopBackTransport()
     : _count(0),
       _packetLoss(0),
+      rtp_payload_registry_(NULL),
+      rtp_receiver_(NULL),
       _rtpRtcpModule(NULL) {
   }
-  void SetSendModule(RtpRtcp* rtpRtcpModule) {
+  void SetSendModule(RtpRtcp* rtpRtcpModule,
+                     RTPPayloadRegistry* payload_registry,
+                     RtpReceiver* receiver,
+                     ReceiveStatistics* receive_statistics) {
     _rtpRtcpModule = rtpRtcpModule;
+    rtp_payload_registry_ = payload_registry;
+    rtp_receiver_ = receiver;
+    receive_statistics_ = receive_statistics;
   }
   void DropEveryNthPacket(int n) {
     _packetLoss = n;
@@ -44,8 +55,15 @@
     if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
       return -1;
     }
-    if (_rtpRtcpModule->IncomingRtpPacket(static_cast<const uint8_t*>(data),
-                                          len, header) < 0) {
+    PayloadUnion payload_specific;
+    if (!rtp_payload_registry_->GetPayloadSpecifics(
+        header.payloadType, &payload_specific)) {
+      return -1;
+    }
+    receive_statistics_->IncomingPacket(header, len, false, true);
+    if (!rtp_receiver_->IncomingRtpPacket(&header,
+                                          static_cast<const uint8_t*>(data),
+                                          len, payload_specific, true)) {
       return -1;
     }
     return len;
@@ -59,10 +77,13 @@
  private:
   int _count;
   int _packetLoss;
+  ReceiveStatistics* receive_statistics_;
+  RTPPayloadRegistry* rtp_payload_registry_;
+  RtpReceiver* rtp_receiver_;
   RtpRtcp* _rtpRtcpModule;
 };
 
-class RtpReceiver : public RtpData {
+class TestRtpReceiver : public NullRtpData {
  public:
 
   virtual int32_t OnReceivedPayloadData(
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
index d285bff..02414e1 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_audio.cc
@@ -16,13 +16,14 @@
 
 #include "webrtc/common_types.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 
 using namespace webrtc;
 
 #define test_rate 64000u
 
-class VerifyingAudioReceiver : public RtpData {
+class VerifyingAudioReceiver : public NullRtpData {
  public:
   virtual int32_t OnReceivedPayloadData(
       const uint8_t* payloadData,
@@ -58,7 +59,7 @@
   }
 };
 
-class RTPCallback : public RtpFeedback {
+class RTPCallback : public NullRtpFeedback {
  public:
   virtual int32_t OnInitializeDecoder(
       const int32_t id,
@@ -73,24 +74,9 @@
     }
     return 0;
   }
-  virtual void OnPacketTimeout(const int32_t id) {
-  }
-  virtual void OnReceivedPacket(const int32_t id,
-                                const RtpRtcpPacketType packetType) {
-  }
-  virtual void OnPeriodicDeadOrAlive(const int32_t id,
-                                     const RTPAliveType alive) {
-  }
-  virtual void OnIncomingSSRCChanged(const int32_t id,
-                                     const uint32_t SSRC) {
-  }
-  virtual void OnIncomingCSRCChanged(const int32_t id,
-                                     const uint32_t CSRC,
-                                     const bool added) {
-  }
 };
 
-class AudioFeedback : public RtpAudioFeedback {
+class AudioFeedback : public NullRtpAudioFeedback {
   virtual void OnReceivedTelephoneEvent(const int32_t id,
                                         const uint8_t event,
                                         const bool end) {
@@ -110,11 +96,6 @@
       expectedEvent = 32;
     }
   }
-  virtual void OnPlayTelephoneEvent(const int32_t id,
-                                    const uint8_t event,
-                                    const uint16_t lengthMs,
-                                    const uint8_t volume) {
-  };
 };
 
 class RtpRtcpAudioTest : public ::testing::Test {
@@ -137,26 +118,41 @@
     transport1 = new LoopBackTransport();
     transport2 = new LoopBackTransport();
 
+    receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
+    receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));
+
+    rtp_payload_registry1_.reset(new RTPPayloadRegistry(
+        test_id, RTPPayloadStrategy::CreateStrategy(true)));
+    rtp_payload_registry2_.reset(new RTPPayloadRegistry(
+        test_id, RTPPayloadStrategy::CreateStrategy(true)));
+
     RtpRtcp::Configuration configuration;
     configuration.id = test_id;
     configuration.audio = true;
     configuration.clock = &fake_clock;
-    configuration.incoming_data = data_receiver1;
+    configuration.receive_statistics = receive_statistics1_.get();
     configuration.outgoing_transport = transport1;
     configuration.audio_messages = audioFeedback;
 
     module1 = RtpRtcp::CreateRtpRtcp(configuration);
+    rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
+        test_id, &fake_clock, audioFeedback, data_receiver1, NULL,
+        rtp_payload_registry1_.get()));
 
     configuration.id = test_id + 1;
-    configuration.incoming_data = data_receiver2;
-    configuration.incoming_messages = rtp_callback;
+    configuration.receive_statistics = receive_statistics2_.get();
     configuration.outgoing_transport = transport2;
     configuration.audio_messages = audioFeedback;
 
     module2 = RtpRtcp::CreateRtpRtcp(configuration);
+    rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
+            test_id + 1, &fake_clock, audioFeedback, data_receiver2, NULL,
+            rtp_payload_registry2_.get()));
 
-    transport1->SetSendModule(module2);
-    transport2->SetSendModule(module1);
+    transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
+                              rtp_receiver2_.get(), receive_statistics2_.get());
+    transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
+                              rtp_receiver1_.get(), receive_statistics1_.get());
   }
 
   virtual void TearDown() {
@@ -173,6 +169,12 @@
   int test_id;
   RtpRtcp* module1;
   RtpRtcp* module2;
+  scoped_ptr<ReceiveStatistics> receive_statistics1_;
+  scoped_ptr<ReceiveStatistics> receive_statistics2_;
+  scoped_ptr<RtpReceiver> rtp_receiver1_;
+  scoped_ptr<RtpReceiver> rtp_receiver2_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
   VerifyingAudioReceiver* data_receiver1;
   VerifyingAudioReceiver* data_receiver2;
   LoopBackTransport* transport1;
@@ -191,63 +193,93 @@
   EXPECT_EQ(0, module1->SetStartTimestamp(test_timestamp));
 
   // Test detection at the end of a DTMF tone.
-  EXPECT_EQ(0, module2->SetTelephoneEventForwardToDecoder(true));
+  //EXPECT_EQ(0, module2->SetTelephoneEventForwardToDecoder(true));
 
   EXPECT_EQ(0, module1->SetSendingStatus(true));
 
   // Start basic RTP test.
 
   // Send an empty RTP packet.
-  // Should fail since we have not registerd the payload type.
+  // Should fail since we have not registered the payload type.
   EXPECT_EQ(-1, module1->SendOutgoingData(webrtc::kAudioFrameSpeech,
                                           96, 0, -1, NULL, 0));
 
-  CodecInst voiceCodec;
-  voiceCodec.pltype = 96;
-  voiceCodec.plfreq = 8000;
-  memcpy(voiceCodec.plname, "PCMU", 5);
+  CodecInst voice_codec;
+  voice_codec.pltype = 96;
+  voice_codec.plfreq = 8000;
+  memcpy(voice_codec.plname, "PCMU", 5);
 
-  EXPECT_EQ(0, module1->RegisterSendPayload(voiceCodec));
-  EXPECT_EQ(0, module1->RegisterReceivePayload(voiceCodec));
-  EXPECT_EQ(0, module2->RegisterSendPayload(voiceCodec));
-  voiceCodec.rate = test_rate;
-  EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+  EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
+  EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
+  EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
+  voice_codec.rate = test_rate;
+  EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
   printf("4\n");
 
   const uint8_t test[5] = "test";
   EXPECT_EQ(0, module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96,
                                          0, -1, test, 4));
 
-  EXPECT_EQ(test_ssrc, module2->RemoteSSRC());
-  EXPECT_EQ(test_timestamp, module2->RemoteTimestamp());
+  EXPECT_EQ(test_ssrc, rtp_receiver2_->SSRC());
+  EXPECT_EQ(test_timestamp, rtp_receiver2_->TimeStamp());
 }
 
 TEST_F(RtpRtcpAudioTest, RED) {
-  CodecInst voiceCodec;
-  voiceCodec.pltype = 96;
-  voiceCodec.plfreq = 8000;
-  memcpy(voiceCodec.plname, "PCMU", 5);
+  CodecInst voice_codec;
+  voice_codec.pltype = 96;
+  voice_codec.plfreq = 8000;
+  memcpy(voice_codec.plname, "PCMU", 5);
 
-  EXPECT_EQ(0, module1->RegisterSendPayload(voiceCodec));
-  EXPECT_EQ(0, module1->RegisterReceivePayload(voiceCodec));
-  EXPECT_EQ(0, module2->RegisterSendPayload(voiceCodec));
-  voiceCodec.rate = test_rate;
-  EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+  EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
+  EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
+  EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
+  voice_codec.rate = test_rate;
+  EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
 
   EXPECT_EQ(0, module1->SetSSRC(test_ssrc));
   EXPECT_EQ(0, module1->SetStartTimestamp(test_timestamp));
   EXPECT_EQ(0, module1->SetSendingStatus(true));
 
-  voiceCodec.pltype = 127;
-  voiceCodec.plfreq = 8000;
-  memcpy(voiceCodec.plname, "RED", 4);
+  voice_codec.pltype = 127;
+  voice_codec.plfreq = 8000;
+  memcpy(voice_codec.plname, "RED", 4);
 
-  EXPECT_EQ(0, module1->SetSendREDPayloadType(voiceCodec.pltype));
+  EXPECT_EQ(0, module1->SetSendREDPayloadType(voice_codec.pltype));
   int8_t red = 0;
   EXPECT_EQ(0, module1->SendREDPayloadType(red));
-  EXPECT_EQ(voiceCodec.pltype, red);
-  EXPECT_EQ(0, module1->RegisterReceivePayload(voiceCodec));
-  EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+  EXPECT_EQ(voice_codec.pltype, red);
+  EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
+  EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
 
   RTPFragmentationHeader fragmentation;
   fragmentation.fragmentationVectorSize = 2;
@@ -275,28 +307,43 @@
 }
 
 TEST_F(RtpRtcpAudioTest, DTMF) {
-  CodecInst voiceCodec;
-  voiceCodec.pltype = 96;
-  voiceCodec.plfreq = 8000;
-  memcpy(voiceCodec.plname, "PCMU", 5);
+  CodecInst voice_codec;
+  voice_codec.pltype = 96;
+  voice_codec.plfreq = 8000;
+  memcpy(voice_codec.plname, "PCMU", 5);
 
-  EXPECT_EQ(0, module1->RegisterSendPayload(voiceCodec));
-  EXPECT_EQ(0, module1->RegisterReceivePayload(voiceCodec));
-  EXPECT_EQ(0, module2->RegisterSendPayload(voiceCodec));
-  voiceCodec.rate = test_rate;
-  EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+  EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
+  EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
+  EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
+  voice_codec.rate = test_rate;
+  EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+      voice_codec.plname,
+      voice_codec.pltype,
+      voice_codec.plfreq,
+      voice_codec.channels,
+      (voice_codec.rate < 0) ? 0 : voice_codec.rate));
 
   EXPECT_EQ(0, module1->SetSSRC(test_ssrc));
   EXPECT_EQ(0, module1->SetStartTimestamp(test_timestamp));
   EXPECT_EQ(0, module1->SetSendingStatus(true));
 
   // Prepare for DTMF.
-  voiceCodec.pltype = 97;
-  voiceCodec.plfreq = 8000;
-  memcpy(voiceCodec.plname, "telephone-event", 16);
+  voice_codec.pltype = 97;
+  voice_codec.plfreq = 8000;
+  memcpy(voice_codec.plname, "telephone-event", 16);
 
-  EXPECT_EQ(0, module1->RegisterSendPayload(voiceCodec));
-  EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+  EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
+  EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+        voice_codec.plname,
+        voice_codec.pltype,
+        voice_codec.plfreq,
+        voice_codec.channels,
+        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
 
   // Start DTMF test.
   uint32_t timeStamp = 160;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
index 632041c..412c7e2 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_rtcp.cc
@@ -14,7 +14,9 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
 
@@ -68,6 +70,20 @@
   RtpRtcp* _rtpRtcpModule;
 };
 
+class TestRtpFeedback : public NullRtpFeedback {
+ public:
+  TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
+  virtual ~TestRtpFeedback() {}
+
+  virtual void OnIncomingSSRCChanged(const int32_t id,
+                                     const uint32_t SSRC) {
+    rtp_rtcp_->SetRemoteSSRC(SSRC);
+  }
+
+ private:
+  RtpRtcp* rtp_rtcp_;
+};
+
 class RtpRtcpRtcpTest : public ::testing::Test {
  protected:
   RtpRtcpRtcpTest() : fake_clock(123456) {
@@ -81,31 +97,55 @@
   ~RtpRtcpRtcpTest() {}
 
   virtual void SetUp() {
-    receiver = new RtpReceiver();
+    receiver = new TestRtpReceiver();
     transport1 = new LoopBackTransport();
     transport2 = new LoopBackTransport();
     myRTCPFeedback1 = new RtcpCallback();
     myRTCPFeedback2 = new RtcpCallback();
 
+    receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
+    receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));
+
     RtpRtcp::Configuration configuration;
     configuration.id = test_id;
     configuration.audio = true;
     configuration.clock = &fake_clock;
+    configuration.receive_statistics = receive_statistics1_.get();
     configuration.outgoing_transport = transport1;
     configuration.rtcp_feedback = myRTCPFeedback1;
     configuration.intra_frame_callback = myRTCPFeedback1;
-    configuration.incoming_data = receiver;
+
+    rtp_payload_registry1_.reset(new RTPPayloadRegistry(
+            test_id, RTPPayloadStrategy::CreateStrategy(true)));
+    rtp_payload_registry2_.reset(new RTPPayloadRegistry(
+            test_id, RTPPayloadStrategy::CreateStrategy(true)));
 
     module1 = RtpRtcp::CreateRtpRtcp(configuration);
 
+    rtp_feedback1_.reset(new TestRtpFeedback(module1));
+
+    rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
+        test_id, &fake_clock, NULL, receiver, rtp_feedback1_.get(),
+        rtp_payload_registry1_.get()));
+
+    configuration.receive_statistics = receive_statistics2_.get();
     configuration.id = test_id + 1;
     configuration.outgoing_transport = transport2;
     configuration.rtcp_feedback = myRTCPFeedback2;
     configuration.intra_frame_callback = myRTCPFeedback2;
+
     module2 = RtpRtcp::CreateRtpRtcp(configuration);
 
-    transport1->SetSendModule(module2);
-    transport2->SetSendModule(module1);
+    rtp_feedback2_.reset(new TestRtpFeedback(module2));
+
+    rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
+        test_id + 1, &fake_clock, NULL, receiver, rtp_feedback2_.get(),
+        rtp_payload_registry2_.get()));
+
+    transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
+                              rtp_receiver2_.get(), receive_statistics2_.get());
+    transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
+                              rtp_receiver1_.get(), receive_statistics1_.get());
     myRTCPFeedback1->SetModule(module1);
     myRTCPFeedback2->SetModule(module2);
 
@@ -121,16 +161,26 @@
 
     EXPECT_EQ(0, module1->SetSendingStatus(true));
 
-    CodecInst voiceCodec;
-    voiceCodec.pltype = 96;
-    voiceCodec.plfreq = 8000;
-    voiceCodec.rate = 64000;
-    memcpy(voiceCodec.plname, "PCMU", 5);
+    CodecInst voice_codec;
+    voice_codec.pltype = 96;
+    voice_codec.plfreq = 8000;
+    voice_codec.rate = 64000;
+    memcpy(voice_codec.plname, "PCMU", 5);
 
-    EXPECT_EQ(0, module1->RegisterSendPayload(voiceCodec));
-    EXPECT_EQ(0, module1->RegisterReceivePayload(voiceCodec));
-    EXPECT_EQ(0, module2->RegisterSendPayload(voiceCodec));
-    EXPECT_EQ(0, module2->RegisterReceivePayload(voiceCodec));
+    EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
+    EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
+        voice_codec.plname,
+        voice_codec.pltype,
+        voice_codec.plfreq,
+        voice_codec.channels,
+        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
+    EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
+    EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
+        voice_codec.plname,
+        voice_codec.pltype,
+        voice_codec.plfreq,
+        voice_codec.channels,
+        (voice_codec.rate < 0) ? 0 : voice_codec.rate));
 
     // We need to send one RTP packet to get the RTCP packet to be accepted by
     // the receiving module.
@@ -151,9 +201,17 @@
   }
 
   int test_id;
+  scoped_ptr<TestRtpFeedback> rtp_feedback1_;
+  scoped_ptr<TestRtpFeedback> rtp_feedback2_;
+  scoped_ptr<ReceiveStatistics> receive_statistics1_;
+  scoped_ptr<ReceiveStatistics> receive_statistics2_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
+  scoped_ptr<RtpReceiver> rtp_receiver1_;
+  scoped_ptr<RtpReceiver> rtp_receiver2_;
   RtpRtcp* module1;
   RtpRtcp* module2;
-  RtpReceiver* receiver;
+  TestRtpReceiver* receiver;
   LoopBackTransport* transport1;
   LoopBackTransport* transport2;
   RtcpCallback* myRTCPFeedback1;
@@ -173,7 +231,7 @@
 
 TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
   uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
-  EXPECT_EQ(2, module2->RemoteCSRCs(testOfCSRC));
+  EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
   EXPECT_EQ(test_CSRC[0], testOfCSRC[0]);
   EXPECT_EQ(test_CSRC[1], testOfCSRC[1]);
 
@@ -192,10 +250,10 @@
   module2->Process();
 
   char cName[RTCP_CNAME_SIZE];
-  EXPECT_EQ(-1, module2->RemoteCNAME(module2->RemoteSSRC() + 1, cName));
+  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC() + 1, cName));
 
   // Check multiple CNAME.
-  EXPECT_EQ(0, module2->RemoteCNAME(module2->RemoteSSRC(), cName));
+  EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
   EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));
 
   EXPECT_EQ(0, module2->RemoteCNAME(test_CSRC[0], cName));
@@ -207,7 +265,7 @@
   EXPECT_EQ(0, module1->SetSendingStatus(false));
 
   // Test that BYE clears the CNAME
-  EXPECT_EQ(-1, module2->RemoteCNAME(module2->RemoteSSRC(), cName));
+  EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
 }
 
 TEST_F(RtpRtcpRtcpTest, RTCP) {
@@ -276,20 +334,12 @@
   EXPECT_EQ(static_cast<uint32_t>(0),
             reportBlockReceived.cumulativeLost);
 
-  uint8_t  fraction_lost = 0;  // scale 0 to 255
-  uint32_t cum_lost = 0;       // number of lost packets
-  uint32_t ext_max = 0;        // highest sequence number received
-  uint32_t jitter = 0;
-  uint32_t max_jitter = 0;
-  EXPECT_EQ(0, module2->StatisticsRTP(&fraction_lost,
-                                      &cum_lost,
-                                      &ext_max,
-                                      &jitter,
-                                      &max_jitter));
-  EXPECT_EQ(0, fraction_lost);
-  EXPECT_EQ((uint32_t)0, cum_lost);
-  EXPECT_EQ(test_sequence_number, ext_max);
-  EXPECT_EQ(reportBlockReceived.jitter, jitter);
+  ReceiveStatistics::RtpReceiveStatistics stats;
+  EXPECT_TRUE(receive_statistics2_->Statistics(&stats, true));
+  EXPECT_EQ(0, stats.fraction_lost);
+  EXPECT_EQ((uint32_t)0, stats.cumulative_lost);
+  EXPECT_EQ(test_sequence_number, stats.extended_max_sequence_number);
+  EXPECT_EQ(reportBlockReceived.jitter, stats.jitter);
 
   uint16_t RTT;
   uint16_t avgRTT;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index 75d3ff9..b509dd8 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -15,6 +15,8 @@
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "webrtc/common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
@@ -26,6 +28,7 @@
  protected:
   RtpRtcpVideoTest()
       : test_id_(123),
+        rtp_payload_registry_(0, RTPPayloadStrategy::CreateStrategy(false)),
         test_ssrc_(3456),
         test_timestamp_(4567),
         test_sequence_number_(2345),
@@ -35,23 +38,26 @@
 
   virtual void SetUp() {
     transport_ = new LoopBackTransport();
-    receiver_ = new RtpReceiver();
+    receiver_ = new TestRtpReceiver();
+    receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
     RtpRtcp::Configuration configuration;
     configuration.id = test_id_;
     configuration.audio = false;
     configuration.clock = &fake_clock;
-    configuration.incoming_data = receiver_;
     configuration.outgoing_transport = transport_;
 
     video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
+    rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
+        test_id_, &fake_clock, receiver_, NULL, &rtp_payload_registry_));
 
     EXPECT_EQ(0, video_module_->SetRTCPStatus(kRtcpCompound));
     EXPECT_EQ(0, video_module_->SetSSRC(test_ssrc_));
-    EXPECT_EQ(0, video_module_->SetNACKStatus(kNackRtcp, 450));
+    EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
     EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true, 600));
     EXPECT_EQ(0, video_module_->SetSendingStatus(true));
 
-    transport_->SetSendModule(video_module_);
+    transport_->SetSendModule(video_module_, &rtp_payload_registry_,
+                              rtp_receiver_.get(), receive_statistics_.get());
 
     VideoCodec video_codec;
     memset(&video_codec, 0, sizeof(video_codec));
@@ -59,7 +65,11 @@
     memcpy(video_codec.plName, "I420", 5);
 
     EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
-    EXPECT_EQ(0, video_module_->RegisterReceivePayload(video_codec));
+    EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                                       video_codec.plType,
+                                                       90000,
+                                                       0,
+                                                       video_codec.maxBitrate));
 
     payload_data_length_ = sizeof(video_frame_);
 
@@ -117,9 +127,12 @@
   }
 
   int test_id_;
+  scoped_ptr<ReceiveStatistics> receive_statistics_;
+  RTPPayloadRegistry rtp_payload_registry_;
+  scoped_ptr<RtpReceiver> rtp_receiver_;
   RtpRtcp* video_module_;
   LoopBackTransport* transport_;
-  RtpReceiver* receiver_;
+  TestRtpReceiver* receiver_;
   uint32_t test_ssrc_;
   uint32_t test_timestamp_;
   uint16_t test_sequence_number_;
@@ -147,7 +160,11 @@
   codec.codecType = kVideoCodecVP8;
   codec.plType = kPayloadType;
   strncpy(codec.plName, "VP8", 4);
-  EXPECT_EQ(0, video_module_->RegisterReceivePayload(codec));
+  EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName,
+                                                     codec.plType,
+                                                     90000,
+                                                     0,
+                                                     codec.maxBitrate));
   for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
     for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
       int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
@@ -156,8 +173,12 @@
       RTPHeader header;
       scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
       EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header));
-      EXPECT_EQ(0, video_module_->IncomingRtpPacket(padding_packet,
-                                                    packet_size, header));
+      PayloadUnion payload_specific;
+      EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
+                                                           &payload_specific));
+      EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(&header, padding_packet,
+                                                   packet_size,
+                                                   payload_specific, true));
       EXPECT_EQ(0, receiver_->payload_size());
       EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength);
     }
diff --git a/modules/video_coding/main/interface/video_coding_defines.h b/modules/video_coding/main/interface/video_coding_defines.h
index b1b52bd..1a749bc 100644
--- a/modules/video_coding/main/interface/video_coding_defines.h
+++ b/modules/video_coding/main/interface/video_coding_defines.h
@@ -119,7 +119,7 @@
 // Callback class used for informing the user of the incoming bit rate and frame rate.
 class VCMReceiveStatisticsCallback {
  public:
-  virtual int32_t ReceiveStatistics(const uint32_t bitRate,
+  virtual int32_t OnReceiveStatisticsUpdate(const uint32_t bitRate,
                                           const uint32_t frameRate) = 0;
 
  protected:
diff --git a/modules/video_coding/main/source/decoding_state_unittest.cc b/modules/video_coding/main/source/decoding_state_unittest.cc
index d1c5569..509ca9e 100644
--- a/modules/video_coding/main/source/decoding_state_unittest.cc
+++ b/modules/video_coding/main/source/decoding_state_unittest.cc
@@ -37,7 +37,7 @@
   packet->timestamp = 1;
   packet->seqNum = 0xffff;
   packet->frameType = kVideoFrameDelta;
-  packet->codecSpecificHeader.codec = kRTPVideoVP8;
+  packet->codecSpecificHeader.codec = kRtpVideoVp8;
   packet->codecSpecificHeader.codecHeader.VP8.pictureId = 0x007F;
   frame.InsertPacket(*packet, 0, false, 0);
   // Always start with a key frame.
@@ -208,7 +208,7 @@
   VCMFrameBuffer frame;
   VCMPacket* packet = new VCMPacket();
   packet->frameType = kVideoFrameDelta;
-  packet->codecSpecificHeader.codec = kRTPVideoVP8;
+  packet->codecSpecificHeader.codec = kRtpVideoVp8;
   packet->timestamp = 0;
   packet->seqNum = 0;
   packet->codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 0;
@@ -361,7 +361,7 @@
   VCMPacket packet;
   frame.Reset();
   packet.frameType = kVideoFrameKey;
-  packet.codecSpecificHeader.codec = kRTPVideoVP8;
+  packet.codecSpecificHeader.codec = kRtpVideoVp8;
   packet.timestamp = 0;
   packet.seqNum = 0;
   packet.codecSpecificHeader.codecHeader.VP8.tl0PicIdx = 0;
diff --git a/modules/video_coding/main/source/encoded_frame.cc b/modules/video_coding/main/source/encoded_frame.cc
index eb16509..bfefee9 100644
--- a/modules/video_coding/main/source/encoded_frame.cc
+++ b/modules/video_coding/main/source/encoded_frame.cc
@@ -104,7 +104,7 @@
     {
         switch (header->codec)
         {
-            case kRTPVideoVP8:
+            case kRtpVideoVp8:
             {
                 if (_codecSpecificInfo.codecType != kVideoCodecVP8)
                 {
diff --git a/modules/video_coding/main/source/packet.cc b/modules/video_coding/main/source/packet.cc
index 4604572..86583da 100644
--- a/modules/video_coding/main/source/packet.cc
+++ b/modules/video_coding/main/source/packet.cc
@@ -94,7 +94,7 @@
 {
     switch(videoHeader.codec)
     {
-        case kRTPVideoVP8:
+        case kRtpVideoVp8:
             {
                 // Handle all packets within a frame as depending on the previous packet
                 // TODO(holmer): This should be changed to make fragments independent
@@ -111,7 +111,7 @@
                 codec = kVideoCodecVP8;
                 break;
             }
-        case kRTPVideoI420:
+        case kRtpVideoI420:
             {
                 codec = kVideoCodecI420;
                 break;
diff --git a/modules/video_coding/main/source/session_info.cc b/modules/video_coding/main/source/session_info.cc
index 24f8b16..e36d2a7 100644
--- a/modules/video_coding/main/source/session_info.cc
+++ b/modules/video_coding/main/source/session_info.cc
@@ -50,35 +50,35 @@
 
 int VCMSessionInfo::PictureId() const {
   if (packets_.empty() ||
-      packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
+      packets_.front().codecSpecificHeader.codec != kRtpVideoVp8)
     return kNoPictureId;
   return packets_.front().codecSpecificHeader.codecHeader.VP8.pictureId;
 }
 
 int VCMSessionInfo::TemporalId() const {
   if (packets_.empty() ||
-      packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
+      packets_.front().codecSpecificHeader.codec != kRtpVideoVp8)
     return kNoTemporalIdx;
   return packets_.front().codecSpecificHeader.codecHeader.VP8.temporalIdx;
 }
 
 bool VCMSessionInfo::LayerSync() const {
   if (packets_.empty() ||
-        packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
+        packets_.front().codecSpecificHeader.codec != kRtpVideoVp8)
     return false;
   return packets_.front().codecSpecificHeader.codecHeader.VP8.layerSync;
 }
 
 int VCMSessionInfo::Tl0PicId() const {
   if (packets_.empty() ||
-      packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
+      packets_.front().codecSpecificHeader.codec != kRtpVideoVp8)
     return kNoTl0PicIdx;
   return packets_.front().codecSpecificHeader.codecHeader.VP8.tl0PicIdx;
 }
 
 bool VCMSessionInfo::NonReference() const {
   if (packets_.empty() ||
-      packets_.front().codecSpecificHeader.codec != kRTPVideoVP8)
+      packets_.front().codecSpecificHeader.codec != kRtpVideoVp8)
     return false;
   return packets_.front().codecSpecificHeader.codecHeader.VP8.nonReference;
 }
diff --git a/modules/video_coding/main/source/session_info_unittest.cc b/modules/video_coding/main/source/session_info_unittest.cc
index 4b35a08..4163359 100644
--- a/modules/video_coding/main/source/session_info_unittest.cc
+++ b/modules/video_coding/main/source/session_info_unittest.cc
@@ -66,7 +66,7 @@
     TestSessionInfo::SetUp();
     vp8_header_ = &packet_header_.type.Video.codecHeader.VP8;
     packet_header_.frameType = kVideoFrameDelta;
-    packet_header_.type.Video.codec = kRTPVideoVP8;
+    packet_header_.type.Video.codec = kRtpVideoVp8;
     vp8_header_->InitRTPVideoHeaderVP8();
     fragmentation_.VerifyAndAllocateFragmentationHeader(kMaxVP8Partitions);
   }
diff --git a/modules/video_coding/main/source/video_coding_impl.cc b/modules/video_coding/main/source/video_coding_impl.cc
index c996b85..b86d6a8 100644
--- a/modules/video_coding/main/source/video_coding_impl.cc
+++ b/modules/video_coding/main/source/video_coding_impl.cc
@@ -157,7 +157,8 @@
             uint32_t bitRate;
             uint32_t frameRate;
             _receiver.ReceiveStatistics(&bitRate, &frameRate);
-            _receiveStatsCallback->ReceiveStatistics(bitRate, frameRate);
+            _receiveStatsCallback->OnReceiveStatisticsUpdate(bitRate,
+                                                             frameRate);
         }
 
         // Size of render buffer.
diff --git a/modules/video_coding/main/source/video_coding_impl_unittest.cc b/modules/video_coding/main/source/video_coding_impl_unittest.cc
index d4fde8a..0a38582 100644
--- a/modules/video_coding/main/source/video_coding_impl_unittest.cc
+++ b/modules/video_coding/main/source/video_coding_impl_unittest.cc
@@ -192,7 +192,7 @@
   header.header.payloadType = kUnusedPayloadType;
   header.header.ssrc = 1;
   header.header.headerLength = 12;
-  header.type.Video.codec = kRTPVideoVP8;
+  header.type.Video.codec = kRtpVideoVp8;
   for (int i = 0; i < 10; ++i) {
     EXPECT_CALL(packet_request_callback_, ResendPackets(_, _))
         .Times(0);
@@ -216,7 +216,7 @@
   header.header.payloadType = kUnusedPayloadType;
   header.header.ssrc = 1;
   header.header.headerLength = 12;
-  header.type.Video.codec = kRTPVideoVP8;
+  header.type.Video.codec = kRtpVideoVp8;
   // Insert one video frame to get one frame decoded.
   header.frameType = kVideoFrameKey;
   header.type.Video.isFirstPacket = true;
@@ -270,7 +270,7 @@
   header.header.payloadType = kUnusedPayloadType;
   header.header.ssrc = 1;
   header.header.headerLength = 12;
-  header.type.Video.codec = kRTPVideoVP8;
+  header.type.Video.codec = kRtpVideoVp8;
   header.type.Video.codecHeader.VP8.pictureId = -1;
   header.type.Video.codecHeader.VP8.tl0PicIdx = -1;
   for (int i = 0; i < 3; ++i) {
diff --git a/modules/video_coding/main/source/video_coding_robustness_unittest.cc b/modules/video_coding/main/source/video_coding_robustness_unittest.cc
index a259aee..3c53945 100644
--- a/modules/video_coding/main/source/video_coding_robustness_unittest.cc
+++ b/modules/video_coding/main/source/video_coding_robustness_unittest.cc
@@ -67,7 +67,7 @@
     rtp_info.header.sequenceNumber = seq_no;
     rtp_info.header.markerBit = marker_bit;
     rtp_info.header.payloadType = video_codec_.plType;
-    rtp_info.type.Video.codec = kRTPVideoVP8;
+    rtp_info.type.Video.codec = kRtpVideoVp8;
     rtp_info.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
     rtp_info.type.Video.isFirstPacket = first;
 
diff --git a/modules/video_coding/main/test/codec_database_test.cc b/modules/video_coding/main/test/codec_database_test.cc
index b62995c..84ddcef 100644
--- a/modules/video_coding/main/test/codec_database_test.cc
+++ b/modules/video_coding/main/test/codec_database_test.cc
@@ -151,7 +151,7 @@
     // Testing with VP8.
     VideoCodingModule::Codec(kVideoCodecVP8, &sendCodec);
     _vcm->RegisterSendCodec(&sendCodec, 1, 1440);
-    _encodeCompleteCallback->SetCodecType(kRTPVideoVP8);
+    _encodeCompleteCallback->SetCodecType(kRtpVideoVp8);
     _vcm->InitializeReceiver();
     TEST (_vcm->AddVideoFrame(sourceFrame) == VCM_OK );
     _vcm->InitializeSender();
@@ -196,7 +196,7 @@
     VideoCodingModule::Codec(kVideoCodecVP8, &vp8EncSettings);
     _vcm->RegisterTransportCallback(_encodeCallback); // encode returns error if callback uninitialized
     _encodeCallback->RegisterReceiverVCM(_vcm);
-    _encodeCallback->SetCodecType(kRTPVideoVP8);
+    _encodeCallback->SetCodecType(kRtpVideoVp8);
     TEST(_vcm->RegisterExternalEncoder(encoder, vp8EncSettings.plType) == VCM_OK);
     TEST(_vcm->RegisterSendCodec(&vp8EncSettings, 4, 1440) == VCM_OK);
     TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
@@ -232,7 +232,7 @@
     TEST(_vcm->RegisterReceiveCodec(&receiveCodec, 1, true) == VCM_OK); // Require key frame
     _vcm->RegisterTransportCallback(_encodeCallback); // encode returns error if callback uninitialized
     _encodeCallback->RegisterReceiverVCM(_vcm);
-    _encodeCallback->SetCodecType(kRTPVideoVP8);
+    _encodeCallback->SetCodecType(kRtpVideoVp8);
     TEST(_vcm->AddVideoFrame(sourceFrame) == VCM_OK);
     TEST(_vcm->Decode() == VCM_OK);
     TEST(_vcm->ResetDecoder() == VCM_OK);
diff --git a/modules/video_coding/main/test/generic_codec_test.cc b/modules/video_coding/main/test/generic_codec_test.cc
index 1a9ca39..0335349 100644
--- a/modules/video_coding/main/test/generic_codec_test.cc
+++ b/modules/video_coding/main/test/generic_codec_test.cc
@@ -549,7 +549,7 @@
     WebRtcRTPHeader rtpInfo;
     rtpInfo.header.markerBit = true; // end of frame
     rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
-    rtpInfo.type.Video.codec = kRTPVideoVP8;
+    rtpInfo.type.Video.codec = kRtpVideoVp8;
     rtpInfo.header.payloadType = payloadType;
     rtpInfo.header.sequenceNumber = _seqNo;
     _seqNo += 2;
diff --git a/modules/video_coding/main/test/media_opt_test.cc b/modules/video_coding/main/test/media_opt_test.cc
index 04da2e8..490e940 100644
--- a/modules/video_coding/main/test/media_opt_test.cc
+++ b/modules/video_coding/main/test/media_opt_test.cc
@@ -18,6 +18,7 @@
 #include <time.h>
 #include <vector>
 
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
 #include "webrtc/modules/video_coding/main/test/test_macros.h"
 #include "webrtc/modules/video_coding/main/test/test_util.h"
@@ -202,7 +203,6 @@
     RtpRtcp::Configuration configuration;
     configuration.id = 1;
     configuration.audio = false;
-    configuration.incoming_data = _dataCallback;
     configuration.outgoing_transport = _outgoingTransport;
     _rtp = RtpRtcp::CreateRtpRtcp(configuration);
 
@@ -211,21 +211,33 @@
     // Registering codecs for the RTP module
 
     // Register receive and send payload
-    VideoCodec videoCodec;
-    strncpy(videoCodec.plName, "VP8", 32);
-    videoCodec.plType = VCM_VP8_PAYLOAD_TYPE;
-    _rtp->RegisterReceivePayload(videoCodec);
-    _rtp->RegisterSendPayload(videoCodec);
+    VideoCodec video_codec;
+    strncpy(video_codec.plName, "VP8", 32);
+    video_codec.plType = VCM_VP8_PAYLOAD_TYPE;
+    rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                          video_codec.plType,
+                                          90000,
+                                          0,
+                                          video_codec.maxBitrate);
+    _rtp->RegisterSendPayload(video_codec);
 
-    strncpy(videoCodec.plName, "ULPFEC", 32);
-    videoCodec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
-    _rtp->RegisterReceivePayload(videoCodec);
-    _rtp->RegisterSendPayload(videoCodec);
+    strncpy(video_codec.plName, "ULPFEC", 32);
+    video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
+    rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                          video_codec.plType,
+                                          90000,
+                                          0,
+                                          video_codec.maxBitrate);
+    _rtp->RegisterSendPayload(video_codec);
 
-    strncpy(videoCodec.plName, "RED", 32);
-    videoCodec.plType = VCM_RED_PAYLOAD_TYPE;
-    _rtp->RegisterReceivePayload(videoCodec);
-    _rtp->RegisterSendPayload(videoCodec);
+    strncpy(video_codec.plName, "RED", 32);
+    video_codec.plType = VCM_RED_PAYLOAD_TYPE;
+    rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                          video_codec.plType,
+                                          90000,
+                                          0,
+                                          video_codec.maxBitrate);
+    _rtp->RegisterSendPayload(video_codec);
 
     if (_nackFecEnabled == 1)
         _rtp->SetGenericFECStatus(_nackFecEnabled, VCM_RED_PAYLOAD_TYPE,
diff --git a/modules/video_coding/main/test/media_opt_test.h b/modules/video_coding/main/test/media_opt_test.h
index cdbd53d..7f6d5e3 100644
--- a/modules/video_coding/main/test/media_opt_test.h
+++ b/modules/video_coding/main/test/media_opt_test.h
@@ -53,6 +53,7 @@
 private:
 
     webrtc::VideoCodingModule*       _vcm;
+    webrtc::RtpReceiver*             rtp_receiver_;
     webrtc::RtpRtcp*                 _rtp;
     webrtc::RTPSendCompleteCallback* _outgoingTransport;
     RtpDataCallback*                 _dataCallback;
diff --git a/modules/video_coding/main/test/mt_rx_tx_test.cc b/modules/video_coding/main/test/mt_rx_tx_test.cc
index 59b4454..c711578 100644
--- a/modules/video_coding/main/test/mt_rx_tx_test.cc
+++ b/modules/video_coding/main/test/mt_rx_tx_test.cc
@@ -16,6 +16,8 @@
 
 #include <string.h>
 
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
 #include "webrtc/modules/video_coding/main/test/media_opt_test.h"
@@ -152,29 +154,46 @@
     RtpRtcp::Configuration configuration;
     configuration.id = 1;
     configuration.audio = false;
-    configuration.incoming_data = &dataCallback;
     configuration.outgoing_transport = outgoingTransport;
     RtpRtcp* rtp = RtpRtcp::CreateRtpRtcp(configuration);
+    scoped_ptr<RTPPayloadRegistry> registry(new RTPPayloadRegistry(
+        -1, RTPPayloadStrategy::CreateStrategy(false)));
+    scoped_ptr<RtpReceiver> rtp_receiver(
+        RtpReceiver::CreateVideoReceiver(-1, Clock::GetRealTimeClock(),
+                                         &dataCallback, NULL, registry.get()));
 
     // registering codecs for the RTP module
-    VideoCodec videoCodec;
-    strncpy(videoCodec.plName, "ULPFEC", 32);
-    videoCodec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
-    TEST(rtp->RegisterReceivePayload(videoCodec) == 0);
+    VideoCodec video_codec;
+    strncpy(video_codec.plName, "ULPFEC", 32);
+    video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
+    TEST(rtp_receiver->RegisterReceivePayload(video_codec.plName,
+                                              video_codec.plType,
+                                              90000,
+                                              0,
+                                              video_codec.maxBitrate) == 0);
 
-    strncpy(videoCodec.plName, "RED", 32);
-    videoCodec.plType = VCM_RED_PAYLOAD_TYPE;
-    TEST(rtp->RegisterReceivePayload(videoCodec) == 0);
+    strncpy(video_codec.plName, "RED", 32);
+    video_codec.plType = VCM_RED_PAYLOAD_TYPE;
+    TEST(rtp_receiver->RegisterReceivePayload(video_codec.plName,
+                                              video_codec.plType,
+                                              90000,
+                                              0,
+                                              video_codec.maxBitrate) == 0);
 
-    strncpy(videoCodec.plName, args.codecName.c_str(), 32);
-    videoCodec.plType = VCM_VP8_PAYLOAD_TYPE;
-    videoCodec.maxBitrate = 10000;
-    videoCodec.codecType = args.codecType;
-    TEST(rtp->RegisterReceivePayload(videoCodec) == 0);
-    TEST(rtp->RegisterSendPayload(videoCodec) == 0);
+    strncpy(video_codec.plName, args.codecName.c_str(), 32);
+    video_codec.plType = VCM_VP8_PAYLOAD_TYPE;
+    video_codec.maxBitrate = 10000;
+    video_codec.codecType = args.codecType;
+    TEST(rtp_receiver->RegisterReceivePayload(video_codec.plName,
+                                              video_codec.plType,
+                                              90000,
+                                              0,
+                                              video_codec.maxBitrate) == 0);
+    TEST(rtp->RegisterSendPayload(video_codec) == 0);
 
     // inform RTP Module of error resilience features
-    TEST(rtp->SetGenericFECStatus(fecEnabled, VCM_RED_PAYLOAD_TYPE, VCM_ULPFEC_PAYLOAD_TYPE) == 0);
+    TEST(rtp->SetGenericFECStatus(fecEnabled, VCM_RED_PAYLOAD_TYPE,
+                                  VCM_ULPFEC_PAYLOAD_TYPE) == 0);
 
     //VCM
     if (vcm->InitializeReceiver() < 0)
@@ -238,7 +257,8 @@
     FecProtectionParams delta_params = protectionCallback.DeltaFecParameters();
     FecProtectionParams key_params = protectionCallback.KeyFecParameters();
     rtp->SetFecParameters(&delta_params, &key_params);
-    rtp->SetNACKStatus(nackEnabled ? kNackRtcp : kNackOff, kMaxPacketAgeToNack);
+    rtp_receiver->SetNACKStatus(nackEnabled ? kNackRtcp : kNackOff,
+        kMaxPacketAgeToNack);
 
     vcm->SetChannelParameters(static_cast<uint32_t>(1000 * bitRate),
                               (uint8_t) lossRate, rttMS);
diff --git a/modules/video_coding/main/test/mt_test_common.cc b/modules/video_coding/main/test/mt_test_common.cc
index 04b180d..cdf57ee 100644
--- a/modules/video_coding/main/test/mt_test_common.cc
+++ b/modules/video_coding/main/test/mt_test_common.cc
@@ -13,6 +13,8 @@
 #include <cmath>
 
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/utility/interface/rtp_dump.h"
 #include "webrtc/system_wrappers/interface/clock.h"
 
@@ -95,7 +97,14 @@
           delete packet;
           return -1;
         }
-        if (_rtp->IncomingRtpPacket(packet->data, packet->length, header) < 0)
+        PayloadUnion payload_specific;
+        if (!rtp_payload_registry_->GetPayloadSpecifics(
+            header.payloadType, &payload_specific)) {
+          return -1;
+        }
+        if (!rtp_receiver_->IncomingRtpPacket(&header, packet->data,
+                                              packet->length, payload_specific,
+                                              true))
         {
             delete packet;
             return -1;
diff --git a/modules/video_coding/main/test/normal_test.cc b/modules/video_coding/main/test/normal_test.cc
index 04efa45..22d5fb2 100644
--- a/modules/video_coding/main/test/normal_test.cc
+++ b/modules/video_coding/main/test/normal_test.cc
@@ -95,7 +95,7 @@
   switch (_test.VideoType())
   {
   case kVideoCodecVP8:
-    rtpInfo.type.Video.codec = kRTPVideoVP8;
+    rtpInfo.type.Video.codec = kRtpVideoVp8;
     rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
     rtpInfo.type.Video.codecHeader.VP8.nonReference =
         videoHdr->codecHeader.VP8.nonReference;
@@ -103,7 +103,7 @@
         videoHdr->codecHeader.VP8.pictureId;
     break;
   case kVideoCodecI420:
-    rtpInfo.type.Video.codec = kRTPVideoI420;
+    rtpInfo.type.Video.codec = kRtpVideoI420;
     break;
   default:
     assert(false);
diff --git a/modules/video_coding/main/test/receiver_tests.h b/modules/video_coding/main/test/receiver_tests.h
index 095a231..47f9572 100644
--- a/modules/video_coding/main/test/receiver_tests.h
+++ b/modules/video_coding/main/test/receiver_tests.h
@@ -21,7 +21,7 @@
 #include <string>
 #include <stdio.h>
 
-class RtpDataCallback : public webrtc::RtpData {
+class RtpDataCallback : public webrtc::NullRtpData {
  public:
   RtpDataCallback(webrtc::VideoCodingModule* vcm) : vcm_(vcm) {}
   virtual ~RtpDataCallback() {}
diff --git a/modules/video_coding/main/test/rtp_player.cc b/modules/video_coding/main/test/rtp_player.cc
index 0e440da..78099d5 100644
--- a/modules/video_coding/main/test/rtp_player.cc
+++ b/modules/video_coding/main/test/rtp_player.cc
@@ -14,6 +14,8 @@
 #include <map>
 
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/video_coding/main/source/internal_defines.h"
 #include "webrtc/modules/video_coding/main/test/pcap_file_reader.h"
@@ -216,8 +218,9 @@
     RtpRtcp::Configuration configuration;
     configuration.id = 1;
     configuration.audio = false;
-    configuration.incoming_data = handler->payload_sink_.get();
-    handler->rtp_module_.reset(RtpRtcp::CreateRtpRtcp(configuration));
+    handler->rtp_module_.reset(RtpReceiver::CreateVideoReceiver(
+        configuration.id, configuration.clock, handler->payload_sink_.get(),
+        NULL, handler->rtp_payload_registry_.get()));
     if (handler->rtp_module_.get() == NULL) {
       return -1;
     }
@@ -226,9 +229,6 @@
                                             kMaxPacketAgeToNack) < 0) {
       return -1;
     }
-    handler->rtp_module_->SetRTCPStatus(kRtcpNonCompound);
-    handler->rtp_module_->SetREMBStatus(true);
-    handler->rtp_module_->SetSSRCFilter(true, ssrc);
     handler->rtp_header_parser_->RegisterRtpHeaderExtension(
         kRtpExtensionTransmissionTimeOffset,
         kDefaultTransmissionTimeOffsetExtensionId);
@@ -240,7 +240,11 @@
       strncpy(codec.plName, it->name().c_str(), sizeof(codec.plName)-1);
       codec.plType = it->payload_type();
       codec.codecType = it->codec_type();
-      if (handler->rtp_module_->RegisterReceivePayload(codec) < 0) {
+      if (handler->rtp_module_->RegisterReceivePayload(codec.plName,
+                                                       codec.plType,
+                                                       90000,
+                                                       0,
+                                                       codec.maxBitrate) < 0) {
         return -1;
       }
     }
@@ -249,20 +253,18 @@
     return 0;
   }
 
-  void Process() {
-    for (HandlerMapIt it = handlers_.begin(); it != handlers_.end(); ++it) {
-      it->second->rtp_module_->Process();
-    }
-  }
-
   void IncomingPacket(const uint8_t* data, uint32_t length) {
     for (HandlerMapIt it = handlers_.begin(); it != handlers_.end(); ++it) {
-      if (it->second->rtp_header_parser_->IsRtcp(data, length)) {
-        it->second->rtp_module_->IncomingRtcpPacket(data, length);
-      } else {
+      if (!it->second->rtp_header_parser_->IsRtcp(data, length)) {
         RTPHeader header;
         it->second->rtp_header_parser_->Parse(data, length, &header);
-        it->second->rtp_module_->IncomingRtpPacket(data, length, header);
+        PayloadUnion payload_specific;
+        it->second->rtp_payload_registry_->GetPayloadSpecifics(
+            header.payloadType, &payload_specific);
+        bool in_order =
+            it->second->rtp_module_->InOrderPacket(header.sequenceNumber);
+        it->second->rtp_module_->IncomingRtpPacket(&header, data, length,
+                                                   payload_specific, in_order);
       }
     }
   }
@@ -273,6 +275,8 @@
     Handler(uint32_t ssrc, const PayloadTypes& payload_types,
             LostPackets* lost_packets)
         : rtp_header_parser_(RtpHeaderParser::Create()),
+          rtp_payload_registry_(new RTPPayloadRegistry(
+              0, RTPPayloadStrategy::CreateStrategy(false))),
           rtp_module_(),
           payload_sink_(),
           ssrc_(ssrc),
@@ -296,7 +300,8 @@
     }
 
     scoped_ptr<RtpHeaderParser> rtp_header_parser_;
-    scoped_ptr<RtpRtcp> rtp_module_;
+    scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+    scoped_ptr<RtpReceiver> rtp_module_;
     scoped_ptr<PayloadSinkInterface> payload_sink_;
 
    private:
@@ -366,8 +371,6 @@
 
     // Send any packets from packet source.
     if (!end_of_file_ && (TimeUntilNextPacket() == 0 || first_packet_)) {
-      ssrc_handlers_.Process();
-
       if (first_packet_) {
         next_packet_length_ = sizeof(next_packet_);
         if (packet_source_->NextPacket(next_packet_, &next_packet_length_,
diff --git a/modules/video_coding/main/test/test_callbacks.cc b/modules/video_coding/main/test/test_callbacks.cc
index bbd7aea..c14c8b1 100644
--- a/modules/video_coding/main/test/test_callbacks.cc
+++ b/modules/video_coding/main/test/test_callbacks.cc
@@ -14,6 +14,8 @@
 
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/utility/interface/rtp_dump.h"
 #include "webrtc/modules/video_coding/main/test/test_macros.h"
 #include "webrtc/system_wrappers/interface/clock.h"
@@ -34,7 +36,7 @@
     _encodeComplete(false),
     _width(0),
     _height(0),
-    _codecType(kRTPVideoNoVideo)
+    _codecType(kRtpVideoNone)
 {
     //
 }
@@ -73,14 +75,14 @@
     rtpInfo.type.Video.width = (uint16_t)_width;
     switch (_codecType)
     {
-    case webrtc::kRTPVideoVP8:
+    case webrtc::kRtpVideoVp8:
         rtpInfo.type.Video.codecHeader.VP8.InitRTPVideoHeaderVP8();
         rtpInfo.type.Video.codecHeader.VP8.nonReference =
             videoHdr->codecHeader.VP8.nonReference;
         rtpInfo.type.Video.codecHeader.VP8.pictureId =
             videoHdr->codecHeader.VP8.pictureId;
         break;
-    case webrtc::kRTPVideoI420:
+    case webrtc::kRtpVideoI420:
         break;
     default:
         assert(false);
@@ -209,6 +211,8 @@
                                                  const char* filename):
     _clock(clock),
     _sendCount(0),
+    rtp_payload_registry_(NULL),
+    rtp_receiver_(NULL),
     _rtp(NULL),
     _lossPct(0),
     _burstLength(0),
@@ -299,7 +303,14 @@
           delete packet;
           return -1;
         }
-        if (_rtp->IncomingRtpPacket(packet->data, packet->length, header) < 0)
+        PayloadUnion payload_specific;
+        if (!rtp_payload_registry_->GetPayloadSpecifics(
+            header.payloadType, &payload_specific)) {
+          return -1;
+        }
+        if (!rtp_receiver_->IncomingRtpPacket(&header, packet->data,
+                                              packet->length, payload_specific,
+                                              true))
         {
             delete packet;
             return -1;
diff --git a/modules/video_coding/main/test/test_callbacks.h b/modules/video_coding/main/test/test_callbacks.h
index 14d76bc..f2375d1 100644
--- a/modules/video_coding/main/test/test_callbacks.h
+++ b/modules/video_coding/main/test/test_callbacks.h
@@ -29,6 +29,7 @@
 
 namespace webrtc
 {
+class RTPPayloadRegistry;
 class RtpDump;
 
 // Send Side - Packetization callback - send an encoded frame to the VCMReceiver
@@ -59,7 +60,7 @@
     // Return encode complete (true/false)
     bool EncodeComplete();
     // Inform callback of codec used
-    void SetCodecType(RTPVideoCodecTypes codecType)
+    void SetCodecType(RtpVideoCodecTypes codecType)
     {_codecType = codecType;}
     // Inform callback of frame dimensions
     void SetFrameDimensions(int32_t width, int32_t height)
@@ -82,7 +83,7 @@
     bool               _encodeComplete;
     int32_t      _width;
     int32_t      _height;
-    RTPVideoCodecTypes _codecType;
+    RtpVideoCodecTypes _codecType;
 
 }; // end of VCMEncodeCompleteCallback
 
@@ -113,7 +114,7 @@
     // Return encode complete (true/false)
     bool EncodeComplete();
     // Inform callback of codec used
-    void SetCodecType(RTPVideoCodecTypes codecType)
+    void SetCodecType(RtpVideoCodecTypes codecType)
     {_codecType = codecType;}
 
     // Inform callback of frame dimensions
@@ -130,7 +131,7 @@
     RtpRtcp*           _RTPModule;
     int16_t      _width;
     int16_t      _height;
-    RTPVideoCodecTypes _codecType;
+    RtpVideoCodecTypes _codecType;
 }; // end of VCMEncodeCompleteCallback
 
 // Decode Complete callback
@@ -188,6 +189,8 @@
 
     Clock*                  _clock;
     uint32_t          _sendCount;
+    RTPPayloadRegistry* rtp_payload_registry_;
+    RtpReceiver* rtp_receiver_;
     RtpRtcp*                _rtp;
     double                  _lossPct;
     double                  _burstLength;
diff --git a/modules/video_coding/main/test/test_util.cc b/modules/video_coding/main/test/test_util.cc
index 159de17..aad2b53 100644
--- a/modules/video_coding/main/test/test_util.cc
+++ b/modules/video_coding/main/test/test_util.cc
@@ -146,12 +146,12 @@
   return 0;
 }
 
-webrtc::RTPVideoCodecTypes ConvertCodecType(const char* plname) {
+webrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname) {
   if (strncmp(plname,"VP8" , 3) == 0) {
-    return webrtc::kRTPVideoVP8;
+    return webrtc::kRtpVideoVp8;
   } else if (strncmp(plname,"I420" , 5) == 0) {
-    return webrtc::kRTPVideoI420;
+    return webrtc::kRtpVideoI420;
   } else {
-    return webrtc::kRTPVideoNoVideo; // Default value
+    return webrtc::kRtpVideoNone;  // Default value
   }
 }
diff --git a/modules/video_coding/main/test/test_util.h b/modules/video_coding/main/test/test_util.h
index 48dd35a..c08786a 100644
--- a/modules/video_coding/main/test/test_util.h
+++ b/modules/video_coding/main/test/test_util.h
@@ -102,6 +102,6 @@
 };
 
 // Codec type conversion
-webrtc::RTPVideoCodecTypes ConvertCodecType(const char* plname);
+webrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname);
 
 #endif
diff --git a/modules/video_coding/main/test/vcm_payload_sink_factory.cc b/modules/video_coding/main/test/vcm_payload_sink_factory.cc
index ccc74e9..beee0cd 100644
--- a/modules/video_coding/main/test/vcm_payload_sink_factory.cc
+++ b/modules/video_coding/main/test/vcm_payload_sink_factory.cc
@@ -67,6 +67,12 @@
     return vcm_->IncomingPacket(payload_data, payload_size, *rtp_header);
   }
 
+  virtual bool OnRecoveredPacket(const uint8_t* packet,
+                                 int packet_length) {
+    // We currently don't handle FEC.
+    return true;
+  }
+
   // VCMPacketRequestCallback
   virtual int32_t ResendPackets(const uint16_t* sequence_numbers,
                                 uint16_t length) {
diff --git a/video_engine/include/vie_network.h b/video_engine/include/vie_network.h
index 575eed1..e1c6bb2 100644
--- a/video_engine/include/vie_network.h
+++ b/video_engine/include/vie_network.h
@@ -32,24 +32,6 @@
   PacketReceived = 1
 };
 
-// This class declares an abstract interface for a user defined observer. It is
-// up to the VideoEngine user to implement a derived class which implements the
-// observer class. The observer is registered using RegisterObserver() and
-// deregistered using DeregisterObserver().
-class WEBRTC_DLLEXPORT ViENetworkObserver {
- public:
-  // This method will be called periodically delivering a dead‐or‐alive
-  // decision for a specified channel.
-  virtual void OnPeriodicDeadOrAlive(const int video_channel,
-                                     const bool alive) = 0;
-
-  // This method is called once if a packet timeout occurred.
-  virtual void PacketTimeout(const int video_channel,
-                             const ViEPacketTimeout timeout) = 0;
- protected:
-  virtual ~ViENetworkObserver() {}
-};
-
 class WEBRTC_DLLEXPORT ViENetwork {
  public:
   // Default values.
@@ -96,27 +78,6 @@
   // over the network.
   virtual int SetMTU(int video_channel, unsigned int mtu) = 0;
 
-  // This function enables or disables warning reports if packets have not
-  // been received for a specified time interval.
-  virtual int SetPacketTimeoutNotification(const int video_channel,
-                                           bool enable,
-                                           int timeout_seconds) = 0;
-
-  // Registers an instance of a user implementation of the ViENetwork
-  // observer.
-  virtual int RegisterObserver(const int video_channel,
-                               ViENetworkObserver& observer) = 0;
-
-  // Removes a registered instance of ViENetworkObserver.
-  virtual int DeregisterObserver(const int video_channel) = 0;
-
-  // This function enables or disables the periodic dead‐or‐alive callback
-  // functionality for a specified channel.
-  virtual int SetPeriodicDeadOrAliveStatus(
-      const int video_channel,
-      const bool enable,
-      const unsigned int sample_time_seconds = KDefaultSampleTimeSeconds) = 0;
-
  protected:
   ViENetwork() {}
   virtual ~ViENetwork() {}
diff --git a/video_engine/test/auto_test/source/vie_autotest_network.cc b/video_engine/test/auto_test/source/vie_autotest_network.cc
index d8edcf5..df5b5ef 100644
--- a/video_engine/test/auto_test/source/vie_autotest_network.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_network.cc
@@ -25,24 +25,6 @@
 #include <qos.h>
 #endif
 
-class ViEAutoTestNetworkObserver: public webrtc::ViENetworkObserver
-{
-public:
-    ViEAutoTestNetworkObserver()
-    {
-    }
-    virtual ~ViEAutoTestNetworkObserver()
-    {
-    }
-    virtual void OnPeriodicDeadOrAlive(const int videoChannel, const bool alive)
-    {
-    }
-    virtual void PacketTimeout(const int videoChannel,
-                               const webrtc::ViEPacketTimeout timeout)
-    {
-    }
-};
-
 void ViEAutoTest::ViENetworkStandardTest()
 {
     TbInterfaces ViE("ViENetworkStandardTest"); // Create VIE
@@ -545,26 +527,6 @@
         EXPECT_NE(0, ViE.network->SetMTU(tbChannel.videoChannel, 1600));
         // Valid input
         EXPECT_EQ(0, ViE.network->SetMTU(tbChannel.videoChannel, 800));
-
-        //
-        // Observer and timeout
-        //
-        ViEAutoTestNetworkObserver vieTestObserver;
-        EXPECT_EQ(0, ViE.network->RegisterObserver(
-            tbChannel.videoChannel, vieTestObserver));
-        EXPECT_NE(0, ViE.network->RegisterObserver(
-            tbChannel.videoChannel, vieTestObserver));
-        EXPECT_EQ(0, ViE.network->SetPeriodicDeadOrAliveStatus(
-            tbChannel.videoChannel, true)); // No observer
-        EXPECT_EQ(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
-
-        EXPECT_NE(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
-        EXPECT_NE(0, ViE.network->SetPeriodicDeadOrAliveStatus(
-            tbChannel.videoChannel, true)); // No observer
-
-        // Packet timout notification
-        EXPECT_EQ(0, ViE.network->SetPacketTimeoutNotification(
-            tbChannel.videoChannel, true, 10));
     }
 
     //***************************************************************
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index 78a9015..77c3c26 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -15,6 +15,7 @@
 
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/pacing/include/paced_sender.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/utility/interface/process_thread.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
@@ -74,7 +75,7 @@
       default_rtp_rtcp_(default_rtp_rtcp),
       rtp_rtcp_(NULL),
       vcm_(*VideoCodingModule::Create(ViEModuleId(engine_id, channel_id))),
-      vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator),
+      vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator, this),
       vie_sender_(channel_id),
       vie_sync_(&vcm_, this),
       stats_observer_(new ChannelStatsObserver(this)),
@@ -83,16 +84,13 @@
       do_key_frame_callbackRequest_(false),
       rtp_observer_(NULL),
       rtcp_observer_(NULL),
-      networkObserver_(NULL),
       intra_frame_observer_(intra_frame_observer),
       rtt_observer_(rtt_observer),
       paced_sender_(paced_sender),
       bandwidth_observer_(bandwidth_observer),
-      rtp_packet_timeout_(false),
       send_timestamp_extension_id_(kInvalidRtpExtensionId),
       absolute_send_time_extension_id_(kInvalidRtpExtensionId),
       receive_absolute_send_time_enabled_(false),
-      using_packet_spread_(false),
       external_transport_(NULL),
       decoder_reset_(true),
       wait_for_key_frame_(false),
@@ -112,8 +110,6 @@
   configuration.id = ViEModuleId(engine_id, channel_id);
   configuration.audio = false;
   configuration.default_module = default_rtp_rtcp;
-  configuration.incoming_data = &vie_receiver_;
-  configuration.incoming_messages = this;
   configuration.outgoing_transport = &vie_sender_;
   configuration.rtcp_feedback = this;
   configuration.intra_frame_callback = intra_frame_observer;
@@ -121,6 +117,7 @@
   configuration.rtt_observer = rtt_observer;
   configuration.remote_bitrate_estimator = remote_bitrate_estimator;
   configuration.paced_sender = paced_sender;
+  configuration.receive_statistics = vie_receiver_.GetReceiveStatistics();
 
   rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
   vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
@@ -132,6 +129,13 @@
                "%s: channel_id: %d, engine_id: %d)", __FUNCTION__, channel_id_,
                engine_id_);
 
+  if (module_process_thread_.RegisterModule(
+      vie_receiver_.GetReceiveStatistics()) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Failed to register receive-statistics to process thread",
+                 __FUNCTION__);
+    return -1;
+  }
   // RTP/RTCP initialization.
   if (rtp_rtcp_->SetSendingMediaStatus(false) != 0) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
@@ -197,7 +201,10 @@
   VideoCodec video_codec;
   if (vcm_.Codec(kVideoCodecVP8, &video_codec) == VCM_OK) {
     rtp_rtcp_->RegisterSendPayload(video_codec);
-    rtp_rtcp_->RegisterReceivePayload(video_codec);
+    // TODO(holmer): Can we call SetReceiveCodec() here instead?
+    if (!vie_receiver_.RegisterPayload(video_codec)) {
+      return -1;
+    }
     vcm_.RegisterReceiveCodec(&video_codec, number_of_cores_);
     vcm_.RegisterSendCodec(&video_codec, number_of_cores_,
                            rtp_rtcp_->MaxDataPayloadLength());
@@ -215,6 +222,7 @@
                channel_id_, engine_id_);
 
   // Make sure we don't get more callbacks from the RTP module.
+  module_process_thread_.DeRegisterModule(vie_receiver_.GetReceiveStatistics());
   module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
   module_process_thread_.DeRegisterModule(&vcm_);
   module_process_thread_.DeRegisterModule(&vie_sync_);
@@ -270,7 +278,6 @@
       (*it)->SetSendingMediaStatus(false);
     }
   }
-  NACKMethod nack_method = rtp_rtcp_->NACK();
 
   bool fec_enabled = false;
   uint8_t payload_type_red;
@@ -317,12 +324,6 @@
         WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
                      "%s: RTP::SetRTCPStatus failure", __FUNCTION__);
       }
-      if (nack_method != kNackOff) {
-        rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
-        rtp_rtcp->SetNACKStatus(nack_method, max_nack_reordering_threshold_);
-      } else if (paced_sender_) {
-        rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
-      }
       if (fec_enabled) {
         rtp_rtcp->SetGenericFECStatus(fec_enabled, payload_type_red,
             payload_type_fec);
@@ -444,12 +445,7 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s", __FUNCTION__);
 
-  int8_t old_pltype = -1;
-  if (rtp_rtcp_->ReceivePayloadType(video_codec, &old_pltype) != -1) {
-    rtp_rtcp_->DeRegisterReceivePayload(old_pltype);
-  }
-
-  if (rtp_rtcp_->RegisterReceivePayload(video_codec) != 0) {
+  if (!vie_receiver_.SetReceiveCodec(video_codec)) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                  "%s: Could not register receive payload type", __FUNCTION__);
     return -1;
@@ -659,8 +655,8 @@
                    "%s: Could not enable NACK, RTPC not on ", __FUNCTION__);
       return -1;
     }
-    if (rtp_rtcp_->SetNACKStatus(nackMethod,
-                                 max_nack_reordering_threshold_) != 0) {
+    if (!vie_receiver_.SetNackStatus(true,
+                                     max_nack_reordering_threshold_)) {
       WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                    "%s: Could not set NACK method %d", __FUNCTION__,
                    nackMethod);
@@ -678,7 +674,6 @@
          it != simulcast_rtp_rtcp_.end();
          it++) {
       RtpRtcp* rtp_rtcp = *it;
-      rtp_rtcp->SetNACKStatus(nackMethod, max_nack_reordering_threshold_);
       rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
     }
   } else {
@@ -690,14 +685,13 @@
       if (paced_sender_ == NULL) {
         rtp_rtcp->SetStorePacketsStatus(false, 0);
       }
-      rtp_rtcp->SetNACKStatus(kNackOff, max_nack_reordering_threshold_);
     }
     vcm_.RegisterPacketRequestCallback(NULL);
     if (paced_sender_ == NULL) {
       rtp_rtcp_->SetStorePacketsStatus(false, 0);
     }
-    if (rtp_rtcp_->SetNACKStatus(kNackOff,
-                                 max_nack_reordering_threshold_) != 0) {
+    if (!vie_receiver_.SetNackStatus(false,
+                                     max_nack_reordering_threshold_)) {
       WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                    "%s: Could not turn off NACK", __FUNCTION__);
       return -1;
@@ -977,14 +971,15 @@
 }
 
 int32_t ViEChannel::SetRemoteSSRCType(const StreamType usage,
-                                      const uint32_t SSRC) const {
+                                      const uint32_t SSRC) {
   WEBRTC_TRACE(webrtc::kTraceInfo,
                webrtc::kTraceVideo,
                ViEId(engine_id_, channel_id_),
                "%s(usage:%d, SSRC: 0x%x)",
                __FUNCTION__, usage, SSRC);
 
-  return rtp_rtcp_->SetRTXReceiveStatus(true, SSRC);
+  vie_receiver_.SetRtxStatus(true, SSRC);
+  return 0;
 }
 
 // TODO(mflodman) Add kViEStreamTypeRtx.
@@ -1014,7 +1009,7 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
 
-  *ssrc = rtp_rtcp_->RemoteSSRC();
+  *ssrc = vie_receiver_.GetRemoteSsrc();
   return 0;
 }
 
@@ -1025,7 +1020,7 @@
   uint32_t arrayCSRC[kRtpCsrcSize];
   memset(arrayCSRC, 0, sizeof(arrayCSRC));
 
-  int num_csrcs = rtp_rtcp_->RemoteCSRCs(arrayCSRC);
+  int num_csrcs = vie_receiver_.GetCsrcs(arrayCSRC);
   if (num_csrcs > 0) {
     memcpy(CSRCs, arrayCSRC, num_csrcs * sizeof(uint32_t));
     for (int idx = 0; idx < num_csrcs; idx++) {
@@ -1055,12 +1050,7 @@
 }
 
 void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
-  rtp_rtcp_->SetRtxReceivePayloadType(payload_type);
-  CriticalSectionScoped cs(rtp_rtcp_cs_.get());
-  for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
-       it != simulcast_rtp_rtcp_.end(); it++) {
-    (*it)->SetRtxReceivePayloadType(payload_type);
-  }
+  vie_receiver_.SetRtxPayloadType(payload_type);
 }
 
 int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
@@ -1096,7 +1086,7 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
 
-  uint32_t remoteSSRC = rtp_rtcp_->RemoteSSRC();
+  uint32_t remoteSSRC = vie_receiver_.GetRemoteSsrc();
   return rtp_rtcp_->RemoteCNAME(remoteSSRC, rtcp_cname);
 }
 
@@ -1203,7 +1193,7 @@
   //      it++) {
   //   RtpRtcp* rtp_rtcp = *it;
   // }
-  uint32_t remote_ssrc = rtp_rtcp_->RemoteSSRC();
+  uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
 
   // Get all RTCP receiver report blocks that have been received on this
   // channel. If we receive RTP packets from a remote source we know the
@@ -1246,24 +1236,33 @@
   return 0;
 }
 
+// TODO(holmer): This is a bad function name as it implies that it returns the
+// received RTCP, while it actually returns the statistics which will be sent
+// in the RTCP.
 int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
-                                                    uint32_t* cumulative_lost,
-                                                    uint32_t* extended_max,
-                                                    uint32_t* jitter_samples,
-                                                    int32_t* rtt_ms) {
+                                              uint32_t* cumulative_lost,
+                                              uint32_t* extended_max,
+                                              uint32_t* jitter_samples,
+                                              int32_t* rtt_ms) {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s", __FUNCTION__);
 
   uint8_t frac_lost = 0;
-  if (rtp_rtcp_->StatisticsRTP(&frac_lost, cumulative_lost, extended_max,
-                              jitter_samples) != 0) {
+  ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
+  ReceiveStatistics::RtpReceiveStatistics receive_stats;
+  if (!receive_statistics || !receive_statistics->Statistics(
+      &receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                  "%s: Could not get received RTP statistics", __FUNCTION__);
     return -1;
   }
+  *fraction_lost = receive_stats.fraction_lost;
+  *cumulative_lost = receive_stats.cumulative_lost;
+  *extended_max = receive_stats.extended_max_sequence_number;
+  *jitter_samples = receive_stats.jitter;
   *fraction_lost = frac_lost;
 
-  uint32_t remote_ssrc = rtp_rtcp_->RemoteSSRC();
+  uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
   uint16_t dummy = 0;
   uint16_t rtt = 0;
   if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
@@ -1275,16 +1274,15 @@
 }
 
 int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
-                                           uint32_t* packets_sent,
-                                           uint32_t* bytes_received,
-                                           uint32_t* packets_received) const {
+                                     uint32_t* packets_sent,
+                                     uint32_t* bytes_received,
+                                     uint32_t* packets_received) const {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
 
-  if (rtp_rtcp_->DataCountersRTP(bytes_sent,
-                                 packets_sent,
-                                 bytes_received,
-                                 packets_received) != 0) {
+  ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
+  receive_statistics->GetDataCounters(bytes_received, packets_received);
+  if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                  "%s: Could not get counters", __FUNCTION__);
     return -1;
@@ -1296,7 +1294,7 @@
     uint32_t bytes_sent_temp = 0;
     uint32_t packets_sent_temp = 0;
     RtpRtcp* rtp_rtcp = *it;
-    rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp, NULL, NULL);
+    rtp_rtcp->DataCountersRTP(&bytes_sent_temp, &packets_sent_temp);
     bytes_sent += bytes_sent_temp;
     packets_sent += packets_sent_temp;
   }
@@ -1557,92 +1555,6 @@
   return rtp_rtcp_->MaxDataPayloadLength();
 }
 
-int32_t ViEChannel::SetPacketTimeoutNotification(
-    bool enable, uint32_t timeout_seconds) {
-  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
-               __FUNCTION__);
-  if (enable) {
-    uint32_t timeout_ms = 1000 * timeout_seconds;
-    if (rtp_rtcp_->SetPacketTimeout(timeout_ms, 0) != 0) {
-      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                   "%s", __FUNCTION__);
-      return -1;
-    }
-  } else {
-    if (rtp_rtcp_->SetPacketTimeout(0, 0) != 0) {
-      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                   "%s", __FUNCTION__);
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int32_t ViEChannel::RegisterNetworkObserver(
-    ViENetworkObserver* observer) {
-  CriticalSectionScoped cs(callback_cs_.get());
-  if (observer) {
-    if (networkObserver_) {
-      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                   "%s: observer alread added", __FUNCTION__);
-      return -1;
-    }
-    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
-                 "%s: observer added", __FUNCTION__);
-    networkObserver_ = observer;
-  } else {
-    if (!networkObserver_) {
-      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                   "%s: no observer added", __FUNCTION__);
-      return -1;
-    }
-    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
-                 "%s: observer removed", __FUNCTION__);
-    networkObserver_ = NULL;
-  }
-  return 0;
-}
-
-bool ViEChannel::NetworkObserverRegistered() {
-  CriticalSectionScoped cs(callback_cs_.get());
-  return networkObserver_ != NULL;
-}
-
-int32_t ViEChannel::SetPeriodicDeadOrAliveStatus(
-  const bool enable, const uint32_t sample_time_seconds) {
-  WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
-               __FUNCTION__);
-
-  CriticalSectionScoped cs(callback_cs_.get());
-  if (!networkObserver_) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                 "%s: no observer added", __FUNCTION__);
-    return -1;
-  }
-
-  bool enabled = false;
-  uint8_t current_sampletime_seconds = 0;
-
-  // Get old settings.
-  rtp_rtcp_->PeriodicDeadOrAliveStatus(enabled, current_sampletime_seconds);
-  // Set new settings.
-  if (rtp_rtcp_->SetPeriodicDeadOrAliveStatus(
-        enable, static_cast<uint8_t>(sample_time_seconds)) != 0) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
-                 "%s: Could not set periodic dead-or-alive status",
-                 __FUNCTION__);
-    return -1;
-  }
-  if (!enable) {
-    // Restore last utilized sample time.
-    // Without this trick, the sample time would always be reset to default
-    // (2 sec), each time dead-or-alive was disabled without sample-time
-    // parameter.
-    rtp_rtcp_->SetPeriodicDeadOrAliveStatus(enable, current_sampletime_seconds);
-  }
-  return 0;
-}
-
 int32_t ViEChannel::EnableColorEnhancement(bool enable) {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s(enable: %d)", __FUNCTION__, enable);
@@ -1699,9 +1611,9 @@
   }
 
   uint32_t arr_ofCSRC[kRtpCsrcSize];
-  int32_t no_of_csrcs = rtp_rtcp_->RemoteCSRCs(arr_ofCSRC);
+  int32_t no_of_csrcs = vie_receiver_.GetCsrcs(arr_ofCSRC);
   if (no_of_csrcs <= 0) {
-    arr_ofCSRC[0] = rtp_rtcp_->RemoteSSRC();
+    arr_ofCSRC[0] = rtp_rtcp_->SSRC();
     no_of_csrcs = 1;
   }
   WEBRTC_TRACE(kTraceStream, kTraceVideo, ViEId(engine_id_, channel_id_),
@@ -1720,8 +1632,8 @@
   return 0;
 }
 
-int32_t ViEChannel::ReceiveStatistics(const uint32_t bit_rate,
-                                            const uint32_t frame_rate) {
+int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate,
+                                              const uint32_t frame_rate) {
   CriticalSectionScoped cs(callback_cs_.get());
   if (codec_observer_) {
     WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
@@ -1874,8 +1786,10 @@
   } else {
     module_process_thread_.DeRegisterModule(&vie_sync_);
   }
-  return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface,
-                                 rtp_rtcp_.get());
+  return vie_sync_.ConfigureSync(ve_channel_id,
+                                 ve_sync_interface,
+                                 rtp_rtcp_.get(),
+                                 vie_receiver_.GetRtpReceiver());
 }
 
 int32_t ViEChannel::VoiceChannel() {
@@ -1947,52 +1861,6 @@
   return 0;
 }
 
-void ViEChannel::OnPacketTimeout(const int32_t id) {
-  assert(ChannelId(id) == channel_id_);
-  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
-               __FUNCTION__);
-
-  CriticalSectionScoped cs(callback_cs_.get());
-  if (networkObserver_) {
-    networkObserver_->PacketTimeout(channel_id_, NoPacket);
-    rtp_packet_timeout_ = true;
-  }
-}
-
-void ViEChannel::OnReceivedPacket(const int32_t id,
-                                  const RtpRtcpPacketType packet_type) {
-  assert(ChannelId(id) == channel_id_);
-  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
-               __FUNCTION__);
-  if (rtp_packet_timeout_ && packet_type == kPacketRtp) {
-    CriticalSectionScoped cs(callback_cs_.get());
-    if (networkObserver_) {
-      networkObserver_->PacketTimeout(channel_id_, PacketReceived);
-    }
-
-    // Reset even if no observer set, might have been removed during timeout.
-    rtp_packet_timeout_ = false;
-  }
-}
-
-void ViEChannel::OnPeriodicDeadOrAlive(const int32_t id,
-                                       const RTPAliveType alive) {
-  assert(ChannelId(id) == channel_id_);
-  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
-               "%s(id=%d, alive=%d)", __FUNCTION__, id, alive);
-
-  CriticalSectionScoped cs(callback_cs_.get());
-  if (!networkObserver_) {
-    return;
-  }
-  bool is_alive = true;
-  if (alive == kRtpDead) {
-    is_alive = false;
-  }
-  networkObserver_->OnPeriodicDeadOrAlive(channel_id_, is_alive);
-  return;
-}
-
 void ViEChannel::OnIncomingSSRCChanged(const int32_t id,
                                        const uint32_t SSRC) {
   if (channel_id_ != ChannelId(id)) {
@@ -2005,6 +1873,8 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s: %u", __FUNCTION__, SSRC);
 
+  rtp_rtcp_->SetRemoteSSRC(SSRC);
+
   CriticalSectionScoped cs(callback_cs_.get());
   {
     if (rtp_observer_) {
@@ -2037,4 +1907,8 @@
   }
 }
 
+void ViEChannel::OnResetStatistics() {
+  vie_receiver_.GetReceiveStatistics()->ResetStatistics();
+}
+
 }  // namespace webrtc
diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h
index 090582b..fc86dfc 100644
--- a/video_engine/vie_channel.h
+++ b/video_engine/vie_channel.h
@@ -41,7 +41,6 @@
 class ThreadWrapper;
 class ViEDecoderObserver;
 class ViEEffectFilter;
-class ViENetworkObserver;
 class ViERTCPObserver;
 class ViERTPObserver;
 class VideoCodingModule;
@@ -209,16 +208,12 @@
       const int frequency,
       const uint8_t channels,
       const uint32_t rate);
-  virtual void OnPacketTimeout(const int32_t id);
-  virtual void OnReceivedPacket(const int32_t id,
-                                const RtpRtcpPacketType packet_type);
-  virtual void OnPeriodicDeadOrAlive(const int32_t id,
-                                     const RTPAliveType alive);
   virtual void OnIncomingSSRCChanged(const int32_t id,
                                      const uint32_t SSRC);
   virtual void OnIncomingCSRCChanged(const int32_t id,
                                      const uint32_t CSRC,
                                      const bool added);
+  virtual void OnResetStatistics();
 
   int32_t SetLocalReceiver(const uint16_t rtp_port,
                            const uint16_t rtcp_port,
@@ -241,7 +236,7 @@
                         char* ip_address,
                         uint32_t ip_address_length);
 
-  int32_t SetRemoteSSRCType(const StreamType usage, const uint32_t SSRC) const;
+  int32_t SetRemoteSSRCType(const StreamType usage, const uint32_t SSRC);
 
   int32_t StartSend();
   int32_t StopSend();
@@ -270,12 +265,6 @@
   int32_t SetMaxPacketBurstSize(uint16_t max_number_of_packets);
   int32_t SetPacketBurstSpreadState(bool enable, const uint16_t frame_periodMS);
 
-  int32_t SetPacketTimeoutNotification(bool enable, uint32_t timeout_seconds);
-  int32_t RegisterNetworkObserver(ViENetworkObserver* observer);
-  bool NetworkObserverRegistered();
-  int32_t SetPeriodicDeadOrAliveStatus(
-      const bool enable, const uint32_t sample_time_seconds);
-
   int32_t EnableColorEnhancement(bool enable);
 
   // Gets the modules used by the channel.
@@ -295,7 +284,7 @@
       const EncodedVideoData& frame_to_store);
 
   // Implements VideoReceiveStatisticsCallback.
-  virtual int32_t ReceiveStatistics(const uint32_t bit_rate,
+  virtual int32_t OnReceiveStatisticsUpdate(const uint32_t bit_rate,
                                     const uint32_t frame_rate);
 
   // Implements VideoFrameTypeCallback.
@@ -368,13 +357,11 @@
   bool do_key_frame_callbackRequest_;
   ViERTPObserver* rtp_observer_;
   ViERTCPObserver* rtcp_observer_;
-  ViENetworkObserver* networkObserver_;
   RtcpIntraFrameObserver* intra_frame_observer_;
   RtcpRttObserver* rtt_observer_;
   PacedSender* paced_sender_;
 
   scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
-  bool rtp_packet_timeout_;
   int send_timestamp_extension_id_;
   int absolute_send_time_extension_id_;
   bool receive_absolute_send_time_enabled_;
diff --git a/video_engine/vie_codec_impl.cc b/video_engine/vie_codec_impl.cc
index b98b0f8..691bd71 100644
--- a/video_engine/vie_codec_impl.cc
+++ b/video_engine/vie_codec_impl.cc
@@ -247,7 +247,7 @@
   shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
 
   // Update the protection mode, we might be switching NACK/FEC.
-  vie_encoder->UpdateProtectionMethod();
+  vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled());
 
   // Get new best format for frame provider.
   if (frame_provider) {
diff --git a/video_engine/vie_encoder.cc b/video_engine/vie_encoder.cc
index e91645b..85b004a 100644
--- a/video_engine/vie_encoder.cc
+++ b/video_engine/vie_encoder.cc
@@ -725,7 +725,7 @@
   return 0;
 }
 
-int32_t ViEEncoder::UpdateProtectionMethod() {
+int32_t ViEEncoder::UpdateProtectionMethod(bool enable_nack) {
   bool fec_enabled = false;
   uint8_t dummy_ptype_red = 0;
   uint8_t dummy_ptypeFEC = 0;
@@ -738,25 +738,23 @@
   if (error) {
     return -1;
   }
-
-  bool nack_enabled = (default_rtp_rtcp_->NACK() == kNackOff) ? false : true;
-  if (fec_enabled_ == fec_enabled && nack_enabled_ == nack_enabled) {
+  if (fec_enabled_ == fec_enabled && nack_enabled_ == enable_nack) {
     // No change needed, we're already in correct state.
     return 0;
   }
   fec_enabled_ = fec_enabled;
-  nack_enabled_ = nack_enabled;
+  nack_enabled_ = enable_nack;
 
   // Set Video Protection for VCM.
-  if (fec_enabled && nack_enabled) {
+  if (fec_enabled && nack_enabled_) {
     vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, true);
   } else {
     vcm_.SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_);
-    vcm_.SetVideoProtection(webrtc::kProtectionNack, nack_enabled_);
+    vcm_.SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_);
     vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, false);
   }
 
-  if (fec_enabled || nack_enabled) {
+  if (fec_enabled_ || nack_enabled_) {
     WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo,
                  ViEId(engine_id_, channel_id_), "%s: FEC status ",
                  __FUNCTION__, fec_enabled);
diff --git a/video_engine/vie_encoder.h b/video_engine/vie_encoder.h
index 368f91b..babd74e 100644
--- a/video_engine/vie_encoder.h
+++ b/video_engine/vie_encoder.h
@@ -114,7 +114,8 @@
 
   int CodecTargetBitrate(uint32_t* bitrate) const;
   // Loss protection.
-  int32_t UpdateProtectionMethod();
+  int32_t UpdateProtectionMethod(bool enable_nack);
+  bool nack_enabled() const { return nack_enabled_; }
 
   // Buffering mode.
   void SetSenderBufferingMode(int target_delay_ms);
diff --git a/video_engine/vie_network_impl.cc b/video_engine/vie_network_impl.cc
index e9082da..0afd2fe 100644
--- a/video_engine/vie_network_impl.cc
+++ b/video_engine/vie_network_impl.cc
@@ -196,99 +196,4 @@
   }
   return 0;
 }
-
-int ViENetworkImpl::SetPacketTimeoutNotification(const int video_channel,
-                                                 bool enable,
-                                                 int timeout_seconds) {
-  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
-               ViEId(shared_data_->instance_id(), video_channel),
-               "%s(channel: %d, enable: %d, timeout_seconds: %u)",
-               __FUNCTION__, video_channel, enable, timeout_seconds);
-  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
-  ViEChannel* vie_channel = cs.Channel(video_channel);
-  if (!vie_channel) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo,
-                 ViEId(shared_data_->instance_id(), video_channel),
-                 "Channel doesn't exist");
-    shared_data_->SetLastError(kViENetworkInvalidChannelId);
-    return -1;
-  }
-  if (vie_channel->SetPacketTimeoutNotification(enable,
-                                                timeout_seconds) != 0) {
-    shared_data_->SetLastError(kViENetworkUnknownError);
-    return -1;
-  }
-  return 0;
-}
-
-int ViENetworkImpl::RegisterObserver(const int video_channel,
-                                     ViENetworkObserver& observer) {
-  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
-               ViEId(shared_data_->instance_id(), video_channel),
-               "%s(channel: %d)", __FUNCTION__, video_channel);
-  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
-  ViEChannel* vie_channel = cs.Channel(video_channel);
-  if (!vie_channel) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo,
-                 ViEId(shared_data_->instance_id(), video_channel),
-                 "Channel doesn't exist");
-    shared_data_->SetLastError(kViENetworkInvalidChannelId);
-    return -1;
-  }
-  if (vie_channel->RegisterNetworkObserver(&observer) != 0) {
-    shared_data_->SetLastError(kViENetworkObserverAlreadyRegistered);
-    return -1;
-  }
-  return 0;
-}
-
-int ViENetworkImpl::DeregisterObserver(const int video_channel) {
-  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
-               ViEId(shared_data_->instance_id(), video_channel),
-               "%s(channel: %d)", __FUNCTION__, video_channel);
-  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
-  ViEChannel* vie_channel = cs.Channel(video_channel);
-  if (!vie_channel) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo,
-                 ViEId(shared_data_->instance_id(), video_channel),
-                 "Channel doesn't exist");
-    shared_data_->SetLastError(kViENetworkInvalidChannelId);
-    return -1;
-  }
-  if (!vie_channel->NetworkObserverRegistered()) {
-    shared_data_->SetLastError(kViENetworkObserverNotRegistered);
-    return -1;
-  }
-  return vie_channel->RegisterNetworkObserver(NULL);
-}
-
-int ViENetworkImpl::SetPeriodicDeadOrAliveStatus(
-    const int video_channel,
-    bool enable,
-    unsigned int sample_time_seconds) {
-  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
-               ViEId(shared_data_->instance_id(), video_channel),
-               "%s(channel: %d, enable: %d, sample_time_seconds: %ul)",
-               __FUNCTION__, video_channel, enable, sample_time_seconds);
-  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
-  ViEChannel* vie_channel = cs.Channel(video_channel);
-  if (!vie_channel) {
-    WEBRTC_TRACE(kTraceError, kTraceVideo,
-                 ViEId(shared_data_->instance_id(), video_channel),
-                 "Channel doesn't exist");
-    shared_data_->SetLastError(kViENetworkInvalidChannelId);
-    return -1;
-  }
-  if (!vie_channel->NetworkObserverRegistered()) {
-    shared_data_->SetLastError(kViENetworkObserverNotRegistered);
-    return -1;
-  }
-  if (vie_channel->SetPeriodicDeadOrAliveStatus(enable, sample_time_seconds)
-      != 0) {
-    shared_data_->SetLastError(kViENetworkUnknownError);
-    return -1;
-  }
-  return 0;
-}
-
 }  // namespace webrtc
diff --git a/video_engine/vie_network_impl.h b/video_engine/vie_network_impl.h
index da79f44..d49c2fe 100644
--- a/video_engine/vie_network_impl.h
+++ b/video_engine/vie_network_impl.h
@@ -37,16 +37,6 @@
                                  const void* data,
                                  const int length);
   virtual int SetMTU(int video_channel, unsigned int mtu);
-  virtual int SetPacketTimeoutNotification(const int video_channel,
-                                           bool enable,
-                                           int timeout_seconds);
-  virtual int RegisterObserver(const int video_channel,
-                               ViENetworkObserver& observer);
-  virtual int DeregisterObserver(const int video_channel);
-  virtual int SetPeriodicDeadOrAliveStatus(
-      const int video_channel,
-      const bool enable,
-      const unsigned int sample_time_seconds);
 
  protected:
   explicit ViENetworkImpl(ViESharedData* shared_data);
diff --git a/video_engine/vie_receiver.cc b/video_engine/vie_receiver.cc
index a39dbee..fc986ea 100644
--- a/video_engine/vie_receiver.cc
+++ b/video_engine/vie_receiver.cc
@@ -13,7 +13,10 @@
 #include <vector>
 
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/utility/interface/rtp_dump.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
@@ -25,10 +28,18 @@
 
 ViEReceiver::ViEReceiver(const int32_t channel_id,
                          VideoCodingModule* module_vcm,
-                         RemoteBitrateEstimator* remote_bitrate_estimator)
+                         RemoteBitrateEstimator* remote_bitrate_estimator,
+                         RtpFeedback* rtp_feedback)
     : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       channel_id_(channel_id),
       rtp_header_parser_(RtpHeaderParser::Create()),
+      rtp_payload_registry_(new RTPPayloadRegistry(
+          channel_id, RTPPayloadStrategy::CreateStrategy(false))),
+      rtp_receiver_(RtpReceiver::CreateVideoReceiver(
+          channel_id, Clock::GetRealTimeClock(), this, rtp_feedback,
+          rtp_payload_registry_.get())),
+      rtp_receive_statistics_(ReceiveStatistics::Create(
+          Clock::GetRealTimeClock())),
       rtp_rtcp_(NULL),
       vcm_(module_vcm),
       remote_bitrate_estimator_(remote_bitrate_estimator),
@@ -51,6 +62,59 @@
   }
 }
 
+bool ViEReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
+  int8_t old_pltype = -1;
+  if (rtp_payload_registry_->ReceivePayloadType(video_codec.plName,
+                                                kVideoPayloadTypeFrequency,
+                                                0,
+                                                video_codec.maxBitrate,
+                                                &old_pltype) != -1) {
+    rtp_payload_registry_->DeRegisterReceivePayload(old_pltype);
+  }
+
+  if (rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                            video_codec.plType,
+                                            kVideoPayloadTypeFrequency,
+                                            0,
+                                            video_codec.maxBitrate) != 0) {
+    return false;
+  }
+  return true;
+}
+
+bool ViEReceiver::RegisterPayload(const VideoCodec& video_codec) {
+  if (rtp_receiver_->RegisterReceivePayload(video_codec.plName,
+                                            video_codec.plType,
+                                            kVideoPayloadTypeFrequency,
+                                            0,
+                                            video_codec.maxBitrate) != 0) {
+    return false;
+  }
+  return true;
+}
+
+bool ViEReceiver::SetNackStatus(bool enable,
+                                int max_nack_reordering_threshold) {
+  return rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff,
+                                      max_nack_reordering_threshold) == 0;
+}
+
+void ViEReceiver::SetRtxStatus(bool enable, uint32_t ssrc) {
+  rtp_receiver_->SetRTXStatus(true, ssrc);
+}
+
+void ViEReceiver::SetRtxPayloadType(uint32_t payload_type) {
+  rtp_receiver_->SetRtxPayloadType(payload_type);
+}
+
+uint32_t ViEReceiver::GetRemoteSsrc() const {
+  return rtp_receiver_->SSRC();
+}
+
+int ViEReceiver::GetCsrcs(uint32_t* csrcs) const {
+  return rtp_receiver_->CSRCs(csrcs);
+}
+
 int ViEReceiver::RegisterExternalDecryption(Encryption* decryption) {
   CriticalSectionScoped cs(receive_cs_.get());
   if (external_decryption_) {
@@ -77,6 +141,10 @@
   rtp_rtcp_ = module;
 }
 
+RtpReceiver* ViEReceiver::GetRtpReceiver() const {
+  return rtp_receiver_.get();
+}
+
 void ViEReceiver::RegisterSimulcastRtpRtcpModules(
     const std::list<RtpRtcp*>& rtp_modules) {
   CriticalSectionScoped cs(receive_cs_.get());
@@ -140,6 +208,25 @@
   return 0;
 }
 
+bool ViEReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
+                                    int rtp_packet_length) {
+  RTPHeader header;
+  if (!rtp_header_parser_->Parse(rtp_packet, rtp_packet_length, &header)) {
+    WEBRTC_TRACE(kTraceDebug, webrtc::kTraceVideo, channel_id_,
+                 "IncomingPacket invalid RTP header");
+    return false;
+  }
+  header.payload_type_frequency = kVideoPayloadTypeFrequency;
+  PayloadUnion payload_specific;
+  if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
+                                                 &payload_specific)) {
+    return false;
+  }
+  return rtp_receiver_->IncomingRtpPacket(&header, rtp_packet,
+                                          rtp_packet_length,
+                                          payload_specific, false);
+}
+
 int ViEReceiver::InsertRTPPacket(const int8_t* rtp_packet,
                                  int rtp_packet_length) {
   // TODO(mflodman) Change decrypt to get rid of this cast.
@@ -185,9 +272,19 @@
   const int payload_size = received_packet_length - header.headerLength;
   remote_bitrate_estimator_->IncomingPacket(TickTime::MillisecondTimestamp(),
                                             payload_size, header);
-  assert(rtp_rtcp_);  // Should be set by owner at construction time.
-  return rtp_rtcp_->IncomingRtpPacket(received_packet, received_packet_length,
-                                      header);
+  header.payload_type_frequency = kVideoPayloadTypeFrequency;
+  bool in_order = rtp_receiver_->InOrderPacket(header.sequenceNumber);
+  bool retransmitted = !in_order && IsPacketRetransmitted(header);
+  rtp_receive_statistics_->IncomingPacket(header, received_packet_length,
+                                          retransmitted, in_order);
+  PayloadUnion payload_specific;
+  if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
+                                                  &payload_specific)) {
+    return -1;
+  }
+  return rtp_receiver_->IncomingRtpPacket(&header, received_packet,
+                                          received_packet_length,
+                                          payload_specific, in_order) ? 0 : -1;
 }
 
 int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
@@ -296,7 +393,7 @@
   // LatestEstimate returns an error if there is no valid bitrate estimate, but
   // ViEReceiver instead returns a zero estimate.
   remote_bitrate_estimator_->LatestEstimate(&ssrcs, available_bandwidth);
-  if (std::find(ssrcs.begin(), ssrcs.end(), rtp_rtcp_->RemoteSSRC()) !=
+  if (std::find(ssrcs.begin(), ssrcs.end(), rtp_receiver_->SSRC()) !=
       ssrcs.end()) {
     *available_bandwidth /= ssrcs.size();
   } else {
@@ -304,4 +401,25 @@
   }
 }
 
+ReceiveStatistics* ViEReceiver::GetReceiveStatistics() const {
+  return rtp_receive_statistics_.get();
+}
+
+bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header) const {
+  bool rtx_enabled = false;
+  uint32_t rtx_ssrc = 0;
+  int rtx_payload_type = 0;
+  rtp_receiver_->RTXStatus(&rtx_enabled, &rtx_ssrc, &rtx_payload_type);
+  if (!rtx_enabled) {
+    // Check if this is a retransmission.
+    ReceiveStatistics::RtpReceiveStatistics stats;
+    if (rtp_receive_statistics_->Statistics(&stats, false)) {
+      uint16_t min_rtt = 0;
+      rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
+      return rtp_receiver_->RetransmitOfOldPacket(header, stats.jitter,
+                                                  min_rtt);
+    }
+  }
+  return false;
+}
 }  // namespace webrtc
diff --git a/video_engine/vie_receiver.h b/video_engine/vie_receiver.h
index 904a951..6301437 100644
--- a/video_engine/vie_receiver.h
+++ b/video_engine/vie_receiver.h
@@ -14,6 +14,7 @@
 #include <list>
 
 #include "webrtc/engine_configurations.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/typedefs.h"
@@ -23,23 +24,39 @@
 
 class CriticalSectionWrapper;
 class Encryption;
+class ReceiveStatistics;
 class RemoteBitrateEstimator;
 class RtpDump;
 class RtpHeaderParser;
+class RTPPayloadRegistry;
+class RtpReceiver;
 class RtpRtcp;
 class VideoCodingModule;
 
 class ViEReceiver : public RtpData {
  public:
   ViEReceiver(const int32_t channel_id, VideoCodingModule* module_vcm,
-              RemoteBitrateEstimator* remote_bitrate_estimator);
+              RemoteBitrateEstimator* remote_bitrate_estimator,
+              RtpFeedback* rtp_feedback);
   ~ViEReceiver();
 
+  bool SetReceiveCodec(const VideoCodec& video_codec);
+  bool RegisterPayload(const VideoCodec& video_codec);
+
+  bool SetNackStatus(bool enable, int max_nack_reordering_threshold);
+  void SetRtxStatus(bool enable, uint32_t ssrc);
+  void SetRtxPayloadType(uint32_t payload_type);
+
+  uint32_t GetRemoteSsrc() const;
+  int GetCsrcs(uint32_t* csrcs) const;
+
   int RegisterExternalDecryption(Encryption* decryption);
   int DeregisterExternalDecryption();
 
   void SetRtpRtcpModule(RtpRtcp* module);
 
+  RtpReceiver* GetRtpReceiver() const;
+
   void RegisterSimulcastRtpRtcpModules(const std::list<RtpRtcp*>& rtp_modules);
 
   bool SetReceiveTimestampOffsetStatus(bool enable, int id);
@@ -54,6 +71,8 @@
   // Receives packets from external transport.
   int ReceivedRTPPacket(const void* rtp_packet, int rtp_packet_length);
   int ReceivedRTCPPacket(const void* rtcp_packet, int rtcp_packet_length);
+  virtual bool OnRecoveredPacket(const uint8_t* packet,
+                                 int packet_length) OVERRIDE;
 
   // Implements RtpData.
   virtual int32_t OnReceivedPayloadData(
@@ -63,13 +82,19 @@
 
   void EstimatedReceiveBandwidth(unsigned int* available_bandwidth) const;
 
+  ReceiveStatistics* GetReceiveStatistics() const;
+
  private:
   int InsertRTPPacket(const int8_t* rtp_packet, int rtp_packet_length);
   int InsertRTCPPacket(const int8_t* rtcp_packet, int rtcp_packet_length);
+  bool IsPacketRetransmitted(const RTPHeader& header) const;
 
   scoped_ptr<CriticalSectionWrapper> receive_cs_;
   const int32_t channel_id_;
   scoped_ptr<RtpHeaderParser> rtp_header_parser_;
+  scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+  scoped_ptr<RtpReceiver> rtp_receiver_;
+  scoped_ptr<ReceiveStatistics> rtp_receive_statistics_;
   RtpRtcp* rtp_rtcp_;
   std::list<RtpRtcp*> rtp_rtcp_simulcast_;
   VideoCodingModule* vcm_;
diff --git a/video_engine/vie_rtp_rtcp_impl.cc b/video_engine/vie_rtp_rtcp_impl.cc
index d8ead12..ecfa1b6 100644
--- a/video_engine/vie_rtp_rtcp_impl.cc
+++ b/video_engine/vie_rtp_rtcp_impl.cc
@@ -501,7 +501,7 @@
     shared_data_->SetLastError(kViERtpRtcpUnknownError);
     return -1;
   }
-  vie_encoder->UpdateProtectionMethod();
+  vie_encoder->UpdateProtectionMethod(enable);
   return 0;
 }
 
@@ -542,7 +542,7 @@
     shared_data_->SetLastError(kViERtpRtcpUnknownError);
     return -1;
   }
-  vie_encoder->UpdateProtectionMethod();
+  vie_encoder->UpdateProtectionMethod(false);
   return 0;
 }
 
@@ -587,7 +587,7 @@
     shared_data_->SetLastError(kViERtpRtcpUnknownError);
     return -1;
   }
-  vie_encoder->UpdateProtectionMethod();
+  vie_encoder->UpdateProtectionMethod(enable);
   return 0;
 }
 
diff --git a/video_engine/vie_sync_module.cc b/video_engine/vie_sync_module.cc
index aecfa2a..906f7df 100644
--- a/video_engine/vie_sync_module.cc
+++ b/video_engine/vie_sync_module.cc
@@ -10,6 +10,7 @@
 
 #include "webrtc/video_engine/vie_sync_module.h"
 
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
@@ -24,15 +25,15 @@
 enum { kSyncInterval = 1000};
 
 int UpdateMeasurements(StreamSynchronization::Measurements* stream,
-                       const RtpRtcp* rtp_rtcp) {
-  stream->latest_timestamp = rtp_rtcp->RemoteTimestamp();
-  stream->latest_receive_time_ms = rtp_rtcp->LocalTimeOfRemoteTimeStamp();
+                       const RtpRtcp& rtp_rtcp, const RtpReceiver& receiver) {
+  stream->latest_timestamp = receiver.TimeStamp();
+  stream->latest_receive_time_ms = receiver.LastReceivedTimeMs();
   synchronization::RtcpMeasurement measurement;
-  if (0 != rtp_rtcp->RemoteNTP(&measurement.ntp_secs,
-                               &measurement.ntp_frac,
-                               NULL,
-                               NULL,
-                               &measurement.rtp_timestamp)) {
+  if (0 != rtp_rtcp.RemoteNTP(&measurement.ntp_secs,
+                              &measurement.ntp_frac,
+                              NULL,
+                              NULL,
+                              &measurement.rtp_timestamp)) {
     return -1;
   }
   if (measurement.ntp_secs == 0 && measurement.ntp_frac == 0) {
@@ -60,6 +61,7 @@
     : data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       vcm_(vcm),
       vie_channel_(vie_channel),
+      video_receiver_(NULL),
       video_rtp_rtcp_(NULL),
       voe_channel_id_(-1),
       voe_sync_interface_(NULL),
@@ -72,10 +74,12 @@
 
 int ViESyncModule::ConfigureSync(int voe_channel_id,
                                  VoEVideoSync* voe_sync_interface,
-                                 RtpRtcp* video_rtcp_module) {
+                                 RtpRtcp* video_rtcp_module,
+                                 RtpReceiver* video_receiver) {
   CriticalSectionScoped cs(data_cs_.get());
   voe_channel_id_ = voe_channel_id;
   voe_sync_interface_ = voe_sync_interface;
+  video_receiver_ = video_receiver;
   video_rtp_rtcp_ = video_rtcp_module;
   sync_.reset(new StreamSynchronization(voe_channel_id, vie_channel_->Id()));
 
@@ -129,16 +133,21 @@
       playout_buffer_delay_ms;
 
   RtpRtcp* voice_rtp_rtcp = NULL;
-  if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, voice_rtp_rtcp)) {
+  RtpReceiver* voice_receiver = NULL;
+  if (0 != voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &voice_rtp_rtcp,
+                                           &voice_receiver)) {
     return 0;
   }
   assert(voice_rtp_rtcp);
+  assert(voice_receiver);
 
-  if (UpdateMeasurements(&video_measurement_, video_rtp_rtcp_) != 0) {
+  if (UpdateMeasurements(&video_measurement_, *video_rtp_rtcp_,
+                         *video_receiver_) != 0) {
     return 0;
   }
 
-  if (UpdateMeasurements(&audio_measurement_, voice_rtp_rtcp) != 0) {
+  if (UpdateMeasurements(&audio_measurement_, *voice_rtp_rtcp,
+                         *voice_receiver) != 0) {
     return 0;
   }
 
diff --git a/video_engine/vie_sync_module.h b/video_engine/vie_sync_module.h
index 51246c1..cc0d92b 100644
--- a/video_engine/vie_sync_module.h
+++ b/video_engine/vie_sync_module.h
@@ -36,7 +36,8 @@
 
   int ConfigureSync(int voe_channel_id,
                     VoEVideoSync* voe_sync_interface,
-                    RtpRtcp* video_rtcp_module);
+                    RtpRtcp* video_rtcp_module,
+                    RtpReceiver* video_receiver);
 
   int VoiceChannel();
 
@@ -51,6 +52,7 @@
   scoped_ptr<CriticalSectionWrapper> data_cs_;
   VideoCodingModule* vcm_;
   ViEChannel* vie_channel_;
+  RtpReceiver* video_receiver_;
   RtpRtcp* video_rtp_rtcp_;
   int voe_channel_id_;
   VoEVideoSync* voe_sync_interface_;
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index dbcccf1..b6b8c29 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -12,6 +12,10 @@
 
 #include "webrtc/modules/audio_device/include/audio_device.h"
 #include "webrtc/modules/audio_processing/include/audio_processing.h"
+#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
+#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
 #include "webrtc/modules/utility/interface/audio_frame_operations.h"
 #include "webrtc/modules/utility/interface/process_thread.h"
 #include "webrtc/modules/utility/interface/rtp_dump.h"
@@ -367,8 +371,8 @@
     assert(channel == _channelId);
 
     // Reset RTP-module counters since a new incoming RTP stream is detected
-    _rtpRtcpModule->ResetReceiveDataCountersRTP();
-    _rtpRtcpModule->ResetStatisticsRTP();
+    rtp_receive_statistics_->ResetDataCounters();
+    rtp_receive_statistics_->ResetStatistics();
 
     if (_rtpObserver)
     {
@@ -404,6 +408,10 @@
     }
 }
 
+void Channel::OnResetStatistics() {
+  rtp_receive_statistics_->ResetStatistics();
+}
+
 void
 Channel::OnApplicationDataReceived(int32_t id,
                                    uint8_t subType,
@@ -629,18 +637,16 @@
     UpdatePacketDelay(rtpHeader->header.timestamp,
                       rtpHeader->header.sequenceNumber);
 
-    if (kNackOff != _rtpRtcpModule->NACK()) {  // Is NACK on?
-        uint16_t round_trip_time = 0;
-        _rtpRtcpModule->RTT(_rtpRtcpModule->RemoteSSRC(), &round_trip_time,
-                            NULL, NULL, NULL);
+    uint16_t round_trip_time = 0;
+    _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time,
+                        NULL, NULL, NULL);
 
-        std::vector<uint16_t> nack_list = _audioCodingModule.GetNackList(
-            round_trip_time);
-        if (!nack_list.empty()) {
-          // Can't use nack_list.data() since it's not supported by all
-          // compilers.
-          ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size()));
-        }
+    std::vector<uint16_t> nack_list = _audioCodingModule.GetNackList(
+        round_trip_time);
+    if (!nack_list.empty()) {
+      // Can't use nack_list.data() since it's not supported by all
+      // compilers.
+      ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size()));
     }
     return 0;
 }
@@ -883,6 +889,15 @@
     _instanceId(instanceId),
     _channelId(channelId),
     rtp_header_parser_(RtpHeaderParser::Create()),
+    rtp_payload_registry_(
+        new RTPPayloadRegistry(channelId,
+                               RTPPayloadStrategy::CreateStrategy(true))),
+    rtp_receive_statistics_(ReceiveStatistics::Create(
+        Clock::GetRealTimeClock())),
+    rtp_receiver_(RtpReceiver::CreateAudioReceiver(
+        VoEModuleId(instanceId, channelId), Clock::GetRealTimeClock(), this,
+        this, this, rtp_payload_registry_.get())),
+    telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()),
     _audioCodingModule(*AudioCodingModule::Create(
         VoEModuleId(instanceId, channelId))),
     _rtpDumpIn(*RtpDump::CreateRtpDump()),
@@ -982,11 +997,10 @@
     RtpRtcp::Configuration configuration;
     configuration.id = VoEModuleId(instanceId, channelId);
     configuration.audio = true;
-    configuration.incoming_data = this;
-    configuration.incoming_messages = this;
     configuration.outgoing_transport = this;
     configuration.rtcp_feedback = this;
     configuration.audio_messages = this;
+    configuration.receive_statistics = rtp_receive_statistics_.get();
 
     _rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
 
@@ -1134,12 +1148,9 @@
     // disabled by the user.
     // After StopListen (when no sockets exists), RTCP packets will no longer
     // be transmitted since the Transport object will then be invalid.
-
-    const bool rtpRtcpFail =
-        ((_rtpRtcpModule->SetTelephoneEventForwardToDecoder(true) == -1) ||
-        // RTCP is enabled by default
-        (_rtpRtcpModule->SetRTCPStatus(kRtcpCompound) == -1));
-    if (rtpRtcpFail)
+    telephone_event_handler_->SetTelephoneEventForwardToDecoder(true);
+    // RTCP is enabled by default.
+    if (_rtpRtcpModule->SetRTCPStatus(kRtcpCompound) == -1)
     {
         _engineStatisticsPtr->SetLastError(
             VE_RTP_RTCP_MODULE_ERROR, kTraceError,
@@ -1170,7 +1181,12 @@
     {
         // Open up the RTP/RTCP receiver for all supported codecs
         if ((_audioCodingModule.Codec(idx, &codec) == -1) ||
-            (_rtpRtcpModule->RegisterReceivePayload(codec) == -1))
+            (rtp_receiver_->RegisterReceivePayload(
+                codec.plname,
+                codec.pltype,
+                codec.plfreq,
+                codec.channels,
+                (codec.rate < 0) ? 0 : codec.rate) == -1))
         {
             WEBRTC_TRACE(kTraceWarning, kTraceVoice,
                          VoEId(_instanceId,_channelId),
@@ -1480,12 +1496,7 @@
     }
 
     // Recover DTMF detection status.
-    int32_t ret = _rtpRtcpModule->SetTelephoneEventForwardToDecoder(true);
-    if (ret != 0) {
-        _engineStatisticsPtr->SetLastError(
-            VE_INVALID_OPERATION, kTraceWarning,
-            "StopReceiving() failed to restore telephone-event status.");
-    }
+    telephone_event_handler_->SetTelephoneEventForwardToDecoder(true);
     RegisterReceiveCodecsToRTPModule();
     _receiving = false;
     return 0;
@@ -1737,10 +1748,15 @@
         CodecInst rxCodec = codec;
 
         // Get payload type for the given codec
-        _rtpRtcpModule->ReceivePayloadType(rxCodec, &pltype);
+        rtp_payload_registry_->ReceivePayloadType(
+            rxCodec.plname,
+            rxCodec.plfreq,
+            rxCodec.channels,
+            (rxCodec.rate < 0) ? 0 : rxCodec.rate,
+            &pltype);
         rxCodec.pltype = pltype;
 
-        if (_rtpRtcpModule->DeRegisterReceivePayload(pltype) != 0)
+        if (rtp_receiver_->DeRegisterReceivePayload(pltype) != 0)
         {
             _engineStatisticsPtr->SetLastError(
                     VE_RTP_RTCP_MODULE_ERROR,
@@ -1759,11 +1775,21 @@
         return 0;
     }
 
-    if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0)
+    if (rtp_receiver_->RegisterReceivePayload(
+        codec.plname,
+        codec.pltype,
+        codec.plfreq,
+        codec.channels,
+        (codec.rate < 0) ? 0 : codec.rate) != 0)
     {
         // First attempt to register failed => de-register and try again
-        _rtpRtcpModule->DeRegisterReceivePayload(codec.pltype);
-        if (_rtpRtcpModule->RegisterReceivePayload(codec) != 0)
+        rtp_receiver_->DeRegisterReceivePayload(codec.pltype);
+        if (rtp_receiver_->RegisterReceivePayload(
+            codec.plname,
+            codec.pltype,
+            codec.plfreq,
+            codec.channels,
+            (codec.rate < 0) ? 0 : codec.rate) != 0)
         {
             _engineStatisticsPtr->SetLastError(
                 VE_RTP_RTCP_MODULE_ERROR, kTraceError,
@@ -1791,7 +1817,12 @@
     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
                  "Channel::GetRecPayloadType()");
     int8_t payloadType(-1);
-    if (_rtpRtcpModule->ReceivePayloadType(codec, &payloadType) != 0)
+    if (rtp_payload_registry_->ReceivePayloadType(
+        codec.plname,
+        codec.plfreq,
+        codec.channels,
+        (codec.rate < 0) ? 0 : codec.rate,
+        &payloadType) != 0)
     {
         _engineStatisticsPtr->SetLastError(
             VE_RTP_RTCP_MODULE_ERROR, kTraceWarning,
@@ -2151,12 +2182,22 @@
                  "IncomingPacket invalid RTP header");
     return -1;
   }
+  bool retransmitted = IsPacketRetransmitted(header);
+  bool in_order = rtp_receiver_->InOrderPacket(header.sequenceNumber);
+  rtp_receive_statistics_->IncomingPacket(header, static_cast<uint16_t>(length),
+                                          retransmitted, in_order);
+  PayloadUnion payload_specific;
+  if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
+                                                 &payload_specific)) {
+    return -1;
+  }
   // Deliver RTP packet to RTP/RTCP module for parsing
   // The packet will be pushed back to the channel thru the
   // OnReceivedPayloadData callback so we don't push it to the ACM here
-  if (_rtpRtcpModule->IncomingRtpPacket(reinterpret_cast<const uint8_t*>(data),
+  if (!rtp_receiver_->IncomingRtpPacket(&header,
+                                        reinterpret_cast<const uint8_t*>(data),
                                         static_cast<uint16_t>(length),
-                                        header) == -1) {
+                                        payload_specific, in_order)) {
     _engineStatisticsPtr->SetLastError(
         VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
         "Channel::IncomingRTPPacket() RTP packet is invalid");
@@ -2164,6 +2205,24 @@
   return 0;
 }
 
+bool Channel::IsPacketRetransmitted(const RTPHeader& header) const {
+  bool rtx_enabled = false;
+  uint32_t rtx_ssrc = 0;
+  int rtx_payload_type = 0;
+  rtp_receiver_->RTXStatus(&rtx_enabled, &rtx_ssrc, &rtx_payload_type);
+  if (!rtx_enabled) {
+    // Check if this is a retransmission.
+    ReceiveStatistics::RtpReceiveStatistics stats;
+    if (rtp_receive_statistics_->Statistics(&stats, false)) {
+      uint16_t min_rtt = 0;
+      _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
+      return rtp_receiver_->RetransmitOfOldPacket(header, stats.jitter,
+                                                  min_rtt);
+    }
+  }
+  return false;
+}
+
 int32_t Channel::ReceivedRTCPPacket(const int8_t* data, int32_t length) {
   WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
                "Channel::ReceivedRTCPPacket()");
@@ -2188,141 +2247,6 @@
   return 0;
 }
 
-int32_t
-Channel::SetPacketTimeoutNotification(bool enable, int timeoutSeconds)
-{
-    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
-                 "Channel::SetPacketTimeoutNotification()");
-    if (enable)
-    {
-        const uint32_t RTPtimeoutMS = 1000*timeoutSeconds;
-        const uint32_t RTCPtimeoutMS = 0;
-        _rtpRtcpModule->SetPacketTimeout(RTPtimeoutMS, RTCPtimeoutMS);
-        _rtpPacketTimeOutIsEnabled = true;
-        _rtpTimeOutSeconds = timeoutSeconds;
-    }
-    else
-    {
-        _rtpRtcpModule->SetPacketTimeout(0, 0);
-        _rtpPacketTimeOutIsEnabled = false;
-        _rtpTimeOutSeconds = 0;
-    }
-    return 0;
-}
-
-int32_t
-Channel::GetPacketTimeoutNotification(bool& enabled, int& timeoutSeconds)
-{
-    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
-                 "Channel::GetPacketTimeoutNotification()");
-    enabled = _rtpPacketTimeOutIsEnabled;
-    if (enabled)
-    {
-        timeoutSeconds = _rtpTimeOutSeconds;
-    }
-    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
-                 "GetPacketTimeoutNotification() => enabled=%d,"
-                 " timeoutSeconds=%d",
-                 enabled, timeoutSeconds);
-    return 0;
-}
-
-int32_t
-Channel::RegisterDeadOrAliveObserver(VoEConnectionObserver& observer)
-{
-    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
-                 "Channel::RegisterDeadOrAliveObserver()");
-    CriticalSectionScoped cs(&_callbackCritSect);
-
-    if (_connectionObserverPtr)
-    {
-        _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION, kTraceError,
-            "RegisterDeadOrAliveObserver() observer already enabled");
-        return -1;
-    }
-
-    _connectionObserverPtr = &observer;
-    _connectionObserver = true;
-
-    return 0;
-}
-
-int32_t
-Channel::DeRegisterDeadOrAliveObserver()
-{
-    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
-                 "Channel::DeRegisterDeadOrAliveObserver()");
-    CriticalSectionScoped cs(&_callbackCritSect);
-
-    if (!_connectionObserverPtr)
-    {
-        _engineStatisticsPtr->SetLastError(
-            VE_INVALID_OPERATION, kTraceWarning,
-            "DeRegisterDeadOrAliveObserver() observer already disabled");
-        return 0;
-    }
-
-    _connectionObserver = false;
-    _connectionObserverPtr = NULL;
-
-    return 0;
-}
-
-int32_t
-Channel::SetPeriodicDeadOrAliveStatus(bool enable, int sampleTimeSeconds)
-{
-    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
-                 "Channel::SetPeriodicDeadOrAliveStatus()");
-    if (!_connectionObserverPtr)
-    {
-        WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
-                     "SetPeriodicDeadOrAliveStatus() connection observer has"
-                     " not been registered");
-    }
-    if (enable)
-    {
-        ResetDeadOrAliveCounters();
-    }
-    bool enabled(false);
-    uint8_t currentSampleTimeSec(0);
-    // Store last state (will be used later if dead-or-alive is disabled).
-    _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, currentSampleTimeSec);
-    // Update the dead-or-alive state.
-    if (_rtpRtcpModule->SetPeriodicDeadOrAliveStatus(
-        enable, (uint8_t)sampleTimeSeconds) != 0)
-    {
-        _engineStatisticsPtr->SetLastError(
-                VE_RTP_RTCP_MODULE_ERROR,
-                kTraceError,
-                "SetPeriodicDeadOrAliveStatus() failed to set dead-or-alive "
-                "status");
-        return -1;
-    }
-    if (!enable)
-    {
-        // Restore last utilized sample time.
-        // Without this, the sample time would always be reset to default
-        // (2 sec), each time dead-or-alived was disabled without sample-time
-        // parameter.
-        _rtpRtcpModule->SetPeriodicDeadOrAliveStatus(enable,
-                                                    currentSampleTimeSec);
-    }
-    return 0;
-}
-
-int32_t
-Channel::GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds)
-{
-    _rtpRtcpModule->PeriodicDeadOrAliveStatus(
-        enabled,
-        (uint8_t&)sampleTimeSeconds);
-    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
-                 "GetPeriodicDeadOrAliveStatus() => enabled=%d,"
-                 " sampleTimeSeconds=%d",
-                 enabled, sampleTimeSeconds);
-    return 0;
-}
-
 int Channel::StartPlayingFileLocally(const char* fileName,
                                      bool loop,
                                      FileFormats format,
@@ -3131,8 +3055,8 @@
 }
 
 int Channel::SendTelephoneEventOutband(unsigned char eventCode,
-                                          int lengthMs, int attenuationDb,
-                                          bool playDtmfEvent)
+                                       int lengthMs, int attenuationDb,
+                                       bool playDtmfEvent)
 {
     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
                "Channel::SendTelephoneEventOutband(..., playDtmfEvent=%d)",
@@ -3661,7 +3585,7 @@
 int
 Channel::GetRemoteSSRC(unsigned int& ssrc)
 {
-    ssrc = _rtpRtcpModule->RemoteSSRC();
+    ssrc = rtp_receiver_->SSRC();
     WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
                  VoEId(_instanceId,_channelId),
                  "GetRemoteSSRC() => ssrc=%lu", ssrc);
@@ -3809,7 +3733,7 @@
         return -1;
     }
     char cname[RTCP_CNAME_SIZE];
-    const uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC();
+    const uint32_t remoteSSRC = rtp_receiver_->SSRC();
     if (_rtpRtcpModule->RemoteCNAME(remoteSSRC, cname) != 0)
     {
         _engineStatisticsPtr->SetLastError(
@@ -3884,7 +3808,7 @@
           return -1;
         }
 
-        uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC();
+        uint32_t remoteSSRC = rtp_receiver_->SSRC();
         std::vector<RTCPReportBlock>::const_iterator it = remote_stats.begin();
         for (; it != remote_stats.end(); ++it) {
           if (it->remoteSSRC == remoteSSRC)
@@ -3976,24 +3900,15 @@
         unsigned int& maxJitterMs,
         unsigned int& discardedPackets)
 {
-    uint8_t fraction_lost(0);
-    uint32_t cum_lost(0);
-    uint32_t ext_max(0);
-    uint32_t jitter(0);
-    uint32_t max_jitter(0);
-
     // The jitter statistics is updated for each received RTP packet and is
     // based on received packets.
-    if (_rtpRtcpModule->StatisticsRTP(&fraction_lost,
-                                     &cum_lost,
-                                     &ext_max,
-                                     &jitter,
-                                     &max_jitter) != 0)
-    {
-        _engineStatisticsPtr->SetLastError(
-            VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
-            "GetRTPStatistics() failed to read RTP statistics from the "
-            "RTP/RTCP module");
+    ReceiveStatistics::RtpReceiveStatistics statistics;
+    if (!rtp_receive_statistics_->Statistics(
+        &statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) {
+      _engineStatisticsPtr->SetLastError(
+          VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
+          "GetRTPStatistics() failed to read RTP statistics from the "
+          "RTP/RTCP module");
     }
 
     const int32_t playoutFrequency =
@@ -4001,8 +3916,8 @@
     if (playoutFrequency > 0)
     {
         // Scale RTP statistics given the current playout frequency
-        maxJitterMs = max_jitter / (playoutFrequency / 1000);
-        averageJitterMs = jitter / (playoutFrequency / 1000);
+        maxJitterMs = statistics.max_jitter / (playoutFrequency / 1000);
+        averageJitterMs = statistics.jitter / (playoutFrequency / 1000);
     }
 
     discardedPackets = _numberOfDiscardedPackets;
@@ -4078,32 +3993,23 @@
 int
 Channel::GetRTPStatistics(CallStatistics& stats)
 {
-    uint8_t fraction_lost(0);
-    uint32_t cum_lost(0);
-    uint32_t ext_max(0);
-    uint32_t jitter(0);
-    uint32_t max_jitter(0);
-
     // --- Part one of the final structure (four values)
 
     // The jitter statistics is updated for each received RTP packet and is
     // based on received packets.
-    if (_rtpRtcpModule->StatisticsRTP(&fraction_lost,
-                                     &cum_lost,
-                                     &ext_max,
-                                     &jitter,
-                                     &max_jitter) != 0)
-    {
-        _engineStatisticsPtr->SetLastError(
-            VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
-            "GetRTPStatistics() failed to read RTP statistics from the "
-            "RTP/RTCP module");
+    ReceiveStatistics::RtpReceiveStatistics statistics;
+    if (!rtp_receive_statistics_->Statistics(
+        &statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) {
+      _engineStatisticsPtr->SetLastError(
+          VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
+          "GetRTPStatistics() failed to read RTP statistics from the "
+          "RTP/RTCP module");
     }
 
-    stats.fractionLost = fraction_lost;
-    stats.cumulativeLost = cum_lost;
-    stats.extendedMax = ext_max;
-    stats.jitterSamples = jitter;
+    stats.fractionLost = statistics.fraction_lost;
+    stats.cumulativeLost = statistics.cumulative_lost;
+    stats.extendedMax = statistics.extended_max_sequence_number;
+    stats.jitterSamples = statistics.jitter;
 
     WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
                  VoEId(_instanceId, _channelId),
@@ -4125,7 +4031,7 @@
     } else
     {
         // The remote SSRC will be zero if no RTP packet has been received.
-        uint32_t remoteSSRC = _rtpRtcpModule->RemoteSSRC();
+        uint32_t remoteSSRC = rtp_receiver_->SSRC();
         if (remoteSSRC > 0)
         {
             uint16_t avgRTT(0);
@@ -4162,10 +4068,10 @@
     uint32_t bytesReceived(0);
     uint32_t packetsReceived(0);
 
+    rtp_receive_statistics_->GetDataCounters(&bytesReceived, &packetsReceived);
+
     if (_rtpRtcpModule->DataCountersRTP(&bytesSent,
-                                       &packetsSent,
-                                       &bytesReceived,
-                                       &packetsReceived) != 0)
+                                        &packetsSent) != 0)
     {
         WEBRTC_TRACE(kTraceWarning, kTraceVoice,
                      VoEId(_instanceId, _channelId),
@@ -4247,8 +4153,8 @@
 void Channel::SetNACKStatus(bool enable, int maxNumberOfPackets) {
   // None of these functions can fail.
   _rtpRtcpModule->SetStorePacketsStatus(enable, maxNumberOfPackets);
-  _rtpRtcpModule->SetNACKStatus(enable ? kNackRtcp : kNackOff,
-                                maxNumberOfPackets);
+  rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff,
+      maxNumberOfPackets);
   if (enable)
     _audioCodingModule.EnableNack(maxNumberOfPackets);
   else
@@ -4631,7 +4537,7 @@
     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
                  "Channel::ResetRTCPStatistics()");
     uint32_t remoteSSRC(0);
-    remoteSSRC = _rtpRtcpModule->RemoteSSRC();
+    remoteSSRC = rtp_receiver_->SSRC();
     return _rtpRtcpModule->ResetRTT(remoteSSRC);
 }
 
@@ -4660,7 +4566,7 @@
     uint16_t maxRTT;
     uint16_t minRTT;
     // The remote SSRC will be zero if no RTP packet has been received.
-    remoteSSRC = _rtpRtcpModule->RemoteSSRC();
+    remoteSSRC = rtp_receiver_->SSRC();
     if (remoteSSRC == 0)
     {
         WEBRTC_TRACE(kTraceWarning, kTraceVoice, VoEId(_instanceId,_channelId),
@@ -4870,11 +4776,12 @@
 }
 
 int
-Channel::GetRtpRtcp(RtpRtcp* &rtpRtcpModule) const
+Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const
 {
     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
                  "Channel::GetRtpRtcp()");
-    rtpRtcpModule = _rtpRtcpModule.get();
+    *rtpRtcpModule = _rtpRtcpModule.get();
+    *rtp_receiver = rtp_receiver_.get();
     return 0;
 }
 
@@ -5094,15 +5001,6 @@
 int
 Channel::GetDeadOrAliveCounters(int& countDead, int& countAlive) const
 {
-    bool enabled;
-    uint8_t timeSec;
-
-    _rtpRtcpModule->PeriodicDeadOrAliveStatus(enabled, timeSec);
-    if (!enabled)
-        return (-1);
-
-    countDead = static_cast<int> (_countDeadDetections);
-    countAlive = static_cast<int> (_countAliveDetections);
     return 0;
 }
 
@@ -5202,7 +5100,12 @@
     {
         // Open up the RTP/RTCP receiver for all supported codecs
         if ((_audioCodingModule.Codec(idx, &codec) == -1) ||
-            (_rtpRtcpModule->RegisterReceivePayload(codec) == -1))
+            (rtp_receiver_->RegisterReceivePayload(
+                codec.plname,
+                codec.pltype,
+                codec.plfreq,
+                codec.channels,
+                (codec.rate < 0) ? 0 : codec.rate) == -1))
         {
             WEBRTC_TRACE(
                          kTraceWarning,
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index a1e16fe..756ac88 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -35,16 +35,21 @@
 
 namespace webrtc
 {
-class CriticalSectionWrapper;
-class ProcessThread;
 class AudioDeviceModule;
-class RtpRtcp;
+class CriticalSectionWrapper;
 class FileWrapper;
+class ProcessThread;
+class ReceiveStatistics;
 class RtpDump;
-class VoiceEngineObserver;
+class RTPPayloadRegistry;
+class RtpReceiver;
+class RTPReceiverAudio;
+class RtpRtcp;
+class TelephoneEventHandler;
 class VoEMediaProcess;
-class VoERTPObserver;
 class VoERTCPObserver;
+class VoERTPObserver;
+class VoiceEngineObserver;
 
 struct CallStatistics;
 struct ReportBlock;
@@ -133,12 +138,6 @@
     int32_t DeRegisterExternalTransport();
     int32_t ReceivedRTPPacket(const int8_t* data, int32_t length);
     int32_t ReceivedRTCPPacket(const int8_t* data, int32_t length);
-    int32_t SetPacketTimeoutNotification(bool enable, int timeoutSeconds);
-    int32_t GetPacketTimeoutNotification(bool& enabled, int& timeoutSeconds);
-    int32_t RegisterDeadOrAliveObserver(VoEConnectionObserver& observer);
-    int32_t DeRegisterDeadOrAliveObserver();
-    int32_t SetPeriodicDeadOrAliveStatus(bool enable, int sampleTimeSeconds);
-    int32_t GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds);
 
     // VoEFile
     int StartPlayingFileLocally(const char* fileName, bool loop,
@@ -215,7 +214,7 @@
     int SetInitSequenceNumber(short sequenceNumber);
 
     // VoEVideoSyncExtended
-    int GetRtpRtcp(RtpRtcp* &rtpRtcpModule) const;
+    int GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const;
 
     // VoEEncryption
     int RegisterExternalEncryption(Encryption& encryption);
@@ -307,6 +306,11 @@
                                   uint16_t payloadSize,
                                   const WebRtcRTPHeader* rtpHeader);
 
+    bool OnRecoveredPacket(const uint8_t* packet, int packet_length) {
+      // Generic FEC not supported for audio.
+      return true;
+    }
+
 public:
     // From RtpFeedback in the RTP/RTCP module
     int32_t OnInitializeDecoder(
@@ -330,6 +334,8 @@
     void OnIncomingCSRCChanged(int32_t id,
                                uint32_t CSRC, bool added);
 
+    void OnResetStatistics();
+
 public:
     // From RtcpFeedback in the RTP/RTCP module
     void OnApplicationDataReceived(int32_t id,
@@ -426,6 +432,7 @@
     uint32_t EncodeAndSend();
 
 private:
+    bool IsPacketRetransmitted(const RTPHeader& header) const;
     int ResendPackets(const uint16_t* sequence_numbers, int length);
     int InsertInbandDtmfTone();
     int32_t MixOrReplaceAudioWithFile(int mixingFrequency);
@@ -446,6 +453,10 @@
 
 private:
     scoped_ptr<RtpHeaderParser> rtp_header_parser_;
+    scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+    scoped_ptr<ReceiveStatistics> rtp_receive_statistics_;
+    scoped_ptr<RtpReceiver> rtp_receiver_;
+    TelephoneEventHandler* telephone_event_handler_;
     scoped_ptr<RtpRtcp> _rtpRtcpModule;
     AudioCodingModule& _audioCodingModule;
     RtpDump& _rtpDumpIn;
diff --git a/voice_engine/include/voe_network.h b/voice_engine/include/voe_network.h
index 7bcf903..8259e32 100644
--- a/voice_engine/include/voe_network.h
+++ b/voice_engine/include/voe_network.h
@@ -89,31 +89,6 @@
     virtual int ReceivedRTCPPacket(
         int channel, const void* data, unsigned int length) = 0;
 
-    // Enables or disables warnings that report if packets have not been
-    // received in |timeoutSeconds| seconds for a specific |channel|.
-    virtual int SetPacketTimeoutNotification(
-        int channel, bool enable, int timeoutSeconds = 2) = 0;
-
-    // Gets the current time-out notification status.
-    virtual int GetPacketTimeoutNotification(
-        int channel, bool& enabled, int& timeoutSeconds) = 0;
-
-    // Installs the observer class implementation for a specified |channel|.
-    virtual int RegisterDeadOrAliveObserver(
-        int channel, VoEConnectionObserver& observer) = 0;
-
-    // Removes the observer class implementation for a specified |channel|.
-    virtual int DeRegisterDeadOrAliveObserver(int channel) = 0;
-
-    // Enables or disables the periodic dead-or-alive callback functionality
-    // for a specified |channel|.
-    virtual int SetPeriodicDeadOrAliveStatus(
-        int channel, bool enable, int sampleTimeSeconds = 2) = 0;
-
-    // Gets the current dead-or-alive notification status.
-    virtual int GetPeriodicDeadOrAliveStatus(
-        int channel, bool& enabled, int& sampleTimeSeconds) = 0;
-
 protected:
     VoENetwork() {}
     virtual ~VoENetwork() {}
diff --git a/voice_engine/include/voe_video_sync.h b/voice_engine/include/voe_video_sync.h
index ef811a9..cf16d3b 100644
--- a/voice_engine/include/voe_video_sync.h
+++ b/voice_engine/include/voe_video_sync.h
@@ -37,6 +37,7 @@
 
 namespace webrtc {
 
+class RtpReceiver;
 class RtpRtcp;
 class VoiceEngine;
 
@@ -92,7 +93,8 @@
     // Get the received RTP timestamp
     virtual int GetPlayoutTimestamp(int channel, unsigned int& timestamp) = 0;
 
-    virtual int GetRtpRtcp (int channel, RtpRtcp* &rtpRtcpModule) = 0;
+    virtual int GetRtpRtcp (int channel, RtpRtcp** rtpRtcpModule,
+                            RtpReceiver** rtp_receiver) = 0;
 
 protected:
     VoEVideoSync() { }
diff --git a/voice_engine/test/auto_test/standard/call_report_test.cc b/voice_engine/test/auto_test/standard/call_report_test.cc
index 26df80b..ee98dc1 100644
--- a/voice_engine/test/auto_test/standard/call_report_test.cc
+++ b/voice_engine/test/auto_test/standard/call_report_test.cc
@@ -54,29 +54,6 @@
   EXPECT_NE(-1, delays.max);
 }
 
-TEST_F(CallReportTest, DeadOrAliveSummaryFailsIfDeadOrAliveTrackingNotActive) {
-  int count_the_dead;
-  int count_the_living;
-  EXPECT_EQ(-1, voe_call_report_->GetDeadOrAliveSummary(channel_,
-                                                        count_the_dead,
-                                                        count_the_living));
-}
-
-TEST_F(CallReportTest,
-       DeadOrAliveSummarySucceedsIfDeadOrAliveTrackingIsActive) {
-  EXPECT_EQ(0, voe_network_->SetPeriodicDeadOrAliveStatus(channel_, true, 1));
-  Sleep(1200);
-
-  int count_the_dead;
-  int count_the_living;
-  EXPECT_EQ(0, voe_call_report_->GetDeadOrAliveSummary(channel_,
-                                                       count_the_dead,
-                                                       count_the_living));
-
-  EXPECT_GE(count_the_dead, 0);
-  EXPECT_GE(count_the_living, 0);
-}
-
 TEST_F(CallReportTest, WriteReportToFileFailsOnBadInput) {
   EXPECT_EQ(-1, voe_call_report_->WriteReportToFile(NULL));
 }
diff --git a/voice_engine/test/auto_test/standard/network_test.cc b/voice_engine/test/auto_test/standard/network_test.cc
index 1c83799..79daf59 100644
--- a/voice_engine/test/auto_test/standard/network_test.cc
+++ b/voice_engine/test/auto_test/standard/network_test.cc
@@ -23,100 +23,6 @@
 
 using ::testing::Between;
 
-TEST_F(NetworkTest,
-    CallsObserverOnTimeoutAndRestartWhenPacketTimeoutNotificationIsEnabled) {
-  // First, get rid of the default, asserting observer and install our observer.
-  EXPECT_EQ(0, voe_base_->DeRegisterVoiceEngineObserver());
-  webrtc::MockVoEObserver mock_observer;
-  EXPECT_EQ(0, voe_base_->RegisterVoiceEngineObserver(mock_observer));
-
-  // Define expectations.
-  int expected_error = VE_RECEIVE_PACKET_TIMEOUT;
-  EXPECT_CALL(mock_observer, CallbackOnError(channel_, expected_error))
-      .Times(1);
-  expected_error = VE_PACKET_RECEIPT_RESTARTED;
-    EXPECT_CALL(mock_observer, CallbackOnError(channel_, expected_error))
-      .Times(1);
-
-  // Get some speech going.
-  Sleep(500);
-
-  // Enable packet timeout.
-  EXPECT_EQ(0, voe_network_->SetPacketTimeoutNotification(channel_, true, 1));
-
-  // Trigger a timeout.
-  EXPECT_EQ(0, voe_base_->StopSend(channel_));
-  Sleep(1500);
-
-  // Trigger a restart event.
-  EXPECT_EQ(0, voe_base_->StartSend(channel_));
-  Sleep(500);
-}
-
-TEST_F(NetworkTest, DoesNotCallDeRegisteredObserver) {
-  // De-register the default observer. This test will fail if the observer gets
-  // called for any reason, so if this de-register doesn't work the test will
-  // fail.
-  EXPECT_EQ(0, voe_base_->DeRegisterVoiceEngineObserver());
-
-  // Get some speech going.
-  Sleep(500);
-
-  // Enable packet timeout.
-  EXPECT_EQ(0, voe_network_->SetPacketTimeoutNotification(channel_, true, 1));
-
-  // Trigger a timeout.
-  EXPECT_EQ(0, voe_base_->StopSend(channel_));
-  Sleep(1500);
-}
-
-// TODO(phoglund): flaky on Linux
-TEST_F(NetworkTest,
-       DISABLED_ON_LINUX(DeadOrAliveObserverSeesAliveMessagesIfEnabled)) {
-  if (!FLAGS_include_timing_dependent_tests) {
-    TEST_LOG("Skipping test - running in slow execution environment...\n");
-    return;
-  }
-
-  webrtc::MockVoeConnectionObserver mock_observer;
-  EXPECT_EQ(0, voe_network_->RegisterDeadOrAliveObserver(
-      channel_, mock_observer));
-
-  // We should be called about 4 times in four seconds, but 3 is OK too.
-  EXPECT_CALL(mock_observer, OnPeriodicDeadOrAlive(channel_, true))
-      .Times(Between(3, 4));
-
-  EXPECT_EQ(0, voe_network_->SetPeriodicDeadOrAliveStatus(channel_, true, 1));
-  Sleep(4000);
-
-  EXPECT_EQ(0, voe_network_->DeRegisterDeadOrAliveObserver(channel_));
-}
-
-TEST_F(NetworkTest, DeadOrAliveObserverSeesDeadMessagesIfEnabled) {
-  if (!FLAGS_include_timing_dependent_tests) {
-    TEST_LOG("Skipping test - running in slow execution environment...\n");
-    return;
-  }
-
-  // "When do you see them?" - "All the time!"
-  webrtc::MockVoeConnectionObserver mock_observer;
-  EXPECT_EQ(0, voe_network_->RegisterDeadOrAliveObserver(
-      channel_, mock_observer));
-
-  Sleep(500);
-
-  // We should be called about 4 times in four seconds, but 3 is OK too.
-  EXPECT_CALL(mock_observer, OnPeriodicDeadOrAlive(channel_, false))
-      .Times(Between(3, 4));
-
-  EXPECT_EQ(0, voe_network_->SetPeriodicDeadOrAliveStatus(channel_, true, 1));
-  EXPECT_EQ(0, voe_rtp_rtcp_->SetRTCPStatus(channel_, false));
-  EXPECT_EQ(0, voe_base_->StopSend(channel_));
-  Sleep(4000);
-
-  EXPECT_EQ(0, voe_network_->DeRegisterDeadOrAliveObserver(channel_));
-}
-
 TEST_F(NetworkTest, CanSwitchToExternalTransport) {
   EXPECT_EQ(0, voe_base_->StopReceive(channel_));
   EXPECT_EQ(0, voe_base_->DeleteChannel(channel_));
diff --git a/voice_engine/test/auto_test/voe_extended_test.cc b/voice_engine/test/auto_test/voe_extended_test.cc
index 9568e89..0504903 100644
--- a/voice_engine/test/auto_test/voe_extended_test.cc
+++ b/voice_engine/test/auto_test/voe_extended_test.cc
@@ -1158,24 +1158,6 @@
    ANL();
    */
 
-  int nDead = 0;
-  int nAlive = 0;
-  TEST(GetDeadOrAliveSummary);
-  ANL();
-  // All results should be -1 since dead-or-alive is not active
-  TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive) != -1);
-  MARK();
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
-  SleepMs(2000);
-  // All results should be >= 0 since dead-or-alive is active
-  TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive));
-  MARK();
-  TEST_MUSTPASS(nDead == -1);
-  TEST_MUSTPASS(nAlive == -1)
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  AOK();
-  ANL();
-
   TEST(WriteReportToFile);
   ANL();
 
@@ -4183,218 +4165,8 @@
 
   // >> end of SetExternalTransport
   // ------------------------------------------------------------------------
-
-  // ------------------------------------------------------------------------
-  // >> RegisterDeadOrAliveObserver
-  // >> DeRegisterDeadOrAliveObserver
-  //
-  // - VE initialized
-  // - no existing channels
-  // - no media
-  TEST(RegisterDeadOrAliveObserver);
-  ANL();
-  TEST(DeRegisterDeadOrAliveObserver);
-  ANL();
-
-  // call without valid channel
-  TEST_MUSTPASS(!voe_network ->RegisterDeadOrAliveObserver(0, *this));
-  MARK();
-  TEST_ERROR(VE_CHANNEL_NOT_VALID);
-
-  TEST_MUSTPASS(voe_base_->CreateChannel());
-
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
-  MARK();
-  TEST_MUSTPASS(!voe_network ->RegisterDeadOrAliveObserver(0, *this));
-  MARK(); // already registered
-  TEST_ERROR(VE_INVALID_OPERATION);
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
-  MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
-  MARK(); // OK to do it again
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
-  MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
-  MARK();
-
-  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
-
-  // STATE: dead-or-alive observer is disabled
-
-  // >> end of RegisterDeadOrAliveObserver
-  // ------------------------------------------------------------------------
-
-  // ------------------------------------------------------------------------
-  // >> SetPeriodicDeadOrAliveStatus
-  // >> GetPeriodicDeadOrAliveStatus
-  //
-  // - VE initialized
-  // - no existing channels
-  // - no media
-
-  // call without valid channel
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  MARK();
-  TEST_ERROR(VE_CHANNEL_NOT_VALID);
-
-  TEST_MUSTPASS(voe_base_->CreateChannel());
-
-  // Invalid paramters
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 0));
-  MARK();
-  TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 151));
-  MARK();
-  TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(1, true, 10));
-  MARK();
-  TEST_ERROR(VE_CHANNEL_NOT_VALID);
-
-  int sampleTime(0);
-  bool enabled;
-
-  // Valid parameters
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
-  MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
-  TEST_MUSTPASS(enabled != true);
-  TEST_MUSTPASS(sampleTime != 1);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 150));
-  MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
-  TEST_MUSTPASS(enabled != true);
-  TEST_MUSTPASS(sampleTime != 150);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
-  TEST_MUSTPASS(enabled != false);
-  TEST_MUSTPASS(sampleTime != 150); // ensure last set time isnt modified
-
-  StartMedia(0, 2000, true, true, true);
-
-  // STATE: full duplex media is active
-
-  // test the dead-or-alive mechanism
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
-  MARK();
-  TEST_LOG("\nVerify that Alive callbacks are received (dT=2sec): ");
-  fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 2));
-  SleepMs(6000);
-  TEST_LOG("\nChange dT to 1 second: ");
-  fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
-  SleepMs(6000);
-  TEST_LOG("\nDisable dead-or-alive callbacks: ");
-  fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  SleepMs(6000);
-  TEST_LOG("\nStop sending and enable callbacks again.\n");
-  TEST_LOG("Verify that Dead callbacks are received (dT=2sec): ");
-  fflush(NULL);
-  TEST_MUSTPASS(voe_base_->StopSend(0));
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 2));
-  SleepMs(6000);
-  TEST_MUSTPASS(voe_base_->StartSend(0));
-  TEST_LOG("\nRestart sending.\n");
-  TEST_LOG("Verify that Alive callbacks are received again (dT=2sec): ");
-  fflush(NULL);
-  SleepMs(6000);
-  TEST_LOG("\nDisable dead-or-alive callbacks.");
-  fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
-  MARK();
-
-  StopMedia(0);
-
-  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
-  ANL();
-  AOK();
-  ANL();
-  ANL();
-
-  // >> end of SetPeriodicDeadOrAliveStatus
-  // ------------------------------------------------------------------------
-
-  // ------------------------------------------------------------------------
-  // >> SetPacketTimeoutNotification
-  // >> GetPacketTimeoutNotification
-  //
-  // - VE initialized
-  // - no existing channels
-  // - no media
-  // - NOTE: dynamic tests are performed in standard test
-
-  int timeOut(0);
-
-  TEST(SetPacketTimeoutNotification);
-  ANL();
-  TEST(GetPacketTimeoutNotification);
-  ANL();
-
-  // call without existing valid channel
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, false));
-  MARK();
-  TEST_ERROR(VE_CHANNEL_NOT_VALID);
-
-  TEST_MUSTPASS(voe_base_->CreateChannel());
-
-  // invalid function calls
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, true, 0));
-  MARK();
-  TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, true, 151));
-  MARK();
-  TEST_ERROR(VE_INVALID_ARGUMENT);
-
-  // valid function calls (no active media)
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 2));
-  MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled,
-                                                           timeOut));
-  MARK();
-  TEST_MUSTPASS(enabled != true);
-  TEST_MUSTPASS(timeOut != 2);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, false));
-  MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled,
-                                                           timeOut));
-  MARK();
-  TEST_MUSTPASS(enabled != false);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 10));
-  MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled,
-                                                           timeOut));
-  MARK();
-  TEST_MUSTPASS(enabled != true);
-  TEST_MUSTPASS(timeOut != 10);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 2));
-  MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled,
-                                                           timeOut));
-  MARK();
-  TEST_MUSTPASS(enabled != true);
-  TEST_MUSTPASS(timeOut != 2);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, false));
-  MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled,
-                                                           timeOut));
-  MARK();
-  TEST_MUSTPASS(enabled != false);
-
-  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
-  ANL();
-  AOK();
-  ANL();
-  ANL();
   return 0;
 }
-  // >> end of SetPacketTimeoutNotification
-  // ------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 //  VoEExtendedTest::TestRTP_RTCP
diff --git a/voice_engine/voe_network_impl.cc b/voice_engine/voe_network_impl.cc
index 6252170..ee87562 100644
--- a/voice_engine/voe_network_impl.cc
+++ b/voice_engine/voe_network_impl.cc
@@ -165,158 +165,4 @@
     }
     return channelPtr->ReceivedRTCPPacket((const int8_t*) data, length);
 }
-
-int VoENetworkImpl::SetPacketTimeoutNotification(int channel,
-                                                 bool enable,
-                                                 int timeoutSeconds)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "SetPacketTimeoutNotification(channel=%d, enable=%d, "
-                 "timeoutSeconds=%d)",
-                 channel, (int) enable, timeoutSeconds);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    if (enable &&
-        ((timeoutSeconds < kVoiceEngineMinPacketTimeoutSec) ||
-        (timeoutSeconds > kVoiceEngineMaxPacketTimeoutSec)))
-    {
-        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
-            "SetPacketTimeoutNotification() invalid timeout size");
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "SetPacketTimeoutNotification() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->SetPacketTimeoutNotification(enable, timeoutSeconds);
-}
-
-int VoENetworkImpl::GetPacketTimeoutNotification(int channel,
-                                                 bool& enabled,
-                                                 int& timeoutSeconds)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "GetPacketTimeoutNotification(channel=%d, enabled=?,"
-                 " timeoutSeconds=?)", channel);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "GetPacketTimeoutNotification() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->GetPacketTimeoutNotification(enabled, timeoutSeconds);
-}
-
-int VoENetworkImpl::RegisterDeadOrAliveObserver(int channel,
-                                                VoEConnectionObserver&
-                                                observer)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "RegisterDeadOrAliveObserver(channel=%d, observer=0x%x)",
-                 channel, &observer);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "RegisterDeadOrAliveObserver() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->RegisterDeadOrAliveObserver(observer);
-}
-
-int VoENetworkImpl::DeRegisterDeadOrAliveObserver(int channel)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "DeRegisterDeadOrAliveObserver(channel=%d)", channel);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "DeRegisterDeadOrAliveObserver() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->DeRegisterDeadOrAliveObserver();
-}
-
-int VoENetworkImpl::SetPeriodicDeadOrAliveStatus(int channel, bool enable,
-                                                 int sampleTimeSeconds)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "SetPeriodicDeadOrAliveStatus(channel=%d, enable=%d,"
-                 " sampleTimeSeconds=%d)",
-                 channel, enable, sampleTimeSeconds);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    if (enable &&
-        ((sampleTimeSeconds < kVoiceEngineMinSampleTimeSec) ||
-        (sampleTimeSeconds > kVoiceEngineMaxSampleTimeSec)))
-    {
-        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
-            "SetPeriodicDeadOrAliveStatus() invalid sample time");
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "SetPeriodicDeadOrAliveStatus() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->SetPeriodicDeadOrAliveStatus(enable, sampleTimeSeconds);
-}
-
-int VoENetworkImpl::GetPeriodicDeadOrAliveStatus(int channel,
-                                                 bool& enabled,
-                                                 int& sampleTimeSeconds)
-{
-    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
-                 "GetPeriodicDeadOrAliveStatus(channel=%d, enabled=?,"
-                 " sampleTimeSeconds=?)", channel);
-    if (!_shared->statistics().Initialized())
-    {
-        _shared->SetLastError(VE_NOT_INITED, kTraceError);
-        return -1;
-    }
-    voe::ScopedChannel sc(_shared->channel_manager(), channel);
-    voe::Channel* channelPtr = sc.ChannelPtr();
-    if (channelPtr == NULL)
-    {
-        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
-            "GetPeriodicDeadOrAliveStatus() failed to locate channel");
-        return -1;
-    }
-    return channelPtr->GetPeriodicDeadOrAliveStatus(enabled,
-                                                    sampleTimeSeconds);
-}
-
 }  // namespace webrtc
diff --git a/voice_engine/voe_network_impl.h b/voice_engine/voe_network_impl.h
index 194899b..6a703cf 100644
--- a/voice_engine/voe_network_impl.h
+++ b/voice_engine/voe_network_impl.h
@@ -34,27 +34,6 @@
                                    const void* data,
                                    unsigned int length);
 
-    virtual int SetPacketTimeoutNotification(int channel,
-                                             bool enable,
-                                             int timeoutSeconds = 2);
-
-    virtual int GetPacketTimeoutNotification(int channel,
-                                             bool& enabled,
-                                             int& timeoutSeconds);
-
-    virtual int RegisterDeadOrAliveObserver(int channel,
-                                            VoEConnectionObserver& observer);
-
-    virtual int DeRegisterDeadOrAliveObserver(int channel);
-
-    virtual int SetPeriodicDeadOrAliveStatus(int channel,
-                                             bool enable,
-                                             int sampleTimeSeconds = 2);
-
-    virtual int GetPeriodicDeadOrAliveStatus(int channel,
-                                             bool& enabled,
-                                             int& sampleTimeSeconds);
-
 protected:
     VoENetworkImpl(voe::SharedData* shared);
     virtual ~VoENetworkImpl();
diff --git a/voice_engine/voe_video_sync_impl.cc b/voice_engine/voe_video_sync_impl.cc
index 91c0750..a0654f7 100644
--- a/voice_engine/voe_video_sync_impl.cc
+++ b/voice_engine/voe_video_sync_impl.cc
@@ -216,7 +216,8 @@
     return 0;
 }
 
-int VoEVideoSyncImpl::GetRtpRtcp(int channel, RtpRtcp* &rtpRtcpModule)
+int VoEVideoSyncImpl::GetRtpRtcp(int channel, RtpRtcp** rtpRtcpModule,
+                                 RtpReceiver** rtp_receiver)
 {
     WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                  "GetRtpRtcp(channel=%i)", channel);
@@ -234,7 +235,7 @@
             "GetPlayoutTimestamp() failed to locate channel");
         return -1;
     }
-    return channelPtr->GetRtpRtcp(rtpRtcpModule);
+    return channelPtr->GetRtpRtcp(rtpRtcpModule, rtp_receiver);
 }
 
 int VoEVideoSyncImpl::GetLeastRequiredDelayMs(int channel) const {
diff --git a/voice_engine/voe_video_sync_impl.h b/voice_engine/voe_video_sync_impl.h
index e0ec3f2..8c516fb 100644
--- a/voice_engine/voe_video_sync_impl.h
+++ b/voice_engine/voe_video_sync_impl.h
@@ -38,7 +38,8 @@
 
     virtual int GetPlayoutTimestamp(int channel, unsigned int& timestamp);
 
-    virtual int GetRtpRtcp(int channel, RtpRtcp* &rtpRtcpModule);
+    virtual int GetRtpRtcp(int channel, RtpRtcp** rtpRtcpModule,
+                           RtpReceiver** rtp_receiver);
 
 protected:
     VoEVideoSyncImpl(voe::SharedData* shared);