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