• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef CAMERA_TEST_SURFACE_TEXTURE_H
2 #define CAMERA_TEST_SURFACE_TEXTURE_H
3 
4 #include "camera_test.h"
5 
6 #ifdef ANDROID_API_JB_OR_LATER
7 #include <gui/Surface.h>
8 #include <gui/GLConsumer.h>
9 #include <gui/SurfaceComposerClient.h>
10 #else
11 #include <surfaceflinger/Surface.h>
12 #include <surfaceflinger/ISurface.h>
13 #include <surfaceflinger/ISurfaceComposer.h>
14 #include <surfaceflinger/ISurfaceComposerClient.h>
15 #include <surfaceflinger/SurfaceComposerClient.h>
16 #endif
17 
18 #ifdef ANDROID_API_JB_OR_LATER
19 #   define CAMHAL_LOGV            ALOGV
20 #   define CAMHAL_LOGE            ALOGE
21 #   define PRINTOVER(arg...)      ALOGD(#arg)
22 #   define LOG_FUNCTION_NAME      ALOGD("%d: %s() ENTER", __LINE__, __FUNCTION__);
23 #   define LOG_FUNCTION_NAME_EXIT ALOGD("%d: %s() EXIT", __LINE__, __FUNCTION__);
24 #else
25 #   define CAMHAL_LOGV            LOGV
26 #   define CAMHAL_LOGE            LOGE
27 #   define PRINTOVER(arg...)      LOGD(#arg)
28 #   define LOG_FUNCTION_NAME      LOGD("%d: %s() ENTER", __LINE__, __FUNCTION__);
29 #   define LOG_FUNCTION_NAME_EXIT LOGD("%d: %s() EXIT", __LINE__, __FUNCTION__);
30 #endif
31 
32 using namespace android;
33 
34 class FrameWaiter : public android::GLConsumer::FrameAvailableListener {
35 public:
FrameWaiter()36     FrameWaiter():
37             mPendingFrames(0) {
38     }
39 
~FrameWaiter()40     virtual ~FrameWaiter() {
41         onFrameAvailable();
42     }
43 
waitForFrame()44     void waitForFrame() {
45         Mutex::Autolock lock(mMutex);
46         while (mPendingFrames == 0) {
47             mCondition.wait(mMutex);
48         }
49         mPendingFrames--;
50     }
51 
onFrameAvailable()52     virtual void onFrameAvailable() {
53         Mutex::Autolock lock(mMutex);
54         mPendingFrames++;
55         mCondition.signal();
56     }
57 
58     int mPendingFrames;
59     Mutex mMutex;
60     Condition mCondition;
61 };
62 
63 class GLSurface {
64 public:
65 
GLSurface()66     GLSurface():
67             mEglDisplay(EGL_NO_DISPLAY),
68             mEglSurface(EGL_NO_SURFACE),
69             mEglContext(EGL_NO_CONTEXT) {
70     }
71 
~GLSurface()72     virtual ~GLSurface() {}
73 
74     void initialize(int display);
75     void deinit();
76     void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader);
77     void createProgram(const char* pVertexSource, const char* pFragmentSource,
78             GLuint* outPgm);
79 
80 private:
81     EGLint const* getConfigAttribs();
82     EGLint const* getContextAttribs();
83 
84 protected:
85     sp<SurfaceComposerClient> mComposerClient;
86     sp<SurfaceControl> mSurfaceControl;
87 
88     EGLDisplay mEglDisplay;
89     EGLSurface mEglSurface;
90     EGLContext mEglContext;
91     EGLConfig  mGlConfig;
92 };
93 
94 class SurfaceTextureBase  {
95 public:
~SurfaceTextureBase()96     virtual ~SurfaceTextureBase() {}
97 
98     void initialize(int tex_id, EGLenum tex_target = EGL_NONE);
99     void deinit();
100     void getId(const char **name);
101 
102     virtual sp<GLConsumer> getST();
103 
104 protected:
105     sp<GLConsumer> mST;
106     sp<Surface> mSTC;
107     sp<ANativeWindow> mANW;
108     int mTexId;
109 };
110 
111 class SurfaceTextureGL : public GLSurface, public SurfaceTextureBase {
112 public:
~SurfaceTextureGL()113     virtual ~SurfaceTextureGL() {}
114 
115     void initialize(int display, int tex_id);
116     void deinit();
117 
118     // drawTexture draws the GLConsumer over the entire GL viewport.
119     void drawTexture();
120 
121 private:
122     GLuint mPgm;
123     GLint mPositionHandle;
124     GLint mTexSamplerHandle;
125     GLint mTexMatrixHandle;
126 };
127 
128 class ST_BufferSourceThread : public BufferSourceThread {
129 public:
ST_BufferSourceThread(int tex_id,sp<Camera> camera)130     ST_BufferSourceThread(int tex_id, sp<Camera> camera) : BufferSourceThread(camera) {
131         mSurfaceTextureBase = new SurfaceTextureBase();
132         mSurfaceTextureBase->initialize(tex_id);
133         mSurfaceTexture = mSurfaceTextureBase->getST();
134         mSurfaceTexture->setSynchronousMode(true);
135         mFW = new FrameWaiter();
136         mSurfaceTexture->setFrameAvailableListener(mFW);
137 #ifndef ANDROID_API_JB_OR_LATER
138         mCamera->setBufferSource(NULL, mSurfaceTexture);
139 #endif
140     }
~ST_BufferSourceThread()141     virtual ~ST_BufferSourceThread() {
142 #ifndef ANDROID_API_JB_OR_LATER
143         mCamera->releaseBufferSource(NULL, mSurfaceTexture);
144 #endif
145         mSurfaceTextureBase->deinit();
146         delete mSurfaceTextureBase;
147     }
148 
threadLoop()149     virtual bool threadLoop() {
150         sp<GraphicBuffer> graphic_buffer;
151 
152         mFW->waitForFrame();
153         if (!mDestroying) {
154             float mtx[16] = {0.0};
155             mSurfaceTexture->updateTexImage();
156             printf("=== Metadata for buffer %d ===\n", mCounter);
157 #ifndef ANDROID_API_JB_OR_LATER
158             showMetadata(mSurfaceTexture->getMetadata());
159 #endif
160             printf("\n");
161             graphic_buffer = mSurfaceTexture->getCurrentBuffer();
162             mSurfaceTexture->getTransformMatrix(mtx);
163             Rect crop = getCrop(graphic_buffer, mtx);
164 
165             mDeferThread->add(graphic_buffer, crop, mCounter++);
166             restartCapture();
167             return true;
168         }
169         return false;
170     }
171 
requestExit()172     virtual void requestExit() {
173         Thread::requestExit();
174 
175         mDestroying = true;
176         mFW->onFrameAvailable();
177     }
178 
setBuffer(android::ShotParameters & params)179     virtual void setBuffer(android::ShotParameters &params) {
180         {
181             const char* id = NULL;
182 
183             mSurfaceTextureBase->getId(&id);
184 
185             if (id) {
186                 params.set(KEY_TAP_OUT_SURFACES, id);
187             } else {
188                 params.remove(KEY_TAP_OUT_SURFACES);
189             }
190         }
191     }
192 
193 private:
194     SurfaceTextureBase *mSurfaceTextureBase;
195     sp<GLConsumer> mSurfaceTexture;
196     sp<FrameWaiter> mFW;
197 };
198 
199 class ST_BufferSourceInput : public BufferSourceInput {
200 public:
ST_BufferSourceInput(int tex_id,sp<Camera> camera)201     ST_BufferSourceInput(int tex_id, sp<Camera> camera) :
202                  BufferSourceInput(camera), mTexId(tex_id) {
203         mSurfaceTexture = new SurfaceTextureBase();
204         sp<GLConsumer> surface_texture;
205         mSurfaceTexture->initialize(mTexId);
206         surface_texture = mSurfaceTexture->getST();
207         surface_texture->setSynchronousMode(true);
208 
209         mWindowTapIn = new Surface(surface_texture);
210 #ifndef ANDROID_API_JB_OR_LATER
211         mCamera->setBufferSource(mSurfaceTexture->getST(), NULL);
212 #else
213         mCamera->setBufferSource(mSurfaceTexture->getST()->getBufferQueue(), NULL);
214 #endif
215     }
~ST_BufferSourceInput()216     virtual ~ST_BufferSourceInput() {
217 #ifndef ANDROID_API_JB_OR_LATER
218         mCamera->releaseBufferSource(mSurfaceTexture->getST(), NULL);
219 #else
220         mCamera->releaseBufferSource(mSurfaceTexture->getST()->getBufferQueue(), NULL);
221 #endif
222         delete mSurfaceTexture;
223     }
224 
setInput(buffer_info_t bufinfo,const char * format)225     virtual void setInput(buffer_info_t bufinfo, const char *format) {
226         android::ShotParameters params;
227         mSurfaceTexture->getST()->setDefaultBufferSize(bufinfo.width, bufinfo.height);
228         BufferSourceInput::setInput(bufinfo, format, params);
229     }
230 
231 private:
232     int mTexId;
233     SurfaceTextureBase *mSurfaceTexture;
234 };
235 
236 #endif
237