CameraSourceTimeLapse.cpp revision 29357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47
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>
2365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSource.h>
2465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h>
2565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/MediaDebug.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,
3954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
4054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t videoFrameRate,
4154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<Surface>& surface,
42e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        int64_t timeBetweenFrameCaptureUs) {
4354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraSourceTimeLapse *source = new
454ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            CameraSourceTimeLapse(camera, proxy, cameraId,
4654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                videoSize, videoFrameRate, surface,
47e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                timeBetweenFrameCaptureUs);
4854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (source != NULL) {
5054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (source->initCheck() != OK) {
5154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            delete source;
5254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return NULL;
5354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
5465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
5554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return source;
5665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
5765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
5854ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSourceTimeLapse::CameraSourceTimeLapse(
5954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<ICamera>& camera,
604ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        const sp<ICameraRecordingProxy>& proxy,
6154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t cameraId,
6254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
6354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t videoFrameRate,
6454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<Surface>& surface,
65e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        int64_t timeBetweenFrameCaptureUs)
664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    : CameraSource(camera, proxy, cameraId, videoSize, videoFrameRate, surface, true),
6765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
6865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mLastTimeLapseFrameRealTimestampUs(0),
6965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mSkipCurrentFrame(false) {
7065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
71e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong    mTimeBetweenFrameCaptureUs = timeBetweenFrameCaptureUs;
72b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("starting time lapse mode: %lld us",
73e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        mTimeBetweenFrameCaptureUs);
743cecf640c4daf2df616b278bd9986018c8182908James Dong
7554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoWidth = videoSize.width;
7654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoHeight = videoSize.height;
77155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
783cecf640c4daf2df616b278bd9986018c8182908James Dong    if (!trySettingVideoSize(videoSize.width, videoSize.height)) {
793cecf640c4daf2df616b278bd9986018c8182908James Dong        mInitCheck = NO_INIT;
8065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
8178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
8278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    // Initialize quick stop variables.
8378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mQuickStop = false;
8478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mForceRead = false;
8578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy = NULL;
8678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mStopWaitingForIdleCamera = false;
8765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
8865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
8965e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse::~CameraSourceTimeLapse() {
9065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
9165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
9278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::startQuickReadReturns() {
933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("startQuickReadReturns");
9478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
9578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
9678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    // Enable quick stop mode.
9778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mQuickStop = true;
9878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
993cecf640c4daf2df616b278bd9986018c8182908James Dong    // Force dataCallbackTimestamp() coming from the video camera to
1003cecf640c4daf2df616b278bd9986018c8182908James Dong    // not skip the next frame as we want read() to get a get a frame
1013cecf640c4daf2df616b278bd9986018c8182908James Dong    // right away.
1023cecf640c4daf2df616b278bd9986018c8182908James Dong    mForceRead = true;
10378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
10478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1053cecf640c4daf2df616b278bd9986018c8182908James Dongbool CameraSourceTimeLapse::trySettingVideoSize(
1063cecf640c4daf2df616b278bd9986018c8182908James Dong        int32_t width, int32_t height) {
1073cecf640c4daf2df616b278bd9986018c8182908James Dong
1083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("trySettingVideoSize");
109155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    int64_t token = IPCThreadState::self()->clearCallingIdentity();
110155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    String8 s = mCamera->getParameters();
111155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
112155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    CameraParameters params(s);
113155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    Vector<Size> supportedSizes;
11428934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    params.getSupportedVideoSizes(supportedSizes);
11528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoOutputSupported = false;
11628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (supportedSizes.size() == 0) {
11728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        params.getSupportedPreviewSizes(supportedSizes);
11828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    } else {
11928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        videoOutputSupported = true;
12028934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    }
121155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
12228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoSizeSupported = false;
123155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
124155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureWidth = supportedSizes[i].width;
125155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureHeight = supportedSizes[i].height;
126155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
127155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        if ((pictureWidth == width) && (pictureHeight == height)) {
12828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            videoSizeSupported = true;
129155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        }
130155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
131155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
132ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    bool isSuccessful = false;
13328934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (videoSizeSupported) {
1343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Video size (%d, %d) is supported", width, height);
13528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        if (videoOutputSupported) {
13628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setVideoSize(width, height);
13728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        } else {
13828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setPreviewSize(width, height);
13928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        }
140ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        if (mCamera->setParameters(params.flatten()) == OK) {
141ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = true;
142ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        } else {
14329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to set preview size to %dx%d", width, height);
144ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = false;
145ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        }
146155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
147155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
148ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    IPCThreadState::self()->restoreCallingIdentity(token);
149ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    return isSuccessful;
150155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra}
151155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
15278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) {
1533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned");
15478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
15578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mQuickStop && (buffer == mLastReadBufferCopy)) {
15678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->setObserver(NULL);
15778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->release();
15878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
15978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return CameraSource::signalBufferReturned(buffer);
16078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
16178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
16278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1633cecf640c4daf2df616b278bd9986018c8182908James Dongvoid createMediaBufferCopy(
1643cecf640c4daf2df616b278bd9986018c8182908James Dong        const MediaBuffer& sourceBuffer,
1653cecf640c4daf2df616b278bd9986018c8182908James Dong        int64_t frameTime,
1663cecf640c4daf2df616b278bd9986018c8182908James Dong        MediaBuffer **newBuffer) {
1673cecf640c4daf2df616b278bd9986018c8182908James Dong
1683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createMediaBufferCopy");
16978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    size_t sourceSize = sourceBuffer.size();
17078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    void* sourcePointer = sourceBuffer.data();
17178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
17278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer) = new MediaBuffer(sourceSize);
17378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    memcpy((*newBuffer)->data(), sourcePointer, sourceSize);
17478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
17578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime);
17678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
17778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
17878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) {
1793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("fillLastReadBufferCopy");
18078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    int64_t frameTime;
18178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime));
18278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
18378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->add_ref();
18478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->setObserver(this);
18578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
18678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
18778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatrastatus_t CameraSourceTimeLapse::read(
18878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        MediaBuffer **buffer, const ReadOptions *options) {
1893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("read");
19078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mLastReadBufferCopy == NULL) {
19178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mLastReadStatus = CameraSource::read(buffer, options);
19278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1933cecf640c4daf2df616b278bd9986018c8182908James Dong        // mQuickStop may have turned to true while read was blocked.
1943cecf640c4daf2df616b278bd9986018c8182908James Dong        // Make a copy of the buffer in that case.
19578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        Mutex::Autolock autoLock(mQuickStopLock);
19678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        if (mQuickStop && *buffer) {
19778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            fillLastReadBufferCopy(**buffer);
19878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        }
19978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
20078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
20178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer) = mLastReadBufferCopy;
20278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer)->add_ref();
20378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
20478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
20578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
20678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
20765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::stopCameraRecording() {
2083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stopCameraRecording");
2093cecf640c4daf2df616b278bd9986018c8182908James Dong    CameraSource::stopCameraRecording();
21078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mLastReadBufferCopy) {
21178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mLastReadBufferCopy->release();
21278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mLastReadBufferCopy = NULL;
21378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
21465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
21565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2163cecf640c4daf2df616b278bd9986018c8182908James Dongsp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
2173cecf640c4daf2df616b278bd9986018c8182908James Dong        const sp<IMemory> &source_data) {
21865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createIMemoryCopy");
22065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    size_t source_size = source_data->size();
22165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    void* source_pointer = source_data->pointer();
22265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
22365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size);
22465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size);
22565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    memcpy(newMemory->pointer(), source_pointer, source_size);
22665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return newMemory;
22765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
22865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
22965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
2303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipCurrentFrame");
231c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra    if (mSkipCurrentFrame) {
23265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        mSkipCurrentFrame = false;
23365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return true;
23465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    } else {
23565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return false;
23665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
23765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
23865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
23965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
2403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipFrameAndModifyTimeStamp");
2413cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mLastTimeLapseFrameRealTimestampUs == 0) {
2423cecf640c4daf2df616b278bd9986018c8182908James Dong        // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
2433cecf640c4daf2df616b278bd9986018c8182908James Dong        // to current time (timestampUs) and save frame data.
2443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: initial frame");
24565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2463cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2473cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2483cecf640c4daf2df616b278bd9986018c8182908James Dong    }
24978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2503cecf640c4daf2df616b278bd9986018c8182908James Dong    {
2513cecf640c4daf2df616b278bd9986018c8182908James Dong        Mutex::Autolock autoLock(mQuickStopLock);
25278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2533cecf640c4daf2df616b278bd9986018c8182908James Dong        // mForceRead may be set to true by startQuickReadReturns(). In that
2543cecf640c4daf2df616b278bd9986018c8182908James Dong        // case don't skip this frame.
2553cecf640c4daf2df616b278bd9986018c8182908James Dong        if (mForceRead) {
2563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dataCallbackTimestamp timelapse: forced read");
2573cecf640c4daf2df616b278bd9986018c8182908James Dong            mForceRead = false;
2583cecf640c4daf2df616b278bd9986018c8182908James Dong            *timestampUs =
2593cecf640c4daf2df616b278bd9986018c8182908James Dong                mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
26093594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong
26193594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            // Really make sure that this video recording frame will not be dropped.
26293594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            if (*timestampUs < mStartTimeUs) {
263df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("set timestampUs to start time stamp %lld us", mStartTimeUs);
26493594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong                *timestampUs = mStartTimeUs;
26593594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            }
26678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            return false;
26765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        }
26865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
2693cecf640c4daf2df616b278bd9986018c8182908James Dong
2703cecf640c4daf2df616b278bd9986018c8182908James Dong    // Workaround to bypass the first 2 input frames for skipping.
2713cecf640c4daf2df616b278bd9986018c8182908James Dong    // The first 2 output frames from the encoder are: decoder specific info and
2723cecf640c4daf2df616b278bd9986018c8182908James Dong    // the compressed video frame data for the first input video frame.
2733cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mNumFramesEncoded >= 1 && *timestampUs <
274e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
2753cecf640c4daf2df616b278bd9986018c8182908James Dong        // Skip all frames from last encoded frame until
276e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
2773cecf640c4daf2df616b278bd9986018c8182908James Dong        // Tell the camera to release its recording frame and return.
2783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
2793cecf640c4daf2df616b278bd9986018c8182908James Dong        return true;
2803cecf640c4daf2df616b278bd9986018c8182908James Dong    } else {
281e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // Desired frame has arrived after mTimeBetweenFrameCaptureUs time:
2823cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
2833cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
2843cecf640c4daf2df616b278bd9986018c8182908James Dong        // of the last encoded frame's time stamp.
2853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: got timelapse frame");
2863cecf640c4daf2df616b278bd9986018c8182908James Dong
2873cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2883cecf640c4daf2df616b278bd9986018c8182908James Dong        *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
2893cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2903cecf640c4daf2df616b278bd9986018c8182908James Dong    }
29165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return false;
29265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
29365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
29465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
29565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra            const sp<IMemory> &data) {
2963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dataCallbackTimestamp");
2973cecf640c4daf2df616b278bd9986018c8182908James Dong    mSkipCurrentFrame = skipFrameAndModifyTimeStamp(&timestampUs);
29865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
29965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
30065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
30165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}  // namespace android
302