Loading services/camera/libcameraservice/Camera2Client.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,9 @@ status_t Camera2Client::initialize(camera_module_t *module) String8 threadName; mStreamingProcessor = new StreamingProcessor(this); threadName = String8::format("C2-%d-StreamProc", mCameraId); mStreamingProcessor->run(threadName.string()); mFrameProcessor = new FrameProcessor(mDevice, this); threadName = String8::format("C2-%d-FrameProc", Loading Loading @@ -411,6 +414,7 @@ void Camera2Client::disconnect() { mCallbackProcessor->deleteStream(); mZslProcessor->deleteStream(); mStreamingProcessor->requestExit(); mFrameProcessor->requestExit(); mCaptureSequencer->requestExit(); mJpegProcessor->requestExit(); Loading @@ -419,6 +423,7 @@ void Camera2Client::disconnect() { ALOGV("Camera %d: Waiting for threads", mCameraId); mStreamingProcessor->join(); mFrameProcessor->join(); mCaptureSequencer->join(); mJpegProcessor->join(); Loading services/camera/libcameraservice/camera2/StreamingProcessor.cpp +46 −11 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ StreamingProcessor::StreamingProcessor(sp<Camera2Client> client): mPreviewStreamId(NO_STREAM), mRecordingRequestId(Camera2Client::kRecordingRequestIdStart), mRecordingStreamId(NO_STREAM), mRecordingFrameAvailable(false), mRecordingHeapCount(kDefaultRecordingHeapCount) { } Loading Loading @@ -535,6 +536,36 @@ status_t StreamingProcessor::incrementStreamingIds() { } void StreamingProcessor::onFrameAvailable() { ATRACE_CALL(); Mutex::Autolock l(mMutex); if (!mRecordingFrameAvailable) { mRecordingFrameAvailable = true; mRecordingFrameAvailableSignal.signal(); } } bool StreamingProcessor::threadLoop() { status_t res; { Mutex::Autolock l(mMutex); while (!mRecordingFrameAvailable) { res = mRecordingFrameAvailableSignal.waitRelative( mMutex, kWaitDuration); if (res == TIMED_OUT) return true; } mRecordingFrameAvailable = false; } do { res = processRecordingFrame(); } while (res == OK); return true; } status_t StreamingProcessor::processRecordingFrame() { ATRACE_CALL(); status_t res; sp<Camera2Heap> recordingHeap; Loading @@ -547,12 +578,14 @@ void StreamingProcessor::onFrameAvailable() { BufferItemConsumer::BufferItem imgBuffer; res = mRecordingConsumer->acquireBuffer(&imgBuffer); if (res != OK) { ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return; } return res; } mRecordingConsumer->releaseBuffer(imgBuffer); return; return OK; } { Loading @@ -563,23 +596,24 @@ void StreamingProcessor::onFrameAvailable() { BufferItemConsumer::BufferItem imgBuffer; res = mRecordingConsumer->acquireBuffer(&imgBuffer); if (res != OK) { ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return; } return res; } timestamp = imgBuffer.mTimestamp; mRecordingFrameCount++; ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount); // TODO: Signal errors here upstream if (l.mParameters.state != Parameters::RECORD && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { ALOGV("%s: Camera %d: Discarding recording image buffers " "received after recording done", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return INVALID_OPERATION; } if (mRecordingHeap == 0) { Loading @@ -594,7 +628,7 @@ void StreamingProcessor::onFrameAvailable() { ALOGE("%s: Camera %d: Unable to allocate memory for recording", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return NO_MEMORY; } for (size_t i = 0; i < mRecordingBuffers.size(); i++) { if (mRecordingBuffers[i].mBuf != Loading @@ -615,7 +649,7 @@ void StreamingProcessor::onFrameAvailable() { ALOGE("%s: Camera %d: No free recording buffers, dropping frame", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return NO_MEMORY; } heapIdx = mRecordingHeapHead; Loading Loading @@ -649,6 +683,7 @@ void StreamingProcessor::onFrameAvailable() { CAMERA_MSG_VIDEO_FRAME, recordingHeap->mBuffers[heapIdx]); } return OK; } void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { Loading services/camera/libcameraservice/camera2/StreamingProcessor.h +10 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ class Camera2Heap; /** * Management and processing for preview and recording streams */ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { class StreamingProcessor: public Thread, public BufferItemConsumer::FrameAvailableListener { public: StreamingProcessor(sp<Camera2Client> client); ~StreamingProcessor(); Loading Loading @@ -103,6 +104,8 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { sp<ANativeWindow> mPreviewWindow; // Recording-related members static const nsecs_t kWaitDuration = 50000000; // 50 ms int32_t mRecordingRequestId; int mRecordingStreamId; int mRecordingFrameCount; Loading @@ -111,11 +114,17 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { CameraMetadata mRecordingRequest; sp<camera2::Camera2Heap> mRecordingHeap; bool mRecordingFrameAvailable; Condition mRecordingFrameAvailableSignal; static const size_t kDefaultRecordingHeapCount = 8; size_t mRecordingHeapCount; Vector<BufferItemConsumer::BufferItem> mRecordingBuffers; size_t mRecordingHeapHead, mRecordingHeapFree; virtual bool threadLoop(); status_t processRecordingFrame(); }; Loading Loading
services/camera/libcameraservice/Camera2Client.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,9 @@ status_t Camera2Client::initialize(camera_module_t *module) String8 threadName; mStreamingProcessor = new StreamingProcessor(this); threadName = String8::format("C2-%d-StreamProc", mCameraId); mStreamingProcessor->run(threadName.string()); mFrameProcessor = new FrameProcessor(mDevice, this); threadName = String8::format("C2-%d-FrameProc", Loading Loading @@ -411,6 +414,7 @@ void Camera2Client::disconnect() { mCallbackProcessor->deleteStream(); mZslProcessor->deleteStream(); mStreamingProcessor->requestExit(); mFrameProcessor->requestExit(); mCaptureSequencer->requestExit(); mJpegProcessor->requestExit(); Loading @@ -419,6 +423,7 @@ void Camera2Client::disconnect() { ALOGV("Camera %d: Waiting for threads", mCameraId); mStreamingProcessor->join(); mFrameProcessor->join(); mCaptureSequencer->join(); mJpegProcessor->join(); Loading
services/camera/libcameraservice/camera2/StreamingProcessor.cpp +46 −11 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ StreamingProcessor::StreamingProcessor(sp<Camera2Client> client): mPreviewStreamId(NO_STREAM), mRecordingRequestId(Camera2Client::kRecordingRequestIdStart), mRecordingStreamId(NO_STREAM), mRecordingFrameAvailable(false), mRecordingHeapCount(kDefaultRecordingHeapCount) { } Loading Loading @@ -535,6 +536,36 @@ status_t StreamingProcessor::incrementStreamingIds() { } void StreamingProcessor::onFrameAvailable() { ATRACE_CALL(); Mutex::Autolock l(mMutex); if (!mRecordingFrameAvailable) { mRecordingFrameAvailable = true; mRecordingFrameAvailableSignal.signal(); } } bool StreamingProcessor::threadLoop() { status_t res; { Mutex::Autolock l(mMutex); while (!mRecordingFrameAvailable) { res = mRecordingFrameAvailableSignal.waitRelative( mMutex, kWaitDuration); if (res == TIMED_OUT) return true; } mRecordingFrameAvailable = false; } do { res = processRecordingFrame(); } while (res == OK); return true; } status_t StreamingProcessor::processRecordingFrame() { ATRACE_CALL(); status_t res; sp<Camera2Heap> recordingHeap; Loading @@ -547,12 +578,14 @@ void StreamingProcessor::onFrameAvailable() { BufferItemConsumer::BufferItem imgBuffer; res = mRecordingConsumer->acquireBuffer(&imgBuffer); if (res != OK) { ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return; } return res; } mRecordingConsumer->releaseBuffer(imgBuffer); return; return OK; } { Loading @@ -563,23 +596,24 @@ void StreamingProcessor::onFrameAvailable() { BufferItemConsumer::BufferItem imgBuffer; res = mRecordingConsumer->acquireBuffer(&imgBuffer); if (res != OK) { ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { ALOGE("%s: Camera %d: Can't acquire recording buffer: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return; } return res; } timestamp = imgBuffer.mTimestamp; mRecordingFrameCount++; ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount); // TODO: Signal errors here upstream if (l.mParameters.state != Parameters::RECORD && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { ALOGV("%s: Camera %d: Discarding recording image buffers " "received after recording done", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return INVALID_OPERATION; } if (mRecordingHeap == 0) { Loading @@ -594,7 +628,7 @@ void StreamingProcessor::onFrameAvailable() { ALOGE("%s: Camera %d: Unable to allocate memory for recording", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return NO_MEMORY; } for (size_t i = 0; i < mRecordingBuffers.size(); i++) { if (mRecordingBuffers[i].mBuf != Loading @@ -615,7 +649,7 @@ void StreamingProcessor::onFrameAvailable() { ALOGE("%s: Camera %d: No free recording buffers, dropping frame", __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; return NO_MEMORY; } heapIdx = mRecordingHeapHead; Loading Loading @@ -649,6 +683,7 @@ void StreamingProcessor::onFrameAvailable() { CAMERA_MSG_VIDEO_FRAME, recordingHeap->mBuffers[heapIdx]); } return OK; } void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { Loading
services/camera/libcameraservice/camera2/StreamingProcessor.h +10 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,8 @@ class Camera2Heap; /** * Management and processing for preview and recording streams */ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { class StreamingProcessor: public Thread, public BufferItemConsumer::FrameAvailableListener { public: StreamingProcessor(sp<Camera2Client> client); ~StreamingProcessor(); Loading Loading @@ -103,6 +104,8 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { sp<ANativeWindow> mPreviewWindow; // Recording-related members static const nsecs_t kWaitDuration = 50000000; // 50 ms int32_t mRecordingRequestId; int mRecordingStreamId; int mRecordingFrameCount; Loading @@ -111,11 +114,17 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { CameraMetadata mRecordingRequest; sp<camera2::Camera2Heap> mRecordingHeap; bool mRecordingFrameAvailable; Condition mRecordingFrameAvailableSignal; static const size_t kDefaultRecordingHeapCount = 8; size_t mRecordingHeapCount; Vector<BufferItemConsumer::BufferItem> mRecordingBuffers; size_t mRecordingHeapHead, mRecordingHeapFree; virtual bool threadLoop(); status_t processRecordingFrame(); }; Loading