Kotlin

Creating a custom Renderer (MyRenderer)

Now you'll create a custom renderer that will actually load the frame data and pass it to OpenGL textures. It will be used to apply the inverted-color fragment shader.

Below is an outline; you will adapt shader code later.

  1. Create a kotlin class MyRenderer (can be internal to InvertedColorsVideoRenderer)
static class MyRenderer implements GLSurfaceView.Renderer {

    private int viewportWidth;
    private int viewportHeight;

    ReentrantLock frameLock = new ReentrantLock();
    Frame currentFrame;

    public void displayFrame(Frame frame) {
        frameLock.lock();

        if (currentFrame != null) {
            currentFrame.destroy(); // Disposes previous frame
        }

        currentFrame = frame;
        frameLock.unlock();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // Initialize shaders, textures, etc.
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        viewportWidth = width;
        viewportHeight = height;
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // Upload YUV frame → textures
        // Draw using shaders
        // Implementation of YUV → RGB shader pipeline
        // using inverted color math
    }
}
  1. Let's examine the displayFrame method. It is important to note that the frame that the sdk sends to the Renderer in the onFrame method is now property of the Renderer. It is up to this class to destroy the frame when it is not needed anymore. That's why we destroy previous frame when a new one comes to the Renderer
public void displayFrame(Frame frame) {
    frameLock.lock();

    if (currentFrame != null) {
        currentFrame.destroy(); // Disposes previous frame
    }
    
    currentFrame = frame;
    frameLock.unlock();
}