CameraSource.cpp revision 95068be1426dc0a4dc856cf9e35550c31b901711
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; 1184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return new CameraSource(camera, NULL, 0, size, -1, NULL, false); 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12130ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 12254ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 12354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 12554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 12654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 12754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 1285c9523154d106b555db6c41f85ab205a4f189b02James Dong const sp<Surface>& surface, 1295c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 13054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSource *source = new CameraSource(camera, proxy, cameraId, 1325c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, surface, 1335c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 13454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 13530ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 13630ab66297501757d745b9ae10da61adcd891f497Andreas Huber 13754ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 13854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 14054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 14154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 14254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 1435c9523154d106b555db6c41f85ab205a4f189b02James Dong const sp<Surface>& surface, 1445c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 14554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 14654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 14754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 14854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 14913aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 15065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 15165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 15213aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 1537757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong mFirstFrameTimeUs(0), 15413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 155f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 156f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 15765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 15854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 15954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 16054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 16195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 1624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mInitCheck = init(camera, proxy, cameraId, 1635c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 1645c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 16595068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mInitCheck != OK) releaseCamera(); 16695068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 16754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 16854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 16954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 17054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 17254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 17354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 1744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, 1754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int32_t cameraId) { 17654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 17754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 17854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::connect(cameraId); 1794ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 1804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // If proxy is not passed in by applications, still use the proxy of 1814ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // our own Camera to simplify the code. 1824ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = mCamera->getRecordingProxy(); 18354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 18454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 1854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // We get the proxy from Camera, not ICamera. We need to get the proxy 1864ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // to the remote Camera owned by the application. Here mCamera is a 1874ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // local Camera object created by us. We cannot use the proxy from 1884ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // mCamera here. 18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 1904ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 1914ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = proxy; 19254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 19354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 19454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1954ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->lock(); 1964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mDeathNotifier = new DeathNotifier(); 1974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // isBinderAlive needs linkToDeath to work. 1984ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier); 1994ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 20054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 20154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 20254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 20554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 20754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 20854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 20954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 21054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 21154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 21354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 21454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGV("isVideoSizeSupported"); 21754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 21854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 21954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 22054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 22154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 22354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 22454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 22554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 22654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 22754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 23054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 23254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 23354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 23554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 24354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGD("Camera does not support setVideoSize()"); 25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Video dimension (%dx%d) is unsupported", width, height); 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Requested video size (%dx%d) is not supported", width, height); 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 32054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 321635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 322635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 323635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 324635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 325635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong LOGV("Supported frame rates: %s", supportedFrameRates); 326635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 327635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 328635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 329635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong LOGE("Requested frame rate (%d) is not supported: %s", 330635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 331635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 332635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 333635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 334635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Could not change settings." 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 35354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 35454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 35554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 35654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 35754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 35854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 35954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 36054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 36154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 36354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 36454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 36554ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 36654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 36754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 369f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 370f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 371f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 372f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 37354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 37454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 375f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 376f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 377f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 378f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 379f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 380f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 381f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 382f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 383f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to retrieve video frame size (%dx%d)", 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 38854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to set video frame size to %dx%d. " 39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 39654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 39754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 39854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 39954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 40054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 40354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 40454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 40554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 40854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 40954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 41054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 41154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 41254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 41354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 41454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 41554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 41854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 42254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("Failed to set preview frame rate to %d fps. The actual " 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 43754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 44854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 4505c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 4515c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 4525c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 4535c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 4545c9523154d106b555db6c41f85ab205a4f189b02James Dong * 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 4594ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 4625c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 4635c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 4669d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 4674ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) { 4684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li LOGE("Camera connection could not be established."); 46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 475be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 483653252be963c07c99109d20f942d1f30c52a9360James Dong 48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 48854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 49054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 49154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 49354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 49454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // This CHECK is good, since we just passed the lock/unlock 49554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // check earlier by calling mCamera->setParameters(). 49654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CHECK_EQ(OK, mCamera->setPreviewDisplay(mSurface)); 4972b37ced30f89437c804c3945b901019b86d210aeJames Dong 498abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong // By default, do not store metadata in video buffers 4995c9523154d106b555db6c41f85ab205a4f189b02James Dong mIsMetaDataStoredInVideoBuffers = false; 500abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong mCamera->storeMetaDataInBuffers(false); 501abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (storeMetaDataInVideoBuffers) { 502abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (OK == mCamera->storeMetaDataInBuffers(true)) { 503abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong mIsMetaDataStoredInVideoBuffers = true; 504abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong } 5055c9523154d106b555db6c41f85ab205a4f189b02James Dong } 5065c9523154d106b555db6c41f85ab205a4f189b02James Dong 50754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 508f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 509f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 510f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 511f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 512ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 513ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 514653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 51554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 51654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 51754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 51854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 51954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 52054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 521393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 52254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::startCameraRecording() { 5324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // Reset the identity to the current thread because media server owns the 5334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // camera and recording is started by the applications. The applications 5344ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // will connect to the camera in ICameraRecordingProxy::startRecording. 5354ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 5364ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->unlock(); 5374ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera.clear(); 5384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 5394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CHECK_EQ(OK, mCameraRecordingProxy->startRecording(new ProxyListener(this))); 54065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 54165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 542f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 5430c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 54454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 54554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong LOGE("CameraSource is not initialized yet"); 54654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 54754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 549365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 550365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 551365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 552365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 553365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 5549d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 555f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 556f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t startTimeUs; 557f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (meta && meta->findInt64(kKeyTime, &startTimeUs)) { 558f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = startTimeUs; 559f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 560f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 561c42478ed7b8a379d2f8a43d4d349680c8a37573fJames Dong startCameraRecording(); 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 5684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy->stopRecording(); 56965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 57065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 571ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() { 572ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong LOGV("releaseCamera"); 57395068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mCamera != 0) { 57495068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) { 57595068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li LOGV("Camera was cold when we started, stopping preview"); 57695068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCamera->stopPreview(); 57795068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCamera->disconnect(); 57895068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } else { 57995068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li // Unlock the camera so the application can lock it back. 58095068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCamera->unlock(); 58195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 58295068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCamera.clear(); 58395068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 58495068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mCameraRecordingProxy != 0) { 58595068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier); 58695068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li mCameraRecordingProxy.clear(); 587ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 588ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong mCameraFlags = 0; 589ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong} 590ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::stop() { 59241152efd144ccf70c380d5c9a32105c02a039f43James Dong LOGD("stop: E"); 593c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong Mutex::Autolock autoLock(mLock); 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 595c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFrameAvailableCondition.signal(); 596365a963142093a1cd8efdcea76b5f65096a5b115James Dong 597c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong releaseQueuedFrames(); 5987278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesBeingEncoded.empty()) { 59941152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 60041152efd144ccf70c380d5c9a32105c02a039f43James Dong mFrameCompleteCondition.waitRelative(mLock, 3000000000LL)) { 60141152efd144ccf70c380d5c9a32105c02a039f43James Dong LOGW("Timed out waiting for outstanding frames being encoded: %d", 602365a963142093a1cd8efdcea76b5f65096a5b115James Dong mFramesBeingEncoded.size()); 60341152efd144ccf70c380d5c9a32105c02a039f43James Dong } 6047278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 605d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong stopCameraRecording(); 606ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong releaseCamera(); 6077278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 608365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (mCollectStats) { 609365a963142093a1cd8efdcea76b5f65096a5b115James Dong LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us", 610365a963142093a1cd8efdcea76b5f65096a5b115James Dong mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 611365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs - mFirstFrameTimeUs); 612365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 61313aec890216948b0c364f8f92792129d0335f506James Dong 614ba29002c7aee13c068049037cd14bba6a244da6bJames Dong if (mNumGlitches > 0) { 615a472613aec322e25891abf5c77bf3f7e3c244920James Dong LOGW("%d long delays between neighboring video frames", mNumGlitches); 616ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 617ba29002c7aee13c068049037cd14bba6a244da6bJames Dong 61813aec890216948b0c364f8f92792129d0335f506James Dong CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 61941152efd144ccf70c380d5c9a32105c02a039f43James Dong LOGD("stop: X"); 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 6244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCameraRecordingProxy != NULL) { 6254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy->releaseRecordingFrame(frame); 626d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong } 62765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 62865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 629c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 630c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 6317278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 6327278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 63365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 6347278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 63513aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 636c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 637c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 638c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 640653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 643f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 64465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 645f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 646f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 6477278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 6487278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong LOGV("signalBufferReturned: %p", buffer->data()); 64956223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 6507278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 6517278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 6527278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 653f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 6547278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 6557278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 6567278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 6577278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 6587278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 6597278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 6607278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 6617278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 6627278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong CHECK_EQ(0, "signalBufferReturned: bogus buffer"); 6637278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 6647278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 667c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("read"); 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 672abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 673abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 678be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 68279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong while (mStarted && mFramesReceived.empty()) { 68341152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 6844ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mFrameAvailableCondition.waitRelative(mLock, 1000000000LL)) { 6854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (!mCameraRecordingProxy->asBinder()->isBinderAlive()) { 6864ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li LOGW("camera recording proxy is gone"); 6874ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return ERROR_END_OF_STREAM; 6884ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 68941152efd144ccf70c380d5c9a32105c02a039f43James Dong LOGW("Timed out waiting for incoming camera video frames: %lld us", 69041152efd144ccf70c380d5c9a32105c02a039f43James Dong mLastFrameTimestampUs); 69141152efd144ccf70c380d5c9a32105c02a039f43James Dong } 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (!mStarted) { 69479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong return OK; 69579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong } 69679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frame = *mFramesReceived.begin(); 69779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesReceived.erase(mFramesReceived.begin()); 69879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong 69979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frameTime = *mFrameTimes.begin(); 70079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFrameTimes.erase(mFrameTimes.begin()); 70179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesBeingEncoded.push_back(frame); 70279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 70379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->setObserver(this); 70479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->add_ref(); 70579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 7067278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 710c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 711c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong int32_t msgType, const sp<IMemory> &data) { 712c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs); 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 714a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) { 715a472613aec322e25891abf5c77bf3f7e3c244920James Dong LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs); 716f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 717c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong return; 718c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72098cfde007490a5903b729a4718c0dada755ae8f8James Dong if (mNumFramesReceived > 0) { 72198cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(timestampUs > mLastFrameTimestampUs); 72298cfde007490a5903b729a4718c0dada755ae8f8James Dong if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 72398cfde007490a5903b729a4718c0dada755ae8f8James Dong ++mNumGlitches; 724f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 725f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 726f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 72765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 72865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 72979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (skipCurrentFrame(timestampUs)) { 73065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseOneRecordingFrame(data); 73165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return; 732fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 733fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 734365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 73513aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 736c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 737f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 738f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 739f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 740f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 741f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 742f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 743f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong return; 744f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 745f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 746f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 747be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 74813aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 749be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 75098cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(data != NULL && data->size() > 0); 7517278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 752f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 753f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 754f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong LOGV("initial delay: %lld, current time stamp: %lld", 755f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7595c9523154d106b555db6c41f85ab205a4f189b02James Dongbool CameraSource::isMetaDataStoredInVideoBuffers() const { 7605c9523154d106b555db6c41f85ab205a4f189b02James Dong LOGV("isMetaDataStoredInVideoBuffers"); 7615c9523154d106b555db6c41f85ab205a4f189b02James Dong return mIsMetaDataStoredInVideoBuffers; 7625c9523154d106b555db6c41f85ab205a4f189b02James Dong} 7635c9523154d106b555db6c41f85ab205a4f189b02James Dong 7644ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) { 7654ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource = source; 7664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 7674ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 7684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp( 7694ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 7704ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr); 7714ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 7724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 7734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who) { 7744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li LOGI("Camera recording proxy died"); 7754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 7764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 778