summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Dong <jdong@google.com>2012-08-01 16:39:55 -0700
committerJames Dong <jdong@google.com>2012-08-02 17:06:05 -0700
commit983cf231ab2d176a14595cdae46ff1b0c239af47 (patch)
tree01942a13a082e2116f8df5dbaca1a902ac52a299
parent15d7245ed2193e4956ea87998321cbc16a3b0a46 (diff)
downloadframeworks_av-983cf231ab2d176a14595cdae46ff1b0c239af47.zip
frameworks_av-983cf231ab2d176a14595cdae46ff1b0c239af47.tar.gz
frameworks_av-983cf231ab2d176a14595cdae46ff1b0c239af47.tar.bz2
Dynamically configure the number of video buffers used by camera source, if supported
o related-to-bug: 6920805 Change-Id: I413bb50954cc84e32ed40bcb713842dc7b58e2b6
-rw-r--r--include/media/stagefright/CameraSource.h1
-rwxr-xr-xmedia/libstagefright/CameraSource.cpp28
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp39
-rw-r--r--services/camera/libcameraservice/Camera2Client.h3
-rw-r--r--services/camera/libcameraservice/CameraClient.cpp3
5 files changed, 63 insertions, 11 deletions
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 5a35358..6d6b8a9 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -137,6 +137,7 @@ protected:
int32_t mCameraFlags;
Size mVideoSize;
+ int32_t mNumInputBuffers;
int32_t mVideoFrameRate;
int32_t mColorFormat;
status_t mInitCheck;
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index a604c8f..efd7af7 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -155,6 +155,7 @@ CameraSource::CameraSource(
const sp<Surface>& surface,
bool storeMetaDataInVideoBuffers)
: mCameraFlags(0),
+ mNumInputBuffers(0),
mVideoFrameRate(-1),
mCamera(0),
mSurface(surface),
@@ -571,6 +572,18 @@ void CameraSource::startCameraRecording() {
// camera and recording is started by the applications. The applications
// will connect to the camera in ICameraRecordingProxy::startRecording.
int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ if (mNumInputBuffers > 0) {
+ status_t err = mCamera->sendCommand(
+ CAMERA_CMD_SET_VIDEO_BUFFER_COUNT, mNumInputBuffers, 0);
+
+ // This could happen for CameraHAL1 clients; thus the failure is
+ // not a fatal error
+ if (err != OK) {
+ ALOGW("Failed to set video buffer count to %d due to %d",
+ mNumInputBuffers, err);
+ }
+ }
+
if (mCameraFlags & FLAGS_HOT_CAMERA) {
mCamera->unlock();
mCamera.clear();
@@ -599,9 +612,18 @@ status_t CameraSource::start(MetaData *meta) {
}
mStartTimeUs = 0;
- int64_t startTimeUs;
- if (meta && meta->findInt64(kKeyTime, &startTimeUs)) {
- mStartTimeUs = startTimeUs;
+ mNumInputBuffers = 0;
+ if (meta) {
+ int64_t startTimeUs;
+ if (meta->findInt64(kKeyTime, &startTimeUs)) {
+ mStartTimeUs = startTimeUs;
+ }
+
+ int32_t nBuffers;
+ if (meta->findInt32(kKeyNumBuffers, &nBuffers)) {
+ CHECK_GT(nBuffers, 0);
+ mNumInputBuffers = nBuffers;
+ }
}
startCameraRecording();
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 3f1a677..6e26b5f 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -58,7 +58,8 @@ Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
mCaptureStreamId(NO_STREAM),
mCaptureRequest(NULL),
mRecordingStreamId(NO_STREAM),
- mRecordingRequest(NULL)
+ mRecordingRequest(NULL),
+ mRecordingHeapCount(kDefaultRecordingHeapCount)
{
ATRACE_CALL();
@@ -1544,6 +1545,30 @@ status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
} else {
return NO_INIT;
}
+ } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
+ if (recordingEnabled()) {
+ ALOGE("%s: Camera %d: Error setting video buffer count after "
+ "recording was started", __FUNCTION__, mCameraId);
+ return INVALID_OPERATION;
+ }
+
+ // 32 is the current upper limit on the video buffer count for BufferQueue
+ if (arg1 <= 0 || arg1 > 32) {
+ ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
+ __FUNCTION__, mCameraId, arg1);
+ return BAD_VALUE;
+ }
+
+ // Need to reallocate memory for heap
+ if (mRecordingHeapCount != arg1) {
+ if (mRecordingHeap != 0) {
+ mRecordingHeap.clear();
+ mRecordingHeap = NULL;
+ }
+ mRecordingHeapCount = arg1;
+ }
+
+ return OK;
}
ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
@@ -1649,17 +1674,17 @@ void Camera2Client::onRecordingFrameAvailable() {
const size_t bufferSize = 4 + sizeof(buffer_handle_t);
ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
"size %d bytes", __FUNCTION__, mCameraId,
- kRecordingHeapCount, bufferSize);
+ mRecordingHeapCount, bufferSize);
if (mRecordingHeap != 0) {
ALOGV("%s: Camera %d: Previous heap has size %d "
"(new will be %d) bytes", __FUNCTION__, mCameraId,
mRecordingHeap->mHeap->getSize(),
- bufferSize * kRecordingHeapCount);
+ bufferSize * mRecordingHeapCount);
}
// Need to allocate memory for heap
mRecordingHeap.clear();
- mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
+ mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
"Camera2Client::RecordingHeap");
if (mRecordingHeap->mHeap->getSize() == 0) {
ALOGE("%s: Camera %d: Unable to allocate memory for recording",
@@ -1668,7 +1693,7 @@ void Camera2Client::onRecordingFrameAvailable() {
return;
}
mRecordingHeapHead = 0;
- mRecordingHeapFree = kRecordingHeapCount;
+ mRecordingHeapFree = mRecordingHeapCount;
}
if ( mRecordingHeapFree == 0) {
@@ -1678,7 +1703,7 @@ void Camera2Client::onRecordingFrameAvailable() {
return;
}
heapIdx = mRecordingHeapHead;
- mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
+ mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
mRecordingHeapFree--;
ALOGV("%s: Camera %d: Timestamp %lld",
@@ -2688,7 +2713,7 @@ status_t Camera2Client::updateRecordingStream(const Parameters &params) {
if (mRecordingConsumer == 0) {
// Create CPU buffer queue endpoint
- mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
+ mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
mRecordingWindow = new SurfaceTextureClient(
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 8ae16a4..9bea8f1 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -288,7 +288,8 @@ private:
// TODO: This needs to be queried from somewhere, or the BufferQueue needs
// to be passed all the way to stagefright. Right now, set to a large number
// to avoid starvation of the video encoders.
- static const size_t kRecordingHeapCount = 8;
+ static const size_t kDefaultRecordingHeapCount = 8;
+ size_t mRecordingHeapCount;
size_t mRecordingHeapHead, mRecordingHeapFree;
// Handle new recording image buffers
void onRecordingFrameAvailable();
diff --git a/services/camera/libcameraservice/CameraClient.cpp b/services/camera/libcameraservice/CameraClient.cpp
index 54829ef..562384d 100644
--- a/services/camera/libcameraservice/CameraClient.cpp
+++ b/services/camera/libcameraservice/CameraClient.cpp
@@ -619,6 +619,9 @@ status_t CameraClient::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
return OK;
} else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
mCameraService->playSound(CameraService::SOUND_RECORDING);
+ } else if (cmd == CAMERA_CMD_SET_VIDEO_BUFFER_COUNT) {
+ // Silently ignore this command
+ return INVALID_OPERATION;
} else if (cmd == CAMERA_CMD_PING) {
// If mHardware is 0, checkPidAndHardware will return error.
return OK;