CameraSource.cpp revision cb9e825306cd0a97e50a4ef9d7c58f4e961692d9
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 592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle); 602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 65be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 72be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 73be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 76be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 7984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(msgType); 8084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext1); 8184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext2); 823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 83be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8557c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr, 8684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber camera_frame_metadata_t * /* metadata */) { 87a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("postData(%d, ptr:%p, size:%zu)", 88be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 8965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 9065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<CameraSource> source = mSource.promote(); 9165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (source.get() != NULL) { 9265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->dataCallback(msgType, dataPtr); 9365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 94be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 95be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 96be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 97be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 98c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 99c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 100c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 101c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 102c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 103be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1052d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSourceListener::postRecordingFrameHandleTimestamp(nsecs_t timestamp, 1062d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 1072d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen sp<CameraSource> source = mSource.promote(); 1082d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (source.get() != nullptr) { 1092d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen source->recordingFrameHandleCallbackTimestamp(timestamp/1000, handle); 1102d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 1112d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 1122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 113653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 114e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { 115e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong return OMX_COLOR_FormatYUV420Planar; 116e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong } 117e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong 118653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 119653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 120653252be963c07c99109d20f942d1f30c52a9360James Dong } 121653252be963c07c99109d20f942d1f30c52a9360James Dong 122653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 123653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 124653252be963c07c99109d20f942d1f30c52a9360James Dong } 125653252be963c07c99109d20f942d1f30c52a9360James Dong 126653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 127653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 128653252be963c07c99109d20f942d1f30c52a9360James Dong } 129653252be963c07c99109d20f942d1f30c52a9360James Dong 130653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 131653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 132653252be963c07c99109d20f942d1f30c52a9360James Dong } 133653252be963c07c99109d20f942d1f30c52a9360James Dong 1341374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) { 1351374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; 1361374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket } 1371374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket 138bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) { 139bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_COLOR_FormatAndroidOpaque; 140bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 141bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 14229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Uknown color format (%s), please add it to " 143a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong "CameraSource::getColorFormat", colorFormat); 144a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong 145f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"Unknown color format"); 146dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn return -1; 147653252be963c07c99109d20f942d1f30c52a9360James Dong} 148653252be963c07c99109d20f942d1f30c52a9360James Dong 149ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) { 15054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size size; 15154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.width = -1; 15254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.height = -1; 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 154d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala sp<hardware::ICamera> camera; 15598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen return new CameraSource(camera, NULL, 0, clientName, Camera::USE_CALLING_UID, 15698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen Camera::USE_CALLING_PID, size, -1, NULL, false); 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15930ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 16054ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 161d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 1624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 16354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 164ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 165ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 16698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 16754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 16854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 16999617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1705c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSource *source = new CameraSource(camera, proxy, cameraId, 17398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, videoSize, frameRate, surface, 174ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala storeMetaDataInVideoBuffers); 17554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 17630ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 17730ab66297501757d745b9ae10da61adcd891f497Andreas Huber 17854ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 179d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 1804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 18154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 182ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 183ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 18498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 18554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 18654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 18799617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1885c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 190983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers(0), 19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 19254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 19354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 19413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 19565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 19665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 19713aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 198e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs(0), 1997757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong mFirstFrameTimeUs(0), 20013aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 201f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 202f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 20365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 20554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2074ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mInitCheck = init(camera, proxy, cameraId, 20898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, 2095c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 2105c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 21195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mInitCheck != OK) releaseCamera(); 21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 21354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 21454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 21754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 21854ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 219d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, 22098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) { 22154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 22398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid); 2244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 22554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 22654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 2274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // We get the proxy from Camera, not ICamera. We need to get the proxy 2284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // to the remote Camera owned by the application. Here mCamera is a 2294ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // local Camera object created by us. We cannot use the proxy from 2304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // mCamera here. 23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 2324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 2334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = proxy; 23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 2353bd3020c00ec8264ac1fe3870800f326487f9221James Dong mDeathNotifier = new DeathNotifier(); 2363bd3020c00ec8264ac1fe3870800f326487f9221James Dong // isBinderAlive needs linkToDeath to work. 23706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier); 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->lock(); 2414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 24354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isVideoSizeSupported"); 25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 295b8a805261bf0282e992d3608035e47d05a898710Steve Block ALOGD("Camera does not support setVideoSize()"); 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 32054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 32554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 32754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("configureCamera"); 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 34229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video dimension (%dx%d) is unsupported", width, height); 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 35354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 35454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 35529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested video size (%dx%d) is not supported", width, height); 35654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 35754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 35854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 35954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 36054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 36154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 363635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 364635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 365635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 366635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 3673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Supported frame rates: %s", supportedFrameRates); 368635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 369635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 370635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 37129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested frame rate (%d) is not supported: %s", 372635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 373635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 374635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 375635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 376635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 37854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 38829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not change settings." 38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 39654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 39754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 39854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 39954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 40054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 40354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 40454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 40554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 40854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 40954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 41054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkVideoSize"); 412f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 413f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 414f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 415f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 418f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 419f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 420f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 421f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 422f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 423f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 424f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 425f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 426f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 42829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve video frame size (%dx%d)", 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 43729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set video frame size to %dx%d. " 43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 44854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 45154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkFrameRate"); 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 46629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 47329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set preview frame rate to %d fps. The actual " 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 48354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 48854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 49054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 49154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 49354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 4945c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 4955c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 4965c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 4975c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 4985c9523154d106b555db6c41f85ab205a4f189b02James Dong * 49954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 50054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 50154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 502d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 5034ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 50454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 505ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 506ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 50798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 50854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 5095c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 5105c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 51154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 51354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 514ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 51598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, clientPid, 516ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong videoSize, frameRate, 517ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong storeMetaDataInVideoBuffers); 518ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 519ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong return err; 520ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong} 521ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong 5222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::createVideoBufferMemoryHeap(size_t size, uint32_t bufferCount) { 5232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryHeapBase = new MemoryHeapBase(size * bufferCount, 0, 5242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen "StageFright-CameraSource-BufferHeap"); 5252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen for (uint32_t i = 0; i < bufferCount; i++) { 5262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBases.push_back(new MemoryBase(mMemoryHeapBase, i * size, size)); 5272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 5282d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 5292d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 5308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenstatus_t CameraSource::initBufferQueue(uint32_t width, uint32_t height, 5318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t format, android_dataspace dataSpace, uint32_t bufferCount) { 5328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initBufferQueue"); 5338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferConsumer != nullptr || mVideoBufferProducer != nullptr) { 5358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Buffer queue already exists", __FUNCTION__); 5368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return ALREADY_EXISTS; 5378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create a buffer queue. 5408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferProducer> producer; 5418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferConsumer> consumer; 5428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferQueue::createBufferQueue(&producer, &consumer); 5438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN; 5458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 5468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen usage = GRALLOC_USAGE_HW_VIDEO_ENCODER; 5478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen bufferCount += kConsumerBufferCount; 5508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer = new BufferItemConsumer(consumer, usage, bufferCount); 5528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->setName(String8::format("StageFright-CameraSource")); 5538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer = producer; 5548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen status_t res = mVideoBufferConsumer->setDefaultBufferSize(width, height); 5568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer dimensions %dx%d: %s (%d)", __FUNCTION__, width, height, 5588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferFormat(format); 5638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer format %d: %s (%d)", __FUNCTION__, format, 5658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferDataSpace(dataSpace); 5708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set data space %d: %s (%d)", __FUNCTION__, dataSpace, 5728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mCamera->setVideoTarget(mVideoBufferProducer); 5778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to set video target: %s (%d)", __FUNCTION__, strerror(-res), res); 5798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create memory heap to store buffers as VideoNativeMetadata. 5832d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen createVideoBufferMemoryHeap(sizeof(VideoNativeMetadata), bufferCount); 5848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener = new BufferQueueListener(mVideoBufferConsumer, this); 5868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mBufferQueueListener->run("CameraSource-BufferQueueListener"); 5878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not run buffer queue listener thread: %s (%d)", __FUNCTION__, 5898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return OK; 5948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 5958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 596ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess( 597d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 598ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICameraRecordingProxy>& proxy, 599ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t cameraId, 600ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 601ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 60298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 603ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong Size videoSize, 604ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t frameRate, 605ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong bool storeMetaDataInVideoBuffers) { 6063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initWithCameraAccess"); 607ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong status_t err = OK; 6089d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 609ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala if ((err = isCameraAvailable(camera, proxy, cameraId, 61098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid)) != OK) { 61129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Camera connection could not be established."); 61254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 61354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 61454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 61554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 61654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 61754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 618be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 61954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 62054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 62154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 62254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 62354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 62454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 62554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 626653252be963c07c99109d20f942d1f30c52a9360James Dong 62754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 62854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 62954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 63054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 63154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 63254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 63354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 63454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 63554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 63654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 6378e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // Set the preview display. Skip this if mSurface is null because 6388e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // applications may already set a surface to the camera. 6398e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li if (mSurface != NULL) { 6408e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // This CHECK is good, since we just passed the lock/unlock 6418e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // check earlier by calling mCamera->setParameters(). 6424b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface)); 6438e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li } 6442b37ced30f89437c804c3945b901019b86d210aeJames Dong 6458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // By default, store real data in video buffers. 646d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV; 647abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (storeMetaDataInVideoBuffers) { 648d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (OK == mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE)) { 649d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE; 6508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else if (OK == mCamera->setVideoBufferMode( 651d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA)) { 652d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA; 6538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 656d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) { 657d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala err = mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV); 6588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 6598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV failed: " 6608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen "%s (err=%d)", __FUNCTION__, strerror(-err), err); 6618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 662abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong } 6635c9523154d106b555db6c41f85ab205a4f189b02James Dong } 6645c9523154d106b555db6c41f85ab205a4f189b02James Dong 66554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 666f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 667f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 668f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 669f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 670ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 671ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 672653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 67354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 67454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 67554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 67654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 67754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 67854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 679393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 68054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 685b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong reset(); 686ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong } else if (mInitCheck == OK) { 687ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera is initialized but because start() is never called, 688ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // the lock on Camera is never released(). This makes sure 689ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera's lock is released in this case. 690ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong releaseCamera(); 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() { 6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("startCameraRecording"); 6964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // Reset the identity to the current thread because media server owns the 6974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // camera and recording is started by the applications. The applications 6984ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // will connect to the camera in ICameraRecordingProxy::startRecording. 6994ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 70026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 7018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 702d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 7038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Initialize buffer queue. 7048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat, 7058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (android_dataspace_t)mEncoderDataSpace, 7068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers > 0 ? mNumInputBuffers : 1); 7078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 7088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__, 7098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-err), err); 7108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 7118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else { 7138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mNumInputBuffers > 0) { 7148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = mCamera->sendCommand( 7158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0); 7168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 7178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // This could happen for CameraHAL1 clients; thus the failure is 7188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // not a fatal error 7198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 7208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video buffer count to %d due to %d", 7218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers, err); 7228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 72526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = mCamera->sendCommand( 7268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace); 727983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 728983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // This could happen for CameraHAL1 clients; thus the failure is 729983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // not a fatal error 730983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (err != OK) { 7318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d", 7328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mEncoderFormat, mEncoderDataSpace, err); 733983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 7342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 7352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Create memory heap to store buffers as VideoNativeMetadata. 7362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen createVideoBufferMemoryHeap(sizeof(VideoNativeHandleMetadata), kDefaultVideoBufferCount); 737983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 738983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 73926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = OK; 7403bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 7413bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->unlock(); 7423bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera.clear(); 74326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = mCameraRecordingProxy->startRecording( 74426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk new ProxyListener(this))) != OK) { 74526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording, received error: %s (%d)", 74626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk strerror(-err), err); 74726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7483bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 7493bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->setListener(new CameraSourceListener(this)); 7503bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->startRecording(); 75126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if (!mCamera->recordingEnabled()) { 75226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = -EINVAL; 75326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording"); 75426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7553bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 7564ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 75726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 75865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 75965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 760f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 7613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("start"); 7620c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 76354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 76429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("CameraSource is not initialized yet"); 76554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 76654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 768365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 769365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 770365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 771365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 772365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 7739d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 774f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 775983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = 0; 776d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 7772cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvala mEncoderDataSpace = HAL_DATASPACE_V0_BT709; 778d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 779983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta) { 780983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int64_t startTimeUs; 781983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt64(kKeyTime, &startTimeUs)) { 782983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mStartTimeUs = startTimeUs; 783983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 784983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 785983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int32_t nBuffers; 786983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt32(kKeyNumBuffers, &nBuffers)) { 787983cf231ab2d176a14595cdae46ff1b0c239af47James Dong CHECK_GT(nBuffers, 0); 788983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = nBuffers; 789983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 790d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 791c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // apply encoder color format if specified 792c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) { 793b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGI("Using encoder format: %#x", mEncoderFormat); 794c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 795c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) { 796b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGI("Using encoder data space: %#x", mEncoderDataSpace); 797c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 798f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 799f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 80026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 80126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = startCameraRecording()) == OK) { 80226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk mStarted = true; 80326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 8093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stopCameraRecording"); 8103bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 8112da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCameraRecordingProxy != 0) { 8122da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCameraRecordingProxy->stopRecording(); 8132da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 8143bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 8152da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCamera != 0) { 8162da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->setListener(NULL); 8172da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->stopRecording(); 8182da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 8193bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 82065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 82165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 822ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() { 8233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseCamera"); 824121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang sp<Camera> camera; 825121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool coldCamera = false; 826121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 827121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 828121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang // get a local ref and clear ref to mCamera now 829121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera = mCamera; 830121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCamera.clear(); 831121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0; 832121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 833121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 834121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (camera != 0) { 835ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 836121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (coldCamera) { 8373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Camera was cold when we started, stopping preview"); 838121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->stopPreview(); 839121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->disconnect(); 84095068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 841121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->unlock(); 842ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 84395068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 844121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 845121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 846121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 847121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCameraRecordingProxy != 0) { 84806b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier); 849121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraRecordingProxy.clear(); 850121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 851121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraFlags = 0; 852ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 853ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong} 854ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 855b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() { 856b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: E"); 857121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 858121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 859121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 860121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mStarted = false; 861121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameAvailableCondition.signal(); 862121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 863121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang int64_t token; 864121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool isTokenValid = false; 865121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCamera != 0) { 866121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang token = IPCThreadState::self()->clearCallingIdentity(); 867121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang isTokenValid = true; 868121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 869121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseQueuedFrames(); 870121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang while (!mFramesBeingEncoded.empty()) { 871121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (NO_ERROR != 872121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameCompleteCondition.waitRelative(mLock, 873121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 874121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("Timed out waiting for outstanding frames being encoded: %zu", 875121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFramesBeingEncoded.size()); 876121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 877121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 878121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang stopCameraRecording(); 879121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (isTokenValid) { 880121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang IPCThreadState::self()->restoreCallingIdentity(token); 88141152efd144ccf70c380d5c9a32105c02a039f43James Dong } 8827278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 883121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCollectStats) { 884121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us", 885121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 886121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mLastFrameTimestampUs - mFirstFrameTimeUs); 887121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 888121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 889121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mNumGlitches > 0) { 890121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("%d long delays between neighboring video frames", mNumGlitches); 891121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 89213aec890216948b0c364f8f92792129d0335f506James Dong 893121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 894ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 895ba29002c7aee13c068049037cd14bba6a244da6bJames Dong 8968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mBufferQueueListener != nullptr) { 8978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->requestExit(); 8988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->join(); 8998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener.clear(); 9008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer.clear(); 9038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer.clear(); 904121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseCamera(); 905121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 906b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: X"); 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 9113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseRecordingFrame"); 9128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 913d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 9148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. 9158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 9168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 9178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = frame->getMemory(&offset, &size); 9188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) { 9198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__, 9208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen heap->getHeapID(), mMemoryHeapBase->getHeapID()); 9218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 9258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 9268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find the corresponding buffer item for the native window buffer. 9288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer); 9298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (index == NAME_NOT_FOUND) { 9308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer); 9318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer = mReceivedBufferItemMap.valueAt(index); 9358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.removeItemsAt(index); 9368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 9378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.push_back(frame); 9380419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mMemoryBaseAvailableCond.signal(); 9392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else { 9402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle = nullptr; 9412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 9422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Check if frame contains a VideoNativeHandleMetadata. 9432d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (frame->size() == sizeof(VideoNativeHandleMetadata)) { 9442d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen VideoNativeHandleMetadata *metadata = 9452d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen (VideoNativeHandleMetadata*)(frame->pointer()); 9462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (metadata->eType == kMetadataBufferTypeNativeHandleSource) { 9472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen handle = metadata->pHandle; 9482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 9492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 9502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 9512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (handle != nullptr) { 9522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Frame contains a VideoNativeHandleMetadata. Send the handle back to camera. 9532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen releaseRecordingFrameHandle(handle); 9542d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBases.push_back(frame); 9552d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBaseAvailableCond.signal(); 9562d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCameraRecordingProxy != nullptr) { 9572d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // mCamera is created by application. Return the frame back to camera via camera 9582d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // recording proxy. 9592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCameraRecordingProxy->releaseRecordingFrame(frame); 9602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCamera != nullptr) { 9612d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // mCamera is created by CameraSource. Return the frame directly back to camera. 9622d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t token = IPCThreadState::self()->clearCallingIdentity(); 9632d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCamera->releaseRecordingFrame(frame); 9642d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen IPCThreadState::self()->restoreCallingIdentity(token); 9652d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 966d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong } 96765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 96865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 969c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 970c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 9717278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 9727278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 97365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 9747278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 97513aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 976c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 977c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 978c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 980653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 983f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 98465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 985f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 986f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 9877278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 9883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: %p", buffer->data()); 98956223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 9907278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 9917278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 9927278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 993f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 9947278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 9957278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 9967278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 9977278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 9987278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 9997278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 10007278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 10017278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 1002f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"signalBufferReturned: bogus buffer"); 10037278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 10047278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 10073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read"); 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1012abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1013abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 1018be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 102120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 102279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong while (mStarted && mFramesReceived.empty()) { 102341152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 1024e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mFrameAvailableCondition.waitRelative(mLock, 1025e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 10263bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraRecordingProxy != 0 && 102706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) { 10285ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("camera recording proxy is gone"); 10294ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return ERROR_END_OF_STREAM; 10304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 1031a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us", 103241152efd144ccf70c380d5c9a32105c02a039f43James Dong mLastFrameTimestampUs); 103341152efd144ccf70c380d5c9a32105c02a039f43James Dong } 103420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 103579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (!mStarted) { 103679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong return OK; 103779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong } 103879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frame = *mFramesReceived.begin(); 103979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesReceived.erase(mFramesReceived.begin()); 104079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong 104179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frameTime = *mFrameTimes.begin(); 104279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFrameTimes.erase(mFrameTimes.begin()); 104379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesBeingEncoded.push_back(frame); 104479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 104579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->setObserver(this); 104679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->add_ref(); 104779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 10487278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::shouldSkipFrameLocked(int64_t timestampUs) { 1053a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) { 1054ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs); 10558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1056c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 105965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 106079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (skipCurrentFrame(timestampUs)) { 10618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1062fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 1063fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 10640aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (mNumFramesReceived > 0) { 10650aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs <= mLastFrameTimestampUs) { 10660aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ALOGW("Dropping frame with backward timestamp %lld (last %lld)", 10670aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang (long long)timestampUs, (long long)mLastFrameTimestampUs); 10688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 10690aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10700aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 10710aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ++mNumGlitches; 10720aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10730aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 10740aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang 1075365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 107613aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 1077c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 1078f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 1079f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 1080f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 1081f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 1082f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 10838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1084f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1085f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 1086f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1087be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 10888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 10908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 10918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 10938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int32_t msgType __unused, const sp<IMemory> &data) { 10948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs); 10958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 10968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 10978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 10988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen releaseOneRecordingFrame(data); 10998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 11008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 110213aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 1103be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 110498cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(data != NULL && data->size() > 0); 11057278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 1106f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 1107f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 1108a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 1109f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 111020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 111120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 111220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11132d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::releaseRecordingFrameHandle(native_handle_t* handle) { 11142d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (mCameraRecordingProxy != nullptr) { 11152d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCameraRecordingProxy->releaseRecordingFrameHandle(handle); 11162d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCamera != nullptr) { 11172d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t token = IPCThreadState::self()->clearCallingIdentity(); 11182d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCamera->releaseRecordingFrameHandle(handle); 11192d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen IPCThreadState::self()->restoreCallingIdentity(token); 1120cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen } else { 1121cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen native_handle_close(handle); 1122cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen native_handle_delete(handle); 11232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 11242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 11252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::recordingFrameHandleCallbackTimestamp(int64_t timestampUs, 11272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 11282d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs); 11292d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen Mutex::Autolock autoLock(mLock); 11302d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (handle == nullptr) return; 11312d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11322d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 11332d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen releaseRecordingFrameHandle(handle); 11342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen return; 11352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 11362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11372d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen while (mMemoryBases.empty()) { 11382d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 11392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen TIMED_OUT) { 11402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 11412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen releaseRecordingFrameHandle(handle); 11422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen return; 11432d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 11442d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 11452d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ++mNumFramesReceived; 11472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen sp<IMemory> data = *mMemoryBases.begin(); 11492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBases.erase(mMemoryBases.begin()); 11502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived. 11522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer()); 11532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen metadata->eType = kMetadataBufferTypeNativeHandleSource; 11542d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen metadata->pHandle = handle; 11552d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11562d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFramesReceived.push_back(data); 11572d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 11582d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFrameTimes.push_back(timeUs); 11592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs); 11602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFrameAvailableCondition.signal(); 11612d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 11622d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 11638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu ChenCameraSource::BufferQueueListener::BufferQueueListener(const sp<BufferItemConsumer>& consumer, 11648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen const sp<CameraSource>& cameraSource) { 11658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer = consumer; 11668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer->setFrameAvailableListener(this); 11678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource = cameraSource; 11688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 11698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::BufferQueueListener::onFrameAvailable(const BufferItem& /*item*/) { 11718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("%s: onFrameAvailable", __FUNCTION__); 11728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 11748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (!mFrameAvailable) { 11768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = true; 11778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableSignal.signal(); 11788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 11808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::BufferQueueListener::threadLoop() { 11828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mConsumer == nullptr || mCameraSource == nullptr) { 11838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 11848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen { 11878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 11888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (!mFrameAvailable) { 11898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mFrameAvailableSignal.waitRelative(mLock, kFrameAvailableTimeout) == TIMED_OUT) { 11908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 11918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = false; 11948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer; 11978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (mConsumer->acquireBuffer(&buffer, 0) == OK) { 11988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource->processBufferQueueFrame(buffer); 11998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 12008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 12028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 12038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12048fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chenvoid CameraSource::processBufferQueueFrame(BufferItem& buffer) { 12058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 12068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timestampUs = buffer.mTimestamp / 1000; 12088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 12098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 12108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 12118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 12128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12130419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen while (mMemoryBases.empty()) { 12140419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 12150419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen TIMED_OUT) { 12160419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 12170419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 12180419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen return; 12190419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen } 12208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 12218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ++mNumFramesReceived; 12238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find a available memory slot to store the buffer as VideoNativeMetadata. 12258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemory> data = *mMemoryBases.begin(); 12268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.erase(mMemoryBases.begin()); 12278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 12298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 12308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = data->getMemory(&offset, &size); 12318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 12328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 12338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen memset(payload, 0, sizeof(VideoNativeMetadata)); 12348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->eType = kMetadataBufferTypeANWBuffer; 12358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->pBuffer = buffer.mGraphicBuffer->getNativeBuffer(); 12368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->nFenceFd = -1; 12378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Add the mapping so we can find the corresponding buffer item to release to the buffer queue 12398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // when the encoder returns the native window buffer. 12408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.add(payload->pBuffer, buffer); 12418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFramesReceived.push_back(data); 12438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 12448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameTimes.push_back(timeUs); 12458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 12468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mStartTimeUs, timeUs); 12478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableCondition.signal(); 12488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 12498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12503e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos MolnarMetadataBufferType CameraSource::metaDataStoredInVideoBuffers() const { 12513e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar ALOGV("metaDataStoredInVideoBuffers"); 12528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 12538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Output buffers will contain metadata if camera sends us buffer in metadata mode or via 12548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // buffer queue. 12553e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar switch (mVideoBufferMode) { 12563e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar case hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA: 12573e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeNativeHandleSource; 12583e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar case hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE: 12593e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeANWBuffer; 12603e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar default: 12613e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeInvalid; 12623e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar } 12635c9523154d106b555db6c41f85ab205a4f189b02James Dong} 12645c9523154d106b555db6c41f85ab205a4f189b02James Dong 12654ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) { 12664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource = source; 12674ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 12684ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 12694ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp( 12704ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 12714ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr); 12724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 12734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 12742d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::ProxyListener::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, 12752d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 12762d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mSource->recordingFrameHandleCallbackTimestamp(timestamp / 1000, handle); 12772d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 12782d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 1279ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnarvoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) { 1280df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Camera recording proxy died"); 12814ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 12824ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 128320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 1284