1 /*
2  *  Copyright 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 package org.webrtc;
12 
13 import java.util.IdentityHashMap;
14 
15 /** Java version of VideoTrackInterface. */
16 public class VideoTrack extends MediaStreamTrack {
17   private final IdentityHashMap<VideoSink, Long> sinks = new IdentityHashMap<VideoSink, Long>();
18 
VideoTrack(long nativeTrack)19   public VideoTrack(long nativeTrack) {
20     super(nativeTrack);
21   }
22 
23   /**
24    * Adds a VideoSink to the track.
25    *
26    * A track can have any number of VideoSinks. VideoSinks will replace
27    * renderers. However, converting old style texture frames will involve costly
28    * conversion to I420 so it is not recommended to upgrade before all your
29    * sources produce VideoFrames.
30    */
addSink(VideoSink sink)31   public void addSink(VideoSink sink) {
32     if (sink == null) {
33       throw new IllegalArgumentException("The VideoSink is not allowed to be null");
34     }
35     // We allow calling addSink() with the same sink multiple times. This is similar to the C++
36     // VideoTrack::AddOrUpdateSink().
37     if (!sinks.containsKey(sink)) {
38       final long nativeSink = nativeWrapSink(sink);
39       sinks.put(sink, nativeSink);
40       nativeAddSink(getNativeMediaStreamTrack(), nativeSink);
41     }
42   }
43 
44   /**
45    * Removes a VideoSink from the track.
46    *
47    * If the VideoSink was not attached to the track, this is a no-op.
48    */
removeSink(VideoSink sink)49   public void removeSink(VideoSink sink) {
50     final Long nativeSink = sinks.remove(sink);
51     if (nativeSink != null) {
52       nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
53       nativeFreeSink(nativeSink);
54     }
55   }
56 
57   @Override
dispose()58   public void dispose() {
59     for (long nativeSink : sinks.values()) {
60       nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
61       nativeFreeSink(nativeSink);
62     }
63     sinks.clear();
64     super.dispose();
65   }
66 
67   /** Returns a pointer to webrtc::VideoTrackInterface. */
getNativeVideoTrack()68   long getNativeVideoTrack() {
69     return getNativeMediaStreamTrack();
70   }
71 
nativeAddSink(long track, long nativeSink)72   private static native void nativeAddSink(long track, long nativeSink);
nativeRemoveSink(long track, long nativeSink)73   private static native void nativeRemoveSink(long track, long nativeSink);
nativeWrapSink(VideoSink sink)74   private static native long nativeWrapSink(VideoSink sink);
nativeFreeSink(long sink)75   private static native void nativeFreeSink(long sink);
76 }
77