From aec3f711706329f3edad26b9c64edbcb522c218a Mon Sep 17 00:00:00 2001 From: Tianli Yu Date: Sat, 24 Oct 2020 10:39:40 -0700 Subject: [PATCH] New version of the NDK api to grab images from camera. --- build.sh | 2 +- ndk-camera | Bin 0 -> 208528 bytes src/main.cc | 301 +------------------------------------ src/ndk/ndk-camera.cc | 290 +++++++++++++++++++++++++++++++++++ src/{ => ndk}/ndk-camera.h | 18 ++- 5 files changed, 307 insertions(+), 304 deletions(-) create mode 100755 ndk-camera create mode 100644 src/ndk/ndk-camera.cc rename src/{ => ndk}/ndk-camera.h (92%) diff --git a/build.sh b/build.sh index 53a625d..7ea9755 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,3 @@ #!/bin/sh -clang++ -o ndk-camera src/main.cc -I libs/ -lcamera2ndk -landroid -lmediandk -llog -lnativewindow -lc -lgui -lui -lutils +clang++ -o ndk-camera src/main.cc src/ndk/ndk-camera.cc -I libs/ -lcamera2ndk -landroid -lmediandk -llog -lnativewindow -lc -lgui -lui -lutils diff --git a/ndk-camera b/ndk-camera new file mode 100755 index 0000000000000000000000000000000000000000..0b071c79b75ccff3552628f386366265b0555f05 GIT binary patch literal 208528 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
  • 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Ý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 J9fGfo{|AjO&_@6O literal 0 HcmV?d00001 diff --git a/src/main.cc b/src/main.cc index bee8d37..d2d0911 100644 --- a/src/main.cc +++ b/src/main.cc @@ -2,306 +2,7 @@ // the unexplainable ndk camera api behavior: camera opens fine but no image // is sent through the api. -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ndk-camera.h" - -void NDKCamera::OnSessionState(ACameraCaptureSession* ses, - CaptureSessionState state) { - if (!ses || ses != captureSession_) { - LOGW("CaptureSession is %s", (ses ? "NOT our session" : "NULL")); - return; - } - - ASSERT(state < CaptureSessionState::MAX_STATE, "Wrong state %d", state); - captureSessionState_ = state; -} - -void OnSessionActive(void* ctx, ACameraCaptureSession* ses) { - LOGW("session %p is active", ses); - reinterpret_cast(ctx) - ->OnSessionState(ses, CaptureSessionState::ACTIVE); - PRINTD("session %p is active", ses); -} - -ACameraCaptureSession_stateCallbacks* NDKCamera::GetSessionListener() { - static ACameraCaptureSession_stateCallbacks sessionListener = { - .context = this, - .onClosed = nullptr, - .onReady = nullptr, - .onActive = ::OnSessionActive, - }; - return &sessionListener; -} - -void NDKCamera::OnDeviceError(ACameraDevice* dev, int err) { - std::string id(ACameraDevice_getId(dev)); - LOGI("CameraDevice %s is in error %#x", id.c_str(), err); - /* - PrintCameraDeviceError(err); - - CameraId& cam = cameras_[id]; - - switch (err) { - case ERROR_CAMERA_IN_USE: - cam.available_ = false; - cam.owner_ = false; - break; - case ERROR_CAMERA_SERVICE: - case ERROR_CAMERA_DEVICE: - case ERROR_CAMERA_DISABLED: - case ERROR_MAX_CAMERAS_IN_USE: - cam.available_ = false; - cam.owner_ = false; - break; - default: - LOGI("Unknown Camera Device Error: %#x", err); - } - */ -} - -void OnDeviceErrorChanges(void* ctx, ACameraDevice* dev, int err) { - reinterpret_cast(ctx)->OnDeviceError(dev, err); -} - -ACameraDevice_stateCallbacks* NDKCamera::GetDeviceListener() { - static ACameraDevice_stateCallbacks cameraDeviceListener = { - .context = this, - .onDisconnected = nullptr, - .onError = ::OnDeviceErrorChanges, - }; - return &cameraDeviceListener; -} - -/* - * Camera Manager Listener object - */ -void NDKCamera::OnCameraStatusChanged(const char* id, bool available) { - //cameras_[std::string(id)].available_ = available ? true : false; - PRINTD("Camera available: %s", available? "True" : "False"); -} -void OnCameraAvailable(void* ctx, const char* id) { - reinterpret_cast(ctx)->OnCameraStatusChanged(id, true); -} -void OnCameraUnavailable(void* ctx, const char* id) { - reinterpret_cast(ctx)->OnCameraStatusChanged(id, false); -} - -ACameraManager_AvailabilityCallbacks* NDKCamera::GetManagerListener() { - static ACameraManager_AvailabilityCallbacks cameraMgrListener = { - .context = this, - .onCameraAvailable = ::OnCameraAvailable, - .onCameraUnavailable = ::OnCameraUnavailable, - }; - return &cameraMgrListener; -} - -NDKCamera::NDKCamera() -: cameraMgr_(nullptr), - outputContainer_(nullptr), - captureSession_(nullptr), - captureSessionState_(CaptureSessionState::MAX_STATE), - pDevice_(nullptr){} - -void NDKCamera::Init(bool rear) { - requests_.resize(CAPTURE_REQUEST_COUNT); - memset(requests_.data(), 0, requests_.size() * sizeof(requests_[0])); - cameraMgr_ = ACameraManager_create(); - ASSERT(cameraMgr_, "Failed to create cameraManager"); - - // Pick up the front or rear camera id. - EnumerateCamera(rear); - ASSERT(activeCameraId_.size(), "Unknown ActiveCameraIdx"); - PRINTD("Found camera ID %s", activeCameraId_.c_str()); - // Create back facing camera device - CALL_MGR(openCamera(cameraMgr_, activeCameraId_.c_str(), GetDeviceListener(), &pDevice_)); - CALL_MGR(registerAvailabilityCallback(cameraMgr_, GetManagerListener())); -} - -void NDKCamera::EnumerateCamera(bool rear) { - bool found_camera = false; - ACameraIdList* cameraIds = nullptr; - CALL_MGR(getCameraIdList(cameraMgr_, &cameraIds)); - - for (int i = 0; i < cameraIds->numCameras; ++i) { - const char* id = cameraIds->cameraIds[i]; - ACameraMetadata* metadataObj; - CALL_MGR(getCameraCharacteristics(cameraMgr_, id, &metadataObj)); - - int32_t count = 0; - const uint32_t* tags = nullptr; - ACameraMetadata_getAllTags(metadataObj, &count, &tags); - for (int tagIdx = 0; tagIdx < count; ++tagIdx) { - if (ACAMERA_LENS_FACING == tags[tagIdx]) { - ACameraMetadata_const_entry lensInfo = { - 0, - }; - CALL_METADATA(getConstEntry(metadataObj, tags[tagIdx], &lensInfo)); - int facing = static_cast( - lensInfo.data.u8[0]); - if (rear && facing == ACAMERA_LENS_FACING_BACK) { - activeCameraId_ = id; - found_camera = true; - } else if (!rear && facing == ACAMERA_LENS_FACING_FRONT) { - activeCameraId_ = id; - found_camera = true; - } - break; - } - } - ACameraMetadata_free(metadataObj); - } - - ASSERT(found_camera, "No Camera Available on the device"); - ACameraManager_deleteCameraIdList(cameraIds); -} - -NDKCamera::~NDKCamera() { - // stop session if it is on: - if (captureSessionState_ == CaptureSessionState::ACTIVE) { - ACameraCaptureSession_stopRepeating(captureSession_); - } - ACameraCaptureSession_close(captureSession_); - - for (auto& req : requests_) { - CALL_REQUEST(removeTarget(req.request_, req.target_)); - ACaptureRequest_free(req.request_); - ACameraOutputTarget_free(req.target_); - - CALL_CONTAINER(remove(outputContainer_, req.sessionOutput_)); - ACaptureSessionOutput_free(req.sessionOutput_); - - ANativeWindow_release(req.outputNativeWindow_); - } - - requests_.resize(0); - ACaptureSessionOutputContainer_free(outputContainer_); - - if (pDevice_) { - CALL_DEV(close(pDevice_)); - } - - if (cameraMgr_) { - CALL_MGR(unregisterAvailabilityCallback(cameraMgr_, GetManagerListener())); - ACameraManager_delete(cameraMgr_); - cameraMgr_ = nullptr; - } -} - -void NDKCamera::StartPreview(bool start) { - if (start) { - CALL_SESSION(setRepeatingRequest(captureSession_, nullptr, 1, - &requests_[PREVIEW_REQUEST_IDX].request_, - nullptr)); - } else if (!start && captureSessionState_ == CaptureSessionState::ACTIVE) { - ACameraCaptureSession_stopRepeating(captureSession_); - } else { - ASSERT(false, "Conflict states(%s, %d)", (start ? "true" : "false"), - captureSessionState_); - } -} - -void NDKCamera::CreateSession(int capture_width, int capture_height) { - surfaceBundle_.session = new android::SurfaceComposerClient(); - ASSERT(surfaceBundle_.session, "failed to create surface composer client"); - surfaceBundle_.dtoken = android::SurfaceComposerClient::getBuiltInDisplay( - android::ISurfaceComposer::eDisplayIdMain); - ASSERT(surfaceBundle_.dtoken, "Failed to get built in display"); - - android::status_t status = android::SurfaceComposerClient::getDisplayInfo( - surfaceBundle_.dtoken, &surfaceBundle_.dinfo); - ASSERT(status == 0, "status not zero"); - PRINTD("Dinfo %dx%d", surfaceBundle_.dinfo.w, surfaceBundle_.dinfo.h); - surfaceBundle_.surfaceControl = surfaceBundle_.session->createSurface( - android::String8("preview"), capture_width, capture_height, - android::PIXEL_FORMAT_RGBX_8888, 0); - ASSERT(surfaceBundle_.surfaceControl, "Failed to create surface control!"); - - surfaceBundle_.surface = surfaceBundle_.surfaceControl->getSurface(); - ASSERT(surfaceBundle_.surface, "Failed to get surface!"); - PRINTD("Surface created!"); - - CreateSession(surfaceBundle_.surface.get()); -} - -android::GraphicBuffer* NDKCamera::GetLatestFrame() { - surfaceBundle_.outBuffer = nullptr; - - android::status_t status = surfaceBundle_.surface->getLastQueuedBuffer( - &surfaceBundle_.outBuffer, &surfaceBundle_.outFence, - surfaceBundle_.outTransformMatrix); - - PRINTD("getLastQueuedBuffer status %d", status); - if (surfaceBundle_.outBuffer) { - PRINTD("GraphicBuffer w=%d, h=%d, fmt=%d", - surfaceBundle_.outBuffer->getWidth(), - surfaceBundle_.outBuffer->getHeight(), - surfaceBundle_.outBuffer->getPixelFormat()); - return surfaceBundle_.outBuffer.get(); - } else { - return nullptr; - } -} - -void NDKCamera::CreateSession(ANativeWindow* previewWindow) { - // Create output from this app's ANativeWindow, and add into output container - requests_[PREVIEW_REQUEST_IDX].outputNativeWindow_ = previewWindow; - requests_[PREVIEW_REQUEST_IDX].template_ = TEMPLATE_PREVIEW; - - CALL_CONTAINER(create(&outputContainer_)); - auto& req = requests_[PREVIEW_REQUEST_IDX]; - { - ANativeWindow_acquire(req.outputNativeWindow_); - CALL_OUTPUT(create(req.outputNativeWindow_, &req.sessionOutput_)); - CALL_CONTAINER(add(outputContainer_, req.sessionOutput_)); - CALL_TARGET(create(req.outputNativeWindow_, &req.target_)); - CALL_DEV(createCaptureRequest(pDevice_, req.template_, &req.request_)); - CALL_REQUEST(addTarget(req.request_, req.target_)); - } - - // Create a capture session for the given preview request - captureSessionState_ = CaptureSessionState::READY; - CALL_DEV(createCaptureSession(pDevice_, - outputContainer_, GetSessionListener(), - &captureSession_)); -} - -void NDKCamera::CreateSession(ANativeWindow* previewWindow, - ANativeWindow* jpgWindow) { - // Create output from this app's ANativeWindow, and add into output container - requests_[PREVIEW_REQUEST_IDX].outputNativeWindow_ = previewWindow; - requests_[PREVIEW_REQUEST_IDX].template_ = TEMPLATE_PREVIEW; - requests_[JPG_CAPTURE_REQUEST_IDX].outputNativeWindow_ = jpgWindow; - requests_[JPG_CAPTURE_REQUEST_IDX].template_ = TEMPLATE_STILL_CAPTURE; - - CALL_CONTAINER(create(&outputContainer_)); - for (auto& req : requests_) { - ANativeWindow_acquire(req.outputNativeWindow_); - CALL_OUTPUT(create(req.outputNativeWindow_, &req.sessionOutput_)); - CALL_CONTAINER(add(outputContainer_, req.sessionOutput_)); - CALL_TARGET(create(req.outputNativeWindow_, &req.target_)); - CALL_DEV(createCaptureRequest(pDevice_, req.template_, &req.request_)); - CALL_REQUEST(addTarget(req.request_, req.target_)); - } - - // Create a capture session for the given preview request - captureSessionState_ = CaptureSessionState::READY; - CALL_DEV(createCaptureSession(pDevice_, - outputContainer_, GetSessionListener(), - &captureSession_)); -} +#include "ndk/ndk-camera.h" int main(int argc, char** argv) { bool rear_camera = false; diff --git a/src/ndk/ndk-camera.cc b/src/ndk/ndk-camera.cc new file mode 100644 index 0000000..478e411 --- /dev/null +++ b/src/ndk/ndk-camera.cc @@ -0,0 +1,290 @@ +#include "ndk-camera.h" + +const char* GetErrorStr(camera_status_t err) { + return GetPairStr(err, errorInfo); +} + +void NDKCamera::OnSessionState(ACameraCaptureSession* ses, + CaptureSessionState state) { + if (!ses || ses != captureSession_) { + LOGW("CaptureSession is %s", (ses ? "NOT our session" : "NULL")); + return; + } + + ASSERT(state < CaptureSessionState::MAX_STATE, "Wrong state %d", state); + captureSessionState_ = state; +} + +void OnSessionActive(void* ctx, ACameraCaptureSession* ses) { + LOGW("session %p is active", ses); + reinterpret_cast(ctx) + ->OnSessionState(ses, CaptureSessionState::ACTIVE); + PRINTD("session %p is active", ses); +} + +ACameraCaptureSession_stateCallbacks* NDKCamera::GetSessionListener() { + static ACameraCaptureSession_stateCallbacks sessionListener = { + .context = this, + .onClosed = nullptr, + .onReady = nullptr, + .onActive = ::OnSessionActive, + }; + return &sessionListener; +} + +void NDKCamera::OnDeviceError(ACameraDevice* dev, int err) { + std::string id(ACameraDevice_getId(dev)); + LOGI("CameraDevice %s is in error %#x", id.c_str(), err); + /* + PrintCameraDeviceError(err); + + CameraId& cam = cameras_[id]; + + switch (err) { + case ERROR_CAMERA_IN_USE: + cam.available_ = false; + cam.owner_ = false; + break; + case ERROR_CAMERA_SERVICE: + case ERROR_CAMERA_DEVICE: + case ERROR_CAMERA_DISABLED: + case ERROR_MAX_CAMERAS_IN_USE: + cam.available_ = false; + cam.owner_ = false; + break; + default: + LOGI("Unknown Camera Device Error: %#x", err); + } + */ +} + +void OnDeviceErrorChanges(void* ctx, ACameraDevice* dev, int err) { + reinterpret_cast(ctx)->OnDeviceError(dev, err); +} + +ACameraDevice_stateCallbacks* NDKCamera::GetDeviceListener() { + static ACameraDevice_stateCallbacks cameraDeviceListener = { + .context = this, + .onDisconnected = nullptr, + .onError = ::OnDeviceErrorChanges, + }; + return &cameraDeviceListener; +} + +/* + * Camera Manager Listener object + */ +void NDKCamera::OnCameraStatusChanged(const char* id, bool available) { + //cameras_[std::string(id)].available_ = available ? true : false; + PRINTD("Camera available: %s", available? "True" : "False"); +} +void OnCameraAvailable(void* ctx, const char* id) { + reinterpret_cast(ctx)->OnCameraStatusChanged(id, true); +} +void OnCameraUnavailable(void* ctx, const char* id) { + reinterpret_cast(ctx)->OnCameraStatusChanged(id, false); +} + +ACameraManager_AvailabilityCallbacks* NDKCamera::GetManagerListener() { + static ACameraManager_AvailabilityCallbacks cameraMgrListener = { + .context = this, + .onCameraAvailable = ::OnCameraAvailable, + .onCameraUnavailable = ::OnCameraUnavailable, + }; + return &cameraMgrListener; +} + +NDKCamera::NDKCamera() +: cameraMgr_(nullptr), + outputContainer_(nullptr), + captureSession_(nullptr), + captureSessionState_(CaptureSessionState::MAX_STATE), + pDevice_(nullptr){} + +void NDKCamera::Init(bool rear) { + requests_.resize(CAPTURE_REQUEST_COUNT); + memset(requests_.data(), 0, requests_.size() * sizeof(requests_[0])); + cameraMgr_ = ACameraManager_create(); + ASSERT(cameraMgr_, "Failed to create cameraManager"); + + // Pick up the front or rear camera id. + EnumerateCamera(rear); + ASSERT(activeCameraId_.size(), "Unknown ActiveCameraIdx"); + PRINTD("Found camera ID %s", activeCameraId_.c_str()); + // Create back facing camera device + CALL_MGR(openCamera(cameraMgr_, activeCameraId_.c_str(), GetDeviceListener(), &pDevice_)); + CALL_MGR(registerAvailabilityCallback(cameraMgr_, GetManagerListener())); +} + +void NDKCamera::EnumerateCamera(bool rear) { + bool found_camera = false; + ACameraIdList* cameraIds = nullptr; + CALL_MGR(getCameraIdList(cameraMgr_, &cameraIds)); + + for (int i = 0; i < cameraIds->numCameras; ++i) { + const char* id = cameraIds->cameraIds[i]; + ACameraMetadata* metadataObj; + CALL_MGR(getCameraCharacteristics(cameraMgr_, id, &metadataObj)); + + int32_t count = 0; + const uint32_t* tags = nullptr; + ACameraMetadata_getAllTags(metadataObj, &count, &tags); + for (int tagIdx = 0; tagIdx < count; ++tagIdx) { + if (ACAMERA_LENS_FACING == tags[tagIdx]) { + ACameraMetadata_const_entry lensInfo = { + 0, + }; + CALL_METADATA(getConstEntry(metadataObj, tags[tagIdx], &lensInfo)); + int facing = static_cast( + lensInfo.data.u8[0]); + if (rear && facing == ACAMERA_LENS_FACING_BACK) { + activeCameraId_ = id; + found_camera = true; + } else if (!rear && facing == ACAMERA_LENS_FACING_FRONT) { + activeCameraId_ = id; + found_camera = true; + } + break; + } + } + ACameraMetadata_free(metadataObj); + } + + ASSERT(found_camera, "No Camera Available on the device"); + ACameraManager_deleteCameraIdList(cameraIds); +} + +NDKCamera::~NDKCamera() { + // stop session if it is on: + if (captureSessionState_ == CaptureSessionState::ACTIVE) { + ACameraCaptureSession_stopRepeating(captureSession_); + } + ACameraCaptureSession_close(captureSession_); + + for (auto& req : requests_) { + CALL_REQUEST(removeTarget(req.request_, req.target_)); + ACaptureRequest_free(req.request_); + ACameraOutputTarget_free(req.target_); + + CALL_CONTAINER(remove(outputContainer_, req.sessionOutput_)); + ACaptureSessionOutput_free(req.sessionOutput_); + + ANativeWindow_release(req.outputNativeWindow_); + } + + requests_.resize(0); + ACaptureSessionOutputContainer_free(outputContainer_); + + if (pDevice_) { + CALL_DEV(close(pDevice_)); + } + + if (cameraMgr_) { + CALL_MGR(unregisterAvailabilityCallback(cameraMgr_, GetManagerListener())); + ACameraManager_delete(cameraMgr_); + cameraMgr_ = nullptr; + } +} + +void NDKCamera::StartPreview(bool start) { + if (start) { + CALL_SESSION(setRepeatingRequest(captureSession_, nullptr, 1, + &requests_[PREVIEW_REQUEST_IDX].request_, + nullptr)); + } else if (!start && captureSessionState_ == CaptureSessionState::ACTIVE) { + ACameraCaptureSession_stopRepeating(captureSession_); + } else { + ASSERT(false, "Conflict states(%s, %d)", (start ? "true" : "false"), + captureSessionState_); + } +} + +void NDKCamera::CreateSession(int capture_width, int capture_height) { + surfaceBundle_.session = new android::SurfaceComposerClient(); + ASSERT(surfaceBundle_.session, "failed to create surface composer client"); + surfaceBundle_.dtoken = android::SurfaceComposerClient::getBuiltInDisplay( + android::ISurfaceComposer::eDisplayIdMain); + ASSERT(surfaceBundle_.dtoken, "Failed to get built in display"); + + android::status_t status = android::SurfaceComposerClient::getDisplayInfo( + surfaceBundle_.dtoken, &surfaceBundle_.dinfo); + ASSERT(status == 0, "status not zero"); + PRINTD("Dinfo %dx%d", surfaceBundle_.dinfo.w, surfaceBundle_.dinfo.h); + surfaceBundle_.surfaceControl = surfaceBundle_.session->createSurface( + android::String8("preview"), capture_width, capture_height, + android::PIXEL_FORMAT_RGBX_8888, 0); + ASSERT(surfaceBundle_.surfaceControl, "Failed to create surface control!"); + + surfaceBundle_.surface = surfaceBundle_.surfaceControl->getSurface(); + ASSERT(surfaceBundle_.surface, "Failed to get surface!"); + PRINTD("Surface created!"); + + CreateSession(surfaceBundle_.surface.get()); +} + +android::GraphicBuffer* NDKCamera::GetLatestFrame() { + surfaceBundle_.outBuffer = nullptr; + + android::status_t status = surfaceBundle_.surface->getLastQueuedBuffer( + &surfaceBundle_.outBuffer, &surfaceBundle_.outFence, + surfaceBundle_.outTransformMatrix); + + PRINTD("getLastQueuedBuffer status %d", status); + if (surfaceBundle_.outBuffer) { + PRINTD("GraphicBuffer w=%d, h=%d, fmt=%d", + surfaceBundle_.outBuffer->getWidth(), + surfaceBundle_.outBuffer->getHeight(), + surfaceBundle_.outBuffer->getPixelFormat()); + return surfaceBundle_.outBuffer.get(); + } else { + return nullptr; + } +} + +void NDKCamera::CreateSession(ANativeWindow* previewWindow) { + // Create output from this app's ANativeWindow, and add into output container + requests_[PREVIEW_REQUEST_IDX].outputNativeWindow_ = previewWindow; + requests_[PREVIEW_REQUEST_IDX].template_ = TEMPLATE_PREVIEW; + + CALL_CONTAINER(create(&outputContainer_)); + auto& req = requests_[PREVIEW_REQUEST_IDX]; + { + ANativeWindow_acquire(req.outputNativeWindow_); + CALL_OUTPUT(create(req.outputNativeWindow_, &req.sessionOutput_)); + CALL_CONTAINER(add(outputContainer_, req.sessionOutput_)); + CALL_TARGET(create(req.outputNativeWindow_, &req.target_)); + CALL_DEV(createCaptureRequest(pDevice_, req.template_, &req.request_)); + CALL_REQUEST(addTarget(req.request_, req.target_)); + } + + // Create a capture session for the given preview request + captureSessionState_ = CaptureSessionState::READY; + CALL_DEV(createCaptureSession(pDevice_, + outputContainer_, GetSessionListener(), + &captureSession_)); +} + +void NDKCamera::CreateSession(ANativeWindow* previewWindow, + ANativeWindow* jpgWindow) { + // Create output from this app's ANativeWindow, and add into output container + requests_[PREVIEW_REQUEST_IDX].outputNativeWindow_ = previewWindow; + requests_[PREVIEW_REQUEST_IDX].template_ = TEMPLATE_PREVIEW; + requests_[JPG_CAPTURE_REQUEST_IDX].outputNativeWindow_ = jpgWindow; + requests_[JPG_CAPTURE_REQUEST_IDX].template_ = TEMPLATE_STILL_CAPTURE; + + CALL_CONTAINER(create(&outputContainer_)); + for (auto& req : requests_) { + ANativeWindow_acquire(req.outputNativeWindow_); + CALL_OUTPUT(create(req.outputNativeWindow_, &req.sessionOutput_)); + CALL_CONTAINER(add(outputContainer_, req.sessionOutput_)); + CALL_TARGET(create(req.outputNativeWindow_, &req.target_)); + CALL_DEV(createCaptureRequest(pDevice_, req.template_, &req.request_)); + CALL_REQUEST(addTarget(req.request_, req.target_)); + } + + // Create a capture session for the given preview request + captureSessionState_ = CaptureSessionState::READY; + CALL_DEV(createCaptureSession(pDevice_, + outputContainer_, GetSessionListener(), + &captureSession_)); +} diff --git a/src/ndk-camera.h b/src/ndk/ndk-camera.h similarity index 92% rename from src/ndk-camera.h rename to src/ndk/ndk-camera.h index d606bfe..61492a7 100644 --- a/src/ndk-camera.h +++ b/src/ndk/ndk-camera.h @@ -1,6 +1,20 @@ #ifndef NDK_CAMERA_H_ #define NDK_CAMERA_H_ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + #define LOG_TAG "NDK-CAMERA" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) @@ -67,9 +81,7 @@ static std::vector errorInfo{ MAKE_PAIR(ACAMERA_ERROR_PERMISSION_DENIED), }; -const char* GetErrorStr(camera_status_t err) { - return GetPairStr(err, errorInfo); -} +const char* GetErrorStr(camera_status_t err); /** * MAX_BUF_COUNT: