Skip to content

Commit

Permalink
Minor VideoView optimization (#492)
Browse files Browse the repository at this point in the history
add/remove video renderer has it's own lock in WebRTC, it doesn't need
to be called from main thread.
  • Loading branch information
hiroshihorie authored Sep 29, 2024
1 parent ea70e68 commit c884f60
Showing 1 changed file with 25 additions and 21 deletions.
46 changes: 25 additions & 21 deletions Sources/LiveKit/Views/VideoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,42 +270,39 @@ public class VideoView: NativeView, Loggable {

let shouldRenderDidUpdate = newState.shouldRender != oldState.shouldRender
let renderModeDidUpdate = newState.renderMode != oldState.renderMode

// track was swapped
let trackDidUpdate = !Self.track(oldState.track as? VideoTrack, isEqualWith: newState.track as? VideoTrack)

// Enter .main only if the following conditions are met...
if trackDidUpdate || shouldRenderDidUpdate {
// Handle track removal outside of main queue
if let track = oldState.track as? VideoTrack {
track.remove(videoRenderer: self)
}
}

// Enter .main only if UI updates are required
if trackDidUpdate || shouldRenderDidUpdate || renderModeDidUpdate {
// Execute on main thread
self.mainSyncOrAsync {
var didReCreateNativeRenderer = false

if trackDidUpdate || shouldRenderDidUpdate {
// clean up old track
if let track = oldState.track as? VideoTrack {
track.remove(videoRenderer: self)

if let r = self._primaryRenderer {
r.removeFromSuperview()
self._primaryRenderer = nil
}
// Clean up old renderers
if let r = self._primaryRenderer {
r.removeFromSuperview()
self._primaryRenderer = nil
}

if let r = self._secondaryRenderer {
r.removeFromSuperview()
self._secondaryRenderer = nil
}
if let r = self._secondaryRenderer {
r.removeFromSuperview()
self._secondaryRenderer = nil
}

// set new track
// Set up new renderer if needed
if let track = newState.track as? VideoTrack, newState.shouldRender {
// re-create renderer on main thread
let nr = self.recreatePrimaryRenderer(for: newState.renderMode)
didReCreateNativeRenderer = true

track.add(videoRenderer: self)

if let frame = track._state.videoFrame {
self.log("rendering cached frame tack: \(String(describing: track._state.sid))")
self.log("rendering cached frame track: \(String(describing: track._state.sid))")
nr.renderFrame(frame.toRTCType())
self.setNeedsLayout()
}
Expand All @@ -318,6 +315,13 @@ public class VideoView: NativeView, Loggable {
}
}

// Handle track addition outside of main queue
if trackDidUpdate || shouldRenderDidUpdate {
if let track = newState.track as? VideoTrack, newState.shouldRender {
track.add(videoRenderer: self)
}
}

// isRendering updated
if newState.isRendering != oldState.isRendering {
self.log("isRendering \(oldState.isRendering) -> \(newState.isRendering)")
Expand Down

0 comments on commit c884f60

Please sign in to comment.