CameraSource.cpp revision 393410a441b6d06daf286ed496470e9d6b2b6ca8
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong//#define LOG_NDEBUG 0 18c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#define LOG_TAG "CameraSource" 19c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX_Component.h> 229d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong#include <binder/IPCThreadState.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h> 240c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 25be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 283cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h> 293cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h> 3054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong#include <surfaceflinger/Surface.h> 31be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h> 32365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener { 37be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const sp<CameraSource> &source); 38be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 39be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); 40be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr); 41be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 42be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postDataTimestamp( 43be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 44be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 45be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 46be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 47be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 50be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 51be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 52be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 57be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 60be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber LOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 64be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) { 67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber LOGV("postData(%d, ptr:%p, size:%d)", 68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 6965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 7065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<CameraSource> source = mSource.promote(); 7165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (source.get() != NULL) { 7265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->dataCallback(msgType, dataPtr); 7365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 74be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 75be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 76be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 77be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 78c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 79c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 80c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 81c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 82c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 83be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 86e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { 87e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong return OMX_COLOR_FormatYUV420Planar; 88e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong } 89e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong 90653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 91653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 92653252be963c07c99109d20f942d1f30c52a9360James Dong } 93653252be963c07c99109d20f942d1f30c52a9360James Dong 94653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 95653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 96653252be963c07c99109d20f942d1f30c52a9360James Dong } 97653252be963c07c99109d20f942d1f30c52a9360James Dong 98653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 99653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 100653252be963c07c99109d20f942d1f30c52a9360James Dong } 101653252be963c07c99109d20f942d1f30c52a9360James Dong 102653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 103653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 104653252be963c07c99109d20f942d1f30c52a9360James Dong } 105653252be963c07c99109d20f942d1f30c52a9360James Dong 106a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong LOGE("Uknown color format (%s), please add it to " 107a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong "CameraSource::getColorFormat", colorFormat); 108a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong 109653252be963c07c99109d20f942d1f30c52a9360James Dong CHECK_EQ(0, "Unknown color format"); 110653252be963c07c99109d20f942d1f30c52a9360James Dong} 111653252be963c07c99109d20f942d1f30c52a9360James Dong 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource *CameraSource::Create() { 11354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size size; 11454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.width = -1; 11554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.height = -1; 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong sp<ICamera> camera; 1185c9523154d106b555db6c41f85ab205a4f189b02James Dong return new CameraSource(camera, 0, size, -1, NULL, false); 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12130ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 12254ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 12354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 12454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 12554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 12654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 1275c9523154d106b555db6c41f85ab205a4f189b02James Dong const sp<Surface>& surface, 1285c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 12954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 13054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraSource *source = new CameraSource(camera, cameraId, 1315c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, surface, 1325c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 13354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 13454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (source != NULL) { 13554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (source->initCheck() != OK) { 13654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong delete source; 13754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return NULL; 13854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 13930ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 14054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 14130ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 14230ab66297501757d745b9ae10da61adcd891f497Andreas Huber 14354ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 14454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 14554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 14654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 14754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 1485c9523154d106b555db6c41f85ab205a4f189b02James Dong const sp<Surface>& surface, 1495c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 15054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 15154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 15254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 15354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 15413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 15565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 15665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 15765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mFirstFrameTimeUs(0), 15813aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 15913aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 160f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 161f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 16265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 1639d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 16454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 16554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 16654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1675c9523154d106b555db6c41f85ab205a4f189b02James Dong mInitCheck = init(camera, cameraId, 1685c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 1695c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 17054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 17254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 17354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 17454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 17554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 17654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 17754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, int32_t cameraId) { 17854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 17954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 18054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::connect(cameraId); 18154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 18254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 18354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 18454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 18554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 18654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 18754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Is camera available? 18854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mCamera == 0) { 18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Camera connection could not be established."); 19054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 19254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!(mCameraFlags & FLAGS_HOT_CAMERA)) { 19354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera->lock(); 19454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 19554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 19654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 19754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 19854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 19954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 20054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 20154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 20254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 20354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 20554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 20754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 20854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 20954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 21054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 21154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGV("isVideoSizeSupported"); 21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 21354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 21454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 21754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 21854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 21954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 22054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 22154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 22354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 22454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 22554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 22654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 22754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 23054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 23254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 23354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 23554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 24354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGD("Camera does not support setVideoSize()"); 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Video dimension (%dx%d) is unsupported", width, height); 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Requested video size (%dx%d) is not supported", width, height); 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 316635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 317635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 318635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 319635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 320635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong LOGV("Supported frame rates: %s", supportedFrameRates); 321635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 322635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 323635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 324635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong LOGE("Requested frame rate (%d) is not supported: %s", 325635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 326635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 327635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 328635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 329635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Could not change settings." 34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 35354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 35454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 35554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 35654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 35754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 35854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 35954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 36054ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 36154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 36354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 364f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 365f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 366f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 367f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 36954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 370f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 371f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 372f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 373f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 374f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 375f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 376f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 377f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 378f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to retrieve video frame size (%dx%d)", 38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 38854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to set video frame size to %dx%d. " 39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 39654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 39754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 39854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 39954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 40054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 40354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 40454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 40554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 40854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 40954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 41054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 41154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 41254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 41354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 41454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 41554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 41854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 42254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to set preview frame rate to %d fps. The actual " 42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 43754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 4455c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 4465c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 4475c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 4485c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 4495c9523154d106b555db6c41f85ab205a4f189b02James Dong * 45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 45154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 4565c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 4575c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 4609d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 4619d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraAvailable(camera, cameraId)) != OK) { 46354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 46654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 469be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 477653252be963c07c99109d20f942d1f30c52a9360James Dong 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 48354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 48854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // This CHECK is good, since we just passed the lock/unlock 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // check earlier by calling mCamera->setParameters(). 49054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CHECK_EQ(OK, mCamera->setPreviewDisplay(mSurface)); 4912b37ced30f89437c804c3945b901019b86d210aeJames Dong 4925c9523154d106b555db6c41f85ab205a4f189b02James Dong mIsMetaDataStoredInVideoBuffers = false; 4935c9523154d106b555db6c41f85ab205a4f189b02James Dong if (storeMetaDataInVideoBuffers && 4945c9523154d106b555db6c41f85ab205a4f189b02James Dong OK == mCamera->storeMetaDataInBuffers(true)) { 4955c9523154d106b555db6c41f85ab205a4f189b02James Dong mIsMetaDataStoredInVideoBuffers = true; 4965c9523154d106b555db6c41f85ab205a4f189b02James Dong } 4975c9523154d106b555db6c41f85ab205a4f189b02James Dong 4982b37ced30f89437c804c3945b901019b86d210aeJames Dong /* 4992b37ced30f89437c804c3945b901019b86d210aeJames Dong * mCamera->startRecording() signals camera hal to make 5002b37ced30f89437c804c3945b901019b86d210aeJames Dong * available the video buffers (for instance, allocation 5012b37ced30f89437c804c3945b901019b86d210aeJames Dong * of the video buffers may be triggered when camera hal's 5022b37ced30f89437c804c3945b901019b86d210aeJames Dong * startRecording() method is called). Making available these 5032b37ced30f89437c804c3945b901019b86d210aeJames Dong * video buffers earlier (before calling start()) is critical, 5042b37ced30f89437c804c3945b901019b86d210aeJames Dong * if one wants to configure omx video encoders to use these 5052b37ced30f89437c804c3945b901019b86d210aeJames Dong * buffers for passing video frame data during video recording 5062b37ced30f89437c804c3945b901019b86d210aeJames Dong * without the need to memcpy the video frame data stored 5072b37ced30f89437c804c3945b901019b86d210aeJames Dong * in these buffers. Eliminating memcpy for video frame data 5082b37ced30f89437c804c3945b901019b86d210aeJames Dong * is crucial in performance for HD quality video recording 5092b37ced30f89437c804c3945b901019b86d210aeJames Dong * applications. 5102b37ced30f89437c804c3945b901019b86d210aeJames Dong * 5112b37ced30f89437c804c3945b901019b86d210aeJames Dong * Based on OMX IL spec, configuring the omx video encoders 5122b37ced30f89437c804c3945b901019b86d210aeJames Dong * must occur in loaded state. When start() is called, omx 5132b37ced30f89437c804c3945b901019b86d210aeJames Dong * video encoders are already in idle state, which is too 5142b37ced30f89437c804c3945b901019b86d210aeJames Dong * late. Thus, we must call mCamera->startRecording() earlier. 5152b37ced30f89437c804c3945b901019b86d210aeJames Dong */ 5162b37ced30f89437c804c3945b901019b86d210aeJames Dong startCameraRecording(); 5172b37ced30f89437c804c3945b901019b86d210aeJames Dong 51854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong IPCThreadState::self()->restoreCallingIdentity(token); 51954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 52054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 521f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 522f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 523f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 524f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 525ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 526ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 527653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 52854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 52954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 53054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 53154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 53254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 53354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 534393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 53554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::startCameraRecording() { 54565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra CHECK_EQ(OK, mCamera->startRecording()); 5462b37ced30f89437c804c3945b901019b86d210aeJames Dong CHECK(mCamera->recordingEnabled()); 54765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 54865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 549f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 5500c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 55154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 55254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("CameraSource is not initialized yet"); 55354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 55454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 556365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 557365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 558365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 559365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 560365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 5619d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 562f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 563f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t startTimeUs; 564f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (meta && meta->findInt64(kKeyTime, &startTimeUs)) { 565f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = startTimeUs; 566f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 567f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 5689d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 569be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber mCamera->setListener(new CameraSourceListener(this)); 5709d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong IPCThreadState::self()->restoreCallingIdentity(token); 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 57778eff720c86eb6d4e3d45a144df60b2ca464d2d4Nipun Kwatra mCamera->setListener(NULL); 57865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCamera->stopRecording(); 57965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 58065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::stop() { 582c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("stop"); 583c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong Mutex::Autolock autoLock(mLock); 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 585c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFrameAvailableCondition.signal(); 586365a963142093a1cd8efdcea76b5f65096a5b115James Dong 5879d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 58865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra stopCameraRecording(); 589c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong releaseQueuedFrames(); 5907278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesBeingEncoded.empty()) { 591365a963142093a1cd8efdcea76b5f65096a5b115James Dong LOGI("Waiting for outstanding frames being encoded: %d", 592365a963142093a1cd8efdcea76b5f65096a5b115James Dong mFramesBeingEncoded.size()); 5937278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.wait(mLock); 5947278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 59554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 59654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGV("Disconnect camera"); 59754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) { 59854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGV("Camera was cold when we started, stopping preview"); 59954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera->stopPreview(); 60054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 60154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera->unlock(); 60254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera.clear(); 60354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = 0; 60454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags = 0; 6059d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong IPCThreadState::self()->restoreCallingIdentity(token); 6067278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 607365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (mCollectStats) { 608365a963142093a1cd8efdcea76b5f65096a5b115James Dong LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us", 609365a963142093a1cd8efdcea76b5f65096a5b115James Dong mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 610365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs - mFirstFrameTimeUs); 611365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 61213aec890216948b0c364f8f92792129d0335f506James Dong 61313aec890216948b0c364f8f92792129d0335f506James Dong CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 61865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCamera->releaseRecordingFrame(frame); 61965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 62065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 621c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 622c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 6237278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 6247278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 62565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 6267278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 62713aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 628c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 629c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 630c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 632653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 635f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 636f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 63765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 638f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong IPCThreadState::self()->restoreCallingIdentity(token); 639f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 640f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 6417278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 6427278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong LOGV("signalBufferReturned: %p", buffer->data()); 64356223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 6447278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 6457278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 6467278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 647f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 6487278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 6497278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 6507278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 6517278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 6527278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 6537278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 6547278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 6557278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 6567278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong CHECK_EQ(0, "signalBufferReturned: bogus buffer"); 6577278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 6587278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 661c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("read"); 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 666abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 667abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 672be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 676542db5d438988360d491a5add1040a2df9aa90c9James Dong while (mStarted) { 677542db5d438988360d491a5add1040a2df9aa90c9James Dong while(mFramesReceived.empty()) { 678542db5d438988360d491a5add1040a2df9aa90c9James Dong mFrameAvailableCondition.wait(mLock); 679542db5d438988360d491a5add1040a2df9aa90c9James Dong } 680542db5d438988360d491a5add1040a2df9aa90c9James Dong 681542db5d438988360d491a5add1040a2df9aa90c9James Dong if (!mStarted) { 682542db5d438988360d491a5add1040a2df9aa90c9James Dong return OK; 683542db5d438988360d491a5add1040a2df9aa90c9James Dong } 684542db5d438988360d491a5add1040a2df9aa90c9James Dong 685542db5d438988360d491a5add1040a2df9aa90c9James Dong frame = *mFramesReceived.begin(); 686542db5d438988360d491a5add1040a2df9aa90c9James Dong mFramesReceived.erase(mFramesReceived.begin()); 687542db5d438988360d491a5add1040a2df9aa90c9James Dong 688542db5d438988360d491a5add1040a2df9aa90c9James Dong frameTime = *mFrameTimes.begin(); 689542db5d438988360d491a5add1040a2df9aa90c9James Dong mFrameTimes.erase(mFrameTimes.begin()); 690542db5d438988360d491a5add1040a2df9aa90c9James Dong int64_t skipTimeUs; 691542db5d438988360d491a5add1040a2df9aa90c9James Dong if (!options || !options->getSkipFrame(&skipTimeUs)) { 692542db5d438988360d491a5add1040a2df9aa90c9James Dong skipTimeUs = frameTime; 693542db5d438988360d491a5add1040a2df9aa90c9James Dong } 694542db5d438988360d491a5add1040a2df9aa90c9James Dong if (skipTimeUs > frameTime) { 695542db5d438988360d491a5add1040a2df9aa90c9James Dong LOGV("skipTimeUs: %lld us > frameTime: %lld us", 696542db5d438988360d491a5add1040a2df9aa90c9James Dong skipTimeUs, frameTime); 697542db5d438988360d491a5add1040a2df9aa90c9James Dong releaseOneRecordingFrame(frame); 698542db5d438988360d491a5add1040a2df9aa90c9James Dong ++mNumFramesDropped; 699542db5d438988360d491a5add1040a2df9aa90c9James Dong // Safeguard against the abuse of the kSkipFrame_Option. 700542db5d438988360d491a5add1040a2df9aa90c9James Dong if (skipTimeUs - frameTime >= 1E6) { 701542db5d438988360d491a5add1040a2df9aa90c9James Dong LOGE("Frame skipping requested is way too long: %lld us", 702542db5d438988360d491a5add1040a2df9aa90c9James Dong skipTimeUs - frameTime); 703542db5d438988360d491a5add1040a2df9aa90c9James Dong return UNKNOWN_ERROR; 704542db5d438988360d491a5add1040a2df9aa90c9James Dong } 705542db5d438988360d491a5add1040a2df9aa90c9James Dong } else { 706542db5d438988360d491a5add1040a2df9aa90c9James Dong mFramesBeingEncoded.push_back(frame); 707542db5d438988360d491a5add1040a2df9aa90c9James Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 708542db5d438988360d491a5add1040a2df9aa90c9James Dong (*buffer)->setObserver(this); 709542db5d438988360d491a5add1040a2df9aa90c9James Dong (*buffer)->add_ref(); 710542db5d438988360d491a5add1040a2df9aa90c9James Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 71156223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber 712542db5d438988360d491a5add1040a2df9aa90c9James Dong return OK; 713542db5d438988360d491a5add1040a2df9aa90c9James Dong } 71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7157278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 719c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 720c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong int32_t msgType, const sp<IMemory> &data) { 721c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs); 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 723c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (!mStarted) { 724f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 72513aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 72613aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 727c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong return; 728c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 730f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mNumFramesReceived > 0 && 731f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 732f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mNumGlitches % 10 == 0) { // Don't spam the log 733f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong LOGW("Long delay detected in video recording"); 734f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 735f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong ++mNumGlitches; 736f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 737f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 73865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 73965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 74065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if(skipCurrentFrame(timestampUs)) { 74165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseOneRecordingFrame(data); 74265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return; 743fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 744fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 745365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 74613aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 747c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 748f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 749f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 750f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 751f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 752f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 753f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 754f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong return; 755f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 756f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 757f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 758be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 75913aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 760be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 7617278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 762f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 763f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 764f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong LOGV("initial delay: %lld, current time stamp: %lld", 765f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7695c9523154d106b555db6c41f85ab205a4f189b02James Dongsize_t CameraSource::getNumberOfVideoBuffers() const { 7705c9523154d106b555db6c41f85ab205a4f189b02James Dong LOGV("getNumberOfVideoBuffers"); 7715c9523154d106b555db6c41f85ab205a4f189b02James Dong size_t nBuffers = 0; 7725c9523154d106b555db6c41f85ab205a4f189b02James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 7735c9523154d106b555db6c41f85ab205a4f189b02James Dong if (mInitCheck == OK && mCamera != 0) { 7745c9523154d106b555db6c41f85ab205a4f189b02James Dong nBuffers = mCamera->getNumberOfVideoBuffers(); 7755c9523154d106b555db6c41f85ab205a4f189b02James Dong } 7765c9523154d106b555db6c41f85ab205a4f189b02James Dong IPCThreadState::self()->restoreCallingIdentity(token); 7775c9523154d106b555db6c41f85ab205a4f189b02James Dong return nBuffers; 7785c9523154d106b555db6c41f85ab205a4f189b02James Dong} 7795c9523154d106b555db6c41f85ab205a4f189b02James Dong 7805c9523154d106b555db6c41f85ab205a4f189b02James Dongsp<IMemory> CameraSource::getVideoBuffer(size_t index) const { 7815c9523154d106b555db6c41f85ab205a4f189b02James Dong LOGV("getVideoBuffer: %d", index); 7825c9523154d106b555db6c41f85ab205a4f189b02James Dong sp<IMemory> buffer = 0; 7835c9523154d106b555db6c41f85ab205a4f189b02James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 7845c9523154d106b555db6c41f85ab205a4f189b02James Dong if (mInitCheck == OK && mCamera != 0) { 7855c9523154d106b555db6c41f85ab205a4f189b02James Dong buffer = mCamera->getVideoBuffer(index); 7865c9523154d106b555db6c41f85ab205a4f189b02James Dong } 7875c9523154d106b555db6c41f85ab205a4f189b02James Dong IPCThreadState::self()->restoreCallingIdentity(token); 7885c9523154d106b555db6c41f85ab205a4f189b02James Dong return buffer; 7895c9523154d106b555db6c41f85ab205a4f189b02James Dong} 7905c9523154d106b555db6c41f85ab205a4f189b02James Dong 7915c9523154d106b555db6c41f85ab205a4f189b02James Dongbool CameraSource::isMetaDataStoredInVideoBuffers() const { 7925c9523154d106b555db6c41f85ab205a4f189b02James Dong LOGV("isMetaDataStoredInVideoBuffers"); 7935c9523154d106b555db6c41f85ab205a4f189b02James Dong return mIsMetaDataStoredInVideoBuffers; 7945c9523154d106b555db6c41f85ab205a4f189b02James Dong} 7955c9523154d106b555db6c41f85ab205a4f189b02James Dong 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 797