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