Hooked up RtcEventLog. It lives in Voice Engine and pointers are propagated to ACM and Call.

An option was added to voe_cmd_test to make a RtcEventLog dump.

BUG=webrtc:4741

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

Cr-Commit-Position: refs/heads/master@{#9901}
diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h
index cea9e40..d0cff57 100644
--- a/talk/media/webrtc/fakewebrtcvoiceengine.h
+++ b/talk/media/webrtc/fakewebrtcvoiceengine.h
@@ -536,6 +536,7 @@
     channels_[channel]->associate_send_channel = accociate_send_channel;
     return 0;
   }
+  webrtc::RtcEventLog* GetEventLog() { return nullptr; }
 
   // webrtc::VoECodec
   WEBRTC_FUNC(NumOfCodecs, ()) {
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn
index 00e3aa7..235eb3c 100644
--- a/webrtc/modules/audio_coding/BUILD.gn
+++ b/webrtc/modules/audio_coding/BUILD.gn
@@ -58,6 +58,12 @@
     ]
   }
 
+  if (is_clang) {
+    # Suppress warnings from Chrome's Clang plugins.
+    # See http://code.google.com/p/webrtc/issues/detail?id=163 for details.
+    configs -= [ "//build/config/clang:find_bad_constructs" ]
+  }
+
   deps = [
     ":cng",
     ":g711",
@@ -68,6 +74,7 @@
     ":neteq",
     ":pcm16b",
     ":red",
+    "../..:rtc_event_log",
     "../..:webrtc_common",
     "../../common_audio",
     "../../system_wrappers",
diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
index 2a81e46..571a509 100644
--- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
+++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc
@@ -27,6 +27,7 @@
 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
 #include "webrtc/system_wrappers/interface/trace.h"
 #include "webrtc/typedefs.h"
+#include "webrtc/video/rtc_event_log.h"
 
 namespace webrtc {
 
@@ -146,7 +147,8 @@
       first_frame_(true),
       callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
       packetization_callback_(NULL),
-      vad_callback_(NULL) {
+      vad_callback_(NULL),
+      event_log_(config.event_log) {
   if (InitializeReceiverSafe() < 0) {
     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
                  "Cannot initialize receiver");
@@ -680,6 +682,10 @@
                  "PlayoutData failed, RecOut Failed");
     return -1;
   }
+  {
+    if (event_log_)
+      event_log_->LogDebugEvent(RtcEventLog::DebugEvent::kAudioPlayout);
+  }
 
   audio_frame->id_ = id_;
   return 0;
diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h
index db3e927..568bf92 100644
--- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h
+++ b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h
@@ -299,6 +299,8 @@
   AudioPacketizationCallback* packetization_callback_
       GUARDED_BY(callback_crit_sect_);
   ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_);
+
+  RtcEventLog* const event_log_;
 };
 
 }  // namespace acm2
diff --git a/webrtc/modules/audio_coding/main/audio_coding_module.gypi b/webrtc/modules/audio_coding/main/audio_coding_module.gypi
index 43d99f8..ce86335 100644
--- a/webrtc/modules/audio_coding/main/audio_coding_module.gypi
+++ b/webrtc/modules/audio_coding/main/audio_coding_module.gypi
@@ -39,6 +39,7 @@
       'dependencies': [
         '<@(audio_coding_dependencies)',
         '<(webrtc_root)/common.gyp:webrtc_common',
+        '<(webrtc_root)/webrtc.gyp:rtc_event_log',
         'neteq',
       ],
       'include_dirs': [
diff --git a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
index f2972e7..085dd61 100644
--- a/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
+++ b/webrtc/modules/audio_coding/main/interface/audio_coding_module.h
@@ -26,10 +26,11 @@
 // forward declarations
 struct CodecInst;
 struct WebRtcRTPHeader;
-class AudioFrame;
-class RTPFragmentationHeader;
-class AudioEncoder;
 class AudioDecoder;
+class AudioEncoder;
+class AudioFrame;
+class RtcEventLog;
+class RTPFragmentationHeader;
 
 #define WEBRTC_10MS_PCM_AUDIO 960  // 16 bits super wideband 48 kHz
 
@@ -85,11 +86,13 @@
     Config()
         : id(0),
           neteq_config(),
-          clock(Clock::GetRealTimeClock()) {}
+          clock(Clock::GetRealTimeClock()),
+          event_log(nullptr) {}
 
     int id;
     NetEq::Config neteq_config;
     Clock* clock;
+    RtcEventLog* event_log;
   };
 
   ///////////////////////////////////////////////////////////////////////////
diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc
index f3a5db4..2df8fe0 100644
--- a/webrtc/video/call.cc
+++ b/webrtc/video/call.cc
@@ -32,8 +32,10 @@
 #include "webrtc/system_wrappers/interface/trace.h"
 #include "webrtc/system_wrappers/interface/trace_event.h"
 #include "webrtc/video/audio_receive_stream.h"
+#include "webrtc/video/rtc_event_log.h"
 #include "webrtc/video/video_receive_stream.h"
 #include "webrtc/video/video_send_stream.h"
+#include "webrtc/voice_engine/include/voe_codec.h"
 
 namespace webrtc {
 
@@ -120,6 +122,8 @@
 
   VideoSendStream::RtpStateMap suspended_video_send_ssrcs_;
 
+  RtcEventLog* event_log_;
+
   DISALLOW_COPY_AND_ASSIGN(Call);
 };
 }  // namespace internal
@@ -138,7 +142,8 @@
       config_(config),
       network_enabled_(true),
       receive_crit_(RWLockWrapper::CreateRWLock()),
-      send_crit_(RWLockWrapper::CreateRWLock()) {
+      send_crit_(RWLockWrapper::CreateRWLock()),
+      event_log_(nullptr) {
   DCHECK_GE(config.bitrate_config.min_bitrate_bps, 0);
   DCHECK_GE(config.bitrate_config.start_bitrate_bps,
             config.bitrate_config.min_bitrate_bps);
@@ -146,6 +151,13 @@
     DCHECK_GE(config.bitrate_config.max_bitrate_bps,
               config.bitrate_config.start_bitrate_bps);
   }
+  if (config.voice_engine) {
+    VoECodec* voe_codec = VoECodec::GetInterface(config.voice_engine);
+    if (voe_codec) {
+      event_log_ = voe_codec->GetEventLog();
+      voe_codec->Release();
+    }
+  }
 
   Trace::CreateTrace();
   module_process_thread_->Start();
@@ -236,6 +248,9 @@
   }
   video_send_streams_.insert(send_stream);
 
+  if (event_log_)
+    event_log_->LogVideoSendStreamConfig(config);
+
   if (!network_enabled_)
     send_stream->SignalNetworkState(kNetworkDown);
   return send_stream;
@@ -302,6 +317,9 @@
   if (!network_enabled_)
     receive_stream->SignalNetworkState(kNetworkDown);
 
+  if (event_log_)
+    event_log_->LogVideoReceiveStreamConfig(config);
+
   return receive_stream;
 }
 
@@ -463,15 +481,21 @@
   if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
     ReadLockScoped read_lock(*receive_crit_);
     for (VideoReceiveStream* stream : video_receive_streams_) {
-      if (stream->DeliverRtcp(packet, length))
+      if (stream->DeliverRtcp(packet, length)) {
         rtcp_delivered = true;
+        if (event_log_)
+          event_log_->LogRtcpPacket(true, media_type, packet, length);
+      }
     }
   }
   if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
     ReadLockScoped read_lock(*send_crit_);
     for (VideoSendStream* stream : video_send_streams_) {
-      if (stream->DeliverRtcp(packet, length))
+      if (stream->DeliverRtcp(packet, length)) {
         rtcp_delivered = true;
+        if (event_log_)
+          event_log_->LogRtcpPacket(false, media_type, packet, length);
+      }
     }
   }
   return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR;
