Cleaned up the data path for payload data, made callbacks to rtp_receiver nonoptional.

The audio receiver is now completely independent of rtp_receiver: video will hopefully be too in the next patch.

BUG=
TEST=vie & voe_auto_test full runs

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3372 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
index 09761d9..a8e129d 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
+++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h
@@ -26,31 +26,19 @@
 class RtpRtcp : public Module {
  public:
   struct Configuration {
-    Configuration()
-        : id(-1),
-          audio(false),
-          clock(NULL),
-          default_module(NULL),
-          incoming_data(NULL),
-          incoming_messages(NULL),
-          outgoing_transport(NULL),
-          rtcp_feedback(NULL),
-          intra_frame_callback(NULL),
-          bandwidth_callback(NULL),
-          rtt_observer(NULL),
-          audio_messages(NULL),
-          remote_bitrate_estimator(NULL),
-          paced_sender(NULL) {
-    }
+    Configuration();
+
    /*  id                   - Unique identifier of this RTP/RTCP module object
     *  audio                - True for a audio version of the RTP/RTCP module
     *                         object false will create a video version
     *  clock                - The clock to use to read time. If NULL object
     *                         will be using the system clock.
     *  incoming_data        - Callback object that will receive the incoming
-    *                         data
+    *                         data. May not be NULL; default callback will do
+    *                         nothing.
     *  incoming_messages    - Callback object that will receive the incoming
-    *                         RTP messages.
+    *                         RTP messages. May not be NULL; default callback
+    *                         will do nothing.
     *  outgoing_transport   - Transport object that will be called when packets
     *                         are ready to be sent out on the network
     *  rtcp_feedback        - Callback object that will receive the incoming
@@ -58,7 +46,8 @@
     *  intra_frame_callback - Called when the receiver request a intra frame.
     *  bandwidth_callback   - Called when we receive a changed estimate from
     *                         the receiver of out stream.
-    *  audio_messages       - Telehone events.
+    *  audio_messages       - Telehone events. May not be NULL; default callback
+    *                         will do nothing.
     *  remote_bitrate_estimator - Estimates the bandwidth available for a set of
     *                             streams from the same client.
     *  paced_sender             - Spread any bursts of packets into smaller
diff --git a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
index 02a6255..53701c4 100644
--- a/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
@@ -269,5 +269,63 @@
   virtual void CurrentNTP(WebRtc_UWord32& secs, WebRtc_UWord32& frac) = 0;
 };
 
+// Null object version of RtpFeedback.
+class NullRtpFeedback : public RtpFeedback {
+ public:
+  virtual ~NullRtpFeedback() {}
+
+  virtual WebRtc_Word32 OnInitializeDecoder(
+      const WebRtc_Word32 id,
+      const WebRtc_Word8 payloadType,
+      const char payloadName[RTP_PAYLOAD_NAME_SIZE],
+      const int frequency,
+      const WebRtc_UWord8 channels,
+      const WebRtc_UWord32 rate) {
+   return 0;
+ }
+
+ virtual void OnPacketTimeout(const WebRtc_Word32 id) {}
+
+ virtual void OnReceivedPacket(const WebRtc_Word32 id,
+                               const RtpRtcpPacketType packetType) {}
+
+ virtual void OnPeriodicDeadOrAlive(const WebRtc_Word32 id,
+                                    const RTPAliveType alive) {}
+
+ virtual void OnIncomingSSRCChanged(const WebRtc_Word32 id,
+                                    const WebRtc_UWord32 SSRC) {}
+
+ virtual void OnIncomingCSRCChanged(const WebRtc_Word32 id,
+                                    const WebRtc_UWord32 CSRC,
+                                    const bool added) {}
+};
+
+// Null object version of RtpData.
+class NullRtpData : public RtpData {
+ public:
+  virtual ~NullRtpData() {}
+  virtual WebRtc_Word32 OnReceivedPayloadData(
+      const WebRtc_UWord8* payloadData,
+      const WebRtc_UWord16 payloadSize,
+      const WebRtcRTPHeader* rtpHeader) {
+   return 0;
+ }
+};
+
+// Null object version of RtpAudioFeedback.
+class NullRtpAudioFeedback : public RtpAudioFeedback {
+ public:
+  virtual ~NullRtpAudioFeedback() {}
+
+  virtual void OnReceivedTelephoneEvent(const WebRtc_Word32 id,
+                                        const WebRtc_UWord8 event,
+                                        const bool endOfEvent) {}
+
+  virtual void OnPlayTelephoneEvent(const WebRtc_Word32 id,
+                                    const WebRtc_UWord8 event,
+                                    const WebRtc_UWord16 lengthMs,
+                                    const WebRtc_UWord8 volume) {}
+};
+
 } // namespace webrtc
 #endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_RTCP_DEFINES_H_
diff --git a/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h b/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h
index 498c864..a8f5cc7 100644
--- a/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h
+++ b/webrtc/modules/rtp_rtcp/source/mock/mock_rtp_receiver_video.h
@@ -17,7 +17,7 @@
 
 class MockRTPReceiverVideo : public RTPReceiverVideo {
  public:
-  MockRTPReceiverVideo() : RTPReceiverVideo(0, NULL, NULL) {}
+  MockRTPReceiverVideo() : RTPReceiverVideo(0, NULL, NULL, NULL) {}
   MOCK_METHOD1(ChangeUniqueId,
       void(const WebRtc_Word32 id));
   MOCK_METHOD3(ReceiveRecoveredPacketCallback,
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver.cc
index 6fd8f77..35895af 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver.cc
@@ -35,13 +35,21 @@
                          const bool audio,
                          RtpRtcpClock* clock,
                          ModuleRtpRtcpImpl* owner,
-                         RtpAudioFeedback* incoming_messages_callback)
+                         RtpAudioFeedback* incoming_audio_messages_callback,
+                         RtpData* incoming_payload_callback,
+                         RtpFeedback* incoming_messages_callback)
     : Bitrate(clock),
+      // TODO(phoglund): Remove hacks requiring direct access to the
+      // audio receiver and only instantiate one of these directly into the
+      // rtp_media_receiver_ field. Right now an audio receiver carries around a
+      // video handler and vice versa, which doesn't make sense.
+      rtp_receiver_audio_(new RTPReceiverAudio(
+          id, incoming_payload_callback, incoming_audio_messages_callback)),
+      rtp_receiver_video_(new RTPReceiverVideo(
+          id, this, incoming_payload_callback, owner)),
       id_(id),
       rtp_rtcp_(*owner),
-      critical_section_cbs_(CriticalSectionWrapper::CreateCriticalSection()),
-      cb_rtp_feedback_(NULL),
-      cb_rtp_data_(NULL),
+      cb_rtp_feedback_(incoming_messages_callback),
 
       critical_section_rtp_receiver_(
         CriticalSectionWrapper::CreateCriticalSection()),
@@ -94,14 +102,9 @@
       nack_method_(kNackOff),
       rtx_(false),
       ssrc_rtx_(0) {
-  // TODO(phoglund): Remove hacks requiring direct access to the audio receiver
-  // and only instantiate one of these directly into the rtp_media_receiver_
-  // field. Right now an audio receiver carries around a video handler and
-  // vice versa, which doesn't make sense.
-  rtp_receiver_audio_ = new RTPReceiverAudio(id, this,
-                                             incoming_messages_callback);
-  rtp_receiver_video_ = new RTPReceiverVideo(id, this, owner);
-
+  assert(incoming_audio_messages_callback &&
+         incoming_messages_callback &&
+         incoming_payload_callback);
   if (audio) {
     rtp_media_receiver_ = rtp_receiver_audio_;
   } else {
@@ -115,13 +118,10 @@
 }
 
 RTPReceiver::~RTPReceiver() {
-  if (cb_rtp_feedback_) {
-    for (int i = 0; i < num_csrcs_; ++i) {
-      cb_rtp_feedback_->OnIncomingCSRCChanged(id_, current_remote_csrc_[i],
-                                              false);
-    }
+  for (int i = 0; i < num_csrcs_; ++i) {
+    cb_rtp_feedback_->OnIncomingCSRCChanged(id_, current_remote_csrc_[i],
+                                            false);
   }
-  delete critical_section_cbs_;
   delete critical_section_rtp_receiver_;
 
   while (!payload_type_map_.empty()) {
@@ -187,18 +187,13 @@
       last_received_media_payload_type_ = -1;
     }
   }
-  CriticalSectionScoped lock(critical_section_cbs_);
-  if (packet_time_out && cb_rtp_feedback_) {
+  if (packet_time_out) {
     cb_rtp_feedback_->OnPacketTimeout(id_);
   }
 }
 
 void RTPReceiver::ProcessDeadOrAlive(const bool rtcp_alive,
                                      const WebRtc_Word64 now) {
-  if (cb_rtp_feedback_ == NULL) {
-    // No callback.
-    return;
-  }
   RTPAliveType alive = kRtpDead;
 
   if (last_receive_time_ + 1000 > now) {
@@ -214,10 +209,7 @@
     }
   }
 
-  CriticalSectionScoped lock(critical_section_cbs_);
-  if (cb_rtp_feedback_) {
-    cb_rtp_feedback_->OnPeriodicDeadOrAlive(id_, alive);
-  }
+  cb_rtp_feedback_->OnPeriodicDeadOrAlive(id_, alive);
 }
 
 WebRtc_UWord16 RTPReceiver::PacketOHReceived() const {
@@ -235,20 +227,6 @@
   return received_byte_count_;
 }
 
-WebRtc_Word32 RTPReceiver::RegisterIncomingRTPCallback(
-    RtpFeedback* incoming_messages_callback) {
-  CriticalSectionScoped lock(critical_section_cbs_);
-  cb_rtp_feedback_ = incoming_messages_callback;
-  return 0;
-}
-
-WebRtc_Word32 RTPReceiver::RegisterIncomingDataCallback(
-    RtpData* incoming_data_callback) {
-  CriticalSectionScoped lock(critical_section_cbs_);
-  cb_rtp_data_ = incoming_data_callback;
-  return 0;
-}
-
 WebRtc_Word32 RTPReceiver::RegisterReceivePayload(
     const char payload_name[RTP_PAYLOAD_NAME_SIZE],
     const WebRtc_Word8 payload_type,
@@ -610,14 +588,11 @@
   }
   if (last_receive_time_ == 0) {
     // Trigger only once.
-    CriticalSectionScoped lock(critical_section_cbs_);
-    if (cb_rtp_feedback_) {
-      if (length - rtp_header->header.headerLength == 0) {
-        // Keep-alive packet.
-        cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive);
-      } else {
-        cb_rtp_feedback_->OnReceivedPacket(id_, kPacketRtp);
-      }
+    if (length - rtp_header->header.headerLength == 0) {
+      // Keep-alive packet.
+      cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive);
+    } else {
+      cb_rtp_feedback_->OnReceivedPacket(id_, kPacketRtp);
     }
   }
   WebRtc_Word8 first_payload_byte = 0;
@@ -686,19 +661,6 @@
   return ret_val;
 }
 
-// Implementation note: must not hold critsect when called!
-WebRtc_Word32 RTPReceiver::CallbackOfReceivedPayloadData(
-    const WebRtc_UWord8* payload_data,
-    const WebRtc_UWord16 payload_size,
-    const WebRtcRTPHeader* rtp_header) {
-  CriticalSectionScoped lock(critical_section_cbs_);
-  if (cb_rtp_data_) {
-    return cb_rtp_data_->OnReceivedPayloadData(payload_data, payload_size,
-                                               rtp_header);
-  }
-  return -1;
-}
-
 // Implementation note: we expect to have the critical_section_rtp_receiver_
 // critsect when we call this.
 void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
@@ -989,21 +951,16 @@
     // We need to get this to our RTCP sender and receiver.
     // We need to do this outside critical section.
     rtp_rtcp_.SetRemoteSSRC(rtp_header->header.ssrc);
+    cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->header.ssrc);
   }
-  CriticalSectionScoped lock(critical_section_cbs_);
-  if (cb_rtp_feedback_) {
-    if (new_ssrc) {
-      cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->header.ssrc);
-    }
-    if (re_initialize_decoder) {
-      if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
-          id_, rtp_header->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->header.payloadType);
-      }
+  if (re_initialize_decoder) {
+    if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
+        id_, rtp_header->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->header.payloadType);
     }
   }
 }
@@ -1104,13 +1061,10 @@
   }   // End critsect.
 
   if (re_initialize_decoder) {
-    CriticalSectionScoped lock(critical_section_cbs_);
-    if (cb_rtp_feedback_) {
-      if (-1 == rtp_media_receiver_->InvokeOnInitializeDecoder(
-            cb_rtp_feedback_, id_, payload_type, payload_name,
-            *specific_payload)) {
-        return -1;  // Wrong payload type.
-      }
+    if (-1 == rtp_media_receiver_->InvokeOnInitializeDecoder(
+        cb_rtp_feedback_, id_, payload_type, payload_name,
+        *specific_payload)) {
+      return -1;  // Wrong payload type.
     }
   }
   return 0;
@@ -1159,10 +1113,6 @@
     }
   }  // End critsect.
 
-  CriticalSectionScoped lock(critical_section_cbs_);
-  if (cb_rtp_feedback_ == NULL) {
-    return;
-  }
   bool have_called_callback = false;
   // Search for new CSRC in old array.
   for (WebRtc_UWord8 i = 0; i < rtp_header->header.numCSRCs; ++i) {
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver.h
index 824b839..318b082 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver.h
@@ -32,11 +32,15 @@
 
 class RTPReceiver : public Bitrate {
  public:
+  // Callbacks passed in here may not be NULL (use Null object callbacks if you
+  // want callbacks to do nothing).
   RTPReceiver(const WebRtc_Word32 id,
               const bool audio,
               RtpRtcpClock* clock,
               ModuleRtpRtcpImpl* owner,
-              RtpAudioFeedback* incoming_messages_callback);
+              RtpAudioFeedback* incoming_audio_messages_callback,
+              RtpData* incoming_payload_callback,
+              RtpFeedback* incoming_messages_callback);
 
   virtual ~RTPReceiver();
 
@@ -50,10 +54,6 @@
 
   void ProcessBitrate();
 
-  WebRtc_Word32 RegisterIncomingDataCallback(RtpData* incoming_data_callback);
-  WebRtc_Word32 RegisterIncomingRTPCallback(
-      RtpFeedback* incoming_messages_callback);
-
   WebRtc_Word32 RegisterReceivePayload(
       const char payload_name[RTP_PAYLOAD_NAME_SIZE],
       const WebRtc_Word8 payload_type,
@@ -161,11 +161,6 @@
     return rtp_receiver_audio_;
   }
 
-  virtual WebRtc_Word32 CallbackOfReceivedPayloadData(
-      const WebRtc_UWord8* payload_data,
-      const WebRtc_UWord16 payload_size,
-      const WebRtcRTPHeader* rtp_header);
-
   virtual WebRtc_Word8 REDPayloadType() const;
 
   bool HaveNotReceivedPackets() const;
@@ -202,9 +197,7 @@
   WebRtc_Word32           id_;
   ModuleRtpRtcpImpl&      rtp_rtcp_;
 
-  CriticalSectionWrapper* critical_section_cbs_;
   RtpFeedback*            cb_rtp_feedback_;
-  RtpData*                cb_rtp_data_;
 
   CriticalSectionWrapper* critical_section_rtp_receiver_;
   mutable WebRtc_Word64   last_receive_time_;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc
index 5d7f334..71d8a2b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.cc
@@ -15,15 +15,14 @@
 #include <math.h>    // pow()
 
 #include "critical_section_wrapper.h"
-#include "rtp_receiver.h"
 #include "trace.h"
 
 namespace webrtc {
 RTPReceiverAudio::RTPReceiverAudio(const WebRtc_Word32 id,
-                                   RTPReceiver* parent,
+                                   RtpData* data_callback,
                                    RtpAudioFeedback* incomingMessagesCallback)
-  : _id(id),
-    _parent(parent),
+  : RTPReceiverStrategy(data_callback),
+    _id(id),
     _criticalSectionRtpReceiverAudio(
         CriticalSectionWrapper::CreateCriticalSection()),
     _lastReceivedFrequency(8000),
@@ -512,13 +511,13 @@
         rtpHeader->header.payloadType = payloadData[0];
 
         // only one frame in the RED strip the one byte to help NetEq
-        return _parent->CallbackOfReceivedPayloadData(payloadData+1,
-                                                      payloadLength-1,
-                                                      rtpHeader);
+        return data_callback_->OnReceivedPayloadData(payloadData+1,
+                                                     payloadLength-1,
+                                                     rtpHeader);
     }
 
     rtpHeader->type.Audio.channel = audioSpecific.channels;
-    return _parent->CallbackOfReceivedPayloadData(
+    return data_callback_->OnReceivedPayloadData(
         payloadData, payloadLength, rtpHeader);
 }
 } // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
index fbe9749..f4b2942 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h
@@ -22,14 +22,13 @@
 
 namespace webrtc {
 class CriticalSectionWrapper;
-class RTPReceiver;
 
 // Handles audio RTP packets. This class is thread-safe.
 class RTPReceiverAudio : public RTPReceiverStrategy
 {
 public:
     RTPReceiverAudio(const WebRtc_Word32 id,
-                     RTPReceiver* parent,
+                     RtpData* data_callback,
                      RtpAudioFeedback* incomingMessagesCallback);
 
     WebRtc_UWord32 AudioFrequency() const;
@@ -122,7 +121,6 @@
         const bool isRED);
 
     WebRtc_Word32                      _id;
-    RTPReceiver*                       _parent;
     scoped_ptr<CriticalSectionWrapper> _criticalSectionRtpReceiverAudio;
 
     WebRtc_UWord32                     _lastReceivedFrequency;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
index d073802..8831e12 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
@@ -14,7 +14,8 @@
 
 namespace webrtc {
 
-RTPReceiverStrategy::RTPReceiverStrategy() {
+RTPReceiverStrategy::RTPReceiverStrategy(RtpData* data_callback)
+    : data_callback_(data_callback) {
   memset(&last_payload_, 0, sizeof(last_payload_));
 }
 
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
index 297cd0f..fc553c0 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h
@@ -22,15 +22,22 @@
 // This class is not thread-safe and must be protected by its caller.
 class RTPReceiverStrategy {
  public:
-  RTPReceiverStrategy();
+  // 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);
   virtual ~RTPReceiverStrategy() {}
 
-  // Parses the RTP packet. Implementations should keep a reference to the
-  // calling RTPReceiver and call CallbackOfReceivedPayloadData if parsing
-  // succeeds.
-  // TODO(phoglund): This interaction is really ugly: clean up by removing
-  // the need of a back reference to parent, perhaps by returning something
-  // instead of calling back.
+  // Parses the RTP packet and calls the data callback with the payload data.
+  // Implementations are encouraged to use the provided packet buffer and RTP
+  // header as arguments to the callback; implementations are also allowed to
+  // make changes in the data as necessary. The specific_payload argument
+  // provides audio or video-specific data.
   virtual WebRtc_Word32 ParseRtpPacket(
     WebRtcRTPHeader* rtp_header,
     const ModuleRTPUtility::PayloadUnion& specific_payload,
@@ -108,6 +115,7 @@
 
  protected:
   ModuleRTPUtility::PayloadUnion last_payload_;
+  RtpData* data_callback_;
 };
 
 }  // namespace webrtc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
index 124e9fc..a3fafe5 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -29,8 +29,10 @@
 
 RTPReceiverVideo::RTPReceiverVideo(const WebRtc_Word32 id,
                                    RTPReceiver* parent,
+                                   RtpData* data_callback,
                                    ModuleRtpRtcpImpl* owner)
-    : _id(id),
+    : RTPReceiverStrategy(data_callback),
+      _id(id),
       _parent(parent),
       _criticalSectionReceiverVideo(
           CriticalSectionWrapper::CreateCriticalSection()),
@@ -176,8 +178,8 @@
       }
       // Pass the length of FEC packets so that they can be accounted for in
       // the bandwidth estimator.
-      retVal = _parent->CallbackOfReceivedPayloadData(NULL, payloadDataLength,
-                                                      rtpHeader);
+      retVal = data_callback_->OnReceivedPayloadData(NULL, payloadDataLength,
+                                                     rtpHeader);
     }
   } else {
     // will leave the _criticalSectionReceiverVideo critsect
@@ -336,7 +338,7 @@
     // we have an "empty" VP8 packet, it's ok, could be one way video
     // Inform the jitter buffer about this packet.
     rtpHeader->frameType = kFrameEmpty;
-    if (_parent->CallbackOfReceivedPayloadData(NULL, 0, rtpHeader) != 0) {
+    if (data_callback_->OnReceivedPayloadData(NULL, 0, rtpHeader) != 0) {
       return -1;
     }
     return 0;
@@ -369,9 +371,9 @@
   toHeader->partitionId = fromHeader->partitionID;
   toHeader->beginningOfPartition = fromHeader->beginningOfPartition;
 
-  if(_parent->CallbackOfReceivedPayloadData(parsedPacket.info.VP8.data,
-                                            parsedPacket.info.VP8.dataLength,
-                                            rtpHeader) != 0) {
+  if(data_callback_->OnReceivedPayloadData(parsedPacket.info.VP8.data,
+                                           parsedPacket.info.VP8.dataLength,
+                                           rtpHeader) != 0) {
     return -1;
   }
   return 0;
@@ -393,8 +395,8 @@
   }
   _criticalSectionReceiverVideo->Leave();
 
-  if (_parent->CallbackOfReceivedPayloadData(payloadData, payloadDataLength,
-                                             rtpHeader) != 0) {
+  if (data_callback_->OnReceivedPayloadData(payloadData, payloadDataLength,
+                                            rtpHeader) != 0) {
     return -1;
   }
   return 0;
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
index 248cb90..530c6b8 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h
@@ -12,7 +12,6 @@
 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_VIDEO_H_
 
 #include "bitrate.h"
-#include "rtp_receiver.h"
 #include "rtp_receiver_strategy.h"
 #include "rtp_rtcp_defines.h"
 #include "rtp_utility.h"
@@ -23,11 +22,14 @@
 class CriticalSectionWrapper;
 class ModuleRtpRtcpImpl;
 class ReceiverFEC;
+class RTPReceiver;
 
 class RTPReceiverVideo : public RTPReceiverStrategy {
  public:
+  // TODO(phoglund): Get rid of dependency on "parent".
   RTPReceiverVideo(const WebRtc_Word32 id,
                    RTPReceiver* parent,
+                   RtpData* data_callback,
                    ModuleRtpRtcpImpl* owner);
 
   virtual ~RTPReceiverVideo();
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 60ad98d..52600d9 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -41,6 +41,38 @@
 
 const WebRtc_UWord16 kDefaultRtt = 200;
 
+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()),
+      outgoing_transport(NULL),
+      rtcp_feedback(NULL),
+      intra_frame_callback(NULL),
+      bandwidth_callback(NULL),
+      rtt_observer(NULL),
+      audio_messages(NullObjectRtpAudioFeedback()),
+      remote_bitrate_estimator(NULL),
+      paced_sender(NULL) {
+}
+
 RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
   if (configuration.clock) {
     return new ModuleRtpRtcpImpl(configuration);
@@ -64,7 +96,9 @@
                  configuration.audio_messages,
                  configuration.paced_sender),
       _rtpReceiver(configuration.id, configuration.audio, configuration.clock,
-                   this, configuration.audio_messages),
+                   this, configuration.audio_messages,
+                   configuration.incoming_data,
+                   configuration.incoming_messages),
       _rtcpSender(configuration.id, configuration.audio, configuration.clock,
                   this),
       _rtcpReceiver(configuration.id, configuration.clock, this),
@@ -103,8 +137,6 @@
     _defaultModule->RegisterChildModule(this);
   }
   // TODO(pwestin) move to constructors of each rtp/rtcp sender/receiver object.
-  _rtpReceiver.RegisterIncomingDataCallback(configuration.incoming_data);
-  _rtpReceiver.RegisterIncomingRTPCallback(configuration.incoming_messages);
   _rtcpReceiver.RegisterRtcpObservers(configuration.intra_frame_callback,
                                       configuration.bandwidth_callback,
                                       configuration.rtcp_feedback);