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 "webrtc/engine_configurations.h"
12#if defined(COCOA_RENDERING)
13
14#ifndef WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_MAC_VIDEO_RENDER_NSOPENGL_H_
15#define WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_MAC_VIDEO_RENDER_NSOPENGL_H_
16
17#import <Cocoa/Cocoa.h>
18#import <OpenGL/OpenGL.h>
19#import <OpenGL/glext.h>
20#import <OpenGL/glu.h>
21#include <QuickTime/QuickTime.h>
22#include <list>
23#include <map>
24
25#include "webrtc/base/thread_annotations.h"
26#include "webrtc/modules/video_render/video_render_defines.h"
27
28#import "webrtc/modules/video_render/mac/cocoa_full_screen_window.h"
29#import "webrtc/modules/video_render/mac/cocoa_render_view.h"
30
31class Trace;
32
33namespace rtc {
34class PlatformThread;
35}  // namespace rtc
36
37namespace webrtc {
38class EventTimerWrapper;
39class VideoRenderNSOpenGL;
40class CriticalSectionWrapper;
41
42class VideoChannelNSOpenGL : public VideoRenderCallback {
43public:
44    VideoChannelNSOpenGL(NSOpenGLContext *nsglContext, int iId, VideoRenderNSOpenGL* owner);
45    virtual ~VideoChannelNSOpenGL();
46
47    // A new frame is delivered
48    virtual int DeliverFrame(const VideoFrame& videoFrame);
49
50    // Called when the incoming frame size and/or number of streams in mix
51    // changes.
52    virtual int FrameSizeChange(int width, int height, int numberOfStreams);
53
54    virtual int UpdateSize(int width, int height);
55
56    // Setup
57    int SetStreamSettings(int streamId, float startWidth, float startHeight, float stopWidth, float stopHeight);
58    int SetStreamCropSettings(int streamId, float startWidth, float startHeight, float stopWidth, float stopHeight);
59
60    // Called when it's time to render the last frame for the channel
61    int RenderOffScreenBuffer();
62
63    // Returns true if a new buffer has been delivered to the texture
64    int IsUpdated(bool& isUpdated);
65    virtual int UpdateStretchSize(int stretchHeight, int stretchWidth);
66
67    // ********** new module functions ************ //
68    virtual int32_t RenderFrame(const uint32_t streamId,
69                                const VideoFrame& videoFrame);
70
71    // ********** new module helper functions ***** //
72    int ChangeContext(NSOpenGLContext *nsglContext);
73    int32_t GetChannelProperties(float& left,
74                                 float& top,
75                                 float& right,
76                                 float& bottom);
77
78private:
79
80    NSOpenGLContext* _nsglContext;
81    const int _id;
82    VideoRenderNSOpenGL* _owner;
83    int32_t _width;
84    int32_t _height;
85    float _startWidth;
86    float _startHeight;
87    float _stopWidth;
88    float _stopHeight;
89    int _stretchedWidth;
90    int _stretchedHeight;
91    int _oldStretchedHeight;
92    int _oldStretchedWidth;
93    unsigned char* _buffer;
94    size_t _bufferSize;
95    size_t _incomingBufferSize;
96    bool _bufferIsUpdated;
97    int _numberOfStreams;
98    GLenum _pixelFormat;
99    GLenum _pixelDataType;
100    unsigned int _texture;
101};
102
103class VideoRenderNSOpenGL
104{
105
106public: // methods
107    VideoRenderNSOpenGL(CocoaRenderView *windowRef, bool fullScreen, int iId);
108    ~VideoRenderNSOpenGL();
109
110    static int GetOpenGLVersion(int& nsglMajor, int& nsglMinor);
111
112    // Allocates textures
113    int Init();
114    VideoChannelNSOpenGL* CreateNSGLChannel(int streamID, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight);
115    VideoChannelNSOpenGL* ConfigureNSGLChannel(int channel, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight);
116    int DeleteNSGLChannel(int channel);
117    int DeleteAllNSGLChannels();
118    int StopThread();
119    bool IsFullScreen();
120    bool HasChannels();
121    bool HasChannel(int channel);
122    int GetChannels(std::list<int>& channelList);
123    void LockAGLCntx() EXCLUSIVE_LOCK_FUNCTION(_nsglContextCritSec);
124    void UnlockAGLCntx() UNLOCK_FUNCTION(_nsglContextCritSec);
125
126    // ********** new module functions ************ //
127    int ChangeWindow(CocoaRenderView* newWindowRef);
128    int32_t StartRender();
129    int32_t StopRender();
130    int32_t DeleteNSGLChannel(const uint32_t streamID);
131    int32_t GetChannelProperties(const uint16_t streamId,
132                                 uint32_t& zOrder,
133                                 float& left,
134                                 float& top,
135                                 float& right,
136                                 float& bottom);
137
138    int32_t SetText(const uint8_t textId,
139                    const uint8_t* text,
140                    const int32_t textLength,
141                    const uint32_t textColorRef,
142                    const uint32_t backgroundColorRef,
143                    const float left,
144                    const float top,
145                    const float right,
146                    const float bottom);
147
148    // ********** new module helper functions ***** //
149    int configureNSOpenGLEngine();
150    int configureNSOpenGLView();
151    int setRenderTargetWindow();
152    int setRenderTargetFullScreen();
153
154protected: // methods
155    static bool ScreenUpdateThreadProc(void* obj);
156    bool ScreenUpdateProcess();
157    int GetWindowRect(Rect& rect);
158
159private: // methods
160
161    int CreateMixingContext();
162    int RenderOffScreenBuffers();
163    int DisplayBuffers();
164
165private: // variables
166
167
168    CocoaRenderView* _windowRef;
169    bool _fullScreen;
170    int _id;
171    CriticalSectionWrapper& _nsglContextCritSec;
172    // TODO(pbos): Remove scoped_ptr and use PlatformThread directly.
173    rtc::scoped_ptr<rtc::PlatformThread> _screenUpdateThread;
174    EventTimerWrapper* _screenUpdateEvent;
175    NSOpenGLContext* _nsglContext;
176    NSOpenGLContext* _nsglFullScreenContext;
177    CocoaFullScreenWindow* _fullScreenWindow;
178    Rect _windowRect; // The size of the window
179    int _windowWidth;
180    int _windowHeight;
181    std::map<int, VideoChannelNSOpenGL*> _nsglChannels;
182    std::multimap<int, int> _zOrderToChannel;
183    bool _renderingIsPaused;
184    NSView* _windowRefSuperView;
185    NSRect _windowRefSuperViewFrame;
186};
187
188}  // namespace webrtc
189
190#endif   // WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_MAC_VIDEO_RENDER_NSOPENGL_H_
191#endif	 // COCOA_RENDERING
192