Home | History | Annotate | Download | only in CameraHal
      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:
     36     FrameWaiter():
     37             mPendingFrames(0) {
     38     }
     39 
     40     virtual ~FrameWaiter() {
     41         onFrameAvailable();
     42     }
     43 
     44     void waitForFrame() {
     45         Mutex::Autolock lock(mMutex);
     46         while (mPendingFrames == 0) {
     47             mCondition.wait(mMutex);
     48         }
     49         mPendingFrames--;
     50     }
     51 
     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 
     66     GLSurface():
     67             mEglDisplay(EGL_NO_DISPLAY),
     68             mEglSurface(EGL_NO_SURFACE),
     69             mEglContext(EGL_NO_CONTEXT) {
     70     }
     71 
     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:
     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:
    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:
    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     }
    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 
    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 
    172     virtual void requestExit() {
    173         Thread::requestExit();
    174 
    175         mDestroying = true;
    176         mFW->onFrameAvailable();
    177     }
    178 
    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:
    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     }
    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 
    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