diff options
author | James Dong <jdong@google.com> | 2010-10-08 11:59:32 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-10-08 18:32:43 -0700 |
commit | 54ff19ac69ace7c05ea90d225e26dab3b133f487 (patch) | |
tree | abf0b910f9a40a2409d7e725c99c6144238d0625 /media | |
parent | fa6a5d481474ba11517c8d0eb6431595d387b81e (diff) | |
download | frameworks_av-54ff19ac69ace7c05ea90d225e26dab3b133f487.zip frameworks_av-54ff19ac69ace7c05ea90d225e26dab3b133f487.tar.gz frameworks_av-54ff19ac69ace7c05ea90d225e26dab3b133f487.tar.bz2 |
Move Camera specific logic out from StagefrightRecorder to CameraSource
o updated comments and streamlined the logic in
checkVideoSize() and checkFrameRate() as suggested
Change-Id: I49d04ac7998d4a215997aa63555dfb6e814e38d3
Diffstat (limited to 'media')
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.cpp | 172 | ||||
-rw-r--r-- | media/libmediaplayerservice/StagefrightRecorder.h | 13 | ||||
-rw-r--r-- | media/libstagefright/CameraSource.cpp | 382 | ||||
-rw-r--r-- | media/libstagefright/CameraSourceTimeLapse.cpp | 68 |
4 files changed, 391 insertions, 244 deletions
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 7a78185..06d5cd5 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -20,7 +20,6 @@ #include "StagefrightRecorder.h" -#include <binder/IPCThreadState.h> #include <media/stagefright/AudioSource.h> #include <media/stagefright/AMRWriter.h> #include <media/stagefright/CameraSource.h> @@ -35,7 +34,6 @@ #include <media/stagefright/OMXCodec.h> #include <media/MediaProfiles.h> #include <camera/ICamera.h> -#include <camera/Camera.h> #include <camera/CameraParameters.h> #include <surfaceflinger/Surface.h> #include <utils/Errors.h> @@ -184,22 +182,7 @@ status_t StagefrightRecorder::setCamera(const sp<ICamera> &camera) { return BAD_VALUE; } - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - mFlags &= ~FLAGS_HOT_CAMERA; - mCamera = Camera::create(camera); - if (mCamera == 0) { - LOGE("Unable to connect to camera"); - IPCThreadState::self()->restoreCallingIdentity(token); - return -EBUSY; - } - - LOGV("Connected to camera"); - if (mCamera->previewEnabled()) { - LOGV("camera is hot"); - mFlags |= FLAGS_HOT_CAMERA; - } - IPCThreadState::self()->restoreCallingIdentity(token); - + mCamera = camera; return OK; } @@ -966,66 +949,7 @@ void StagefrightRecorder::clipVideoFrameWidth() { } } -/* - * Check to see whether the requested video width and height is one - * of the supported sizes. It returns true if so; otherwise, it - * returns false. - */ -bool StagefrightRecorder::isVideoSizeSupported( - const Vector<Size>& supportedSizes) const { - - LOGV("isVideoSizeSupported"); - for (size_t i = 0; i < supportedSizes.size(); ++i) { - if (mVideoWidth == supportedSizes[i].width && - mVideoHeight == supportedSizes[i].height) { - return true; - } - } - return false; -} - -/* - * If the preview and video output is separate, we only set the - * the video size, and applications should set the preview size - * to some proper value, and the recording framework will not - * change the preview size; otherwise, if the video and preview - * output is the same, we need to set the preview to be the same - * as the requested video size. - * - * On return, it also returns whether the setVideoSize() is - * supported. - */ -status_t StagefrightRecorder::setCameraVideoSize( - CameraParameters* params, - bool* isSetVideoSizeSupported) { - LOGV("setCameraVideoSize: %dx%d", mVideoWidth, mVideoHeight); - - // Check whether the requested video size is supported - Vector<Size> sizes; - params->getSupportedVideoSizes(sizes); - *isSetVideoSizeSupported = true; - if (sizes.size() == 0) { - LOGD("Camera does not support setVideoSize()"); - params->getSupportedPreviewSizes(sizes); - *isSetVideoSizeSupported = false; - } - if (!isVideoSizeSupported(sizes)) { - LOGE("Camera does not support video size (%dx%d)!", - mVideoWidth, mVideoHeight); - return BAD_VALUE; - } - - // Actually set the video size - if (isSetVideoSizeSupported) { - params->setVideoSize(mVideoWidth, mVideoHeight); - } else { - params->setPreviewSize(mVideoWidth, mVideoHeight); - } - - return OK; -} - -status_t StagefrightRecorder::setupCamera() { +status_t StagefrightRecorder::checkVideoEncoderCapabilities() { if (!mCaptureTimeLapse) { // Dont clip for time lapse capture as encoder will have enough // time to encode because of slow capture rate of time lapse. @@ -1034,67 +958,6 @@ status_t StagefrightRecorder::setupCamera() { clipVideoFrameWidth(); clipVideoFrameHeight(); } - - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - if (mCamera == 0) { - mCamera = Camera::connect(mCameraId); - if (mCamera == 0) { - LOGE("Camera connection could not be established."); - return -EBUSY; - } - mFlags &= ~FLAGS_HOT_CAMERA; - mCamera->lock(); - } - - // Set the actual video recording frame size - CameraParameters params(mCamera->getParameters()); - - // dont change the preview size because time lapse may be using still camera - // as mVideoWidth, mVideoHeight may correspond to HD resolution not - // supported by the video camera. - bool isSetVideoSizeSupported = false; - if (!mCaptureTimeLapse) { - if (OK != setCameraVideoSize(¶ms, &isSetVideoSizeSupported)) { - return BAD_VALUE; - } - } - - params.setPreviewFrameRate(mFrameRate); - String8 s = params.flatten(); - if (OK != mCamera->setParameters(s)) { - LOGE("Could not change settings." - " Someone else is using camera %d?", mCameraId); - return -EBUSY; - } - CameraParameters newCameraParams(mCamera->getParameters()); - - // Check on video frame size - int frameWidth = 0, frameHeight = 0; - if (isSetVideoSizeSupported) { - newCameraParams.getVideoSize(&frameWidth, &frameHeight); - } else { - newCameraParams.getPreviewSize(&frameWidth, &frameHeight); - } - if (!mCaptureTimeLapse && - (frameWidth < 0 || frameWidth != mVideoWidth || - frameHeight < 0 || frameHeight != mVideoHeight)) { - LOGE("Failed to set the video frame size to %dx%d", - mVideoWidth, mVideoHeight); - IPCThreadState::self()->restoreCallingIdentity(token); - return UNKNOWN_ERROR; - } - - // Check on video frame rate - int frameRate = newCameraParams.getPreviewFrameRate(); - if (frameRate < 0 || (frameRate - mFrameRate) != 0) { - LOGE("Failed to set frame rate to %d fps. The actual " - "frame rate is %d", mFrameRate, frameRate); - } - - // This CHECK is good, since we just passed the lock/unlock - // check earlier by calling mCamera->setParameters(). - CHECK_EQ(OK, mCamera->setPreviewDisplay(mPreviewSurface)); - IPCThreadState::self()->restoreCallingIdentity(token); return OK; } @@ -1116,15 +979,18 @@ void StagefrightRecorder::clipVideoFrameHeight() { } status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) { - status_t err = setupCamera(); - if (err != OK) return err; - + Size videoSize; + videoSize.width = mVideoWidth; + videoSize.height = mVideoHeight; if (mCaptureTimeLapse) { - mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera(mCamera, - mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate); + mCameraSourceTimeLapse = CameraSourceTimeLapse::CreateFromCamera( + mCamera, mCameraId, + videoSize, mFrameRate, mPreviewSurface, + mTimeBetweenTimeLapseFrameCaptureUs); *cameraSource = mCameraSourceTimeLapse; } else { - *cameraSource = CameraSource::CreateFromCamera(mCamera); + *cameraSource = CameraSource::CreateFromCamera( + mCamera, mCameraId, videoSize, mFrameRate, mPreviewSurface); } CHECK(*cameraSource != NULL); @@ -1411,19 +1277,6 @@ status_t StagefrightRecorder::stop() { mWriter.clear(); } - if (mCamera != 0) { - LOGV("Disconnect camera"); - int64_t token = IPCThreadState::self()->clearCallingIdentity(); - if ((mFlags & FLAGS_HOT_CAMERA) == 0) { - LOGV("Camera was cold when we started, stopping preview"); - mCamera->stopPreview(); - } - mCamera->unlock(); - mCamera.clear(); - IPCThreadState::self()->restoreCallingIdentity(token); - mFlags = 0; - } - if (mOutputFd >= 0) { ::close(mOutputFd); mOutputFd = -1; @@ -1490,7 +1343,6 @@ status_t StagefrightRecorder::reset() { mOutputFd = -1; mOutputFdAux = -1; - mFlags = 0; return OK; } @@ -1561,8 +1413,6 @@ status_t StagefrightRecorder::dump( result.append(buffer); snprintf(buffer, SIZE, " Camera Id: %d\n", mCameraId); result.append(buffer); - snprintf(buffer, SIZE, " Camera flags: %d\n", mFlags); - result.append(buffer); snprintf(buffer, SIZE, " Encoder: %d\n", mVideoEncoder); result.append(buffer); snprintf(buffer, SIZE, " Encoder profile: %d\n", mVideoEncoderProfile); diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h index f14c704..039bc16 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.h +++ b/media/libmediaplayerservice/StagefrightRecorder.h @@ -63,12 +63,7 @@ struct StagefrightRecorder : public MediaRecorderBase { virtual status_t dump(int fd, const Vector<String16>& args) const; private: - enum CameraFlags { - FLAGS_SET_CAMERA = 1L << 0, - FLAGS_HOT_CAMERA = 1L << 1, - }; - - sp<Camera> mCamera; + sp<ICamera> mCamera; sp<Surface> mPreviewSurface; sp<IMediaRecorderClient> mListener; sp<MediaWriter> mWriter, mWriterAux; @@ -107,7 +102,6 @@ private: String8 mParams; int mOutputFd, mOutputFdAux; - int32_t mFlags; MediaProfiles *mEncoderProfiles; @@ -125,10 +119,7 @@ private: status_t startAACRecording(); status_t startRTPRecording(); sp<MediaSource> createAudioSource(); - status_t setupCamera(); - bool isVideoSizeSupported(const Vector<Size>& supportedSizes) const; - status_t setCameraVideoSize(CameraParameters* params, - bool *isSetVideoSizeSupported); + status_t checkVideoEncoderCapabilities(); status_t setupCameraSource(sp<CameraSource> *cameraSource); status_t setupAudioEncoder(const sp<MediaWriter>& writer); status_t setupVideoEncoder( diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 0c9eef4..f7b76f8 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -27,6 +27,7 @@ #include <media/stagefright/MetaData.h> #include <camera/Camera.h> #include <camera/CameraParameters.h> +#include <surfaceflinger/Surface.h> #include <utils/String8.h> #include <cutils/properties.h> @@ -108,28 +109,45 @@ static int32_t getColorFormat(const char* colorFormat) { CHECK_EQ(0, "Unknown color format"); } -// static CameraSource *CameraSource::Create() { - sp<Camera> camera = Camera::connect(0); - - if (camera.get() == NULL) { - return NULL; - } + Size size; + size.width = -1; + size.height = -1; - return new CameraSource(camera); + sp<ICamera> camera; + return new CameraSource(camera, 0, size, -1, NULL); } // static -CameraSource *CameraSource::CreateFromCamera(const sp<Camera> &camera) { - if (camera.get() == NULL) { - return NULL; +CameraSource *CameraSource::CreateFromCamera( + const sp<ICamera>& camera, + int32_t cameraId, + Size videoSize, + int32_t frameRate, + const sp<Surface>& surface) { + + CameraSource *source = new CameraSource(camera, cameraId, + videoSize, frameRate, surface); + + if (source != NULL) { + if (source->initCheck() != OK) { + delete source; + return NULL; + } } - - return new CameraSource(camera); + return source; } -CameraSource::CameraSource(const sp<Camera> &camera) - : mCamera(camera), +CameraSource::CameraSource( + const sp<ICamera>& camera, + int32_t cameraId, + Size videoSize, + int32_t frameRate, + const sp<Surface>& surface) + : mCameraFlags(0), + mVideoFrameRate(-1), + mCamera(0), + mSurface(surface), mNumFramesReceived(0), mLastFrameTimestampUs(0), mStarted(false), @@ -140,39 +158,316 @@ CameraSource::CameraSource(const sp<Camera> &camera) mGlitchDurationThresholdUs(200000), mCollectStats(false) { + mVideoSize.width = -1; + mVideoSize.height = -1; + + mInitCheck = init(camera, cameraId, videoSize, frameRate); +} + +status_t CameraSource::initCheck() const { + return mInitCheck; +} + +status_t CameraSource::isCameraAvailable( + const sp<ICamera>& camera, int32_t cameraId) { + + if (camera == 0) { + mCamera = Camera::connect(cameraId); + mCameraFlags &= ~FLAGS_HOT_CAMERA; + } else { + mCamera = Camera::create(camera); + mCameraFlags |= FLAGS_HOT_CAMERA; + } + + // Is camera available? + if (mCamera == 0) { + LOGE("Camera connection could not be established."); + return -EBUSY; + } + if (!(mCameraFlags & FLAGS_HOT_CAMERA)) { + mCamera->lock(); + } + return OK; +} + + +/* + * Check to see whether the requested video width and height is one + * of the supported sizes. + * @param width the video frame width in pixels + * @param height the video frame height in pixels + * @param suppportedSizes the vector of sizes that we check against + * @return true if the dimension (width and height) is supported. + */ +static bool isVideoSizeSupported( + int32_t width, int32_t height, + const Vector<Size>& supportedSizes) { + + LOGV("isVideoSizeSupported"); + for (size_t i = 0; i < supportedSizes.size(); ++i) { + if (width == supportedSizes[i].width && + height == supportedSizes[i].height) { + return true; + } + } + return false; +} + +/* + * If the preview and video output is separate, we only set the + * the video size, and applications should set the preview size + * to some proper value, and the recording framework will not + * change the preview size; otherwise, if the video and preview + * output is the same, we need to set the preview to be the same + * as the requested video size. + * + */ +/* + * Query the camera to retrieve the supported video frame sizes + * and also to see whether CameraParameters::setVideoSize() + * is supported or not. + * @param params CameraParameters to retrieve the information + * @@param isSetVideoSizeSupported retunrs whether method + * CameraParameters::setVideoSize() is supported or not. + * @param sizes returns the vector of Size objects for the + * supported video frame sizes advertised by the camera. + */ +static void getSupportedVideoSizes( + const CameraParameters& params, + bool *isSetVideoSizeSupported, + Vector<Size>& sizes) { + + *isSetVideoSizeSupported = true; + params.getSupportedVideoSizes(sizes); + if (sizes.size() == 0) { + LOGD("Camera does not support setVideoSize()"); + params.getSupportedPreviewSizes(sizes); + *isSetVideoSizeSupported = false; + } +} + +/* + * Check whether the camera has the supported color format + * @param params CameraParameters to retrieve the information + * @return OK if no error. + */ +status_t CameraSource::isCameraColorFormatSupported( + const CameraParameters& params) { + mColorFormat = getColorFormat(params.get( + CameraParameters::KEY_VIDEO_FRAME_FORMAT)); + if (mColorFormat == -1) { + return BAD_VALUE; + } + return OK; +} + +/* + * Configure the camera to use the requested video size + * (width and height) and/or frame rate. If both width and + * height are -1, configuration on the video size is skipped. + * if frameRate is -1, configuration on the frame rate + * is skipped. Skipping the configuration allows one to + * use the current camera setting without the need to + * actually know the specific values (see Create() method). + * + * @param params the CameraParameters to be configured + * @param width the target video frame width in pixels + * @param height the target video frame height in pixels + * @param frameRate the target frame rate in frames per second. + * @return OK if no error. + */ +status_t CameraSource::configureCamera( + CameraParameters* params, + int32_t width, int32_t height, + int32_t frameRate) { + + Vector<Size> sizes; + bool isSetVideoSizeSupportedByCamera = true; + getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes); + bool isCameraParamChanged = false; + if (width != -1 && height != -1) { + if (!isVideoSizeSupported(width, height, sizes)) { + LOGE("Video dimension (%dx%d) is unsupported", width, height); + return BAD_VALUE; + } + if (isSetVideoSizeSupportedByCamera) { + params->setVideoSize(width, height); + } else { + params->setPreviewSize(width, height); + } + isCameraParamChanged = true; + } else if ((width == -1 && height != -1) || + (width != -1 && height == -1)) { + // If one and only one of the width and height is -1 + // we reject such a request. + LOGE("Requested video size (%dx%d) is not supported", width, height); + return BAD_VALUE; + } else { // width == -1 && height == -1 + // Do not configure the camera. + // Use the current width and height value setting from the camera. + } + + if (frameRate != -1) { + params->setPreviewFrameRate(frameRate); + isCameraParamChanged = true; + } else { // frameRate == -1 + // Do not configure the camera. + // Use the current frame rate value setting from the camera + } + + if (isCameraParamChanged) { + // Either frame rate or frame size needs to be changed. + String8 s = params->flatten(); + if (OK != mCamera->setParameters(s)) { + LOGE("Could not change settings." + " Someone else is using camera %p?", mCamera.get()); + return -EBUSY; + } + } + return OK; +} + +/* + * Check whether the requested video frame size + * has been successfully configured or not. If both width and height + * are -1, check on the current width and height value setting + * is performed. + * + * @param params CameraParameters to retrieve the information + * @param the target video frame width in pixels to check against + * @param the target video frame height in pixels to check against + * @return OK if no error + */ +status_t CameraSource::checkVideoSize( + const CameraParameters& params, + int32_t width, int32_t height) { + + int32_t frameWidthActual = -1; + int32_t frameHeightActual = -1; + params.getPreviewSize(&frameWidthActual, &frameHeightActual); + if (frameWidthActual < 0 || frameHeightActual < 0) { + LOGE("Failed to retrieve video frame size (%dx%d)", + frameWidthActual, frameHeightActual); + return UNKNOWN_ERROR; + } + + // Check the actual video frame size against the target/requested + // video frame size. + if (width != -1 && height != -1) { + if (frameWidthActual != width || frameHeightActual != height) { + LOGE("Failed to set video frame size to %dx%d. " + "The actual video size is %dx%d ", width, height, + frameWidthActual, frameHeightActual); + return UNKNOWN_ERROR; + } + } + + // Good now. + mVideoSize.width = frameWidthActual; + mVideoSize.height = frameHeightActual; + return OK; +} + +/* + * Check the requested frame rate has been successfully configured or not. + * If the target frameRate is -1, check on the current frame rate value + * setting is performed. + * + * @param params CameraParameters to retrieve the information + * @param the target video frame rate to check against + * @return OK if no error. + */ +status_t CameraSource::checkFrameRate( + const CameraParameters& params, + int32_t frameRate) { + + int32_t frameRateActual = params.getPreviewFrameRate(); + if (frameRateActual < 0) { + LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual); + return UNKNOWN_ERROR; + } + + // Check the actual video frame rate against the target/requested + // video frame rate. + if (frameRate != -1 && (frameRateActual - frameRate) != 0) { + LOGE("Failed to set preview frame rate to %d fps. The actual " + "frame rate is %d", frameRate, frameRateActual); + return UNKNOWN_ERROR; + } + + // Good now. + mVideoFrameRate = frameRateActual; + return OK; +} + +/* + * Initialize the CameraSource to so that it becomes + * ready for providing the video input streams as requested. + * @param camera the camera object used for the video source + * @param cameraId if camera == 0, use camera with this id + * as the video source + * @param videoSize the target video frame size. If both + * width and height in videoSize is -1, use the current + * width and heigth settings by the camera + * @param frameRate the target frame rate in frames per second. + * if it is -1, use the current camera frame rate setting. + * @return OK if no error. + */ +status_t CameraSource::init( + const sp<ICamera>& camera, + int32_t cameraId, + Size videoSize, + int32_t frameRate) { + + status_t err = OK; int64_t token = IPCThreadState::self()->clearCallingIdentity(); - String8 s = mCamera->getParameters(); - IPCThreadState::self()->restoreCallingIdentity(token); - printf("params: \"%s\"\n", s.string()); + if ((err = isCameraAvailable(camera, cameraId)) != OK) { + return err; + } + CameraParameters params(mCamera->getParameters()); + if ((err = isCameraColorFormatSupported(params)) != OK) { + return err; + } - int32_t width, height, stride, sliceHeight; - CameraParameters params(s); - params.getPreviewSize(&width, &height); + // Set the camera to use the requested video frame size + // and/or frame rate. + if ((err = configureCamera(¶ms, + videoSize.width, videoSize.height, + frameRate))) { + return err; + } - // Calculate glitch duraton threshold based on frame rate - int32_t frameRate = params.getPreviewFrameRate(); - int64_t glitchDurationUs = (1000000LL / frameRate); + // Check on video frame size and frame rate. + CameraParameters newCameraParams(mCamera->getParameters()); + if ((err = checkVideoSize(newCameraParams, + videoSize.width, videoSize.height)) != OK) { + return err; + } + if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) { + return err; + } + + // This CHECK is good, since we just passed the lock/unlock + // check earlier by calling mCamera->setParameters(). + CHECK_EQ(OK, mCamera->setPreviewDisplay(mSurface)); + IPCThreadState::self()->restoreCallingIdentity(token); + + int64_t glitchDurationUs = (1000000LL / mVideoFrameRate); if (glitchDurationUs > mGlitchDurationThresholdUs) { mGlitchDurationThresholdUs = glitchDurationUs; } - const char *colorFormatStr = params.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT); - CHECK(colorFormatStr != NULL); - int32_t colorFormat = getColorFormat(colorFormatStr); - // XXX: query camera for the stride and slice height // when the capability becomes available. - stride = width; - sliceHeight = height; - mMeta = new MetaData; - mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); - mMeta->setInt32(kKeyColorFormat, colorFormat); - mMeta->setInt32(kKeyWidth, width); - mMeta->setInt32(kKeyHeight, height); - mMeta->setInt32(kKeyStride, stride); - mMeta->setInt32(kKeySliceHeight, sliceHeight); + mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); + mMeta->setInt32(kKeyColorFormat, mColorFormat); + mMeta->setInt32(kKeyWidth, mVideoSize.width); + mMeta->setInt32(kKeyHeight, mVideoSize.height); + mMeta->setInt32(kKeyStride, mVideoSize.width); + mMeta->setInt32(kKeySliceHeight, mVideoSize.height); + return OK; } CameraSource::~CameraSource() { @@ -187,6 +482,10 @@ void CameraSource::startCameraRecording() { status_t CameraSource::start(MetaData *meta) { CHECK(!mStarted); + if (mInitCheck != OK) { + LOGE("CameraSource is not initialized yet"); + return mInitCheck; + } char value[PROPERTY_VALUE_MAX]; if (property_get("media.stagefright.record-stats", value, NULL) @@ -228,7 +527,16 @@ status_t CameraSource::stop() { mFramesBeingEncoded.size()); mFrameCompleteCondition.wait(mLock); } - mCamera = NULL; + + LOGV("Disconnect camera"); + if ((mCameraFlags & FLAGS_HOT_CAMERA) == 0) { + LOGV("Camera was cold when we started, stopping preview"); + mCamera->stopPreview(); + } + mCamera->unlock(); + mCamera.clear(); + mCamera = 0; + mCameraFlags = 0; IPCThreadState::self()->restoreCallingIdentity(token); if (mCollectStats) { diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp index c1bc433..2f3f20b 100644 --- a/media/libstagefright/CameraSourceTimeLapse.cpp +++ b/media/libstagefright/CameraSourceTimeLapse.cpp @@ -37,57 +37,55 @@ namespace android { // static -CameraSourceTimeLapse *CameraSourceTimeLapse::Create( - int64_t timeBetweenTimeLapseFrameCaptureUs, - int32_t width, int32_t height, - int32_t videoFrameRate) { - sp<Camera> camera = Camera::connect(0); - - if (camera.get() == NULL) { - return NULL; - } - - return new CameraSourceTimeLapse(camera, timeBetweenTimeLapseFrameCaptureUs, - width, height, videoFrameRate); -} - -// static -CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(const sp<Camera> &camera, - int64_t timeBetweenTimeLapseFrameCaptureUs, - int32_t width, int32_t height, - int32_t videoFrameRate) { - if (camera.get() == NULL) { - return NULL; +CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera( + const sp<ICamera> &camera, + int32_t cameraId, + Size videoSize, + int32_t videoFrameRate, + const sp<Surface>& surface, + int64_t timeBetweenTimeLapseFrameCaptureUs) { + + CameraSourceTimeLapse *source = new + CameraSourceTimeLapse(camera, cameraId, + videoSize, videoFrameRate, surface, + timeBetweenTimeLapseFrameCaptureUs); + + if (source != NULL) { + if (source->initCheck() != OK) { + delete source; + return NULL; + } } - - return new CameraSourceTimeLapse(camera, timeBetweenTimeLapseFrameCaptureUs, - width, height, videoFrameRate); + return source; } -CameraSourceTimeLapse::CameraSourceTimeLapse(const sp<Camera> &camera, - int64_t timeBetweenTimeLapseFrameCaptureUs, - int32_t width, int32_t height, - int32_t videoFrameRate) - : CameraSource(camera), +CameraSourceTimeLapse::CameraSourceTimeLapse( + const sp<ICamera>& camera, + int32_t cameraId, + Size videoSize, + int32_t videoFrameRate, + const sp<Surface>& surface, + int64_t timeBetweenTimeLapseFrameCaptureUs) + : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface), mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs), mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate), mLastTimeLapseFrameRealTimestampUs(0), mSkipCurrentFrame(false) { LOGV("starting time lapse mode"); - mVideoWidth = width; - mVideoHeight = height; + mVideoWidth = videoSize.width; + mVideoHeight = videoSize.height; - if (trySettingPreviewSize(width, height)) { + if (trySettingPreviewSize(videoSize.width, videoSize.height)) { mUseStillCameraForTimeLapse = false; } else { // TODO: Add a check to see that mTimeBetweenTimeLapseFrameCaptureUs is greater // than the fastest rate at which the still camera can take pictures. mUseStillCameraForTimeLapse = true; - CHECK(setPictureSizeToClosestSupported(width, height)); + CHECK(setPictureSizeToClosestSupported(videoSize.width, videoSize.height)); mNeedCropping = computeCropRectangleOffset(); - mMeta->setInt32(kKeyWidth, width); - mMeta->setInt32(kKeyHeight, height); + mMeta->setInt32(kKeyWidth, videoSize.width); + mMeta->setInt32(kKeyHeight, videoSize.height); } // Initialize quick stop variables. |