Merge third_party/webrtc from https://chromium.googlesource.com/external/webrtc/trunk/webrtc.git at f854f30d7981795f687f9b4379100c037934535d

This commit was generated by merge_from_chromium.py.

Change-Id: Ic25930ad2a0758a4b68350bbc1368924011f37d1
diff --git a/base/latebindingsymboltable.cc b/base/latebindingsymboltable.cc
index 1896bd0..030f720 100644
--- a/base/latebindingsymboltable.cc
+++ b/base/latebindingsymboltable.cc
@@ -100,7 +100,7 @@
                    // is necessary for same-named symbols in different ABI
                    // versions of the same library to not explode.
                    RTLD_NOW|RTLD_LOCAL
-#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
+#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID) && defined(RTLD_DEEPBIND)
                    // RTLD_DEEPBIND makes symbol dependencies in the
                    // newly-loaded tree prefer to resolve to definitions within
                    // that tree (the default on OS X). This is necessary for
diff --git a/modules/audio_coding/main/acm2/acm_send_test.cc b/modules/audio_coding/main/acm2/acm_send_test.cc
new file mode 100644
index 0000000..67cc9b2
--- /dev/null
+++ b/modules/audio_coding/main/acm2/acm_send_test.cc
@@ -0,0 +1,139 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/checks.h"
+#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
+#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
+
+namespace webrtc {
+namespace test {
+
+AcmSendTest::AcmSendTest(InputAudioFile* audio_source,
+                         int source_rate_hz,
+                         int test_duration_ms)
+    : clock_(0),
+      acm_(webrtc::AudioCodingModule::Create(0, &clock_)),
+      audio_source_(audio_source),
+      source_rate_hz_(source_rate_hz),
+      input_block_size_samples_(source_rate_hz_ * kBlockSizeMs / 1000),
+      codec_registered_(false),
+      test_duration_ms_(test_duration_ms),
+      frame_type_(kAudioFrameSpeech),
+      payload_type_(0),
+      timestamp_(0),
+      sequence_number_(0) {
+  input_frame_.sample_rate_hz_ = source_rate_hz_;
+  input_frame_.num_channels_ = 1;
+  input_frame_.samples_per_channel_ = input_block_size_samples_;
+  assert(input_block_size_samples_ * input_frame_.num_channels_ <=
+         AudioFrame::kMaxDataSizeSamples);
+  acm_->RegisterTransportCallback(this);
+}
+
+bool AcmSendTest::RegisterCodec(const char* payload_name,
+                                int sampling_freq_hz,
+                                int channels,
+                                int payload_type,
+                                int frame_size_samples) {
+  FATAL_ERROR_IF(AudioCodingModule::Codec(
+                     payload_name, &codec_, sampling_freq_hz, channels) != 0);
+  codec_.pltype = payload_type;
+  codec_.pacsize = frame_size_samples;
+  codec_registered_ = (acm_->RegisterSendCodec(codec_) == 0);
+  assert(channels == 1);  // TODO(henrik.lundin) Add multi-channel support.
+  input_frame_.num_channels_ = channels;
+  assert(input_block_size_samples_ * input_frame_.num_channels_ <=
+         AudioFrame::kMaxDataSizeSamples);
+  return codec_registered_;
+}
+
+Packet* AcmSendTest::NextPacket() {
+  assert(codec_registered_);
+  if (filter_.test(payload_type_)) {
+    // This payload type should be filtered out. Since the payload type is the
+    // same throughout the whole test run, no packet at all will be delivered.
+    // We can just as well signal that the test is over by returning NULL.
+    return NULL;
+  }
+  // Insert audio and process until one packet is produced.
+  while (clock_.TimeInMilliseconds() < test_duration_ms_) {
+    clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
+    FATAL_ERROR_IF(
+        !audio_source_->Read(input_block_size_samples_, input_frame_.data_));
+    FATAL_ERROR_IF(acm_->Add10MsData(input_frame_) != 0);
+    input_frame_.timestamp_ += input_block_size_samples_;
+    int32_t encoded_bytes = acm_->Process();
+    if (encoded_bytes > 0) {
+      // Encoded packet received.
+      return CreatePacket();
+    }
+  }
+  // Test ended.
+  return NULL;
+}
+
+// This method receives the callback from ACM when a new packet is produced.
+int32_t AcmSendTest::SendData(FrameType frame_type,
+                              uint8_t payload_type,
+                              uint32_t timestamp,
+                              const uint8_t* payload_data,
+                              uint16_t payload_len_bytes,
+                              const RTPFragmentationHeader* fragmentation) {
+  // Store the packet locally.
+  frame_type_ = frame_type;
+  payload_type_ = payload_type;
+  timestamp_ = timestamp;
+  last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
+  assert(last_payload_vec_.size() == payload_len_bytes);
+  return 0;
+}
+
+Packet* AcmSendTest::CreatePacket() {
+  const size_t kRtpHeaderSize = 12;
+  size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize;
+  uint8_t* packet_memory = new uint8_t[allocated_bytes];
+  // Populate the header bytes.
+  packet_memory[0] = 0x80;
+  packet_memory[1] = payload_type_;
+  packet_memory[2] = (sequence_number_ >> 8) & 0xFF;
+  packet_memory[3] = (sequence_number_) & 0xFF;
+  packet_memory[4] = (timestamp_ >> 24) & 0xFF;
+  packet_memory[5] = (timestamp_ >> 16) & 0xFF;
+  packet_memory[6] = (timestamp_ >> 8) & 0xFF;
+  packet_memory[7] = timestamp_ & 0xFF;
+  // Set SSRC to 0x12345678.
+  packet_memory[8] = 0x12;
+  packet_memory[9] = 0x34;
+  packet_memory[10] = 0x56;
+  packet_memory[11] = 0x78;
+
+  ++sequence_number_;
+
+  // Copy the payload data.
+  memcpy(packet_memory + kRtpHeaderSize,
+         &last_payload_vec_[0],
+         last_payload_vec_.size());
+  Packet* packet =
+      new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds());
+  assert(packet);
+  assert(packet->valid_header());
+  return packet;
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/modules/audio_coding/main/acm2/acm_send_test.h b/modules/audio_coding/main/acm2/acm_send_test.h
new file mode 100644
index 0000000..5e9bd97
--- /dev/null
+++ b/modules/audio_coding/main/acm2/acm_send_test.h
@@ -0,0 +1,85 @@
+/*
+ *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
+#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
+
+#include <vector>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
+#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h"
+#include "webrtc/system_wrappers/interface/clock.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+namespace test {
+class InputAudioFile;
+class Packet;
+
+class AcmSendTest : public AudioPacketizationCallback, public PacketSource {
+ public:
+  AcmSendTest(InputAudioFile* audio_source,
+              int source_rate_hz,
+              int test_duration_ms);
+  virtual ~AcmSendTest() {}
+
+  // Registers the send codec. Returns true on success, false otherwise.
+  bool RegisterCodec(const char* payload_name,
+                     int sampling_freq_hz,
+                     int channels,
+                     int payload_type,
+                     int frame_size_samples);
+
+  // Returns the next encoded packet. Returns NULL if the test duration was
+  // exceeded. Ownership of the packet is handed over to the caller.
+  // Inherited from PacketSource.
+  Packet* NextPacket();
+
+  // Inherited from AudioPacketizationCallback.
+  virtual int32_t SendData(
+      FrameType frame_type,
+      uint8_t payload_type,
+      uint32_t timestamp,
+      const uint8_t* payload_data,
+      uint16_t payload_len_bytes,
+      const RTPFragmentationHeader* fragmentation) OVERRIDE;
+
+ private:
+  static const int kBlockSizeMs = 10;
+
+  // Creates a Packet object from the last packet produced by ACM (and received
+  // through the SendData method as a callback). Ownership of the new Packet
+  // object is transferred to the caller.
+  Packet* CreatePacket();
+
+  SimulatedClock clock_;
+  scoped_ptr<AudioCodingModule> acm_;
+  InputAudioFile* audio_source_;
+  int source_rate_hz_;
+  const int input_block_size_samples_;
+  AudioFrame input_frame_;
+  CodecInst codec_;
+  bool codec_registered_;
+  int test_duration_ms_;
+  // The following member variables are set whenever SendData() is called.
+  FrameType frame_type_;
+  int payload_type_;
+  uint32_t timestamp_;
+  uint16_t sequence_number_;
+  std::vector<uint8_t> last_payload_vec_;
+
+  DISALLOW_COPY_AND_ASSIGN(AcmSendTest);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_
diff --git a/modules/audio_coding/main/acm2/audio_coding_module.gypi b/modules/audio_coding/main/acm2/audio_coding_module.gypi
index dccfe68..f88dbd3 100644
--- a/modules/audio_coding/main/acm2/audio_coding_module.gypi
+++ b/modules/audio_coding/main/acm2/audio_coding_module.gypi
@@ -130,6 +130,19 @@
           ],
         }, # acm_receive_test
         {
+          'target_name': 'acm_send_test',
+          'type': 'static_library',
+          'dependencies': [
+            'audio_coding_module',
+            'neteq_unittest_tools',
+            '<(DEPTH)/testing/gtest.gyp:gtest',
+          ],
+          'sources': [
+            'acm_send_test.cc',
+            'acm_send_test.h',
+          ],
+        }, # acm_send_test
+        {
           'target_name': 'delay_test',
           'type': 'executable',
           'dependencies': [
diff --git a/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc
index 7e2ede5..9c21fec 100644
--- a/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/main/acm2/audio_coding_module_unittest.cc
@@ -12,12 +12,16 @@
 #include <vector>
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/base/md5digest.h"
 #include "webrtc/modules/audio_coding/main/acm2/acm_receive_test.h"
+#include "webrtc/modules/audio_coding/main/acm2/acm_send_test.h"
 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
 #include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h"
 #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
+#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
 #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h"
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"
 #include "webrtc/modules/interface/module_common_types.h"
 #include "webrtc/system_wrappers/interface/clock.h"
@@ -516,6 +520,19 @@
 }
 
 class AcmReceiverBitExactness : public ::testing::Test {
+ public:
+  static std::string PlatformChecksum(std::string win64,
+                                      std::string android,
+                                      std::string others) {
+#if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS)
+    return win64;
+#elif defined(WEBRTC_ANDROID)
+    return android;
+#else
+    return others;
+#endif
+  }
+
  protected:
   void Run(int output_freq_hz, const std::string& checksum_ref) {
     const std::string input_file_name =
@@ -546,18 +563,6 @@
     std::string checksum_string = checksum.Finish();
     EXPECT_EQ(checksum_ref, checksum_string);
   }
-
-  static std::string PlatformChecksum(std::string win64,
-                                      std::string android,
-                                      std::string others) {
-#if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS)
-    return win64;
-#elif defined(WEBRTC_ANDROID)
-    return android;
-#else
-    return others;
-#endif
-  }
 };
 
 TEST_F(AcmReceiverBitExactness, 8kHzOutput) {
@@ -587,4 +592,188 @@
                        "76b9e99e0a3998aa28355e7a2bd836f7",
                        "89b4b19bdb4de40f1d88302ef8cb9f9b"));
 }
+
+// This test verifies bit exactness for the send-side of ACM. The test setup is
+// a chain of three different test classes:
+//
+// test::AcmSendTest -> AcmSenderBitExactness -> test::AcmReceiveTest
+//
+// The receiver side is driving the test by requesting new packets from
+// AcmSenderBitExactness::NextPacket(). This method, in turn, asks for the
+// packet from test::AcmSendTest::NextPacket, which inserts audio from the
+// input file until one packet is produced. (The input file loops indefinitely.)
+// Before passing the packet to the receiver, this test class verifies the
+// packet header and updates a payload checksum with the new payload. The
+// decoded output from the receiver is also verified with a (separate) checksum.
+class AcmSenderBitExactness : public ::testing::Test,
+                              public test::PacketSource {
+ protected:
+  static const int kTestDurationMs = 1000;
+
+  AcmSenderBitExactness()
+      : frame_size_rtp_timestamps_(0),
+        packet_count_(0),
+        payload_type_(0),
+        last_sequence_number_(0),
+        last_timestamp_(0) {}
+
+  // Sets up the test::AcmSendTest object. Returns true on success, otherwise
+  // false.
+  bool SetUpSender() {
+    const std::string input_file_name =
+        webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
+    // Note that |audio_source_| will loop forever. The test duration is set
+    // explicitly by |kTestDurationMs|.
+    audio_source_.reset(new test::InputAudioFile(input_file_name));
+    static const int kSourceRateHz = 32000;
+    send_test_.reset(new test::AcmSendTest(
+        audio_source_.get(), kSourceRateHz, kTestDurationMs));
+    return send_test_.get() != NULL;
+  }
+
+  // Registers a send codec in the test::AcmSendTest object. Returns true on
+  // success, false on failure.
+  bool RegisterSendCodec(const char* payload_name,
+                         int sampling_freq_hz,
+                         int channels,
+                         int payload_type,
+                         int frame_size_samples,
+                         int frame_size_rtp_timestamps) {
+    payload_type_ = payload_type;
+    frame_size_rtp_timestamps_ = frame_size_rtp_timestamps;
+    return send_test_->RegisterCodec(payload_name,
+                                     sampling_freq_hz,
+                                     channels,
+                                     payload_type,
+                                     frame_size_samples);
+  }
+
+  // Runs the test. SetUpSender() and RegisterSendCodec() must have been called
+  // before calling this method.
+  void Run(const std::string& audio_checksum_ref,
+           const std::string& payload_checksum_ref,
+           int expected_packets) {
+    // Set up the receiver used to decode the packets and verify the decoded
+    // output.
+    test::AudioChecksum audio_checksum;
+    const std::string output_file_name =
+        webrtc::test::OutputPath() +
+        ::testing::UnitTest::GetInstance()
+            ->current_test_info()
+            ->test_case_name() +
+        "_" +
+        ::testing::UnitTest::GetInstance()->current_test_info()->name() +
+        "_output.pcm";
+    test::OutputAudioFile output_file(output_file_name);
+    // Have the output audio sent both to file and to the checksum calculator.
+    test::AudioSinkFork output(&audio_checksum, &output_file);
+    const int kOutputFreqHz = 8000;
+    test::AcmReceiveTest receive_test(this, &output, kOutputFreqHz);
+    ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs());
+
+    // This is where the actual test is executed.
+    receive_test.Run();
+
+    // Extract and verify the audio checksum.
+    std::string checksum_string = audio_checksum.Finish();
+    EXPECT_EQ(audio_checksum_ref, checksum_string);
+
+    // Extract and verify the payload checksum.
+    char checksum_result[rtc::Md5Digest::kSize];
+    payload_checksum_.Finish(checksum_result, rtc::Md5Digest::kSize);
+    checksum_string = rtc::hex_encode(checksum_result, rtc::Md5Digest::kSize);
+    EXPECT_EQ(payload_checksum_ref, checksum_string);
+
+    // Verify number of packets produced.
+    EXPECT_EQ(expected_packets, packet_count_);
+  }
+
+  // Returns a pointer to the next packet. Returns NULL if the source is
+  // depleted (i.e., the test duration is exceeded), or if an error occurred.
+  // Inherited from test::PacketSource.
+  test::Packet* NextPacket() OVERRIDE {
+    // Get the next packet from AcmSendTest. Ownership of |packet| is
+    // transferred to this method.
+    test::Packet* packet = send_test_->NextPacket();
+    if (!packet)
+      return NULL;
+
+    VerifyPacket(packet);
+    // TODO(henrik.lundin) Save the packet to file as well.
+
+    // Pass it on to the caller. The caller becomes the owner of |packet|.
+    return packet;
+  }
+
+  // Verifies the packet.
+  void VerifyPacket(const test::Packet* packet) {
+    EXPECT_TRUE(packet->valid_header());
+    // (We can check the header fields even if valid_header() is false.)
+    EXPECT_EQ(payload_type_, packet->header().payloadType);
+    if (packet_count_ > 0) {
+      // This is not the first packet.
+      uint16_t sequence_number_diff =
+          packet->header().sequenceNumber - last_sequence_number_;
+      EXPECT_EQ(1, sequence_number_diff);
+      uint32_t timestamp_diff = packet->header().timestamp - last_timestamp_;
+      EXPECT_EQ(frame_size_rtp_timestamps_, timestamp_diff);
+    }
+    ++packet_count_;
+    last_sequence_number_ = packet->header().sequenceNumber;
+    last_timestamp_ = packet->header().timestamp;
+    // Update the checksum.
+    payload_checksum_.Update(packet->payload(), packet->payload_length_bytes());
+  }
+
+  void SetUpTest(const char* codec_name,
+                 int codec_sample_rate_hz,
+                 int channels,
+                 int payload_type,
+                 int codec_frame_size_samples,
+                 int codec_frame_size_rtp_timestamps) {
+    ASSERT_TRUE(SetUpSender());
+    ASSERT_TRUE(RegisterSendCodec(codec_name,
+                                  codec_sample_rate_hz,
+                                  channels,
+                                  payload_type,
+                                  codec_frame_size_samples,
+                                  codec_frame_size_rtp_timestamps));
+  }
+
+  scoped_ptr<test::AcmSendTest> send_test_;
+  scoped_ptr<test::InputAudioFile> audio_source_;
+  uint32_t frame_size_rtp_timestamps_;
+  int packet_count_;
+  uint8_t payload_type_;
+  uint16_t last_sequence_number_;
+  uint32_t last_timestamp_;
+  rtc::Md5Digest payload_checksum_;
+};
+
+TEST_F(AcmSenderBitExactness, IsacWb30ms) {
+  ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 480, 480));
+  Run(AcmReceiverBitExactness::PlatformChecksum(
+          "c7e5bdadfa2871df95639fcc297cf23d",
+          "0499ca260390769b3172136faad925b9",
+          "0b58f9eeee43d5891f5f6c75e77984a3"),
+      AcmReceiverBitExactness::PlatformChecksum(
+          "d42cb5195463da26c8129bbfe73a22e6",
+          "83de248aea9c3c2bd680b6952401b4ca",
+          "3c79f16f34218271f3dca4e2b1dfe1bb"),
+      33);
+}
+
+TEST_F(AcmSenderBitExactness, IsacWb60ms) {
+  ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 960, 960));
+  Run(AcmReceiverBitExactness::PlatformChecksum(
+          "14d63c5f08127d280e722e3191b73bdd",
+          "8da003e16c5371af2dc2be79a50f9076",
+          "1ad29139a04782a33daad8c2b9b35875"),
+      AcmReceiverBitExactness::PlatformChecksum(
+          "ebe04a819d3a9d83a83a17f271e1139a",
+          "97aeef98553b5a4b5a68f8b716e8eaf0",
+          "9e0a0ab743ad987b55b8e14802769c56"),
+      16);
+}
+
 }  // namespace webrtc
diff --git a/modules/modules.gyp b/modules/modules.gyp
index e6919f1..f68ea7c 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -69,6 +69,7 @@
           ],
           'dependencies': [
             'acm_receive_test',
+            'acm_send_test',
             'audio_coding_module',
             'audio_processing',
             'bitrate_controller',