Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/renderer/media/media_stream_impl.h" |
| 6 | |
| 7 | #include <utility> |
| 8 | |
| 9 | #include "base/logging.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 10 | #include "base/strings/string_number_conversions.h" |
| 11 | #include "base/strings/stringprintf.h" |
| 12 | #include "base/strings/utf_string_conversions.h" |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 13 | #include "content/renderer/media/media_stream_audio_renderer.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 14 | #include "content/renderer/media/media_stream_dependency_factory.h" |
| 15 | #include "content/renderer/media/media_stream_dispatcher.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 16 | #include "content/renderer/media/media_stream_extra_data.h" |
| 17 | #include "content/renderer/media/media_stream_source_extra_data.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 18 | #include "content/renderer/media/rtc_video_renderer.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 19 | #include "content/renderer/media/webrtc_audio_capturer.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 20 | #include "content/renderer/media/webrtc_audio_renderer.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 21 | #include "content/renderer/media/webrtc_local_audio_renderer.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 22 | #include "content/renderer/media/webrtc_uma_histograms.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 23 | #include "third_party/WebKit/public/platform/WebMediaConstraints.h" |
| 24 | #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
| 25 | #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
| 26 | #include "third_party/WebKit/public/platform/WebVector.h" |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 27 | #include "third_party/WebKit/public/web/WebDocument.h" |
| 28 | #include "third_party/WebKit/public/web/WebFrame.h" |
| 29 | #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 30 | |
| 31 | namespace content { |
| 32 | namespace { |
| 33 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 34 | std::string GetStreamConstraint( |
| 35 | const WebKit::WebMediaConstraints& constraints, const std::string& key, |
| 36 | bool is_mandatory) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 37 | if (constraints.isNull()) |
| 38 | return std::string(); |
| 39 | |
| 40 | WebKit::WebString value; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 41 | if (is_mandatory) { |
| 42 | constraints.getMandatoryConstraintValue(UTF8ToUTF16(key), value); |
| 43 | } else { |
| 44 | constraints.getOptionalConstraintValue(UTF8ToUTF16(key), value); |
| 45 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 46 | return UTF16ToUTF8(value); |
| 47 | } |
| 48 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 49 | void UpdateRequestOptions( |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 50 | const WebKit::WebUserMediaRequest& user_media_request, |
| 51 | StreamOptions* options) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 52 | if (options->audio_type != content::MEDIA_NO_SERVICE) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 53 | std::string audio_stream_source = GetStreamConstraint( |
| 54 | user_media_request.audioConstraints(), kMediaStreamSource, true); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 55 | if (audio_stream_source == kMediaStreamSourceTab) { |
| 56 | options->audio_type = content::MEDIA_TAB_AUDIO_CAPTURE; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 57 | options->audio_device_id = GetStreamConstraint( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 58 | user_media_request.audioConstraints(), |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 59 | kMediaStreamSourceId, true); |
Torne (Richard Coles) | a36e592 | 2013-08-05 13:57:33 +0100 | [diff] [blame] | 60 | } else if (audio_stream_source == kMediaStreamSourceSystem) { |
| 61 | options->audio_type = content::MEDIA_SYSTEM_AUDIO_CAPTURE; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 62 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 63 | } |
| 64 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 65 | if (options->video_type != content::MEDIA_NO_SERVICE) { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 66 | std::string video_stream_source = GetStreamConstraint( |
| 67 | user_media_request.videoConstraints(), kMediaStreamSource, true); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 68 | if (video_stream_source == kMediaStreamSourceTab) { |
| 69 | options->video_type = content::MEDIA_TAB_VIDEO_CAPTURE; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 70 | options->video_device_id = GetStreamConstraint( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 71 | user_media_request.videoConstraints(), |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 72 | kMediaStreamSourceId, true); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 73 | } else if (video_stream_source == kMediaStreamSourceScreen) { |
| 74 | options->video_type = content::MEDIA_SCREEN_VIDEO_CAPTURE; |
| 75 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 76 | } |
| 77 | } |
| 78 | |
| 79 | static int g_next_request_id = 0; |
| 80 | |
| 81 | // Creates a WebKit representation of a stream sources based on |
| 82 | // |devices| from the MediaStreamDispatcher. |
| 83 | void CreateWebKitSourceVector( |
| 84 | const std::string& label, |
| 85 | const StreamDeviceInfoArray& devices, |
| 86 | WebKit::WebMediaStreamSource::Type type, |
| 87 | WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { |
| 88 | CHECK_EQ(devices.size(), webkit_sources.size()); |
| 89 | for (size_t i = 0; i < devices.size(); ++i) { |
| 90 | const char* track_type = |
| 91 | (type == WebKit::WebMediaStreamSource::TypeAudio) ? "a" : "v"; |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 92 | std::string source_id = base::StringPrintf("%s%s%u", label.c_str(), |
| 93 | track_type, |
| 94 | static_cast<unsigned int>(i)); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 95 | webkit_sources[i].initialize( |
| 96 | UTF8ToUTF16(source_id), |
| 97 | type, |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 98 | UTF8ToUTF16(devices[i].device.name)); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 99 | webkit_sources[i].setExtraData( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 100 | new content::MediaStreamSourceExtraData(devices[i], webkit_sources[i])); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 101 | webkit_sources[i].setDeviceId(UTF8ToUTF16( |
| 102 | base::IntToString(devices[i].session_id))); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 103 | } |
| 104 | } |
| 105 | |
| 106 | webrtc::MediaStreamInterface* GetNativeMediaStream( |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 107 | const WebKit::WebMediaStream& web_stream) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 108 | content::MediaStreamExtraData* extra_data = |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 109 | static_cast<content::MediaStreamExtraData*>(web_stream.extraData()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 110 | if (!extra_data) |
| 111 | return NULL; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 112 | return extra_data->stream().get(); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | } // namespace |
| 116 | |
| 117 | MediaStreamImpl::MediaStreamImpl( |
| 118 | RenderView* render_view, |
| 119 | MediaStreamDispatcher* media_stream_dispatcher, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 120 | MediaStreamDependencyFactory* dependency_factory) |
| 121 | : RenderViewObserver(render_view), |
| 122 | dependency_factory_(dependency_factory), |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 123 | media_stream_dispatcher_(media_stream_dispatcher) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | MediaStreamImpl::~MediaStreamImpl() { |
| 127 | } |
| 128 | |
| 129 | void MediaStreamImpl::OnLocalMediaStreamStop( |
| 130 | const std::string& label) { |
| 131 | DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop(" << label << ")"; |
| 132 | |
| 133 | UserMediaRequestInfo* user_media_request = FindUserMediaRequestInfo(label); |
| 134 | if (user_media_request) { |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 135 | StopLocalAudioTrack(user_media_request->web_stream); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 136 | media_stream_dispatcher_->StopStream(label); |
| 137 | DeleteUserMediaRequestInfo(user_media_request); |
| 138 | } else { |
| 139 | DVLOG(1) << "MediaStreamImpl::OnLocalMediaStreamStop: the stream has " |
| 140 | << "already been stopped."; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | void MediaStreamImpl::requestUserMedia( |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 145 | const WebKit::WebUserMediaRequest& user_media_request) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 146 | // Save histogram data so we can see how much GetUserMedia is used. |
| 147 | // The histogram counts the number of calls to the JS API |
| 148 | // webGetUserMedia. |
| 149 | UpdateWebRTCMethodCount(WEBKIT_GET_USER_MEDIA); |
| 150 | DCHECK(CalledOnValidThread()); |
| 151 | int request_id = g_next_request_id++; |
| 152 | StreamOptions options(MEDIA_NO_SERVICE, MEDIA_NO_SERVICE); |
| 153 | WebKit::WebFrame* frame = NULL; |
| 154 | GURL security_origin; |
| 155 | |
| 156 | // |user_media_request| can't be mocked. So in order to test at all we check |
| 157 | // if it isNull. |
| 158 | if (user_media_request.isNull()) { |
| 159 | // We are in a test. |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 160 | options.audio_type = MEDIA_DEVICE_AUDIO_CAPTURE; |
| 161 | options.video_type = MEDIA_DEVICE_VIDEO_CAPTURE; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 162 | } else { |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 163 | if (user_media_request.audio()) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 164 | options.audio_type = MEDIA_DEVICE_AUDIO_CAPTURE; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 165 | options.audio_device_id = GetStreamConstraint( |
| 166 | user_media_request.audioConstraints(), |
| 167 | kMediaStreamSourceInfoId, false); |
| 168 | } |
| 169 | if (user_media_request.video()) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 170 | options.video_type = MEDIA_DEVICE_VIDEO_CAPTURE; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 171 | options.video_device_id = GetStreamConstraint( |
| 172 | user_media_request.videoConstraints(), |
| 173 | kMediaStreamSourceInfoId, false); |
| 174 | } |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 175 | |
| 176 | security_origin = GURL(user_media_request.securityOrigin().toString()); |
| 177 | // Get the WebFrame that requested a MediaStream. |
| 178 | // The frame is needed to tell the MediaStreamDispatcher when a stream goes |
| 179 | // out of scope. |
| 180 | frame = user_media_request.ownerDocument().frame(); |
| 181 | DCHECK(frame); |
| 182 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 183 | UpdateRequestOptions(user_media_request, &options); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | DVLOG(1) << "MediaStreamImpl::requestUserMedia(" << request_id << ", [ " |
| 187 | << "audio=" << (options.audio_type) |
| 188 | << ", video=" << (options.video_type) << " ], " |
| 189 | << security_origin.spec() << ")"; |
| 190 | |
| 191 | user_media_requests_.push_back( |
| 192 | new UserMediaRequestInfo(request_id, frame, user_media_request)); |
| 193 | |
| 194 | media_stream_dispatcher_->GenerateStream( |
| 195 | request_id, |
| 196 | AsWeakPtr(), |
| 197 | options, |
| 198 | security_origin); |
| 199 | } |
| 200 | |
| 201 | void MediaStreamImpl::cancelUserMediaRequest( |
| 202 | const WebKit::WebUserMediaRequest& user_media_request) { |
| 203 | DCHECK(CalledOnValidThread()); |
| 204 | UserMediaRequestInfo* request = FindUserMediaRequestInfo(user_media_request); |
| 205 | if (request) { |
| 206 | // We can't abort the stream generation process. |
| 207 | // Instead, erase the request. Once the stream is generated we will stop the |
| 208 | // stream if the request does not exist. |
| 209 | DeleteUserMediaRequestInfo(request); |
| 210 | } |
| 211 | } |
| 212 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 213 | WebKit::WebMediaStream MediaStreamImpl::GetMediaStream( |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 214 | const GURL& url) { |
| 215 | return WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url); |
| 216 | } |
| 217 | |
| 218 | bool MediaStreamImpl::IsMediaStream(const GURL& url) { |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 219 | WebKit::WebMediaStream web_stream( |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 220 | WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); |
| 221 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 222 | if (web_stream.isNull() || !web_stream.extraData()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 223 | return false; // This is not a valid stream. |
| 224 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 225 | webrtc::MediaStreamInterface* stream = GetNativeMediaStream(web_stream); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 226 | return (stream && |
| 227 | (!stream->GetVideoTracks().empty() || !stream->GetAudioTracks().empty())); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 228 | } |
| 229 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 230 | scoped_refptr<VideoFrameProvider> |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 231 | MediaStreamImpl::GetVideoFrameProvider( |
| 232 | const GURL& url, |
| 233 | const base::Closure& error_cb, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 234 | const VideoFrameProvider::RepaintCB& repaint_cb) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 235 | DCHECK(CalledOnValidThread()); |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 236 | WebKit::WebMediaStream web_stream(GetMediaStream(url)); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 237 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 238 | if (web_stream.isNull() || !web_stream.extraData()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 239 | return NULL; // This is not a valid stream. |
| 240 | |
| 241 | DVLOG(1) << "MediaStreamImpl::GetVideoFrameProvider stream:" |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 242 | << UTF16ToUTF8(web_stream.id()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 243 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 244 | webrtc::MediaStreamInterface* stream = GetNativeMediaStream(web_stream); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 245 | if (stream) |
| 246 | return CreateVideoFrameProvider(stream, error_cb, repaint_cb); |
| 247 | NOTREACHED(); |
| 248 | return NULL; |
| 249 | } |
| 250 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 251 | scoped_refptr<MediaStreamAudioRenderer> |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 252 | MediaStreamImpl::GetAudioRenderer(const GURL& url) { |
| 253 | DCHECK(CalledOnValidThread()); |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 254 | WebKit::WebMediaStream web_stream(GetMediaStream(url)); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 255 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 256 | if (web_stream.isNull() || !web_stream.extraData()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 257 | return NULL; // This is not a valid stream. |
| 258 | |
| 259 | DVLOG(1) << "MediaStreamImpl::GetAudioRenderer stream:" |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 260 | << UTF16ToUTF8(web_stream.id()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 261 | |
| 262 | MediaStreamExtraData* extra_data = |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 263 | static_cast<MediaStreamExtraData*>(web_stream.extraData()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 264 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 265 | if (extra_data->is_local()) { |
| 266 | // Create the local audio renderer if the stream contains audio tracks. |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 267 | return CreateLocalAudioRenderer(extra_data->stream().get()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 268 | } |
| 269 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 270 | webrtc::MediaStreamInterface* stream = extra_data->stream().get(); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 271 | if (!stream || stream->GetAudioTracks().empty()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 272 | return NULL; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 273 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 274 | // This is a remote media stream. |
| 275 | WebRtcAudioDeviceImpl* audio_device = |
| 276 | dependency_factory_->GetWebRtcAudioDevice(); |
| 277 | |
| 278 | // Share the existing renderer if any, otherwise create a new one. |
| 279 | scoped_refptr<WebRtcAudioRenderer> renderer(audio_device->renderer()); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 280 | if (!renderer.get()) { |
| 281 | renderer = CreateRemoteAudioRenderer(extra_data->stream().get()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 282 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 283 | if (renderer.get() && !audio_device->SetAudioRenderer(renderer.get())) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 284 | renderer = NULL; |
| 285 | } |
| 286 | return renderer; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 287 | } |
| 288 | |
| 289 | // Callback from MediaStreamDispatcher. |
| 290 | // The requested stream have been generated by the MediaStreamDispatcher. |
| 291 | void MediaStreamImpl::OnStreamGenerated( |
| 292 | int request_id, |
| 293 | const std::string& label, |
| 294 | const StreamDeviceInfoArray& audio_array, |
| 295 | const StreamDeviceInfoArray& video_array) { |
| 296 | DCHECK(CalledOnValidThread()); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 297 | DVLOG(1) << "MediaStreamImpl::OnStreamGenerated stream:" << label; |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 298 | |
| 299 | UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); |
| 300 | if (!request_info) { |
| 301 | // This can happen if the request is canceled or the frame reloads while |
| 302 | // MediaStreamDispatcher is processing the request. |
| 303 | // We need to tell the dispatcher to stop the stream. |
| 304 | media_stream_dispatcher_->StopStream(label); |
| 305 | DVLOG(1) << "Request ID not found"; |
| 306 | return; |
| 307 | } |
| 308 | request_info->generated = true; |
| 309 | |
| 310 | WebKit::WebVector<WebKit::WebMediaStreamSource> audio_source_vector( |
| 311 | audio_array.size()); |
| 312 | CreateWebKitSourceVector(label, audio_array, |
| 313 | WebKit::WebMediaStreamSource::TypeAudio, |
| 314 | audio_source_vector); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 315 | request_info->audio_sources.assign(audio_source_vector); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 316 | WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector( |
| 317 | video_array.size()); |
| 318 | CreateWebKitSourceVector(label, video_array, |
| 319 | WebKit::WebMediaStreamSource::TypeVideo, |
| 320 | video_source_vector); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 321 | request_info->video_sources.assign(video_source_vector); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 322 | |
| 323 | WebKit::WebUserMediaRequest* request = &(request_info->request); |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 324 | WebKit::WebString webkit_id = UTF8ToUTF16(label); |
| 325 | WebKit::WebMediaStream* web_stream = &(request_info->web_stream); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 326 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 327 | WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_track_vector( |
| 328 | audio_array.size()); |
| 329 | for (size_t i = 0; i < audio_track_vector.size(); ++i) { |
| 330 | audio_track_vector[i].initialize(audio_source_vector[i].id(), |
| 331 | audio_source_vector[i]); |
| 332 | } |
| 333 | |
| 334 | WebKit::WebVector<WebKit::WebMediaStreamTrack> video_track_vector( |
| 335 | video_array.size()); |
| 336 | for (size_t i = 0; i < video_track_vector.size(); ++i) { |
| 337 | video_track_vector[i].initialize(video_source_vector[i].id(), |
| 338 | video_source_vector[i]); |
| 339 | } |
| 340 | |
| 341 | web_stream->initialize(webkit_id, audio_track_vector, |
| 342 | video_track_vector); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 343 | |
| 344 | // WebUserMediaRequest don't have an implementation in unit tests. |
| 345 | // Therefore we need to check for isNull here. |
| 346 | WebKit::WebMediaConstraints audio_constraints = request->isNull() ? |
| 347 | WebKit::WebMediaConstraints() : request->audioConstraints(); |
| 348 | WebKit::WebMediaConstraints video_constraints = request->isNull() ? |
| 349 | WebKit::WebMediaConstraints() : request->videoConstraints(); |
| 350 | |
| 351 | dependency_factory_->CreateNativeMediaSources( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 352 | RenderViewObserver::routing_id(), |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 353 | audio_constraints, video_constraints, web_stream, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 354 | base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr())); |
| 355 | } |
| 356 | |
| 357 | // Callback from MediaStreamDispatcher. |
| 358 | // The requested stream failed to be generated. |
| 359 | void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { |
| 360 | DCHECK(CalledOnValidThread()); |
| 361 | DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" |
| 362 | << request_id << ")"; |
| 363 | UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(request_id); |
| 364 | if (!request_info) { |
| 365 | // This can happen if the request is canceled or the frame reloads while |
| 366 | // MediaStreamDispatcher is processing the request. |
| 367 | DVLOG(1) << "Request ID not found"; |
| 368 | return; |
| 369 | } |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 370 | CompleteGetUserMediaRequest(request_info->web_stream, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 371 | &request_info->request, |
| 372 | false); |
| 373 | DeleteUserMediaRequestInfo(request_info); |
| 374 | } |
| 375 | |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 376 | // Callback from MediaStreamDependencyFactory when the sources in |web_stream| |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 377 | // have been generated. |
| 378 | void MediaStreamImpl::OnCreateNativeSourcesComplete( |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 379 | WebKit::WebMediaStream* web_stream, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 380 | bool request_succeeded) { |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 381 | UserMediaRequestInfo* request_info = FindUserMediaRequestInfo(web_stream); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 382 | if (!request_info) { |
| 383 | // This can happen if the request is canceled or the frame reloads while |
| 384 | // MediaStreamDependencyFactory is creating the sources. |
| 385 | DVLOG(1) << "Request ID not found"; |
| 386 | return; |
| 387 | } |
| 388 | |
| 389 | // Create a native representation of the stream. |
| 390 | if (request_succeeded) { |
| 391 | dependency_factory_->CreateNativeLocalMediaStream( |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 392 | web_stream, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 393 | base::Bind(&MediaStreamImpl::OnLocalMediaStreamStop, AsWeakPtr())); |
| 394 | } |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 395 | CompleteGetUserMediaRequest(request_info->web_stream, &request_info->request, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 396 | request_succeeded); |
| 397 | if (!request_succeeded) { |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 398 | OnLocalMediaStreamStop(UTF16ToUTF8(web_stream->id())); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 399 | } |
| 400 | } |
| 401 | |
| 402 | void MediaStreamImpl::OnDevicesEnumerated( |
| 403 | int request_id, |
| 404 | const StreamDeviceInfoArray& device_array) { |
| 405 | DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerated(" |
| 406 | << request_id << ")"; |
| 407 | NOTIMPLEMENTED(); |
| 408 | } |
| 409 | |
| 410 | void MediaStreamImpl::OnDevicesEnumerationFailed(int request_id) { |
| 411 | DVLOG(1) << "MediaStreamImpl::OnDevicesEnumerationFailed(" |
| 412 | << request_id << ")"; |
| 413 | NOTIMPLEMENTED(); |
| 414 | } |
| 415 | |
| 416 | void MediaStreamImpl::OnDeviceOpened( |
| 417 | int request_id, |
| 418 | const std::string& label, |
| 419 | const StreamDeviceInfo& video_device) { |
| 420 | DVLOG(1) << "MediaStreamImpl::OnDeviceOpened(" |
| 421 | << request_id << ", " << label << ")"; |
| 422 | NOTIMPLEMENTED(); |
| 423 | } |
| 424 | |
| 425 | void MediaStreamImpl::OnDeviceOpenFailed(int request_id) { |
| 426 | DVLOG(1) << "MediaStreamImpl::VideoDeviceOpenFailed(" |
| 427 | << request_id << ")"; |
| 428 | NOTIMPLEMENTED(); |
| 429 | } |
| 430 | |
| 431 | void MediaStreamImpl::CompleteGetUserMediaRequest( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 432 | const WebKit::WebMediaStream& stream, |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 433 | WebKit::WebUserMediaRequest* request_info, |
| 434 | bool request_succeeded) { |
| 435 | if (request_succeeded) { |
| 436 | request_info->requestSucceeded(stream); |
| 437 | } else { |
| 438 | request_info->requestFailed(); |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | MediaStreamImpl::UserMediaRequestInfo* |
| 443 | MediaStreamImpl::FindUserMediaRequestInfo(int request_id) { |
| 444 | UserMediaRequests::iterator it = user_media_requests_.begin(); |
| 445 | for (; it != user_media_requests_.end(); ++it) { |
| 446 | if ((*it)->request_id == request_id) |
| 447 | return (*it); |
| 448 | } |
| 449 | return NULL; |
| 450 | } |
| 451 | |
| 452 | MediaStreamImpl::UserMediaRequestInfo* |
| 453 | MediaStreamImpl::FindUserMediaRequestInfo( |
| 454 | const WebKit::WebUserMediaRequest& request) { |
| 455 | UserMediaRequests::iterator it = user_media_requests_.begin(); |
| 456 | for (; it != user_media_requests_.end(); ++it) { |
| 457 | if ((*it)->request == request) |
| 458 | return (*it); |
| 459 | } |
| 460 | return NULL; |
| 461 | } |
| 462 | |
| 463 | MediaStreamImpl::UserMediaRequestInfo* |
| 464 | MediaStreamImpl::FindUserMediaRequestInfo(const std::string& label) { |
| 465 | UserMediaRequests::iterator it = user_media_requests_.begin(); |
| 466 | for (; it != user_media_requests_.end(); ++it) { |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 467 | if ((*it)->generated && (*it)->web_stream.id() == UTF8ToUTF16(label)) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 468 | return (*it); |
| 469 | } |
| 470 | return NULL; |
| 471 | } |
| 472 | |
| 473 | MediaStreamImpl::UserMediaRequestInfo* |
| 474 | MediaStreamImpl::FindUserMediaRequestInfo( |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 475 | WebKit::WebMediaStream* web_stream) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 476 | UserMediaRequests::iterator it = user_media_requests_.begin(); |
| 477 | for (; it != user_media_requests_.end(); ++it) { |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 478 | if (&((*it)->web_stream) == web_stream) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 479 | return (*it); |
| 480 | } |
| 481 | return NULL; |
| 482 | } |
| 483 | |
| 484 | void MediaStreamImpl::DeleteUserMediaRequestInfo( |
| 485 | UserMediaRequestInfo* request) { |
| 486 | UserMediaRequests::iterator it = user_media_requests_.begin(); |
| 487 | for (; it != user_media_requests_.end(); ++it) { |
| 488 | if ((*it) == request) { |
| 489 | user_media_requests_.erase(it); |
| 490 | return; |
| 491 | } |
| 492 | } |
| 493 | NOTREACHED(); |
| 494 | } |
| 495 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 496 | void MediaStreamImpl::FrameDetached(WebKit::WebFrame* frame) { |
| 497 | // Do same thing as FrameWillClose. |
| 498 | FrameWillClose(frame); |
| 499 | } |
| 500 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 501 | void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) { |
| 502 | // Loop through all UserMediaRequests and find the requests that belong to the |
| 503 | // frame that is being closed. |
| 504 | UserMediaRequests::iterator request_it = user_media_requests_.begin(); |
| 505 | |
| 506 | while (request_it != user_media_requests_.end()) { |
| 507 | if ((*request_it)->frame == frame) { |
| 508 | DVLOG(1) << "MediaStreamImpl::FrameWillClose: " |
| 509 | << "Cancel user media request " << (*request_it)->request_id; |
| 510 | // If the request is generated, it means that the MediaStreamDispatcher |
| 511 | // has generated a stream for us and we need to let the |
| 512 | // MediaStreamDispatcher know that the stream is no longer wanted. |
| 513 | // If not, we cancel the request and delete the request object. |
| 514 | if ((*request_it)->generated) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 515 | // Stop the local audio track before closing the device in the browser. |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 516 | StopLocalAudioTrack((*request_it)->web_stream); |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 517 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 518 | media_stream_dispatcher_->StopStream( |
Ben Murdoch | bbcdd45 | 2013-07-25 10:06:34 +0100 | [diff] [blame] | 519 | UTF16ToUTF8((*request_it)->web_stream.id())); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 520 | } else { |
| 521 | media_stream_dispatcher_->CancelGenerateStream( |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 522 | (*request_it)->request_id, AsWeakPtr()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 523 | } |
| 524 | request_it = user_media_requests_.erase(request_it); |
| 525 | } else { |
| 526 | ++request_it; |
| 527 | } |
| 528 | } |
| 529 | } |
| 530 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 531 | scoped_refptr<VideoFrameProvider> |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 532 | MediaStreamImpl::CreateVideoFrameProvider( |
| 533 | webrtc::MediaStreamInterface* stream, |
| 534 | const base::Closure& error_cb, |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 535 | const VideoFrameProvider::RepaintCB& repaint_cb) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 536 | if (stream->GetVideoTracks().empty()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 537 | return NULL; |
| 538 | |
| 539 | DVLOG(1) << "MediaStreamImpl::CreateRemoteVideoFrameProvider label:" |
| 540 | << stream->label(); |
| 541 | |
| 542 | return new RTCVideoRenderer( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 543 | stream->GetVideoTracks()[0], |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 544 | error_cb, |
| 545 | repaint_cb); |
| 546 | } |
| 547 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 548 | scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer( |
| 549 | webrtc::MediaStreamInterface* stream) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 550 | if (stream->GetAudioTracks().empty()) |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 551 | return NULL; |
| 552 | |
| 553 | DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:" |
| 554 | << stream->label(); |
| 555 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 556 | return new WebRtcAudioRenderer(RenderViewObserver::routing_id()); |
| 557 | } |
| 558 | |
| 559 | scoped_refptr<WebRtcLocalAudioRenderer> |
| 560 | MediaStreamImpl::CreateLocalAudioRenderer( |
| 561 | webrtc::MediaStreamInterface* stream) { |
| 562 | if (stream->GetAudioTracks().empty()) |
| 563 | return NULL; |
| 564 | |
| 565 | DVLOG(1) << "MediaStreamImpl::CreateLocalAudioRenderer label:" |
| 566 | << stream->label(); |
| 567 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 568 | webrtc::AudioTrackVector audio_tracks = stream->GetAudioTracks(); |
| 569 | DCHECK_EQ(audio_tracks.size(), 1u); |
| 570 | webrtc::AudioTrackInterface* audio_track = audio_tracks[0]; |
| 571 | DVLOG(1) << "audio_track.kind : " << audio_track->kind() |
| 572 | << "audio_track.id : " << audio_track->id() |
| 573 | << "audio_track.enabled: " << audio_track->enabled(); |
| 574 | |
| 575 | // Create a new WebRtcLocalAudioRenderer instance and connect it to the |
| 576 | // existing WebRtcAudioCapturer so that the renderer can use it as source. |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 577 | return new WebRtcLocalAudioRenderer( |
| 578 | static_cast<WebRtcLocalAudioTrack*>(audio_track), |
| 579 | RenderViewObserver::routing_id()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 580 | } |
| 581 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 582 | void MediaStreamImpl::StopLocalAudioTrack( |
| 583 | const WebKit::WebMediaStream& web_stream) { |
| 584 | MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>( |
| 585 | web_stream.extraData()); |
| 586 | if (extra_data && extra_data->is_local() && extra_data->stream().get() && |
| 587 | !extra_data->stream()->GetAudioTracks().empty()) { |
| 588 | webrtc::AudioTrackVector audio_tracks = |
| 589 | extra_data->stream()->GetAudioTracks(); |
| 590 | for (size_t i = 0; i < audio_tracks.size(); ++i) { |
| 591 | WebRtcLocalAudioTrack* audio_track = static_cast<WebRtcLocalAudioTrack*>( |
| 592 | audio_tracks[i].get()); |
| 593 | // Remove the WebRtcAudioDevice as the sink to the local audio track. |
| 594 | audio_track->RemoveSink(dependency_factory_->GetWebRtcAudioDevice()); |
| 595 | // Stop the audio track. This will unhook the audio track from the |
| 596 | // capturer and will shutdown the source of the capturer if it is the |
| 597 | // last audio track connecting to the capturer. |
| 598 | audio_track->Stop(); |
| 599 | } |
| 600 | } |
| 601 | } |
| 602 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 603 | MediaStreamSourceExtraData::MediaStreamSourceExtraData( |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 604 | const StreamDeviceInfo& device_info, |
| 605 | const WebKit::WebMediaStreamSource& webkit_source) |
| 606 | : device_info_(device_info), |
| 607 | webkit_source_(webkit_source) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 608 | } |
| 609 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 610 | MediaStreamSourceExtraData::MediaStreamSourceExtraData( |
| 611 | media::AudioCapturerSource* source) |
| 612 | : audio_source_(source) { |
| 613 | } |
| 614 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 615 | MediaStreamSourceExtraData::~MediaStreamSourceExtraData() {} |
| 616 | |
| 617 | MediaStreamExtraData::MediaStreamExtraData( |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 618 | webrtc::MediaStreamInterface* stream, bool is_local) |
| 619 | : stream_(stream), |
| 620 | is_local_(is_local) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 621 | } |
| 622 | |
| 623 | MediaStreamExtraData::~MediaStreamExtraData() { |
| 624 | } |
| 625 | |
| 626 | void MediaStreamExtraData::SetLocalStreamStopCallback( |
| 627 | const StreamStopCallback& stop_callback) { |
| 628 | stream_stop_callback_ = stop_callback; |
| 629 | } |
| 630 | |
| 631 | void MediaStreamExtraData::OnLocalStreamStop() { |
| 632 | if (!stream_stop_callback_.is_null()) |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 633 | stream_stop_callback_.Run(stream_->label()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 634 | } |
| 635 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 636 | MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo() |
| 637 | : request_id(0), generated(false), frame(NULL), request() { |
| 638 | } |
| 639 | |
| 640 | MediaStreamImpl::UserMediaRequestInfo::UserMediaRequestInfo( |
| 641 | int request_id, |
| 642 | WebKit::WebFrame* frame, |
| 643 | const WebKit::WebUserMediaRequest& request) |
| 644 | : request_id(request_id), generated(false), frame(frame), |
| 645 | request(request) { |
| 646 | } |
| 647 | |
| 648 | MediaStreamImpl::UserMediaRequestInfo::~UserMediaRequestInfo() { |
| 649 | // Release the extra data field of all sources created by |
| 650 | // MediaStreamImpl for this request. This breaks the circular reference to |
| 651 | // WebKit::MediaStreamSource. |
| 652 | // TODO(tommyw): Remove this once WebKit::MediaStreamSource::Owner has been |
| 653 | // implemented to fully avoid a circular dependency. |
| 654 | for (size_t i = 0; i < audio_sources.size(); ++i) { |
| 655 | audio_sources[i].setReadyState( |
| 656 | WebKit::WebMediaStreamSource::ReadyStateEnded); |
| 657 | audio_sources[i].setExtraData(NULL); |
| 658 | } |
| 659 | |
| 660 | for (size_t i = 0; i < video_sources.size(); ++i) { |
| 661 | video_sources[i].setReadyState( |
| 662 | WebKit::WebMediaStreamSource::ReadyStateEnded); |
| 663 | video_sources[i].setExtraData(NULL); |
| 664 | } |
| 665 | } |
| 666 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 667 | } // namespace content |