Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix memory-leak a MediaMixer instance. #1655

Merged
merged 1 commit into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions HaishinKit/Sources/Mixer/AudioCaptureUnit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ final class AudioCaptureUnit: CaptureUnit {
return audioMixer.inputFormats
}
var output: AsyncStream<(AVAudioPCMBuffer, AVAudioTime)> {
let (stream, continutation) = AsyncStream<(AVAudioPCMBuffer, AVAudioTime)>.makeStream()
self.continutation = continutation
return stream
AsyncStream<(AVAudioPCMBuffer, AVAudioTime)> { continutation in
self.continutation = continutation
}
}
private lazy var audioMixer: any AudioMixer = {
if isMultiTrackAudioMixingEnabled {
Expand Down Expand Up @@ -106,6 +106,10 @@ final class AudioCaptureUnit: CaptureUnit {
break
}
}

func finish() {
continutation?.finish()
}
}

extension AudioCaptureUnit: AudioMixerDelegate {
Expand Down
13 changes: 9 additions & 4 deletions HaishinKit/Sources/Mixer/MediaMixer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ public final actor MediaMixer {
}

func setVideoRenderingMode(_ mode: VideoMixerSettings.Mode) {
guard isRunning else {
return
}
switch mode {
case .passthrough:
Task { @ScreenActor in
Expand All @@ -355,7 +358,7 @@ public final actor MediaMixer {
Task { @ScreenActor in
displayLink.preferredFramesPerSecond = await Int(frameRate)
displayLink.startRunning()
for await updateFrame in displayLink.updateFrames where displayLink.isRunning {
for await updateFrame in displayLink.updateFrames {
guard let buffer = screen.makeSampleBuffer(updateFrame) else {
continue
}
Expand Down Expand Up @@ -390,7 +393,7 @@ extension MediaMixer: AsyncRunner {
}
isRunning = true
Task {
for await inputs in videoIO.inputs where isRunning {
for await inputs in videoIO.inputs {
Task { @ScreenActor in
var sampleBuffer = inputs.1
screen.append(inputs.0, buffer: sampleBuffer)
Expand All @@ -405,14 +408,14 @@ extension MediaMixer: AsyncRunner {
}
}
Task {
for await video in videoIO.output where isRunning {
for await video in videoIO.output {
for output in outputs where await output.videoTrackId == UInt8.max {
output.mixer(self, didOutput: video)
}
}
}
Task {
for await audio in audioIO.output where isRunning {
for await audio in audioIO.output {
for output in outputs where await output.audioTrackId == UInt8.max {
output.mixer(self, didOutput: audio.0, when: audio.1)
}
Expand Down Expand Up @@ -450,6 +453,8 @@ extension MediaMixer: AsyncRunner {
if useManualCapture {
session.stopRunning()
}
audioIO.finish()
videoIO.finish()
cancellables.forEach { $0.cancel() }
cancellables.removeAll()
Task { @ScreenActor in
Expand Down
17 changes: 11 additions & 6 deletions HaishinKit/Sources/Mixer/VideoCaptureUnit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ final class VideoCaptureUnit: CaptureUnit {
#endif

var inputs: AsyncStream<(UInt8, CMSampleBuffer)> {
let (stream, continutation) = AsyncStream<(UInt8, CMSampleBuffer)>.makeStream()
self.inputsContinuation = continutation
return stream
AsyncStream<(UInt8, CMSampleBuffer)> { continutation in
self.inputsContinuation = continutation
}
}

var output: AsyncStream<CMSampleBuffer> {
let (stream, continutation) = AsyncStream<CMSampleBuffer>.makeStream()
self.outputContinuation = continutation
return stream
AsyncStream<CMSampleBuffer> { continutation in
self.outputContinuation = continutation
}
}

private lazy var videoMixer = {
Expand Down Expand Up @@ -153,6 +153,11 @@ final class VideoCaptureUnit: CaptureUnit {
return .init(track: track, videoMixer: videoMixer)
}

func finish() {
inputsContinuation?.finish()
outputContinuation?.finish()
}

@available(tvOS 17.0, *)
private func device(for track: UInt8) -> VideoDeviceUnit? {
#if os(tvOS)
Expand Down
3 changes: 2 additions & 1 deletion HaishinKit/Sources/Screen/DisplayLinkChoreographer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ extension DisplayLinkChoreographer: Runner {
guard isRunning else {
return
}
displayLink = nil
isRunning = false
displayLink = nil
continutation?.finish()
}
}