Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / media / cast / video_receiver / video_receiver.cc
index 0ee93fd..8d68431 100644 (file)
@@ -9,22 +9,34 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/message_loop/message_loop.h"
-#include "crypto/encryptor.h"
-#include "crypto/symmetric_key.h"
 #include "media/cast/cast_defines.h"
 #include "media/cast/framer/framer.h"
+#include "media/cast/rtcp/receiver_rtcp_event_subscriber.h"
 #include "media/cast/rtcp/rtcp_sender.h"
 #include "media/cast/video_receiver/video_decoder.h"
 
-namespace media {
-namespace cast {
+namespace {
 
-const int64 kMinSchedulingDelayMs = 1;
+using media::cast::kMaxIpPacketSize;
+using media::cast::kRtcpCastLogHeaderSize;
+using media::cast::kRtcpReceiverEventLogSize;
+
+static const int64 kMinSchedulingDelayMs = 1;
 
 static const int64 kMinTimeBetweenOffsetUpdatesMs = 2000;
 static const int kTimeOffsetFilter = 8;
 static const int64_t kMinProcessIntervalMs = 5;
 
+// This is an upper bound on number of events that can fit into a single RTCP
+// packet.
+static const int64 kMaxEventSubscriberEntries =
+    (kMaxIpPacketSize - kRtcpCastLogHeaderSize) / kRtcpReceiverEventLogSize;
+
+}  // namespace
+
+namespace media {
+namespace cast {
+
 // Local implementation of RtpData (defined in rtp_rtcp_defines.h).
 // Used to pass payload data into the video receiver.
 class LocalRtpVideoData : public RtpData {
@@ -37,12 +49,14 @@ class LocalRtpVideoData : public RtpData {
   virtual void OnReceivedPayloadData(const uint8* payload_data,
                                      size_t payload_size,
                                      const RtpCastHeader* rtp_header) OVERRIDE {
-    video_receiver_->IncomingParsedRtpPacket(payload_data, payload_size,
-                                             *rtp_header);
+    video_receiver_->IncomingParsedRtpPacket(
+        payload_data, payload_size, *rtp_header);
   }
 
  private:
   VideoReceiver* video_receiver_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpVideoData);
 };
 
 // Local implementation of RtpPayloadFeedback (defined in rtp_defines.h)
@@ -51,8 +65,7 @@ class LocalRtpVideoData : public RtpData {
 class LocalRtpVideoFeedback : public RtpPayloadFeedback {
  public:
   explicit LocalRtpVideoFeedback(VideoReceiver* video_receiver)
-      : video_receiver_(video_receiver) {
-  }
+      : video_receiver_(video_receiver) {}
 
   virtual void CastFeedback(const RtcpCastMessage& cast_message) OVERRIDE {
     video_receiver_->CastFeedback(cast_message);
@@ -60,6 +73,8 @@ class LocalRtpVideoFeedback : public RtpPayloadFeedback {
 
  private:
   VideoReceiver* video_receiver_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpVideoFeedback);
 };
 
 // Local implementation of RtpReceiverStatistics (defined by rtcp.h).
@@ -67,84 +82,79 @@ class LocalRtpVideoFeedback : public RtpPayloadFeedback {
 class LocalRtpReceiverStatistics : public RtpReceiverStatistics {
  public:
   explicit LocalRtpReceiverStatistics(RtpReceiver* rtp_receiver)
-     : rtp_receiver_(rtp_receiver) {
-  }
+      : rtp_receiver_(rtp_receiver) {}
 
   virtual void GetStatistics(uint8* fraction_lost,
                              uint32* cumulative_lost,  // 24 bits valid.
                              uint32* extended_high_sequence_number,
                              uint32* jitter) OVERRIDE {
-    rtp_receiver_->GetStatistics(fraction_lost,
-                                 cumulative_lost,
-                                 extended_high_sequence_number,
-                                 jitter);
+    rtp_receiver_->GetStatistics(
+        fraction_lost, cumulative_lost, extended_high_sequence_number, jitter);
   }
 
  private:
   RtpReceiver* rtp_receiver_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpReceiverStatistics);
 };
 
-VideoReceiver::VideoReceiver(
-    scoped_refptr<CastEnvironment> cast_environment,
-    const VideoReceiverConfig& video_config,
-    transport::PacedPacketSender* const packet_sender)
-      : cast_environment_(cast_environment),
-        codec_(video_config.codec),
-        target_delay_delta_(
-            base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)),
-        frame_delay_(base::TimeDelta::FromMilliseconds(
-            1000 / video_config.max_frame_rate)),
-        incoming_payload_callback_(new LocalRtpVideoData(this)),
-        incoming_payload_feedback_(new LocalRtpVideoFeedback(this)),
-        rtp_receiver_(cast_environment_->Clock(), NULL, &video_config,
-                      incoming_payload_callback_.get()),
-        rtp_video_receiver_statistics_(
-            new LocalRtpReceiverStatistics(&rtp_receiver_)),
-        time_incoming_packet_updated_(false),
-        incoming_rtp_timestamp_(0),
-        weak_factory_(this) {
-  int max_unacked_frames = video_config.rtp_max_delay_ms *
-      video_config.max_frame_rate / 1000;
+VideoReceiver::VideoReceiver(scoped_refptr<CastEnvironment> cast_environment,
+                             const VideoReceiverConfig& video_config,
+                             transport::PacedPacketSender* const packet_sender)
+    : cast_environment_(cast_environment),
+      event_subscriber_(
+          kMaxEventSubscriberEntries,
+          ReceiverRtcpEventSubscriber::kVideoEventSubscriber),
+      codec_(video_config.codec),
+      target_delay_delta_(
+          base::TimeDelta::FromMilliseconds(video_config.rtp_max_delay_ms)),
+      frame_delay_(base::TimeDelta::FromMilliseconds(
+          1000 / video_config.max_frame_rate)),
+      incoming_payload_callback_(new LocalRtpVideoData(this)),
+      incoming_payload_feedback_(new LocalRtpVideoFeedback(this)),
+      rtp_receiver_(cast_environment_->Clock(),
+                    NULL,
+                    &video_config,
+                    incoming_payload_callback_.get()),
+      rtp_video_receiver_statistics_(
+          new LocalRtpReceiverStatistics(&rtp_receiver_)),
+      decryptor_(),
+      time_incoming_packet_updated_(false),
+      incoming_rtp_timestamp_(0),
+      weak_factory_(this) {
+  int max_unacked_frames =
+      video_config.rtp_max_delay_ms * video_config.max_frame_rate / 1000;
   DCHECK(max_unacked_frames) << "Invalid argument";
 
-  if (video_config.aes_iv_mask.size() == kAesKeySize &&
-      video_config.aes_key.size() == kAesKeySize) {
-    iv_mask_ = video_config.aes_iv_mask;
-    decryption_key_.reset(crypto::SymmetricKey::Import(
-        crypto::SymmetricKey::AES, video_config.aes_key));
-    decryptor_.reset(new crypto::Encryptor());
-    decryptor_->Init(decryption_key_.get(),
-                     crypto::Encryptor::CTR,
-                     std::string());
-  } else if (video_config.aes_iv_mask.size() != 0 ||
-             video_config.aes_key.size() != 0) {
-    DCHECK(false) << "Invalid crypto configuration";
-  }
-
+  decryptor_.Initialize(video_config.aes_key, video_config.aes_iv_mask);
   framer_.reset(new Framer(cast_environment->Clock(),
                            incoming_payload_feedback_.get(),
                            video_config.incoming_ssrc,
                            video_config.decoder_faster_than_max_frame_rate,
                            max_unacked_frames));
+
   if (!video_config.use_external_decoder) {
     video_decoder_.reset(new VideoDecoder(video_config, cast_environment));
   }
 
-  rtcp_.reset(new Rtcp(
-      cast_environment_,
-      NULL,
-      NULL,
-      packet_sender,
-      NULL,
-      rtp_video_receiver_statistics_.get(),
-      video_config.rtcp_mode,
-      base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
-      video_config.feedback_ssrc,
-      video_config.incoming_ssrc,
-      video_config.rtcp_c_name));
+  rtcp_.reset(
+      new Rtcp(cast_environment_,
+               NULL,
+               NULL,
+               packet_sender,
+               NULL,
+               rtp_video_receiver_statistics_.get(),
+               video_config.rtcp_mode,
+               base::TimeDelta::FromMilliseconds(video_config.rtcp_interval),
+               video_config.feedback_ssrc,
+               video_config.incoming_ssrc,
+               video_config.rtcp_c_name));
+  cast_environment_->Logging()->AddRawEventSubscriber(&event_subscriber_);
 }
 
-VideoReceiver::~VideoReceiver() {}
+VideoReceiver::~VideoReceiver() {
+  cast_environment_->Logging()->RemoveRawEventSubscriber(&event_subscriber_);
+}
 
 void VideoReceiver::InitializeTimers() {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
@@ -155,8 +165,8 @@ void VideoReceiver::InitializeTimers() {
 void VideoReceiver::GetRawVideoFrame(
     const VideoFrameDecodedCallback& callback) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-  GetEncodedVideoFrame(base::Bind(&VideoReceiver::DecodeVideoFrame,
-                                  base::Unretained(this), callback));
+  GetEncodedVideoFrame(base::Bind(
+      &VideoReceiver::DecodeVideoFrame, base::Unretained(this), callback));
 }
 
 // Called when we have a frame to decode.
@@ -166,9 +176,13 @@ void VideoReceiver::DecodeVideoFrame(
     const base::TimeTicks& render_time) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
   // Hand the ownership of the encoded frame to the decode thread.
-  cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER, FROM_HERE,
-      base::Bind(&VideoReceiver::DecodeVideoFrameThread, base::Unretained(this),
-                 base::Passed(&encoded_frame), render_time, callback));
+  cast_environment_->PostTask(CastEnvironment::VIDEO_DECODER,
+                              FROM_HERE,
+                              base::Bind(&VideoReceiver::DecodeVideoFrameThread,
+                                         base::Unretained(this),
+                                         base::Passed(&encoded_frame),
+                                         render_time,
+                                         callback));
 }
 
 // Utility function to run the decoder on a designated decoding thread.
@@ -179,28 +193,28 @@ void VideoReceiver::DecodeVideoFrameThread(
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::VIDEO_DECODER));
   DCHECK(video_decoder_);
 
-  if (!(video_decoder_->DecodeVideoFrame(encoded_frame.get(), render_time,
-        frame_decoded_callback))) {
+  if (!(video_decoder_->DecodeVideoFrame(
+           encoded_frame.get(), render_time, frame_decoded_callback))) {
     // This will happen if we decide to decode but not show a frame.
-    cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
-        base::Bind(&VideoReceiver::GetRawVideoFrame, base::Unretained(this),
-                   frame_decoded_callback));
+    cast_environment_->PostTask(CastEnvironment::MAIN,
+                                FROM_HERE,
+                                base::Bind(&VideoReceiver::GetRawVideoFrame,
+                                           base::Unretained(this),
+                                           frame_decoded_callback));
   }
 }
 
 bool VideoReceiver::DecryptVideoFrame(
     scoped_ptr<transport::EncodedVideoFrame>* video_frame) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-  DCHECK(decryptor_) << "Invalid state";
 
-  if (!decryptor_->SetCounter(GetAesNonce((*video_frame)->frame_id,
-                                          iv_mask_))) {
-    NOTREACHED() << "Failed to set counter";
+  if (!decryptor_.initialized())
     return false;
-  }
+
   std::string decrypted_video_data;
-  if (!decryptor_->Decrypt((*video_frame)->data, &decrypted_video_data)) {
-    VLOG(1) << "Decryption error";
+  if (!decryptor_.Decrypt((*video_frame)->frame_id,
+                          (*video_frame)->data,
+                          &decrypted_video_data)) {
     // Give up on this frame, release it from jitter buffer.
     framer_->ReleaseFrame((*video_frame)->frame_id);
     return false;
@@ -218,23 +232,23 @@ void VideoReceiver::GetEncodedVideoFrame(
   uint32 rtp_timestamp = 0;
   bool next_frame = false;
 
-  if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp,
-                                     &next_frame)) {
+  if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &next_frame)) {
     // We have no video frames. Wait for new packet(s).
     queued_encoded_callbacks_.push_back(callback);
     return;
   }
 
-  if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) {
+  if (decryptor_.initialized() && !DecryptVideoFrame(&encoded_frame)) {
     // Logging already done.
     queued_encoded_callbacks_.push_back(callback);
     return;
   }
 
   base::TimeTicks render_time;
-  if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
-                            &render_time)) {
-    cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
+  if (PullEncodedVideoFrame(next_frame, &encoded_frame, &render_time)) {
+    cast_environment_->PostTask(
+        CastEnvironment::MAIN,
+        FROM_HERE,
         base::Bind(callback, base::Passed(&encoded_frame), render_time));
   } else {
     // We have a video frame; however we are missing packets and we have time
@@ -248,16 +262,20 @@ void VideoReceiver::GetEncodedVideoFrame(
 // frame.
 // If the frame is too old to be rendered we set the don't show flag in the
 // video bitstream where possible.
-bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp,
-    bool next_frame, scoped_ptr<transport::EncodedVideoFrame>* encoded_frame,
+bool VideoReceiver::PullEncodedVideoFrame(
+    bool next_frame,
+    scoped_ptr<transport::EncodedVideoFrame>* encoded_frame,
     base::TimeTicks* render_time) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-  *render_time = GetRenderTime(now, rtp_timestamp);
+  *render_time = GetRenderTime(now, (*encoded_frame)->rtp_timestamp);
 
   // TODO(mikhal): Store actual render time and not diff.
-  cast_environment_->Logging()->InsertFrameEventWithDelay(now,
-      kVideoRenderDelay, rtp_timestamp, (*encoded_frame)->frame_id,
+  cast_environment_->Logging()->InsertFrameEventWithDelay(
+      now,
+      kVideoRenderDelay,
+      (*encoded_frame)->rtp_timestamp,
+      (*encoded_frame)->frame_id,
       now - *render_time);
 
   // Minimum time before a frame is due to be rendered before we pull it for
@@ -271,12 +289,14 @@ bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp,
     // will wait for 2 to arrive, however if 2 never show up this timer will hit
     // and we will pull out frame 3 for decoding and rendering.
     base::TimeDelta time_until_release = time_until_render - min_wait_delta;
-    cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
+    cast_environment_->PostDelayedTask(
+        CastEnvironment::MAIN,
+        FROM_HERE,
         base::Bind(&VideoReceiver::PlayoutTimeout, weak_factory_.GetWeakPtr()),
         time_until_release);
     VLOG(1) << "Wait before releasing frame "
-            << static_cast<int>((*encoded_frame)->frame_id)
-            << " time " << time_until_release.InMilliseconds();
+            << static_cast<int>((*encoded_frame)->frame_id) << " time "
+            << time_until_release.InMilliseconds();
     return false;
   }
 
@@ -289,8 +309,7 @@ bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp,
             << static_cast<int>((*encoded_frame)->frame_id)
             << " time_until_render:" << time_until_render.InMilliseconds();
   } else {
-    VLOG(1) << "Show frame "
-            << static_cast<int>((*encoded_frame)->frame_id)
+    VLOG(1) << "Show frame " << static_cast<int>((*encoded_frame)->frame_id)
             << " time_until_render:" << time_until_render.InMilliseconds();
   }
   // We have a copy of the frame, release this one.
@@ -301,15 +320,14 @@ bool VideoReceiver::PullEncodedVideoFrame(uint32 rtp_timestamp,
 
 void VideoReceiver::PlayoutTimeout() {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-  if (queued_encoded_callbacks_.empty()) return;
+  if (queued_encoded_callbacks_.empty())
+    return;
 
-  uint32 rtp_timestamp = 0;
   bool next_frame = false;
   scoped_ptr<transport::EncodedVideoFrame> encoded_frame(
       new transport::EncodedVideoFrame());
 
-  if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &rtp_timestamp,
-                                     &next_frame)) {
+  if (!framer_->GetEncodedVideoFrame(encoded_frame.get(), &next_frame)) {
     // We have no video frames. Wait for new packet(s).
     // Since the application can post multiple VideoFrameEncodedCallback and
     // we only check the next frame to play out we might have multiple timeout
@@ -320,24 +338,24 @@ void VideoReceiver::PlayoutTimeout() {
   VLOG(1) << "PlayoutTimeout retrieved frame "
           << static_cast<int>(encoded_frame->frame_id);
 
-  if (decryptor_ && !DecryptVideoFrame(&encoded_frame)) {
+  if (decryptor_.initialized() && !DecryptVideoFrame(&encoded_frame)) {
     // Logging already done.
     return;
   }
 
   base::TimeTicks render_time;
-  if (PullEncodedVideoFrame(rtp_timestamp, next_frame, &encoded_frame,
-                            &render_time)) {
+  if (PullEncodedVideoFrame(next_frame, &encoded_frame, &render_time)) {
     if (!queued_encoded_callbacks_.empty()) {
       VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front();
       queued_encoded_callbacks_.pop_front();
-      cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
+      cast_environment_->PostTask(
+          CastEnvironment::MAIN,
+          FROM_HERE,
           base::Bind(callback, base::Passed(&encoded_frame), render_time));
     }
-  } else {
-    // We have a video frame; however we are missing packets and we have time
-    // to wait for new packet(s).
   }
+  // Else we have a video frame; however we are missing packets and we have time
+  // to wait for new packet(s).
 }
 
 base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now,
@@ -347,6 +365,7 @@ base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now,
   // Note: the senders clock and our local clock might not be synced.
   base::TimeTicks rtp_timestamp_in_ticks;
 
+  // Compute the time offset_in_ticks based on the incoming_rtp_timestamp_.
   if (time_offset_.InMilliseconds() == 0) {
     if (!rtcp_->RtpTimestampInSenderTime(kVideoFrequency,
                                          incoming_rtp_timestamp_,
@@ -363,15 +382,15 @@ base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now,
       // Time to update the time_offset.
       base::TimeDelta time_offset =
           time_incoming_packet_ - rtp_timestamp_in_ticks;
-      time_offset_ = ((kTimeOffsetFilter - 1) * time_offset_ + time_offset)
-          / kTimeOffsetFilter;
+      time_offset_ = ((kTimeOffsetFilter - 1) * time_offset_ + time_offset) /
+                     kTimeOffsetFilter;
     }
   }
   // Reset |time_incoming_packet_updated_| to enable a future measurement.
   time_incoming_packet_updated_ = false;
-  if (!rtcp_->RtpTimestampInSenderTime(kVideoFrequency,
-                                       rtp_timestamp,
-                                       &rtp_timestamp_in_ticks)) {
+  // Compute the actual rtp_timestamp_in_ticks based on the current timestamp.
+  if (!rtcp_->RtpTimestampInSenderTime(
+           kVideoFrequency, rtp_timestamp, &rtp_timestamp_in_ticks)) {
     // This can fail if we have not received any RTCP packets in a long time.
     return now;
   }
@@ -383,15 +402,13 @@ base::TimeTicks VideoReceiver::GetRenderTime(base::TimeTicks now,
   return render_time;
 }
 
-void VideoReceiver::IncomingPacket(const uint8* packet, size_t length,
-                                   const base::Closure callback) {
+void VideoReceiver::IncomingPacket(scoped_ptr<Packet> packet) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
-  if (Rtcp::IsRtcpPacket(packet, length)) {
-    rtcp_->IncomingRtcpPacket(packet, length);
+  if (Rtcp::IsRtcpPacket(&packet->front(), packet->size())) {
+    rtcp_->IncomingRtcpPacket(&packet->front(), packet->size());
   } else {
-    rtp_receiver_.ReceivedPacket(packet, length);
+    rtp_receiver_.ReceivedPacket(&packet->front(), packet->size());
   }
-  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE, callback);
 }
 
 void VideoReceiver::IncomingParsedRtpPacket(const uint8* payload_data,
@@ -400,38 +417,53 @@ void VideoReceiver::IncomingParsedRtpPacket(const uint8* payload_data,
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
 
   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-  if (time_incoming_packet_.is_null() || now - time_incoming_packet_ >
-      base::TimeDelta::FromMilliseconds(kMinTimeBetweenOffsetUpdatesMs)) {
-    if (time_incoming_packet_.is_null()) InitializeTimers();
+  if (time_incoming_packet_.is_null() ||
+      now - time_incoming_packet_ >
+          base::TimeDelta::FromMilliseconds(kMinTimeBetweenOffsetUpdatesMs)) {
+    if (time_incoming_packet_.is_null())
+      InitializeTimers();
     incoming_rtp_timestamp_ = rtp_header.webrtc.header.timestamp;
     time_incoming_packet_ = now;
     time_incoming_packet_updated_ = true;
   }
 
-  cast_environment_->Logging()->InsertPacketEvent(now, kVideoPacketReceived,
-      rtp_header.webrtc.header.timestamp, rtp_header.frame_id,
-      rtp_header.packet_id, rtp_header.max_packet_id, payload_size);
+  cast_environment_->Logging()->InsertPacketEvent(
+      now,
+      kVideoPacketReceived,
+      rtp_header.webrtc.header.timestamp,
+      rtp_header.frame_id,
+      rtp_header.packet_id,
+      rtp_header.max_packet_id,
+      payload_size);
 
   bool duplicate = false;
-  bool complete = framer_->InsertPacket(payload_data, payload_size, rtp_header,
-                                        &duplicate);
+  bool complete =
+      framer_->InsertPacket(payload_data, payload_size, rtp_header, &duplicate);
 
   if (duplicate) {
-    cast_environment_->Logging()->InsertPacketEvent(now,
-        kDuplicatePacketReceived,
-        rtp_header.webrtc.header.timestamp, rtp_header.frame_id,
-        rtp_header.packet_id, rtp_header.max_packet_id, payload_size);
+    cast_environment_->Logging()->InsertPacketEvent(
+        now,
+        kDuplicateVideoPacketReceived,
+        rtp_header.webrtc.header.timestamp,
+        rtp_header.frame_id,
+        rtp_header.packet_id,
+        rtp_header.max_packet_id,
+        payload_size);
     // Duplicate packets are ignored.
     return;
   }
-  if (!complete) return;  // Video frame not complete; wait for more packets.
-  if (queued_encoded_callbacks_.empty()) return;  // No pending callback.
+  if (!complete)
+    return;  // Video frame not complete; wait for more packets.
+  if (queued_encoded_callbacks_.empty())
+    return;  // No pending callback.
 
   VideoFrameEncodedCallback callback = queued_encoded_callbacks_.front();
   queued_encoded_callbacks_.pop_front();
-  cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
-      base::Bind(&VideoReceiver::GetEncodedVideoFrame,
-          weak_factory_.GetWeakPtr(), callback));
+  cast_environment_->PostTask(CastEnvironment::MAIN,
+                              FROM_HERE,
+                              base::Bind(&VideoReceiver::GetEncodedVideoFrame,
+                                         weak_factory_.GetWeakPtr(),
+                                         callback));
 }
 
 // Send a cast feedback message. Actual message created in the framer (cast
@@ -439,39 +471,11 @@ void VideoReceiver::IncomingParsedRtpPacket(const uint8* payload_data,
 void VideoReceiver::CastFeedback(const RtcpCastMessage& cast_message) {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
 
-  RtcpReceiverLogMessage receiver_log;
-  VideoRtcpRawMap video_logs =
-      cast_environment_->Logging()->GetVideoRtcpRawData();
-
-  while (!video_logs.empty()) {
-    // TODO(hclam): Avoid calling begin() within a loop.
-    VideoRtcpRawMap::iterator it = video_logs.begin();
-    uint32 rtp_timestamp = it->first;
-    std::pair<VideoRtcpRawMap::iterator, VideoRtcpRawMap::iterator>
-        frame_range = video_logs.equal_range(rtp_timestamp);
-
-    RtcpReceiverFrameLogMessage frame_log(rtp_timestamp);
-
-    VideoRtcpRawMap::const_iterator event_it = frame_range.first;
-    for (; event_it != frame_range.second; ++event_it) {
-      if (!RtcpSender::IsReceiverEvent(event_it->second.type))
-        continue;
-      RtcpReceiverEventLogMessage event_log_message;
-      event_log_message.type = event_it->second.type;
-      event_log_message.event_timestamp = event_it->second.timestamp;
-      event_log_message.delay_delta = event_it->second.delay_delta;
-      event_log_message.packet_id = event_it->second.packet_id;
-      frame_log.event_log_messages_.push_back(event_log_message);
-    }
-    receiver_log.push_back(frame_log);
-    video_logs.erase(rtp_timestamp);
-  }
   base::TimeTicks now = cast_environment_->Clock()->NowTicks();
-  cast_environment_->Logging()->InsertGenericEvent(now, kVideoAckSent,
-      cast_message.ack_frame_id_);
+  cast_environment_->Logging()->InsertGenericEvent(
+      now, kVideoAckSent, cast_message.ack_frame_id_);
 
-  rtcp_->SendRtcpFromRtpReceiver(&cast_message, &receiver_log);
-  time_last_sent_cast_message_= now;
+  rtcp_->SendRtcpFromRtpReceiver(&cast_message, &event_subscriber_);
 }
 
 // Cast messages should be sent within a maximum interval. Schedule a call
@@ -481,13 +485,16 @@ void VideoReceiver::ScheduleNextCastMessage() {
   base::TimeTicks send_time;
   framer_->TimeToSendNextCastMessage(&send_time);
 
-  base::TimeDelta time_to_send = send_time -
-      cast_environment_->Clock()->NowTicks();
-  time_to_send = std::max(time_to_send,
-      base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
-  cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
+  base::TimeDelta time_to_send =
+      send_time - cast_environment_->Clock()->NowTicks();
+  time_to_send = std::max(
+      time_to_send, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
+  cast_environment_->PostDelayedTask(
+      CastEnvironment::MAIN,
+      FROM_HERE,
       base::Bind(&VideoReceiver::SendNextCastMessage,
-                 weak_factory_.GetWeakPtr()), time_to_send);
+                 weak_factory_.GetWeakPtr()),
+      time_to_send);
 }
 
 void VideoReceiver::SendNextCastMessage() {
@@ -500,14 +507,17 @@ void VideoReceiver::SendNextCastMessage() {
 void VideoReceiver::ScheduleNextRtcpReport() {
   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
   base::TimeDelta time_to_next = rtcp_->TimeToSendNextRtcpReport() -
-      cast_environment_->Clock()->NowTicks();
+                                 cast_environment_->Clock()->NowTicks();
 
-  time_to_next = std::max(time_to_next,
-      base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
+  time_to_next = std::max(
+      time_to_next, base::TimeDelta::FromMilliseconds(kMinSchedulingDelayMs));
 
-  cast_environment_->PostDelayedTask(CastEnvironment::MAIN, FROM_HERE,
+  cast_environment_->PostDelayedTask(
+      CastEnvironment::MAIN,
+      FROM_HERE,
       base::Bind(&VideoReceiver::SendNextRtcpReport,
-                weak_factory_.GetWeakPtr()), time_to_next);
+                 weak_factory_.GetWeakPtr()),
+      time_to_next);
 }
 
 void VideoReceiver::SendNextRtcpReport() {