@@ -491,17 +515,23 @@
   if (media_type == MediaType::ANY || media_type == MediaType::AUDIO) {
     auto it = audio_receive_ssrcs_.find(ssrc);
     if (it != audio_receive_ssrcs_.end()) {
-      return it->second->DeliverRtp(packet, length, packet_time)
-                 ? DELIVERY_OK
-                 : DELIVERY_PACKET_ERROR;
+      auto status = it->second->DeliverRtp(packet, length, packet_time)
+                        ? DELIVERY_OK
+                        : DELIVERY_PACKET_ERROR;
+      if (status == DELIVERY_OK && event_log_)
+        event_log_->LogRtpHeader(true, media_type, packet, length);
+      return status;
     }
   }
   if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
     auto it = video_receive_ssrcs_.find(ssrc);
     if (it != video_receive_ssrcs_.end()) {
-      return it->second->DeliverRtp(packet, length, packet_time)
-                 ? DELIVERY_OK
-                 : DELIVERY_PACKET_ERROR;
+      auto status = it->second->DeliverRtp(packet, length, packet_time)
+                        ? DELIVERY_OK
+                        : DELIVERY_PACKET_ERROR;
+      if (status == DELIVERY_OK && event_log_)
+        event_log_->LogRtpHeader(true, media_type, packet, length);
+      return status;
     }
   }
   return DELIVERY_UNKNOWN_SSRC;
diff --git a/webrtc/video/webrtc_video.gypi b/webrtc/video/webrtc_video.gypi
index 59b2e73..03dc0ff 100644
--- a/webrtc/video/webrtc_video.gypi
+++ b/webrtc/video/webrtc_video.gypi
@@ -20,6 +20,7 @@
       '<(webrtc_root)/modules/modules.gyp:webrtc_video_coding',
       '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
       '<(webrtc_root)/voice_engine/voice_engine.gyp:voice_engine',
+      '<(webrtc_root)/webrtc.gyp:rtc_event_log',
     ],
     'webrtc_video_sources': [
       'video/audio_receive_stream.cc',
diff --git a/webrtc/voice_engine/BUILD.gn b/webrtc/voice_engine/BUILD.gn
index 62386f5..efe4781 100644
--- a/webrtc/voice_engine/BUILD.gn
+++ b/webrtc/voice_engine/BUILD.gn
@@ -95,6 +95,7 @@
   }
 
   deps = [
+    "..:rtc_event_log",
     "..:webrtc_common",
     "../common_audio",
     "../modules/audio_coding",
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 06812dd..d602bb4 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -628,17 +628,16 @@
     return(highestNeeded);
 }
 
-int32_t
-Channel::CreateChannel(Channel*& channel,
-                       int32_t channelId,
-                       uint32_t instanceId,
-                       const Config& config)
-{
+int32_t Channel::CreateChannel(Channel*& channel,
+                               int32_t channelId,
+                               uint32_t instanceId,
+                               RtcEventLog* const event_log,
+                               const Config& config) {
     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(instanceId,channelId),
                  "Channel::CreateChannel(channelId=%d, instanceId=%d)",
         channelId, instanceId);
 
-    channel = new Channel(channelId, instanceId, config);
+    channel = new Channel(channelId, instanceId, event_log, config);
     if (channel == NULL)
     {
         WEBRTC_TRACE(kTraceMemory, kTraceVoice,
@@ -713,8 +712,9 @@
 
 Channel::Channel(int32_t channelId,
                  uint32_t instanceId,
-                 const Config& config) :
-    _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
+                 RtcEventLog* const event_log,
+                 const Config& config)
+  : _fileCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
     _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
     volume_settings_critsect_(*CriticalSectionWrapper::CreateCriticalSection()),
     _instanceId(instanceId),
@@ -722,11 +722,15 @@
     rtp_header_parser_(RtpHeaderParser::Create()),
     rtp_payload_registry_(
         new RTPPayloadRegistry(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())),
+    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()),
     _outputAudioLevel(),
     _externalTransport(false),
@@ -744,7 +748,8 @@
     _outputExternalMedia(false),
     _inputExternalMediaCallbackPtr(NULL),
     _outputExternalMediaCallbackPtr(NULL),
-    _timeStamp(0), // This is just an offset, RTP module will add it's own random offset
+    _timeStamp(0),  // This is just an offset, RTP module will add it's own
+                    // random offset
     _sendTelephoneEventPayloadType(106),
     ntp_estimator_(Clock::GetRealTimeClock()),
     jitter_buffer_playout_timestamp_(0),
@@ -791,8 +796,7 @@
     rtcp_observer_(new VoERtcpObserver(this)),
     network_predictor_(new NetworkPredictor(Clock::GetRealTimeClock())),
     assoc_send_channel_lock_(CriticalSectionWrapper::CreateCriticalSection()),
-    associate_send_channel_(ChannelOwner(nullptr))
-{
+    associate_send_channel_(ChannelOwner(nullptr)) {
     WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_instanceId,_channelId),
                  "Channel::Channel() - ctor");
     AudioCodingModule::Config acm_config;
@@ -805,6 +809,7 @@
     }
     acm_config.neteq_config.enable_fast_accelerate =
         config.Get<NetEqFastAccelerate>().enabled;
