diff options
author | Igor Murashkin <iam@google.com> | 2013-02-28 11:21:00 -0800 |
---|---|---|
committer | Igor Murashkin <iam@google.com> | 2013-02-28 16:25:55 -0800 |
commit | fb413768551ea8ba3af05efb9906e7e2348f2431 (patch) | |
tree | 86da75f59deea0393f167bd604a60f5acf0b028e /camera | |
parent | 8fdfbe27acd157d58fa35a849ec50c82464062f0 (diff) | |
download | frameworks_av-fb413768551ea8ba3af05efb9906e7e2348f2431.zip frameworks_av-fb413768551ea8ba3af05efb9906e7e2348f2431.tar.gz frameworks_av-fb413768551ea8ba3af05efb9906e7e2348f2431.tar.bz2 |
ProCamera: Add CpuConsumer asynchronous mode support
Bug: 8290146
Bug: 8291751
Change-Id: I25423a2b8a70ac7169911b1c7b482aa17190fe0f
Diffstat (limited to 'camera')
-rw-r--r-- | camera/ProCamera.cpp | 21 | ||||
-rw-r--r-- | camera/tests/ProCameraTests.cpp | 56 |
2 files changed, 74 insertions, 3 deletions
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp index 13ba07c..3cfabf6 100644 --- a/camera/ProCamera.cpp +++ b/camera/ProCamera.cpp @@ -241,6 +241,17 @@ status_t ProCamera::createStreamCpu(int width, int height, int format, int heapCount, /*out*/ sp<CpuConsumer>* cpuConsumer, + int* streamId) { + return createStreamCpu(width, height, format, heapCount, + /*synchronousMode*/true, + cpuConsumer, streamId); +} + +status_t ProCamera::createStreamCpu(int width, int height, int format, + int heapCount, + bool synchronousMode, + /*out*/ + sp<CpuConsumer>* cpuConsumer, int* streamId) { ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height, @@ -251,7 +262,7 @@ status_t ProCamera::createStreamCpu(int width, int height, int format, sp <IProCameraUser> c = mCamera; if (c == 0) return NO_INIT; - sp<CpuConsumer> cc = new CpuConsumer(heapCount); + sp<CpuConsumer> cc = new CpuConsumer(heapCount, synchronousMode); cc->setName(String8("ProCamera::mCpuConsumer")); sp<Surface> stc = new Surface( @@ -272,6 +283,7 @@ status_t ProCamera::createStreamCpu(int width, int height, int format, getStreamInfo(*streamId).cpuStream = true; getStreamInfo(*streamId).cpuConsumer = cc; + getStreamInfo(*streamId).synchronousMode = synchronousMode; getStreamInfo(*streamId).stc = stc; // for lifetime management getStreamInfo(*streamId).frameAvailableListener = frameAvailableListener; @@ -373,6 +385,13 @@ int ProCamera::dropFrameBuffer(int streamId, int count) { return BAD_VALUE; } + if (!si.synchronousMode) { + ALOGW("%s: No need to drop frames on asynchronous streams," + " as asynchronous mode only keeps 1 latest frame around.", + __FUNCTION__); + return BAD_VALUE; + } + int numDropped = 0; for (int i = 0; i < count; ++i) { CpuConsumer::LockedBuffer buffer; diff --git a/camera/tests/ProCameraTests.cpp b/camera/tests/ProCameraTests.cpp index c61e71a..1a8564e 100644 --- a/camera/tests/ProCameraTests.cpp +++ b/camera/tests/ProCameraTests.cpp @@ -1061,7 +1061,7 @@ TEST_F(ProCameraTest, WaitForDualStreamBuffer) { EXPECT_OK(mCamera->exclusiveUnlock()); } -TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { +TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) { if (HasFatalFailure()) { return; } @@ -1071,7 +1071,8 @@ TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { int streamId = -1; sp<CpuConsumer> consumer; EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, - TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId)); + TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, + /*synchronousMode*/true, &consumer, &streamId)); EXPECT_NE(-1, streamId); EXPECT_OK(mCamera->exclusiveTryLock()); @@ -1114,6 +1115,57 @@ TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { EXPECT_OK(mCamera->exclusiveUnlock()); } +TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesAsync) { + if (HasFatalFailure()) { + return; + } + + const int NUM_REQUESTS = 20 * TEST_CPU_FRAME_COUNT; + + int streamId = -1; + sp<CpuConsumer> consumer; + EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, + TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, + /*synchronousMode*/false, &consumer, &streamId)); + EXPECT_NE(-1, streamId); + + EXPECT_OK(mCamera->exclusiveTryLock()); + + uint8_t streams[] = { streamId }; + ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1, + /*requests*/NUM_REQUESTS)); + + // Consume a couple of results + for (int i = 0; i < NUM_REQUESTS; ++i) { + int numFrames; + EXPECT_TRUE((numFrames = mCamera->waitForFrameBuffer(streamId)) > 0); + + dout << "Dropped " << (numFrames - 1) << " frames" << std::endl; + + // Skip the counter ahead, don't try to consume these frames again + i += numFrames-1; + + // "Consume" the buffer + CpuConsumer::LockedBuffer buf; + EXPECT_OK(consumer->lockNextBuffer(&buf)); + + dout << "Buffer asynchronously received on streamId = " << streamId << + ", dataPtr = " << (void*)buf.data << + ", timestamp = " << buf.timestamp << std::endl; + + // Process at 10fps, stream is at 15fps. + // This means we will definitely fill up the buffer queue with + // extra buffers and need to drop them. + usleep(TEST_FRAME_PROCESSING_DELAY_US); + + EXPECT_OK(consumer->unlockBuffer(buf)); + } + + // Done: clean up + EXPECT_OK(mCamera->deleteStream(streamId)); + EXPECT_OK(mCamera->exclusiveUnlock()); +} + //TODO: refactor into separate file |