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