livekit / client-sdk-swift

LiveKit Swift Client SDK. Easily build live audio or video experiences into your mobile app, game or website.
https://livekit.io
Apache License 2.0
173 stars 84 forks source link

Huge memory leaks produced by publishing/unpublishing camera tracks #420

Open VatamanuBogdan opened 2 days ago

VatamanuBogdan commented 2 days ago

Describe the bug I encountered huge memory leaks (around 50MB) when I attempted to publish -> unpublish camera tracks several times.

SDK Version 2.0.11

iOS Version Tested on iOS 17 and iOS 15

Xcode Version Version 15.4 (15F31d) Swift version: Apple Swift version 5.10

Steps to Reproduce

Demo Application

I created a demo application (two simple screens) where the microphone and camera are enabled/disabled by publishing/unpublishing new tracks. I used this approach and not the canonical one (with track unmute/mute) to highlight the memory leaks problem. The problem can be replicated by turning the camera on/off multiple times. On every camera switch the memory will increase significantly.

Demo Repository: https://github.com/VatamanuBogdan/livekit.playground/tree/master Commit: d1c2b043d375a44a63e0df373e531e9dc02cefcd

Steps:

  1. Login into your room using the form found on the Login Screen (you can hardcode the room URL and Token by modifying the values of defaultServerURL and defaultToken constants that can be found at LiveKit-Playground/Utils/Constants.swift )
  2. After you log in with success the Conference Screen will appear and then you should enable -> disable camera by using the Camera toggle button
  3. On every enable -> disable repetition you will see that memory increases drastically see

The entire camera-enabling logic is placed inside ConferenceScreenViewModel.setCamera method.

Code

  1. Initialize a room with the following connect and room options

ConnectOptions

let connectOptions = ConnectOptions(autoSubscribe: false, protocolVersion: .v9)

RoomOptions

let cameraCaptureOptions = CameraCaptureOptions()
let audioCaptureOptions = AudioCaptureOptions()
let videoPublishOptions = VideoPublishOptions(encoding: VideoEncoding(maxBitrate: 2_000_000, maxFps: 30),
                                                                                  simulcast: false,
                                                                                  preferredCodec: VideoCodec.vp8)
let audioPublishOptions = AudioPublishOptions()

let roomOptions = RoomOptions(
          defaultCameraCaptureOptions: cameraCaptureOptions,
          defaultAudioCaptureOptions: audioCaptureOptions,
          defaultVideoPublishOptions: videoPublishOptions,
          defaultAudioPublishOptions: audioPublishOptions,
          adaptiveStream: false,
          dynacast: false,
          reportRemoteTrackStatistics: true
  )
  1. Connect to room

    let room = try await room.connect(url: <Server URL>,
                                                          token: <Token>,
                                                          connectOptions: connectOptions,
                                                          roomOptions: roomOptions)
  2. Create and publish a new camera track

    let videoTrack = LocalVideoTrack.createCameraTrack()
    try await localParticipant.publish(videoTrack: videoTrack)
  3. Unpublish camera track

    let cameraPublication = room.localParticipant.firstCameraPublication as! LocalTrackPublication
    try await self.localParticipant.unpublish(publication: cameraPublication)
  4. Repeat steps 2 and then 3 several times and you will see that memory increases with every repetition

An important thing to notice is that the following room's option changes increased the amount of leaked memory
from 3 - 4MB to 50MB:
https://github.com/VatamanuBogdan/livekit.playground/commit/d16c9375ef187dda15852dc51602ded5e5b28915

Expected behavior

After the camera track unpublish the memory should decrease but it remains the same.

Screenshots

Application Screens

Login Screen Conference Screen
login screen conference screen

Memory Usage

Memory-Usage-Screenshot

Every memory increase represents a camera enabling.