+    acm_config.event_log = event_log;
     audio_coding_.reset(AudioCodingModule::Create(acm_config));
 
     _inbandDtmfQueue.ResetDtmf();
diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h
index 5ecd3a6..56f6ce4 100644
--- a/webrtc/voice_engine/channel.h
+++ b/webrtc/voice_engine/channel.h
@@ -51,6 +51,7 @@
 class ProcessThread;
 class ReceiveStatistics;
 class RemoteNtpTimeEstimator;
+class RtcEventLog;
 class RTPPayloadRegistry;
 class RtpReceiver;
 class RTPReceiverAudio;
@@ -170,8 +171,12 @@
     static int32_t CreateChannel(Channel*& channel,
                                  int32_t channelId,
                                  uint32_t instanceId,
+                                 RtcEventLog* const event_log,
                                  const Config& config);
-    Channel(int32_t channelId, uint32_t instanceId, const Config& config);
+    Channel(int32_t channelId,
+            uint32_t instanceId,
+            RtcEventLog* const event_log,
+            const Config& config);
     int32_t Init();
     int32_t SetEngineInformation(
         Statistics& engineStatistics,
diff --git a/webrtc/voice_engine/channel_manager.cc b/webrtc/voice_engine/channel_manager.cc
index 76664d4..8452c8b 100644
--- a/webrtc/voice_engine/channel_manager.cc
+++ b/webrtc/voice_engine/channel_manager.cc
@@ -49,7 +49,8 @@
     : instance_id_(instance_id),
       last_channel_id_(-1),
       lock_(CriticalSectionWrapper::CreateCriticalSection()),
-      config_(config) {}
+      config_(config),
+      event_log_(RtcEventLog::Create()) {}
 
 ChannelOwner ChannelManager::CreateChannel() {
   return CreateChannelInternal(config_);
@@ -61,7 +62,8 @@
 
 ChannelOwner ChannelManager::CreateChannelInternal(const Config& config) {
   Channel* channel;
-  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_, config);
+  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_,
+                         event_log_.get(), config);
   ChannelOwner channel_owner(channel);
 
   CriticalSectionScoped crit(lock_.get());
@@ -128,6 +130,10 @@
   return channels_.size();
 }
 
