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 之后初始化了成员变量backTextureIdfrontTextureId,因此它将垃圾数据记录到输出中。

【讨论】:

以上是关于Grafika TextureMovieEncoder的主要内容,如果未能解决你的问题,请参考以下文章

Grafika 和 OpenGL 在 android 上以方形录制视频

PHP图片处理库Grafika详细教程

相机的 SurfaceView 与 TextureView 对比?

Android - 高斯模糊效果 - OpenGL

Android 边播放边缓存视频框架AndroidVideoCache简析

在 Android 中使用 Open GL Framebuffer 时如何转换图像