camera.h revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_ 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/ref_counted.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h" 143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "third_party/skia/include/core/SkBitmap.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass Task; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace base { 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass Thread; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace base 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Class that wraps interaction with video capturing device. Returns 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// frames captured with specified intervals of time via delegate interface. 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// All communication with camera driver is performed on a separate camera 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// thread. Delegate's callback are called on UI thread. 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass Camera : public base::RefCountedThreadSafe<Camera> { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch class Delegate { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual ~Delegate() {} 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Callbacks that notify of the initialization status. 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnInitializeSuccess() = 0; 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnInitializeFailure() = 0; 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Callbacks that notify if video capturing was started successfully or 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // not. 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnStartCapturingSuccess() = 0; 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnStartCapturingFailure() = 0; 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Notifies the delegate that new frame was captured. 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // The frame can be obtained via GetFrame() method. 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual void OnCaptureSuccess() = 0; 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Notifies the delegate that we failed to capture the next frame. 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick virtual void OnCaptureFailure() = 0; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Initializes object members. |delegate| is object that will receive 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // notifications about success of async method calls. |thread| is a thread 53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // to post blocking tasks to. |mirrored| determines if the returned video 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // image is mirrored horizontally. 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Camera(Delegate* delegate, base::Thread* thread, bool mirrored); 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Initializes camera device on camera thread. Corresponding delegate's 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // callback is called on UI thread to notify about success or failure. Does 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // nothing if camera is successfully initialized already. Sets the desired 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // width and height of the frame to receive from camera. 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void Initialize(int desired_width, int desired_height); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Uninitializes the camera on camera thread. Can be called anytime, any 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // number of times. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Uninitialize(); 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Starts capturing video frames on camera thread. Frames can be retrieved 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // by calling GetFrame method. 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void StartCapturing(); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Stops capturing video frames. Can be called anytime, any number of 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // times. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void StopCapturing(); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Setter for delegate: allows to set it to NULL when delegate is about to 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // be destroyed. 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void set_delegate(Delegate* delegate) { delegate_ = delegate; } 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Returns the last successful frame in the member passed. 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void GetFrame(SkBitmap* frame); 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Destructor is private so only its base class can delete Camera objects. 84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~Camera(); 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick friend class base::RefCountedThreadSafe<Camera>; 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Tries to open the device with specified name. Returns opened device 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // descriptor if succeeds, -1 otherwise. 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int OpenDevice(const char* device_name) const; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Initializes reading mode for the device. Returns true on success, false 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // otherwise. 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool InitializeReadingMode(int fd); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Unmaps video buffers stored in |buffers_|. 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void UnmapVideoBuffers(); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Task for camera thread that queries camera about the next frame and 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // saves it to |frame_image| buffer for UI thread to pick up. Schedules the 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // next task for itself if capturing still takes place. 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnCapture(); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reads a frame from the video device. If retry is needed, returns false. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise, returns true despite of success status. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ReadFrame(); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Transforms raw data received from camera into SkBitmap with desired 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // size and notifies the delegate that the image is ready. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ProcessImage(void* data); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Actual routines that run on camera thread and call delegate's callbacks. 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // See the corresponding methods without Do prefix for details. 113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void DoInitialize(int desired_width, int desired_height); 114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void DoStartCapturing(); 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void DoUninitialize(); 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void DoStopCapturing(); 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Helper method that reports failure to the delegate via method 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // corresponding to the current state of the object. 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void ReportFailure(); 121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Methods called on UI thread to call delegate. 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnInitializeSuccess(); 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnInitializeFailure(); 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnStartCapturingSuccess(); 126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnStartCapturingFailure(); 127513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void OnCaptureSuccess(); 128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick void OnCaptureFailure(); 129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Returns true if the code is executed on camera thread right now, false 131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // otherwise. 132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool IsOnCameraThread() const; 133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Posts task to camera thread. 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch void PostCameraTask(const tracked_objects::Location& from_here, 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Task* task); 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Defines a buffer in memory where one frame from the camera is stored. 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct VideoBuffer { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* start; 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Delegate that receives the frames from the camera. 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Delegate is accessed only on UI thread. 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Delegate* delegate_; 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Thread where all work with the device is going on. 149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::Thread* thread_; 150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // All the members below are accessed only on camera thread. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Name of the device file, i.e. "/dev/video0". 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string device_name_; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // File descriptor of the opened device. 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int device_descriptor_; 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Vector of buffers where to store video frames from camera. 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<VideoBuffer> buffers_; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Indicates if capturing has been started. 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool is_capturing_; 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Desired size of the frame to get from camera. If it doesn't match 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // camera's supported resolution, higher resolution is selected (if 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // available) and frame is cropped. If higher resolution is not available, 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the highest is selected and resized. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int desired_width_; 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int desired_height_; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Size of the frame that camera will give to us. It may not match the 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // desired size. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int frame_width_; 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int frame_height_; 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If set to true, the returned image will be reflected from the Y axis to 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // mimic mirror behavior. 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool mirrored_; 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Image where camera frames are stored for UI thread to pick up. 181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch SkBitmap frame_image_; 182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Lock that guards references to |frame_image_|. 18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen mutable base::Lock image_lock_; 185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Lock that guards references to |camera_thread_|. 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen mutable base::Lock thread_lock_; 188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(Camera); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace chromeos 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // CHROME_BROWSER_CHROMEOS_LOGIN_CAMERA_H_ 195