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/engine_configurations.h" 14 #include "webrtc/modules/video_render/i_video_render.h" 15 #include "webrtc/modules/video_render/include/video_render_defines.h" 16 #include "webrtc/modules/video_render/incoming_video_stream.h" 17 #include "webrtc/modules/video_render/video_render_impl.h" 18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 19 #include "webrtc/system_wrappers/interface/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 int32_t ModuleVideoRenderImpl::ChangeUniqueId(const int32_t id) 298 { 299 300 CriticalSectionScoped cs(&_moduleCrit); 301 302 _id = id; 303 304 if (_ptrRenderer) 305 { 306 _ptrRenderer->ChangeUniqueId(_id); 307 } 308 309 return 0; 310 } 311 312 int32_t ModuleVideoRenderImpl::TimeUntilNextProcess() 313 { 314 // Not used 315 return 50; 316 } 317 int32_t ModuleVideoRenderImpl::Process() 318 { 319 // Not used 320 return 0; 321 } 322 323 void* 324 ModuleVideoRenderImpl::Window() 325 { 326 CriticalSectionScoped cs(&_moduleCrit); 327 return _ptrWindow; 328 } 329 330 int32_t ModuleVideoRenderImpl::ChangeWindow(void* window) 331 { 332 333 CriticalSectionScoped cs(&_moduleCrit); 334 335 #if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC 336 _ptrRenderer = NULL; 337 delete _ptrRenderer; 338 339 VideoRenderIosImpl* ptrRenderer; 340 ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen); 341 if (!ptrRenderer) 342 { 343 return -1; 344 } 345 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 346 return _ptrRenderer->ChangeWindow(window); 347 #elif defined(WEBRTC_MAC) 348 349 _ptrRenderer = NULL; 350 delete _ptrRenderer; 351 352 #if defined(COCOA_RENDERING) 353 VideoRenderMacCocoaImpl* ptrRenderer; 354 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen); 355 #elif defined(CARBON_RENDERING) 356 VideoRenderMacCarbonImpl* ptrRenderer; 357 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen); 358 #endif 359 if (!ptrRenderer) 360 { 361 return -1; 362 } 363 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 364 return _ptrRenderer->ChangeWindow(window); 365 366 #else 367 if (!_ptrRenderer) 368 { 369 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 370 "%s: No renderer", __FUNCTION__); 371 return -1; 372 } 373 return _ptrRenderer->ChangeWindow(window); 374 375 #endif 376 } 377 378 int32_t ModuleVideoRenderImpl::Id() 379 { 380 CriticalSectionScoped cs(&_moduleCrit); 381 return _id; 382 } 383 384 uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) { 385 CriticalSectionScoped cs(&_moduleCrit); 386 387 IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId); 388 389 if (it == _streamRenderMap.end()) { 390 // This stream doesn't exist 391 WEBRTC_TRACE(kTraceError, 392 kTraceVideoRenderer, 393 _id, 394 "%s: stream doesn't exist", 395 __FUNCTION__); 396 return 0; 397 } 398 assert(it->second != NULL); 399 return it->second->IncomingRate(); 400 } 401 402 VideoRenderCallback* 403 ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId, 404 const uint32_t zOrder, 405 const float left, 406 const float top, 407 const float right, 408 const float bottom) 409 { 410 CriticalSectionScoped cs(&_moduleCrit); 411 412 if (!_ptrRenderer) 413 { 414 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 415 "%s: No renderer", __FUNCTION__); 416 return NULL; 417 } 418 419 if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) { 420 // The stream already exists... 421 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 422 "%s: stream already exists", __FUNCTION__); 423 return NULL; 424 } 425 426 VideoRenderCallback* ptrRenderCallback = 427 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top, 428 right, bottom); 429 if (ptrRenderCallback == NULL) 430 { 431 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 432 "%s: Can't create incoming stream in renderer", 433 __FUNCTION__); 434 return NULL; 435 } 436 437 // Create platform independant code 438 IncomingVideoStream* ptrIncomingStream = new IncomingVideoStream(_id, 439 streamId); 440 if (ptrIncomingStream == NULL) 441 { 442 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 443 "%s: Can't create incoming stream", __FUNCTION__); 444 return NULL; 445 } 446 447 448 if (ptrIncomingStream->SetRenderCallback(ptrRenderCallback) == -1) 449 { 450 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 451 "%s: Can't set render callback", __FUNCTION__); 452 delete ptrIncomingStream; 453 _ptrRenderer->DeleteIncomingRenderStream(streamId); 454 return NULL; 455 } 456 457 VideoRenderCallback* moduleCallback = 458 ptrIncomingStream->ModuleCallback(); 459 460 // Store the stream 461 _streamRenderMap[streamId] = ptrIncomingStream; 462 463 return moduleCallback; 464 } 465 466 int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream( 467 const uint32_t streamId) 468 { 469 CriticalSectionScoped cs(&_moduleCrit); 470 471 if (!_ptrRenderer) 472 { 473 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 474 "%s: No renderer", __FUNCTION__); 475 return -1; 476 } 477 478 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 479 if (item == _streamRenderMap.end()) 480 { 481 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 482 "%s: stream doesn't exist", __FUNCTION__); 483 return -1; 484 } 485 486 delete item->second; 487 488 _ptrRenderer->DeleteIncomingRenderStream(streamId); 489 490 _streamRenderMap.erase(item); 491 492 return 0; 493 } 494 495 int32_t ModuleVideoRenderImpl::AddExternalRenderCallback( 496 const uint32_t streamId, 497 VideoRenderCallback* renderObject) { 498 CriticalSectionScoped cs(&_moduleCrit); 499 500 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 501 502 if (item == _streamRenderMap.end()) 503 { 504 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 505 "%s: stream doesn't exist", __FUNCTION__); 506 return -1; 507 } 508 509 if (item->second == NULL) { 510 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 511 "%s: could not get stream", __FUNCTION__); 512 return -1; 513 } 514 return item->second->SetExternalCallback(renderObject); 515 } 516 517 int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( 518 const uint32_t streamId, 519 uint32_t& zOrder, 520 float& left, 521 float& top, 522 float& right, 523 float& bottom) const { 524 CriticalSectionScoped cs(&_moduleCrit); 525 526 if (!_ptrRenderer) 527 { 528 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 529 "%s: No renderer", __FUNCTION__); 530 return -1; 531 } 532 533 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder, 534 left, top, right, 535 bottom); 536 } 537 538 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const 539 { 540 CriticalSectionScoped cs(&_moduleCrit); 541 542 return static_cast<uint32_t>(_streamRenderMap.size()); 543 } 544 545 bool ModuleVideoRenderImpl::HasIncomingRenderStream( 546 const uint32_t streamId) const { 547 CriticalSectionScoped cs(&_moduleCrit); 548 549 return _streamRenderMap.find(streamId) != _streamRenderMap.end(); 550 } 551 552 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback( 553 const uint32_t streamId, 554 VideoRenderCallback* callbackObj) { 555 return -1; 556 } 557 558 int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId) 559 { 560 CriticalSectionScoped cs(&_moduleCrit); 561 562 if (!_ptrRenderer) 563 { 564 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 565 "%s: No renderer", __FUNCTION__); 566 return -1; 567 } 568 569 // Start the stream 570 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 571 572 if (item == _streamRenderMap.end()) 573 { 574 return -1; 575 } 576 577 if (item->second->Start() == -1) 578 { 579 return -1; 580 } 581 582 // Start the HW renderer 583 if (_ptrRenderer->StartRender() == -1) 584 { 585 return -1; 586 } 587 return 0; 588 } 589 590 int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId) 591 { 592 CriticalSectionScoped cs(&_moduleCrit); 593 594 if (!_ptrRenderer) 595 { 596 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 597 "%s(%d): No renderer", __FUNCTION__, streamId); 598 return -1; 599 } 600 601 // Stop the incoming stream 602 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 603 604 if (item == _streamRenderMap.end()) 605 { 606 return -1; 607 } 608 609 if (item->second->Stop() == -1) 610 { 611 return -1; 612 } 613 614 return 0; 615 } 616 617 int32_t ModuleVideoRenderImpl::ResetRender() 618 { 619 CriticalSectionScoped cs(&_moduleCrit); 620 621 int32_t ret = 0; 622 // Loop through all incoming streams and reset them 623 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); 624 it != _streamRenderMap.end(); 625 ++it) { 626 if (it->second->Reset() == -1) 627 ret = -1; 628 } 629 return ret; 630 } 631 632 RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const 633 { 634 CriticalSectionScoped cs(&_moduleCrit); 635 636 if (_ptrRenderer == NULL) 637 { 638 return kVideoI420; 639 } 640 641 return _ptrRenderer->PerferedVideoType(); 642 } 643 644 bool ModuleVideoRenderImpl::IsFullScreen() 645 { 646 CriticalSectionScoped cs(&_moduleCrit); 647 648 if (!_ptrRenderer) 649 { 650 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 651 "%s: No renderer", __FUNCTION__); 652 return false; 653 } 654 return _ptrRenderer->FullScreen(); 655 } 656 657 int32_t ModuleVideoRenderImpl::GetScreenResolution( 658 uint32_t& screenWidth, 659 uint32_t& screenHeight) const 660 { 661 CriticalSectionScoped cs(&_moduleCrit); 662 663 if (!_ptrRenderer) 664 { 665 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 666 "%s: No renderer", __FUNCTION__); 667 return false; 668 } 669 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight); 670 } 671 672 uint32_t ModuleVideoRenderImpl::RenderFrameRate( 673 const uint32_t streamId) 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->RenderFrameRate(streamId); 684 } 685 686 int32_t ModuleVideoRenderImpl::SetStreamCropping( 687 const uint32_t streamId, 688 const float left, 689 const float top, 690 const float right, 691 const float bottom) 692 { 693 CriticalSectionScoped cs(&_moduleCrit); 694 695 if (!_ptrRenderer) 696 { 697 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 698 "%s: No renderer", __FUNCTION__); 699 return false; 700 } 701 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom); 702 } 703 704 int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable) 705 { 706 CriticalSectionScoped cs(&_moduleCrit); 707 708 if (!_ptrRenderer) 709 { 710 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 711 "%s: No renderer", __FUNCTION__); 712 return false; 713 } 714 return _ptrRenderer->SetTransparentBackground(enable); 715 } 716 717 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable) 718 { 719 return -1; 720 } 721 722 int32_t ModuleVideoRenderImpl::SetText( 723 const uint8_t textId, 724 const uint8_t* text, 725 const int32_t textLength, 726 const uint32_t textColorRef, 727 const uint32_t backgroundColorRef, 728 const float left, const float top, 729 const float right, 730 const float bottom) 731 { 732 CriticalSectionScoped cs(&_moduleCrit); 733 734 if (!_ptrRenderer) 735 { 736 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 737 "%s: No renderer", __FUNCTION__); 738 return -1; 739 } 740 return _ptrRenderer->SetText(textId, text, textLength, textColorRef, 741 backgroundColorRef, left, top, right, bottom); 742 } 743 744 int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap, 745 const uint8_t pictureId, 746 const void* colorKey, 747 const float left, 748 const float top, 749 const float right, 750 const float bottom) 751 { 752 CriticalSectionScoped cs(&_moduleCrit); 753 754 if (!_ptrRenderer) 755 { 756 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 757 "%s: No renderer", __FUNCTION__); 758 return -1; 759 } 760 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, 761 right, bottom); 762 } 763 764 int32_t ModuleVideoRenderImpl::GetLastRenderedFrame( 765 const uint32_t streamId, 766 I420VideoFrame &frame) const 767 { 768 CriticalSectionScoped cs(&_moduleCrit); 769 770 if (!_ptrRenderer) 771 { 772 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 773 "%s: No renderer", __FUNCTION__); 774 return -1; 775 } 776 777 IncomingVideoStreamMap::const_iterator item = 778 _streamRenderMap.find(streamId); 779 if (item == _streamRenderMap.end()) 780 { 781 // This stream doesn't exist 782 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 783 "%s: stream doesn't exist", __FUNCTION__); 784 return 0; 785 } 786 787 assert(item->second != NULL); 788 return item->second->GetLastRenderedFrame(frame); 789 } 790 791 int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay( 792 uint32_t stream_id, int32_t delay_ms) { 793 CriticalSectionScoped cs(&_moduleCrit); 794 795 if (!_ptrRenderer) { 796 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 797 "%s: No renderer", __FUNCTION__); 798 return false; 799 } 800 801 IncomingVideoStreamMap::const_iterator item = 802 _streamRenderMap.find(stream_id); 803 if (item == _streamRenderMap.end()) { 804 // This stream doesn't exist 805 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 806 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, 807 delay_ms); 808 return -1; 809 } 810 811 assert(item->second != NULL); 812 return item->second->SetExpectedRenderDelay(delay_ms); 813 } 814 815 int32_t ModuleVideoRenderImpl::ConfigureRenderer( 816 const uint32_t streamId, 817 const unsigned int zOrder, 818 const float left, 819 const float top, 820 const float right, 821 const float bottom) 822 { 823 CriticalSectionScoped cs(&_moduleCrit); 824 825 if (!_ptrRenderer) 826 { 827 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 828 "%s: No renderer", __FUNCTION__); 829 return false; 830 } 831 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, 832 bottom); 833 } 834 835 int32_t ModuleVideoRenderImpl::SetStartImage( 836 const uint32_t streamId, 837 const I420VideoFrame& videoFrame) 838 { 839 CriticalSectionScoped cs(&_moduleCrit); 840 841 if (!_ptrRenderer) 842 { 843 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 844 "%s: No renderer", __FUNCTION__); 845 return -1; 846 } 847 848 IncomingVideoStreamMap::const_iterator item = 849 _streamRenderMap.find(streamId); 850 if (item == _streamRenderMap.end()) 851 { 852 // This stream doesn't exist 853 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 854 "%s: stream doesn't exist", __FUNCTION__); 855 return -1; 856 } 857 assert (item->second != NULL); 858 return item->second->SetStartImage(videoFrame); 859 860 } 861 862 int32_t ModuleVideoRenderImpl::SetTimeoutImage( 863 const uint32_t streamId, 864 const I420VideoFrame& videoFrame, 865 const uint32_t timeout) 866 { 867 CriticalSectionScoped cs(&_moduleCrit); 868 869 if (!_ptrRenderer) 870 { 871 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 872 "%s: No renderer", __FUNCTION__); 873 return -1; 874 } 875 876 IncomingVideoStreamMap::const_iterator item = 877 _streamRenderMap.find(streamId); 878 if (item == _streamRenderMap.end()) 879 { 880 // This stream doesn't exist 881 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 882 "%s: stream doesn't exist", __FUNCTION__); 883 return -1; 884 } 885 assert(item->second != NULL); 886 return item->second->SetTimeoutImage(videoFrame, timeout); 887 } 888 889 int32_t ModuleVideoRenderImpl::MirrorRenderStream(const int renderId, 890 const bool enable, 891 const bool mirrorXAxis, 892 const bool mirrorYAxis) 893 { 894 CriticalSectionScoped cs(&_moduleCrit); 895 896 if (!_ptrRenderer) 897 { 898 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 899 "%s: No renderer", __FUNCTION__); 900 return -1; 901 } 902 903 IncomingVideoStreamMap::const_iterator item = 904 _streamRenderMap.find(renderId); 905 if (item == _streamRenderMap.end()) 906 { 907 // This stream doesn't exist 908 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 909 "%s: stream doesn't exist", __FUNCTION__); 910 return 0; 911 } 912 assert(item->second != NULL); 913 914 return item->second->EnableMirroring(enable, mirrorXAxis, mirrorYAxis); 915 } 916 917 } // namespace webrtc 918