Home | History | Annotate | Download | only in media
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/message_loop/message_loop.h"
      6 #include "content/child/child_process.h"
      7 #include "content/common/media/video_capture_messages.h"
      8 #include "content/renderer/media/video_capture_impl.h"
      9 #include "media/base/bind_to_current_loop.h"
     10 #include "testing/gmock/include/gmock/gmock.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 using ::testing::_;
     14 using ::testing::AtLeast;
     15 using ::testing::InvokeWithoutArgs;
     16 using ::testing::Return;
     17 using ::testing::SaveArg;
     18 
     19 namespace content {
     20 
     21 class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter {
     22  public:
     23   MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {}
     24 
     25   // Filter implementation.
     26   MOCK_METHOD1(Send, bool(IPC::Message* message));
     27 
     28  protected:
     29   virtual ~MockVideoCaptureMessageFilter() {}
     30 
     31  private:
     32   DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter);
     33 };
     34 
     35 class VideoCaptureImplTest : public ::testing::Test {
     36  public:
     37   class MockVideoCaptureImpl : public VideoCaptureImpl {
     38    public:
     39     MockVideoCaptureImpl(const media::VideoCaptureSessionId id,
     40                          VideoCaptureMessageFilter* filter)
     41         : VideoCaptureImpl(id, filter) {
     42     }
     43     virtual ~MockVideoCaptureImpl() {}
     44 
     45     // Override Send() to mimic device to send events.
     46     virtual void Send(IPC::Message* message) OVERRIDE {
     47       CHECK(message);
     48 
     49       // In this method, messages are sent to the according handlers as if
     50       // we are the device.
     51       bool handled = true;
     52       IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
     53         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture)
     54         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
     55         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
     56         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
     57                             DeviceReceiveEmptyBuffer)
     58         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
     59                             DeviceGetSupportedFormats)
     60         IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
     61                             DeviceGetFormatsInUse)
     62         IPC_MESSAGE_UNHANDLED(handled = false)
     63       IPC_END_MESSAGE_MAP()
     64       EXPECT_TRUE(handled);
     65       delete message;
     66     }
     67 
     68     void DeviceStartCapture(int device_id,
     69                             media::VideoCaptureSessionId session_id,
     70                             const media::VideoCaptureParams& params) {
     71       OnStateChanged(VIDEO_CAPTURE_STATE_STARTED);
     72       capture_params_ = params;
     73     }
     74 
     75     void DevicePauseCapture(int device_id) {}
     76 
     77     void DeviceStopCapture(int device_id) {
     78       OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED);
     79     }
     80 
     81     void DeviceReceiveEmptyBuffer(int device_id,
     82                                   int buffer_id,
     83                                   uint32 sync_point) {}
     84 
     85     void DeviceGetSupportedFormats(int device_id,
     86                                    media::VideoCaptureSessionId session_id) {
     87       // When the mock message filter receives a request for the device
     88       // supported formats, replies immediately with an empty format list.
     89       OnDeviceSupportedFormatsEnumerated(
     90           media::VideoCaptureFormats());
     91     }
     92 
     93     void DeviceGetFormatsInUse(int device_id,
     94                                media::VideoCaptureSessionId session_id) {
     95       OnDeviceFormatsInUseReceived(media::VideoCaptureFormats());
     96     }
     97 
     98     void ReceiveStateChangeMessage(VideoCaptureState state) {
     99       OnStateChanged(state);
    100     }
    101 
    102     const media::VideoCaptureParams& capture_params() const {
    103       return capture_params_;
    104     }
    105 
    106    private:
    107     media::VideoCaptureParams capture_params_;
    108   };
    109 
    110   VideoCaptureImplTest() {
    111     params_small_.requested_format = media::VideoCaptureFormat(
    112         gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420);
    113 
    114     params_large_.requested_format = media::VideoCaptureFormat(
    115         gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);
    116 
    117     child_process_.reset(new ChildProcess());
    118 
    119     message_filter_ = new MockVideoCaptureMessageFilter;
    120     session_id_ = 1;
    121 
    122     video_capture_impl_.reset(new MockVideoCaptureImpl(
    123         session_id_, message_filter_.get()));
    124 
    125     video_capture_impl_->device_id_ = 2;
    126   }
    127 
    128   virtual ~VideoCaptureImplTest() {
    129   }
    130 
    131  protected:
    132   MOCK_METHOD3(OnFrameReady,
    133               void(const scoped_refptr<media::VideoFrame>&,
    134                    const media::VideoCaptureFormat&,
    135                    const base::TimeTicks&));
    136   MOCK_METHOD1(OnStateUpdate, void(VideoCaptureState));
    137   MOCK_METHOD1(OnDeviceFormatsInUse,
    138                void(const media::VideoCaptureFormats&));
    139   MOCK_METHOD1(OnDeviceSupportedFormats,
    140                void(const media::VideoCaptureFormats&));
    141 
    142   void Init() {
    143     video_capture_impl_->Init();
    144   }
    145 
    146   void StartCapture(int client_id,
    147                     const media::VideoCaptureParams& params) {
    148     video_capture_impl_->StartCapture(
    149         client_id, params,
    150         base::Bind(&VideoCaptureImplTest::OnStateUpdate,
    151                    base::Unretained(this)),
    152         base::Bind(&VideoCaptureImplTest::OnFrameReady,
    153                    base::Unretained(this)));
    154   }
    155 
    156   void StopCapture(int client_id) {
    157     video_capture_impl_->StopCapture(client_id);
    158   }
    159 
    160   void DeInit() {
    161     video_capture_impl_->DeInit();
    162   }
    163 
    164   void GetDeviceSupportedFormats() {
    165     const base::Callback<void(const media::VideoCaptureFormats&)>
    166         callback = base::Bind(
    167             &VideoCaptureImplTest::OnDeviceSupportedFormats,
    168             base::Unretained(this));
    169     video_capture_impl_->GetDeviceSupportedFormats(callback);
    170   }
    171 
    172   void GetDeviceFormatsInUse() {
    173     const base::Callback<void(const media::VideoCaptureFormats&)>
    174         callback = base::Bind(
    175             &VideoCaptureImplTest::OnDeviceFormatsInUse,
    176             base::Unretained(this));
    177     video_capture_impl_->GetDeviceFormatsInUse(callback);
    178   }
    179 
    180   base::MessageLoop message_loop_;
    181   scoped_ptr<ChildProcess> child_process_;
    182   scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
    183   media::VideoCaptureSessionId session_id_;
    184   scoped_ptr<MockVideoCaptureImpl> video_capture_impl_;
    185   media::VideoCaptureParams params_small_;
    186   media::VideoCaptureParams params_large_;
    187 
    188  private:
    189   DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest);
    190 };
    191 
    192 TEST_F(VideoCaptureImplTest, Simple) {
    193   // Execute SetCapture() and StopCapture() for one client.
    194   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
    195   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED));
    196 
    197   Init();
    198   StartCapture(0, params_small_);
    199   StopCapture(0);
    200   DeInit();
    201 }
    202 
    203 TEST_F(VideoCaptureImplTest, TwoClientsInSequence) {
    204   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2);
    205   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2);
    206 
    207   Init();
    208   StartCapture(0, params_small_);
    209   StopCapture(0);
    210   StartCapture(1, params_small_);
    211   StopCapture(1);
    212   DeInit();
    213 }
    214 
    215 TEST_F(VideoCaptureImplTest, LargeAndSmall) {
    216   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2);
    217   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2);
    218 
    219   Init();
    220   StartCapture(0, params_large_);
    221   StopCapture(0);
    222   StartCapture(1, params_small_);
    223   StopCapture(1);
    224   DeInit();
    225 }
    226 
    227 TEST_F(VideoCaptureImplTest, SmallAndLarge) {
    228   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2);
    229   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2);
    230 
    231   Init();
    232   StartCapture(0, params_small_);
    233   StopCapture(0);
    234   StartCapture(1, params_large_);
    235   StopCapture(1);
    236   DeInit();
    237 }
    238 
    239 // Check that a request to GetDeviceSupportedFormats() ends up eventually in the
    240 // provided callback.
    241 TEST_F(VideoCaptureImplTest, GetDeviceFormats) {
    242   EXPECT_CALL(*this, OnDeviceSupportedFormats(_));
    243 
    244   Init();
    245   GetDeviceSupportedFormats();
    246   DeInit();
    247 }
    248 
    249 // Check that two requests to GetDeviceSupportedFormats() end up eventually
    250 // calling the provided callbacks.
    251 TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) {
    252   EXPECT_CALL(*this, OnDeviceSupportedFormats(_)).Times(2);
    253 
    254   Init();
    255   GetDeviceSupportedFormats();
    256   GetDeviceSupportedFormats();
    257   DeInit();
    258 }
    259 
    260 // Check that a request to GetDeviceFormatsInUse() ends up eventually in the
    261 // provided callback.
    262 TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) {
    263   EXPECT_CALL(*this, OnDeviceFormatsInUse(_));
    264 
    265   Init();
    266   GetDeviceFormatsInUse();
    267   DeInit();
    268 }
    269 
    270 TEST_F(VideoCaptureImplTest, AlreadyStarted) {
    271   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED)).Times(2);
    272   EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED)).Times(2);
    273 
    274   Init();
    275   StartCapture(0, params_small_);
    276   StartCapture(1, params_large_);
    277   StopCapture(0);
    278   StopCapture(1);
    279   DeInit();
    280   DCHECK(video_capture_impl_->capture_params().requested_format
    281             .frame_size ==
    282          params_small_.requested_format.frame_size);
    283 }
    284 
    285 TEST_F(VideoCaptureImplTest, EndedBeforeStop) {
    286    EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
    287    EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STOPPED));
    288 
    289    Init();
    290    StartCapture(0, params_small_);
    291 
    292    // Receive state change message from browser.
    293    video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ENDED);
    294 
    295    StopCapture(0);
    296    DeInit();
    297 }
    298 
    299 TEST_F(VideoCaptureImplTest, ErrorBeforeStop) {
    300    EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_STARTED));
    301    EXPECT_CALL(*this, OnStateUpdate(VIDEO_CAPTURE_STATE_ERROR));
    302 
    303    Init();
    304    StartCapture(0, params_small_);
    305 
    306    // Receive state change message from browser.
    307    video_capture_impl_->ReceiveStateChangeMessage(VIDEO_CAPTURE_STATE_ERROR);
    308 
    309    StopCapture(0);
    310    DeInit();
    311 }
    312 
    313 }  // namespace content
    314