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 
33 namespace android {
34 
35 class IMemory;
36 class Camera;
37 class Surface;
38 
39 class CameraSource : public MediaSource, public MediaBufferObserver {
40 public:
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);
stop()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 
130 protected:
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:
DeathNotifier()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.
skipCurrentFrame(int64_t timestampUs)219     virtual bool skipCurrentFrame(int64_t timestampUs) {return false;}
220 
221     // Callback called when still camera raw data is available.
dataCallback(int32_t msgType,const sp<IMemory> & data)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 
235 private:
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