| Index: media/capture/video/video_capture_device_client_unittest.cc
 | 
| diff --git a/content/browser/renderer_host/media/video_capture_device_client_unittest.cc b/media/capture/video/video_capture_device_client_unittest.cc
 | 
| similarity index 66%
 | 
| rename from content/browser/renderer_host/media/video_capture_device_client_unittest.cc
 | 
| rename to media/capture/video/video_capture_device_client_unittest.cc
 | 
| index 9e2fcc47556ac318b12af140fc9d4bb388d41403..48d1fecc7e5675f544b979ebab88feb96b7f8b9d 100644
 | 
| --- a/content/browser/renderer_host/media/video_capture_device_client_unittest.cc
 | 
| +++ b/media/capture/video/video_capture_device_client_unittest.cc
 | 
| @@ -11,49 +11,59 @@
 | 
|  #include "base/bind.h"
 | 
|  #include "base/logging.h"
 | 
|  #include "base/macros.h"
 | 
| -#include "base/run_loop.h"
 | 
| -#include "base/single_thread_task_runner.h"
 | 
| -#include "base/threading/thread_task_runner_handle.h"
 | 
|  #include "build/build_config.h"
 | 
| -#include "content/browser/renderer_host/media/video_capture_controller.h"
 | 
| -#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
 | 
| -#include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread.h"
 | 
| -#include "content/public/test/test_browser_thread_bundle.h"
 | 
|  #include "media/base/limits.h"
 | 
|  #include "media/capture/video/video_capture_buffer_pool_impl.h"
 | 
|  #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
 | 
| +#include "media/capture/video/video_capture_jpeg_decoder.h"
 | 
| +#include "media/capture/video/video_frame_receiver.h"
 | 
|  #include "testing/gmock/include/gmock/gmock.h"
 | 
|  #include "testing/gtest/include/gtest/gtest.h"
 | 
|  
 | 
|  using ::testing::_;
 | 
|  using ::testing::Mock;
 | 
|  using ::testing::InSequence;
 | 
| +using ::testing::Invoke;
 | 
|  using ::testing::SaveArg;
 | 
|  
 | 
