CameraSource.cpp revision 8fc3c670fff26cb21d1e16dbfcbc4410d7758574
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 17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 19c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong//#define LOG_NDEBUG 0 20c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#define LOG_TAG "CameraSource" 21c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <utils/Log.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX_Component.h> 249d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong#include <binder/IPCThreadState.h> 258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <binder/MemoryBase.h> 268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <binder/MemoryHeapBase.h> 278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <media/hardware/HardwareAPI.h> 28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h> 30be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 333cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h> 343cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h> 35df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h> 36be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h> 37365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG 4084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x) 4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else 4284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) 4384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif 4484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dongstatic const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL; 48e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong 49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener { 50be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const sp<CameraSource> &source); 51be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 52be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); 5357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr, 5457c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li camera_frame_metadata_t *metadata); 55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postDataTimestamp( 57be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 58be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 59be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 60be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 64be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 65be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 70be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 74be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 7784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(msgType); 7884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext1); 7984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext2); 803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 81be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr, 8484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber camera_frame_metadata_t * /* metadata */) { 85a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("postData(%d, ptr:%p, size:%zu)", 86be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 8765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 8865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<CameraSource> source = mSource.promote(); 8965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (source.get() != NULL) { 9065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->dataCallback(msgType, dataPtr); 9165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 92be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 93be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 94be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 95be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 96c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 97c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 98c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 99c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 100c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 101be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 104e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { 105e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong return OMX_COLOR_FormatYUV420Planar; 106e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong } 107e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong 108653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 109653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 110653252be963c07c99109d20f942d1f30c52a9360James Dong } 111653252be963c07c99109d20f942d1f30c52a9360James Dong 112653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 113653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 114653252be963c07c99109d20f942d1f30c52a9360James Dong } 115653252be963c07c99109d20f942d1f30c52a9360James Dong 116653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 117653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 118653252be963c07c99109d20f942d1f30c52a9360James Dong } 119653252be963c07c99109d20f942d1f30c52a9360James Dong 120653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 121653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 122653252be963c07c99109d20f942d1f30c52a9360James Dong } 123653252be963c07c99109d20f942d1f30c52a9360James Dong 1241374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) { 1251374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; 1261374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket } 1271374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket 128bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) { 129bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_COLOR_FormatAndroidOpaque; 130bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 131bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 13229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Uknown color format (%s), please add it to " 133a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong "CameraSource::getColorFormat", colorFormat); 134a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong 135f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"Unknown color format"); 136dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn return -1; 137653252be963c07c99109d20f942d1f30c52a9360James Dong} 138653252be963c07c99109d20f942d1f30c52a9360James Dong 139ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) { 14054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size size; 14154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.width = -1; 14254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.height = -1; 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong sp<ICamera> camera; 14598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen return new CameraSource(camera, NULL, 0, clientName, Camera::USE_CALLING_UID, 14698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen Camera::USE_CALLING_PID, size, -1, NULL, false); 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14930ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 15054ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 15154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1524ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 15354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 154ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 155ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 15698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 15754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 15854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 15999617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1605c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 16154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSource *source = new CameraSource(camera, proxy, cameraId, 16398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, videoSize, frameRate, surface, 164ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala storeMetaDataInVideoBuffers); 16554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 16630ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 16730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 16854ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 16954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1704ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 172ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 173ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 17498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 17554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 17654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 17799617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1785c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 17954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 180983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers(0), 18154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 18254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 18354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 18413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 18565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 18665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 18713aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 188e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs(0), 1897757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong mFirstFrameTimeUs(0), 19013aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 191f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 192f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 19365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 19454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 19554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 19654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mInitCheck = init(camera, proxy, cameraId, 19898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, 1995c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 2005c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 20195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mInitCheck != OK) releaseCamera(); 20254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 20354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 20554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 20754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20854ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 2094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, 21098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) { 21154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 21398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid); 2144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 2174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // We get the proxy from Camera, not ICamera. We need to get the proxy 2184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // to the remote Camera owned by the application. Here mCamera is a 2194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // local Camera object created by us. We cannot use the proxy from 2204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // mCamera here. 22154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 2224ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 2234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = proxy; 22454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 2253bd3020c00ec8264ac1fe3870800f326487f9221James Dong mDeathNotifier = new DeathNotifier(); 2263bd3020c00ec8264ac1fe3870800f326487f9221James Dong // isBinderAlive needs linkToDeath to work. 22706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier); 22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->lock(); 2314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 23254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 23354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 23554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 24354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isVideoSizeSupported"); 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 285b8a805261bf0282e992d3608035e47d05a898710Steve Block ALOGD("Camera does not support setVideoSize()"); 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 32054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 3253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("configureCamera"); 32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 32754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 33229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video dimension (%dx%d) is unsupported", width, height); 33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 34529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested video size (%dx%d) is not supported", width, height); 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 353635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 354635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 355635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 356635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 3573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Supported frame rates: %s", supportedFrameRates); 358635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 359635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 360635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 36129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested frame rate (%d) is not supported: %s", 362635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 363635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 364635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 365635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 366635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 36754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 36954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 37054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 37154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 37254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 37354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 37454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 37554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 37654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 37829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not change settings." 37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 38854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 39654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 39754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 39854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 39954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 40054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkVideoSize"); 402f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 403f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 404f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 405f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 408f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 409f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 410f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 411f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 412f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 413f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 414f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 415f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 416f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 41829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve video frame size (%dx%d)", 41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 42729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set video frame size to %dx%d. " 42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 43754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 44854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 45154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkFrameRate"); 45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 45629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 46329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set preview frame rate to %d fps. The actual " 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 46654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 48354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 4845c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 4855c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 4865c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 4875c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 4885c9523154d106b555db6c41f85ab205a4f189b02James Dong * 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 49054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 49154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 4934ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 49454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 495ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 496ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 49798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 49854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 4995c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 5005c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 50154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 50354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 504ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 50598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, clientPid, 506ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong videoSize, frameRate, 507ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong storeMetaDataInVideoBuffers); 508ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 509ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong return err; 510ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong} 511ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong 5128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenstatus_t CameraSource::initBufferQueue(uint32_t width, uint32_t height, 5138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t format, android_dataspace dataSpace, uint32_t bufferCount) { 5148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initBufferQueue"); 5158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferConsumer != nullptr || mVideoBufferProducer != nullptr) { 5178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Buffer queue already exists", __FUNCTION__); 5188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return ALREADY_EXISTS; 5198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create a buffer queue. 5228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferProducer> producer; 5238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferConsumer> consumer; 5248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferQueue::createBufferQueue(&producer, &consumer); 5258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN; 5278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 5288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen usage = GRALLOC_USAGE_HW_VIDEO_ENCODER; 5298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen bufferCount += kConsumerBufferCount; 5328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer = new BufferItemConsumer(consumer, usage, bufferCount); 5348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->setName(String8::format("StageFright-CameraSource")); 5358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer = producer; 5368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen status_t res = mVideoBufferConsumer->setDefaultBufferSize(width, height); 5388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer dimensions %dx%d: %s (%d)", __FUNCTION__, width, height, 5408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferFormat(format); 5458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer format %d: %s (%d)", __FUNCTION__, format, 5478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferDataSpace(dataSpace); 5528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set data space %d: %s (%d)", __FUNCTION__, dataSpace, 5548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mCamera->setVideoTarget(mVideoBufferProducer); 5598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to set video target: %s (%d)", __FUNCTION__, strerror(-res), res); 5618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create memory heap to store buffers as VideoNativeMetadata. 5658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t bufferSize = sizeof(VideoNativeMetadata); 5668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryHeapBase = new MemoryHeapBase(bufferSize * bufferCount, 0, 5678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen "StageFright-CameraSource-BufferHeap"); 5688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen for (uint32_t i = 0; i < bufferCount; i++) { 5698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.push_back(new MemoryBase(mMemoryHeapBase, i * bufferSize, bufferSize)); 5708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener = new BufferQueueListener(mVideoBufferConsumer, this); 5738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mBufferQueueListener->run("CameraSource-BufferQueueListener"); 5748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not run buffer queue listener thread: %s (%d)", __FUNCTION__, 5768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return OK; 5818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 5828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 583ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess( 584ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICamera>& camera, 585ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICameraRecordingProxy>& proxy, 586ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t cameraId, 587ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 588ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 58998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 590ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong Size videoSize, 591ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t frameRate, 592ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong bool storeMetaDataInVideoBuffers) { 5933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initWithCameraAccess"); 594ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong status_t err = OK; 5959d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 596ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala if ((err = isCameraAvailable(camera, proxy, cameraId, 59798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid)) != OK) { 59829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Camera connection could not be established."); 59954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 60054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 60154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 60254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 60354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 60454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 605be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 60654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 60754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 60854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 60954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 61054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 61154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 61254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 613653252be963c07c99109d20f942d1f30c52a9360James Dong 61454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 61554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 61654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 61754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 61854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 61954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 62054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 62154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 62254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 62354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 6248e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // Set the preview display. Skip this if mSurface is null because 6258e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // applications may already set a surface to the camera. 6268e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li if (mSurface != NULL) { 6278e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // This CHECK is good, since we just passed the lock/unlock 6288e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // check earlier by calling mCamera->setParameters(). 6294b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface)); 6308e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li } 6312b37ced30f89437c804c3945b901019b86d210aeJames Dong 6328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // By default, store real data in video buffers. 6338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferMode = ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV; 634abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (storeMetaDataInVideoBuffers) { 6358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (OK == mCamera->setVideoBufferMode(ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE)) { 6368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferMode = ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE; 6378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else if (OK == mCamera->setVideoBufferMode( 6388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA)) { 6398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferMode = ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA; 6408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferMode == ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) { 6448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = mCamera->setVideoBufferMode(ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV); 6458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 6468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV failed: " 6478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen "%s (err=%d)", __FUNCTION__, strerror(-err), err); 6488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 649abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong } 6505c9523154d106b555db6c41f85ab205a4f189b02James Dong } 6515c9523154d106b555db6c41f85ab205a4f189b02James Dong 65254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 653f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 654f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 655f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 656f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 657ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 658ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 659653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 66054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 66154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 66254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 66354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 66454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 66554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 666393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 66754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 672b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong reset(); 673ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong } else if (mInitCheck == OK) { 674ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera is initialized but because start() is never called, 675ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // the lock on Camera is never released(). This makes sure 676ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera's lock is released in this case. 677ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong releaseCamera(); 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() { 6823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("startCameraRecording"); 6834ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // Reset the identity to the current thread because media server owns the 6844ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // camera and recording is started by the applications. The applications 6854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // will connect to the camera in ICameraRecordingProxy::startRecording. 6864ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 68726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 6888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferMode == ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 6908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Initialize buffer queue. 6918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat, 6928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (android_dataspace_t)mEncoderDataSpace, 6938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers > 0 ? mNumInputBuffers : 1); 6948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 6958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__, 6968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-err), err); 6978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 6988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else { 7008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mNumInputBuffers > 0) { 7018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = mCamera->sendCommand( 7028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0); 7038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 7048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // This could happen for CameraHAL1 clients; thus the failure is 7058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // not a fatal error 7068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 7078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video buffer count to %d due to %d", 7088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers, err); 7098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 71226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = mCamera->sendCommand( 7138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace); 714983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 715983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // This could happen for CameraHAL1 clients; thus the failure is 716983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // not a fatal error 717983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (err != OK) { 7188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d", 7198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mEncoderFormat, mEncoderDataSpace, err); 720983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 721983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 722983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 72326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = OK; 7243bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 7253bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->unlock(); 7263bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera.clear(); 72726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = mCameraRecordingProxy->startRecording( 72826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk new ProxyListener(this))) != OK) { 72926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording, received error: %s (%d)", 73026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk strerror(-err), err); 73126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7323bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 7333bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->setListener(new CameraSourceListener(this)); 7343bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->startRecording(); 73526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if (!mCamera->recordingEnabled()) { 73626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = -EINVAL; 73726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording"); 73826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7393bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 7404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 74126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 74265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 74365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 744f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 7453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("start"); 7460c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 74754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 74829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("CameraSource is not initialized yet"); 74954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 75054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 752365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 753365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 754365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 755365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 756365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 7579d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 758f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 759983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = 0; 760d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 761d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala mEncoderDataSpace = HAL_DATASPACE_BT709; 762d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 763983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta) { 764983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int64_t startTimeUs; 765983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt64(kKeyTime, &startTimeUs)) { 766983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mStartTimeUs = startTimeUs; 767983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 768983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 769983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int32_t nBuffers; 770983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt32(kKeyNumBuffers, &nBuffers)) { 771983cf231ab2d176a14595cdae46ff1b0c239af47James Dong CHECK_GT(nBuffers, 0); 772983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = nBuffers; 773983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 774d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 775c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // apply encoder color format if specified 776c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) { 777c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar ALOGV("Using encoder format: %#x", mEncoderFormat); 778c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 779c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) { 780c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar ALOGV("Using encoder data space: %#x", mEncoderDataSpace); 781c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 782f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 783f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 78426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 78526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = startCameraRecording()) == OK) { 78626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk mStarted = true; 78726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 7933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stopCameraRecording"); 7943bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 7952da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCameraRecordingProxy != 0) { 7962da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCameraRecordingProxy->stopRecording(); 7972da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 7983bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 7992da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCamera != 0) { 8002da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->setListener(NULL); 8012da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->stopRecording(); 8022da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 8033bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 80465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 80565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 806ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() { 8073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseCamera"); 808121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang sp<Camera> camera; 809121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool coldCamera = false; 810121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 811121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 812121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang // get a local ref and clear ref to mCamera now 813121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera = mCamera; 814121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCamera.clear(); 815121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0; 816121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 817121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 818121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (camera != 0) { 819ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 820121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (coldCamera) { 8213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Camera was cold when we started, stopping preview"); 822121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->stopPreview(); 823121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->disconnect(); 82495068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 825121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->unlock(); 826ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 82795068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 828121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 829121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 830121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 831121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCameraRecordingProxy != 0) { 83206b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier); 833121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraRecordingProxy.clear(); 834121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 835121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraFlags = 0; 836ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 837ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong} 838ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 839b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() { 840b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: E"); 841121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 842121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 843121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 844121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mStarted = false; 845121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameAvailableCondition.signal(); 846121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 847121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang int64_t token; 848121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool isTokenValid = false; 849121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCamera != 0) { 850121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang token = IPCThreadState::self()->clearCallingIdentity(); 851121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang isTokenValid = true; 852121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 853121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseQueuedFrames(); 854121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang while (!mFramesBeingEncoded.empty()) { 855121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (NO_ERROR != 856121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameCompleteCondition.waitRelative(mLock, 857121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 858121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("Timed out waiting for outstanding frames being encoded: %zu", 859121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFramesBeingEncoded.size()); 860121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 861121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 862121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang stopCameraRecording(); 863121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (isTokenValid) { 864121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang IPCThreadState::self()->restoreCallingIdentity(token); 86541152efd144ccf70c380d5c9a32105c02a039f43James Dong } 8667278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 867121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCollectStats) { 868121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us", 869121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 870121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mLastFrameTimestampUs - mFirstFrameTimeUs); 871121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 872121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 873121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mNumGlitches > 0) { 874121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("%d long delays between neighboring video frames", mNumGlitches); 875121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 87613aec890216948b0c364f8f92792129d0335f506James Dong 877121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 878ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 879ba29002c7aee13c068049037cd14bba6a244da6bJames Dong 8808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mBufferQueueListener != nullptr) { 8818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->requestExit(); 8828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->join(); 8838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener.clear(); 8848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 8858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 8868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer.clear(); 8878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer.clear(); 888121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseCamera(); 889121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 890b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: X"); 89120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 89220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 89320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 89465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 8953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseRecordingFrame"); 8968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 8978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferMode == ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 8988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. 8998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 9008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 9018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = frame->getMemory(&offset, &size); 9028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) { 9038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__, 9048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen heap->getHeapID(), mMemoryHeapBase->getHeapID()); 9058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 9098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 9108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find the corresponding buffer item for the native window buffer. 9128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer); 9138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (index == NAME_NOT_FOUND) { 9148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer); 9158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer = mReceivedBufferItemMap.valueAt(index); 9198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.removeItemsAt(index); 9208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 9218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.push_back(frame); 9220419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mMemoryBaseAvailableCond.signal(); 9238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else if (mCameraRecordingProxy != NULL) { 9244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy->releaseRecordingFrame(frame); 925334d097870eefeb45137b6df026f7db861d47663James Dong } else if (mCamera != NULL) { 9263bd3020c00ec8264ac1fe3870800f326487f9221James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 9273bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->releaseRecordingFrame(frame); 9283bd3020c00ec8264ac1fe3870800f326487f9221James Dong IPCThreadState::self()->restoreCallingIdentity(token); 929d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong } 93065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 93165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 932c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 933c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 9347278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 9357278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 93665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 9377278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 93813aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 939c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 940c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 941c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 94220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 943653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 94420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 94520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 946f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 94765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 948f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 949f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 9507278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 9513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: %p", buffer->data()); 95256223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 9537278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 9547278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 9557278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 956f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 9577278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 9587278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 9597278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 9607278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 9617278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 9627278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 9637278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 9647278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 965f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"signalBufferReturned: bogus buffer"); 9667278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 9677278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 9703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read"); 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 97320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 975abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 976abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 981be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 98579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong while (mStarted && mFramesReceived.empty()) { 98641152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 987e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mFrameAvailableCondition.waitRelative(mLock, 988e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 9893bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraRecordingProxy != 0 && 99006b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) { 9915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("camera recording proxy is gone"); 9924ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return ERROR_END_OF_STREAM; 9934ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 994a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us", 99541152efd144ccf70c380d5c9a32105c02a039f43James Dong mLastFrameTimestampUs); 99641152efd144ccf70c380d5c9a32105c02a039f43James Dong } 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (!mStarted) { 99979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong return OK; 100079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong } 100179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frame = *mFramesReceived.begin(); 100279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesReceived.erase(mFramesReceived.begin()); 100379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong 100479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frameTime = *mFrameTimes.begin(); 100579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFrameTimes.erase(mFrameTimes.begin()); 100679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesBeingEncoded.push_back(frame); 100779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 100879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->setObserver(this); 100979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->add_ref(); 101079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 10117278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::shouldSkipFrameLocked(int64_t timestampUs) { 1016a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) { 1017ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs); 10188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1019c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 102265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 102379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (skipCurrentFrame(timestampUs)) { 10248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1025fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 1026fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 10270aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (mNumFramesReceived > 0) { 10280aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs <= mLastFrameTimestampUs) { 10290aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ALOGW("Dropping frame with backward timestamp %lld (last %lld)", 10300aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang (long long)timestampUs, (long long)mLastFrameTimestampUs); 10318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 10320aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10330aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 10340aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ++mNumGlitches; 10350aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10360aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10370aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang 1038365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 103913aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 1040c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 1041f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 1042f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 1043f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 1044f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 1045f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 10468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1047f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1048f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 1049f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1050be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 10518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 10538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 10548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 10568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int32_t msgType __unused, const sp<IMemory> &data) { 10578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs); 10588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 10598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 10618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen releaseOneRecordingFrame(data); 10628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 10638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 10648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 106513aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 1066be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 106798cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(data != NULL && data->size() > 0); 10687278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 1069f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 1070f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 1071a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 1072f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu ChenCameraSource::BufferQueueListener::BufferQueueListener(const sp<BufferItemConsumer>& consumer, 10778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen const sp<CameraSource>& cameraSource) { 10788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer = consumer; 10798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer->setFrameAvailableListener(this); 10808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource = cameraSource; 10818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 10828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::BufferQueueListener::onFrameAvailable(const BufferItem& /*item*/) { 10848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("%s: onFrameAvailable", __FUNCTION__); 10858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 10878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (!mFrameAvailable) { 10898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = true; 10908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableSignal.signal(); 10918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 10928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 10938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::BufferQueueListener::threadLoop() { 10958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mConsumer == nullptr || mCameraSource == nullptr) { 10968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 10978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 10988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen { 11008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 11018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (!mFrameAvailable) { 11028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mFrameAvailableSignal.waitRelative(mLock, kFrameAvailableTimeout) == TIMED_OUT) { 11038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 11048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = false; 11078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer; 11108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (mConsumer->acquireBuffer(&buffer, 0) == OK) { 11118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource->processBufferQueueFrame(buffer); 11128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 11158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 11168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11178fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chenvoid CameraSource::processBufferQueueFrame(BufferItem& buffer) { 11188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 11198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timestampUs = buffer.mTimestamp / 1000; 11218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 11228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 11238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 11248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11260419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen while (mMemoryBases.empty()) { 11270419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 11280419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen TIMED_OUT) { 11290419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 11300419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 11310419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen return; 11320419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen } 11338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ++mNumFramesReceived; 11368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find a available memory slot to store the buffer as VideoNativeMetadata. 11388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemory> data = *mMemoryBases.begin(); 11398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.erase(mMemoryBases.begin()); 11408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 11428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 11438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = data->getMemory(&offset, &size); 11448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 11458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 11468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen memset(payload, 0, sizeof(VideoNativeMetadata)); 11478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->eType = kMetadataBufferTypeANWBuffer; 11488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->pBuffer = buffer.mGraphicBuffer->getNativeBuffer(); 11498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->nFenceFd = -1; 11508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Add the mapping so we can find the corresponding buffer item to release to the buffer queue 11528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // when the encoder returns the native window buffer. 11538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.add(payload->pBuffer, buffer); 11548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFramesReceived.push_back(data); 11568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 11578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameTimes.push_back(timeUs); 11588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 11598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mStartTimeUs, timeUs); 11608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableCondition.signal(); 11618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 11628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11635c9523154d106b555db6c41f85ab205a4f189b02James Dongbool CameraSource::isMetaDataStoredInVideoBuffers() const { 11643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isMetaDataStoredInVideoBuffers"); 11658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Output buffers will contain metadata if camera sends us buffer in metadata mode or via 11678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // buffer queue. 11688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return (mVideoBufferMode == ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA || 11698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferMode == ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE); 11705c9523154d106b555db6c41f85ab205a4f189b02James Dong} 11715c9523154d106b555db6c41f85ab205a4f189b02James Dong 11724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) { 11734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource = source; 11744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 11754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 11764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp( 11774ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 11784ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr); 11794ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 11804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 1181ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnarvoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) { 1182df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Camera recording proxy died"); 11834ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 11844ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 118520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 1186