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/include/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 
31 class Trace;
32 
33 namespace webrtc {
34 class EventWrapper;
35 class ThreadWrapper;
36 class VideoRenderNSOpenGL;
37 class CriticalSectionWrapper;
38 
39 class VideoChannelNSOpenGL : public VideoRenderCallback
40 {
41 
42 public:
43 
44     VideoChannelNSOpenGL(NSOpenGLContext *nsglContext, int iId, VideoRenderNSOpenGL* owner);
45     virtual ~VideoChannelNSOpenGL();
46 
47     // A new frame is delivered
48     virtual int DeliverFrame(const I420VideoFrame& 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 I420VideoFrame& 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 
78 private:
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 
103 class VideoRenderNSOpenGL
104 {
105 
106 public: // 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 
154 protected: // methods
155     static bool ScreenUpdateThreadProc(void* obj);
156     bool ScreenUpdateProcess();
157     int GetWindowRect(Rect& rect);
158 
159 private: // methods
160 
161     int CreateMixingContext();
162     int RenderOffScreenBuffers();
163     int DisplayBuffers();
164 
165 private: // variables
166 
167 
168     CocoaRenderView* _windowRef;
169     bool _fullScreen;
170     int _id;
171     CriticalSectionWrapper& _nsglContextCritSec;
172     rtc::scoped_ptr<ThreadWrapper> _screenUpdateThread;
173     EventWrapper* _screenUpdateEvent;
174     NSOpenGLContext* _nsglContext;
175     NSOpenGLContext* _nsglFullScreenContext;
176     CocoaFullScreenWindow* _fullScreenWindow;
177     Rect _windowRect; // The size of the window
178     int _windowWidth;
179     int _windowHeight;
180     std::map<int, VideoChannelNSOpenGL*> _nsglChannels;
181     std::multimap<int, int> _zOrderToChannel;
182     bool _renderingIsPaused;
183     NSView* _windowRefSuperView;
184     NSRect _windowRefSuperViewFrame;
185 };
186 
187 }  // namespace webrtc
188 
189 #endif   // WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_MAC_VIDEO_RENDER_NSOPENGL_H_
190 #endif	 // COCOA_RENDERING
191