blob: a5a6eb0a43cc8d9b85dc3115bff50a04325aeafe [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11package org.webrtc;
12
sakal0ba43b52017-08-14 05:17:49 -070013import java.util.IdentityHashMap;
Magnus Jedvert6062f372017-11-16 16:53:12 +010014import java.util.ArrayList;
15import java.util.List;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
17/** Java version of VideoTrackInterface. */
18public class VideoTrack extends MediaStreamTrack {
Magnus Jedvert6062f372017-11-16 16:53:12 +010019 private final List<VideoRenderer> renderers = new ArrayList<>();
sakal0ba43b52017-08-14 05:17:49 -070020 private final IdentityHashMap<VideoSink, Long> sinks = new IdentityHashMap<VideoSink, Long>();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000021
22 public VideoTrack(long nativeTrack) {
23 super(nativeTrack);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024 }
25
sakal0ba43b52017-08-14 05:17:49 -070026 /**
27 * Adds a VideoSink to the track.
28 *
29 * A track can have any number of VideoSinks. VideoSinks will replace
30 * renderers. However, converting old style texture frames will involve costly
31 * conversion to I420 so it is not recommended to upgrade before all your
32 * sources produce VideoFrames.
33 */
34 public void addSink(VideoSink sink) {
Magnus Jedvertb7700d32018-06-13 17:26:59 +020035 if (sink == null) {
36 throw new IllegalArgumentException("The VideoSink is not allowed to be null");
37 }
38 // We allow calling addSink() with the same sink multiple times. This is similar to the C++
39 // VideoTrack::AddOrUpdateSink().
40 if (!sinks.containsKey(sink)) {
41 final long nativeSink = nativeWrapSink(sink);
42 sinks.put(sink, nativeSink);
43 nativeAddSink(nativeTrack, nativeSink);
44 }
sakal0ba43b52017-08-14 05:17:49 -070045 }
46
47 /**
48 * Removes a VideoSink from the track.
49 *
50 * If the VideoSink was not attached to the track, this is a no-op.
51 */
52 public void removeSink(VideoSink sink) {
Magnus Jedvertb7700d32018-06-13 17:26:59 +020053 final Long nativeSink = sinks.remove(sink);
54 if (nativeSink != null) {
sakal0ba43b52017-08-14 05:17:49 -070055 nativeRemoveSink(nativeTrack, nativeSink);
56 nativeFreeSink(nativeSink);
57 }
58 }
59
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060 public void addRenderer(VideoRenderer renderer) {
61 renderers.add(renderer);
sakal0ba43b52017-08-14 05:17:49 -070062 nativeAddSink(nativeTrack, renderer.nativeVideoRenderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063 }
64
65 public void removeRenderer(VideoRenderer renderer) {
66 if (!renderers.remove(renderer)) {
67 return;
68 }
sakal0ba43b52017-08-14 05:17:49 -070069 nativeRemoveSink(nativeTrack, renderer.nativeVideoRenderer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070 renderer.dispose();
71 }
72
Sami Kalliomäkibde473e2017-10-30 13:34:41 +010073 @Override
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 public void dispose() {
Magnus Jedvert6062f372017-11-16 16:53:12 +010075 for (VideoRenderer renderer : renderers) {
76 nativeRemoveSink(nativeTrack, renderer.nativeVideoRenderer);
77 renderer.dispose();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078 }
Magnus Jedvert6062f372017-11-16 16:53:12 +010079 renderers.clear();
sakal0ba43b52017-08-14 05:17:49 -070080 for (long nativeSink : sinks.values()) {
81 nativeRemoveSink(nativeTrack, nativeSink);
82 nativeFreeSink(nativeSink);
83 }
84 sinks.clear();
fischman@webrtc.org32001ef2013-08-12 23:26:21 +000085 super.dispose();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 }
87
Magnus Jedvert84d8ae52017-12-20 15:12:10 +010088 private static native void nativeAddSink(long track, long nativeSink);
89 private static native void nativeRemoveSink(long track, long nativeSink);
sakal0ba43b52017-08-14 05:17:49 -070090 private static native long nativeWrapSink(VideoSink sink);
Magnus Jedvert84d8ae52017-12-20 15:12:10 +010091 private static native void nativeFreeSink(long sink);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092}