Rename neteq4 folder to neteq

Keep the old neteq4/audio_decoder_unittests.isolate while waiting for
a hard-coded reference to change.

This CL effectively reverts r6257 "Rename neteq4 folder to neteq".

BUG=2996
TBR=tina.legrand@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6367 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc b/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc
new file mode 100644
index 0000000..2d2a7e3
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2013 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/neteq/tools/audio_loop.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+namespace webrtc {
+namespace test {
+
+bool AudioLoop::Init(const std::string file_name,
+                     size_t max_loop_length_samples,
+                     size_t block_length_samples) {
+  FILE* fp = fopen(file_name.c_str(), "rb");
+  if (!fp) return false;
+
+  audio_array_.reset(new int16_t[max_loop_length_samples +
+                                 block_length_samples]);
+  size_t samples_read = fread(audio_array_.get(), sizeof(int16_t),
+                              max_loop_length_samples, fp);
+  fclose(fp);
+
+  // Block length must be shorter than the loop length.
+  if (block_length_samples > samples_read) return false;
+
+  // Add an extra block length of samples to the end of the array, starting
+  // over again from the beginning of the array. This is done to simplify
+  // the reading process when reading over the end of the loop.
+  memcpy(&audio_array_[samples_read], audio_array_.get(),
+         block_length_samples * sizeof(int16_t));
+
+  loop_length_samples_ = samples_read;
+  block_length_samples_ = block_length_samples;
+  return true;
+}
+
+const int16_t* AudioLoop::GetNextBlock() {
+  // Check that the AudioLoop is initialized.
+  if (block_length_samples_ == 0) return NULL;
+
+  const int16_t* output_ptr = &audio_array_[next_index_];
+  next_index_ = (next_index_ + block_length_samples_) % loop_length_samples_;
+  return output_ptr;
+}
+
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/audio_loop.h b/webrtc/modules/audio_coding/neteq/tools/audio_loop.h
new file mode 100644
index 0000000..9647d82
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/audio_loop.h
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2013 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_NETEQ_TOOLS_AUDIO_LOOP_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_AUDIO_LOOP_H_
+
+#include <string>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+// Class serving as an infinite source of audio, realized by looping an audio
+// clip.
+class AudioLoop {
+ public:
+  AudioLoop()
+      : next_index_(0),
+        loop_length_samples_(0),
+        block_length_samples_(0) {
+  }
+
+  virtual ~AudioLoop() {}
+
+  // Initializes the AudioLoop by reading from |file_name|. The loop will be no
+  // longer than |max_loop_length_samples|, if the length of the file is
+  // greater. Otherwise, the loop length is the same as the file length.
+  // The audio will be delivered in blocks of |block_length_samples|.
+  // Returns false if the initialization failed, otherwise true.
+  bool Init(const std::string file_name, size_t max_loop_length_samples,
+            size_t block_length_samples);
+
+  // Returns a pointer to the next block of audio. The number given as
+  // |block_length_samples| to the Init() function determines how many samples
+  // that can be safely read from the pointer.
+  const int16_t* GetNextBlock();
+
+ private:
+  size_t next_index_;
+  size_t loop_length_samples_;
+  size_t block_length_samples_;
+  scoped_ptr<int16_t[]> audio_array_;
+
+  DISALLOW_COPY_AND_ASSIGN(AudioLoop);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_AUDIO_LOOP_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/input_audio_file.cc b/webrtc/modules/audio_coding/neteq/tools/input_audio_file.cc
new file mode 100644
index 0000000..8063173
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/input_audio_file.cc
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2013 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/neteq/tools/input_audio_file.h"
+
+namespace webrtc {
+namespace test {
+
+InputAudioFile::InputAudioFile(const std::string file_name) {
+  fp_ = fopen(file_name.c_str(), "rb");
+}
+
+InputAudioFile::~InputAudioFile() { fclose(fp_); }
+
+bool InputAudioFile::Read(size_t samples, int16_t* destination) {
+  if (!fp_) {
+    return false;
+  }
+  size_t samples_read = fread(destination, sizeof(int16_t), samples, fp_);
+  if (samples_read < samples) {
+    // Rewind and read the missing samples.
+    rewind(fp_);
+    size_t missing_samples = samples - samples_read;
+    if (fread(destination, sizeof(int16_t), missing_samples, fp_) <
+        missing_samples) {
+      // Could not read enough even after rewinding the file.
+      return false;
+    }
+  }
+  return true;
+}
+
+void InputAudioFile::DuplicateInterleaved(const int16_t* source, size_t samples,
+                                          size_t channels,
+                                          int16_t* destination) {
+  for (size_t i = 0; i < samples; ++i) {
+    for (size_t j = 0; j < channels; ++j) {
+      destination[i * channels + j] = source[i];
+    }
+  }
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/input_audio_file.h b/webrtc/modules/audio_coding/neteq/tools/input_audio_file.h
new file mode 100644
index 0000000..274f8ea
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/input_audio_file.h
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2013 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_NETEQ_TOOLS_INPUT_AUDIO_FILE_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_INPUT_AUDIO_FILE_H_
+
+#include <stdio.h>
+
+#include <string>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+// Class for handling a looping input audio file.
+class InputAudioFile {
+ public:
+  explicit InputAudioFile(const std::string file_name);
+
+  virtual ~InputAudioFile();
+
+  // Reads |samples| elements from source file to |destination|. Returns true
+  // if the read was successful, otherwise false. If the file end is reached,
+  // the file is rewound and reading continues from the beginning.
+  // The output |destination| must have the capacity to hold |samples| elements.
+  bool Read(size_t samples, int16_t* destination);
+
+  // Creates a multi-channel signal from a mono signal. Each sample is repeated
+  // |channels| times to create an interleaved multi-channel signal where all
+  // channels are identical. The output |destination| must have the capacity to
+  // hold samples * channels elements.
+  static void DuplicateInterleaved(const int16_t* source, size_t samples,
+                                   size_t channels, int16_t* destination);
+
+ private:
+  FILE* fp_;
+  DISALLOW_COPY_AND_ASSIGN(InputAudioFile);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_INPUT_AUDIO_FILE_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc
new file mode 100644
index 0000000..433546f
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc
@@ -0,0 +1,132 @@
+/*
+ *  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/neteq/tools/neteq_performance_test.h"
+
+#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
+#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
+#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h"
+#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/system_wrappers/interface/clock.h"
+#include "webrtc/test/testsupport/fileutils.h"
+#include "webrtc/typedefs.h"
+
+using webrtc::NetEq;
+using webrtc::test::AudioLoop;
+using webrtc::test::RtpGenerator;
+using webrtc::WebRtcRTPHeader;
+
+namespace webrtc {
+namespace test {
+
+int64_t NetEqPerformanceTest::Run(int runtime_ms,
+                                  int lossrate,
+                                  double drift_factor) {
+  const std::string kInputFileName =
+      webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
+  const int kSampRateHz = 32000;
+  const webrtc::NetEqDecoder kDecoderType = webrtc::kDecoderPCM16Bswb32kHz;
+  const int kPayloadType = 95;
+
+  // Initialize NetEq instance.
+  NetEq::Config config;
+  config.sample_rate_hz = kSampRateHz;
+  NetEq* neteq = NetEq::Create(config);
+  // Register decoder in |neteq|.
+  if (neteq->RegisterPayloadType(kDecoderType, kPayloadType) != 0)
+    return -1;
+
+  // Set up AudioLoop object.
+  AudioLoop audio_loop;
+  const size_t kMaxLoopLengthSamples = kSampRateHz * 10;  // 10 second loop.
+  const size_t kInputBlockSizeSamples = 60 * kSampRateHz / 1000;  // 60 ms.
+  if (!audio_loop.Init(kInputFileName, kMaxLoopLengthSamples,
+                       kInputBlockSizeSamples))
+    return -1;
+
+  int32_t time_now_ms = 0;
+
+  // Get first input packet.
+  WebRtcRTPHeader rtp_header;
+  RtpGenerator rtp_gen(kSampRateHz / 1000);
+  // Start with positive drift first half of simulation.
+  rtp_gen.set_drift_factor(drift_factor);
+  bool drift_flipped = false;
+  int32_t packet_input_time_ms =
+      rtp_gen.GetRtpHeader(kPayloadType, kInputBlockSizeSamples, &rtp_header);
+  const int16_t* input_samples = audio_loop.GetNextBlock();
+  if (!input_samples) exit(1);
+  uint8_t input_payload[kInputBlockSizeSamples * sizeof(int16_t)];
+  int payload_len = WebRtcPcm16b_Encode(const_cast<int16_t*>(input_samples),
+                                        kInputBlockSizeSamples,
+                                        input_payload);
+  assert(payload_len == kInputBlockSizeSamples * sizeof(int16_t));
+
+  // Main loop.
+  webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
+  int64_t start_time_ms = clock->TimeInMilliseconds();
+  while (time_now_ms < runtime_ms) {
+    while (packet_input_time_ms <= time_now_ms) {
+      // Drop every N packets, where N = FLAGS_lossrate.
+      bool lost = false;
+      if (lossrate > 0) {
+        lost = ((rtp_header.header.sequenceNumber - 1) % lossrate) == 0;
+      }
+      if (!lost) {
+        // Insert packet.
+        int error = neteq->InsertPacket(
+            rtp_header, input_payload, payload_len,
+            packet_input_time_ms * kSampRateHz / 1000);
+        if (error != NetEq::kOK)
+          return -1;
+      }
+
+      // Get next packet.
+      packet_input_time_ms = rtp_gen.GetRtpHeader(kPayloadType,
+                                                  kInputBlockSizeSamples,
+                                                  &rtp_header);
+      input_samples = audio_loop.GetNextBlock();
+      if (!input_samples) return -1;
+      payload_len = WebRtcPcm16b_Encode(const_cast<int16_t*>(input_samples),
+                                        kInputBlockSizeSamples,
+                                        input_payload);
+      assert(payload_len == kInputBlockSizeSamples * sizeof(int16_t));
+    }
+
+    // Get output audio, but don't do anything with it.
+    static const int kMaxChannels = 1;
+    static const int kMaxSamplesPerMs = 48000 / 1000;
+    static const int kOutputBlockSizeMs = 10;
+    static const int kOutDataLen = kOutputBlockSizeMs * kMaxSamplesPerMs *
+        kMaxChannels;
+    int16_t out_data[kOutDataLen];
+    int num_channels;
+    int samples_per_channel;
+    int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel,
+                                &num_channels, NULL);
+    if (error != NetEq::kOK)
+      return -1;
+
+    assert(samples_per_channel == kSampRateHz * 10 / 1000);
+
+    time_now_ms += kOutputBlockSizeMs;
+    if (time_now_ms >= runtime_ms / 2 && !drift_flipped) {
+      // Apply negative drift second half of simulation.
+      rtp_gen.set_drift_factor(-drift_factor);
+      drift_flipped = true;
+    }
+  }
+  int64_t end_time_ms = clock->TimeInMilliseconds();
+  delete neteq;
+  return end_time_ms - start_time_ms;
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.h
new file mode 100644
index 0000000..d094db0
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.h
@@ -0,0 +1,32 @@
+/*
+ *  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_NETEQ_TOOLS_NETEQ_PERFORMANCE_TEST_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PERFORMANCE_TEST_H_
+
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+class NetEqPerformanceTest {
+ public:
+  // Runs a performance test with parameters as follows:
+  //   |runtime_ms|: the simulation time, i.e., the duration of the audio data.
+  //   |lossrate|: drop one out of |lossrate| packets, e.g., one out of 10.
+  //   |drift_factor|: clock drift in [0, 1].
+  // Returns the runtime in ms.
+  static int64_t Run(int runtime_ms, int lossrate, double drift_factor);
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PERFORMANCE_TEST_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc
new file mode 100644
index 0000000..fc5d8ab
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc
@@ -0,0 +1,115 @@
+/*
+ *  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 <stdio.h>
+#include "webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h"
+
+namespace webrtc {
+namespace test {
+
+const uint8_t kPayloadType = 95;
+const int kOutputSizeMs = 10;
+
+NetEqQualityTest::NetEqQualityTest(int block_duration_ms,
+                                   int in_sampling_khz,
+                                   int out_sampling_khz,
+                                   enum NetEqDecoder decoder_type,
+                                   int channels,
+                                   double drift_factor,
+                                   std::string in_filename,
+                                   std::string out_filename)
+    : decoded_time_ms_(0),
+      decodable_time_ms_(0),
+      drift_factor_(drift_factor),
+      block_duration_ms_(block_duration_ms),
+      in_sampling_khz_(in_sampling_khz),
+      out_sampling_khz_(out_sampling_khz),
+      decoder_type_(decoder_type),
+      channels_(channels),
+      in_filename_(in_filename),
+      out_filename_(out_filename),
+      in_size_samples_(in_sampling_khz_ * block_duration_ms_),
+      out_size_samples_(out_sampling_khz_ * kOutputSizeMs),
+      payload_size_bytes_(0),
+      max_payload_bytes_(0),
+      in_file_(new InputAudioFile(in_filename_)),
+      out_file_(NULL),
+      rtp_generator_(new RtpGenerator(in_sampling_khz_, 0, 0,
+                                      decodable_time_ms_)) {
+  NetEq::Config config;
+  config.sample_rate_hz = out_sampling_khz_ * 1000;
+  neteq_.reset(NetEq::Create(config));
+  max_payload_bytes_ = in_size_samples_ * channels_ * sizeof(int16_t);
+  in_data_.reset(new int16_t[in_size_samples_ * channels_]);
+  payload_.reset(new uint8_t[max_payload_bytes_]);
+  out_data_.reset(new int16_t[out_size_samples_ * channels_]);
+}
+
+void NetEqQualityTest::SetUp() {
+  out_file_ = fopen(out_filename_.c_str(), "wb");
+  ASSERT_TRUE(out_file_ != NULL);
+  ASSERT_EQ(0, neteq_->RegisterPayloadType(decoder_type_, kPayloadType));
+  rtp_generator_->set_drift_factor(drift_factor_);
+}
+
+void NetEqQualityTest::TearDown() {
+  fclose(out_file_);
+}
+
+int NetEqQualityTest::Transmit() {
+  int packet_input_time_ms =
+      rtp_generator_->GetRtpHeader(kPayloadType, in_size_samples_,
+                                   &rtp_header_);
+  if (!PacketLost(packet_input_time_ms) && payload_size_bytes_ > 0) {
+    int ret = neteq_->InsertPacket(rtp_header_, &payload_[0],
+                                   payload_size_bytes_,
+                                   packet_input_time_ms * in_sampling_khz_);
+    if (ret != NetEq::kOK)
+      return -1;
+  }
+  return packet_input_time_ms;
+}
+
+int NetEqQualityTest::DecodeBlock() {
+  int channels;
+  int samples;
+  int ret = neteq_->GetAudio(out_size_samples_ * channels_, &out_data_[0],
+                             &samples, &channels, NULL);
+
+  if (ret != NetEq::kOK) {
+    return -1;
+  } else {
+    assert(channels == channels_);
+    assert(samples == kOutputSizeMs * out_sampling_khz_);
+    fwrite(&out_data_[0], sizeof(int16_t), samples * channels, out_file_);
+    return samples;
+  }
+}
+
+void NetEqQualityTest::Simulate(int end_time_ms) {
+  int audio_size_samples;
+
+  while (decoded_time_ms_ < end_time_ms) {
+    while (decodable_time_ms_ - kOutputSizeMs < decoded_time_ms_) {
+      ASSERT_TRUE(in_file_->Read(in_size_samples_ * channels_, &in_data_[0]));
+      payload_size_bytes_ = EncodeBlock(&in_data_[0],
+                                        in_size_samples_, &payload_[0],
+                                        max_payload_bytes_);
+      decodable_time_ms_ = Transmit() + block_duration_ms_;
+    }
+    audio_size_samples = DecodeBlock();
+    if (audio_size_samples > 0) {
+      decoded_time_ms_ += audio_size_samples / out_sampling_khz_;
+    }
+  }
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h
new file mode 100644
index 0000000..87fc507
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h
@@ -0,0 +1,100 @@
+/*
+ *  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_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_
+
+#include <string>
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
+#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
+#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+class NetEqQualityTest : public ::testing::Test {
+ protected:
+  NetEqQualityTest(int block_duration_ms,
+                   int in_sampling_khz,
+                   int out_sampling_khz,
+                   enum NetEqDecoder decoder_type,
+                   int channels,
+                   double drift_factor,
+                   std::string in_filename,
+                   std::string out_filename);
+  virtual void SetUp() OVERRIDE;
+  virtual void TearDown() OVERRIDE;
+
+  // EncodeBlock(...) does the following:
+  // 1. encodes a block of audio, saved in |in_data| and has a length of
+  // |block_size_samples| (samples per channel),
+  // 2. save the bit stream to |payload| of |max_bytes| bytes in size,
+  // 3. returns the length of the payload (in bytes),
+  virtual int EncodeBlock(int16_t* in_data, int block_size_samples,
+                          uint8_t* payload, int max_bytes) = 0;
+
+  // PacketLoss(...) determines weather a packet sent at an indicated time gets
+  // lost or not.
+  virtual bool PacketLost(int packet_input_time_ms) { return false; }
+
+  // DecodeBlock() decodes a block of audio using the payload stored in
+  // |payload_| with the length of |payload_size_bytes_| (bytes). The decoded
+  // audio is to be stored in |out_data_|.
+  int DecodeBlock();
+
+  // Transmit() uses |rtp_generator_| to generate a packet and passes it to
+  // |neteq_|.
+  int Transmit();
+
+  // Simulate(...) runs encoding / transmitting / decoding up to |end_time_ms|
+  // (miliseconds), the resulted audio is stored in the file with the name of
+  // |out_filename_|.
+  void Simulate(int end_time_ms);
+
+ private:
+  int decoded_time_ms_;
+  int decodable_time_ms_;
+  double drift_factor_;
+  const int block_duration_ms_;
+  const int in_sampling_khz_;
+  const int out_sampling_khz_;
+  const enum NetEqDecoder decoder_type_;
+  const int channels_;
+  const std::string in_filename_;
+  const std::string out_filename_;
+
+  // Number of samples per channel in a frame.
+  const int in_size_samples_;
+
+  // Expected output number of samples per channel in a frame.
+  const int out_size_samples_;
+
+  int payload_size_bytes_;
+  int max_payload_bytes_;
+
+  scoped_ptr<InputAudioFile> in_file_;
+  FILE* out_file_;
+
+  scoped_ptr<RtpGenerator> rtp_generator_;
+  scoped_ptr<NetEq> neteq_;
+
+  scoped_ptr<int16_t[]> in_data_;
+  scoped_ptr<uint8_t[]> payload_;
+  scoped_ptr<int16_t[]> out_data_;
+  WebRtcRTPHeader rtp_header_;
+};
+
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_QUALITY_TEST_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
new file mode 100644
index 0000000..3c5f6b0
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -0,0 +1,628 @@
+/*
+ *  Copyright (c) 2013 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.
+ */
+
+// TODO(hlundin): The functionality in this file should be moved into one or
+// several classes.
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+
+#include "google/gflags.h"
+#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
+#include "webrtc/modules/audio_coding/neteq/interface/neteq.h"
+#include "webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h"
+#include "webrtc/modules/audio_coding/neteq/test/NETEQTEST_DummyRTPpacket.h"
+#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/system_wrappers/interface/trace.h"
+#include "webrtc/test/testsupport/fileutils.h"
+#include "webrtc/typedefs.h"
+
+using webrtc::NetEq;
+using webrtc::WebRtcRTPHeader;
+
+// Flag validators.
+static bool ValidatePayloadType(const char* flagname, int32_t value) {
+  if (value >= 0 && value <= 127)  // Value is ok.
+    return true;
+  printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
+  return false;
+}
+
+// Define command line flags.
+DEFINE_int32(pcmu, 0, "RTP payload type for PCM-u");
+static const bool pcmu_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcmu, &ValidatePayloadType);
+DEFINE_int32(pcma, 8, "RTP payload type for PCM-a");
+static const bool pcma_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcma, &ValidatePayloadType);
+DEFINE_int32(ilbc, 102, "RTP payload type for iLBC");
+static const bool ilbc_dummy =
+    google::RegisterFlagValidator(&FLAGS_ilbc, &ValidatePayloadType);
+DEFINE_int32(isac, 103, "RTP payload type for iSAC");
+static const bool isac_dummy =
+    google::RegisterFlagValidator(&FLAGS_isac, &ValidatePayloadType);
+DEFINE_int32(isac_swb, 104, "RTP payload type for iSAC-swb (32 kHz)");
+static const bool isac_swb_dummy =
+    google::RegisterFlagValidator(&FLAGS_isac_swb, &ValidatePayloadType);
+DEFINE_int32(pcm16b, 93, "RTP payload type for PCM16b-nb (8 kHz)");
+static const bool pcm16b_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcm16b, &ValidatePayloadType);
+DEFINE_int32(pcm16b_wb, 94, "RTP payload type for PCM16b-wb (16 kHz)");
+static const bool pcm16b_wb_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcm16b_wb, &ValidatePayloadType);
+DEFINE_int32(pcm16b_swb32, 95, "RTP payload type for PCM16b-swb32 (32 kHz)");
+static const bool pcm16b_swb32_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcm16b_swb32, &ValidatePayloadType);
+DEFINE_int32(pcm16b_swb48, 96, "RTP payload type for PCM16b-swb48 (48 kHz)");
+static const bool pcm16b_swb48_dummy =
+    google::RegisterFlagValidator(&FLAGS_pcm16b_swb48, &ValidatePayloadType);
+DEFINE_int32(g722, 9, "RTP payload type for G.722");
+static const bool g722_dummy =
+    google::RegisterFlagValidator(&FLAGS_g722, &ValidatePayloadType);
+DEFINE_int32(avt, 106, "RTP payload type for AVT/DTMF");
+static const bool avt_dummy =
+    google::RegisterFlagValidator(&FLAGS_avt, &ValidatePayloadType);
+DEFINE_int32(red, 117, "RTP payload type for redundant audio (RED)");
+static const bool red_dummy =
+    google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType);
+DEFINE_int32(cn_nb, 13, "RTP payload type for comfort noise (8 kHz)");
+static const bool cn_nb_dummy =
+    google::RegisterFlagValidator(&FLAGS_cn_nb, &ValidatePayloadType);
+DEFINE_int32(cn_wb, 98, "RTP payload type for comfort noise (16 kHz)");
+static const bool cn_wb_dummy =
+    google::RegisterFlagValidator(&FLAGS_cn_wb, &ValidatePayloadType);
+DEFINE_int32(cn_swb32, 99, "RTP payload type for comfort noise (32 kHz)");
+static const bool cn_swb32_dummy =
+    google::RegisterFlagValidator(&FLAGS_cn_swb32, &ValidatePayloadType);
+DEFINE_int32(cn_swb48, 100, "RTP payload type for comfort noise (48 kHz)");
+static const bool cn_swb48_dummy =
+    google::RegisterFlagValidator(&FLAGS_cn_swb48, &ValidatePayloadType);
+DEFINE_bool(codec_map, false, "Prints the mapping between RTP payload type and "
+    "codec");
+DEFINE_bool(dummy_rtp, false, "The input file contains ""dummy"" RTP data, "
+            "i.e., only headers");
+DEFINE_string(replacement_audio_file, "",
+              "A PCM file that will be used to populate ""dummy"" RTP packets");
+
+// Declaring helper functions (defined further down in this file).
+std::string CodecName(webrtc::NetEqDecoder codec);
+void RegisterPayloadTypes(NetEq* neteq);
+void PrintCodecMapping();
+size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file,
+                      webrtc::scoped_ptr<int16_t[]>* replacement_audio,
+                      webrtc::scoped_ptr<uint8_t[]>* payload,
+                      size_t* payload_mem_size_bytes,
+                      size_t* frame_size_samples,
+                      WebRtcRTPHeader* rtp_header,
+                      NETEQTEST_RTPpacket* next_rtp);
+int CodecSampleRate(uint8_t payload_type);
+int CodecTimestampRate(uint8_t payload_type);
+bool IsComfortNosie(uint8_t payload_type);
+
+int main(int argc, char* argv[]) {
+  static const int kMaxChannels = 5;
+  static const int kMaxSamplesPerMs = 48000 / 1000;
+  static const int kOutputBlockSizeMs = 10;
+
+  std::string program_name = argv[0];
+  std::string usage = "Tool for decoding an RTP dump file using NetEq.\n"
+      "Run " + program_name + " --helpshort for usage.\n"
+      "Example usage:\n" + program_name +
+      " input.rtp output.pcm\n";
+  google::SetUsageMessage(usage);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  if (FLAGS_codec_map) {
+    PrintCodecMapping();
+  }
+
+  if (argc != 3) {
+    if (FLAGS_codec_map) {
+      // We have already printed the codec map. Just end the program.
+      return 0;
+    }
+    // Print usage information.
+    std::cout << google::ProgramUsage();
+    return 0;
+  }
+
+  FILE* in_file = fopen(argv[1], "rb");
+  if (!in_file) {
+    std::cerr << "Cannot open input file " << argv[1] << std::endl;
+    exit(1);
+  }
+  std::cout << "Input file: " << argv[1] << std::endl;
+
+  FILE* out_file = fopen(argv[2], "wb");
+  if (!in_file) {
+    std::cerr << "Cannot open output file " << argv[2] << std::endl;
+    exit(1);
+  }
+  std::cout << "Output file: " << argv[2] << std::endl;
+
+  // Check if a replacement audio file was provided, and if so, open it.
+  bool replace_payload = false;
+  webrtc::scoped_ptr<webrtc::test::InputAudioFile> replacement_audio_file;
+  if (!FLAGS_replacement_audio_file.empty()) {
+    replacement_audio_file.reset(
+        new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file));
+    replace_payload = true;
+  }
+
+  // Read RTP file header.
+  if (NETEQTEST_RTPpacket::skipFileHeader(in_file) != 0) {
+    std::cerr << "Wrong format in RTP file" << std::endl;
+    exit(1);
+  }
+
+  // Enable tracing.
+  webrtc::Trace::CreateTrace();
+  webrtc::Trace::SetTraceFile((webrtc::test::OutputPath() +
+      "neteq_trace.txt").c_str());
+  webrtc::Trace::set_level_filter(webrtc::kTraceAll);
+
+  // Initialize NetEq instance.
+  int sample_rate_hz = 16000;
+  NetEq::Config config;
+  config.sample_rate_hz = sample_rate_hz;
+  NetEq* neteq = NetEq::Create(config);
+  RegisterPayloadTypes(neteq);
+
+  // Read first packet.
+  NETEQTEST_RTPpacket* rtp;
+  NETEQTEST_RTPpacket* next_rtp = NULL;
+  if (!FLAGS_dummy_rtp) {
+    rtp = new NETEQTEST_RTPpacket();
+    if (replace_payload) {
+      next_rtp = new NETEQTEST_RTPpacket();
+    }
+  } else {
+    rtp = new NETEQTEST_DummyRTPpacket();
+    if (replace_payload) {
+      next_rtp = new NETEQTEST_DummyRTPpacket();
+    }
+  }
+  rtp->readFromFile(in_file);
+  if (rtp->dataLen() < 0) {
+    std::cout  << "Warning: RTP file is empty" << std::endl;
+  }
+
+  // Set up variables for audio replacement if needed.
+  size_t input_frame_size_timestamps = 0;
+  webrtc::scoped_ptr<int16_t[]> replacement_audio;
+  webrtc::scoped_ptr<uint8_t[]> payload;
+  size_t payload_mem_size_bytes = 0;
+  if (replace_payload) {
+    // Initially assume that the frame size is 30 ms at the initial sample rate.
+    // This value will be replaced with the correct one as soon as two
+    // consecutive packets are found.
+    input_frame_size_timestamps = 30 * sample_rate_hz / 1000;
+    replacement_audio.reset(new int16_t[input_frame_size_timestamps]);
+    payload_mem_size_bytes = 2 * input_frame_size_timestamps;
+    payload.reset(new uint8_t[payload_mem_size_bytes]);
+    assert(next_rtp);
+    next_rtp->readFromFile(in_file);
+  }
+
+  // This is the main simulation loop.
+  int time_now_ms = rtp->time();  // Start immediately with the first packet.
+  int next_input_time_ms = rtp->time();
+  int next_output_time_ms = time_now_ms;
+  if (time_now_ms % kOutputBlockSizeMs != 0) {
+    // Make sure that next_output_time_ms is rounded up to the next multiple
+    // of kOutputBlockSizeMs. (Legacy bit-exactness.)
+    next_output_time_ms +=
+        kOutputBlockSizeMs - time_now_ms % kOutputBlockSizeMs;
+  }
+  while (rtp->dataLen() >= 0) {
+    // Check if it is time to insert packet.
+    while (time_now_ms >= next_input_time_ms && rtp->dataLen() >= 0) {
+      if (rtp->dataLen() > 0) {
+        // Parse RTP header.
+        WebRtcRTPHeader rtp_header;
+        rtp->parseHeader(&rtp_header);
+        uint8_t* payload_ptr = rtp->payload();
+        size_t payload_len = rtp->payloadLen();
+        if (replace_payload) {
+          payload_len = ReplacePayload(replacement_audio_file.get(),
+                                       &replacement_audio,
+                                       &payload,
+                                       &payload_mem_size_bytes,
+                                       &input_frame_size_timestamps,
+                                       &rtp_header,
+                                       next_rtp);
+          payload_ptr = payload.get();
+        }
+        int error = neteq->InsertPacket(rtp_header, payload_ptr,
+                                        static_cast<int>(payload_len),
+                                        rtp->time() * sample_rate_hz / 1000);
+        if (error != NetEq::kOK) {
+          std::cerr << "InsertPacket returned error code " <<
+              neteq->LastError() << std::endl;
+        }
+      }
+      // Get next packet from file.
+      rtp->readFromFile(in_file);
+      if (replace_payload) {
+        // At this point |rtp| contains the packet *after* |next_rtp|.
+        // Swap RTP packet objects between |rtp| and |next_rtp|.
+        NETEQTEST_RTPpacket* temp_rtp = rtp;
+        rtp = next_rtp;
+        next_rtp = temp_rtp;
+      }
+      next_input_time_ms = rtp->time();
+    }
+
+    // Check if it is time to get output audio.
+    if (time_now_ms >= next_output_time_ms) {
+      static const int kOutDataLen = kOutputBlockSizeMs * kMaxSamplesPerMs *
+          kMaxChannels;
+      int16_t out_data[kOutDataLen];
+      int num_channels;
+      int samples_per_channel;
+      int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel,
+                                   &num_channels, NULL);
+      if (error != NetEq::kOK) {
+        std::cerr << "GetAudio returned error code " <<
+            neteq->LastError() << std::endl;
+      } else {
+        // Calculate sample rate from output size.
+        sample_rate_hz = 1000 * samples_per_channel / kOutputBlockSizeMs;
+      }
+
+      // Write to file.
+      // TODO(hlundin): Make writing to file optional.
+      size_t write_len = samples_per_channel * num_channels;
+      if (fwrite(out_data, sizeof(out_data[0]), write_len, out_file) !=
+          write_len) {
+        std::cerr << "Error while writing to file" << std::endl;
+        webrtc::Trace::ReturnTrace();
+        exit(1);
+      }
+      next_output_time_ms += kOutputBlockSizeMs;
+    }
+    // Advance time to next event.
+    time_now_ms = std::min(next_input_time_ms, next_output_time_ms);
+  }
+
+  std::cout << "Simulation done" << std::endl;
+
+  fclose(in_file);
+  fclose(out_file);
+  delete rtp;
+  delete next_rtp;
+  delete neteq;
+  webrtc::Trace::ReturnTrace();
+  return 0;
+}
+
+
+// Help functions.
+
+// Maps a codec type to a printable name string.
+std::string CodecName(webrtc::NetEqDecoder codec) {
+  switch (codec) {
+    case webrtc::kDecoderPCMu:
+      return "PCM-u";
+    case webrtc::kDecoderPCMa:
+      return "PCM-a";
+    case webrtc::kDecoderILBC:
+      return "iLBC";
+    case webrtc::kDecoderISAC:
+      return "iSAC";
+    case webrtc::kDecoderISACswb:
+      return "iSAC-swb (32 kHz)";
+    case webrtc::kDecoderPCM16B:
+      return "PCM16b-nb (8 kHz)";
+    case webrtc::kDecoderPCM16Bwb:
+      return "PCM16b-wb (16 kHz)";
+    case webrtc::kDecoderPCM16Bswb32kHz:
+      return "PCM16b-swb32 (32 kHz)";
+    case webrtc::kDecoderPCM16Bswb48kHz:
+      return "PCM16b-swb48 (48 kHz)";
+    case webrtc::kDecoderG722:
+      return "G.722";
+    case webrtc::kDecoderRED:
+      return "redundant audio (RED)";
+    case webrtc::kDecoderAVT:
+      return "AVT/DTMF";
+    case webrtc::kDecoderCNGnb:
+      return "comfort noise (8 kHz)";
+    case webrtc::kDecoderCNGwb:
+      return "comfort noise (16 kHz)";
+    case webrtc::kDecoderCNGswb32kHz:
+      return "comfort noise (32 kHz)";
+    case webrtc::kDecoderCNGswb48kHz:
+      return "comfort noise (48 kHz)";
+    default:
+      assert(false);
+      return "undefined";
+  }
+}
+
+// Registers all decoders in |neteq|.
+void RegisterPayloadTypes(NetEq* neteq) {
+  assert(neteq);
+  int error;
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCMu, FLAGS_pcmu);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcmu <<
+        " as " << CodecName(webrtc::kDecoderPCMu).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCMa, FLAGS_pcma);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcma <<
+        " as " << CodecName(webrtc::kDecoderPCMa).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderILBC, FLAGS_ilbc);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_ilbc <<
+        " as " << CodecName(webrtc::kDecoderILBC).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderISAC, FLAGS_isac);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_isac <<
+        " as " << CodecName(webrtc::kDecoderISAC).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderISACswb, FLAGS_isac_swb);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_isac_swb <<
+        " as " << CodecName(webrtc::kDecoderISACswb).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16B, FLAGS_pcm16b);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcm16b <<
+        " as " << CodecName(webrtc::kDecoderPCM16B).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bwb,
+                                      FLAGS_pcm16b_wb);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcm16b_wb <<
+        " as " << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb32kHz,
+                                      FLAGS_pcm16b_swb32);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb32 <<
+        " as " << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() <<
+        std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderPCM16Bswb48kHz,
+                                      FLAGS_pcm16b_swb48);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_pcm16b_swb48 <<
+        " as " << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() <<
+        std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderG722, FLAGS_g722);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_g722 <<
+        " as " << CodecName(webrtc::kDecoderG722).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderAVT, FLAGS_avt);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_avt <<
+        " as " << CodecName(webrtc::kDecoderAVT).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderRED, FLAGS_red);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_red <<
+        " as " << CodecName(webrtc::kDecoderRED).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderCNGnb, FLAGS_cn_nb);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_cn_nb <<
+        " as " << CodecName(webrtc::kDecoderCNGnb).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderCNGwb, FLAGS_cn_wb);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_cn_wb <<
+        " as " << CodecName(webrtc::kDecoderCNGwb).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb32kHz,
+                                      FLAGS_cn_swb32);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_cn_swb32 <<
+        " as " << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << std::endl;
+    exit(1);
+  }
+  error = neteq->RegisterPayloadType(webrtc::kDecoderCNGswb48kHz,
+                                     FLAGS_cn_swb48);
+  if (error) {
+    std::cerr << "Cannot register payload type " << FLAGS_cn_swb48 <<
+        " as " << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << std::endl;
+    exit(1);
+  }
+}
+
+void PrintCodecMapping() {
+  std::cout << CodecName(webrtc::kDecoderPCMu).c_str() << ": " << FLAGS_pcmu <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderPCMa).c_str() << ": " << FLAGS_pcma <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderILBC).c_str() << ": " << FLAGS_ilbc <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderISAC).c_str() << ": " << FLAGS_isac <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderISACswb).c_str() << ": " <<
+      FLAGS_isac_swb << std::endl;
+  std::cout << CodecName(webrtc::kDecoderPCM16B).c_str() << ": " <<
+      FLAGS_pcm16b << std::endl;
+  std::cout << CodecName(webrtc::kDecoderPCM16Bwb).c_str() << ": " <<
+      FLAGS_pcm16b_wb << std::endl;
+  std::cout << CodecName(webrtc::kDecoderPCM16Bswb32kHz).c_str() << ": " <<
+      FLAGS_pcm16b_swb32 << std::endl;
+  std::cout << CodecName(webrtc::kDecoderPCM16Bswb48kHz).c_str() << ": " <<
+      FLAGS_pcm16b_swb48 << std::endl;
+  std::cout << CodecName(webrtc::kDecoderG722).c_str() << ": " << FLAGS_g722 <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderAVT).c_str() << ": " << FLAGS_avt <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderRED).c_str() << ": " << FLAGS_red <<
+      std::endl;
+  std::cout << CodecName(webrtc::kDecoderCNGnb).c_str() << ": " <<
+      FLAGS_cn_nb << std::endl;
+  std::cout << CodecName(webrtc::kDecoderCNGwb).c_str() << ": " <<
+      FLAGS_cn_wb << std::endl;
+  std::cout << CodecName(webrtc::kDecoderCNGswb32kHz).c_str() << ": " <<
+      FLAGS_cn_swb32 << std::endl;
+  std::cout << CodecName(webrtc::kDecoderCNGswb48kHz).c_str() << ": " <<
+      FLAGS_cn_swb48 << std::endl;
+}
+
+size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file,
+                      webrtc::scoped_ptr<int16_t[]>* replacement_audio,
+                      webrtc::scoped_ptr<uint8_t[]>* payload,
+                      size_t* payload_mem_size_bytes,
+                      size_t* frame_size_samples,
+                      WebRtcRTPHeader* rtp_header,
+                      NETEQTEST_RTPpacket* next_rtp) {
+  size_t payload_len = 0;
+  // Check for CNG.
+  if (IsComfortNosie(rtp_header->header.payloadType)) {
+    // If CNG, simply insert a zero-energy one-byte payload.
+    if (*payload_mem_size_bytes < 1) {
+      (*payload).reset(new uint8_t[1]);
+      *payload_mem_size_bytes = 1;
+    }
+    (*payload)[0] = 127;  // Max attenuation of CNG.
+    payload_len = 1;
+  } else {
+    if (next_rtp->payloadLen() > 0) {
+      // Check if payload length has changed.
+      if (next_rtp->sequenceNumber() == rtp_header->header.sequenceNumber + 1) {
+        if (*frame_size_samples !=
+            next_rtp->timeStamp() - rtp_header->header.timestamp) {
+          *frame_size_samples =
+              next_rtp->timeStamp() - rtp_header->header.timestamp;
+          (*replacement_audio).reset(
+              new int16_t[*frame_size_samples]);
+          *payload_mem_size_bytes = 2 * *frame_size_samples;
+          (*payload).reset(new uint8_t[*payload_mem_size_bytes]);
+        }
+      }
+    }
+    // Get new speech.
+    assert((*replacement_audio).get());
+    if (CodecTimestampRate(rtp_header->header.payloadType) !=
+        CodecSampleRate(rtp_header->header.payloadType) ||
+        rtp_header->header.payloadType == FLAGS_red ||
+        rtp_header->header.payloadType == FLAGS_avt) {
+      // Some codecs have different sample and timestamp rates. And neither
+      // RED nor DTMF is supported for replacement.
+      std::cerr << "Codec not supported for audio replacement." <<
+          std::endl;
+      webrtc::Trace::ReturnTrace();
+      exit(1);
+    }
+    assert(*frame_size_samples > 0);
+    if (!replacement_audio_file->Read(*frame_size_samples,
+                                      (*replacement_audio).get())) {
+      std::cerr << "Could no read replacement audio file." << std::endl;
+      webrtc::Trace::ReturnTrace();
+      exit(1);
+    }
+    // Encode it as PCM16.
+    assert((*payload).get());
+    payload_len = WebRtcPcm16b_Encode((*replacement_audio).get(),
+                                      static_cast<int16_t>(*frame_size_samples),
+                                      (*payload).get());
+    assert(payload_len == 2 * *frame_size_samples);
+    // Change payload type to PCM16.
+    switch (CodecSampleRate(rtp_header->header.payloadType)) {
+      case 8000:
+        rtp_header->header.payloadType = FLAGS_pcm16b;
+        break;
+      case 16000:
+        rtp_header->header.payloadType = FLAGS_pcm16b_wb;
+        break;
+      case 32000:
+        rtp_header->header.payloadType = FLAGS_pcm16b_swb32;
+        break;
+      case 48000:
+        rtp_header->header.payloadType = FLAGS_pcm16b_swb48;
+        break;
+      default:
+        std::cerr << "Payload type " <<
+            static_cast<int>(rtp_header->header.payloadType) <<
+            " not supported or unknown." << std::endl;
+        webrtc::Trace::ReturnTrace();
+        exit(1);
+        assert(false);
+    }
+  }
+  return payload_len;
+}
+
+int CodecSampleRate(uint8_t payload_type) {
+  if (payload_type == FLAGS_pcmu ||
+      payload_type == FLAGS_pcma ||
+      payload_type == FLAGS_ilbc ||
+      payload_type == FLAGS_pcm16b ||
+      payload_type == FLAGS_cn_nb) {
+    return 8000;
+  } else if (payload_type == FLAGS_isac ||
+      payload_type == FLAGS_pcm16b_wb ||
+      payload_type == FLAGS_g722 ||
+      payload_type == FLAGS_cn_wb) {
+    return 16000;
+  } else if (payload_type == FLAGS_isac_swb ||
+      payload_type == FLAGS_pcm16b_swb32 ||
+      payload_type == FLAGS_cn_swb32) {
+    return 32000;
+  } else if (payload_type == FLAGS_pcm16b_swb48 ||
+      payload_type == FLAGS_cn_swb48) {
+    return 48000;
+  } else if (payload_type == FLAGS_avt ||
+      payload_type == FLAGS_red) {
+      return 0;
+  } else {
+    return -1;
+  }
+}
+
+int CodecTimestampRate(uint8_t payload_type) {
+  if (payload_type == FLAGS_g722) {
+    return 8000;
+  } else {
+    return CodecSampleRate(payload_type);
+  }
+}
+
+bool IsComfortNosie(uint8_t payload_type) {
+  if (payload_type == FLAGS_cn_nb ||
+      payload_type == FLAGS_cn_wb ||
+      payload_type == FLAGS_cn_swb32 ||
+      payload_type == FLAGS_cn_swb48) {
+    return true;
+  } else {
+    return false;
+  }
+}
diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.cc b/webrtc/modules/audio_coding/neteq/tools/packet.cc
new file mode 100644
index 0000000..d8fb713
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/packet.cc
@@ -0,0 +1,155 @@
+/*
+ *  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/neteq/tools/packet.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+
+namespace webrtc {
+namespace test {
+
+Packet::Packet(uint8_t* packet_memory,
+               size_t allocated_bytes,
+               double time_ms,
+               const RtpHeaderParser& parser)
+    : payload_memory_(packet_memory),
+      payload_(NULL),
+      packet_length_bytes_(allocated_bytes),
+      payload_length_bytes_(0),
+      virtual_packet_length_bytes_(allocated_bytes),
+      virtual_payload_length_bytes_(0),
+      time_ms_(time_ms) {
+  valid_header_ = ParseHeader(parser);
+}
+
+Packet::Packet(uint8_t* packet_memory,
+               size_t allocated_bytes,
+               size_t virtual_packet_length_bytes,
+               double time_ms,
+               const RtpHeaderParser& parser)
+    : payload_memory_(packet_memory),
+      payload_(NULL),
+      packet_length_bytes_(allocated_bytes),
+      payload_length_bytes_(0),
+      virtual_packet_length_bytes_(virtual_packet_length_bytes),
+      virtual_payload_length_bytes_(0),
+      time_ms_(time_ms) {
+  valid_header_ = ParseHeader(parser);
+}
+
+Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
+    : payload_memory_(packet_memory),
+      payload_(NULL),
+      packet_length_bytes_(allocated_bytes),
+      payload_length_bytes_(0),
+      virtual_packet_length_bytes_(allocated_bytes),
+      virtual_payload_length_bytes_(0),
+      time_ms_(time_ms) {
+  scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+  valid_header_ = ParseHeader(*parser);
+}
+
+Packet::Packet(uint8_t* packet_memory,
+               size_t allocated_bytes,
+               size_t virtual_packet_length_bytes,
+               double time_ms)
+    : payload_memory_(packet_memory),
+      payload_(NULL),
+      packet_length_bytes_(allocated_bytes),
+      payload_length_bytes_(0),
+      virtual_packet_length_bytes_(virtual_packet_length_bytes),
+      virtual_payload_length_bytes_(0),
+      time_ms_(time_ms) {
+  scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+  valid_header_ = ParseHeader(*parser);
+}
+
+bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
+  //
+  //  0                   1                    2                   3
+  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3  4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  // |1|   block PT  |  timestamp offset         |   block length    |
+  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  // |1|    ...                                                      |
+  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  // |0|   block PT  |
+  // +-+-+-+-+-+-+-+-+
+  //
+
+  assert(payload_);
+  const uint8_t* payload_ptr = payload_;
+  const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
+
+  // Find all RED headers with the extension bit set to 1. That is, all headers
+  // but the last one.
+  while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
+    RTPHeader* header = new RTPHeader;
+    CopyToHeader(header);
+    header->payloadType = payload_ptr[0] & 0x7F;
+    uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
+    header->timestamp -= offset;
+    headers->push_front(header);
+    payload_ptr += 4;
+  }
+  // Last header.
+  assert(payload_ptr < payload_end_ptr);
+  if (payload_ptr >= payload_end_ptr) {
+    return false;  // Payload too short.
+  }
+  RTPHeader* header = new RTPHeader;
+  CopyToHeader(header);
+  header->payloadType = payload_ptr[0] & 0x7F;
+  headers->push_front(header);
+  return true;
+}
+
+void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
+  while (!headers->empty()) {
+    delete headers->front();
+    headers->pop_front();
+  }
+}
+
+bool Packet::ParseHeader(const RtpHeaderParser& parser) {
+  bool valid_header = parser.Parse(
+      payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_);
+  assert(valid_header);
+  if (!valid_header) {
+    return false;
+  }
+  assert(header_.headerLength <= packet_length_bytes_);
+  payload_ = &payload_memory_[header_.headerLength];
+  assert(packet_length_bytes_ >= header_.headerLength);
+  payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
+  assert(virtual_packet_length_bytes_ >= header_.headerLength);
+  virtual_payload_length_bytes_ =
+      virtual_packet_length_bytes_ - header_.headerLength;
+  return true;
+}
+
+void Packet::CopyToHeader(RTPHeader* destination) const {
+  destination->markerBit = header_.markerBit;
+  destination->payloadType = header_.payloadType;
+  destination->sequenceNumber = header_.sequenceNumber;
+  destination->timestamp = header_.timestamp;
+  destination->ssrc = header_.ssrc;
+  destination->numCSRCs = header_.numCSRCs;
+  destination->paddingLength = header_.paddingLength;
+  destination->headerLength = header_.headerLength;
+  destination->payload_type_frequency = header_.payload_type_frequency;
+  memcpy(&destination->arrOfCSRCs,
+         &header_.arrOfCSRCs,
+         sizeof(header_.arrOfCSRCs));
+  memcpy(
+      &destination->extension, &header_.extension, sizeof(header_.extension));
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.h b/webrtc/modules/audio_coding/neteq/tools/packet.h
new file mode 100644
index 0000000..eb8ce28
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/packet.h
@@ -0,0 +1,117 @@
+/*
+ *  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_NETEQ_TOOLS_PACKET_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_PACKET_H_
+
+#include <list>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/common_types.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class RtpHeaderParser;
+
+namespace test {
+
+// Class for handling RTP packets in test applications.
+class Packet {
+ public:
+  // Creates a packet, with the packet payload (including header bytes) in
+  // |packet_memory|. The length of |packet_memory| is |allocated_bytes|.
+  // The new object assumes ownership of |packet_memory| and will delete it
+  // when the Packet object is deleted. The |time_ms| is an extra time
+  // associated with this packet, typically used to denote arrival time.
+  // The first bytes in |packet_memory| will be parsed using |parser|.
+  Packet(uint8_t* packet_memory,
+         size_t allocated_bytes,
+         double time_ms,
+         const RtpHeaderParser& parser);
+
+  // Same as above, but with the extra argument |virtual_packet_length_bytes|.
+  // This is typically used when reading RTP dump files that only contain the
+  // RTP headers, and no payload (a.k.a RTP dummy files or RTP light). The
+  // |virtual_packet_length_bytes| tells what size the packet had on wire,
+  // including the now discarded payload, whereas |allocated_bytes| is the
+  // length of the remaining payload (typically only the RTP header).
+  Packet(uint8_t* packet_memory,
+         size_t allocated_bytes,
+         size_t virtual_packet_length_bytes,
+         double time_ms,
+         const RtpHeaderParser& parser);
+
+  // The following two constructors are the same as above, but without a
+  // parser. Note that when the object is constructed using any of these
+  // methods, the header will be parsed using a default RtpHeaderParser object.
+  // In particular, RTP header extensions won't be parsed.
+  Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms);
+
+  Packet(uint8_t* packet_memory,
+         size_t allocated_bytes,
+         size_t virtual_packet_length_bytes,
+         double time_ms);
+
+  virtual ~Packet() {}
+
+  // Parses the first bytes of the RTP payload, interpreting them as RED headers
+  // according to RFC 2198. The headers will be inserted into |headers|. The
+  // caller of the method assumes ownership of the objects in the list, and
+  // must delete them properly.
+  bool ExtractRedHeaders(std::list<RTPHeader*>* headers) const;
+
+  // Deletes all RTPHeader objects in |headers|, but does not delete |headers|
+  // itself.
+  static void DeleteRedHeaders(std::list<RTPHeader*>* headers);
+
+  const uint8_t* payload() const { return payload_; }
+
+  size_t packet_length_bytes() const { return packet_length_bytes_; }
+
+  size_t payload_length_bytes() const { return payload_length_bytes_; }
+
+  size_t virtual_packet_length_bytes() const {
+    return virtual_packet_length_bytes_;
+  }
+
+  size_t virtual_payload_length_bytes() const {
+    return virtual_payload_length_bytes_;
+  }
+
+  const RTPHeader& header() const { return header_; }
+
+  void set_time_ms(double time) { time_ms_ = time; }
+  double time_ms() const { return time_ms_; }
+  bool valid_header() const { return valid_header_; }
+
+ private:
+  bool ParseHeader(const RtpHeaderParser& parser);
+  void CopyToHeader(RTPHeader* destination) const;
+
+  RTPHeader header_;
+  scoped_ptr<uint8_t[]> payload_memory_;
+  const uint8_t* payload_;            // First byte after header.
+  const size_t packet_length_bytes_;  // Total length of packet.
+  size_t payload_length_bytes_;  // Length of the payload, after RTP header.
+                                 // Zero for dummy RTP packets.
+  // Virtual lengths are used when parsing RTP header files (dummy RTP files).
+  const size_t virtual_packet_length_bytes_;
+  size_t virtual_payload_length_bytes_;
+  double time_ms_;     // Used to denote a packet's arrival time.
+  bool valid_header_;  // Set by the RtpHeaderParser.
+
+  DISALLOW_COPY_AND_ASSIGN(Packet);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_PACKET_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/packet_source.h b/webrtc/modules/audio_coding/neteq/tools/packet_source.h
new file mode 100644
index 0000000..c539b8e
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/packet_source.h
@@ -0,0 +1,36 @@
+/*
+ *  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_NETEQ_TOOLS_PACKET_SOURCE_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_PACKET_SOURCE_H_
+
+#include "webrtc/base/constructormagic.h"
+
+namespace webrtc {
+namespace test {
+
+class Packet;
+
+// Interface class for an object delivering RTP packets to test applications.
+class PacketSource {
+ public:
+  PacketSource() {}
+  virtual ~PacketSource() {}
+
+  // Returns a pointer to the next packet.
+  virtual Packet* NextPacket() = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PacketSource);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_PACKET_SOURCE_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/packet_unittest.cc b/webrtc/modules/audio_coding/neteq/tools/packet_unittest.cc
new file mode 100644
index 0000000..df844ee
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/packet_unittest.cc
@@ -0,0 +1,202 @@
+/*
+ *  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.
+ */
+
+// Unit tests for test Packet class.
+
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
+
+#include "gtest/gtest.h"
+
+namespace webrtc {
+namespace test {
+
+namespace {
+const int kHeaderLengthBytes = 12;
+
+void MakeRtpHeader(int payload_type,
+                   int seq_number,
+                   uint32_t timestamp,
+                   uint32_t ssrc,
+                   uint8_t* rtp_data) {
+  rtp_data[0] = 0x80;
+  rtp_data[1] = payload_type & 0xFF;
+  rtp_data[2] = (seq_number >> 8) & 0xFF;
+  rtp_data[3] = (seq_number) & 0xFF;
+  rtp_data[4] = (timestamp >> 24) & 0xFF;
+  rtp_data[5] = (timestamp >> 16) & 0xFF;
+  rtp_data[6] = (timestamp >> 8) & 0xFF;
+  rtp_data[7] = timestamp & 0xFF;
+  rtp_data[8] = (ssrc >> 24) & 0xFF;
+  rtp_data[9] = (ssrc >> 16) & 0xFF;
+  rtp_data[10] = (ssrc >> 8) & 0xFF;
+  rtp_data[11] = ssrc & 0xFF;
+}
+}  // namespace
+
+TEST(TestPacket, RegularPacket) {
+  const size_t kPacketLengthBytes = 100;
+  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
+  const uint8_t kPayloadType = 17;
+  const uint16_t kSequenceNumber = 4711;
+  const uint32_t kTimestamp = 47114711;
+  const uint32_t kSsrc = 0x12345678;
+  MakeRtpHeader(
+      kPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
+  const double kPacketTime = 1.0;
+  // Hand over ownership of |packet_memory| to |packet|.
+  Packet packet(packet_memory, kPacketLengthBytes, kPacketTime);
+  ASSERT_TRUE(packet.valid_header());
+  EXPECT_EQ(kPayloadType, packet.header().payloadType);
+  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
+  EXPECT_EQ(kTimestamp, packet.header().timestamp);
+  EXPECT_EQ(kSsrc, packet.header().ssrc);
+  EXPECT_EQ(0, packet.header().numCSRCs);
+  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
+            packet.payload_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
+            packet.virtual_payload_length_bytes());
+  EXPECT_EQ(kPacketTime, packet.time_ms());
+}
+
+TEST(TestPacket, DummyPacket) {
+  const size_t kPacketLengthBytes = kHeaderLengthBytes;  // Only RTP header.
+  const size_t kVirtualPacketLengthBytes = 100;
+  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
+  const uint8_t kPayloadType = 17;
+  const uint16_t kSequenceNumber = 4711;
+  const uint32_t kTimestamp = 47114711;
+  const uint32_t kSsrc = 0x12345678;
+  MakeRtpHeader(
+      kPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
+  const double kPacketTime = 1.0;
+  // Hand over ownership of |packet_memory| to |packet|.
+  Packet packet(packet_memory,
+                kPacketLengthBytes,
+                kVirtualPacketLengthBytes,
+                kPacketTime);
+  ASSERT_TRUE(packet.valid_header());
+  EXPECT_EQ(kPayloadType, packet.header().payloadType);
+  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
+  EXPECT_EQ(kTimestamp, packet.header().timestamp);
+  EXPECT_EQ(kSsrc, packet.header().ssrc);
+  EXPECT_EQ(0, packet.header().numCSRCs);
+  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
+            packet.payload_length_bytes());
+  EXPECT_EQ(kVirtualPacketLengthBytes, packet.virtual_packet_length_bytes());
+  EXPECT_EQ(kVirtualPacketLengthBytes - kHeaderLengthBytes,
+            packet.virtual_payload_length_bytes());
+  EXPECT_EQ(kPacketTime, packet.time_ms());
+}
+
+namespace {
+// Writes one RED block header starting at |rtp_data|, according to RFC 2198.
+// returns the number of bytes written (1 or 4).
+//
+// Format if |last_payoad| is false:
+// 0                   1                    2                   3
+// 0 1 2 3 4 5 6 7 8 9 0 1 2 3  4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |1|   block PT  |  timestamp offset         |   block length    |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// Format if |last_payoad| is true:
+// 0 1 2 3 4 5 6 7
+// +-+-+-+-+-+-+-+-+
+// |0|   Block PT  |
+// +-+-+-+-+-+-+-+-+
+
+int MakeRedHeader(int payload_type,
+                  uint32_t timestamp_offset,
+                  int block_length,
+                  bool last_payload,
+                  uint8_t* rtp_data) {
+  rtp_data[0] = 0x80 | (payload_type & 0x7F);  // Set the first bit to 1.
+  if (last_payload) {
+    rtp_data[0] &= 0x7F;  // Reset the first but to 0 to indicate last block.
+    return 1;
+  }
+  rtp_data[1] = timestamp_offset >> 6;
+  rtp_data[2] = (timestamp_offset & 0x3F) << 2;
+  rtp_data[2] |= block_length >> 8;
+  rtp_data[3] = block_length & 0xFF;
+  return 4;
+}
+}  // namespace
+
+TEST(TestPacket, RED) {
+  const size_t kPacketLengthBytes = 100;
+  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
+  const uint8_t kRedPayloadType = 17;
+  const uint16_t kSequenceNumber = 4711;
+  const uint32_t kTimestamp = 47114711;
+  const uint32_t kSsrc = 0x12345678;
+  MakeRtpHeader(
+      kRedPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
+  // Create four RED headers.
+  // Payload types are just the same as the block index the offset is 100 times
+  // the block index.
+  const int kRedBlocks = 4;
+  uint8_t* payload_ptr =
+      &packet_memory[kHeaderLengthBytes];  // First byte after header.
+  for (int i = 0; i < kRedBlocks; ++i) {
+    int payload_type = i;
+    // Offset value is not used for the last block.
+    uint32_t timestamp_offset = 100 * i;
+    int block_length = 10 * i;
+    bool last_block = (i == kRedBlocks - 1) ? true : false;
+    payload_ptr += MakeRedHeader(
+        payload_type, timestamp_offset, block_length, last_block, payload_ptr);
+  }
+  const double kPacketTime = 1.0;
+  // Hand over ownership of |packet_memory| to |packet|.
+  Packet packet(packet_memory, kPacketLengthBytes, kPacketTime);
+  ASSERT_TRUE(packet.valid_header());
+  EXPECT_EQ(kRedPayloadType, packet.header().payloadType);
+  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
+  EXPECT_EQ(kTimestamp, packet.header().timestamp);
+  EXPECT_EQ(kSsrc, packet.header().ssrc);
+  EXPECT_EQ(0, packet.header().numCSRCs);
+  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
+            packet.payload_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
+  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
+            packet.virtual_payload_length_bytes());
+  EXPECT_EQ(kPacketTime, packet.time_ms());
+  std::list<RTPHeader*> red_headers;
+  EXPECT_TRUE(packet.ExtractRedHeaders(&red_headers));
+  EXPECT_EQ(kRedBlocks, static_cast<int>(red_headers.size()));
+  int block_index = 0;
+  for (std::list<RTPHeader*>::reverse_iterator it = red_headers.rbegin();
+       it != red_headers.rend();
+       ++it) {
+    // Reading list from the back, since the extraction puts the main payload
+    // (which is the last one on wire) first.
+    RTPHeader* red_block = *it;
+    EXPECT_EQ(block_index, red_block->payloadType);
+    EXPECT_EQ(kSequenceNumber, red_block->sequenceNumber);
+    if (block_index == kRedBlocks - 1) {
+      // Last block has zero offset per definition.
+      EXPECT_EQ(kTimestamp, red_block->timestamp);
+    } else {
+      EXPECT_EQ(kTimestamp - 100 * block_index, red_block->timestamp);
+    }
+    EXPECT_EQ(kSsrc, red_block->ssrc);
+    EXPECT_EQ(0, red_block->numCSRCs);
+    ++block_index;
+  }
+  Packet::DeleteRedHeaders(&red_headers);
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc
new file mode 100644
index 0000000..773cc2c
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/rtp_analyze.cc
@@ -0,0 +1,147 @@
+/*
+ *  Copyright (c) 2012 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 <assert.h>
+#include <stdio.h>
+#include <vector>
+
+#include "google/gflags.h"
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
+#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+// Flag validator.
+static bool ValidatePayloadType(const char* flagname, int32_t value) {
+  if (value >= 0 && value <= 127)  // Value is ok.
+    return true;
+  printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
+  return false;
+}
+static bool ValidateExtensionId(const char* flagname, int32_t value) {
+  if (value > 0 && value <= 255)  // Value is ok.
+    return true;
+  printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value));
+  return false;
+}
+
+// Define command line flags.
+DEFINE_int32(red, 117, "RTP payload type for RED");
+static const bool red_dummy =
+    google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType);
+DEFINE_int32(audio_level, 1, "Extension ID for audio level (RFC 6464)");
+static const bool audio_level_dummy =
+    google::RegisterFlagValidator(&FLAGS_audio_level, &ValidateExtensionId);
+
+int main(int argc, char* argv[]) {
+  std::string program_name = argv[0];
+  std::string usage =
+      "Tool for parsing an RTP dump file to text output.\n"
+      "Run " +
+      program_name +
+      " --helpshort for usage.\n"
+      "Example usage:\n" +
+      program_name + " input.rtp output.txt\n\n" +
+      "Output is sent to stdout if no output file is given." +
+      "Note that this tool can read files with our without payloads.";
+  google::SetUsageMessage(usage);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  if (argc != 2 && argc != 3) {
+    // Print usage information.
+    printf("%s", google::ProgramUsage());
+    return 0;
+  }
+
+  FILE* in_file = fopen(argv[1], "rb");
+  if (!in_file) {
+    printf("Cannot open input file %s\n", argv[1]);
+    return -1;
+  }
+  printf("Input file: %s\n", argv[1]);
+  webrtc::scoped_ptr<webrtc::test::RtpFileSource> file_source(
+      webrtc::test::RtpFileSource::Create(argv[1]));
+  assert(file_source.get());
+  // Set RTP extension ID.
+  bool print_audio_level = false;
+  if (!google::GetCommandLineFlagInfoOrDie("audio_level").is_default) {
+    print_audio_level = true;
+    file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel,
+                                            FLAGS_audio_level);
+  }
+
+  FILE* out_file;
+  if (argc == 3) {
+    out_file = fopen(argv[2], "wt");
+    if (!out_file) {
+      printf("Cannot open output file %s\n", argv[2]);
+      return -1;
+    }
+    printf("Output file: %s\n\n", argv[2]);
+  } else {
+    out_file = stdout;
+  }
+
+  // Print file header.
+  fprintf(out_file, "SeqNo  TimeStamp   SendTime  Size    PT  M       SSRC");
+  if (print_audio_level) {
+    fprintf(out_file, " AuLvl (V)");
+  }
+  fprintf(out_file, "\n");
+
+  webrtc::scoped_ptr<webrtc::test::Packet> packet;
+  while (!file_source->EndOfFile()) {
+    packet.reset(file_source->NextPacket());
+    if (!packet.get()) {
+      // This is probably an RTCP packet. Move on to the next one.
+      continue;
+    }
+    assert(packet.get());
+    // Write packet data to file.
+    fprintf(out_file,
+            "%5u %10u %10u %5i %5i %2i %#08X",
+            packet->header().sequenceNumber,
+            packet->header().timestamp,
+            static_cast<unsigned int>(packet->time_ms()),
+            static_cast<int>(packet->packet_length_bytes()),
+            packet->header().payloadType,
+            packet->header().markerBit,
+            packet->header().ssrc);
+    if (print_audio_level && packet->header().extension.hasAudioLevel) {
+      // |audioLevel| consists of one bit for "V" and then 7 bits level.
+      fprintf(out_file,
+              " %5u (%1i)",
+              packet->header().extension.audioLevel & 0x7F,
+              (packet->header().extension.audioLevel & 0x80) == 0 ? 0 : 1);
+    }
+    fprintf(out_file, "\n");
+
+    if (packet->header().payloadType == FLAGS_red) {
+      std::list<webrtc::RTPHeader*> red_headers;
+      packet->ExtractRedHeaders(&red_headers);
+      while (!red_headers.empty()) {
+        webrtc::RTPHeader* red = red_headers.front();
+        assert(red);
+        fprintf(out_file,
+                "* %5u %10u %10u %5i\n",
+                red->sequenceNumber,
+                red->timestamp,
+                static_cast<unsigned int>(packet->time_ms()),
+                red->payloadType);
+        red_headers.pop_front();
+        delete red;
+      }
+    }
+  }
+
+  fclose(in_file);
+  fclose(out_file);
+
+  return 0;
+}
diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc
new file mode 100644
index 0000000..8278635
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc
@@ -0,0 +1,140 @@
+/*
+ *  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/neteq/tools/rtp_file_source.h"
+
+#include <assert.h>
+#include <string.h>
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+
+namespace webrtc {
+namespace test {
+
+RtpFileSource* RtpFileSource::Create(const std::string& file_name) {
+  RtpFileSource* source = new RtpFileSource;
+  assert(source);
+  if (!source->OpenFile(file_name) || !source->SkipFileHeader()) {
+    assert(false);
+    delete source;
+    return NULL;
+  }
+  return source;
+}
+
+RtpFileSource::~RtpFileSource() {
+  if (in_file_)
+    fclose(in_file_);
+}
+
+bool RtpFileSource::RegisterRtpHeaderExtension(RTPExtensionType type,
+                                               uint8_t id) {
+  assert(parser_.get());
+  return parser_->RegisterRtpHeaderExtension(type, id);
+}
+
+Packet* RtpFileSource::NextPacket() {
+  uint16_t length;
+  if (fread(&length, sizeof(uint16_t), 1, in_file_) == 0) {
+    assert(false);
+    return NULL;
+  }
+  length = ntohs(length);
+
+  uint16_t plen;
+  if (fread(&plen, sizeof(uint16_t), 1, in_file_) == 0) {
+    assert(false);
+    return NULL;
+  }
+  plen = ntohs(plen);
+
+  uint32_t offset;
+  if (fread(&offset, sizeof(uint32_t), 1, in_file_) == 0) {
+    assert(false);
+    return NULL;
+  }
+
+  // Use length here because a plen of 0 specifies RTCP.
+  size_t packet_size_bytes = length - kPacketHeaderSize;
+  if (packet_size_bytes <= 0) {
+    // May be an RTCP packet.
+    return NULL;
+  }
+  uint8_t* packet_memory = new uint8_t[packet_size_bytes];
+  if (fread(packet_memory, 1, packet_size_bytes, in_file_) !=
+      packet_size_bytes) {
+    assert(false);
+    delete[] packet_memory;
+    return NULL;
+  }
+  Packet* packet = new Packet(
+      packet_memory, packet_size_bytes, plen, ntohl(offset), *parser_.get());
+  if (!packet->valid_header()) {
+    assert(false);
+    delete packet;
+    return NULL;
+  }
+  return packet;
+}
+
+bool RtpFileSource::EndOfFile() const {
+  assert(in_file_);
+  return ftell(in_file_) >= file_end_;
+}
+
+RtpFileSource::RtpFileSource()
+    : PacketSource(),
+      in_file_(NULL),
+      file_end_(-1),
+      parser_(RtpHeaderParser::Create()) {}
+
+bool RtpFileSource::OpenFile(const std::string& file_name) {
+  in_file_ = fopen(file_name.c_str(), "rb");
+  assert(in_file_);
+  if (in_file_ == NULL) {
+    return false;
+  }
+
+  // Find out how long the file is.
+  fseek(in_file_, 0, SEEK_END);
+  file_end_ = ftell(in_file_);
+  rewind(in_file_);
+  return true;
+}
+
+bool RtpFileSource::SkipFileHeader() {
+  char firstline[kFirstLineLength];
+  assert(in_file_);
+  if (fgets(firstline, kFirstLineLength, in_file_) == NULL) {
+    assert(false);
+    return false;
+  }
+  // Check that the first line is ok.
+  if ((strncmp(firstline, "#!rtpplay1.0", 12) != 0) &&
+      (strncmp(firstline, "#!RTPencode1.0", 14) != 0)) {
+    assert(false);
+    return false;
+  }
+  // Skip the file header.
+  if (fseek(in_file_, kRtpFileHeaderSize, SEEK_CUR) != 0) {
+    assert(false);
+    return false;
+  }
+  return true;
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h
new file mode 100644
index 0000000..527018e
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h
@@ -0,0 +1,66 @@
+/*
+ *  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_NETEQ_TOOLS_RTP_FILE_SOURCE_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RTP_FILE_SOURCE_H_
+
+#include <stdio.h>
+#include <string>
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/common_types.h"
+#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+class RtpHeaderParser;
+
+namespace test {
+
+class RtpFileSource : public PacketSource {
+ public:
+  // Creates an RtpFileSource reading from |file_name|. If the file cannot be
+  // opened, or has the wrong format, NULL will be returned.
+  static RtpFileSource* Create(const std::string& file_name);
+
+  virtual ~RtpFileSource();
+
+  // Registers an RTP header extension and binds it to |id|.
+  virtual bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
+
+  // Returns a pointer to the next packet.
+  virtual Packet* NextPacket();
+
+  // Returns true if the end of file has been reached.
+  virtual bool EndOfFile() const;
+
+ private:
+  static const int kFirstLineLength = 40;
+  static const int kRtpFileHeaderSize = 4 + 4 + 4 + 2 + 2;
+  static const size_t kPacketHeaderSize = 8;
+
+  RtpFileSource();
+
+  bool OpenFile(const std::string& file_name);
+
+  bool SkipFileHeader();
+
+  FILE* in_file_;
+  int64_t file_end_;
+  scoped_ptr<RtpHeaderParser> parser_;
+
+  DISALLOW_COPY_AND_ASSIGN(RtpFileSource);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RTP_FILE_SOURCE_H_
diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_generator.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.cc
new file mode 100644
index 0000000..17ac209
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.cc
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2013 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 <assert.h>
+
+#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h"
+
+namespace webrtc {
+namespace test {
+
+uint32_t RtpGenerator::GetRtpHeader(uint8_t payload_type,
+                                    size_t payload_length_samples,
+                                    WebRtcRTPHeader* rtp_header) {
+  assert(rtp_header);
+  if (!rtp_header) {
+    return 0;
+  }
+  rtp_header->header.sequenceNumber = seq_number_++;
+  rtp_header->header.timestamp = timestamp_;
+  timestamp_ += static_cast<uint32_t>(payload_length_samples);
+  rtp_header->header.payloadType = payload_type;
+  rtp_header->header.markerBit = false;
+  rtp_header->header.ssrc = ssrc_;
+  rtp_header->header.numCSRCs = 0;
+  rtp_header->frameType = kAudioFrameSpeech;
+
+  uint32_t this_send_time = next_send_time_ms_;
+  assert(samples_per_ms_ > 0);
+  next_send_time_ms_ += ((1.0 + drift_factor_) * payload_length_samples) /
+      samples_per_ms_;
+  return this_send_time;
+}
+
+void RtpGenerator::set_drift_factor(double factor) {
+  if (factor > -1.0) {
+    drift_factor_ = factor;
+  }
+}
+
+}  // namespace test
+}  // namespace webrtc
diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h
new file mode 100644
index 0000000..d3824c8
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2012 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_NETEQ_TOOLS_RTP_GENERATOR_H_
+#define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RTP_GENERATOR_H_
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+namespace test {
+
+// Class for generating RTP headers.
+class RtpGenerator {
+ public:
+  RtpGenerator(int samples_per_ms,
+               uint16_t start_seq_number = 0,
+               uint32_t start_timestamp = 0,
+               uint32_t start_send_time_ms = 0,
+               uint32_t ssrc = 0x12345678)
+      : seq_number_(start_seq_number),
+        timestamp_(start_timestamp),
+        next_send_time_ms_(start_send_time_ms),
+        ssrc_(ssrc),
+        samples_per_ms_(samples_per_ms),
+        drift_factor_(0.0) {
+  }
+
+  // Writes the next RTP header to |rtp_header|, which will be of type
+  // |payload_type|. Returns the send time for this packet (in ms). The value of
+  // |payload_length_samples| determines the send time for the next packet.
+  uint32_t GetRtpHeader(uint8_t payload_type, size_t payload_length_samples,
+                        WebRtcRTPHeader* rtp_header);
+
+  void set_drift_factor(double factor);
+
+ private:
+  uint16_t seq_number_;
+  uint32_t timestamp_;
+  uint32_t next_send_time_ms_;
+  const uint32_t ssrc_;
+  const int samples_per_ms_;
+  double drift_factor_;
+  DISALLOW_COPY_AND_ASSIGN(RtpGenerator);
+};
+
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RTP_GENERATOR_H_