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

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

Issue 2409893003: VideoCapture: more migration IPC-->mojo, part 5 (Closed)
Patch Set: rebase content/common/BUILD.gn Created 4 years, 2 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 return; 194 return;
195 } 195 }
196 const bool inserted = 196 const bool inserted =
197 client_buffers_.insert(std::make_pair( 197 client_buffers_.insert(std::make_pair(
198 buffer_id, 198 buffer_id,
199 new ClientBuffer(std::move(shm), length))) 199 new ClientBuffer(std::move(shm), length)))
200 .second; 200 .second;
201 DCHECK(inserted); 201 DCHECK(inserted);
202 } 202 }
203 203
204 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { 204 void VideoCaptureImpl::OnDelegateAdded(int32_t device_id) {
205 DVLOG(1) << __func__ << " " << device_id;
205 DCHECK(io_task_runner_->BelongsToCurrentThread()); 206 DCHECK(io_task_runner_->BelongsToCurrentThread());
206 207
207 const auto& cb_iter = client_buffers_.find(buffer_id); 208 device_id_ = device_id;
208 if (cb_iter != client_buffers_.end()) { 209 ClientInfoMap::iterator it = clients_pending_on_filter_.begin();
209 DCHECK(!cb_iter->second.get() || cb_iter->second->HasOneRef()) 210 while (it != clients_pending_on_filter_.end()) {
210 << "Instructed to delete buffer we are still using."; 211 const int client_id = it->first;
211 client_buffers_.erase(cb_iter); 212 const ClientInfo client_info = it->second;
213 clients_pending_on_filter_.erase(it++);
214 StartCapture(client_id, client_info.params, client_info.state_update_cb,
215 client_info.deliver_frame_cb);
212 } 216 }
213 } 217 }
214 218
215 void VideoCaptureImpl::OnBufferReceived( 219 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) {
216 int buffer_id, 220 DVLOG(1) << __func__ << " state: " << state;
217 base::TimeDelta timestamp,
218 const base::DictionaryValue& metadata,
219 media::VideoPixelFormat pixel_format,
220 media::VideoFrame::StorageType storage_type,
221 const gfx::Size& coded_size,
222 const gfx::Rect& visible_rect) {
223 DCHECK(io_task_runner_->BelongsToCurrentThread()); 221 DCHECK(io_task_runner_->BelongsToCurrentThread());
224 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); 222
225 DCHECK_EQ(media::VideoFrame::STORAGE_SHMEM, storage_type); 223 switch (state) {
224 case mojom::VideoCaptureState::STARTED:
225 // Capture has started in the browser process. Since we have already
226 // told all clients that we have started there's nothing to do.
227 break;
228 case mojom::VideoCaptureState::STOPPED:
229 state_ = VIDEO_CAPTURE_STATE_STOPPED;
230 client_buffers_.clear();
231 weak_factory_.InvalidateWeakPtrs();
232 if (!clients_.empty() || !clients_pending_on_restart_.empty())
233 RestartCapture();
234 break;
235 case mojom::VideoCaptureState::PAUSED:
236 for (const auto& client : clients_)
237 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_PAUSED);
238 break;
239 case mojom::VideoCaptureState::RESUMED:
240 for (const auto& client : clients_)
241 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_RESUMED);
242 break;
243 case mojom::VideoCaptureState::FAILED:
244 for (const auto& client : clients_)
245 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR);
246 clients_.clear();
247 state_ = VIDEO_CAPTURE_STATE_ERROR;
248 break;
249 case mojom::VideoCaptureState::ENDED:
250 // We'll only notify the client that the stream has stopped.
251 for (const auto& client : clients_)
252 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED);
253 clients_.clear();
254 state_ = VIDEO_CAPTURE_STATE_ENDED;
255 break;
256 }
257 }
258
259 void VideoCaptureImpl::OnBufferReady(int32_t buffer_id,
260 mojom::VideoFrameInfoPtr info) {
261 DVLOG(1) << __func__ << " buffer_id: " << buffer_id;
262
263 DCHECK(io_task_runner_->BelongsToCurrentThread());
264 DCHECK_EQ(media::mojom::VideoFormat::I420, info->pixel_format);
265 DCHECK_EQ(media::PIXEL_STORAGE_CPU, info->storage_type);
226 266
227 if (state_ != VIDEO_CAPTURE_STATE_STARTED || 267 if (state_ != VIDEO_CAPTURE_STATE_STARTED ||
228 pixel_format != media::PIXEL_FORMAT_I420 || 268 info->pixel_format != media::mojom::VideoFormat::I420 ||
229 storage_type != media::VideoFrame::STORAGE_SHMEM) { 269 info->storage_type != media::PIXEL_STORAGE_CPU) {
230 GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, 270 GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id,
231 gpu::SyncToken(), -1.0); 271 gpu::SyncToken(), -1.0);
232 return; 272 return;
233 } 273 }
234 274
235 base::TimeTicks reference_time; 275 base::TimeTicks reference_time;
236 media::VideoFrameMetadata frame_metadata; 276 media::VideoFrameMetadata frame_metadata;
237 frame_metadata.MergeInternalValuesFrom(metadata); 277 frame_metadata.MergeInternalValuesFrom(info->metadata);
238 const bool success = frame_metadata.GetTimeTicks( 278 const bool success = frame_metadata.GetTimeTicks(
239 media::VideoFrameMetadata::REFERENCE_TIME, &reference_time); 279 media::VideoFrameMetadata::REFERENCE_TIME, &reference_time);
240 DCHECK(success); 280 DCHECK(success);
241 281
242 if (first_frame_ref_time_.is_null()) 282 if (first_frame_ref_time_.is_null())
243 first_frame_ref_time_ = reference_time; 283 first_frame_ref_time_ = reference_time;
244 284
245 // If the timestamp is not prepared, we use reference time to make a rough 285 // If the timestamp is not prepared, we use reference time to make a rough
246 // estimate. e.g. ThreadSafeCaptureOracle::DidCaptureFrame(). 286 // estimate. e.g. ThreadSafeCaptureOracle::DidCaptureFrame().
247 // TODO(miu): Fix upstream capturers to always set timestamp and reference 287 // TODO(miu): Fix upstream capturers to always set timestamp and reference
248 // time. See http://crbug/618407/ for tracking. 288 // time. See http://crbug/618407/ for tracking.
249 if (timestamp.is_zero()) 289 if (info->timestamp.is_zero())
250 timestamp = reference_time - first_frame_ref_time_; 290 info->timestamp = reference_time - first_frame_ref_time_;
251 291
252 // TODO(qiangchen): Change the metric name to "reference_time" and 292 // TODO(qiangchen): Change the metric name to "reference_time" and
253 // "timestamp", so that we have consistent naming everywhere. 293 // "timestamp", so that we have consistent naming everywhere.
254 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc 294 // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
255 TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived", 295 TRACE_EVENT_INSTANT2("cast_perf_test", "OnBufferReceived",
256 TRACE_EVENT_SCOPE_THREAD, "timestamp", 296 TRACE_EVENT_SCOPE_THREAD, "timestamp",
257 (reference_time - base::TimeTicks()).InMicroseconds(), 297 (reference_time - base::TimeTicks()).InMicroseconds(),
258 "time_delta", timestamp.InMicroseconds()); 298 "time_delta", info->timestamp.InMicroseconds());
259 299
260 const auto& iter = client_buffers_.find(buffer_id); 300 const auto& iter = client_buffers_.find(buffer_id);
261 DCHECK(iter != client_buffers_.end()); 301 DCHECK(iter != client_buffers_.end());
262 const scoped_refptr<ClientBuffer> buffer = iter->second; 302 const scoped_refptr<ClientBuffer> buffer = iter->second;
263 scoped_refptr<media::VideoFrame> frame = 303 scoped_refptr<media::VideoFrame> frame =
264 media::VideoFrame::WrapExternalSharedMemory( 304 media::VideoFrame::WrapExternalSharedMemory(
265 pixel_format, coded_size, visible_rect, 305 static_cast<media::VideoPixelFormat>(info->pixel_format),
266 gfx::Size(visible_rect.width(), visible_rect.height()), 306 info->coded_size, info->visible_rect, info->visible_rect.size(),
267 reinterpret_cast<uint8_t*>(buffer->buffer()->memory()), 307 reinterpret_cast<uint8_t*>(buffer->buffer()->memory()),
268 buffer->buffer_size(), buffer->buffer()->handle(), 308 buffer->buffer_size(), buffer->buffer()->handle(),
269 0 /* shared_memory_offset */, timestamp); 309 0 /* shared_memory_offset */, info->timestamp);
270 if (!frame) { 310 if (!frame) {
271 GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id, 311 GetVideoCaptureHost()->ReleaseBuffer(device_id_, buffer_id,
272 gpu::SyncToken(), -1.0); 312 gpu::SyncToken(), -1.0);
273 return; 313 return;
274 } 314 }
275 315
276 BufferFinishedCallback buffer_finished_callback = media::BindToCurrentLoop( 316 BufferFinishedCallback buffer_finished_callback = media::BindToCurrentLoop(
277 base::Bind(&VideoCaptureImpl::OnClientBufferFinished, 317 base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
278 weak_factory_.GetWeakPtr(), buffer_id, buffer)); 318 weak_factory_.GetWeakPtr(), buffer_id, buffer));
279 std::unique_ptr<gpu::SyncToken> release_sync_token(new gpu::SyncToken); 319 std::unique_ptr<gpu::SyncToken> release_sync_token(new gpu::SyncToken);
280 frame->AddDestructionObserver( 320 frame->AddDestructionObserver(
281 base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(), 321 base::Bind(&VideoCaptureImpl::DidFinishConsumingFrame, frame->metadata(),
282 base::Passed(&release_sync_token), buffer_finished_callback)); 322 base::Passed(&release_sync_token), buffer_finished_callback));
283 323
284 frame->metadata()->MergeInternalValuesFrom(metadata); 324 frame->metadata()->MergeInternalValuesFrom(info->metadata);
285 325
286 // TODO(qiangchen): Dive into the full code path to let frame metadata hold 326 // TODO(qiangchen): Dive into the full code path to let frame metadata hold
287 // reference time rather than using an extra parameter. 327 // reference time rather than using an extra parameter.
288 for (const auto& client : clients_) 328 for (const auto& client : clients_)
289 client.second.deliver_frame_cb.Run(frame, reference_time); 329 client.second.deliver_frame_cb.Run(frame, reference_time);
290 } 330 }
291 331
292 void VideoCaptureImpl::OnDelegateAdded(int32_t device_id) { 332 void VideoCaptureImpl::OnBufferDestroyed(int32_t buffer_id) {
293 DVLOG(1) << __func__ << " " << device_id;
294 DCHECK(io_task_runner_->BelongsToCurrentThread()); 333 DCHECK(io_task_runner_->BelongsToCurrentThread());
295 334
296 device_id_ = device_id; 335 const auto& cb_iter = client_buffers_.find(buffer_id);
297 ClientInfoMap::iterator it = clients_pending_on_filter_.begin(); 336 if (cb_iter != client_buffers_.end()) {
298 while (it != clients_pending_on_filter_.end()) { 337 DCHECK(!cb_iter->second.get() || cb_iter->second->HasOneRef())
299 const int client_id = it->first; 338 << "Instructed to delete buffer we are still using.";
300 const ClientInfo client_info = it->second; 339 client_buffers_.erase(cb_iter);
301 clients_pending_on_filter_.erase(it++);
302 StartCapture(client_id, client_info.params, client_info.state_update_cb,
303 client_info.deliver_frame_cb);
304 } 340 }
305 } 341 }
306 342
307 void VideoCaptureImpl::OnStateChanged(mojom::VideoCaptureState state) {
308 DVLOG(1) << __func__ << " state: " << state;
309 DCHECK(io_task_runner_->BelongsToCurrentThread());
310
311 switch (state) {
312 case mojom::VideoCaptureState::STARTED:
313 // Capture has started in the browser process. Since we have already
314 // told all clients that we have started there's nothing to do.
315 break;
316 case mojom::VideoCaptureState::STOPPED:
317 state_ = VIDEO_CAPTURE_STATE_STOPPED;
318 client_buffers_.clear();
319 weak_factory_.InvalidateWeakPtrs();
320 if (!clients_.empty() || !clients_pending_on_restart_.empty())
321 RestartCapture();
322 break;
323 case mojom::VideoCaptureState::PAUSED:
324 for (const auto& client : clients_)
325 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_PAUSED);
326 break;
327 case mojom::VideoCaptureState::RESUMED:
328 for (const auto& client : clients_)
329 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_RESUMED);
330 break;
331 case mojom::VideoCaptureState::FAILED:
332 for (const auto& client : clients_)
333 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR);
334 clients_.clear();
335 state_ = VIDEO_CAPTURE_STATE_ERROR;
336 break;
337 case mojom::VideoCaptureState::ENDED:
338 // We'll only notify the client that the stream has stopped.
339 for (const auto& client : clients_)
340 client.second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED);
341 clients_.clear();
342 state_ = VIDEO_CAPTURE_STATE_ENDED;
343 break;
344 }
345 }
346
347 void VideoCaptureImpl::OnClientBufferFinished( 343 void VideoCaptureImpl::OnClientBufferFinished(
348 int buffer_id, 344 int buffer_id,
349 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, 345 const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
350 const gpu::SyncToken& release_sync_token, 346 const gpu::SyncToken& release_sync_token,
351 double consumer_resource_utilization) { 347 double consumer_resource_utilization) {
352 DCHECK(io_task_runner_->BelongsToCurrentThread()); 348 DCHECK(io_task_runner_->BelongsToCurrentThread());
353 GetVideoCaptureHost()->ReleaseBuffer( 349 GetVideoCaptureHost()->ReleaseBuffer(
354 device_id_, buffer_id, release_sync_token, consumer_resource_utilization); 350 device_id_, buffer_id, release_sync_token, consumer_resource_utilization);
355 } 351 }
356 352
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 double consumer_resource_utilization = -1.0; 445 double consumer_resource_utilization = -1.0;
450 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, 446 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
451 &consumer_resource_utilization)) { 447 &consumer_resource_utilization)) {
452 consumer_resource_utilization = -1.0; 448 consumer_resource_utilization = -1.0;
453 } 449 }
454 450
455 callback_to_io_thread.Run(*release_sync_token, consumer_resource_utilization); 451 callback_to_io_thread.Run(*release_sync_token, consumer_resource_utilization);
456 } 452 }
457 453
458 } // namespace content 454 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_capture_impl.h ('k') | content/renderer/media/video_capture_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698