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> 25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h> 27be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 303cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h> 313cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h> 32df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h> 33be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h> 34365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG 3784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x) 3884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else 3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) 4084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif 4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dongstatic const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL; 45e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong 46be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener { 47be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const sp<CameraSource> &source); 48be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); 5057c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr, 5157c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li camera_frame_metadata_t *metadata); 52be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 53be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postDataTimestamp( 54be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 57be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 58be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 60be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 7484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(msgType); 7584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext1); 7684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext2); 773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 78be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8057c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr, 8184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber camera_frame_metadata_t * /* metadata */) { 82a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("postData(%d, ptr:%p, size:%zu)", 83be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 8465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 8565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<CameraSource> source = mSource.promote(); 8665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (source.get() != NULL) { 8765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->dataCallback(msgType, dataPtr); 8865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 89be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 90be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 91be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 92be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 93c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 94c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 95c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 96c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 97c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 98be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 101e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { 102e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong return OMX_COLOR_FormatYUV420Planar; 103e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong } 104e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong 105653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 106653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 107653252be963c07c99109d20f942d1f30c52a9360James Dong } 108653252be963c07c99109d20f942d1f30c52a9360James Dong 109653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 110653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 111653252be963c07c99109d20f942d1f30c52a9360James Dong } 112653252be963c07c99109d20f942d1f30c52a9360James Dong 113653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 114653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 115653252be963c07c99109d20f942d1f30c52a9360James Dong } 116653252be963c07c99109d20f942d1f30c52a9360James Dong 117653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 118653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 119653252be963c07c99109d20f942d1f30c52a9360James Dong } 120653252be963c07c99109d20f942d1f30c52a9360James Dong 1211374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) { 1221374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; 1231374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket } 1241374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket 125bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) { 126bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_COLOR_FormatAndroidOpaque; 127bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 128bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 12929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Uknown color format (%s), please add it to " 130a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong "CameraSource::getColorFormat", colorFormat); 131a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong 132f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"Unknown color format"); 133dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn return -1; 134653252be963c07c99109d20f942d1f30c52a9360James Dong} 135653252be963c07c99109d20f942d1f30c52a9360James Dong 136ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) { 13754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size size; 13854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.width = -1; 13954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.height = -1; 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong sp<ICamera> camera; 142ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala return new CameraSource(camera, NULL, 0, clientName, -1, 143ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala size, -1, NULL, false); 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14630ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 14754ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 14854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1494ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 15054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 151ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 152ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 15354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 15454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 15599617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1565c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 15754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1584ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSource *source = new CameraSource(camera, proxy, cameraId, 159ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala clientName, clientUid, videoSize, frameRate, surface, 160ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala storeMetaDataInVideoBuffers); 16154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 16230ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 16330ab66297501757d745b9ae10da61adcd891f497Andreas Huber 16454ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 16554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 1664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 16754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 168ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 169ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 17054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 17299617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1735c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 17454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 175983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers(0), 17654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 17754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 17854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 17913aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 18065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 18165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 18213aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 183e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs(0), 1847757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong mFirstFrameTimeUs(0), 18513aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 186f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 187f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 18865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 19054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1924ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mInitCheck = init(camera, proxy, cameraId, 193ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala clientName, clientUid, 1945c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 1955c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 19695068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mInitCheck != OK) releaseCamera(); 19754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 19854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 19954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 20054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 20154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 20254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 2044ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, 205ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala int32_t cameraId, const String16& clientName, uid_t clientUid) { 20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 20754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 208ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala mCamera = Camera::connect(cameraId, clientName, clientUid); 2094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 21054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 21154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 2124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // We get the proxy from Camera, not ICamera. We need to get the proxy 2134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // to the remote Camera owned by the application. Here mCamera is a 2144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // local Camera object created by us. We cannot use the proxy from 2154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // mCamera here. 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 2174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 2184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = proxy; 21954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 2203bd3020c00ec8264ac1fe3870800f326487f9221James Dong mDeathNotifier = new DeathNotifier(); 2213bd3020c00ec8264ac1fe3870800f326487f9221James Dong // isBinderAlive needs linkToDeath to work. 2223bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier); 22354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 22454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->lock(); 2264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 22754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 23054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 23254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 23354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 23554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isVideoSizeSupported"); 24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 280b8a805261bf0282e992d3608035e47d05a898710Steve Block ALOGD("Camera does not support setVideoSize()"); 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 3203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("configureCamera"); 32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 32554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 32729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video dimension (%dx%d) is unsupported", width, height); 32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 34029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested video size (%dx%d) is not supported", width, height); 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 348635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 349635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 350635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 351635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 3523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Supported frame rates: %s", supportedFrameRates); 353635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 354635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 355635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 35629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested frame rate (%d) is not supported: %s", 357635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 358635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 359635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 360635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 361635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 36354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 36454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 36554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 36654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 36754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 36954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 37054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 37154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 37254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 37329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not change settings." 37454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 37554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 37654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 37854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 38854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 3963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkVideoSize"); 397f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 398f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 399f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 400f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 403f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 404f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 405f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 406f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 407f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 408f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 409f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 410f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 411f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 41254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 41329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve video frame size (%dx%d)", 41454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 41554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 41854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 42229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set video frame size to %dx%d. " 42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 43754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkFrameRate"); 44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 45129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 45829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set preview frame rate to %d fps. The actual " 45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 46654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 4795c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 4805c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 4815c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 4825c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 4835c9523154d106b555db6c41f85ab205a4f189b02James Dong * 48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const sp<ICamera>& camera, 4884ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 490ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 491ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 4935c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 4945c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 49554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 49754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 498ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 499ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, 500ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong videoSize, frameRate, 501ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong storeMetaDataInVideoBuffers); 502ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 503ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong return err; 504ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong} 505ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong 506ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess( 507ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICamera>& camera, 508ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICameraRecordingProxy>& proxy, 509ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t cameraId, 510ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 511ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 512ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong Size videoSize, 513ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t frameRate, 514ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong bool storeMetaDataInVideoBuffers) { 5153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initWithCameraAccess"); 516ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong status_t err = OK; 5179d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 518ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala if ((err = isCameraAvailable(camera, proxy, cameraId, 519ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala clientName, clientUid)) != OK) { 52029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Camera connection could not be established."); 52154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 52254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 52354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 52454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 52554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 52654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 527be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 52854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 52954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 53054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 53154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 53254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 53354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 53454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 535653252be963c07c99109d20f942d1f30c52a9360James Dong 53654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 53754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 53854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 53954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 54054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 54154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 54254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 54354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 54454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 54554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5468e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // Set the preview display. Skip this if mSurface is null because 5478e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // applications may already set a surface to the camera. 5488e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li if (mSurface != NULL) { 5498e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // This CHECK is good, since we just passed the lock/unlock 5508e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // check earlier by calling mCamera->setParameters(). 5514b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface)); 5528e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li } 5532b37ced30f89437c804c3945b901019b86d210aeJames Dong 554abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong // By default, do not store metadata in video buffers 5555c9523154d106b555db6c41f85ab205a4f189b02James Dong mIsMetaDataStoredInVideoBuffers = false; 556abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong mCamera->storeMetaDataInBuffers(false); 557abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (storeMetaDataInVideoBuffers) { 558abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (OK == mCamera->storeMetaDataInBuffers(true)) { 559abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong mIsMetaDataStoredInVideoBuffers = true; 560abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong } 5615c9523154d106b555db6c41f85ab205a4f189b02James Dong } 5625c9523154d106b555db6c41f85ab205a4f189b02James Dong 56354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 564f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 565f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 566f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 567f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 568ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 569ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 570653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 57154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 57254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 57354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 57454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 57554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 57654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 577393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 57854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 583b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong reset(); 584ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong } else if (mInitCheck == OK) { 585ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera is initialized but because start() is never called, 586ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // the lock on Camera is never released(). This makes sure 587ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera's lock is released in this case. 588ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong releaseCamera(); 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() { 5933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("startCameraRecording"); 5944ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // Reset the identity to the current thread because media server owns the 5954ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // camera and recording is started by the applications. The applications 5964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // will connect to the camera in ICameraRecordingProxy::startRecording. 5974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 59826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 599983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (mNumInputBuffers > 0) { 60026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = mCamera->sendCommand( 601983cf231ab2d176a14595cdae46ff1b0c239af47James Dong CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0); 602983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 603983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // This could happen for CameraHAL1 clients; thus the failure is 604983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // not a fatal error 605983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (err != OK) { 606983cf231ab2d176a14595cdae46ff1b0c239af47James Dong ALOGW("Failed to set video buffer count to %d due to %d", 607983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers, err); 608983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 609983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 610983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 61126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = OK; 6123bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 6133bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->unlock(); 6143bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera.clear(); 61526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = mCameraRecordingProxy->startRecording( 61626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk new ProxyListener(this))) != OK) { 61726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording, received error: %s (%d)", 61826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk strerror(-err), err); 61926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 6203bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 6213bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->setListener(new CameraSourceListener(this)); 6223bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->startRecording(); 62326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if (!mCamera->recordingEnabled()) { 62426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = -EINVAL; 62526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording"); 62626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 6273bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 6284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 62926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 63065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 63165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 632f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 6333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("start"); 6340c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 63554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("CameraSource is not initialized yet"); 63754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 63854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 640365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 641365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 642365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 643365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 644365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 6459d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 646f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 647983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = 0; 648983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta) { 649983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int64_t startTimeUs; 650983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt64(kKeyTime, &startTimeUs)) { 651983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mStartTimeUs = startTimeUs; 652983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 653983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 654983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int32_t nBuffers; 655983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt32(kKeyNumBuffers, &nBuffers)) { 656983cf231ab2d176a14595cdae46ff1b0c239af47James Dong CHECK_GT(nBuffers, 0); 657983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = nBuffers; 658983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 659f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 660f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 66126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 66226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = startCameraRecording()) == OK) { 66326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk mStarted = true; 66426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 6703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stopCameraRecording"); 6713bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 6723bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCameraRecordingProxy->stopRecording(); 6733bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 6743bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->setListener(NULL); 6753bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->stopRecording(); 6763bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 67765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 67865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 679ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() { 6803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseCamera"); 681121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang sp<Camera> camera; 682121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool coldCamera = false; 683121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 684121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 685121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang // get a local ref and clear ref to mCamera now 686121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera = mCamera; 687121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCamera.clear(); 688121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0; 689121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 690121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 691121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (camera != 0) { 692ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 693121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (coldCamera) { 6943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Camera was cold when we started, stopping preview"); 695121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->stopPreview(); 696121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->disconnect(); 69795068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 698121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->unlock(); 699ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 70095068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 701121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 702121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 703121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 704121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCameraRecordingProxy != 0) { 705121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier); 706121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraRecordingProxy.clear(); 707121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 708121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraFlags = 0; 709ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 710ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong} 711ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 712b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() { 713b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: E"); 714121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 715121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 716121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 717121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mStarted = false; 718121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameAvailableCondition.signal(); 719121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 720121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang int64_t token; 721121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool isTokenValid = false; 722121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCamera != 0) { 723121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang token = IPCThreadState::self()->clearCallingIdentity(); 724121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang isTokenValid = true; 725121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 726121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseQueuedFrames(); 727121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang while (!mFramesBeingEncoded.empty()) { 728121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (NO_ERROR != 729121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameCompleteCondition.waitRelative(mLock, 730121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 731121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("Timed out waiting for outstanding frames being encoded: %zu", 732121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFramesBeingEncoded.size()); 733121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 734121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 735121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang stopCameraRecording(); 736121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (isTokenValid) { 737121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang IPCThreadState::self()->restoreCallingIdentity(token); 73841152efd144ccf70c380d5c9a32105c02a039f43James Dong } 7397278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 740121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCollectStats) { 741121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us", 742121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 743121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mLastFrameTimestampUs - mFirstFrameTimeUs); 744121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 745121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 746121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mNumGlitches > 0) { 747121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("%d long delays between neighboring video frames", mNumGlitches); 748121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 74913aec890216948b0c364f8f92792129d0335f506James Dong 750121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 751ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 752ba29002c7aee13c068049037cd14bba6a244da6bJames Dong 753121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseCamera(); 754121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 755b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: X"); 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 7603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseRecordingFrame"); 7614ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCameraRecordingProxy != NULL) { 7624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy->releaseRecordingFrame(frame); 763334d097870eefeb45137b6df026f7db861d47663James Dong } else if (mCamera != NULL) { 7643bd3020c00ec8264ac1fe3870800f326487f9221James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 7653bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->releaseRecordingFrame(frame); 7663bd3020c00ec8264ac1fe3870800f326487f9221James Dong IPCThreadState::self()->restoreCallingIdentity(token); 767d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong } 76865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 76965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 770c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 771c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 7727278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 7737278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 77465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 7757278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 77613aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 777c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 778c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 779c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 781653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 784f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 78565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 786f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 787f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 7887278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 7893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: %p", buffer->data()); 79056223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 7917278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 7927278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 7937278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 794f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 7957278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 7967278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 7977278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 7987278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 7997278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 8007278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 8017278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 8027278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 803f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"signalBufferReturned: bogus buffer"); 8047278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 8057278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 8083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read"); 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 813abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 814abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 819be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 82379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong while (mStarted && mFramesReceived.empty()) { 82441152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 825e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mFrameAvailableCondition.waitRelative(mLock, 826e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 8273bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraRecordingProxy != 0 && 8283bd3020c00ec8264ac1fe3870800f326487f9221James Dong !mCameraRecordingProxy->asBinder()->isBinderAlive()) { 8295ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("camera recording proxy is gone"); 8304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return ERROR_END_OF_STREAM; 8314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 832a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us", 83341152efd144ccf70c380d5c9a32105c02a039f43James Dong mLastFrameTimestampUs); 83441152efd144ccf70c380d5c9a32105c02a039f43James Dong } 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (!mStarted) { 83779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong return OK; 83879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong } 83979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frame = *mFramesReceived.begin(); 84079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesReceived.erase(mFramesReceived.begin()); 84179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong 84279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frameTime = *mFrameTimes.begin(); 84379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFrameTimes.erase(mFrameTimes.begin()); 84479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesBeingEncoded.push_back(frame); 84579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 84679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->setObserver(this); 84779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->add_ref(); 84879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 8497278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 853c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 854c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong int32_t msgType, const sp<IMemory> &data) { 855a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("dataCallbackTimestamp: timestamp %" PRId64 " us", timestampUs); 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 857a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) { 858a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Drop frame at %" PRId64 "/%" PRId64 " us", timestampUs, mStartTimeUs); 859f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 860c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong return; 861c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 86398cfde007490a5903b729a4718c0dada755ae8f8James Dong if (mNumFramesReceived > 0) { 86498cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(timestampUs > mLastFrameTimestampUs); 86598cfde007490a5903b729a4718c0dada755ae8f8James Dong if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 86698cfde007490a5903b729a4718c0dada755ae8f8James Dong ++mNumGlitches; 867f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 868f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 869f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 87065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 87165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 87279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (skipCurrentFrame(timestampUs)) { 87365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseOneRecordingFrame(data); 87465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra return; 875fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 876fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 877365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 87813aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 879c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 880f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 881f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 882f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 883f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 884f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 885f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 886f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong return; 887f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 888f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 889f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 890be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 89113aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 892be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 89398cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(data != NULL && data->size() > 0); 8947278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 895f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 896f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 897a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 898f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 90120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9025c9523154d106b555db6c41f85ab205a4f189b02James Dongbool CameraSource::isMetaDataStoredInVideoBuffers() const { 9033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isMetaDataStoredInVideoBuffers"); 9045c9523154d106b555db6c41f85ab205a4f189b02James Dong return mIsMetaDataStoredInVideoBuffers; 9055c9523154d106b555db6c41f85ab205a4f189b02James Dong} 9065c9523154d106b555db6c41f85ab205a4f189b02James Dong 9074ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) { 9084ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource = source; 9094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 9104ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 9114ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp( 9124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 9134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr); 9144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 9154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 9164ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who) { 917df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Camera recording proxy died"); 9184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 9194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 921