Grafika TextureMovieEncoder
Posted
技术标签:
【中文标题】Grafika TextureMovieEncoder【英文标题】: 【发布时间】:2015-01-08 02:51:10 【问题描述】:我最近一直在修改 Grafika 的 TextureMovieEncoder
以创建我在屏幕上显示的内容的记录:两个重叠的 Sprite2d。使用CameraCaptureActivity
示例作为参考点,我有效地将我为渲染线程创建的内容移植到TextureMovieEncoder
,但输出是屏幕上的锯齿线。我想我明白出了什么问题,但我不知道如何解决它:
一些代码:
private void prepareEncoder(EGLContext sharedContext, int width, int height, int bitRate,
File outputFile)
try
mVideoEncoder = new VideoEncoderCore(width, height, bitRate, outputFile);
catch (IOException ioe)
throw new RuntimeException(ioe);
mEglCore = new EglCore(sharedContext, EglCore.FLAG_RECORDABLE);
mInputWindowSurface = new WindowSurface(mEglCore, mVideoEncoder.getInputSurface(), true);
mInputWindowSurface.makeCurrent();
textureProgram = new Texture2dProgram(Texture2dProgram.ProgramType.TEXTURE_EXT);
backgroundDrawable = new Drawable2d(Drawable2d.Prefab.RECTANGLE);
backgroundRect = new Sprite2d(backgroundDrawable);
frontDrawable = new Drawable2d(Drawable2d.Prefab.RECTANGLE);
frontRect = new Sprite2d(frontDrawable);
backgroundRect.setTexture(backTextureId);
frontRect.setTexture(frontTextureId);
updateGeometry();
private void handleFrameAvailable(Transform transform, long timestampNanos)
if (VERBOSE) Log.d(TAG, "handleFrameAvailable tr=" + transform);
mVideoEncoder.drainEncoder(false);
backgroundRect.draw(textureProgram, transform.movieMatrix);
frontRect.draw(textureProgram, transform.cameraMatrix);
mInputWindowSurface.setPresentationTime(timestampNanos);
mInputWindowSurface.swapBuffers();
我认为问题归结为我对如何为VideoEncoder
建立正确的投影到WindowSurface
缺乏了解。在 Grafika 示例中,使用了FullFrameRect
,这更容易,因为您可以只使用单位矩阵将给定的纹理拉伸到表面区域。但是,由于我想创建重叠效果,我需要使用 Sprite2d。问题是共享的 EGLContext 吗?我是否需要创建一个新的以便我可以设置视口以匹配WindowSurface
大小?有点迷失从这里去哪里。
【问题讨论】:
在许多方面,“连续捕获”活动是一个更好的起点,因为它避免了 GLSurfaceView 引起的体操;特别是它使用单个 EGL 上下文。无论如何,EGL 上下文共享纹理和其他好东西,但不共享视口或任何绘图状态,因此所有这些都是独立配置的。您是否仅在屏幕上、仅在视频上或两者中看到不良输出? “来自相机的纹理”活动显示将视频(来自相机)输入 Sprite2d 而不是 FullFrameRect。 嘿法登。感谢您的澄清。我看到了两者的输出,但是视频被混叠弄乱了。我尝试设置视口,然后使用 orthM 设置投影矩阵,但这不起作用(视频仍然有混叠......但不同)。GLES20.glViewport(0, 0, width, height);
Matrix.orthoM(mDisplayProjectionMatrix, 0, 0, width, 0, height, -1, 1);
还有。如果我将所有绘图更改为使用 FullFrameRect 而不是 Sprite2d,则输出视频会显示而不会出现锯齿;但是,没有正确的缩放/定位。
看起来不错。是几何问题还是纹理问题?即,您是否看到具有正确位置和大小的形状,但渲染到其上的视频纹理却搞砸了?参看。 “硬件缩放器练习器”,它在平面阴影和纹理形状之间翻转。
嘿fadden,你在这个钱上是对的。问题在于我的 Sprite2d 的初始化。我太早或太晚传递纹理ID。在线程启动之前以及录制开始之后。因此,它只是拉错了纹理
【参考方案1】:
原来上面代码的功能很好。问题是 TextureEncoder 和调用父级之间的交互。
我在prepareEncoder 之后初始化了成员变量backTextureId
和frontTextureId
,因此它将垃圾数据记录到输出中。
【讨论】:
以上是关于Grafika TextureMovieEncoder的主要内容,如果未能解决你的问题,请参考以下文章
Grafika 和 OpenGL 在 android 上以方形录制视频
相机的 SurfaceView 与 TextureView 对比?