120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
19c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong//#define LOG_NDEBUG 0
20c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#define LOG_TAG "CameraSource"
21c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <utils/Log.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX_Component.h>
249d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong#include <binder/IPCThreadState.h>
258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <binder/MemoryBase.h>
268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <binder/MemoryHeapBase.h>
278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen#include <media/hardware/HardwareAPI.h>
28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h>
30be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h>
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h>
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
333cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h>
343cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h>
35df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
36be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h>
37365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h>
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG
4084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else
4284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x)
4384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif
4484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dongstatic const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
48e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong
49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener {
50be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener(const sp<CameraSource> &source);
51be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
52be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
5357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
5457c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li                          camera_frame_metadata_t *metadata);
55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual void postDataTimestamp(
57be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber            nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
58be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected:
62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual ~CameraSourceListener();
63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
65be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    wp<CameraSource> mSource;
66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener(const CameraSourceListener &);
68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener &operator=(const CameraSourceListener &);
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source)
72be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    : mSource(source) {
73be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
75be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() {
76be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
78be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
7984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(msgType);
8084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(ext1);
8184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(ext2);
823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
83be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8557c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
8684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                                    camera_frame_metadata_t * /* metadata */) {
87a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("postData(%d, ptr:%p, size:%zu)",
88be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber         msgType, dataPtr->pointer(), dataPtr->size());
8965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
9065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<CameraSource> source = mSource.promote();
9165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    if (source.get() != NULL) {
9265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        source->dataCallback(msgType, dataPtr);
9365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
94be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
95be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
96be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp(
97be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber        nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
98c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong
99c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    sp<CameraSource> source = mSource.promote();
100c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    if (source.get() != NULL) {
101c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong        source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
102c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
103be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1052d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSourceListener::postRecordingFrameHandleTimestamp(nsecs_t timestamp,
1062d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_t* handle) {
1072d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    sp<CameraSource> source = mSource.promote();
1082d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    if (source.get() != nullptr) {
1092d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        source->recordingFrameHandleCallbackTimestamp(timestamp/1000, handle);
1102d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
1112d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen}
1122d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
113653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) {
114e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
115e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong       return OMX_COLOR_FormatYUV420Planar;
116e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong    }
117e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong
118653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) {
119653252be963c07c99109d20f942d1f30c52a9360James Dong       return OMX_COLOR_FormatYUV422SemiPlanar;
120653252be963c07c99109d20f942d1f30c52a9360James Dong    }
121653252be963c07c99109d20f942d1f30c52a9360James Dong
122653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
123653252be963c07c99109d20f942d1f30c52a9360James Dong        return OMX_COLOR_FormatYUV420SemiPlanar;
124653252be963c07c99109d20f942d1f30c52a9360James Dong    }
125653252be963c07c99109d20f942d1f30c52a9360James Dong
126653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) {
127653252be963c07c99109d20f942d1f30c52a9360James Dong        return OMX_COLOR_FormatYCbYCr;
128653252be963c07c99109d20f942d1f30c52a9360James Dong    }
129653252be963c07c99109d20f942d1f30c52a9360James Dong
130653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) {
131653252be963c07c99109d20f942d1f30c52a9360James Dong       return OMX_COLOR_Format16bitRGB565;
132653252be963c07c99109d20f942d1f30c52a9360James Dong    }
133653252be963c07c99109d20f942d1f30c52a9360James Dong
1341374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket    if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) {
1351374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket       return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
1361374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket    }
1371374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket
138bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) {
139bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala        return OMX_COLOR_FormatAndroidOpaque;
140bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala    }
141bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala
14229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("Uknown color format (%s), please add it to "
143a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong         "CameraSource::getColorFormat", colorFormat);
144a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong
145f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(!"Unknown color format");
146dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn    return -1;
147653252be963c07c99109d20f942d1f30c52a9360James Dong}
148653252be963c07c99109d20f942d1f30c52a9360James Dong
149ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) {
15054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size size;
15154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    size.width = -1;
15254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    size.height = -1;
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
154d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICamera> camera;
15598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    return new CameraSource(camera, NULL, 0, clientName, Camera::USE_CALLING_UID,
15698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            Camera::USE_CALLING_PID, size, -1, NULL, false);
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15930ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static
16054ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera(
161d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    const sp<hardware::ICamera>& camera,
1624ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    const sp<ICameraRecordingProxy>& proxy,
16354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t cameraId,
164ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    const String16& clientName,
165ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    uid_t clientUid,
16698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    pid_t clientPid,
16754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size videoSize,
16854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRate,
16999617adda9bc46c43f511f0940bc735c73de61deMathias Agopian    const sp<IGraphicBufferProducer>& surface,
1705c9523154d106b555db6c41f85ab205a4f189b02James Dong    bool storeMetaDataInVideoBuffers) {
17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
1724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    CameraSource *source = new CameraSource(camera, proxy, cameraId,
17398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            clientName, clientUid, clientPid, videoSize, frameRate, surface,
174ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            storeMetaDataInVideoBuffers);
17554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return source;
17630ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
17730ab66297501757d745b9ae10da61adcd891f497Andreas Huber
17854ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource(
179d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    const sp<hardware::ICamera>& camera,
1804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    const sp<ICameraRecordingProxy>& proxy,
18154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t cameraId,
182ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    const String16& clientName,
183ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    uid_t clientUid,
18498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    pid_t clientPid,
18554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size videoSize,
18654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRate,
18799617adda9bc46c43f511f0940bc735c73de61deMathias Agopian    const sp<IGraphicBufferProducer>& surface,
1885c9523154d106b555db6c41f85ab205a4f189b02James Dong    bool storeMetaDataInVideoBuffers)
18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    : mCameraFlags(0),
190983cf231ab2d176a14595cdae46ff1b0c239af47James Dong      mNumInputBuffers(0),
19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mVideoFrameRate(-1),
19254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mCamera(0),
19354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mSurface(surface),
19413aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesReceived(0),
19565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mLastFrameTimestampUs(0),
19665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mStarted(false),
19713aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesEncoded(0),
198e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong      mTimeBetweenFrameCaptureUs(0),
1997757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong      mFirstFrameTimeUs(0),
20013aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesDropped(0),
201f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong      mNumGlitches(0),
202f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong      mGlitchDurationThresholdUs(200000),
20365e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mCollectStats(false) {
20454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.width  = -1;
20554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.height = -1;
20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
2074ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mInitCheck = init(camera, proxy, cameraId,
20898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen                    clientName, clientUid, clientPid,
2095c9523154d106b555db6c41f85ab205a4f189b02James Dong                    videoSize, frameRate,
2105c9523154d106b555db6c41f85ab205a4f189b02James Dong                    storeMetaDataInVideoBuffers);
21195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li    if (mInitCheck != OK) releaseCamera();
21254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
21354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
21454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const {
21554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return mInitCheck;
21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
21754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
21854ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable(
219d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
22098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    int32_t cameraId, const String16& clientName, uid_t clientUid, pid_t clientPid) {
22154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
22254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (camera == 0) {
22398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        mCamera = Camera::connect(cameraId, clientName, clientUid, clientPid);
2244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        if (mCamera == 0) return -EBUSY;
22554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCameraFlags &= ~FLAGS_HOT_CAMERA;
22654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {
2274ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // We get the proxy from Camera, not ICamera. We need to get the proxy
2284ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // to the remote Camera owned by the application. Here mCamera is a
2294ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // local Camera object created by us. We cannot use the proxy from
2304ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // mCamera here.
23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCamera = Camera::create(camera);
2324ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        if (mCamera == 0) return -EBUSY;
2334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        mCameraRecordingProxy = proxy;
23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCameraFlags |= FLAGS_HOT_CAMERA;
2353bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mDeathNotifier = new DeathNotifier();
2363bd3020c00ec8264ac1fe3870800f326487f9221James Dong        // isBinderAlive needs linkToDeath to work.
23706b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier);
23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
2404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mCamera->lock();
2414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
24354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one
24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes.
24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels
25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels
25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against
25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported.
25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported(
25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t width, int32_t height,
25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const Vector<Size>& supportedSizes) {
25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
2583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isVideoSizeSupported");
25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    for (size_t i = 0; i < supportedSizes.size(); ++i) {
26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (width  == supportedSizes[i].width &&
26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            height == supportedSizes[i].height) {
26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return true;
26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return false;
26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the
27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size
27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not
27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview
27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same
27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size.
27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes
27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize()
28054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not.
28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method
28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      CameraParameters::setVideoSize() is supported or not.
28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the
28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      supported video frame sizes advertised by the camera.
28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes(
28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const CameraParameters& params,
28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool *isSetVideoSizeSupported,
29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Vector<Size>& sizes) {
29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    *isSetVideoSizeSupported = true;
29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    params.getSupportedVideoSizes(sizes);
29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (sizes.size() == 0) {
295b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("Camera does not support setVideoSize()");
29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        params.getSupportedPreviewSizes(sizes);
29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        *isSetVideoSizeSupported = false;
29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format
30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported(
30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params) {
30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mColorFormat = getColorFormat(params.get(
30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            CameraParameters::KEY_VIDEO_FRAME_FORMAT));
31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (mColorFormat == -1) {
31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return BAD_VALUE;
31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size
31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and
31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped.
32054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate
32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to
32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to
32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method).
32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
32554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured
32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels
32754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels
32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second.
32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera(
33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        CameraParameters* params,
33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t width, int32_t height,
33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t frameRate) {
3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("configureCamera");
33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Vector<Size> sizes;
33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool isSetVideoSizeSupportedByCamera = true;
33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool isCameraParamChanged = false;
34054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (width != -1 && height != -1) {
34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (!isVideoSizeSupported(width, height, sizes)) {
34229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Video dimension (%dx%d) is unsupported", width, height);
34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return BAD_VALUE;
34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (isSetVideoSizeSupportedByCamera) {
34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            params->setVideoSize(width, height);
34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        } else {
34854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            params->setPreviewSize(width, height);
34954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
35054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        isCameraParamChanged = true;
35154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else if ((width == -1 && height != -1) ||
35254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong               (width != -1 && height == -1)) {
35354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // If one and only one of the width and height is -1
35454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // we reject such a request.
35529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Requested video size (%dx%d) is not supported", width, height);
35654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return BAD_VALUE;
35754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {  // width == -1 && height == -1
35854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Do not configure the camera.
35954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Use the current width and height value setting from the camera.
36054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
36154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRate != -1) {
363635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        CHECK(frameRate > 0 && frameRate <= 120);
364635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        const char* supportedFrameRates =
365635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong                params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
366635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        CHECK(supportedFrameRates != NULL);
3673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Supported frame rates: %s", supportedFrameRates);
368635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        char buf[4];
369635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        snprintf(buf, 4, "%d", frameRate);
370635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        if (strstr(supportedFrameRates, buf) == NULL) {
37129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Requested frame rate (%d) is not supported: %s",
372635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong                frameRate, supportedFrameRates);
373635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong            return BAD_VALUE;
374635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        }
375635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong
376635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        // The frame rate is supported, set the camera to the requested value.
37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        params->setPreviewFrameRate(frameRate);
37854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        isCameraParamChanged = true;
37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {  // frameRate == -1
38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Do not configure the camera.
38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Use the current frame rate value setting from the camera
38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (isCameraParamChanged) {
38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Either frame rate or frame size needs to be changed.
38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        String8 s = params->flatten();
38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (OK != mCamera->setParameters(s)) {
38829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Could not change settings."
38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                 " Someone else is using camera %p?", mCamera.get());
39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return -EBUSY;
39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
39654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
39754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size
39854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height
39954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting
40054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed.
40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
40354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against
40454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against
40554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error
40654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
40754ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize(
40854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params,
40954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t width, int32_t height) {
41054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("checkVideoSize");
412f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // The actual video size is the same as the preview size
413f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // if the camera hal does not support separate video and
414f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // preview output. In this case, we retrieve the video
415f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // size from preview.
41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameWidthActual = -1;
41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameHeightActual = -1;
418f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    Vector<Size> sizes;
419f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    params.getSupportedVideoSizes(sizes);
420f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    if (sizes.size() == 0) {
421f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        // video size is the same as preview size
422f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        params.getPreviewSize(&frameWidthActual, &frameHeightActual);
423f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    } else {
424f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        // video size may not be the same as preview
425f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        params.getVideoSize(&frameWidthActual, &frameHeightActual);
426f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    }
42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameWidthActual < 0 || frameHeightActual < 0) {
42829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to retrieve video frame size (%dx%d)",
42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                frameWidthActual, frameHeightActual);
43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check the actual video frame size against the target/requested
43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // video frame size.
43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (width != -1 && height != -1) {
43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (frameWidthActual != width || frameHeightActual != height) {
43729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to set video frame size to %dx%d. "
43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    "The actual video size is %dx%d ", width, height,
43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    frameWidthActual, frameHeightActual);
44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return UNKNOWN_ERROR;
44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Good now.
44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.width = frameWidthActual;
44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.height = frameHeightActual;
44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
44854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
45154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not.
45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value
45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed.
45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against
45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
45854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate(
46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params,
46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t frameRate) {
46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("checkFrameRate");
46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRateActual = params.getPreviewFrameRate();
46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRateActual < 0) {
46629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check the actual video frame rate against the target/requested
47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // video frame rate.
47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRate != -1 && (frameRateActual - frameRate) != 0) {
47329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to set preview frame rate to %d fps. The actual "
47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                "frame rate is %d", frameRate, frameRateActual);
47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Good now.
47954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoFrameRate = frameRateActual;
48054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
48154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
48254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
48354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes
48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested.
48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source
48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id
48854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      as the video source
48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both
49054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      width and height in videoSize is -1, use the current
49154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      width and heigth settings by the camera
49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second.
49354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      if it is -1, use the current camera frame rate setting.
4945c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta
4955c9523154d106b555db6c41f85ab205a4f189b02James Dong *      data or real YUV data in video buffers. Request to
4965c9523154d106b555db6c41f85ab205a4f189b02James Dong *      store meta data in video buffers may not be honored
4975c9523154d106b555db6c41f85ab205a4f189b02James Dong *      if the source does not support this feature.
4985c9523154d106b555db6c41f85ab205a4f189b02James Dong *
49954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
50054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
50154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init(
502d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::ICamera>& camera,
5034ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        const sp<ICameraRecordingProxy>& proxy,
50454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t cameraId,
505ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
506ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
50798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        pid_t clientPid,
50854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
5095c9523154d106b555db6c41f85ab205a4f189b02James Dong        int32_t frameRate,
5105c9523154d106b555db6c41f85ab205a4f189b02James Dong        bool storeMetaDataInVideoBuffers) {
51154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
5123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init");
51354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    status_t err = OK;
514ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    int64_t token = IPCThreadState::self()->clearCallingIdentity();
51598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid, clientPid,
516ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong                               videoSize, frameRate,
517ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong                               storeMetaDataInVideoBuffers);
518ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    IPCThreadState::self()->restoreCallingIdentity(token);
519ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    return err;
520ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong}
521ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong
5222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::createVideoBufferMemoryHeap(size_t size, uint32_t bufferCount) {
5232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mMemoryHeapBase = new MemoryHeapBase(size * bufferCount, 0,
5242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            "StageFright-CameraSource-BufferHeap");
5252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    for (uint32_t i = 0; i < bufferCount; i++) {
5262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        mMemoryBases.push_back(new MemoryBase(mMemoryHeapBase, i * size, size));
5272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
5282d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen}
5292d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
5308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenstatus_t CameraSource::initBufferQueue(uint32_t width, uint32_t height,
5318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        uint32_t format, android_dataspace dataSpace, uint32_t bufferCount) {
5328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ALOGV("initBufferQueue");
5338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (mVideoBufferConsumer != nullptr || mVideoBufferProducer != nullptr) {
5358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Buffer queue already exists", __FUNCTION__);
5368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return ALREADY_EXISTS;
5378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // Create a buffer queue.
5408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    sp<IGraphicBufferProducer> producer;
5418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    sp<IGraphicBufferConsumer> consumer;
5428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    BufferQueue::createBufferQueue(&producer, &consumer);
5438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN;
5458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
5468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        usage = GRALLOC_USAGE_HW_VIDEO_ENCODER;
5478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    bufferCount += kConsumerBufferCount;
5508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mVideoBufferConsumer = new BufferItemConsumer(consumer, usage, bufferCount);
5528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mVideoBufferConsumer->setName(String8::format("StageFright-CameraSource"));
5538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mVideoBufferProducer = producer;
5548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    status_t res = mVideoBufferConsumer->setDefaultBufferSize(width, height);
5568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (res != OK) {
5578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Could not set buffer dimensions %dx%d: %s (%d)", __FUNCTION__, width, height,
5588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                strerror(-res), res);
5598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return res;
5608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    res = mVideoBufferConsumer->setDefaultBufferFormat(format);
5638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (res != OK) {
5648cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Could not set buffer format %d: %s (%d)", __FUNCTION__, format,
5658cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                strerror(-res), res);
5668cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return res;
5678cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5688cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    res = mVideoBufferConsumer->setDefaultBufferDataSpace(dataSpace);
5708cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (res != OK) {
5718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Could not set data space %d: %s (%d)", __FUNCTION__, dataSpace,
5728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                strerror(-res), res);
5738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return res;
5748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    res = mCamera->setVideoTarget(mVideoBufferProducer);
5778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (res != OK) {
5788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Failed to set video target: %s (%d)", __FUNCTION__, strerror(-res), res);
5798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return res;
5808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // Create memory heap to store buffers as VideoNativeMetadata.
5832d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    createVideoBufferMemoryHeap(sizeof(VideoNativeMetadata), bufferCount);
5848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mBufferQueueListener = new BufferQueueListener(mVideoBufferConsumer, this);
5868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    res = mBufferQueueListener->run("CameraSource-BufferQueueListener");
5878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (res != OK) {
5888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ALOGE("%s: Could not run buffer queue listener thread: %s (%d)", __FUNCTION__,
5898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                strerror(-res), res);
5908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return res;
5918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
5928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
5938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    return OK;
5948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
5958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
596ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess(
597d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        const sp<hardware::ICamera>& camera,
598ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        const sp<ICameraRecordingProxy>& proxy,
599ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int32_t cameraId,
600ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
601ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
60298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        pid_t clientPid,
603ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        Size videoSize,
604ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int32_t frameRate,
605ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        bool storeMetaDataInVideoBuffers) {
6063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("initWithCameraAccess");
607ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    status_t err = OK;
6089d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong
609ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if ((err = isCameraAvailable(camera, proxy, cameraId,
61098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen            clientName, clientUid, clientPid)) != OK) {
61129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera connection could not be established.");
61254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
61354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
61454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraParameters params(mCamera->getParameters());
61554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = isCameraColorFormatSupported(params)) != OK) {
61654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
61754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
618be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
61954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Set the camera to use the requested video frame size
62054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // and/or frame rate.
62154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = configureCamera(&params,
62254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    videoSize.width, videoSize.height,
62354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    frameRate))) {
62454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
62554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
626653252be963c07c99109d20f942d1f30c52a9360James Dong
62754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check on video frame size and frame rate.
62854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraParameters newCameraParams(mCamera->getParameters());
62954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = checkVideoSize(newCameraParams,
63054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                videoSize.width, videoSize.height)) != OK) {
63154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
63254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
63354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) {
63454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
63554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
63654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
6378e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    // Set the preview display. Skip this if mSurface is null because
6388e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    // applications may already set a surface to the camera.
6398e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    if (mSurface != NULL) {
6408e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li        // This CHECK is good, since we just passed the lock/unlock
6418e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li        // check earlier by calling mCamera->setParameters().
6424b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala        CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface));
6438e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    }
6442b37ced30f89437c804c3945b901019b86d210aeJames Dong
6458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // By default, store real data in video buffers.
646d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV;
647abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong    if (storeMetaDataInVideoBuffers) {
648d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (OK == mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE)) {
649d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE;
6508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        } else if (OK == mCamera->setVideoBufferMode(
651d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA)) {
652d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            mVideoBufferMode = hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA;
6538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
6548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
6558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
656d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV) {
657d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        err = mCamera->setVideoBufferMode(hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV);
6588cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        if (err != OK) {
6598cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            ALOGE("%s: Setting video buffer mode to VIDEO_BUFFER_MODE_DATA_CALLBACK_YUV failed: "
6608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                    "%s (err=%d)", __FUNCTION__, strerror(-err), err);
6618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            return err;
662abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong        }
6635c9523154d106b555db6c41f85ab205a4f189b02James Dong    }
6645c9523154d106b555db6c41f85ab205a4f189b02James Dong
66554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
666f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    if (glitchDurationUs > mGlitchDurationThresholdUs) {
667f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        mGlitchDurationThresholdUs = glitchDurationUs;
668f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    }
669f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
670ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    // XXX: query camera for the stride and slice height
671ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    // when the capability becomes available.
672653252be963c07c99109d20f942d1f30c52a9360James Dong    mMeta = new MetaData;
67354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setCString(kKeyMIMEType,  MEDIA_MIMETYPE_VIDEO_RAW);
67454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyColorFormat, mColorFormat);
67554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyWidth,       mVideoSize.width);
67654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyHeight,      mVideoSize.height);
67754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyStride,      mVideoSize.width);
67854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
679393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong    mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
68054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
68320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() {
68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
685b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        reset();
686ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    } else if (mInitCheck == OK) {
687ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // Camera is initialized but because start() is never called,
688ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // the lock on Camera is never released(). This makes sure
689ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // Camera's lock is released in this case.
690ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        releaseCamera();
69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
69426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() {
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("startCameraRecording");
6964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // Reset the identity to the current thread because media server owns the
6974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // camera and recording is started by the applications. The applications
6984ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // will connect to the camera in ICameraRecordingProxy::startRecording.
6994ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    int64_t token = IPCThreadState::self()->clearCallingIdentity();
70026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    status_t err;
7018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
702d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) {
7038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        // Initialize buffer queue.
7048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        err = initBufferQueue(mVideoSize.width, mVideoSize.height, mEncoderFormat,
7058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                (android_dataspace_t)mEncoderDataSpace,
7068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                mNumInputBuffers > 0 ? mNumInputBuffers : 1);
7078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        if (err != OK) {
7088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            ALOGE("%s: Failed to initialize buffer queue: %s (err=%d)", __FUNCTION__,
7098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                    strerror(-err), err);
7108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            return err;
7118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
7128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    } else {
7138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        if (mNumInputBuffers > 0) {
7148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            err = mCamera->sendCommand(
7158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);
7168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
7178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            // This could happen for CameraHAL1 clients; thus the failure is
7188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            // not a fatal error
7198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            if (err != OK) {
7208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                ALOGW("Failed to set video buffer count to %d due to %d",
7218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                    mNumInputBuffers, err);
7228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            }
7238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
7248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
72526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        err = mCamera->sendCommand(
7268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace);
727983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
728983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        // This could happen for CameraHAL1 clients; thus the failure is
729983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        // not a fatal error
730983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (err != OK) {
7318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d",
7328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                    mEncoderFormat, mEncoderDataSpace, err);
733983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
7342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
7352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        // Create memory heap to store buffers as VideoNativeMetadata.
7362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        createVideoBufferMemoryHeap(sizeof(VideoNativeHandleMetadata), kDefaultVideoBufferCount);
737983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    }
738983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
73926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    err = OK;
7403bd3020c00ec8264ac1fe3870800f326487f9221James Dong    if (mCameraFlags & FLAGS_HOT_CAMERA) {
7413bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->unlock();
7423bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera.clear();
74326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        if ((err = mCameraRecordingProxy->startRecording(
74426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk                new ProxyListener(this))) != OK) {
74526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            ALOGE("Failed to start recording, received error: %s (%d)",
74626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk                    strerror(-err), err);
74726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        }
7483bd3020c00ec8264ac1fe3870800f326487f9221James Dong    } else {
7493bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->setListener(new CameraSourceListener(this));
7503bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->startRecording();
75126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        if (!mCamera->recordingEnabled()) {
75226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            err = -EINVAL;
75326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            ALOGE("Failed to start recording");
75426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        }
7553bd3020c00ec8264ac1fe3870800f326487f9221James Dong    }
7564ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    IPCThreadState::self()->restoreCallingIdentity(token);
75726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    return err;
75865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
75965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
760f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) {
7613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
7620c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(!mStarted);
76354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (mInitCheck != OK) {
76429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraSource is not initialized yet");
76554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return mInitCheck;
76654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
768365a963142093a1cd8efdcea76b5f65096a5b115James Dong    char value[PROPERTY_VALUE_MAX];
769365a963142093a1cd8efdcea76b5f65096a5b115James Dong    if (property_get("media.stagefright.record-stats", value, NULL)
770365a963142093a1cd8efdcea76b5f65096a5b115James Dong        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
771365a963142093a1cd8efdcea76b5f65096a5b115James Dong        mCollectStats = true;
772365a963142093a1cd8efdcea76b5f65096a5b115James Dong    }
7739d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong
774f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mStartTimeUs = 0;
775983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    mNumInputBuffers = 0;
776d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
7772cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvala    mEncoderDataSpace = HAL_DATASPACE_V0_BT709;
778d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
779983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    if (meta) {
780983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        int64_t startTimeUs;
781983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (meta->findInt64(kKeyTime, &startTimeUs)) {
782983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            mStartTimeUs = startTimeUs;
783983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
784983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
785983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        int32_t nBuffers;
786983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
787983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            CHECK_GT(nBuffers, 0);
788983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            mNumInputBuffers = nBuffers;
789983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
790d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
791c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        // apply encoder color format if specified
792c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) {
793b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGI("Using encoder format: %#x", mEncoderFormat);
794c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
795c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) {
796b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGI("Using encoder data space: %#x", mEncoderDataSpace);
797c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
798f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    }
799f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
80026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    status_t err;
80126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    if ((err = startCameraRecording()) == OK) {
80226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        mStarted = true;
80326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    }
80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    return err;
80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
80865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() {
8093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stopCameraRecording");
8103bd3020c00ec8264ac1fe3870800f326487f9221James Dong    if (mCameraFlags & FLAGS_HOT_CAMERA) {
8112da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim        if (mCameraRecordingProxy != 0) {
8122da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim            mCameraRecordingProxy->stopRecording();
8132da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim        }
8143bd3020c00ec8264ac1fe3870800f326487f9221James Dong    } else {
8152da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim        if (mCamera != 0) {
8162da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim            mCamera->setListener(NULL);
8172da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim            mCamera->stopRecording();
8182da037b416ad30b7d9a7447d17435026ddc77727Wonsik Kim        }
8193bd3020c00ec8264ac1fe3870800f326487f9221James Dong    }
82065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
82165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
822ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() {
8233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releaseCamera");
824121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    sp<Camera> camera;
825121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    bool coldCamera = false;
826121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
827121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
828121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        // get a local ref and clear ref to mCamera now
829121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        camera = mCamera;
830121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mCamera.clear();
831121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0;
832121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    }
833121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
834121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    if (camera != 0) {
835ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int64_t token = IPCThreadState::self()->clearCallingIdentity();
836121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (coldCamera) {
8373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Camera was cold when we started, stopping preview");
838121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            camera->stopPreview();
839121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            camera->disconnect();
84095068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li        }
841121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        camera->unlock();
842ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        IPCThreadState::self()->restoreCallingIdentity(token);
84395068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li    }
844121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
845121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
846121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
847121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCameraRecordingProxy != 0) {
84806b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen            IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier);
849121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            mCameraRecordingProxy.clear();
850121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
851121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mCameraFlags = 0;
852ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    }
853ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong}
854ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong
855b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() {
856b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    ALOGD("reset: E");
857121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
858121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
859121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
860121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mStarted = false;
861121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mFrameAvailableCondition.signal();
862121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
863121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        int64_t token;
864121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        bool isTokenValid = false;
865121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCamera != 0) {
866121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            token = IPCThreadState::self()->clearCallingIdentity();
867121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            isTokenValid = true;
868121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
869121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        releaseQueuedFrames();
870121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        while (!mFramesBeingEncoded.empty()) {
871121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            if (NO_ERROR !=
872121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                mFrameCompleteCondition.waitRelative(mLock,
873121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                        mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
874121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                ALOGW("Timed out waiting for outstanding frames being encoded: %zu",
875121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mFramesBeingEncoded.size());
876121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            }
877121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
878121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        stopCameraRecording();
879121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (isTokenValid) {
880121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            IPCThreadState::self()->restoreCallingIdentity(token);
88141152efd144ccf70c380d5c9a32105c02a039f43James Dong        }
8827278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong
883121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCollectStats) {
884121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us",
885121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
886121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mLastFrameTimestampUs - mFirstFrameTimeUs);
887121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
888121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
889121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mNumGlitches > 0) {
890121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            ALOGW("%d long delays between neighboring video frames", mNumGlitches);
891121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
89213aec890216948b0c364f8f92792129d0335f506James Dong
893121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
894ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    }
895ba29002c7aee13c068049037cd14bba6a244da6bJames Dong
8968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (mBufferQueueListener != nullptr) {
8978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mBufferQueueListener->requestExit();
8988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mBufferQueueListener->join();
8998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mBufferQueueListener.clear();
9008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
9018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
9028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mVideoBufferConsumer.clear();
9038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mVideoBufferProducer.clear();
904121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    releaseCamera();
905121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
906b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    ALOGD("reset: X");
90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
91065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
9113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releaseRecordingFrame");
9128cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
913d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE) {
9148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        // Return the buffer to buffer queue in VIDEO_BUFFER_MODE_BUFFER_QUEUE mode.
9158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ssize_t offset;
9168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        size_t size;
9178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        sp<IMemoryHeap> heap = frame->getMemory(&offset, &size);
9188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) {
9198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)", __FUNCTION__,
9208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                    heap->getHeapID(), mMemoryHeapBase->getHeapID());
9218cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            return;
9228cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
9238cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
9248cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
9258cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                (uint8_t*)heap->getBase() + offset);
9268cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
9278cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        // Find the corresponding buffer item for the native window buffer.
9288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        ssize_t index = mReceivedBufferItemMap.indexOfKey(payload->pBuffer);
9298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        if (index == NAME_NOT_FOUND) {
9308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            ALOGE("%s: Couldn't find buffer item for %p", __FUNCTION__, payload->pBuffer);
9318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            return;
9328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
9338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
9348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        BufferItem buffer = mReceivedBufferItemMap.valueAt(index);
9358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mReceivedBufferItemMap.removeItemsAt(index);
9368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mVideoBufferConsumer->releaseBuffer(buffer);
9378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mMemoryBases.push_back(frame);
9380419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen        mMemoryBaseAvailableCond.signal();
9392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    } else {
9402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_t* handle = nullptr;
9412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
9422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        // Check if frame contains a VideoNativeHandleMetadata.
9432d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        if (frame->size() == sizeof(VideoNativeHandleMetadata)) {
9442d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            VideoNativeHandleMetadata *metadata =
9452d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                (VideoNativeHandleMetadata*)(frame->pointer());
9462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            if (metadata->eType == kMetadataBufferTypeNativeHandleSource) {
9472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                handle = metadata->pHandle;
9482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            }
9492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        }
9502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
9512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        if (handle != nullptr) {
9522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // Frame contains a VideoNativeHandleMetadata. Send the handle back to camera.
953d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick            ssize_t offset;
954d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick            size_t size;
955d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick            sp<IMemoryHeap> heap = frame->getMemory(&offset, &size);
956d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick            if (heap->getHeapID() != mMemoryHeapBase->getHeapID()) {
957d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick                ALOGE("%s: Mismatched heap ID, ignoring release (got %x, expected %x)",
958d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick		     __FUNCTION__, heap->getHeapID(), mMemoryHeapBase->getHeapID());
959d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick                return;
960d1ccf2f058f34766a9cfcd94ca947b4d77959c7dRay Essick            }
9612d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            releaseRecordingFrameHandle(handle);
9622d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            mMemoryBases.push_back(frame);
9632d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            mMemoryBaseAvailableCond.signal();
9642d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        } else if (mCameraRecordingProxy != nullptr) {
9652d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // mCamera is created by application. Return the frame back to camera via camera
9662d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // recording proxy.
9672d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            mCameraRecordingProxy->releaseRecordingFrame(frame);
9682d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        } else if (mCamera != nullptr) {
9692d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            // mCamera is created by CameraSource. Return the frame directly back to camera.
9702d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            int64_t token = IPCThreadState::self()->clearCallingIdentity();
9712d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            mCamera->releaseRecordingFrame(frame);
9722d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            IPCThreadState::self()->restoreCallingIdentity(token);
9732d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        }
974d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong    }
97565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
97665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
977c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() {
978c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    List<sp<IMemory> >::iterator it;
9797278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    while (!mFramesReceived.empty()) {
9807278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        it = mFramesReceived.begin();
98165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        releaseRecordingFrame(*it);
9827278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        mFramesReceived.erase(it);
98313aec890216948b0c364f8f92792129d0335f506James Dong        ++mNumFramesDropped;
984c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
985c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong}
986c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong
98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() {
988653252be963c07c99109d20f942d1f30c52a9360James Dong    return mMeta;
98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
991f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) {
99265e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    releaseRecordingFrame(frame);
993f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong}
994f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
9957278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) {
9963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned: %p", buffer->data());
99756223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber    Mutex::Autolock autoLock(mLock);
9987278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
9997278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong         it != mFramesBeingEncoded.end(); ++it) {
10007278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        if ((*it)->pointer() ==  buffer->data()) {
1001f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            releaseOneRecordingFrame((*it));
10027278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            mFramesBeingEncoded.erase(it);
10037278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            ++mNumFramesEncoded;
10047278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            buffer->setObserver(0);
10057278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            buffer->release();
10067278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            mFrameCompleteCondition.signal();
10077278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            return;
10087278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        }
10097278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    }
1010f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(!"signalBufferReturned: bogus buffer");
10117278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong}
10127278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong
101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read(
101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
10153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("read");
101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *buffer = NULL;
101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
1020abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
1021abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
102220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_UNSUPPORTED;
102320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<IMemory> frame;
1026be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    int64_t frameTime;
102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
102820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    {
102920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        Mutex::Autolock autoLock(mLock);
103079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        while (mStarted && mFramesReceived.empty()) {
103141152efd144ccf70c380d5c9a32105c02a039f43James Dong            if (NO_ERROR !=
1032e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                mFrameAvailableCondition.waitRelative(mLock,
1033e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                    mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
10343bd3020c00ec8264ac1fe3870800f326487f9221James Dong                if (mCameraRecordingProxy != 0 &&
103506b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen                    !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) {
10365ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("camera recording proxy is gone");
10374ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                    return ERROR_END_OF_STREAM;
10384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                }
1039a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us",
104041152efd144ccf70c380d5c9a32105c02a039f43James Dong                    mLastFrameTimestampUs);
104141152efd144ccf70c380d5c9a32105c02a039f43James Dong            }
104220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
104379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        if (!mStarted) {
104479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong            return OK;
104579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        }
104679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        frame = *mFramesReceived.begin();
104779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFramesReceived.erase(mFramesReceived.begin());
104879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong
104979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        frameTime = *mFrameTimes.begin();
105079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFrameTimes.erase(mFrameTimes.begin());
105179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFramesBeingEncoded.push_back(frame);
105279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        *buffer = new MediaBuffer(frame->pointer(), frame->size());
105379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->setObserver(this);
105479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->add_ref();
105579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
10567278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    }
105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::shouldSkipFrameLocked(int64_t timestampUs) {
1061a472613aec322e25891abf5c77bf3f7e3c244920James Dong    if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
1062ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs);
10638cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return true;
1064c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
106665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    // May need to skip frame or modify timestamp. Currently implemented
106765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    // by the subclass CameraSourceTimeLapse.
106879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong    if (skipCurrentFrame(timestampUs)) {
10698cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return true;
1070fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra    }
1071fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra
10720aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang    if (mNumFramesReceived > 0) {
10730aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        if (timestampUs <= mLastFrameTimestampUs) {
10740aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            ALOGW("Dropping frame with backward timestamp %lld (last %lld)",
10750aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang                    (long long)timestampUs, (long long)mLastFrameTimestampUs);
10768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            return true;
10770aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        }
10780aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
10790aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            ++mNumGlitches;
10800aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        }
10810aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang    }
10820aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang
1083365a963142093a1cd8efdcea76b5f65096a5b115James Dong    mLastFrameTimestampUs = timestampUs;
108413aec890216948b0c364f8f92792129d0335f506James Dong    if (mNumFramesReceived == 0) {
1085c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong        mFirstFrameTimeUs = timestampUs;
1086f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        // Initial delay
1087f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        if (mStartTimeUs > 0) {
1088f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            if (timestampUs < mStartTimeUs) {
1089f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                // Frame was captured before recording was started
1090f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                // Drop it without updating the statistical data.
10918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                return true;
1092f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            }
1093f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            mStartTimeUs = timestampUs - mStartTimeUs;
1094f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        }
1095be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    }
10968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
10978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    return false;
10988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
10998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs,
11018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        int32_t msgType __unused, const sp<IMemory> &data) {
11028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs);
11038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    Mutex::Autolock autoLock(mLock);
11048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (shouldSkipFrameLocked(timestampUs)) {
11068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        releaseOneRecordingFrame(data);
11078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return;
11088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
11098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
111013aec890216948b0c364f8f92792129d0335f506James Dong    ++mNumFramesReceived;
1111be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
111298cfde007490a5903b729a4718c0dada755ae8f8James Dong    CHECK(data != NULL && data->size() > 0);
11137278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    mFramesReceived.push_back(data);
1114f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
1115f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mFrameTimes.push_back(timeUs);
1116a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64,
1117f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        mStartTimeUs, timeUs);
111820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mFrameAvailableCondition.signal();
111920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11212d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::releaseRecordingFrameHandle(native_handle_t* handle) {
11222d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    if (mCameraRecordingProxy != nullptr) {
11232d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        mCameraRecordingProxy->releaseRecordingFrameHandle(handle);
11242d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    } else if (mCamera != nullptr) {
11252d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        int64_t token = IPCThreadState::self()->clearCallingIdentity();
11262d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        mCamera->releaseRecordingFrameHandle(handle);
11272d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        IPCThreadState::self()->restoreCallingIdentity(token);
1128cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen    } else {
1129cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen        native_handle_close(handle);
1130cb9e825306cd0a97e50a4ef9d7c58f4e961692d9Chien-Yu Chen        native_handle_delete(handle);
11312d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
11322d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen}
11332d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11342d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::recordingFrameHandleCallbackTimestamp(int64_t timestampUs,
11352d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                native_handle_t* handle) {
11362d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    ALOGV("%s: timestamp %lld us", __FUNCTION__, (long long)timestampUs);
11372d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    Mutex::Autolock autoLock(mLock);
11382d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    if (handle == nullptr) return;
11392d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11402d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    if (shouldSkipFrameLocked(timestampUs)) {
11412d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        releaseRecordingFrameHandle(handle);
11422d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        return;
11432d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
11442d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11452d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    while (mMemoryBases.empty()) {
11462d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) ==
11472d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen                TIMED_OUT) {
11482d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            ALOGW("Waiting on an available memory base timed out. Dropping a recording frame.");
11492d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            releaseRecordingFrameHandle(handle);
11502d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen            return;
11512d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        }
11522d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    }
11532d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11542d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    ++mNumFramesReceived;
11552d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11562d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    sp<IMemory> data = *mMemoryBases.begin();
11572d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mMemoryBases.erase(mMemoryBases.begin());
11582d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11592d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    // Wrap native handle in sp<IMemory> so it can be pushed to mFramesReceived.
11602d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    VideoNativeHandleMetadata *metadata = (VideoNativeHandleMetadata*)(data->pointer());
11612d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    metadata->eType = kMetadataBufferTypeNativeHandleSource;
11622d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    metadata->pHandle = handle;
11632d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11642d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mFramesReceived.push_back(data);
11652d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
11662d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mFrameTimes.push_back(timeUs);
11672d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64, mStartTimeUs, timeUs);
11682d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mFrameAvailableCondition.signal();
11692d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen}
11702d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
11718cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu ChenCameraSource::BufferQueueListener::BufferQueueListener(const sp<BufferItemConsumer>& consumer,
11728cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        const sp<CameraSource>& cameraSource) {
11738cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mConsumer = consumer;
11748cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mConsumer->setFrameAvailableListener(this);
11758cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mCameraSource = cameraSource;
11768cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
11778cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11788cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenvoid CameraSource::BufferQueueListener::onFrameAvailable(const BufferItem& /*item*/) {
11798cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ALOGV("%s: onFrameAvailable", __FUNCTION__);
11808cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11818cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    Mutex::Autolock l(mLock);
11828cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11838cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (!mFrameAvailable) {
11848cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mFrameAvailable = true;
11858cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mFrameAvailableSignal.signal();
11868cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
11878cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
11888cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11898cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chenbool CameraSource::BufferQueueListener::threadLoop() {
11908cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (mConsumer == nullptr || mCameraSource == nullptr) {
11918cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return false;
11928cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
11938cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
11948cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    {
11958cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        Mutex::Autolock l(mLock);
11968cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        while (!mFrameAvailable) {
11978cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            if (mFrameAvailableSignal.waitRelative(mLock, kFrameAvailableTimeout) == TIMED_OUT) {
11988cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen                return true;
11998cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen            }
12008cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        }
12018cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mFrameAvailable = false;
12028cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
12038cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12048cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    BufferItem buffer;
12058cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    while (mConsumer->acquireBuffer(&buffer, 0) == OK) {
12068cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mCameraSource->processBufferQueueFrame(buffer);
12078cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
12088cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12098cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    return true;
12108cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
12118cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12128fc3c670fff26cb21d1e16dbfcbc4410d7758574Chien-Yu Chenvoid CameraSource::processBufferQueueFrame(BufferItem& buffer) {
12138cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    Mutex::Autolock autoLock(mLock);
12148cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12158cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    int64_t timestampUs = buffer.mTimestamp / 1000;
12168cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    if (shouldSkipFrameLocked(timestampUs)) {
12178cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mVideoBufferConsumer->releaseBuffer(buffer);
12188cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        return;
12198cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
12208cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12210419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen    while (mMemoryBases.empty()) {
12220419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen        if (mMemoryBaseAvailableCond.waitRelative(mLock, kMemoryBaseAvailableTimeoutNs) ==
12230419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen                TIMED_OUT) {
12240419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen            ALOGW("Waiting on an available memory base timed out. Dropping a recording frame.");
12250419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen            mVideoBufferConsumer->releaseBuffer(buffer);
12260419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen            return;
12270419ba7b1c1bd4f19b2fab06234eacb4547a7c04Chien-Yu Chen        }
12288cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    }
12298cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12308cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ++mNumFramesReceived;
12318cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12328cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // Find a available memory slot to store the buffer as VideoNativeMetadata.
12338cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    sp<IMemory> data = *mMemoryBases.begin();
12348cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mMemoryBases.erase(mMemoryBases.begin());
12358cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12368cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ssize_t offset;
12378cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    size_t size;
12388cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    sp<IMemoryHeap> heap = data->getMemory(&offset, &size);
12398cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    VideoNativeMetadata *payload = reinterpret_cast<VideoNativeMetadata*>(
12408cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        (uint8_t*)heap->getBase() + offset);
12418cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    memset(payload, 0, sizeof(VideoNativeMetadata));
12428cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    payload->eType = kMetadataBufferTypeANWBuffer;
12438cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    payload->pBuffer = buffer.mGraphicBuffer->getNativeBuffer();
12448cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    payload->nFenceFd = -1;
12458cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12468cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // Add the mapping so we can find the corresponding buffer item to release to the buffer queue
12478cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // when the encoder returns the native window buffer.
12488cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mReceivedBufferItemMap.add(payload->pBuffer, buffer);
12498cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12508cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mFramesReceived.push_back(data);
12518cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
12528cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mFrameTimes.push_back(timeUs);
12538cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64,
12548cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen        mStartTimeUs, timeUs);
12558cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    mFrameAvailableCondition.signal();
12568cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen}
12578cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12583e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos MolnarMetadataBufferType CameraSource::metaDataStoredInVideoBuffers() const {
12593e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar    ALOGV("metaDataStoredInVideoBuffers");
12608cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen
12618cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // Output buffers will contain metadata if camera sends us buffer in metadata mode or via
12628cca0750a84c2d97224c0cfef7cf255308ee80b3Chien-Yu Chen    // buffer queue.
12633e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar    switch (mVideoBufferMode) {
12643e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        case hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA:
12653e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            return kMetadataBufferTypeNativeHandleSource;
12663e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        case hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE:
12673e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            return kMetadataBufferTypeANWBuffer;
12683e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        default:
12693e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            return kMetadataBufferTypeInvalid;
12703e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar    }
12715c9523154d106b555db6c41f85ab205a4f189b02James Dong}
12725c9523154d106b555db6c41f85ab205a4f189b02James Dong
12734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
12744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mSource = source;
12754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
12764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
12774ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp(
12784ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
12794ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
12804ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
12814ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
12822d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chenvoid CameraSource::ProxyListener::recordingFrameHandleCallbackTimestamp(nsecs_t timestamp,
12832d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen        native_handle_t* handle) {
12842d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen    mSource->recordingFrameHandleCallbackTimestamp(timestamp / 1000, handle);
12852d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen}
12862d13b1d3eeaba31d8c15acc6037fd68b150a9a66Chien-Yu Chen
1287ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnarvoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
1288df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("Camera recording proxy died");
12894ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
12904ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
129120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
1292