15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind_helpers.h"
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/ref_counted.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/run_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_device.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/video/capture/video_capture_device_factory.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_types.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_com_initializer.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/video/capture/win/video_capture_device_factory_win.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(OS_MACOSX)
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "media/video/capture/mac/video_capture_device_factory_mac.h"
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/android/jni_android.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/video/capture/android/video_capture_device_android.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mac/QTKit will always give you the size you ask for and this case will fail.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// We will always get YUYV from the Mac QTKit/AVFoundation implementations.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AllocateBadSize AllocateBadSize
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows currently uses DirectShow to convert from MJPEG and a raw format is
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// always delivered.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_ANDROID)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(wjia): enable those tests on Android.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// On Android, native camera (JAVA) delivers frames on UI thread which is the
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// main thread for tests. This results in no frame received by
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// VideoCaptureAndroid.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CaptureVGA DISABLED_CaptureVGA
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define Capture720p DISABLED_Capture720p
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_AllocateBadSize DISABLED_AllocateBadSize
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ReAllocateCamera DISABLED_ReAllocateCamera
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DeAllocateCameraWhileRunning DISABLED_DeAllocateCameraWhileRunning
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_AllocateBadSize AllocateBadSize
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_CaptureMjpeg CaptureMjpeg
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ::testing::_;
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using ::testing::SaveArg;
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class MockClient : public media::VideoCaptureDevice::Client {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MOCK_METHOD2(ReserveOutputBuffer,
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               scoped_refptr<Buffer>(media::VideoFrame::Format format,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const gfx::Size& dimensions));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(OnErr, void());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : main_thread_(base::MessageLoopProxy::current()), frame_cb_(frame_cb) {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnError(const std::string& error_message) OVERRIDE {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnErr();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnIncomingCapturedData(const uint8* data,
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      int length,
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      const VideoCaptureFormat& format,
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      int rotation,
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      base::TimeTicks timestamp) OVERRIDE {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format));
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnIncomingCapturedVideoFrame(
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const scoped_refptr<Buffer>& buffer,
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const media::VideoCaptureFormat& buffer_format,
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const scoped_refptr<media::VideoFrame>& frame,
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::TimeTicks timestamp) OVERRIDE {
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Callback<void(const VideoCaptureFormat&)> frame_cb_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class DeviceEnumerationListener :
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    public base::RefCounted<DeviceEnumerationListener>{
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr,
10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)               void(media::VideoCaptureDevice::Names* names));
10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // GMock doesn't support move-only arguments, so we use this forward method.
10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void OnEnumeratedDevicesCallback(
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      scoped_ptr<media::VideoCaptureDevice::Names> names) {
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    OnEnumeratedDevicesCallbackPtr(names.release());
10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  friend class base::RefCounted<DeviceEnumerationListener>;
11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~DeviceEnumerationListener() {}
11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VideoCaptureDeviceTest : public testing::Test {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  typedef media::VideoCaptureDevice::Client Client;
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureDeviceTest()
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : loop_(new base::MessageLoop()),
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        client_(
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            new MockClient(base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured,
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                      base::Unretained(this)))),
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory(
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            base::MessageLoopProxy::current())) {
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    device_enumeration_listener_ = new DeviceEnumerationListener();
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    media::VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::android::AttachCurrentThread());
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void ResetWithNewClient() {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    client_.reset(new MockClient(base::Bind(
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this))));
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnFrameCaptured(const VideoCaptureFormat& format) {
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_format_ = format;
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    run_loop_->QuitClosure().Run();
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void WaitForCapturedFrame() {
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    run_loop_.reset(new base::RunLoop());
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    run_loop_->Run();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<media::VideoCaptureDevice::Names> EnumerateDevices() {
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    media::VideoCaptureDevice::Names* names;
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*device_enumeration_listener_.get(),
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                OnEnumeratedDevicesCallbackPtr(_)).WillOnce(SaveArg<0>(&names));
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    video_capture_device_factory_->EnumerateDeviceNames(
15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback,
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   device_enumeration_listener_));
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return scoped_ptr<media::VideoCaptureDevice::Names>(names);
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const VideoCaptureFormat& last_format() const { return last_format_; }
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<VideoCaptureDevice::Name> GetFirstDeviceNameSupportingPixelFormat(
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      const VideoPixelFormat& pixel_format) {
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    names_ = EnumerateDevices();
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!names_->size()) {
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      DVLOG(1) << "No camera available.";
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return scoped_ptr<VideoCaptureDevice::Name>();
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    VideoCaptureDevice::Names::iterator names_iterator;
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    for (names_iterator = names_->begin(); names_iterator != names_->end();
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch         ++names_iterator) {
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      VideoCaptureFormats supported_formats;
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      video_capture_device_factory_->GetDeviceSupportedFormats(
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          *names_iterator,
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &supported_formats);
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      VideoCaptureFormats::iterator formats_iterator;
180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      for (formats_iterator = supported_formats.begin();
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch           formats_iterator != supported_formats.end(); ++formats_iterator) {
182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        if (formats_iterator->pixel_format == pixel_format) {
183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          return scoped_ptr<VideoCaptureDevice::Name>(
184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch              new VideoCaptureDevice::Name(*names_iterator));
185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        }
186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      }
187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DVLOG(1) << "No camera can capture the format: " << pixel_format;
189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return scoped_ptr<VideoCaptureDevice::Name>();
190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::win::ScopedCOMInitializer initialize_com_;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<VideoCaptureDevice::Names> names_;
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::MessageLoop> loop_;
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::RunLoop> run_loop_;
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockClient> client_;
19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_;
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureFormat last_format_;
2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) {
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  VideoCaptureDevice::Name::CaptureApiType api_type =
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation()
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          ? VideoCaptureDevice::Name::MEDIA_FOUNDATION
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          : VideoCaptureDevice::Name::DIRECT_SHOW;
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  VideoCaptureDevice::Name device_name("jibberish", "jibberish", api_type);
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#elif defined(OS_MACOSX)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  VideoCaptureDevice::Name device_name("jibberish", "jibberish",
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      VideoCaptureDeviceFactoryMac::PlatformSupportsAVFoundation()
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          ? VideoCaptureDevice::Name::AVFOUNDATION
21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          : VideoCaptureDevice::Name::QTKIT);
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else
217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  VideoCaptureDevice::Name device_name("jibberish", "jibberish");
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device =
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(device_name);
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if !defined(OS_MACOSX)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(device == NULL);
22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#else
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (VideoCaptureDeviceFactoryMac::PlatformSupportsAVFoundation()) {
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_TRUE(device == NULL);
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // The presence of the actual device is only checked on AllocateAndStart()
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // and not on creation for QTKit API in Mac OS X platform.
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_CALL(*client_, OnErr()).Times(1);
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    VideoCaptureParams capture_params;
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    capture_params.requested_format.frame_size.SetSize(640, 480);
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    capture_params.requested_format.frame_rate = 30;
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    device->AllocateAndStart(capture_params, client_.PassAs<Client>());
23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    device->StopAndDeAllocate();
23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  names_ = EnumerateDevices();
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!names_->size()) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "No camera available. Exiting test.";
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(names_->front()));
250a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(device);
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DVLOG(1) << names_->front().id();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_CALL(*client_, OnErr())
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(640, 480);
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 30;
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get captured video frames.
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForCapturedFrame();
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.width(), 640);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.height(), 480);
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, Capture720p) {
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  names_ = EnumerateDevices();
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!names_->size()) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "No camera available. Exiting test.";
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(names_->front()));
277a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(device);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_CALL(*client_, OnErr())
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(1280, 720);
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 30;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get captured video frames.
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WaitForCapturedFrame();
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  names_ = EnumerateDevices();
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!names_->size()) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "No camera available. Exiting test.";
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(names_->front()));
300a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(device);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_CALL(*client_, OnErr())
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(637, 472);
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 35;
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForCapturedFrame();
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.width(), 640);
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.height(), 480);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  names_ = EnumerateDevices();
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!names_->size()) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "No camera available. Exiting test.";
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // First, do a number of very fast device start/stops.
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  for (int i = 0; i <= 5; i++) {
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResetWithNewClient();
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<VideoCaptureDevice> device(
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        video_capture_device_factory_->Create(names_->front()));
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::Size resolution;
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (i % 2) {
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resolution = gfx::Size(640, 480);
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      resolution = gfx::Size(1280, 1024);
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    VideoCaptureParams capture_params;
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    capture_params.requested_format.frame_size = resolution;
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    capture_params.requested_format.frame_rate = 30;
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    device->AllocateAndStart(capture_params, client_.PassAs<Client>());
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    device->StopAndDeAllocate();
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Finally, do a device start and wait for it to finish.
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(320, 240);
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 30;
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResetWithNewClient();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(names_->front()));
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WaitForCapturedFrame();
354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device.reset();
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.width(), 320);
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.height(), 240);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  names_ = EnumerateDevices();
36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!names_->size()) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "No camera available. Exiting test.";
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(names_->front()));
368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(device);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_CALL(*client_, OnErr())
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(640, 480);
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 30;
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get captured video frames.
379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WaitForCapturedFrame();
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.width(), 640);
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_size.height(), 480);
382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().frame_rate, 30);
383d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the camera in 720p to capture MJPEG instead of a raw format.
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) {
388a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<VideoCaptureDevice::Name> name =
389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MJPEG);
390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!name) {
391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DVLOG(1) << "No camera supports MJPEG format. Exiting test.";
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<VideoCaptureDevice> device(
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      video_capture_device_factory_->Create(*name));
396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(device);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_CALL(*client_, OnErr())
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(0);
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureParams capture_params;
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_size.SetSize(1280, 720);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.frame_rate = 30;
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG;
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  device->AllocateAndStart(capture_params, client_.PassAs<Client>());
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get captured video frames.
407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  WaitForCapturedFrame();
408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Verify we get MJPEG from the device. Not all devices can capture 1280x720
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // @ 30 fps, so we don't care about the exact resolution we get.
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG);
411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  device->StopAndDeAllocate();
412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) {
415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Use PIXEL_FORMAT_MAX to iterate all device names for testing
416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // GetDeviceSupportedFormats().
417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<VideoCaptureDevice::Name> name =
418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX);
419a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here
420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // since we cannot forecast the hardware capabilities.
421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_FALSE(name);
4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};  // namespace media
425