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 |
| 146 #if defined(OS_IOS) || defined(OS_ANDROID) |
| 147 scoped_ptr<uint8[]> i420_intermediate_buffer_; |
| 148 #endif // #if defined(OS_IOS) || defined(OS_ANDROID) |
142 }; | 149 }; |
143 | 150 |
144 VideoCaptureController::VideoCaptureController() | 151 VideoCaptureController::VideoCaptureController() |
145 : state_(VIDEO_CAPTURE_STATE_STARTED), | 152 : state_(VIDEO_CAPTURE_STATE_STARTED), |
146 weak_ptr_factory_(this) { | 153 weak_ptr_factory_(this) { |
147 memset(¤t_params_, 0, sizeof(current_params_)); | 154 memset(¤t_params_, 0, sizeof(current_params_)); |
148 } | 155 } |
149 | 156 |
150 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient( | 157 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient( |
151 const base::WeakPtr<VideoCaptureController>& controller) | 158 const base::WeakPtr<VideoCaptureController>& controller) |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 #else | 405 #else |
399 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( | 406 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame( |
400 const uint8* data, | 407 const uint8* data, |
401 int length, | 408 int length, |
402 base::Time timestamp, | 409 base::Time timestamp, |
403 int rotation, | 410 int rotation, |
404 bool flip_vert, | 411 bool flip_vert, |
405 bool flip_horiz) { | 412 bool flip_horiz) { |
406 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || | 413 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || |
407 frame_info_.color == media::PIXEL_FORMAT_YV12 || | 414 frame_info_.color == media::PIXEL_FORMAT_YV12 || |
| 415 frame_info_.color == media::PIXEL_FORMAT_NV21 || |
408 (rotation == 0 && !flip_vert && !flip_horiz)); | 416 (rotation == 0 && !flip_vert && !flip_horiz)); |
409 | 417 |
410 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); | 418 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); |
411 | 419 |
412 if (!buffer_pool_) | 420 if (!buffer_pool_) |
413 return; | 421 return; |
414 scoped_refptr<media::VideoFrame> dst = | 422 scoped_refptr<media::VideoFrame> dst = |
415 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, | 423 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, |
416 frame_info_.height), | 424 frame_info_.height), |
417 rotation); | 425 rotation); |
(...skipping 14 matching lines...) Expand all Loading... |
432 RotatePackedYV12Frame( | 440 RotatePackedYV12Frame( |
433 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, | 441 data, yplane, uplane, vplane, frame_info_.width, frame_info_.height, |
434 rotation, flip_vert, flip_horiz); | 442 rotation, flip_vert, flip_horiz); |
435 break; | 443 break; |
436 case media::PIXEL_FORMAT_YV12: | 444 case media::PIXEL_FORMAT_YV12: |
437 DCHECK(!chopped_width_ && !chopped_height_); | 445 DCHECK(!chopped_width_ && !chopped_height_); |
438 RotatePackedYV12Frame( | 446 RotatePackedYV12Frame( |
439 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, | 447 data, yplane, vplane, uplane, frame_info_.width, frame_info_.height, |
440 rotation, flip_vert, flip_horiz); | 448 rotation, flip_vert, flip_horiz); |
441 break; | 449 break; |
442 case media::PIXEL_FORMAT_NV21: | 450 case media::PIXEL_FORMAT_NV21: { |
443 DCHECK(!chopped_width_ && !chopped_height_); | 451 DCHECK(!chopped_width_ && !chopped_height_); |
444 media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 452 int num_pixels = frame_info_.width * frame_info_.height; |
| 453 media::ConvertNV21ToYUV(data, |
| 454 &i420_intermediate_buffer_[0], |
| 455 &i420_intermediate_buffer_[num_pixels], |
| 456 &i420_intermediate_buffer_[num_pixels * 5 / 4], |
| 457 frame_info_.width, |
445 frame_info_.height); | 458 frame_info_.height); |
446 break; | 459 RotatePackedYV12Frame( |
| 460 i420_intermediate_buffer_.get(), yplane, uplane, vplane, |
| 461 frame_info_.width, frame_info_.height, |
| 462 rotation, flip_vert, flip_horiz); |
| 463 break; |
| 464 } |
447 case media::PIXEL_FORMAT_YUY2: | 465 case media::PIXEL_FORMAT_YUY2: |
448 DCHECK(!chopped_width_ && !chopped_height_); | 466 DCHECK(!chopped_width_ && !chopped_height_); |
449 if (frame_info_.width * frame_info_.height * 2 != length) { | 467 if (frame_info_.width * frame_info_.height * 2 != length) { |
450 // If |length| of |data| does not match the expected width and height | 468 // 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. | 469 // we can't convert the frame to I420. YUY2 is 2 bytes per pixel. |
452 break; | 470 break; |
453 } | 471 } |
454 | 472 |
455 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, | 473 media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width, |
456 frame_info_.height); | 474 frame_info_.height); |
(...skipping 22 matching lines...) Expand all Loading... |
479 FROM_HERE, | 497 FROM_HERE, |
480 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, | 498 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
481 controller_, dst, timestamp)); | 499 controller_, dst, timestamp)); |
482 } | 500 } |
483 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) | 501 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) |
484 | 502 |
485 void | 503 void |
486 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | 504 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( |
487 const scoped_refptr<media::VideoFrame>& frame, | 505 const scoped_refptr<media::VideoFrame>& frame, |
488 base::Time timestamp) { | 506 base::Time timestamp) { |
489 | |
490 if (!buffer_pool_) | 507 if (!buffer_pool_) |
491 return; | 508 return; |
492 | 509 |
493 // If this is a frame that belongs to the buffer pool, we can forward it | 510 // If this is a frame that belongs to the buffer pool, we can forward it |
494 // directly to the IO thread and be done. | 511 // directly to the IO thread and be done. |
495 if (buffer_pool_->RecognizeReservedBuffer( | 512 if (buffer_pool_->RecognizeReservedBuffer( |
496 frame->shared_memory_handle()) >= 0) { | 513 frame->shared_memory_handle()) >= 0) { |
497 BrowserThread::PostTask(BrowserThread::IO, | 514 BrowserThread::PostTask(BrowserThread::IO, |
498 FROM_HERE, | 515 FROM_HERE, |
499 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, | 516 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 chopped_width_ = 1; | 629 chopped_width_ = 1; |
613 } else { | 630 } else { |
614 chopped_width_ = 0; | 631 chopped_width_ = 0; |
615 } | 632 } |
616 if (info.height & 1) { | 633 if (info.height & 1) { |
617 --frame_info_.height; | 634 --frame_info_.height; |
618 chopped_height_ = 1; | 635 chopped_height_ = 1; |
619 } else { | 636 } else { |
620 chopped_height_ = 0; | 637 chopped_height_ = 0; |
621 } | 638 } |
| 639 #if defined(OS_IOS) || defined(OS_ANDROID) |
| 640 if (frame_info_.color == media::PIXEL_FORMAT_NV21 && |
| 641 !i420_intermediate_buffer_) { |
| 642 i420_intermediate_buffer_.reset( |
| 643 new uint8[frame_info_.width * frame_info_.height * 12 / 8]); |
| 644 } |
| 645 #endif // #if defined(OS_IOS) || defined(OS_ANDROID) |
622 | 646 |
623 DCHECK(!buffer_pool_.get()); | 647 DCHECK(!buffer_pool_.get()); |
624 | 648 |
625 // TODO(nick): Give BufferPool the same lifetime as the controller, have it | 649 // TODO(nick): Give BufferPool the same lifetime as the controller, have it |
626 // support frame size changes, and stop checking it for NULL everywhere. | 650 // support frame size changes, and stop checking it for NULL everywhere. |
627 // http://crbug.com/266082 | 651 // http://crbug.com/266082 |
628 buffer_pool_ = new VideoCaptureBufferPool( | 652 buffer_pool_ = new VideoCaptureBufferPool( |
629 media::VideoFrame::AllocationSize( | 653 media::VideoFrame::AllocationSize( |
630 media::VideoFrame::I420, | 654 media::VideoFrame::I420, |
631 gfx::Size(frame_info_.width, frame_info_.height)), | 655 gfx::Size(frame_info_.width, frame_info_.height)), |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 } | 811 } |
788 return NULL; | 812 return NULL; |
789 } | 813 } |
790 | 814 |
791 int VideoCaptureController::GetClientCount() { | 815 int VideoCaptureController::GetClientCount() { |
792 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
793 return controller_clients_.size(); | 817 return controller_clients_.size(); |
794 } | 818 } |
795 | 819 |
796 } // namespace content | 820 } // namespace content |
OLD | NEW |