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 17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 1965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra//#define LOG_NDEBUG 0 2065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#define LOG_TAG "CameraSourceTimeLapse" 2165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 2265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/IPCThreadState.h> 2365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/MemoryBase.h> 2465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <binder/MemoryHeapBase.h> 25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSource.h> 2765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/CameraSourceTimeLapse.h> 2865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <media/stagefright/MetaData.h> 2965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/Camera.h> 3065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/CameraParameters.h> 3165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <utils/String8.h> 3240e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra#include <utils/Vector.h> 3365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 3465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatranamespace android { 3565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 3665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra// static 3754ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera( 38d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera> &camera, 394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy> &proxy, 4054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 41ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 42ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 4398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 4454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 4554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t videoFrameRate, 4699617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 479c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar int64_t timeBetweenFrameCaptureUs, 489c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar bool storeMetaDataInVideoBuffers) { 4954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraSourceTimeLapse *source = new 514ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSourceTimeLapse(camera, proxy, cameraId, 5298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, 5354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize, videoFrameRate, surface, 549c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar timeBetweenFrameCaptureUs, 559c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar storeMetaDataInVideoBuffers); 5654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (source != NULL) { 5854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (source->initCheck() != OK) { 5954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong delete source; 6054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return NULL; 6154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 6265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 6354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 6465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 6565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 6654ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSourceTimeLapse::CameraSourceTimeLapse( 67d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 6954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 70ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 71ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 7298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 7354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 7454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t videoFrameRate, 7599617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 769c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar int64_t timeBetweenFrameCaptureUs, 779c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar bool storeMetaDataInVideoBuffers) 7898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen : CameraSource(camera, proxy, cameraId, clientName, clientUid, clientPid, 799c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar videoSize, videoFrameRate, surface, 809c7f845780d62ea09469a8dac7117cc01adfea5cLajos Molnar storeMetaDataInVideoBuffers), 8165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate), 8265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastTimeLapseFrameRealTimestampUs(0), 8365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mSkipCurrentFrame(false) { 8465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 85e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs = timeBetweenFrameCaptureUs; 86a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGD("starting time lapse mode: %" PRId64 " us", 87e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs); 883cecf640c4daf2df616b278bd9986018c8182908James Dong 8954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoWidth = videoSize.width; 9054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoHeight = videoSize.height; 91155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 929bb976e1c78048081cf9df4d8a1db67311413e5bRobert Shih if (OK == mInitCheck && !trySettingVideoSize(videoSize.width, videoSize.height)) { 939bb976e1c78048081cf9df4d8a1db67311413e5bRobert Shih releaseCamera(); 943cecf640c4daf2df616b278bd9986018c8182908James Dong mInitCheck = NO_INIT; 9565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 9678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 9778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Initialize quick stop variables. 9878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mQuickStop = false; 9978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mForceRead = false; 10078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy = NULL; 10178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mStopWaitingForIdleCamera = false; 10265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 10365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 10465e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse::~CameraSourceTimeLapse() { 105b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong if (mLastReadBufferCopy) { 106b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong mLastReadBufferCopy->release(); 107b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong mLastReadBufferCopy = NULL; 108b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong } 10965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 11065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 11178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::startQuickReadReturns() { 1123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("startQuickReadReturns"); 11378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 11478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 11578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Enable quick stop mode. 11678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mQuickStop = true; 11778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 1183cecf640c4daf2df616b278bd9986018c8182908James Dong // Force dataCallbackTimestamp() coming from the video camera to 1193cecf640c4daf2df616b278bd9986018c8182908James Dong // not skip the next frame as we want read() to get a get a frame 1203cecf640c4daf2df616b278bd9986018c8182908James Dong // right away. 1213cecf640c4daf2df616b278bd9986018c8182908James Dong mForceRead = true; 12278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 12378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 1243cecf640c4daf2df616b278bd9986018c8182908James Dongbool CameraSourceTimeLapse::trySettingVideoSize( 1253cecf640c4daf2df616b278bd9986018c8182908James Dong int32_t width, int32_t height) { 1263cecf640c4daf2df616b278bd9986018c8182908James Dong 1273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("trySettingVideoSize"); 128155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int64_t token = IPCThreadState::self()->clearCallingIdentity(); 129155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra String8 s = mCamera->getParameters(); 130155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 131155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra CameraParameters params(s); 132155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra Vector<Size> supportedSizes; 13328934a90e168291f6c77c56e8a05f272e5151bbdJames Dong params.getSupportedVideoSizes(supportedSizes); 13428934a90e168291f6c77c56e8a05f272e5151bbdJames Dong bool videoOutputSupported = false; 13528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong if (supportedSizes.size() == 0) { 13628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong params.getSupportedPreviewSizes(supportedSizes); 13728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong } else { 13828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong videoOutputSupported = true; 13928934a90e168291f6c77c56e8a05f272e5151bbdJames Dong } 140155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 14128934a90e168291f6c77c56e8a05f272e5151bbdJames Dong bool videoSizeSupported = false; 1423ab368e0810d894dcbc0971350c095049478a055Mark Salyzyn for (size_t i = 0; i < supportedSizes.size(); ++i) { 143155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int32_t pictureWidth = supportedSizes[i].width; 144155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int32_t pictureHeight = supportedSizes[i].height; 145155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 146155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra if ((pictureWidth == width) && (pictureHeight == height)) { 14728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong videoSizeSupported = true; 148155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 149155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 150155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 151ba29002c7aee13c068049037cd14bba6a244da6bJames Dong bool isSuccessful = false; 15228934a90e168291f6c77c56e8a05f272e5151bbdJames Dong if (videoSizeSupported) { 1533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Video size (%d, %d) is supported", width, height); 15428934a90e168291f6c77c56e8a05f272e5151bbdJames Dong if (videoOutputSupported) { 15528934a90e168291f6c77c56e8a05f272e5151bbdJames Dong params.setVideoSize(width, height); 15628934a90e168291f6c77c56e8a05f272e5151bbdJames Dong } else { 15728934a90e168291f6c77c56e8a05f272e5151bbdJames Dong params.setPreviewSize(width, height); 15828934a90e168291f6c77c56e8a05f272e5151bbdJames Dong } 159ba29002c7aee13c068049037cd14bba6a244da6bJames Dong if (mCamera->setParameters(params.flatten()) == OK) { 160ba29002c7aee13c068049037cd14bba6a244da6bJames Dong isSuccessful = true; 161ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } else { 16229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set preview size to %dx%d", width, height); 163ba29002c7aee13c068049037cd14bba6a244da6bJames Dong isSuccessful = false; 164ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 165155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 166155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 167ba29002c7aee13c068049037cd14bba6a244da6bJames Dong IPCThreadState::self()->restoreCallingIdentity(token); 168ba29002c7aee13c068049037cd14bba6a244da6bJames Dong return isSuccessful; 169155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra} 170155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 17178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) { 1723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned"); 17378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 17478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mQuickStop && (buffer == mLastReadBufferCopy)) { 17578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra buffer->setObserver(NULL); 17678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra buffer->release(); 17778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 17878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return CameraSource::signalBufferReturned(buffer); 17978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 18078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 18178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 1823cecf640c4daf2df616b278bd9986018c8182908James Dongvoid createMediaBufferCopy( 1833cecf640c4daf2df616b278bd9986018c8182908James Dong const MediaBuffer& sourceBuffer, 1843cecf640c4daf2df616b278bd9986018c8182908James Dong int64_t frameTime, 1853cecf640c4daf2df616b278bd9986018c8182908James Dong MediaBuffer **newBuffer) { 1863cecf640c4daf2df616b278bd9986018c8182908James Dong 1873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("createMediaBufferCopy"); 18878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra size_t sourceSize = sourceBuffer.size(); 18978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra void* sourcePointer = sourceBuffer.data(); 19078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 19178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*newBuffer) = new MediaBuffer(sourceSize); 19278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra memcpy((*newBuffer)->data(), sourcePointer, sourceSize); 19378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 19478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime); 19578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 19678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 19778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) { 1983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("fillLastReadBufferCopy"); 19978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra int64_t frameTime; 20078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime)); 20178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy); 20278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy->add_ref(); 20378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy->setObserver(this); 20478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 20578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 20678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatrastatus_t CameraSourceTimeLapse::read( 20778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra MediaBuffer **buffer, const ReadOptions *options) { 2083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read"); 20978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mLastReadBufferCopy == NULL) { 21078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadStatus = CameraSource::read(buffer, options); 21178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 2123cecf640c4daf2df616b278bd9986018c8182908James Dong // mQuickStop may have turned to true while read was blocked. 2133cecf640c4daf2df616b278bd9986018c8182908James Dong // Make a copy of the buffer in that case. 21478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 21578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mQuickStop && *buffer) { 21678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra fillLastReadBufferCopy(**buffer); 21778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 21878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return mLastReadStatus; 21978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 22078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*buffer) = mLastReadBufferCopy; 22178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*buffer)->add_ref(); 22278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return mLastReadStatus; 22378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 22478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 22578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 2263cecf640c4daf2df616b278bd9986018c8182908James Dongsp<IMemory> CameraSourceTimeLapse::createIMemoryCopy( 2273cecf640c4daf2df616b278bd9986018c8182908James Dong const sp<IMemory> &source_data) { 22865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 2293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("createIMemoryCopy"); 23065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra size_t source_size = source_data->size(); 23165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra void* source_pointer = source_data->pointer(); 23265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 23365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size); 23465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size); 23565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra memcpy(newMemory->pointer(), source_pointer, source_size); 23665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return newMemory; 23765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 23865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 23984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberbool CameraSourceTimeLapse::skipCurrentFrame(int64_t /* timestampUs */) { 2403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("skipCurrentFrame"); 241c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mSkipCurrentFrame) { 24265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mSkipCurrentFrame = false; 24365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return true; 24465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 24565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return false; 24665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 24765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 24865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 24965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) { 2503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("skipFrameAndModifyTimeStamp"); 2513cecf640c4daf2df616b278bd9986018c8182908James Dong if (mLastTimeLapseFrameRealTimestampUs == 0) { 2523cecf640c4daf2df616b278bd9986018c8182908James Dong // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs 2533cecf640c4daf2df616b278bd9986018c8182908James Dong // to current time (timestampUs) and save frame data. 2543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp timelapse: initial frame"); 25565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 2563cecf640c4daf2df616b278bd9986018c8182908James Dong mLastTimeLapseFrameRealTimestampUs = *timestampUs; 2573cecf640c4daf2df616b278bd9986018c8182908James Dong return false; 2583cecf640c4daf2df616b278bd9986018c8182908James Dong } 25978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 2603cecf640c4daf2df616b278bd9986018c8182908James Dong { 2613cecf640c4daf2df616b278bd9986018c8182908James Dong Mutex::Autolock autoLock(mQuickStopLock); 26278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 2633cecf640c4daf2df616b278bd9986018c8182908James Dong // mForceRead may be set to true by startQuickReadReturns(). In that 2643cecf640c4daf2df616b278bd9986018c8182908James Dong // case don't skip this frame. 2653cecf640c4daf2df616b278bd9986018c8182908James Dong if (mForceRead) { 2663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp timelapse: forced read"); 2673cecf640c4daf2df616b278bd9986018c8182908James Dong mForceRead = false; 2683cecf640c4daf2df616b278bd9986018c8182908James Dong *timestampUs = 2693cecf640c4daf2df616b278bd9986018c8182908James Dong mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs; 27093594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong 27193594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong // Really make sure that this video recording frame will not be dropped. 27293594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong if (*timestampUs < mStartTimeUs) { 273a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGI("set timestampUs to start time stamp %" PRId64 " us", mStartTimeUs); 27493594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong *timestampUs = mStartTimeUs; 27593594b5aa16dbbb0b196f6e181a8ca099d7ab62bJames Dong } 27678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return false; 27765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 27865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 2793cecf640c4daf2df616b278bd9986018c8182908James Dong 2803cecf640c4daf2df616b278bd9986018c8182908James Dong // Workaround to bypass the first 2 input frames for skipping. 2813cecf640c4daf2df616b278bd9986018c8182908James Dong // The first 2 output frames from the encoder are: decoder specific info and 2823cecf640c4daf2df616b278bd9986018c8182908James Dong // the compressed video frame data for the first input video frame. 2833cecf640c4daf2df616b278bd9986018c8182908James Dong if (mNumFramesEncoded >= 1 && *timestampUs < 284e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenFrameCaptureUs)) { 2853cecf640c4daf2df616b278bd9986018c8182908James Dong // Skip all frames from last encoded frame until 286e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong // sufficient time (mTimeBetweenFrameCaptureUs) has passed. 2873cecf640c4daf2df616b278bd9986018c8182908James Dong // Tell the camera to release its recording frame and return. 2883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp timelapse: skipping intermediate frame"); 2893cecf640c4daf2df616b278bd9986018c8182908James Dong return true; 2903cecf640c4daf2df616b278bd9986018c8182908James Dong } else { 291e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong // Desired frame has arrived after mTimeBetweenFrameCaptureUs time: 2923cecf640c4daf2df616b278bd9986018c8182908James Dong // - Reset mLastTimeLapseFrameRealTimestampUs to current time. 2933cecf640c4daf2df616b278bd9986018c8182908James Dong // - Artificially modify timestampUs to be one frame time (1/framerate) ahead 2943cecf640c4daf2df616b278bd9986018c8182908James Dong // of the last encoded frame's time stamp. 2953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp timelapse: got timelapse frame"); 2963cecf640c4daf2df616b278bd9986018c8182908James Dong 2973cecf640c4daf2df616b278bd9986018c8182908James Dong mLastTimeLapseFrameRealTimestampUs = *timestampUs; 2983cecf640c4daf2df616b278bd9986018c8182908James Dong *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs; 2993cecf640c4daf2df616b278bd9986018c8182908James Dong return false; 3003cecf640c4daf2df616b278bd9986018c8182908James Dong } 30165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return false; 30265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 30365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 30465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, 30565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra const sp<IMemory> &data) { 3063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("dataCallbackTimestamp"); 3073cecf640c4daf2df616b278bd9986018c8182908James Dong mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs); 30865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CameraSource::dataCallbackTimestamp(timestampUs, msgType, data); 30965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 31065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 3112d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSourceTimeLapse::recordingFrameHandleCallbackTimestamp(int64_t timestampUs, 3122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 3132d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGV("recordingFrameHandleCallbackTimestamp"); 3142d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs); 3152d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen CameraSource::recordingFrameHandleCallbackTimestamp(timestampUs, handle); 3162d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 3172d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 3188fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chenvoid CameraSourceTimeLapse::processBufferQueueFrame(BufferItem& buffer) { 3198fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen ALOGV("processBufferQueueFrame"); 3208fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen int64_t timestampUs = buffer.mTimestamp / 1000; 3218fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs); 3228fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen buffer.mTimestamp = timestampUs * 1000; 3238fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen CameraSource::processBufferQueueFrame(buffer); 3248fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen} 3258fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chen 32665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} // namespace android 327