blob: 8fbb4f9e57fc252870dde0391d90f94763282309 [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//
40// We allocate a SurfaceTexture for each RenderInput and the user can use
41// the getTargetWindow() function to get the corresponding ANativeWindow
42// for that SurfaceTexture. 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
46namespace android {
47
48class SurfaceTexture;
49class 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
113 // We use a different GL id for each SurfaceTexture.
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
147class RenderInput {
148public:
149 // Returns the ANativeWindow corresponds to the SurfaceTexture.
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 SurfaceTexture.
160 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;
167 sp<SurfaceTexture> mST;
168 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_