@@ -9,81 +9,116 @@ namespace Unity.WebRTC
9
9
public class MediaStream
10
10
{
11
11
private IntPtr self ;
12
- private RenderTexture rt ;
13
12
private string id ;
14
13
public string Id { get => id ; private set { } }
15
14
16
- public RenderTexture Rt { get => rt ; private set => rt = value ; }
15
+ private Dictionary < MediaStreamTrack , RenderTexture [ ] > VideoTrackToRts ;
16
+ private List < MediaStreamTrack > AudioTracks ;
17
17
18
- public MediaStreamTrack [ ] GetTracks ( )
19
- {
20
- int audioTrackSize = 0 , videoTrackSize = 0 ;
21
- IntPtr audioPtr = NativeMethods . MediaStreamGetAudioTracks ( self , ref audioTrackSize ) ;
22
- IntPtr videoPtr = NativeMethods . MediaStreamGetVideoTracks ( self , ref videoTrackSize ) ;
23
- IntPtr [ ] tracksPtr = new IntPtr [ audioTrackSize + videoTrackSize ] ;
24
- Marshal . Copy ( audioPtr , tracksPtr , 0 , audioTrackSize ) ;
25
- Marshal . Copy ( videoPtr , tracksPtr , audioTrackSize , videoTrackSize ) ;
26
- //TODO: Linux compatibility
27
- Marshal . FreeCoTaskMem ( audioPtr ) ;
28
- Marshal . FreeCoTaskMem ( videoPtr ) ;
29
- MediaStreamTrack [ ] tracks = new MediaStreamTrack [ audioTrackSize + videoTrackSize ] ;
30
- for ( int i = 0 ; i < audioTrackSize + videoTrackSize ; i ++ )
18
+ private void StopTrack ( MediaStreamTrack track )
19
+ {
20
+
21
+ if ( track . Kind == TrackKind . Video )
31
22
{
32
- tracks [ i ] = new MediaStreamTrack ( Rt , tracksPtr [ i ] ) ;
23
+ NativeMethods . StopMediaStreamTrack ( track . self ) ;
24
+ RenderTexture [ ] rts = VideoTrackToRts [ track ] ;
25
+ if ( rts != null )
26
+ {
27
+ CameraExtension . RemoveRt ( rts ) ;
28
+ rts [ 0 ] . Release ( ) ;
29
+ rts [ 1 ] . Release ( ) ;
30
+ UnityEngine . Object . Destroy ( rts [ 0 ] ) ;
31
+ UnityEngine . Object . Destroy ( rts [ 1 ] ) ;
32
+ }
33
33
}
34
+ else
35
+ {
36
+ Audio . Stop ( ) ;
37
+ }
38
+
39
+ }
40
+ private RenderTexture [ ] GetRts ( MediaStreamTrack track )
41
+ {
42
+ return VideoTrackToRts [ track ] ;
43
+ }
44
+ public MediaStreamTrack [ ] GetTracks ( )
45
+ {
46
+ MediaStreamTrack [ ] tracks = new MediaStreamTrack [ VideoTrackToRts . Keys . Count + AudioTracks . Count ] ;
47
+ AudioTracks . CopyTo ( tracks , 0 ) ;
48
+ VideoTrackToRts . Keys . CopyTo ( tracks , AudioTracks . Count ) ;
34
49
return tracks ;
35
50
}
36
51
public MediaStreamTrack [ ] GetAudioTracks ( )
37
52
{
38
- int trackSize = 0 ;
39
- IntPtr ptr = NativeMethods . MediaStreamGetAudioTracks ( self , ref trackSize ) ;
40
- IntPtr [ ] tracksPtr = new IntPtr [ trackSize ] ;
41
- Marshal . Copy ( ptr , tracksPtr , 0 , trackSize ) ;
42
- //TODO: Linux compatibility
43
- Marshal . FreeCoTaskMem ( ptr ) ;
44
-
45
- MediaStreamTrack [ ] tracks = new MediaStreamTrack [ trackSize ] ;
46
- for ( int i = 0 ; i < trackSize ; i ++ )
47
- {
48
- tracks [ i ] = new MediaStreamTrack ( tracksPtr [ i ] ) ;
49
- }
50
- return tracks ;
53
+ return AudioTracks . ToArray ( ) ;
51
54
}
52
55
public MediaStreamTrack [ ] GetVideoTracks ( )
53
56
{
54
- int trackSize = 0 ;
55
- IntPtr ptr = NativeMethods . MediaStreamGetVideoTracks ( self , ref trackSize ) ;
56
- IntPtr [ ] tracksPtr = new IntPtr [ trackSize ] ;
57
- Marshal . Copy ( ptr , tracksPtr , 0 , trackSize ) ;
58
- //TODO: Linux compatibility
59
- Marshal . FreeCoTaskMem ( ptr ) ;
60
-
61
- MediaStreamTrack [ ] tracks = new MediaStreamTrack [ trackSize ] ;
62
- for ( int i = 0 ; i < trackSize ; i ++ )
63
- {
64
- tracks [ i ] = new MediaStreamTrack ( Rt , tracksPtr [ i ] ) ;
65
- }
57
+ MediaStreamTrack [ ] tracks = new MediaStreamTrack [ VideoTrackToRts . Keys . Count ] ;
58
+ VideoTrackToRts . Keys . CopyTo ( tracks , 0 ) ;
66
59
return tracks ;
67
60
}
68
61
69
62
public void AddTrack ( MediaStreamTrack track )
70
63
{
64
+ if ( track . Kind == TrackKind . Video )
65
+ {
66
+ VideoTrackToRts [ track ] = track . getRts ( track ) ;
67
+ }
68
+ else
69
+ {
70
+ AudioTracks . Add ( track ) ;
71
+ }
71
72
NativeMethods . MediaStreamAddTrack ( self , track . self ) ;
72
73
}
73
74
public void RemoveTrack ( MediaStreamTrack track )
74
75
{
75
76
NativeMethods . MediaStreamRemoveTrack ( self , track . self ) ;
76
77
}
77
- internal MediaStream ( RenderTexture rt , IntPtr ptr )
78
+ //for camera CaptureStream
79
+ internal MediaStream ( RenderTexture [ ] rts , IntPtr ptr )
78
80
{
79
81
self = ptr ;
80
82
id = Marshal . PtrToStringAnsi ( NativeMethods . MediaStreamGetID ( self ) ) ;
81
- Rt = rt ;
83
+ VideoTrackToRts = new Dictionary < MediaStreamTrack , RenderTexture [ ] > ( ) ;
84
+ AudioTracks = new List < MediaStreamTrack > ( ) ;
85
+ //get initial tracks
86
+ int trackSize = 0 ;
87
+ IntPtr tracksNativePtr = NativeMethods . MediaStreamGetVideoTracks ( self , ref trackSize ) ;
88
+ IntPtr [ ] tracksPtr = new IntPtr [ trackSize ] ;
89
+ Marshal . Copy ( tracksNativePtr , tracksPtr , 0 , trackSize ) ;
90
+ //TODO: Linux compatibility
91
+ Marshal . FreeCoTaskMem ( tracksNativePtr ) ;
92
+ for ( int i = 0 ; i < trackSize ; i ++ )
93
+ {
94
+ MediaStreamTrack track = new MediaStreamTrack ( tracksPtr [ i ] ) ;
95
+ track . stopTrack += StopTrack ;
96
+ track . getRts += GetRts ;
97
+ VideoTrackToRts [ track ] = rts ;
98
+ }
82
99
}
100
+ //for audio CaptureStream
83
101
internal MediaStream ( IntPtr ptr )
84
102
{
85
103
self = ptr ;
86
104
id = Marshal . PtrToStringAnsi ( NativeMethods . MediaStreamGetID ( self ) ) ;
105
+ VideoTrackToRts = new Dictionary < MediaStreamTrack , RenderTexture [ ] > ( ) ;
106
+ AudioTracks = new List < MediaStreamTrack > ( ) ;
107
+ //get initial tracks
108
+ int trackSize = 0 ;
109
+ IntPtr trackNativePtr = NativeMethods . MediaStreamGetAudioTracks ( self , ref trackSize ) ;
110
+ IntPtr [ ] tracksPtr = new IntPtr [ trackSize ] ;
111
+ Marshal . Copy ( trackNativePtr , tracksPtr , 0 , trackSize ) ;
112
+ //TODO: Linux compatibility
113
+ Marshal . FreeCoTaskMem ( trackNativePtr ) ;
114
+
115
+ for ( int i = 0 ; i < trackSize ; i ++ )
116
+ {
117
+ MediaStreamTrack track = new MediaStreamTrack ( tracksPtr [ i ] ) ;
118
+ track . stopTrack += StopTrack ;
119
+ track . getRts += GetRts ;
120
+ AudioTracks . Add ( track ) ;
121
+ }
87
122
}
88
123
89
124
}
@@ -117,30 +152,36 @@ public static void AddCleanerCallback(this GameObject obj, Action callback)
117
152
}
118
153
public static class CameraExtension
119
154
{
120
- private static List < RenderTexture > camCopyRts = new List < RenderTexture > ( ) ;
155
+ internal static List < RenderTexture [ ] > camCopyRts = new List < RenderTexture [ ] > ( ) ;
121
156
internal static bool started = false ;
122
157
public static MediaStream CaptureStream ( this Camera cam , int width , int height )
123
158
{
124
- RenderTexture rt = new RenderTexture ( width , height , 0 , RenderTextureFormat . BGRA32 ) ;
125
- rt . Create ( ) ;
126
- camCopyRts . Add ( rt ) ;
127
- cam . targetTexture = rt ;
159
+ RenderTexture [ ] rts = new RenderTexture [ 2 ] ;
160
+ //rts[0] for render target, rts[1] for flip and WebRTC source
161
+ rts [ 0 ] = new RenderTexture ( width , height , 0 , RenderTextureFormat . BGRA32 ) ;
162
+ rts [ 1 ] = new RenderTexture ( width , height , 0 , RenderTextureFormat . BGRA32 ) ;
163
+ rts [ 0 ] . Create ( ) ;
164
+ rts [ 1 ] . Create ( ) ;
165
+ camCopyRts . Add ( rts ) ;
166
+ cam . targetTexture = rts [ 0 ] ;
128
167
cam . gameObject . AddCleanerCallback ( ( ) =>
129
168
{
130
- if ( rt != null )
169
+ if ( rts != null )
131
170
{
132
- CameraExtension . RemoveRt ( rt ) ;
133
- rt . Release ( ) ;
134
- UnityEngine . Object . Destroy ( rt ) ;
171
+ CameraExtension . RemoveRt ( rts ) ;
172
+ rts [ 0 ] . Release ( ) ;
173
+ rts [ 1 ] . Release ( ) ;
174
+ UnityEngine . Object . Destroy ( rts [ 0 ] ) ;
175
+ UnityEngine . Object . Destroy ( rts [ 1 ] ) ;
135
176
}
136
177
} ) ;
137
178
started = true ;
138
- return new MediaStream ( rt , WebRTC . Context . CaptureVideoStream ( rt . GetNativeTexturePtr ( ) , width , height ) ) ;
179
+ return new MediaStream ( rts , WebRTC . Context . CaptureVideoStream ( rts [ 1 ] . GetNativeTexturePtr ( ) , width , height ) ) ;
139
180
}
140
- public static void RemoveRt ( RenderTexture rt )
181
+ public static void RemoveRt ( RenderTexture [ ] rts )
141
182
{
142
- camCopyRts . Remove ( rt ) ;
143
- if ( camCopyRts . Count == 0 )
183
+ camCopyRts . Remove ( rts ) ;
184
+ if ( camCopyRts . Count == 0 )
144
185
{
145
186
started = false ;
146
187
}
0 commit comments