Loading services/camera/libcameraservice/Camera2Client.cpp +67 −25 Original line number Diff line number Diff line Loading @@ -611,29 +611,37 @@ void Camera2Client::setPreviewCallbackFlag(int flag) { void Camera2Client::setPreviewCallbackFlagL(Parameters ¶ms, int flag) { status_t res = OK; switch(params.state) { case Parameters::STOPPED: case Parameters::WAITING_FOR_PREVIEW_WINDOW: case Parameters::PREVIEW: // OK break; default: if (flag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { ALOGE("%s: Camera %d: Can't use preview callbacks " "in state %d", __FUNCTION__, mCameraId, params.state); return; } } if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { ALOGV("%s: setting oneshot", __FUNCTION__); params.previewCallbackOneShot = true; } if (params.previewCallbackFlags != (uint32_t)flag) { params.previewCallbackFlags = flag; switch(params.state) { case Parameters::PREVIEW: if (params.state == Parameters::PREVIEW) { res = startPreviewL(params, true); break; case Parameters::RECORD: case Parameters::VIDEO_SNAPSHOT: res = startRecordingL(params, true); break; default: break; } if (res != OK) { ALOGE("%s: Camera %d: Unable to refresh request in state %s", __FUNCTION__, mCameraId, Parameters::getStateName(params.state)); } } } } Loading Loading @@ -702,6 +710,26 @@ status_t Camera2Client::startPreviewL(Parameters ¶ms, bool restart) { bool callbacksEnabled = params.previewCallbackFlags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK; if (callbacksEnabled) { // Can't have recording stream hanging around when enabling callbacks, // since it exceeds the max stream count on some devices. if (mStreamingProcessor->getRecordingStreamId() != NO_STREAM) { ALOGV("%s: Camera %d: Clearing out recording stream before " "creating callback stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Can't stop streaming to delete " "recording stream", __FUNCTION__, mCameraId); return res; } res = mStreamingProcessor->deleteRecordingStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete recording stream before " "enabling callbacks: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } } res = mCallbackProcessor->updateStream(params); if (res != OK) { ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)", Loading Loading @@ -898,6 +926,29 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { } } // Not all devices can support a preview callback stream and a recording // stream at the same time, so assume none of them can. if (mCallbackProcessor->getStreamId() != NO_STREAM) { ALOGV("%s: Camera %d: Clearing out callback stream before " "creating recording stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream", __FUNCTION__, mCameraId); return res; } res = mCallbackProcessor->deleteStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete callback stream before " "record: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } } // Disable callbacks if they're enabled; can't record and use callbacks, // and we can't fail record start without stagefright asserting. params.previewCallbackFlags = 0; res = updateProcessorStream< StreamingProcessor, &StreamingProcessor::updateRecordingStream>(mStreamingProcessor, Loading @@ -909,17 +960,6 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { } Vector<uint8_t> outputStreams; bool callbacksEnabled = params.previewCallbackFlags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK; if (callbacksEnabled) { res = mCallbackProcessor->updateStream(params); if (res != OK) { ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } outputStreams.push(getCallbackStreamId()); } outputStreams.push(getPreviewStreamId()); outputStreams.push(getRecordingStreamId()); Loading Loading @@ -1651,6 +1691,8 @@ status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor, * queue) and then try again. Resume streaming once we're done. */ if (res == -EBUSY) { ALOGV("%s: Camera %d: Pausing to update stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->togglePauseStream(/*pause*/true); if (res != OK) { ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)", Loading services/camera/libcameraservice/camera2/CallbackProcessor.cpp +18 −4 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { } if (mCallbackConsumer == 0) { // Create CPU buffer queue endpoint mCallbackConsumer = new CpuConsumer(kCallbackHeapCount); // Create CPU buffer queue endpoint. Make it async to avoid disconnect // deadlocks. mCallbackConsumer = new CpuConsumer(kCallbackHeapCount, /*synchronized*/ false); mCallbackConsumer->setFrameAvailableListener(this); mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer")); mCallbackWindow = new Surface( Loading Loading @@ -133,7 +135,7 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { status_t CallbackProcessor::deleteStream() { ATRACE_CALL(); sp<CameraDeviceBase> device; status_t res; { Mutex::Autolock l(mInputMutex); Loading @@ -146,7 +148,19 @@ status_t CallbackProcessor::deleteStream() { return INVALID_OPERATION; } } device->deleteStream(mCallbackStreamId); res = device->waitUntilDrained(); if (res != OK) { ALOGE("%s: Error waiting for HAL to drain: %s (%d)", __FUNCTION__, strerror(-res), res); return res; } res = device->deleteStream(mCallbackStreamId); if (res != OK) { ALOGE("%s: Unable to delete callback stream: %s (%d)", __FUNCTION__, strerror(-res), res); return res; } { Mutex::Autolock l(mInputMutex); Loading Loading
services/camera/libcameraservice/Camera2Client.cpp +67 −25 Original line number Diff line number Diff line Loading @@ -611,29 +611,37 @@ void Camera2Client::setPreviewCallbackFlag(int flag) { void Camera2Client::setPreviewCallbackFlagL(Parameters ¶ms, int flag) { status_t res = OK; switch(params.state) { case Parameters::STOPPED: case Parameters::WAITING_FOR_PREVIEW_WINDOW: case Parameters::PREVIEW: // OK break; default: if (flag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { ALOGE("%s: Camera %d: Can't use preview callbacks " "in state %d", __FUNCTION__, mCameraId, params.state); return; } } if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { ALOGV("%s: setting oneshot", __FUNCTION__); params.previewCallbackOneShot = true; } if (params.previewCallbackFlags != (uint32_t)flag) { params.previewCallbackFlags = flag; switch(params.state) { case Parameters::PREVIEW: if (params.state == Parameters::PREVIEW) { res = startPreviewL(params, true); break; case Parameters::RECORD: case Parameters::VIDEO_SNAPSHOT: res = startRecordingL(params, true); break; default: break; } if (res != OK) { ALOGE("%s: Camera %d: Unable to refresh request in state %s", __FUNCTION__, mCameraId, Parameters::getStateName(params.state)); } } } } Loading Loading @@ -702,6 +710,26 @@ status_t Camera2Client::startPreviewL(Parameters ¶ms, bool restart) { bool callbacksEnabled = params.previewCallbackFlags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK; if (callbacksEnabled) { // Can't have recording stream hanging around when enabling callbacks, // since it exceeds the max stream count on some devices. if (mStreamingProcessor->getRecordingStreamId() != NO_STREAM) { ALOGV("%s: Camera %d: Clearing out recording stream before " "creating callback stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Can't stop streaming to delete " "recording stream", __FUNCTION__, mCameraId); return res; } res = mStreamingProcessor->deleteRecordingStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete recording stream before " "enabling callbacks: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } } res = mCallbackProcessor->updateStream(params); if (res != OK) { ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)", Loading Loading @@ -898,6 +926,29 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { } } // Not all devices can support a preview callback stream and a recording // stream at the same time, so assume none of them can. if (mCallbackProcessor->getStreamId() != NO_STREAM) { ALOGV("%s: Camera %d: Clearing out callback stream before " "creating recording stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->stopStream(); if (res != OK) { ALOGE("%s: Camera %d: Can't stop streaming to delete callback stream", __FUNCTION__, mCameraId); return res; } res = mCallbackProcessor->deleteStream(); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete callback stream before " "record: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } } // Disable callbacks if they're enabled; can't record and use callbacks, // and we can't fail record start without stagefright asserting. params.previewCallbackFlags = 0; res = updateProcessorStream< StreamingProcessor, &StreamingProcessor::updateRecordingStream>(mStreamingProcessor, Loading @@ -909,17 +960,6 @@ status_t Camera2Client::startRecordingL(Parameters ¶ms, bool restart) { } Vector<uint8_t> outputStreams; bool callbacksEnabled = params.previewCallbackFlags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK; if (callbacksEnabled) { res = mCallbackProcessor->updateStream(params); if (res != OK) { ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res); return res; } outputStreams.push(getCallbackStreamId()); } outputStreams.push(getPreviewStreamId()); outputStreams.push(getRecordingStreamId()); Loading Loading @@ -1651,6 +1691,8 @@ status_t Camera2Client::updateProcessorStream(sp<ProcessorT> processor, * queue) and then try again. Resume streaming once we're done. */ if (res == -EBUSY) { ALOGV("%s: Camera %d: Pausing to update stream", __FUNCTION__, mCameraId); res = mStreamingProcessor->togglePauseStream(/*pause*/true); if (res != OK) { ALOGE("%s: Camera %d: Can't pause streaming: %s (%d)", Loading
services/camera/libcameraservice/camera2/CallbackProcessor.cpp +18 −4 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { } if (mCallbackConsumer == 0) { // Create CPU buffer queue endpoint mCallbackConsumer = new CpuConsumer(kCallbackHeapCount); // Create CPU buffer queue endpoint. Make it async to avoid disconnect // deadlocks. mCallbackConsumer = new CpuConsumer(kCallbackHeapCount, /*synchronized*/ false); mCallbackConsumer->setFrameAvailableListener(this); mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer")); mCallbackWindow = new Surface( Loading Loading @@ -133,7 +135,7 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { status_t CallbackProcessor::deleteStream() { ATRACE_CALL(); sp<CameraDeviceBase> device; status_t res; { Mutex::Autolock l(mInputMutex); Loading @@ -146,7 +148,19 @@ status_t CallbackProcessor::deleteStream() { return INVALID_OPERATION; } } device->deleteStream(mCallbackStreamId); res = device->waitUntilDrained(); if (res != OK) { ALOGE("%s: Error waiting for HAL to drain: %s (%d)", __FUNCTION__, strerror(-res), res); return res; } res = device->deleteStream(mCallbackStreamId); if (res != OK) { ALOGE("%s: Unable to delete callback stream: %s (%d)", __FUNCTION__, strerror(-res), res); return res; } { Mutex::Autolock l(mInputMutex); Loading