Loading camera/camera2/CaptureRequest.cpp +66 −22 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { mMetadata.clear(); mSurfaceList.clear(); mStreamIdxList.clear(); mSurfaceIdxList.clear(); status_t err = OK; Loading @@ -53,6 +55,13 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { } ALOGV("%s: Read metadata from parcel", __FUNCTION__); int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__); return err; } mIsReprocess = (isReprocess != 0); int32_t size; if ((err = parcel->readInt32(&size)) != OK) { ALOGE("%s: Failed to read surface list size from parcel", __FUNCTION__); Loading @@ -61,7 +70,7 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { ALOGV("%s: Read surface list size = %d", __FUNCTION__, size); // Do not distinguish null arrays from 0-sized arrays. for (int i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) { // Parcel.writeParcelableArray size_t len; const char16_t* className = parcel->readString16Inplace(&len); Loading @@ -88,12 +97,32 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { mSurfaceList.push_back(surface); } int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__); int32_t streamSurfaceSize; if ((err = parcel->readInt32(&streamSurfaceSize)) != OK) { ALOGE("%s: Failed to read streamSurfaceSize from parcel", __FUNCTION__); return err; } mIsReprocess = (isReprocess != 0); if (streamSurfaceSize < 0) { ALOGE("%s: Bad streamSurfaceSize %d from parcel", __FUNCTION__, streamSurfaceSize); return BAD_VALUE; } for (int32_t i = 0; i < streamSurfaceSize; ++i) { int streamIdx; if ((err = parcel->readInt32(&streamIdx)) != OK) { ALOGE("%s: Failed to read stream index from parcel", __FUNCTION__); return err; } mStreamIdxList.push_back(streamIdx); int surfaceIdx; if ((err = parcel->readInt32(&surfaceIdx)) != OK) { ALOGE("%s: Failed to read surface index from parcel", __FUNCTION__); return err; } mSurfaceIdxList.push_back(surfaceIdx); } return OK; } Loading @@ -110,6 +139,11 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { return err; } parcel->writeInt32(mIsReprocess ? 1 : 0); if (mSurfaceConverted) { parcel->writeInt32(0); // 0-sized array } else { int32_t size = static_cast<int32_t>(mSurfaceList.size()); // Send 0-sized arrays when it's empty. Do not send null arrays. Loading @@ -129,9 +163,19 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { return err; } } } parcel->writeInt32(mIsReprocess ? 1 : 0); parcel->writeInt32(mStreamIdxList.size()); for (size_t i = 0; i < mStreamIdxList.size(); ++i) { if ((err = parcel->writeInt32(mStreamIdxList[i])) != OK) { ALOGE("%s: Failed to write stream index to parcel", __FUNCTION__); return err; } if ((err = parcel->writeInt32(mSurfaceIdxList[i])) != OK) { ALOGE("%s: Failed to write surface index to parcel", __FUNCTION__); return err; } } return OK; } Loading camera/include/camera/camera2/CaptureRequest.h +16 −0 Original line number Diff line number Diff line Loading @@ -41,14 +41,30 @@ struct CaptureRequest : public Parcelable { virtual ~CaptureRequest(); CameraMetadata mMetadata; // Used by NDK client to pass surfaces by stream/surface index. bool mSurfaceConverted = false; // Starting in Android O, create a Surface from Parcel will take one extra // IPC call. Vector<sp<Surface> > mSurfaceList; // Optional way of passing surface list since passing Surface over binder // is expensive. Use the stream/surface index from current output configuration // to represent an configured output Surface. When stream/surface index is used, // set mSurfaceList to zero length to save unparcel time. Vector<int> mStreamIdxList; Vector<int> mSurfaceIdxList; // per stream surface list index bool mIsReprocess; void* mContext; // arbitrary user context from NDK apps, null for java apps /** * Keep impl up-to-date with CaptureRequest.java in frameworks/base */ // used by cameraserver to receive CaptureRequest from java/NDK client status_t readFromParcel(const android::Parcel* parcel) override; // used by NDK client to send CaptureRequest to cameraserver status_t writeToParcel(android::Parcel* parcel) const override; }; Loading camera/ndk/impl/ACameraCaptureSession.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSession dev->lockDeviceForSessionOps(); { Mutex::Autolock _l(mSessionLock); ret = dev->updateOutputConfiguration(output); ret = dev->updateOutputConfigurationLocked(output); } dev->unlockDevice(); return ret; Loading camera/ndk/impl/ACameraDevice.cpp +50 −23 Original line number Diff line number Diff line Loading @@ -289,7 +289,7 @@ CameraDevice::submitRequestsLocked( return ACAMERA_OK; } camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) { camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) { camera_status_t ret = checkCameraClosedOrErrorLocked(); if (ret != ACAMERA_OK) { return ret; Loading Loading @@ -361,6 +361,7 @@ camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *o return ACAMERA_ERROR_UNKNOWN; } } mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig); return ACAMERA_OK; } Loading @@ -373,6 +374,7 @@ CameraDevice::allocateCaptureRequest( req->mMetadata = request->settings->getInternalData(); req->mIsReprocess = false; // NDK does not support reprocessing yet req->mContext = request->context; req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC for (auto outputTarget : request->targets->mOutputs) { ANativeWindow* anw = outputTarget.mWindow; Loading @@ -383,7 +385,31 @@ CameraDevice::allocateCaptureRequest( return ret; } req->mSurfaceList.push_back(surface); bool found = false; // lookup stream/surface ID for (const auto& kvPair : mConfiguredOutputs) { int streamId = kvPair.first; const OutputConfiguration& outConfig = kvPair.second.second; const auto& gbps = outConfig.getGraphicBufferProducers(); for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) { if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) { found = true; req->mStreamIdxList.push_back(streamId); req->mSurfaceIdxList.push_back(surfaceId); break; } } if (found) { break; } } if (!found) { ALOGE("Unconfigured output target %p in capture request!", anw); return ret; } } outReq = req; return ACAMERA_OK; } Loading Loading @@ -564,17 +590,11 @@ camera_status_t CameraDevice::getIGBPfromAnw( ANativeWindow* anw, sp<IGraphicBufferProducer>& out) { if (anw == nullptr) { ALOGE("Error: output ANativeWindow is null"); return ACAMERA_ERROR_INVALID_PARAMETER; } int value; int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface!"); return ACAMERA_ERROR_INVALID_PARAMETER; sp<Surface> surface; camera_status_t ret = getSurfaceFromANativeWindow(anw, surface); if (ret != ACAMERA_OK) { return ret; } const sp<Surface> surface(static_cast<Surface*>(anw)); out = surface->getIGraphicBufferProducer(); return ACAMERA_OK; } Loading Loading @@ -809,8 +829,12 @@ CameraDevice::onCaptureErrorLocked( setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE); return; } ANativeWindow* anw = outputPairIt->second.first; const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers(); for (const auto& outGbp : gbps) { for (auto surface : request->mSurfaceList) { if (surface->getIGraphicBufferProducer() == outGbp) { ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get()); ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64, getId(), anw, frameNumber); Loading @@ -822,6 +846,9 @@ CameraDevice::onCaptureErrorLocked( msg->setPointer(kAnwKey, (void*) anw); msg->setInt64(kFrameNumberKey, frameNumber); postSessionMsgAndCleanup(msg); } } } } else { // Handle other capture failures // Fire capture failure callback if there is one registered ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed; Loading camera/ndk/impl/ACameraDevice.h +2 −2 Original line number Diff line number Diff line Loading @@ -123,9 +123,9 @@ class CameraDevice final : public RefBase { /*out*/int* captureSequenceId, bool isRepeating); camera_status_t updateOutputConfiguration(ACaptureSessionOutput *output); camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output); static camera_status_t allocateCaptureRequest( camera_status_t allocateCaptureRequest( const ACaptureRequest* request, sp<CaptureRequest>& outReq); static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req); Loading Loading
camera/camera2/CaptureRequest.cpp +66 −22 Original line number Diff line number Diff line Loading @@ -44,6 +44,8 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { mMetadata.clear(); mSurfaceList.clear(); mStreamIdxList.clear(); mSurfaceIdxList.clear(); status_t err = OK; Loading @@ -53,6 +55,13 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { } ALOGV("%s: Read metadata from parcel", __FUNCTION__); int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__); return err; } mIsReprocess = (isReprocess != 0); int32_t size; if ((err = parcel->readInt32(&size)) != OK) { ALOGE("%s: Failed to read surface list size from parcel", __FUNCTION__); Loading @@ -61,7 +70,7 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { ALOGV("%s: Read surface list size = %d", __FUNCTION__, size); // Do not distinguish null arrays from 0-sized arrays. for (int i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) { // Parcel.writeParcelableArray size_t len; const char16_t* className = parcel->readString16Inplace(&len); Loading @@ -88,12 +97,32 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { mSurfaceList.push_back(surface); } int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__); int32_t streamSurfaceSize; if ((err = parcel->readInt32(&streamSurfaceSize)) != OK) { ALOGE("%s: Failed to read streamSurfaceSize from parcel", __FUNCTION__); return err; } mIsReprocess = (isReprocess != 0); if (streamSurfaceSize < 0) { ALOGE("%s: Bad streamSurfaceSize %d from parcel", __FUNCTION__, streamSurfaceSize); return BAD_VALUE; } for (int32_t i = 0; i < streamSurfaceSize; ++i) { int streamIdx; if ((err = parcel->readInt32(&streamIdx)) != OK) { ALOGE("%s: Failed to read stream index from parcel", __FUNCTION__); return err; } mStreamIdxList.push_back(streamIdx); int surfaceIdx; if ((err = parcel->readInt32(&surfaceIdx)) != OK) { ALOGE("%s: Failed to read surface index from parcel", __FUNCTION__); return err; } mSurfaceIdxList.push_back(surfaceIdx); } return OK; } Loading @@ -110,6 +139,11 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { return err; } parcel->writeInt32(mIsReprocess ? 1 : 0); if (mSurfaceConverted) { parcel->writeInt32(0); // 0-sized array } else { int32_t size = static_cast<int32_t>(mSurfaceList.size()); // Send 0-sized arrays when it's empty. Do not send null arrays. Loading @@ -129,9 +163,19 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { return err; } } } parcel->writeInt32(mIsReprocess ? 1 : 0); parcel->writeInt32(mStreamIdxList.size()); for (size_t i = 0; i < mStreamIdxList.size(); ++i) { if ((err = parcel->writeInt32(mStreamIdxList[i])) != OK) { ALOGE("%s: Failed to write stream index to parcel", __FUNCTION__); return err; } if ((err = parcel->writeInt32(mSurfaceIdxList[i])) != OK) { ALOGE("%s: Failed to write surface index to parcel", __FUNCTION__); return err; } } return OK; } Loading
camera/include/camera/camera2/CaptureRequest.h +16 −0 Original line number Diff line number Diff line Loading @@ -41,14 +41,30 @@ struct CaptureRequest : public Parcelable { virtual ~CaptureRequest(); CameraMetadata mMetadata; // Used by NDK client to pass surfaces by stream/surface index. bool mSurfaceConverted = false; // Starting in Android O, create a Surface from Parcel will take one extra // IPC call. Vector<sp<Surface> > mSurfaceList; // Optional way of passing surface list since passing Surface over binder // is expensive. Use the stream/surface index from current output configuration // to represent an configured output Surface. When stream/surface index is used, // set mSurfaceList to zero length to save unparcel time. Vector<int> mStreamIdxList; Vector<int> mSurfaceIdxList; // per stream surface list index bool mIsReprocess; void* mContext; // arbitrary user context from NDK apps, null for java apps /** * Keep impl up-to-date with CaptureRequest.java in frameworks/base */ // used by cameraserver to receive CaptureRequest from java/NDK client status_t readFromParcel(const android::Parcel* parcel) override; // used by NDK client to send CaptureRequest to cameraserver status_t writeToParcel(android::Parcel* parcel) const override; }; Loading
camera/ndk/impl/ACameraCaptureSession.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSession dev->lockDeviceForSessionOps(); { Mutex::Autolock _l(mSessionLock); ret = dev->updateOutputConfiguration(output); ret = dev->updateOutputConfigurationLocked(output); } dev->unlockDevice(); return ret; Loading
camera/ndk/impl/ACameraDevice.cpp +50 −23 Original line number Diff line number Diff line Loading @@ -289,7 +289,7 @@ CameraDevice::submitRequestsLocked( return ACAMERA_OK; } camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) { camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) { camera_status_t ret = checkCameraClosedOrErrorLocked(); if (ret != ACAMERA_OK) { return ret; Loading Loading @@ -361,6 +361,7 @@ camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *o return ACAMERA_ERROR_UNKNOWN; } } mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig); return ACAMERA_OK; } Loading @@ -373,6 +374,7 @@ CameraDevice::allocateCaptureRequest( req->mMetadata = request->settings->getInternalData(); req->mIsReprocess = false; // NDK does not support reprocessing yet req->mContext = request->context; req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC for (auto outputTarget : request->targets->mOutputs) { ANativeWindow* anw = outputTarget.mWindow; Loading @@ -383,7 +385,31 @@ CameraDevice::allocateCaptureRequest( return ret; } req->mSurfaceList.push_back(surface); bool found = false; // lookup stream/surface ID for (const auto& kvPair : mConfiguredOutputs) { int streamId = kvPair.first; const OutputConfiguration& outConfig = kvPair.second.second; const auto& gbps = outConfig.getGraphicBufferProducers(); for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) { if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) { found = true; req->mStreamIdxList.push_back(streamId); req->mSurfaceIdxList.push_back(surfaceId); break; } } if (found) { break; } } if (!found) { ALOGE("Unconfigured output target %p in capture request!", anw); return ret; } } outReq = req; return ACAMERA_OK; } Loading Loading @@ -564,17 +590,11 @@ camera_status_t CameraDevice::getIGBPfromAnw( ANativeWindow* anw, sp<IGraphicBufferProducer>& out) { if (anw == nullptr) { ALOGE("Error: output ANativeWindow is null"); return ACAMERA_ERROR_INVALID_PARAMETER; } int value; int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value); if (err != OK || value != NATIVE_WINDOW_SURFACE) { ALOGE("Error: ANativeWindow is not backed by Surface!"); return ACAMERA_ERROR_INVALID_PARAMETER; sp<Surface> surface; camera_status_t ret = getSurfaceFromANativeWindow(anw, surface); if (ret != ACAMERA_OK) { return ret; } const sp<Surface> surface(static_cast<Surface*>(anw)); out = surface->getIGraphicBufferProducer(); return ACAMERA_OK; } Loading Loading @@ -809,8 +829,12 @@ CameraDevice::onCaptureErrorLocked( setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE); return; } ANativeWindow* anw = outputPairIt->second.first; const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers(); for (const auto& outGbp : gbps) { for (auto surface : request->mSurfaceList) { if (surface->getIGraphicBufferProducer() == outGbp) { ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get()); ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64, getId(), anw, frameNumber); Loading @@ -822,6 +846,9 @@ CameraDevice::onCaptureErrorLocked( msg->setPointer(kAnwKey, (void*) anw); msg->setInt64(kFrameNumberKey, frameNumber); postSessionMsgAndCleanup(msg); } } } } else { // Handle other capture failures // Fire capture failure callback if there is one registered ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed; Loading
camera/ndk/impl/ACameraDevice.h +2 −2 Original line number Diff line number Diff line Loading @@ -123,9 +123,9 @@ class CameraDevice final : public RefBase { /*out*/int* captureSequenceId, bool isRepeating); camera_status_t updateOutputConfiguration(ACaptureSessionOutput *output); camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output); static camera_status_t allocateCaptureRequest( camera_status_t allocateCaptureRequest( const ACaptureRequest* request, sp<CaptureRequest>& outReq); static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req); Loading