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 <set> | 7 #include <set> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 // The pool of shared-memory buffers used for capturing. | 132 // The pool of shared-memory buffers used for capturing. |
133 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; | 133 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; |
134 | 134 |
135 // Chopped pixels in width/height in case video capture device has odd | 135 // Chopped pixels in width/height in case video capture device has odd |
136 // numbers for width/height. | 136 // numbers for width/height. |
137 int chopped_width_; | 137 int chopped_width_; |
138 int chopped_height_; | 138 int chopped_height_; |
139 | 139 |
140 // Tracks the current frame format. | 140 // Tracks the current frame format. |
141 media::VideoCaptureCapability frame_info_; | 141 media::VideoCaptureCapability frame_info_; |
142 | |
143 // For NV21 we have to do color conversion into the intermediate buffer and | |
144 // from there the rotations. This variable won't be needed after | |
145 // http://crbug.com/292400 . | |
scherkus (not reviewing)
2013/09/17 01:52:56
nit: remove trailing " ."
mcasas
2013/09/17 15:38:36
Done.
| |
146 #if defined(OS_IOS) || defined(OS_ANDROID) | |
147 scoped_ptr<uint8[]> i420_intermediate_buffer_; | |
148 #endif // #if defined(OS_IOS) || defined(OS_ANDROID) | |
149 | |
scherkus (not reviewing)
2013/09/17 01:52:56
remove extra blank line
mcasas
2013/09/17 15:38:36
Done.
| |
142 }; | 150 }; |
143 | 151 |
144 VideoCaptureController::VideoCaptureController() | 152 VideoCaptureController::VideoCaptureController() |
145 : state_(VIDEO_CAPTURE_STATE_STARTED), | 153 : state_(VIDEO_CAPTURE_STATE_STARTED), |
146 weak_ptr_factory_(this) { | 154 weak_ptr_factory_(this) { |
147 memset(¤t_params_, 0, sizeof(current_params_)); | 155 memset(¤t_params_, 0, sizeof(current_params_)); |
148 } | 156 } |
149 | 157 |
150 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient( | 158 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient( |
151 const base::WeakPtr<VideoCaptureController>& controller) | 159 const base::WeakPtr<VideoCaptureController>& controller) |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); | 270 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); |
263 } | 271 } |
264 | 272 |
265 scoped_refptr<media::VideoFrame> | 273 scoped_refptr<media::VideoFrame> |
266 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer() { | 274 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer() { |
267 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, | 275 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, |
268 frame_info_.height), | 276 frame_info_.height), |
269 0); | 277 0); |
270 } | 278 } |
271 | 279 |
272 #if !defined(OS_IOS) && !defined(OS_ANDROID) | 280 #if !defined(OS_IOS) && !defined(OS_ANDROID) |
scherkus (not reviewing)
2013/09/17 01:52:56
what about fischman's proposal for a more accurate
mcasas
2013/09/17 15:38:36
Totally accepted but not done in this cl, tracked
| |
273 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( | 281 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( |
274 const uint8* data, | 282 const uint8* data, |
275 int length, | 283 int length, |
276 base::Time timestamp, | 284 base::Time timestamp, |
277 int rotation, | 285 int rotation, |
278 bool flip_vert, | 286 bool flip_vert, |
279 bool flip_horiz) { | 287 bool flip_horiz) { |
280 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); | 288 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
281 | 289 |
282 if (!buffer_pool_.get()) | 290 if (!buffer_pool_.get()) |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 #else | 406 #else |
399 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( | 407 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( |
400 const uint8* data, | 408 const uint8* data, |
401 int length, | 409 int length, |
402 base::Time timestamp, | 410 base::Time timestamp, |
403 int rotation, | 411 int rotation, |
404 bool flip_vert, | 412 bool flip_vert, |
405 bool flip_horiz) { | 413 bool flip_horiz) { |
406 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || | 414 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || |
407 frame_info_.color == media::PIXEL_FORMAT_YV12 || | 415 frame_info_.color == media::PIXEL_FORMAT_YV12 || |
416 frame_info_.color == media::PIXEL_FORMAT_NV21 || | |
408 (rotation == 0 && !flip_vert && !flip_horiz)); | 417 (rotation == 0 && !flip_vert && !flip_horiz)); |
409 | 418 |
410 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); | 419 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
411 | 420 |
412 if (!buffer_pool_) | 421 if (!buffer_pool_) |
413 return; | 422 return; |
414 scoped_refptr<media::VideoFrame> dst = | 423 scoped_refptr<media::VideoFrame> dst = |
415 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, | 424 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, |
416 frame_info_.height), | 425 frame_info_.height), |
417 rotation); | 426 rotation); |
(...skipping 14 matching lines...) Expand all Loading... | |
432 RotatePackedYV12Frame( | 441 RotatePackedYV12Frame( |
433 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, | 442 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, |
434 rotation, flip_vert, flip_horiz); | 443 rotation, flip_vert, flip_horiz); |
435 break; | 444 break; |
436 case media::PIXEL_FORMAT_YV12: | 445 case media::PIXEL_FORMAT_YV12: |
437 DCHECK(!chopped_width_ && !chopped_height_); | 446 DCHECK(!chopped_width_ && !chopped_height_); |
438 RotatePackedYV12Frame( | 447 RotatePackedYV12Frame( |
439 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, | 448 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, |
440 rotation, flip_vert, flip_horiz); | 449 rotation, flip_vert, flip_horiz); |
441 break; | 450 break; |
442 case media::PIXEL_FORMAT_NV21: | 451 case media::PIXEL_FORMAT_NV21: { |
443 DCHECK(!chopped_width_ && !chopped_height_); | 452 DCHECK(!chopped_width_ && !chopped_height_); |
444 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 453 int num_pixels = frame_info_.width * frame_info_.height; |
454 media::ConvertNV21ToYUV(data, | |
455 &i420_intermediate_buffer_[0], | |
456 &i420_intermediate_buffer_[num_pixels], | |
457 &i420_intermediate_buffer_[num_pixels * 5 / 4], | |
458 frame_info_.width, | |
445 frame_info_.height); | 459 frame_info_.height); |
446 break; | 460 RotatePackedYV12Frame( |
461 &i420_intermediate_buffer_[0], yplane, uplane, vplane, | |
scherkus (not reviewing)
2013/09/17 01:52:56
i420_intermedia_buffer_.get() ?
mcasas
2013/09/17 15:38:36
Done.
| |
462 frame_info_.width, frame_info_.height, | |
463 rotation, flip_vert, flip_horiz); | |
464 break; | |
465 } | |
447 case media::PIXEL_FORMAT_YUY2: | 466 case media::PIXEL_FORMAT_YUY2: |
448 DCHECK(!chopped_width_ && !chopped_height_); | 467 DCHECK(!chopped_width_ && !chopped_height_); |
449 if (frame_info_.width * frame_info_.height * 2 != length) { | 468 if (frame_info_.width * frame_info_.height * 2 != length) { |
450 // If |length| of |data| does not match the expected width and height | 469 // If |length| of |data| does not match the expected width and height |
451 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. | 470 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. |
452 break; | 471 break; |
453 } | 472 } |
454 | 473 |
455 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 474 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
456 frame_info_.height); | 475 frame_info_.height); |
(...skipping 22 matching lines...) Expand all Loading... | |
479 FROM_HERE, | 498 FROM_HERE, |
480 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, | 499 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
481 controller_, dst, timestamp)); | 500 controller_, dst, timestamp)); |
482 } | 501 } |
483 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) | 502 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) |
484 | 503 |
485 void | 504 void |
486 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | 505 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( |
487 const scoped_refptr<media::VideoFrame>& frame, | 506 const scoped_refptr<media::VideoFrame>& frame, |
488 base::Time timestamp) { | 507 base::Time timestamp) { |
489 | 508 |
scherkus (not reviewing)
2013/09/17 01:52:56
remove extra blank line here
mcasas
2013/09/17 15:38:36
Done.
| |
490 if (!buffer_pool_) | 509 if (!buffer_pool_) |
491 return; | 510 return; |
492 | 511 |
493 // If this is a frame that belongs to the buffer pool, we can forward it | 512 // If this is a frame that belongs to the buffer pool, we can forward it |
494 // directly to the IO thread and be done. | 513 // directly to the IO thread and be done. |
495 if (buffer_pool_->RecognizeReservedBuffer( | 514 if (buffer_pool_->RecognizeReservedBuffer( |
496 frame->shared_memory_handle()) >= 0) { | 515 frame->shared_memory_handle()) >= 0) { |
497 BrowserThread::PostTask(BrowserThread::IO, | 516 BrowserThread::PostTask(BrowserThread::IO, |
498 FROM_HERE, | 517 FROM_HERE, |
499 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, | 518 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
612 chopped_width_ = 1; | 631 chopped_width_ = 1; |
613 } else { | 632 } else { |
614 chopped_width_ = 0; | 633 chopped_width_ = 0; |
615 } | 634 } |
616 if (info.height & 1) { | 635 if (info.height & 1) { |
617 --frame_info_.height; | 636 --frame_info_.height; |
618 chopped_height_ = 1; | 637 chopped_height_ = 1; |
619 } else { | 638 } else { |
620 chopped_height_ = 0; | 639 chopped_height_ = 0; |
621 } | 640 } |
641 #if defined(OS_IOS) || defined(OS_ANDROID) | |
642 if ((frame_info_.color == media::PIXEL_FORMAT_NV21) && | |
scherkus (not reviewing)
2013/09/17 01:52:56
drop extra ( ) around comparisons
mcasas
2013/09/17 15:38:36
Done.
| |
643 (i420_intermediate_buffer_.get() == NULL)) { | |
scherkus (not reviewing)
2013/09/17 01:52:56
scoped_ptr<T> allows pointers to be testable, so y
mcasas
2013/09/17 15:38:36
Done.
| |
644 i420_intermediate_buffer_.reset( | |
645 new uint8[frame_info_.width * frame_info_.height * 12 / 8]); | |
646 } | |
647 #endif // #if defined(OS_IOS) || defined(OS_ANDROID) | |
622 | 648 |
623 DCHECK(!buffer_pool_.get()); | 649 DCHECK(!buffer_pool_.get()); |
624 | 650 |
625 // TODO(nick): Give BufferPool the same lifetime as the controller, have it | 651 // TODO(nick): Give BufferPool the same lifetime as the controller, have it |
626 // support frame size changes, and stop checking it for NULL everywhere. | 652 // support frame size changes, and stop checking it for NULL everywhere. |
627 // http://crbug.com/266082 | 653 // http://crbug.com/266082 |
628 buffer_pool_ = new VideoCaptureBufferPool( | 654 buffer_pool_ = new VideoCaptureBufferPool( |
629 media::VideoFrame::AllocationSize( | 655 media::VideoFrame::AllocationSize( |
630 media::VideoFrame::I420, | 656 media::VideoFrame::I420, |
631 gfx::Size(frame_info_.width, frame_info_.height)), | 657 gfx::Size(frame_info_.width, frame_info_.height)), |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 } | 813 } |
788 return NULL; | 814 return NULL; |
789 } | 815 } |
790 | 816 |
791 int VideoCaptureController::GetClientCount() { | 817 int VideoCaptureController::GetClientCount() { |
792 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 818 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
793 return controller_clients_.size(); | 819 return controller_clients_.size(); |
794 } | 820 } |
795 | 821 |
796 } // namespace content | 822 } // namespace content |
OLD | NEW |