Wire up currently-received video codec to stats.

BUG=webrtc:1844, webrtc:4808
R=mflodman@webrtc.org, pthatcher@webrtc.org

Review URL: https://codereview.webrtc.org/1315413002

Cr-Original-Commit-Position: refs/heads/master@{#9810}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: f42376c60111edba6f29060bf3dd79e75d8dbb97
diff --git a/modules/video_coding/main/interface/video_coding_defines.h b/modules/video_coding/main/interface/video_coding_defines.h
index ff844c6..fd38d64 100644
--- a/modules/video_coding/main/interface/video_coding_defines.h
+++ b/modules/video_coding/main/interface/video_coding_defines.h
@@ -76,7 +76,7 @@
     return -1;
   }
   // Called when the current receive codec changes.
-  virtual void IncomingCodecChanged(const VideoCodec& codec) {}
+  virtual void OnIncomingPayloadType(int payload_type) {}
 
  protected:
   virtual ~VCMReceiveCallback() {
diff --git a/modules/video_coding/main/source/codec_database.cc b/modules/video_coding/main/source/codec_database.cc
index 2e2d91e..c0ec2c8 100644
--- a/modules/video_coding/main/source/codec_database.cc
+++ b/modules/video_coding/main/source/codec_database.cc
@@ -581,7 +581,7 @@
     return NULL;
   }
   VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
-  if (callback) callback->IncomingCodecChanged(receive_codec_);
+  if (callback) callback->OnIncomingPayloadType(receive_codec_.plType);
   if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback)
       < 0) {
     ReleaseDecoder(ptr_decoder_);
diff --git a/video/end_to_end_tests.cc b/video/end_to_end_tests.cc
index 52bacc5..9f62ec8 100644
--- a/video/end_to_end_tests.cc
+++ b/video/end_to_end_tests.cc
@@ -2216,6 +2216,11 @@
             stats.rtcp_packet_type_counts.pli_packets != 0 ||
             stats.rtcp_packet_type_counts.nack_requests != 0 ||
             stats.rtcp_packet_type_counts.unique_nack_requests != 0;
+
+        assert(stats.current_payload_type == -1 ||
+               stats.current_payload_type == kFakeSendPayloadType);
+        receive_stats_filled_["IncomingPayloadType"] |=
+            stats.current_payload_type == kFakeSendPayloadType;
       }
 
       return AllStatsFilled(receive_stats_filled_);
diff --git a/video/receive_statistics_proxy.cc b/video/receive_statistics_proxy.cc
index 6604d3d..ec5aacb 100644
--- a/video/receive_statistics_proxy.cc
+++ b/video/receive_statistics_proxy.cc
@@ -59,21 +59,25 @@
   return stats_;
 }
 
-void ReceiveStatisticsProxy::IncomingRate(const int video_channel,
-                                          const unsigned int framerate,
-                                          const unsigned int bitrate_bps) {
+void ReceiveStatisticsProxy::OnIncomingPayloadType(int payload_type) {
+  rtc::CritScope lock(&crit_);
+  stats_.current_payload_type = payload_type;
+}
+
+void ReceiveStatisticsProxy::OnIncomingRate(unsigned int framerate,
+                                            unsigned int bitrate_bps) {
   rtc::CritScope lock(&crit_);
   stats_.network_frame_rate = framerate;
   stats_.total_bitrate_bps = bitrate_bps;
 }
 
-void ReceiveStatisticsProxy::DecoderTiming(int decode_ms,
-                                           int max_decode_ms,
-                                           int current_delay_ms,
-                                           int target_delay_ms,
-                                           int jitter_buffer_ms,
-                                           int min_playout_delay_ms,
-                                           int render_delay_ms) {
+void ReceiveStatisticsProxy::OnDecoderTiming(int decode_ms,
+                                             int max_decode_ms,
+                                             int current_delay_ms,
+                                             int target_delay_ms,
+                                             int jitter_buffer_ms,
+                                             int min_playout_delay_ms,
+                                             int render_delay_ms) {
   rtc::CritScope lock(&crit_);
   stats_.decode_ms = decode_ms;
   stats_.max_decode_ms = max_decode_ms;
diff --git a/video/receive_statistics_proxy.h b/video/receive_statistics_proxy.h
index 5042210..3041d31 100644
--- a/video/receive_statistics_proxy.h
+++ b/video/receive_statistics_proxy.h
@@ -31,8 +31,7 @@
 class ViECodec;
 class ViEDecoderObserver;
 
-class ReceiveStatisticsProxy : public ViEDecoderObserver,
-                               public VCMReceiveStatisticsCallback,
+class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback,
                                public RtcpStatisticsCallback,
                                public RtcpPacketTypeCounterObserver,
                                public StreamDataCountersCallback {
@@ -44,26 +43,21 @@
 
   void OnDecodedFrame();
   void OnRenderedFrame(int width, int height);
+  void OnIncomingPayloadType(int payload_type);
+  void OnIncomingRate(unsigned int framerate, unsigned int bitrate_bps);
+  void OnDecoderTiming(int decode_ms,
+                       int max_decode_ms,
+                       int current_delay_ms,
+                       int target_delay_ms,
+                       int jitter_buffer_ms,
+                       int min_playout_delay_ms,
+                       int render_delay_ms);
 
   // Overrides VCMReceiveStatisticsCallback.
   void OnReceiveRatesUpdated(uint32_t bitRate, uint32_t frameRate) override;
   void OnFrameCountsUpdated(const FrameCounts& frame_counts) override;
   void OnDiscardedPacketsUpdated(int discarded_packets) override;
 
-  // Overrides ViEDecoderObserver.
-  void IncomingCodecChanged(const int video_channel,
-                            const VideoCodec& video_codec) override {}
-  void IncomingRate(const int video_channel,
-                    const unsigned int framerate,
-                    const unsigned int bitrate_bps) override;
-  void DecoderTiming(int decode_ms,
-                     int max_decode_ms,
-                     int current_delay_ms,
-                     int target_delay_ms,
-                     int jitter_buffer_ms,
-                     int min_playout_delay_ms,
-                     int render_delay_ms) override;
-
   // Overrides RtcpStatisticsCallback.
   void StatisticsUpdated(const webrtc::RtcpStatistics& statistics,
                          uint32_t ssrc) override;
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index f3e2091..52e37b7 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -215,13 +215,11 @@
   stats_proxy_.reset(
       new ReceiveStatisticsProxy(config_.rtp.remote_ssrc, clock_));
 
+  vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get());
   vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(
       stats_proxy_.get());
   vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(stats_proxy_.get());
   vie_channel_->RegisterRtcpPacketTypeCounterObserver(stats_proxy_.get());
-  vie_channel_->RegisterCodecObserver(stats_proxy_.get());
-
-  vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get());
 
   DCHECK(!config_.decoders.empty());
   for (size_t i = 0; i < config_.decoders.size(); ++i) {
@@ -254,10 +252,6 @@
   for (size_t i = 0; i < config_.decoders.size(); ++i)
     vie_channel_->DeRegisterExternalDecoder(config_.decoders[i].payload_type);
 
-  vie_channel_->RegisterCodecObserver(nullptr);
-  vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(nullptr);
-  vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(nullptr);
-  vie_channel_->RegisterRtcpPacketTypeCounterObserver(nullptr);
   channel_group_->DeleteChannel(channel_id_);
 }
 
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index b8664ce..29b9efe 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -105,16 +105,14 @@
       vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this),
       vie_sync_(vcm_),
       stats_observer_(new ChannelStatsObserver(this)),
-      vcm_receive_stats_callback_(NULL),
+      receive_stats_callback_(nullptr),
       incoming_video_stream_(nullptr),
-      codec_observer_(NULL),
       intra_frame_observer_(intra_frame_observer),
       rtt_stats_(rtt_stats),
       paced_sender_(paced_sender),
       packet_router_(packet_router),
       bandwidth_observer_(bandwidth_observer),
       send_time_observer_(send_time_observer),
-      decoder_reset_(true),
       nack_history_size_sender_(kSendSidePacketHistorySize),
       max_nack_reordering_threshold_(kMaxPacketAgeToNack),
       pre_render_callback_(NULL),
@@ -437,20 +435,6 @@
   return 0;
 }
 
