Loading camera/camera2/CaptureRequest.cpp +42 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ // #define LOG_NDEBUG 0 #define LOG_TAG "CameraRequest" #include <utils/Log.h> #include <utils/String16.h> #include <camera/camera2/CaptureRequest.h> Loading @@ -42,18 +43,39 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { return BAD_VALUE; } mMetadata.clear(); mSurfaceList.clear(); mStreamIdxList.clear(); mSurfaceIdxList.clear(); mPhysicalCameraSettings.clear(); status_t err = OK; if ((err = mMetadata.readFromParcel(parcel)) != OK) { int32_t settingsCount; if ((err = parcel->readInt32(&settingsCount)) != OK) { ALOGE("%s: Failed to read the settings count from parcel: %d", __FUNCTION__, err); return err; } if (settingsCount <= 0) { ALOGE("%s: Settings count %d should always be positive!", __FUNCTION__, settingsCount); return BAD_VALUE; } for (int32_t i = 0; i < settingsCount; i++) { String16 id; if ((err = parcel->readString16(&id)) != OK) { ALOGE("%s: Failed to read camera id!", __FUNCTION__); return BAD_VALUE; } CameraMetadata settings; if ((err = settings.readFromParcel(parcel)) != OK) { ALOGE("%s: Failed to read metadata from parcel", __FUNCTION__); return err; } ALOGV("%s: Read metadata from parcel", __FUNCTION__); mPhysicalCameraSettings.push_back({std::string(String8(id).string()), settings}); } int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { Loading Loading @@ -135,10 +157,25 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { status_t err = OK; if ((err = mMetadata.writeToParcel(parcel)) != OK) { int32_t settingsCount = static_cast<int32_t>(mPhysicalCameraSettings.size()); if ((err = parcel->writeInt32(settingsCount)) != OK) { ALOGE("%s: Failed to write settings count!", __FUNCTION__); return err; } for (const auto &it : mPhysicalCameraSettings) { if ((err = parcel->writeString16(String16(it.id.c_str()))) != OK) { ALOGE("%s: Failed to camera id!", __FUNCTION__); return err; } if ((err = it.settings.writeToParcel(parcel)) != OK) { ALOGE("%s: Failed to write settings!", __FUNCTION__); return err; } } parcel->writeInt32(mIsReprocess ? 1 : 0); if (mSurfaceConverted) { Loading camera/include/camera/camera2/CaptureRequest.h +5 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,11 @@ struct CaptureRequest : public Parcelable { CaptureRequest(CaptureRequest&& rhs) noexcept; virtual ~CaptureRequest(); CameraMetadata mMetadata; struct PhysicalCameraSettings { std::string id; CameraMetadata settings; }; std::vector<PhysicalCameraSettings> mPhysicalCameraSettings; // Used by NDK client to pass surfaces by stream/surface index. bool mSurfaceConverted = false; Loading camera/ndk/impl/ACameraDevice.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -372,7 +372,8 @@ CameraDevice::allocateCaptureRequest( const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) { camera_status_t ret; sp<CaptureRequest> req(new CaptureRequest()); req->mMetadata = request->settings->getInternalData(); req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()), 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 Loading Loading @@ -418,7 +419,7 @@ CameraDevice::allocateCaptureRequest( ACaptureRequest* CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) { ACaptureRequest* pRequest = new ACaptureRequest(); CameraMetadata clone = req->mMetadata; CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings; pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST); pRequest->targets = new ACameraOutputTargets(); for (size_t i = 0; i < req->mSurfaceList.size(); i++) { Loading camera/tests/CameraBinderTests.cpp +71 −5 Original line number Diff line number Diff line Loading @@ -317,6 +317,9 @@ TEST(CameraServiceBinderTest, CheckBinderCameraService) { EXPECT_TRUE(res.isOk()) << res; EXPECT_EQ(numCameras, static_cast<const int>(statuses.size())); for (const auto &it : statuses) { listener->onStatusChanged(it.status, String16(it.cameraId)); } for (int32_t i = 0; i < numCameras; i++) { String16 cameraId = String16(String8::format("%d", i)); Loading Loading @@ -421,6 +424,9 @@ protected: serviceListener = new TestCameraServiceListener(); std::vector<hardware::CameraStatus> statuses; service->addListener(serviceListener, &statuses); for (const auto &it : statuses) { serviceListener->onStatusChanged(it.status, String16(it.cameraId)); } service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, &numCameras); } Loading @@ -439,8 +445,9 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { ASSERT_NOT_NULL(service); EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); for (int32_t i = 0; i < numCameras; i++) { String8 cameraId8 = String8::format("%d", i); // Make sure we're available, or skip device tests otherwise String16 cameraId(String8::format("%d",i)); String16 cameraId(cameraId8); int32_t s = serviceListener->getStatus(cameraId); EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s); if (s != hardware::ICameraServiceListener::STATUS_PRESENT) { Loading Loading @@ -488,7 +495,7 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { EXPECT_TRUE(res.isOk()) << res; hardware::camera2::CaptureRequest request; request.mMetadata = requestTemplate; request.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request.mSurfaceList.add(surface); request.mIsReprocess = false; int64_t lastFrameNumber = 0; Loading @@ -515,7 +522,7 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { /*out*/&requestTemplate); EXPECT_TRUE(res.isOk()) << res; hardware::camera2::CaptureRequest request2; request2.mMetadata = requestTemplate; request2.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request2.mSurfaceList.add(surface); request2.mIsReprocess = false; callbacks->clearStatus(); Loading Loading @@ -548,10 +555,10 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { EXPECT_TRUE(res.isOk()) << res; android::hardware::camera2::CaptureRequest request3; android::hardware::camera2::CaptureRequest request4; request3.mMetadata = requestTemplate; request3.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request3.mSurfaceList.add(surface); request3.mIsReprocess = false; request4.mMetadata = requestTemplate2; request4.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate2}); request4.mSurfaceList.add(surface); request4.mIsReprocess = false; std::vector<hardware::camera2::CaptureRequest> requestList; Loading Loading @@ -585,3 +592,62 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { } }; TEST_F(CameraClientBinderTest, CheckBinderCaptureRequest) { sp<CaptureRequest> requestOriginal, requestParceled; sp<IGraphicBufferProducer> gbProducer; sp<IGraphicBufferConsumer> gbConsumer; BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); Vector<sp<Surface>> surfaceList; surfaceList.push_back(surface); std::string physicalDeviceId1 = "0"; std::string physicalDeviceId2 = "1"; CameraMetadata physicalDeviceSettings1, physicalDeviceSettings2; uint8_t intent1 = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; uint8_t intent2 = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; EXPECT_EQ(OK, physicalDeviceSettings1.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent1, 1)); EXPECT_EQ(OK, physicalDeviceSettings2.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent2, 1)); requestParceled = new CaptureRequest(); Parcel p; EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.writeInt32(0); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.freeData(); p.writeInt32(-1); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.freeData(); p.writeInt32(1); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); requestOriginal = new CaptureRequest(); requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId1, physicalDeviceSettings1}); requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId2, physicalDeviceSettings2}); requestOriginal->mSurfaceList.push_back(surface); requestOriginal->mIsReprocess = false; requestOriginal->mSurfaceConverted = false; p.freeData(); EXPECT_TRUE(requestOriginal->writeToParcel(&p) == OK); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) == OK); EXPECT_EQ(requestParceled->mIsReprocess, false); EXPECT_FALSE(requestParceled->mSurfaceList.empty()); EXPECT_EQ(2u, requestParceled->mPhysicalCameraSettings.size()); auto it = requestParceled->mPhysicalCameraSettings.begin(); EXPECT_EQ(physicalDeviceId1, it->id); EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)); auto entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT); EXPECT_EQ(entry.data.u8[0], intent1); it++; EXPECT_EQ(physicalDeviceId2, it->id); EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)); entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT); EXPECT_EQ(entry.data.u8[0], intent2); }; camera/tests/VendorTagDescriptorTests.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ TEST(VendorTagDescriptorTest, ConsistentAcrossParcel) { EXPECT_EQ(OK, vDescOriginal->writeToParcel(&p)); p.setDataPosition(0); vDescParceled = new VendorTagDescriptor(); ASSERT_EQ(OK, vDescParceled->readFromParcel(&p)); // Ensure consistent tag count Loading Loading
camera/camera2/CaptureRequest.cpp +42 −5 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ // #define LOG_NDEBUG 0 #define LOG_TAG "CameraRequest" #include <utils/Log.h> #include <utils/String16.h> #include <camera/camera2/CaptureRequest.h> Loading @@ -42,18 +43,39 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) { return BAD_VALUE; } mMetadata.clear(); mSurfaceList.clear(); mStreamIdxList.clear(); mSurfaceIdxList.clear(); mPhysicalCameraSettings.clear(); status_t err = OK; if ((err = mMetadata.readFromParcel(parcel)) != OK) { int32_t settingsCount; if ((err = parcel->readInt32(&settingsCount)) != OK) { ALOGE("%s: Failed to read the settings count from parcel: %d", __FUNCTION__, err); return err; } if (settingsCount <= 0) { ALOGE("%s: Settings count %d should always be positive!", __FUNCTION__, settingsCount); return BAD_VALUE; } for (int32_t i = 0; i < settingsCount; i++) { String16 id; if ((err = parcel->readString16(&id)) != OK) { ALOGE("%s: Failed to read camera id!", __FUNCTION__); return BAD_VALUE; } CameraMetadata settings; if ((err = settings.readFromParcel(parcel)) != OK) { ALOGE("%s: Failed to read metadata from parcel", __FUNCTION__); return err; } ALOGV("%s: Read metadata from parcel", __FUNCTION__); mPhysicalCameraSettings.push_back({std::string(String8(id).string()), settings}); } int isReprocess = 0; if ((err = parcel->readInt32(&isReprocess)) != OK) { Loading Loading @@ -135,10 +157,25 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const { status_t err = OK; if ((err = mMetadata.writeToParcel(parcel)) != OK) { int32_t settingsCount = static_cast<int32_t>(mPhysicalCameraSettings.size()); if ((err = parcel->writeInt32(settingsCount)) != OK) { ALOGE("%s: Failed to write settings count!", __FUNCTION__); return err; } for (const auto &it : mPhysicalCameraSettings) { if ((err = parcel->writeString16(String16(it.id.c_str()))) != OK) { ALOGE("%s: Failed to camera id!", __FUNCTION__); return err; } if ((err = it.settings.writeToParcel(parcel)) != OK) { ALOGE("%s: Failed to write settings!", __FUNCTION__); return err; } } parcel->writeInt32(mIsReprocess ? 1 : 0); if (mSurfaceConverted) { Loading
camera/include/camera/camera2/CaptureRequest.h +5 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,11 @@ struct CaptureRequest : public Parcelable { CaptureRequest(CaptureRequest&& rhs) noexcept; virtual ~CaptureRequest(); CameraMetadata mMetadata; struct PhysicalCameraSettings { std::string id; CameraMetadata settings; }; std::vector<PhysicalCameraSettings> mPhysicalCameraSettings; // Used by NDK client to pass surfaces by stream/surface index. bool mSurfaceConverted = false; Loading
camera/ndk/impl/ACameraDevice.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -372,7 +372,8 @@ CameraDevice::allocateCaptureRequest( const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) { camera_status_t ret; sp<CaptureRequest> req(new CaptureRequest()); req->mMetadata = request->settings->getInternalData(); req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()), 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 Loading Loading @@ -418,7 +419,7 @@ CameraDevice::allocateCaptureRequest( ACaptureRequest* CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) { ACaptureRequest* pRequest = new ACaptureRequest(); CameraMetadata clone = req->mMetadata; CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings; pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST); pRequest->targets = new ACameraOutputTargets(); for (size_t i = 0; i < req->mSurfaceList.size(); i++) { Loading
camera/tests/CameraBinderTests.cpp +71 −5 Original line number Diff line number Diff line Loading @@ -317,6 +317,9 @@ TEST(CameraServiceBinderTest, CheckBinderCameraService) { EXPECT_TRUE(res.isOk()) << res; EXPECT_EQ(numCameras, static_cast<const int>(statuses.size())); for (const auto &it : statuses) { listener->onStatusChanged(it.status, String16(it.cameraId)); } for (int32_t i = 0; i < numCameras; i++) { String16 cameraId = String16(String8::format("%d", i)); Loading Loading @@ -421,6 +424,9 @@ protected: serviceListener = new TestCameraServiceListener(); std::vector<hardware::CameraStatus> statuses; service->addListener(serviceListener, &statuses); for (const auto &it : statuses) { serviceListener->onStatusChanged(it.status, String16(it.cameraId)); } service->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE, &numCameras); } Loading @@ -439,8 +445,9 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { ASSERT_NOT_NULL(service); EXPECT_TRUE(serviceListener->waitForNumCameras(numCameras)); for (int32_t i = 0; i < numCameras; i++) { String8 cameraId8 = String8::format("%d", i); // Make sure we're available, or skip device tests otherwise String16 cameraId(String8::format("%d",i)); String16 cameraId(cameraId8); int32_t s = serviceListener->getStatus(cameraId); EXPECT_EQ(hardware::ICameraServiceListener::STATUS_PRESENT, s); if (s != hardware::ICameraServiceListener::STATUS_PRESENT) { Loading Loading @@ -488,7 +495,7 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { EXPECT_TRUE(res.isOk()) << res; hardware::camera2::CaptureRequest request; request.mMetadata = requestTemplate; request.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request.mSurfaceList.add(surface); request.mIsReprocess = false; int64_t lastFrameNumber = 0; Loading @@ -515,7 +522,7 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { /*out*/&requestTemplate); EXPECT_TRUE(res.isOk()) << res; hardware::camera2::CaptureRequest request2; request2.mMetadata = requestTemplate; request2.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request2.mSurfaceList.add(surface); request2.mIsReprocess = false; callbacks->clearStatus(); Loading Loading @@ -548,10 +555,10 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { EXPECT_TRUE(res.isOk()) << res; android::hardware::camera2::CaptureRequest request3; android::hardware::camera2::CaptureRequest request4; request3.mMetadata = requestTemplate; request3.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate}); request3.mSurfaceList.add(surface); request3.mIsReprocess = false; request4.mMetadata = requestTemplate2; request4.mPhysicalCameraSettings.push_back({cameraId8.string(), requestTemplate2}); request4.mSurfaceList.add(surface); request4.mIsReprocess = false; std::vector<hardware::camera2::CaptureRequest> requestList; Loading Loading @@ -585,3 +592,62 @@ TEST_F(CameraClientBinderTest, CheckBinderCameraDeviceUser) { } }; TEST_F(CameraClientBinderTest, CheckBinderCaptureRequest) { sp<CaptureRequest> requestOriginal, requestParceled; sp<IGraphicBufferProducer> gbProducer; sp<IGraphicBufferConsumer> gbConsumer; BufferQueue::createBufferQueue(&gbProducer, &gbConsumer); sp<Surface> surface(new Surface(gbProducer, /*controlledByApp*/false)); Vector<sp<Surface>> surfaceList; surfaceList.push_back(surface); std::string physicalDeviceId1 = "0"; std::string physicalDeviceId2 = "1"; CameraMetadata physicalDeviceSettings1, physicalDeviceSettings2; uint8_t intent1 = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; uint8_t intent2 = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; EXPECT_EQ(OK, physicalDeviceSettings1.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent1, 1)); EXPECT_EQ(OK, physicalDeviceSettings2.update(ANDROID_CONTROL_CAPTURE_INTENT, &intent2, 1)); requestParceled = new CaptureRequest(); Parcel p; EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.writeInt32(0); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.freeData(); p.writeInt32(-1); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); p.freeData(); p.writeInt32(1); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) != OK); requestOriginal = new CaptureRequest(); requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId1, physicalDeviceSettings1}); requestOriginal->mPhysicalCameraSettings.push_back({physicalDeviceId2, physicalDeviceSettings2}); requestOriginal->mSurfaceList.push_back(surface); requestOriginal->mIsReprocess = false; requestOriginal->mSurfaceConverted = false; p.freeData(); EXPECT_TRUE(requestOriginal->writeToParcel(&p) == OK); p.setDataPosition(0); EXPECT_TRUE(requestParceled->readFromParcel(&p) == OK); EXPECT_EQ(requestParceled->mIsReprocess, false); EXPECT_FALSE(requestParceled->mSurfaceList.empty()); EXPECT_EQ(2u, requestParceled->mPhysicalCameraSettings.size()); auto it = requestParceled->mPhysicalCameraSettings.begin(); EXPECT_EQ(physicalDeviceId1, it->id); EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)); auto entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT); EXPECT_EQ(entry.data.u8[0], intent1); it++; EXPECT_EQ(physicalDeviceId2, it->id); EXPECT_TRUE(it->settings.exists(ANDROID_CONTROL_CAPTURE_INTENT)); entry = it->settings.find(ANDROID_CONTROL_CAPTURE_INTENT); EXPECT_EQ(entry.data.u8[0], intent2); };
camera/tests/VendorTagDescriptorTests.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ TEST(VendorTagDescriptorTest, ConsistentAcrossParcel) { EXPECT_EQ(OK, vDescOriginal->writeToParcel(&p)); p.setDataPosition(0); vDescParceled = new VendorTagDescriptor(); ASSERT_EQ(OK, vDescParceled->readFromParcel(&p)); // Ensure consistent tag count Loading