+RtcEventLog* ChannelManager::GetEventLog() const {
+  return event_log_.get();
+}
+
 ChannelManager::Iterator::Iterator(ChannelManager* channel_manager)
     : iterator_pos_(0) {
   channel_manager->GetAllChannels(&channels_);
diff --git a/webrtc/voice_engine/channel_manager.h b/webrtc/voice_engine/channel_manager.h
index 07cebb0..4aeb422 100644
--- a/webrtc/voice_engine/channel_manager.h
+++ b/webrtc/voice_engine/channel_manager.h
@@ -18,6 +18,7 @@
 #include "webrtc/system_wrappers/interface/atomic32.h"
 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
 #include "webrtc/typedefs.h"
+#include "webrtc/video/rtc_event_log.h"
 
 namespace webrtc {
 
@@ -111,6 +112,9 @@
 
   size_t NumOfChannels() const;
 
+  // Returns a pointer to the event log object stored within the ChannelManager.
+  RtcEventLog* GetEventLog() const;
+
  private:
   // Create a channel given a configuration, |config|.
   ChannelOwner CreateChannelInternal(const Config& config);
@@ -123,6 +127,7 @@
   std::vector<ChannelOwner> channels_;
 
   const Config& config_;
+  rtc::scoped_ptr<RtcEventLog> event_log_;
 
   DISALLOW_COPY_AND_ASSIGN(ChannelManager);
 };
diff --git a/webrtc/voice_engine/include/voe_codec.h b/webrtc/voice_engine/include/voe_codec.h
index 5d94ac2..6c4fb38 100644
--- a/webrtc/voice_engine/include/voe_codec.h
+++ b/webrtc/voice_engine/include/voe_codec.h
@@ -35,6 +35,7 @@
 
 namespace webrtc {
 
+class RtcEventLog;
 class VoiceEngine;
 
 class WEBRTC_DLLEXPORT VoECodec {
@@ -131,6 +132,10 @@
   // success, and -1 if failed.
   virtual int SetOpusDtx(int channel, bool enable_dtx) = 0;
 
+  // Get a pointer to the event logging object associated with this Voice
+  // Engine. This pointer will remain valid until VoiceEngine is destroyed.
+  virtual RtcEventLog* GetEventLog() = 0;
+
  protected:
   VoECodec() {}
   virtual ~VoECodec() {}
diff --git a/webrtc/voice_engine/test/auto_test/standard/codec_test.cc b/webrtc/voice_engine/test/auto_test/standard/codec_test.cc
index bfc2a30..e7c9fbf 100644
--- a/webrtc/voice_engine/test/auto_test/standard/codec_test.cc
+++ b/webrtc/voice_engine/test/auto_test/standard/codec_test.cc
@@ -8,8 +8,14 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <stdio.h>
+#include <string>
+
+#include "webrtc/test/test_suite.h"
+#include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
 #include "webrtc/voice_engine/voice_engine_defines.h"
+#include "webrtc/video/rtc_event_log.h"
 
 class CodecTest : public AfterStreamingFixture {
  protected:
@@ -182,6 +188,30 @@
   }
 }
 
+#ifdef ENABLE_RTC_EVENT_LOG
+TEST_F(CodecTest, RtcEventLogIntegrationTest) {
+  webrtc::RtcEventLog* event_log = voe_codec_->GetEventLog();
+  ASSERT_TRUE(event_log);
+
+  // Find the name of the current test, in order to use it as a temporary
+  // filename.
+  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
+  const std::string temp_filename = webrtc::test::OutputPath() +
+                                    test_info->test_case_name() +
+                                    test_info->name();
+  // Create a log file.
+  event_log->StartLogging(temp_filename, 1000);
+  event_log->StopLogging();
+
+  // Check if the file has been created.
+  FILE* event_file = fopen(temp_filename.c_str(), "r");
+  ASSERT_TRUE(event_file);
+  fclose(event_file);
+  // Remove the temporary file.
+  remove(temp_filename.c_str());
+}
+#endif  // ENABLE_RTC_EVENT_LOG
+
 // TODO(xians, phoglund): Re-enable when issue 372 is resolved.
 TEST_F(CodecTest, DISABLED_ManualVerifySendCodecsForAllPacketSizes) {
   for (int i = 0; i < voe_codec_->NumOfCodecs(); ++i) {
diff --git a/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
index ee9306d..bb52463 100644
--- a/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
+++ b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc
@@ -25,6 +25,7 @@
 #include "webrtc/test/channel_transport/include/channel_transport.h"
 #include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/test/testsupport/trace_to_stderr.h"
+#include "webrtc/video/rtc_event_log.h"
 #include "webrtc/voice_engine/include/voe_audio_processing.h"
 #include "webrtc/voice_engine/include/voe_base.h"
 #include "webrtc/voice_engine/include/voe_codec.h"
@@ -451,7 +452,8 @@
       printf("%i. Toggle Opus DTX \n", option_index++);
       printf("%i. Set bit rate (only take effect on codecs that allow the "
              "change) \n", option_index++);
-      printf("%i. Toggle debug recording \n", option_index++);
+      printf("%i. Toggle AECdump recording \n", option_index++);
+      printf("%i. Record RtcEventLog file of 30 seconds \n", option_index++);
 
       printf("Select action or %i to stop the call: ", option_index);
       int option_selection;
@@ -798,6 +800,9 @@
           printf("Debug recording named %s started\n", kDebugFileName);
         }
         debug_recording_started = !debug_recording_started;
+      } else if (option_selection == option_index++) {
+        const char* kDebugFileName = "eventlog.rel";
+        codec->GetEventLog()->StartLogging(kDebugFileName, 30000);
       } else {
         break;
       }
diff --git a/webrtc/voice_engine/voe_base_impl.cc b/webrtc/voice_engine/voe_base_impl.cc
index 94cd98f..14e9052 100644
--- a/webrtc/voice_engine/voe_base_impl.cc
+++ b/webrtc/voice_engine/voe_base_impl.cc
@@ -424,7 +424,6 @@
         channel_owner->channel()->ChannelId());
     return -1;
   }
