Skip to content

Commit e84ca84

Browse files
committed
feat: handle lifecycle on android video effects
1 parent 43f91de commit e84ca84

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,11 @@ void setVideoEffects(String trackId, ReadableArray names) {
584584
VideoSource videoSource = (VideoSource) track.mediaSource;
585585
SurfaceTextureHelper surfaceTextureHelper = track.surfaceTextureHelper;
586586

587+
// Swap first, dispose last — otherwise a frame in flight could hit a freed
588+
// processor. onCapturerStopped can't replace this; it also fires on pauses.
589+
VideoEffectProcessor previousProcessor = track.videoEffectProcessor;
590+
track.videoEffectProcessor = null;
591+
587592
if (names != null) {
588593
List<VideoFrameProcessor> processors =
589594
names.toArrayList()
@@ -602,10 +607,15 @@ void setVideoEffects(String trackId, ReadableArray names) {
602607

603608
VideoEffectProcessor videoEffectProcessor = new VideoEffectProcessor(processors, surfaceTextureHelper);
604609
videoSource.setVideoProcessor(videoEffectProcessor);
610+
track.videoEffectProcessor = videoEffectProcessor;
605611

606612
} else {
607613
videoSource.setVideoProcessor(null);
608614
}
615+
616+
if (previousProcessor != null) {
617+
previousProcessor.dispose();
618+
}
609619
}
610620
}
611621

@@ -643,6 +653,9 @@ private static class TrackPrivate {
643653
*/
644654
public final VideoTrackAdapter videoTrackAdapter;
645655

656+
/** Current effect processor, disposed on filter switch and on track teardown. */
657+
public VideoEffectProcessor videoEffectProcessor;
658+
646659
/**
647660
* Whether this object has been disposed or not.
648661
*/
@@ -693,6 +706,13 @@ public void dispose() {
693706
}
694707
}
695708

709+
// After stopCapture so no frame can still reach it; before
710+
// surfaceTextureHelper dispose so GL is still alive for cleanup.
711+
if (!isClone && videoEffectProcessor != null) {
712+
videoEffectProcessor.dispose();
713+
videoEffectProcessor = null;
714+
}
715+
696716
// Clean up VideoTrackAdapter for video tracks (each TrackPrivate, incl. clones, has its own)
697717
if (videoTrackAdapter != null && track instanceof VideoTrack) {
698718
videoTrackAdapter.removeDimensionDetector((VideoTrack) track);

android/src/main/java/com/oney/WebRTCModule/videoEffects/VideoEffectProcessor.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class VideoEffectProcessor implements VideoProcessor {
1515
private VideoSink mSink;
1616
final private SurfaceTextureHelper textureHelper;
1717
final private List<VideoFrameProcessor> videoFrameProcessors;
18+
private boolean disposed = false;
1819

1920
public VideoEffectProcessor(List<VideoFrameProcessor> processors, SurfaceTextureHelper textureHelper) {
2021
this.textureHelper = textureHelper;
@@ -27,6 +28,22 @@ public void onCapturerStarted(boolean success) {}
2728
@Override
2829
public void onCapturerStopped() {}
2930

31+
/**
32+
* Disposes each wrapped processor. Posted to the capturer handler so it runs
33+
* after any in-flight {@link #onFrameCaptured}, letting implementations release
34+
* GL resources inline. Idempotent. Called by the owner — not wired to
35+
* {@link #onCapturerStopped}, which also fires on pauses.
36+
*/
37+
public void dispose() {
38+
textureHelper.getHandler().post(() -> {
39+
if (disposed) return;
40+
disposed = true;
41+
for (VideoFrameProcessor processor : this.videoFrameProcessors) {
42+
processor.dispose();
43+
}
44+
});
45+
}
46+
3047
@Override
3148
public void setSink(VideoSink sink) {
3249
mSink = sink;

android/src/main/java/com/oney/WebRTCModule/videoEffects/VideoFrameProcessor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,10 @@ public interface VideoFrameProcessor {
1616
* @return processed videoframe which will rendered
1717
*/
1818
public VideoFrame process(VideoFrame frame, SurfaceTextureHelper textureHelper);
19+
20+
/**
21+
* Called once when this processor leaves the pipeline. Release any native or
22+
* GL resources here. Runs on the capturer handler. Default no-op.
23+
*/
24+
default void dispose() {}
1925
}

0 commit comments

Comments
 (0)