使用 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.
fadden 关于 z 轴的旋转矩阵需要跟随正确的平移才能将其重新显示在屏幕上,可以这么说.我已经在 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);
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:
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:
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);
这篇关于使用 Matrix 的 rotateM() 从 SurfaceTexture 旋转矩阵但损坏视频输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!