• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef NATIVE_WINDOW_RENDERER_H_
18 #define NATIVE_WINDOW_RENDERER_H_
19 
20 #include <EGL/egl.h>
21 #include <GLES2/gl2.h>
22 #include <media/stagefright/MediaBuffer.h>
23 #include <media/stagefright/MetaData.h>
24 #include <utils/RefBase.h>
25 #include <utils/threads.h>
26 
27 #include "M4xVSS_API.h"
28 
29 // The NativeWindowRenderer draws video frames stored in MediaBuffers to
30 // an ANativeWindow.  It can apply "rendering mode" and color effects to
31 // the frames. "Rendering mode" is the option to do resizing, cropping,
32 // or black-bordering when the source and destination aspect ratio are
33 // different. Color effects include sepia, negative, and gradient.
34 //
35 // The input to NativeWindowRenderer is provided by the RenderInput class,
36 // and there can be multiple active RenderInput at the same time. Although
37 // we only expect that happens briefly when one clip is about to finish
38 // and the next clip is about to start.
39 //
40 // We allocate a Surface for each RenderInput and the user can use
41 // the getTargetWindow() function to get the corresponding ANativeWindow
42 // for that Surface. The intention is that the user can pass that
43 // ANativeWindow to OMXCodec::Create() so the codec can decode directly
44 // to buffers provided by the texture.
45 
46 namespace android {
47 
48 class GLConsumer;
49 class Surface;
50 class RenderInput;
51 
52 class NativeWindowRenderer {
53 public:
54     NativeWindowRenderer(sp<ANativeWindow> nativeWindow, int width, int height);
55     ~NativeWindowRenderer();
56 
57     RenderInput* createRenderInput();
58     void destroyRenderInput(RenderInput* input);
59 
60 private:
61     // No copy constructor and assignment
62     NativeWindowRenderer(const NativeWindowRenderer &);
63     NativeWindowRenderer &operator=(const NativeWindowRenderer &);
64 
65     // Initialization and finialization
66     void initializeEGL();
67     void terminateEGL();
68     void createPrograms();
69     void createProgram(
70             GLuint vertexShader, GLuint fragmentShader, GLuint* outPgm);
71     void loadShader(
72             GLenum shaderType, const char* pSource, GLuint* outShader);
73 
74     // These functions are executed every frame.
75     void render(RenderInput* input);
76     void queueInternalBuffer(ANativeWindow* anw, MediaBuffer* buffer);
77     void queueExternalBuffer(ANativeWindow* anw, MediaBuffer* buffer,
78             int width, int height);
79     void copyI420Buffer(MediaBuffer* src, uint8_t* dst,
80             int srcWidth, int srcHeight, int stride);
81     void updateProgramAndHandle(uint32_t videoEffect);
82     void calculatePositionCoordinates(M4xVSS_MediaRendering renderingMode,
83             int srcWidth, int srcHeight);
84 
85     // These variables are initialized once and doesn't change afterwards.
86     sp<ANativeWindow> mNativeWindow;
87     int mDstWidth, mDstHeight;
88     EGLDisplay mEglDisplay;
89     EGLSurface mEglSurface;
90     EGLContext mEglContext;
91     enum {
92         EFFECT_NORMAL,
93         EFFECT_SEPIA,
94         EFFECT_NEGATIVE,
95         EFFECT_GRADIENT,
96         NUMBER_OF_EFFECTS
97     };
98     GLuint mProgram[NUMBER_OF_EFFECTS];
99 
100     // We use one shader program for each effect. mLastVideoEffect remembers
101     // the program used for the last frame. when the effect used changes,
102     // we change the program used and update the handles.
103     uint32_t mLastVideoEffect;
104     GLint mPositionHandle;
105     GLint mTexPosHandle;
106     GLint mTexMatrixHandle;
107 
108     // This is the vertex coordinates used for the frame texture.
109     // It's calculated according the the rendering mode and the source and
110     // destination aspect ratio.
111     GLfloat mPositionCoordinates[8];
112 
113     // We use a different GL id for each Surface.
114     GLuint mNextTextureId;
115 
116     // Number of existing RenderInputs, just for debugging.
117     int mActiveInputs;
118 
119     // The GL thread functions
120     static int threadStart(void* self);
121     void glThread();
122 
123     // These variables are used to communicate between the GL thread and
124     // other threads.
125     Mutex mLock;
126     Condition mCond;
127     enum {
128         CMD_IDLE,
129         CMD_RENDER_INPUT,
130         CMD_RESERVE_TEXTURE,
131         CMD_DELETE_TEXTURE,
132         CMD_QUIT,
133     };
134     int mThreadCmd;
135     RenderInput* mThreadRenderInput;
136     GLuint mThreadTextureId;
137 
138     // These functions are used to send commands to the GL thread.
139     // sendRequest() also waits for the GL thread acknowledges the
140     // command is finished.
141     void startRequest(int cmd);
142     void sendRequest();
143 
144     friend class RenderInput;
145 };
146 
147 class RenderInput {
148 public:
149     // Returns the ANativeWindow corresponds to the Surface.
150     ANativeWindow* getTargetWindow();
151 
152     // Updates video frame size from the MediaSource's metadata. Specifically
153     // we look for kKeyWidth, kKeyHeight, and (optionally) kKeyCropRect.
154     void updateVideoSize(sp<MetaData> meta);
155 
156     // Renders the buffer with the given video effect and rending mode.
157     // The video effets are defined in VideoEditorTools.h
158     // Set isExternalBuffer to true only when the buffer given is not
159     // provided by the Surface.
160     void render(MediaBuffer *buffer, uint32_t videoEffect,
161         M4xVSS_MediaRendering renderingMode, bool isExternalBuffer);
162 private:
163     RenderInput(NativeWindowRenderer* renderer, GLuint textureId);
164     ~RenderInput();
165     NativeWindowRenderer* mRenderer;
166     GLuint mTextureId;
167     sp<GLConsumer> mST;
168     sp<Surface> mSTC;
169     int mWidth, mHeight;
170 
171     // These are only valid during render() calls
172     uint32_t mVideoEffect;
173     M4xVSS_MediaRendering mRenderingMode;
174     bool mIsExternalBuffer;
175     MediaBuffer* mBuffer;
176 
177     friend class NativeWindowRenderer;
178 };
179 
180 }  // namespace android
181 
182 #endif  // NATIVE_WINDOW_RENDERER_H_
183