summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2010-10-08 11:59:32 -0700
committerJames Dong <jdong@google.com>2010-10-08 18:32:43 -0700
commit54ff19ac69ace7c05ea90d225e26dab3b133f487 (patch)
treeabf0b910f9a40a2409d7e725c99c6144238d0625 /media
parentfa6a5d481474ba11517c8d0eb6431595d387b81e (diff)
downloadframeworks_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.cpp172
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h13
-rw-r--r--media/libstagefright/CameraSource.cpp382
-rw-r--r--media/libstagefright/CameraSourceTimeLapse.cpp68
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(&params, &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(&params,
+ 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.