Skip to content

Commit 0345208

Browse files
authored
fix: don't dispose the mediaSource when disposing a cloned track (#10)
When disposing of a cloned track, we shouldn't dispose of the shared resources, as they'll lead to "blackened" root tracks. TrackPrivate has been extended with an extra parent field that points to the parent track when cloned. In the future, we should extend the implementation and ensure we properly clean up resources in both directions (top to bottom, and bottom-up). Currently, we only handle bottom-up. Ref: https://linear.app/stream/issue/RN-168/issue-with-camera-not-turning-on-by-default-after-upgrading-sdk
1 parent 32cd63c commit 0345208

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ public void startCapture() {
8686

8787
public boolean stopCapture() {
8888
try {
89-
videoCapturer.stopCapture();
89+
if (videoCapturer != null) {
90+
videoCapturer.stopCapture();
91+
}
9092
return true;
9193
} catch (InterruptedException e) {
9294
return false;

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

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ void mediaStreamTrackSetEnabled(String trackId, final boolean enabled) {
234234
if (enabled) {
235235
track.videoCaptureController.startCapture();
236236
} else {
237-
track.videoCaptureController.stopCapture();
237+
if (!track.isClone()) {
238+
track.videoCaptureController.stopCapture();
239+
}
238240
}
239241
}
240242
}
@@ -419,17 +421,28 @@ MediaStreamTrack cloneTrack(String trackId) {
419421
if (track == null) {
420422
throw new IllegalArgumentException("No track found for id: " + trackId);
421423
}
424+
422425
PeerConnectionFactory pcFactory = webRTCModule.mFactory;
426+
423427
String id = UUID.randomUUID().toString();
424428
MediaStreamTrack nativeTrack = track.track;
425-
MediaStreamTrack clonedNativeTrack;
429+
final MediaStreamTrack clonedNativeTrack;
426430
if (nativeTrack instanceof VideoTrack) {
427431
clonedNativeTrack = pcFactory.createVideoTrack(id, (VideoSource) track.mediaSource);
428432
} else {
429433
clonedNativeTrack = pcFactory.createAudioTrack(id, (AudioSource) track.mediaSource);
430434
}
431435
clonedNativeTrack.setEnabled(nativeTrack.enabled());
432-
tracks.put(id, new TrackPrivate(clonedNativeTrack, track.mediaSource, track.videoCaptureController, track.surfaceTextureHelper));
436+
437+
final TrackPrivate clone = new TrackPrivate(
438+
clonedNativeTrack,
439+
track.mediaSource,
440+
track.videoCaptureController,
441+
track.surfaceTextureHelper
442+
);
443+
clone.setParent(track);
444+
tracks.put(id, clone);
445+
433446
return clonedNativeTrack;
434447
}
435448

@@ -494,6 +507,11 @@ private static class TrackPrivate {
494507
*/
495508
private boolean disposed;
496509

510+
/**
511+
* Whether this object is a clone of another object.
512+
*/
513+
private TrackPrivate parent = null;
514+
497515
/**
498516
* Initializes a new {@code TrackPrivate} instance.
499517
*
@@ -514,8 +532,9 @@ public TrackPrivate(MediaStreamTrack track, MediaSource mediaSource,
514532
}
515533

516534
public void dispose() {
535+
final boolean isClone = this.isClone();
517536
if (!disposed) {
518-
if (videoCaptureController != null) {
537+
if (!isClone && videoCaptureController != null) {
519538
if (videoCaptureController.stopCapture()) {
520539
videoCaptureController.dispose();
521540
}
@@ -527,16 +546,28 @@ public void dispose() {
527546
* called. This also means that the caller can reuse the SurfaceTextureHelper to initialize a new
528547
* VideoCapturer once the previous VideoCapturer has been disposed. */
529548

530-
if (surfaceTextureHelper != null) {
549+
if (!isClone && surfaceTextureHelper != null) {
531550
surfaceTextureHelper.stopListening();
532551
surfaceTextureHelper.dispose();
533552
}
534553

535-
mediaSource.dispose();
554+
// clones should not dispose the mediaSource as that will affect the original track
555+
// and other clones as well (since they share the same mediaSource).
556+
if (!isClone) {
557+
mediaSource.dispose();
558+
}
536559
track.dispose();
537560
disposed = true;
538561
}
539562
}
563+
564+
public void setParent(TrackPrivate parent) {
565+
this.parent = parent;
566+
}
567+
568+
public boolean isClone() {
569+
return this.parent != null;
570+
}
540571
}
541572

542573
public interface BiConsumer<T, U> { void accept(T t, U u); }

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stream-io/react-native-webrtc",
3-
"version": "125.0.7",
3+
"version": "125.0.8-rc.2",
44
"repository": {
55
"type": "git",
66
"url": "git+https://github.com/GetStream/react-native-webrtc.git"

0 commit comments

Comments
 (0)