| -namespace content {
 | 
| +namespace media {
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| -class MockVideoCaptureController : public VideoCaptureController {
 | 
| +class MockVideoCaptureController : public VideoFrameReceiver {
 | 
|   public:
 | 
| -  explicit MockVideoCaptureController() : VideoCaptureController() {}
 | 
| -  ~MockVideoCaptureController() override {}
 | 
| -
 | 
| -  MOCK_METHOD1(MockOnIncomingCapturedVideoFrame, void(const gfx::Size&));
 | 
| +  MOCK_METHOD1(MockOnNewBufferHandle, void(int buffer_id));
 | 
| +  MOCK_METHOD3(
 | 
| +      MockOnFrameReadyInBuffer,
 | 
| +      void(int buffer_id,
 | 
| +           std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::
 | 
| +                               ScopedAccessPermission>* buffer_read_permission,
 | 
| +           const gfx::Size&));
 | 
|    MOCK_METHOD0(OnError, void());
 | 
|    MOCK_METHOD1(OnLog, void(const std::string& message));
 | 
|    MOCK_METHOD1(OnBufferRetired, void(int buffer_id));
 | 
|  
 | 
| -  void OnIncomingCapturedVideoFrame(
 | 
| -      media::VideoCaptureDevice::Client::Buffer buffer,
 | 
| -      scoped_refptr<media::VideoFrame> frame) override {
 | 
| -    MockOnIncomingCapturedVideoFrame(frame->coded_size());
 | 
| +  void OnNewBufferHandle(
 | 
| +      int buffer_id,
 | 
| +      std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::HandleProvider>
 | 
| +          handle_provider) override {
 | 
| +    MockOnNewBufferHandle(buffer_id);
 | 
| +  }
 | 
| +
 | 
| +  void OnFrameReadyInBuffer(
 | 
| +      int32_t buffer_id,
 | 
| +      int frame_feedback_id,
 | 
| +      std::unique_ptr<
 | 
| +          media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>
 | 
| +          buffer_read_permission,
 | 
| +      media::mojom::VideoFrameInfoPtr frame_info) override {
 | 
| +    MockOnFrameReadyInBuffer(buffer_id, &buffer_read_permission,
 | 
| +                             frame_info->coded_size);
 | 
|    }
 | 
|  };
 | 
|  
 | 
| -std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
 | 
| -    const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) {
 | 
| -  return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb);
 | 
| +std::unique_ptr<media::VideoCaptureJpegDecoder> ReturnNullPtrAsJpecDecoder() {
 | 
| +  return nullptr;
 | 
|  }
 | 
|  
 | 
|  // Test fixture for testing a unit consisting of an instance of
 | 
| @@ -63,29 +73,21 @@ std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
 | 
|  // production.
 | 
|  class VideoCaptureDeviceClientTest : public ::testing::Test {
 | 
|   public:
 | 
| -  VideoCaptureDeviceClientTest()
 | 
| -      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
 | 
| +  VideoCaptureDeviceClientTest() {
 | 
|      scoped_refptr<media::VideoCaptureBufferPoolImpl> buffer_pool(
 | 
|          new media::VideoCaptureBufferPoolImpl(
 | 
|              base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
 | 
|              1));
 | 
| -    controller_ = base::MakeUnique<MockVideoCaptureController>();
 | 
| +    auto controller = base::MakeUnique<MockVideoCaptureController>();
 | 
| +    controller_ = controller.get();
 | 
|      device_client_ = base::MakeUnique<media::VideoCaptureDeviceClient>(
 | 
| -        base::MakeUnique<VideoFrameReceiverOnIOThread>(
 | 
| -            controller_->GetWeakPtrForIOThread()),
 | 
| -        buffer_pool,
 | 
| -        base::Bind(
 | 
| -            &CreateGpuJpegDecoder,
 | 
| -            base::Bind(&media::VideoFrameReceiver::OnIncomingCapturedVideoFrame,
 | 
| -                       controller_->GetWeakPtrForIOThread())));
 | 
| +        std::move(controller), buffer_pool,
 | 
| +        base::Bind(&ReturnNullPtrAsJpecDecoder));
 | 
|    }
 | 
|    ~VideoCaptureDeviceClientTest() override {}
 | 
|  
 | 
| -  void TearDown() override { base::RunLoop().RunUntilIdle(); }
 | 
| -
 | 
|   protected:
 | 
| -  const content::TestBrowserThreadBundle thread_bundle_;
 | 
| -  std::unique_ptr<MockVideoCaptureController> controller_;
 | 
| +  MockVideoCaptureController* controller_;
 | 
|    std::unique_ptr<media::VideoCaptureDeviceClient> device_client_;
 | 
|  
 | 
|   private:
 | 
| @@ -100,17 +102,23 @@ TEST_F(VideoCaptureDeviceClientTest, Minimal) {
 | 
|    const size_t kScratchpadSizeInBytes = 400;
 | 
|    unsigned char data[kScratchpadSizeInBytes] = {};
 | 
|    const media::VideoCaptureFormat kFrameFormat(
 | 
| -      gfx::Size(10, 10), 30.0f /*frame_rate*/,
 | 
| -      media::PIXEL_FORMAT_I420,
 | 
| +      gfx::Size(10, 10), 30.0f /*frame_rate*/, media::PIXEL_FORMAT_I420,
 | 
|        media::PIXEL_STORAGE_CPU);
 | 
|    DCHECK(device_client_.get());
 | 
| -  EXPECT_CALL(*controller_, OnLog(_)).Times(1);
 | 
| -  EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1);
 | 
| +  {
 | 
| +    InSequence s;
 | 
| +    const int expected_buffer_id = 0;
 | 
| +    EXPECT_CALL(*controller_, OnLog(_));
 | 
| +    EXPECT_CALL(*controller_, MockOnNewBufferHandle(expected_buffer_id));
 | 
| +    EXPECT_CALL(*controller_,
 | 
| +                MockOnFrameReadyInBuffer(expected_buffer_id, _, _));
 | 
| +    EXPECT_CALL(*controller_, OnBufferRetired(expected_buffer_id));
 | 
| +  }
 | 
|    device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes,
 | 
|                                           kFrameFormat, 0 /*clockwise rotation*/,
 | 
|                                           base::TimeTicks(), base::TimeDelta());
 | 
| -  base::RunLoop().RunUntilIdle();
 | 
| -  Mock::VerifyAndClearExpectations(controller_.get());
 | 
| +  // Releasing |device_client_| will also release |controller_|.
 | 
| +  device_client_.reset();
 | 
|  }
 | 
|  
 | 
|  // Tests that we don't try to pass on frames with an invalid frame format.
 | 
| @@ -126,12 +134,11 @@ TEST_F(VideoCaptureDeviceClientTest, FailsSilentlyGivenInvalidFrameFormat) {
 | 
|    DCHECK(device_client_.get());
 | 
|    // Expect the the call to fail silently inside the VideoCaptureDeviceClient.
 | 
|    EXPECT_CALL(*controller_, OnLog(_)).Times(1);
 | 
| -  EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(0);
 | 
| +  EXPECT_CALL(*controller_, MockOnFrameReadyInBuffer(_, _, _)).Times(0);
 | 
|    device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes,
 | 
|                                           kFrameFormat, 0 /*clockwise rotation*/,
 | 
|                                           base::TimeTicks(), base::TimeDelta());
 | 
| -  base::RunLoop().RunUntilIdle();
 | 
| -  Mock::VerifyAndClearExpectations(controller_.get());
 | 
| +  Mock::VerifyAndClearExpectations(controller_);
 | 
|  }
 | 
|  
 | 
|  // Tests that we fail silently if no available buffers to use.
 | 
| @@ -139,13 +146,23 @@ TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) {
 | 
|    const size_t kScratchpadSizeInBytes = 400;
 | 
|    unsigned char data[kScratchpadSizeInBytes] = {};
 | 
|    const media::VideoCaptureFormat kFrameFormat(
 | 
| -      gfx::Size(10, 10), 30.0f /*frame_rate*/,
 | 
| -      media::PIXEL_FORMAT_I420,
 | 
| +      gfx::Size(10, 10), 30.0f /*frame_rate*/, media::PIXEL_FORMAT_I420,
 | 
|        media::PIXEL_STORAGE_CPU);
 | 
| -  // We expect the second frame to be silently dropped, so these should
 | 
| -  // only be called once despite the two frames.
 | 
|    EXPECT_CALL(*controller_, OnLog(_)).Times(1);
 | 
| -  EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1);
 | 
| +  // Simulate that receiver still holds |buffer_read_permission| for the first
 | 
| +  // buffer when the second call to OnIncomingCapturedData comes in.
 | 
| +  // Since we set up the buffer pool to max out at 1 buffer, this should cause
 | 
| +  // |device_client_| to drop the frame.
 | 
| +  std::unique_ptr<VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>
 | 
| +      read_permission;
 | 
| +  EXPECT_CALL(*controller_, MockOnFrameReadyInBuffer(_, _, _))
 | 
| +      .WillOnce(Invoke([&read_permission](
 | 
| +          int buffer_id,
 | 
| +          std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::
 | 
| +                              ScopedAccessPermission>* buffer_read_permission,
 | 
| +          const gfx::Size&) {
 | 
| +        read_permission = std::move(*buffer_read_permission);
 | 
| +      }));
 | 
|    // Pass two frames. The second will be dropped.
 | 
|    device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes,
 | 
|                                           kFrameFormat, 0 /*clockwise rotation*/,
 | 
| @@ -153,8 +170,7 @@ TEST_F(VideoCaptureDeviceClientTest, DropsFrameIfNoBuffer) {
 | 
|    device_client_->OnIncomingCapturedData(data, kScratchpadSizeInBytes,
 | 
|                                           kFrameFormat, 0 /*clockwise rotation*/,
 | 
|                                           base::TimeTicks(), base::TimeDelta());
 | 
| -  base::RunLoop().RunUntilIdle();
 | 
| -  Mock::VerifyAndClearExpectations(controller_.get());
 | 
| +  Mock::VerifyAndClearExpectations(controller_);
 | 
|  }
 | 
|  
 | 
|  // Tests that buffer-based capture API accepts some memory-backed pixel formats.
 | 
| @@ -194,13 +210,12 @@ TEST_F(VideoCaptureDeviceClientTest, DataCaptureGoodPixelFormats) {
 | 
|      params.requested_format.pixel_format = format;
 | 
|  
 | 
|      EXPECT_CALL(*controller_, OnLog(_)).Times(1);
 | 
| -    EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_)).Times(1);
 | 
