Loading camera/ProCamera.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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( Loading @@ -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; Loading Loading @@ -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; Loading camera/tests/ProCameraTests.cpp +54 −2 Original line number Diff line number Diff line Loading @@ -1061,7 +1061,7 @@ TEST_F(ProCameraTest, WaitForDualStreamBuffer) { EXPECT_OK(mCamera->exclusiveUnlock()); } TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) { if (HasFatalFailure()) { return; } Loading @@ -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()); Loading Loading @@ -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 Loading include/camera/ProCamera.h +7 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,12 @@ public: /*out*/ sp<CpuConsumer>* cpuConsumer, int* streamId); status_t createStreamCpu(int width, int height, int format, int heapCount, bool synchronousMode, /*out*/ sp<CpuConsumer>* cpuConsumer, int* streamId); // Create a request object from a template. status_t createDefaultRequest(int templateId, Loading Loading @@ -296,6 +302,7 @@ private: int streamID; bool cpuStream; sp<CpuConsumer> cpuConsumer; bool synchronousMode; sp<ProFrameListener> frameAvailableListener; sp<Surface> stc; int frameReady; Loading Loading
camera/ProCamera.cpp +20 −1 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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( Loading @@ -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; Loading Loading @@ -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; Loading
camera/tests/ProCameraTests.cpp +54 −2 Original line number Diff line number Diff line Loading @@ -1061,7 +1061,7 @@ TEST_F(ProCameraTest, WaitForDualStreamBuffer) { EXPECT_OK(mCamera->exclusiveUnlock()); } TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFrames) { TEST_F(ProCameraTest, WaitForSingleStreamBufferAndDropFramesSync) { if (HasFatalFailure()) { return; } Loading @@ -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()); Loading Loading @@ -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 Loading
include/camera/ProCamera.h +7 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,12 @@ public: /*out*/ sp<CpuConsumer>* cpuConsumer, int* streamId); status_t createStreamCpu(int width, int height, int format, int heapCount, bool synchronousMode, /*out*/ sp<CpuConsumer>* cpuConsumer, int* streamId); // Create a request object from a template. status_t createDefaultRequest(int templateId, Loading Loading @@ -296,6 +302,7 @@ private: int streamID; bool cpuStream; sp<CpuConsumer> cpuConsumer; bool synchronousMode; sp<ProFrameListener> frameAvailableListener; sp<Surface> stc; int frameReady; Loading