androidopengl-esandroid-camerasurfaceholder

Grafika TextureMovieEncoder


I have recently been modifying Grafika's TextureMovieEncoder to create a recording of what I displayed onscreen: two Sprite2ds which are overlapping. Using the CameraCaptureActivity example as a reference point, I effectively ported what I created for my rendering thread into the TextureMovieEncoder but the output is jagged lines across the screen. I think I understand what's wrong, but I don't know how to fix it:

Some code:

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

I think the problem comes down to my lack of understanding of how to establish the right projection onto the WindowSurface for the VideoEncoder. In the Grafika example, FullFrameRect is used, which is easier since you can just use the identity matrix to stretch a given texture to the surface area. However, since I want to create the overlapping effect, I needed to use Sprite2d. Is the problem the shared EGLContext? Do I need to create a new one so that I can set the viewport to match the WindowSurface size? A bit lost on where to go from here.


Solution

  • Turns out the functionality of the code above was fine. The problem was the interaction between the TextureEncoder and the calling parent.

    I was initializing the member variables backTextureId and frontTextureId after prepareEncoder and it was therefore recording garbage data into the output.