Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Side by Side Diff: content/renderer/media/media_stream_video_capturer_source.cc

Issue 242013002: Refactor video capturing code in the render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments and merged Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_video_capturer_source.h" 5 #include "content/renderer/media/media_stream_video_capturer_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
8 #include "base/location.h" 9 #include "base/location.h"
9 #include "content/renderer/media/video_capture_impl_manager.h" 10 #include "content/renderer/media/video_capture_impl_manager.h"
10 #include "content/renderer/render_thread_impl.h" 11 #include "content/renderer/render_thread_impl.h"
12 #include "media/base/bind_to_current_loop.h"
11 #include "media/base/video_frame.h" 13 #include "media/base/video_frame.h"
12 14
13 namespace { 15 namespace {
14 16
15 struct SourceVideoFormat { 17 struct SourceVideoFormat {
16 int width; 18 int width;
17 int height; 19 int height;
18 int frame_rate; 20 int frame_rate;
19 }; 21 };
20 22
(...skipping 10 matching lines...) Expand all
31 33
32 namespace content { 34 namespace content {
33 35
34 VideoCapturerDelegate::VideoCapturerDelegate( 36 VideoCapturerDelegate::VideoCapturerDelegate(
35 const StreamDeviceInfo& device_info) 37 const StreamDeviceInfo& device_info)
36 : session_id_(device_info.session_id), 38 : session_id_(device_info.session_id),
37 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE || 39 is_screen_cast_(device_info.device.type == MEDIA_TAB_VIDEO_CAPTURE ||
38 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE), 40 device_info.device.type == MEDIA_DESKTOP_VIDEO_CAPTURE),
39 got_first_frame_(false) { 41 got_first_frame_(false) {
40 DVLOG(3) << "VideoCapturerDelegate::ctor"; 42 DVLOG(3) << "VideoCapturerDelegate::ctor";
41 // RenderThreadImpl::current() may be NULL in testing. 43
44 // NULL in unit test.
42 if (RenderThreadImpl::current()) { 45 if (RenderThreadImpl::current()) {
43 capture_engine_ = RenderThreadImpl::current()->video_capture_impl_manager() 46 VideoCaptureImplManager* manager =
44 ->UseDevice(device_info.session_id); 47 RenderThreadImpl::current()->video_capture_impl_manager();
45 DCHECK(capture_engine_); 48 if (manager)
Ami GONE FROM CHROMIUM 2014/04/24 23:05:18 If that is possible then can StopCapture() fail to
Alpha Left Google 2014/04/24 23:33:53 In the destructor of VCIM if there are clients it
49 release_device_cb_ = manager->UseDevice(session_id_);
46 } 50 }
47 message_loop_proxy_ = base::MessageLoopProxy::current();
48 } 51 }
49 52
50 VideoCapturerDelegate::~VideoCapturerDelegate() { 53 VideoCapturerDelegate::~VideoCapturerDelegate() {
51 DVLOG(3) << "VideoCapturerDelegate::dtor"; 54 DVLOG(3) << "VideoCapturerDelegate::dtor";
52 DCHECK(new_frame_callback_.is_null()); 55 DCHECK(new_frame_callback_.is_null());
56 if (!release_device_cb_.is_null())
57 release_device_cb_.Run();
53 } 58 }
54 59
55 void VideoCapturerDelegate::GetCurrentSupportedFormats( 60 void VideoCapturerDelegate::GetCurrentSupportedFormats(
56 int max_requested_width, 61 int max_requested_width,
57 int max_requested_height, 62 int max_requested_height,
58 const SupportedFormatsCallback& callback) { 63 const VideoCaptureDeviceFormatsCB& callback) {
59 DVLOG(3) << "GetCurrentSupportedFormats(" 64 DVLOG(3) << "GetCurrentSupportedFormats("
60 << " { max_requested_height = " << max_requested_height << "})" 65 << " { max_requested_height = " << max_requested_height << "})"
61 << " { max_requested_width = " << max_requested_width << "})"; 66 << " { max_requested_width = " << max_requested_width << "})";
62 67
63 if (is_screen_cast_) { 68 if (is_screen_cast_) {
64 media::VideoCaptureFormats formats; 69 media::VideoCaptureFormats formats;
65 const int width = max_requested_width ? 70 const int width = max_requested_width ?
66 max_requested_width : MediaStreamVideoSource::kDefaultWidth; 71 max_requested_width : MediaStreamVideoSource::kDefaultWidth;
67 const int height = max_requested_height ? 72 const int height = max_requested_height ?
68 max_requested_height : MediaStreamVideoSource::kDefaultHeight; 73 max_requested_height : MediaStreamVideoSource::kDefaultHeight;
69 formats.push_back( 74 formats.push_back(
70 media::VideoCaptureFormat( 75 media::VideoCaptureFormat(
71 gfx::Size(width, height), 76 gfx::Size(width, height),
72 MediaStreamVideoSource::kDefaultFrameRate, 77 MediaStreamVideoSource::kDefaultFrameRate,
73 media::PIXEL_FORMAT_I420)); 78 media::PIXEL_FORMAT_I420));
74 callback.Run(formats); 79 callback.Run(formats);
75 return; 80 return;
76 } 81 }
77 82
83 // NULL in unit test.
84 if (!RenderThreadImpl::current())
85 return;
86 VideoCaptureImplManager* manager =
87 RenderThreadImpl::current()->video_capture_impl_manager();
88 if (!manager)
89 return;
78 DCHECK(source_formats_callback_.is_null()); 90 DCHECK(source_formats_callback_.is_null());
79 source_formats_callback_ = callback; 91 source_formats_callback_ = callback;
80 capture_engine_->GetDeviceFormatsInUse(base::Bind( 92 manager->GetDeviceFormatsInUse(
81 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)); 93 session_id_,
94 media::BindToCurrentLoop(
95 base::Bind(
96 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, this)));
82 } 97 }
83 98
84 void VideoCapturerDelegate::StartDeliver( 99 void VideoCapturerDelegate::StartCapture(
85 const media::VideoCaptureParams& params, 100 const media::VideoCaptureParams& params,
86 const NewFrameCallback& new_frame_callback, 101 const VideoCaptureDeliverFrameCB& new_frame_callback,
87 const StartedCallback& started_callback) { 102 const StartedCallback& started_callback) {
88 DCHECK(params.requested_format.IsValid()); 103 DCHECK(params.requested_format.IsValid());
89 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 104 DCHECK(thread_checker_.CalledOnValidThread());
90 new_frame_callback_ = new_frame_callback; 105 new_frame_callback_ = new_frame_callback;
91 started_callback_ = started_callback; 106 started_callback_ = started_callback;
92 got_first_frame_ = false; 107 got_first_frame_ = false;
93 108
94 // Increase the reference count to ensure the object is not deleted until 109 // NULL in unit test.
95 // it is unregistered in VideoCapturerDelegate::OnRemoved. 110 if (!RenderThreadImpl::current())
96 AddRef(); 111 return;
97 capture_engine_->StartCapture(this, params); 112 VideoCaptureImplManager* manager =
113 RenderThreadImpl::current()->video_capture_impl_manager();
114 if (!manager)
115 return;
116 stop_capture_cb_ =
117 manager->StartCapture(
118 session_id_,
119 params,
120 media::BindToCurrentLoop(base::Bind(
121 &VideoCapturerDelegate::OnStateUpdateOnRenderThread, this)),
122 media::BindToCurrentLoop(base::Bind(
123 &VideoCapturerDelegate::OnFrameReadyOnRenderThread, this)));
98 } 124 }
99 125
100 void VideoCapturerDelegate::StopDeliver() { 126 void VideoCapturerDelegate::StopCapture() {
101 // Immediately make sure we don't provide more frames. 127 // Immediately make sure we don't provide more frames.
102 DVLOG(3) << "VideoCapturerDelegate::StopDeliver()"; 128 DVLOG(3) << "VideoCapturerDelegate::StopCapture()";
103 DCHECK(message_loop_proxy_->BelongsToCurrentThread()); 129 DCHECK(thread_checker_.CalledOnValidThread());
104 capture_engine_->StopCapture(this); 130 if (!stop_capture_cb_.is_null()) {
131 base::ResetAndReturn(&stop_capture_cb_).Run();
132 }
105 new_frame_callback_.Reset(); 133 new_frame_callback_.Reset();
106 started_callback_.Reset(); 134 started_callback_.Reset();
107 source_formats_callback_.Reset(); 135 source_formats_callback_.Reset();
108 } 136 }
109 137
110 void VideoCapturerDelegate::OnStarted(media::VideoCapture* capture) {
111 DVLOG(3) << "VideoCapturerDelegate::OnStarted";
112 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
113 }
114
115 void VideoCapturerDelegate::OnStopped(media::VideoCapture* capture) {
116 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
117 }
118
119 void VideoCapturerDelegate::OnPaused(media::VideoCapture* capture) {
120 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
121 }
122
123 void VideoCapturerDelegate::OnError(media::VideoCapture* capture,
124 int error_code) {
125 DVLOG(3) << "VideoCapturerDelegate::OnError";
126 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
127 message_loop_proxy_->PostTask(
128 FROM_HERE,
129 base::Bind(&VideoCapturerDelegate::OnErrorOnRenderThread, this, capture));
130 }
131
132 void VideoCapturerDelegate::OnRemoved(media::VideoCapture* capture) {
133 DVLOG(3) << " MediaStreamVideoCapturerSource::OnRemoved";
134 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
135
136 // Balance the AddRef in StartDeliver.
137 // This means we are no longer registered as an event handler and can safely
138 // be deleted.
139 Release();
140 }
141
142 void VideoCapturerDelegate::OnFrameReady(
143 media::VideoCapture* capture,
144 const scoped_refptr<media::VideoFrame>& frame) {
145 DCHECK(!message_loop_proxy_->BelongsToCurrentThread());
146 message_loop_proxy_->PostTask(
147 FROM_HERE,
148 base::Bind(&VideoCapturerDelegate::OnFrameReadyOnRenderThread,
149 this,
150 capture,
151 frame));
152 }
153
154 void VideoCapturerDelegate::OnFrameReadyOnRenderThread( 138 void VideoCapturerDelegate::OnFrameReadyOnRenderThread(
155 media::VideoCapture* capture, 139 const scoped_refptr<media::VideoFrame>& frame,
156 const scoped_refptr<media::VideoFrame>& frame) { 140 const media::VideoCaptureFormat& format,
141 const base::TimeTicks& timestamp) {
157 if (!got_first_frame_) { 142 if (!got_first_frame_) {
158 got_first_frame_ = true; 143 got_first_frame_ = true;
159 if (!started_callback_.is_null()) 144 if (!started_callback_.is_null())
160 started_callback_.Run(true); 145 started_callback_.Run(true);
161 } 146 }
162 147
163 if (!new_frame_callback_.is_null()) { 148 if (!new_frame_callback_.is_null()) {
164 new_frame_callback_.Run(frame); 149 new_frame_callback_.Run(frame, format, timestamp);
165 } 150 }
166 } 151 }
167 152
168 void VideoCapturerDelegate::OnErrorOnRenderThread( 153 void VideoCapturerDelegate::OnStateUpdateOnRenderThread(
169 media::VideoCapture* capture) { 154 VideoCaptureState state) {
170 if (!started_callback_.is_null()) 155 if (state == VIDEO_CAPTURE_STATE_ERROR && !started_callback_.is_null()) {
171 started_callback_.Run(false); 156 started_callback_.Run(false);
157 }
172 } 158 }
173 159
174 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( 160 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived(
175 const media::VideoCaptureFormats& formats_in_use) { 161 const media::VideoCaptureFormats& formats_in_use) {
176 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); 162 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size();
177 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 163 DCHECK(thread_checker_.CalledOnValidThread());
178 // StopDeliver() might have destroyed |source_formats_callback_| before 164 // StopCapture() might have destroyed |source_formats_callback_| before
179 // arriving here. 165 // arriving here.
180 if (source_formats_callback_.is_null()) 166 if (source_formats_callback_.is_null())
181 return; 167 return;
168 // If there are no formats in use, try to retrieve the whole list of
169 // supported form.
182 if (!formats_in_use.empty()) { 170 if (!formats_in_use.empty()) {
183 source_formats_callback_.Run(formats_in_use); 171 source_formats_callback_.Run(formats_in_use);
184 source_formats_callback_.Reset(); 172 source_formats_callback_.Reset();
185 } else { 173 return;
186 // If there are no formats in use, try to retrieve the whole list of
187 // supported formats.
188 capture_engine_->GetDeviceSupportedFormats(base::Bind(
189 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, this));
190 } 174 }
175
176 // NULL in unit test.
177 if (!RenderThreadImpl::current())
178 return;
179 VideoCaptureImplManager* manager =
180 RenderThreadImpl::current()->video_capture_impl_manager();
181 if (!manager)
182 return;
183 manager->GetDeviceSupportedFormats(
184 session_id_,
185 media::BindToCurrentLoop(
186 base::Bind(
187 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated,
188 this)));
191 } 189 }
192 190
193 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( 191 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated(
194 const media::VideoCaptureFormats& formats) { 192 const media::VideoCaptureFormats& formats) {
195 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() 193 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size()
196 << " received"; 194 << " received";
197 DCHECK(message_loop_proxy_ == base::MessageLoopProxy::current()); 195 DCHECK(thread_checker_.CalledOnValidThread());
198 // StopDeliver() might have destroyed |source_formats_callback_| before 196 // StopCapture() might have destroyed |source_formats_callback_| before
199 // arriving here. 197 // arriving here.
200 if (source_formats_callback_.is_null()) 198 if (source_formats_callback_.is_null())
201 return; 199 return;
202 if (formats.size()) { 200 if (formats.size()) {
203 source_formats_callback_.Run(formats); 201 source_formats_callback_.Run(formats);
204 } else { 202 } else {
205 // The capture device doesn't seem to support capability enumeration, 203 // The capture device doesn't seem to support capability enumeration,
206 // compose a fallback list of capabilities. 204 // compose a fallback list of capabilities.
207 media::VideoCaptureFormats default_formats; 205 media::VideoCaptureFormats default_formats;
208 for (size_t i = 0; i < arraysize(kVideoFormats); ++i) { 206 for (size_t i = 0; i < arraysize(kVideoFormats); ++i) {
(...skipping 30 matching lines...) Expand all
239 base::Unretained(this))); 237 base::Unretained(this)));
240 } 238 }
241 239
242 void MediaStreamVideoCapturerSource::StartSourceImpl( 240 void MediaStreamVideoCapturerSource::StartSourceImpl(
243 const media::VideoCaptureParams& params) { 241 const media::VideoCaptureParams& params) {
244 media::VideoCaptureParams new_params(params); 242 media::VideoCaptureParams new_params(params);
245 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || 243 if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
246 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 244 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
247 new_params.allow_resolution_change = true; 245 new_params.allow_resolution_change = true;
248 } 246 }
249 delegate_->StartDeliver( 247 delegate_->StartCapture(
250 new_params, 248 new_params,
251 base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame, 249 base::Bind(&MediaStreamVideoCapturerSource::DeliverVideoFrame,
252 base::Unretained(this)), 250 base::Unretained(this)),
253 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone, 251 base::Bind(&MediaStreamVideoCapturerSource::OnStartDone,
254 base::Unretained(this))); 252 base::Unretained(this)));
255 } 253 }
256 254
257 void MediaStreamVideoCapturerSource::StopSourceImpl() { 255 void MediaStreamVideoCapturerSource::StopSourceImpl() {
258 delegate_->StopDeliver(); 256 delegate_->StopCapture();
259 } 257 }
260 258
261 } // namespace content 259 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_video_capturer_source.h ('k') | content/renderer/media/media_stream_video_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698