-int32_t ViEChannel::RegisterCodecObserver(ViEDecoderObserver* observer) {
-  CriticalSectionScoped cs(crit_.get());
-  if (observer) {
-    if (codec_observer_) {
-      LOG_F(LS_ERROR) << "Observer already registered.";
-      return -1;
-    }
-    codec_observer_ = observer;
-  } else {
-    codec_observer_ = NULL;
-  }
-  return 0;
-}
-
 int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type,
                                             VideoDecoder* decoder,
                                             bool buffered_rendering,
@@ -1042,18 +1026,6 @@
 int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) {  // NOLINT
   CriticalSectionScoped cs(crit_.get());
 
-  if (decoder_reset_) {
-    // Trigger a callback to the user if the incoming codec has changed.
-    if (codec_observer_) {
-      // The codec set by RegisterReceiveCodec might not be the size we're
-      // actually decoding.
-      receive_codec_.width = static_cast<uint16_t>(video_frame.width());
-      receive_codec_.height = static_cast<uint16_t>(video_frame.height());
-      codec_observer_->IncomingCodecChanged(channel_id_, receive_codec_);
-    }
-    decoder_reset_ = false;
-  }
-
   if (pre_render_callback_ != NULL)
     pre_render_callback_->FrameCallback(&video_frame);
 
@@ -1066,28 +1038,29 @@
   return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id);
 }
 
-void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) {
+void ViEChannel::OnIncomingPayloadType(int payload_type) {
   CriticalSectionScoped cs(crit_.get());
-  receive_codec_ = codec;
+  if (receive_stats_callback_)
+    receive_stats_callback_->OnIncomingPayloadType(payload_type);
 }
 
 void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) {
   CriticalSectionScoped cs(crit_.get());
-  if (codec_observer_)
-    codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate);
+  if (receive_stats_callback_)
+    receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
 }
 
 void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) {
   CriticalSectionScoped cs(crit_.get());
-  if (vcm_receive_stats_callback_ != NULL)
-    vcm_receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
+  if (receive_stats_callback_)
+    receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
 }
 
 void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
   CriticalSectionScoped cs(crit_.get());
   receive_frame_counts_ = frame_counts;
-  if (vcm_receive_stats_callback_ != NULL)
-    vcm_receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
+  if (receive_stats_callback_)
+    receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
 }
 
 void ViEChannel::OnDecoderTiming(int decode_ms,
@@ -1098,15 +1071,11 @@
                                  int min_playout_delay_ms,
                                  int render_delay_ms) {
   CriticalSectionScoped cs(crit_.get());
-  if (!codec_observer_)
+  if (!receive_stats_callback_)
     return;
-  codec_observer_->DecoderTiming(decode_ms,
-                                 max_decode_ms,
-                                 current_delay_ms,
-                                 target_delay_ms,
-                                 jitter_buffer_ms,
-                                 min_playout_delay_ms,
-                                 render_delay_ms);
+  receive_stats_callback_->OnDecoderTiming(
+      decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
+      jitter_buffer_ms, min_playout_delay_ms, render_delay_ms);
 }
 
 int32_t ViEChannel::RequestKeyFrame() {
@@ -1261,6 +1230,8 @@
   vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
 }
 
+// TODO(pbos): Remove OnInitializeDecoder which is called from the RTP module,
+// any decoder resetting should be handled internally within the VCM.
 int32_t ViEChannel::OnInitializeDecoder(
     const int32_t id,
     const int8_t payload_type,
@@ -1272,8 +1243,6 @@
                << " " << payload_name;
   vcm_->ResetDecoder();
 
-  CriticalSectionScoped cs(crit_.get());
-  decoder_reset_ = true;
   return 0;
 }
 
