OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/media_stream_renderer_factory_impl.h" | 5 #include "content/renderer/media/media_stream_renderer_factory_impl.h" |
6 | 6 |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "content/renderer/media/media_stream.h" | 8 #include "content/renderer/media/media_stream.h" |
9 #include "content/renderer/media/media_stream_audio_track.h" | 9 #include "content/renderer/media/media_stream_audio_track.h" |
10 #include "content/renderer/media/media_stream_video_renderer_sink.h" | 10 #include "content/renderer/media/media_stream_video_renderer_sink.h" |
11 #include "content/renderer/media/media_stream_video_track.h" | 11 #include "content/renderer/media/media_stream_video_track.h" |
| 12 #include "content/renderer/media/track_audio_renderer.h" |
12 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | 13 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
13 #include "content/renderer/media/webrtc_audio_renderer.h" | 14 #include "content/renderer/media/webrtc_audio_renderer.h" |
14 #include "content/renderer/media/webrtc_local_audio_renderer.h" | |
15 #include "content/renderer/render_thread_impl.h" | 15 #include "content/renderer/render_thread_impl.h" |
16 #include "media/base/audio_hardware_config.h" | 16 #include "media/base/audio_hardware_config.h" |
17 #include "third_party/WebKit/public/platform/WebMediaStream.h" | 17 #include "third_party/WebKit/public/platform/WebMediaStream.h" |
18 #include "third_party/WebKit/public/platform/WebURL.h" | 18 #include "third_party/WebKit/public/platform/WebURL.h" |
19 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" | 19 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" |
20 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" | 20 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" |
21 | 21 |
22 namespace content { | 22 namespace content { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 PeerConnectionDependencyFactory* GetPeerConnectionDependencyFactory() { | 26 PeerConnectionDependencyFactory* GetPeerConnectionDependencyFactory() { |
27 return RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(); | 27 return RenderThreadImpl::current()->GetPeerConnectionDependencyFactory(); |
28 } | 28 } |
29 | 29 |
30 // Returns a valid session id if a single capture device is currently open | 30 // Returns a valid session id if a single WebRTC capture device is currently |
31 // (and then the matching session_id), otherwise -1. | 31 // open (and then the matching session_id), otherwise 0. |
32 // This is used to pass on a session id to a webrtc audio renderer (either | 32 // This is used to pass on a session id to an audio renderer, so that audio will |
33 // local or remote), so that audio will be rendered to a matching output | 33 // be rendered to a matching output device, should one exist. |
34 // device, should one exist. | |
35 // Note that if there are more than one open capture devices the function | 34 // Note that if there are more than one open capture devices the function |
36 // will not be able to pick an appropriate device and return false. | 35 // will not be able to pick an appropriate device and return 0. |
37 bool GetSessionIdForAudioRenderer(int* session_id) { | 36 int GetSessionIdForWebRtcAudioRenderer() { |
38 WebRtcAudioDeviceImpl* audio_device = | 37 WebRtcAudioDeviceImpl* audio_device = |
39 GetPeerConnectionDependencyFactory()->GetWebRtcAudioDevice(); | 38 GetPeerConnectionDependencyFactory()->GetWebRtcAudioDevice(); |
40 if (!audio_device) | 39 if (!audio_device) |
41 return false; | 40 return 0; |
42 | 41 |
| 42 int session_id = 0; |
43 int sample_rate; // ignored, read from output device | 43 int sample_rate; // ignored, read from output device |
44 int frames_per_buffer; // ignored, read from output device | 44 int frames_per_buffer; // ignored, read from output device |
45 return audio_device->GetAuthorizedDeviceInfoForAudioRenderer( | 45 if (!audio_device->GetAuthorizedDeviceInfoForAudioRenderer( |
46 session_id, &sample_rate, &frames_per_buffer); | 46 &session_id, &sample_rate, &frames_per_buffer)) { |
47 } | 47 session_id = 0; |
48 | 48 } |
49 scoped_refptr<WebRtcAudioRenderer> CreateRemoteAudioRenderer( | 49 return session_id; |
50 const blink::WebMediaStream& stream, | |
51 int render_frame_id, | |
52 const std::string& device_id, | |
53 const url::Origin& security_origin) { | |
54 DVLOG(1) << "MediaStreamRendererFactoryImpl::CreateRemoteAudioRenderer id:" | |
55 << stream.id().utf8(); | |
56 // |stream| will always contain at least one audio track. | |
57 // See MediaStreamRendererFactoryImpl::GetAudioRenderer. | |
58 | |
59 // TODO(tommi): Change the default value of session_id to be | |
60 // StreamDeviceInfo::kNoId. Also update AudioOutputDevice etc. | |
61 int session_id = 0; | |
62 GetSessionIdForAudioRenderer(&session_id); | |
63 | |
64 return new WebRtcAudioRenderer( | |
65 GetPeerConnectionDependencyFactory()->GetWebRtcSignalingThread(), stream, | |
66 render_frame_id, session_id, device_id, security_origin); | |
67 } | |
68 | |
69 scoped_refptr<WebRtcLocalAudioRenderer> CreateLocalAudioRenderer( | |
70 const blink::WebMediaStreamTrack& audio_track, | |
71 int render_frame_id, | |
72 const std::string& device_id, | |
73 const url::Origin& security_origin) { | |
74 DVLOG(1) << "MediaStreamRendererFactoryImpl::CreateLocalAudioRenderer"; | |
75 | |
76 int session_id = 0; | |
77 GetSessionIdForAudioRenderer(&session_id); | |
78 | |
79 // Create a new WebRtcLocalAudioRenderer instance and connect it to the | |
80 // existing WebRtcAudioCapturer so that the renderer can use it as source. | |
81 return new WebRtcLocalAudioRenderer(audio_track, render_frame_id, session_id, | |
82 device_id, security_origin); | |
83 } | 50 } |
84 | 51 |
85 } // namespace | 52 } // namespace |
86 | 53 |
87 | 54 |
88 MediaStreamRendererFactoryImpl::MediaStreamRendererFactoryImpl() { | 55 MediaStreamRendererFactoryImpl::MediaStreamRendererFactoryImpl() { |
89 } | 56 } |
90 | 57 |
91 MediaStreamRendererFactoryImpl::~MediaStreamRendererFactoryImpl() { | 58 MediaStreamRendererFactoryImpl::~MediaStreamRendererFactoryImpl() { |
92 } | 59 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 // in the stream is local or remote. | 111 // in the stream is local or remote. |
145 MediaStreamAudioTrack* audio_track = MediaStreamAudioTrack::GetTrack( | 112 MediaStreamAudioTrack* audio_track = MediaStreamAudioTrack::GetTrack( |
146 audio_tracks[0]); | 113 audio_tracks[0]); |
147 if (!audio_track) { | 114 if (!audio_track) { |
148 // This can happen if the track was cloned. | 115 // This can happen if the track was cloned. |
149 // TODO(tommi, perkj): Fix cloning of tracks to handle extra data too. | 116 // TODO(tommi, perkj): Fix cloning of tracks to handle extra data too. |
150 LOG(ERROR) << "No native track for WebMediaStreamTrack."; | 117 LOG(ERROR) << "No native track for WebMediaStreamTrack."; |
151 return nullptr; | 118 return nullptr; |
152 } | 119 } |
153 | 120 |
154 if (audio_track->is_local_track()) { | 121 // If the track has a local source, or is a remote track that does not use the |
| 122 // WebRTC audio pipeline, return a new TrackAudioRenderer instance. |
| 123 // |
| 124 // TODO(miu): In a soon up-coming change, I'll introduce a cleaner way (i.e., |
| 125 // rather than calling GetAudioAdapter()) to determine whether a remote source |
| 126 // is via WebRTC or something else. |
| 127 if (audio_track->is_local_track() || !audio_track->GetAudioAdapter()) { |
155 // TODO(xians): Add support for the case where the media stream contains | 128 // TODO(xians): Add support for the case where the media stream contains |
156 // multiple audio tracks. | 129 // multiple audio tracks. |
157 return CreateLocalAudioRenderer(audio_tracks[0], render_frame_id, device_id, | 130 DVLOG(1) << "Creating TrackAudioRenderer for " |
158 security_origin); | 131 << (audio_track->is_local_track() ? "local" : "remote") |
| 132 << " track."; |
| 133 return new TrackAudioRenderer(audio_tracks[0], render_frame_id, |
| 134 0 /* no session_id */, device_id, |
| 135 security_origin); |
159 } | 136 } |
160 | 137 |
161 // This is a remote WebRTC media stream. | 138 // This is a remote WebRTC media stream. |
162 WebRtcAudioDeviceImpl* audio_device = | 139 WebRtcAudioDeviceImpl* audio_device = |
163 GetPeerConnectionDependencyFactory()->GetWebRtcAudioDevice(); | 140 GetPeerConnectionDependencyFactory()->GetWebRtcAudioDevice(); |
| 141 DCHECK(audio_device); |
164 | 142 |
165 // Share the existing renderer if any, otherwise create a new one. | 143 // Share the existing renderer if any, otherwise create a new one. |
166 scoped_refptr<WebRtcAudioRenderer> renderer(audio_device->renderer()); | 144 scoped_refptr<WebRtcAudioRenderer> renderer(audio_device->renderer()); |
167 if (!renderer.get()) { | 145 if (renderer) { |
168 renderer = CreateRemoteAudioRenderer(web_stream, render_frame_id, | 146 DVLOG(1) << "Using existing WebRtcAudioRenderer for remote WebRTC track."; |
169 device_id, security_origin); | 147 } else { |
| 148 DVLOG(1) << "Creating WebRtcAudioRenderer for remote WebRTC track."; |
| 149 renderer = new WebRtcAudioRenderer( |
| 150 GetPeerConnectionDependencyFactory()->GetWebRtcSignalingThread(), |
| 151 web_stream, render_frame_id, GetSessionIdForWebRtcAudioRenderer(), |
| 152 device_id, security_origin); |
170 | 153 |
171 if (renderer.get() && !audio_device->SetAudioRenderer(renderer.get())) | 154 if (!audio_device->SetAudioRenderer(renderer.get())) |
172 renderer = NULL; | 155 return nullptr; |
173 } | 156 } |
174 | 157 |
175 return renderer.get() ? renderer->CreateSharedAudioRendererProxy(web_stream) | 158 return renderer->CreateSharedAudioRendererProxy(web_stream); |
176 : NULL; | |
177 } | 159 } |
178 | 160 |
179 } // namespace content | 161 } // namespace content |
OLD | NEW |