Siv
Siv

Reputation: 183

Android mirror the camera Preview using SurfaceTexture TransformMatrix

I started from Grafika example and I want to render the camera preview with GlRenderView. My question is how I can modify the transform matrix obtained from surfacetexture in order to get video preview mirrored like with device front camera:

mDisplaySurface.makeCurrent();
mCameraTexture.updateTexImage();
mCameraTexture.getTransformMatrix(mTmpMatrix);

mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);

I tried with the below line but my video gets a weird effect: // Apply horizontal flip.

// Apply horizontal flip.
android.opengl.Matrix.scaleM(mTmpMatrix, 0, -1, 1, 1);

Thank you all.

Upvotes: 3

Views: 1767

Answers (1)

Michael.Z
Michael.Z

Reputation: 31

I have also encounter this issue, and it`s weird that every time I call the drawFrame function twice it is correct for the first time and upside down for the second time, like this:

  mSurfaceTexture.updateTexImage();
  mSurfaceTexture.getTransformMatrix(mTmpMatrix);


  mDisplaySurface.makeCurrent();
  GLES20.glViewport(0, 0, mSurfaceView.getWidth(), mSurfaceView.getHeight());
  mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);//draws in correct direction
  mDisplaySurface.swapBuffers();

  mOffscreenSurface.makeCurrent();
  GLES20.glViewport(0, 0, desiredSize.getWidth(), desiredSize.getHeight());
  mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);//draws upside down
  mOffscreenSurface.getPixels();

Quite curious about why would this happen.....

Anyway, the solution is simple, just add a drawFrameFilpped function in FullFrameRect class and call that to draw a flipped image:

    public void drawFrameFlipped(int textureId, float[] texMatrix) {
    float[] mMatrix=GlUtil.IDENTITY_MATRIX.clone();//must clone a new one...
    Matrix m=new Matrix();
    m.setValues(mMatrix);
    m.postScale(1,-1);
    m.getValues(mMatrix);
    //note: the mMatrix is how gl will transform the scene, and 
    //texMatrix is how the texture to be drawn onto transforms, as @fadden has mentioned
    mProgram.draw(mMatrix, mRectDrawable.getVertexArray(), 0,
            mRectDrawable.getVertexCount(), mRectDrawable.getCoordsPerVertex(),
            mRectDrawable.getVertexStride(),
            texMatrix, mRectDrawable.getTexCoordArray(), textureId,
            mRectDrawable.getTexCoordStride());
    }

and call

    mFullFrameBlit.drawFrameFlipped(mTextureId, mTmpMatrix);

Upvotes: 1

Related Questions