| +    EXPECT_CALL(*controller_, MockOnFrameReadyInBuffer(_, _, _)).Times(1);
 | 
|      device_client_->OnIncomingCapturedData(
 | 
|          data, params.requested_format.ImageAllocationSize(),
 | 
|          params.requested_format, 0 /* clockwise_rotation */, base::TimeTicks(),
 | 
|          base::TimeDelta());
 | 
| -    base::RunLoop().RunUntilIdle();
 | 
| -    Mock::VerifyAndClearExpectations(controller_.get());
 | 
| +    Mock::VerifyAndClearExpectations(controller_);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -211,14 +226,10 @@ TEST_F(VideoCaptureDeviceClientTest, CheckRotationsAndCrops) {
 | 
|      gfx::Size input_resolution;
 | 
|      int rotation;
 | 
|      gfx::Size output_resolution;
 | 
| -  } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}},
 | 
| -                           {{6, 4}, 90, {4, 6}},
 | 
| -                           {{6, 4}, 180, {6, 4}},
 | 
| -                           {{6, 4}, 270, {4, 6}},
 | 
| -                           {{7, 4}, 0, {6, 4}},
 | 
| -                           {{7, 4}, 90, {4, 6}},
 | 
| -                           {{7, 4}, 180, {6, 4}},
 | 
| -                           {{7, 4}, 270, {4, 6}}};
 | 
| +  } kSizeAndRotations[] = {{{6, 4}, 0, {6, 4}},   {{6, 4}, 90, {4, 6}},
 | 
| +                           {{6, 4}, 180, {6, 4}}, {{6, 4}, 270, {4, 6}},
 | 
| +                           {{7, 4}, 0, {6, 4}},   {{7, 4}, 90, {4, 6}},
 | 
| +                           {{7, 4}, 180, {6, 4}}, {{7, 4}, 270, {4, 6}}};
 | 
|  
 | 
|    // The usual ReserveOutputBuffer() -> OnIncomingCapturedVideoFrame() cannot
 | 
|    // be used since it does not resolve rotations or crops. The memory backed
 | 
| @@ -234,25 +245,23 @@ TEST_F(VideoCaptureDeviceClientTest, CheckRotationsAndCrops) {
 | 
|      ASSERT_GE(kScratchpadSizeInBytes,
 | 
|                size_and_rotation.input_resolution.GetArea() * 4u)
 | 
|          << "Scratchpad is too small to hold the largest pixel format (ARGB).";
 | 
| -    params.requested_format =
 | 
| -        media::VideoCaptureFormat(size_and_rotation.input_resolution, 30.0f,
 | 
| -                                  media::PIXEL_FORMAT_ARGB);
 | 
| +    params.requested_format = media::VideoCaptureFormat(
 | 
| +        size_and_rotation.input_resolution, 30.0f, media::PIXEL_FORMAT_ARGB);
 | 
|      gfx::Size coded_size;
 | 
| -    EXPECT_CALL(*controller_, MockOnIncomingCapturedVideoFrame(_))
 | 
| +    EXPECT_CALL(*controller_, MockOnFrameReadyInBuffer(_, _, _))
 | 
|          .Times(1)
 | 
| -        .WillOnce(SaveArg<0>(&coded_size));
 | 
| +        .WillOnce(SaveArg<2>(&coded_size));
 | 
|      device_client_->OnIncomingCapturedData(
 | 
|          data, params.requested_format.ImageAllocationSize(),
 | 
|          params.requested_format, size_and_rotation.rotation, base::TimeTicks(),
 | 
|          base::TimeDelta());
 | 
| -    base::RunLoop().RunUntilIdle();
 | 
|  
 | 
|      EXPECT_EQ(coded_size.width(), size_and_rotation.output_resolution.width());
 | 
|      EXPECT_EQ(coded_size.height(),
 | 
|                size_and_rotation.output_resolution.height());
 | 
|  
 | 
| -    Mock::VerifyAndClearExpectations(controller_.get());
 | 
| +    Mock::VerifyAndClearExpectations(controller_);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -}  // namespace content
 | 
| +}  // namespace media
 | 
| 
 |