使用 Matrix 的 rotateM() 从 SurfaceTexture 旋转矩阵但损坏视频输出

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

我用opengl es播放视频,我用的是grafika的ContinuousCaptureActivity的方式,我的数据源是MediaPlayer而不是Camera,这没什么区别。 MediaPlayer 连续生成视频帧,我在 onFrameAvailable 回调中将每个帧绘制到屏幕上。代码如下,运行良好:

    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();

现在想把视频帧旋转270度,所以改了代码:

        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();

但是结果很奇怪,请看下图:

但是我可以使用下面的代码成功翻转视频帧:

        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();

如何实现旋转,谁能帮帮我?

添加:

首先,我想告诉大家,我每次绘制动作都使用这段代码:

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

我用这个demo来做我的测试,这个demo非常适合这个测试。 https://github.com/izacus/AndroidOpenGLVideoDemo

从surfacetexture得到的矩阵为:

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

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

变成了:

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

而这个视频效果是:

您正在绕 X 轴旋转:

Matrix.rotateM(mTmpMatrix, 0, 270, 1f, 0, 0);

按照惯例,从左到右运行。轴就像一个轴;将它翻转 270 度,就是在旋转平面,因此您可以从侧面观察它,它实际上正在消失。我认为你看到的基本上是未初始化的数据,如果你调用 glClear() 你会看到背景颜色。

尝试围绕 Z 轴旋转,这是一条指向屏幕外的线:

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

(尝试绕 X 轴旋转约 15 度只是为了看看它的外观可能也很有趣。在摆弄矩阵时,从小值开始通常很有用。)

fadden 关于 z-axis 的旋转矩阵需要跟随正确的翻译才能将其带回 on-screen,可以这么说。我已经在 SurfaceTexture 视频中测试了以下所有 3 个旋转:

旋转 90

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

旋转 180

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

旋转 270

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