| OLD | NEW |
| 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 #include "content/browser/renderer_host/media/video_capture_controller.h" | 5 #include "content/browser/renderer_host/media/video_capture_controller.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/metrics/sparse_histogram.h" | 13 #include "base/metrics/sparse_histogram.h" |
| 14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 15 #include "content/browser/renderer_host/media/media_stream_manager.h" | 15 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 16 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 16 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
| 17 #include "content/browser/renderer_host/media/video_capture_device_client.h" | 17 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
| 18 #include "content/browser/renderer_host/media/video_capture_manager.h" | 18 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 19 #include "content/common/gpu/client/gl_helper.h" | 19 #include "content/common/gpu/client/gl_helper.h" |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
| 22 #include "gpu/command_buffer/common/mailbox_holder.h" | 22 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 23 #include "media/base/video_frame.h" | 23 #include "media/base/video_frame.h" |
| 24 | 24 |
| 25 #if !defined(OS_ANDROID) | 25 #if !defined(OS_ANDROID) |
| 26 #include "content/browser/compositor/image_transport_factory.h" | 26 #include "content/browser/compositor/image_transport_factory.h" |
| 27 #endif | 27 #endif |
| 28 | 28 |
| 29 #if defined(ENABLE_WEBRTC) && (defined(OS_LINUX) || defined(OS_MACOSX)) |
| 30 #include "content/browser/renderer_host/media/video_capture_texture_wrapper.h" |
| 31 #endif |
| 32 |
| 29 using media::VideoCaptureFormat; | 33 using media::VideoCaptureFormat; |
| 30 using media::VideoFrame; | 34 using media::VideoFrame; |
| 31 | 35 |
| 32 namespace content { | 36 namespace content { |
| 33 | 37 |
| 34 namespace { | 38 namespace { |
| 35 | 39 |
| 36 static const int kInfiniteRatio = 99999; | 40 static const int kInfiniteRatio = 99999; |
| 37 | 41 |
| 38 #define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) \ | 42 #define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) \ |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 134 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 131 } | 135 } |
| 132 | 136 |
| 133 base::WeakPtr<VideoCaptureController> | 137 base::WeakPtr<VideoCaptureController> |
| 134 VideoCaptureController::GetWeakPtrForIOThread() { | 138 VideoCaptureController::GetWeakPtrForIOThread() { |
| 135 return weak_ptr_factory_.GetWeakPtr(); | 139 return weak_ptr_factory_.GetWeakPtr(); |
| 136 } | 140 } |
| 137 | 141 |
| 138 scoped_ptr<media::VideoCaptureDevice::Client> | 142 scoped_ptr<media::VideoCaptureDevice::Client> |
| 139 VideoCaptureController::NewDeviceClient( | 143 VideoCaptureController::NewDeviceClient( |
| 140 const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner) { | 144 const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner, |
| 145 const media::VideoCaptureFormat& format) { |
| 141 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 146 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 142 return make_scoped_ptr(new VideoCaptureDeviceClient( | 147 #if defined(ENABLE_WEBRTC) && (defined(OS_LINUX) || defined(OS_MACOSX)) |
| 143 this->GetWeakPtrForIOThread(), buffer_pool_, capture_task_runner)); | 148 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 149 switches::kEnableWebRtcCaptureToTexture)) { |
| 150 return make_scoped_ptr(new VideoCaptureTextureWrapper( |
| 151 this->GetWeakPtrForIOThread(), buffer_pool_, capture_task_runner, |
| 152 format)); |
| 153 DVLOG(1) << "TextureWrapper, format " << format.ToString(); |
| 154 } |
| 155 #endif |
| 156 return make_scoped_ptr( |
| 157 new VideoCaptureDeviceClient(this->GetWeakPtrForIOThread(), |
| 158 buffer_pool_)); |
| 144 } | 159 } |
| 145 | 160 |
| 146 void VideoCaptureController::AddClient( | 161 void VideoCaptureController::AddClient( |
| 147 VideoCaptureControllerID id, | 162 VideoCaptureControllerID id, |
| 148 VideoCaptureControllerEventHandler* event_handler, | 163 VideoCaptureControllerEventHandler* event_handler, |
| 149 base::ProcessHandle render_process, | 164 base::ProcessHandle render_process, |
| 150 media::VideoCaptureSessionId session_id, | 165 media::VideoCaptureSessionId session_id, |
| 151 const media::VideoCaptureParams& params) { | 166 const media::VideoCaptureParams& params) { |
| 152 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 167 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 153 DVLOG(1) << "VideoCaptureController::AddClient, id " << id | 168 DVLOG(1) << "VideoCaptureController::AddClient, id " << id |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 266 return video_capture_format_; | 281 return video_capture_format_; |
| 267 } | 282 } |
| 268 | 283 |
| 269 VideoCaptureController::~VideoCaptureController() { | 284 VideoCaptureController::~VideoCaptureController() { |
| 270 STLDeleteContainerPointers(controller_clients_.begin(), | 285 STLDeleteContainerPointers(controller_clients_.begin(), |
| 271 controller_clients_.end()); | 286 controller_clients_.end()); |
| 272 } | 287 } |
| 273 | 288 |
| 274 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( | 289 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( |
| 275 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, | 290 const scoped_refptr<media::VideoCaptureDevice::Client::Buffer>& buffer, |
| 276 const scoped_refptr<VideoFrame>& frame, | 291 const scoped_refptr<VideoFrame>& frame, |
| 277 const base::TimeTicks& timestamp) { | 292 const base::TimeTicks& timestamp) { |
| 278 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 293 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 279 const int buffer_id = buffer->id(); | 294 DCHECK_NE(buffer->id(), VideoCaptureBufferPool::kInvalidId); |
| 280 DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId); | |
| 281 | 295 |
| 282 int count = 0; | 296 int count = 0; |
| 283 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 297 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
| 284 if (!frame->metadata()->HasKey(media::VideoFrameMetadata::FRAME_RATE)) { | 298 if (!frame->metadata()->HasKey(media::VideoFrameMetadata::FRAME_RATE)) { |
| 285 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, | 299 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, |
| 286 video_capture_format_.frame_rate); | 300 video_capture_format_.frame_rate); |
| 287 } | 301 } |
| 288 scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue()); | 302 scoped_ptr<base::DictionaryValue> metadata(new base::DictionaryValue()); |
| 289 frame->metadata()->MergeInternalValuesInto(metadata.get()); | 303 frame->metadata()->MergeInternalValuesInto(metadata.get()); |
| 290 | 304 |
| 291 for (const auto& client : controller_clients_) { | 305 for (const auto& client : controller_clients_) { |
| 292 if (client->session_closed || client->paused) | 306 if (client->session_closed || client->paused) |
| 293 continue; | 307 continue; |
| 294 | 308 |
| 295 scoped_ptr<base::DictionaryValue> copy_of_metadata; | 309 scoped_ptr<base::DictionaryValue> copy_of_metadata; |
| 296 if (client == controller_clients_.back()) | 310 if (client == controller_clients_.back()) |
| 297 copy_of_metadata = metadata.Pass(); | 311 copy_of_metadata = metadata.Pass(); |
| 298 else | 312 else |
| 299 copy_of_metadata.reset(metadata->DeepCopy()); | 313 copy_of_metadata.reset(metadata->DeepCopy()); |
| 300 | 314 |
| 301 if (frame->format() == VideoFrame::NATIVE_TEXTURE) { | 315 if (frame->format() == VideoFrame::NATIVE_TEXTURE) { |
| 302 DCHECK(frame->coded_size() == frame->visible_rect().size()) | 316 DCHECK(frame->coded_size() == frame->visible_rect().size()) |
| 303 << "Textures are always supposed to be tightly packed."; | 317 << "Textures are always supposed to be tightly packed."; |
| 304 client->event_handler->OnMailboxBufferReady(client->controller_id, | 318 client->event_handler->OnMailboxBufferReady(client->controller_id, |
| 305 buffer_id, | 319 buffer->id(), |
| 306 *frame->mailbox_holder(), | 320 *frame->mailbox_holder(), |
| 307 frame->coded_size(), | 321 frame->coded_size(), |
| 308 timestamp, | 322 timestamp, |
| 309 copy_of_metadata.Pass()); | 323 copy_of_metadata.Pass()); |
| 310 } else if (frame->format() == media::VideoFrame::I420) { | 324 } else if (frame->format() == media::VideoFrame::I420) { |
| 311 bool is_new_buffer = client->known_buffers.insert(buffer_id).second; | 325 bool is_new_buffer = client->known_buffers.insert(buffer->id()).second; |
| 312 if (is_new_buffer) { | 326 if (is_new_buffer) { |
| 313 // On the first use of a buffer on a client, share the memory handle. | 327 // On the first use of a buffer on a client, share the memory handle. |
| 314 size_t memory_size = 0; | 328 size_t memory_size = 0; |
| 315 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( | 329 base::SharedMemoryHandle remote_handle = buffer_pool_->ShareToProcess( |
| 316 buffer_id, client->render_process_handle, &memory_size); | 330 buffer->id(), client->render_process_handle, &memory_size); |
| 317 client->event_handler->OnBufferCreated( | 331 client->event_handler->OnBufferCreated( |
| 318 client->controller_id, remote_handle, memory_size, buffer_id); | 332 client->controller_id, remote_handle, memory_size, buffer->id()); |
| 319 } | 333 } |
| 320 | 334 |
| 321 client->event_handler->OnBufferReady( | 335 client->event_handler->OnBufferReady( |
| 322 client->controller_id, buffer_id, frame->coded_size(), | 336 client->controller_id, buffer->id(), frame->coded_size(), |
| 323 frame->visible_rect(), timestamp, copy_of_metadata.Pass()); | 337 frame->visible_rect(), timestamp, copy_of_metadata.Pass()); |
| 324 } else { | 338 } else { |
| 325 // VideoFrame format not supported. | 339 // VideoFrame format not supported. |
| 326 NOTREACHED(); | 340 NOTREACHED(); |
| 327 break; | 341 break; |
| 328 } | 342 } |
| 329 | 343 |
| 330 bool inserted = | 344 bool inserted = |
| 331 client->active_buffers.insert(std::make_pair(buffer_id, frame)) | 345 client->active_buffers.insert(std::make_pair(buffer->id(), frame)) |
| 332 .second; | 346 .second; |
| 333 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer_id; | 347 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer->id(); |
| 334 count++; | 348 count++; |
| 335 } | 349 } |
| 336 } | 350 } |
| 337 | 351 |
| 338 if (!has_received_frames_) { | 352 if (!has_received_frames_) { |
| 339 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width", | 353 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width", |
| 340 frame->visible_rect().width()); | 354 frame->visible_rect().width()); |
| 341 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height", | 355 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height", |
| 342 frame->visible_rect().height()); | 356 frame->visible_rect().height()); |
| 343 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio", | 357 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio", |
| 344 frame->visible_rect().width(), | 358 frame->visible_rect().width(), |
| 345 frame->visible_rect().height()); | 359 frame->visible_rect().height()); |
| 346 double frame_rate; | 360 double frame_rate; |
| 347 if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, | 361 if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, |
| 348 &frame_rate)) | 362 &frame_rate)) |
| 349 frame_rate = video_capture_format_.frame_rate; | 363 frame_rate = video_capture_format_.frame_rate; |
| 350 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); | 364 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); |
| 351 has_received_frames_ = true; | 365 has_received_frames_ = true; |
| 352 } | 366 } |
| 353 | 367 |
| 354 buffer_pool_->HoldForConsumers(buffer_id, count); | 368 buffer_pool_->HoldForConsumers(buffer->id(), count); |
| 355 } | 369 } |
| 356 | 370 |
| 357 void VideoCaptureController::DoErrorOnIOThread() { | 371 void VideoCaptureController::DoErrorOnIOThread() { |
| 358 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 372 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 359 state_ = VIDEO_CAPTURE_STATE_ERROR; | 373 state_ = VIDEO_CAPTURE_STATE_ERROR; |
| 360 | 374 |
| 361 for (const auto* client : controller_clients_) { | 375 for (const auto* client : controller_clients_) { |
| 362 if (client->session_closed) | 376 if (client->session_closed) |
| 363 continue; | 377 continue; |
| 364 client->event_handler->OnError(client->controller_id); | 378 client->event_handler->OnError(client->controller_id); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 429 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 416 int active_client_count = 0; | 430 int active_client_count = 0; |
| 417 for (ControllerClient* client : controller_clients_) { | 431 for (ControllerClient* client : controller_clients_) { |
| 418 if (!client->paused) | 432 if (!client->paused) |
| 419 ++active_client_count; | 433 ++active_client_count; |
| 420 } | 434 } |
| 421 return active_client_count; | 435 return active_client_count; |
| 422 } | 436 } |
| 423 | 437 |
| 424 } // namespace content | 438 } // namespace content |
| OLD | NEW |