blob: d96ef27416720bf06f1e215d9cef63099a2a9e54 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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#ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_
6#define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/compiler_specific.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/scoped_vector.h"
16#include "base/memory/weak_ptr.h"
17#include "base/threading/non_thread_safe.h"
18#include "content/common/content_export.h"
Ben Murdoch116680a2014-07-20 18:25:52 -070019#include "content/public/renderer/render_frame_observer.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000021#include "content/renderer/media/media_stream_source.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010022#include "third_party/WebKit/public/platform/WebMediaStream.h"
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +010023#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
24#include "third_party/WebKit/public/platform/WebVector.h"
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +010025#include "third_party/WebKit/public/web/WebMediaDevicesRequest.h"
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010026#include "third_party/WebKit/public/web/WebUserMediaClient.h"
27#include "third_party/WebKit/public/web/WebUserMediaRequest.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000028#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029
30namespace content {
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010031class PeerConnectionDependencyFactory;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000032class MediaStreamDispatcher;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000033class MediaStreamVideoSource;
34class VideoCapturerDelegate;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000035
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010036// MediaStreamImpl is a delegate for the Media Stream GetUserMedia API.
37// It ties together WebKit and MediaStreamManager
38// (via MediaStreamDispatcher and MediaStreamDispatcherHost)
Torne (Richard Coles)58218062012-11-14 11:43:16 +000039// in the browser process. It must be created, called and destroyed on the
40// render thread.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000041class CONTENT_EXPORT MediaStreamImpl
Ben Murdoch116680a2014-07-20 18:25:52 -070042 : public RenderFrameObserver,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000043 NON_EXPORTED_BASE(public blink::WebUserMediaClient),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000044 public MediaStreamDispatcherEventHandler,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000045 NON_EXPORTED_BASE(public base::NonThreadSafe) {
46 public:
Ben Murdoch116680a2014-07-20 18:25:52 -070047 // |render_frame| and |dependency_factory| must outlive this instance.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000048 MediaStreamImpl(
Ben Murdoch116680a2014-07-20 18:25:52 -070049 RenderFrame* render_frame,
50 PeerConnectionDependencyFactory* dependency_factory,
51 scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000052 virtual ~MediaStreamImpl();
53
Ben Murdoch116680a2014-07-20 18:25:52 -070054 MediaStreamDispatcher* media_stream_dispatcher() const {
55 return media_stream_dispatcher_.get();
56 }
57
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000058 // blink::WebUserMediaClient implementation
Torne (Richard Coles)58218062012-11-14 11:43:16 +000059 virtual void requestUserMedia(
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010060 const blink::WebUserMediaRequest& user_media_request);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000061 virtual void cancelUserMediaRequest(
Torne (Richard Coles)cedac222014-06-03 10:58:34 +010062 const blink::WebUserMediaRequest& user_media_request);
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +010063 virtual void requestMediaDevices(
64 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE;
65 virtual void cancelMediaDevicesRequest(
66 const blink::WebMediaDevicesRequest& media_devices_request) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000067
68 // MediaStreamDispatcherEventHandler implementation.
69 virtual void OnStreamGenerated(
70 int request_id,
71 const std::string& label,
72 const StreamDeviceInfoArray& audio_array,
73 const StreamDeviceInfoArray& video_array) OVERRIDE;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000074 virtual void OnStreamGenerationFailed(
75 int request_id,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +010076 MediaStreamRequestResult result) OVERRIDE;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000077 virtual void OnDeviceStopped(const std::string& label,
78 const StreamDeviceInfo& device_info) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000079 virtual void OnDevicesEnumerated(
80 int request_id,
81 const StreamDeviceInfoArray& device_array) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000082 virtual void OnDeviceOpened(
83 int request_id,
84 const std::string& label,
85 const StreamDeviceInfo& device_info) OVERRIDE;
86 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
87
Ben Murdoch116680a2014-07-20 18:25:52 -070088 // RenderFrameObserver OVERRIDE
89 virtual void FrameWillClose() OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000090
91 protected:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000092 // Called when |source| has been stopped from JavaScript.
93 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +010094
Ben Murdoch0529e5d2014-04-24 10:50:13 +010095 // These methods are virtual for test purposes. A test can override them to
Torne (Richard Coles)58218062012-11-14 11:43:16 +000096 // test requesting local media streams. The function notifies WebKit that the
Ben Murdoch0529e5d2014-04-24 10:50:13 +010097 // |request| have completed.
98 virtual void GetUserMediaRequestSucceeded(
99 const blink::WebMediaStream& stream,
100 blink::WebUserMediaRequest* request_info);
101 virtual void GetUserMediaRequestFailed(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000102 blink::WebUserMediaRequest* request_info,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100103 MediaStreamRequestResult result);
104 virtual void GetUserMediaRequestTrackStartedFailed(
105 blink::WebUserMediaRequest* request_info,
106 MediaStreamRequestResult result,
107 const blink::WebString& result_name);
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100108 virtual void EnumerateDevicesSucceded(
109 blink::WebMediaDevicesRequest* request,
110 blink::WebVector<blink::WebMediaDeviceInfo>& devices);
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000111 // Creates a MediaStreamVideoSource object.
112 // This is virtual for test purposes.
113 virtual MediaStreamVideoSource* CreateVideoSource(
114 const StreamDeviceInfo& device,
115 const MediaStreamSource::SourceStoppedCallback& stop_callback);
116
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000117 private:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000118 // Class for storing information about a WebKit request to create a
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000119 // MediaStream.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000120 class UserMediaRequestInfo
121 : public base::SupportsWeakPtr<UserMediaRequestInfo> {
122 public:
123 typedef base::Callback<void(UserMediaRequestInfo* request_info,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100124 MediaStreamRequestResult result,
125 const blink::WebString& result_name)>
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000126 ResourcesReady;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000127
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000128 UserMediaRequestInfo(int request_id,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000129 const blink::WebUserMediaRequest& request,
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100130 bool enable_automatic_output_device_selection);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100131 ~UserMediaRequestInfo();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000132 int request_id;
133 // True if MediaStreamDispatcher has generated the stream, see
134 // OnStreamGenerated.
135 bool generated;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100136 const bool enable_automatic_output_device_selection;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000137 blink::WebMediaStream web_stream;
138 blink::WebUserMediaRequest request;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000139
Ben Murdocheffb81e2014-03-31 11:51:25 +0100140 void StartAudioTrack(const blink::WebMediaStreamTrack& track,
141 const blink::WebMediaConstraints& constraints);
142
143 blink::WebMediaStreamTrack CreateAndStartVideoTrack(
144 const blink::WebMediaStreamSource& source,
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100145 const blink::WebMediaConstraints& constraints);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000146
147 // Triggers |callback| when all sources used in this request have either
148 // successfully started, or a source has failed to start.
149 void CallbackOnTracksStarted(const ResourcesReady& callback);
150
151 bool IsSourceUsed(const blink::WebMediaStreamSource& source) const;
152 void RemoveSource(const blink::WebMediaStreamSource& source);
153
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +0100154 bool HasPendingSources() const;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000155
156 private:
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100157 void OnTrackStarted(
158 MediaStreamSource* source,
159 MediaStreamRequestResult result,
160 const blink::WebString& result_name);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000161 void CheckAllTracksStarted();
162
163 ResourcesReady ready_callback_;
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100164 MediaStreamRequestResult request_result_;
165 blink::WebString request_result_name_;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000166 // Sources used in this request.
167 std::vector<blink::WebMediaStreamSource> sources_;
168 std::vector<MediaStreamSource*> sources_waiting_for_callback_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000169 };
170 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
171
Ben Murdoch116680a2014-07-20 18:25:52 -0700172 typedef std::vector<blink::WebMediaStreamSource> LocalStreamSources;
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100173
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100174 struct MediaDevicesRequestInfo;
175 typedef ScopedVector<MediaDevicesRequestInfo> MediaDevicesRequests;
176
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100177 // Creates a WebKit representation of stream sources based on
178 // |devices| from the MediaStreamDispatcher.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000179 void InitializeSourceObject(
180 const StreamDeviceInfo& device,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000181 blink::WebMediaStreamSource::Type type,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000182 const blink::WebMediaConstraints& constraints,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000183 blink::WebMediaStreamSource* webkit_source);
184
185 void CreateVideoTracks(
186 const StreamDeviceInfoArray& devices,
187 const blink::WebMediaConstraints& constraints,
188 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
189 UserMediaRequestInfo* request);
190
191 void CreateAudioTracks(
192 const StreamDeviceInfoArray& devices,
193 const blink::WebMediaConstraints& constraints,
194 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
195 UserMediaRequestInfo* request);
196
197 // Callback function triggered when all native versions of the
198 // underlying media sources and tracks have been created and started.
199 void OnCreateNativeTracksCompleted(
200 UserMediaRequestInfo* request,
Torne (Richard Coles)6e8cce62014-08-19 13:00:08 +0100201 MediaStreamRequestResult result,
202 const blink::WebString& result_name);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100203
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +0100204 void OnStreamGeneratedForCancelledRequest(
205 const StreamDeviceInfoArray& audio_array,
206 const StreamDeviceInfoArray& video_array);
207
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000208 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id);
209 UserMediaRequestInfo* FindUserMediaRequestInfo(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000210 const blink::WebUserMediaRequest& request);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000211 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request);
Torne (Richard Coles)5f1c9432014-08-12 13:47:38 +0100212 void DeleteAllUserMediaRequests();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000213
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100214 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(int request_id);
215 MediaDevicesRequestInfo* FindMediaDevicesRequestInfo(
216 const blink::WebMediaDevicesRequest& request);
Ben Murdoch116680a2014-07-20 18:25:52 -0700217 void CancelAndDeleteMediaDevicesRequest(MediaDevicesRequestInfo* request);
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100218
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100219 // Returns the source that use a device with |device.session_id|
220 // and |device.device.id|. NULL if such source doesn't exist.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000221 const blink::WebMediaStreamSource* FindLocalSource(
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100222 const StreamDeviceInfo& device) const;
223
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000224 void StopLocalSource(const blink::WebMediaStreamSource& source,
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100225 bool notify_dispatcher);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100226
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100227 // Weak ref to a PeerConnectionDependencyFactory, owned by the RenderThread.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000228 // It's valid for the lifetime of RenderThread.
Torne (Richard Coles)cedac222014-06-03 10:58:34 +0100229 // TODO(xians): Remove this dependency once audio do not need it for local
230 // audio.
Ben Murdoch116680a2014-07-20 18:25:52 -0700231 PeerConnectionDependencyFactory* const dependency_factory_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000232
Ben Murdoch116680a2014-07-20 18:25:52 -0700233 // MediaStreamImpl owns MediaStreamDispatcher instead of RenderFrameImpl
234 // (or RenderFrameObserver) to ensure tear-down occurs in the right order.
235 const scoped_ptr<MediaStreamDispatcher> media_stream_dispatcher_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000236
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100237 LocalStreamSources local_sources_;
238
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100239 UserMediaRequests user_media_requests_;
240
Torne (Richard Coles)46d4c2b2014-06-09 12:00:27 +0100241 // Requests to enumerate media devices.
242 MediaDevicesRequests media_devices_requests_;
243
Ben Murdoch116680a2014-07-20 18:25:52 -0700244 // Note: This member must be the last to ensure all outstanding weak pointers
245 // are invalidated first.
246 base::WeakPtrFactory<MediaStreamImpl> weak_factory_;
247
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000248 DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
249};
250
251} // namespace content
252
253#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_