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