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

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

Issue 2721113002: getUserMedia: handle the device starting status report. (Closed)
Patch Set: address nits Created 3 years, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 // Notes about usage of this object by VideoCaptureImplManager. 5 // Notes about usage of this object by VideoCaptureImplManager.
6 // 6 //
7 // VideoCaptureImplManager access this object by using a Unretained() 7 // VideoCaptureImplManager access this object by using a Unretained()
8 // binding and tasks on the IO thread. It is then important that 8 // binding and tasks on the IO thread. It is then important that
9 // VideoCaptureImpl never post task to itself. All operations must be 9 // VideoCaptureImpl never post task to itself. All operations must be
10 // synchronous. 10 // synchronous.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (ChildThread::Get()) { // This will be null in unit tests. 76 if (ChildThread::Get()) { // This will be null in unit tests.
77 mojom::VideoCaptureHostPtr temp_video_capture_host; 77 mojom::VideoCaptureHostPtr temp_video_capture_host;
78 ChildThread::Get()->GetRemoteInterfaces()->GetInterface( 78 ChildThread::Get()->GetRemoteInterfaces()->GetInterface(
79 mojo::MakeRequest(&temp_video_capture_host)); 79 mojo::MakeRequest(&temp_video_capture_host));
80 video_capture_host_info_ = temp_video_capture_host.PassInterface(); 80 video_capture_host_info_ = temp_video_capture_host.PassInterface();
81 } 81 }
82 } 82 }
83 83
84 VideoCaptureImpl::~VideoCaptureImpl() { 84 VideoCaptureImpl::~VideoCaptureImpl() {
85 DCHECK(io_thread_checker_.CalledOnValidThread()); 85 DCHECK(io_thread_checker_.CalledOnValidThread());
86 if (state_ == VIDEO_CAPTURE_STATE_STARTED && GetVideoCaptureHost()) 86 if ((state_ == VIDEO_CAPTURE_STATE_STARTING ||
87 state_ == VIDEO_CAPTURE_STATE_STARTED) &&
88 GetVideoCaptureHost())
87 GetVideoCaptureHost()->Stop(device_id_); 89 GetVideoCaptureHost()->Stop(device_id_);
88 } 90 }
89 91
90 void VideoCaptureImpl::SuspendCapture(bool suspend) { 92 void VideoCaptureImpl::SuspendCapture(bool suspend) {
91 DCHECK(io_thread_checker_.CalledOnValidThread()); 93 DCHECK(io_thread_checker_.CalledOnValidThread());
92 if (suspend) 94 if (suspend)
93 GetVideoCaptureHost()->Pause(device_id_); 95 GetVideoCaptureHost()->Pause(device_id_);
94 else 96 else
95 GetVideoCaptureHost()->Resume(device_id_, session_id_, params_); 97 GetVideoCaptureHost()->Resume(device_id_, session_id_, params_);
96 } 98 }
97 99
98 void VideoCaptureImpl::StartCapture( 100 void VideoCaptureImpl::StartCapture(
99 int client_id, 101 int client_id,
100 const media::VideoCaptureParams& params, 102 const media::VideoCaptureParams& params,
101 const VideoCaptureStateUpdateCB& state_update_cb, 103 const VideoCaptureStateUpdateCB& state_update_cb,
102 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { 104 const VideoCaptureDeliverFrameCB& deliver_frame_cb) {
103 DVLOG(1) << __func__ << " |device_id_| = " << device_id_; 105 DVLOG(1) << __func__ << " |device_id_| = " << device_id_;
104 DCHECK(io_thread_checker_.CalledOnValidThread()); 106 DCHECK(io_thread_checker_.CalledOnValidThread());
105 ClientInfo client_info; 107 ClientInfo client_info;
106 client_info.params = params; 108 client_info.params = params;
107 client_info.state_update_cb = state_update_cb; 109 client_info.state_update_cb = state_update_cb;
108 client_info.deliver_frame_cb = deliver_frame_cb; 110 client_info.deliver_frame_cb = deliver_frame_cb;
109 111
110 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { 112 switch (state_) {
111 state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR); 113 case VIDEO_CAPTURE_STATE_STARTING:
112 } else if (clients_pending_on_restart_.count(client_id) || 114 case VIDEO_CAPTURE_STATE_STARTED:
113 clients_.count(client_id)) {
114 DLOG(FATAL) << __func__ << " This client has already started.";
115 } else {
116 // Note: |state_| might not be started at this point. But we tell
117 // client that we have started.
118 state_update_cb.Run(VIDEO_CAPTURE_STATE_STARTED);
119 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
120 clients_[client_id] = client_info; 115 clients_[client_id] = client_info;
121 // TODO(sheu): Allowing resolution change will require that all 116 // TODO(sheu): Allowing resolution change will require that all
122 // outstanding clients of a capture session support resolution change. 117 // outstanding clients of a capture session support resolution change.
123 DCHECK_EQ(params_.resolution_change_policy, 118 DCHECK_EQ(params_.resolution_change_policy,
124 params.resolution_change_policy); 119 params.resolution_change_policy);
125 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { 120 return;
121 case VIDEO_CAPTURE_STATE_STOPPING:
126 clients_pending_on_restart_[client_id] = client_info; 122 clients_pending_on_restart_[client_id] = client_info;
127 DVLOG(1) << __func__ << " Got new resolution while stopping: " 123 DVLOG(1) << __func__ << " Got new resolution while stopping: "
128 << params.requested_format.frame_size.ToString(); 124 << params.requested_format.frame_size.ToString();
129 } else { 125 return;
126 case VIDEO_CAPTURE_STATE_STOPPED:
127 case VIDEO_CAPTURE_STATE_ENDED:
130 clients_[client_id] = client_info; 128 clients_[client_id] = client_info;
131 if (state_ == VIDEO_CAPTURE_STATE_STARTED)
132 return;
133 params_ = params; 129 params_ = params;
134 params_.requested_format.frame_rate = 130 params_.requested_format.frame_rate =
135 std::min(params_.requested_format.frame_rate, 131 std::min(params_.requested_format.frame_rate,
136 static_cast<float>(media::limits::kMaxFramesPerSecond)); 132 static_cast<float>(media::limits::kMaxFramesPerSecond));
137 133
138 DVLOG(1) << "StartCapture: starting with first resolution " 134 DVLOG(1) << "StartCapture: starting with first resolution "
139 << params_.requested_format.frame_size.ToString(); 135 << params_.requested_format.frame_size.ToString();
140 StartCaptureInternal(); 136 StartCaptureInternal();
141 } 137 return;
138 case VIDEO_CAPTURE_STATE_ERROR:
139 state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR);
140 return;
141 case VIDEO_CAPTURE_STATE_PAUSED:
142 case VIDEO_CAPTURE_STATE_RESUMED:
143 // The internal |state_| is never set to PAUSED/RESUMED since
144 // VideoCaptureImpl is not modified by those.
145 NOTREACHED();
146 return;
142 } 147 }
143 } 148 }
144 149
145 void VideoCaptureImpl::StopCapture(int client_id) { 150 void VideoCaptureImpl::StopCapture(int client_id) {
146 DCHECK(io_thread_checker_.CalledOnValidThread()); 151 DCHECK(io_thread_checker_.CalledOnValidThread());
147 // A client ID can be in only one client list. 152 // A client ID can be in only one client list.
148 // If this ID is in any client list, we can just remove it from 153 // If this ID is in any client list, we can just remove it from
149 // that client list and don't have to run the other following RemoveClient(). 154 // that client list and don't have to run the other following RemoveClient().
150 if (!RemoveClient(client_id, &clients_pending_on_restart_)) { 155 if (!RemoveClient(client_id, &clients_pending_on_restart_)) {
151 RemoveClient(client_id, &clients_); 156 RemoveClient(client_id, &clients_);
(...skipping 29 matching lines...) Expand all
181 base::Bind(&VideoCaptureImpl::OnDeviceFormatsInUse, 186 base::Bind(&VideoCaptureImpl::OnDeviceFormatsInUse,
182 weak_factory_.GetWeakPtr(), callback)); 187 weak_factory_.GetWeakPtr(), callback));
183 } 188 }
184 189
185 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) { 190 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) {
186 DVLOG(1) << __func__ << " state: " << state; 191 DVLOG(1) << __func__ << " state: " << state;
187 DCHECK(io_thread_checker_.CalledOnValidThread()); 192 DCHECK(io_thread_checker_.CalledOnValidThread());
188 193
189 switch (state) { 194 switch (state) {
190 case mojom::VideoCaptureState::STARTED: 195 case mojom::VideoCaptureState::STARTED:
191 // Capture has started in the browser process. Since we have already 196 state_ = VIDEO_CAPTURE_STATE_STARTED;
192 // told all clients that we have started there's nothing to do. 197 for (const auto& client : clients_)
198 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STARTED);
199 // In case there is any frame dropped before STARTED, always request for
200 // a frame refresh to start the video call with.
201 // Capture device will make a decision if it should refresh a frame.
202 RequestRefreshFrame();
193 break; 203 break;
194 case mojom::VideoCaptureState::STOPPED: 204 case mojom::VideoCaptureState::STOPPED:
195 state_ = VIDEO_CAPTURE_STATE_STOPPED; 205 state_ = VIDEO_CAPTURE_STATE_STOPPED;
196 client_buffers_.clear(); 206 client_buffers_.clear();
197 weak_factory_.InvalidateWeakPtrs(); 207 weak_factory_.InvalidateWeakPtrs();
198 if (!clients_.empty() || !clients_pending_on_restart_.empty()) 208 if (!clients_.empty() || !clients_pending_on_restart_.empty())
199 RestartCapture(); 209 RestartCapture();
200 break; 210 break;
201 case mojom::VideoCaptureState::PAUSED: 211 case mojom::VideoCaptureState::PAUSED:
202 for (const auto& client : clients_) 212 for (const auto& client : clients_)
(...skipping 18 matching lines...) Expand all
221 break; 231 break;
222 } 232 }
223 } 233 }
224 234
225 void VideoCaptureImpl::OnBufferCreated(int32_t buffer_id, 235 void VideoCaptureImpl::OnBufferCreated(int32_t buffer_id,
226 mojo::ScopedSharedBufferHandle handle) { 236 mojo::ScopedSharedBufferHandle handle) {
227 DVLOG(1) << __func__ << " buffer_id: " << buffer_id; 237 DVLOG(1) << __func__ << " buffer_id: " << buffer_id;
228 DCHECK(io_thread_checker_.CalledOnValidThread()); 238 DCHECK(io_thread_checker_.CalledOnValidThread());
229 DCHECK(handle.is_valid()); 239 DCHECK(handle.is_valid());
230 240
231 if (state_ != VIDEO_CAPTURE_STATE_STARTED)
232 return;
233
234 base::SharedMemoryHandle memory_handle; 241 base::SharedMemoryHandle memory_handle;
235 size_t memory_size = 0; 242 size_t memory_size = 0;
236 bool read_only_flag = false; 243 bool read_only_flag = false;
237 244
238 const MojoResult result = mojo::UnwrapSharedMemoryHandle( 245 const MojoResult result = mojo::UnwrapSharedMemoryHandle(
239 std::move(handle), &memory_handle, &memory_size, &read_only_flag); 246 std::move(handle), &memory_handle, &memory_size, &read_only_flag);
240 DCHECK_EQ(MOJO_RESULT_OK, result); 247 DCHECK_EQ(MOJO_RESULT_OK, result);
241 DCHECK_GT(memory_size, 0u); 248 DCHECK_GT(memory_size, 0u);
242 249
243 std::unique_ptr<base::SharedMemory> shm( 250 std::unique_ptr<base::SharedMemory> shm(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 int buffer_id, 350 int buffer_id,
344 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, 351 const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
345 double consumer_resource_utilization) { 352 double consumer_resource_utilization) {
346 DCHECK(io_thread_checker_.CalledOnValidThread()); 353 DCHECK(io_thread_checker_.CalledOnValidThread());
347 GetVideoCaptureHost()->ReleaseBuffer( 354 GetVideoCaptureHost()->ReleaseBuffer(
348 device_id_, buffer_id, consumer_resource_utilization); 355 device_id_, buffer_id, consumer_resource_utilization);
349 } 356 }
350 357
351 void VideoCaptureImpl::StopDevice() { 358 void VideoCaptureImpl::StopDevice() {
352 DCHECK(io_thread_checker_.CalledOnValidThread()); 359 DCHECK(io_thread_checker_.CalledOnValidThread());
353 if (state_ != VIDEO_CAPTURE_STATE_STARTED) 360 if (state_ != VIDEO_CAPTURE_STATE_STARTING &&
361 state_ != VIDEO_CAPTURE_STATE_STARTED)
354 return; 362 return;
355 state_ = VIDEO_CAPTURE_STATE_STOPPING; 363 state_ = VIDEO_CAPTURE_STATE_STOPPING;
356 GetVideoCaptureHost()->Stop(device_id_); 364 GetVideoCaptureHost()->Stop(device_id_);
357 params_.requested_format.frame_size.SetSize(0, 0); 365 params_.requested_format.frame_size.SetSize(0, 0);
358 } 366 }
359 367
360 void VideoCaptureImpl::RestartCapture() { 368 void VideoCaptureImpl::RestartCapture() {
361 DCHECK(io_thread_checker_.CalledOnValidThread()); 369 DCHECK(io_thread_checker_.CalledOnValidThread());
362 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); 370 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED);
363 371
364 int width = 0; 372 int width = 0;
365 int height = 0; 373 int height = 0;
366 clients_.insert(clients_pending_on_restart_.begin(), 374 clients_.insert(clients_pending_on_restart_.begin(),
367 clients_pending_on_restart_.end()); 375 clients_pending_on_restart_.end());
368 clients_pending_on_restart_.clear(); 376 clients_pending_on_restart_.clear();
369 for (const auto& client : clients_) { 377 for (const auto& client : clients_) {
370 width = std::max(width, 378 width = std::max(width,
371 client.second.params.requested_format.frame_size.width()); 379 client.second.params.requested_format.frame_size.width());
372 height = std::max( 380 height = std::max(
373 height, client.second.params.requested_format.frame_size.height()); 381 height, client.second.params.requested_format.frame_size.height());
374 } 382 }
375 params_.requested_format.frame_size.SetSize(width, height); 383 params_.requested_format.frame_size.SetSize(width, height);
376 DVLOG(1) << __func__ << " " << params_.requested_format.frame_size.ToString(); 384 DVLOG(1) << __func__ << " " << params_.requested_format.frame_size.ToString();
377 StartCaptureInternal(); 385 StartCaptureInternal();
378 } 386 }
379 387
380 void VideoCaptureImpl::StartCaptureInternal() { 388 void VideoCaptureImpl::StartCaptureInternal() {
381 DCHECK(io_thread_checker_.CalledOnValidThread()); 389 DCHECK(io_thread_checker_.CalledOnValidThread());
390 state_ = VIDEO_CAPTURE_STATE_STARTING;
382 391
383 GetVideoCaptureHost()->Start(device_id_, session_id_, params_, 392 GetVideoCaptureHost()->Start(device_id_, session_id_, params_,
384 observer_binding_.CreateInterfacePtrAndBind()); 393 observer_binding_.CreateInterfacePtrAndBind());
385 state_ = VIDEO_CAPTURE_STATE_STARTED;
386 } 394 }
387 395
388 void VideoCaptureImpl::OnDeviceSupportedFormats( 396 void VideoCaptureImpl::OnDeviceSupportedFormats(
389 const VideoCaptureDeviceFormatsCB& callback, 397 const VideoCaptureDeviceFormatsCB& callback,
390 const media::VideoCaptureFormats& supported_formats) { 398 const media::VideoCaptureFormats& supported_formats) {
391 DCHECK(io_thread_checker_.CalledOnValidThread()); 399 DCHECK(io_thread_checker_.CalledOnValidThread());
392 callback.Run(supported_formats); 400 callback.Run(supported_formats);
393 } 401 }
394 402
395 void VideoCaptureImpl::OnDeviceFormatsInUse( 403 void VideoCaptureImpl::OnDeviceFormatsInUse(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 // destructor. |metadata| is still valid for read-access at this point. 437 // destructor. |metadata| is still valid for read-access at this point.
430 double consumer_resource_utilization = -1.0; 438 double consumer_resource_utilization = -1.0;
431 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, 439 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
432 &consumer_resource_utilization)) { 440 &consumer_resource_utilization)) {
433 consumer_resource_utilization = -1.0; 441 consumer_resource_utilization = -1.0;
434 } 442 }
435 callback_to_io_thread.Run(consumer_resource_utilization); 443 callback_to_io_thread.Run(consumer_resource_utilization);
436 } 444 }
437 445
438 } // namespace content 446 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/user_media_client_impl.cc ('k') | content/renderer/media/video_capture_impl_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698