CameraSourceTimeLapse.h revision 54ff19ac69ace7c05ea90d225e26dab3b133f487
1/*
2 * Copyright (C) 2010 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_TIME_LAPSE_H_
18
19#define CAMERA_SOURCE_TIME_LAPSE_H_
20
21#include <pthread.h>
22
23#include <utils/RefBase.h>
24#include <utils/threads.h>
25
26namespace android {
27
28class ICamera;
29class IMemory;
30class Camera;
31
32class CameraSourceTimeLapse : public CameraSource {
33public:
34    static CameraSourceTimeLapse *CreateFromCamera(
35        const sp<ICamera> &camera,
36        int32_t cameraId,
37        Size videoSize,
38        int32_t videoFrameRate,
39        const sp<Surface>& surface,
40        int64_t timeBetweenTimeLapseFrameCaptureUs);
41
42    virtual ~CameraSourceTimeLapse();
43
44    // If the frame capture interval is large, read will block for a long time.
45    // Due to the way the mediaRecorder framework works, a stop() call from
46    // mediaRecorder waits until the read returns, causing a long wait for
47    // stop() to return. To avoid this, we can make read() return a copy of the
48    // last read frame with the same time stamp frequently. This keeps the
49    // read() call from blocking too long. Calling this function quickly
50    // captures another frame, keeps its copy, and enables this mode of read()
51    // returning quickly.
52    void startQuickReadReturns();
53
54private:
55    // If true, will use still camera takePicture() for time lapse frames
56    // If false, will use the videocamera frames instead.
57    bool mUseStillCameraForTimeLapse;
58
59    // Size of picture taken from still camera. This may be larger than the size
60    // of the video, as still camera may not support the exact video resolution
61    // demanded. See setPictureSizeToClosestSupported().
62    int32_t mPictureWidth;
63    int32_t mPictureHeight;
64
65    // size of the encoded video.
66    int32_t mVideoWidth;
67    int32_t mVideoHeight;
68
69    // True if we need to crop the still camera image to get the video frame.
70    bool mNeedCropping;
71
72    // Start location of the cropping rectangle.
73    int32_t mCropRectStartX;
74    int32_t mCropRectStartY;
75
76    // Time between capture of two frames during time lapse recording
77    // Negative value indicates that timelapse is disabled.
78    int64_t mTimeBetweenTimeLapseFrameCaptureUs;
79
80    // Time between two frames in final video (1/frameRate)
81    int64_t mTimeBetweenTimeLapseVideoFramesUs;
82
83    // Real timestamp of the last encoded time lapse frame
84    int64_t mLastTimeLapseFrameRealTimestampUs;
85
86    // Thread id of thread which takes still picture and sleeps in a loop.
87    pthread_t mThreadTimeLapse;
88
89    // Variable set in dataCallbackTimestamp() to help skipCurrentFrame()
90    // to know if current frame needs to be skipped.
91    bool mSkipCurrentFrame;
92
93    // Lock for accessing mCameraIdle
94    Mutex mCameraIdleLock;
95
96    // Condition variable to wait on if camera is is not yet idle. Once the
97    // camera gets idle, this variable will be signalled.
98    Condition mCameraIdleCondition;
99
100    // True if camera is in preview mode and ready for takePicture().
101    // False after a call to takePicture() but before the final compressed
102    // data callback has been called and preview has been restarted.
103    volatile bool mCameraIdle;
104
105    // True if stop() is waiting for camera to get idle, i.e. for the last
106    // takePicture() to complete. This is needed so that dataCallbackTimestamp()
107    // can return immediately.
108    volatile bool mStopWaitingForIdleCamera;
109
110    // Lock for accessing quick stop variables.
111    Mutex mQuickStopLock;
112
113    // Condition variable to wake up still picture thread.
114    Condition mTakePictureCondition;
115
116    // mQuickStop is set to true if we use quick read() returns, otherwise it is set
117    // to false. Once in this mode read() return a copy of the last read frame
118    // with the same time stamp. See startQuickReadReturns().
119    volatile bool mQuickStop;
120
121    // Forces the next frame passed to dataCallbackTimestamp() to be read
122    // as a time lapse frame. Used by startQuickReadReturns() so that the next
123    // frame wakes up any blocking read.
124    volatile bool mForceRead;
125
126    // Stores a copy of the MediaBuffer read in the last read() call after
127    // mQuickStop was true.
128    MediaBuffer* mLastReadBufferCopy;
129
130    // Status code for last read.
131    status_t mLastReadStatus;
132
133    CameraSourceTimeLapse(
134        const sp<ICamera> &camera,
135        int32_t cameraId,
136        Size videoSize,
137        int32_t videoFrameRate,
138        const sp<Surface>& surface,
139        int64_t timeBetweenTimeLapseFrameCaptureUs);
140
141    // Wrapper over CameraSource::signalBufferReturned() to implement quick stop.
142    // It only handles the case when mLastReadBufferCopy is signalled. Otherwise
143    // it calls the base class' function.
144    virtual void signalBufferReturned(MediaBuffer* buffer);
145
146    // Wrapper over CameraSource::read() to implement quick stop.
147    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
148
149    // For still camera case starts a thread which calls camera's takePicture()
150    // in a loop. For video camera case, just starts the camera's video recording.
151    virtual void startCameraRecording();
152
153    // For still camera case joins the thread created in startCameraRecording().
154    // For video camera case, just stops the camera's video recording.
155    virtual void stopCameraRecording();
156
157    // For still camera case don't need to do anything as memory is locally
158    // allocated with refcounting.
159    // For video camera case just tell the camera to release the frame.
160    virtual void releaseRecordingFrame(const sp<IMemory>& frame);
161
162    // mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current
163    // frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
164    virtual bool skipCurrentFrame(int64_t timestampUs);
165
166    // Handles the callback to handle raw frame data from the still camera.
167    // Creates a copy of the frame data as the camera can reuse the frame memory
168    // once this callback returns. The function also sets a new timstamp corresponding
169    // to one frame time ahead of the last encoded frame's time stamp. It then
170    // calls dataCallbackTimestamp() of the base class with the copied data and the
171    // modified timestamp, which will think that it recieved the frame from a video
172    // camera and proceed as usual.
173    virtual void dataCallback(int32_t msgType, const sp<IMemory> &data);
174
175    // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
176    // timestamp and set mSkipCurrentFrame.
177    // Then it calls the base CameraSource::dataCallbackTimestamp()
178    virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
179            const sp<IMemory> &data);
180
181    // Convenience function to fill mLastReadBufferCopy from the just read
182    // buffer.
183    void fillLastReadBufferCopy(MediaBuffer& sourceBuffer);
184
185    // If the passed in size (width x height) is a supported preview size,
186    // the function sets the camera's preview size to it and returns true.
187    // Otherwise returns false.
188    bool trySettingPreviewSize(int32_t width, int32_t height);
189
190    // The still camera may not support the demanded video width and height.
191    // We look for the supported picture sizes from the still camera and
192    // choose the smallest one with either dimensions higher than the corresponding
193    // video dimensions. The still picture will be cropped to get the video frame.
194    // The function returns true if the camera supports picture sizes greater than
195    // or equal to the passed in width and height, and false otherwise.
196    bool setPictureSizeToClosestSupported(int32_t width, int32_t height);
197
198    // Computes the offset of the rectangle from where to start cropping the
199    // still image into the video frame. We choose the center of the image to be
200    // cropped. The offset is stored in (mCropRectStartX, mCropRectStartY).
201    bool computeCropRectangleOffset();
202
203    // Crops the source data into a smaller image starting at
204    // (mCropRectStartX, mCropRectStartY) and of the size of the video frame.
205    // The data is returned into a newly allocated IMemory.
206    sp<IMemory> cropYUVImage(const sp<IMemory> &source_data);
207
208    // When video camera is used for time lapse capture, returns true
209    // until enough time has passed for the next time lapse frame. When
210    // the frame needs to be encoded, it returns false and also modifies
211    // the time stamp to be one frame time ahead of the last encoded
212    // frame's time stamp.
213    bool skipFrameAndModifyTimeStamp(int64_t *timestampUs);
214
215    // Wrapper to enter threadTimeLapseEntry()
216    static void *ThreadTimeLapseWrapper(void *me);
217
218    // Runs a loop which sleeps until a still picture is required
219    // and then calls mCamera->takePicture() to take the still picture.
220    // Used only in the case mUseStillCameraForTimeLapse = true.
221    void threadTimeLapseEntry();
222
223    // Wrapper to enter threadStartPreview()
224    static void *ThreadStartPreviewWrapper(void *me);
225
226    // Starts the camera's preview.
227    void threadStartPreview();
228
229    // Starts thread ThreadStartPreviewWrapper() for restarting preview.
230    // Needs to be done in a thread so that dataCallback() which calls this function
231    // can return, and the camera can know that takePicture() is done.
232    void restartPreview();
233
234    // Creates a copy of source_data into a new memory of final type MemoryBase.
235    sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);
236
237    CameraSourceTimeLapse(const CameraSourceTimeLapse &);
238    CameraSourceTimeLapse &operator=(const CameraSourceTimeLapse &);
239};
240
241}  // namespace android
242
243#endif  // CAMERA_SOURCE_TIME_LAPSE_H_
244