1 // Copyright 2013 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 #ifndef MEDIA_CAPTURE_VIDEO_MAC_VIDEO_CAPTURE_DEVICE_AVFOUNDATION_MAC_H_
6 #define MEDIA_CAPTURE_VIDEO_MAC_VIDEO_CAPTURE_DEVICE_AVFOUNDATION_MAC_H_
7 
8 #import <AVFoundation/AVFoundation.h>
9 #import <Foundation/Foundation.h>
10 
11 #include "base/mac/scoped_dispatch_object.h"
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/synchronization/lock.h"
14 #include "base/threading/thread_checker.h"
15 #include "media/capture/video/mac/sample_buffer_transformer_mac.h"
16 #import "media/capture/video/mac/video_capture_device_avfoundation_protocol_mac.h"
17 #include "media/capture/video/video_capture_device.h"
18 #include "media/capture/video_capture_types.h"
19 
20 namespace media {
21 
22 // Find the best capture format from |formats| for the specified dimensions and
23 // frame rate. Returns an element of |formats|, or nil.
24 AVCaptureDeviceFormat* CAPTURE_EXPORT
25 FindBestCaptureFormat(NSArray<AVCaptureDeviceFormat*>* formats,
26                       int width,
27                       int height,
28                       float frame_rate);
29 
30 }  // namespace media
31 
32 // TODO(crbug.com/1126690): rename this file to be suffixed by the
33 // "next generation" moniker.
34 CAPTURE_EXPORT
35 @interface VideoCaptureDeviceAVFoundation
36     : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate,
37                 VideoCaptureDeviceAVFoundationProtocol> {
38  @private
39   // The following attributes are set via -setCaptureHeight:width:frameRate:.
40   int _frameWidth;
41   int _frameHeight;
42   float _frameRate;
43 
44   // The capture format that best matches the above attributes.
45   base::scoped_nsobject<AVCaptureDeviceFormat> _bestCaptureFormat;
46 
47   // A serial queue to deliver frames on, ensuring frames are delivered in
48   // order.
49   base::ScopedDispatchObject<dispatch_queue_t> _sampleQueue;
50 
51   // Protects concurrent setting and using |frameReceiver_|. Note that the
52   // GUARDED_BY decoration below does not have any effect.
53   base::Lock _lock;
54   media::VideoCaptureDeviceAVFoundationFrameReceiver* _frameReceiver
55       GUARDED_BY(_lock);  // weak.
56 
57   base::scoped_nsobject<AVCaptureSession> _captureSession;
58 
59   // |captureDevice_| is an object coming from AVFoundation, used only to be
60   // plugged in |captureDeviceInput_| and to query for session preset support.
61   base::scoped_nsobject<AVCaptureDevice> _captureDevice;
62   base::scoped_nsobject<AVCaptureDeviceInput> _captureDeviceInput;
63   base::scoped_nsobject<AVCaptureVideoDataOutput> _captureVideoDataOutput;
64 
65   // When enabled, converts captured frames to NV12.
66   std::unique_ptr<media::SampleBufferTransformer> _sampleBufferTransformer;
67 
68   // An AVDataOutput specialized for taking pictures out of |captureSession_|.
69   base::scoped_nsobject<AVCaptureStillImageOutput> _stillImageOutput;
70   size_t _takePhotoStartedCount;
71   size_t _takePhotoPendingCount;
72   size_t _takePhotoCompletedCount;
73   bool _stillImageOutputWarmupCompleted;
74   std::unique_ptr<base::WeakPtrFactory<VideoCaptureDeviceAVFoundation>>
75       _weakPtrFactoryForTakePhoto;
76 
77   // For testing.
78   base::RepeatingCallback<void()> _onStillImageOutputStopped;
79 
80   scoped_refptr<base::SingleThreadTaskRunner> _mainThreadTaskRunner;
81 }
82 
83 // This function translates Mac Core Video pixel formats to Chromium pixel
84 // formats. This implementation recognizes NV12.
85 + (media::VideoPixelFormat)FourCCToChromiumPixelFormat:(FourCharCode)code;
86 
87 - (void)setOnStillImageOutputStoppedForTesting:
88     (base::RepeatingCallback<void()>)onStillImageOutputStopped;
89 
90 @end
91 
92 #endif  // MEDIA_CAPTURE_VIDEO_MAC_VIDEO_CAPTURE_DEVICE_AVFOUNDATION_MAC_H_
93