CameraSourceTimeLapse.cpp revision 99617adda9bc46c43f511f0940bc735c73de61de
165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra/*
265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * Copyright (C) 2010 The Android Open Source Project
365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra *
465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * Licensed under the Apache License, Version 2.0 (the "License");
565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * you may not use this file except in compliance with the License.
665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * You may obtain a copy of the License at
765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra *
865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra *      http://www.apache.org/licenses/LICENSE-2.0
965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra *
1065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * Unless required by applicable law or agreed to in writing, software
1165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * distributed under the License is distributed on an "AS IS" BASIS,
1265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * See the License for the specific language governing permissions and
1465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra * limitations under the License.
1565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra */
1665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
1765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra//#define LOG_NDEBUG 0
1865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#define LOG_TAG "CameraSourceTimeLapse"
1965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/IPCThreadState.h>
2165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/MemoryBase.h>
2265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/MemoryHeapBase.h>
23f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
2465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSource.h>
2565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h>
2665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/MetaData.h>
2765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/Camera.h>
2865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/CameraParameters.h>
2965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <utils/String8.h>
3040e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra#include <utils/Vector.h>
3165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
3265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatranamespace android {
3365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
3465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra// static
3554ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(
3654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<ICamera> &camera,
374ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        const sp<ICameraRecordingProxy> &proxy,
3854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t cameraId,
39ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
40ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
4154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
4254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t videoFrameRate,
4399617adda9bc46c43f511f0940bc735c73de61deMathias Agopian        const sp<IGraphicBufferProducer>& surface,
44e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        int64_t timeBetweenFrameCaptureUs) {
4554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraSourceTimeLapse *source = new
474ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CameraSourceTimeLapse(camera, proxy, cameraId,
48ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientName, clientUid,
4954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                videoSize, videoFrameRate, surface,
50e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                timeBetweenFrameCaptureUs);
5154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
5254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (source != NULL) {
5354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (source->initCheck() != OK) {
5454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            delete source;
5554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return NULL;
5654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
5765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
5854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return source;
5965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
6065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
6154ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSourceTimeLapse::CameraSourceTimeLapse(
6254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<ICamera>& camera,
634ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        const sp<ICameraRecordingProxy>& proxy,
6454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t cameraId,
65ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
66ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
6754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
6854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t videoFrameRate,
6999617adda9bc46c43f511f0940bc735c73de61deMathias Agopian        const sp<IGraphicBufferProducer>& surface,
70e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        int64_t timeBetweenFrameCaptureUs)
71ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala      : CameraSource(camera, proxy, cameraId, clientName, clientUid,
72ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                videoSize, videoFrameRate, surface, true),
7365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
7465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mLastTimeLapseFrameRealTimestampUs(0),
7565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mSkipCurrentFrame(false) {
7665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
77e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong    mTimeBetweenFrameCaptureUs = timeBetweenFrameCaptureUs;
78b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("starting time lapse mode: %lld us",
79e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        mTimeBetweenFrameCaptureUs);
803cecf640c4daf2df616b278bd9986018c8182908James Dong
8154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoWidth = videoSize.width;
8254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoHeight = videoSize.height;
83155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
843cecf640c4daf2df616b278bd9986018c8182908James Dong    if (!trySettingVideoSize(videoSize.width, videoSize.height)) {
853cecf640c4daf2df616b278bd9986018c8182908James Dong        mInitCheck = NO_INIT;
8665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
8778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
8878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    // Initialize quick stop variables.
8978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mQuickStop = false;
9078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mForceRead = false;
9178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy = NULL;
9278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mStopWaitingForIdleCamera = false;
9365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
9465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
9565e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse::~CameraSourceTimeLapse() {
96b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    if (mLastReadBufferCopy) {
97b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        mLastReadBufferCopy->release();
98b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        mLastReadBufferCopy = NULL;
99b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    }
10065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
10165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
10278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::startQuickReadReturns() {
1033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("startQuickReadReturns");
10478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
10578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
10678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    // Enable quick stop mode.
10778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mQuickStop = true;
10878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1093cecf640c4daf2df616b278bd9986018c8182908James Dong    // Force dataCallbackTimestamp() coming from the video camera to
1103cecf640c4daf2df616b278bd9986018c8182908James Dong    // not skip the next frame as we want read() to get a get a frame
1113cecf640c4daf2df616b278bd9986018c8182908James Dong    // right away.
1123cecf640c4daf2df616b278bd9986018c8182908James Dong    mForceRead = true;
11378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
11478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1153cecf640c4daf2df616b278bd9986018c8182908James Dongbool CameraSourceTimeLapse::trySettingVideoSize(
1163cecf640c4daf2df616b278bd9986018c8182908James Dong        int32_t width, int32_t height) {
1173cecf640c4daf2df616b278bd9986018c8182908James Dong
1183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("trySettingVideoSize");
119155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    int64_t token = IPCThreadState::self()->clearCallingIdentity();
120155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    String8 s = mCamera->getParameters();
121155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
122155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    CameraParameters params(s);
123155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    Vector<Size> supportedSizes;
12428934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    params.getSupportedVideoSizes(supportedSizes);
12528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoOutputSupported = false;
12628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (supportedSizes.size() == 0) {
12728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        params.getSupportedPreviewSizes(supportedSizes);
12828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    } else {
12928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        videoOutputSupported = true;
13028934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    }
131155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
13228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoSizeSupported = false;
133155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
134155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureWidth = supportedSizes[i].width;
135155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureHeight = supportedSizes[i].height;
136155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
137155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        if ((pictureWidth == width) && (pictureHeight == height)) {
13828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            videoSizeSupported = true;
139155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        }
140155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
141155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
142ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    bool isSuccessful = false;
14328934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (videoSizeSupported) {
1443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Video size (%d, %d) is supported", width, height);
14528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        if (videoOutputSupported) {
14628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setVideoSize(width, height);
14728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        } else {
14828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setPreviewSize(width, height);
14928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        }
150ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        if (mCamera->setParameters(params.flatten()) == OK) {
151ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = true;
152ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        } else {
15329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to set preview size to %dx%d", width, height);
154ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = false;
155ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        }
156155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
157155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
158ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    IPCThreadState::self()->restoreCallingIdentity(token);
159ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    return isSuccessful;
160155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra}
161155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
16278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) {
1633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned");
16478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
16578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mQuickStop && (buffer == mLastReadBufferCopy)) {
16678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->setObserver(NULL);
16778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->release();
16878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
16978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return CameraSource::signalBufferReturned(buffer);
17078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
17178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
17278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1733cecf640c4daf2df616b278bd9986018c8182908James Dongvoid createMediaBufferCopy(
1743cecf640c4daf2df616b278bd9986018c8182908James Dong        const MediaBuffer& sourceBuffer,
1753cecf640c4daf2df616b278bd9986018c8182908James Dong        int64_t frameTime,
1763cecf640c4daf2df616b278bd9986018c8182908James Dong        MediaBuffer **newBuffer) {
1773cecf640c4daf2df616b278bd9986018c8182908James Dong
1783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createMediaBufferCopy");
17978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    size_t sourceSize = sourceBuffer.size();
18078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    void* sourcePointer = sourceBuffer.data();
18178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
18278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer) = new MediaBuffer(sourceSize);
18378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    memcpy((*newBuffer)->data(), sourcePointer, sourceSize);
18478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
18578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime);
18678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
18778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
18878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) {
1893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("fillLastReadBufferCopy");
19078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    int64_t frameTime;
19178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime));
19278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
19378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->add_ref();
19478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->setObserver(this);
19578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
19678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
19778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatrastatus_t CameraSourceTimeLapse::read(
19878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        MediaBuffer **buffer, const ReadOptions *options) {
1993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("read");
20078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mLastReadBufferCopy == NULL) {
20178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mLastReadStatus = CameraSource::read(buffer, options);
20278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2033cecf640c4daf2df616b278bd9986018c8182908James Dong        // mQuickStop may have turned to true while read was blocked.
2043cecf640c4daf2df616b278bd9986018c8182908James Dong        // Make a copy of the buffer in that case.
20578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        Mutex::Autolock autoLock(mQuickStopLock);
20678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        if (mQuickStop && *buffer) {
20778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            fillLastReadBufferCopy(**buffer);
20878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        }
20978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
21078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
21178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer) = mLastReadBufferCopy;
21278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer)->add_ref();
21378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
21478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
21578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
21678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2173cecf640c4daf2df616b278bd9986018c8182908James Dongsp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
2183cecf640c4daf2df616b278bd9986018c8182908James Dong        const sp<IMemory> &source_data) {
21965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createIMemoryCopy");
22165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    size_t source_size = source_data->size();
22265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    void* source_pointer = source_data->pointer();
22365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
22465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size);
22565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size);
22665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    memcpy(newMemory->pointer(), source_pointer, source_size);
22765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return newMemory;
22865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
22965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
23065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
2313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipCurrentFrame");
232c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra    if (mSkipCurrentFrame) {
23365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        mSkipCurrentFrame = false;
23465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return true;
23565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    } else {
23665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return false;
23765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
23865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
23965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
24065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
2413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipFrameAndModifyTimeStamp");
2423cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mLastTimeLapseFrameRealTimestampUs == 0) {
2433cecf640c4daf2df616b278bd9986018c8182908James Dong        // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
2443cecf640c4daf2df616b278bd9986018c8182908James Dong        // to current time (timestampUs) and save frame data.
2453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: initial frame");
24665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2473cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2483cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2493cecf640c4daf2df616b278bd9986018c8182908James Dong    }
25078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2513cecf640c4daf2df616b278bd9986018c8182908James Dong    {
2523cecf640c4daf2df616b278bd9986018c8182908James Dong        Mutex::Autolock autoLock(mQuickStopLock);
25378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2543cecf640c4daf2df616b278bd9986018c8182908James Dong        // mForceRead may be set to true by startQuickReadReturns(). In that
2553cecf640c4daf2df616b278bd9986018c8182908James Dong        // case don't skip this frame.
2563cecf640c4daf2df616b278bd9986018c8182908James Dong        if (mForceRead) {
2573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dataCallbackTimestamp timelapse: forced read");
2583cecf640c4daf2df616b278bd9986018c8182908James Dong            mForceRead = false;
2593cecf640c4daf2df616b278bd9986018c8182908James Dong            *timestampUs =
2603cecf640c4daf2df616b278bd9986018c8182908James Dong                mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
26193594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong
26293594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            // Really make sure that this video recording frame will not be dropped.
26393594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            if (*timestampUs < mStartTimeUs) {
264df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("set timestampUs to start time stamp %lld us", mStartTimeUs);
26593594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong                *timestampUs = mStartTimeUs;
26693594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            }
26778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            return false;
26865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        }
26965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
2703cecf640c4daf2df616b278bd9986018c8182908James Dong
2713cecf640c4daf2df616b278bd9986018c8182908James Dong    // Workaround to bypass the first 2 input frames for skipping.
2723cecf640c4daf2df616b278bd9986018c8182908James Dong    // The first 2 output frames from the encoder are: decoder specific info and
2733cecf640c4daf2df616b278bd9986018c8182908James Dong    // the compressed video frame data for the first input video frame.
2743cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mNumFramesEncoded >= 1 && *timestampUs <
275e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
2763cecf640c4daf2df616b278bd9986018c8182908James Dong        // Skip all frames from last encoded frame until
277e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
2783cecf640c4daf2df616b278bd9986018c8182908James Dong        // Tell the camera to release its recording frame and return.
2793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
2803cecf640c4daf2df616b278bd9986018c8182908James Dong        return true;
2813cecf640c4daf2df616b278bd9986018c8182908James Dong    } else {
282e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // Desired frame has arrived after mTimeBetweenFrameCaptureUs time:
2833cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
2843cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
2853cecf640c4daf2df616b278bd9986018c8182908James Dong        // of the last encoded frame's time stamp.
2863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: got timelapse frame");
2873cecf640c4daf2df616b278bd9986018c8182908James Dong
2883cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2893cecf640c4daf2df616b278bd9986018c8182908James Dong        *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
2903cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2913cecf640c4daf2df616b278bd9986018c8182908James Dong    }
29265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return false;
29365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
29465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
29565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
29665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra            const sp<IMemory> &data) {
2973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dataCallbackTimestamp");
2983cecf640c4daf2df616b278bd9986018c8182908James Dong    mSkipCurrentFrame = skipFrameAndModifyTimeStamp(&timestampUs);
29965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
30065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
30165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
30265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}  // namespace android
303