blob: af9e13506b5430504256f8eff192662062338f4b [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"
19#include "content/public/renderer/render_view_observer.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010020#include "content/renderer/media/media_stream_client.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000021#include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000022#include "content/renderer/media/media_stream_source.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010023#include "third_party/WebKit/public/platform/WebMediaStream.h"
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +010024#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
25#include "third_party/WebKit/public/platform/WebVector.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 {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010031class MediaStreamAudioRenderer;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000032class MediaStreamDependencyFactory;
33class MediaStreamDispatcher;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000034class MediaStreamVideoSource;
35class VideoCapturerDelegate;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036class WebRtcAudioRenderer;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000037class WebRtcLocalAudioRenderer;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000038
39// MediaStreamImpl is a delegate for the Media Stream API messages used by
40// WebKit. It ties together WebKit, native PeerConnection in libjingle and
41// MediaStreamManager (via MediaStreamDispatcher and MediaStreamDispatcherHost)
42// in the browser process. It must be created, called and destroyed on the
43// render thread.
44// MediaStreamImpl have weak pointers to a MediaStreamDispatcher.
45class CONTENT_EXPORT MediaStreamImpl
46 : public RenderViewObserver,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000047 NON_EXPORTED_BASE(public blink::WebUserMediaClient),
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010048 NON_EXPORTED_BASE(public MediaStreamClient),
Torne (Richard Coles)58218062012-11-14 11:43:16 +000049 public MediaStreamDispatcherEventHandler,
50 public base::SupportsWeakPtr<MediaStreamImpl>,
51 NON_EXPORTED_BASE(public base::NonThreadSafe) {
52 public:
53 MediaStreamImpl(
54 RenderView* render_view,
55 MediaStreamDispatcher* media_stream_dispatcher,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000056 MediaStreamDependencyFactory* dependency_factory);
57 virtual ~MediaStreamImpl();
58
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000059 // blink::WebUserMediaClient implementation
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060 virtual void requestUserMedia(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000061 const blink::WebUserMediaRequest& user_media_request) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000062 virtual void cancelUserMediaRequest(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000063 const blink::WebUserMediaRequest& user_media_request) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000064
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010065 // MediaStreamClient implementation.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000066 virtual bool IsMediaStream(const GURL& url) OVERRIDE;
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010067 virtual scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068 const GURL& url,
69 const base::Closure& error_cb,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010070 const VideoFrameProvider::RepaintCB& repaint_cb) OVERRIDE;
71 virtual scoped_refptr<MediaStreamAudioRenderer>
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000072 GetAudioRenderer(const GURL& url, int render_frame_id) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000073
74 // MediaStreamDispatcherEventHandler implementation.
75 virtual void OnStreamGenerated(
76 int request_id,
77 const std::string& label,
78 const StreamDeviceInfoArray& audio_array,
79 const StreamDeviceInfoArray& video_array) OVERRIDE;
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000080 virtual void OnStreamGenerationFailed(
81 int request_id,
82 content::MediaStreamRequestResult result) OVERRIDE;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000083 virtual void OnDeviceStopped(const std::string& label,
84 const StreamDeviceInfo& device_info) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000085 virtual void OnDevicesEnumerated(
86 int request_id,
87 const StreamDeviceInfoArray& device_array) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000088 virtual void OnDeviceOpened(
89 int request_id,
90 const std::string& label,
91 const StreamDeviceInfo& device_info) OVERRIDE;
92 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
93
94 // RenderViewObserver OVERRIDE
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000095 virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
96 virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000097
98 protected:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000099 // Called when |source| has been stopped from JavaScript.
100 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100101
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100102 // These methods are virtual for test purposes. A test can override them to
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000103 // test requesting local media streams. The function notifies WebKit that the
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100104 // |request| have completed.
105 virtual void GetUserMediaRequestSucceeded(
106 const blink::WebMediaStream& stream,
107 blink::WebUserMediaRequest* request_info);
108 virtual void GetUserMediaRequestFailed(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000109 blink::WebUserMediaRequest* request_info,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000110 content::MediaStreamRequestResult result);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000111
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100112
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000113 // Returns the WebKit representation of a MediaStream given an URL.
114 // This is virtual for test purposes.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000115 virtual blink::WebMediaStream GetMediaStream(const GURL& url);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000116
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000117 // Creates a MediaStreamVideoSource object.
118 // This is virtual for test purposes.
119 virtual MediaStreamVideoSource* CreateVideoSource(
120 const StreamDeviceInfo& device,
121 const MediaStreamSource::SourceStoppedCallback& stop_callback);
122
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000123 private:
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000124 // Class for storing information about a WebKit request to create a
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000125 // MediaStream.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000126 class UserMediaRequestInfo
127 : public base::SupportsWeakPtr<UserMediaRequestInfo> {
128 public:
129 typedef base::Callback<void(UserMediaRequestInfo* request_info,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000130 content::MediaStreamRequestResult result)>
131 ResourcesReady;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000132
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000133 UserMediaRequestInfo(int request_id,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000134 blink::WebFrame* frame,
135 const blink::WebUserMediaRequest& request,
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100136 bool enable_automatic_output_device_selection);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100137 ~UserMediaRequestInfo();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000138 int request_id;
139 // True if MediaStreamDispatcher has generated the stream, see
140 // OnStreamGenerated.
141 bool generated;
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100142 const bool enable_automatic_output_device_selection;
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000143 blink::WebFrame* frame; // WebFrame that requested the MediaStream.
144 blink::WebMediaStream web_stream;
145 blink::WebUserMediaRequest request;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000146
Ben Murdocheffb81e2014-03-31 11:51:25 +0100147 void StartAudioTrack(const blink::WebMediaStreamTrack& track,
148 const blink::WebMediaConstraints& constraints);
149
150 blink::WebMediaStreamTrack CreateAndStartVideoTrack(
151 const blink::WebMediaStreamSource& source,
152 const blink::WebMediaConstraints& constraints,
153 MediaStreamDependencyFactory* factory);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000154
155 // Triggers |callback| when all sources used in this request have either
156 // successfully started, or a source has failed to start.
157 void CallbackOnTracksStarted(const ResourcesReady& callback);
158
159 bool IsSourceUsed(const blink::WebMediaStreamSource& source) const;
160 void RemoveSource(const blink::WebMediaStreamSource& source);
161
162 bool AreAllSourcesRemoved() const { return sources_.empty(); };
163
164 private:
165 void OnTrackStarted(MediaStreamSource* source, bool success);
166 void CheckAllTracksStarted();
167
168 ResourcesReady ready_callback_;
169 bool request_failed_;
170 // Sources used in this request.
171 std::vector<blink::WebMediaStreamSource> sources_;
172 std::vector<MediaStreamSource*> sources_waiting_for_callback_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000173 };
174 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
175
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100176 struct LocalStreamSource {
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000177 LocalStreamSource(blink::WebFrame* frame,
178 const blink::WebMediaStreamSource& source)
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100179 : frame(frame), source(source) {
180 }
181 // |frame| is the WebFrame that requested |source|. NULL in unit tests.
182 // TODO(perkj): Change so that |frame| is not NULL in unit tests.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000183 blink::WebFrame* frame;
184 blink::WebMediaStreamSource source;
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100185 };
186 typedef std::vector<LocalStreamSource> LocalStreamSources;
187
188 // Creates a WebKit representation of stream sources based on
189 // |devices| from the MediaStreamDispatcher.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000190 void InitializeSourceObject(
191 const StreamDeviceInfo& device,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000192 blink::WebMediaStreamSource::Type type,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000193 const blink::WebMediaConstraints& constraints,
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000194 blink::WebFrame* frame,
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000195 blink::WebMediaStreamSource* webkit_source);
196
197 void CreateVideoTracks(
198 const StreamDeviceInfoArray& devices,
199 const blink::WebMediaConstraints& constraints,
200 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
201 UserMediaRequestInfo* request);
202
203 void CreateAudioTracks(
204 const StreamDeviceInfoArray& devices,
205 const blink::WebMediaConstraints& constraints,
206 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
207 UserMediaRequestInfo* request);
208
209 // Callback function triggered when all native versions of the
210 // underlying media sources and tracks have been created and started.
211 void OnCreateNativeTracksCompleted(
212 UserMediaRequestInfo* request,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000213 content::MediaStreamRequestResult result);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100214
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000215 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id);
216 UserMediaRequestInfo* FindUserMediaRequestInfo(
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000217 const blink::WebUserMediaRequest& request);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000218 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request);
219
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100220 // Returns the source that use a device with |device.session_id|
221 // and |device.device.id|. NULL if such source doesn't exist.
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000222 const blink::WebMediaStreamSource* FindLocalSource(
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100223 const StreamDeviceInfo& device) const;
224
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +0000225 void StopLocalSource(const blink::WebMediaStreamSource& source,
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100226 bool notify_dispatcher);
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100227
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000228 scoped_refptr<WebRtcAudioRenderer> CreateRemoteAudioRenderer(
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000229 webrtc::MediaStreamInterface* stream, int render_frame_id);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000230 scoped_refptr<WebRtcLocalAudioRenderer> CreateLocalAudioRenderer(
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000231 const blink::WebMediaStreamTrack& audio_track,
232 int render_frame_id);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000233
Torne (Richard Coles)58537e22013-09-12 12:10:22 +0100234 // Returns a valid session id if a single capture device is currently open
235 // (and then the matching session_id), otherwise -1.
236 // This is used to pass on a session id to a webrtc audio renderer (either
237 // local or remote), so that audio will be rendered to a matching output
238 // device, should one exist.
239 // Note that if there are more than one open capture devices the function
240 // will not be able to pick an appropriate device and return false.
241 bool GetAuthorizedDeviceInfoForAudioRenderer(
242 int* session_id, int* output_sample_rate, int* output_buffer_size);
243
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000244 // Weak ref to a MediaStreamDependencyFactory, owned by the RenderThread.
245 // It's valid for the lifetime of RenderThread.
246 MediaStreamDependencyFactory* dependency_factory_;
247
248 // media_stream_dispatcher_ is a weak reference, owned by RenderView. It's
249 // valid for the lifetime of RenderView.
250 MediaStreamDispatcher* media_stream_dispatcher_;
251
Torne (Richard Coles)8bcbed82013-10-22 16:41:35 +0100252 LocalStreamSources local_sources_;
253
Ben Murdoch0529e5d2014-04-24 10:50:13 +0100254 UserMediaRequests user_media_requests_;
255
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000256 DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
257};
258
259} // namespace content
260
261#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_