@@ -1297,7 +1266,7 @@
 void ViEChannel::RegisterReceiveStatisticsProxy(
     ReceiveStatisticsProxy* receive_statistics_proxy) {
   CriticalSectionScoped cs(crit_.get());
-  vcm_receive_stats_callback_ = receive_statistics_proxy;
+  receive_stats_callback_ = receive_statistics_proxy;
 }
 
 void ViEChannel::SetIncomingVideoStream(
diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h
index 85b18cf..b93dc04 100644
--- a/video_engine/vie_channel.h
+++ b/video_engine/vie_channel.h
@@ -44,7 +44,6 @@
 class RtcpRttStats;
 class ThreadWrapper;
 class ViEChannelProtectionCallback;
-class ViEDecoderObserver;
 class ViERTPObserver;
 class VideoCodingModule;
 class VideoDecoder;
@@ -56,36 +55,6 @@
   kViEStreamTypeRtx = 1      // Retransmission media stream
 };
 
-// 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 RegisterDecoderObserver()
-// and deregistered using DeregisterDecoderObserver().
-class ViEDecoderObserver {
- public:
-  // This method is called when a new incoming stream is detected, normally
-  // triggered by a new incoming SSRC or payload type.
-  virtual void IncomingCodecChanged(const int video_channel,
-                                    const VideoCodec& video_codec) = 0;
-
-  // This method is called once per second containing the frame rate and bit
-  // rate for the incoming stream
-  virtual void IncomingRate(const int video_channel,
-                            const unsigned int framerate,
-                            const unsigned int bitrate) = 0;
-
-  // Called periodically with decoder timing information.  All values are
-  // "current" snapshots unless decorated with a min_/max_ prefix.
-  virtual void DecoderTiming(int decode_ms,
-                             int max_decode_ms,
-                             int current_delay_ms,
-                             int target_delay_ms,
-                             int jitter_buffer_ms,
-                             int min_playout_delay_ms,
-                             int render_delay_ms) = 0;
-
- protected:
-  virtual ~ViEDecoderObserver() {}
-};
 class ViEChannel : public VCMFrameTypeCallback,
                    public VCMReceiveCallback,
                    public VCMReceiveStatisticsCallback,
@@ -118,7 +87,6 @@
   // type has changed and we should start a new RTP stream.
   int32_t SetSendCodec(const VideoCodec& video_codec, bool new_stream = true);
   int32_t SetReceiveCodec(const VideoCodec& video_codec);
-  int32_t RegisterCodecObserver(ViEDecoderObserver* observer);
   // Registers an external decoder. |buffered_rendering| means that the decoder
   // will render frames after decoding according to the render timestamp
   // provided by the video coding module. |render_delay| indicates the time
@@ -271,7 +239,7 @@
       const uint64_t picture_id);
 
   // Implements VCMReceiveCallback.
-  virtual void IncomingCodecChanged(const VideoCodec& codec);
+  void OnIncomingPayloadType(int payload_type) override;
 
   // Implements VCMReceiveStatisticsCallback.
   void OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) override;
@@ -464,11 +432,9 @@
   rtc::scoped_ptr<ChannelStatsObserver> stats_observer_;
 
   // Not owned.
-  VCMReceiveStatisticsCallback* vcm_receive_stats_callback_
-      GUARDED_BY(crit_);
+  ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
   FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
   IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
-  ViEDecoderObserver* codec_observer_ GUARDED_BY(crit_);
   RtcpIntraFrameObserver* const intra_frame_observer_;
   RtcpRttStats* const rtt_stats_;
   PacedSender* const paced_sender_;
@@ -477,9 +443,6 @@
   const rtc::scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
   SendTimeObserver* const send_time_observer_;
 
-  bool decoder_reset_ GUARDED_BY(crit_);
-  // Current receive codec used for codec change callback.
-  VideoCodec receive_codec_ GUARDED_BY(crit_);
   rtc::scoped_ptr<ThreadWrapper> decode_thread_;
 
   int nack_history_size_sender_;
diff --git a/video_receive_stream.h b/video_receive_stream.h
index e613006..955d875 100644
--- a/video_receive_stream.h
+++ b/video_receive_stream.h
@@ -75,6 +75,8 @@
     int min_playout_delay_ms = 0;
     int render_delay_ms = 10;
 
+    int current_payload_type = -1;
+
     int total_bitrate_bps = 0;
     int discarded_packets = 0;