1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef CAMERA_SOURCE_H_
18
19#define CAMERA_SOURCE_H_
20
21#include <deque>
22#include <media/MediaSource.h>
23#include <media/stagefright/MediaBuffer.h>
24#include <camera/android/hardware/ICamera.h>
25#include <camera/ICameraRecordingProxy.h>
26#include <camera/ICameraRecordingProxyListener.h>
27#include <camera/CameraParameters.h>
28#include <gui/BufferItemConsumer.h>
29#include <utils/List.h>
30#include <utils/RefBase.h>
31#include <utils/String16.h>
32#include <media/hardware/MetadataBufferType.h>
33
34namespace android {
35
36class IMemory;
37class Camera;
38class Surface;
39
40class CameraSource : public MediaSource, public MediaBufferObserver {
41public:
42    /**
43     * Factory method to create a new CameraSource using the current
44     * settings (such as video size, frame rate, color format, etc)
45     * from the default camera.
46     *
47     * @param clientName The package/process name of the client application.
48     *    This is used for permissions checking.
49     * @return NULL on error.
50     */
51    static CameraSource *Create(const String16 &clientName);
52
53    /**
54     * Factory method to create a new CameraSource.
55     *
56     * @param camera the video input frame data source. If it is NULL,
57     *          we will try to connect to the camera with the given
58     *          cameraId.
59     *
60     * @param cameraId the id of the camera that the source will connect
61     *          to if camera is NULL; otherwise ignored.
62     * @param clientName the package/process name of the camera-using
63     *          application if camera is NULL; otherwise ignored. Used for
64     *          permissions checking.
65     * @param clientUid the UID of the camera-using application if camera is
66     *          NULL; otherwise ignored. Used for permissions checking.
67     * @param clientPid the PID of the camera-using application if camera is
68     *          NULL; otherwise ignored. Used for permissions checking.
69     * @param videoSize the dimension (in pixels) of the video frame
70     * @param frameRate the target frames per second
71     * @param surface the preview surface for display where preview
72     *          frames are sent to
73     * @param storeMetaDataInVideoBuffers true to request the camera
74     *          source to store meta data in video buffers; false to
75     *          request the camera source to store real YUV frame data
76     *          in the video buffers. The camera source may not support
77     *          storing meta data in video buffers, if so, a request
78     *          to do that will NOT be honored. To find out whether
79     *          meta data is actually being stored in video buffers
80     *          during recording, call isMetaDataStoredInVideoBuffers().
81     *
82     * @return NULL on error.
83     */
84    static CameraSource *CreateFromCamera(const sp<hardware::ICamera> &camera,
85                                          const sp<ICameraRecordingProxy> &proxy,
86                                          int32_t cameraId,
87                                          const String16& clientName,
88                                          uid_t clientUid,
89                                          pid_t clientPid,
90                                          Size videoSize,
91                                          int32_t frameRate,
92                                          const sp<IGraphicBufferProducer>& surface,
93                                          bool storeMetaDataInVideoBuffers = true);
94
95    virtual ~CameraSource();
96
97    virtual status_t start(MetaData *params = NULL);
98    virtual status_t stop() { return reset(); }
99    virtual status_t read(
100            MediaBufferBase **buffer, const ReadOptions *options = NULL);
101    virtual status_t setStopTimeUs(int64_t stopTimeUs);
102
103    /**
104     * Check whether a CameraSource object is properly initialized.
105     * Must call this method before stop().
106     * @return OK if initialization has successfully completed.
107     */
108    virtual status_t initCheck() const;
109
110    /**
111     * Returns the MetaData associated with the CameraSource,
112     * including:
113     * kKeyColorFormat: YUV color format of the video frames
114     * kKeyWidth, kKeyHeight: dimension (in pixels) of the video frames
115     * kKeySampleRate: frame rate in frames per second
116     * kKeyMIMEType: always fixed to be MEDIA_MIMETYPE_VIDEO_RAW
117     */
118    virtual sp<MetaData> getFormat();
119
120    /**
121     * Tell whether this camera source stores meta data or real YUV
122     * frame data in video buffers.
123     *
124     * @return a valid type if meta data is stored in the video
125     *      buffers; kMetadataBufferTypeInvalid if real YUV data is stored in
126     *      the video buffers.
127     */
128    MetadataBufferType metaDataStoredInVideoBuffers() const;
129
130    virtual void signalBufferReturned(MediaBufferBase* buffer);
131
132protected:
133
134    /**
135     * The class for listening to BnCameraRecordingProxyListener. This is used to receive video
136     * buffers in VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV and VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA
137     * mode. When a frame is available, CameraSource::dataCallbackTimestamp() will be called.
138     */
139    class ProxyListener: public BnCameraRecordingProxyListener {
140    public:
141        ProxyListener(const sp<CameraSource>& source);
142        virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
143                const sp<IMemory> &data);
144        virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
145                native_handle_t* handle);
146        virtual void recordingFrameHandleCallbackTimestampBatch(
147                const std::vector<int64_t>& timestampsUs,
148                const std::vector<native_handle_t*>& handles);
149
150    private:
151        sp<CameraSource> mSource;
152    };
153
154    /**
155     * The class for listening to BufferQueue's onFrameAvailable. This is used to receive video
156     * buffers in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. When a frame is available,
157     * CameraSource::processBufferQueueFrame() will be called.
158     */
159    class BufferQueueListener : public Thread,  public BufferItemConsumer::FrameAvailableListener {
160    public:
161        BufferQueueListener(const sp<BufferItemConsumer> &consumer,
162                const sp<CameraSource> &cameraSource);
163        virtual void onFrameAvailable(const BufferItem& item);
164        virtual bool threadLoop();
165    private:
166        static const nsecs_t kFrameAvailableTimeout = 50000000; // 50ms
167
168        sp<BufferItemConsumer> mConsumer;
169        sp<CameraSource> mCameraSource;
170
171        Mutex mLock;
172        Condition mFrameAvailableSignal;
173        bool mFrameAvailable;
174    };
175
176    // isBinderAlive needs linkToDeath to work.
177    class DeathNotifier: public IBinder::DeathRecipient {
178    public:
179        DeathNotifier() {}
180        virtual void binderDied(const wp<IBinder>& who);
181    };
182
183    enum CameraFlags {
184        FLAGS_SET_CAMERA = 1L << 0,
185        FLAGS_HOT_CAMERA = 1L << 1,
186    };
187
188    int32_t  mCameraFlags;
189    Size     mVideoSize;
190    int32_t  mNumInputBuffers;
191    int32_t  mVideoFrameRate;
192    int32_t  mColorFormat;
193    int32_t  mEncoderFormat;
194    int32_t  mEncoderDataSpace;
195    status_t mInitCheck;
196
197    sp<Camera>   mCamera;
198    sp<ICameraRecordingProxy>   mCameraRecordingProxy;
199    sp<DeathNotifier> mDeathNotifier;
200    sp<IGraphicBufferProducer>  mSurface;
201    sp<MetaData> mMeta;
202
203    int64_t mStartTimeUs;
204    int32_t mNumFramesReceived;
205    int64_t mLastFrameTimestampUs;
206    bool mStarted;
207    int32_t mNumFramesEncoded;
208
209    // Time between capture of two frames.
210    int64_t mTimeBetweenFrameCaptureUs;
211
212    CameraSource(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
213                 int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
214                 Size videoSize, int32_t frameRate,
215                 const sp<IGraphicBufferProducer>& surface,
216                 bool storeMetaDataInVideoBuffers);
217
218    virtual status_t startCameraRecording();
219    virtual void releaseRecordingFrame(const sp<IMemory>& frame);
220    virtual void releaseRecordingFrameHandle(native_handle_t* handle);
221    // stagefright recorder not using this for now
222    virtual void releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles);
223
224    // Returns true if need to skip the current frame.
225    // Called from dataCallbackTimestamp.
226    virtual bool skipCurrentFrame(int64_t /*timestampUs*/) {return false;}
227
228    // Callback called when still camera raw data is available.
229    virtual void dataCallback(int32_t /*msgType*/, const sp<IMemory>& /*data*/) {}
230
231    virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
232            const sp<IMemory> &data);
233
234    virtual void recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
235            native_handle_t* handle);
236
237    virtual void recordingFrameHandleCallbackTimestampBatch(
238            const std::vector<int64_t>& timestampsUs,
239            const std::vector<native_handle_t*>& handles);
240
241    // Process a buffer item received in BufferQueueListener.
242    virtual void processBufferQueueFrame(BufferItem& buffer);
243
244    void releaseCamera();
245
246private:
247    friend struct CameraSourceListener;
248
249    Mutex mLock;
250    Condition mFrameAvailableCondition;
251    Condition mFrameCompleteCondition;
252    List<sp<IMemory> > mFramesReceived;
253    List<sp<IMemory> > mFramesBeingEncoded;
254    List<int64_t> mFrameTimes;
255
256    int64_t mFirstFrameTimeUs;
257    int64_t mStopSystemTimeUs;
258    int32_t mNumFramesDropped;
259    int32_t mNumGlitches;
260    int64_t mGlitchDurationThresholdUs;
261    bool mCollectStats;
262
263    // The mode video buffers are received from camera. One of VIDEO_BUFFER_MODE_*.
264    int32_t mVideoBufferMode;
265
266    static const uint32_t kDefaultVideoBufferCount = 32;
267
268    /**
269     * The following variables are used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
270     */
271    static const size_t kConsumerBufferCount = 8;
272    static const nsecs_t kMemoryBaseAvailableTimeoutNs = 200000000; // 200ms
273    // Consumer and producer of the buffer queue between this class and camera.
274    sp<BufferItemConsumer> mVideoBufferConsumer;
275    sp<IGraphicBufferProducer> mVideoBufferProducer;
276    // Memory used to send the buffers to encoder, where sp<IMemory> stores VideoNativeMetadata.
277    sp<IMemoryHeap> mMemoryHeapBase;
278    List<sp<IMemory>> mMemoryBases;
279    // The condition that will be signaled when there is an entry available in mMemoryBases.
280    Condition mMemoryBaseAvailableCond;
281    // A mapping from ANativeWindowBuffer sent to encoder to BufferItem received from camera.
282    // This is protected by mLock.
283    KeyedVector<ANativeWindowBuffer*, BufferItem> mReceivedBufferItemMap;
284    sp<BufferQueueListener> mBufferQueueListener;
285
286    Mutex mBatchLock; // protecting access to mInflightXXXXX members below
287    // Start of members protected by mBatchLock
288    std::deque<uint32_t> mInflightBatchSizes;
289    std::vector<native_handle_t*> mInflightReturnedHandles;
290    std::vector<const sp<IMemory>> mInflightReturnedMemorys;
291    // End of members protected by mBatchLock
292
293    void releaseQueuedFrames();
294    void releaseOneRecordingFrame(const sp<IMemory>& frame);
295    void createVideoBufferMemoryHeap(size_t size, uint32_t bufferCount);
296
297    status_t init(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
298                  int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
299                  Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
300
301    status_t initWithCameraAccess(
302                  const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
303                  int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid,
304                  Size videoSize, int32_t frameRate, bool storeMetaDataInVideoBuffers);
305
306    // Initialize the buffer queue used in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
307    status_t initBufferQueue(uint32_t width, uint32_t height, uint32_t format,
308                  android_dataspace dataSpace, uint32_t bufferCount);
309
310    status_t isCameraAvailable(const sp<hardware::ICamera>& camera,
311                               const sp<ICameraRecordingProxy>& proxy,
312                               int32_t cameraId,
313                               const String16& clientName,
314                               uid_t clientUid,
315                               pid_t clientPid);
316
317    status_t isCameraColorFormatSupported(const CameraParameters& params);
318    status_t configureCamera(CameraParameters* params,
319                    int32_t width, int32_t height,
320                    int32_t frameRate);
321
322    status_t checkVideoSize(const CameraParameters& params,
323                    int32_t width, int32_t height);
324
325    status_t checkFrameRate(const CameraParameters& params,
326                    int32_t frameRate);
327
328    // Check if this frame should be skipped based on the frame's timestamp in microsecond.
329    // mLock must be locked before calling this function.
330    bool shouldSkipFrameLocked(int64_t timestampUs);
331
332    void stopCameraRecording();
333    status_t reset();
334
335    CameraSource(const CameraSource &);
336    CameraSource &operator=(const CameraSource &);
337};
338
339}  // namespace android
340
341#endif  // CAMERA_SOURCE_H_
342