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

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

Issue 2721113002: getUserMedia: handle the device starting status report. (Closed)
Patch Set: address comments on PS#4 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 // Do nothing becase these states aren't taken here.
miu 2017/03/10 23:56:56 nit: Please add NOT_REACHED() here for safety. The
braveyao 2017/03/13 19:04:44 Done.
144 return;
142 } 145 }
143 } 146 }
144 147
145 void VideoCaptureImpl::StopCapture(int client_id) { 148 void VideoCaptureImpl::StopCapture(int client_id) {
146 DCHECK(io_thread_checker_.CalledOnValidThread()); 149 DCHECK(io_thread_checker_.CalledOnValidThread());
147 // A client ID can be in only one client list. 150 // 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 151 // 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(). 152 // that client list and don't have to run the other following RemoveClient().
150 if (!RemoveClient(client_id, &clients_pending_on_restart_)) { 153 if (!RemoveClient(client_id, &clients_pending_on_restart_)) {
151 RemoveClient(client_id, &clients_); 154 RemoveClient(client_id, &clients_);
(...skipping 29 matching lines...) Expand all
181 base::Bind(&VideoCaptureImpl::OnDeviceFormatsInUse, 184 base::Bind(&VideoCaptureImpl::OnDeviceFormatsInUse,
182 weak_factory_.GetWeakPtr(), callback)); 185 weak_factory_.GetWeakPtr(), callback));
183 } 186 }
184 187
185 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) { 188 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) {
186 DVLOG(1) << __func__ << " state: " << state; 189 DVLOG(1) << __func__ << " state: " << state;
187 DCHECK(io_thread_checker_.CalledOnValidThread()); 190 DCHECK(io_thread_checker_.CalledOnValidThread());
188 191
189 switch (state) { 192 switch (state) {
190 case mojom::VideoCaptureState::STARTED: 193 case mojom::VideoCaptureState::STARTED:
191 // Capture has started in the browser process. Since we have already 194 state_ = VIDEO_CAPTURE_STATE_STARTED;
192 // told all clients that we have started there's nothing to do. 195 for (const auto& client : clients_)
196 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STARTED);
197 // In case there is any frame dropped before STARTED, always request for
198 // a frame refresh to start the video call with.
199 // Capture device will make a decision if it should refresh a frame.
200 RequestRefreshFrame();
193 break; 201 break;
194 case mojom::VideoCaptureState::STOPPED: 202 case mojom::VideoCaptureState::STOPPED:
195 state_ = VIDEO_CAPTURE_STATE_STOPPED; 203 state_ = VIDEO_CAPTURE_STATE_STOPPED;
196 client_buffers_.clear(); 204 client_buffers_.clear();
197 weak_factory_.InvalidateWeakPtrs(); 205 weak_factory_.InvalidateWeakPtrs();
198 if (!clients_.empty() || !clients_pending_on_restart_.empty()) 206 if (!clients_.empty() || !clients_pending_on_restart_.empty())
199 RestartCapture(); 207 RestartCapture();
200 break; 208 break;
201 case mojom::VideoCaptureState::PAUSED: 209 case mojom::VideoCaptureState::PAUSED:
202 for (const auto& client : clients_) 210 for (const auto& client : clients_)
(...skipping 18 matching lines...) Expand all
221 break; 229 break;
222 } 230 }
223 } 231 }
224 232
225 void VideoCaptureImpl::OnBufferCreated(int32_t buffer_id, 233 void VideoCaptureImpl::OnBufferCreated(int32_t buffer_id,
226 mojo::ScopedSharedBufferHandle handle) { 234 mojo::ScopedSharedBufferHandle handle) {
227 DVLOG(1) << __func__ << " buffer_id: " << buffer_id; 235 DVLOG(1) << __func__ << " buffer_id: " << buffer_id;
228 DCHECK(io_thread_checker_.CalledOnValidThread()); 236 DCHECK(io_thread_checker_.CalledOnValidThread());
229 DCHECK(handle.is_valid()); 237 DCHECK(handle.is_valid());
230 238
231 if (state_ != VIDEO_CAPTURE_STATE_STARTED)
232 return;
233
234 base::SharedMemoryHandle memory_handle; 239 base::SharedMemoryHandle memory_handle;
235 size_t memory_size = 0; 240 size_t memory_size = 0;
236 bool read_only_flag = false; 241 bool read_only_flag = false;
237 242
238 const MojoResult result = mojo::UnwrapSharedMemoryHandle( 243 const MojoResult result = mojo::UnwrapSharedMemoryHandle(
239 std::move(handle), &memory_handle, &memory_size, &read_only_flag); 244 std::move(handle), &memory_handle, &memory_size, &read_only_flag);
240 DCHECK_EQ(MOJO_RESULT_OK, result); 245 DCHECK_EQ(MOJO_RESULT_OK, result);
241 DCHECK_GT(memory_size, 0u); 246 DCHECK_GT(memory_size, 0u);
242 247
243 std::unique_ptr<base::SharedMemory> shm( 248 std::unique_ptr<base::SharedMemory> shm(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 int buffer_id, 348 int buffer_id,
344 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, 349 const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
345 double consumer_resource_utilization) { 350 double consumer_resource_utilization) {
346 DCHECK(io_thread_checker_.CalledOnValidThread()); 351 DCHECK(io_thread_checker_.CalledOnValidThread());
347 GetVideoCaptureHost()->ReleaseBuffer( 352 GetVideoCaptureHost()->ReleaseBuffer(
348 device_id_, buffer_id, consumer_resource_utilization); 353 device_id_, buffer_id, consumer_resource_utilization);
349 } 354 }
350 355
351 void VideoCaptureImpl::StopDevice() { 356 void VideoCaptureImpl::StopDevice() {
352 DCHECK(io_thread_checker_.CalledOnValidThread()); 357 DCHECK(io_thread_checker_.CalledOnValidThread());
353 if (state_ != VIDEO_CAPTURE_STATE_STARTED) 358 if (state_ != VIDEO_CAPTURE_STATE_STARTING &&
359 state_ != VIDEO_CAPTURE_STATE_STARTED)
354 return; 360 return;
355 state_ = VIDEO_CAPTURE_STATE_STOPPING; 361 state_ = VIDEO_CAPTURE_STATE_STOPPING;
356 GetVideoCaptureHost()->Stop(device_id_); 362 GetVideoCaptureHost()->Stop(device_id_);
357 params_.requested_format.frame_size.SetSize(0, 0); 363 params_.requested_format.frame_size.SetSize(0, 0);
358 } 364 }
359 365
360 void VideoCaptureImpl::RestartCapture() { 366 void VideoCaptureImpl::RestartCapture() {
361 DCHECK(io_thread_checker_.CalledOnValidThread()); 367 DCHECK(io_thread_checker_.CalledOnValidThread());
362 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); 368 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED);
363 369
364 int width = 0; 370 int width = 0;
365 int height = 0; 371 int height = 0;
366 clients_.insert(clients_pending_on_restart_.begin(), 372 clients_.insert(clients_pending_on_restart_.begin(),
367 clients_pending_on_restart_.end()); 373 clients_pending_on_restart_.end());
368 clients_pending_on_restart_.clear(); 374 clients_pending_on_restart_.clear();
369 for (const auto& client : clients_) { 375 for (const auto& client : clients_) {
370 width = std::max(width, 376 width = std::max(width,
371 client.second.params.requested_format.frame_size.width()); 377 client.second.params.requested_format.frame_size.width());
372 height = std::max( 378 height = std::max(
373 height, client.second.params.requested_format.frame_size.height()); 379 height, client.second.params.requested_format.frame_size.height());
374 } 380 }
375 params_.requested_format.frame_size.SetSize(width, height); 381 params_.requested_format.frame_size.SetSize(width, height);
376 DVLOG(1) << __func__ << " " << params_.requested_format.frame_size.ToString(); 382 DVLOG(1) << __func__ << " " << params_.requested_format.frame_size.ToString();
377 StartCaptureInternal(); 383 StartCaptureInternal();
378 } 384 }
379 385
380 void VideoCaptureImpl::StartCaptureInternal() { 386 void VideoCaptureImpl::StartCaptureInternal() {
381 DCHECK(io_thread_checker_.CalledOnValidThread()); 387 DCHECK(io_thread_checker_.CalledOnValidThread());
388 state_ = VIDEO_CAPTURE_STATE_STARTING;
382 389
383 GetVideoCaptureHost()->Start(device_id_, session_id_, params_, 390 GetVideoCaptureHost()->Start(device_id_, session_id_, params_,
384 observer_binding_.CreateInterfacePtrAndBind()); 391 observer_binding_.CreateInterfacePtrAndBind());
385 state_ = VIDEO_CAPTURE_STATE_STARTED;
386 } 392 }
387 393
388 void VideoCaptureImpl::OnDeviceSupportedFormats( 394 void VideoCaptureImpl::OnDeviceSupportedFormats(
389 const VideoCaptureDeviceFormatsCB& callback, 395 const VideoCaptureDeviceFormatsCB& callback,
390 const media::VideoCaptureFormats& supported_formats) { 396 const media::VideoCaptureFormats& supported_formats) {
391 DCHECK(io_thread_checker_.CalledOnValidThread()); 397 DCHECK(io_thread_checker_.CalledOnValidThread());
392 callback.Run(supported_formats); 398 callback.Run(supported_formats);
393 } 399 }
394 400
395 void VideoCaptureImpl::OnDeviceFormatsInUse( 401 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. 435 // destructor. |metadata| is still valid for read-access at this point.
430 double consumer_resource_utilization = -1.0; 436 double consumer_resource_utilization = -1.0;
431 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, 437 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
432 &consumer_resource_utilization)) { 438 &consumer_resource_utilization)) {
433 consumer_resource_utilization = -1.0; 439 consumer_resource_utilization = -1.0;
434 } 440 }
435 callback_to_io_thread.Run(consumer_resource_utilization); 441 callback_to_io_thread.Run(consumer_resource_utilization);
436 } 442 }
437 443
438 } // namespace content 444 } // 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