blob: b0623bad37089b4096f78dc1db736dc86ff434f6 [file] [log] [blame]
Chih-Chung Chang43fcc392011-08-02 16:17:39 +08001/*
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>
Glenn Kastenc1e3ed12012-03-13 15:22:11 -070022#include <media/stagefright/MediaBuffer.h>
23#include <media/stagefright/MetaData.h>
Chih-Chung Chang43fcc392011-08-02 16:17:39 +080024#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//
Andy McFadden8ba01022012-12-18 09:46:54 -080040// We allocate a SurfaceTextureClient for each RenderInput and the user can use
Chih-Chung Chang43fcc392011-08-02 16:17:39 +080041// the getTargetWindow() function to get the corresponding ANativeWindow
Andy McFadden8ba01022012-12-18 09:46:54 -080042// for that SurfaceTextureClient. The intention is that the user can pass that
Chih-Chung Chang43fcc392011-08-02 16:17:39 +080043// ANativeWindow to OMXCodec::Create() so the codec can decode directly
44// to buffers provided by the texture.
45
46namespace android {
47
Andy McFadden8ba01022012-12-18 09:46:54 -080048class GLConsumer;
Chih-Chung Chang43fcc392011-08-02 16:17:39 +080049class SurfaceTextureClient;
50class RenderInput;
51
52class NativeWindowRenderer {
53public:
54 NativeWindowRenderer(sp<ANativeWindow> nativeWindow, int width, int height);
55 ~NativeWindowRenderer();
56
57 RenderInput* createRenderInput();
58 void destroyRenderInput(RenderInput* input);
59
60private:
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);
Chih-Chung Chang2aa01fd2011-08-05 17:52:45 +080079 void copyI420Buffer(MediaBuffer* src, uint8_t* dst,
Chih-Chung Chang43fcc392011-08-02 16:17:39 +080080 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
Andy McFadden8ba01022012-12-18 09:46:54 -0800113 // We use a different GL id for each SurfaceTextureClient.
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800114 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
147class RenderInput {
148public:
Andy McFadden8ba01022012-12-18 09:46:54 -0800149 // Returns the ANativeWindow corresponds to the SurfaceTextureClient.
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800150 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
Andy McFadden8ba01022012-12-18 09:46:54 -0800159 // provided by the SurfaceTextureClient.
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800160 void render(MediaBuffer *buffer, uint32_t videoEffect,
161 M4xVSS_MediaRendering renderingMode, bool isExternalBuffer);
162private:
163 RenderInput(NativeWindowRenderer* renderer, GLuint textureId);
164 ~RenderInput();
165 NativeWindowRenderer* mRenderer;
166 GLuint mTextureId;
Andy McFadden8ba01022012-12-18 09:46:54 -0800167 sp<GLConsumer> mST;
Chih-Chung Chang43fcc392011-08-02 16:17:39 +0800168 sp<SurfaceTextureClient> 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_