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 { 50090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit 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 61b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh virtual void postRecordingFrameHandleTimestampBatch( 62b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<nsecs_t>& timestamps, 63b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<native_handle_t*>& handles); 64b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 65be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 69be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 70be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 72be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 76be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 77be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 80be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 8384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(msgType); 8484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext1); 8584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber UNUSED_UNLESS_VERBOSE(ext2); 863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 87be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8957c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr, 9084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber camera_frame_metadata_t * /* metadata */) { 91a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("postData(%d, ptr:%p, size:%zu)", 92be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 9365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 9465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra sp<CameraSource> source = mSource.promote(); 9565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra if (source.get() != NULL) { 9665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra source->dataCallback(msgType, dataPtr); 9765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra } 98be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 99be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 100be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 101be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 102c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 103c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 104c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 105c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 106c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 107be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1092d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSourceListener::postRecordingFrameHandleTimestamp(nsecs_t timestamp, 1102d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 1112d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen sp<CameraSource> source = mSource.promote(); 1122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (source.get() != nullptr) { 1132d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen source->recordingFrameHandleCallbackTimestamp(timestamp/1000, handle); 1142d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 1152d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 1162d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 117b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yehvoid CameraSourceListener::postRecordingFrameHandleTimestampBatch( 118b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<nsecs_t>& timestamps, 119b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<native_handle_t*>& handles) { 120b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh sp<CameraSource> source = mSource.promote(); 121b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (source.get() != nullptr) { 122b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int n = timestamps.size(); 123b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh std::vector<nsecs_t> modifiedTimestamps(n); 124b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (int i = 0; i < n; i++) { 125b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh modifiedTimestamps[i] = timestamps[i] / 1000; 126b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 127b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh source->recordingFrameHandleCallbackTimestampBatch(modifiedTimestamps, handles); 128b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 129b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh} 130b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 131653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 1322d1bcf2b8f2f23e204adcca45ca134247bdf87f9Praveen Chavan if (!colorFormat) { 1332d1bcf2b8f2f23e204adcca45ca134247bdf87f9Praveen Chavan ALOGE("Invalid color format"); 1342d1bcf2b8f2f23e204adcca45ca134247bdf87f9Praveen Chavan return -1; 1352d1bcf2b8f2f23e204adcca45ca134247bdf87f9Praveen Chavan } 1362d1bcf2b8f2f23e204adcca45ca134247bdf87f9Praveen Chavan 137e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) { 138e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong return OMX_COLOR_FormatYUV420Planar; 139e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong } 140e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong 141653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 142653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 143653252be963c07c99109d20f942d1f30c52a9360James Dong } 144653252be963c07c99109d20f942d1f30c52a9360James Dong 145653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 146653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 147653252be963c07c99109d20f942d1f30c52a9360James Dong } 148653252be963c07c99109d20f942d1f30c52a9360James Dong 149653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 150653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 151653252be963c07c99109d20f942d1f30c52a9360James Dong } 152653252be963c07c99109d20f942d1f30c52a9360James Dong 153653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 154653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 155653252be963c07c99109d20f942d1f30c52a9360James Dong } 156653252be963c07c99109d20f942d1f30c52a9360James Dong 1571374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) { 1581374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar; 1591374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket } 1601374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket 161bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) { 162bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala return OMX_COLOR_FormatAndroidOpaque; 163bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala } 164bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala 16529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Uknown color format (%s), please add it to " 166a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong "CameraSource::getColorFormat", colorFormat); 167a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong 168f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"Unknown color format"); 169dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn return -1; 170653252be963c07c99109d20f942d1f30c52a9360James Dong} 171653252be963c07c99109d20f942d1f30c52a9360James Dong 172ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) { 17354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size size; 17454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.width = -1; 17554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong size.height = -1; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala sp<hardware::ICamera> camera; 17898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen return new CameraSource(camera, NULL, 0, clientName, Camera::USE_CALLING_UID, 17998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen Camera::USE_CALLING_PID, size, -1, NULL, false); 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18230ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 18354ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera( 184d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 1854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 18654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 187ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 188ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 18998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 19054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 19299617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 1935c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 19454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 1954ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li CameraSource *source = new CameraSource(camera, proxy, cameraId, 19698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, videoSize, frameRate, surface, 197ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala storeMetaDataInVideoBuffers); 19854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return source; 19930ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 20030ab66297501757d745b9ae10da61adcd891f497Andreas Huber 20154ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource( 202d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 2034ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 205ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 206ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 20798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 20854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 20954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate, 21099617adda9bc46c43f511f0940bc735c73de61deMathias Agopian const sp<IGraphicBufferProducer>& surface, 2115c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) 21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong : mCameraFlags(0), 213983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers(0), 21454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate(-1), 21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera(0), 21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mSurface(surface), 21713aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 21865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mLastFrameTimestampUs(0), 21965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mStarted(false), 22013aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 221e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs(0), 2227757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong mFirstFrameTimeUs(0), 223f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang mStopSystemTimeUs(-1), 22413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 225f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 226f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 22765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra mCollectStats(false) { 22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = -1; 22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = -1; 23054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2314ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mInitCheck = init(camera, proxy, cameraId, 23298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid, 2335c9523154d106b555db6c41f85ab205a4f189b02James Dong videoSize, frameRate, 2345c9523154d106b555db6c41f85ab205a4f189b02James Dong storeMetaDataInVideoBuffers); 23595068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li if (mInitCheck != OK) releaseCamera(); 23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const { 23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable( 243d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy, 24498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) { 24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (camera == 0) { 24798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid); 2484ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags &= ~FLAGS_HOT_CAMERA; 25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 2514ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // We get the proxy from Camera, not ICamera. We need to get the proxy 2524ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // to the remote Camera owned by the application. Here mCamera is a 2534ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // local Camera object created by us. We cannot use the proxy from 2544ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // mCamera here. 25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCamera = Camera::create(camera); 2564ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mCamera == 0) return -EBUSY; 2574ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCameraRecordingProxy = proxy; 25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mCameraFlags |= FLAGS_HOT_CAMERA; 2593bd3020c00ec8264ac1fe3870800f326487f9221James Dong mDeathNotifier = new DeathNotifier(); 2603bd3020c00ec8264ac1fe3870800f326487f9221James Dong // isBinderAlive needs linkToDeath to work. 26106b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier); 26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2644ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mCamera->lock(); 2654ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one 27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes. 27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels 27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels 27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against 27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported. 27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported( 27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const Vector<Size>& supportedSizes) { 28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 2823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isVideoSizeSupported"); 28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong for (size_t i = 0; i < supportedSizes.size(); ++i) { 28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width == supportedSizes[i].width && 28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong height == supportedSizes[i].height) { 28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return true; 28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return false; 29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the 29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size 29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not 29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview 29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same 29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size. 29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes 30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize() 30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not. 30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method 30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * CameraParameters::setVideoSize() is supported or not. 30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the 30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * supported video frame sizes advertised by the camera. 31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes( 31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool *isSetVideoSizeSupported, 31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size>& sizes) { 31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = true; 31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedVideoSizes(sizes); 31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (sizes.size() == 0) { 319b8a805261bf0282e992d3608035e47d05a898710Steve Block ALOGD("Camera does not support setVideoSize()"); 32054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params.getSupportedPreviewSizes(sizes); 32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *isSetVideoSizeSupported = false; 32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 32554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format 32754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported( 33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params) { 33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mColorFormat = getColorFormat(params.get( 33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters::KEY_VIDEO_FRAME_FORMAT)); 33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mColorFormat == -1) { 33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size 34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and 34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped. 34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate 34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to 34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to 34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method). 34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured 35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels 35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels 35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 35354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 35454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 35554ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera( 35654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters* params, 35754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height, 35854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 3593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("configureCamera"); 36054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Vector<Size> sizes; 36154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isSetVideoSizeSupportedByCamera = true; 36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); 36354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong bool isCameraParamChanged = false; 36454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 36554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (!isVideoSizeSupported(width, height, sizes)) { 36629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Video dimension (%dx%d) is unsupported", width, height); 36754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 36954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isSetVideoSizeSupportedByCamera) { 37054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setVideoSize(width, height); 37154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { 37254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewSize(width, height); 37354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 37454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 37554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else if ((width == -1 && height != -1) || 37654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong (width != -1 && height == -1)) { 37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // If one and only one of the width and height is -1 37854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // we reject such a request. 37929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested video size (%dx%d) is not supported", width, height); 38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return BAD_VALUE; 38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // width == -1 && height == -1 38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current width and height value setting from the camera. 38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1) { 387635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(frameRate > 0 && frameRate <= 120); 388635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong const char* supportedFrameRates = 389635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); 390635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong CHECK(supportedFrameRates != NULL); 3913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Supported frame rates: %s", supportedFrameRates); 392635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong char buf[4]; 393635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong snprintf(buf, 4, "%d", frameRate); 394635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong if (strstr(supportedFrameRates, buf) == NULL) { 39529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Requested frame rate (%d) is not supported: %s", 396635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong frameRate, supportedFrameRates); 397635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong return BAD_VALUE; 398635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong } 399635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong 400635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong // The frame rate is supported, set the camera to the requested value. 40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong params->setPreviewFrameRate(frameRate); 40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong isCameraParamChanged = true; 40354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } else { // frameRate == -1 40454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Do not configure the camera. 40554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Use the current frame rate value setting from the camera 40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 40854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (isCameraParamChanged) { 40954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Either frame rate or frame size needs to be changed. 41054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong String8 s = params->flatten(); 41154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (OK != mCamera->setParameters(s)) { 41229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Could not change settings." 41354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong " Someone else is using camera %p?", mCamera.get()); 41454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return -EBUSY; 41554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 41854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size 42254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height 42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting 42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed. 42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against 42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against 42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error 43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize( 43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t width, int32_t height) { 43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkVideoSize"); 436f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // The actual video size is the same as the preview size 437f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // if the camera hal does not support separate video and 438f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // preview output. In this case, we retrieve the video 439f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // size from preview. 44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameWidthActual = -1; 44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameHeightActual = -1; 442f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong Vector<Size> sizes; 443f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getSupportedVideoSizes(sizes); 444f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong if (sizes.size() == 0) { 445f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size is the same as preview size 446f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getPreviewSize(&frameWidthActual, &frameHeightActual); 447f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } else { 448f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong // video size may not be the same as preview 449f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong params.getVideoSize(&frameWidthActual, &frameHeightActual); 450f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong } 45154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual < 0 || frameHeightActual < 0) { 45229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve video frame size (%dx%d)", 45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame size against the target/requested 45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame size. 45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (width != -1 && height != -1) { 46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameWidthActual != width || frameHeightActual != height) { 46129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set video frame size to %dx%d. " 46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "The actual video size is %dx%d ", width, height, 46354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameWidthActual, frameHeightActual); 46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.width = frameWidthActual; 47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoSize.height = frameHeightActual; 47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not. 47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value 47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed. 47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * 47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information 48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against 48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 48354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate( 48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong const CameraParameters& params, 48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRate) { 48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 4873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("checkFrameRate"); 48854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t frameRateActual = params.getPreviewFrameRate(); 48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRateActual < 0) { 49029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); 49154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 49354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 49454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check the actual video frame rate against the target/requested 49554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // video frame rate. 49654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (frameRate != -1 && (frameRateActual - frameRate) != 0) { 49729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Failed to set preview frame rate to %d fps. The actual " 49854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong "frame rate is %d", frameRate, frameRateActual); 49954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return UNKNOWN_ERROR; 50054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 50154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 50254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Good now. 50354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mVideoFrameRate = frameRateActual; 50454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 50554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong} 50654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 50754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/* 50854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes 50954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested. 51054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source 51154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id 51254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the video source 51354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both 51454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and height in videoSize is -1, use the current 51554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * width and heigth settings by the camera 51654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second. 51754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if it is -1, use the current camera frame rate setting. 5185c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta 5195c9523154d106b555db6c41f85ab205a4f189b02James Dong * data or real YUV data in video buffers. Request to 5205c9523154d106b555db6c41f85ab205a4f189b02James Dong * store meta data in video buffers may not be honored 5215c9523154d106b555db6c41f85ab205a4f189b02James Dong * if the source does not support this feature. 5225c9523154d106b555db6c41f85ab205a4f189b02James Dong * 52354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error. 52454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */ 52554ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init( 526d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 5274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li const sp<ICameraRecordingProxy>& proxy, 52854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int32_t cameraId, 529ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 530ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 53198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 53254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong Size videoSize, 5335c9523154d106b555db6c41f85ab205a4f189b02James Dong int32_t frameRate, 5345c9523154d106b555db6c41f85ab205a4f189b02James Dong bool storeMetaDataInVideoBuffers) { 53554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 5363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init"); 53754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong status_t err = OK; 538ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 53998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, clientPid, 540ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong videoSize, frameRate, 541ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong storeMetaDataInVideoBuffers); 542ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 543ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong return err; 544ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong} 545ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong 5462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::createVideoBufferMemoryHeap(size_t size, uint32_t bufferCount) { 5472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryHeapBase = new MemoryHeapBase(size * bufferCount, 0, 5482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen "StageFright-CameraSource-BufferHeap"); 5492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen for (uint32_t i = 0; i < bufferCount; i++) { 5502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBases.push_back(new MemoryBase(mMemoryHeapBase, i * size, size)); 5512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 5522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 5532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 5548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenstatus_t CameraSource::initBufferQueue(uint32_t width, uint32_t height, 5558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t format, android_dataspace dataSpace, uint32_t bufferCount) { 5568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initBufferQueue"); 5578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mVideoBufferConsumer != nullptr || mVideoBufferProducer != nullptr) { 5598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Buffer queue already exists", __FUNCTION__); 5608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return ALREADY_EXISTS; 5618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create a buffer queue. 5648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferProducer> producer; 5658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IGraphicBufferConsumer> consumer; 5668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferQueue::createBufferQueue(&producer, &consumer); 5678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN; 5698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 5708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen usage = GRALLOC_USAGE_HW_VIDEO_ENCODER; 5718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen bufferCount += kConsumerBufferCount; 5748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer = new BufferItemConsumer(consumer, usage, bufferCount); 5768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->setName(String8::format("StageFright-CameraSource")); 5778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer = producer; 5788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen status_t res = mVideoBufferConsumer->setDefaultBufferSize(width, height); 5808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer dimensions %dx%d: %s (%d)", __FUNCTION__, width, height, 5828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferFormat(format); 5878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set buffer format %d: %s (%d)", __FUNCTION__, format, 5898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 5938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mVideoBufferConsumer->setDefaultBufferDataSpace(dataSpace); 5948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 5958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not set data space %d: %s (%d)", __FUNCTION__, dataSpace, 5968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 5978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 5988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 5998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mCamera->setVideoTarget(mVideoBufferProducer); 6018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 6028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to set video target: %s (%d)", __FUNCTION__, strerror(-res), res); 6038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 6048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Create memory heap to store buffers as VideoNativeMetadata. 6072d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen createVideoBufferMemoryHeap(sizeof(VideoNativeMetadata), bufferCount); 6088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener = new BufferQueueListener(mVideoBufferConsumer, this); 6108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen res = mBufferQueueListener->run("CameraSource-BufferQueueListener"); 6118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (res != OK) { 6128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Could not run buffer queue listener thread: %s (%d)", __FUNCTION__, 6138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-res), res); 6148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return res; 6158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 6178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return OK; 6188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 6198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 620ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess( 621d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala const sp<hardware::ICamera>& camera, 622ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong const sp<ICameraRecordingProxy>& proxy, 623ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t cameraId, 624ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala const String16& clientName, 625ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala uid_t clientUid, 62698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen pid_t clientPid, 627ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong Size videoSize, 628ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int32_t frameRate, 629ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong bool storeMetaDataInVideoBuffers) { 6303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("initWithCameraAccess"); 631ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong status_t err = OK; 6329d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 633ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala if ((err = isCameraAvailable(camera, proxy, cameraId, 63498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen clientName, clientUid, clientPid)) != OK) { 63529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Camera connection could not be established."); 63654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 63754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 63854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters params(mCamera->getParameters()); 63954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = isCameraColorFormatSupported(params)) != OK) { 64054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 64154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 642be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 64354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Set the camera to use the requested video frame size 64454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // and/or frame rate. 64554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = configureCamera(¶ms, 64654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height, 64754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong frameRate))) { 64854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 64954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 650653252be963c07c99109d20f942d1f30c52a9360James Dong 65154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong // Check on video frame size and frame rate. 65254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong CameraParameters newCameraParams(mCamera->getParameters()); 65354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkVideoSize(newCameraParams, 65454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong videoSize.width, videoSize.height)) != OK) { 65554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 65654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 65754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { 65854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return err; 65954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 66054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong 6618e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // Set the preview display. Skip this if mSurface is null because 6628e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // applications may already set a surface to the camera. 6638e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li if (mSurface != NULL) { 6648e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // This CHECK is good, since we just passed the lock/unlock 6658e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li // check earlier by calling mCamera->setParameters(). 6664b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface)); 6678e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li } 6682b37ced30f89437c804c3945b901019b86d210aeJames Dong 6698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // By default, store real data in video buffers. 670d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV; 671abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong if (storeMetaDataInVideoBuffers) { 672d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (OK == mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE)) { 673d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE; 6748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else if (OK == mCamera->setVideoBufferMode( 675d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA)) { 676d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA; 6778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 6798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 680d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) { 681d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala err = mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV); 6828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 6838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV failed: " 6848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen "%s (err=%d)", __FUNCTION__, strerror(-err), err); 6858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 686abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong } 6875c9523154d106b555db6c41f85ab205a4f189b02James Dong } 6885c9523154d106b555db6c41f85ab205a4f189b02James Dong 68954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); 690f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 691f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 692f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 693f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 694ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 695ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 696653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 69754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 69854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyColorFormat, mColorFormat); 69954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyWidth, mVideoSize.width); 70054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyHeight, mVideoSize.height); 70154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeyStride, mVideoSize.width); 70254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong mMeta->setInt32(kKeySliceHeight, mVideoSize.height); 703393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong mMeta->setInt32(kKeyFrameRate, mVideoFrameRate); 70454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return OK; 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 709b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong reset(); 710ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong } else if (mInitCheck == OK) { 711ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera is initialized but because start() is never called, 712ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // the lock on Camera is never released(). This makes sure 713ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong // Camera's lock is released in this case. 714ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong releaseCamera(); 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() { 7193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("startCameraRecording"); 7204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // Reset the identity to the current thread because media server owns the 7214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // camera and recording is started by the applications. The applications 7224ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li // will connect to the camera in ICameraRecordingProxy::startRecording. 7234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li int64_t token = IPCThreadState::self()->clearCallingIdentity(); 72426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 7258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 726d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 7278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Initialize buffer queue. 7288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat, 7298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (android_dataspace_t)mEncoderDataSpace, 7308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers > 0 ? mNumInputBuffers : 1); 7318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 7328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__, 7338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen strerror(-err), err); 7348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return err; 7358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } else { 7378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mNumInputBuffers > 0) { 7388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen err = mCamera->sendCommand( 7398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0); 7408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 7418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // This could happen for CameraHAL1 clients; thus the failure is 7428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // not a fatal error 7438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (err != OK) { 7448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video buffer count to %d due to %d", 7458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mNumInputBuffers, err); 7468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 7488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 74926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = mCamera->sendCommand( 7508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace); 751983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 752983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // This could happen for CameraHAL1 clients; thus the failure is 753983cf231ab2d176a14595cdae46ff1b0c239af47James Dong // not a fatal error 754983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (err != OK) { 7558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d", 7568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mEncoderFormat, mEncoderDataSpace, err); 757983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 7582d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 7592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Create memory heap to store buffers as VideoNativeMetadata. 7602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen createVideoBufferMemoryHeap(sizeof(VideoNativeHandleMetadata), kDefaultVideoBufferCount); 761983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 762983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 76326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = OK; 7643bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 7653bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->unlock(); 7663bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera.clear(); 76726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = mCameraRecordingProxy->startRecording( 76826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk new ProxyListener(this))) != OK) { 76926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording, received error: %s (%d)", 77026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk strerror(-err), err); 77126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7723bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 7733bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->setListener(new CameraSourceListener(this)); 7743bd3020c00ec8264ac1fe3870800f326487f9221James Dong mCamera->startRecording(); 77526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if (!mCamera->recordingEnabled()) { 77626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk err = -EINVAL; 77726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk ALOGE("Failed to start recording"); 77826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 7793bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 7804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li IPCThreadState::self()->restoreCallingIdentity(token); 78126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 78265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 78365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 784f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 7853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("start"); 7860c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 78754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong if (mInitCheck != OK) { 78829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("CameraSource is not initialized yet"); 78954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong return mInitCheck; 79054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong } 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79296626b7f9a4e5c9e1e04f7f710383631d1470364Marco Nelissen if (property_get_bool("media.stagefright.record-stats", false)) { 793365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 794365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 7959d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 796f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 797983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = 0; 798d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 7992cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvala mEncoderDataSpace = HAL_DATASPACE_V0_BT709; 800d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 801983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta) { 802983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int64_t startTimeUs; 803983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt64(kKeyTime, &startTimeUs)) { 804983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mStartTimeUs = startTimeUs; 805983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 806983cf231ab2d176a14595cdae46ff1b0c239af47James Dong 807983cf231ab2d176a14595cdae46ff1b0c239af47James Dong int32_t nBuffers; 808983cf231ab2d176a14595cdae46ff1b0c239af47James Dong if (meta->findInt32(kKeyNumBuffers, &nBuffers)) { 809983cf231ab2d176a14595cdae46ff1b0c239af47James Dong CHECK_GT(nBuffers, 0); 810983cf231ab2d176a14595cdae46ff1b0c239af47James Dong mNumInputBuffers = nBuffers; 811983cf231ab2d176a14595cdae46ff1b0c239af47James Dong } 812d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala 813c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // apply encoder color format if specified 814c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) { 815b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGI("Using encoder format: %#x", mEncoderFormat); 816c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 817c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) { 818b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGI("Using encoder data space: %#x", mEncoderDataSpace); 819c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 820f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 821f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 82226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk status_t err; 82326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk if ((err = startCameraRecording()) == OK) { 82426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk mStarted = true; 82526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk } 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk return err; 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() { 8313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("stopCameraRecording"); 8323bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraFlags & FLAGS_HOT_CAMERA) { 8332da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCameraRecordingProxy != 0) { 8342da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCameraRecordingProxy->stopRecording(); 8352da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 8363bd3020c00ec8264ac1fe3870800f326487f9221James Dong } else { 8372da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim if (mCamera != 0) { 8382da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->setListener(NULL); 8392da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim mCamera->stopRecording(); 8402da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim } 8413bd3020c00ec8264ac1fe3870800f326487f9221James Dong } 84265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 84365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 844ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() { 8453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseCamera"); 846121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang sp<Camera> camera; 847121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool coldCamera = false; 848121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 849121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 850121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang // get a local ref and clear ref to mCamera now 851121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera = mCamera; 852121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCamera.clear(); 853121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0; 854121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 855121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 856121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (camera != 0) { 857ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 858121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (coldCamera) { 8593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Camera was cold when we started, stopping preview"); 860121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->stopPreview(); 861121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->disconnect(); 86295068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 863121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang camera->unlock(); 864ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong IPCThreadState::self()->restoreCallingIdentity(token); 86595068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li } 866121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 867121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 868121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 869121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCameraRecordingProxy != 0) { 87006b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier); 871121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraRecordingProxy.clear(); 872121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 873121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mCameraFlags = 0; 874ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong } 875ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong} 876ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong 877b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() { 878b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: E"); 879121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 880121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang { 881121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang Mutex::Autolock autoLock(mLock); 882121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mStarted = false; 883f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang mStopSystemTimeUs = -1; 884121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameAvailableCondition.signal(); 885121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 886121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang int64_t token; 887121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang bool isTokenValid = false; 888121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCamera != 0) { 889121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang token = IPCThreadState::self()->clearCallingIdentity(); 890121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang isTokenValid = true; 891121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 892121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseQueuedFrames(); 893121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang while (!mFramesBeingEncoded.empty()) { 894121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (NO_ERROR != 895121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFrameCompleteCondition.waitRelative(mLock, 896121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 897121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("Timed out waiting for outstanding frames being encoded: %zu", 898121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mFramesBeingEncoded.size()); 899121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 900121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 901121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang stopCameraRecording(); 902121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (isTokenValid) { 903121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang IPCThreadState::self()->restoreCallingIdentity(token); 90441152efd144ccf70c380d5c9a32105c02a039f43James Dong } 9057278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 906121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mCollectStats) { 907121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us", 908121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 909121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang mLastFrameTimestampUs - mFirstFrameTimeUs); 910121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 911121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 912121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang if (mNumGlitches > 0) { 913121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang ALOGW("%d long delays between neighboring video frames", mNumGlitches); 914121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang } 91513aec890216948b0c364f8f92792129d0335f506James Dong 916121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 917ba29002c7aee13c068049037cd14bba6a244da6bJames Dong } 918ba29002c7aee13c068049037cd14bba6a244da6bJames Dong 9198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mBufferQueueListener != nullptr) { 9208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->requestExit(); 9218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener->join(); 9228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mBufferQueueListener.clear(); 9238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer.clear(); 9268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferProducer.clear(); 927121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang releaseCamera(); 928121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang 929b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong ALOGD("reset: X"); 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 93365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) { 9343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("releaseRecordingFrame"); 9358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 936d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) { 9378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode. 9388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 9398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 9408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = frame->getMemory(&offset, &size); 9418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) { 9428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__, 9438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen heap->getHeapID(), mMemoryHeapBase->getHeapID()); 9448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 9488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 9498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find the corresponding buffer item for the native window buffer. 9518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer); 9528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (index == NAME_NOT_FOUND) { 9538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer); 9548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 9558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 9568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 9578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer = mReceivedBufferItemMap.valueAt(index); 9588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.removeItemsAt(index); 9598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 9608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.push_back(frame); 9610419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mMemoryBaseAvailableCond.signal(); 9622d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else { 9632d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle = nullptr; 9642d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 9652d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Check if frame contains a VideoNativeHandleMetadata. 9662d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (frame->size() == sizeof(VideoNativeHandleMetadata)) { 9672d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen VideoNativeHandleMetadata *metadata = 9682d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen (VideoNativeHandleMetadata*)(frame->pointer()); 9692d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (metadata->eType == kMetadataBufferTypeNativeHandleSource) { 9702d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen handle = metadata->pHandle; 9712d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 9722d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 9732d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 9742d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (handle != nullptr) { 9757eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick ssize_t offset; 9767eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick size_t size; 9777eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick sp<IMemoryHeap> heap = frame->getMemory(&offset, &size); 9787eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) { 9797eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", 9807eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick __FUNCTION__, heap->getHeapID(), mMemoryHeapBase->getHeapID()); 9817eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick return; 9827eb18466d9ee817ae1087ddc895902e8eae05535Ray Essick } 983b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh uint32_t batchSize = 0; 984b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh { 985b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh Mutex::Autolock autoLock(mBatchLock); 986b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (mInflightBatchSizes.size() > 0) { 987b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh batchSize = mInflightBatchSizes[0]; 988b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 989b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 990b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (batchSize == 0) { // return buffers one by one 991b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh // Frame contains a VideoNativeHandleMetadata. Send the handle back to camera. 992b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh releaseRecordingFrameHandle(handle); 993b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mMemoryBases.push_back(frame); 994b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mMemoryBaseAvailableCond.signal(); 995b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } else { // Group buffers in batch then return 996b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh Mutex::Autolock autoLock(mBatchLock); 997b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightReturnedHandles.push_back(handle); 998b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightReturnedMemorys.push_back(frame); 999b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (mInflightReturnedHandles.size() == batchSize) { 1000b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh releaseRecordingFrameHandleBatch(mInflightReturnedHandles); 1001b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1002b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightBatchSizes.pop_front(); 1003b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightReturnedHandles.clear(); 1004b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (const auto& mem : mInflightReturnedMemorys) { 1005b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mMemoryBases.push_back(mem); 1006b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mMemoryBaseAvailableCond.signal(); 1007b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1008b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightReturnedMemorys.clear(); 1009b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1010b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1011b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 10122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCameraRecordingProxy != nullptr) { 10132d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // mCamera is created by application. Return the frame back to camera via camera 10142d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // recording proxy. 10152d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCameraRecordingProxy->releaseRecordingFrame(frame); 10162d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCamera != nullptr) { 10172d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // mCamera is created by CameraSource. Return the frame directly back to camera. 10182d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t token = IPCThreadState::self()->clearCallingIdentity(); 10192d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCamera->releaseRecordingFrame(frame); 10202d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen IPCThreadState::self()->restoreCallingIdentity(token); 10212d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 1022d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong } 102365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra} 102465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra 1025c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 1026c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 10277278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 10287278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 102965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(*it); 10307278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 103113aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 1032c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 1033c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 1034c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 103520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 1036653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 103720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 103820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1039f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 104065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra releaseRecordingFrame(frame); 1041f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 1042f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 10437278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 10443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: %p", buffer->data()); 104556223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber Mutex::Autolock autoLock(mLock); 10467278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 10477278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 10487278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 1049f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 10507278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 10517278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 10527278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 10537278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 10547278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 10557278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 10567278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 10577278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 1058f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"signalBufferReturned: bogus buffer"); 10597278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 10607278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 10633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("read"); 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 1068abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 1069abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 107020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 1074be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 107879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong while (mStarted && mFramesReceived.empty()) { 107941152efd144ccf70c380d5c9a32105c02a039f43James Dong if (NO_ERROR != 1080e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mFrameAvailableCondition.waitRelative(mLock, 1081e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) { 10823bd3020c00ec8264ac1fe3870800f326487f9221James Dong if (mCameraRecordingProxy != 0 && 108306b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) { 10845ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("camera recording proxy is gone"); 10854ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return ERROR_END_OF_STREAM; 10864ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 1087a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us", 108841152efd144ccf70c380d5c9a32105c02a039f43James Dong mLastFrameTimestampUs); 108941152efd144ccf70c380d5c9a32105c02a039f43James Dong } 109020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 109179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (!mStarted) { 109279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong return OK; 109379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong } 109479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frame = *mFramesReceived.begin(); 109579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesReceived.erase(mFramesReceived.begin()); 109679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong 109779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong frameTime = *mFrameTimes.begin(); 109879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFrameTimes.erase(mFrameTimes.begin()); 109979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong mFramesBeingEncoded.push_back(frame); 110079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 110179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->setObserver(this); 110279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->add_ref(); 110379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 11047278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 110520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 110620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 110720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1108f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t CameraSource::setStopTimeUs(int64_t stopTimeUs) { 1109f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang Mutex::Autolock autoLock(mLock); 1110f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang ALOGV("Set stoptime: %lld us", (long long)stopTimeUs); 1111f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 1112f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang if (stopTimeUs < -1) { 1113f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang ALOGE("Invalid stop time %lld us", (long long)stopTimeUs); 1114f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang return BAD_VALUE; 1115f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } else if (stopTimeUs == -1) { 1116f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang ALOGI("reset stopTime to be -1"); 1117f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } 1118f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 1119f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang mStopSystemTimeUs = stopTimeUs; 1120f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang return OK; 1121f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang} 1122f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 11238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::shouldSkipFrameLocked(int64_t timestampUs) { 1124a472613aec322e25891abf5c77bf3f7e3c244920James Dong if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) { 1125ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs); 11268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1127c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1129f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang if (mStopSystemTimeUs != -1 && timestampUs >= mStopSystemTimeUs) { 1130f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang ALOGV("Drop Camera frame at %lld stop time: %lld us", 1131f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang (long long)timestampUs, (long long)mStopSystemTimeUs); 1132f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang return true; 1133f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } 1134f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 113565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // May need to skip frame or modify timestamp. Currently implemented 113665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra // by the subclass CameraSourceTimeLapse. 113779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong if (skipCurrentFrame(timestampUs)) { 11388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1139fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra } 1140fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra 11410aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (mNumFramesReceived > 0) { 11420aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs <= mLastFrameTimestampUs) { 11430aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ALOGW("Dropping frame with backward timestamp %lld (last %lld)", 11440aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang (long long)timestampUs, (long long)mLastFrameTimestampUs); 11458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 11460aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 11470aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 11480aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang ++mNumGlitches; 11490aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 11500aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang } 11510aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang 1152365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 115313aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 1154c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 1155f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 1156f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 1157f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 1158f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 1159f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 11608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 1161f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1162f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 1163f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 1164be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 11658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 11678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 11688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 11708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int32_t msgType __unused, const sp<IMemory> &data) { 11718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs); 11728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 11738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 11748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 11758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen releaseOneRecordingFrame(data); 11768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 11778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 11788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 117913aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 1180be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 118198cfde007490a5903b729a4718c0dada755ae8f8James Dong CHECK(data != NULL && data->size() > 0); 11827278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 1183f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 1184f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 1185a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 1186f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 118720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 118820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 118920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11902d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::releaseRecordingFrameHandle(native_handle_t* handle) { 11912d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (mCameraRecordingProxy != nullptr) { 11922d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCameraRecordingProxy->releaseRecordingFrameHandle(handle); 11932d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } else if (mCamera != nullptr) { 11942d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t token = IPCThreadState::self()->clearCallingIdentity(); 11952d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mCamera->releaseRecordingFrameHandle(handle); 11962d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen IPCThreadState::self()->restoreCallingIdentity(token); 1197cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen } else { 1198cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen native_handle_close(handle); 1199cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen native_handle_delete(handle); 12002d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 12012d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 12022d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 1203b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yehvoid CameraSource::releaseRecordingFrameHandleBatch(const std::vector<native_handle_t*>& handles) { 1204b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (mCameraRecordingProxy != nullptr) { 1205b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mCameraRecordingProxy->releaseRecordingFrameHandleBatch(handles); 1206b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } else if (mCamera != nullptr) { 1207b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int64_t token = IPCThreadState::self()->clearCallingIdentity(); 1208b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mCamera->releaseRecordingFrameHandleBatch(handles); 1209b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh IPCThreadState::self()->restoreCallingIdentity(token); 1210b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } else { 1211b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (auto& handle : handles) { 1212b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh native_handle_close(handle); 1213b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh native_handle_delete(handle); 1214b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1215b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1216b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh} 1217b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 12182d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::recordingFrameHandleCallbackTimestamp(int64_t timestampUs, 12192d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 12202d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs); 12212d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen Mutex::Autolock autoLock(mLock); 12222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (handle == nullptr) return; 12232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 12252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen releaseRecordingFrameHandle(handle); 12262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen return; 12272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 12282d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12292d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen while (mMemoryBases.empty()) { 12302d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 12312d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen TIMED_OUT) { 12322d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 12332d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen releaseRecordingFrameHandle(handle); 12342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen return; 12352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 12362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen } 12372d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12382d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ++mNumFramesReceived; 12392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen sp<IMemory> data = *mMemoryBases.begin(); 12412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mMemoryBases.erase(mMemoryBases.begin()); 12422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12432d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived. 12442d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer()); 12452d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen metadata->eType = kMetadataBufferTypeNativeHandleSource; 12462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen metadata->pHandle = handle; 12472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 12482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFramesReceived.push_back(data); 12492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 12502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFrameTimes.push_back(timeUs); 12512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs); 12522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mFrameAvailableCondition.signal(); 12532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 12542d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 1255b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yehvoid CameraSource::recordingFrameHandleCallbackTimestampBatch( 1256b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<int64_t>& timestampsUs, 1257b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<native_handle_t*>& handles) { 1258b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh size_t n = timestampsUs.size(); 1259b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (n != handles.size()) { 1260b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ALOGE("%s: timestampsUs(%zu) and handles(%zu) size mismatch!", 1261b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh __FUNCTION__, timestampsUs.size(), handles.size()); 1262b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1263b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1264b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh Mutex::Autolock autoLock(mLock); 1265b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int batchSize = 0; 1266b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (size_t i = 0; i < n; i++) { 1267b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int64_t timestampUs = timestampsUs[i]; 1268b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh native_handle_t* handle = handles[i]; 1269b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1270b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs); 1271b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (handle == nullptr) continue; 1272b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1273b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (shouldSkipFrameLocked(timestampUs)) { 1274b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh releaseRecordingFrameHandle(handle); 1275b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh continue; 1276b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1277b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1278b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh while (mMemoryBases.empty()) { 1279b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 1280b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh TIMED_OUT) { 1281b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 1282b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh releaseRecordingFrameHandle(handle); 1283b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh continue; 1284b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1285b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1286b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ++batchSize; 1287b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ++mNumFramesReceived; 1288b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh sp<IMemory> data = *mMemoryBases.begin(); 1289b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mMemoryBases.erase(mMemoryBases.begin()); 1290b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1291b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived. 1292b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer()); 1293b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh metadata->eType = kMetadataBufferTypeNativeHandleSource; 1294b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh metadata->pHandle = handle; 1295b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1296b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mFramesReceived.push_back(data); 1297b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 1298b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mFrameTimes.push_back(timeUs); 1299b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs); 1300b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1301b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1302b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh if (batchSize > 0) { 1303b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh Mutex::Autolock autoLock(mBatchLock); 1304b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mInflightBatchSizes.push_back(batchSize); 1305b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1306b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (int i = 0; i < batchSize; i++) { 1307b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mFrameAvailableCondition.signal(); 1308b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1309b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh} 1310b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 13118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu ChenCameraSource::BufferQueueListener::BufferQueueListener(const sp<BufferItemConsumer>& consumer, 13128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen const sp<CameraSource>& cameraSource) { 13138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer = consumer; 13148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mConsumer->setFrameAvailableListener(this); 13158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource = cameraSource; 13168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 13178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::BufferQueueListener::onFrameAvailable(const BufferItem& /*item*/) { 13198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("%s: onFrameAvailable", __FUNCTION__); 13208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 13228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (!mFrameAvailable) { 13248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = true; 13258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableSignal.signal(); 13268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 13288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::BufferQueueListener::threadLoop() { 13308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mConsumer == nullptr || mCameraSource == nullptr) { 13318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return false; 13328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen { 13358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock l(mLock); 13368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (!mFrameAvailable) { 13378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (mFrameAvailableSignal.waitRelative(mLock, kFrameAvailableTimeout) == TIMED_OUT) { 13388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 13398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailable = false; 13428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen BufferItem buffer; 13458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen while (mConsumer->acquireBuffer(&buffer, 0) == OK) { 13468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mCameraSource->processBufferQueueFrame(buffer); 13478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return true; 13508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 13518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13528fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chenvoid CameraSource::processBufferQueueFrame(BufferItem& buffer) { 13538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen Mutex::Autolock autoLock(mLock); 13548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timestampUs = buffer.mTimestamp / 1000; 13568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen if (shouldSkipFrameLocked(timestampUs)) { 13578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 13588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen return; 13598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13610419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen while (mMemoryBases.empty()) { 13620419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) == 13630419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen TIMED_OUT) { 13640419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen ALOGW("Waiting on an available memory base timed out. Dropping a recording frame."); 13650419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen mVideoBufferConsumer->releaseBuffer(buffer); 13660419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen return; 13670419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen } 13688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen } 13698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ++mNumFramesReceived; 13718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Find a available memory slot to store the buffer as VideoNativeMetadata. 13738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemory> data = *mMemoryBases.begin(); 13748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mMemoryBases.erase(mMemoryBases.begin()); 13758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ssize_t offset; 13778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen size_t size; 13788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen sp<IMemoryHeap> heap = data->getMemory(&offset, &size); 13798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>( 13808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen (uint8_t*)heap->getBase() + offset); 13818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen memset(payload, 0, sizeof(VideoNativeMetadata)); 13828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->eType = kMetadataBufferTypeANWBuffer; 13838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->pBuffer = buffer.mGraphicBuffer->getNativeBuffer(); 13848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen payload->nFenceFd = -1; 13858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Add the mapping so we can find the corresponding buffer item to release to the buffer queue 13878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // when the encoder returns the native window buffer. 13888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mReceivedBufferItemMap.add(payload->pBuffer, buffer); 13898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFramesReceived.push_back(data); 13918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 13928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameTimes.push_back(timeUs); 13938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, 13948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mStartTimeUs, timeUs); 13958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen mFrameAvailableCondition.signal(); 13968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen} 13978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 13983e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos MolnarMetadataBufferType CameraSource::metaDataStoredInVideoBuffers() const { 13993e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar ALOGV("metaDataStoredInVideoBuffers"); 14008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen 14018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // Output buffers will contain metadata if camera sends us buffer in metadata mode or via 14028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen // buffer queue. 14033e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar switch (mVideoBufferMode) { 14043e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar case hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA: 14053e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeNativeHandleSource; 14063e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar case hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE: 14073e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeANWBuffer; 14083e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar default: 14093e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar return kMetadataBufferTypeInvalid; 14103e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar } 14115c9523154d106b555db6c41f85ab205a4f189b02James Dong} 14125c9523154d106b555db6c41f85ab205a4f189b02James Dong 14134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) { 14144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource = source; 14154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 14164ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 14174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp( 14184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 14194ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr); 14204ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 14214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 14222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::ProxyListener::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp, 14232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen native_handle_t* handle) { 14242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen mSource->recordingFrameHandleCallbackTimestamp(timestamp / 1000, handle); 14252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen} 14262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen 1427b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yehvoid CameraSource::ProxyListener::recordingFrameHandleCallbackTimestampBatch( 1428b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<int64_t>& timestampsUs, 1429b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh const std::vector<native_handle_t*>& handles) { 1430b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh int n = timestampsUs.size(); 1431b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh std::vector<nsecs_t> modifiedTimestamps(n); 1432b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh for (int i = 0; i < n; i++) { 1433b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh modifiedTimestamps[i] = timestampsUs[i] / 1000; 1434b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh } 1435b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh mSource->recordingFrameHandleCallbackTimestampBatch(modifiedTimestamps, handles); 1436b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh} 1437b5df547bce900fa5764d735bee304e79c001d60dYin-Chia Yeh 1438ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnarvoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) { 1439df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("Camera recording proxy died"); 14404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li} 14414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 144220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 1443