| 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/media/capture/web_contents_video_capture_device.h" | 5 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
| 6 | 6 |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/debug/debugger.h" | 8 #include "base/debug/debugger.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "content/public/test/test_browser_context.h" | 23 #include "content/public/test/test_browser_context.h" |
| 24 #include "content/public/test/test_browser_thread_bundle.h" | 24 #include "content/public/test/test_browser_thread_bundle.h" |
| 25 #include "content/public/test/test_utils.h" | 25 #include "content/public/test/test_utils.h" |
| 26 #include "content/test/test_render_view_host.h" | 26 #include "content/test/test_render_view_host.h" |
| 27 #include "content/test/test_web_contents.h" | 27 #include "content/test/test_web_contents.h" |
| 28 #include "media/base/video_capture_types.h" | 28 #include "media/base/video_capture_types.h" |
| 29 #include "media/base/video_frame.h" | 29 #include "media/base/video_frame.h" |
| 30 #include "media/base/video_util.h" | 30 #include "media/base/video_util.h" |
| 31 #include "media/base/yuv_convert.h" | 31 #include "media/base/yuv_convert.h" |
| 32 #include "skia/ext/platform_canvas.h" | 32 #include "skia/ext/platform_canvas.h" |
| 33 #include "testing/gmock/include/gmock/gmock.h" |
| 33 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
| 34 #include "third_party/skia/include/core/SkColor.h" | 35 #include "third_party/skia/include/core/SkColor.h" |
| 35 #include "ui/gfx/display.h" | 36 #include "ui/gfx/display.h" |
| 36 #include "ui/gfx/screen.h" | 37 #include "ui/gfx/screen.h" |
| 37 | 38 |
| 38 namespace content { | 39 namespace content { |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 const int kTestWidth = 320; | 42 const int kTestWidth = 320; |
| 42 const int kTestHeight = 240; | 43 const int kTestHeight = 240; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 class StubClient : public media::VideoCaptureDevice::Client { | 309 class StubClient : public media::VideoCaptureDevice::Client { |
| 309 public: | 310 public: |
| 310 StubClient(const base::Callback<void(SkColor)>& color_callback, | 311 StubClient(const base::Callback<void(SkColor)>& color_callback, |
| 311 const base::Closure& error_callback) | 312 const base::Closure& error_callback) |
| 312 : color_callback_(color_callback), | 313 : color_callback_(color_callback), |
| 313 error_callback_(error_callback) { | 314 error_callback_(error_callback) { |
| 314 buffer_pool_ = new VideoCaptureBufferPool(2); | 315 buffer_pool_ = new VideoCaptureBufferPool(2); |
| 315 } | 316 } |
| 316 ~StubClient() override {} | 317 ~StubClient() override {} |
| 317 | 318 |
| 318 void OnIncomingCapturedData(const uint8* data, | 319 MOCK_METHOD5(OnIncomingCapturedData, |
| 319 int length, | 320 void(const uint8* data, |
| 320 const media::VideoCaptureFormat& frame_format, | 321 int length, |
| 321 int rotation, | 322 const media::VideoCaptureFormat& frame_format, |
| 322 const base::TimeTicks& timestamp) override { | 323 int rotation, |
| 323 FAIL(); | 324 const base::TimeTicks& timestamp)); |
| 324 } | 325 MOCK_METHOD9(OnIncomingCapturedYuvData, |
| 326 void (const uint8* y_data, |
| 327 const uint8* u_data, |
| 328 const uint8* v_data, |
| 329 size_t y_stride, |
| 330 size_t u_stride, |
| 331 size_t v_stride, |
| 332 const media::VideoCaptureFormat& frame_format, |
| 333 int clockwise_rotation, |
| 334 const base::TimeTicks& timestamp)); |
| 325 | 335 |
| 326 void OnIncomingCapturedYuvData(const uint8* y_data, | 336 MOCK_METHOD3(OnIncomingCapturedBuffer, |
| 327 const uint8* u_data, | 337 void(const scoped_refptr<Buffer>& buffer, |
| 328 const uint8* v_data, | 338 const media::VideoCaptureFormat& frame_format, |
| 329 size_t y_stride, | 339 const base::TimeTicks& timestamp)); |
| 330 size_t u_stride, | |
| 331 size_t v_stride, | |
| 332 const media::VideoCaptureFormat& frame_format, | |
| 333 int clockwise_rotation, | |
| 334 const base::TimeTicks& timestamp) override { | |
| 335 FAIL(); | |
| 336 } | |
| 337 | 340 |
| 338 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer( | 341 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> ReserveOutputBuffer( |
| 339 media::VideoPixelFormat format, | 342 media::VideoPixelFormat format, |
| 340 const gfx::Size& dimensions) override { | 343 const gfx::Size& dimensions) override { |
| 341 CHECK_EQ(format, media::PIXEL_FORMAT_I420); | 344 CHECK_EQ(format, media::PIXEL_FORMAT_I420); |
| 342 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. | 345 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; // Ignored. |
| 343 int buffer_id = buffer_pool_->ReserveForProducer(format, dimensions, | 346 int buffer_id = buffer_pool_->ReserveForProducer(format, dimensions, |
| 344 &buffer_id_to_drop); | 347 &buffer_id_to_drop); |
| 345 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 348 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
| 346 return NULL; | 349 return NULL; |
| 347 void* data; | 350 |
| 348 size_t size; | 351 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle = |
| 349 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); | 352 buffer_pool_->GetBufferHandle(buffer_id); |
| 350 return scoped_refptr<media::VideoCaptureDevice::Client::Buffer>( | 353 return scoped_refptr<media::VideoCaptureDevice::Client::Buffer>( |
| 351 new AutoReleaseBuffer(buffer_pool_, buffer_id, data, size)); | 354 new AutoReleaseBuffer(buffer_pool_, buffer_handle.Pass(), buffer_id)); |
| 352 } | 355 } |
| 353 | 356 |
| 354 void OnIncomingCapturedVideoFrame( | 357 void OnIncomingCapturedVideoFrame( |
| 355 const scoped_refptr<Buffer>& buffer, | 358 const scoped_refptr<Buffer>& buffer, |
| 356 const scoped_refptr<media::VideoFrame>& frame, | 359 const scoped_refptr<media::VideoFrame>& frame, |
| 357 const base::TimeTicks& timestamp) override { | 360 const base::TimeTicks& timestamp) override { |
| 358 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size()); | 361 EXPECT_EQ(gfx::Size(kTestWidth, kTestHeight), frame->visible_rect().size()); |
| 359 EXPECT_EQ(media::VideoFrame::I420, frame->format()); | 362 EXPECT_EQ(media::VideoFrame::I420, frame->format()); |
| 360 double frame_rate = 0; | 363 double frame_rate = 0; |
| 361 EXPECT_TRUE( | 364 EXPECT_TRUE( |
| 362 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, | 365 frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, |
| 363 &frame_rate)); | 366 &frame_rate)); |
| 364 EXPECT_EQ(kTestFramesPerSecond, frame_rate); | 367 EXPECT_EQ(kTestFramesPerSecond, frame_rate); |
| 365 uint8 yuv[3]; | 368 uint8 yuv[3]; |
| 366 for (int plane = 0; plane < 3; ++plane) | 369 for (int plane = 0; plane < 3; ++plane) |
| 367 yuv[plane] = frame->visible_data(plane)[0]; | 370 yuv[plane] = frame->visible_data(plane)[0]; |
| 368 // TODO(nick): We just look at the first pixel presently, because if | 371 // TODO(nick): We just look at the first pixel presently, because if |
| 369 // the analysis is too slow, the backlog of frames will grow without bound | 372 // the analysis is too slow, the backlog of frames will grow without bound |
| 370 // and trouble erupts. http://crbug.com/174519 | 373 // and trouble erupts. http://crbug.com/174519 |
| 371 color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2]))); | 374 color_callback_.Run((SkColorSetRGB(yuv[0], yuv[1], yuv[2]))); |
| 372 } | 375 } |
| 373 | 376 |
| 374 void OnError(const std::string& reason) override { error_callback_.Run(); } | 377 void OnError(const std::string& reason) override { error_callback_.Run(); } |
| 375 | 378 |
| 376 private: | 379 private: |
| 377 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { | 380 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { |
| 378 public: | 381 public: |
| 379 AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, | 382 AutoReleaseBuffer( |
| 380 int buffer_id, | 383 const scoped_refptr<VideoCaptureBufferPool>& pool, |
| 381 void* data, | 384 scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle, |
| 382 size_t size) | 385 int buffer_id) |
| 383 : pool_(pool), | 386 : pool_(pool), |
| 384 id_(buffer_id), | 387 id_(buffer_id), |
| 385 data_(data), | 388 buffer_handle_(buffer_handle.Pass()) { |
| 386 size_(size) { | |
| 387 DCHECK(pool_.get()); | 389 DCHECK(pool_.get()); |
| 388 } | 390 } |
| 389 int id() const override { return id_; } | 391 int id() const override { return id_; } |
| 390 void* data() const override { return data_; } | 392 size_t size() const override { return buffer_handle_->size(); } |
| 391 size_t size() const override { return size_; } | 393 scoped_ptr<media::DataHandle> GetDataHandle() override { |
| 394 return buffer_handle_->GetDataHandle().Pass(); |
| 395 } |
| 396 ClientBuffer AsClientBuffer() override { return nullptr; } |
| 392 | 397 |
| 393 private: | 398 private: |
| 394 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } | 399 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } |
| 395 | 400 |
| 396 const scoped_refptr<VideoCaptureBufferPool> pool_; | 401 const scoped_refptr<VideoCaptureBufferPool> pool_; |
| 397 const int id_; | 402 const int id_; |
| 398 void* const data_; | 403 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; |
| 399 const size_t size_; | |
| 400 }; | 404 }; |
| 401 | 405 |
| 402 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; | 406 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; |
| 403 base::Callback<void(SkColor)> color_callback_; | 407 base::Callback<void(SkColor)> color_callback_; |
| 404 base::Closure error_callback_; | 408 base::Closure error_callback_; |
| 405 | 409 |
| 406 DISALLOW_COPY_AND_ASSIGN(StubClient); | 410 DISALLOW_COPY_AND_ASSIGN(StubClient); |
| 407 }; | 411 }; |
| 408 | 412 |
| 409 class StubClientObserver { | 413 class StubClientObserver { |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 source()->SetSolidColor(SK_ColorGREEN); | 871 source()->SetSolidColor(SK_ColorGREEN); |
| 868 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); | 872 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorGREEN)); |
| 869 source()->SetSolidColor(SK_ColorRED); | 873 source()->SetSolidColor(SK_ColorRED); |
| 870 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); | 874 ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForNextColor(SK_ColorRED)); |
| 871 | 875 |
| 872 device()->StopAndDeAllocate(); | 876 device()->StopAndDeAllocate(); |
| 873 } | 877 } |
| 874 | 878 |
| 875 } // namespace | 879 } // namespace |
| 876 } // namespace content | 880 } // namespace content |
| OLD | NEW |