@Override
    public void initialize() {
        try {
            program =
                    new GlProgram(
                            context,
                            /* vertexShaderFilePath= */ "bitmap_overlay_video_processor_vertex.glsl",
                            /* fragmentShaderFilePath= */ "bitmap_overlay_video_processor_fragment.glsl");
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        program.setBufferAttribute(
                "aFramePosition",
                GlUtil.getNormalizedCoordinateBounds(),
                GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
        program.setBufferAttribute(
                "aTexCoords",
                GlUtil.getTextureCoordinateBounds(),
                GlUtil.HOMOGENEOUS_COORDINATE_VECTOR_SIZE);
        GLES20.glGenTextures(1, textures, 0);
        GLES20.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
        GLES20.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, /* level= */ 0, overlayBitmap, /* border= */ 0);
    }
Video processor that demonstrates how to overlay a bitmap on video output using a GL shader. The
bitmap is drawn using an Android {@link Canvas}.
dkplayer-sample/src/main/java/xyz/doikki/dkplayer/widget/render/gl/BitmapOverlayVideoProcessor.java