Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
464 views
in Technique[技术] by (71.8m points)

android - Use rotateM() of Matrix to rotate matrix from SurfaceTexture but corrupt the video output

I managed to play video with opengl es, I used the way of grafika's ContinuousCaptureActivity, my data source is MediaPlayer rather than Camera which makes no difference. MediaPlayer produces video frames continuously and I draw each frame to screen in onFrameAvailable callback. The code is as follows which works well:

    mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers();

Now I want to rotate video frames with 270 degrees, so I changed the code:

        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    Matrix.rotateM(mTmpMatrix, 0, 270, 1f, 0, 0);
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers();

But the result is weird, take a look at the picture below: enter image description here

But I can flip video frame successfully with the code below:

        mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    mTmpMatrix[5] = -1 * mTmpMatrix[5];
    mTmpMatrix[13] = 1.0f - mTmpMatrix[13];
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers();

How to achieve the rotation, Could anyone give me some help?

ADD:

At first, I want to tell that I always used this code for each draw action:

        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

I use this demo to do my test, it is a very good demo for this test. https://github.com/izacus/AndroidOpenGLVideoDemo

The matrix got from the surfacetexture is:

1.0, 0.0, 0.0, 0.0

0.0, -1.0, 0.0, 0.0

0.0, 0.0, 1.0, 0.0

0.0, 1.0, 0.0, 1.0

After "Matrix.setRotateM(videoTextureTransform, 0, 270 , 0, 0, 1);",

it became:

1.1924881E-8, -1.0, 0.0, 0.0

1.0, 1.1924881E-8, 0.0, 0.0

0.0, 0.0, 1.0, 0.0

0.0, 0.0, 0.0, 1.0

And this video effect is: enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

fadden's rotation matrix about the z-axis needs to be followed by the correct translation to bring it back on-screen, so to speak. I've tested all 3 rotations below on SurfaceTexture video:

ROTATE 90

Matrix.rotateM(mTmpMatrix, 0, 90, 0, 0, 1);
Matrix.translateM(mTmpMatrix, 0, 0, -1, 0);

ROTATE 180

Matrix.rotateM(mTmpMatrix, 0, 180, 0, 0, 1);
Matrix.translateM(mTmpMatrix, 0, -1, -1, 0);

ROTATE 270

Matrix.rotateM(mTmpMatrix, 0, 270, 0, 0, 1);
Matrix.translateM(mTmpMatrix, 0, -1, 0, 0);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...