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/base/buffer.h" 38 #include "talk/base/stringutils.h" 39 #include "talk/media/base/audiorenderer.h" 40 #include "talk/media/base/mediaengine.h" 41 #include "talk/media/base/rtputils.h" 42 #include "talk/media/base/streamparams.h" 43 #include "talk/p2p/base/sessiondescription.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 talk_base::Buffer packet(data, len, kMaxRtpPacketLen); 77 return Base::SendPacket(&packet); 78 } 79 bool SendRtcp(const void* data, int len) { 80 talk_base::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(talk_base::Buffer* packet, 195 const talk_base::PacketTime& packet_time) { 196 rtp_packets_.push_back(std::string(packet->data(), packet->length())); 197 } 198 virtual void OnRtcpReceived(talk_base::Buffer* packet, 199 const talk_base::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 SetSendBandwidth(bool autobw, int bps) { return true; } 285 virtual bool AddRecvStream(const StreamParams& sp) { 286 if (!RtpHelper<VoiceMediaChannel>::AddRecvStream(sp)) 287 return false; 288 output_scalings_[sp.first_ssrc()] = OutputScaling(); 289 return true; 290 } 291 virtual bool RemoveRecvStream(uint32 ssrc) { 292 if (!RtpHelper<VoiceMediaChannel>::RemoveRecvStream(ssrc)) 293 return false; 294 output_scalings_.erase(ssrc); 295 return true; 296 } 297 virtual bool SetRemoteRenderer(uint32 ssrc, AudioRenderer* renderer) { 298 std::map<uint32, AudioRenderer*>::iterator it = 299 remote_renderers_.find(ssrc); 300 if (renderer) { 301 if (it != remote_renderers_.end()) { 302 ASSERT(it->second == renderer); 303 } else { 304 remote_renderers_.insert(std::make_pair(ssrc, renderer)); 305 renderer->AddChannel(0); 306 } 307 } else { 308 if (it != remote_renderers_.end()) { 309 it->second->RemoveChannel(0); 310 remote_renderers_.erase(it); 311 } else { 312 return false; 313 } 314 } 315 return true; 316 } 317 virtual bool SetLocalRenderer(uint32 ssrc, AudioRenderer* renderer) { 318 std::map<uint32, AudioRenderer*>::iterator it = local_renderers_.find(ssrc); 319 if (renderer) { 320 if (it != local_renderers_.end()) { 321 ASSERT(it->second == renderer); 322 } else { 323 local_renderers_.insert(std::make_pair(ssrc, renderer)); 324 renderer->AddChannel(0); 325 } 326 } else { 327 if (it != local_renderers_.end()) { 328 it->second->RemoveChannel(0); 329 local_renderers_.erase(it); 330 } else { 331 return false; 332 } 333 } 334 return true; 335 } 336 337 virtual bool GetActiveStreams(AudioInfo::StreamList* streams) { return true; } 338 virtual int GetOutputLevel() { return 0; } 339 void set_time_since_last_typing(int ms) { time_since_last_typing_ = ms; } 340 virtual int GetTimeSinceLastTyping() { return time_since_last_typing_; } 341 virtual void SetTypingDetectionParameters( 342 int time_window, int cost_per_typing, int reporting_threshold, 343 int penalty_decay, int type_event_delay) {} 344 345 virtual bool SetRingbackTone(const char* buf, int len) { return true; } 346 virtual bool PlayRingbackTone(uint32 ssrc, bool play, bool loop) { 347 ringback_tone_ssrc_ = ssrc; 348 ringback_tone_play_ = play; 349 ringback_tone_loop_ = loop; 350 return true; 351 } 352 353 virtual bool CanInsertDtmf() { 354 for (std::vector<AudioCodec>::const_iterator it = send_codecs_.begin(); 355 it != send_codecs_.end(); ++it) { 356 // Find the DTMF telephone event "codec". 357 if (_stricmp(it->name.c_str(), "telephone-event") == 0) { 358 return true; 359 } 360 } 361 return false; 362 } 363 virtual bool InsertDtmf(uint32 ssrc, int event_code, int duration, 364 int flags) { 365 dtmf_info_queue_.push_back(DtmfInfo(ssrc, event_code, duration, flags)); 366 return true; 367 } 368 369 virtual bool SetOutputScaling(uint32 ssrc, double left, double right) { 370 if (0 == ssrc) { 371 std::map<uint32, OutputScaling>::iterator it; 372 for (it = output_scalings_.begin(); it != output_scalings_.end(); ++it) { 373 it->second.left = left; 374 it->second.right = right; 375 } 376 return true; 377 } else if (output_scalings_.find(ssrc) != output_scalings_.end()) { 378 output_scalings_[ssrc].left = left; 379 output_scalings_[ssrc].right = right; 380 return true; 381 } 382 return false; 383 } 384 virtual bool GetOutputScaling(uint32 ssrc, double* left, double* right) { 385 if (output_scalings_.find(ssrc) == output_scalings_.end()) 386 return false; 387 *left = output_scalings_[ssrc].left; 388 *right = output_scalings_[ssrc].right; 389 return true; 390 } 391 392 virtual bool GetStats(VoiceMediaInfo* info) { return false; } 393 virtual void GetLastMediaError(uint32* ssrc, 394 VoiceMediaChannel::Error* error) { 395 *ssrc = 0; 396 *error = fail_set_send_ ? VoiceMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED 397 : VoiceMediaChannel::ERROR_NONE; 398 } 399 400 void set_fail_set_send(bool fail) { fail_set_send_ = fail; } 401 void TriggerError(uint32 ssrc, VoiceMediaChannel::Error error) { 402 VoiceMediaChannel::SignalMediaError(ssrc, error); 403 } 404 405 virtual bool SetOptions(const AudioOptions& options) { 406 // Does a "merge" of current options and set options. 407 options_.SetAll(options); 408 return true; 409 } 410 virtual bool GetOptions(AudioOptions* options) const { 411 *options = options_; 412 return true; 413 } 414 415 private: 416 struct OutputScaling { 417 OutputScaling() : left(1.0), right(1.0) {} 418 double left, right; 419 }; 420 421 FakeVoiceEngine* engine_; 422 std::vector<AudioCodec> recv_codecs_; 423 std::vector<AudioCodec> send_codecs_; 424 std::map<uint32, OutputScaling> output_scalings_; 425 std::vector<DtmfInfo> dtmf_info_queue_; 426 bool fail_set_send_; 427 uint32 ringback_tone_ssrc_; 428 bool ringback_tone_play_; 429 bool ringback_tone_loop_; 430 int time_since_last_typing_; 431 AudioOptions options_; 432 std::map<uint32, AudioRenderer*> local_renderers_; 433 std::map<uint32, AudioRenderer*> remote_renderers_; 434 }; 435 436 // A helper function to compare the FakeVoiceMediaChannel::DtmfInfo. 437 inline bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info, 438 uint32 ssrc, int event_code, int duration, 439 int flags) { 440 return (info.duration == duration && info.event_code == event_code && 441 info.flags == flags && info.ssrc == ssrc); 442 } 443 444 class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> { 445 public: 446 explicit FakeVideoMediaChannel(FakeVideoEngine* engine) 447 : engine_(engine), 448 sent_intra_frame_(false), 449 requested_intra_frame_(false) {} 450 ~FakeVideoMediaChannel(); 451 452 const std::vector<VideoCodec>& recv_codecs() const { return recv_codecs_; } 453 const std::vector<VideoCodec>& send_codecs() const { return send_codecs_; } 454 const std::vector<VideoCodec>& codecs() const { return send_codecs(); } 455 bool rendering() const { return playout(); } 456 const VideoOptions& options() const { return options_; } 457 const std::map<uint32, VideoRenderer*>& renderers() const { 458 return renderers_; 459 } 460 bool GetSendStreamFormat(uint32 ssrc, VideoFormat* format) { 461 if (send_formats_.find(ssrc) == send_formats_.end()) { 462 return false; 463 } 464 *format = send_formats_[ssrc]; 465 return true; 466 } 467 virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format) { 468 if (send_formats_.find(ssrc) == send_formats_.end()) { 469 return false; 470 } 471 send_formats_[ssrc] = format; 472 return true; 473 } 474 475 virtual bool AddSendStream(const StreamParams& sp) { 476 if (!RtpHelper<VideoMediaChannel>::AddSendStream(sp)) { 477 return false; 478 } 479 SetSendStreamDefaultFormat(sp.first_ssrc()); 480 return true; 481 } 482 virtual bool RemoveSendStream(uint32 ssrc) { 483 send_formats_.erase(ssrc); 484 return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc); 485 } 486 487 virtual bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) { 488 if (fail_set_recv_codecs()) { 489 // Fake the failure in SetRecvCodecs. 490 return false; 491 } 492 recv_codecs_ = codecs; 493 return true; 494 } 495 virtual bool SetSendCodecs(const std::vector<VideoCodec>& codecs) { 496 if (fail_set_send_codecs()) { 497 // Fake the failure in SetSendCodecs. 498 return false; 499 } 500 send_codecs_ = codecs; 501 502 for (std::vector<StreamParams>::const_iterator it = send_streams().begin(); 503 it != send_streams().end(); ++it) { 504 SetSendStreamDefaultFormat(it->first_ssrc()); 505 } 506 return true; 507 } 508 virtual bool GetSendCodec(VideoCodec* send_codec) { 509 if (send_codecs_.empty()) { 510 return false; 511 } 512 *send_codec = send_codecs_[0]; 513 return true; 514 } 515 virtual bool SetRender(bool render) { 516 set_playout(render); 517 return true; 518 } 519 virtual bool SetRenderer(uint32 ssrc, VideoRenderer* r) { 520 if (ssrc != 0 && renderers_.find(ssrc) == renderers_.end()) { 521 return false; 522 } 523 if (ssrc != 0) { 524 renderers_[ssrc] = r; 525 } 526 return true; 527 } 528 529 virtual bool SetSend(bool send) { return set_sending(send); } 530 virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) { 531 capturers_[ssrc] = capturer; 532 return true; 533 } 534 bool HasCapturer(uint32 ssrc) const { 535 return capturers_.find(ssrc) != capturers_.end(); 536 } 537 virtual bool SetSendBandwidth(bool autobw, int bps) { return true; } 538 virtual bool AddRecvStream(const StreamParams& sp) { 539 if (!RtpHelper<VideoMediaChannel>::AddRecvStream(sp)) 540 return false; 541 renderers_[sp.first_ssrc()] = NULL; 542 return true; 543 } 544 virtual bool RemoveRecvStream(uint32 ssrc) { 545 if (!RtpHelper<VideoMediaChannel>::RemoveRecvStream(ssrc)) 546 return false; 547 renderers_.erase(ssrc); 548 return true; 549 } 550 551 virtual bool GetStats(VideoMediaInfo* info) { return false; } 552 virtual bool SendIntraFrame() { 553 sent_intra_frame_ = true; 554 return true; 555 } 556 virtual bool RequestIntraFrame() { 557 requested_intra_frame_ = true; 558 return true; 559 } 560 virtual bool SetOptions(const VideoOptions& options) { 561 options_ = options; 562 return true; 563 } 564 virtual bool GetOptions(VideoOptions* options) const { 565 *options = options_; 566 return true; 567 } 568 virtual void UpdateAspectRatio(int ratio_w, int ratio_h) {} 569 void set_sent_intra_frame(bool v) { sent_intra_frame_ = v; } 570 bool sent_intra_frame() const { return sent_intra_frame_; } 571 void set_requested_intra_frame(bool v) { requested_intra_frame_ = v; } 572 bool requested_intra_frame() const { return requested_intra_frame_; } 573 574 private: 575 // Be default, each send stream uses the first send codec format. 576 void SetSendStreamDefaultFormat(uint32 ssrc) { 577 if (!send_codecs_.empty()) { 578 send_formats_[ssrc] = VideoFormat( 579 send_codecs_[0].width, send_codecs_[0].height, 580 cricket::VideoFormat::FpsToInterval(send_codecs_[0].framerate), 581 cricket::FOURCC_I420); 582 } 583 } 584 585 FakeVideoEngine* engine_; 586 std::vector<VideoCodec> recv_codecs_; 587 std::vector<VideoCodec> send_codecs_; 588 std::map<uint32, VideoRenderer*> renderers_; 589 std::map<uint32, VideoFormat> send_formats_; 590 std::map<uint32, VideoCapturer*> capturers_; 591 bool sent_intra_frame_; 592 bool requested_intra_frame_; 593 VideoOptions options_; 594 }; 595 596 class FakeSoundclipMedia : public SoundclipMedia { 597 public: 598 virtual bool PlaySound(const char* buf, int len, int flags) { return true; } 599 }; 600 601 class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> { 602 public: 603 explicit FakeDataMediaChannel(void* unused) 604 : auto_bandwidth_(false), send_blocked_(false), max_bps_(-1) {} 605 ~FakeDataMediaChannel() {} 606 const std::vector<DataCodec>& recv_codecs() const { return recv_codecs_; } 607 const std::vector<DataCodec>& send_codecs() const { return send_codecs_; } 608 const std::vector<DataCodec>& codecs() const { return send_codecs(); } 609 bool auto_bandwidth() const { return auto_bandwidth_; } 610 int max_bps() const { return max_bps_; } 611 612 virtual bool SetRecvCodecs(const std::vector<DataCodec>& codecs) { 613 if (fail_set_recv_codecs()) { 614 // Fake the failure in SetRecvCodecs. 615 return false; 616 } 617 recv_codecs_ = codecs; 618 return true; 619 } 620 virtual bool SetSendCodecs(const std::vector<DataCodec>& codecs) { 621 if (fail_set_send_codecs()) { 622 // Fake the failure in SetSendCodecs. 623 return false; 624 } 625 send_codecs_ = codecs; 626 return true; 627 } 628 virtual bool SetSend(bool send) { return set_sending(send); } 629 virtual bool SetReceive(bool receive) { 630 set_playout(receive); 631 return true; 632 } 633 virtual bool SetSendBandwidth(bool autobw, int bps) { 634 auto_bandwidth_ = autobw; 635 max_bps_ = bps; 636 return true; 637 } 638 virtual bool AddRecvStream(const StreamParams& sp) { 639 if (!RtpHelper<DataMediaChannel>::AddRecvStream(sp)) 640 return false; 641 return true; 642 } 643 virtual bool RemoveRecvStream(uint32 ssrc) { 644 if (!RtpHelper<DataMediaChannel>::RemoveRecvStream(ssrc)) 645 return false; 646 return true; 647 } 648 649 virtual bool SendData(const SendDataParams& params, 650 const talk_base::Buffer& payload, 651 SendDataResult* result) { 652 if (send_blocked_) { 653 *result = SDR_BLOCK; 654 return false; 655 } else { 656 last_sent_data_params_ = params; 657 last_sent_data_ = std::string(payload.data(), payload.length()); 658 return true; 659 } 660 } 661 662 SendDataParams last_sent_data_params() { return last_sent_data_params_; } 663 std::string last_sent_data() { return last_sent_data_; } 664 bool is_send_blocked() { return send_blocked_; } 665 void set_send_blocked(bool blocked) { send_blocked_ = blocked; } 666 667 private: 668 std::vector<DataCodec> recv_codecs_; 669 std::vector<DataCodec> send_codecs_; 670 SendDataParams last_sent_data_params_; 671 std::string last_sent_data_; 672 bool auto_bandwidth_; 673 bool send_blocked_; 674 int max_bps_; 675 }; 676 677 // A base class for all of the shared parts between FakeVoiceEngine 678 // and FakeVideoEngine. 679 class FakeBaseEngine { 680 public: 681 FakeBaseEngine() 682 : loglevel_(-1), 683 options_changed_(false), 684 fail_create_channel_(false) {} 685 bool Init(talk_base::Thread* worker_thread) { return true; } 686 void Terminate() {} 687 688 void SetLogging(int level, const char* filter) { 689 loglevel_ = level; 690 logfilter_ = filter; 691 } 692 693 void set_fail_create_channel(bool fail) { fail_create_channel_ = fail; } 694 695 const std::vector<RtpHeaderExtension>& rtp_header_extensions() const { 696 return rtp_header_extensions_; 697 } 698 699 protected: 700 int loglevel_; 701 std::string logfilter_; 702 // Flag used by optionsmessagehandler_unittest for checking whether any 703 // relevant setting has been updated. 704 // TODO(thaloun): Replace with explicit checks of before & after values. 705 bool options_changed_; 706 bool fail_create_channel_; 707 std::vector<RtpHeaderExtension> rtp_header_extensions_; 708 }; 709 710 class FakeVoiceEngine : public FakeBaseEngine { 711 public: 712 FakeVoiceEngine() 713 : output_volume_(-1), 714 delay_offset_(0), 715 rx_processor_(NULL), 716 tx_processor_(NULL) { 717 // Add a fake audio codec. Note that the name must not be "" as there are 718 // sanity checks against that. 719 codecs_.push_back(AudioCodec(101, "fake_audio_codec", 0, 0, 1, 0)); 720 } 721 int GetCapabilities() { return AUDIO_SEND | AUDIO_RECV; } 722 AudioOptions GetAudioOptions() const { 723 return options_; 724 } 725 AudioOptions GetOptions() const { 726 return options_; 727 } 728 bool SetOptions(const AudioOptions& options) { 729 options_ = options; 730 options_changed_ = true; 731 return true; 732 } 733 734 VoiceMediaChannel* CreateChannel() { 735 if (fail_create_channel_) { 736 return NULL; 737 } 738 739 FakeVoiceMediaChannel* ch = new FakeVoiceMediaChannel(this); 740 channels_.push_back(ch); 741 return ch; 742 } 743 FakeVoiceMediaChannel* GetChannel(size_t index) { 744 return (channels_.size() > index) ? channels_[index] : NULL; 745 } 746 void UnregisterChannel(VoiceMediaChannel* channel) { 747 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 748 } 749 SoundclipMedia* CreateSoundclip() { return new FakeSoundclipMedia(); } 750 751 const std::vector<AudioCodec>& codecs() { return codecs_; } 752 void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; } 753 754 bool SetDelayOffset(int offset) { 755 delay_offset_ = offset; 756 return true; 757 } 758 759 bool SetDevices(const Device* in_device, const Device* out_device) { 760 in_device_ = (in_device) ? in_device->name : ""; 761 out_device_ = (out_device) ? out_device->name : ""; 762 options_changed_ = true; 763 return true; 764 } 765 766 bool GetOutputVolume(int* level) { 767 *level = output_volume_; 768 return true; 769 } 770 771 bool SetOutputVolume(int level) { 772 output_volume_ = level; 773 options_changed_ = true; 774 return true; 775 } 776 777 int GetInputLevel() { return 0; } 778 779 bool SetLocalMonitor(bool enable) { return true; } 780 781 bool RegisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor, 782 MediaProcessorDirection direction) { 783 if (direction == MPD_RX) { 784 rx_processor_ = voice_processor; 785 return true; 786 } else if (direction == MPD_TX) { 787 tx_processor_ = voice_processor; 788 return true; 789 } 790 return false; 791 } 792 793 bool UnregisterProcessor(uint32 ssrc, VoiceProcessor* voice_processor, 794 MediaProcessorDirection direction) { 795 bool unregistered = false; 796 if (direction & MPD_RX) { 797 rx_processor_ = NULL; 798 unregistered = true; 799 } 800 if (direction & MPD_TX) { 801 tx_processor_ = NULL; 802 unregistered = true; 803 } 804 return unregistered; 805 } 806 807 private: 808 std::vector<FakeVoiceMediaChannel*> channels_; 809 std::vector<AudioCodec> codecs_; 810 int output_volume_; 811 int delay_offset_; 812 std::string in_device_; 813 std::string out_device_; 814 VoiceProcessor* rx_processor_; 815 VoiceProcessor* tx_processor_; 816 AudioOptions options_; 817 818 friend class FakeMediaEngine; 819 }; 820 821 class FakeVideoEngine : public FakeBaseEngine { 822 public: 823 FakeVideoEngine() : renderer_(NULL), capture_(false), processor_(NULL) { 824 // Add a fake video codec. Note that the name must not be "" as there are 825 // sanity checks against that. 826 codecs_.push_back(VideoCodec(0, "fake_video_codec", 0, 0, 0, 0)); 827 } 828 bool GetOptions(VideoOptions* options) const { 829 *options = options_; 830 return true; 831 } 832 bool SetOptions(const VideoOptions& options) { 833 options_ = options; 834 options_changed_ = true; 835 return true; 836 } 837 int GetCapabilities() { return VIDEO_SEND | VIDEO_RECV; } 838 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config) { 839 default_encoder_config_ = config; 840 return true; 841 } 842 VideoEncoderConfig GetDefaultEncoderConfig() const { 843 return default_encoder_config_; 844 } 845 const VideoEncoderConfig& default_encoder_config() const { 846 return default_encoder_config_; 847 } 848 849 VideoMediaChannel* CreateChannel(VoiceMediaChannel* channel) { 850 if (fail_create_channel_) { 851 return NULL; 852 } 853 854 FakeVideoMediaChannel* ch = new FakeVideoMediaChannel(this); 855 channels_.push_back(ch); 856 return ch; 857 } 858 FakeVideoMediaChannel* GetChannel(size_t index) { 859 return (channels_.size() > index) ? channels_[index] : NULL; 860 } 861 void UnregisterChannel(VideoMediaChannel* channel) { 862 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 863 } 864 865 const std::vector<VideoCodec>& codecs() const { return codecs_; } 866 bool FindCodec(const VideoCodec& in) { 867 for (size_t i = 0; i < codecs_.size(); ++i) { 868 if (codecs_[i].Matches(in)) { 869 return true; 870 } 871 } 872 return false; 873 } 874 void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; } 875 876 bool SetCaptureDevice(const Device* device) { 877 in_device_ = (device) ? device->name : ""; 878 options_changed_ = true; 879 return true; 880 } 881 bool SetLocalRenderer(VideoRenderer* r) { 882 renderer_ = r; 883 return true; 884 } 885 bool SetCapture(bool capture) { 886 capture_ = capture; 887 return true; 888 } 889 VideoFormat GetStartCaptureFormat() const { 890 return VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30), 891 FOURCC_I420); 892 } 893 894 sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 895 896 private: 897 std::vector<FakeVideoMediaChannel*> channels_; 898 std::vector<VideoCodec> codecs_; 899 VideoEncoderConfig default_encoder_config_; 900 std::string in_device_; 901 VideoRenderer* renderer_; 902 bool capture_; 903 VideoProcessor* processor_; 904 VideoOptions options_; 905 906 friend class FakeMediaEngine; 907 }; 908 909 class FakeMediaEngine : 910 public CompositeMediaEngine<FakeVoiceEngine, FakeVideoEngine> { 911 public: 912 FakeMediaEngine() { 913 voice_ = FakeVoiceEngine(); 914 video_ = FakeVideoEngine(); 915 } 916 virtual ~FakeMediaEngine() {} 917 918 virtual void SetAudioCodecs(const std::vector<AudioCodec> codecs) { 919 voice_.SetCodecs(codecs); 920 } 921 922 virtual void SetVideoCodecs(const std::vector<VideoCodec> codecs) { 923 video_.SetCodecs(codecs); 924 } 925 926 FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { 927 return voice_.GetChannel(index); 928 } 929 930 FakeVideoMediaChannel* GetVideoChannel(size_t index) { 931 return video_.GetChannel(index); 932 } 933 934 AudioOptions audio_options() const { return voice_.options_; } 935 int audio_delay_offset() const { return voice_.delay_offset_; } 936 int output_volume() const { return voice_.output_volume_; } 937 const VideoEncoderConfig& default_video_encoder_config() const { 938 return video_.default_encoder_config_; 939 } 940 const std::string& audio_in_device() const { return voice_.in_device_; } 941 const std::string& audio_out_device() const { return voice_.out_device_; } 942 VideoRenderer* local_renderer() { return video_.renderer_; } 943 int voice_loglevel() const { return voice_.loglevel_; } 944 const std::string& voice_logfilter() const { return voice_.logfilter_; } 945 int video_loglevel() const { return video_.loglevel_; } 946 const std::string& video_logfilter() const { return video_.logfilter_; } 947 bool capture() const { return video_.capture_; } 948 bool options_changed() const { 949 return voice_.options_changed_ || video_.options_changed_; 950 } 951 void clear_options_changed() { 952 video_.options_changed_ = false; 953 voice_.options_changed_ = false; 954 } 955 void set_fail_create_channel(bool fail) { 956 voice_.set_fail_create_channel(fail); 957 video_.set_fail_create_channel(fail); 958 } 959 bool voice_processor_registered(MediaProcessorDirection direction) const { 960 if (direction == MPD_RX) { 961 return voice_.rx_processor_ != NULL; 962 } else if (direction == MPD_TX) { 963 return voice_.tx_processor_ != NULL; 964 } 965 return false; 966 } 967 }; 968 969 // CompositeMediaEngine with FakeVoiceEngine to expose SetAudioCodecs to 970 // establish a media connectionwith minimum set of audio codes required 971 template <class VIDEO> 972 class CompositeMediaEngineWithFakeVoiceEngine : 973 public CompositeMediaEngine<FakeVoiceEngine, VIDEO> { 974 public: 975 CompositeMediaEngineWithFakeVoiceEngine() {} 976 virtual ~CompositeMediaEngineWithFakeVoiceEngine() {} 977 978 virtual void SetAudioCodecs(const std::vector<AudioCodec>& codecs) { 979 CompositeMediaEngine<FakeVoiceEngine, VIDEO>::voice_.SetCodecs(codecs); 980 } 981 }; 982 983 // Have to come afterwards due to declaration order 984 inline FakeVoiceMediaChannel::~FakeVoiceMediaChannel() { 985 if (engine_) { 986 engine_->UnregisterChannel(this); 987 } 988 } 989 990 inline FakeVideoMediaChannel::~FakeVideoMediaChannel() { 991 if (engine_) { 992 engine_->UnregisterChannel(this); 993 } 994 } 995 996 class FakeDataEngine : public DataEngineInterface { 997 public: 998 FakeDataEngine() : last_channel_type_(DCT_NONE) {} 999 1000 virtual DataMediaChannel* CreateChannel(DataChannelType data_channel_type) { 1001 last_channel_type_ = data_channel_type; 1002 FakeDataMediaChannel* ch = new FakeDataMediaChannel(this); 1003 channels_.push_back(ch); 1004 return ch; 1005 } 1006 1007 FakeDataMediaChannel* GetChannel(size_t index) { 1008 return (channels_.size() > index) ? channels_[index] : NULL; 1009 } 1010 1011 void UnregisterChannel(DataMediaChannel* channel) { 1012 channels_.erase(std::find(channels_.begin(), channels_.end(), channel)); 1013 } 1014 1015 virtual void SetDataCodecs(const std::vector<DataCodec>& data_codecs) { 1016 data_codecs_ = data_codecs; 1017 } 1018 1019 virtual const std::vector<DataCodec>& data_codecs() { return data_codecs_; } 1020 1021 DataChannelType last_channel_type() const { return last_channel_type_; } 1022 1023 private: 1024 std::vector<FakeDataMediaChannel*> channels_; 1025 std::vector<DataCodec> data_codecs_; 1026 DataChannelType last_channel_type_; 1027 }; 1028 1029 } // namespace cricket 1030 1031 #endif // TALK_MEDIA_BASE_FAKEMEDIAENGINE_H_ 1032