Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <inttypes.h>
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "CameraSource"
     21 #include <utils/Log.h>
     22 
     23 #include <OMX_Component.h>
     24 #include <binder/IPCThreadState.h>
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/CameraSource.h>
     27 #include <media/stagefright/MediaDefs.h>
     28 #include <media/stagefright/MediaErrors.h>
     29 #include <media/stagefright/MetaData.h>
     30 #include <camera/Camera.h>
     31 #include <camera/CameraParameters.h>
     32 #include <gui/Surface.h>
     33 #include <utils/String8.h>
     34 #include <cutils/properties.h>
     35 
     36 #if LOG_NDEBUG
     37 #define UNUSED_UNLESS_VERBOSE(x) (void)(x)
     38 #else
     39 #define UNUSED_UNLESS_VERBOSE(x)
     40 #endif
     41 
     42 namespace android {
     43 
     44 static const int64_t CAMERA_SOURCE_TIMEOUT_NS = 3000000000LL;
     45 
     46 struct CameraSourceListener : public CameraListener {
     47     CameraSourceListener(const sp<CameraSource> &source);
     48 
     49     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
     50     virtual void postData(int32_t msgType, const sp<IMemory> &dataPtr,
     51                           camera_frame_metadata_t *metadata);
     52 
     53     virtual void postDataTimestamp(
     54             nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
     55 
     56 protected:
     57     virtual ~CameraSourceListener();
     58 
     59 private:
     60     wp<CameraSource> mSource;
     61 
     62     CameraSourceListener(const CameraSourceListener &);
     63     CameraSourceListener &operator=(const CameraSourceListener &);
     64 };
     65 
     66 CameraSourceListener::CameraSourceListener(const sp<CameraSource> &source)
     67     : mSource(source) {
     68 }
     69 
     70 CameraSourceListener::~CameraSourceListener() {
     71 }
     72 
     73 void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
     74     UNUSED_UNLESS_VERBOSE(msgType);
     75     UNUSED_UNLESS_VERBOSE(ext1);
     76     UNUSED_UNLESS_VERBOSE(ext2);
     77     ALOGV("notify(%d, %d, %d)", msgType, ext1, ext2);
     78 }
     79 
     80 void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
     81                                     camera_frame_metadata_t * /* metadata */) {
     82     ALOGV("postData(%d, ptr:%p, size:%zu)",
     83          msgType, dataPtr->pointer(), dataPtr->size());
     84 
     85     sp<CameraSource> source = mSource.promote();
     86     if (source.get() != NULL) {
     87         source->dataCallback(msgType, dataPtr);
     88     }
     89 }
     90 
     91 void CameraSourceListener::postDataTimestamp(
     92         nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
     93 
     94     sp<CameraSource> source = mSource.promote();
     95     if (source.get() != NULL) {
     96         source->dataCallbackTimestamp(timestamp/1000, msgType, dataPtr);
     97     }
     98 }
     99 
    100 static int32_t getColorFormat(const char* colorFormat) {
    101     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420P)) {
    102        return OMX_COLOR_FormatYUV420Planar;
    103     }
    104 
    105     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422SP)) {
    106        return OMX_COLOR_FormatYUV422SemiPlanar;
    107     }
    108 
    109     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV420SP)) {
    110         return OMX_COLOR_FormatYUV420SemiPlanar;
    111     }
    112 
    113     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_YUV422I)) {
    114         return OMX_COLOR_FormatYCbYCr;
    115     }
    116 
    117     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_RGB565)) {
    118        return OMX_COLOR_Format16bitRGB565;
    119     }
    120 
    121     if (!strcmp(colorFormat, "OMX_TI_COLOR_FormatYUV420PackedSemiPlanar")) {
    122        return OMX_TI_COLOR_FormatYUV420PackedSemiPlanar;
    123     }
    124 
    125     if (!strcmp(colorFormat, CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE)) {
    126         return OMX_COLOR_FormatAndroidOpaque;
    127     }
    128 
    129     ALOGE("Uknown color format (%s), please add it to "
    130          "CameraSource::getColorFormat", colorFormat);
    131 
    132     CHECK(!"Unknown color format");
    133 }
    134 
    135 CameraSource *CameraSource::Create(const String16 &clientName) {
    136     Size size;
    137     size.width = -1;
    138     size.height = -1;
    139 
    140     sp<ICamera> camera;
    141     return new CameraSource(camera, NULL, 0, clientName, -1,
    142             size, -1, NULL, false);
    143 }
    144 
    145 // static
    146 CameraSource *CameraSource::CreateFromCamera(
    147     const sp<ICamera>& camera,
    148     const sp<ICameraRecordingProxy>& proxy,
    149     int32_t cameraId,
    150     const String16& clientName,
    151     uid_t clientUid,
    152     Size videoSize,
    153     int32_t frameRate,
    154     const sp<IGraphicBufferProducer>& surface,
    155     bool storeMetaDataInVideoBuffers) {
    156 
    157     CameraSource *source = new CameraSource(camera, proxy, cameraId,
    158             clientName, clientUid, videoSize, frameRate, surface,
    159             storeMetaDataInVideoBuffers);
    160     return source;
    161 }
    162 
    163 CameraSource::CameraSource(
    164     const sp<ICamera>& camera,
    165     const sp<ICameraRecordingProxy>& proxy,
    166     int32_t cameraId,
    167     const String16& clientName,
    168     uid_t clientUid,
    169     Size videoSize,
    170     int32_t frameRate,
    171     const sp<IGraphicBufferProducer>& surface,
    172     bool storeMetaDataInVideoBuffers)
    173     : mCameraFlags(0),
    174       mNumInputBuffers(0),
    175       mVideoFrameRate(-1),
    176       mCamera(0),
    177       mSurface(surface),
    178       mNumFramesReceived(0),
    179       mLastFrameTimestampUs(0),
    180       mStarted(false),
    181       mNumFramesEncoded(0),
    182       mTimeBetweenFrameCaptureUs(0),
    183       mFirstFrameTimeUs(0),
    184       mNumFramesDropped(0),
    185       mNumGlitches(0),
    186       mGlitchDurationThresholdUs(200000),
    187       mCollectStats(false) {
    188     mVideoSize.width  = -1;
    189     mVideoSize.height = -1;
    190 
    191     mInitCheck = init(camera, proxy, cameraId,
    192                     clientName, clientUid,
    193                     videoSize, frameRate,
    194                     storeMetaDataInVideoBuffers);
    195     if (mInitCheck != OK) releaseCamera();
    196 }
    197 
    198 status_t CameraSource::initCheck() const {
    199     return mInitCheck;
    200 }
    201 
    202 status_t CameraSource::isCameraAvailable(
    203     const sp<ICamera>& camera, const sp<ICameraRecordingProxy>& proxy,
    204     int32_t cameraId, const String16& clientName, uid_t clientUid) {
    205 
    206     if (camera == 0) {
    207         mCamera = Camera::connect(cameraId, clientName, clientUid);
    208         if (mCamera == 0) return -EBUSY;
    209         mCameraFlags &= ~FLAGS_HOT_CAMERA;
    210     } else {
    211         // We get the proxy from Camera, not ICamera. We need to get the proxy
    212         // to the remote Camera owned by the application. Here mCamera is a
    213         // local Camera object created by us. We cannot use the proxy from
    214         // mCamera here.
    215         mCamera = Camera::create(camera);
    216         if (mCamera == 0) return -EBUSY;
    217         mCameraRecordingProxy = proxy;
    218         mCameraFlags |= FLAGS_HOT_CAMERA;
    219         mDeathNotifier = new DeathNotifier();
    220         // isBinderAlive needs linkToDeath to work.
    221         mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier);
    222     }
    223 
    224     mCamera->lock();
    225 
    226     return OK;
    227 }
    228 
    229 
    230 /*
    231  * Check to see whether the requested video width and height is one
    232  * of the supported sizes.
    233  * @param width the video frame width in pixels
    234  * @param height the video frame height in pixels
    235  * @param suppportedSizes the vector of sizes that we check against
    236  * @return true if the dimension (width and height) is supported.
    237  */
    238 static bool isVideoSizeSupported(
    239     int32_t width, int32_t height,
    240     const Vector<Size>& supportedSizes) {
    241 
    242     ALOGV("isVideoSizeSupported");
    243     for (size_t i = 0; i < supportedSizes.size(); ++i) {
    244         if (width  == supportedSizes[i].width &&
    245             height == supportedSizes[i].height) {
    246             return true;
    247         }
    248     }
    249     return false;
    250 }
    251 
    252 /*
    253  * If the preview and video output is separate, we only set the
    254  * the video size, and applications should set the preview size
    255  * to some proper value, and the recording framework will not
    256  * change the preview size; otherwise, if the video and preview
    257  * output is the same, we need to set the preview to be the same
    258  * as the requested video size.
    259  *
    260  */
    261 /*
    262  * Query the camera to retrieve the supported video frame sizes
    263  * and also to see whether CameraParameters::setVideoSize()
    264  * is supported or not.
    265  * @param params CameraParameters to retrieve the information
    266  * @@param isSetVideoSizeSupported retunrs whether method
    267  *      CameraParameters::setVideoSize() is supported or not.
    268  * @param sizes returns the vector of Size objects for the
    269  *      supported video frame sizes advertised by the camera.
    270  */
    271 static void getSupportedVideoSizes(
    272     const CameraParameters& params,
    273     bool *isSetVideoSizeSupported,
    274     Vector<Size>& sizes) {
    275 
    276     *isSetVideoSizeSupported = true;
    277     params.getSupportedVideoSizes(sizes);
    278     if (sizes.size() == 0) {
    279         ALOGD("Camera does not support setVideoSize()");
    280         params.getSupportedPreviewSizes(sizes);
    281         *isSetVideoSizeSupported = false;
    282     }
    283 }
    284 
    285 /*
    286  * Check whether the camera has the supported color format
    287  * @param params CameraParameters to retrieve the information
    288  * @return OK if no error.
    289  */
    290 status_t CameraSource::isCameraColorFormatSupported(
    291         const CameraParameters& params) {
    292     mColorFormat = getColorFormat(params.get(
    293             CameraParameters::KEY_VIDEO_FRAME_FORMAT));
    294     if (mColorFormat == -1) {
    295         return BAD_VALUE;
    296     }
    297     return OK;
    298 }
    299 
    300 /*
    301  * Configure the camera to use the requested video size
    302  * (width and height) and/or frame rate. If both width and
    303  * height are -1, configuration on the video size is skipped.
    304  * if frameRate is -1, configuration on the frame rate
    305  * is skipped. Skipping the configuration allows one to
    306  * use the current camera setting without the need to
    307  * actually know the specific values (see Create() method).
    308  *
    309  * @param params the CameraParameters to be configured
    310  * @param width the target video frame width in pixels
    311  * @param height the target video frame height in pixels
    312  * @param frameRate the target frame rate in frames per second.
    313  * @return OK if no error.
    314  */
    315 status_t CameraSource::configureCamera(
    316         CameraParameters* params,
    317         int32_t width, int32_t height,
    318         int32_t frameRate) {
    319     ALOGV("configureCamera");
    320     Vector<Size> sizes;
    321     bool isSetVideoSizeSupportedByCamera = true;
    322     getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
    323     bool isCameraParamChanged = false;
    324     if (width != -1 && height != -1) {
    325         if (!isVideoSizeSupported(width, height, sizes)) {
    326             ALOGE("Video dimension (%dx%d) is unsupported", width, height);
    327             return BAD_VALUE;
    328         }
    329         if (isSetVideoSizeSupportedByCamera) {
    330             params->setVideoSize(width, height);
    331         } else {
    332             params->setPreviewSize(width, height);
    333         }
    334         isCameraParamChanged = true;
    335     } else if ((width == -1 && height != -1) ||
    336                (width != -1 && height == -1)) {
    337         // If one and only one of the width and height is -1
    338         // we reject such a request.
    339         ALOGE("Requested video size (%dx%d) is not supported", width, height);
    340         return BAD_VALUE;
    341     } else {  // width == -1 && height == -1
    342         // Do not configure the camera.
    343         // Use the current width and height value setting from the camera.
    344     }
    345 
    346     if (frameRate != -1) {
    347         CHECK(frameRate > 0 && frameRate <= 120);
    348         const char* supportedFrameRates =
    349                 params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES);
    350         CHECK(supportedFrameRates != NULL);
    351         ALOGV("Supported frame rates: %s", supportedFrameRates);
    352         char buf[4];
    353         snprintf(buf, 4, "%d", frameRate);
    354         if (strstr(supportedFrameRates, buf) == NULL) {
    355             ALOGE("Requested frame rate (%d) is not supported: %s",
    356                 frameRate, supportedFrameRates);
    357             return BAD_VALUE;
    358         }
    359 
    360         // The frame rate is supported, set the camera to the requested value.
    361         params->setPreviewFrameRate(frameRate);
    362         isCameraParamChanged = true;
    363     } else {  // frameRate == -1
    364         // Do not configure the camera.
    365         // Use the current frame rate value setting from the camera
    366     }
    367 
    368     if (isCameraParamChanged) {
    369         // Either frame rate or frame size needs to be changed.
    370         String8 s = params->flatten();
    371         if (OK != mCamera->setParameters(s)) {
    372             ALOGE("Could not change settings."
    373                  " Someone else is using camera %p?", mCamera.get());
    374             return -EBUSY;
    375         }
    376     }
    377     return OK;
    378 }
    379 
    380 /*
    381  * Check whether the requested video frame size
    382  * has been successfully configured or not. If both width and height
    383  * are -1, check on the current width and height value setting
    384  * is performed.
    385  *
    386  * @param params CameraParameters to retrieve the information
    387  * @param the target video frame width in pixels to check against
    388  * @param the target video frame height in pixels to check against
    389  * @return OK if no error
    390  */
    391 status_t CameraSource::checkVideoSize(
    392         const CameraParameters& params,
    393         int32_t width, int32_t height) {
    394 
    395     ALOGV("checkVideoSize");
    396     // The actual video size is the same as the preview size
    397     // if the camera hal does not support separate video and
    398     // preview output. In this case, we retrieve the video
    399     // size from preview.
    400     int32_t frameWidthActual = -1;
    401     int32_t frameHeightActual = -1;
    402     Vector<Size> sizes;
    403     params.getSupportedVideoSizes(sizes);
    404     if (sizes.size() == 0) {
    405         // video size is the same as preview size
    406         params.getPreviewSize(&frameWidthActual, &frameHeightActual);
    407     } else {
    408         // video size may not be the same as preview
    409         params.getVideoSize(&frameWidthActual, &frameHeightActual);
    410     }
    411     if (frameWidthActual < 0 || frameHeightActual < 0) {
    412         ALOGE("Failed to retrieve video frame size (%dx%d)",
    413                 frameWidthActual, frameHeightActual);
    414         return UNKNOWN_ERROR;
    415     }
    416 
    417     // Check the actual video frame size against the target/requested
    418     // video frame size.
    419     if (width != -1 && height != -1) {
    420         if (frameWidthActual != width || frameHeightActual != height) {
    421             ALOGE("Failed to set video frame size to %dx%d. "
    422                     "The actual video size is %dx%d ", width, height,
    423                     frameWidthActual, frameHeightActual);
    424             return UNKNOWN_ERROR;
    425         }
    426     }
    427 
    428     // Good now.
    429     mVideoSize.width = frameWidthActual;
    430     mVideoSize.height = frameHeightActual;
    431     return OK;
    432 }
    433 
    434 /*
    435  * Check the requested frame rate has been successfully configured or not.
    436  * If the target frameRate is -1, check on the current frame rate value
    437  * setting is performed.
    438  *
    439  * @param params CameraParameters to retrieve the information
    440  * @param the target video frame rate to check against
    441  * @return OK if no error.
    442  */
    443 status_t CameraSource::checkFrameRate(
    444         const CameraParameters& params,
    445         int32_t frameRate) {
    446 
    447     ALOGV("checkFrameRate");
    448     int32_t frameRateActual = params.getPreviewFrameRate();
    449     if (frameRateActual < 0) {
    450         ALOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
    451         return UNKNOWN_ERROR;
    452     }
    453 
    454     // Check the actual video frame rate against the target/requested
    455     // video frame rate.
    456     if (frameRate != -1 && (frameRateActual - frameRate) != 0) {
    457         ALOGE("Failed to set preview frame rate to %d fps. The actual "
    458                 "frame rate is %d", frameRate, frameRateActual);
    459         return UNKNOWN_ERROR;
    460     }
    461 
    462     // Good now.
    463     mVideoFrameRate = frameRateActual;
    464     return OK;
    465 }
    466 
    467 /*
    468  * Initialize the CameraSource to so that it becomes
    469  * ready for providing the video input streams as requested.
    470  * @param camera the camera object used for the video source
    471  * @param cameraId if camera == 0, use camera with this id
    472  *      as the video source
    473  * @param videoSize the target video frame size. If both
    474  *      width and height in videoSize is -1, use the current
    475  *      width and heigth settings by the camera
    476  * @param frameRate the target frame rate in frames per second.
    477  *      if it is -1, use the current camera frame rate setting.
    478  * @param storeMetaDataInVideoBuffers request to store meta
    479  *      data or real YUV data in video buffers. Request to
    480  *      store meta data in video buffers may not be honored
    481  *      if the source does not support this feature.
    482  *
    483  * @return OK if no error.
    484  */
    485 status_t CameraSource::init(
    486         const sp<ICamera>& camera,
    487         const sp<ICameraRecordingProxy>& proxy,
    488         int32_t cameraId,
    489         const String16& clientName,
    490         uid_t clientUid,
    491         Size videoSize,
    492         int32_t frameRate,
    493         bool storeMetaDataInVideoBuffers) {
    494 
    495     ALOGV("init");
    496     status_t err = OK;
    497     int64_t token = IPCThreadState::self()->clearCallingIdentity();
    498     err = initWithCameraAccess(camera, proxy, cameraId, clientName, clientUid,
    499                                videoSize, frameRate,
    500                                storeMetaDataInVideoBuffers);
    501     IPCThreadState::self()->restoreCallingIdentity(token);
    502     return err;
    503 }
    504 
    505 status_t CameraSource::initWithCameraAccess(
    506         const sp<ICamera>& camera,
    507         const sp<ICameraRecordingProxy>& proxy,
    508         int32_t cameraId,
    509         const String16& clientName,
    510         uid_t clientUid,
    511         Size videoSize,
    512         int32_t frameRate,
    513         bool storeMetaDataInVideoBuffers) {
    514     ALOGV("initWithCameraAccess");
    515     status_t err = OK;
    516 
    517     if ((err = isCameraAvailable(camera, proxy, cameraId,
    518             clientName, clientUid)) != OK) {
    519         ALOGE("Camera connection could not be established.");
    520         return err;
    521     }
    522     CameraParameters params(mCamera->getParameters());
    523     if ((err = isCameraColorFormatSupported(params)) != OK) {
    524         return err;
    525     }
    526 
    527     // Set the camera to use the requested video frame size
    528     // and/or frame rate.
    529     if ((err = configureCamera(&params,
    530                     videoSize.width, videoSize.height,
    531                     frameRate))) {
    532         return err;
    533     }
    534 
    535     // Check on video frame size and frame rate.
    536     CameraParameters newCameraParams(mCamera->getParameters());
    537     if ((err = checkVideoSize(newCameraParams,
    538                 videoSize.width, videoSize.height)) != OK) {
    539         return err;
    540     }
    541     if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) {
    542         return err;
    543     }
    544 
    545     // Set the preview display. Skip this if mSurface is null because
    546     // applications may already set a surface to the camera.
    547     if (mSurface != NULL) {
    548         // This CHECK is good, since we just passed the lock/unlock
    549         // check earlier by calling mCamera->setParameters().
    550         CHECK_EQ((status_t)OK, mCamera->setPreviewTarget(mSurface));
    551     }
    552 
    553     // By default, do not store metadata in video buffers
    554     mIsMetaDataStoredInVideoBuffers = false;
    555     mCamera->storeMetaDataInBuffers(false);
    556     if (storeMetaDataInVideoBuffers) {
    557         if (OK == mCamera->storeMetaDataInBuffers(true)) {
    558             mIsMetaDataStoredInVideoBuffers = true;
    559         }
    560     }
    561 
    562     int64_t glitchDurationUs = (1000000LL / mVideoFrameRate);
    563     if (glitchDurationUs > mGlitchDurationThresholdUs) {
    564         mGlitchDurationThresholdUs = glitchDurationUs;
    565     }
    566 
    567     // XXX: query camera for the stride and slice height
    568     // when the capability becomes available.
    569     mMeta = new MetaData;
    570     mMeta->setCString(kKeyMIMEType,  MEDIA_MIMETYPE_VIDEO_RAW);
    571     mMeta->setInt32(kKeyColorFormat, mColorFormat);
    572     mMeta->setInt32(kKeyWidth,       mVideoSize.width);
    573     mMeta->setInt32(kKeyHeight,      mVideoSize.height);
    574     mMeta->setInt32(kKeyStride,      mVideoSize.width);
    575     mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
    576     mMeta->setInt32(kKeyFrameRate,   mVideoFrameRate);
    577     return OK;
    578 }
    579 
    580 CameraSource::~CameraSource() {
    581     if (mStarted) {
    582         reset();
    583     } else if (mInitCheck == OK) {
    584         // Camera is initialized but because start() is never called,
    585         // the lock on Camera is never released(). This makes sure
    586         // Camera's lock is released in this case.
    587         releaseCamera();
    588     }
    589 }
    590 
    591 status_t CameraSource::startCameraRecording() {
    592     ALOGV("startCameraRecording");
    593     // Reset the identity to the current thread because media server owns the
    594     // camera and recording is started by the applications. The applications
    595     // will connect to the camera in ICameraRecordingProxy::startRecording.
    596     int64_t token = IPCThreadState::self()->clearCallingIdentity();
    597     status_t err;
    598     if (mNumInputBuffers > 0) {
    599         err = mCamera->sendCommand(
    600             CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);
    601 
    602         // This could happen for CameraHAL1 clients; thus the failure is
    603         // not a fatal error
    604         if (err != OK) {
    605             ALOGW("Failed to set video buffer count to %d due to %d",
    606                 mNumInputBuffers, err);
    607         }
    608     }
    609 
    610     err = OK;
    611     if (mCameraFlags & FLAGS_HOT_CAMERA) {
    612         mCamera->unlock();
    613         mCamera.clear();
    614         if ((err = mCameraRecordingProxy->startRecording(
    615                 new ProxyListener(this))) != OK) {
    616             ALOGE("Failed to start recording, received error: %s (%d)",
    617                     strerror(-err), err);
    618         }
    619     } else {
    620         mCamera->setListener(new CameraSourceListener(this));
    621         mCamera->startRecording();
    622         if (!mCamera->recordingEnabled()) {
    623             err = -EINVAL;
    624             ALOGE("Failed to start recording");
    625         }
    626     }
    627     IPCThreadState::self()->restoreCallingIdentity(token);
    628     return err;
    629 }
    630 
    631 status_t CameraSource::start(MetaData *meta) {
    632     ALOGV("start");
    633     CHECK(!mStarted);
    634     if (mInitCheck != OK) {
    635         ALOGE("CameraSource is not initialized yet");
    636         return mInitCheck;
    637     }
    638 
    639     char value[PROPERTY_VALUE_MAX];
    640     if (property_get("media.stagefright.record-stats", value, NULL)
    641         && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
    642         mCollectStats = true;
    643     }
    644 
    645     mStartTimeUs = 0;
    646     mNumInputBuffers = 0;
    647     if (meta) {
    648         int64_t startTimeUs;
    649         if (meta->findInt64(kKeyTime, &startTimeUs)) {
    650             mStartTimeUs = startTimeUs;
    651         }
    652 
    653         int32_t nBuffers;
    654         if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
    655             CHECK_GT(nBuffers, 0);
    656             mNumInputBuffers = nBuffers;
    657         }
    658     }
    659 
    660     status_t err;
    661     if ((err = startCameraRecording()) == OK) {
    662         mStarted = true;
    663     }
    664 
    665     return err;
    666 }
    667 
    668 void CameraSource::stopCameraRecording() {
    669     ALOGV("stopCameraRecording");
    670     if (mCameraFlags & FLAGS_HOT_CAMERA) {
    671         mCameraRecordingProxy->stopRecording();
    672     } else {
    673         mCamera->setListener(NULL);
    674         mCamera->stopRecording();
    675     }
    676 }
    677 
    678 void CameraSource::releaseCamera() {
    679     ALOGV("releaseCamera");
    680     sp<Camera> camera;
    681     bool coldCamera = false;
    682     {
    683         Mutex::Autolock autoLock(mLock);
    684         // get a local ref and clear ref to mCamera now
    685         camera = mCamera;
    686         mCamera.clear();
    687         coldCamera = (mCameraFlags & FLAGS_HOT_CAMERA) == 0;
    688     }
    689 
    690     if (camera != 0) {
    691         int64_t token = IPCThreadState::self()->clearCallingIdentity();
    692         if (coldCamera) {
    693             ALOGV("Camera was cold when we started, stopping preview");
    694             camera->stopPreview();
    695             camera->disconnect();
    696         }
    697         camera->unlock();
    698         IPCThreadState::self()->restoreCallingIdentity(token);
    699     }
    700 
    701     {
    702         Mutex::Autolock autoLock(mLock);
    703         if (mCameraRecordingProxy != 0) {
    704             mCameraRecordingProxy->asBinder()->unlinkToDeath(mDeathNotifier);
    705             mCameraRecordingProxy.clear();
    706         }
    707         mCameraFlags = 0;
    708     }
    709 }
    710 
    711 status_t CameraSource::reset() {
    712     ALOGD("reset: E");
    713 
    714     {
    715         Mutex::Autolock autoLock(mLock);
    716         mStarted = false;
    717         mFrameAvailableCondition.signal();
    718 
    719         int64_t token;
    720         bool isTokenValid = false;
    721         if (mCamera != 0) {
    722             token = IPCThreadState::self()->clearCallingIdentity();
    723             isTokenValid = true;
    724         }
    725         releaseQueuedFrames();
    726         while (!mFramesBeingEncoded.empty()) {
    727             if (NO_ERROR !=
    728                 mFrameCompleteCondition.waitRelative(mLock,
    729                         mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
    730                 ALOGW("Timed out waiting for outstanding frames being encoded: %zu",
    731                     mFramesBeingEncoded.size());
    732             }
    733         }
    734         stopCameraRecording();
    735         if (isTokenValid) {
    736             IPCThreadState::self()->restoreCallingIdentity(token);
    737         }
    738 
    739         if (mCollectStats) {
    740             ALOGI("Frames received/encoded/dropped: %d/%d/%d in %" PRId64 " us",
    741                     mNumFramesReceived, mNumFramesEncoded, mNumFramesDropped,
    742                     mLastFrameTimestampUs - mFirstFrameTimeUs);
    743         }
    744 
    745         if (mNumGlitches > 0) {
    746             ALOGW("%d long delays between neighboring video frames", mNumGlitches);
    747         }
    748 
    749         CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
    750     }
    751 
    752     releaseCamera();
    753 
    754     ALOGD("reset: X");
    755     return OK;
    756 }
    757 
    758 void CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
    759     ALOGV("releaseRecordingFrame");
    760     if (mCameraRecordingProxy != NULL) {
    761         mCameraRecordingProxy->releaseRecordingFrame(frame);
    762     } else if (mCamera != NULL) {
    763         int64_t token = IPCThreadState::self()->clearCallingIdentity();
    764         mCamera->releaseRecordingFrame(frame);
    765         IPCThreadState::self()->restoreCallingIdentity(token);
    766     }
    767 }
    768 
    769 void CameraSource::releaseQueuedFrames() {
    770     List<sp<IMemory> >::iterator it;
    771     while (!mFramesReceived.empty()) {
    772         it = mFramesReceived.begin();
    773         releaseRecordingFrame(*it);
    774         mFramesReceived.erase(it);
    775         ++mNumFramesDropped;
    776     }
    777 }
    778 
    779 sp<MetaData> CameraSource::getFormat() {
    780     return mMeta;
    781 }
    782 
    783 void CameraSource::releaseOneRecordingFrame(const sp<IMemory>& frame) {
    784     releaseRecordingFrame(frame);
    785 }
    786 
    787 void CameraSource::signalBufferReturned(MediaBuffer *buffer) {
    788     ALOGV("signalBufferReturned: %p", buffer->data());
    789     Mutex::Autolock autoLock(mLock);
    790     for (List<sp<IMemory> >::iterator it = mFramesBeingEncoded.begin();
    791          it != mFramesBeingEncoded.end(); ++it) {
    792         if ((*it)->pointer() ==  buffer->data()) {
    793             releaseOneRecordingFrame((*it));
    794             mFramesBeingEncoded.erase(it);
    795             ++mNumFramesEncoded;
    796             buffer->setObserver(0);
    797             buffer->release();
    798             mFrameCompleteCondition.signal();
    799             return;
    800         }
    801     }
    802     CHECK(!"signalBufferReturned: bogus buffer");
    803 }
    804 
    805 status_t CameraSource::read(
    806         MediaBuffer **buffer, const ReadOptions *options) {
    807     ALOGV("read");
    808 
    809     *buffer = NULL;
    810 
    811     int64_t seekTimeUs;
    812     ReadOptions::SeekMode mode;
    813     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
    814         return ERROR_UNSUPPORTED;
    815     }
    816 
    817     sp<IMemory> frame;
    818     int64_t frameTime;
    819 
    820     {
    821         Mutex::Autolock autoLock(mLock);
    822         while (mStarted && mFramesReceived.empty()) {
    823             if (NO_ERROR !=
    824                 mFrameAvailableCondition.waitRelative(mLock,
    825                     mTimeBetweenFrameCaptureUs * 1000LL + CAMERA_SOURCE_TIMEOUT_NS)) {
    826                 if (mCameraRecordingProxy != 0 &&
    827                     !mCameraRecordingProxy->asBinder()->isBinderAlive()) {
    828                     ALOGW("camera recording proxy is gone");
    829                     return ERROR_END_OF_STREAM;
    830                 }
    831                 ALOGW("Timed out waiting for incoming camera video frames: %" PRId64 " us",
    832                     mLastFrameTimestampUs);
    833             }
    834         }
    835         if (!mStarted) {
    836             return OK;
    837         }
    838         frame = *mFramesReceived.begin();
    839         mFramesReceived.erase(mFramesReceived.begin());
    840 
    841         frameTime = *mFrameTimes.begin();
    842         mFrameTimes.erase(mFrameTimes.begin());
    843         mFramesBeingEncoded.push_back(frame);
    844         *buffer = new MediaBuffer(frame->pointer(), frame->size());
    845         (*buffer)->setObserver(this);
    846         (*buffer)->add_ref();
    847         (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
    848     }
    849     return OK;
    850 }
    851 
    852 void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
    853         int32_t msgType, const sp<IMemory> &data) {
    854     ALOGV("dataCallbackTimestamp: timestamp %" PRId64 " us", timestampUs);
    855     Mutex::Autolock autoLock(mLock);
    856     if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
    857         ALOGV("Drop frame at %" PRId64 "/%" PRId64 " us", timestampUs, mStartTimeUs);
    858         releaseOneRecordingFrame(data);
    859         return;
    860     }
    861 
    862     if (mNumFramesReceived > 0) {
    863         CHECK(timestampUs > mLastFrameTimestampUs);
    864         if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
    865             ++mNumGlitches;
    866         }
    867     }
    868 
    869     // May need to skip frame or modify timestamp. Currently implemented
    870     // by the subclass CameraSourceTimeLapse.
    871     if (skipCurrentFrame(timestampUs)) {
    872         releaseOneRecordingFrame(data);
    873         return;
    874     }
    875 
    876     mLastFrameTimestampUs = timestampUs;
    877     if (mNumFramesReceived == 0) {
    878         mFirstFrameTimeUs = timestampUs;
    879         // Initial delay
    880         if (mStartTimeUs > 0) {
    881             if (timestampUs < mStartTimeUs) {
    882                 // Frame was captured before recording was started
    883                 // Drop it without updating the statistical data.
    884                 releaseOneRecordingFrame(data);
    885                 return;
    886             }
    887             mStartTimeUs = timestampUs - mStartTimeUs;
    888         }
    889     }
    890     ++mNumFramesReceived;
    891 
    892     CHECK(data != NULL && data->size() > 0);
    893     mFramesReceived.push_back(data);
    894     int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
    895     mFrameTimes.push_back(timeUs);
    896     ALOGV("initial delay: %" PRId64 ", current time stamp: %" PRId64,
    897         mStartTimeUs, timeUs);
    898     mFrameAvailableCondition.signal();
    899 }
    900 
    901 bool CameraSource::isMetaDataStoredInVideoBuffers() const {
    902     ALOGV("isMetaDataStoredInVideoBuffers");
    903     return mIsMetaDataStoredInVideoBuffers;
    904 }
    905 
    906 CameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
    907     mSource = source;
    908 }
    909 
    910 void CameraSource::ProxyListener::dataCallbackTimestamp(
    911         nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) {
    912     mSource->dataCallbackTimestamp(timestamp / 1000, msgType, dataPtr);
    913 }
    914 
    915 void CameraSource::DeathNotifier::binderDied(const wp<IBinder>& who) {
    916     ALOGI("Camera recording proxy died");
    917 }
    918 
    919 }  // namespace android
    920