video_render_impl.cc revision 9841d92b8d41356a72d5ca2b815906f581616c7d
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 WebRtc_Word32 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 WebRtc_Word32 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 313WebRtc_Word32 ModuleVideoRenderImpl::ChangeUniqueId(const WebRtc_Word32 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 328WebRtc_Word32 ModuleVideoRenderImpl::TimeUntilNextProcess() 329{ 330 // Not used 331 return 50; 332} 333WebRtc_Word32 ModuleVideoRenderImpl::Process() 334{ 335 // Not used 336 return 0; 337} 338 339void* 340ModuleVideoRenderImpl::Window() 341{ 342 CriticalSectionScoped cs(&_moduleCrit); 343 return _ptrWindow; 344} 345 346WebRtc_Word32 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 401WebRtc_Word32 ModuleVideoRenderImpl::Id() 402{ 403 CriticalSectionScoped cs(&_moduleCrit); 404 return _id; 405} 406 407WebRtc_UWord32 ModuleVideoRenderImpl::GetIncomingFrameRate( 408 const WebRtc_UWord32 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 WebRtc_UWord32 streamId, 434 const WebRtc_UWord32 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 497WebRtc_Word32 ModuleVideoRenderImpl::DeleteIncomingRenderStream( 498 const WebRtc_UWord32 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 527WebRtc_Word32 ModuleVideoRenderImpl::AddExternalRenderCallback( 528 const WebRtc_UWord32 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 551WebRtc_Word32 ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( 552 const WebRtc_UWord32 streamId, 553 WebRtc_UWord32& 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 573WebRtc_UWord32 ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const 574{ 575 CriticalSectionScoped cs(&_moduleCrit); 576 577 return (WebRtc_UWord32) _streamRenderMap.Size(); 578} 579 580bool ModuleVideoRenderImpl::HasIncomingRenderStream( 581 const WebRtc_UWord32 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 593WebRtc_Word32 ModuleVideoRenderImpl::RegisterRawFrameCallback( 594 const WebRtc_UWord32 streamId, 595 VideoRenderCallback* callbackObj) 596{ 597 return -1; 598} 599 600WebRtc_Word32 ModuleVideoRenderImpl::StartRender(const WebRtc_UWord32 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 633WebRtc_Word32 ModuleVideoRenderImpl::StopRender(const WebRtc_UWord32 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 661WebRtc_Word32 ModuleVideoRenderImpl::ResetRender() 662{ 663 CriticalSectionScoped cs(&_moduleCrit); 664 665 WebRtc_Word32 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 707WebRtc_Word32 ModuleVideoRenderImpl::GetScreenResolution( 708 WebRtc_UWord32& screenWidth, 709 WebRtc_UWord32& 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 722WebRtc_UWord32 ModuleVideoRenderImpl::RenderFrameRate( 723 const WebRtc_UWord32 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 736WebRtc_Word32 ModuleVideoRenderImpl::SetStreamCropping( 737 const WebRtc_UWord32 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 754WebRtc_Word32 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 767WebRtc_Word32 ModuleVideoRenderImpl::FullScreenRender(void* window, 768 const bool enable) 769{ 770 return -1; 771} 772 773WebRtc_Word32 ModuleVideoRenderImpl::SetText( 774 const WebRtc_UWord8 textId, 775 const WebRtc_UWord8* text, 776 const WebRtc_Word32 textLength, 777 const WebRtc_UWord32 textColorRef, 778 const WebRtc_UWord32 backgroundColorRef, 779 const float left, const float top, 780 const float right, 781 const float bottom) 782{ 783 CriticalSectionScoped cs(&_moduleCrit); 784 785 if (!_ptrRenderer) 786 { 787 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 788 "%s: No renderer", __FUNCTION__); 789 return -1; 790 } 791 return _ptrRenderer->SetText(textId, text, textLength, textColorRef, 792 backgroundColorRef, left, top, right, bottom); 793} 794 795WebRtc_Word32 ModuleVideoRenderImpl::SetBitmap(const void* bitMap, 796 const WebRtc_UWord8 pictureId, 797 const void* colorKey, 798 const float left, 799 const float top, 800 const float right, 801 const float bottom) 802{ 803 CriticalSectionScoped cs(&_moduleCrit); 804 805 if (!_ptrRenderer) 806 { 807 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 808 "%s: No renderer", __FUNCTION__); 809 return -1; 810 } 811 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, 812 right, bottom); 813} 814 815WebRtc_Word32 ModuleVideoRenderImpl::GetLastRenderedFrame( 816 const WebRtc_UWord32 streamId, 817 I420VideoFrame &frame) const 818{ 819 CriticalSectionScoped cs(&_moduleCrit); 820 821 if (!_ptrRenderer) 822 { 823 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 824 "%s: No renderer", __FUNCTION__); 825 return -1; 826 } 827 828 MapItem *item = _streamRenderMap.Find(streamId); 829 if (item == NULL) 830 { 831 // This stream doesn't exist 832 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 833 "%s: stream doesn't exist", __FUNCTION__); 834 return 0; 835 } 836 IncomingVideoStream* incomingStream = 837 static_cast<IncomingVideoStream*> (item->GetItem()); 838 if (incomingStream == NULL) 839 { 840 // This should never happen 841 assert(false); 842 _streamRenderMap.Erase(item); 843 return 0; 844 } 845 return incomingStream->GetLastRenderedFrame(frame); 846} 847 848WebRtc_Word32 ModuleVideoRenderImpl::SetExpectedRenderDelay( 849 WebRtc_UWord32 stream_id, WebRtc_Word32 delay_ms) { 850 CriticalSectionScoped cs(&_moduleCrit); 851 852 if (!_ptrRenderer) { 853 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 854 "%s: No renderer", __FUNCTION__); 855 return false; 856 } 857 858 MapItem *item = _streamRenderMap.Find(stream_id); 859 if (item == NULL) { 860 // This stream doesn't exist 861 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 862 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, 863 delay_ms); 864 return -1; 865 } 866 867 IncomingVideoStream* incoming_stream = 868 static_cast<IncomingVideoStream*> (item->GetItem()); 869 if (incoming_stream == NULL) { 870 // This should never happen 871 assert(false); 872 _streamRenderMap.Erase(item); 873 return 0; 874 } 875 876 return incoming_stream->SetExpectedRenderDelay(delay_ms); 877} 878 879WebRtc_Word32 ModuleVideoRenderImpl::ConfigureRenderer( 880 const WebRtc_UWord32 streamId, 881 const unsigned int zOrder, 882 const float left, 883 const float top, 884 const float right, 885 const float bottom) 886{ 887 CriticalSectionScoped cs(&_moduleCrit); 888 889 if (!_ptrRenderer) 890 { 891 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 892 "%s: No renderer", __FUNCTION__); 893 return false; 894 } 895 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, 896 bottom); 897} 898 899WebRtc_Word32 ModuleVideoRenderImpl::SetStartImage( 900 const WebRtc_UWord32 streamId, 901 const I420VideoFrame& videoFrame) 902{ 903 CriticalSectionScoped cs(&_moduleCrit); 904 905 if (!_ptrRenderer) 906 { 907 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 908 "%s: No renderer", __FUNCTION__); 909 return -1; 910 } 911 912 MapItem *item = _streamRenderMap.Find(streamId); 913 if (item == NULL) 914 { 915 // This stream doesn't exist 916 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 917 "%s: stream doesn't exist", __FUNCTION__); 918 return -1; 919 } 920 IncomingVideoStream* incomingStream = 921 static_cast<IncomingVideoStream*> (item->GetItem()); 922 if (incomingStream == NULL) 923 { 924 // This should never happen 925 assert(false); 926 _streamRenderMap.Erase(item); 927 return 0; 928 } 929 return incomingStream->SetStartImage(videoFrame); 930 931} 932 933WebRtc_Word32 ModuleVideoRenderImpl::SetTimeoutImage( 934 const WebRtc_UWord32 streamId, 935 const I420VideoFrame& videoFrame, 936 const WebRtc_UWord32 timeout) 937{ 938 CriticalSectionScoped cs(&_moduleCrit); 939 940 if (!_ptrRenderer) 941 { 942 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 943 "%s: No renderer", __FUNCTION__); 944 return -1; 945 } 946 947 MapItem *item = _streamRenderMap.Find(streamId); 948 if (item == NULL) 949 { 950 // This stream doesn't exist 951 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 952 "%s: stream doesn't exist", __FUNCTION__); 953 return -1; 954 } 955 IncomingVideoStream* incomingStream = 956 static_cast<IncomingVideoStream*> (item->GetItem()); 957 if (incomingStream == NULL) 958 { 959 // This should never happen 960 assert(false); 961 _streamRenderMap.Erase(item); 962 return 0; 963 } 964 return incomingStream->SetTimeoutImage(videoFrame, timeout); 965} 966 967WebRtc_Word32 ModuleVideoRenderImpl::MirrorRenderStream(const int renderId, 968 const bool enable, 969 const bool mirrorXAxis, 970 const bool mirrorYAxis) 971{ 972 CriticalSectionScoped cs(&_moduleCrit); 973 974 if (!_ptrRenderer) 975 { 976 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 977 "%s: No renderer", __FUNCTION__); 978 return -1; 979 } 980 981 MapItem *item = _streamRenderMap.Find(renderId); 982 if (item == NULL) 983 { 984 // This stream doesn't exist 985 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 986 "%s: stream doesn't exist", __FUNCTION__); 987 return 0; 988 } 989 IncomingVideoStream* incomingStream = 990 static_cast<IncomingVideoStream*> (item->GetItem()); 991 if (incomingStream == NULL) 992 { 993 // This should never happen 994 assert(false); 995 _streamRenderMap.Erase(item); 996 return 0; 997 } 998 999 return incomingStream->EnableMirroring(enable, mirrorXAxis, mirrorYAxis); 1000} 1001 1002} //namespace webrtc 1003