CameraSource.cpp revision abd1f4f870925d6776dbe4b930b759a1ab6595ca
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 17c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong//#define LOG_NDEBUG 0 18c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#define LOG_TAG "CameraSource" 19c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX_Component.h> 229d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong#include <binder/IPCThreadState.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/CameraSource.h> 240c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 25be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <media/stagefright/MediaDefs.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaErrors.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 283cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/Camera.h> 293cf613507f1e2f7bd932d921a6e222e426fd3be4Mathias Agopian#include <camera/CameraParameters.h> 30be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber#include <utils/String8.h> 31365a963142093a1cd8efdcea76b5f65096a5b115James Dong#include <cutils/properties.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberstruct CameraSourceListener : public CameraListener { 36be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const sp<CameraSource> &source); 37be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 38be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); 39be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr); 40be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 41be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual void postDataTimestamp( 42be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 43be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 44be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huberprotected: 45be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber virtual ~CameraSourceListener(); 46be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 48be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber wp<CameraSource> mSource; 49be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 50be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener(const CameraSourceListener &); 51be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraSourceListener &operator=(const CameraSourceListener &); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::CameraSourceListener(const sp<CameraSource> &source) 55be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber : mSource(source) { 56be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSourceListener::~CameraSourceListener() { 59be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) { 62be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber LOGV("notify(%d, %d, %d)", msgType, ext1, ext2); 63be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr) { 66be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber LOGV("postData(%d, ptr:%p, size:%d)", 67be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber msgType, dataPtr->pointer(), dataPtr->size()); 68be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 69be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 70be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Hubervoid CameraSourceListener::postDataTimestamp( 71be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) { 72c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 73c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong sp<CameraSource> source = mSource.promote(); 74c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (source.get() != NULL) { 75c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr); 76c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 77be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber} 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79653252be963c07c99109d20f942d1f30c52a9360James Dongstatic int32_t getColorFormat(const char* colorFormat) { 80653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) { 81653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV422SemiPlanar; 82653252be963c07c99109d20f942d1f30c52a9360James Dong } 83653252be963c07c99109d20f942d1f30c52a9360James Dong 84653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) { 85653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYUV420SemiPlanar; 86653252be963c07c99109d20f942d1f30c52a9360James Dong } 87653252be963c07c99109d20f942d1f30c52a9360James Dong 88653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) { 89653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_FormatYCbYCr; 90653252be963c07c99109d20f942d1f30c52a9360James Dong } 91653252be963c07c99109d20f942d1f30c52a9360James Dong 92653252be963c07c99109d20f942d1f30c52a9360James Dong if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) { 93653252be963c07c99109d20f942d1f30c52a9360James Dong return OMX_COLOR_Format16bitRGB565; 94653252be963c07c99109d20f942d1f30c52a9360James Dong } 95653252be963c07c99109d20f942d1f30c52a9360James Dong 96653252be963c07c99109d20f942d1f30c52a9360James Dong CHECK_EQ(0, "Unknown color format"); 97653252be963c07c99109d20f942d1f30c52a9360James Dong} 98653252be963c07c99109d20f942d1f30c52a9360James Dong 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource *CameraSource::Create() { 10135a055b8bfc6f3cbea409b2897caf936654519cbChih-Chung Chang sp<Camera> camera = Camera::connect(0); 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 103be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber if (camera.get() == NULL) { 104be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber return NULL; 105be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber return new CameraSource(camera); 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11030ab66297501757d745b9ae10da61adcd891f497Andreas Huber// static 111c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James DongCameraSource *CameraSource::CreateFromCamera(const sp<Camera> &camera) { 11230ab66297501757d745b9ae10da61adcd891f497Andreas Huber if (camera.get() == NULL) { 11330ab66297501757d745b9ae10da61adcd891f497Andreas Huber return NULL; 11430ab66297501757d745b9ae10da61adcd891f497Andreas Huber } 11530ab66297501757d745b9ae10da61adcd891f497Andreas Huber 11630ab66297501757d745b9ae10da61adcd891f497Andreas Huber return new CameraSource(camera); 11730ab66297501757d745b9ae10da61adcd891f497Andreas Huber} 11830ab66297501757d745b9ae10da61adcd891f497Andreas Huber 119be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas HuberCameraSource::CameraSource(const sp<Camera> &camera) 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mCamera(camera), 121be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber mFirstFrameTimeUs(0), 122c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mLastFrameTimestampUs(0), 12313aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesReceived(0), 12413aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesEncoded(0), 12513aec890216948b0c364f8f92792129d0335f506James Dong mNumFramesDropped(0), 126f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mNumGlitches(0), 127f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs(200000), 128365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats(false), 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false) { 1309d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 1319d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 132be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber String8 s = mCamera->getParameters(); 1339d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong IPCThreadState::self()->restoreCallingIdentity(token); 1349d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 135be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber printf("params: \"%s\"\n", s.string()); 136be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 137ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong int32_t width, height, stride, sliceHeight; 138be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber CameraParameters params(s); 139653252be963c07c99109d20f942d1f30c52a9360James Dong params.getPreviewSize(&width, &height); 140653252be963c07c99109d20f942d1f30c52a9360James Dong 141f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Calculate glitch duraton threshold based on frame rate 142f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int32_t frameRate = params.getPreviewFrameRate(); 143f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t glitchDurationUs = (1000000LL / frameRate); 144f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (glitchDurationUs > mGlitchDurationThresholdUs) { 145f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mGlitchDurationThresholdUs = glitchDurationUs; 146f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 147f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 148653252be963c07c99109d20f942d1f30c52a9360James Dong const char *colorFormatStr = params.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT); 149653252be963c07c99109d20f942d1f30c52a9360James Dong CHECK(colorFormatStr != NULL); 150653252be963c07c99109d20f942d1f30c52a9360James Dong int32_t colorFormat = getColorFormat(colorFormatStr); 151653252be963c07c99109d20f942d1f30c52a9360James Dong 152ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // XXX: query camera for the stride and slice height 153ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong // when the capability becomes available. 154ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong stride = width; 155ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong sliceHeight = height; 156ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong 157653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta = new MetaData; 158653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 159653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta->setInt32(kKeyColorFormat, colorFormat); 160653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta->setInt32(kKeyWidth, width); 161653252be963c07c99109d20f942d1f30c52a9360James Dong mMeta->setInt32(kKeyHeight, height); 162ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong mMeta->setInt32(kKeyStride, stride); 163ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong mMeta->setInt32(kKeySliceHeight, sliceHeight); 164ddcc4a66d848deef6fb4689e64e30cd9bd2684feJames Dong 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberCameraSource::~CameraSource() { 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 173f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongstatus_t CameraSource::start(MetaData *meta) { 1740c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(!mStarted); 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 176365a963142093a1cd8efdcea76b5f65096a5b115James Dong char value[PROPERTY_VALUE_MAX]; 177365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (property_get("media.stagefright.record-stats", value, NULL) 178365a963142093a1cd8efdcea76b5f65096a5b115James Dong && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { 179365a963142093a1cd8efdcea76b5f65096a5b115James Dong mCollectStats = true; 180365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 1819d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 182f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = 0; 183f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t startTimeUs; 184f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (meta && meta->findInt64(kKeyTime, &startTimeUs)) { 185f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = startTimeUs; 186f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 187f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 1889d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 189be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber mCamera->setListener(new CameraSourceListener(this)); 19065ae665befd929efd1a7d1c9addac41c699f04b2James Dong CHECK_EQ(OK, mCamera->startRecording()); 1919d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong IPCThreadState::self()->restoreCallingIdentity(token); 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::stop() { 198c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("stop"); 199c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong Mutex::Autolock autoLock(mLock); 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 201c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFrameAvailableCondition.signal(); 202365a963142093a1cd8efdcea76b5f65096a5b115James Dong 2039d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 204c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mCamera->setListener(NULL); 205c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mCamera->stopRecording(); 206c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong releaseQueuedFrames(); 2077278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesBeingEncoded.empty()) { 208365a963142093a1cd8efdcea76b5f65096a5b115James Dong LOGI("Waiting for outstanding frames being encoded: %d", 209365a963142093a1cd8efdcea76b5f65096a5b115James Dong mFramesBeingEncoded.size()); 2107278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.wait(mLock); 2117278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 2129d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong mCamera = NULL; 2139d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong IPCThreadState::self()->restoreCallingIdentity(token); 2147278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 215365a963142093a1cd8efdcea76b5f65096a5b115James Dong if (mCollectStats) { 216365a963142093a1cd8efdcea76b5f65096a5b115James Dong LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us", 217365a963142093a1cd8efdcea76b5f65096a5b115James Dong mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped, 218365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs - mFirstFrameTimeUs); 219365a963142093a1cd8efdcea76b5f65096a5b115James Dong } 22013aec890216948b0c364f8f92792129d0335f506James Dong 22113aec890216948b0c364f8f92792129d0335f506James Dong CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped); 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 225c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::releaseQueuedFrames() { 226c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong List<sp<IMemory> >::iterator it; 2277278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (!mFramesReceived.empty()) { 2287278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it = mFramesReceived.begin(); 229c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mCamera->releaseRecordingFrame(*it); 2307278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(it); 23113aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 232c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 233c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong} 234c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> CameraSource::getFormat() { 236653252be963c07c99109d20f942d1f30c52a9360James Dong return mMeta; 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 239f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dongvoid CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) { 240f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t token = IPCThreadState::self()->clearCallingIdentity(); 241f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mCamera->releaseRecordingFrame(frame); 242f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong IPCThreadState::self()->restoreCallingIdentity(token); 243f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong} 244f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 2457278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dongvoid CameraSource::signalBufferReturned(MediaBuffer *buffer) { 2467278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong LOGV("signalBufferReturned: %p", buffer->data()); 2477278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin(); 2487278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong it != mFramesBeingEncoded.end(); ++it) { 2497278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong if ((*it)->pointer() == buffer->data()) { 2509d7f58a7da8502a4174a17ac49fcba6efa35a457James Dong 251f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame((*it)); 2527278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.erase(it); 2537278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong ++mNumFramesEncoded; 2547278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->setObserver(0); 2557278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong buffer->release(); 2567278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFrameCompleteCondition.signal(); 2577278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong return; 2587278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 2597278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 2607278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong CHECK_EQ(0, "signalBufferReturned: bogus buffer"); 2617278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong} 2627278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t CameraSource::read( 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options) { 265c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("read"); 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *buffer = NULL; 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 270abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 271abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (options && options->getSeekTo(&seekTimeUs, &mode)) { 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<IMemory> frame; 276be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber int64_t frameTime; 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 2807278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong while (mStarted && mFramesReceived.empty()) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.wait(mLock); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 283c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (!mStarted) { 284c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong return OK; 285c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 2867278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong frame = *mFramesReceived.begin(); 2877278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.erase(mFramesReceived.begin()); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 289be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber frameTime = *mFrameTimes.begin(); 290be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber mFrameTimes.erase(mFrameTimes.begin()); 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2927278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesBeingEncoded.push_back(frame); 2937278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong *buffer = new MediaBuffer(frame->pointer(), frame->size()); 2947278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong (*buffer)->setObserver(this); 2957278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong (*buffer)->add_ref(); 2967278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong (*buffer)->meta_data()->setInt64(kKeyTime, frameTime); 2977278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong } 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 301c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dongvoid CameraSource::dataCallbackTimestamp(int64_t timestampUs, 302c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong int32_t msgType, const sp<IMemory> &data) { 303c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 305c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong if (!mStarted) { 306f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 30713aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 30813aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesDropped; 309c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong return; 310c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong } 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 312f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mNumFramesReceived > 0 && 313f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) { 314f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mNumGlitches % 10 == 0) { // Don't spam the log 315f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong LOGW("Long delay detected in video recording"); 316f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 317f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong ++mNumGlitches; 318f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 319f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong 320365a963142093a1cd8efdcea76b5f65096a5b115James Dong mLastFrameTimestampUs = timestampUs; 32113aec890216948b0c364f8f92792129d0335f506James Dong if (mNumFramesReceived == 0) { 322c32cd79d9ad4aba7d959b5b3be7361b4715e6f18James Dong mFirstFrameTimeUs = timestampUs; 323f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Initial delay 324f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (mStartTimeUs > 0) { 325f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong if (timestampUs < mStartTimeUs) { 326f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Frame was captured before recording was started 327f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong // Drop it without updating the statistical data. 328f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong releaseOneRecordingFrame(data); 329f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong return; 330f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 331f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs = timestampUs - mStartTimeUs; 332f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong } 333be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber } 33413aec890216948b0c364f8f92792129d0335f506James Dong ++mNumFramesReceived; 335be5c74f5da6a93b0d23f96e11848acfcc3b4d1d9Andreas Huber 3367278cf32f1aa6a322f6dff1f8b7dacf7b6dddba6James Dong mFramesReceived.push_back(data); 337f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs); 338f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mFrameTimes.push_back(timeUs); 339f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong LOGV("initial delay: %lld, current time stamp: %lld", 340f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mStartTimeUs, timeUs); 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFrameAvailableCondition.signal(); 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 345