summaryrefslogtreecommitdiffstats
path: root/include/media/stagefright/CameraSourceTimeLapse.h
blob: eeb453fed225d480be787f2ca6f35968aae97591 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef CAMERA_SOURCE_TIME_LAPSE_H_

#define CAMERA_SOURCE_TIME_LAPSE_H_

#include <pthread.h>

#include <media/stagefright/CameraSource.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <utils/String16.h>

namespace android {

class ICamera;
class IMemory;
class Camera;

class CameraSourceTimeLapse : public CameraSource {
public:
    static CameraSourceTimeLapse *CreateFromCamera(
        const sp<ICamera> &camera,
        const sp<ICameraRecordingProxy> &proxy,
        int32_t cameraId,
        const String16& clientName,
        uid_t clientUid,
        Size videoSize,
        int32_t videoFrameRate,
        const sp<IGraphicBufferProducer>& surface,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        bool storeMetaDataInVideoBuffers = true);

    virtual ~CameraSourceTimeLapse();

    // If the frame capture interval is large, read will block for a long time.
    // Due to the way the mediaRecorder framework works, a stop() call from
    // mediaRecorder waits until the read returns, causing a long wait for
    // stop() to return. To avoid this, we can make read() return a copy of the
    // last read frame with the same time stamp frequently. This keeps the
    // read() call from blocking too long. Calling this function quickly
    // captures another frame, keeps its copy, and enables this mode of read()
    // returning quickly.
    void startQuickReadReturns();

protected:
    // size of the encoded video.
    int32_t mVideoWidth;
    int32_t mVideoHeight;

    // Time between two frames in final video (1/frameRate)
    int64_t mTimeBetweenTimeLapseVideoFramesUs;

    // Real timestamp of the last encoded time lapse frame
    int64_t mLastTimeLapseFrameRealTimestampUs;
    // Adjusted continuous timestamp based on recording fps
    // of the last encoded time lapse frame
    int64_t mLastTimeLapseFrameTimeStampUs;

    // Variable set in dataCallbackTimestamp() to help skipCurrentFrame()
    // to know if current frame needs to be skipped.
    bool mSkipCurrentFrame;

    // Lock for accessing mCameraIdle
    Mutex mCameraIdleLock;

    // Condition variable to wait on if camera is is not yet idle. Once the
    // camera gets idle, this variable will be signalled.
    Condition mCameraIdleCondition;

    // True if camera is in preview mode and ready for takePicture().
    // False after a call to takePicture() but before the final compressed
    // data callback has been called and preview has been restarted.
    volatile bool mCameraIdle;

    // True if stop() is waiting for camera to get idle, i.e. for the last
    // takePicture() to complete. This is needed so that dataCallbackTimestamp()
    // can return immediately.
    volatile bool mStopWaitingForIdleCamera;

    // Lock for accessing quick stop variables.
    Mutex mQuickStopLock;

    // mQuickStop is set to true if we use quick read() returns, otherwise it is set
    // to false. Once in this mode read() return a copy of the last read frame
    // with the same time stamp. See startQuickReadReturns().
    volatile bool mQuickStop;

    // Forces the next frame passed to dataCallbackTimestamp() to be read
    // as a time lapse frame. Used by startQuickReadReturns() so that the next
    // frame wakes up any blocking read.
    volatile bool mForceRead;

    // Stores a copy of the MediaBuffer read in the last read() call after
    // mQuickStop was true.
    MediaBuffer* mLastReadBufferCopy;

    // Status code for last read.
    status_t mLastReadStatus;

    CameraSourceTimeLapse(
        const sp<ICamera> &camera,
        const sp<ICameraRecordingProxy> &proxy,
        int32_t cameraId,
        const String16& clientName,
        uid_t clientUid,
        Size videoSize,
        int32_t videoFrameRate,
        const sp<IGraphicBufferProducer>& surface,
        int64_t timeBetweenTimeLapseFrameCaptureUs,
        bool storeMetaDataInVideoBuffers = true);

    // Wrapper over CameraSource::signalBufferReturned() to implement quick stop.
    // It only handles the case when mLastReadBufferCopy is signalled. Otherwise
    // it calls the base class' function.
    virtual void signalBufferReturned(MediaBuffer* buffer);

    // Wrapper over CameraSource::read() to implement quick stop.
    virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);

    // mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current
    // frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
    virtual bool skipCurrentFrame(int64_t timestampUs);

    // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
    // timestamp and set mSkipCurrentFrame.
    // Then it calls the base CameraSource::dataCallbackTimestamp()
    virtual void dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
            const sp<IMemory> &data);

    // Convenience function to fill mLastReadBufferCopy from the just read
    // buffer.
    void fillLastReadBufferCopy(MediaBuffer& sourceBuffer);

    // If the passed in size (width x height) is a supported video/preview size,
    // the function sets the camera's video/preview size to it and returns true.
    // Otherwise returns false.
    bool trySettingVideoSize(int32_t width, int32_t height);

    // When video camera is used for time lapse capture, returns true
    // until enough time has passed for the next time lapse frame. When
    // the frame needs to be encoded, it returns false and also modifies
    // the time stamp to be one frame time ahead of the last encoded
    // frame's time stamp.
    virtual bool skipFrameAndModifyTimeStamp(int64_t *timestampUs);

    // Wrapper to enter threadTimeLapseEntry()
    static void *ThreadTimeLapseWrapper(void *me);

    // Creates a copy of source_data into a new memory of final type MemoryBase.
    sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);

    CameraSourceTimeLapse(const CameraSourceTimeLapse &);
    CameraSourceTimeLapse &operator=(const CameraSourceTimeLapse &);
};

}  // namespace android

#endif  // CAMERA_SOURCE_TIME_LAPSE_H_