override fun onReceiveFrame()

in amazon-chime-sdk/src/main/java/com/amazonaws/services/chime/sdk/meetings/audiovideo/video/DefaultVideoTileController.kt [31:99]


    override fun onReceiveFrame(
        frame: VideoFrame?,
        videoId: Int,
        attendeeId: String?,
        pauseState: VideoPauseState
    ) {
        /**
         * There are FOUR possible outcomes:
         * 1) Create - Someone has started sharing video
         * 2) Render / Resume - Someone is sending new frames for their video
         * 3) Pause - Someone is sending a pause frame
         * 4) Stop - Someone has stopped sharing video
         *
         * In both pause and stop cases, the frame is null but the pauseType differs
         */
        val tile: VideoTile? = videoTileMap[videoId]

        val videoStreamContentWidth = frame?.width ?: 0
        val videoStreamContentHeight = frame?.height ?: 0

        if (tile != null) {
            if (frame == null && pauseState == VideoPauseState.Unpaused) {
                logger.info(
                    TAG,
                    "Removing video tile with videoId = $videoId & attendeeId = $attendeeId"
                )
                onRemoveVideoTile(videoId)
                return
            }

            if (frame != null && (videoStreamContentWidth != tile.state.videoStreamContentWidth ||
                videoStreamContentHeight != tile.state.videoStreamContentHeight)) {
                tile.state.videoStreamContentWidth = videoStreamContentWidth
                tile.state.videoStreamContentHeight = videoStreamContentHeight
                forEachObserver { observer -> observer.onVideoTileSizeChanged(tile.state) }
            }

            // Account for any internally changed pause states, but ignore if the tile is paused by
            // user since the pause might not have propagated yet
            if (pauseState != tile.state.pauseState && tile.state.pauseState != VideoPauseState.PausedByUserRequest) {
                // Note that currently, since we preemptively mark tiles as PausedByUserRequest when requested by user
                // this path will only be hit when we are either transitioning from .unpaused to PausedForPoorConnection
                // or PausedForPoorConnection to Unpaused
                tile.setPauseState(pauseState)
                if (pauseState == VideoPauseState.Unpaused) {
                    forEachObserver { observer -> observer.onVideoTileResumed(tile.state) }
                } else {
                    forEachObserver { observer -> observer.onVideoTilePaused(tile.state) }
                }
            }

            // Ignore any frames which come to an already paused tile
            if (tile.state.pauseState == VideoPauseState.Unpaused) {
                frame?.run { tile.onVideoFrameReceived(frame) }
            } else {
                logger.verbose(TAG, "Ignoring video frame received on paused tile")
            }
        } else {
            if (frame != null || pauseState != VideoPauseState.Unpaused) {
                run {
                    logger.info(
                        TAG,
                        "Adding video tile with videoId = $videoId, attendeeId = $attendeeId, pauseState = $pauseState"
                    )
                    onAddVideoTile(videoId, attendeeId, pauseState, videoStreamContentWidth, videoStreamContentHeight)
                }
            }
        }
    }