1/* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <assert.h> 12 13#include "webrtc/common_video/include/incoming_video_stream.h" 14#include "webrtc/engine_configurations.h" 15#include "webrtc/modules/video_render/i_video_render.h" 16#include "webrtc/modules/video_render/video_render_defines.h" 17#include "webrtc/modules/video_render/video_render_impl.h" 18#include "webrtc/system_wrappers/include/critical_section_wrapper.h" 19#include "webrtc/system_wrappers/include/trace.h" 20 21#if defined (_WIN32) 22#include "webrtc/modules/video_render/windows/video_render_windows_impl.h" 23#define STANDARD_RENDERING kRenderWindows 24 25// WEBRTC_IOS should go before WEBRTC_MAC because WEBRTC_MAC 26// gets defined if WEBRTC_IOS is defined 27#elif defined(WEBRTC_IOS) 28#define STANDARD_RENDERING kRenderiOS 29#include "webrtc/modules/video_render/ios/video_render_ios_impl.h" 30#elif defined(WEBRTC_MAC) 31#if defined(COCOA_RENDERING) 32#define STANDARD_RENDERING kRenderCocoa 33#include "webrtc/modules/video_render/mac/video_render_mac_cocoa_impl.h" 34#elif defined(CARBON_RENDERING) 35#define STANDARD_RENDERING kRenderCarbon 36#include "webrtc/modules/video_render/mac/video_render_mac_carbon_impl.h" 37#endif 38 39#elif defined(WEBRTC_ANDROID) 40#include "webrtc/modules/video_render/android/video_render_android_impl.h" 41#include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h" 42#include "webrtc/modules/video_render/android/video_render_android_surface_view.h" 43#define STANDARD_RENDERING kRenderAndroid 44 45#elif defined(WEBRTC_LINUX) 46#include "webrtc/modules/video_render/linux/video_render_linux_impl.h" 47#define STANDARD_RENDERING kRenderX11 48 49#else 50//Other platforms 51#endif 52 53// For external rendering 54#include "webrtc/modules/video_render/external/video_render_external_impl.h" 55#ifndef STANDARD_RENDERING 56#define STANDARD_RENDERING kRenderExternal 57#endif // STANDARD_RENDERING 58 59namespace webrtc { 60 61VideoRender* 62VideoRender::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 76void VideoRender::DestroyVideoRender( 77 VideoRender* module) 78{ 79 if (module) 80 { 81 delete module; 82 } 83} 84 85ModuleVideoRenderImpl::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 207ModuleVideoRenderImpl::~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 297int64_t ModuleVideoRenderImpl::TimeUntilNextProcess() 298{ 299 // Not used 300 return 50; 301} 302int32_t ModuleVideoRenderImpl::Process() 303{ 304 // Not used 305 return 0; 306} 307 308void* 309ModuleVideoRenderImpl::Window() 310{ 311 CriticalSectionScoped cs(&_moduleCrit); 312 return _ptrWindow; 313} 314 315int32_t ModuleVideoRenderImpl::ChangeWindow(void* window) 316{ 317 318 CriticalSectionScoped cs(&_moduleCrit); 319 320#if defined(WEBRTC_IOS) // WEBRTC_IOS must go before WEBRTC_MAC 321 _ptrRenderer = NULL; 322 delete _ptrRenderer; 323 324 VideoRenderIosImpl* ptrRenderer; 325 ptrRenderer = new VideoRenderIosImpl(_id, window, _fullScreen); 326 if (!ptrRenderer) 327 { 328 return -1; 329 } 330 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 331 return _ptrRenderer->ChangeWindow(window); 332#elif defined(WEBRTC_MAC) 333 334 _ptrRenderer = NULL; 335 delete _ptrRenderer; 336 337#if defined(COCOA_RENDERING) 338 VideoRenderMacCocoaImpl* ptrRenderer; 339 ptrRenderer = new VideoRenderMacCocoaImpl(_id, kRenderCocoa, window, _fullScreen); 340#elif defined(CARBON_RENDERING) 341 VideoRenderMacCarbonImpl* ptrRenderer; 342 ptrRenderer = new VideoRenderMacCarbonImpl(_id, kRenderCarbon, window, _fullScreen); 343#endif 344 if (!ptrRenderer) 345 { 346 return -1; 347 } 348 _ptrRenderer = reinterpret_cast<IVideoRender*>(ptrRenderer); 349 return _ptrRenderer->ChangeWindow(window); 350 351#else 352 if (!_ptrRenderer) 353 { 354 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 355 "%s: No renderer", __FUNCTION__); 356 return -1; 357 } 358 return _ptrRenderer->ChangeWindow(window); 359 360#endif 361} 362 363int32_t ModuleVideoRenderImpl::Id() 364{ 365 CriticalSectionScoped cs(&_moduleCrit); 366 return _id; 367} 368 369uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) { 370 CriticalSectionScoped cs(&_moduleCrit); 371 372 IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId); 373 374 if (it == _streamRenderMap.end()) { 375 // This stream doesn't exist 376 WEBRTC_TRACE(kTraceError, 377 kTraceVideoRenderer, 378 _id, 379 "%s: stream doesn't exist", 380 __FUNCTION__); 381 return 0; 382 } 383 assert(it->second != NULL); 384 return it->second->IncomingRate(); 385} 386 387VideoRenderCallback* 388ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId, 389 const uint32_t zOrder, 390 const float left, 391 const float top, 392 const float right, 393 const float bottom) 394{ 395 CriticalSectionScoped cs(&_moduleCrit); 396 397 if (!_ptrRenderer) 398 { 399 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 400 "%s: No renderer", __FUNCTION__); 401 return NULL; 402 } 403 404 if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) { 405 // The stream already exists... 406 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 407 "%s: stream already exists", __FUNCTION__); 408 return NULL; 409 } 410 411 VideoRenderCallback* ptrRenderCallback = 412 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top, 413 right, bottom); 414 if (ptrRenderCallback == NULL) 415 { 416 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 417 "%s: Can't create incoming stream in renderer", 418 __FUNCTION__); 419 return NULL; 420 } 421 422 // Create platform independant code 423 IncomingVideoStream* ptrIncomingStream = 424 new IncomingVideoStream(streamId, false); 425 ptrIncomingStream->SetRenderCallback(ptrRenderCallback); 426 VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback(); 427 428 // Store the stream 429 _streamRenderMap[streamId] = ptrIncomingStream; 430 431 return moduleCallback; 432} 433 434int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream( 435 const uint32_t streamId) 436{ 437 CriticalSectionScoped cs(&_moduleCrit); 438 439 if (!_ptrRenderer) 440 { 441 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 442 "%s: No renderer", __FUNCTION__); 443 return -1; 444 } 445 446 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 447 if (item == _streamRenderMap.end()) 448 { 449 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 450 "%s: stream doesn't exist", __FUNCTION__); 451 return -1; 452 } 453 454 delete item->second; 455 456 _ptrRenderer->DeleteIncomingRenderStream(streamId); 457 458 _streamRenderMap.erase(item); 459 460 return 0; 461} 462 463int32_t ModuleVideoRenderImpl::AddExternalRenderCallback( 464 const uint32_t streamId, 465 VideoRenderCallback* renderObject) { 466 CriticalSectionScoped cs(&_moduleCrit); 467 468 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 469 470 if (item == _streamRenderMap.end()) 471 { 472 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 473 "%s: stream doesn't exist", __FUNCTION__); 474 return -1; 475 } 476 477 if (item->second == NULL) { 478 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 479 "%s: could not get stream", __FUNCTION__); 480 return -1; 481 } 482 item->second->SetExternalCallback(renderObject); 483 return 0; 484} 485 486int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( 487 const uint32_t streamId, 488 uint32_t& zOrder, 489 float& left, 490 float& top, 491 float& right, 492 float& bottom) const { 493 CriticalSectionScoped cs(&_moduleCrit); 494 495 if (!_ptrRenderer) 496 { 497 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 498 "%s: No renderer", __FUNCTION__); 499 return -1; 500 } 501 502 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder, 503 left, top, right, 504 bottom); 505} 506 507uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const 508{ 509 CriticalSectionScoped cs(&_moduleCrit); 510 511 return static_cast<uint32_t>(_streamRenderMap.size()); 512} 513 514bool ModuleVideoRenderImpl::HasIncomingRenderStream( 515 const uint32_t streamId) const { 516 CriticalSectionScoped cs(&_moduleCrit); 517 518 return _streamRenderMap.find(streamId) != _streamRenderMap.end(); 519} 520 521int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback( 522 const uint32_t streamId, 523 VideoRenderCallback* callbackObj) { 524 return -1; 525} 526 527int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId) 528{ 529 CriticalSectionScoped cs(&_moduleCrit); 530 531 if (!_ptrRenderer) 532 { 533 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 534 "%s: No renderer", __FUNCTION__); 535 return -1; 536 } 537 538 // Start the stream 539 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 540 541 if (item == _streamRenderMap.end()) 542 { 543 return -1; 544 } 545 546 if (item->second->Start() == -1) 547 { 548 return -1; 549 } 550 551 // Start the HW renderer 552 if (_ptrRenderer->StartRender() == -1) 553 { 554 return -1; 555 } 556 return 0; 557} 558 559int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId) 560{ 561 CriticalSectionScoped cs(&_moduleCrit); 562 563 if (!_ptrRenderer) 564 { 565 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 566 "%s(%d): No renderer", __FUNCTION__, streamId); 567 return -1; 568 } 569 570 // Stop the incoming stream 571 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); 572 573 if (item == _streamRenderMap.end()) 574 { 575 return -1; 576 } 577 578 if (item->second->Stop() == -1) 579 { 580 return -1; 581 } 582 583 return 0; 584} 585 586int32_t ModuleVideoRenderImpl::ResetRender() 587{ 588 CriticalSectionScoped cs(&_moduleCrit); 589 590 int32_t ret = 0; 591 // Loop through all incoming streams and reset them 592 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); 593 it != _streamRenderMap.end(); 594 ++it) { 595 if (it->second->Reset() == -1) 596 ret = -1; 597 } 598 return ret; 599} 600 601RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const 602{ 603 CriticalSectionScoped cs(&_moduleCrit); 604 605 if (_ptrRenderer == NULL) 606 { 607 return kVideoI420; 608 } 609 610 return _ptrRenderer->PerferedVideoType(); 611} 612 613bool ModuleVideoRenderImpl::IsFullScreen() 614{ 615 CriticalSectionScoped cs(&_moduleCrit); 616 617 if (!_ptrRenderer) 618 { 619 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 620 "%s: No renderer", __FUNCTION__); 621 return false; 622 } 623 return _ptrRenderer->FullScreen(); 624} 625 626int32_t ModuleVideoRenderImpl::GetScreenResolution( 627 uint32_t& screenWidth, 628 uint32_t& screenHeight) const 629{ 630 CriticalSectionScoped cs(&_moduleCrit); 631 632 if (!_ptrRenderer) 633 { 634 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 635 "%s: No renderer", __FUNCTION__); 636 return false; 637 } 638 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight); 639} 640 641uint32_t ModuleVideoRenderImpl::RenderFrameRate( 642 const uint32_t streamId) 643{ 644 CriticalSectionScoped cs(&_moduleCrit); 645 646 if (!_ptrRenderer) 647 { 648 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 649 "%s: No renderer", __FUNCTION__); 650 return false; 651 } 652 return _ptrRenderer->RenderFrameRate(streamId); 653} 654 655int32_t ModuleVideoRenderImpl::SetStreamCropping( 656 const uint32_t streamId, 657 const float left, 658 const float top, 659 const float right, 660 const float bottom) 661{ 662 CriticalSectionScoped cs(&_moduleCrit); 663 664 if (!_ptrRenderer) 665 { 666 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 667 "%s: No renderer", __FUNCTION__); 668 return false; 669 } 670 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom); 671} 672 673int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable) 674{ 675 CriticalSectionScoped cs(&_moduleCrit); 676 677 if (!_ptrRenderer) 678 { 679 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 680 "%s: No renderer", __FUNCTION__); 681 return false; 682 } 683 return _ptrRenderer->SetTransparentBackground(enable); 684} 685 686int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable) 687{ 688 return -1; 689} 690 691int32_t ModuleVideoRenderImpl::SetText( 692 const uint8_t textId, 693 const uint8_t* text, 694 const int32_t textLength, 695 const uint32_t textColorRef, 696 const uint32_t backgroundColorRef, 697 const float left, const float top, 698 const float right, 699 const float bottom) 700{ 701 CriticalSectionScoped cs(&_moduleCrit); 702 703 if (!_ptrRenderer) 704 { 705 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 706 "%s: No renderer", __FUNCTION__); 707 return -1; 708 } 709 return _ptrRenderer->SetText(textId, text, textLength, textColorRef, 710 backgroundColorRef, left, top, right, bottom); 711} 712 713int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap, 714 const uint8_t pictureId, 715 const void* colorKey, 716 const float left, 717 const float top, 718 const float right, 719 const float bottom) 720{ 721 CriticalSectionScoped cs(&_moduleCrit); 722 723 if (!_ptrRenderer) 724 { 725 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 726 "%s: No renderer", __FUNCTION__); 727 return -1; 728 } 729 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, 730 right, bottom); 731} 732 733int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay( 734 uint32_t stream_id, int32_t delay_ms) { 735 CriticalSectionScoped cs(&_moduleCrit); 736 737 if (!_ptrRenderer) { 738 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 739 "%s: No renderer", __FUNCTION__); 740 return false; 741 } 742 743 IncomingVideoStreamMap::const_iterator item = 744 _streamRenderMap.find(stream_id); 745 if (item == _streamRenderMap.end()) { 746 // This stream doesn't exist 747 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 748 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, 749 delay_ms); 750 return -1; 751 } 752 753 assert(item->second != NULL); 754 return item->second->SetExpectedRenderDelay(delay_ms); 755} 756 757int32_t ModuleVideoRenderImpl::ConfigureRenderer( 758 const uint32_t streamId, 759 const unsigned int zOrder, 760 const float left, 761 const float top, 762 const float right, 763 const float bottom) 764{ 765 CriticalSectionScoped cs(&_moduleCrit); 766 767 if (!_ptrRenderer) 768 { 769 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 770 "%s: No renderer", __FUNCTION__); 771 return false; 772 } 773 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, 774 bottom); 775} 776 777int32_t ModuleVideoRenderImpl::SetStartImage(const uint32_t streamId, 778 const VideoFrame& videoFrame) { 779 CriticalSectionScoped cs(&_moduleCrit); 780 781 if (!_ptrRenderer) 782 { 783 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 784 "%s: No renderer", __FUNCTION__); 785 return -1; 786 } 787 788 IncomingVideoStreamMap::const_iterator item = 789 _streamRenderMap.find(streamId); 790 if (item == _streamRenderMap.end()) 791 { 792 // This stream doesn't exist 793 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 794 "%s: stream doesn't exist", __FUNCTION__); 795 return -1; 796 } 797 assert (item->second != NULL); 798 return item->second->SetStartImage(videoFrame); 799 800} 801 802int32_t ModuleVideoRenderImpl::SetTimeoutImage(const uint32_t streamId, 803 const VideoFrame& videoFrame, 804 const uint32_t timeout) { 805 CriticalSectionScoped cs(&_moduleCrit); 806 807 if (!_ptrRenderer) 808 { 809 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 810 "%s: No renderer", __FUNCTION__); 811 return -1; 812 } 813 814 IncomingVideoStreamMap::const_iterator item = 815 _streamRenderMap.find(streamId); 816 if (item == _streamRenderMap.end()) 817 { 818 // This stream doesn't exist 819 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, 820 "%s: stream doesn't exist", __FUNCTION__); 821 return -1; 822 } 823 assert(item->second != NULL); 824 return item->second->SetTimeoutImage(videoFrame, timeout); 825} 826 827} // namespace webrtc 828