I am using surface view to render frames after extracted from video, the problem is that there is a flickering effect while rendering, the origin video was smooth, I play the frames in ImageViewer and hold on press NEXT key to switch next and next it was smooth too, only flicker after render them in SurfaceView.

the problem is I have a period between frames drawing, because I want to control the playing frame rate, make it slower or faster via user's choice, once I give up the delay drawing the problem gone, but that's no my intention, I need to make them delay.

I understand that this is due to double/triple buffering problem, even though I went through many posts, including turn to use GLSurfaceView to render, also drawBitmap twice intent to keep front-buffer and back-buffer align, it doesn't help to fix this problem.

I found this [Flickering while using surface view](https://stackoverflow.com/q/29348022/1294681) post, and try all the solution-like mention inside, but it's not work, the accepted answer mention about dirty rect, remind me to update every pixels if call `lockCanvas()` without rect specified, but I think I already draw the whole bitmap in the next, imply I updated every pixels, so I get not idea of this.

below are the code and the problem's gif, please take a look at my code and help me get this fixed.

```kotlin
class CustomView(
    context: Context, attrs: AttributeSet?
) : SurfaceView(context, attrs), Runnable {
    private var animationThread: Thread? = null

    @Volatile private var running = false
    private var frameList: List<BitmapFrame1>? = null
    private var index = 0

    fun start(frameList: List<BitmapFrame1>) {
        if (running) return
        running = true
        index = 0
        this.frameList = frameList
        animationThread = Thread(this).apply {
            start()
        }
    }

    override fun run() {
        val surHolder = holder
        var nextFrameTimeMs = 0L
        while (running) {
            if (!surHolder.surface.isValid) continue
            if (SystemClock.uptimeMillis() >= nextFrameTimeMs) {
                val currentFrame = frameList!!.getOrNull(++index)
                if (currentFrame == null) {
                    running = false
                } else {
                    val canvas = surHolder.lockCanvas()
                    canvas.drawBitmap(currentFrame.bitmap, 0f, 0f, Paint())
                    val drawTimestamp = SystemClock.uptimeMillis()
                    surHolder.unlockCanvasAndPost(canvas)
                    nextFrameTimeMs = drawTimestamp + currentFrame.delayMs
                }
            } else {
                // have tried to draw the current frame again before delay time's up,
                // but not effect
                val currentFrame = frameList!![index]
                val canvas = surHolder.lockCanvas()
                canvas.drawBitmap(currentFrame.bitmap, 0f, 0f, Paint())
                surHolder.unlockCanvasAndPost(canvas)
            }
        }
    }
}

```

[![flicker effect](https://i.stack.imgur.com/uw8Ei.gif)](https://i.stack.imgur.com/uw8Ei.gif)