Kotlin

Creating the Inverted Video Renderer

InvertedColorsVideoRenderer is your main custom renderer. This class plugs directly into Vonage Video SDK. It does NOT render video itself—it delegates all rendering to MyRenderer.

Key responsibilities:

  • Create and configure a GLSurfaceView
  • Receive video frames from Vonage Video SDK (onFrame)
  • Pass them to the OpenGL renderer
  • Handle video scaling ("fit", "fill")`
  • Pause/resume rendering
  1. Create a separate kotlin file with the InvertedColorsVideoRenderer

The InvertedColorsVideoRenderer() constructor sets a renderer property to a GLSurfaceView object. The app uses this object to display the video using OpenGL ES 2.0. The renderer for this GLSurfaceView object is set to a MyRenderer object. MyRenderer is a custom class that we'll create extends GLSurfaceView.Renderer, and it is used to render the video to the GLSurfaceView object

class InvertedColorsVideoRenderer(private val context: Context) : BaseVideoRenderer() {

    private val view: GLSurfaceView
    private val renderer: MyRenderer

    interface InvertedColorsVideoRendererMetadataListener {
        fun onMetadataReady(metadata: ByteArray)
    }

    init {
        view = GLSurfaceView(context)
        view.setEGLContextClientVersion(2)

        renderer = MyRenderer()
        view.setRenderer(renderer)

        view.renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
    }

    override fun onFrame(frame: Frame) {
        renderer.displayFrame(frame)
        view.requestRender()
    }

    override fun setStyle(key: String, value: String) {
        if (BaseVideoRenderer.STYLE_VIDEO_SCALE == key) {
            when (value) {
                BaseVideoRenderer.STYLE_VIDEO_FIT -> renderer.enableVideoFit(true)
                BaseVideoRenderer.STYLE_VIDEO_FILL -> renderer.enableVideoFit(false)
            }
        }
    }

    override fun onVideoPropertiesChanged(videoEnabled: Boolean) {
        renderer.disableVideo(!videoEnabled)
    }

    override fun getView(): View {
        return view
    }

    override fun onPause() {
        view.onPause()
    }

    override fun onResume() {
        view.onResume()
    }
}
  1. Explore the created code and what it does.
  • Vonage Video SDK calls onFrame() for every incoming frame
  • We hand the frame to the OpenGL renderer renderer.displayFrame()
  • We ask GLSurfaceView to draw immediately requestRender()
  • This sets up a clean separation between Vonage Video SDK logic and OpenGL logic.
  1. Let's take a closer look at the onFrame() method of the video renderer

It is inherited from the BaseVideoRenderer class. The BaseVideoRenderer.onFrame() method is called when the publisher (or subscriber) renders a video frame to the video renderer. The InvertedColorsVideoRenderer implementation of this method, it takes the frame's image buffer (YUV representation of the frame), passes it to the displayFrame method of the MyRenderer object and calls the requestRender() method of the GLSurfaceView object:

@Override
public void onFrame(Frame frame) {
    renderer.displayFrame(frame);
    view.requestRender();
}