1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_ 29 #define TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_ 30 31 #include <list> 32 #include <map> 33 #include <set> 34 #include <string> 35 #include <vector> 36 37 #include "talk/media/base/audiorenderer.h" 38 #include "talk/media/base/mediaengine.h" 39 #include "talk/media/base/rtputils.h" 40 #include "talk/media/base/streamparams.h" 41 #include "talk/p2p/base/sessiondescription.h" 42 #include "webrtc/base/buffer.h" 43 #include "webrtc/base/stringutils.h" 44 45 namespace cricket { 46 47 class FakeMediaEngine; 48 class FakeVideoEngine; 49 class FakeVoiceEngine; 50 51 // A common helper class that handles sending and receiving RTP/RTCP packets. 52 template <class Base> class RtpHelper : public Base { 53 public: 54 RtpHelper() 55 : sending_(false), 56 playout_(false), 57 fail_set_send_codecs_(false), 58 fail_set_recv_codecs_(false), 59 send_ssrc_(0), 60 ready_to_send_(false) {} 61 const std::vector<RtpHeaderExtension>& recv_extensions() { 62 return recv_extensions_; 63 } 64 const std::vector<RtpHeaderExtension>& send_extensions() { 65 return send_extensions_; 66 } 67 bool sending() const { return sending_; } 68 bool playout() const { return playout_; } 69 const std::list<std::string>& rtp_packets() const { return rtp_packets_; } 70 const std::list<std::string>& rtcp_packets() const { return rtcp_packets_; } 71 72 bool SendRtp(const void* data, int len) { 73 if (!sending_) { 74 return false; 75 } 76 rtc::Buffer packet(data, len, kMaxRtpPacketLen); 77 return Base::SendPacket(&packet); 78 } 79 bool SendRtcp(const void* data, int len) { 80 rtc::Buffer packet(data, len, kMaxRtpPacketLen); 81 return Base::SendRtcp(&packet); 82 } 83 84 bool CheckRtp(const void* data, int len) { 85 bool success = !rtp_packets_.empty(); 86 if (success) { 87 std::string packet = rtp_packets_.front(); 88 rtp_packets_.pop_front(); 89 success = (packet == std::string(static_cast<const char*>(data), len)); 90 } 91 return success; 92 } 93 bool CheckRtcp(const void* data, int len) { 94 bool success = !rtcp_packets_.empty(); 95 if (success) { 96 std::string packet = rtcp_packets_.front(); 97 rtcp_packets_.pop_front(); 98 success = (packet == std::string(static_cast<const char*>(data), len)); 99 } 100 return success; 101 } 102 bool CheckNoRtp() { return rtp_packets_.empty(); } 103 bool CheckNoRtcp() { return rtcp_packets_.empty(); } 104 virtual bool SetRecvRtpHeaderExtensions( 105 const std::vector<RtpHeaderExtension>& extensions) { 106 recv_extensions_ = extensions; 107 return true; 108 } 109 virtual bool SetSendRtpHeaderExtensions( 110 const std::vector<RtpHeaderExtension>& extensions) { 111 send_extensions_ = extensions; 112 return true; 113 } 114 void set_fail_set_send_codecs(bool fail) { fail_set_send_codecs_ = fail; } 115 void set_fail_set_recv_codecs(bool fail) { fail_set_recv_codecs_ = fail; } 116 virtual bool AddSendStream(const StreamParams& sp) { 117 if (std::find(send_streams_.begin(), send_streams_.end(), sp) != 118 send_streams_.end()) { 119 return false; 120 } 121 send_streams_.push_back(sp); 122 return true; 123 } 124 virtual bool RemoveSendStream(uint32 ssrc) { 125 return RemoveStreamBySsrc(&send_streams_, ssrc); 126 } 127 virtual bool AddRecvStream(const StreamParams& sp) { 128 if (std::find(receive_streams_.begin(), receive_streams_.end(), sp) != 129 receive_streams_.end()) { 130 return false; 131 } 132 receive_streams_.push_back(sp); 133 return true; 134 } 135 virtual bool RemoveRecvStream(uint32 ssrc) { 136 return RemoveStreamBySsrc(&receive_streams_, ssrc); 137 } 138 virtual bool MuteStream(uint32 ssrc, bool on) { 139 if (!HasSendStream(ssrc) && ssrc != 0) 140 return false; 141 if (on) 142 muted_streams_.insert(ssrc); 143 else 144 muted_streams_.erase(ssrc); 145 return true; 146 } 147 bool IsStreamMuted(uint32 ssrc) const { 148 bool ret = muted_streams_.find(ssrc) != muted_streams_.end(); 149 // If |ssrc = 0| check if the first send stream is muted. 150 if (!ret && ssrc == 0 && !send_streams_.empty()) { 151 return muted_streams_.find(send_streams_[0].first_ssrc()) != 152 muted_streams_.end(); 153 } 154 return ret; 155 } 156 const std::vector<StreamParams>& send_streams() const { 157 return send_streams_; 158 } 159 const std::vector<StreamParams>& recv_streams() const { 160 return receive_streams_; 161 } 162 bool HasRecvStream(uint32 ssrc) const { 163 return GetStreamBySsrc(receive_streams_, ssrc, NULL); 164 } 165 bool HasSendStream(uint32 ssrc) const { 166 return GetStreamBySsrc(send_streams_, ssrc, NULL); 167 } 168 // TODO(perkj): This is to support legacy unit test that only check one 169 // sending stream. 170 const uint32 send_ssrc() { 171 if (send_streams_.empty()) 172 return 0; 173 return send_streams_[0].first_ssrc(); 174 } 175 176 // TODO(perkj): This is to support legacy unit test that only check one 177 // sending stream. 178 const std::string rtcp_cname() { 179 if (send_streams_.empty()) 180 return ""; 181 return send_streams_[0].cname; 182 } 183 184 bool ready_to_send() const { 185 return ready_to_send_; 186 } 187 188 protected: 189 bool set_sending(bool send) { 190 sending_ = send; 191 return true; 192 } 193 void set_playout(bool playout) { playout_ = playout; } 194 virtual void OnPacketReceived(rtc::Buffer* packet, 195 const rtc::PacketTime& packet_time) { 196 rtp_packets_.push_back(std::string(packet->data(), packet->length())); 197 } 198 virtual void OnRtcpReceived(rtc::Buffer* packet, 199 const rtc::PacketTime& packet_time) { 200 rtcp_packets_.push_back(std::string(packet->data(), packet->length())); 201 } 202 virtual void OnReadyToSend(bool ready) { 203 ready_to_send_ = ready; 204 } 205 bool fail_set_send_codecs() const { return fail_set_send_codecs_; } 206 bool fail_set_recv_codecs() const { return fail_set_recv_codecs_; } 207 208 private: 209 bool sending_; 210 bool playout_; 211 std::vector<RtpHeaderExtension> recv_extensions_; 212 std::vector<RtpHeaderExtension> send_extensions_; 213 std::list<std::string> rtp_packets_; 214 std::list<std::string> rtcp_packets_; 215 std::vector<StreamParams> send_streams_; 216 std::vector<StreamParams> receive_streams_; 217 std::set<uint32> muted_streams_; 218 bool fail_set_send_codecs_; 219 bool fail_set_recv_codecs_; 220 uint32 send_ssrc_; 221 std::string rtcp_cname_; 222 bool ready_to_send_; 223 }; 224 225 class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> { 226 public: 227 struct DtmfInfo { 228 DtmfInfo(uint32 ssrc, int event_code, int duration, int flags) 229 : ssrc(ssrc), event_code(event_code), duration(duration), flags(flags) { 230 } 231 uint32 ssrc; 232 int event_code; 233 int duration; 234 int flags; 235 }; 236 explicit FakeVoiceMediaChannel(FakeVoiceEngine* engine) 237 : engine_(engine), 238 fail_set_send_(false), 239 ringback_tone_ssrc_(0), 240 ringback_tone_play_(false), 241 ringback_tone_loop_(false), 242 time_since_last_typing_(-1) { 243 output_scalings_[0] = OutputScaling(); // For default channel. 244 } 245 ~FakeVoiceMediaChannel(); 246 const std::vector<AudioCodec>& recv_codecs() const { return recv_codecs_; } 247 const std::vector<AudioCodec>& send_codecs() const { return send_codecs_; } 248 const std::vector<AudioCodec>& codecs() const { return send_codecs(); } 249 const std::vector<DtmfInfo>& dtmf_info_queue() const { 250 return dtmf_info_queue_; 251 } 252 const AudioOptions& options() const { return options_; } 253 254 uint32 ringback_tone_ssrc() const { return ringback_tone_ssrc_; } 255 bool ringback_tone_play() const { return ringback_tone_play_; } 256 bool ringback_tone_loop() const { return ringback_tone_loop_; } 257 258 virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) { 259 if (fail_set_recv_codecs()) { 260 // Fake the failure in SetRecvCodecs. 261 return false; 262 } 263 recv_codecs_ = codecs; 264 return true; 265 } 266 virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs) { 267 if (fail_set_send_codecs()) { 268 // Fake the failure in SetSendCodecs. 269 return false; 270 } 271 send_codecs_ = codecs; 272 return true; 273 } 274 virtual bool SetPlayout(bool playout) { 275 set_playout(playout); 276 return true; 277 } 278 virtual bool SetSend(SendFlags flag) { 279 if (fail_set_send_) { 280 return false; 281 } 282 return set_sending(flag != SEND_NOTHING); 283 } 284 virtual bool SetStartSendBandwidth(int bps) { return true; } 285 virtual bool SetMaxSendBandwidth(int bps) { return true; } 286 virtual bool AddRecvStream(const StreamParams& sp) { 287 if (!RtpHelper<VoiceMediaChannel>::AddRecvStream(sp)) 288 return false; 289 output_scalings_[sp.first_ssrc()] = OutputScaling(); 290 return true; 291 } 292 virtual bool RemoveRecvStream(uint32 ssrc) { 293 if (!RtpHelper<VoiceMediaChannel>::RemoveRecvStream(ssrc)) 294 return false; 295 output_scalings_.erase(ssrc); 296 return true; 297 } 298 virtual bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { 299 std::map<uint32, AudioRenderer*>::iterator it = 300 remote_renderers_.find(ssrc); 301 if (renderer) { 302 if (it != remote_renderers_.end()) { 303 ASSERT(it->second == renderer); 304 } else { 305 remote_renderers_.insert(std::make_pair(ssrc, renderer)); 306 renderer->AddChannel(0); 307 } 308 } else { 309 if (it != remote_renderers_.end()) { 310 it->second->RemoveChannel(0); 311 remote_renderers_.erase(it); 312 } else { 313 return false; 314 } 315 } 316 return true; 317 } 318 virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) { 319 std::map<uint32, VoiceChannelAudioSink*>::iterator it = 320 local_renderers_.find(ssrc); 321 if (renderer) { 322 if (it != local_renderers_.end()) { 323 ASSERT(it->second->renderer() == renderer); 324 } else { 325 local_renderers_.insert(std::make_pair( 326 ssrc, new VoiceChannelAudioSink(renderer))); 327 } 328 } else { 329 if (it != local_renderers_.end()) { 330 delete it->second; 331 local_renderers_.erase(it); 332 } else { 333 return false; 334 } 335 } 336 return true; 337 } 338 339 virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; } 340 virtual int GetOutputLevel() { return 0; } 341 void set_time_since_last_typing(int ms) { time_since_last_typing_ = ms; } 342 virtual int GetTimeSinceLastTyping() { return time_since_last_typing_; } 343 virtual void SetTypingDetectionParameters( 344 int time_window, int cost_per_typing, int reporting_threshold, 345 int penalty_decay, int type_event_delay) {} 346 347 virtual bool SetRingbackTone(const char* buf, int len) { return true; } 348 virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) { 349 ringback_tone_ssrc_ = ssrc; 350 ringback_tone_play_ = play; 351 ringback_tone_loop_ = loop; 352 return true; 353 } 354 355 virtual bool CanInsertDtmf() { 356 for (std::vector<AudioCodec>::const_iterator it = send_codecs_.begin(); 357 it != send_codecs_.end(); ++it) { 358 // Find the DTMF telephone event "codec". 359 if (_stricmp(it->name.c_str(), "telephone-event") == 0) { 360 return true; 361 } 362 } 363 return false; 364 } 365 virtual bool InsertDtmf(uint32 ssrc, int event_code, int duration, 366 int flags) { 367 dtmf_info_queue_.push_back(DtmfInfo(ssrc, event_code, duration, flags)); 368 return true; 369 } 370 371 virtual bool SetOutputScaling(uint32 ssrc, double left, double right) { 372 if (0 == ssrc) { 373 std::map<uint32, OutputScaling>::iterator it; 374 for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) { 375 it->second.left = left; 376 it->second.right = right; 377 } 378 return true; 379 } else if (output_scalings_.find(ssrc) != output_scalings_.end()) { 380 output_scalings_[ssrc].left = left; 381 output_scalings_[ssrc].right = right; 382 return true; 383 } 384 return false; 385 } 386 virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) { 387 if (output_scalings_.find(ssrc) == output_scalings_.end()) 388 return false; 389 *left = output_scalings_[ssrc].left; 390 *right = output_scalings_[ssrc].right; 391 return true; 392 } 393 394 virtual bool GetStats(VoiceMediaInfo* info) { return false; } 395 virtual void GetLastMediaError(uint32* ssrc, 396 VoiceMediaChannel::Error* error) { 397 *ssrc = 0; 398 *error = fail_set_send_ ? VoiceMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED 399 : VoiceMediaChannel::ERROR_NONE; 400 } 401 402 void set_fail_set_send(bool fail) { fail_set_send_ = fail; } 403 void TriggerError(uint32 ssrc, VoiceMediaChannel::Error error) { 404 VoiceMediaChannel::SignalMediaError(ssrc, error); 405 } 406 407 virtual bool SetOptions(const AudioOptions& options) { 408 // Does a "merge" of current options and set options. 409 options_.SetAll(options); 410 return true; 411 } 412 virtual bool GetOptions(AudioOptions* options) const { 413 *options = options_; 414 return true; 415 } 416 417 private: 418 struct OutputScaling { 419 OutputScaling() : left(1.0), right(1.0) {} 420 double left, right; 421 }; 422 423 class VoiceChannelAudioSink : public AudioRenderer::Sink { 424 public: 425 explicit VoiceChannelAudioSink(AudioRenderer* renderer) 426 : renderer_(renderer) { 427 renderer_->AddChannel(0); 428 renderer_->SetSink(this); 429 } 430 virtual ~VoiceChannelAudioSink() { 431 if (renderer_) { 432 renderer_->RemoveChannel(0); 433 renderer_->SetSink(NULL); 434 } 435 } 436 virtual void OnData(const void* audio_data, 437 int bits_per_sample, 438 int sample_rate, 439 int number_of_channels, 440 int number_of_frames) OVERRIDE {} 441 virtual void OnClose() OVERRIDE { 442 renderer_ = NULL; 443 } 444 AudioRenderer* renderer() const { return renderer_; } 445 446 private: 447 AudioRenderer* renderer_; 448 }; 449 450 451 FakeVoiceEngine* engine_; 452 std::vector<AudioCodec> recv_codecs_; 453 std::vector<AudioCodec> send_codecs_; 454 std::map<uint32, OutputScaling> output_scalings_; 455 std::vector<DtmfInfo> dtmf_info_queue_; 456 bool fail_set_send_; 457 uint32 ringback_tone_ssrc_; 458 bool ringback_tone_play_; 459 bool ringback_tone_loop_; 460 int time_since_last_typing_; 461 AudioOptions options_; 462 std::map<uint32, VoiceChannelAudioSink*> local_renderers_; 463 std::map<uint32, AudioRenderer*> remote_renderers_; 464 }; 465 466 // A helper function to compare the FakeVoiceMediaChannel::DtmfInfo. 467 inline bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info, 468 uint32 ssrc, int event_code, int duration, 469 int flags) { 470 return (info.duration == duration && info.event_code == event_code && 471 info.flags == flags && info.ssrc == ssrc); 472 } 473 474 class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> { 475 public: 476 explicit FakeVideoMediaChannel(FakeVideoEngine* engine) 477 : engine_(engine), 478 sent_intra_frame_(false), 479 requested_intra_frame_(false), 480 start_bps_(-1), 481 max_bps_(-1) {} 482 ~FakeVideoMediaChannel(); 483 484 const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; } 485 const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; } 486 const std::vector<VideoCodec>& codecs() const { return send_codecs(); } 487 bool rendering() const { return playout(); } 488 const VideoOptions& options() const { return options_; } 489 const std::map<uint32, VideoRenderer*>& renderers() const { 490 return renderers_; 491 } 492 int start_bps() const { return start_bps_; } 493 int max_bps() const { return max_bps_; } 494 bool GetSendStreamFormat(uint32 ssrc, VideoFormat* format) { 495 if (send_formats_.find(ssrc) == send_formats_.end()) { 496 return false; 497 } 498 *format = send_formats_[ssrc]; 499 return true; 500 } 501 virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) { 502 if (send_formats_.find(ssrc) == send_formats_.end()) { 503 return false; 504 } 505 send_formats_[ssrc] = format; 506 return true; 507 } 508 509 virtual bool AddSendStream(const StreamParams& sp) { 510 if (!RtpHelper<VideoMediaChannel>::AddSendStream(sp)) { 511 return false; 512 } 513 SetSendStreamDefaultFormat(sp.first_ssrc()); 514 return true; 515 } 516 virtual bool RemoveSendStream(uint32 ssrc) { 517 send_formats_.erase(ssrc); 518 return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc); 519 } 520 521 virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 522 if (fail_set_recv_codecs()) { 523 // Fake the failure in SetRecvCodecs. 524 return false; 525 } 526 recv_codecs_ = codecs; 527 return true; 528 } 529 virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) { 530 if (fail_set_send_codecs()) { 531 // Fake the failure in SetSendCodecs. 532 return false; 533 } 534 send_codecs_ = codecs; 535 536 for (std::vector<StreamParams>::const_iterator it = send_streams().begin(); 537 it != send_streams().end(); ++it) { 538 SetSendStreamDefaultFormat(it->first_ssrc()); 539 } 540 return true; 541 } 542 virtual bool GetSendCodec(VideoCodec* send_codec) { 543 if (send_codecs_.empty()) { 544 return false; 545 } 546 *send_codec = send_codecs_[0]; 547 return true; 548 } 549 virtual bool SetRender(bool render) { 550 set_playout(render); 551 return true; 552 } 553 virtual bool SetRenderer(uint32 ssrc, VideoRenderer* r) { 554 if (ssrc != 0 && renderers_.find(ssrc) == renderers_.end()) { 555 return false; 556 } 557 if (ssrc != 0) { 558 renderers_[ssrc] = r; 559 } 560 return true; 561 } 562 563 virtual bool SetSend(bool send) { return set_sending(send); } 564 virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 565 capturers_[ssrc] = capturer; 566 return true; 567 } 568 bool HasCapturer(uint32 ssrc) const { 569 return capturers_.find(ssrc) != capturers_.end(); 570 } 571 virtual bool SetStartSendBandwidth(int bps) { 572 start_bps_ = bps; 573 return true; 574 } 575 virtual bool SetMaxSendBandwidth(int bps) { 576 max_bps_ = bps; 577 return true; 578 } 579 virtual bool AddRecvStream(const StreamParams& sp) { 580 if (!RtpHelper<VideoMediaChannel>::AddRecvStream(sp)) 581 return false; 582 renderers_[sp.first_ssrc()] = NULL; 583 return true; 584 } 585 virtual bool RemoveRecvStream(uint32 ssrc) { 586 if (!RtpHelper<VideoMediaChannel>::RemoveRecvStream(ssrc)) 587 return false; 588 renderers_.erase(ssrc); 589 return true; 590 } 591 592 virtual bool GetStats(const StatsOptions& options, 593 VideoMediaInfo* info) { return false; } 594 virtual bool SendIntraFrame() { 595 sent_intra_frame_ = true; 596 return true; 597 } 598 virtual bool RequestIntraFrame() { 599 requested_intra_frame_ = true; 600 return true; 601 } 602 virtual bool SetOptions(const VideoOptions& options) { 603 options_ = options; 604 return true; 605 } 606 virtual bool GetOptions(VideoOptions* options) const { 607 *options = options_; 608 return true; 609 } 610 virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {} 611 void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; } 612 bool sent_intra_frame() const { return sent_intra_frame_; } 613 void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; } 614 bool requested_intra_frame() const { return requested_intra_frame_; } 615 616 private: 617 // Be default, each send stream uses the first send codec format. 618 void SetSendStreamDefaultFormat(uint32 ssrc) { 619 if (!send_codecs_.empty()) { 620 send_formats_[ssrc] = VideoFormat( 621 send_codecs_[0].width, send_codecs_[0].height, 622 cricket::VideoFormat::FpsToInterval(send_codecs_[0].framerate), 623 cricket::FOURCC_I420); 624 } 625 } 626 627 FakeVideoEngine* engine_; 628 std::vector<VideoCodec> recv_codecs_; 629 std::vector<VideoCodec> send_codecs_; 630 std::map<uint32, VideoRenderer*> renderers_; 631 std::map<uint32, VideoFormat> send_formats_; 632 std::map<uint32, VideoCapturer*> capturers_; 633 bool sent_intra_frame_; 634 bool requested_intra_frame_; 635 VideoOptions options_; 636 int start_bps_; 637 int max_bps_; 638 }; 639 640 class FakeSoundclipMedia : public SoundclipMedia { 641 public: 642 virtual bool PlaySound(const char* buf, int len, int flags) { return true; } 643 }; 644 645 class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> { 646 public: 647 explicit FakeDataMediaChannel(void* unused) 648 : send_blocked_(false), max_bps_(-1) {} 649 ~FakeDataMediaChannel() {} 650 const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; } 651 const std::vector<DataCodec>& send_codecs() const { return send_codecs_; } 652 const std::vector<DataCodec>& codecs() const { return send_codecs(); } 653 int max_bps() const { return max_bps_; } 654 655 virtual bool SetRecvCodecs(const std::vector<DataCodec>& codecs) { 656 if (fail_set_recv_codecs()) { 657 // Fake the failure in SetRecvCodecs. 658 return false; 659 } 660 recv_codecs_ = codecs; 661 return true; 662 } 663 virtual bool SetSendCodecs(const std::vector<DataCodec>& codecs) { 664 if (fail_set_send_codecs()) { 665 // Fake the failure in SetSendCodecs. 666 return false; 667 } 668 send_codecs_ = codecs; 669 return true; 670 } 671 virtual bool SetSend(bool send) { return set_sending(send); } 672 virtual bool SetReceive(bool receive) { 673 set_playout(receive); 674 return true; 675 } 676 virtual bool SetStartSendBandwidth(int bps) { return true; } 677 virtual bool SetMaxSendBandwidth(int bps) { 678 max_bps_ = bps; 679 return true; 680 } 681 virtual bool AddRecvStream(const StreamParams& sp) { 682 if (!RtpHelper<DataMediaChannel>::AddRecvStream(sp)) 683 return false; 684 return true; 685 } 686 virtual bool RemoveRecvStream(uint32 ssrc) { 687 if (!RtpHelper<DataMediaChannel>::RemoveRecvStream(ssrc)) 688 return false; 689 return true; 690 } 691 692 virtual bool SendData(const SendDataParams& params, 693 const rtc::Buffer& payload, 694 SendDataResult* result) { 695 if (send_blocked_) { 696 *result = SDR_BLOCK; 697 return false; 698 } else { 699 last_sent_data_params_ = params; 700 last_sent_data_ = std::string(payload.data(), payload.length()); 701 return true; 702 } 703 } 704 705 SendDataParams last_sent_data_params() { return last_sent_data_params_; } 706 std::string last_sent_data() { return last_sent_data_; } 707 bool is_send_blocked() { return send_blocked_; } 708 void set_send_blocked(bool blocked) { send_blocked_ = blocked; } 709 710 private: 711 std::vector<DataCodec> recv_codecs_; 712 std::vector<DataCodec> send_codecs_; 713 SendDataParams last_sent_data_params_; 714 std::string last_sent_data_; 715 bool send_blocked_; 716 int max_bps_; 717 }; 718 719 // A base class for all of the shared parts between FakeVoiceEngine 720 // and FakeVideoEngine. 721 class FakeBaseEngine { 722 public: 723 FakeBaseEngine() 724 : loglevel_(-1), 725 options_changed_(false), 726 fail_create_channel_(false) {} 727 bool Init(rtc::Thread* worker_thread) { return true; } 728 void Terminate() {} 729 730 void SetLogging(int level, const char* filter) { 731 loglevel_ = level; 732 logfilter_ = filter; 733 } 734 735 void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; } 736 737 const std::vector<RtpHeaderExtension>& rtp_header_extensions() const { 738 return rtp_header_extensions_; 739 } 740 void set_rtp_header_extensions( 741 const std::vector<RtpHeaderExtension>& extensions) { 742 rtp_header_extensions_ = extensions; 743 } 744 745 protected: 746 int loglevel_; 747 std::string logfilter_; 748 // Flag used by optionsmessagehandler_unittest for checking whether any 749 // relevant setting has been updated. 750 // TODO(thaloun): Replace with explicit checks of before & after values. 751 bool options_changed_; 752 bool fail_create_channel_; 753 std::vector<RtpHeaderExtension> rtp_header_extensions_; 754 }; 755 756 class FakeVoiceEngine : public FakeBaseEngine { 757 public: 758 FakeVoiceEngine() 759 : output_volume_(-1), 760 delay_offset_(0), 761 rx_processor_(NULL), 762 tx_processor_(NULL) { 763 // Add a fake audio codec. Note that the name must not be "" as there are 764 // sanity checks against that. 765 codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1, 0)); 766 } 767 int GetCapabilities() { return AUDIO_SEND | AUDIO_RECV; } 768 AudioOptions GetAudioOptions() const { 769 return options_; 770 } 771 AudioOptions GetOptions() const { 772 return options_; 773 } 774 bool SetOptions(const AudioOptions& options) { 775 options_ = options; 776 options_changed_ = true; 777 return true; 778 } 779 780 VoiceMediaChannel* CreateChannel() { 781 if (fail_create_channel_) { 782 return NULL; 783 } 784 785 FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this); 786 channels_.push_back(ch); 787 return ch; 788 } 789 FakeVoiceMediaChannel* GetChannel(size_t index) { 790 return (channels_.size() > index) ? channels_[index] : NULL; 791 } 792 void UnregisterChannel(VoiceMediaChannel* channel) { 793 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 794 } 795 SoundclipMedia* CreateSoundclip() { return new FakeSoundclipMedia(); } 796 797 const std::vector<AudioCodec>& codecs() { return codecs_; } 798 void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; } 799 800 bool SetDelayOffset(int offset) { 801 delay_offset_ = offset; 802 return true; 803 } 804 805 bool SetDevices(const Device* in_device, const Device* out_device) { 806 in_device_ = (in_device) ? in_device->name : ""; 807 out_device_ = (out_device) ? out_device->name : ""; 808 options_changed_ = true; 809 return true; 810 } 811 812 bool GetOutputVolume(int* level) { 813 *level = output_volume_; 814 return true; 815 } 816 817 bool SetOutputVolume(int level) { 818 output_volume_ = level; 819 options_changed_ = true; 820 return true; 821 } 822 823 int GetInputLevel() { return 0; } 824 825 bool SetLocalMonitor(bool enable) { return true; } 826 827 bool StartAecDump(rtc::PlatformFile file) { return false; } 828 829 bool RegisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor, 830 MediaProcessorDirection direction) { 831 if (direction == MPD_RX) { 832 rx_processor_ = voice_processor; 833 return true; 834 } else if (direction == MPD_TX) { 835 tx_processor_ = voice_processor; 836 return true; 837 } 838 return false; 839 } 840 841 bool UnregisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor, 842 MediaProcessorDirection direction) { 843 bool unregistered = false; 844 if (direction & MPD_RX) { 845 rx_processor_ = NULL; 846 unregistered = true; 847 } 848 if (direction & MPD_TX) { 849 tx_processor_ = NULL; 850 unregistered = true; 851 } 852 return unregistered; 853 } 854 855 private: 856 std::vector<FakeVoiceMediaChannel*> channels_; 857 std::vector<AudioCodec> codecs_; 858 int output_volume_; 859 int delay_offset_; 860 std::string in_device_; 861 std::string out_device_; 862 VoiceProcessor* rx_processor_; 863 VoiceProcessor* tx_processor_; 864 AudioOptions options_; 865 866 friend class FakeMediaEngine; 867 }; 868 869 class FakeVideoEngine : public FakeBaseEngine { 870 public: 871 FakeVideoEngine() : capture_(false), processor_(NULL) { 872 // Add a fake video codec. Note that the name must not be "" as there are 873 // sanity checks against that. 874 codecs_.push_back(VideoCodec(0, "fake_video_codec", 0, 0, 0, 0)); 875 } 876 bool GetOptions(VideoOptions* options) const { 877 *options = options_; 878 return true; 879 } 880 bool SetOptions(const VideoOptions& options) { 881 options_ = options; 882 options_changed_ = true; 883 return true; 884 } 885 int GetCapabilities() { return VIDEO_SEND | VIDEO_RECV; } 886 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { 887 default_encoder_config_ = config; 888 return true; 889 } 890 VideoEncoderConfig GetDefaultEncoderConfig() const { 891 return default_encoder_config_; 892 } 893 const VideoEncoderConfig& default_encoder_config() const { 894 return default_encoder_config_; 895 } 896 897 VideoMediaChannel* CreateChannel(VoiceMediaChannel* channel) { 898 if (fail_create_channel_) { 899 return NULL; 900 } 901 902 FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this); 903 channels_.push_back(ch); 904 return ch; 905 } 906 FakeVideoMediaChannel* GetChannel(size_t index) { 907 return (channels_.size() > index) ? channels_[index] : NULL; 908 } 909 void UnregisterChannel(VideoMediaChannel* channel) { 910 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 911 } 912 913 const std::vector<VideoCodec>& codecs() const { return codecs_; } 914 bool FindCodec(const VideoCodec& in) { 915 for (size_t i = 0; i < codecs_.size(); ++i) { 916 if (codecs_[i].Matches(in)) { 917 return true; 918 } 919 } 920 return false; 921 } 922 void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; } 923 924 bool SetCaptureDevice(const Device* device) { 925 in_device_ = (device) ? device->name : ""; 926 options_changed_ = true; 927 return true; 928 } 929 bool SetCapture(bool capture) { 930 capture_ = capture; 931 return true; 932 } 933 VideoFormat GetStartCaptureFormat() const { 934 return VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30), 935 FOURCC_I420); 936 } 937 938 sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 939 940 private: 941 std::vector<FakeVideoMediaChannel*> channels_; 942 std::vector<VideoCodec> codecs_; 943 VideoEncoderConfig default_encoder_config_; 944 std::string in_device_; 945 bool capture_; 946 VideoProcessor* processor_; 947 VideoOptions options_; 948 949 friend class FakeMediaEngine; 950 }; 951 952 class FakeMediaEngine : 953 public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> { 954 public: 955 FakeMediaEngine() { 956 voice_ = FakeVoiceEngine(); 957 video_ = FakeVideoEngine(); 958 } 959 virtual ~FakeMediaEngine() {} 960 961 void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { 962 voice_.SetCodecs(codecs); 963 } 964 void SetVideoCodecs(const std::vector<VideoCodec>& codecs) { 965 video_.SetCodecs(codecs); 966 } 967 968 void SetAudioRtpHeaderExtensions( 969 const std::vector<RtpHeaderExtension>& extensions) { 970 voice_.set_rtp_header_extensions(extensions); 971 } 972 void SetVideoRtpHeaderExtensions( 973 const std::vector<RtpHeaderExtension>& extensions) { 974 video_.set_rtp_header_extensions(extensions); 975 } 976 977 FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { 978 return voice_.GetChannel(index); 979 } 980 FakeVideoMediaChannel* GetVideoChannel(size_t index) { 981 return video_.GetChannel(index); 982 } 983 984 AudioOptions audio_options() const { return voice_.options_; } 985 int audio_delay_offset() const { return voice_.delay_offset_; } 986 int output_volume() const { return voice_.output_volume_; } 987 const VideoEncoderConfig& default_video_encoder_config() const { 988 return video_.default_encoder_config_; 989 } 990 const std::string& audio_in_device() const { return voice_.in_device_; } 991 const std::string& audio_out_device() const { return voice_.out_device_; } 992 int voice_loglevel() const { return voice_.loglevel_; } 993 const std::string& voice_logfilter() const { return voice_.logfilter_; } 994 int video_loglevel() const { return video_.loglevel_; } 995 const std::string& video_logfilter() const { return video_.logfilter_; } 996 bool capture() const { return video_.capture_; } 997 bool options_changed() const { 998 return voice_.options_changed_ || video_.options_changed_; 999 } 1000 void clear_options_changed() { 1001 video_.options_changed_ = false; 1002 voice_.options_changed_ = false; 1003 } 1004 void set_fail_create_channel(bool fail) { 1005 voice_.set_fail_create_channel(fail); 1006 video_.set_fail_create_channel(fail); 1007 } 1008 bool voice_processor_registered(MediaProcessorDirection direction) const { 1009 if (direction == MPD_RX) { 1010 return voice_.rx_processor_ != NULL; 1011 } else if (direction == MPD_TX) { 1012 return voice_.tx_processor_ != NULL; 1013 } 1014 return false; 1015 } 1016 }; 1017 1018 // CompositeMediaEngine with FakeVoiceEngine to expose SetAudioCodecs to 1019 // establish a media connectionwith minimum set of audio codes required 1020 template <class VIDEO> 1021 class CompositeMediaEngineWithFakeVoiceEngine : 1022 public CompositeMediaEngine<FakeVoiceEngine, VIDEO> { 1023 public: 1024 CompositeMediaEngineWithFakeVoiceEngine() {} 1025 virtual ~CompositeMediaEngineWithFakeVoiceEngine() {} 1026 1027 virtual void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { 1028 CompositeMediaEngine<FakeVoiceEngine, VIDEO>::voice_.SetCodecs(codecs); 1029 } 1030 }; 1031 1032 // Have to come afterwards due to declaration order 1033 inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() { 1034 if (engine_) { 1035 engine_->UnregisterChannel(this); 1036 } 1037 } 1038 1039 inline FakeVideoMediaChannel::~FakeVideoMediaChannel() { 1040 if (engine_) { 1041 engine_->UnregisterChannel(this); 1042 } 1043 } 1044 1045 class FakeDataEngine : public DataEngineInterface { 1046 public: 1047 FakeDataEngine() : last_channel_type_(DCT_NONE) {} 1048 1049 virtual DataMediaChannel* CreateChannel(DataChannelType data_channel_type) { 1050 last_channel_type_ = data_channel_type; 1051 FakeDataMediaChannel* ch = new FakeDataMediaChannel(this); 1052 channels_.push_back(ch); 1053 return ch; 1054 } 1055 1056 FakeDataMediaChannel* GetChannel(size_t index) { 1057 return (channels_.size() > index) ? channels_[index] : NULL; 1058 } 1059 1060 void UnregisterChannel(DataMediaChannel* channel) { 1061 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 1062 } 1063 1064 virtual void SetDataCodecs(const std::vector<DataCodec>& data_codecs) { 1065 data_codecs_ = data_codecs; 1066 } 1067 1068 virtual const std::vector<DataCodec>& data_codecs() { return data_codecs_; } 1069 1070 DataChannelType last_channel_type() const { return last_channel_type_; } 1071 1072 private: 1073 std::vector<FakeDataMediaChannel*> channels_; 1074 std::vector<DataCodec> data_codecs_; 1075 DataChannelType last_channel_type_; 1076 }; 1077 1078 } // namespace cricket 1079 1080 #endif // TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_ 1081