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 "webrtc/audio/audio_sink.h" 42 #include "webrtc/base/buffer.h" 43 #include "webrtc/base/stringutils.h" 44 #include "webrtc/p2p/base/sessiondescription.h" 45 46 namespace cricket { 47 48 class FakeMediaEngine; 49 class FakeVideoEngine; 50 class FakeVoiceEngine; 51 52 // A common helper class that handles sending and receiving RTP/RTCP packets. 53 template <class Base> class RtpHelper : public Base { 54 public: 55 RtpHelper() 56 : sending_(false), 57 playout_(false), 58 fail_set_send_codecs_(false), 59 fail_set_recv_codecs_(false), 60 send_ssrc_(0), 61 ready_to_send_(false) {} 62 const std::vector<RtpHeaderExtension>& recv_extensions() { 63 return recv_extensions_; 64 } 65 const std::vector<RtpHeaderExtension>& send_extensions() { 66 return send_extensions_; 67 } 68 bool sending() const { return sending_; } 69 bool playout() const { return playout_; } 70 const std::list<std::string>& rtp_packets() const { return rtp_packets_; } 71 const std::list<std::string>& rtcp_packets() const { return rtcp_packets_; } 72 73 bool SendRtp(const void* data, int len, const rtc::PacketOptions& options) { 74 if (!sending_) { 75 return false; 76 } 77 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len, 78 kMaxRtpPacketLen); 79 return Base::SendPacket(&packet, options); 80 } 81 bool SendRtcp(const void* data, int len) { 82 rtc::Buffer packet(reinterpret_cast<const uint8_t*>(data), len, 83 kMaxRtpPacketLen); 84 return Base::SendRtcp(&packet, rtc::PacketOptions()); 85 } 86 87 bool CheckRtp(const void* data, int len) { 88 bool success = !rtp_packets_.empty(); 89 if (success) { 90 std::string packet = rtp_packets_.front(); 91 rtp_packets_.pop_front(); 92 success = (packet == std::string(static_cast<const char*>(data), len)); 93 } 94 return success; 95 } 96 bool CheckRtcp(const void* data, int len) { 97 bool success = !rtcp_packets_.empty(); 98 if (success) { 99 std::string packet = rtcp_packets_.front(); 100 rtcp_packets_.pop_front(); 101 success = (packet == std::string(static_cast<const char*>(data), len)); 102 } 103 return success; 104 } 105 bool CheckNoRtp() { return rtp_packets_.empty(); } 106 bool CheckNoRtcp() { return rtcp_packets_.empty(); } 107 void set_fail_set_send_codecs(bool fail) { fail_set_send_codecs_ = fail; } 108 void set_fail_set_recv_codecs(bool fail) { fail_set_recv_codecs_ = fail; } 109 virtual bool AddSendStream(const StreamParams& sp) { 110 if (std::find(send_streams_.begin(), send_streams_.end(), sp) != 111 send_streams_.end()) { 112 return false; 113 } 114 send_streams_.push_back(sp); 115 return true; 116 } 117 virtual bool RemoveSendStream(uint32_t ssrc) { 118 return RemoveStreamBySsrc(&send_streams_, ssrc); 119 } 120 virtual bool AddRecvStream(const StreamParams& sp) { 121 if (std::find(receive_streams_.begin(), receive_streams_.end(), sp) != 122 receive_streams_.end()) { 123 return false; 124 } 125 receive_streams_.push_back(sp); 126 return true; 127 } 128 virtual bool RemoveRecvStream(uint32_t ssrc) { 129 return RemoveStreamBySsrc(&receive_streams_, ssrc); 130 } 131 bool IsStreamMuted(uint32_t ssrc) const { 132 bool ret = muted_streams_.find(ssrc) != muted_streams_.end(); 133 // If |ssrc = 0| check if the first send stream is muted. 134 if (!ret && ssrc == 0 && !send_streams_.empty()) { 135 return muted_streams_.find(send_streams_[0].first_ssrc()) != 136 muted_streams_.end(); 137 } 138 return ret; 139 } 140 const std::vector<StreamParams>& send_streams() const { 141 return send_streams_; 142 } 143 const std::vector<StreamParams>& recv_streams() const { 144 return receive_streams_; 145 } 146 bool HasRecvStream(uint32_t ssrc) const { 147 return GetStreamBySsrc(receive_streams_, ssrc) != nullptr; 148 } 149 bool HasSendStream(uint32_t ssrc) const { 150 return GetStreamBySsrc(send_streams_, ssrc) != nullptr; 151 } 152 // TODO(perkj): This is to support legacy unit test that only check one 153 // sending stream. 154 uint32_t send_ssrc() const { 155 if (send_streams_.empty()) 156 return 0; 157 return send_streams_[0].first_ssrc(); 158 } 159 160 // TODO(perkj): This is to support legacy unit test that only check one 161 // sending stream. 162 const std::string rtcp_cname() { 163 if (send_streams_.empty()) 164 return ""; 165 return send_streams_[0].cname; 166 } 167 168 bool ready_to_send() const { 169 return ready_to_send_; 170 } 171 172 protected: 173 bool MuteStream(uint32_t ssrc, bool mute) { 174 if (!HasSendStream(ssrc) && ssrc != 0) { 175 return false; 176 } 177 if (mute) { 178 muted_streams_.insert(ssrc); 179 } else { 180 muted_streams_.erase(ssrc); 181 } 182 return true; 183 } 184 bool set_sending(bool send) { 185 sending_ = send; 186 return true; 187 } 188 void set_playout(bool playout) { playout_ = playout; } 189 bool SetRecvRtpHeaderExtensions( 190 const std::vector<RtpHeaderExtension>& extensions) { 191 recv_extensions_ = extensions; 192 return true; 193 } 194 bool SetSendRtpHeaderExtensions( 195 const std::vector<RtpHeaderExtension>& extensions) { 196 send_extensions_ = extensions; 197 return true; 198 } 199 virtual void OnPacketReceived(rtc::Buffer* packet, 200 const rtc::PacketTime& packet_time) { 201 rtp_packets_.push_back(std::string(packet->data<char>(), packet->size())); 202 } 203 virtual void OnRtcpReceived(rtc::Buffer* packet, 204 const rtc::PacketTime& packet_time) { 205 rtcp_packets_.push_back(std::string(packet->data<char>(), packet->size())); 206 } 207 virtual void OnReadyToSend(bool ready) { 208 ready_to_send_ = ready; 209 } 210 bool fail_set_send_codecs() const { return fail_set_send_codecs_; } 211 bool fail_set_recv_codecs() const { return fail_set_recv_codecs_; } 212 213 private: 214 bool sending_; 215 bool playout_; 216 std::vector<RtpHeaderExtension> recv_extensions_; 217 std::vector<RtpHeaderExtension> send_extensions_; 218 std::list<std::string> rtp_packets_; 219 std::list<std::string> rtcp_packets_; 220 std::vector<StreamParams> send_streams_; 221 std::vector<StreamParams> receive_streams_; 222 std::set<uint32_t> muted_streams_; 223 bool fail_set_send_codecs_; 224 bool fail_set_recv_codecs_; 225 uint32_t send_ssrc_; 226 std::string rtcp_cname_; 227 bool ready_to_send_; 228 }; 229 230 class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> { 231 public: 232 struct DtmfInfo { 233 DtmfInfo(uint32_t ssrc, int event_code, int duration) 234 : ssrc(ssrc), 235 event_code(event_code), 236 duration(duration) {} 237 uint32_t ssrc; 238 int event_code; 239 int duration; 240 }; 241 explicit FakeVoiceMediaChannel(FakeVoiceEngine* engine, 242 const AudioOptions& options) 243 : engine_(engine), 244 time_since_last_typing_(-1) { 245 output_scalings_[0] = 1.0; // For default channel. 246 SetOptions(options); 247 } 248 ~FakeVoiceMediaChannel(); 249 const std::vector<AudioCodec>& recv_codecs() const { return recv_codecs_; } 250 const std::vector<AudioCodec>& send_codecs() const { return send_codecs_; } 251 const std::vector<AudioCodec>& codecs() const { return send_codecs(); } 252 const std::vector<DtmfInfo>& dtmf_info_queue() const { 253 return dtmf_info_queue_; 254 } 255 const AudioOptions& options() const { return options_; } 256 257 virtual bool SetSendParameters(const AudioSendParameters& params) { 258 return (SetSendCodecs(params.codecs) && 259 SetSendRtpHeaderExtensions(params.extensions) && 260 SetMaxSendBandwidth(params.max_bandwidth_bps) && 261 SetOptions(params.options)); 262 } 263 264 virtual bool SetRecvParameters(const AudioRecvParameters& params) { 265 return (SetRecvCodecs(params.codecs) && 266 SetRecvRtpHeaderExtensions(params.extensions)); 267 } 268 virtual bool SetPlayout(bool playout) { 269 set_playout(playout); 270 return true; 271 } 272 virtual bool SetSend(SendFlags flag) { 273 return set_sending(flag != SEND_NOTHING); 274 } 275 virtual bool SetAudioSend(uint32_t ssrc, 276 bool enable, 277 const AudioOptions* options, 278 AudioRenderer* renderer) { 279 if (!SetLocalRenderer(ssrc, renderer)) { 280 return false; 281 } 282 if (!RtpHelper<VoiceMediaChannel>::MuteStream(ssrc, !enable)) { 283 return false; 284 } 285 if (enable && options) { 286 return SetOptions(*options); 287 } 288 return true; 289 } 290 virtual bool AddRecvStream(const StreamParams& sp) { 291 if (!RtpHelper<VoiceMediaChannel>::AddRecvStream(sp)) 292 return false; 293 output_scalings_[sp.first_ssrc()] = 1.0; 294 return true; 295 } 296 virtual bool RemoveRecvStream(uint32_t ssrc) { 297 if (!RtpHelper<VoiceMediaChannel>::RemoveRecvStream(ssrc)) 298 return false; 299 output_scalings_.erase(ssrc); 300 return true; 301 } 302 303 virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; } 304 virtual int GetOutputLevel() { return 0; } 305 void set_time_since_last_typing(int ms) { time_since_last_typing_ = ms; } 306 virtual int GetTimeSinceLastTyping() { return time_since_last_typing_; } 307 virtual void SetTypingDetectionParameters( 308 int time_window, int cost_per_typing, int reporting_threshold, 309 int penalty_decay, int type_event_delay) {} 310 311 virtual bool CanInsertDtmf() { 312 for (std::vector<AudioCodec>::const_iterator it = send_codecs_.begin(); 313 it != send_codecs_.end(); ++it) { 314 // Find the DTMF telephone event "codec". 315 if (_stricmp(it->name.c_str(), "telephone-event") == 0) { 316 return true; 317 } 318 } 319 return false; 320 } 321 virtual bool InsertDtmf(uint32_t ssrc, 322 int event_code, 323 int duration) { 324 dtmf_info_queue_.push_back(DtmfInfo(ssrc, event_code, duration)); 325 return true; 326 } 327 328 virtual bool SetOutputVolume(uint32_t ssrc, double volume) { 329 if (0 == ssrc) { 330 std::map<uint32_t, double>::iterator it; 331 for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) { 332 it->second = volume; 333 } 334 return true; 335 } else if (output_scalings_.find(ssrc) != output_scalings_.end()) { 336 output_scalings_[ssrc] = volume; 337 return true; 338 } 339 return false; 340 } 341 bool GetOutputVolume(uint32_t ssrc, double* volume) { 342 if (output_scalings_.find(ssrc) == output_scalings_.end()) 343 return false; 344 *volume = output_scalings_[ssrc]; 345 return true; 346 } 347 348 virtual bool GetStats(VoiceMediaInfo* info) { return false; } 349 350 virtual void SetRawAudioSink( 351 uint32_t ssrc, 352 rtc::scoped_ptr<webrtc::AudioSinkInterface> sink) { 353 sink_ = std::move(sink); 354 } 355 356 private: 357 class VoiceChannelAudioSink : public AudioRenderer::Sink { 358 public: 359 explicit VoiceChannelAudioSink(AudioRenderer* renderer) 360 : renderer_(renderer) { 361 renderer_->SetSink(this); 362 } 363 virtual ~VoiceChannelAudioSink() { 364 if (renderer_) { 365 renderer_->SetSink(NULL); 366 } 367 } 368 void OnData(const void* audio_data, 369 int bits_per_sample, 370 int sample_rate, 371 size_t number_of_channels, 372 size_t number_of_frames) override {} 373 void OnClose() override { renderer_ = NULL; } 374 AudioRenderer* renderer() const { return renderer_; } 375 376 private: 377 AudioRenderer* renderer_; 378 }; 379 380 bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) { 381 if (fail_set_recv_codecs()) { 382 // Fake the failure in SetRecvCodecs. 383 return false; 384 } 385 recv_codecs_ = codecs; 386 return true; 387 } 388 bool SetSendCodecs(const std::vector<AudioCodec>& codecs) { 389 if (fail_set_send_codecs()) { 390 // Fake the failure in SetSendCodecs. 391 return false; 392 } 393 send_codecs_ = codecs; 394 return true; 395 } 396 bool SetMaxSendBandwidth(int bps) { return true; } 397 bool SetOptions(const AudioOptions& options) { 398 // Does a "merge" of current options and set options. 399 options_.SetAll(options); 400 return true; 401 } 402 bool SetLocalRenderer(uint32_t ssrc, AudioRenderer* renderer) { 403 auto it = local_renderers_.find(ssrc); 404 if (renderer) { 405 if (it != local_renderers_.end()) { 406 ASSERT(it->second->renderer() == renderer); 407 } else { 408 local_renderers_.insert(std::make_pair( 409 ssrc, new VoiceChannelAudioSink(renderer))); 410 } 411 } else { 412 if (it != local_renderers_.end()) { 413 delete it->second; 414 local_renderers_.erase(it); 415 } 416 } 417 return true; 418 } 419 420 FakeVoiceEngine* engine_; 421 std::vector<AudioCodec> recv_codecs_; 422 std::vector<AudioCodec> send_codecs_; 423 std::map<uint32_t, double> output_scalings_; 424 std::vector<DtmfInfo> dtmf_info_queue_; 425 int time_since_last_typing_; 426 AudioOptions options_; 427 std::map<uint32_t, VoiceChannelAudioSink*> local_renderers_; 428 rtc::scoped_ptr<webrtc::AudioSinkInterface> sink_; 429 }; 430 431 // A helper function to compare the FakeVoiceMediaChannel::DtmfInfo. 432 inline bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info, 433 uint32_t ssrc, 434 int event_code, 435 int duration) { 436 return (info.duration == duration && info.event_code == event_code && 437 info.ssrc == ssrc); 438 } 439 440 class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> { 441 public: 442 explicit FakeVideoMediaChannel(FakeVideoEngine* engine, 443 const VideoOptions& options) 444 : engine_(engine), 445 sent_intra_frame_(false), 446 requested_intra_frame_(false), 447 max_bps_(-1) { 448 SetOptions(options); 449 } 450 451 ~FakeVideoMediaChannel(); 452 453 const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; } 454 const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; } 455 const std::vector<VideoCodec>& codecs() const { return send_codecs(); } 456 bool rendering() const { return playout(); } 457 const VideoOptions& options() const { return options_; } 458 const std::map<uint32_t, VideoRenderer*>& renderers() const { 459 return renderers_; 460 } 461 int max_bps() const { return max_bps_; } 462 bool GetSendStreamFormat(uint32_t ssrc, VideoFormat* format) { 463 if (send_formats_.find(ssrc) == send_formats_.end()) { 464 return false; 465 } 466 *format = send_formats_[ssrc]; 467 return true; 468 } 469 virtual bool SetSendStreamFormat(uint32_t ssrc, const VideoFormat& format) { 470 if (send_formats_.find(ssrc) == send_formats_.end()) { 471 return false; 472 } 473 send_formats_[ssrc] = format; 474 return true; 475 } 476 virtual bool SetSendParameters(const VideoSendParameters& params) { 477 return (SetSendCodecs(params.codecs) && 478 SetSendRtpHeaderExtensions(params.extensions) && 479 SetMaxSendBandwidth(params.max_bandwidth_bps) && 480 SetOptions(params.options)); 481 } 482 483 virtual bool SetRecvParameters(const VideoRecvParameters& params) { 484 return (SetRecvCodecs(params.codecs) && 485 SetRecvRtpHeaderExtensions(params.extensions)); 486 } 487 virtual bool AddSendStream(const StreamParams& sp) { 488 if (!RtpHelper<VideoMediaChannel>::AddSendStream(sp)) { 489 return false; 490 } 491 SetSendStreamDefaultFormat(sp.first_ssrc()); 492 return true; 493 } 494 virtual bool RemoveSendStream(uint32_t ssrc) { 495 send_formats_.erase(ssrc); 496 return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc); 497 } 498 499 virtual bool GetSendCodec(VideoCodec* send_codec) { 500 if (send_codecs_.empty()) { 501 return false; 502 } 503 *send_codec = send_codecs_[0]; 504 return true; 505 } 506 virtual bool SetRenderer(uint32_t ssrc, VideoRenderer* r) { 507 if (ssrc != 0 && renderers_.find(ssrc) == renderers_.end()) { 508 return false; 509 } 510 if (ssrc != 0) { 511 renderers_[ssrc] = r; 512 } 513 return true; 514 } 515 516 virtual bool SetSend(bool send) { return set_sending(send); } 517 virtual bool SetVideoSend(uint32_t ssrc, bool enable, 518 const VideoOptions* options) { 519 if (!RtpHelper<VideoMediaChannel>::MuteStream(ssrc, !enable)) { 520 return false; 521 } 522 if (enable && options) { 523 return SetOptions(*options); 524 } 525 return true; 526 } 527 virtual bool SetCapturer(uint32_t ssrc, VideoCapturer* capturer) { 528 capturers_[ssrc] = capturer; 529 return true; 530 } 531 bool HasCapturer(uint32_t ssrc) const { 532 return capturers_.find(ssrc) != capturers_.end(); 533 } 534 virtual bool AddRecvStream(const StreamParams& sp) { 535 if (!RtpHelper<VideoMediaChannel>::AddRecvStream(sp)) 536 return false; 537 renderers_[sp.first_ssrc()] = NULL; 538 return true; 539 } 540 virtual bool RemoveRecvStream(uint32_t ssrc) { 541 if (!RtpHelper<VideoMediaChannel>::RemoveRecvStream(ssrc)) 542 return false; 543 renderers_.erase(ssrc); 544 return true; 545 } 546 547 virtual bool GetStats(VideoMediaInfo* info) { return false; } 548 virtual bool SendIntraFrame() { 549 sent_intra_frame_ = true; 550 return true; 551 } 552 virtual bool RequestIntraFrame() { 553 requested_intra_frame_ = true; 554 return true; 555 } 556 virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {} 557 void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; } 558 bool sent_intra_frame() const { return sent_intra_frame_; } 559 void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; } 560 bool requested_intra_frame() const { return requested_intra_frame_; } 561 562 private: 563 bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 564 if (fail_set_recv_codecs()) { 565 // Fake the failure in SetRecvCodecs. 566 return false; 567 } 568 recv_codecs_ = codecs; 569 return true; 570 } 571 bool SetSendCodecs(const std::vector<VideoCodec>& codecs) { 572 if (fail_set_send_codecs()) { 573 // Fake the failure in SetSendCodecs. 574 return false; 575 } 576 send_codecs_ = codecs; 577 578 for (std::vector<StreamParams>::const_iterator it = send_streams().begin(); 579 it != send_streams().end(); ++it) { 580 SetSendStreamDefaultFormat(it->first_ssrc()); 581 } 582 return true; 583 } 584 bool SetOptions(const VideoOptions& options) { 585 options_ = options; 586 return true; 587 } 588 bool SetMaxSendBandwidth(int bps) { 589 max_bps_ = bps; 590 return true; 591 } 592 593 // Be default, each send stream uses the first send codec format. 594 void SetSendStreamDefaultFormat(uint32_t ssrc) { 595 if (!send_codecs_.empty()) { 596 send_formats_[ssrc] = VideoFormat( 597 send_codecs_[0].width, send_codecs_[0].height, 598 cricket::VideoFormat::FpsToInterval(send_codecs_[0].framerate), 599 cricket::FOURCC_I420); 600 } 601 } 602 603 FakeVideoEngine* engine_; 604 std::vector<VideoCodec> recv_codecs_; 605 std::vector<VideoCodec> send_codecs_; 606 std::map<uint32_t, VideoRenderer*> renderers_; 607 std::map<uint32_t, VideoFormat> send_formats_; 608 std::map<uint32_t, VideoCapturer*> capturers_; 609 bool sent_intra_frame_; 610 bool requested_intra_frame_; 611 VideoOptions options_; 612 int max_bps_; 613 }; 614 615 class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> { 616 public: 617 explicit FakeDataMediaChannel(void* unused, const DataOptions& options) 618 : send_blocked_(false), max_bps_(-1) {} 619 ~FakeDataMediaChannel() {} 620 const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; } 621 const std::vector<DataCodec>& send_codecs() const { return send_codecs_; } 622 const std::vector<DataCodec>& codecs() const { return send_codecs(); } 623 int max_bps() const { return max_bps_; } 624 625 virtual bool SetSendParameters(const DataSendParameters& params) { 626 return (SetSendCodecs(params.codecs) && 627 SetMaxSendBandwidth(params.max_bandwidth_bps)); 628 } 629 virtual bool SetRecvParameters(const DataRecvParameters& params) { 630 return SetRecvCodecs(params.codecs); 631 } 632 virtual bool SetSend(bool send) { return set_sending(send); } 633 virtual bool SetReceive(bool receive) { 634 set_playout(receive); 635 return true; 636 } 637 virtual bool AddRecvStream(const StreamParams& sp) { 638 if (!RtpHelper<DataMediaChannel>::AddRecvStream(sp)) 639 return false; 640 return true; 641 } 642 virtual bool RemoveRecvStream(uint32_t ssrc) { 643 if (!RtpHelper<DataMediaChannel>::RemoveRecvStream(ssrc)) 644 return false; 645 return true; 646 } 647 648 virtual bool SendData(const SendDataParams& params, 649 const rtc::Buffer& payload, 650 SendDataResult* result) { 651 if (send_blocked_) { 652 *result = SDR_BLOCK; 653 return false; 654 } else { 655 last_sent_data_params_ = params; 656 last_sent_data_ = std::string(payload.data<char>(), payload.size()); 657 return true; 658 } 659 } 660 661 SendDataParams last_sent_data_params() { return last_sent_data_params_; } 662 std::string last_sent_data() { return last_sent_data_; } 663 bool is_send_blocked() { return send_blocked_; } 664 void set_send_blocked(bool blocked) { send_blocked_ = blocked; } 665 666 private: 667 bool SetRecvCodecs(const std::vector<DataCodec>& codecs) { 668 if (fail_set_recv_codecs()) { 669 // Fake the failure in SetRecvCodecs. 670 return false; 671 } 672 recv_codecs_ = codecs; 673 return true; 674 } 675 bool SetSendCodecs(const std::vector<DataCodec>& codecs) { 676 if (fail_set_send_codecs()) { 677 // Fake the failure in SetSendCodecs. 678 return false; 679 } 680 send_codecs_ = codecs; 681 return true; 682 } 683 bool SetMaxSendBandwidth(int bps) { 684 max_bps_ = bps; 685 return true; 686 } 687 688 std::vector<DataCodec> recv_codecs_; 689 std::vector<DataCodec> send_codecs_; 690 SendDataParams last_sent_data_params_; 691 std::string last_sent_data_; 692 bool send_blocked_; 693 int max_bps_; 694 }; 695 696 // A base class for all of the shared parts between FakeVoiceEngine 697 // and FakeVideoEngine. 698 class FakeBaseEngine { 699 public: 700 FakeBaseEngine() 701 : options_changed_(false), 702 fail_create_channel_(false) {} 703 void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; } 704 705 RtpCapabilities GetCapabilities() const { return capabilities_; } 706 void set_rtp_header_extensions( 707 const std::vector<RtpHeaderExtension>& extensions) { 708 capabilities_.header_extensions = extensions; 709 } 710 711 protected: 712 // Flag used by optionsmessagehandler_unittest for checking whether any 713 // relevant setting has been updated. 714 // TODO(thaloun): Replace with explicit checks of before & after values. 715 bool options_changed_; 716 bool fail_create_channel_; 717 RtpCapabilities capabilities_; 718 }; 719 720 class FakeVoiceEngine : public FakeBaseEngine { 721 public: 722 FakeVoiceEngine() 723 : output_volume_(-1) { 724 // Add a fake audio codec. Note that the name must not be "" as there are 725 // sanity checks against that. 726 codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1, 0)); 727 } 728 bool Init(rtc::Thread* worker_thread) { return true; } 729 void Terminate() {} 730 rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const { 731 return rtc::scoped_refptr<webrtc::AudioState>(); 732 } 733 734 VoiceMediaChannel* CreateChannel(webrtc::Call* call, 735 const AudioOptions& options) { 736 if (fail_create_channel_) { 737 return nullptr; 738 } 739 740 FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this, options); 741 channels_.push_back(ch); 742 return ch; 743 } 744 FakeVoiceMediaChannel* GetChannel(size_t index) { 745 return (channels_.size() > index) ? channels_[index] : NULL; 746 } 747 void UnregisterChannel(VoiceMediaChannel* channel) { 748 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 749 } 750 751 const std::vector<AudioCodec>& codecs() { return codecs_; } 752 void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; } 753 754 bool GetOutputVolume(int* level) { 755 *level = output_volume_; 756 return true; 757 } 758 bool SetOutputVolume(int level) { 759 output_volume_ = level; 760 return true; 761 } 762 763 int GetInputLevel() { return 0; } 764 765 bool StartAecDump(rtc::PlatformFile file) { return false; } 766 767 void StopAecDump() {} 768 769 bool StartRtcEventLog(rtc::PlatformFile file) { return false; } 770 771 void StopRtcEventLog() {} 772 773 private: 774 std::vector<FakeVoiceMediaChannel*> channels_; 775 std::vector<AudioCodec> codecs_; 776 int output_volume_; 777 778 friend class FakeMediaEngine; 779 }; 780 781 class FakeVideoEngine : public FakeBaseEngine { 782 public: 783 FakeVideoEngine() : capture_(false) { 784 // Add a fake video codec. Note that the name must not be "" as there are 785 // sanity checks against that. 786 codecs_.push_back(VideoCodec(0, "fake_video_codec", 0, 0, 0, 0)); 787 } 788 void Init() {} 789 bool SetOptions(const VideoOptions& options) { 790 options_ = options; 791 options_changed_ = true; 792 return true; 793 } 794 795 VideoMediaChannel* CreateChannel(webrtc::Call* call, 796 const VideoOptions& options) { 797 if (fail_create_channel_) { 798 return NULL; 799 } 800 801 FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this, options); 802 channels_.push_back(ch); 803 return ch; 804 } 805 FakeVideoMediaChannel* GetChannel(size_t index) { 806 return (channels_.size() > index) ? channels_[index] : NULL; 807 } 808 void UnregisterChannel(VideoMediaChannel* channel) { 809 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 810 } 811 812 const std::vector<VideoCodec>& codecs() const { return codecs_; } 813 bool FindCodec(const VideoCodec& in) { 814 for (size_t i = 0; i < codecs_.size(); ++i) { 815 if (codecs_[i].Matches(in)) { 816 return true; 817 } 818 } 819 return false; 820 } 821 void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; } 822 823 bool SetCaptureDevice(const Device* device) { 824 in_device_ = (device) ? device->name : ""; 825 options_changed_ = true; 826 return true; 827 } 828 bool SetCapture(bool capture) { 829 capture_ = capture; 830 return true; 831 } 832 833 private: 834 std::vector<FakeVideoMediaChannel*> channels_; 835 std::vector<VideoCodec> codecs_; 836 std::string in_device_; 837 bool capture_; 838 VideoOptions options_; 839 840 friend class FakeMediaEngine; 841 }; 842 843 class FakeMediaEngine : 844 public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> { 845 public: 846 FakeMediaEngine() {} 847 virtual ~FakeMediaEngine() {} 848 849 void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { 850 voice_.SetCodecs(codecs); 851 } 852 void SetVideoCodecs(const std::vector<VideoCodec>& codecs) { 853 video_.SetCodecs(codecs); 854 } 855 856 void SetAudioRtpHeaderExtensions( 857 const std::vector<RtpHeaderExtension>& extensions) { 858 voice_.set_rtp_header_extensions(extensions); 859 } 860 void SetVideoRtpHeaderExtensions( 861 const std::vector<RtpHeaderExtension>& extensions) { 862 video_.set_rtp_header_extensions(extensions); 863 } 864 865 FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { 866 return voice_.GetChannel(index); 867 } 868 FakeVideoMediaChannel* GetVideoChannel(size_t index) { 869 return video_.GetChannel(index); 870 } 871 872 int output_volume() const { return voice_.output_volume_; } 873 bool capture() const { return video_.capture_; } 874 bool options_changed() const { 875 return video_.options_changed_; 876 } 877 void clear_options_changed() { 878 video_.options_changed_ = false; 879 } 880 void set_fail_create_channel(bool fail) { 881 voice_.set_fail_create_channel(fail); 882 video_.set_fail_create_channel(fail); 883 } 884 }; 885 886 // CompositeMediaEngine with FakeVoiceEngine to expose SetAudioCodecs to 887 // establish a media connectionwith minimum set of audio codes required 888 template <class VIDEO> 889 class CompositeMediaEngineWithFakeVoiceEngine : 890 public CompositeMediaEngine<FakeVoiceEngine, VIDEO> { 891 public: 892 CompositeMediaEngineWithFakeVoiceEngine() {} 893 virtual ~CompositeMediaEngineWithFakeVoiceEngine() {} 894 895 virtual void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { 896 CompositeMediaEngine<FakeVoiceEngine, VIDEO>::voice_.SetCodecs(codecs); 897 } 898 }; 899 900 // Have to come afterwards due to declaration order 901 inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() { 902 if (engine_) { 903 engine_->UnregisterChannel(this); 904 } 905 } 906 907 inline FakeVideoMediaChannel::~FakeVideoMediaChannel() { 908 if (engine_) { 909 engine_->UnregisterChannel(this); 910 } 911 } 912 913 class FakeDataEngine : public DataEngineInterface { 914 public: 915 FakeDataEngine() : last_channel_type_(DCT_NONE) {} 916 917 virtual DataMediaChannel* CreateChannel(DataChannelType data_channel_type) { 918 last_channel_type_ = data_channel_type; 919 FakeDataMediaChannel* ch = new FakeDataMediaChannel(this, DataOptions()); 920 channels_.push_back(ch); 921 return ch; 922 } 923 924 FakeDataMediaChannel* GetChannel(size_t index) { 925 return (channels_.size() > index) ? channels_[index] : NULL; 926 } 927 928 void UnregisterChannel(DataMediaChannel* channel) { 929 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 930 } 931 932 virtual void SetDataCodecs(const std::vector<DataCodec>& data_codecs) { 933 data_codecs_ = data_codecs; 934 } 935 936 virtual const std::vector<DataCodec>& data_codecs() { return data_codecs_; } 937 938 DataChannelType last_channel_type() const { return last_channel_type_; } 939 940 private: 941 std::vector<FakeDataMediaChannel*> channels_; 942 std::vector<DataCodec> data_codecs_; 943 DataChannelType last_channel_type_; 944 }; 945 946 } // namespace cricket 947 948 #endif // TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_ 949