CameraSourceTimeLapse.cpp revision f1d5aa162c02a16b7195a43a9bcea4d592600ac4
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,
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() {
90b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    if (mLastReadBufferCopy) {
91b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        mLastReadBufferCopy->release();
92b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        mLastReadBufferCopy = NULL;
93b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    }
9465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
9565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
9678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::startQuickReadReturns() {
973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("startQuickReadReturns");
9878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
9978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
10078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    // Enable quick stop mode.
10178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mQuickStop = true;
10278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1033cecf640c4daf2df616b278bd9986018c8182908James Dong    // Force dataCallbackTimestamp() coming from the video camera to
1043cecf640c4daf2df616b278bd9986018c8182908James Dong    // not skip the next frame as we want read() to get a get a frame
1053cecf640c4daf2df616b278bd9986018c8182908James Dong    // right away.
1063cecf640c4daf2df616b278bd9986018c8182908James Dong    mForceRead = true;
10778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
10878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1093cecf640c4daf2df616b278bd9986018c8182908James Dongbool CameraSourceTimeLapse::trySettingVideoSize(
1103cecf640c4daf2df616b278bd9986018c8182908James Dong        int32_t width, int32_t height) {
1113cecf640c4daf2df616b278bd9986018c8182908James Dong
1123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("trySettingVideoSize");
113155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    int64_t token = IPCThreadState::self()->clearCallingIdentity();
114155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    String8 s = mCamera->getParameters();
115155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
116155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    CameraParameters params(s);
117155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    Vector<Size> supportedSizes;
11828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    params.getSupportedVideoSizes(supportedSizes);
11928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoOutputSupported = false;
12028934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (supportedSizes.size() == 0) {
12128934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        params.getSupportedPreviewSizes(supportedSizes);
12228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    } else {
12328934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        videoOutputSupported = true;
12428934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    }
125155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
12628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    bool videoSizeSupported = false;
127155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
128155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureWidth = supportedSizes[i].width;
129155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        int32_t pictureHeight = supportedSizes[i].height;
130155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
131155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        if ((pictureWidth == width) && (pictureHeight == height)) {
13228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            videoSizeSupported = true;
133155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra        }
134155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
135155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
136ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    bool isSuccessful = false;
13728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong    if (videoSizeSupported) {
1383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Video size (%d, %d) is supported", width, height);
13928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        if (videoOutputSupported) {
14028934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setVideoSize(width, height);
14128934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        } else {
14228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong            params.setPreviewSize(width, height);
14328934a90e168291f6c77c56e8a05f272e5151bbdJames Dong        }
144ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        if (mCamera->setParameters(params.flatten()) == OK) {
145ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = true;
146ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        } else {
14729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to set preview size to %dx%d", width, height);
148ba29002c7aee13c068049037cd14bba6a244da6bJames Dong            isSuccessful = false;
149ba29002c7aee13c068049037cd14bba6a244da6bJames Dong        }
150155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra    }
151155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
152ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    IPCThreadState::self()->restoreCallingIdentity(token);
153ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    return isSuccessful;
154155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra}
155155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra
15678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) {
1573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned");
15878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    Mutex::Autolock autoLock(mQuickStopLock);
15978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mQuickStop && (buffer == mLastReadBufferCopy)) {
16078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->setObserver(NULL);
16178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        buffer->release();
16278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
16378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return CameraSource::signalBufferReturned(buffer);
16478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
16578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
16678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1673cecf640c4daf2df616b278bd9986018c8182908James Dongvoid createMediaBufferCopy(
1683cecf640c4daf2df616b278bd9986018c8182908James Dong        const MediaBuffer& sourceBuffer,
1693cecf640c4daf2df616b278bd9986018c8182908James Dong        int64_t frameTime,
1703cecf640c4daf2df616b278bd9986018c8182908James Dong        MediaBuffer **newBuffer) {
1713cecf640c4daf2df616b278bd9986018c8182908James Dong
1723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createMediaBufferCopy");
17378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    size_t sourceSize = sourceBuffer.size();
17478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    void* sourcePointer = sourceBuffer.data();
17578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
17678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer) = new MediaBuffer(sourceSize);
17778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    memcpy((*newBuffer)->data(), sourcePointer, sourceSize);
17878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
17978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime);
18078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
18178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
18278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) {
1833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("fillLastReadBufferCopy");
18478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    int64_t frameTime;
18578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime));
18678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
18778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->add_ref();
18878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    mLastReadBufferCopy->setObserver(this);
18978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
19078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
19178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatrastatus_t CameraSourceTimeLapse::read(
19278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        MediaBuffer **buffer, const ReadOptions *options) {
1933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("read");
19478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    if (mLastReadBufferCopy == NULL) {
19578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        mLastReadStatus = CameraSource::read(buffer, options);
19678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
1973cecf640c4daf2df616b278bd9986018c8182908James Dong        // mQuickStop may have turned to true while read was blocked.
1983cecf640c4daf2df616b278bd9986018c8182908James Dong        // Make a copy of the buffer in that case.
19978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        Mutex::Autolock autoLock(mQuickStopLock);
20078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        if (mQuickStop && *buffer) {
20178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            fillLastReadBufferCopy(**buffer);
20278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        }
20378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
20478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    } else {
20578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer) = mLastReadBufferCopy;
20678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        (*buffer)->add_ref();
20778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra        return mLastReadStatus;
20878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra    }
20978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra}
21078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2113cecf640c4daf2df616b278bd9986018c8182908James Dongsp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
2123cecf640c4daf2df616b278bd9986018c8182908James Dong        const sp<IMemory> &source_data) {
21365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("createIMemoryCopy");
21565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    size_t source_size = source_data->size();
21665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    void* source_pointer = source_data->pointer();
21765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
21865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size);
21965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size);
22065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    memcpy(newMemory->pointer(), source_pointer, source_size);
22165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return newMemory;
22265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
22365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
22465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
2253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipCurrentFrame");
226c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra    if (mSkipCurrentFrame) {
22765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        mSkipCurrentFrame = false;
22865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return true;
22965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    } else {
23065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return false;
23165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
23265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
23365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
23465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
2353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("skipFrameAndModifyTimeStamp");
2363cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mLastTimeLapseFrameRealTimestampUs == 0) {
2373cecf640c4daf2df616b278bd9986018c8182908James Dong        // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
2383cecf640c4daf2df616b278bd9986018c8182908James Dong        // to current time (timestampUs) and save frame data.
2393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: initial frame");
24065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
2413cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2423cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2433cecf640c4daf2df616b278bd9986018c8182908James Dong    }
24478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2453cecf640c4daf2df616b278bd9986018c8182908James Dong    {
2463cecf640c4daf2df616b278bd9986018c8182908James Dong        Mutex::Autolock autoLock(mQuickStopLock);
24778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra
2483cecf640c4daf2df616b278bd9986018c8182908James Dong        // mForceRead may be set to true by startQuickReadReturns(). In that
2493cecf640c4daf2df616b278bd9986018c8182908James Dong        // case don't skip this frame.
2503cecf640c4daf2df616b278bd9986018c8182908James Dong        if (mForceRead) {
2513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("dataCallbackTimestamp timelapse: forced read");
2523cecf640c4daf2df616b278bd9986018c8182908James Dong            mForceRead = false;
2533cecf640c4daf2df616b278bd9986018c8182908James Dong            *timestampUs =
2543cecf640c4daf2df616b278bd9986018c8182908James Dong                mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
25593594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong
25693594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            // Really make sure that this video recording frame will not be dropped.
25793594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            if (*timestampUs < mStartTimeUs) {
258df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block                ALOGI("set timestampUs to start time stamp %lld us", mStartTimeUs);
25993594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong                *timestampUs = mStartTimeUs;
26093594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong            }
26178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra            return false;
26265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        }
26365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
2643cecf640c4daf2df616b278bd9986018c8182908James Dong
2653cecf640c4daf2df616b278bd9986018c8182908James Dong    // Workaround to bypass the first 2 input frames for skipping.
2663cecf640c4daf2df616b278bd9986018c8182908James Dong    // The first 2 output frames from the encoder are: decoder specific info and
2673cecf640c4daf2df616b278bd9986018c8182908James Dong    // the compressed video frame data for the first input video frame.
2683cecf640c4daf2df616b278bd9986018c8182908James Dong    if (mNumFramesEncoded >= 1 && *timestampUs <
269e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) {
2703cecf640c4daf2df616b278bd9986018c8182908James Dong        // Skip all frames from last encoded frame until
271e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // sufficient time (mTimeBetweenFrameCaptureUs) has passed.
2723cecf640c4daf2df616b278bd9986018c8182908James Dong        // Tell the camera to release its recording frame and return.
2733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
2743cecf640c4daf2df616b278bd9986018c8182908James Dong        return true;
2753cecf640c4daf2df616b278bd9986018c8182908James Dong    } else {
276e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong        // Desired frame has arrived after mTimeBetweenFrameCaptureUs time:
2773cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
2783cecf640c4daf2df616b278bd9986018c8182908James Dong        // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
2793cecf640c4daf2df616b278bd9986018c8182908James Dong        // of the last encoded frame's time stamp.
2803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("dataCallbackTimestamp timelapse: got timelapse frame");
2813cecf640c4daf2df616b278bd9986018c8182908James Dong
2823cecf640c4daf2df616b278bd9986018c8182908James Dong        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
2833cecf640c4daf2df616b278bd9986018c8182908James Dong        *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
2843cecf640c4daf2df616b278bd9986018c8182908James Dong        return false;
2853cecf640c4daf2df616b278bd9986018c8182908James Dong    }
28665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    return false;
28765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
28865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
28965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
29065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra            const sp<IMemory> &data) {
2913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dataCallbackTimestamp");
2923cecf640c4daf2df616b278bd9986018c8182908James Dong    mSkipCurrentFrame = skipFrameAndModifyTimeStamp(&timestampUs);
29365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
29465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
29565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
29665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}  // namespace android
297