1731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// libjingle 2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Copyright 2004--2005, Google Inc. 3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Redistribution and use in source and binary forms, with or without 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// modification, are permitted provided that the following conditions are met: 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 1. Redistributions of source code must retain the above copyright notice, 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// this list of conditions and the following disclaimer. 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 2. Redistributions in binary form must reproduce the above copyright notice, 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// this list of conditions and the following disclaimer in the documentation 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// and/or other materials provided with the distribution. 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 3. The name of the author may not be used to endorse or promote products 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// derived from this software without specific prior written permission. 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/session/phone/filemediaengine.h" 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include <climits> 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/base/buffer.h" 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/event.h" 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/logging.h" 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/pathutils.h" 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/stream.h" 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/session/phone/rtpdump.h" 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace cricket { 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Implementation of FileMediaEngine. 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint FileMediaEngine::GetCapabilities() { 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int capabilities = 0; 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!voice_input_filename_.empty()) { 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick capabilities |= MediaEngine::AUDIO_SEND; 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!voice_output_filename_.empty()) { 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick capabilities |= MediaEngine::AUDIO_RECV; 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!video_input_filename_.empty()) { 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick capabilities |= MediaEngine::VIDEO_SEND; 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!video_output_filename_.empty()) { 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick capabilities |= MediaEngine::VIDEO_RECV; 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return capabilities; 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 59731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVoiceMediaChannel* FileMediaEngine::CreateChannel() { 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!voice_input_filename_.empty() || !voice_output_filename_.empty()) { 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return new FileVoiceChannel(voice_input_filename_, voice_output_filename_); 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 67731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVideoMediaChannel* FileMediaEngine::CreateVideoChannel( 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VoiceMediaChannel* voice_ch) { 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!video_input_filename_.empty() || !video_output_filename_.empty()) { 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return new FileVideoChannel(video_input_filename_, video_output_filename_); 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return NULL; 73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Definition of RtpSenderReceiver. 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass RtpSenderReceiver 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : public talk_base::Thread, public talk_base::MessageHandler { 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public: 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RtpSenderReceiver(MediaChannel* channel, const std::string& in_file, 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& out_file); 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Called by media channel. Context: media channel thread. 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool SetSend(bool send); 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void OnPacketReceived(talk_base::Buffer* packet); 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Override virtual method of parent MessageHandler. Context: Worker Thread. 90731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnMessage(talk_base::Message* pmsg); 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private: 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Read the next RTP dump packet, whose RTP SSRC is the same as first_ssrc_. 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Return true if successful. 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool ReadNextPacket(RtpDumpPacket* packet); 96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Send a RTP packet to the network. The input parameter data points to the 97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // start of the RTP packet and len is the packet size. Return true if the sent 98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // size is equal to len. 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool SendRtpPacket(const void* data, size_t len); 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick MediaChannel* media_channel_; 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::scoped_ptr<talk_base::StreamInterface> input_stream_; 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::scoped_ptr<talk_base::StreamInterface> output_stream_; 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::scoped_ptr<RtpDumpLoopReader> rtp_dump_reader_; 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::scoped_ptr<RtpDumpWriter> rtp_dump_writer_; 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // RTP dump packet read from the input stream. 107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick RtpDumpPacket rtp_dump_packet_; 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 start_send_time_; 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool sending_; 110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool first_packet_; 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 first_ssrc_; 112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DISALLOW_COPY_AND_ASSIGN(RtpSenderReceiver); 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Implementation of RtpSenderReceiver. 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 119731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickRtpSenderReceiver::RtpSenderReceiver(MediaChannel* channel, 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& in_file, 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& out_file) 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : media_channel_(channel), 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick sending_(false), 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick first_packet_(true) { 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick input_stream_.reset(talk_base::Filesystem::OpenFile( 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::Pathname(in_file), "rb")); 127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (input_stream_.get()) { 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rtp_dump_reader_.reset(new RtpDumpLoopReader(input_stream_.get())); 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Start the sender thread, which reads rtp dump records, waits based on 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the record timestamps, and sends the RTP packets to the network. 131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Thread::Start(); 132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Create a rtp dump writer for the output RTP dump stream. 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output_stream_.reset(talk_base::Filesystem::OpenFile( 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::Pathname(out_file), "wb")); 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (output_stream_.get()) { 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick rtp_dump_writer_.reset(new RtpDumpWriter(output_stream_.get())); 139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool RtpSenderReceiver::SetSend(bool send) { 143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool was_sending = sending_; 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick sending_ = send; 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!was_sending && sending_) { 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick PostDelayed(0, this); // Wake up the send thread. 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen start_send_time_ = talk_base::Time(); 148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid RtpSenderReceiver::OnPacketReceived(talk_base::Buffer* packet) { 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (rtp_dump_writer_.get()) { 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen rtp_dump_writer_->WriteRtpPacket(packet->data(), packet->length()); 155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid RtpSenderReceiver::OnMessage(talk_base::Message* pmsg) { 159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!sending_) { 160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // If the sender thread is not sending, ignore this message. The thread goes 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // to sleep until SetSend(true) wakes it up. 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!first_packet_) { 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Send the previously read packet. 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SendRtpPacket(&rtp_dump_packet_.data[0], rtp_dump_packet_.data.size()); 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ReadNextPacket(&rtp_dump_packet_)) { 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int wait = talk_base::TimeUntil( 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen start_send_time_ + rtp_dump_packet_.elapsed_time); 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen wait = talk_base::_max(0, wait); 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PostDelayed(wait, this); 175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Quit(); 177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool RtpSenderReceiver::ReadNextPacket(RtpDumpPacket* packet) { 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (talk_base::SR_SUCCESS == rtp_dump_reader_->ReadPacket(packet)) { 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen uint32 ssrc; 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!packet->GetRtpSsrc(&ssrc)) { 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (first_packet_) { 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_packet_ = false; 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen first_ssrc_ = ssrc; 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ssrc == first_ssrc_) { 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool RtpSenderReceiver::SendRtpPacket(const void* data, size_t len) { 198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!media_channel_ || !media_channel_->network_interface()) { 199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return media_channel_->network_interface()->SendPacket(&packet); 204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Implementation of FileVoiceChannel. 208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 209731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFileVoiceChannel::FileVoiceChannel(const std::string& in_file, 210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& out_file) 211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : rtp_sender_receiver_(new RtpSenderReceiver(this, in_file, out_file)) { 212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 214731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFileVoiceChannel::~FileVoiceChannel() {} 215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool FileVoiceChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) { 217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Check the format of RTP dump input. 218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool FileVoiceChannel::SetSend(SendFlags flag) { 222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return rtp_sender_receiver_->SetSend(flag != SEND_NOTHING); 223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid FileVoiceChannel::OnPacketReceived(talk_base::Buffer* packet) { 226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen rtp_sender_receiver_->OnPacketReceived(packet); 227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Implementation of FileVideoChannel. 231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick/////////////////////////////////////////////////////////////////////////// 232731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFileVideoChannel::FileVideoChannel(const std::string& in_file, 233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& out_file) 234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : rtp_sender_receiver_(new RtpSenderReceiver(this, in_file, out_file)) { 235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 237731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFileVideoChannel::~FileVideoChannel() {} 238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool FileVideoChannel::SetSendCodecs(const std::vector<VideoCodec>& codecs) { 240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO: Check the format of RTP dump input. 241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool FileVideoChannel::SetSend(bool send) { 245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return rtp_sender_receiver_->SetSend(send); 246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid FileVideoChannel::OnPacketReceived(talk_base::Buffer* packet) { 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen rtp_sender_receiver_->OnPacketReceived(packet); 250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace cricket 253