diff --git a/talk/libjingle.gyp b/talk/libjingle.gyp
index d8288b7..abeeb55 100755
--- a/talk/libjingle.gyp
+++ b/talk/libjingle.gyp
@@ -438,8 +438,6 @@
         'media/base/cryptoparams.h',
         'media/base/device.h',
         'media/base/fakescreencapturerfactory.h',
-        'media/base/filemediaengine.cc',
-        'media/base/filemediaengine.h',
         'media/base/hybriddataengine.h',
         'media/base/mediachannel.h',
         'media/base/mediacommon.h',
diff --git a/talk/libjingle_tests.gyp b/talk/libjingle_tests.gyp
index 80cd1fa..c1f9ab3 100755
--- a/talk/libjingle_tests.gyp
+++ b/talk/libjingle_tests.gyp
@@ -84,7 +84,6 @@
       'sources': [
         'media/base/capturemanager_unittest.cc',
         'media/base/codec_unittest.cc',
-        'media/base/filemediaengine_unittest.cc',
         'media/base/rtpdataengine_unittest.cc',
         'media/base/rtpdump_unittest.cc',
         'media/base/rtputils_unittest.cc',
diff --git a/talk/media/base/filemediaengine.cc b/talk/media/base/filemediaengine.cc
deleted file mode 100644
index 5f4c839..0000000
--- a/talk/media/base/filemediaengine.cc
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "talk/media/base/filemediaengine.h"
-
-#include <algorithm>
-#include <limits.h>
-
-#include "talk/media/base/rtpdump.h"
-#include "talk/media/base/rtputils.h"
-#include "talk/media/base/streamparams.h"
-#include "webrtc/base/buffer.h"
-#include "webrtc/base/event.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/pathutils.h"
-#include "webrtc/base/stream.h"
-
-namespace cricket {
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileMediaEngine.
-///////////////////////////////////////////////////////////////////////////
-int FileMediaEngine::GetCapabilities() {
-  int capabilities = 0;
-  if (!voice_input_filename_.empty()) {
-    capabilities |= AUDIO_SEND;
-  }
-  if (!voice_output_filename_.empty()) {
-    capabilities |= AUDIO_RECV;
-  }
-  if (!video_input_filename_.empty()) {
-    capabilities |= VIDEO_SEND;
-  }
-  if (!video_output_filename_.empty()) {
-    capabilities |= VIDEO_RECV;
-  }
-  return capabilities;
-}
-
-VoiceMediaChannel* FileMediaEngine::CreateChannel(const AudioOptions& options) {
-  rtc::FileStream* input_file_stream = nullptr;
-  rtc::FileStream* output_file_stream = nullptr;
-
-  if (voice_input_filename_.empty() && voice_output_filename_.empty())
-    return nullptr;
-  if (!voice_input_filename_.empty()) {
-    input_file_stream = rtc::Filesystem::OpenFile(
-        rtc::Pathname(voice_input_filename_), "rb");
-    if (!input_file_stream) {
-      LOG(LS_ERROR) << "Not able to open the input audio stream file.";
-      return nullptr;
-    }
-  }
-
-  if (!voice_output_filename_.empty()) {
-    output_file_stream = rtc::Filesystem::OpenFile(
-        rtc::Pathname(voice_output_filename_), "wb");
-    if (!output_file_stream) {
-      delete input_file_stream;
-      LOG(LS_ERROR) << "Not able to open the output audio stream file.";
-      return nullptr;
-    }
-  }
-
-  FileVoiceChannel* channel = new FileVoiceChannel(
-      input_file_stream, output_file_stream, rtp_sender_thread_);
-  channel->SetOptions(options);
-  return channel;
-}
-
-VideoMediaChannel* FileMediaEngine::CreateVideoChannel(
-    const VideoOptions& options,
-    VoiceMediaChannel* voice_ch) {
-  rtc::FileStream* input_file_stream = NULL;
-  rtc::FileStream* output_file_stream = NULL;
-
-  if (video_input_filename_.empty() && video_output_filename_.empty())
-      return NULL;
-
-  if (!video_input_filename_.empty()) {
-    input_file_stream = rtc::Filesystem::OpenFile(
-        rtc::Pathname(video_input_filename_), "rb");
-    if (!input_file_stream) {
-      LOG(LS_ERROR) << "Not able to open the input video stream file.";
-      return NULL;
-    }
-  }
-
-  if (!video_output_filename_.empty()) {
-    output_file_stream = rtc::Filesystem::OpenFile(
-        rtc::Pathname(video_output_filename_), "wb");
-    if (!output_file_stream) {
-      delete input_file_stream;
-      LOG(LS_ERROR) << "Not able to open the output video stream file.";
-      return NULL;
-    }
-  }
-
-  FileVideoChannel* channel = new FileVideoChannel(
-      input_file_stream, output_file_stream, rtp_sender_thread_);
-  channel->SetOptions(options);
-  return channel;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Definition of RtpSenderReceiver.
-///////////////////////////////////////////////////////////////////////////
-class RtpSenderReceiver : public rtc::MessageHandler {
- public:
-  RtpSenderReceiver(MediaChannel* channel,
-                    rtc::StreamInterface* input_file_stream,
-                    rtc::StreamInterface* output_file_stream,
-                    rtc::Thread* sender_thread);
-  virtual ~RtpSenderReceiver();
-
-  // Called by media channel. Context: media channel thread.
-  bool SetSend(bool send);
-  void SetSendSsrc(uint32 ssrc);
-  void OnPacketReceived(rtc::Buffer* packet);
-
-  // Override virtual method of parent MessageHandler. Context: Worker Thread.
-  virtual void OnMessage(rtc::Message* pmsg);
-
- private:
-  // Read the next RTP dump packet, whose RTP SSRC is the same as first_ssrc_.
-  // Return true if successful.
-  bool ReadNextPacket(RtpDumpPacket* packet);
-  // Send a RTP packet to the network. The input parameter data points to the
-  // start of the RTP packet and len is the packet size. Return true if the sent
-  // size is equal to len.
-  bool SendRtpPacket(const void* data, size_t len);
-
-  MediaChannel* media_channel_;
-  rtc::scoped_ptr<rtc::StreamInterface> input_stream_;
-  rtc::scoped_ptr<rtc::StreamInterface> output_stream_;
-  rtc::scoped_ptr<RtpDumpLoopReader> rtp_dump_reader_;
-  rtc::scoped_ptr<RtpDumpWriter> rtp_dump_writer_;
-  rtc::Thread* sender_thread_;
-  bool own_sender_thread_;
-  // RTP dump packet read from the input stream.
-  RtpDumpPacket rtp_dump_packet_;
-  uint32 start_send_time_;
-  bool sending_;
-  bool first_packet_;
-  uint32 first_ssrc_;
-
-  DISALLOW_COPY_AND_ASSIGN(RtpSenderReceiver);
-};
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of RtpSenderReceiver.
-///////////////////////////////////////////////////////////////////////////
-RtpSenderReceiver::RtpSenderReceiver(
-    MediaChannel* channel,
-    rtc::StreamInterface* input_file_stream,
-    rtc::StreamInterface* output_file_stream,
-    rtc::Thread* sender_thread)
-    : media_channel_(channel),
-      input_stream_(input_file_stream),
-      output_stream_(output_file_stream),
-      sending_(false),
-      first_packet_(true) {
-  if (sender_thread == NULL) {
-    sender_thread_ = new rtc::Thread();
-    own_sender_thread_ = true;
-  } else {
-    sender_thread_ = sender_thread;
-    own_sender_thread_ = false;
-  }
-
-  if (input_stream_) {
-    rtp_dump_reader_.reset(new RtpDumpLoopReader(input_stream_.get()));
-    // Start the sender thread, which reads rtp dump records, waits based on
-    // the record timestamps, and sends the RTP packets to the network.
-    if (own_sender_thread_) {
-      sender_thread_->Start();
-    }
-  }
-
-  // Create a rtp dump writer for the output RTP dump stream.
-  if (output_stream_) {
-    rtp_dump_writer_.reset(new RtpDumpWriter(output_stream_.get()));
-  }
-}
-
-RtpSenderReceiver::~RtpSenderReceiver() {
-  if (own_sender_thread_) {
-    sender_thread_->Stop();
-    delete sender_thread_;
-  }
-}
-
-bool RtpSenderReceiver::SetSend(bool send) {
-  bool was_sending = sending_;
-  sending_ = send;
-  if (!was_sending && sending_) {
-    sender_thread_->PostDelayed(0, this);  // Wake up the send thread.
-    start_send_time_ = rtc::Time();
-  }
-  return true;
-}
-
-void RtpSenderReceiver::SetSendSsrc(uint32 ssrc) {
-  if (rtp_dump_reader_) {
-    rtp_dump_reader_->SetSsrc(ssrc);
-  }
-}
-
-void RtpSenderReceiver::OnPacketReceived(rtc::Buffer* packet) {
-  if (rtp_dump_writer_) {
-    rtp_dump_writer_->WriteRtpPacket(packet->data(), packet->size());
-  }
-}
-
-void RtpSenderReceiver::OnMessage(rtc::Message* pmsg) {
-  if (!sending_) {
-    // If the sender thread is not sending, ignore this message. The thread goes
-    // to sleep until SetSend(true) wakes it up.
-    return;
-  }
-  if (!first_packet_) {
-    // Send the previously read packet.
-    SendRtpPacket(&rtp_dump_packet_.data[0], rtp_dump_packet_.data.size());
-  }
-
-  if (ReadNextPacket(&rtp_dump_packet_)) {
-    int wait = rtc::TimeUntil(
-        start_send_time_ + rtp_dump_packet_.elapsed_time);
-    wait = std::max(0, wait);
-    sender_thread_->PostDelayed(wait, this);
-  } else {
-    sender_thread_->Quit();
-  }
-}
-
-bool RtpSenderReceiver::ReadNextPacket(RtpDumpPacket* packet) {
-  while (rtc::SR_SUCCESS == rtp_dump_reader_->ReadPacket(packet)) {
-    uint32 ssrc;
-    if (!packet->GetRtpSsrc(&ssrc)) {
-      return false;
-    }
-    if (first_packet_) {
-      first_packet_ = false;
-      first_ssrc_ = ssrc;
-    }
-    if (ssrc == first_ssrc_) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool RtpSenderReceiver::SendRtpPacket(const void* data, size_t len) {
-  if (!media_channel_)
-    return false;
-
-  rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len,
-                     kMaxRtpPacketLen);
-  return media_channel_->SendPacket(&packet);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileVoiceChannel.
-///////////////////////////////////////////////////////////////////////////
-FileVoiceChannel::FileVoiceChannel(
-    rtc::StreamInterface* input_file_stream,
-    rtc::StreamInterface* output_file_stream,
-    rtc::Thread* rtp_sender_thread)
-    : send_ssrc_(0),
-      rtp_sender_receiver_(new RtpSenderReceiver(this, input_file_stream,
-                                                 output_file_stream,
-                                                 rtp_sender_thread)) {}
-
-FileVoiceChannel::~FileVoiceChannel() {}
-
-bool FileVoiceChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) {
-  // TODO(whyuan): Check the format of RTP dump input.
-  return true;
-}
-
-bool FileVoiceChannel::SetSend(SendFlags flag) {
-  return rtp_sender_receiver_->SetSend(flag != SEND_NOTHING);
-}
-
-bool FileVoiceChannel::AddSendStream(const StreamParams& sp) {
-  if (send_ssrc_ != 0 || sp.ssrcs.size() != 1) {
-    LOG(LS_ERROR) << "FileVoiceChannel only supports one send stream.";
-    return false;
-  }
-  send_ssrc_ = sp.ssrcs[0];
-  rtp_sender_receiver_->SetSendSsrc(send_ssrc_);
-  return true;
-}
-
-bool FileVoiceChannel::RemoveSendStream(uint32 ssrc) {
-  if (ssrc != send_ssrc_)
-    return false;
-  send_ssrc_ = 0;
-  rtp_sender_receiver_->SetSendSsrc(send_ssrc_);
-  return true;
-}
-
-void FileVoiceChannel::OnPacketReceived(
-    rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
-  rtp_sender_receiver_->OnPacketReceived(packet);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Implementation of FileVideoChannel.
-///////////////////////////////////////////////////////////////////////////
-FileVideoChannel::FileVideoChannel(
-    rtc::StreamInterface* input_file_stream,
-    rtc::StreamInterface* output_file_stream,
-    rtc::Thread* rtp_sender_thread)
-    : send_ssrc_(0),
-      rtp_sender_receiver_(new RtpSenderReceiver(this, input_file_stream,
-                                                 output_file_stream,
-                                                 rtp_sender_thread)) {}
-
-FileVideoChannel::~FileVideoChannel() {}
-
-bool FileVideoChannel::SetSendCodecs(const std::vector<VideoCodec>& codecs) {
-  // TODO(whyuan): Check the format of RTP dump input.
-  return true;
-}
-
-bool FileVideoChannel::SetSend(bool send) {
-  return rtp_sender_receiver_->SetSend(send);
-}
-
-bool FileVideoChannel::AddSendStream(const StreamParams& sp) {
-  if (send_ssrc_ != 0 || sp.ssrcs.size() != 1) {
-    LOG(LS_ERROR) << "FileVideoChannel only support one send stream.";
-    return false;
-  }
-  send_ssrc_ = sp.ssrcs[0];
-  rtp_sender_receiver_->SetSendSsrc(send_ssrc_);
-  return true;
-}
-
-bool FileVideoChannel::RemoveSendStream(uint32 ssrc) {
-  if (ssrc != send_ssrc_)
-    return false;
-  send_ssrc_ = 0;
-  rtp_sender_receiver_->SetSendSsrc(send_ssrc_);
-  return true;
-}
-
-void FileVideoChannel::OnPacketReceived(
-    rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
-  rtp_sender_receiver_->OnPacketReceived(packet);
-}
-
-}  // namespace cricket
diff --git a/talk/media/base/filemediaengine.h b/talk/media/base/filemediaengine.h
deleted file mode 100644
index 88f179f..0000000
--- a/talk/media/base/filemediaengine.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TALK_MEDIA_BASE_FILEMEDIAENGINE_H_
-#define TALK_MEDIA_BASE_FILEMEDIAENGINE_H_
-
-#include <string>
-#include <vector>
-
-#include "talk/media/base/codec.h"
-#include "talk/media/base/mediachannel.h"
-#include "talk/media/base/mediaengine.h"
-#include "webrtc/base/scoped_ptr.h"
-#include "webrtc/base/stream.h"
-
-namespace rtc {
-class StreamInterface;
-}
-
-namespace cricket {
-
-// A media engine contains a capturer, an encoder, and a sender in the sender
-// side and a receiver, a decoder, and a renderer in the receiver side.
-// FileMediaEngine simulates the capturer and the encoder via an input RTP dump
-// stream and simulates the decoder and the renderer via an output RTP dump
-// stream. Depending on the parameters of the constructor, FileMediaEngine can
-// act as file voice engine, file video engine, or both. Currently, we use
-// only the RTP dump packets. TODO(whyuan): Enable RTCP packets.
-class FileMediaEngine : public MediaEngineInterface {
- public:
-  FileMediaEngine() : rtp_sender_thread_(NULL) {}
-  virtual ~FileMediaEngine() {}
-
-  // Set the file name of the input or output RTP dump for voice or video.
-  // Should be called before the channel is created.
-  void set_voice_input_filename(const std::string& filename) {
-    voice_input_filename_ = filename;
-  }
-  void set_voice_output_filename(const std::string& filename) {
-    voice_output_filename_ = filename;
-  }
-  void set_video_input_filename(const std::string& filename) {
-    video_input_filename_ = filename;
-  }
-  void set_video_output_filename(const std::string& filename) {
-    video_output_filename_ = filename;
-  }
-
-  // Should be called before codecs() and video_codecs() are called. We need to
-  // set the voice and video codecs; otherwise, Jingle initiation will fail.
-  void set_voice_codecs(const std::vector<AudioCodec>& codecs) {
-    voice_codecs_ = codecs;
-  }
-  void set_video_codecs(const std::vector<VideoCodec>& codecs) {
-    video_codecs_ = codecs;
-  }
-
-  // Implement pure virtual methods of MediaEngine.
-  virtual bool Init(rtc::Thread* worker_thread) {
-    return true;
-  }
-  virtual void Terminate() {}
-  virtual int GetCapabilities();
-  virtual VoiceMediaChannel* CreateChannel(const AudioOptions& options);
-  virtual VideoMediaChannel* CreateVideoChannel(const VideoOptions& options,
-                                                VoiceMediaChannel* voice_ch);
-  virtual AudioOptions GetAudioOptions() const { return AudioOptions(); }
-  virtual bool SetAudioOptions(const AudioOptions& options) { return true; }
-  virtual bool SetAudioDelayOffset(int offset) { return true; }
-  virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
-    return true;
-  }
-  virtual bool SetSoundDevices(const Device* in_dev, const Device* out_dev) {
-    return true;
-  }
-  virtual bool SetVideoCaptureDevice(const Device* cam_device) { return true; }
-  virtual bool SetVideoCapturer(VideoCapturer* /*capturer*/) {
-    return true;
-  }
-  virtual VideoCapturer* GetVideoCapturer() const {
-    return NULL;
-  }
-  virtual bool GetOutputVolume(int* level) {
-    *level = 0;
-    return true;
-  }
-  virtual bool SetOutputVolume(int level) { return true; }
-  virtual int GetInputLevel() { return 0; }
-  virtual bool SetLocalMonitor(bool enable) { return true; }
-  // TODO(whyuan): control channel send?
-  virtual bool SetVideoCapture(bool capture) { return true; }
-  virtual const std::vector<AudioCodec>& audio_codecs() {
-    return voice_codecs_;
-  }
-  virtual const std::vector<VideoCodec>& video_codecs() {
-    return video_codecs_;
-  }
-  virtual const std::vector<RtpHeaderExtension>& audio_rtp_header_extensions() {
-    return audio_rtp_header_extensions_;
-  }
-  virtual const std::vector<RtpHeaderExtension>& video_rtp_header_extensions() {
-    return video_rtp_header_extensions_;
-  }
-
-  virtual bool FindAudioCodec(const AudioCodec& codec) { return true; }
-  virtual bool FindVideoCodec(const VideoCodec& codec) { return true; }
-  virtual void SetVoiceLogging(int min_sev, const char* filter) {}
-  virtual void SetVideoLogging(int min_sev, const char* filter) {}
-  virtual bool StartAecDump(rtc::PlatformFile) { return false; }
-
-  virtual bool RegisterVideoProcessor(VideoProcessor* processor) {
-    return true;
-  }
-  virtual bool UnregisterVideoProcessor(VideoProcessor* processor) {
-    return true;
-  }
-  virtual bool RegisterVoiceProcessor(uint32 ssrc,
-                                      VoiceProcessor* processor,
-                                      MediaProcessorDirection direction) {
-    return true;
-  }
-  virtual bool UnregisterVoiceProcessor(uint32 ssrc,
-                                        VoiceProcessor* processor,
-                                        MediaProcessorDirection direction) {
-    return true;
-  }
-
-  virtual sigslot::repeater2<VideoCapturer*, CaptureState>&
-      SignalVideoCaptureStateChange() {
-    return signal_state_change_;
-  }
-
-  void set_rtp_sender_thread(rtc::Thread* thread) {
-    rtp_sender_thread_ = thread;
-  }
-
- private:
-  std::string voice_input_filename_;
-  std::string voice_output_filename_;
-  std::string video_input_filename_;
-  std::string video_output_filename_;
-  std::vector<AudioCodec> voice_codecs_;
-  std::vector<VideoCodec> video_codecs_;
-  std::vector<RtpHeaderExtension> audio_rtp_header_extensions_;
-  std::vector<RtpHeaderExtension> video_rtp_header_extensions_;
-  sigslot::repeater2<VideoCapturer*, CaptureState>
-     signal_state_change_;
-  rtc::Thread* rtp_sender_thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileMediaEngine);
-};
-
-class RtpSenderReceiver;  // Forward declaration. Defined in the .cc file.
-
-class FileVoiceChannel : public VoiceMediaChannel {
- public:
-  FileVoiceChannel(rtc::StreamInterface* input_file_stream,
-      rtc::StreamInterface* output_file_stream,
-      rtc::Thread* rtp_sender_thread);
-  virtual ~FileVoiceChannel();
-
-  // Implement pure virtual methods of VoiceMediaChannel.
-  virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) {
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs);
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetPlayout(bool playout) { return true; }
-  virtual bool SetSend(SendFlags flag);
-  virtual bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) {
-    return false;
-  }
-  virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) {
-    return false;
-  }
-  virtual bool GetActiveStreams(AudioInfo::StreamList* actives) { return true; }
-  virtual int GetOutputLevel() { return 0; }
-  virtual int GetTimeSinceLastTyping() { return -1; }
-  virtual void SetTypingDetectionParameters(int time_window,
-    int cost_per_typing, int reporting_threshold, int penalty_decay,
-    int type_event_delay) {}
-
-  virtual bool SetOutputScaling(uint32 ssrc, double left, double right) {
-    return false;
-  }
-  virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) {
-    return false;
-  }
-  virtual bool SetRingbackTone(const char* buf, int len) { return true; }
-  virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) {
-    return true;
-  }
-  virtual bool InsertDtmf(uint32 ssrc, int event, int duration, int flags) {
-    return false;
-  }
-  virtual bool GetStats(VoiceMediaInfo* info) { return true; }
-
-  // Implement pure virtual methods of MediaChannel.
-  virtual void OnPacketReceived(rtc::Buffer* packet,
-                                const rtc::PacketTime& packet_time);
-  virtual void OnRtcpReceived(rtc::Buffer* packet,
-                              const rtc::PacketTime& packet_time) {}
-  virtual void OnReadyToSend(bool ready) {}
-  virtual bool AddSendStream(const StreamParams& sp);
-  virtual bool RemoveSendStream(uint32 ssrc);
-  virtual bool AddRecvStream(const StreamParams& sp) { return true; }
-  virtual bool RemoveRecvStream(uint32 ssrc) { return true; }
-  virtual bool MuteStream(uint32 ssrc, bool on) { return false; }
-  virtual bool SetMaxSendBandwidth(int bps) { return true; }
-  virtual bool SetOptions(const AudioOptions& options) {
-    options_ = options;
-    return true;
-  }
-  virtual bool GetOptions(AudioOptions* options) const {
-    *options = options_;
-    return true;
-  }
-
- private:
-  uint32 send_ssrc_;
-  rtc::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_;
-  AudioOptions options_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVoiceChannel);
-};
-
-class FileVideoChannel : public VideoMediaChannel {
- public:
-  FileVideoChannel(rtc::StreamInterface* input_file_stream,
-      rtc::StreamInterface* output_file_stream,
-      rtc::Thread* rtp_sender_thread);
-  virtual ~FileVideoChannel();
-  // Implement pure virtual methods of VideoMediaChannel.
-  void DetachVoiceChannel() override {}
-  virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) {
-    return true;
-  }
-  virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs);
-  virtual bool GetSendCodec(VideoCodec* send_codec) {
-    *send_codec = VideoCodec();
-    return true;
-  }
-  virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) {
-    return true;
-  }
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) {
-    return true;
-  }
-  virtual bool SetRender(bool render) { return true; }
-  virtual bool SetSend(bool send);
-  virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) {
-    return true;
-  }
-  virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
-    return false;
-  }
-  virtual bool GetStats(VideoMediaInfo* info) { return true; }
-  virtual bool SendIntraFrame() { return false; }
-  virtual bool RequestIntraFrame() { return false; }
-
-  // Implement pure virtual methods of MediaChannel.
-  virtual void OnPacketReceived(rtc::Buffer* packet,
-                                const rtc::PacketTime& packet_time);
-  virtual void OnRtcpReceived(rtc::Buffer* packet,
-                              const rtc::PacketTime& packet_time) {}
-  virtual void OnReadyToSend(bool ready) {}
-  virtual bool AddSendStream(const StreamParams& sp);
-  virtual bool RemoveSendStream(uint32 ssrc);
-  virtual bool AddRecvStream(const StreamParams& sp) { return true; }
-  virtual bool RemoveRecvStream(uint32 ssrc) { return true; }
-  virtual bool MuteStream(uint32 ssrc, bool on) { return false; }
-  virtual bool SetMaxSendBandwidth(int bps) { return true; }
-  virtual bool SetOptions(const VideoOptions& options) {
-    options_ = options;
-    return true;
-  }
-  virtual bool GetOptions(VideoOptions* options) const {
-    *options = options_;
-    return true;
-  }
-  virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {}
-
- private:
-  uint32 send_ssrc_;
-  rtc::scoped_ptr<RtpSenderReceiver> rtp_sender_receiver_;
-  VideoOptions options_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileVideoChannel);
-};
-
-}  // namespace cricket
-
-#endif  // TALK_MEDIA_BASE_FILEMEDIAENGINE_H_
diff --git a/talk/media/base/filemediaengine_unittest.cc b/talk/media/base/filemediaengine_unittest.cc
deleted file mode 100644
index 9b26c3b..0000000
--- a/talk/media/base/filemediaengine_unittest.cc
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * libjingle
- * Copyright 2004 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *     this list of conditions and the following disclaimer.
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *     this list of conditions and the following disclaimer in the documentation
- *     and/or other materials provided with the distribution.
- *  3. The name of the author may not be used to endorse or promote products
- *     derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <set>
-
-#include "talk/media/base/filemediaengine.h"
-#include "talk/media/base/rtpdump.h"
-#include "talk/media/base/streamparams.h"
-#include "talk/media/base/testutils.h"
-#include "webrtc/base/buffer.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/helpers.h"
-#include "webrtc/base/pathutils.h"
-#include "webrtc/base/stream.h"
-
-namespace cricket {
-
-static const int kWaitTimeMs = 100;
-static const std::string kFakeFileName = "foobar";
-
-//////////////////////////////////////////////////////////////////////////////
-// Media channel sends RTP packets via NetworkInterface. Rather than sending
-// packets to the network, FileNetworkInterface writes packets to a stream and
-// feeds packets back to the channel via OnPacketReceived.
-//////////////////////////////////////////////////////////////////////////////
-class FileNetworkInterface : public MediaChannel::NetworkInterface {
- public:
-  FileNetworkInterface(rtc::StreamInterface* output, MediaChannel* ch)
-      : media_channel_(ch),
-        num_sent_packets_(0) {
-    if (output) {
-      dump_writer_.reset(new RtpDumpWriter(output));
-    }
-  }
-
-  // Implement pure virtual methods of NetworkInterface.
-  virtual bool SendPacket(rtc::Buffer* packet,
-                          rtc::DiffServCodePoint dscp) {
-    if (!packet) return false;
-
-    if (media_channel_) {
-      media_channel_->OnPacketReceived(packet, rtc::PacketTime());
-    }
-    if (dump_writer_.get() &&
-        rtc::SR_SUCCESS !=
-            dump_writer_->WriteRtpPacket(packet->data(), packet->size())) {
-      return false;
-    }
-
-    ++num_sent_packets_;
-    return true;
-  }
-
-  virtual bool SendRtcp(rtc::Buffer* packet,
-                        rtc::DiffServCodePoint dscp) { return false; }
-  virtual int SetOption(MediaChannel::NetworkInterface::SocketType type,
-      rtc::Socket::Option opt, int option) {
-    return 0;
-  }
-  virtual void SetDefaultDSCPCode(rtc::DiffServCodePoint dscp) {}
-
-  size_t num_sent_packets() const { return num_sent_packets_; }
-
- private:
-  MediaChannel* media_channel_;
-  rtc::scoped_ptr<RtpDumpWriter> dump_writer_;
-  size_t num_sent_packets_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileNetworkInterface);
-};
-
-class FileMediaEngineTest : public testing::Test {
- public:
-  virtual void SetUp() {
-    ASSERT_TRUE(GetTempFilename(&voice_input_filename_));
-    ASSERT_TRUE(GetTempFilename(&voice_output_filename_));
-    ASSERT_TRUE(GetTempFilename(&video_input_filename_));
-    ASSERT_TRUE(GetTempFilename(&video_output_filename_));
-  }
-  virtual void TearDown() {
-    // Force to close the dump files, if opened.
-    voice_channel_.reset();
-    video_channel_.reset();
-
-    DeleteTempFile(voice_input_filename_);
-    DeleteTempFile(voice_output_filename_);
-    DeleteTempFile(video_input_filename_);
-    DeleteTempFile(video_output_filename_);
-  }
-
- protected:
-  void CreateEngineAndChannels(const std::string& voice_in,
-                               const std::string& voice_out,
-                               const std::string& video_in,
-                               const std::string& video_out,
-                               size_t ssrc_count) {
-    // Force to close the dump files, if opened.
-    voice_channel_.reset();
-    video_channel_.reset();
-
-    if (!voice_in.empty()) {
-      EXPECT_TRUE(WriteTestPacketsToFile(voice_in, ssrc_count));
-    }
-    if (!video_in.empty()) {
-      EXPECT_TRUE(WriteTestPacketsToFile(video_in, ssrc_count));
-    }
-
-    engine_.reset(new FileMediaEngine);
-    engine_->set_voice_input_filename(voice_in);
-    engine_->set_voice_output_filename(voice_out);
-    engine_->set_video_input_filename(video_in);
-    engine_->set_video_output_filename(video_out);
-    engine_->set_rtp_sender_thread(rtc::Thread::Current());
-
-    voice_channel_.reset(engine_->CreateChannel(AudioOptions()));
-    video_channel_.reset(engine_->CreateVideoChannel(VideoOptions(), nullptr));
-  }
-
-  bool GetTempFilename(std::string* filename) {
-    rtc::Pathname temp_path;
-    if (!rtc::Filesystem::GetTemporaryFolder(temp_path, true, NULL)) {
-      return false;
-    }
-    temp_path.SetPathname(
-        rtc::Filesystem::TempFilename(temp_path, "fme-test-"));
-
-    if (filename) {
-      *filename = temp_path.pathname();
-    }
-    return true;
-  }
-
-  bool WriteTestPacketsToFile(const std::string& filename, size_t ssrc_count) {
-    rtc::scoped_ptr<rtc::StreamInterface> stream(
-        rtc::Filesystem::OpenFile(rtc::Pathname(filename), "wb"));
-    bool ret = (NULL != stream.get());
-    RtpDumpWriter writer(stream.get());
-
-    for (size_t i = 0; i < ssrc_count; ++i) {
-      ret &= RtpTestUtility::WriteTestPackets(
-          RtpTestUtility::GetTestPacketCount(), false,
-          static_cast<uint32>(RtpTestUtility::kDefaultSsrc + i),
-          &writer);
-    }
-    return ret;
-  }
-
-  void DeleteTempFile(std::string filename) {
-    rtc::Pathname pathname(filename);
-    if (rtc::Filesystem::IsFile(rtc::Pathname(pathname))) {
-      rtc::Filesystem::DeleteFile(pathname);
-    }
-  }
-
-  bool GetSsrcAndPacketCounts(rtc::StreamInterface* stream,
-                              size_t* ssrc_count, size_t* packet_count) {
-    rtc::scoped_ptr<RtpDumpReader> reader(new RtpDumpReader(stream));
-    size_t count = 0;
-    RtpDumpPacket packet;
-    std::set<uint32> ssrcs;
-    while (rtc::SR_SUCCESS == reader->ReadPacket(&packet)) {
-      count++;
-      uint32 ssrc;
-      if (!packet.GetRtpSsrc(&ssrc)) {
-        return false;
-      }
-      ssrcs.insert(ssrc);
-    }
-    if (ssrc_count) {
-      *ssrc_count = ssrcs.size();
-    }
-    if (packet_count) {
-      *packet_count = count;
-    }
-    return true;
-  }
-
-  static const uint32 kWaitTimeout = 3000;
-  std::string voice_input_filename_;
-  std::string voice_output_filename_;
-  std::string video_input_filename_;
-  std::string video_output_filename_;
-  rtc::scoped_ptr<FileMediaEngine> engine_;
-  rtc::scoped_ptr<VoiceMediaChannel> voice_channel_;
-  rtc::scoped_ptr<VideoMediaChannel> video_channel_;
-};
-
-TEST_F(FileMediaEngineTest, TestDefaultImplementation) {
-  CreateEngineAndChannels("", "", "", "", 1);
-  EXPECT_TRUE(engine_->Init(rtc::Thread::Current()));
-  EXPECT_EQ(0, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL == voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-  cricket::AudioOptions audio_options;
-  EXPECT_TRUE(engine_->SetAudioOptions(audio_options));
-  VideoEncoderConfig video_encoder_config;
-  EXPECT_TRUE(engine_->SetDefaultVideoEncoderConfig(video_encoder_config));
-  EXPECT_TRUE(engine_->SetSoundDevices(NULL, NULL));
-  EXPECT_TRUE(engine_->SetVideoCaptureDevice(NULL));
-  EXPECT_TRUE(engine_->SetOutputVolume(0));
-  EXPECT_EQ(0, engine_->GetInputLevel());
-  EXPECT_TRUE(engine_->SetLocalMonitor(true));
-  EXPECT_TRUE(engine_->SetVideoCapture(true));
-  EXPECT_EQ(0U, engine_->audio_codecs().size());
-  EXPECT_EQ(0U, engine_->video_codecs().size());
-  AudioCodec voice_codec;
-  EXPECT_TRUE(engine_->FindAudioCodec(voice_codec));
-  VideoCodec video_codec;
-  EXPECT_TRUE(engine_->FindVideoCodec(video_codec));
-  engine_->Terminate();
-}
-
-// Test that when file path is not pointing to a valid stream file, the channel
-// creation function should fail and return NULL.
-TEST_F(FileMediaEngineTest, TestBadFilePath) {
-  engine_.reset(new FileMediaEngine);
-  engine_->set_voice_input_filename(kFakeFileName);
-  engine_->set_video_input_filename(kFakeFileName);
-  EXPECT_TRUE(engine_->CreateChannel(AudioOptions()) == nullptr);
-  EXPECT_TRUE(engine_->CreateVideoChannel(VideoOptions(), nullptr) == nullptr);
-}
-
-TEST_F(FileMediaEngineTest, TestCodecs) {
-  CreateEngineAndChannels("", "", "", "", 1);
-  std::vector<AudioCodec> voice_codecs = engine_->audio_codecs();
-  std::vector<VideoCodec> video_codecs = engine_->video_codecs();
-  EXPECT_EQ(0U, voice_codecs.size());
-  EXPECT_EQ(0U, video_codecs.size());
-
-  AudioCodec voice_codec(103, "ISAC", 16000, 0, 1, 0);
-  voice_codecs.push_back(voice_codec);
-  engine_->set_voice_codecs(voice_codecs);
-  voice_codecs = engine_->audio_codecs();
-  ASSERT_EQ(1U, voice_codecs.size());
-  EXPECT_EQ(voice_codec, voice_codecs[0]);
-
-  VideoCodec video_codec(96, "H264-SVC", 320, 240, 30, 0);
-  video_codecs.push_back(video_codec);
-  engine_->set_video_codecs(video_codecs);
-  video_codecs = engine_->video_codecs();
-  ASSERT_EQ(1U, video_codecs.size());
-  EXPECT_EQ(video_codec, video_codecs[0]);
-}
-
-// Test that the capabilities and channel creation of the Filemedia engine
-// depend on the stream parameters passed to its constructor.
-TEST_F(FileMediaEngineTest, TestGetCapabilities) {
-  CreateEngineAndChannels(voice_input_filename_, "", "", "", 1);
-  EXPECT_EQ(AUDIO_SEND, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
-                          1);
-  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL == video_channel_.get());
-
-  CreateEngineAndChannels("", "", video_input_filename_, "", 1);
-  EXPECT_EQ(VIDEO_SEND, engine_->GetCapabilities());
-  EXPECT_TRUE(NULL == voice_channel_.get());
-  EXPECT_TRUE(NULL != video_channel_.get());
-
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_,
-                          video_input_filename_, video_output_filename_, 1);
-  EXPECT_EQ(AUDIO_SEND | AUDIO_RECV | VIDEO_SEND | VIDEO_RECV,
-            engine_->GetCapabilities());
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  EXPECT_TRUE(NULL != video_channel_.get());
-}
-
-// FileVideoChannel is the same as FileVoiceChannel in terms of receiving and
-// sending the RTP packets. We therefore test only FileVoiceChannel.
-
-// Test that SetSend() controls whether a voice channel sends RTP packets.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSetSend) {
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
-                          1);
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  rtc::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  // The channel is not sending yet.
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_EQ(0U, net_interface.num_sent_packets());
-
-  // The channel starts sending.
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() >= 1U, kWaitTimeout);
-
-  // The channel stops sending.
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  size_t old_number = net_interface.num_sent_packets();
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_EQ(old_number, net_interface.num_sent_packets());
-
-  // The channel starts sending again.
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(net_interface.num_sent_packets() > old_number, kWaitTimeout);
-
-  // When the function exits, the net_interface object is released. The sender
-  // thread may call net_interface to send packets, which results in a segment
-  // fault. We hence stop sending and wait until all packets are delivered
-  // before we exit this function.
-  voice_channel_->SetSend(SEND_NOTHING);
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-}
-
-// Test the sender thread of the channel. The sender sends RTP packets
-// continuously with proper sequence number, timestamp, and payload.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThread) {
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
-                          1);
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  rtc::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), &net_dump,
-      RtpTestUtility::kDefaultSsrc));
-
-  // Each sent packet is dumped to net_dump and is also feed to the channel
-  // via OnPacketReceived, which in turn writes the packets into voice_output_.
-  // We next verify the packets in voice_output_.
-  voice_channel_.reset();  // Force to close the files.
-  rtc::scoped_ptr<rtc::StreamInterface> voice_output_;
-  voice_output_.reset(rtc::Filesystem::OpenFile(
-      rtc::Pathname(voice_output_filename_), "rb"));
-  EXPECT_TRUE(voice_output_.get() != NULL);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
-      RtpTestUtility::kDefaultSsrc));
-}
-
-// Test that we can specify the ssrc for outgoing RTP packets.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSendSsrc) {
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
-                          1);
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  const uint32 send_ssrc = RtpTestUtility::kDefaultSsrc + 1;
-  voice_channel_->AddSendStream(StreamParams::CreateLegacy(send_ssrc));
-
-  rtc::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  // Wait until the number of sent packets is no less than 2 * kPacketNumber.
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), &net_dump, send_ssrc));
-
-  // Each sent packet is dumped to net_dump and is also feed to the channel
-  // via OnPacketReceived, which in turn writes the packets into voice_output_.
-  // We next verify the packets in voice_output_.
-  voice_channel_.reset();  // Force to close the files.
-  rtc::scoped_ptr<rtc::StreamInterface> voice_output_;
-  voice_output_.reset(rtc::Filesystem::OpenFile(
-      rtc::Pathname(voice_output_filename_), "rb"));
-  EXPECT_TRUE(voice_output_.get() != NULL);
-  EXPECT_TRUE(RtpTestUtility::VerifyTestPacketsFromStream(
-      2 * RtpTestUtility::GetTestPacketCount(), voice_output_.get(),
-      send_ssrc));
-}
-
-// Test the sender thread of the channel, where the input rtpdump has two SSRCs.
-TEST_F(FileMediaEngineTest, TestVoiceChannelSenderThreadTwoSsrcs) {
-  CreateEngineAndChannels(voice_input_filename_, voice_output_filename_, "", "",
-                          2);
-  // Verify that voice_input_filename_ contains 2 *
-  // RtpTestUtility::GetTestPacketCount() packets
-  // with different SSRCs.
-  rtc::scoped_ptr<rtc::StreamInterface> input_stream(
-      rtc::Filesystem::OpenFile(
-          rtc::Pathname(voice_input_filename_), "rb"));
-  ASSERT_TRUE(NULL != input_stream.get());
-  size_t ssrc_count;
-  size_t packet_count;
-  EXPECT_TRUE(GetSsrcAndPacketCounts(input_stream.get(), &ssrc_count,
-                                     &packet_count));
-  EXPECT_EQ(2U, ssrc_count);
-  EXPECT_EQ(2 * RtpTestUtility::GetTestPacketCount(), packet_count);
-  input_stream.reset();
-
-  // Send 2 * RtpTestUtility::GetTestPacketCount() packets and verify that all
-  // these packets have the same SSRCs (that is, the packets with different
-  // SSRCs are skipped by the filemediaengine).
-  EXPECT_TRUE(NULL != voice_channel_.get());
-  rtc::MemoryStream net_dump;
-  FileNetworkInterface net_interface(&net_dump, voice_channel_.get());
-  voice_channel_->SetInterface(&net_interface);
-  voice_channel_->SetSend(SEND_MICROPHONE);
-  EXPECT_TRUE_WAIT(
-      net_interface.num_sent_packets() >=
-          2 * RtpTestUtility::GetTestPacketCount(),
-      kWaitTimeout);
-  voice_channel_->SetSend(SEND_NOTHING);
-  // Wait until packets are all delivered.
-  rtc::Thread::Current()->ProcessMessages(kWaitTimeMs);
-  net_dump.Rewind();
-  EXPECT_TRUE(GetSsrcAndPacketCounts(&net_dump, &ssrc_count, &packet_count));
-  EXPECT_EQ(1U, ssrc_count);
-  EXPECT_GE(packet_count, 2 * RtpTestUtility::GetTestPacketCount());
-}
-
-// Test SendIntraFrame() and RequestIntraFrame() of video channel.
-TEST_F(FileMediaEngineTest, TestVideoChannelIntraFrame) {
-  CreateEngineAndChannels("", "", video_input_filename_, video_output_filename_,
-                          1);
-  EXPECT_TRUE(NULL != video_channel_.get());
-  EXPECT_FALSE(video_channel_->SendIntraFrame());
-  EXPECT_FALSE(video_channel_->RequestIntraFrame());
-}
-
-}  // namespace cricket
