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.
5 #ifndef CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_
6 #define CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_
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"
20 #include "content/renderer/media/media_stream_client.h"
21 #include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
22 #include "third_party/WebKit/public/platform/WebMediaStream.h"
23 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
24 #include "third_party/WebKit/public/platform/WebVector.h"
25 #include "third_party/WebKit/public/web/WebUserMediaClient.h"
26 #include "third_party/WebKit/public/web/WebUserMediaRequest.h"
27 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
30 class MediaStreamAudioRenderer;
31 class MediaStreamDependencyFactory;
32 class MediaStreamDispatcher;
33 class MediaStreamSource;
34 class WebRtcAudioRenderer;
35 class WebRtcLocalAudioRenderer;
37 // MediaStreamImpl is a delegate for the Media Stream API messages used by
38 // WebKit. It ties together WebKit, native PeerConnection in libjingle and
39 // MediaStreamManager (via MediaStreamDispatcher and MediaStreamDispatcherHost)
40 // in the browser process. It must be created, called and destroyed on the
42 // MediaStreamImpl have weak pointers to a MediaStreamDispatcher.
43 class CONTENT_EXPORT MediaStreamImpl
44 : public RenderViewObserver,
45 NON_EXPORTED_BASE(public blink::WebUserMediaClient),
46 NON_EXPORTED_BASE(public MediaStreamClient),
47 public MediaStreamDispatcherEventHandler,
48 public base::SupportsWeakPtr<MediaStreamImpl>,
49 NON_EXPORTED_BASE(public base::NonThreadSafe) {
52 RenderView* render_view,
53 MediaStreamDispatcher* media_stream_dispatcher,
54 MediaStreamDependencyFactory* dependency_factory);
55 virtual ~MediaStreamImpl();
57 // blink::WebUserMediaClient implementation
58 virtual void requestUserMedia(
59 const blink::WebUserMediaRequest& user_media_request) OVERRIDE;
60 virtual void cancelUserMediaRequest(
61 const blink::WebUserMediaRequest& user_media_request) OVERRIDE;
63 // MediaStreamClient implementation.
64 virtual bool IsMediaStream(const GURL& url) OVERRIDE;
65 virtual scoped_refptr<VideoFrameProvider> GetVideoFrameProvider(
67 const base::Closure& error_cb,
68 const VideoFrameProvider::RepaintCB& repaint_cb) OVERRIDE;
69 virtual scoped_refptr<MediaStreamAudioRenderer>
70 GetAudioRenderer(const GURL& url, int render_frame_id) OVERRIDE;
72 // MediaStreamDispatcherEventHandler implementation.
73 virtual void OnStreamGenerated(
75 const std::string& label,
76 const StreamDeviceInfoArray& audio_array,
77 const StreamDeviceInfoArray& video_array) OVERRIDE;
78 virtual void OnStreamGenerationFailed(int request_id) OVERRIDE;
79 virtual void OnDeviceStopped(const std::string& label,
80 const StreamDeviceInfo& device_info) OVERRIDE;
81 virtual void OnDevicesEnumerated(
83 const StreamDeviceInfoArray& device_array) OVERRIDE;
84 virtual void OnDeviceOpened(
86 const std::string& label,
87 const StreamDeviceInfo& device_info) OVERRIDE;
88 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE;
90 // RenderViewObserver OVERRIDE
91 virtual void FrameDetached(blink::WebFrame* frame) OVERRIDE;
92 virtual void FrameWillClose(blink::WebFrame* frame) OVERRIDE;
95 // Called when |source| has been stopped from JavaScript.
96 void OnLocalSourceStopped(const blink::WebMediaStreamSource& source);
98 // Called when a MediaStream with label |label| has been ordered to stop from
99 // JavaScript. The implementation must stop all sources that are not used by
100 // other MediaStreams.
101 // TODO(perkj): MediaStream::Stop has been deprecated from the spec and all
102 // applications should move to use MediaStreamTrack::Stop instead and this
103 // method be removed.
104 void OnLocalMediaStreamStop(const std::string& label);
106 // This function is virtual for test purposes. A test can override this to
107 // test requesting local media streams. The function notifies WebKit that the
108 // |request| have completed and generated the MediaStream |stream|.
109 virtual void CompleteGetUserMediaRequest(
110 const blink::WebMediaStream& stream,
111 blink::WebUserMediaRequest* request_info,
112 bool request_succeeded);
114 // Returns the WebKit representation of a MediaStream given an URL.
115 // This is virtual for test purposes.
116 virtual blink::WebMediaStream GetMediaStream(const GURL& url);
119 // Class for storing information about a WebKit request to create a
121 class UserMediaRequestInfo
122 : public base::SupportsWeakPtr<UserMediaRequestInfo> {
124 typedef base::Callback<void(UserMediaRequestInfo* request_info,
125 bool request_succeeded)> ResourcesReady;
127 UserMediaRequestInfo(int request_id,
128 blink::WebFrame* frame,
129 const blink::WebUserMediaRequest& request,
130 bool enable_automatic_output_device_selection);
131 ~UserMediaRequestInfo();
133 // True if MediaStreamDispatcher has generated the stream, see
134 // OnStreamGenerated.
136 const bool enable_automatic_output_device_selection;
137 blink::WebFrame* frame; // WebFrame that requested the MediaStream.
138 blink::WebMediaStream web_stream;
139 blink::WebUserMediaRequest request;
141 void StartTrack(const blink::WebMediaStreamTrack& track,
142 const blink::WebMediaConstraints& constraints);
144 // Triggers |callback| when all sources used in this request have either
145 // successfully started, or a source has failed to start.
146 void CallbackOnTracksStarted(const ResourcesReady& callback);
148 bool IsSourceUsed(const blink::WebMediaStreamSource& source) const;
149 void RemoveSource(const blink::WebMediaStreamSource& source);
151 bool AreAllSourcesRemoved() const { return sources_.empty(); };
154 void OnTrackStarted(MediaStreamSource* source, bool success);
155 void CheckAllTracksStarted();
157 ResourcesReady ready_callback_;
158 bool request_failed_;
159 // Sources used in this request.
160 std::vector<blink::WebMediaStreamSource> sources_;
161 std::vector<MediaStreamSource*> sources_waiting_for_callback_;
163 typedef ScopedVector<UserMediaRequestInfo> UserMediaRequests;
165 struct LocalStreamSource {
166 LocalStreamSource(blink::WebFrame* frame,
167 const blink::WebMediaStreamSource& source)
168 : frame(frame), source(source) {
170 // |frame| is the WebFrame that requested |source|. NULL in unit tests.
171 // TODO(perkj): Change so that |frame| is not NULL in unit tests.
172 blink::WebFrame* frame;
173 blink::WebMediaStreamSource source;
175 typedef std::vector<LocalStreamSource> LocalStreamSources;
177 // Creates a WebKit representation of stream sources based on
178 // |devices| from the MediaStreamDispatcher.
179 void InitializeSourceObject(
180 const StreamDeviceInfo& device,
181 blink::WebMediaStreamSource::Type type,
182 const blink::WebMediaConstraints& constraints,
183 blink::WebFrame* frame,
184 blink::WebMediaStreamSource* webkit_source);
186 void CreateVideoTracks(
187 const StreamDeviceInfoArray& devices,
188 const blink::WebMediaConstraints& constraints,
189 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
190 UserMediaRequestInfo* request);
192 void CreateAudioTracks(
193 const StreamDeviceInfoArray& devices,
194 const blink::WebMediaConstraints& constraints,
195 blink::WebVector<blink::WebMediaStreamTrack>* webkit_tracks,
196 UserMediaRequestInfo* request);
198 // Callback function triggered when all native versions of the
199 // underlying media sources and tracks have been created and started.
200 void OnCreateNativeTracksCompleted(
201 UserMediaRequestInfo* request,
202 bool request_succeeded);
204 UserMediaRequestInfo* FindUserMediaRequestInfo(int request_id);
205 UserMediaRequestInfo* FindUserMediaRequestInfo(
206 const blink::WebUserMediaRequest& request);
207 UserMediaRequestInfo* FindUserMediaRequestInfo(const std::string& label);
208 void DeleteUserMediaRequestInfo(UserMediaRequestInfo* request);
210 // Returns the source that use a device with |device.session_id|
211 // and |device.device.id|. NULL if such source doesn't exist.
212 const blink::WebMediaStreamSource* FindLocalSource(
213 const StreamDeviceInfo& device) const;
215 // Returns true if |source| exists in |user_media_requests_|
216 bool IsSourceInRequests(const blink::WebMediaStreamSource& source) const;
218 void StopLocalSource(const blink::WebMediaStreamSource& source,
219 bool notify_dispatcher);
220 // Stops all local sources that don't exist in exist in
221 // |user_media_requests_|.
222 void StopUnreferencedSources(bool notify_dispatcher);
224 scoped_refptr<WebRtcAudioRenderer> CreateRemoteAudioRenderer(
225 webrtc::MediaStreamInterface* stream, int render_frame_id);
226 scoped_refptr<WebRtcLocalAudioRenderer> CreateLocalAudioRenderer(
227 const blink::WebMediaStreamTrack& audio_track,
228 int render_frame_id);
230 // Returns a valid session id if a single capture device is currently open
231 // (and then the matching session_id), otherwise -1.
232 // This is used to pass on a session id to a webrtc audio renderer (either
233 // local or remote), so that audio will be rendered to a matching output
234 // device, should one exist.
235 // Note that if there are more than one open capture devices the function
236 // will not be able to pick an appropriate device and return false.
237 bool GetAuthorizedDeviceInfoForAudioRenderer(
238 int* session_id, int* output_sample_rate, int* output_buffer_size);
240 // Weak ref to a MediaStreamDependencyFactory, owned by the RenderThread.
241 // It's valid for the lifetime of RenderThread.
242 MediaStreamDependencyFactory* dependency_factory_;
244 // media_stream_dispatcher_ is a weak reference, owned by RenderView. It's
245 // valid for the lifetime of RenderView.
246 MediaStreamDispatcher* media_stream_dispatcher_;
248 UserMediaRequests user_media_requests_;
250 LocalStreamSources local_sources_;
252 DISALLOW_COPY_AND_ASSIGN(MediaStreamImpl);
255 } // namespace content
257 #endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_IMPL_H_