1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <assert.h> 12 13 #include "webrtc/common_video/include/incoming_video_stream.h" 14 #include "webrtc/engine_configurations.h" 15 #include "webrtc/modules/video_render/i_video_render.h" 16 #include "webrtc/modules/video_render/video_render_defines.h" 17 #include "webrtc/modules/video_render/video_render_impl.h" 18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" 19 #include "webrtc/system_wrappers/include/trace.h" 20 21 #if defined (_WIN32) 22 #include "webrtc/modules/video_render/windows/video_render_windows_impl.h" 23 #define STANDARD_RENDERING kRenderWindows 24 25 // WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC 26 // gets defined if WEBRTC_IOS is defined 27 #elif defined(WEBRTC_IOS) 28 #define STANDARD_RENDERING kRenderiOS 29 #include "webrtc/modules/video_render/ios/video_render_ios_impl.h" 30 #elif defined(WEBRTC_MAC) 31 #if defined(COCOA_RENDERING) 32 #define STANDARD_RENDERING kRenderCocoa 33 #include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h" 34 #elif defined(CARBON_RENDERING) 35 #define STANDARD_RENDERING kRenderCarbon 36 #include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h" 37 #endif 38 39 #elif defined(WEBRTC_ANDROID) 40 #include "webrtc/modules/video_render/android/video_render_android_impl.h" 41 #include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h" 42 #include "webrtc/modules/video_render/android/video_render_android_surface_view.h" 43 #define STANDARD_RENDERING kRenderAndroid 44 45 #elif defined(WEBRTC_LINUX) 46 #include "webrtc/modules/video_render/linux/video_render_linux_impl.h" 47 #define STANDARD_RENDERING kRenderX11 48 49 #else 50 //Other platforms 51 #endif 52 53 // For external rendering 54 #include "webrtc/modules/video_render/external/video_render_external_impl.h" 55 #ifndef STANDARD_RENDERING 56 #define STANDARD_RENDERING kRenderExternal 57 #endif // STANDARD_RENDERING 58 59 namespace webrtc { 60 61 VideoRender* 62 VideoRender::CreateVideoRender(const int32_t id, 63 void* window, 64 const bool fullscreen, 65 const VideoRenderType videoRenderType/*=kRenderDefault*/) 66 { 67 VideoRenderType resultVideoRenderType = videoRenderType; 68 if (videoRenderType == kRenderDefault) 69 { 70 resultVideoRenderType = STANDARD_RENDERING; 71 } 72 return new ModuleVideoRenderImpl(id, resultVideoRenderType, window, 73 fullscreen); 74 } 75 76 void VideoRender::DestroyVideoRender( 77 VideoRender* module) 78 { 79 if (module) 80 { 81 delete module; 82 } 83 } 84 85 ModuleVideoRenderImpl::ModuleVideoRenderImpl( 86 const int32_t id, 87 const VideoRenderType videoRenderType, 88 void* window, 89 const bool fullscreen) : 90 _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()), 91 _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL) 92 { 93 94 // Create platform specific renderer 95 switch (videoRenderType) 96 { 97 #if defined(_WIN32) 98 case kRenderWindows: 99 { 100 VideoRenderWindowsImpl* ptrRenderer; 101 ptrRenderer = new VideoRenderWindowsImpl(_id, videoRenderType, window, _fullScreen); 102 if (ptrRenderer) 103 { 104 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 105 } 106 } 107 break; 108 109 #elif defined(WEBRTC_IOS) 110 case kRenderiOS: 111 { 112 VideoRenderIosImpl* ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen); 113 if(ptrRenderer) 114 { 115 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 116 } 117 } 118 break; 119 120 #elif defined(WEBRTC_MAC) 121 122 #if defined(COCOA_RENDERING) 123 case kRenderCocoa: 124 { 125 VideoRenderMacCocoaImpl* ptrRenderer = new VideoRenderMacCocoaImpl(_id, videoRenderType, window, _fullScreen); 126 if(ptrRenderer) 127 { 128 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 129 } 130 } 131 132 break; 133 #elif defined(CARBON_RENDERING) 134 case kRenderCarbon: 135 { 136 VideoRenderMacCarbonImpl* ptrRenderer = new VideoRenderMacCarbonImpl(_id, videoRenderType, window, _fullScreen); 137 if(ptrRenderer) 138 { 139 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 140 } 141 } 142 break; 143 #endif 144 145 #elif defined(WEBRTC_ANDROID) 146 case kRenderAndroid: 147 { 148 if(AndroidNativeOpenGl2Renderer::UseOpenGL2(window)) 149 { 150 AndroidNativeOpenGl2Renderer* ptrRenderer = NULL; 151 ptrRenderer = new AndroidNativeOpenGl2Renderer(_id, videoRenderType, window, _fullScreen); 152 if (ptrRenderer) 153 { 154 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); 155 } 156 } 157 else 158 { 159 AndroidSurfaceViewRenderer* ptrRenderer = NULL; 160 ptrRenderer = new AndroidSurfaceViewRenderer(_id, videoRenderType, window, _fullScreen); 161 if (ptrRenderer) 162 { 163 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); 164 } 165 } 166 167 } 168 break; 169 #elif defined(WEBRTC_LINUX) 170 case kRenderX11: 171 { 172 VideoRenderLinuxImpl* ptrRenderer = NULL; 173 ptrRenderer = new VideoRenderLinuxImpl(_id, videoRenderType, window, _fullScreen); 174 if ( ptrRenderer ) 175 { 176 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); 177 } 178 } 179 break; 180 181 #else 182 // Other platforms 183 #endif 184 case kRenderExternal: 185 { 186 VideoRenderExternalImpl* ptrRenderer(NULL); 187 ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType, 188 window, _fullScreen); 189 if (ptrRenderer) 190 { 191 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); 192 } 193 } 194 break; 195 default: 196 // Error... 197 break; 198 } 199 if (_ptrRenderer) 200 { 201 if (_ptrRenderer->Init() == -1) 202 { 203 } 204 } 205 } 206 207 ModuleVideoRenderImpl::~ModuleVideoRenderImpl() 208 { 209 delete &_moduleCrit; 210 211 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); 212 it != _streamRenderMap.end(); 213 ++it) { 214 delete it->second; 215 } 216 217 // Delete platform specific renderer 218 if (_ptrRenderer) 219 { 220 VideoRenderType videoRenderType = _ptrRenderer->RenderType(); 221 222 switch (videoRenderType) 223 { 224 case kRenderExternal: 225 { 226 VideoRenderExternalImpl 227 * ptrRenderer = 228 reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer); 229 _ptrRenderer = NULL; 230 delete ptrRenderer; 231 } 232 break; 233 #if defined(_WIN32) 234 case kRenderWindows: 235 { 236 VideoRenderWindowsImpl* ptrRenderer = reinterpret_cast<VideoRenderWindowsImpl*>(_ptrRenderer); 237 _ptrRenderer = NULL; 238 delete ptrRenderer; 239 } 240 break; 241 #elif defined(WEBRTC_IOS) 242 case kRenderiOS: 243 { 244 VideoRenderIosImpl* ptrRenderer = reinterpret_cast<VideoRenderIosImpl*> (_ptrRenderer); 245 _ptrRenderer = NULL; 246 delete ptrRenderer; 247 } 248 break; 249 #elif defined(WEBRTC_MAC) 250 251 #if defined(COCOA_RENDERING) 252 case kRenderCocoa: 253 { 254 VideoRenderMacCocoaImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCocoaImpl*> (_ptrRenderer); 255 _ptrRenderer = NULL; 256 delete ptrRenderer; 257 } 258 break; 259 #elif defined(CARBON_RENDERING) 260 case kRenderCarbon: 261 { 262 VideoRenderMacCarbonImpl* ptrRenderer = reinterpret_cast<VideoRenderMacCarbonImpl*> (_ptrRenderer); 263 _ptrRenderer = NULL; 264 delete ptrRenderer; 265 } 266 break; 267 #endif 268 269 #elif defined(WEBRTC_ANDROID) 270 case kRenderAndroid: 271 { 272 VideoRenderAndroid* ptrRenderer = reinterpret_cast<VideoRenderAndroid*> (_ptrRenderer); 273 _ptrRenderer = NULL; 274 delete ptrRenderer; 275 } 276 break; 277 278 #elif defined(WEBRTC_LINUX) 279 case kRenderX11: 280 { 281 VideoRenderLinuxImpl* ptrRenderer = reinterpret_cast<VideoRenderLinuxImpl*> (_ptrRenderer); 282 _ptrRenderer = NULL; 283 delete ptrRenderer; 284 } 285 break; 286 #else 287 //other platforms 288 #endif 289 290 default: 291 // Error... 292 break; 293 } 294 } 295 } 296 297 int64_t ModuleVideoRenderImpl::TimeUntilNextProcess() 298 { 299 // Not used 300 return 50; 301 } 302 int32_t ModuleVideoRenderImpl::Process() 303 { 304 // Not used 305 return 0; 306 } 307 308 void* 309 ModuleVideoRenderImpl::Window() 310 { 311 CriticalSectionScoped cs(&_moduleCrit); 312 return _ptrWindow; 313 } 314 315 int32_t ModuleVideoRenderImpl::ChangeWindow(void* window) 316 { 317 318 CriticalSectionScoped cs(&_moduleCrit); 319 320 #if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC 321 _ptrRenderer = NULL; 322 delete _ptrRenderer; 323 324 VideoRenderIosImpl* ptrRenderer; 325 ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen); 326 if (!ptrRenderer) 327 { 328 return -1; 329 } 330 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 331 return _ptrRenderer->ChangeWindow(window); 332 #elif defined(WEBRTC_MAC) 333 334 _ptrRenderer = NULL; 335 delete _ptrRenderer; 336 337 #if defined(COCOA_RENDERING) 338 VideoRenderMacCocoaImpl* ptrRenderer; 339 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen); 340 #elif defined(CARBON_RENDERING) 341 VideoRenderMacCarbonImpl* ptrRenderer; 342 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen); 343 #endif 344 if (!ptrRenderer) 345 { 346 return -1; 347 } 348 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 349 return _ptrRenderer->ChangeWindow(window); 350 351 #else 352 if (!_ptrRenderer) 353 { 354 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 355 "%s: No renderer", __FUNCTION__); 356 return -1; 357 } 358 return _ptrRenderer->ChangeWindow(window); 359 360 #endif 361 } 362 363 int32_t ModuleVideoRenderImpl::Id() 364 { 365 CriticalSectionScoped cs(&_moduleCrit); 366 return _id; 367 } 368 369 uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) { 370 CriticalSectionScoped cs(&_moduleCrit); 371 372 IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId); 373 374 if (it == _streamRenderMap.end()) { 375 // This stream doesn't exist 376 WEBRTC_TRACE(kTraceError, 377 kTraceVideoRenderer, 378 _id, 379 "%s: stream doesn't exist", 380 __FUNCTION__); 381 return 0; 382 } 383 assert(it->second != NULL); 384 return it->second->IncomingRate(); 385 } 386 387 VideoRenderCallback* 388 ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId, 389 const uint32_t zOrder, 390 const float left, 391 const float top, 392 const float right, 393 const float bottom) 394 { 395 CriticalSectionScoped cs(&_moduleCrit); 396 397 if (!_ptrRenderer) 398 { 399 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 400 "%s: No renderer", __FUNCTION__); 401 return NULL; 402 } 403 404 if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) { 405 // The stream already exists... 406 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 407 "%s: stream already exists", __FUNCTION__); 408 return NULL; 409 } 410 411 VideoRenderCallback* ptrRenderCallback = 412 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top, 413 right, bottom); 414 if (ptrRenderCallback == NULL) 415 { 416 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 417 "%s: Can't create incoming stream in renderer", 418 __FUNCTION__); 419 return NULL; 420 } 421 422 // Create platform independant code 423 IncomingVideoStream* ptrIncomingStream = 424 new IncomingVideoStream(streamId, false); 425 ptrIncomingStream->SetRenderCallback(ptrRenderCallback); 426 VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback(); 427 428 // Store the stream 429 _streamRenderMap[streamId] = ptrIncomingStream; 430 431 return moduleCallback; 432 } 433 434 int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream( 435 const uint32_t streamId) 436 { 437 CriticalSectionScoped cs(&_moduleCrit); 438 439 if (!_ptrRenderer) 440 { 441 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 442 "%s: No renderer", __FUNCTION__); 443 return -1; 444 } 445 446 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 447 if (item == _streamRenderMap.end()) 448 { 449 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 450 "%s: stream doesn't exist", __FUNCTION__); 451 return -1; 452 } 453 454 delete item->second; 455 456 _ptrRenderer->DeleteIncomingRenderStream(streamId); 457 458 _streamRenderMap.erase(item); 459 460 return 0; 461 } 462 463 int32_t ModuleVideoRenderImpl::AddExternalRenderCallback( 464 const uint32_t streamId, 465 VideoRenderCallback* renderObject) { 466 CriticalSectionScoped cs(&_moduleCrit); 467 468 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 469 470 if (item == _streamRenderMap.end()) 471 { 472 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 473 "%s: stream doesn't exist", __FUNCTION__); 474 return -1; 475 } 476 477 if (item->second == NULL) { 478 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 479 "%s: could not get stream", __FUNCTION__); 480 return -1; 481 } 482 item->second->SetExternalCallback(renderObject); 483 return 0; 484 } 485 486 int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( 487 const uint32_t streamId, 488 uint32_t& zOrder, 489 float& left, 490 float& top, 491 float& right, 492 float& bottom) const { 493 CriticalSectionScoped cs(&_moduleCrit); 494 495 if (!_ptrRenderer) 496 { 497 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 498 "%s: No renderer", __FUNCTION__); 499 return -1; 500 } 501 502 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder, 503 left, top, right, 504 bottom); 505 } 506 507 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const 508 { 509 CriticalSectionScoped cs(&_moduleCrit); 510 511 return static_cast<uint32_t>(_streamRenderMap.size()); 512 } 513 514 bool ModuleVideoRenderImpl::HasIncomingRenderStream( 515 const uint32_t streamId) const { 516 CriticalSectionScoped cs(&_moduleCrit); 517 518 return _streamRenderMap.find(streamId) != _streamRenderMap.end(); 519 } 520 521 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback( 522 const uint32_t streamId, 523 VideoRenderCallback* callbackObj) { 524 return -1; 525 } 526 527 int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId) 528 { 529 CriticalSectionScoped cs(&_moduleCrit); 530 531 if (!_ptrRenderer) 532 { 533 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 534 "%s: No renderer", __FUNCTION__); 535 return -1; 536 } 537 538 // Start the stream 539 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 540 541 if (item == _streamRenderMap.end()) 542 { 543 return -1; 544 } 545 546 if (item->second->Start() == -1) 547 { 548 return -1; 549 } 550 551 // Start the HW renderer 552 if (_ptrRenderer->StartRender() == -1) 553 { 554 return -1; 555 } 556 return 0; 557 } 558 559 int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId) 560 { 561 CriticalSectionScoped cs(&_moduleCrit); 562 563 if (!_ptrRenderer) 564 { 565 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 566 "%s(%d): No renderer", __FUNCTION__, streamId); 567 return -1; 568 } 569 570 // Stop the incoming stream 571 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 572 573 if (item == _streamRenderMap.end()) 574 { 575 return -1; 576 } 577 578 if (item->second->Stop() == -1) 579 { 580 return -1; 581 } 582 583 return 0; 584 } 585 586 int32_t ModuleVideoRenderImpl::ResetRender() 587 { 588 CriticalSectionScoped cs(&_moduleCrit); 589 590 int32_t ret = 0; 591 // Loop through all incoming streams and reset them 592 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); 593 it != _streamRenderMap.end(); 594 ++it) { 595 if (it->second->Reset() == -1) 596 ret = -1; 597 } 598 return ret; 599 } 600 601 RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const 602 { 603 CriticalSectionScoped cs(&_moduleCrit); 604 605 if (_ptrRenderer == NULL) 606 { 607 return kVideoI420; 608 } 609 610 return _ptrRenderer->PerferedVideoType(); 611 } 612 613 bool ModuleVideoRenderImpl::IsFullScreen() 614 { 615 CriticalSectionScoped cs(&_moduleCrit); 616 617 if (!_ptrRenderer) 618 { 619 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 620 "%s: No renderer", __FUNCTION__); 621 return false; 622 } 623 return _ptrRenderer->FullScreen(); 624 } 625 626 int32_t ModuleVideoRenderImpl::GetScreenResolution( 627 uint32_t& screenWidth, 628 uint32_t& screenHeight) const 629 { 630 CriticalSectionScoped cs(&_moduleCrit); 631 632 if (!_ptrRenderer) 633 { 634 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 635 "%s: No renderer", __FUNCTION__); 636 return false; 637 } 638 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight); 639 } 640 641 uint32_t ModuleVideoRenderImpl::RenderFrameRate( 642 const uint32_t streamId) 643 { 644 CriticalSectionScoped cs(&_moduleCrit); 645 646 if (!_ptrRenderer) 647 { 648 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 649 "%s: No renderer", __FUNCTION__); 650 return false; 651 } 652 return _ptrRenderer->RenderFrameRate(streamId); 653 } 654 655 int32_t ModuleVideoRenderImpl::SetStreamCropping( 656 const uint32_t streamId, 657 const float left, 658 const float top, 659 const float right, 660 const float bottom) 661 { 662 CriticalSectionScoped cs(&_moduleCrit); 663 664 if (!_ptrRenderer) 665 { 666 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 667 "%s: No renderer", __FUNCTION__); 668 return false; 669 } 670 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom); 671 } 672 673 int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable) 674 { 675 CriticalSectionScoped cs(&_moduleCrit); 676 677 if (!_ptrRenderer) 678 { 679 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 680 "%s: No renderer", __FUNCTION__); 681 return false; 682 } 683 return _ptrRenderer->SetTransparentBackground(enable); 684 } 685 686 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable) 687 { 688 return -1; 689 } 690 691 int32_t ModuleVideoRenderImpl::SetText( 692 const uint8_t textId, 693 const uint8_t* text, 694 const int32_t textLength, 695 const uint32_t textColorRef, 696 const uint32_t backgroundColorRef, 697 const float left, const float top, 698 const float right, 699 const float bottom) 700 { 701 CriticalSectionScoped cs(&_moduleCrit); 702 703 if (!_ptrRenderer) 704 { 705 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 706 "%s: No renderer", __FUNCTION__); 707 return -1; 708 } 709 return _ptrRenderer->SetText(textId, text, textLength, textColorRef, 710 backgroundColorRef, left, top, right, bottom); 711 } 712 713 int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap, 714 const uint8_t pictureId, 715 const void* colorKey, 716 const float left, 717 const float top, 718 const float right, 719 const float bottom) 720 { 721 CriticalSectionScoped cs(&_moduleCrit); 722 723 if (!_ptrRenderer) 724 { 725 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 726 "%s: No renderer", __FUNCTION__); 727 return -1; 728 } 729 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, 730 right, bottom); 731 } 732 733 int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay( 734 uint32_t stream_id, int32_t delay_ms) { 735 CriticalSectionScoped cs(&_moduleCrit); 736 737 if (!_ptrRenderer) { 738 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 739 "%s: No renderer", __FUNCTION__); 740 return false; 741 } 742 743 IncomingVideoStreamMap::const_iterator item = 744 _streamRenderMap.find(stream_id); 745 if (item == _streamRenderMap.end()) { 746 // This stream doesn't exist 747 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 748 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, 749 delay_ms); 750 return -1; 751 } 752 753 assert(item->second != NULL); 754 return item->second->SetExpectedRenderDelay(delay_ms); 755 } 756 757 int32_t ModuleVideoRenderImpl::ConfigureRenderer( 758 const uint32_t streamId, 759 const unsigned int zOrder, 760 const float left, 761 const float top, 762 const float right, 763 const float bottom) 764 { 765 CriticalSectionScoped cs(&_moduleCrit); 766 767 if (!_ptrRenderer) 768 { 769 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 770 "%s: No renderer", __FUNCTION__); 771 return false; 772 } 773 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, 774 bottom); 775 } 776 777 int32_t ModuleVideoRenderImpl::SetStartImage(const uint32_t streamId, 778 const VideoFrame& videoFrame) { 779 CriticalSectionScoped cs(&_moduleCrit); 780 781 if (!_ptrRenderer) 782 { 783 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 784 "%s: No renderer", __FUNCTION__); 785 return -1; 786 } 787 788 IncomingVideoStreamMap::const_iterator item = 789 _streamRenderMap.find(streamId); 790 if (item == _streamRenderMap.end()) 791 { 792 // This stream doesn't exist 793 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 794 "%s: stream doesn't exist", __FUNCTION__); 795 return -1; 796 } 797 assert (item->second != NULL); 798 return item->second->SetStartImage(videoFrame); 799 800 } 801 802 int32_t ModuleVideoRenderImpl::SetTimeoutImage(const uint32_t streamId, 803 const VideoFrame& videoFrame, 804 const uint32_t timeout) { 805 CriticalSectionScoped cs(&_moduleCrit); 806 807 if (!_ptrRenderer) 808 { 809 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 810 "%s: No renderer", __FUNCTION__); 811 return -1; 812 } 813 814 IncomingVideoStreamMap::const_iterator item = 815 _streamRenderMap.find(streamId); 816 if (item == _streamRenderMap.end()) 817 { 818 // This stream doesn't exist 819 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 820 "%s: stream doesn't exist", __FUNCTION__); 821 return -1; 822 } 823 assert(item->second != NULL); 824 return item->second->SetTimeoutImage(videoFrame, timeout); 825 } 826 827 } // namespace webrtc 828