-
   return channel_owner->channel()->ChannelId();
 }
 
diff --git a/webrtc/voice_engine/voe_codec_impl.cc b/webrtc/voice_engine/voe_codec_impl.cc
index b8fa5ce..a4d0b7d 100644
--- a/webrtc/voice_engine/voe_codec_impl.cc
+++ b/webrtc/voice_engine/voe_codec_impl.cc
@@ -473,6 +473,10 @@
   }
 }
 
+RtcEventLog* VoECodecImpl::GetEventLog() {
+  return _shared->channel_manager().GetEventLog();
+}
+
 #endif  // WEBRTC_VOICE_ENGINE_CODEC_API
 
 }  // namespace webrtc
diff --git a/webrtc/voice_engine/voe_codec_impl.h b/webrtc/voice_engine/voe_codec_impl.h
index a60ce6d..a0eed4d 100644
--- a/webrtc/voice_engine/voe_codec_impl.h
+++ b/webrtc/voice_engine/voe_codec_impl.h
@@ -58,6 +58,8 @@
 
   int SetOpusDtx(int channel, bool enable_dtx) override;
 
+  RtcEventLog* GetEventLog() override;
+
  protected:
   VoECodecImpl(voe::SharedData* shared);
   ~VoECodecImpl() override;
diff --git a/webrtc/voice_engine/voice_engine.gyp b/webrtc/voice_engine/voice_engine.gyp
index 8bd606d..37ffc53 100644
--- a/webrtc/voice_engine/voice_engine.gyp
+++ b/webrtc/voice_engine/voice_engine.gyp
@@ -26,6 +26,7 @@
         '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
         '<(webrtc_root)/modules/modules.gyp:webrtc_utility',
         '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers',
+        '<(webrtc_root)/webrtc.gyp:rtc_event_log',
       ],
       'sources': [
         'include/voe_audio_processing.h',
@@ -153,6 +154,7 @@
             '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers_default',
             '<(webrtc_root)/test/test.gyp:channel_transport',
             '<(webrtc_root)/test/test.gyp:test_support',
+            '<(webrtc_root)/webrtc.gyp:rtc_event_log',
            ],
           'sources': [
             'test/auto_test/automated_mode.cc',
@@ -208,6 +210,11 @@
                 'test/auto_test/standard/hardware_before_streaming_test.cc',
               ],
             }],
+            ['enable_protobuf==1', {
+              'defines': [
+                'ENABLE_RTC_EVENT_LOG',
+              ],
+            }],
           ],
           # Disable warnings to enable Win64 build, issue 1323.
           'msvs_disabled_warnings': [
@@ -226,6 +233,7 @@
             '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers_default',
             '<(webrtc_root)/test/test.gyp:channel_transport',
             '<(webrtc_root)/test/test.gyp:test_support',
+            '<(webrtc_root)/webrtc.gyp:rtc_event_log',
           ],
           'sources': [
             'test/cmd_test/voe_cmd_test.cc',