Используйте rotateM() Matrix, чтобы повернуть матрицу из SurfaceTexture, но испортить вывод видео
Мне удалось воспроизвести видео с помощью OpenGLES, я использовал способ ContinuousCaptureActivity от Grafika, мой источник данных - 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);
Я использую эту демонстрацию, чтобы сделать мой тест, это очень хорошая демонстрация для этого теста. https://github.com/izacus/AndroidOpenGLVideoDemo
Матрица, полученная из поверхностной текстуры, имеет вид:
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
2 ответа
За матрицей вращения Фаддена вокруг оси z должен следовать правильный перевод, чтобы, так сказать, вернуть его на экран. Я проверил все 3 поворота ниже на видео SurfaceTexture:
ПОВЕРНУТЬ 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);
Вы вращаетесь вокруг оси X:
Matrix.rotateM(mTmpMatrix, 0, 270, 1f, 0, 0);
По соглашению, который идет слева направо. Ось действует как ось; переворачивая его на 270 градусов, вы поворачиваете плоскость так, что смотрите на нее с края, и она фактически исчезает. Я думаю, что вы видите по сути неинициализированные данные, и если вы позвоните glClear()
вместо этого вы увидите цвет фона.
Попробуйте повернуть вокруг оси Z, которая является линией, указывающей на экран:
Matrix.rotateM(mTmpMatrix, 0, 270, 0, 0, 1);
(Также было бы интересно поэкспериментировать с поворотом на 15 градусов вокруг оси X, просто чтобы посмотреть, как это выглядит. При работе с матрицами часто полезно начинать с небольших значений.)