func frameDidSend()

in AmazonChimeSDK/AmazonChimeSDK/internal/video/VideoFrameResender.swift [45:99]


    func frameDidSend(videoFrame: VideoFrame) {
        lastSendTimestamp = CMClockGetTime(CMClockGetHostTimeClock())
        lastVideoFrame = videoFrame

        if let resendTimer = resendTimer,
           resendTimer.isCancelled == false {
            // There is already a timer running
            return
        }
        let timer = DispatchSource.makeTimerSource(flags: .strict, queue: resendQueue)
        resendTimer = timer

        // This timer is invoked every resendTimeInterval when no frame is sent from video source
        timer.setEventHandler(handler: { [weak self] in
            guard let `self` = self else {
                timer.cancel()
                return
            }

            guard let lastSendTimestamp = self.lastSendTimestamp,
                  let lastVideoFrame = self.lastVideoFrame else { return }

            let currentTimestamp = CMClockGetTime(CMClockGetHostTimeClock())
            let delta = CMTimeSubtract(currentTimestamp, lastSendTimestamp)

            // Resend the last input frame if there is no new input frame after resendTimeInterval
            if delta > self.resendTimeInterval {
                // Update the timestamp so it's not dropped by downstream as a duplicate
                let lastVideoFrameTime = CMTimeMake(value: lastVideoFrame.timestampNs,
                                                    timescale: Int32(Constants.nanosecondsPerSecond))
                let newVideoFrame = VideoFrame(timestampNs: Int64(CMTimeAdd(lastVideoFrameTime, delta).seconds
                                                                    * Double(Constants.nanosecondsPerSecond)),
                                               rotation: lastVideoFrame.rotation,
                                               buffer: lastVideoFrame.buffer)

                // Cancel the current timer so that new frames will kick it off again
                self.resendTimer?.cancel()
                self.resendTimer = nil

                self.resendFrameHandler(newVideoFrame)
            } else {
                // Reset resending schedule if there is an input frame between internals
                let remainingSeconds = self.resendTimeInterval.seconds - delta.seconds
                let deadline = DispatchTime.now() + DispatchTimeInterval.milliseconds(Int(remainingSeconds *
                                                           Double(Constants.millisecondsPerSecond)))
                self.resendTimer?.schedule(deadline: deadline, leeway: self.resendScheduleLeewayMs)
            }

        })

        let deadline = DispatchTime.now()
            + DispatchTimeInterval.milliseconds(Constants.millisecondsPerSecond / Int(minFrameRate))
        timer.schedule(deadline: deadline, leeway: resendScheduleLeewayMs)
        timer.activate()
    }