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