CameraSource.cpp revision 0aaff700f6c7885887bbf42f7bb64754e21e5fce
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
18a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
19c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong//#define LOG_NDEBUG 0
20c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#define LOG_TAG "CameraSource"
21c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <utils/Log.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX_Component.h>
249d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong#include <binder/IPCThreadState.h>
25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h>
27be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
303cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h>
313cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h>
32df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
33be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h>
34365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h>
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#if LOG_NDEBUG
3784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x) (void)(x)
3884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#else
3984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#define UNUSED_UNLESS_VERBOSE(x)
4084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber#endif
4184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dongstatic const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
45e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong
46be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener {
47be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener(const sp<CameraSource> &source);
48be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
5057c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
5157c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li                          camera_frame_metadata_t *metadata);
52be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
53be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual void postDataTimestamp(
54be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber            nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected:
57be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    virtual ~CameraSourceListener();
58be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate:
60be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    wp<CameraSource> mSource;
61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener(const CameraSourceListener &);
63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    CameraSourceListener &operator=(const CameraSourceListener &);
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber};
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source)
67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    : mSource(source) {
68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
70be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() {
71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
73be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
7484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(msgType);
7584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(ext1);
7684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    UNUSED_UNLESS_VERBOSE(ext2);
773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
78be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8057c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
8184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                                    camera_frame_metadata_t * /* metadata */) {
82a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("postData(%d, ptr:%p, size:%zu)",
83be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber         msgType, dataPtr->pointer(), dataPtr->size());
8465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
8565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    sp<CameraSource> source = mSource.promote();
8665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    if (source.get() != NULL) {
8765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        source->dataCallback(msgType, dataPtr);
8865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    }
89be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
90be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
91be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp(
92be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber        nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
93c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong
94c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    sp<CameraSource> source = mSource.promote();
95c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    if (source.get() != NULL) {
96c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong        source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
97c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
98be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber}
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
100653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) {
101e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
102e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong       return OMX_COLOR_FormatYUV420Planar;
103e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong    }
104e2d8ba8c36fd39eb98f604b11654aa5466673260James Dong
105653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) {
106653252be963c07c99109d20f942d1f30c52a9360James Dong       return OMX_COLOR_FormatYUV422SemiPlanar;
107653252be963c07c99109d20f942d1f30c52a9360James Dong    }
108653252be963c07c99109d20f942d1f30c52a9360James Dong
109653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
110653252be963c07c99109d20f942d1f30c52a9360James Dong        return OMX_COLOR_FormatYUV420SemiPlanar;
111653252be963c07c99109d20f942d1f30c52a9360James Dong    }
112653252be963c07c99109d20f942d1f30c52a9360James Dong
113653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) {
114653252be963c07c99109d20f942d1f30c52a9360James Dong        return OMX_COLOR_FormatYCbYCr;
115653252be963c07c99109d20f942d1f30c52a9360James Dong    }
116653252be963c07c99109d20f942d1f30c52a9360James Dong
117653252be963c07c99109d20f942d1f30c52a9360James Dong    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) {
118653252be963c07c99109d20f942d1f30c52a9360James Dong       return OMX_COLOR_Format16bitRGB565;
119653252be963c07c99109d20f942d1f30c52a9360James Dong    }
120653252be963c07c99109d20f942d1f30c52a9360James Dong
1211374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket    if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) {
1221374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket       return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
1231374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket    }
1241374eddc4455b26d1dffdca10fc70534b3f08c1dDandawate Saket
125bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala    if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) {
126bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala        return OMX_COLOR_FormatAndroidOpaque;
127bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala    }
128bf5bea96f236adb5eef78c2f414ef82b3602a0f7Eino-Ville Talvala
12929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("Uknown color format (%s), please add it to "
130a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong         "CameraSource::getColorFormat", colorFormat);
131a1abc1a76741914c7bc43f1df9e32744f023ab75James Dong
132f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(!"Unknown color format");
133dba83c1cb1bef03bc5d1760c2639d06ff71c0fa7Mark Salyzyn    return -1;
134653252be963c07c99109d20f942d1f30c52a9360James Dong}
135653252be963c07c99109d20f942d1f30c52a9360James Dong
136ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraSource *CameraSource::Create(const String16 &clientName) {
13754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size size;
13854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    size.width = -1;
13954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    size.height = -1;
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    sp<ICamera> camera;
142ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return new CameraSource(camera, NULL, 0, clientName, -1,
143ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            size, -1, NULL, false);
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14630ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static
14754ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource *CameraSource::CreateFromCamera(
14854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const sp<ICamera>& camera,
1494ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    const sp<ICameraRecordingProxy>& proxy,
15054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t cameraId,
151ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    const String16& clientName,
152ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    uid_t clientUid,
15354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size videoSize,
15454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRate,
15599617adda9bc46c43f511f0940bc735c73de61deMathias Agopian    const sp<IGraphicBufferProducer>& surface,
1565c9523154d106b555db6c41f85ab205a4f189b02James Dong    bool storeMetaDataInVideoBuffers) {
15754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
1584ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    CameraSource *source = new CameraSource(camera, proxy, cameraId,
159ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            clientName, clientUid, videoSize, frameRate, surface,
160ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            storeMetaDataInVideoBuffers);
16154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return source;
16230ab66297501757d745b9ae10da61adcd891f497Andreas Huber}
16330ab66297501757d745b9ae10da61adcd891f497Andreas Huber
16454ff19ac69ace7c05ea90d225e26dab3b133f487James DongCameraSource::CameraSource(
16554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const sp<ICamera>& camera,
1664ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    const sp<ICameraRecordingProxy>& proxy,
16754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t cameraId,
168ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    const String16& clientName,
169ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    uid_t clientUid,
17054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Size videoSize,
17154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRate,
17299617adda9bc46c43f511f0940bc735c73de61deMathias Agopian    const sp<IGraphicBufferProducer>& surface,
1735c9523154d106b555db6c41f85ab205a4f189b02James Dong    bool storeMetaDataInVideoBuffers)
17454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    : mCameraFlags(0),
175983cf231ab2d176a14595cdae46ff1b0c239af47James Dong      mNumInputBuffers(0),
17654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mVideoFrameRate(-1),
17754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mCamera(0),
17854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong      mSurface(surface),
17913aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesReceived(0),
18065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mLastFrameTimestampUs(0),
18165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mStarted(false),
18213aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesEncoded(0),
183e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong      mTimeBetweenFrameCaptureUs(0),
1847757f5010a771fb8824b6fdf9788f588a1577e3fJames Dong      mFirstFrameTimeUs(0),
18513aec890216948b0c364f8f92792129d0335f506James Dong      mNumFramesDropped(0),
186f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong      mNumGlitches(0),
187f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong      mGlitchDurationThresholdUs(200000),
18865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra      mCollectStats(false) {
18954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.width  = -1;
19054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.height = -1;
19154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
1924ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mInitCheck = init(camera, proxy, cameraId,
193ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                    clientName, clientUid,
1945c9523154d106b555db6c41f85ab205a4f189b02James Dong                    videoSize, frameRate,
1955c9523154d106b555db6c41f85ab205a4f189b02James Dong                    storeMetaDataInVideoBuffers);
19695068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li    if (mInitCheck != OK) releaseCamera();
19754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
19854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
19954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::initCheck() const {
20054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return mInitCheck;
20154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
20254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
20354ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraAvailable(
2044ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
205ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t cameraId, const String16& clientName, uid_t clientUid) {
20654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
20754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (camera == 0) {
208ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mCamera = Camera::connect(cameraId, clientName, clientUid);
2094ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        if (mCamera == 0) return -EBUSY;
21054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCameraFlags &= ~FLAGS_HOT_CAMERA;
21154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {
2124ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // We get the proxy from Camera, not ICamera. We need to get the proxy
2134ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // to the remote Camera owned by the application. Here mCamera is a
2144ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // local Camera object created by us. We cannot use the proxy from
2154ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        // mCamera here.
21654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCamera = Camera::create(camera);
2174ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        if (mCamera == 0) return -EBUSY;
2184ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        mCameraRecordingProxy = proxy;
21954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        mCameraFlags |= FLAGS_HOT_CAMERA;
2203bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mDeathNotifier = new DeathNotifier();
2213bd3020c00ec8264ac1fe3870800f326487f9221James Dong        // isBinderAlive needs linkToDeath to work.
22206b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen        IInterface::asBinder(mCameraRecordingProxy)->linkToDeath(mDeathNotifier);
22354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
22454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
2254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mCamera->lock();
2264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
22754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
22854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
22954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
23054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
23154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
23254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check to see whether the requested video width and height is one
23354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * of the supported sizes.
23454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the video frame width in pixels
23554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the video frame height in pixels
23654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param suppportedSizes the vector of sizes that we check against
23754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return true if the dimension (width and height) is supported.
23854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
23954ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic bool isVideoSizeSupported(
24054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t width, int32_t height,
24154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const Vector<Size>& supportedSizes) {
24254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
2433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isVideoSizeSupported");
24454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    for (size_t i = 0; i < supportedSizes.size(); ++i) {
24554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (width  == supportedSizes[i].width &&
24654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            height == supportedSizes[i].height) {
24754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return true;
24854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
24954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
25054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return false;
25154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
25254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
25354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
25454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the preview and video output is separate, we only set the
25554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * the video size, and applications should set the preview size
25654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * to some proper value, and the recording framework will not
25754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * change the preview size; otherwise, if the video and preview
25854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * output is the same, we need to set the preview to be the same
25954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * as the requested video size.
26054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
26154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
26254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
26354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Query the camera to retrieve the supported video frame sizes
26454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * and also to see whether CameraParameters::setVideoSize()
26554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is supported or not.
26654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
26754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @@param isSetVideoSizeSupported retunrs whether method
26854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      CameraParameters::setVideoSize() is supported or not.
26954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param sizes returns the vector of Size objects for the
27054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      supported video frame sizes advertised by the camera.
27154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
27254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatic void getSupportedVideoSizes(
27354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    const CameraParameters& params,
27454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool *isSetVideoSizeSupported,
27554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Vector<Size>& sizes) {
27654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
27754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    *isSetVideoSizeSupported = true;
27854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    params.getSupportedVideoSizes(sizes);
27954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (sizes.size() == 0) {
280b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("Camera does not support setVideoSize()");
28154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        params.getSupportedPreviewSizes(sizes);
28254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        *isSetVideoSizeSupported = false;
28354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
28454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
28554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
28654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
28754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the camera has the supported color format
28854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
28954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
29054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
29154ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::isCameraColorFormatSupported(
29254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params) {
29354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mColorFormat = getColorFormat(params.get(
29454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            CameraParameters::KEY_VIDEO_FRAME_FORMAT));
29554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (mColorFormat == -1) {
29654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return BAD_VALUE;
29754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
29854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
29954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
30054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
30154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
30254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Configure the camera to use the requested video size
30354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * (width and height) and/or frame rate. If both width and
30454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * height are -1, configuration on the video size is skipped.
30554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * if frameRate is -1, configuration on the frame rate
30654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is skipped. Skipping the configuration allows one to
30754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * use the current camera setting without the need to
30854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * actually know the specific values (see Create() method).
30954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
31054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params the CameraParameters to be configured
31154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param width the target video frame width in pixels
31254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param height the target video frame height in pixels
31354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second.
31454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
31554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
31654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::configureCamera(
31754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        CameraParameters* params,
31854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t width, int32_t height,
31954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t frameRate) {
3203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("configureCamera");
32154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    Vector<Size> sizes;
32254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool isSetVideoSizeSupportedByCamera = true;
32354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
32454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    bool isCameraParamChanged = false;
32554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (width != -1 && height != -1) {
32654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (!isVideoSizeSupported(width, height, sizes)) {
32729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Video dimension (%dx%d) is unsupported", width, height);
32854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return BAD_VALUE;
32954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
33054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (isSetVideoSizeSupportedByCamera) {
33154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            params->setVideoSize(width, height);
33254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        } else {
33354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            params->setPreviewSize(width, height);
33454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
33554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        isCameraParamChanged = true;
33654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else if ((width == -1 && height != -1) ||
33754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong               (width != -1 && height == -1)) {
33854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // If one and only one of the width and height is -1
33954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // we reject such a request.
34029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Requested video size (%dx%d) is not supported", width, height);
34154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return BAD_VALUE;
34254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {  // width == -1 && height == -1
34354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Do not configure the camera.
34454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Use the current width and height value setting from the camera.
34554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
34654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
34754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRate != -1) {
348635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        CHECK(frameRate > 0 && frameRate <= 120);
349635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        const char* supportedFrameRates =
350635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong                params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
351635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        CHECK(supportedFrameRates != NULL);
3523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Supported frame rates: %s", supportedFrameRates);
353635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        char buf[4];
354635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        snprintf(buf, 4, "%d", frameRate);
355635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        if (strstr(supportedFrameRates, buf) == NULL) {
35629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Requested frame rate (%d) is not supported: %s",
357635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong                frameRate, supportedFrameRates);
358635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong            return BAD_VALUE;
359635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        }
360635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong
361635730831e08c32a5fe7c59125e0919b7e7899cdJames Dong        // The frame rate is supported, set the camera to the requested value.
36254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        params->setPreviewFrameRate(frameRate);
36354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        isCameraParamChanged = true;
36454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    } else {  // frameRate == -1
36554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Do not configure the camera.
36654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Use the current frame rate value setting from the camera
36754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
36854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
36954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (isCameraParamChanged) {
37054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        // Either frame rate or frame size needs to be changed.
37154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        String8 s = params->flatten();
37254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (OK != mCamera->setParameters(s)) {
37329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Could not change settings."
37454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                 " Someone else is using camera %p?", mCamera.get());
37554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return -EBUSY;
37654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
37754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
37854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
37954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
38054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
38154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
38254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check whether the requested video frame size
38354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * has been successfully configured or not. If both width and height
38454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * are -1, check on the current width and height value setting
38554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * is performed.
38654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
38754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
38854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame width in pixels to check against
38954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame height in pixels to check against
39054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error
39154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
39254ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkVideoSize(
39354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params,
39454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t width, int32_t height) {
39554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
3963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("checkVideoSize");
397f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // The actual video size is the same as the preview size
398f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // if the camera hal does not support separate video and
399f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // preview output. In this case, we retrieve the video
400f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    // size from preview.
40154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameWidthActual = -1;
40254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameHeightActual = -1;
403f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    Vector<Size> sizes;
404f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    params.getSupportedVideoSizes(sizes);
405f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    if (sizes.size() == 0) {
406f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        // video size is the same as preview size
407f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        params.getPreviewSize(&frameWidthActual, &frameHeightActual);
408f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    } else {
409f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        // video size may not be the same as preview
410f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong        params.getVideoSize(&frameWidthActual, &frameHeightActual);
411f96c9d193c70c7216b34e6c65f046a09a2a81f14James Dong    }
41254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameWidthActual < 0 || frameHeightActual < 0) {
41329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to retrieve video frame size (%dx%d)",
41454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                frameWidthActual, frameHeightActual);
41554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
41654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
41754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
41854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check the actual video frame size against the target/requested
41954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // video frame size.
42054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (width != -1 && height != -1) {
42154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        if (frameWidthActual != width || frameHeightActual != height) {
42229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to set video frame size to %dx%d. "
42354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    "The actual video size is %dx%d ", width, height,
42454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    frameWidthActual, frameHeightActual);
42554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong            return UNKNOWN_ERROR;
42654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        }
42754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
42854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
42954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Good now.
43054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.width = frameWidthActual;
43154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoSize.height = frameHeightActual;
43254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
43354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
43454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
43554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
43654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Check the requested frame rate has been successfully configured or not.
43754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * If the target frameRate is -1, check on the current frame rate value
43854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * setting is performed.
43954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *
44054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param params CameraParameters to retrieve the information
44154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param the target video frame rate to check against
44254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
44354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
44454ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::checkFrameRate(
44554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const CameraParameters& params,
44654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t frameRate) {
44754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("checkFrameRate");
44954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int32_t frameRateActual = params.getPreviewFrameRate();
45054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRateActual < 0) {
45129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
45254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
45354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
45454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
45554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check the actual video frame rate against the target/requested
45654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // video frame rate.
45754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (frameRate != -1 && (frameRateActual - frameRate) != 0) {
45829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to set preview frame rate to %d fps. The actual "
45954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                "frame rate is %d", frameRate, frameRateActual);
46054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return UNKNOWN_ERROR;
46154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
46254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
46354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Good now.
46454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mVideoFrameRate = frameRateActual;
46554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
46654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong}
46754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
46854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong/*
46954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * Initialize the CameraSource to so that it becomes
47054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * ready for providing the video input streams as requested.
47154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param camera the camera object used for the video source
47254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param cameraId if camera == 0, use camera with this id
47354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      as the video source
47454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param videoSize the target video frame size. If both
47554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      width and height in videoSize is -1, use the current
47654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      width and heigth settings by the camera
47754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @param frameRate the target frame rate in frames per second.
47854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong *      if it is -1, use the current camera frame rate setting.
4795c9523154d106b555db6c41f85ab205a4f189b02James Dong * @param storeMetaDataInVideoBuffers request to store meta
4805c9523154d106b555db6c41f85ab205a4f189b02James Dong *      data or real YUV data in video buffers. Request to
4815c9523154d106b555db6c41f85ab205a4f189b02James Dong *      store meta data in video buffers may not be honored
4825c9523154d106b555db6c41f85ab205a4f189b02James Dong *      if the source does not support this feature.
4835c9523154d106b555db6c41f85ab205a4f189b02James Dong *
48454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong * @return OK if no error.
48554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong */
48654ff19ac69ace7c05ea90d225e26dab3b133f487James Dongstatus_t CameraSource::init(
48754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        const sp<ICamera>& camera,
4884ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        const sp<ICameraRecordingProxy>& proxy,
48954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        int32_t cameraId,
490ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
491ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
49254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        Size videoSize,
4935c9523154d106b555db6c41f85ab205a4f189b02James Dong        int32_t frameRate,
4945c9523154d106b555db6c41f85ab205a4f189b02James Dong        bool storeMetaDataInVideoBuffers) {
49554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
4963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init");
49754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    status_t err = OK;
498ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    int64_t token = IPCThreadState::self()->clearCallingIdentity();
499ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid,
500ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong                               videoSize, frameRate,
501ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong                               storeMetaDataInVideoBuffers);
502ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    IPCThreadState::self()->restoreCallingIdentity(token);
503ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    return err;
504ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong}
505ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong
506ae4c1ac6401185539c03ce0819e174fd1b04b136James Dongstatus_t CameraSource::initWithCameraAccess(
507ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        const sp<ICamera>& camera,
508ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        const sp<ICameraRecordingProxy>& proxy,
509ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int32_t cameraId,
510ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientName,
511ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
512ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        Size videoSize,
513ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int32_t frameRate,
514ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        bool storeMetaDataInVideoBuffers) {
5153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("initWithCameraAccess");
516ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    status_t err = OK;
5179d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong
518ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if ((err = isCameraAvailable(camera, proxy, cameraId,
519ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            clientName, clientUid)) != OK) {
52029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera connection could not be established.");
52154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
52254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
52354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraParameters params(mCamera->getParameters());
52454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = isCameraColorFormatSupported(params)) != OK) {
52554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
52654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
527be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
52854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Set the camera to use the requested video frame size
52954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // and/or frame rate.
53054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = configureCamera(&params,
53154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    videoSize.width, videoSize.height,
53254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                    frameRate))) {
53354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
53454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
535653252be963c07c99109d20f942d1f30c52a9360James Dong
53654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    // Check on video frame size and frame rate.
53754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    CameraParameters newCameraParams(mCamera->getParameters());
53854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = checkVideoSize(newCameraParams,
53954ff19ac69ace7c05ea90d225e26dab3b133f487James Dong                videoSize.width, videoSize.height)) != OK) {
54054ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
54154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
54254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) {
54354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return err;
54454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
54554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong
5468e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    // Set the preview display. Skip this if mSurface is null because
5478e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    // applications may already set a surface to the camera.
5488e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    if (mSurface != NULL) {
5498e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li        // This CHECK is good, since we just passed the lock/unlock
5508e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li        // check earlier by calling mCamera->setParameters().
5514b820b0e1fa069714b123fc35784541d0f94d267Eino-Ville Talvala        CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface));
5528e0792bb55a604ffcd4aa90fdb4419d8b3c6ad24Wu-cheng Li    }
5532b37ced30f89437c804c3945b901019b86d210aeJames Dong
554abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong    // By default, do not store metadata in video buffers
5555c9523154d106b555db6c41f85ab205a4f189b02James Dong    mIsMetaDataStoredInVideoBuffers = false;
556abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong    mCamera->storeMetaDataInBuffers(false);
557abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong    if (storeMetaDataInVideoBuffers) {
558abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong        if (OK == mCamera->storeMetaDataInBuffers(true)) {
559abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong            mIsMetaDataStoredInVideoBuffers = true;
560abdd2ba259a5dc863a821c9d1187d83f2e2395acJames Dong        }
5615c9523154d106b555db6c41f85ab205a4f189b02James Dong    }
5625c9523154d106b555db6c41f85ab205a4f189b02James Dong
56354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
564f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    if (glitchDurationUs > mGlitchDurationThresholdUs) {
565f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        mGlitchDurationThresholdUs = glitchDurationUs;
566f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    }
567f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
568ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    // XXX: query camera for the stride and slice height
569ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong    // when the capability becomes available.
570653252be963c07c99109d20f942d1f30c52a9360James Dong    mMeta = new MetaData;
57154ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setCString(kKeyMIMEType,  MEDIA_MIMETYPE_VIDEO_RAW);
57254ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyColorFormat, mColorFormat);
57354ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyWidth,       mVideoSize.width);
57454ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyHeight,      mVideoSize.height);
57554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeyStride,      mVideoSize.width);
57654ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
577393410a441b6d06daf286ed496470e9d6b2b6ca8James Dong    mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
57854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    return OK;
57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
58120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() {
58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mStarted) {
583b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong        reset();
584ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong    } else if (mInitCheck == OK) {
585ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // Camera is initialized but because start() is never called,
586ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // the lock on Camera is never released(). This makes sure
587ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        // Camera's lock is released in this case.
588ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        releaseCamera();
58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
59226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunkstatus_t CameraSource::startCameraRecording() {
5933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("startCameraRecording");
5944ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // Reset the identity to the current thread because media server owns the
5954ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // camera and recording is started by the applications. The applications
5964ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    // will connect to the camera in ICameraRecordingProxy::startRecording.
5974ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    int64_t token = IPCThreadState::self()->clearCallingIdentity();
59826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    status_t err;
599983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    if (mNumInputBuffers > 0) {
60026cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        err = mCamera->sendCommand(
601983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);
602983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
603983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        // This could happen for CameraHAL1 clients; thus the failure is
604983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        // not a fatal error
605983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (err != OK) {
606983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            ALOGW("Failed to set video buffer count to %d due to %d",
607983cf231ab2d176a14595cdae46ff1b0c239af47James Dong                mNumInputBuffers, err);
608983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
609983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    }
610983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
611d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    err = mCamera->sendCommand(
612d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala        CAMERA_CMD_SET_VIDEO_FORMAT, mEncoderFormat, mEncoderDataSpace);
613d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
614d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    // This could happen for CameraHAL1 clients; thus the failure is
615d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    // not a fatal error
616d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    if (err != OK) {
617d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala        ALOGW("Failed to set video encoder format/dataspace to %d, %d due to %d",
618d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala                mEncoderFormat, mEncoderDataSpace, err);
619d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    }
620d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
62126cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    err = OK;
6223bd3020c00ec8264ac1fe3870800f326487f9221James Dong    if (mCameraFlags & FLAGS_HOT_CAMERA) {
6233bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->unlock();
6243bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera.clear();
62526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        if ((err = mCameraRecordingProxy->startRecording(
62626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk                new ProxyListener(this))) != OK) {
62726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            ALOGE("Failed to start recording, received error: %s (%d)",
62826cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk                    strerror(-err), err);
62926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        }
6303bd3020c00ec8264ac1fe3870800f326487f9221James Dong    } else {
6313bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->setListener(new CameraSourceListener(this));
6323bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->startRecording();
63326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        if (!mCamera->recordingEnabled()) {
63426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            err = -EINVAL;
63526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk            ALOGE("Failed to start recording");
63626cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        }
6373bd3020c00ec8264ac1fe3870800f326487f9221James Dong    }
6384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    IPCThreadState::self()->restoreCallingIdentity(token);
63926cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    return err;
64065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
64165e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
642f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) {
6433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
6440c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(!mStarted);
64554ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    if (mInitCheck != OK) {
64629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraSource is not initialized yet");
64754ff19ac69ace7c05ea90d225e26dab3b133f487James Dong        return mInitCheck;
64854ff19ac69ace7c05ea90d225e26dab3b133f487James Dong    }
64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
650365a963142093a1cd8efdcea76b5f65096a5b115James Dong    char value[PROPERTY_VALUE_MAX];
651365a963142093a1cd8efdcea76b5f65096a5b115James Dong    if (property_get("media.stagefright.record-stats", value, NULL)
652365a963142093a1cd8efdcea76b5f65096a5b115James Dong        && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
653365a963142093a1cd8efdcea76b5f65096a5b115James Dong        mCollectStats = true;
654365a963142093a1cd8efdcea76b5f65096a5b115James Dong    }
6559d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong
656f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mStartTimeUs = 0;
657983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    mNumInputBuffers = 0;
658d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    mEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
659d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala    mEncoderDataSpace = HAL_DATASPACE_BT709;
660d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
661983cf231ab2d176a14595cdae46ff1b0c239af47James Dong    if (meta) {
662983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        int64_t startTimeUs;
663983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (meta->findInt64(kKeyTime, &startTimeUs)) {
664983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            mStartTimeUs = startTimeUs;
665983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
666983cf231ab2d176a14595cdae46ff1b0c239af47James Dong
667983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        int32_t nBuffers;
668983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
669983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            CHECK_GT(nBuffers, 0);
670983cf231ab2d176a14595cdae46ff1b0c239af47James Dong            mNumInputBuffers = nBuffers;
671983cf231ab2d176a14595cdae46ff1b0c239af47James Dong        }
672d46a6b9fd8b2a4f9098757384711e2cd03a91651Eino-Ville Talvala
673c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        // apply encoder color format if specified
674c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) {
675c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            ALOGV("Using encoder format: %#x", mEncoderFormat);
676c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
677c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) {
678c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            ALOGV("Using encoder data space: %#x", mEncoderDataSpace);
679c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
680f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    }
681f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
68226cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    status_t err;
68326cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    if ((err = startCameraRecording()) == OK) {
68426cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk        mStarted = true;
68526cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    }
68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
68726cee964ab4e0a2bd6ae9ad199ba78ea9634421cRuben Brunk    return err;
68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
69065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::stopCameraRecording() {
6913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stopCameraRecording");
6923bd3020c00ec8264ac1fe3870800f326487f9221James Dong    if (mCameraFlags & FLAGS_HOT_CAMERA) {
6933bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCameraRecordingProxy->stopRecording();
6943bd3020c00ec8264ac1fe3870800f326487f9221James Dong    } else {
6953bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->setListener(NULL);
6963bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->stopRecording();
6973bd3020c00ec8264ac1fe3870800f326487f9221James Dong    }
69865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
69965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
700ea7b485595f8cec6a66668b5c54c8f297d843f77James Dongvoid CameraSource::releaseCamera() {
7013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releaseCamera");
702121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    sp<Camera> camera;
703121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    bool coldCamera = false;
704121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
705121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
706121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        // get a local ref and clear ref to mCamera now
707121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        camera = mCamera;
708121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mCamera.clear();
709121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0;
710121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    }
711121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
712121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    if (camera != 0) {
713ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        int64_t token = IPCThreadState::self()->clearCallingIdentity();
714121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (coldCamera) {
7153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Camera was cold when we started, stopping preview");
716121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            camera->stopPreview();
717121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            camera->disconnect();
71895068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li        }
719121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        camera->unlock();
720ae4c1ac6401185539c03ce0819e174fd1b04b136James Dong        IPCThreadState::self()->restoreCallingIdentity(token);
72195068be1426dc0a4dc856cf9e35550c31b901711Wu-cheng Li    }
722121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
723121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
724121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
725121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCameraRecordingProxy != 0) {
72606b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen            IInterface::asBinder(mCameraRecordingProxy)->unlinkToDeath(mDeathNotifier);
727121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            mCameraRecordingProxy.clear();
728121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
729121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mCameraFlags = 0;
730ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong    }
731ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong}
732ea7b485595f8cec6a66668b5c54c8f297d843f77James Dong
733b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dongstatus_t CameraSource::reset() {
734b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    ALOGD("reset: E");
735121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
736121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    {
737121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        Mutex::Autolock autoLock(mLock);
738121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mStarted = false;
739121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        mFrameAvailableCondition.signal();
740121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
741121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        int64_t token;
742121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        bool isTokenValid = false;
743121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCamera != 0) {
744121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            token = IPCThreadState::self()->clearCallingIdentity();
745121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            isTokenValid = true;
746121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
747121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        releaseQueuedFrames();
748121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        while (!mFramesBeingEncoded.empty()) {
749121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            if (NO_ERROR !=
750121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                mFrameCompleteCondition.waitRelative(mLock,
751121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                        mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
752121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                ALOGW("Timed out waiting for outstanding frames being encoded: %zu",
753121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mFramesBeingEncoded.size());
754121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            }
755121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
756121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        stopCameraRecording();
757121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (isTokenValid) {
758121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            IPCThreadState::self()->restoreCallingIdentity(token);
75941152efd144ccf70c380d5c9a32105c02a039f43James Dong        }
7607278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong
761121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mCollectStats) {
762121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us",
763121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
764121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang                    mLastFrameTimestampUs - mFirstFrameTimeUs);
765121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
766121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
767121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        if (mNumGlitches > 0) {
768121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang            ALOGW("%d long delays between neighboring video frames", mNumGlitches);
769121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        }
77013aec890216948b0c364f8f92792129d0335f506James Dong
771121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang        CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
772ba29002c7aee13c068049037cd14bba6a244da6bJames Dong    }
773ba29002c7aee13c068049037cd14bba6a244da6bJames Dong
774121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang    releaseCamera();
775121969b7e0d958092fae76226dc55fe8547a1da6Chong Zhang
776b44c9d2bdc0d5b9cb03254022a58e017b516e9e6James Dong    ALOGD("reset: X");
77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
78065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatravoid CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
7813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("releaseRecordingFrame");
7824ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    if (mCameraRecordingProxy != NULL) {
7834ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        mCameraRecordingProxy->releaseRecordingFrame(frame);
784334d097870eefeb45137b6df026f7db861d47663James Dong    } else if (mCamera != NULL) {
7853bd3020c00ec8264ac1fe3870800f326487f9221James Dong        int64_t token = IPCThreadState::self()->clearCallingIdentity();
7863bd3020c00ec8264ac1fe3870800f326487f9221James Dong        mCamera->releaseRecordingFrame(frame);
7873bd3020c00ec8264ac1fe3870800f326487f9221James Dong        IPCThreadState::self()->restoreCallingIdentity(token);
788d69c7f654cc772b03717999c1b24402d5c40e69fJames Dong    }
78965e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra}
79065e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra
791c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() {
792c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    List<sp<IMemory> >::iterator it;
7937278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    while (!mFramesReceived.empty()) {
7947278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        it = mFramesReceived.begin();
79565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        releaseRecordingFrame(*it);
7967278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        mFramesReceived.erase(it);
79713aec890216948b0c364f8f92792129d0335f506James Dong        ++mNumFramesDropped;
798c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
799c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong}
800c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong
80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() {
802653252be963c07c99109d20f942d1f30c52a9360James Dong    return mMeta;
80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
805f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) {
80665e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    releaseRecordingFrame(frame);
807f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong}
808f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong
8097278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) {
8103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned: %p", buffer->data());
81156223b96c2f6de5998496fac9d6703f06adc1dcaAndreas Huber    Mutex::Autolock autoLock(mLock);
8127278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
8137278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong         it != mFramesBeingEncoded.end(); ++it) {
8147278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        if ((*it)->pointer() ==  buffer->data()) {
815f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            releaseOneRecordingFrame((*it));
8167278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            mFramesBeingEncoded.erase(it);
8177278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            ++mNumFramesEncoded;
8187278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            buffer->setObserver(0);
8197278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            buffer->release();
8207278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            mFrameCompleteCondition.signal();
8217278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong            return;
8227278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong        }
8237278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    }
824f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(!"signalBufferReturned: bogus buffer");
8257278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong}
8267278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong
82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read(
82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        MediaBuffer **buffer, const ReadOptions *options) {
8293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("read");
83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *buffer = NULL;
83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int64_t seekTimeUs;
834abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
835abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_UNSUPPORTED;
83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    sp<IMemory> frame;
840be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    int64_t frameTime;
84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    {
84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        Mutex::Autolock autoLock(mLock);
84479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        while (mStarted && mFramesReceived.empty()) {
84541152efd144ccf70c380d5c9a32105c02a039f43James Dong            if (NO_ERROR !=
846e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                mFrameAvailableCondition.waitRelative(mLock,
847e8e5f86e9e310b065596c8cbbca1543eb833dee1James Dong                    mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
8483bd3020c00ec8264ac1fe3870800f326487f9221James Dong                if (mCameraRecordingProxy != 0 &&
84906b46062d2f8bc82ca3061a23d197734ae51918bMarco Nelissen                    !IInterface::asBinder(mCameraRecordingProxy)->isBinderAlive()) {
8505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("camera recording proxy is gone");
8514ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                    return ERROR_END_OF_STREAM;
8524ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li                }
853a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn                ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us",
85441152efd144ccf70c380d5c9a32105c02a039f43James Dong                    mLastFrameTimestampUs);
85541152efd144ccf70c380d5c9a32105c02a039f43James Dong            }
85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
85779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        if (!mStarted) {
85879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong            return OK;
85979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        }
86079e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        frame = *mFramesReceived.begin();
86179e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFramesReceived.erase(mFramesReceived.begin());
86279e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong
86379e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        frameTime = *mFrameTimes.begin();
86479e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFrameTimes.erase(mFrameTimes.begin());
86579e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        mFramesBeingEncoded.push_back(frame);
86679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        *buffer = new MediaBuffer(frame->pointer(), frame->size());
86779e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->setObserver(this);
86879e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->add_ref();
86979e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
8707278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    }
87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
874c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs,
875ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t msgType __unused, const sp<IMemory> &data) {
876ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("dataCallbackTimestamp: timestamp %lld us", (long long)timestampUs);
87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
878a472613aec322e25891abf5c77bf3f7e3c244920James Dong    if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
879ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("Drop frame at %lld/%lld us", (long long)timestampUs, (long long)mStartTimeUs);
880f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        releaseOneRecordingFrame(data);
881c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong        return;
882c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong    }
88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
88465e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    // May need to skip frame or modify timestamp. Currently implemented
88565e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra    // by the subclass CameraSourceTimeLapse.
88679e23b41fad961008bfde6e26b3c6f86878ca69dJames Dong    if (skipCurrentFrame(timestampUs)) {
88765e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        releaseOneRecordingFrame(data);
88865e7e6facda89927cb26594b3b65ae81b3235ebcNipun Kwatra        return;
889fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra    }
890fc20aab463f527ab3b0664986f0381a86b375884Nipun Kwatra
8910aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang    if (mNumFramesReceived > 0) {
8920aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        if (timestampUs <= mLastFrameTimestampUs) {
8930aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            ALOGW("Dropping frame with backward timestamp %lld (last %lld)",
8940aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang                    (long long)timestampUs, (long long)mLastFrameTimestampUs);
8950aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            releaseOneRecordingFrame(data);
8960aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            return;
8970aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        }
8980aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
8990aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang            ++mNumGlitches;
9000aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang        }
9010aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang    }
9020aaff700f6c7885887bbf42f7bb64754e21e5fceChong Zhang
903365a963142093a1cd8efdcea76b5f65096a5b115James Dong    mLastFrameTimestampUs = timestampUs;
90413aec890216948b0c364f8f92792129d0335f506James Dong    if (mNumFramesReceived == 0) {
905c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong        mFirstFrameTimeUs = timestampUs;
906f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        // Initial delay
907f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        if (mStartTimeUs > 0) {
908f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            if (timestampUs < mStartTimeUs) {
909f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                // Frame was captured before recording was started
910f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                // Drop it without updating the statistical data.
911f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                releaseOneRecordingFrame(data);
912f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong                return;
913f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            }
914f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong            mStartTimeUs = timestampUs - mStartTimeUs;
915f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        }
916be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber    }
91713aec890216948b0c364f8f92792129d0335f506James Dong    ++mNumFramesReceived;
918be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber
91998cfde007490a5903b729a4718c0dada755ae8f8James Dong    CHECK(data != NULL && data->size() > 0);
9207278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong    mFramesReceived.push_back(data);
921f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
922f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mFrameTimes.push_back(timeUs);
923a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64,
924f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong        mStartTimeUs, timeUs);
92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mFrameAvailableCondition.signal();
92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9285c9523154d106b555db6c41f85ab205a4f189b02James Dongbool CameraSource::isMetaDataStoredInVideoBuffers() const {
9293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isMetaDataStoredInVideoBuffers");
9305c9523154d106b555db6c41f85ab205a4f189b02James Dong    return mIsMetaDataStoredInVideoBuffers;
9315c9523154d106b555db6c41f85ab205a4f189b02James Dong}
9325c9523154d106b555db6c41f85ab205a4f189b02James Dong
9334ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng LiCameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
9344ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mSource = source;
9354ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
9364ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
9374ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Livoid CameraSource::ProxyListener::dataCallbackTimestamp(
9384ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
9394ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li    mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
9404ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
9414ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
942ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnarvoid CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who __unused) {
943df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("Camera recording proxy died");
9444ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li}
9454ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li
94620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
947