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)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// MacOSX implementation of generic VideoCaptureDevice, using either QTKit or
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// AVFoundation as native capture API. QTKit is available in all OSX versions,
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// although namely deprecated in 10.9, and AVFoundation is available in versions
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 10.7 (Lion) and later.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#import <Foundation/Foundation.h>
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/mac/scoped_nsobject.h"
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/ref_counted.h"
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_device.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_types.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)@protocol PlatformVideoCapturingMac;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace base {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Small class to bundle device name and connection type into a dictionary.
31116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMEDIA_EXPORT
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch@interface DeviceNameAndTransportType : NSObject {
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @private
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::scoped_nsobject<NSString> deviceName_;
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The transport type of the device (USB, PCI, etc), values are defined in
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // <IOKit/audio/IOAudioTypes.h> as kIOAudioDeviceTransportType*.
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int32_t transportType_;
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (id)initWithName:(NSString*)name transportType:(int32_t)transportType;
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (NSString*)deviceName;
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (int32_t)transportType;
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch@end
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdochenum {
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Unknown transport type, addition to the kIOAudioDeviceTransportType*
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // family for QTKit devices where this attribute isn't published.
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  kIOAudioDeviceTransportTypeUnknown = 'unkn'
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called by VideoCaptureManager to open, close and start, stop Mac video
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// capture devices.
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class VideoCaptureDeviceMac : public VideoCaptureDevice {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit VideoCaptureDeviceMac(const Name& device_name);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~VideoCaptureDeviceMac();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // VideoCaptureDevice implementation.
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void AllocateAndStart(
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const VideoCaptureParams& params,
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE;
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void StopAndDeAllocate() OVERRIDE;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool Init(VideoCaptureDevice::Name::CaptureApiType capture_api_type);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called to deliver captured video frames.
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  void ReceiveFrame(const uint8* video_frame,
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    int video_frame_length,
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    const VideoCaptureFormat& frame_format,
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    int aspect_numerator,
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    int aspect_denominator);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Forwarder to VideoCaptureDevice::Client::OnError().
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void ReceiveError(const std::string& reason);
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Forwarder to VideoCaptureDevice::Client::OnLog().
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void LogMessage(const std::string& message);
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetErrorState(const std::string& reason);
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool UpdateCaptureResolution();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flag indicating the internal state.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum InternalState {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kNotInitialized,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kIdle,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kCapturing,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kError
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  Name device_name_;
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<VideoCaptureDevice::Client> client_;
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VideoCaptureFormat capture_format_;
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // These variables control the two-step configure-start process for QTKit HD:
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // the device is first started with no configuration and the captured frames
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // are inspected to check if the camera really supports HD. AVFoundation does
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // not need this process so |final_resolution_selected_| is false then.
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool final_resolution_selected_;
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool tried_to_square_pixels_;
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Only read and write state_ from inside this loop.
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalState state_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  id<PlatformVideoCapturingMac> capture_device_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Used with Bind and PostTask to ensure that methods aren't called after the
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // VideoCaptureDeviceMac is destroyed.
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<VideoCaptureDeviceMac> weak_factory_;
11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceMac);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
122