CameraSourceTimeLapse.cpp revision 78eff720c86eb6d4e3d45a144df60b2ca464d2d4
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> 27c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra#include <media/stagefright/YUVImage.h> 28c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra#include <media/stagefright/YUVCanvas.h> 2965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/Camera.h> 3065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <camera/CameraParameters.h> 31c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra#include <ui/Rect.h> 3265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra#include <utils/String8.h> 3340e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra#include <utils/Vector.h> 34c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra#include "OMX_Video.h" 35fd150a8e03cdd8462eafd68f4a4231aa52f0e5a1Nipun Kwatra#include <limits.h> 3665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 3765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatranamespace android { 3865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 3965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra// static 40155e833a7a5fc3e193691324cf9326da1bc3289aNipun KwatraCameraSourceTimeLapse *CameraSourceTimeLapse::Create( 4165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int64_t timeBetweenTimeLapseFrameCaptureUs, 42e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra int32_t width, int32_t height, 4365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int32_t videoFrameRate) { 4465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<Camera> camera = Camera::connect(0); 4565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 4665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (camera.get() == NULL) { 4765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return NULL; 4865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 4965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 50155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra return new CameraSourceTimeLapse(camera, timeBetweenTimeLapseFrameCaptureUs, 51155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra width, height, videoFrameRate); 5265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 5365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 5465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra// static 5565e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(const sp<Camera> &camera, 5665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int64_t timeBetweenTimeLapseFrameCaptureUs, 57e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra int32_t width, int32_t height, 5865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int32_t videoFrameRate) { 5965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (camera.get() == NULL) { 6065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return NULL; 6165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 6265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 63155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra return new CameraSourceTimeLapse(camera, timeBetweenTimeLapseFrameCaptureUs, 64155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra width, height, videoFrameRate); 6565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 6665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 6765e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse::CameraSourceTimeLapse(const sp<Camera> &camera, 6865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int64_t timeBetweenTimeLapseFrameCaptureUs, 69e4e0a6994d39c4a7cba09c5fff442b2dca1df8f8Nipun Kwatra int32_t width, int32_t height, 7065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int32_t videoFrameRate) 7165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra : CameraSource(camera), 7265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs), 7365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate), 7465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastTimeLapseFrameRealTimestampUs(0), 7565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mSkipCurrentFrame(false) { 7665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 7765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("starting time lapse mode"); 78c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mVideoWidth = width; 79c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mVideoHeight = height; 80155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 81155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra if (trySettingPreviewSize(width, height)) { 82155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra mUseStillCameraForTimeLapse = false; 83155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } else { 84155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra // TODO: Add a check to see that mTimeBetweenTimeLapseFrameCaptureUs is greater 85155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra // than the fastest rate at which the still camera can take pictures. 86155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra mUseStillCameraForTimeLapse = true; 8740e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra CHECK(setPictureSizeToClosestSupported(width, height)); 88c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mNeedCropping = computeCropRectangleOffset(); 8965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mMeta->setInt32(kKeyWidth, width); 9065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mMeta->setInt32(kKeyHeight, height); 9165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 9278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 9378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Initialize quick stop variables. 9478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mQuickStop = false; 9578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mForceRead = false; 9678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy = NULL; 9778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mStopWaitingForIdleCamera = false; 9865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 9965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 10065e7e6facda89927cb26594b3b65ae81b3235ebcNipun KwatraCameraSourceTimeLapse::~CameraSourceTimeLapse() { 10165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 10265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 10378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::startQuickReadReturns() { 10478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 10578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra LOGV("Enabling quick read returns"); 10678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 10778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Enable quick stop mode. 10878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mQuickStop = true; 10978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 11078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mUseStillCameraForTimeLapse) { 11178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // wake up the thread right away. 11278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mTakePictureCondition.signal(); 11378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 11478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Force dataCallbackTimestamp() coming from the video camera to not skip the 11578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // next frame as we want read() to get a get a frame right away. 11678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mForceRead = true; 11778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 11878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 11978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 120155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatrabool CameraSourceTimeLapse::trySettingPreviewSize(int32_t width, int32_t height) { 121155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int64_t token = IPCThreadState::self()->clearCallingIdentity(); 122155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra String8 s = mCamera->getParameters(); 123155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra IPCThreadState::self()->restoreCallingIdentity(token); 124155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 125155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra CameraParameters params(s); 126155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra Vector<Size> supportedSizes; 127155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra params.getSupportedPreviewSizes(supportedSizes); 128155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 129155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra bool previewSizeSupported = false; 130155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra for (uint32_t i = 0; i < supportedSizes.size(); ++i) { 131155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int32_t pictureWidth = supportedSizes[i].width; 132155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra int32_t pictureHeight = supportedSizes[i].height; 133155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 134155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra if ((pictureWidth == width) && (pictureHeight == height)) { 135155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra previewSizeSupported = true; 136155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 137155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 138155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 139155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra if (previewSizeSupported) { 140155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra LOGV("Video size (%d, %d) is a supported preview size", width, height); 141155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra params.setPreviewSize(width, height); 142155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra CHECK(mCamera->setParameters(params.flatten())); 143155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra return true; 144155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra } 145155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 146155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra return false; 147155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra} 148155e833a7a5fc3e193691324cf9326da1bc3289aNipun Kwatra 14940e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatrabool CameraSourceTimeLapse::setPictureSizeToClosestSupported(int32_t width, int32_t height) { 15040e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra int64_t token = IPCThreadState::self()->clearCallingIdentity(); 15140e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra String8 s = mCamera->getParameters(); 15240e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra IPCThreadState::self()->restoreCallingIdentity(token); 15340e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra 15440e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra CameraParameters params(s); 15540e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra Vector<Size> supportedSizes; 15640e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra params.getSupportedPictureSizes(supportedSizes); 15740e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra 15840e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra int32_t minPictureSize = INT_MAX; 15940e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra for (uint32_t i = 0; i < supportedSizes.size(); ++i) { 16040e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra int32_t pictureWidth = supportedSizes[i].width; 16140e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra int32_t pictureHeight = supportedSizes[i].height; 16240e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra 16340e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra if ((pictureWidth >= width) && (pictureHeight >= height)) { 16440e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra int32_t pictureSize = pictureWidth*pictureHeight; 16540e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra if (pictureSize < minPictureSize) { 16640e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra minPictureSize = pictureSize; 16740e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra mPictureWidth = pictureWidth; 16840e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra mPictureHeight = pictureHeight; 16940e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra } 17040e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra } 17140e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra } 17240e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra LOGV("Picture size = (%d, %d)", mPictureWidth, mPictureHeight); 17340e2f3f9b41f44bdb59f7708a421b87f169a6edeNipun Kwatra return (minPictureSize != INT_MAX); 174c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra} 175c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 176c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatrabool CameraSourceTimeLapse::computeCropRectangleOffset() { 177c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if ((mPictureWidth == mVideoWidth) && (mPictureHeight == mVideoHeight)) { 178c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra return false; 179c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra } 180c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 181c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra CHECK((mPictureWidth > mVideoWidth) && (mPictureHeight > mVideoHeight)); 182c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 183c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra int32_t widthDifference = mPictureWidth - mVideoWidth; 184c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra int32_t heightDifference = mPictureHeight - mVideoHeight; 185c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 186c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mCropRectStartX = widthDifference/2; 187c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mCropRectStartY = heightDifference/2; 188c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 189c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra LOGV("setting crop rectangle offset to (%d, %d)", mCropRectStartX, mCropRectStartY); 190c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 191c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra return true; 192c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra} 193c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 19478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) { 19578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 19678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mQuickStop && (buffer == mLastReadBufferCopy)) { 19778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra buffer->setObserver(NULL); 19878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra buffer->release(); 19978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 20078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return CameraSource::signalBufferReturned(buffer); 20178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 20278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 20378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 20478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid createMediaBufferCopy(const MediaBuffer& sourceBuffer, int64_t frameTime, MediaBuffer **newBuffer) { 20578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra size_t sourceSize = sourceBuffer.size(); 20678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra void* sourcePointer = sourceBuffer.data(); 20778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 20878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*newBuffer) = new MediaBuffer(sourceSize); 20978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra memcpy((*newBuffer)->data(), sourcePointer, sourceSize); 21078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 21178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*newBuffer)->meta_data()->setInt64(kKeyTime, frameTime); 21278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 21378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 21478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatravoid CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) { 21578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra int64_t frameTime; 21678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime)); 21778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy); 21878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy->add_ref(); 21978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy->setObserver(this); 22078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 22178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 22278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatrastatus_t CameraSourceTimeLapse::read( 22378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra MediaBuffer **buffer, const ReadOptions *options) { 22478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mLastReadBufferCopy == NULL) { 22578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadStatus = CameraSource::read(buffer, options); 22678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 22778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // mQuickStop may have turned to true while read was blocked. Make a copy of 22878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // the buffer in that case. 22978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 23078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mQuickStop && *buffer) { 23178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra fillLastReadBufferCopy(**buffer); 23278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 23378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return mLastReadStatus; 23478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 23578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*buffer) = mLastReadBufferCopy; 23678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra (*buffer)->add_ref(); 23778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return mLastReadStatus; 23878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 23978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra} 24078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 24165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra// static 24265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid *CameraSourceTimeLapse::ThreadTimeLapseWrapper(void *me) { 24365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me); 24465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->threadTimeLapseEntry(); 24565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return NULL; 24665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 24765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 24865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::threadTimeLapseEntry() { 24978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra while (mStarted) { 25078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra { 25178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mCameraIdleLock); 25278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (!mCameraIdle) { 25378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraIdleCondition.wait(mCameraIdleLock); 25478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 25578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra CHECK(mCameraIdle); 2560aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra mCameraIdle = false; 2570aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra } 25878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 25978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Even if mQuickStop == true we need to take one more picture 26078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // as a read() may be blocked, waiting for a frame to get available. 26178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // After this takePicture, if mQuickStop == true, we can safely exit 26278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // this thread as read() will make a copy of this last frame and keep 26378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // returning it in the quick stop mode. 26478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 26578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra CHECK_EQ(OK, mCamera->takePicture()); 26678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mQuickStop) { 26778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra LOGV("threadTimeLapseEntry: Exiting due to mQuickStop = true"); 26878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return; 26978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 27078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mTakePictureCondition.waitRelative(mQuickStopLock, 27178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mTimeBetweenTimeLapseFrameCaptureUs * 1000); 27265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 27378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra LOGV("threadTimeLapseEntry: Exiting due to mStarted = false"); 27465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 27565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 27665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::startCameraRecording() { 277c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mUseStillCameraForTimeLapse) { 27865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("start time lapse recording using still camera"); 27965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 28065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int64_t token = IPCThreadState::self()->clearCallingIdentity(); 28165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra String8 s = mCamera->getParameters(); 28265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra IPCThreadState::self()->restoreCallingIdentity(token); 28365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 28465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CameraParameters params(s); 285c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra params.setPictureSize(mPictureWidth, mPictureHeight); 28665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCamera->setParameters(params.flatten()); 2870aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra mCameraIdle = true; 28878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mStopWaitingForIdleCamera = false; 28965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 2903ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra // disable shutter sound and play the recording sound. 2913ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0); 2923ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0); 2933ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra 29465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // create a thread which takes pictures in a loop 29565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_attr_t attr; 29665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_attr_init(&attr); 29765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 29865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 29965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_create(&mThreadTimeLapse, &attr, ThreadTimeLapseWrapper, this); 30065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_attr_destroy(&attr); 30165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 30265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("start time lapse recording using video camera"); 30365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CHECK_EQ(OK, mCamera->startRecording()); 30465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 30565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 30665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 30765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::stopCameraRecording() { 308c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mUseStillCameraForTimeLapse) { 30965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra void *dummy; 31065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra pthread_join(mThreadTimeLapse, &dummy); 3113ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra 31278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // Last takePicture may still be underway. Wait for the camera to get 31378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // idle. 31478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mCameraIdleLock); 31578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mStopWaitingForIdleCamera = true; 31678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (!mCameraIdle) { 31778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraIdleCondition.wait(mCameraIdleLock); 31878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 31978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra CHECK(mCameraIdle); 32078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCamera->setListener(NULL); 32178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 32278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // play the recording sound. 3233ee899e0466ecce107257beec04a2178939cf24eNipun Kwatra mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0); 32465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 32578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCamera->setListener(NULL); 32665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCamera->stopRecording(); 32765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 32878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mLastReadBufferCopy) { 32978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy->release(); 33078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mLastReadBufferCopy = NULL; 33178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 33265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 33365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 33465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::releaseRecordingFrame(const sp<IMemory>& frame) { 335c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (!mUseStillCameraForTimeLapse) { 33665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCamera->releaseRecordingFrame(frame); 33765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 33865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 33965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 34065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrasp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(const sp<IMemory> &source_data) { 34165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra size_t source_size = source_data->size(); 34265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra void* source_pointer = source_data->pointer(); 34365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 34465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(source_size); 34565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, source_size); 34665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra memcpy(newMemory->pointer(), source_pointer, source_size); 34765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return newMemory; 34865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 34965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 350c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra// Allocates IMemory of final type MemoryBase with the given size. 351c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatrasp<IMemory> allocateIMemory(size_t size) { 352c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(size); 353c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, size); 354c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra return newMemory; 355c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra} 356c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 3570aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra// static 3580aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatravoid *CameraSourceTimeLapse::ThreadStartPreviewWrapper(void *me) { 3590aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me); 3600aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra source->threadStartPreview(); 3610aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra return NULL; 3620aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra} 3630aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra 3640aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatravoid CameraSourceTimeLapse::threadStartPreview() { 3650aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra CHECK_EQ(OK, mCamera->startPreview()); 36678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mCameraIdleLock); 3670aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra mCameraIdle = true; 36878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCameraIdleCondition.signal(); 3690aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra} 3700aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra 3710aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatravoid CameraSourceTimeLapse::restartPreview() { 3720aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra // Start this in a different thread, so that the dataCallback can return 3730aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra LOGV("restartPreview"); 3740aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_attr_t attr; 3750aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_attr_init(&attr); 3760aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 3770aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra 3780aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_t threadPreview; 3790aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_create(&threadPreview, &attr, ThreadStartPreviewWrapper, this); 3800aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra pthread_attr_destroy(&attr); 3810aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra} 3820aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra 383c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatrasp<IMemory> CameraSourceTimeLapse::cropYUVImage(const sp<IMemory> &source_data) { 384c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra // find the YUV format 385c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra int32_t srcFormat; 386c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra CHECK(mMeta->findInt32(kKeyColorFormat, &srcFormat)); 387c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra YUVImage::YUVFormat yuvFormat; 388c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (srcFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 389c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra yuvFormat = YUVImage::YUV420SemiPlanar; 390616715ab614ce25ea395a8e9a553a82637f1021dJames Dong } else { 391616715ab614ce25ea395a8e9a553a82637f1021dJames Dong CHECK_EQ(srcFormat, OMX_COLOR_FormatYUV420Planar); 392c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra yuvFormat = YUVImage::YUV420Planar; 393c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra } 394c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 395c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra // allocate memory for cropped image and setup a canvas using it. 396c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra sp<IMemory> croppedImageMemory = allocateIMemory( 397c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra YUVImage::bufferSize(yuvFormat, mVideoWidth, mVideoHeight)); 398c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra YUVImage yuvImageCropped(yuvFormat, 399c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mVideoWidth, mVideoHeight, 400c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra (uint8_t *)croppedImageMemory->pointer()); 401c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra YUVCanvas yuvCanvasCrop(yuvImageCropped); 402c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 403c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra YUVImage yuvImageSource(yuvFormat, 404c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mPictureWidth, mPictureHeight, 405c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra (uint8_t *)source_data->pointer()); 406c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra yuvCanvasCrop.CopyImageRect( 407c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra Rect(mCropRectStartX, mCropRectStartY, 408c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mCropRectStartX + mVideoWidth, 409c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra mCropRectStartY + mVideoHeight), 410c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 0, 0, 411c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra yuvImageSource); 412c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 413c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra return croppedImageMemory; 414c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra} 415c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 41665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallback(int32_t msgType, const sp<IMemory> &data) { 417c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (msgType == CAMERA_MSG_COMPRESSED_IMAGE) { 4180aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra // takePicture will complete after this callback, so restart preview. 4190aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra restartPreview(); 420c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra return; 4210aacf105eea098a0b47761a4a9a5c4d820611f2dNipun Kwatra } 422c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (msgType != CAMERA_MSG_RAW_IMAGE) { 42365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return; 42465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 42565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 42665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("dataCallback for timelapse still frame"); 42765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CHECK_EQ(true, mUseStillCameraForTimeLapse); 42865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 42965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra int64_t timestampUs; 43065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (mNumFramesReceived == 0) { 43165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra timestampUs = mStartTimeUs; 43265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 43365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs; 43465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 435c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra 436c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mNeedCropping) { 437c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra sp<IMemory> croppedImageData = cropYUVImage(data); 438c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra dataCallbackTimestamp(timestampUs, msgType, croppedImageData); 439c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra } else { 440c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra sp<IMemory> dataCopy = createIMemoryCopy(data); 441c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra dataCallbackTimestamp(timestampUs, msgType, dataCopy); 442c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra } 44365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 44465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 44565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) { 446c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mSkipCurrentFrame) { 44765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mSkipCurrentFrame = false; 44865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return true; 44965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 45065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return false; 45165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 45265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 45365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 45465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatrabool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) { 455c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (!mUseStillCameraForTimeLapse) { 456c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (mLastTimeLapseFrameRealTimestampUs == 0) { 45765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs 45865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // to current time (timestampUs) and save frame data. 45965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("dataCallbackTimestamp timelapse: initial frame"); 46065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 46165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastTimeLapseFrameRealTimestampUs = *timestampUs; 46278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return false; 46378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 46478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 46578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra { 46678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mQuickStopLock); 46778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 46878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // mForceRead may be set to true by startQuickReadReturns(). In that 46978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // case don't skip this frame. 47078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mForceRead) { 47178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra LOGV("dataCallbackTimestamp timelapse: forced read"); 47278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mForceRead = false; 47378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra *timestampUs = mLastFrameTimestampUs; 47478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return false; 47578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 47678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 47778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra 47878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (*timestampUs < 47965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) { 48065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // Skip all frames from last encoded frame until 48165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed. 48265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // Tell the camera to release its recording frame and return. 48365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame"); 48465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return true; 48565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } else { 48665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time: 48765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // - Reset mLastTimeLapseFrameRealTimestampUs to current time. 48865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // - Artificially modify timestampUs to be one frame time (1/framerate) ahead 48965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // of the last encoded frame's time stamp. 49065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra LOGV("dataCallbackTimestamp timelapse: got timelapse frame"); 49165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 49265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastTimeLapseFrameRealTimestampUs = *timestampUs; 49365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs; 49478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return false; 49565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 49665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 49765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return false; 49865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 49965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 50065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType, 50165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra const sp<IMemory> &data) { 502c4e47d1e81c4e4403663cb911e98dbf3ada9942cNipun Kwatra if (!mUseStillCameraForTimeLapse) { 50365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mSkipCurrentFrame = skipFrameAndModifyTimeStamp(×tampUs); 50478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } else { 50578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra Mutex::Autolock autoLock(mCameraIdleLock); 50678eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // If we are using the still camera and stop() has been called, it may 50778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // be waiting for the camera to get idle. In that case return 50878eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // immediately. Calling CameraSource::dataCallbackTimestamp() will lead 50978eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // to a deadlock since it tries to access CameraSource::mLock which in 51078eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // this case is held by CameraSource::stop() currently waiting for the 51178eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // camera to get idle. And camera will not get idle until this call 51278eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra // returns. 51378eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra if (mStopWaitingForIdleCamera) { 51478eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra return; 51578eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra } 51665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 51765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CameraSource::dataCallbackTimestamp(timestampUs, msgType, data); 51865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 51965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 52065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} // namespace android 521