override fun onVideoFrameReceived()

in app/src/main/java/com/amazonaws/services/chime/sdkdemo/utils/CpuVideoProcessor.kt [86:138]


    override fun onVideoFrameReceived(frame: VideoFrame) {
        frame.retain()
        handler.post {
            // Note: This processor assumes that the incoming call will be on a valid EGL context
            textureFrameBuffer.setSize(frame.getRotatedWidth(), frame.getRotatedHeight())
            GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, textureFrameBuffer.frameBufferId)

            val matrix = Matrix()
            // Shift before flipping
            matrix.preTranslate(0.5f, 0.5f)
            // RGBA frames are upside down relative to texture coordinates
            matrix.preScale(1f, -1f)
            // Unshift following flip
            matrix.preTranslate(-0.5f, -0.5f)
            // Note the draw call will account for any rotation, so we need to account for that in viewport width/height
            rectDrawer.drawFrame(
                frame,
                0,
                0,
                frame.getRotatedWidth(),
                frame.getRotatedHeight(),
                matrix
            )

            // Read RGBA data to native byte buffer
            val rgbaData = JniUtil.nativeAllocateByteBuffer(frame.width * frame.height * 4)
            GLES20.glReadPixels(
                0,
                0,
                frame.getRotatedWidth(),
                frame.getRotatedHeight(),
                GLES20.GL_RGBA,
                GLES20.GL_UNSIGNED_BYTE,
                rgbaData
            )
            GlUtil.checkGlError("glReadPixels")

            val rgbaBuffer =
                VideoFrameRGBABuffer(
                    frame.getRotatedWidth(),
                    frame.getRotatedHeight(),
                    rgbaData, frame.getRotatedWidth() * 4,
                    Runnable { JniUtil.nativeFreeByteBuffer(rgbaData) })

            convertToBlackAndWhite(rgbaBuffer)

            val processedFrame = VideoFrame(frame.timestampNs, rgbaBuffer)
            frame.release()

            sinks.forEach { it.onVideoFrameReceived(processedFrame) }
            processedFrame.release()
        }
    }