| 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 |